1 /* $OpenBSD: mvpcie.c,v 1.6 2022/02/13 16:44:50 tobhe 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 40 /* Registers */ 41 #define PCIE_DEV_ID 0x0000 42 #define PCIE_CMD 0x0004 43 #define PCIE_DEV_REV 0x0008 44 #define PCIE_BAR_LO(n) (0x0010 + ((n) << 3)) 45 #define PCIE_BAR_HI(n) (0x0014 + ((n) << 3)) 46 #define PCIE_BAR_CTRL(n) (0x1804 + (((n) - 1) * 4)) 47 #define PCIE_WIN04_CTRL(n) (0x1820 + ((n) << 4)) 48 #define PCIE_WIN04_BASE(n) (0x1824 + ((n) << 4)) 49 #define PCIE_WIN04_REMAP(n) (0x182c + ((n) << 4)) 50 #define PCIE_WIN5_CTRL 0x1880 51 #define PCIE_WIN5_BASE 0x1884 52 #define PCIE_WIN5_REMAP 0x188c 53 #define PCIE_CONF_ADDR 0x18f8 54 #define PCIE_CONF_ADDR_EN 0x80000000 55 #define PCIE_CONF_REG(r) ((((r) & 0xf00) << 16) | ((r) & 0xfc)) 56 #define PCIE_CONF_BUS(b) (((b) & 0xff) << 16) 57 #define PCIE_CONF_DEV(d) (((d) & 0x1f) << 11) 58 #define PCIE_CONF_FUNC(f) (((f) & 0x7) << 8) 59 #define PCIE_CONF_DATA 0x18fc 60 #define PCIE_MASK 0x1910 61 #define PCIE_MASK_ENABLE_INTS (0xf << 24) 62 #define PCIE_STAT 0x1a04 63 #define PCIE_STAT_LINK_DOWN (1 << 0) 64 #define PCIE_STAT_BUS_SHIFT 8 65 #define PCIE_STAT_BUS_MASK 0xff 66 #define PCIE_STAT_DEV_SHIFT 16 67 #define PCIE_STAT_DEV_MASK 0x1f 68 69 #define PCIE_SWCAP 0x0040 70 71 #define PCIE_TARGET(target) (((target) & 0xf) << 4) 72 #define PCIE_ATTR(attr) (((attr) & 0xff) << 8) 73 #define PCIE_BASEADDR(base) ((base) & 0xffff0000) 74 #define PCIE_SIZE(size) (((size) - 1) & 0xffff0000) 75 #define PCIE_WINEN (1 << 0) 76 77 #define HREAD4(po, reg) \ 78 (bus_space_read_4((po)->po_iot, (po)->po_ioh, (reg))) 79 #define HWRITE4(po, reg, val) \ 80 bus_space_write_4((po)->po_iot, (po)->po_ioh, (reg), (val)) 81 #define HSET4(po, reg, bits) \ 82 HWRITE4((po), (reg), HREAD4((po), (reg)) | (bits)) 83 #define HCLR4(po, reg, bits) \ 84 HWRITE4((po), (reg), HREAD4((po), (reg)) & ~(bits)) 85 86 struct mvpcie_softc; 87 88 struct mvpcie_range { 89 uint32_t flags; 90 uint32_t slot; 91 uint32_t pci_base; 92 uint64_t phys_base; 93 uint64_t size; 94 }; 95 96 struct mvpcie_port { 97 struct mvpcie_softc *po_sc; 98 bus_space_tag_t po_iot; 99 bus_space_handle_t po_ioh; 100 bus_dma_tag_t po_dmat; 101 int po_node; 102 103 int po_port; 104 int po_lane; 105 int po_dev; 106 int po_fn; 107 108 uint32_t *po_gpio; 109 int po_gpiolen; 110 111 struct arm32_pci_chipset po_pc; 112 int po_bus; 113 114 uint32_t po_bridge_command; 115 uint32_t po_bridge_bar0; 116 uint32_t po_bridge_bar1; 117 uint32_t po_bridge_businfo; 118 uint32_t po_bridge_iobase; 119 uint32_t po_bridge_iobaseupper; 120 uint32_t po_bridge_iolimit; 121 uint32_t po_bridge_iolimitupper; 122 uint32_t po_bridge_membase; 123 uint32_t po_bridge_memlimit; 124 125 uint32_t po_win_iotarget; 126 uint32_t po_win_ioattr; 127 uint32_t po_win_memtarget; 128 uint32_t po_win_memattr; 129 130 uint32_t po_win_iobase; 131 uint32_t po_win_iosize; 132 uint32_t po_win_ioremap; 133 uint32_t po_win_membase; 134 uint32_t po_win_memsize; 135 }; 136 137 struct mvpcie_softc { 138 struct device sc_dev; 139 bus_space_tag_t sc_iot; 140 bus_dma_tag_t sc_dmat; 141 142 int sc_node; 143 int sc_acells; 144 int sc_scells; 145 int sc_pacells; 146 int sc_pscells; 147 struct mvpcie_range *sc_ranges; 148 int sc_rangeslen; 149 150 struct extent *sc_busex; 151 struct extent *sc_memex; 152 struct extent *sc_ioex; 153 char sc_busex_name[32]; 154 char sc_ioex_name[32]; 155 char sc_memex_name[32]; 156 157 int sc_nports; 158 struct mvpcie_port *sc_ports; 159 }; 160 161 int mvpcie_match(struct device *, void *, void *); 162 void mvpcie_attach(struct device *, struct device *, void *); 163 164 const struct cfattach mvpcie_ca = { 165 sizeof (struct mvpcie_softc), mvpcie_match, mvpcie_attach 166 }; 167 168 struct cfdriver mvpcie_cd = { 169 NULL, "mvpcie", DV_DULL 170 }; 171 172 int 173 mvpcie_match(struct device *parent, void *match, void *aux) 174 { 175 struct fdt_attach_args *faa = aux; 176 177 return OF_is_compatible(faa->fa_node, "marvell,armada-370-pcie"); 178 } 179 180 void mvpcie_port_attach(struct mvpcie_softc *, struct mvpcie_port *, int); 181 void mvpcie_wininit(struct mvpcie_port *); 182 void mvpcie_add_windows(paddr_t, size_t, paddr_t, uint8_t, uint8_t); 183 void mvpcie_del_windows(paddr_t, size_t); 184 void mvpcie_io_change(struct mvpcie_port *); 185 void mvpcie_mem_change(struct mvpcie_port *); 186 int mvpcie_link_up(struct mvpcie_port *); 187 188 void mvpcie_attach_hook(struct device *, struct device *, 189 struct pcibus_attach_args *); 190 int mvpcie_bus_maxdevs(void *, int); 191 pcitag_t mvpcie_make_tag(void *, int, int, int); 192 void mvpcie_decompose_tag(void *, pcitag_t, int *, int *, int *); 193 int mvpcie_conf_size(void *, pcitag_t); 194 pcireg_t mvpcie_conf_read(void *, pcitag_t, int); 195 void mvpcie_conf_write(void *, pcitag_t, int, pcireg_t); 196 int mvpcie_probe_device_hook(void *, struct pci_attach_args *); 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 > 0) { 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 po->po_pc.pc_probe_device_hook = mvpcie_probe_device_hook; 425 426 po->po_pc.pc_intr_v = po; 427 po->po_pc.pc_intr_map = mvpcie_intr_map; 428 po->po_pc.pc_intr_map_msi = mvpcie_intr_map_msi; 429 po->po_pc.pc_intr_map_msix = mvpcie_intr_map_msix; 430 po->po_pc.pc_intr_string = mvpcie_intr_string; 431 po->po_pc.pc_intr_establish = mvpcie_intr_establish; 432 po->po_pc.pc_intr_disestablish = mvpcie_intr_disestablish; 433 434 /* Skip address translation. */ 435 extern struct bus_space armv7_bs_tag; 436 memset(&pba, 0, sizeof(pba)); 437 pba.pba_busname = "pci"; 438 pba.pba_iot = &armv7_bs_tag; 439 pba.pba_memt = &armv7_bs_tag; 440 pba.pba_dmat = po->po_dmat; 441 pba.pba_pc = &po->po_pc; 442 pba.pba_busex = sc->sc_busex; 443 pba.pba_memex = sc->sc_memex; 444 pba.pba_ioex = sc->sc_ioex; 445 pba.pba_domain = pci_ndomains++; 446 pba.pba_bus = po->po_bus; 447 448 config_found(&sc->sc_dev, &pba, NULL); 449 } 450 451 void 452 mvpcie_wininit(struct mvpcie_port *po) 453 { 454 size_t size; 455 int i; 456 457 if (mvmbus_dram_info == NULL) 458 panic("%s: mbus dram information not set up", __func__); 459 460 for (i = 0; i < 3; i++) { 461 HWRITE4(po, PCIE_BAR_CTRL(i), 0); 462 HWRITE4(po, PCIE_BAR_LO(i), 0); 463 HWRITE4(po, PCIE_BAR_HI(i), 0); 464 } 465 466 for (i = 0; i < 5; i++) { 467 HWRITE4(po, PCIE_WIN04_CTRL(i), 0); 468 HWRITE4(po, PCIE_WIN04_BASE(i), 0); 469 HWRITE4(po, PCIE_WIN04_REMAP(i), 0); 470 } 471 472 HWRITE4(po, PCIE_WIN5_CTRL, 0); 473 HWRITE4(po, PCIE_WIN5_BASE, 0); 474 HWRITE4(po, PCIE_WIN5_REMAP, 0); 475 476 size = 0; 477 for (i = 0; i < mvmbus_dram_info->numcs; i++) { 478 struct mbus_dram_window *win = &mvmbus_dram_info->cs[i]; 479 480 HWRITE4(po, PCIE_WIN04_BASE(i), PCIE_BASEADDR(win->base)); 481 HWRITE4(po, PCIE_WIN04_REMAP(i), 0); 482 HWRITE4(po, PCIE_WIN04_CTRL(i), 483 PCIE_WINEN | 484 PCIE_TARGET(mvmbus_dram_info->targetid) | 485 PCIE_ATTR(win->attr) | 486 PCIE_SIZE(win->size)); 487 488 size += win->size; 489 } 490 491 if ((size & (size - 1)) != 0) 492 size = 1 << fls(size); 493 494 HWRITE4(po, PCIE_BAR_LO(1), mvmbus_dram_info->cs[0].base); 495 HWRITE4(po, PCIE_BAR_HI(1), 0); 496 HWRITE4(po, PCIE_BAR_CTRL(1), PCIE_WINEN | PCIE_SIZE(size)); 497 } 498 499 void 500 mvpcie_add_windows(paddr_t base, size_t size, paddr_t remap, 501 uint8_t target, uint8_t attr) 502 { 503 while (size) { 504 size_t sz = 1 << (fls(size) - 1); 505 506 mvmbus_add_window(base, size, remap, target, attr); 507 base += sz; 508 size -= sz; 509 if (remap != MVMBUS_NO_REMAP) 510 remap += sz; 511 } 512 } 513 514 void 515 mvpcie_del_windows(paddr_t base, size_t size) 516 { 517 while (size) { 518 size_t sz = 1 << (fls(size) - 1); 519 520 mvmbus_del_window(base, sz); 521 base += sz; 522 size -= sz; 523 } 524 } 525 526 void 527 mvpcie_io_change(struct mvpcie_port *po) 528 { 529 paddr_t base, remap; 530 size_t size; 531 532 /* If the limits are bogus or IO is disabled ... */ 533 if ((po->po_bridge_iolimit < po->po_bridge_iobase || 534 po->po_bridge_iolimitupper < po->po_bridge_iobaseupper || 535 (po->po_bridge_command & PCI_COMMAND_IO_ENABLE) == 0)) { 536 /* ... delete the window if enabled. */ 537 if (po->po_win_iosize) { 538 mvpcie_del_windows(po->po_win_iobase, po->po_win_iosize); 539 po->po_win_iosize = 0; 540 } 541 } 542 543 remap = po->po_bridge_iobaseupper << 16 | 544 (po->po_bridge_iobase & 0xf0) << 8; 545 base = mvmbus_pcie_io_aperture[0] + remap; 546 size = (po->po_bridge_iobaseupper << 16 | 547 (po->po_bridge_iobase & 0xf0) << 8 | 548 0xfff) - remap + 1; 549 550 if (po->po_win_iobase == base && po->po_win_iosize == size && 551 po->po_win_ioremap == remap) 552 return; 553 554 if (po->po_win_iosize) 555 mvpcie_del_windows(po->po_win_iobase, po->po_win_iosize); 556 557 if (size == 0) 558 return; 559 560 po->po_win_iobase = base; 561 po->po_win_iosize = size; 562 po->po_win_ioremap = remap; 563 564 mvpcie_add_windows(po->po_win_iobase, po->po_win_iosize, 565 po->po_win_ioremap, po->po_win_iotarget, po->po_win_ioattr); 566 } 567 568 void 569 mvpcie_mem_change(struct mvpcie_port *po) 570 { 571 paddr_t base; 572 size_t size; 573 574 /* If the limits are bogus or MEM is disabled ... */ 575 if ((po->po_bridge_memlimit < po->po_bridge_membase || 576 (po->po_bridge_command & PCI_COMMAND_MEM_ENABLE) == 0)) { 577 /* ... delete the window if enabled. */ 578 if (po->po_win_memsize) { 579 mvpcie_del_windows(po->po_win_membase, po->po_win_memsize); 580 po->po_win_memsize = 0; 581 } 582 } 583 584 base = (po->po_bridge_membase & 0xfff0) << 16; 585 size = (((po->po_bridge_memlimit & 0xfff0) << 16) | 586 0xfffff) - base + 1; 587 588 if (po->po_win_membase == base && po->po_win_memsize == size) 589 return; 590 591 if (po->po_win_memsize) 592 mvpcie_del_windows(po->po_win_membase, po->po_win_memsize); 593 594 if (size == 0) 595 return; 596 597 po->po_win_membase = base; 598 po->po_win_memsize = size; 599 600 mvpcie_add_windows(po->po_win_membase, po->po_win_memsize, 601 MVMBUS_NO_REMAP, po->po_win_memtarget, po->po_win_memattr); 602 } 603 604 int 605 mvpcie_link_up(struct mvpcie_port *po) 606 { 607 return !(HREAD4(po, PCIE_STAT) & PCIE_STAT_LINK_DOWN); 608 } 609 610 void 611 mvpcie_attach_hook(struct device *parent, struct device *self, 612 struct pcibus_attach_args *pba) 613 { 614 } 615 616 int 617 mvpcie_bus_maxdevs(void *v, int bus) 618 { 619 return 1; 620 } 621 622 pcitag_t 623 mvpcie_make_tag(void *v, int bus, int device, int function) 624 { 625 return ((bus << 24) | (device << 19) | (function << 16)); 626 } 627 628 void 629 mvpcie_decompose_tag(void *v, pcitag_t tag, int *bp, int *dp, int *fp) 630 { 631 if (bp != NULL) 632 *bp = (tag >> 24) & 0xff; 633 if (dp != NULL) 634 *dp = (tag >> 19) & 0x1f; 635 if (fp != NULL) 636 *fp = (tag >> 16) & 0x7; 637 } 638 639 int 640 mvpcie_conf_size(void *v, pcitag_t tag) 641 { 642 return PCIE_CONFIG_SPACE_SIZE; 643 } 644 645 pcireg_t 646 mvpcie_conf_read_bridge(struct mvpcie_port *po, int reg) 647 { 648 switch (reg) { 649 case PCI_ID_REG: 650 return PCI_VENDOR_MARVELL | 651 (HREAD4(po, PCIE_DEV_ID) & 0xffff0000); 652 case PCI_COMMAND_STATUS_REG: 653 return po->po_bridge_command; 654 case PCI_CLASS_REG: 655 return PCI_CLASS_BRIDGE << PCI_CLASS_SHIFT | 656 PCI_SUBCLASS_BRIDGE_PCI << PCI_SUBCLASS_SHIFT | 657 (HREAD4(po, PCIE_DEV_REV) & 0xff); 658 case PCI_BHLC_REG: 659 return 1 << PCI_HDRTYPE_SHIFT | 660 0x10 << PCI_CACHELINE_SHIFT; 661 case PPB_REG_BASE0: 662 return po->po_bridge_bar0; 663 case PPB_REG_BASE1: 664 return po->po_bridge_bar1; 665 case PPB_REG_BUSINFO: 666 return po->po_bridge_businfo; 667 case PPB_REG_IOSTATUS: 668 return po->po_bridge_iolimit << 8 | 669 po->po_bridge_iobase; 670 case PPB_REG_MEM: 671 return po->po_bridge_memlimit << 16 | 672 po->po_bridge_membase; 673 case PPB_REG_IO_HI: 674 return po->po_bridge_iolimitupper << 16 | 675 po->po_bridge_iobaseupper; 676 case PPB_REG_PREFMEM: 677 case PPB_REG_PREFBASE_HI32: 678 case PPB_REG_PREFLIM_HI32: 679 case PPB_REG_BRIDGECONTROL: 680 return 0; 681 default: 682 printf("%s: reg %x\n", __func__, reg); 683 break; 684 } 685 return 0; 686 } 687 688 void 689 mvpcie_conf_write_bridge(struct mvpcie_port *po, int reg, pcireg_t data) 690 { 691 switch (reg) { 692 case PCI_COMMAND_STATUS_REG: { 693 uint32_t old = po->po_bridge_command; 694 po->po_bridge_command = data & 0xffffff; 695 if ((old ^ po->po_bridge_command) & PCI_COMMAND_IO_ENABLE) 696 mvpcie_io_change(po); 697 if ((old ^ po->po_bridge_command) & PCI_COMMAND_MEM_ENABLE) 698 mvpcie_mem_change(po); 699 break; 700 } 701 case PPB_REG_BASE0: 702 po->po_bridge_bar0 = data; 703 break; 704 case PPB_REG_BASE1: 705 po->po_bridge_bar1 = data; 706 break; 707 case PPB_REG_BUSINFO: 708 po->po_bridge_businfo = data; 709 HWRITE4(po, PCIE_STAT, (HREAD4(po, PCIE_STAT) & 710 ~(PCIE_STAT_BUS_MASK << PCIE_STAT_BUS_SHIFT)) | 711 ((data >> 8) & 0xff) << PCIE_STAT_BUS_SHIFT); 712 break; 713 case PPB_REG_IOSTATUS: 714 po->po_bridge_iobase = (data & 0xff) | 1; 715 po->po_bridge_iolimit = ((data >> 8) & 0xff) | 1; 716 mvpcie_io_change(po); 717 break; 718 case PPB_REG_MEM: 719 po->po_bridge_membase = data & 0xffff; 720 po->po_bridge_memlimit = data >> 16; 721 mvpcie_mem_change(po); 722 break; 723 case PPB_REG_IO_HI: 724 po->po_bridge_iobaseupper = data & 0xffff; 725 po->po_bridge_iolimitupper = data >> 16; 726 mvpcie_io_change(po); 727 break; 728 case PPB_REG_PREFMEM: 729 case PPB_REG_PREFBASE_HI32: 730 case PPB_REG_PREFLIM_HI32: 731 break; 732 default: 733 printf("%s: reg %x data %x\n", __func__, reg, data); 734 break; 735 } 736 } 737 738 pcireg_t 739 mvpcie_conf_read(void *v, pcitag_t tag, int reg) 740 { 741 struct mvpcie_port *po = v; 742 int bus, dev, fn; 743 744 mvpcie_decompose_tag(NULL, tag, &bus, &dev, &fn); 745 if (bus == po->po_bus) { 746 KASSERT(dev == 0); 747 return mvpcie_conf_read_bridge(po, reg); 748 } 749 750 if (!mvpcie_link_up(po)) 751 return 0; 752 753 HWRITE4(po, PCIE_CONF_ADDR, PCIE_CONF_BUS(bus) | PCIE_CONF_DEV(dev) | 754 PCIE_CONF_FUNC(fn) | PCIE_CONF_REG(reg) | PCIE_CONF_ADDR_EN); 755 return HREAD4(po, PCIE_CONF_DATA); 756 } 757 758 void 759 mvpcie_conf_write(void *v, pcitag_t tag, int reg, pcireg_t data) 760 { 761 struct mvpcie_port *po = v; 762 int bus, dev, fn; 763 764 mvpcie_decompose_tag(NULL, tag, &bus, &dev, &fn); 765 if (bus == po->po_bus) { 766 KASSERT(dev == 0); 767 mvpcie_conf_write_bridge(po, reg, data); 768 return; 769 } 770 771 if (!mvpcie_link_up(po)) 772 return; 773 774 HWRITE4(po, PCIE_CONF_ADDR, PCIE_CONF_BUS(bus) | PCIE_CONF_DEV(dev) | 775 PCIE_CONF_FUNC(fn) | PCIE_CONF_REG(reg) | PCIE_CONF_ADDR_EN); 776 HWRITE4(po, PCIE_CONF_DATA, data); 777 } 778 779 int 780 mvpcie_probe_device_hook(void *v, struct pci_attach_args *pa) 781 { 782 return 0; 783 } 784 785 struct mvpcie_intr_handle { 786 pci_chipset_tag_t ih_pc; 787 pcitag_t ih_tag; 788 int ih_intrpin; 789 }; 790 791 int 792 mvpcie_intr_map(struct pci_attach_args *pa, pci_intr_handle_t *ihp) 793 { 794 struct mvpcie_intr_handle *ih; 795 int pin = pa->pa_rawintrpin; 796 797 if (pin == 0 || pin > PCI_INTERRUPT_PIN_MAX) 798 return -1; 799 800 if (pa->pa_tag == 0) 801 return -1; 802 803 ih = malloc(sizeof(struct mvpcie_intr_handle), M_DEVBUF, M_WAITOK); 804 ih->ih_pc = pa->pa_pc; 805 ih->ih_tag = pa->pa_intrtag; 806 ih->ih_intrpin = pa->pa_intrpin; 807 *ihp = (pci_intr_handle_t)ih; 808 809 return 0; 810 } 811 812 int 813 mvpcie_intr_map_msi(struct pci_attach_args *pa, pci_intr_handle_t *ihp) 814 { 815 return -1; 816 } 817 818 int 819 mvpcie_intr_map_msix(struct pci_attach_args *pa, int vec, 820 pci_intr_handle_t *ihp) 821 { 822 return -1; 823 } 824 825 const char * 826 mvpcie_intr_string(void *v, pci_intr_handle_t ihp) 827 { 828 return "intx"; 829 } 830 831 void * 832 mvpcie_intr_establish(void *v, pci_intr_handle_t ihp, int level, 833 struct cpu_info *ci, int (*func)(void *), void *arg, char *name) 834 { 835 struct mvpcie_port *po = v; 836 struct mvpcie_intr_handle *ih = (struct mvpcie_intr_handle *)ihp; 837 int bus, dev, fn; 838 uint32_t reg[4]; 839 void *cookie; 840 841 mvpcie_decompose_tag(NULL, ih->ih_tag, &bus, &dev, &fn); 842 843 reg[0] = bus << 16 | dev << 11 | fn << 8; 844 reg[1] = reg[2] = 0; 845 reg[3] = ih->ih_intrpin; 846 847 cookie = arm_intr_establish_fdt_imap_cpu(po->po_node, reg, 848 sizeof(reg), level, ci, func, arg, name); 849 850 free(ih, M_DEVBUF, sizeof(struct mvpcie_intr_handle)); 851 return cookie; 852 } 853 854 void 855 mvpcie_intr_disestablish(void *v, void *cookie) 856 { 857 panic("%s", __func__); 858 } 859