1 /* $OpenBSD: dwpcie.c,v 1.11 2018/08/22 21:15:53 kettenis Exp $ */ 2 /* 3 * Copyright (c) 2018 Mark Kettenis <kettenis@openbsd.org> 4 * 5 * Permission to use, copy, modify, and distribute this software for any 6 * purpose with or without fee is hereby granted, provided that the above 7 * copyright notice and this permission notice appear in all copies. 8 * 9 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 10 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 11 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 12 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 13 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 14 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 15 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 16 */ 17 18 #include <sys/param.h> 19 #include <sys/systm.h> 20 #include <sys/device.h> 21 #include <sys/extent.h> 22 #include <sys/malloc.h> 23 24 #include <machine/intr.h> 25 #include <machine/bus.h> 26 #include <machine/fdt.h> 27 28 #include <dev/pci/pcidevs.h> 29 #include <dev/pci/pcireg.h> 30 #include <dev/pci/pcivar.h> 31 #include <dev/pci/ppbreg.h> 32 33 #include <dev/ofw/openfirm.h> 34 #include <dev/ofw/ofw_clock.h> 35 #include <dev/ofw/ofw_pinctrl.h> 36 #include <dev/ofw/fdt.h> 37 38 /* Registers */ 39 #define MISC_CONTROL_1 0x8bc 40 #define MISC_CONTROL_1_DBI_RO_WR_EN (1 << 0) 41 #define IATU_VIEWPORT 0x900 42 #define IATU_REGION_CTRL_1 0x904 43 #define IATU_REGION_CTRL_1_TYPE_IO 2 44 #define IATU_REGION_CTRL_1_TYPE_CFG0 4 45 #define IATU_REGION_CTRL_1_TYPE_CFG1 5 46 #define IATU_REGION_CTRL_2 0x908 47 #define IATU_REGION_CTRL_2_REGION_EN (1U << 31) 48 #define IATU_LWR_BASE_ADDR 0x90c 49 #define IATU_UPPER_BASE_ADDR 0x910 50 #define IATU_LIMIT_ADDR 0x914 51 #define IATU_LWR_TARGET_ADDR 0x918 52 #define IATU_UPPER_TARGET_ADDR 0x91c 53 54 #define PCIE_GLOBAL_CTRL 0x8000 55 #define PCIE_GLOBAL_CTRL_APP_LTSSM_EN (1 << 2) 56 #define PCIE_GLOBAL_CTRL_DEVICE_TYPE_MASK (0xf << 4) 57 #define PCIE_GLOBAL_CTRL_DEVICE_TYPE_RC (0x4 << 4) 58 #define PCIE_GLOBAL_STATUS 0x8008 59 #define PCIE_GLOBAL_STATUS_RDLH_LINK_UP (1 << 1) 60 #define PCIE_GLOBAL_STATUS_PHY_LINK_UP (1 << 9) 61 #define PCIE_PM_STATUS 0x8014 62 #define PCIE_GLOBAL_INT_CAUSE 0x801c 63 #define PCIE_GLOBAL_INT_MASK 0x8020 64 #define PCIE_GLOBAL_INT_MASK_INT_A (1 << 9) 65 #define PCIE_GLOBAL_INT_MASK_INT_B (1 << 10) 66 #define PCIE_GLOBAL_INT_MASK_INT_C (1 << 11) 67 #define PCIE_GLOBAL_INT_MASK_INT_D (1 << 12) 68 #define PCIE_ARCACHE_TRC 0x8050 69 #define PCIE_ARCACHE_TRC_DEFAULT 0x3511 70 #define PCIE_AWCACHE_TRC 0x8054 71 #define PCIE_AWCACHE_TRC_DEFAULT 0x5311 72 #define PCIE_ARUSER 0x805c 73 #define PCIE_AWUSER 0x8060 74 #define PCIE_AXUSER_DOMAIN_MASK (0x3 << 4) 75 #define PCIE_AXUSER_DOMAIN_INNER_SHARABLE (0x1 << 4) 76 #define PCIE_AXUSER_DOMAIN_OUTER_SHARABLE (0x2 << 4) 77 78 #define HREAD4(sc, reg) \ 79 (bus_space_read_4((sc)->sc_iot, (sc)->sc_ioh, (reg))) 80 #define HWRITE4(sc, reg, val) \ 81 bus_space_write_4((sc)->sc_iot, (sc)->sc_ioh, (reg), (val)) 82 #define HSET4(sc, reg, bits) \ 83 HWRITE4((sc), (reg), HREAD4((sc), (reg)) | (bits)) 84 #define HCLR4(sc, reg, bits) \ 85 HWRITE4((sc), (reg), HREAD4((sc), (reg)) & ~(bits)) 86 87 struct dwpcie_range { 88 uint32_t flags; 89 uint64_t pci_base; 90 uint64_t phys_base; 91 uint64_t size; 92 }; 93 94 struct dwpcie_softc { 95 struct device sc_dev; 96 bus_space_tag_t sc_iot; 97 bus_space_handle_t sc_ioh; 98 bus_space_handle_t sc_cfg_ioh; 99 bus_addr_t sc_cfg_addr; 100 bus_size_t sc_cfg_size; 101 102 int sc_node; 103 int sc_acells; 104 int sc_scells; 105 int sc_pacells; 106 int sc_pscells; 107 struct dwpcie_range *sc_ranges; 108 int sc_nranges; 109 110 struct bus_space sc_bus_iot; 111 struct bus_space sc_bus_memt; 112 113 struct arm64_pci_chipset sc_pc; 114 int sc_bus; 115 116 void *sc_ih; 117 }; 118 119 int dwpcie_match(struct device *, void *, void *); 120 void dwpcie_attach(struct device *, struct device *, void *); 121 122 struct cfattach dwpcie_ca = { 123 sizeof (struct dwpcie_softc), dwpcie_match, dwpcie_attach 124 }; 125 126 struct cfdriver dwpcie_cd = { 127 NULL, "dwpcie", DV_DULL 128 }; 129 130 int 131 dwpcie_match(struct device *parent, void *match, void *aux) 132 { 133 struct fdt_attach_args *faa = aux; 134 135 return OF_is_compatible(faa->fa_node, "marvell,armada8k-pcie"); 136 } 137 138 void dwpcie_armada8k_init(struct dwpcie_softc *); 139 int dwpcie_armada8k_link_up(struct dwpcie_softc *); 140 int dwpcie_armada8k_intr(void *); 141 142 void dwpcie_attach_hook(struct device *, struct device *, 143 struct pcibus_attach_args *); 144 int dwpcie_bus_maxdevs(void *, int); 145 pcitag_t dwpcie_make_tag(void *, int, int, int); 146 void dwpcie_decompose_tag(void *, pcitag_t, int *, int *, int *); 147 int dwpcie_conf_size(void *, pcitag_t); 148 pcireg_t dwpcie_conf_read(void *, pcitag_t, int); 149 void dwpcie_conf_write(void *, pcitag_t, int, pcireg_t); 150 151 int dwpcie_intr_map(struct pci_attach_args *, pci_intr_handle_t *); 152 int dwpcie_intr_map_msi(struct pci_attach_args *, pci_intr_handle_t *); 153 int dwpcie_intr_map_msix(struct pci_attach_args *, int, 154 pci_intr_handle_t *); 155 const char *dwpcie_intr_string(void *, pci_intr_handle_t); 156 void *dwpcie_intr_establish(void *, pci_intr_handle_t, int, 157 int (*)(void *), void *, char *); 158 void dwpcie_intr_disestablish(void *, void *); 159 160 void *dwpcie_armada8k_intr_establish(void *, pci_intr_handle_t, int, 161 int (*)(void *), void *, char *); 162 163 int dwpcie_bs_iomap(bus_space_tag_t, bus_addr_t, bus_size_t, int, 164 bus_space_handle_t *); 165 int dwpcie_bs_memmap(bus_space_tag_t, bus_addr_t, bus_size_t, int, 166 bus_space_handle_t *); 167 168 void 169 dwpcie_attach(struct device *parent, struct device *self, void *aux) 170 { 171 struct dwpcie_softc *sc = (struct dwpcie_softc *)self; 172 struct fdt_attach_args *faa = aux; 173 struct pcibus_attach_args pba; 174 bus_addr_t iobase, iolimit; 175 bus_addr_t membase, memlimit; 176 uint32_t bus_range[2]; 177 uint32_t *ranges; 178 int i, j, nranges, rangeslen; 179 pcireg_t bir, blr, csr; 180 181 if (faa->fa_nreg < 2) { 182 printf(": no registers\n"); 183 return; 184 } 185 186 sc->sc_iot = faa->fa_iot; 187 sc->sc_node = faa->fa_node; 188 189 sc->sc_acells = OF_getpropint(sc->sc_node, "#address-cells", 190 faa->fa_acells); 191 sc->sc_scells = OF_getpropint(sc->sc_node, "#size-cells", 192 faa->fa_scells); 193 sc->sc_pacells = faa->fa_acells; 194 sc->sc_pscells = faa->fa_scells; 195 196 rangeslen = OF_getproplen(sc->sc_node, "ranges"); 197 if (rangeslen <= 0 || (rangeslen % sizeof(uint32_t)) || 198 (rangeslen / sizeof(uint32_t)) % (sc->sc_acells + 199 sc->sc_pacells + sc->sc_scells)) { 200 printf(": invalid ranges property\n"); 201 return; 202 } 203 204 ranges = malloc(rangeslen, M_TEMP, M_WAITOK); 205 OF_getpropintarray(sc->sc_node, "ranges", ranges, 206 rangeslen); 207 208 nranges = (rangeslen / sizeof(uint32_t)) / 209 (sc->sc_acells + sc->sc_pacells + sc->sc_scells); 210 sc->sc_ranges = mallocarray(nranges, 211 sizeof(struct dwpcie_range), M_TEMP, M_WAITOK); 212 sc->sc_nranges = nranges; 213 214 for (i = 0, j = 0; i < sc->sc_nranges; i++) { 215 sc->sc_ranges[i].flags = ranges[j++]; 216 sc->sc_ranges[i].pci_base = ranges[j++]; 217 if (sc->sc_acells - 1 == 2) { 218 sc->sc_ranges[i].pci_base <<= 32; 219 sc->sc_ranges[i].pci_base |= ranges[j++]; 220 } 221 sc->sc_ranges[i].phys_base = ranges[j++]; 222 if (sc->sc_pacells == 2) { 223 sc->sc_ranges[i].phys_base <<= 32; 224 sc->sc_ranges[i].phys_base |= ranges[j++]; 225 } 226 sc->sc_ranges[i].size = ranges[j++]; 227 if (sc->sc_scells == 2) { 228 sc->sc_ranges[i].size <<= 32; 229 sc->sc_ranges[i].size |= ranges[j++]; 230 } 231 } 232 233 free(ranges, M_TEMP, rangeslen); 234 235 if (bus_space_map(sc->sc_iot, faa->fa_reg[0].addr, 236 faa->fa_reg[0].size, 0, &sc->sc_ioh)) { 237 printf(": can't map ctrl registers\n"); 238 return; 239 } 240 241 if (bus_space_map(sc->sc_iot, faa->fa_reg[1].addr, 242 faa->fa_reg[1].size, 0, &sc->sc_cfg_ioh)) { 243 bus_space_unmap(sc->sc_iot, sc->sc_ioh, faa->fa_reg[0].size); 244 printf(": can't map config registers\n"); 245 return; 246 } 247 sc->sc_cfg_addr = faa->fa_reg[1].addr; 248 sc->sc_cfg_size = faa->fa_reg[1].size; 249 250 printf("\n"); 251 252 pinctrl_byname(sc->sc_node, "default"); 253 254 clock_enable_all(sc->sc_node); 255 256 if (OF_is_compatible(sc->sc_node, "marvell,armada8k-pcie")) 257 dwpcie_armada8k_init(sc); 258 259 /* Enable modification of read-only bits. */ 260 HSET4(sc, MISC_CONTROL_1, MISC_CONTROL_1_DBI_RO_WR_EN); 261 262 /* A Root Port is a PCI-PCI Bridge. */ 263 HWRITE4(sc, PCI_CLASS_REG, 264 PCI_CLASS_BRIDGE << PCI_CLASS_SHIFT | 265 PCI_SUBCLASS_BRIDGE_PCI << PCI_SUBCLASS_SHIFT); 266 267 /* Clear BAR as U-Boot seems to leave garbage in it. */ 268 HWRITE4(sc, PCI_MAPREG_START, PCI_MAPREG_MEM_TYPE_64BIT); 269 HWRITE4(sc, PCI_MAPREG_START + 4, 0); 270 271 /* Make sure read-only bits are write-protected. */ 272 HCLR4(sc, MISC_CONTROL_1, MISC_CONTROL_1_DBI_RO_WR_EN); 273 274 /* Set up bus range. */ 275 if (OF_getpropintarray(sc->sc_node, "bus-range", bus_range, 276 sizeof(bus_range)) != sizeof(bus_range) || 277 bus_range[0] >= 32 || bus_range[1] >= 32) { 278 bus_range[0] = 0; 279 bus_range[1] = 31; 280 } 281 sc->sc_bus = bus_range[0]; 282 283 /* Initialize bus range. */ 284 bir = bus_range[0]; 285 bir |= ((bus_range[0] + 1) << 8); 286 bir |= (bus_range[1] << 16); 287 HWRITE4(sc, PPB_REG_BUSINFO, bir); 288 289 /* Set up I/O and memory mapped I/O ranges. */ 290 iobase = 0xffff; iolimit = 0; 291 membase = 0xffffffff; memlimit = 0; 292 for (i = 0; i < sc->sc_nranges; i++) { 293 if ((sc->sc_ranges[i].flags & 0x03000000) == 0x01000000 && 294 sc->sc_ranges[i].size > 0) { 295 iobase = sc->sc_ranges[i].pci_base; 296 iolimit = iobase + sc->sc_ranges[i].size - 1; 297 } 298 if ((sc->sc_ranges[i].flags & 0x03000000) == 0x02000000 && 299 sc->sc_ranges[i].size > 0) { 300 membase = sc->sc_ranges[i].pci_base; 301 memlimit = membase + sc->sc_ranges[i].size - 1; 302 } 303 } 304 305 /* Initialize I/O window. */ 306 blr = iolimit & PPB_IO_MASK; 307 blr |= (iobase >> PPB_IO_SHIFT); 308 HWRITE4(sc, PPB_REG_IOSTATUS, blr); 309 blr = (iobase & 0xffff0000) >> 16; 310 blr |= iolimit & 0xffff0000; 311 HWRITE4(sc, PPB_REG_IO_HI, blr); 312 313 /* Initialize memory mapped I/O window. */ 314 blr = memlimit & PPB_MEM_MASK; 315 blr |= (membase >> PPB_MEM_SHIFT); 316 HWRITE4(sc, PPB_REG_MEM, blr); 317 318 /* Reset prefetchable memory mapped I/O window. */ 319 HWRITE4(sc, PPB_REG_PREFMEM, 0x0000ffff); 320 HWRITE4(sc, PPB_REG_PREFBASE_HI32, 0); 321 HWRITE4(sc, PPB_REG_PREFLIM_HI32, 0); 322 323 csr = PCI_COMMAND_MASTER_ENABLE; 324 if (iolimit > iobase) 325 csr |= PCI_COMMAND_IO_ENABLE; 326 if (memlimit > membase) 327 csr |= PCI_COMMAND_MEM_ENABLE; 328 HWRITE4(sc, PCI_COMMAND_STATUS_REG, csr); 329 330 memcpy(&sc->sc_bus_iot, sc->sc_iot, sizeof(sc->sc_bus_iot)); 331 sc->sc_bus_iot.bus_private = sc; 332 sc->sc_bus_iot._space_map = dwpcie_bs_iomap; 333 memcpy(&sc->sc_bus_memt, sc->sc_iot, sizeof(sc->sc_bus_memt)); 334 sc->sc_bus_memt.bus_private = sc; 335 sc->sc_bus_memt._space_map = dwpcie_bs_memmap; 336 337 sc->sc_pc.pc_conf_v = sc; 338 sc->sc_pc.pc_attach_hook = dwpcie_attach_hook; 339 sc->sc_pc.pc_bus_maxdevs = dwpcie_bus_maxdevs; 340 sc->sc_pc.pc_make_tag = dwpcie_make_tag; 341 sc->sc_pc.pc_decompose_tag = dwpcie_decompose_tag; 342 sc->sc_pc.pc_conf_size = dwpcie_conf_size; 343 sc->sc_pc.pc_conf_read = dwpcie_conf_read; 344 sc->sc_pc.pc_conf_write = dwpcie_conf_write; 345 346 sc->sc_pc.pc_intr_v = sc; 347 sc->sc_pc.pc_intr_map = dwpcie_intr_map; 348 sc->sc_pc.pc_intr_map_msi = dwpcie_intr_map_msi; 349 sc->sc_pc.pc_intr_map_msix = dwpcie_intr_map_msix; 350 sc->sc_pc.pc_intr_string = dwpcie_intr_string; 351 sc->sc_pc.pc_intr_establish = dwpcie_intr_establish; 352 sc->sc_pc.pc_intr_disestablish = dwpcie_intr_disestablish; 353 354 memset(&pba, 0, sizeof(pba)); 355 pba.pba_busname = "pci"; 356 pba.pba_iot = &sc->sc_bus_iot; 357 pba.pba_memt = &sc->sc_bus_memt; 358 pba.pba_dmat = faa->fa_dmat; 359 pba.pba_pc = &sc->sc_pc; 360 pba.pba_domain = pci_ndomains++; 361 pba.pba_bus = sc->sc_bus; 362 pba.pba_flags |= PCI_FLAGS_MSI_ENABLED; 363 364 config_found(self, &pba, NULL); 365 } 366 367 void 368 dwpcie_armada8k_init(struct dwpcie_softc *sc) 369 { 370 int i, timo, viewport = 0; 371 uint32_t reg; 372 373 if (!dwpcie_armada8k_link_up(sc)) { 374 reg = HREAD4(sc, PCIE_GLOBAL_CTRL); 375 reg &= ~PCIE_GLOBAL_CTRL_APP_LTSSM_EN; 376 HWRITE4(sc, PCIE_GLOBAL_CTRL, reg); 377 } 378 379 /* Enable Root Complex mode. */ 380 reg = HREAD4(sc, PCIE_GLOBAL_CTRL); 381 reg &= ~PCIE_GLOBAL_CTRL_DEVICE_TYPE_MASK; 382 reg |= PCIE_GLOBAL_CTRL_DEVICE_TYPE_RC; 383 HWRITE4(sc, PCIE_GLOBAL_CTRL, reg); 384 385 HWRITE4(sc, PCIE_ARCACHE_TRC, PCIE_ARCACHE_TRC_DEFAULT); 386 HWRITE4(sc, PCIE_AWCACHE_TRC, PCIE_AWCACHE_TRC_DEFAULT); 387 reg = HREAD4(sc, PCIE_ARUSER); 388 reg &= ~PCIE_AXUSER_DOMAIN_MASK; 389 reg |= PCIE_AXUSER_DOMAIN_OUTER_SHARABLE; 390 HWRITE4(sc, PCIE_ARUSER, reg); 391 reg = HREAD4(sc, PCIE_AWUSER); 392 reg &= ~PCIE_AXUSER_DOMAIN_MASK; 393 reg |= PCIE_AXUSER_DOMAIN_OUTER_SHARABLE; 394 HWRITE4(sc, PCIE_AWUSER, reg); 395 396 /* Set up addres translation for PCI confg space. */ 397 HWRITE4(sc, IATU_VIEWPORT, viewport++); 398 HWRITE4(sc, IATU_LWR_BASE_ADDR, sc->sc_cfg_addr); 399 HWRITE4(sc, IATU_UPPER_BASE_ADDR, sc->sc_cfg_addr >> 32); 400 HWRITE4(sc, IATU_LIMIT_ADDR, sc->sc_cfg_addr + sc->sc_cfg_size - 1); 401 HWRITE4(sc, IATU_LWR_TARGET_ADDR, 0); 402 HWRITE4(sc, IATU_UPPER_TARGET_ADDR, 0); 403 HWRITE4(sc, IATU_REGION_CTRL_2, IATU_REGION_CTRL_2_REGION_EN); 404 405 /* Set up address translation for I/O space. */ 406 for (i = 0; i < sc->sc_nranges; i++) { 407 if ((sc->sc_ranges[i].flags & 0x03000000) != 0x01000000) 408 continue; 409 HWRITE4(sc, IATU_VIEWPORT, viewport++); 410 HWRITE4(sc, IATU_LWR_BASE_ADDR, 411 sc->sc_ranges[i].phys_base); 412 HWRITE4(sc, IATU_UPPER_BASE_ADDR, 413 sc->sc_ranges[i].phys_base >> 32); 414 HWRITE4(sc, IATU_LIMIT_ADDR, 415 sc->sc_ranges[i].phys_base + sc->sc_ranges[i].size - 1); 416 HWRITE4(sc, IATU_LWR_TARGET_ADDR, 417 sc->sc_ranges[i].pci_base); 418 HWRITE4(sc, IATU_UPPER_TARGET_ADDR, 419 sc->sc_ranges[i].pci_base >> 32); 420 HWRITE4(sc, IATU_REGION_CTRL_1, IATU_REGION_CTRL_1_TYPE_IO); 421 HWRITE4(sc, IATU_REGION_CTRL_2, IATU_REGION_CTRL_2_REGION_EN); 422 } 423 424 if (!dwpcie_armada8k_link_up(sc)) { 425 reg = HREAD4(sc, PCIE_GLOBAL_CTRL); 426 reg |= PCIE_GLOBAL_CTRL_APP_LTSSM_EN; 427 HWRITE4(sc, PCIE_GLOBAL_CTRL, reg); 428 } 429 430 for (timo = 40; timo > 0; timo--) { 431 if (dwpcie_armada8k_link_up(sc)) 432 break; 433 delay(1000); 434 } 435 436 sc->sc_ih = fdt_intr_establish(sc->sc_node, IPL_AUDIO | IPL_MPSAFE, 437 dwpcie_armada8k_intr, sc, sc->sc_dev.dv_xname); 438 439 /* Unmask INTx interrupts. */ 440 HWRITE4(sc, PCIE_GLOBAL_INT_MASK, 441 PCIE_GLOBAL_INT_MASK_INT_A | PCIE_GLOBAL_INT_MASK_INT_B | 442 PCIE_GLOBAL_INT_MASK_INT_C | PCIE_GLOBAL_INT_MASK_INT_D); 443 } 444 445 int 446 dwpcie_armada8k_link_up(struct dwpcie_softc *sc) 447 { 448 uint32_t reg, mask; 449 450 mask = PCIE_GLOBAL_STATUS_RDLH_LINK_UP; 451 mask |= PCIE_GLOBAL_STATUS_PHY_LINK_UP; 452 reg = HREAD4(sc, PCIE_GLOBAL_STATUS); 453 return ((reg & mask) == mask); 454 } 455 456 int 457 dwpcie_armada8k_intr(void *arg) 458 { 459 struct dwpcie_softc *sc = arg; 460 uint32_t cause; 461 462 /* Acknowledge interrupts. */ 463 cause = HREAD4(sc, PCIE_GLOBAL_INT_CAUSE); 464 HWRITE4(sc, PCIE_GLOBAL_INT_CAUSE, cause); 465 466 /* INTx interrupt, so not really ours. */ 467 return 0; 468 } 469 470 void 471 dwpcie_atu_config(struct dwpcie_softc *sc, pcitag_t tag, int type) 472 { 473 HWRITE4(sc, IATU_VIEWPORT, 0); 474 HWRITE4(sc, IATU_REGION_CTRL_1, type); 475 HWRITE4(sc, IATU_LWR_TARGET_ADDR, tag); 476 } 477 478 void 479 dwpcie_attach_hook(struct device *parent, struct device *self, 480 struct pcibus_attach_args *pba) 481 { 482 } 483 484 int 485 dwpcie_bus_maxdevs(void *v, int bus) 486 { 487 struct dwpcie_softc *sc = v; 488 489 if (bus == sc->sc_bus || bus == sc->sc_bus + 1) 490 return 1; 491 return 32; 492 } 493 494 pcitag_t 495 dwpcie_make_tag(void *v, int bus, int device, int function) 496 { 497 return ((bus << 24) | (device << 19) | (function << 16)); 498 } 499 500 void 501 dwpcie_decompose_tag(void *v, pcitag_t tag, int *bp, int *dp, int *fp) 502 { 503 if (bp != NULL) 504 *bp = (tag >> 24) & 0xff; 505 if (dp != NULL) 506 *dp = (tag >> 19) & 0x1f; 507 if (fp != NULL) 508 *fp = (tag >> 16) & 0x7; 509 } 510 511 int 512 dwpcie_conf_size(void *v, pcitag_t tag) 513 { 514 return PCIE_CONFIG_SPACE_SIZE; 515 } 516 517 pcireg_t 518 dwpcie_conf_read(void *v, pcitag_t tag, int reg) 519 { 520 struct dwpcie_softc *sc = v; 521 int bus, dev, fn; 522 523 dwpcie_decompose_tag(sc, tag, &bus, &dev, &fn); 524 if (bus == sc->sc_bus) { 525 KASSERT(dev == 0); 526 return HREAD4(sc, tag | reg); 527 } 528 529 if (bus == sc->sc_bus + 1) 530 dwpcie_atu_config(sc, tag, IATU_REGION_CTRL_1_TYPE_CFG0); 531 else 532 dwpcie_atu_config(sc, tag, IATU_REGION_CTRL_1_TYPE_CFG1); 533 return bus_space_read_4(sc->sc_iot, sc->sc_cfg_ioh, reg); 534 } 535 536 void 537 dwpcie_conf_write(void *v, pcitag_t tag, int reg, pcireg_t data) 538 { 539 struct dwpcie_softc *sc = v; 540 int bus, dev, fn; 541 542 dwpcie_decompose_tag(sc, tag, &bus, &dev, &fn); 543 if (bus == sc->sc_bus) { 544 KASSERT(dev == 0); 545 HWRITE4(sc, tag | reg, data); 546 return; 547 } 548 549 if (bus == sc->sc_bus + 1) 550 dwpcie_atu_config(sc, tag, IATU_REGION_CTRL_1_TYPE_CFG0); 551 else 552 dwpcie_atu_config(sc, tag, IATU_REGION_CTRL_1_TYPE_CFG1); 553 bus_space_write_4(sc->sc_iot, sc->sc_cfg_ioh, reg, data); 554 } 555 556 struct dwpcie_intr_handle { 557 pci_chipset_tag_t ih_pc; 558 pcitag_t ih_tag; 559 int ih_intrpin; 560 int ih_msi; 561 }; 562 563 int 564 dwpcie_intr_map(struct pci_attach_args *pa, pci_intr_handle_t *ihp) 565 { 566 struct dwpcie_intr_handle *ih; 567 int pin = pa->pa_rawintrpin; 568 569 if (pin == 0 || pin > PCI_INTERRUPT_PIN_MAX) 570 return -1; 571 572 if (pa->pa_tag == 0) 573 return -1; 574 575 ih = malloc(sizeof(struct dwpcie_intr_handle), M_DEVBUF, M_WAITOK); 576 ih->ih_pc = pa->pa_pc; 577 ih->ih_tag = pa->pa_intrtag; 578 ih->ih_intrpin = pa->pa_intrpin; 579 ih->ih_msi = 0; 580 *ihp = (pci_intr_handle_t)ih; 581 582 return 0; 583 } 584 585 int 586 dwpcie_intr_map_msi(struct pci_attach_args *pa, pci_intr_handle_t *ihp) 587 { 588 pci_chipset_tag_t pc = pa->pa_pc; 589 pcitag_t tag = pa->pa_tag; 590 struct dwpcie_intr_handle *ih; 591 592 if ((pa->pa_flags & PCI_FLAGS_MSI_ENABLED) == 0 || 593 pci_get_capability(pc, tag, PCI_CAP_MSI, NULL, NULL) == 0) 594 return -1; 595 596 ih = malloc(sizeof(struct dwpcie_intr_handle), M_DEVBUF, M_WAITOK); 597 ih->ih_pc = pa->pa_pc; 598 ih->ih_tag = pa->pa_tag; 599 ih->ih_intrpin = pa->pa_intrpin; 600 ih->ih_msi = 1; 601 *ihp = (pci_intr_handle_t)ih; 602 603 return 0; 604 } 605 606 int 607 dwpcie_intr_map_msix(struct pci_attach_args *pa, int vec, 608 pci_intr_handle_t *ihp) 609 { 610 return -1; 611 } 612 613 const char * 614 dwpcie_intr_string(void *v, pci_intr_handle_t ihp) 615 { 616 struct dwpcie_intr_handle *ih = (struct dwpcie_intr_handle *)ihp; 617 618 if (ih->ih_msi) 619 return "msi"; 620 621 return "intx"; 622 } 623 624 void * 625 dwpcie_intr_establish(void *v, pci_intr_handle_t ihp, int level, 626 int (*func)(void *), void *arg, char *name) 627 { 628 struct dwpcie_softc *sc = v; 629 struct dwpcie_intr_handle *ih = (struct dwpcie_intr_handle *)ihp; 630 void *cookie; 631 632 if (ih->ih_msi) { 633 uint64_t addr, data; 634 pcireg_t reg; 635 int off; 636 637 /* Assume hardware passes Requester ID as sideband data. */ 638 data = pci_requester_id(ih->ih_pc, ih->ih_tag); 639 cookie = fdt_intr_establish_msi(sc->sc_node, &addr, 640 &data, level, func, arg, (void *)name); 641 if (cookie == NULL) 642 return NULL; 643 644 /* TODO: translate address to the PCI device's view */ 645 646 if (pci_get_capability(ih->ih_pc, ih->ih_tag, PCI_CAP_MSI, 647 &off, ®) == 0) 648 panic("%s: no msi capability", __func__); 649 650 if (reg & PCI_MSI_MC_C64) { 651 pci_conf_write(ih->ih_pc, ih->ih_tag, 652 off + PCI_MSI_MA, addr); 653 pci_conf_write(ih->ih_pc, ih->ih_tag, 654 off + PCI_MSI_MAU32, addr >> 32); 655 pci_conf_write(ih->ih_pc, ih->ih_tag, 656 off + PCI_MSI_MD64, data); 657 } else { 658 pci_conf_write(ih->ih_pc, ih->ih_tag, 659 off + PCI_MSI_MA, addr); 660 pci_conf_write(ih->ih_pc, ih->ih_tag, 661 off + PCI_MSI_MD32, data); 662 } 663 pci_conf_write(ih->ih_pc, ih->ih_tag, 664 off, reg | PCI_MSI_MC_MSIE); 665 } else { 666 int bus, dev, fn; 667 uint32_t reg[4]; 668 669 dwpcie_decompose_tag(sc, ih->ih_tag, &bus, &dev, &fn); 670 671 reg[0] = bus << 16 | dev << 11 | fn << 8; 672 reg[1] = reg[2] = 0; 673 reg[3] = ih->ih_intrpin; 674 675 cookie = fdt_intr_establish_imap(sc->sc_node, reg, 676 sizeof(reg), level, func, arg, name); 677 } 678 679 free(ih, M_DEVBUF, sizeof(struct dwpcie_intr_handle)); 680 return cookie; 681 } 682 683 void 684 dwpcie_intr_disestablish(void *v, void *cookie) 685 { 686 panic("%s", __func__); 687 } 688 689 int 690 dwpcie_bs_iomap(bus_space_tag_t t, bus_addr_t addr, bus_size_t size, 691 int flags, bus_space_handle_t *bshp) 692 { 693 struct dwpcie_softc *sc = t->bus_private; 694 int i; 695 696 for (i = 0; i < sc->sc_nranges; i++) { 697 uint64_t pci_start = sc->sc_ranges[i].pci_base; 698 uint64_t pci_end = pci_start + sc->sc_ranges[i].size; 699 uint64_t phys_start = sc->sc_ranges[i].phys_base; 700 701 if ((sc->sc_ranges[i].flags & 0x03000000) == 0x01000000 && 702 addr >= pci_start && addr + size <= pci_end) { 703 return bus_space_map(sc->sc_iot, 704 addr - pci_start + phys_start, size, flags, bshp); 705 } 706 } 707 708 return ENXIO; 709 } 710 711 int 712 dwpcie_bs_memmap(bus_space_tag_t t, bus_addr_t addr, bus_size_t size, 713 int flags, bus_space_handle_t *bshp) 714 { 715 struct dwpcie_softc *sc = t->bus_private; 716 int i; 717 718 for (i = 0; i < sc->sc_nranges; i++) { 719 uint64_t pci_start = sc->sc_ranges[i].pci_base; 720 uint64_t pci_end = pci_start + sc->sc_ranges[i].size; 721 uint64_t phys_start = sc->sc_ranges[i].phys_base; 722 723 if ((sc->sc_ranges[i].flags & 0x03000000) == 0x02000000 && 724 addr >= pci_start && addr + size <= pci_end) { 725 return bus_space_map(sc->sc_iot, 726 addr - pci_start + phys_start, size, flags, bshp); 727 } 728 } 729 730 return ENXIO; 731 } 732