1 /* $OpenBSD: aplpcie.c,v 1.19 2024/02/03 10:37:25 kettenis Exp $ */ 2 /* 3 * Copyright (c) 2021 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 32 #include <dev/ofw/openfirm.h> 33 #include <dev/ofw/ofw_gpio.h> 34 #include <dev/ofw/ofw_misc.h> 35 #include <dev/ofw/ofw_pinctrl.h> 36 #include <dev/ofw/ofw_power.h> 37 #include <dev/ofw/fdt.h> 38 39 #define PCIE_RC_PHY_BASE(port) (0x84000 + (port) * 0x4000) 40 #define PCIE_RC_PHY_SIZE 0x4000 41 42 #define PCIE_PHY_LANE_CONF 0x0000 43 #define PCIE_PHY_LANE_CONF_REFCLK0REQ (1 << 0) 44 #define PCIE_PHY_LANE_CONF_REFCLK1REQ (1 << 1) 45 #define PCIE_PHY_LANE_CONF_REFCLK0ACK (1 << 2) 46 #define PCIE_PHY_LANE_CONF_REFCLK1ACK (1 << 3) 47 #define PCIE_PHY_LANE_CONF_REFCLK0EN (1 << 9) 48 #define PCIE_PHY_LANE_CONF_REFCLK1EN (1 << 10) 49 #define PCIE_PHY_LANE_CONF_REFCLK0CGEN (1 << 30) 50 #define PCIE_PHY_LANE_CONF_REFCLK1CGEN (1U << 31) 51 #define PCIE_PHY_LANE_CTRL 0x0004 52 #define PCIE_PHY_LANE_CTRL_CFGACC (1 << 15) 53 54 #define PCIE_PORT_LTSSM_CTRL 0x0080 55 #define PCIE_PORT_LTSSM_CTRL_START (1 << 0) 56 #define PCIE_PORT_MSI_CTRL 0x0124 57 #define PCIE_PORT_MSI_CTRL_ENABLE (1 << 0) 58 #define PCIE_PORT_MSI_CTRL_32 (5 << 4) 59 #define PCIE_PORT_MSI_REMAP 0x0128 60 #define PCIE_PORT_MSI_DOORBELL 0x0168 61 #define PCIE_PORT_LINK_STAT 0x0208 62 #define PCIE_PORT_LINK_STAT_UP (1 << 0) 63 #define PCIE_PORT_APPCLK 0x0800 64 #define PCIE_PORT_APPCLK_EN (1 << 0) 65 #define PCIE_PORT_APPCLK_CGDIS (1 << 8) 66 #define PCIE_PORT_STAT 0x0804 67 #define PCIE_PORT_STAT_READY (1 << 0) 68 #define PCIE_PORT_REFCLK 0x0810 69 #define PCIE_PORT_REFCLK_EN (1 << 0) 70 #define PCIE_PORT_REFCLK_CGDIS (1 << 8) 71 #define PCIE_PORT_PERST 0x0814 72 #define PCIE_PORT_PERST_DIS (1 << 0) 73 #define PCIE_PORT_RID2SID(idx) (0x0828 + (idx) * 4) 74 #define PCIE_PORT_RID2SID_VALID (1U << 31) 75 #define PCIE_PORT_RID2SID_SID_SHIFT 16 76 #define PCIE_PORT_RID2SID_RID_MASK 0x0000ffff 77 #define PCIE_PORT_MAX_RID2SID 64 78 79 #define PCIE_T6020_PORT_MSI_DOORBELL_LO 0x016c 80 #define PCIE_T6020_PORT_MSI_DOORBELL_HI 0x0170 81 #define PCIE_T6020_PORT_PERST 0x082c 82 #define PCIE_T6020_PORT_RID2SID(idx) (0x3000 + (idx) * 4) 83 #define PCIE_T6020_PORT_MAX_RID2SID 512 84 #define PCIE_T6020_PORT_MSI_MAP(idx) (0x3800 + (idx) * 4) 85 #define PCIE_T6020_PORT_MSI_MAP_ENABLE (1U << 31) 86 87 #define HREAD4(sc, reg) \ 88 (bus_space_read_4((sc)->sc_iot, (sc)->sc_ioh, (reg))) 89 #define HWRITE4(sc, reg, val) \ 90 bus_space_write_4((sc)->sc_iot, (sc)->sc_ioh, (reg), (val)) 91 92 #define RREAD4(sc, reg) \ 93 (bus_space_read_4((sc)->sc_iot, (sc)->sc_rc_ioh, (reg))) 94 #define RWRITE4(sc, reg, val) \ 95 bus_space_write_4((sc)->sc_iot, (sc)->sc_rc_ioh, (reg), (val)) 96 #define RSET4(sc, reg, bits) \ 97 RWRITE4((sc), (reg), RREAD4((sc), (reg)) | (bits)) 98 #define RCLR4(sc, reg, bits) \ 99 RWRITE4((sc), (reg), RREAD4((sc), (reg)) & ~(bits)) 100 101 #define LREAD4(sc, port, reg) \ 102 (bus_space_read_4((sc)->sc_iot, (sc)->sc_phy_ioh[port], (reg))) 103 #define LWRITE4(sc, port, reg, val) \ 104 bus_space_write_4((sc)->sc_iot, (sc)->sc_phy_ioh[port], (reg), (val)) 105 #define LSET4(sc, port, reg, bits) \ 106 LWRITE4((sc), (port), (reg), LREAD4((sc), (port), (reg)) | (bits)) 107 #define LCLR4(sc, port, reg, bits) \ 108 LWRITE4((sc), (port), (reg), LREAD4((sc), (port), (reg)) & ~(bits)) 109 110 #define PREAD4(sc, port, reg) \ 111 (bus_space_read_4((sc)->sc_iot, (sc)->sc_port_ioh[(port)], (reg))) 112 #define PWRITE4(sc, port, reg, val) \ 113 bus_space_write_4((sc)->sc_iot, (sc)->sc_port_ioh[(port)], (reg), (val)) 114 #define PSET4(sc, port, reg, bits) \ 115 PWRITE4((sc), (port), (reg), PREAD4((sc), (port), (reg)) | (bits)) 116 #define PCLR4(sc, port, reg, bits) \ 117 PWRITE4((sc), (port), (reg), PREAD4((sc), (port), (reg)) & ~(bits)) 118 119 struct aplpcie_range { 120 uint32_t flags; 121 uint64_t pci_base; 122 uint64_t phys_base; 123 uint64_t size; 124 }; 125 126 #define APLPCIE_MAX_PORTS 4 127 128 struct aplpcie_softc { 129 struct device sc_dev; 130 bus_space_tag_t sc_iot; 131 bus_space_handle_t sc_ioh; 132 bus_space_handle_t sc_rc_ioh; 133 bus_space_handle_t sc_phy_ioh[APLPCIE_MAX_PORTS]; 134 bus_size_t sc_phy_ios[APLPCIE_MAX_PORTS]; 135 bus_space_handle_t sc_port_ioh[APLPCIE_MAX_PORTS]; 136 bus_size_t sc_port_ios[APLPCIE_MAX_PORTS]; 137 bus_dma_tag_t sc_dmat; 138 139 int sc_node; 140 int sc_acells; 141 int sc_scells; 142 int sc_pacells; 143 int sc_pscells; 144 struct aplpcie_range *sc_ranges; 145 int sc_nranges; 146 147 struct bus_space sc_bus_iot; 148 struct bus_space sc_bus_memt; 149 150 struct machine_pci_chipset sc_pc; 151 struct extent *sc_busex; 152 struct extent *sc_memex; 153 struct extent *sc_pmemex; 154 struct extent *sc_ioex; 155 int sc_bus; 156 157 int sc_msi; 158 bus_addr_t sc_msi_doorbell; 159 uint32_t sc_msi_range[6]; 160 int sc_msi_rangelen; 161 struct interrupt_controller sc_msi_ic; 162 }; 163 164 int aplpcie_match(struct device *, void *, void *); 165 void aplpcie_attach(struct device *, struct device *, void *); 166 167 const struct cfattach aplpcie_ca = { 168 sizeof (struct aplpcie_softc), aplpcie_match, aplpcie_attach 169 }; 170 171 struct cfdriver aplpcie_cd = { 172 NULL, "aplpcie", DV_DULL 173 }; 174 175 int 176 aplpcie_match(struct device *parent, void *match, void *aux) 177 { 178 struct fdt_attach_args *faa = aux; 179 180 return OF_is_compatible(faa->fa_node, "apple,pcie") || 181 OF_is_compatible(faa->fa_node, "apple,t6020-pcie"); 182 } 183 184 void aplpcie_init_port(struct aplpcie_softc *, int); 185 void aplpcie_t6020_init_port(struct aplpcie_softc *, int); 186 187 void aplpcie_attach_hook(struct device *, struct device *, 188 struct pcibus_attach_args *); 189 int aplpcie_bus_maxdevs(void *, int); 190 pcitag_t aplpcie_make_tag(void *, int, int, int); 191 void aplpcie_decompose_tag(void *, pcitag_t, int *, int *, int *); 192 int aplpcie_conf_size(void *, pcitag_t); 193 pcireg_t aplpcie_conf_read(void *, pcitag_t, int); 194 void aplpcie_conf_write(void *, pcitag_t, int, pcireg_t); 195 int aplpcie_probe_device_hook(void *, struct pci_attach_args *); 196 197 int aplpcie_intr_map(struct pci_attach_args *, pci_intr_handle_t *); 198 const char *aplpcie_intr_string(void *, pci_intr_handle_t); 199 void *aplpcie_intr_establish(void *, pci_intr_handle_t, int, 200 struct cpu_info *, int (*)(void *), void *, char *); 201 void aplpcie_intr_disestablish(void *, void *); 202 203 int aplpcie_bs_iomap(bus_space_tag_t, bus_addr_t, bus_size_t, int, 204 bus_space_handle_t *); 205 int aplpcie_bs_memmap(bus_space_tag_t, bus_addr_t, bus_size_t, int, 206 bus_space_handle_t *); 207 208 void *aplpcie_intr_establish_msi(void *, uint64_t *, uint64_t *, 209 int, struct cpu_info *, int (*)(void *), void *, char *); 210 void aplpcie_intr_disestablish_msi(void *); 211 212 void 213 aplpcie_attach(struct device *parent, struct device *self, void *aux) 214 { 215 struct aplpcie_softc *sc = (struct aplpcie_softc *)self; 216 struct fdt_attach_args *faa = aux; 217 struct pcibus_attach_args pba; 218 uint32_t *ranges; 219 int i, j, nranges, rangeslen; 220 uint32_t bus_range[2]; 221 char name[32]; 222 int idx, node, port; 223 224 sc->sc_iot = faa->fa_iot; 225 226 idx = OF_getindex(faa->fa_node, "config", "reg-names"); 227 if (idx < 0 || idx >= faa->fa_nreg || 228 bus_space_map(sc->sc_iot, faa->fa_reg[idx].addr, 229 faa->fa_reg[idx].size, 0, &sc->sc_ioh)) { 230 printf(": can't map registers\n"); 231 return; 232 } 233 234 idx = OF_getindex(faa->fa_node, "rc", "reg-names"); 235 if (idx < 0 || idx >= faa->fa_nreg || 236 bus_space_map(sc->sc_iot, faa->fa_reg[idx].addr, 237 faa->fa_reg[idx].size, 0, &sc->sc_rc_ioh)) { 238 printf(": can't map registers\n"); 239 return; 240 } 241 242 for (port = 0; port < APLPCIE_MAX_PORTS; port++) { 243 snprintf(name, sizeof(name), "port%d", port); 244 idx = OF_getindex(faa->fa_node, name, "reg-names"); 245 if (idx < 0) 246 continue; 247 if (idx > faa->fa_nreg || 248 bus_space_map(sc->sc_iot, faa->fa_reg[idx].addr, 249 faa->fa_reg[idx].size, 0, &sc->sc_port_ioh[port])) { 250 printf(": can't map registers\n"); 251 return; 252 } 253 sc->sc_port_ios[port] = faa->fa_reg[idx].size; 254 255 snprintf(name, sizeof(name), "phy%d", port); 256 idx = OF_getindex(faa->fa_node, name, "reg-names"); 257 if (idx < 0) { 258 bus_space_subregion(sc->sc_iot, sc->sc_rc_ioh, 259 PCIE_RC_PHY_BASE(port), PCIE_RC_PHY_SIZE, 260 &sc->sc_phy_ioh[port]); 261 continue; 262 } 263 if (idx > faa->fa_nreg || 264 bus_space_map(sc->sc_iot, faa->fa_reg[idx].addr, 265 faa->fa_reg[idx].size, 0, &sc->sc_phy_ioh[port])) { 266 printf(": can't map registers\n"); 267 return; 268 } 269 sc->sc_phy_ios[port] = faa->fa_reg[idx].size; 270 } 271 272 sc->sc_dmat = faa->fa_dmat; 273 sc->sc_node = faa->fa_node; 274 275 power_domain_enable(sc->sc_node); 276 pinctrl_byname(sc->sc_node, "default"); 277 278 sc->sc_msi_doorbell = 279 OF_getpropint64(sc->sc_node, "msi-doorbell", 0xffff000ULL); 280 sc->sc_msi_rangelen = OF_getpropintarray(sc->sc_node, "msi-ranges", 281 sc->sc_msi_range, sizeof(sc->sc_msi_range)); 282 if (sc->sc_msi_rangelen <= 0 || 283 (sc->sc_msi_rangelen % sizeof(uint32_t)) || 284 (sc->sc_msi_rangelen / sizeof(uint32_t)) < 5 || 285 (sc->sc_msi_rangelen / sizeof(uint32_t) > 6)) { 286 printf(": invalid msi-ranges property\n"); 287 return; 288 } 289 290 if (OF_is_compatible(sc->sc_node, "apple,t6020-pcie")) { 291 for (node = OF_child(sc->sc_node); node; node = OF_peer(node)) 292 aplpcie_t6020_init_port(sc, node); 293 } else { 294 for (node = OF_child(sc->sc_node); node; node = OF_peer(node)) 295 aplpcie_init_port(sc, node); 296 } 297 298 /* 299 * Must wait at least 100ms after link training completes 300 * before sending a configuration request to a device 301 * immediately below a port. 302 */ 303 delay(100000); 304 305 sc->sc_acells = OF_getpropint(sc->sc_node, "#address-cells", 306 faa->fa_acells); 307 sc->sc_scells = OF_getpropint(sc->sc_node, "#size-cells", 308 faa->fa_scells); 309 sc->sc_pacells = faa->fa_acells; 310 sc->sc_pscells = faa->fa_scells; 311 312 rangeslen = OF_getproplen(sc->sc_node, "ranges"); 313 if (rangeslen <= 0 || (rangeslen % sizeof(uint32_t)) || 314 (rangeslen / sizeof(uint32_t)) % (sc->sc_acells + 315 sc->sc_pacells + sc->sc_scells)) { 316 printf(": invalid ranges property\n"); 317 return; 318 } 319 320 ranges = malloc(rangeslen, M_TEMP, M_WAITOK); 321 OF_getpropintarray(sc->sc_node, "ranges", ranges, 322 rangeslen); 323 324 nranges = (rangeslen / sizeof(uint32_t)) / 325 (sc->sc_acells + sc->sc_pacells + sc->sc_scells); 326 sc->sc_ranges = mallocarray(nranges, 327 sizeof(struct aplpcie_range), M_TEMP, M_WAITOK); 328 sc->sc_nranges = nranges; 329 330 for (i = 0, j = 0; i < sc->sc_nranges; i++) { 331 sc->sc_ranges[i].flags = ranges[j++]; 332 sc->sc_ranges[i].pci_base = ranges[j++]; 333 if (sc->sc_acells - 1 == 2) { 334 sc->sc_ranges[i].pci_base <<= 32; 335 sc->sc_ranges[i].pci_base |= ranges[j++]; 336 } 337 sc->sc_ranges[i].phys_base = ranges[j++]; 338 if (sc->sc_pacells == 2) { 339 sc->sc_ranges[i].phys_base <<= 32; 340 sc->sc_ranges[i].phys_base |= ranges[j++]; 341 } 342 sc->sc_ranges[i].size = ranges[j++]; 343 if (sc->sc_scells == 2) { 344 sc->sc_ranges[i].size <<= 32; 345 sc->sc_ranges[i].size |= ranges[j++]; 346 } 347 } 348 349 free(ranges, M_TEMP, rangeslen); 350 351 printf("\n"); 352 353 /* Create extents for our address spaces. */ 354 sc->sc_busex = extent_create("pcibus", 0, 255, 355 M_DEVBUF, NULL, 0, EX_WAITOK | EX_FILLED); 356 sc->sc_memex = extent_create("pcimem", 0, (u_long)-1, 357 M_DEVBUF, NULL, 0, EX_WAITOK | EX_FILLED); 358 sc->sc_pmemex = extent_create("pcipmem", 0, (u_long)-1, 359 M_DEVBUF, NULL, 0, EX_WAITOK | EX_FILLED); 360 sc->sc_ioex = extent_create("pciio", 0, 0xffffffff, 361 M_DEVBUF, NULL, 0, EX_WAITOK | EX_FILLED); 362 for (i = 0; i < sc->sc_nranges; i++) { 363 if ((sc->sc_ranges[i].flags & 0x03000000) == 0x01000000) { 364 extent_free(sc->sc_ioex, sc->sc_ranges[i].pci_base, 365 sc->sc_ranges[i].size, EX_WAITOK); 366 } 367 if ((sc->sc_ranges[i].flags & 0x03000000) == 0x02000000) { 368 extent_free(sc->sc_memex, sc->sc_ranges[i].pci_base, 369 sc->sc_ranges[i].size, EX_WAITOK); 370 } 371 if ((sc->sc_ranges[i].flags & 0x03000000) == 0x03000000) { 372 extent_free(sc->sc_pmemex, sc->sc_ranges[i].pci_base, 373 sc->sc_ranges[i].size, EX_WAITOK); 374 } 375 } 376 377 /* Set up bus range. */ 378 if (OF_getpropintarray(sc->sc_node, "bus-range", bus_range, 379 sizeof(bus_range)) != sizeof(bus_range) || 380 bus_range[0] >= 32 || bus_range[1] >= 32) { 381 bus_range[0] = 0; 382 bus_range[1] = 31; 383 } 384 sc->sc_bus = bus_range[0]; 385 extent_free(sc->sc_busex, bus_range[0], 386 bus_range[1] - bus_range[0] + 1, EX_WAITOK); 387 388 memcpy(&sc->sc_bus_iot, sc->sc_iot, sizeof(sc->sc_bus_iot)); 389 sc->sc_bus_iot.bus_private = sc; 390 sc->sc_bus_iot._space_map = aplpcie_bs_iomap; 391 memcpy(&sc->sc_bus_memt, sc->sc_iot, sizeof(sc->sc_bus_memt)); 392 sc->sc_bus_memt.bus_private = sc; 393 sc->sc_bus_memt._space_map = aplpcie_bs_memmap; 394 395 sc->sc_pc.pc_conf_v = sc; 396 sc->sc_pc.pc_attach_hook = aplpcie_attach_hook; 397 sc->sc_pc.pc_bus_maxdevs = aplpcie_bus_maxdevs; 398 sc->sc_pc.pc_make_tag = aplpcie_make_tag; 399 sc->sc_pc.pc_decompose_tag = aplpcie_decompose_tag; 400 sc->sc_pc.pc_conf_size = aplpcie_conf_size; 401 sc->sc_pc.pc_conf_read = aplpcie_conf_read; 402 sc->sc_pc.pc_conf_write = aplpcie_conf_write; 403 sc->sc_pc.pc_probe_device_hook = aplpcie_probe_device_hook; 404 405 sc->sc_pc.pc_intr_v = sc; 406 sc->sc_pc.pc_intr_map = aplpcie_intr_map; 407 sc->sc_pc.pc_intr_map_msi = _pci_intr_map_msi; 408 sc->sc_pc.pc_intr_map_msivec = _pci_intr_map_msivec; 409 sc->sc_pc.pc_intr_map_msix = _pci_intr_map_msix; 410 sc->sc_pc.pc_intr_string = aplpcie_intr_string; 411 sc->sc_pc.pc_intr_establish = aplpcie_intr_establish; 412 sc->sc_pc.pc_intr_disestablish = aplpcie_intr_disestablish; 413 414 memset(&pba, 0, sizeof(pba)); 415 pba.pba_busname = "pci"; 416 pba.pba_iot = &sc->sc_bus_iot; 417 pba.pba_memt = &sc->sc_bus_memt; 418 pba.pba_dmat = sc->sc_dmat; 419 pba.pba_pc = &sc->sc_pc; 420 pba.pba_busex = sc->sc_busex; 421 pba.pba_memex = sc->sc_memex; 422 pba.pba_pmemex = sc->sc_pmemex; 423 pba.pba_ioex = sc->sc_ioex; 424 pba.pba_domain = pci_ndomains++; 425 pba.pba_bus = sc->sc_bus; 426 pba.pba_flags |= PCI_FLAGS_MSI_ENABLED; 427 428 sc->sc_msi_ic.ic_node = sc->sc_node; 429 sc->sc_msi_ic.ic_cookie = sc; 430 sc->sc_msi_ic.ic_establish_msi = aplpcie_intr_establish_msi; 431 sc->sc_msi_ic.ic_disestablish = aplpcie_intr_disestablish_msi; 432 sc->sc_msi_ic.ic_barrier = intr_barrier; 433 fdt_intr_register(&sc->sc_msi_ic); 434 435 pci_dopm = 1; 436 437 config_found(self, &pba, NULL); 438 } 439 440 void 441 aplpcie_init_port(struct aplpcie_softc *sc, int node) 442 { 443 char status[32]; 444 uint32_t reg[5]; 445 uint32_t *pwren_gpio; 446 uint32_t *reset_gpio; 447 int pwren_gpiolen, reset_gpiolen; 448 uint32_t stat; 449 int idx, port, timo; 450 451 if (OF_getprop(node, "status", status, sizeof(status)) > 0 && 452 strcmp(status, "disabled") == 0) 453 return; 454 455 if (OF_getpropintarray(node, "reg", reg, sizeof(reg)) != sizeof(reg)) 456 return; 457 458 port = reg[0] >> 11; 459 if (port >= APLPCIE_MAX_PORTS || sc->sc_port_ios[port] == 0) 460 return; 461 462 pwren_gpiolen = OF_getproplen(node, "pwren-gpios"); 463 reset_gpiolen = OF_getproplen(node, "reset-gpios"); 464 if (reset_gpiolen <= 0) 465 return; 466 467 /* 468 * Set things up such that we can share the 32 available MSIs 469 * across all ports. 470 */ 471 PWRITE4(sc, port, PCIE_PORT_MSI_CTRL, 472 PCIE_PORT_MSI_CTRL_32 | PCIE_PORT_MSI_CTRL_ENABLE); 473 PWRITE4(sc, port, PCIE_PORT_MSI_REMAP, 0); 474 PWRITE4(sc, port, PCIE_PORT_MSI_DOORBELL, sc->sc_msi_doorbell); 475 476 /* 477 * Clear stream ID mappings. 478 */ 479 for (idx = 0; idx < PCIE_PORT_MAX_RID2SID; idx++) 480 PWRITE4(sc, port, PCIE_PORT_RID2SID(idx), 0); 481 482 /* Check if the link is already up. */ 483 stat = PREAD4(sc, port, PCIE_PORT_LINK_STAT); 484 if (stat & PCIE_PORT_LINK_STAT_UP) 485 return; 486 487 PSET4(sc, port, PCIE_PORT_APPCLK, PCIE_PORT_APPCLK_EN); 488 489 /* Assert PERST#. */ 490 reset_gpio = malloc(reset_gpiolen, M_TEMP, M_WAITOK); 491 OF_getpropintarray(node, "reset-gpios", reset_gpio, reset_gpiolen); 492 gpio_controller_config_pin(reset_gpio, GPIO_CONFIG_OUTPUT); 493 gpio_controller_set_pin(reset_gpio, 1); 494 495 /* Power up the device if necessary. */ 496 if (pwren_gpiolen > 0) { 497 pwren_gpio = malloc(pwren_gpiolen, M_TEMP, M_WAITOK); 498 OF_getpropintarray(node, "pwren-gpios", 499 pwren_gpio, pwren_gpiolen); 500 gpio_controller_config_pin(pwren_gpio, GPIO_CONFIG_OUTPUT); 501 gpio_controller_set_pin(pwren_gpio, 1); 502 free(pwren_gpio, M_TEMP, pwren_gpiolen); 503 } 504 505 /* Setup Refclk. */ 506 LSET4(sc, port, PCIE_PHY_LANE_CTRL, PCIE_PHY_LANE_CTRL_CFGACC); 507 LSET4(sc, port, PCIE_PHY_LANE_CONF, PCIE_PHY_LANE_CONF_REFCLK0REQ); 508 for (timo = 500; timo > 0; timo--) { 509 stat = LREAD4(sc, port, PCIE_PHY_LANE_CONF); 510 if (stat & PCIE_PHY_LANE_CONF_REFCLK0ACK) 511 break; 512 delay(100); 513 } 514 LSET4(sc, port, PCIE_PHY_LANE_CONF, PCIE_PHY_LANE_CONF_REFCLK1REQ); 515 for (timo = 500; timo > 0; timo--) { 516 stat = LREAD4(sc, port, PCIE_PHY_LANE_CONF); 517 if (stat & PCIE_PHY_LANE_CONF_REFCLK1ACK) 518 break; 519 delay(100); 520 } 521 LCLR4(sc, port, PCIE_PHY_LANE_CTRL, PCIE_PHY_LANE_CTRL_CFGACC); 522 LSET4(sc, port, PCIE_PHY_LANE_CONF, 523 PCIE_PHY_LANE_CONF_REFCLK0EN | PCIE_PHY_LANE_CONF_REFCLK1EN); 524 PSET4(sc, port, PCIE_PORT_REFCLK, PCIE_PORT_REFCLK_EN); 525 526 /* 527 * PERST# must remain asserted for at least 100us after the 528 * reference clock becomes stable. But also has to remain 529 * active at least 100ms after power up. 530 */ 531 if (pwren_gpiolen > 0) 532 delay(100000); 533 else 534 delay(100); 535 536 /* Deassert PERST#. */ 537 PSET4(sc, port, PCIE_PORT_PERST, PCIE_PORT_PERST_DIS); 538 gpio_controller_set_pin(reset_gpio, 0); 539 free(reset_gpio, M_TEMP, reset_gpiolen); 540 541 for (timo = 2500; timo > 0; timo--) { 542 stat = PREAD4(sc, port, PCIE_PORT_STAT); 543 if (stat & PCIE_PORT_STAT_READY) 544 break; 545 delay(100); 546 } 547 if ((stat & PCIE_PORT_STAT_READY) == 0) 548 return; 549 550 PCLR4(sc, port, PCIE_PORT_REFCLK, PCIE_PORT_REFCLK_CGDIS); 551 PCLR4(sc, port, PCIE_PORT_APPCLK, PCIE_PORT_APPCLK_CGDIS); 552 553 /* Bring up the link. */ 554 PWRITE4(sc, port, PCIE_PORT_LTSSM_CTRL, PCIE_PORT_LTSSM_CTRL_START); 555 for (timo = 1000; timo > 0; timo--) { 556 stat = PREAD4(sc, port, PCIE_PORT_LINK_STAT); 557 if (stat & PCIE_PORT_LINK_STAT_UP) 558 break; 559 delay(100); 560 } 561 } 562 563 void 564 aplpcie_t6020_init_port(struct aplpcie_softc *sc, int node) 565 { 566 char status[32]; 567 uint32_t reg[5]; 568 uint32_t *pwren_gpio; 569 uint32_t *reset_gpio; 570 int pwren_gpiolen, reset_gpiolen; 571 uint32_t stat; 572 int idx, msi, port, timo; 573 574 if (OF_getprop(node, "status", status, sizeof(status)) > 0 && 575 strcmp(status, "disabled") == 0) 576 return; 577 578 if (OF_getpropintarray(node, "reg", reg, sizeof(reg)) != sizeof(reg)) 579 return; 580 581 port = reg[0] >> 11; 582 if (port >= APLPCIE_MAX_PORTS || sc->sc_port_ios[port] == 0) 583 return; 584 585 pwren_gpiolen = OF_getproplen(node, "pwren-gpios"); 586 reset_gpiolen = OF_getproplen(node, "reset-gpios"); 587 if (reset_gpiolen <= 0) 588 return; 589 590 /* 591 * Set things up such that we can share the 32 available MSIs 592 * across all ports. 593 */ 594 PWRITE4(sc, port, PCIE_PORT_MSI_CTRL, PCIE_PORT_MSI_CTRL_ENABLE); 595 for (msi = 0; msi < 32; msi++) 596 PWRITE4(sc, port, PCIE_T6020_PORT_MSI_MAP(msi), 597 msi | PCIE_T6020_PORT_MSI_MAP_ENABLE); 598 PWRITE4(sc, port, PCIE_T6020_PORT_MSI_DOORBELL_LO, 599 sc->sc_msi_doorbell); 600 PWRITE4(sc, port, PCIE_T6020_PORT_MSI_DOORBELL_HI, 601 sc->sc_msi_doorbell >> 32); 602 603 /* 604 * Clear stream ID mappings. 605 */ 606 for (idx = 0; idx < PCIE_T6020_PORT_MAX_RID2SID; idx++) 607 PWRITE4(sc, port, PCIE_T6020_PORT_RID2SID(idx), 0); 608 609 /* Check if the link is already up. */ 610 stat = PREAD4(sc, port, PCIE_PORT_LINK_STAT); 611 if (stat & PCIE_PORT_LINK_STAT_UP) 612 return; 613 614 PSET4(sc, port, PCIE_PORT_APPCLK, PCIE_PORT_APPCLK_EN); 615 616 /* Assert PERST#. */ 617 reset_gpio = malloc(reset_gpiolen, M_TEMP, M_WAITOK); 618 OF_getpropintarray(node, "reset-gpios", reset_gpio, reset_gpiolen); 619 gpio_controller_config_pin(reset_gpio, GPIO_CONFIG_OUTPUT); 620 gpio_controller_set_pin(reset_gpio, 1); 621 622 /* Power up the device if necessary. */ 623 if (pwren_gpiolen > 0) { 624 pwren_gpio = malloc(pwren_gpiolen, M_TEMP, M_WAITOK); 625 OF_getpropintarray(node, "pwren-gpios", 626 pwren_gpio, pwren_gpiolen); 627 gpio_controller_config_pin(pwren_gpio, GPIO_CONFIG_OUTPUT); 628 gpio_controller_set_pin(pwren_gpio, 1); 629 free(pwren_gpio, M_TEMP, pwren_gpiolen); 630 } 631 632 /* Setup Refclk. */ 633 LSET4(sc, port, PCIE_PHY_LANE_CONF, PCIE_PHY_LANE_CONF_REFCLK0REQ); 634 for (timo = 500; timo > 0; timo--) { 635 stat = LREAD4(sc, port, PCIE_PHY_LANE_CONF); 636 if (stat & PCIE_PHY_LANE_CONF_REFCLK0ACK) 637 break; 638 delay(100); 639 } 640 LSET4(sc, port, PCIE_PHY_LANE_CONF, PCIE_PHY_LANE_CONF_REFCLK1REQ); 641 for (timo = 500; timo > 0; timo--) { 642 stat = LREAD4(sc, port, PCIE_PHY_LANE_CONF); 643 if (stat & PCIE_PHY_LANE_CONF_REFCLK1ACK) 644 break; 645 delay(100); 646 } 647 LSET4(sc, port, PCIE_PHY_LANE_CONF, 648 PCIE_PHY_LANE_CONF_REFCLK0EN | PCIE_PHY_LANE_CONF_REFCLK1EN); 649 650 /* 651 * PERST# must remain asserted for at least 100us after the 652 * reference clock becomes stable. But also has to remain 653 * active at least 100ms after power up. 654 */ 655 if (pwren_gpiolen > 0) 656 delay(100000); 657 else 658 delay(100); 659 660 /* Deassert PERST#. */ 661 PSET4(sc, port, PCIE_T6020_PORT_PERST, PCIE_PORT_PERST_DIS); 662 gpio_controller_set_pin(reset_gpio, 0); 663 free(reset_gpio, M_TEMP, reset_gpiolen); 664 665 for (timo = 2500; timo > 0; timo--) { 666 stat = PREAD4(sc, port, PCIE_PORT_STAT); 667 if (stat & PCIE_PORT_STAT_READY) 668 break; 669 delay(100); 670 } 671 if ((stat & PCIE_PORT_STAT_READY) == 0) 672 return; 673 674 LSET4(sc, port, PCIE_PHY_LANE_CONF, 675 PCIE_PHY_LANE_CONF_REFCLK0CGEN | PCIE_PHY_LANE_CONF_REFCLK1CGEN); 676 PCLR4(sc, port, PCIE_PORT_APPCLK, PCIE_PORT_APPCLK_CGDIS); 677 678 /* Bring up the link. */ 679 PWRITE4(sc, port, PCIE_PORT_LTSSM_CTRL, PCIE_PORT_LTSSM_CTRL_START); 680 for (timo = 1000; timo > 0; timo--) { 681 stat = PREAD4(sc, port, PCIE_PORT_LINK_STAT); 682 if (stat & PCIE_PORT_LINK_STAT_UP) 683 break; 684 delay(100); 685 } 686 } 687 688 void 689 aplpcie_attach_hook(struct device *parent, struct device *self, 690 struct pcibus_attach_args *pba) 691 { 692 } 693 694 int 695 aplpcie_bus_maxdevs(void *v, int bus) 696 { 697 return 32; 698 } 699 700 int 701 aplpcie_find_node(int node, int bus, int device, int function) 702 { 703 uint32_t reg[5]; 704 uint32_t phys_hi; 705 int child; 706 707 phys_hi = ((bus << 16) | (device << 11) | (function << 8)); 708 709 for (child = OF_child(node); child; child = OF_peer(child)) { 710 if (OF_getpropintarray(child, "reg", 711 reg, sizeof(reg)) != sizeof(reg)) 712 continue; 713 714 if (reg[0] == phys_hi) 715 return child; 716 717 node = aplpcie_find_node(child, bus, device, function); 718 if (node) 719 return node; 720 } 721 722 return 0; 723 } 724 725 pcitag_t 726 aplpcie_make_tag(void *v, int bus, int device, int function) 727 { 728 struct aplpcie_softc *sc = v; 729 int node; 730 731 node = aplpcie_find_node(sc->sc_node, bus, device, function); 732 return (((pcitag_t)node << 32) | 733 (bus << 20) | (device << 15) | (function << 12)); 734 } 735 736 void 737 aplpcie_decompose_tag(void *v, pcitag_t tag, int *bp, int *dp, int *fp) 738 { 739 if (bp != NULL) 740 *bp = (tag >> 20) & 0xff; 741 if (dp != NULL) 742 *dp = (tag >> 15) & 0x1f; 743 if (fp != NULL) 744 *fp = (tag >> 12) & 0x7; 745 } 746 747 int 748 aplpcie_conf_size(void *v, pcitag_t tag) 749 { 750 return PCIE_CONFIG_SPACE_SIZE; 751 } 752 753 pcireg_t 754 aplpcie_conf_read(void *v, pcitag_t tag, int reg) 755 { 756 struct aplpcie_softc *sc = v; 757 758 tag = PCITAG_OFFSET(tag); 759 return HREAD4(sc, tag | reg); 760 } 761 762 void 763 aplpcie_conf_write(void *v, pcitag_t tag, int reg, pcireg_t data) 764 { 765 struct aplpcie_softc *sc = v; 766 767 tag = PCITAG_OFFSET(tag); 768 HWRITE4(sc, tag | reg, data); 769 } 770 771 int 772 aplpcie_find_port(struct aplpcie_softc *sc, int bus) 773 { 774 uint32_t bus_range[2]; 775 uint32_t reg[5]; 776 int node; 777 778 for (node = OF_child(sc->sc_node); node; node = OF_peer(node)) { 779 /* Check if bus is in the range for this node. */ 780 if (OF_getpropintarray(node, "bus-range", bus_range, 781 sizeof(bus_range)) != sizeof(bus_range)) 782 continue; 783 if (bus < bus_range[0] || bus > bus_range[1]) 784 continue; 785 786 if (OF_getpropintarray(node, "reg", reg, 787 sizeof(reg)) != sizeof(reg)) 788 continue; 789 return reg[0] >> 11; 790 } 791 792 return -1; 793 } 794 795 int 796 aplpcie_map_rid(struct aplpcie_softc *sc, int port, uint16_t rid, uint32_t sid) 797 { 798 uint32_t reg; 799 int idx; 800 801 for (idx = 0; idx < PCIE_PORT_MAX_RID2SID; idx++) { 802 reg = PREAD4(sc, port, PCIE_PORT_RID2SID(idx)); 803 804 /* If already mapped, we're done. */ 805 if ((reg & PCIE_PORT_RID2SID_RID_MASK) == rid) 806 return 0; 807 808 /* Is this an empty slot? */ 809 if (reg & PCIE_PORT_RID2SID_VALID) 810 continue; 811 812 /* Map using this slot. */ 813 reg = (sid << PCIE_PORT_RID2SID_SID_SHIFT) | rid | 814 PCIE_PORT_RID2SID_VALID; 815 PWRITE4(sc, port, PCIE_PORT_RID2SID(idx), reg); 816 817 /* Read back to check the slot is implemented. */ 818 if (PREAD4(sc, port, PCIE_PORT_RID2SID(idx)) != reg) 819 return ENODEV; 820 return 0; 821 } 822 823 return ENODEV; 824 } 825 826 int 827 aplpcie_t6020_map_rid(struct aplpcie_softc *sc, int port, uint16_t rid, 828 uint32_t sid) 829 { 830 uint32_t reg; 831 int idx; 832 833 for (idx = 0; idx < PCIE_T6020_PORT_MAX_RID2SID; idx++) { 834 reg = PREAD4(sc, port, PCIE_T6020_PORT_RID2SID(idx)); 835 836 /* If already mapped, we're done. */ 837 if ((reg & PCIE_PORT_RID2SID_RID_MASK) == rid) 838 return 0; 839 840 /* Is this an empty slot? */ 841 if (reg & PCIE_PORT_RID2SID_VALID) 842 continue; 843 844 /* Map using this slot. */ 845 reg = (sid << PCIE_PORT_RID2SID_SID_SHIFT) | rid | 846 PCIE_PORT_RID2SID_VALID; 847 PWRITE4(sc, port, PCIE_T6020_PORT_RID2SID(idx), reg); 848 849 /* Read back to check the slot is implemented. */ 850 if (PREAD4(sc, port, PCIE_T6020_PORT_RID2SID(idx)) != reg) 851 return ENODEV; 852 return 0; 853 } 854 855 return ENODEV; 856 } 857 858 int 859 aplpcie_probe_device_hook(void *v, struct pci_attach_args *pa) 860 { 861 struct aplpcie_softc *sc = v; 862 uint32_t phandle, sid; 863 uint16_t rid; 864 int error, port; 865 866 rid = pci_requester_id(pa->pa_pc, pa->pa_tag); 867 pa->pa_dmat = iommu_device_map_pci(sc->sc_node, rid, pa->pa_dmat); 868 if (iommu_device_lookup_pci(sc->sc_node, rid, &phandle, &sid)) 869 return 0; 870 871 /* 872 * Create a stream ID mapping for this device. The mappings 873 * are per-port so we first need to find the port for this 874 * device. Then we find a free mapping slot to enter the 875 * mapping. If we run out of mappings, we print a warning; as 876 * long as the device doesn't do DMA, it will still work. 877 */ 878 879 port = aplpcie_find_port(sc, pa->pa_bus); 880 if (port == -1) 881 return EINVAL; 882 883 if (OF_is_compatible(sc->sc_node, "apple,t6020-pcie")) 884 error = aplpcie_t6020_map_rid(sc, port, rid, sid); 885 else 886 error = aplpcie_map_rid(sc, port, rid, sid); 887 if (error) { 888 printf("%s: out of stream ID mapping slots\n", 889 sc->sc_dev.dv_xname); 890 } 891 892 /* 893 * Not all PCI devices do DMA, so don't return an error if we 894 * ran out of stream ID mapping slots. 895 */ 896 return 0; 897 } 898 899 int 900 aplpcie_intr_map(struct pci_attach_args *pa, pci_intr_handle_t *ihp) 901 { 902 int pin = pa->pa_rawintrpin; 903 904 if (pin == 0 || pin > PCI_INTERRUPT_PIN_MAX) 905 return -1; 906 907 if (pa->pa_tag == 0) 908 return -1; 909 910 ihp->ih_pc = pa->pa_pc; 911 ihp->ih_tag = pa->pa_intrtag; 912 ihp->ih_intrpin = pa->pa_intrpin; 913 ihp->ih_type = PCI_INTX; 914 915 return 0; 916 } 917 918 const char * 919 aplpcie_intr_string(void *v, pci_intr_handle_t ih) 920 { 921 switch (ih.ih_type) { 922 case PCI_MSI: 923 return "msi"; 924 case PCI_MSIX: 925 return "msix"; 926 } 927 928 return "intx"; 929 } 930 931 void * 932 aplpcie_intr_establish(void *v, pci_intr_handle_t ih, int level, 933 struct cpu_info *ci, int (*func)(void *), void *arg, char *name) 934 { 935 struct aplpcie_softc *sc = v; 936 void *cookie; 937 938 KASSERT(ih.ih_type != PCI_NONE); 939 940 if (ih.ih_type != PCI_INTX) { 941 uint64_t addr, data; 942 943 addr = data = 0; 944 cookie = fdt_intr_establish_msi_cpu(sc->sc_node, &addr, 945 &data, level, ci, func, arg, name); 946 if (cookie == NULL) 947 return NULL; 948 949 if (ih.ih_type == PCI_MSIX) { 950 pci_msix_enable(ih.ih_pc, ih.ih_tag, 951 &sc->sc_bus_memt, ih.ih_intrpin, addr, data); 952 } else 953 pci_msi_enable(ih.ih_pc, ih.ih_tag, addr, data); 954 } else { 955 int bus, dev, fn; 956 uint32_t reg[4]; 957 958 aplpcie_decompose_tag(sc, ih.ih_tag, &bus, &dev, &fn); 959 960 reg[0] = bus << 16 | dev << 11 | fn << 8; 961 reg[1] = reg[2] = 0; 962 reg[3] = ih.ih_intrpin; 963 964 cookie = fdt_intr_establish_imap_cpu(sc->sc_node, reg, 965 sizeof(reg), level, ci, func, arg, name); 966 } 967 968 return cookie; 969 } 970 971 void 972 aplpcie_intr_disestablish(void *v, void *cookie) 973 { 974 } 975 976 void * 977 aplpcie_intr_establish_msi(void *cookie, uint64_t *addr, uint64_t *data, 978 int level, struct cpu_info *ci, int (*func)(void *), void *arg, char *name) 979 { 980 struct aplpcie_softc *sc = cookie; 981 uint32_t cells[4]; 982 int ncells; 983 984 ncells = sc->sc_msi_rangelen / sizeof(uint32_t); 985 if (sc->sc_msi >= sc->sc_msi_range[ncells - 1]) 986 return NULL; 987 988 *addr = sc->sc_msi_doorbell; 989 *data = sc->sc_msi++; 990 991 memcpy(cells, &sc->sc_msi_range[1], sizeof(cells)); 992 cells[ncells - 4] += *data; 993 994 return fdt_intr_parent_establish(&sc->sc_msi_ic, cells, 995 level, ci, func, arg, name); 996 } 997 998 void 999 aplpcie_intr_disestablish_msi(void *cookie) 1000 { 1001 fdt_intr_parent_disestablish(cookie); 1002 } 1003 1004 int 1005 aplpcie_bs_iomap(bus_space_tag_t t, bus_addr_t addr, bus_size_t size, 1006 int flags, bus_space_handle_t *bshp) 1007 { 1008 struct aplpcie_softc *sc = t->bus_private; 1009 int i; 1010 1011 for (i = 0; i < sc->sc_nranges; i++) { 1012 uint64_t pci_start = sc->sc_ranges[i].pci_base; 1013 uint64_t pci_end = pci_start + sc->sc_ranges[i].size; 1014 uint64_t phys_start = sc->sc_ranges[i].phys_base; 1015 1016 if ((sc->sc_ranges[i].flags & 0x03000000) == 0x01000000 && 1017 addr >= pci_start && addr + size <= pci_end) { 1018 return bus_space_map(sc->sc_iot, 1019 addr - pci_start + phys_start, size, flags, bshp); 1020 } 1021 } 1022 1023 return ENXIO; 1024 } 1025 1026 int 1027 aplpcie_bs_memmap(bus_space_tag_t t, bus_addr_t addr, bus_size_t size, 1028 int flags, bus_space_handle_t *bshp) 1029 { 1030 struct aplpcie_softc *sc = t->bus_private; 1031 int i; 1032 1033 flags |= BUS_SPACE_MAP_POSTED; 1034 1035 for (i = 0; i < sc->sc_nranges; i++) { 1036 uint64_t pci_start = sc->sc_ranges[i].pci_base; 1037 uint64_t pci_end = pci_start + sc->sc_ranges[i].size; 1038 uint64_t phys_start = sc->sc_ranges[i].phys_base; 1039 1040 if ((sc->sc_ranges[i].flags & 0x02000000) == 0x02000000 && 1041 addr >= pci_start && addr + size <= pci_end) { 1042 return bus_space_map(sc->sc_iot, 1043 addr - pci_start + phys_start, size, flags, bshp); 1044 } 1045 } 1046 1047 return ENXIO; 1048 } 1049