1 /* $OpenBSD: mvpcie.c,v 1.2 2020/07/14 15:42:19 patrick Exp $ */ 2 /* 3 * Copyright (c) 2018 Patrick Wildt <patrick@blueri.se> 4 * Copyright (c) 2018 Mark Kettenis <kettenis@openbsd.org> 5 * 6 * Permission to use, copy, modify, and distribute this software for any 7 * purpose with or without fee is hereby granted, provided that the above 8 * copyright notice and this permission notice appear in all copies. 9 * 10 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 11 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 12 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 13 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 14 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 15 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 16 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 17 */ 18 19 #include <sys/param.h> 20 #include <sys/systm.h> 21 #include <sys/device.h> 22 #include <sys/extent.h> 23 #include <sys/malloc.h> 24 25 #include <machine/intr.h> 26 #include <machine/bus.h> 27 #include <machine/fdt.h> 28 29 #include <armv7/marvell/mvmbusvar.h> 30 31 #include <dev/pci/pcidevs.h> 32 #include <dev/pci/pcireg.h> 33 #include <dev/pci/pcivar.h> 34 #include <dev/pci/ppbreg.h> 35 36 #include <dev/ofw/openfirm.h> 37 #include <dev/ofw/ofw_clock.h> 38 #include <dev/ofw/ofw_gpio.h> 39 #include <dev/ofw/fdt.h> 40 41 /* Registers */ 42 #define PCIE_DEV_ID 0x0000 43 #define PCIE_CMD 0x0004 44 #define PCIE_DEV_REV 0x0008 45 #define PCIE_BAR_LO(n) (0x0010 + ((n) << 3)) 46 #define PCIE_BAR_HI(n) (0x0014 + ((n) << 3)) 47 #define PCIE_BAR_CTRL(n) (0x1804 + (((n) - 1) * 4)) 48 #define PCIE_WIN04_CTRL(n) (0x1820 + ((n) << 4)) 49 #define PCIE_WIN04_BASE(n) (0x1824 + ((n) << 4)) 50 #define PCIE_WIN04_REMAP(n) (0x182c + ((n) << 4)) 51 #define PCIE_WIN5_CTRL 0x1880 52 #define PCIE_WIN5_BASE 0x1884 53 #define PCIE_WIN5_REMAP 0x188c 54 #define PCIE_CONF_ADDR 0x18f8 55 #define PCIE_CONF_ADDR_EN 0x80000000 56 #define PCIE_CONF_REG(r) ((((r) & 0xf00) << 16) | ((r) & 0xfc)) 57 #define PCIE_CONF_BUS(b) (((b) & 0xff) << 16) 58 #define PCIE_CONF_DEV(d) (((d) & 0x1f) << 11) 59 #define PCIE_CONF_FUNC(f) (((f) & 0x7) << 8) 60 #define PCIE_CONF_DATA 0x18fc 61 #define PCIE_MASK 0x1910 62 #define PCIE_MASK_ENABLE_INTS (0xf << 24) 63 #define PCIE_STAT 0x1a04 64 #define PCIE_STAT_LINK_DOWN (1 << 0) 65 #define PCIE_STAT_BUS_SHIFT 8 66 #define PCIE_STAT_BUS_MASK 0xff 67 #define PCIE_STAT_DEV_SHIFT 16 68 #define PCIE_STAT_DEV_MASK 0x1f 69 70 #define PCIE_SWCAP 0x0040 71 72 #define PCIE_TARGET(target) (((target) & 0xf) << 4) 73 #define PCIE_ATTR(attr) (((attr) & 0xff) << 8) 74 #define PCIE_BASEADDR(base) ((base) & 0xffff0000) 75 #define PCIE_SIZE(size) (((size) - 1) & 0xffff0000) 76 #define PCIE_WINEN (1 << 0) 77 78 #define HREAD4(po, reg) \ 79 (bus_space_read_4((po)->po_iot, (po)->po_ioh, (reg))) 80 #define HWRITE4(po, reg, val) \ 81 bus_space_write_4((po)->po_iot, (po)->po_ioh, (reg), (val)) 82 #define HSET4(po, reg, bits) \ 83 HWRITE4((po), (reg), HREAD4((po), (reg)) | (bits)) 84 #define HCLR4(po, reg, bits) \ 85 HWRITE4((po), (reg), HREAD4((po), (reg)) & ~(bits)) 86 87 struct mvpcie_softc; 88 89 struct mvpcie_range { 90 uint32_t flags; 91 uint32_t slot; 92 uint32_t pci_base; 93 uint64_t phys_base; 94 uint64_t size; 95 }; 96 97 struct mvpcie_port { 98 struct mvpcie_softc *po_sc; 99 bus_space_tag_t po_iot; 100 bus_space_handle_t po_ioh; 101 bus_dma_tag_t po_dmat; 102 int po_node; 103 104 int po_port; 105 int po_lane; 106 int po_dev; 107 int po_fn; 108 109 uint32_t *po_gpio; 110 size_t po_gpiolen; 111 112 struct arm32_pci_chipset po_pc; 113 int po_bus; 114 115 uint32_t po_bridge_command; 116 uint32_t po_bridge_bar0; 117 uint32_t po_bridge_bar1; 118 uint32_t po_bridge_businfo; 119 uint32_t po_bridge_iobase; 120 uint32_t po_bridge_iobaseupper; 121 uint32_t po_bridge_iolimit; 122 uint32_t po_bridge_iolimitupper; 123 uint32_t po_bridge_membase; 124 uint32_t po_bridge_memlimit; 125 126 uint32_t po_win_iotarget; 127 uint32_t po_win_ioattr; 128 uint32_t po_win_memtarget; 129 uint32_t po_win_memattr; 130 131 uint32_t po_win_iobase; 132 uint32_t po_win_iosize; 133 uint32_t po_win_ioremap; 134 uint32_t po_win_membase; 135 uint32_t po_win_memsize; 136 }; 137 138 struct mvpcie_softc { 139 struct device sc_dev; 140 bus_space_tag_t sc_iot; 141 bus_dma_tag_t sc_dmat; 142 143 int sc_node; 144 int sc_acells; 145 int sc_scells; 146 int sc_pacells; 147 int sc_pscells; 148 struct mvpcie_range *sc_ranges; 149 int sc_rangeslen; 150 151 struct extent *sc_busex; 152 struct extent *sc_memex; 153 struct extent *sc_ioex; 154 char sc_busex_name[32]; 155 char sc_ioex_name[32]; 156 char sc_memex_name[32]; 157 158 int sc_nports; 159 struct mvpcie_port *sc_ports; 160 }; 161 162 int mvpcie_match(struct device *, void *, void *); 163 void mvpcie_attach(struct device *, struct device *, void *); 164 165 struct cfattach mvpcie_ca = { 166 sizeof (struct mvpcie_softc), mvpcie_match, mvpcie_attach 167 }; 168 169 struct cfdriver mvpcie_cd = { 170 NULL, "mvpcie", DV_DULL 171 }; 172 173 int 174 mvpcie_match(struct device *parent, void *match, void *aux) 175 { 176 struct fdt_attach_args *faa = aux; 177 178 return OF_is_compatible(faa->fa_node, "marvell,armada-370-pcie"); 179 } 180 181 void mvpcie_port_attach(struct mvpcie_softc *, struct mvpcie_port *, int); 182 void mvpcie_wininit(struct mvpcie_port *); 183 void mvpcie_add_windows(paddr_t, size_t, paddr_t, uint8_t, uint8_t); 184 void mvpcie_del_windows(paddr_t, size_t); 185 void mvpcie_io_change(struct mvpcie_port *); 186 void mvpcie_mem_change(struct mvpcie_port *); 187 int mvpcie_link_up(struct mvpcie_port *); 188 189 void mvpcie_attach_hook(struct device *, struct device *, 190 struct pcibus_attach_args *); 191 int mvpcie_bus_maxdevs(void *, int); 192 pcitag_t mvpcie_make_tag(void *, int, int, int); 193 void mvpcie_decompose_tag(void *, pcitag_t, int *, int *, int *); 194 int mvpcie_conf_size(void *, pcitag_t); 195 pcireg_t mvpcie_conf_read(void *, pcitag_t, int); 196 void mvpcie_conf_write(void *, pcitag_t, int, pcireg_t); 197 198 int mvpcie_intr_map(struct pci_attach_args *, pci_intr_handle_t *); 199 int mvpcie_intr_map_msi(struct pci_attach_args *, pci_intr_handle_t *); 200 int mvpcie_intr_map_msix(struct pci_attach_args *, int, 201 pci_intr_handle_t *); 202 const char *mvpcie_intr_string(void *, pci_intr_handle_t); 203 void *mvpcie_intr_establish(void *, pci_intr_handle_t, int, 204 struct cpu_info *ci, int (*)(void *), void *, char *); 205 void mvpcie_intr_disestablish(void *, void *); 206 207 void 208 mvpcie_attach(struct device *parent, struct device *self, void *aux) 209 { 210 struct mvpcie_softc *sc = (struct mvpcie_softc *)self; 211 struct fdt_attach_args *faa = aux; 212 uint32_t bus_range[2]; 213 uint32_t *ranges; 214 int i, j, nranges, rangeslen; 215 char buf[32]; 216 int node; 217 218 sc->sc_iot = faa->fa_iot; 219 sc->sc_dmat = faa->fa_dmat; 220 sc->sc_node = faa->fa_node; 221 222 sc->sc_acells = OF_getpropint(sc->sc_node, "#address-cells", 223 faa->fa_acells); 224 sc->sc_scells = OF_getpropint(sc->sc_node, "#size-cells", 225 faa->fa_scells); 226 sc->sc_pacells = faa->fa_acells; 227 sc->sc_pscells = faa->fa_scells; 228 229 rangeslen = OF_getproplen(sc->sc_node, "ranges"); 230 if (rangeslen <= 0 || (rangeslen % sizeof(uint32_t)) || 231 (rangeslen / sizeof(uint32_t)) % (sc->sc_acells + 232 sc->sc_pacells + sc->sc_scells)) { 233 printf(": invalid ranges property\n"); 234 return; 235 } 236 237 ranges = malloc(rangeslen, M_TEMP, M_WAITOK); 238 OF_getpropintarray(sc->sc_node, "ranges", ranges, 239 rangeslen); 240 241 nranges = (rangeslen / sizeof(uint32_t)) / 242 (sc->sc_acells + sc->sc_pacells + sc->sc_scells); 243 sc->sc_ranges = mallocarray(nranges, 244 sizeof(struct mvpcie_range), M_TEMP, M_WAITOK); 245 sc->sc_rangeslen = nranges; 246 247 for (i = 0, j = 0; i < nranges; i++) { 248 sc->sc_ranges[i].flags = ranges[j++]; 249 sc->sc_ranges[i].slot = ranges[j++]; 250 sc->sc_ranges[i].pci_base = ranges[j++]; 251 sc->sc_ranges[i].phys_base = ranges[j++]; 252 if (sc->sc_pacells == 2) { 253 sc->sc_ranges[i].phys_base <<= 32; 254 sc->sc_ranges[i].phys_base |= ranges[j++]; 255 } 256 sc->sc_ranges[i].size = ranges[j++]; 257 if (sc->sc_scells == 2) { 258 sc->sc_ranges[i].size <<= 32; 259 sc->sc_ranges[i].size |= ranges[j++]; 260 } 261 } 262 263 free(ranges, M_TEMP, rangeslen); 264 265 printf("\n"); 266 267 /* Create extents for our address spaces. */ 268 snprintf(sc->sc_busex_name, sizeof(sc->sc_busex_name), 269 "%s pcibus", sc->sc_dev.dv_xname); 270 snprintf(sc->sc_ioex_name, sizeof(sc->sc_ioex_name), 271 "%s pciio", sc->sc_dev.dv_xname); 272 snprintf(sc->sc_memex_name, sizeof(sc->sc_memex_name), 273 "%s pcimem", sc->sc_dev.dv_xname); 274 sc->sc_busex = extent_create(sc->sc_busex_name, 0, 255, 275 M_DEVBUF, NULL, 0, EX_WAITOK | EX_FILLED); 276 sc->sc_ioex = extent_create(sc->sc_ioex_name, 0, 0xffffffff, 277 M_DEVBUF, NULL, 0, EX_WAITOK | EX_FILLED); 278 sc->sc_memex = extent_create(sc->sc_memex_name, 0, (u_long)-1, 279 M_DEVBUF, NULL, 0, EX_WAITOK | EX_FILLED); 280 281 /* Set up bus range. */ 282 if (OF_getpropintarray(sc->sc_node, "bus-range", bus_range, 283 sizeof(bus_range)) != sizeof(bus_range) || 284 bus_range[0] >= 32 || bus_range[1] >= 32) { 285 bus_range[0] = 0; 286 bus_range[1] = 31; 287 } 288 extent_free(sc->sc_busex, bus_range[0], 289 bus_range[1] - bus_range[0] + 1, EX_WAITOK); 290 291 /* Set up memory mapped I/O range. */ 292 extent_free(sc->sc_memex, mvmbus_pcie_mem_aperture[0], 293 mvmbus_pcie_mem_aperture[1], EX_NOWAIT); 294 extent_free(sc->sc_ioex, mvmbus_pcie_io_aperture[0], 295 mvmbus_pcie_io_aperture[1], EX_NOWAIT); 296 297 for (node = OF_child(sc->sc_node); node != 0; node = OF_peer(node)) { 298 if (OF_getproplen(node, "status") <= 0) 299 continue; 300 OF_getprop(node, "status", buf, sizeof(buf)); 301 if (strcmp(buf, "disabled") == 0) 302 continue; 303 sc->sc_nports++; 304 } 305 306 if (!sc->sc_nports) 307 return; 308 309 sc->sc_ports = mallocarray(sc->sc_nports, 310 sizeof(struct mvpcie_port), M_DEVBUF, M_WAITOK); 311 312 i = 0; 313 for (node = OF_child(sc->sc_node); node != 0; node = OF_peer(node)) { 314 if (OF_getproplen(node, "status") <= 0) 315 continue; 316 OF_getprop(node, "status", buf, sizeof(buf)); 317 if (strcmp(buf, "disabled") == 0) 318 continue; 319 mvpcie_port_attach(sc, &sc->sc_ports[i++], node); 320 } 321 } 322 323 void 324 mvpcie_port_attach(struct mvpcie_softc *sc, struct mvpcie_port *po, int node) 325 { 326 struct pcibus_attach_args pba; 327 uint32_t assigned[5]; 328 uint32_t reg[5]; 329 int i; 330 331 po->po_bus = 0; 332 po->po_sc = sc; 333 po->po_iot = sc->sc_iot; 334 po->po_dmat = sc->sc_dmat; 335 po->po_node = node; 336 337 clock_enable_all(po->po_node); 338 339 if (OF_getpropintarray(po->po_node, "reg", reg, 340 sizeof(reg)) != sizeof(reg)) 341 return; 342 343 if (OF_getpropintarray(po->po_node, "assigned-addresses", assigned, 344 sizeof(assigned)) != sizeof(assigned)) 345 return; 346 347 po->po_port = OF_getpropint(po->po_node, "marvell,pcie-port", 0); 348 po->po_port = OF_getpropint(po->po_node, "marvell,pcie-lane", 0); 349 po->po_dev = (reg[0] >> 11) & 0x1f; 350 po->po_fn = (reg[0] >> 8) & 0x7; 351 352 po->po_bridge_iobase = 1; 353 po->po_bridge_iolimit = 1; 354 355 po->po_gpiolen = OF_getproplen(po->po_node, "reset-gpios"); 356 if (po->po_gpiolen) { 357 po->po_gpio = malloc(po->po_gpiolen, M_DEVBUF, M_WAITOK); 358 OF_getpropintarray(po->po_node, "reset-gpios", 359 po->po_gpio, po->po_gpiolen); 360 gpio_controller_config_pin(po->po_gpio, GPIO_CONFIG_OUTPUT); 361 gpio_controller_set_pin(po->po_gpio, 1); 362 delay(100 * 1000); 363 gpio_controller_set_pin(po->po_gpio, 0); 364 delay(100 * 1000); 365 } 366 367 /* Look for IO and MEM mbus window info. */ 368 for (i = 0; i < sc->sc_rangeslen; i++) { 369 if (sc->sc_ranges[i].slot != po->po_dev) 370 continue; 371 if (((sc->sc_ranges[i].flags >> 24) & 0x3) == 0x1) { 372 po->po_win_iotarget = ((sc->sc_ranges[i].phys_base) >> 373 56) & 0xff; 374 po->po_win_ioattr = ((sc->sc_ranges[i].phys_base) >> 375 48) & 0xff; 376 } 377 if (((sc->sc_ranges[i].flags >> 24) & 0x3) == 0x2) { 378 po->po_win_memtarget = ((sc->sc_ranges[i].phys_base) >> 379 56) & 0xff; 380 po->po_win_memattr = ((sc->sc_ranges[i].phys_base) >> 381 48) & 0xff; 382 } 383 } 384 385 /* Map space. */ 386 for (i = 0; i < sc->sc_rangeslen; i++) { 387 if (sc->sc_ranges[i].pci_base == assigned[2]) 388 break; 389 } 390 if (i == sc->sc_rangeslen) 391 return; 392 393 if (bus_space_map(po->po_iot, sc->sc_ranges[i].phys_base, 394 sc->sc_ranges[i].size, 0, &po->po_ioh)) { 395 printf("%s: can't map ctrl registers\n", 396 sc->sc_dev.dv_xname); 397 return; 398 } 399 400 /* Set local dev number to 1. */ 401 HWRITE4(po, PCIE_STAT, (HREAD4(po, PCIE_STAT) & 402 ~(PCIE_STAT_DEV_MASK << PCIE_STAT_DEV_SHIFT)) | 403 1 << PCIE_STAT_DEV_SHIFT); 404 405 mvpcie_wininit(po); 406 407 HWRITE4(po, PCIE_CMD, HREAD4(po, PCIE_CMD) | 408 PCI_COMMAND_IO_ENABLE | PCI_COMMAND_MEM_ENABLE | 409 PCI_COMMAND_MASTER_ENABLE); 410 HWRITE4(po, PCIE_MASK, HREAD4(po, PCIE_MASK) | 411 PCIE_MASK_ENABLE_INTS); 412 413 if (!mvpcie_link_up(po)) 414 return; 415 416 po->po_pc.pc_conf_v = po; 417 po->po_pc.pc_attach_hook = mvpcie_attach_hook; 418 po->po_pc.pc_bus_maxdevs = mvpcie_bus_maxdevs; 419 po->po_pc.pc_make_tag = mvpcie_make_tag; 420 po->po_pc.pc_decompose_tag = mvpcie_decompose_tag; 421 po->po_pc.pc_conf_size = mvpcie_conf_size; 422 po->po_pc.pc_conf_read = mvpcie_conf_read; 423 po->po_pc.pc_conf_write = mvpcie_conf_write; 424 425 po->po_pc.pc_intr_v = po; 426 po->po_pc.pc_intr_map = mvpcie_intr_map; 427 po->po_pc.pc_intr_map_msi = mvpcie_intr_map_msi; 428 po->po_pc.pc_intr_map_msix = mvpcie_intr_map_msix; 429 po->po_pc.pc_intr_string = mvpcie_intr_string; 430 po->po_pc.pc_intr_establish = mvpcie_intr_establish; 431 po->po_pc.pc_intr_disestablish = mvpcie_intr_disestablish; 432 433 /* Skip address translation. */ 434 extern struct bus_space armv7_bs_tag; 435 memset(&pba, 0, sizeof(pba)); 436 pba.pba_busname = "pci"; 437 pba.pba_iot = &armv7_bs_tag; 438 pba.pba_memt = &armv7_bs_tag; 439 pba.pba_dmat = po->po_dmat; 440 pba.pba_pc = &po->po_pc; 441 pba.pba_busex = sc->sc_busex; 442 pba.pba_memex = sc->sc_memex; 443 pba.pba_ioex = sc->sc_ioex; 444 pba.pba_domain = pci_ndomains++; 445 pba.pba_bus = po->po_bus; 446 447 config_found(&sc->sc_dev, &pba, NULL); 448 } 449 450 void 451 mvpcie_wininit(struct mvpcie_port *po) 452 { 453 size_t size; 454 int i; 455 456 if (mvmbus_dram_info == NULL) 457 panic("%s: mbus dram information not set up", __func__); 458 459 for (i = 0; i < 3; i++) { 460 HWRITE4(po, PCIE_BAR_CTRL(i), 0); 461 HWRITE4(po, PCIE_BAR_LO(i), 0); 462 HWRITE4(po, PCIE_BAR_HI(i), 0); 463 } 464 465 for (i = 0; i < 5; i++) { 466 HWRITE4(po, PCIE_WIN04_CTRL(i), 0); 467 HWRITE4(po, PCIE_WIN04_BASE(i), 0); 468 HWRITE4(po, PCIE_WIN04_REMAP(i), 0); 469 } 470 471 HWRITE4(po, PCIE_WIN5_CTRL, 0); 472 HWRITE4(po, PCIE_WIN5_BASE, 0); 473 HWRITE4(po, PCIE_WIN5_REMAP, 0); 474 475 size = 0; 476 for (i = 0; i < mvmbus_dram_info->numcs; i++) { 477 struct mbus_dram_window *win = &mvmbus_dram_info->cs[i]; 478 479 HWRITE4(po, PCIE_WIN04_BASE(i), PCIE_BASEADDR(win->base)); 480 HWRITE4(po, PCIE_WIN04_REMAP(i), 0); 481 HWRITE4(po, PCIE_WIN04_CTRL(i), 482 PCIE_WINEN | 483 PCIE_TARGET(mvmbus_dram_info->targetid) | 484 PCIE_ATTR(win->attr) | 485 PCIE_SIZE(win->size)); 486 487 size += win->size; 488 } 489 490 if ((size & (size - 1)) != 0) 491 size = 1 << fls(size); 492 493 HWRITE4(po, PCIE_BAR_LO(1), mvmbus_dram_info->cs[0].base); 494 HWRITE4(po, PCIE_BAR_HI(1), 0); 495 HWRITE4(po, PCIE_BAR_CTRL(1), PCIE_WINEN | PCIE_SIZE(size)); 496 } 497 498 void 499 mvpcie_add_windows(paddr_t base, size_t size, paddr_t remap, 500 uint8_t target, uint8_t attr) 501 { 502 while (size) { 503 size_t sz = 1 << (fls(size) - 1); 504 505 mvmbus_add_window(base, size, remap, target, attr); 506 base += sz; 507 size -= sz; 508 if (remap != MVMBUS_NO_REMAP) 509 remap += sz; 510 } 511 } 512 513 void 514 mvpcie_del_windows(paddr_t base, size_t size) 515 { 516 while (size) { 517 size_t sz = 1 << (fls(size) - 1); 518 519 mvmbus_del_window(base, sz); 520 base += sz; 521 size -= sz; 522 } 523 } 524 525 void 526 mvpcie_io_change(struct mvpcie_port *po) 527 { 528 paddr_t base, remap; 529 size_t size; 530 531 /* If the limits are bogus or IO is disabled ... */ 532 if ((po->po_bridge_iolimit < po->po_bridge_iobase || 533 po->po_bridge_iolimitupper < po->po_bridge_iobaseupper || 534 (po->po_bridge_command & PCI_COMMAND_IO_ENABLE) == 0)) { 535 /* ... delete the window if enabled. */ 536 if (po->po_win_iosize) { 537 mvpcie_del_windows(po->po_win_iobase, po->po_win_iosize); 538 po->po_win_iosize = 0; 539 } 540 } 541 542 remap = po->po_bridge_iobaseupper << 16 | 543 (po->po_bridge_iobase & 0xf0) << 8; 544 base = mvmbus_pcie_io_aperture[0] + remap; 545 size = (po->po_bridge_iobaseupper << 16 | 546 (po->po_bridge_iobase & 0xf0) << 8 | 547 0xfff) - remap + 1; 548 549 if (po->po_win_iobase == base && po->po_win_iosize == size && 550 po->po_win_ioremap == remap) 551 return; 552 553 if (po->po_win_iosize) 554 mvpcie_del_windows(po->po_win_iobase, po->po_win_iosize); 555 556 if (size == 0) 557 return; 558 559 po->po_win_iobase = base; 560 po->po_win_iosize = size; 561 po->po_win_ioremap = remap; 562 563 mvpcie_add_windows(po->po_win_iobase, po->po_win_iosize, 564 po->po_win_ioremap, po->po_win_iotarget, po->po_win_ioattr); 565 } 566 567 void 568 mvpcie_mem_change(struct mvpcie_port *po) 569 { 570 paddr_t base; 571 size_t size; 572 573 /* If the limits are bogus or MEM is disabled ... */ 574 if ((po->po_bridge_memlimit < po->po_bridge_membase || 575 (po->po_bridge_command & PCI_COMMAND_MEM_ENABLE) == 0)) { 576 /* ... delete the window if enabled. */ 577 if (po->po_win_memsize) { 578 mvpcie_del_windows(po->po_win_membase, po->po_win_memsize); 579 po->po_win_memsize = 0; 580 } 581 } 582 583 base = (po->po_bridge_membase & 0xfff0) << 16; 584 size = (((po->po_bridge_memlimit & 0xfff0) << 16) | 585 0xfffff) - base + 1; 586 587 if (po->po_win_membase == base && po->po_win_memsize == size) 588 return; 589 590 if (po->po_win_memsize) 591 mvpcie_del_windows(po->po_win_membase, po->po_win_memsize); 592 593 if (size == 0) 594 return; 595 596 po->po_win_membase = base; 597 po->po_win_memsize = size; 598 599 mvpcie_add_windows(po->po_win_membase, po->po_win_memsize, 600 MVMBUS_NO_REMAP, po->po_win_memtarget, po->po_win_memattr); 601 } 602 603 int 604 mvpcie_link_up(struct mvpcie_port *po) 605 { 606 return !(HREAD4(po, PCIE_STAT) & PCIE_STAT_LINK_DOWN); 607 } 608 609 void 610 mvpcie_attach_hook(struct device *parent, struct device *self, 611 struct pcibus_attach_args *pba) 612 { 613 } 614 615 int 616 mvpcie_bus_maxdevs(void *v, int bus) 617 { 618 return 1; 619 } 620 621 pcitag_t 622 mvpcie_make_tag(void *v, int bus, int device, int function) 623 { 624 return ((bus << 24) | (device << 19) | (function << 16)); 625 } 626 627 void 628 mvpcie_decompose_tag(void *v, pcitag_t tag, int *bp, int *dp, int *fp) 629 { 630 if (bp != NULL) 631 *bp = (tag >> 24) & 0xff; 632 if (dp != NULL) 633 *dp = (tag >> 19) & 0x1f; 634 if (fp != NULL) 635 *fp = (tag >> 16) & 0x7; 636 } 637 638 int 639 mvpcie_conf_size(void *v, pcitag_t tag) 640 { 641 return PCIE_CONFIG_SPACE_SIZE; 642 } 643 644 pcireg_t 645 mvpcie_conf_read_bridge(struct mvpcie_port *po, int reg) 646 { 647 switch (reg) { 648 case PCI_ID_REG: 649 return PCI_VENDOR_MARVELL | 650 (HREAD4(po, PCIE_DEV_ID) & 0xffff0000); 651 case PCI_COMMAND_STATUS_REG: 652 return po->po_bridge_command; 653 case PCI_CLASS_REG: 654 return PCI_CLASS_BRIDGE << PCI_CLASS_SHIFT | 655 PCI_SUBCLASS_BRIDGE_PCI << PCI_SUBCLASS_SHIFT | 656 (HREAD4(po, PCIE_DEV_REV) & 0xff); 657 case PCI_BHLC_REG: 658 return 1 << PCI_HDRTYPE_SHIFT | 659 0x10 << PCI_CACHELINE_SHIFT; 660 case PPB_REG_BASE0: 661 return po->po_bridge_bar0; 662 case PPB_REG_BASE1: 663 return po->po_bridge_bar1; 664 case PPB_REG_BUSINFO: 665 return po->po_bridge_businfo; 666 case PPB_REG_IOSTATUS: 667 return po->po_bridge_iolimit << 8 | 668 po->po_bridge_iobase; 669 case PPB_REG_MEM: 670 return po->po_bridge_memlimit << 16 | 671 po->po_bridge_membase; 672 case PPB_REG_IO_HI: 673 return po->po_bridge_iolimitupper << 16 | 674 po->po_bridge_iobaseupper; 675 case PPB_REG_PREFMEM: 676 case PPB_REG_PREFBASE_HI32: 677 case PPB_REG_PREFLIM_HI32: 678 case PPB_REG_BRIDGECONTROL: 679 return 0; 680 default: 681 printf("%s: reg %x\n", __func__, reg); 682 break; 683 } 684 return 0; 685 } 686 687 void 688 mvpcie_conf_write_bridge(struct mvpcie_port *po, int reg, pcireg_t data) 689 { 690 switch (reg) { 691 case PCI_COMMAND_STATUS_REG: { 692 uint32_t old = po->po_bridge_command; 693 po->po_bridge_command = data & 0xffffff; 694 if ((old ^ po->po_bridge_command) & PCI_COMMAND_IO_ENABLE) 695 mvpcie_io_change(po); 696 if ((old ^ po->po_bridge_command) & PCI_COMMAND_MEM_ENABLE) 697 mvpcie_mem_change(po); 698 break; 699 } 700 case PPB_REG_BASE0: 701 po->po_bridge_bar0 = data; 702 break; 703 case PPB_REG_BASE1: 704 po->po_bridge_bar1 = data; 705 break; 706 case PPB_REG_BUSINFO: 707 po->po_bridge_businfo = data; 708 HWRITE4(po, PCIE_STAT, (HREAD4(po, PCIE_STAT) & 709 ~(PCIE_STAT_BUS_MASK << PCIE_STAT_BUS_SHIFT)) | 710 ((data >> 8) & 0xff) << PCIE_STAT_BUS_SHIFT); 711 break; 712 case PPB_REG_IOSTATUS: 713 po->po_bridge_iobase = (data & 0xff) | 1; 714 po->po_bridge_iolimit = ((data >> 8) & 0xff) | 1; 715 mvpcie_io_change(po); 716 break; 717 case PPB_REG_MEM: 718 po->po_bridge_membase = data & 0xffff; 719 po->po_bridge_memlimit = data >> 16; 720 mvpcie_mem_change(po); 721 break; 722 case PPB_REG_IO_HI: 723 po->po_bridge_iobaseupper = data & 0xffff; 724 po->po_bridge_iolimitupper = data >> 16; 725 mvpcie_io_change(po); 726 break; 727 case PPB_REG_PREFMEM: 728 case PPB_REG_PREFBASE_HI32: 729 case PPB_REG_PREFLIM_HI32: 730 break; 731 default: 732 printf("%s: reg %x data %x\n", __func__, reg, data); 733 break; 734 } 735 } 736 737 pcireg_t 738 mvpcie_conf_read(void *v, pcitag_t tag, int reg) 739 { 740 struct mvpcie_port *po = v; 741 int bus, dev, fn; 742 743 mvpcie_decompose_tag(NULL, tag, &bus, &dev, &fn); 744 if (bus == po->po_bus) { 745 KASSERT(dev == 0); 746 return mvpcie_conf_read_bridge(po, reg); 747 } 748 749 if (!mvpcie_link_up(po)) 750 return 0; 751 752 HWRITE4(po, PCIE_CONF_ADDR, PCIE_CONF_BUS(bus) | PCIE_CONF_DEV(dev) | 753 PCIE_CONF_FUNC(fn) | PCIE_CONF_REG(reg) | PCIE_CONF_ADDR_EN); 754 return HREAD4(po, PCIE_CONF_DATA); 755 } 756 757 void 758 mvpcie_conf_write(void *v, pcitag_t tag, int reg, pcireg_t data) 759 { 760 struct mvpcie_port *po = v; 761 int bus, dev, fn; 762 763 mvpcie_decompose_tag(NULL, tag, &bus, &dev, &fn); 764 if (bus == po->po_bus) { 765 KASSERT(dev == 0); 766 mvpcie_conf_write_bridge(po, reg, data); 767 return; 768 } 769 770 if (!mvpcie_link_up(po)) 771 return; 772 773 HWRITE4(po, PCIE_CONF_ADDR, PCIE_CONF_BUS(bus) | PCIE_CONF_DEV(dev) | 774 PCIE_CONF_FUNC(fn) | PCIE_CONF_REG(reg) | PCIE_CONF_ADDR_EN); 775 HWRITE4(po, PCIE_CONF_DATA, data); 776 } 777 778 struct mvpcie_intr_handle { 779 pci_chipset_tag_t ih_pc; 780 pcitag_t ih_tag; 781 int ih_intrpin; 782 }; 783 784 int 785 mvpcie_intr_map(struct pci_attach_args *pa, pci_intr_handle_t *ihp) 786 { 787 struct mvpcie_intr_handle *ih; 788 int pin = pa->pa_rawintrpin; 789 790 if (pin == 0 || pin > PCI_INTERRUPT_PIN_MAX) 791 return -1; 792 793 if (pa->pa_tag == 0) 794 return -1; 795 796 ih = malloc(sizeof(struct mvpcie_intr_handle), M_DEVBUF, M_WAITOK); 797 ih->ih_pc = pa->pa_pc; 798 ih->ih_tag = pa->pa_intrtag; 799 ih->ih_intrpin = pa->pa_intrpin; 800 *ihp = (pci_intr_handle_t)ih; 801 802 return 0; 803 } 804 805 int 806 mvpcie_intr_map_msi(struct pci_attach_args *pa, pci_intr_handle_t *ihp) 807 { 808 return -1; 809 } 810 811 int 812 mvpcie_intr_map_msix(struct pci_attach_args *pa, int vec, 813 pci_intr_handle_t *ihp) 814 { 815 return -1; 816 } 817 818 const char * 819 mvpcie_intr_string(void *v, pci_intr_handle_t ihp) 820 { 821 return "intx"; 822 } 823 824 void * 825 mvpcie_intr_establish(void *v, pci_intr_handle_t ihp, int level, 826 struct cpu_info *ci, int (*func)(void *), void *arg, char *name) 827 { 828 struct mvpcie_port *po = v; 829 struct mvpcie_intr_handle *ih = (struct mvpcie_intr_handle *)ihp; 830 int bus, dev, fn; 831 uint32_t reg[4]; 832 void *cookie; 833 834 mvpcie_decompose_tag(NULL, ih->ih_tag, &bus, &dev, &fn); 835 836 reg[0] = bus << 16 | dev << 11 | fn << 8; 837 reg[1] = reg[2] = 0; 838 reg[3] = ih->ih_intrpin; 839 840 cookie = arm_intr_establish_fdt_imap_cpu(po->po_node, reg, 841 sizeof(reg), level, ci, func, arg, name); 842 843 free(ih, M_DEVBUF, sizeof(struct mvpcie_intr_handle)); 844 return cookie; 845 } 846 847 void 848 mvpcie_intr_disestablish(void *v, void *cookie) 849 { 850 panic("%s", __func__); 851 } 852