1 /* $OpenBSD: dwpcie.c,v 1.22 2020/07/14 15:42:19 patrick 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_gpio.h> 36 #include <dev/ofw/ofw_misc.h> 37 #include <dev/ofw/ofw_pinctrl.h> 38 #include <dev/ofw/ofw_power.h> 39 #include <dev/ofw/fdt.h> 40 41 /* Registers */ 42 #define PCIE_PORT_LINK_CTRL 0x710 43 #define PCIE_PORT_LINK_CTRL_LANES_MASK (0x3f << 16) 44 #define PCIE_PORT_LINK_CTRL_LANES_1 (0x1 << 16) 45 #define PCIE_PORT_LINK_CTRL_LANES_2 (0x3 << 16) 46 #define PCIE_PORT_LINK_CTRL_LANES_4 (0x7 << 16) 47 #define PCIE_PORT_LINK_CTRL_LANES_8 (0xf << 16) 48 #define PCIE_PHY_DEBUG_R1 0x72c 49 #define PCIE_PHY_DEBUG_R1_XMLH_LINK_IN_TRAINING (1 << 29) 50 #define PCIE_PHY_DEBUG_R1_XMLH_LINK_UP (1 << 4) 51 #define PCIE_LINK_WIDTH_SPEED_CTRL 0x80c 52 #define PCIE_LINK_WIDTH_SPEED_CTRL_LANES_MASK (0x1f << 8) 53 #define PCIE_LINK_WIDTH_SPEED_CTRL_LANES_1 (0x1 << 8) 54 #define PCIE_LINK_WIDTH_SPEED_CTRL_LANES_2 (0x2 << 8) 55 #define PCIE_LINK_WIDTH_SPEED_CTRL_LANES_4 (0x4 << 8) 56 #define PCIE_LINK_WIDTH_SPEED_CTRL_LANES_8 (0x8 << 8) 57 #define PCIE_LINK_WIDTH_SPEED_CTRL_CHANGE (1 << 17) 58 59 #define MISC_CONTROL_1 0x8bc 60 #define MISC_CONTROL_1_DBI_RO_WR_EN (1 << 0) 61 #define IATU_VIEWPORT 0x900 62 #define IATU_VIEWPORT_INDEX0 0 63 #define IATU_VIEWPORT_INDEX1 1 64 #define IATU_VIEWPORT_INDEX2 2 65 #define IATU_OFFSET_VIEWPORT 0x904 66 #define IATU_OFFSET_UNROLL(x) (0x200 * (x)) 67 #define IATU_REGION_CTRL_1 0x000 68 #define IATU_REGION_CTRL_1_TYPE_MEM 0 69 #define IATU_REGION_CTRL_1_TYPE_IO 2 70 #define IATU_REGION_CTRL_1_TYPE_CFG0 4 71 #define IATU_REGION_CTRL_1_TYPE_CFG1 5 72 #define IATU_REGION_CTRL_2 0x004 73 #define IATU_REGION_CTRL_2_REGION_EN (1U << 31) 74 #define IATU_LWR_BASE_ADDR 0x08 75 #define IATU_UPPER_BASE_ADDR 0x0c 76 #define IATU_LIMIT_ADDR 0x10 77 #define IATU_LWR_TARGET_ADDR 0x14 78 #define IATU_UPPER_TARGET_ADDR 0x18 79 80 #define PCIE_GLOBAL_CTRL 0x8000 81 #define PCIE_GLOBAL_CTRL_APP_LTSSM_EN (1 << 2) 82 #define PCIE_GLOBAL_CTRL_DEVICE_TYPE_MASK (0xf << 4) 83 #define PCIE_GLOBAL_CTRL_DEVICE_TYPE_RC (0x4 << 4) 84 #define PCIE_GLOBAL_STATUS 0x8008 85 #define PCIE_GLOBAL_STATUS_RDLH_LINK_UP (1 << 1) 86 #define PCIE_GLOBAL_STATUS_PHY_LINK_UP (1 << 9) 87 #define PCIE_PM_STATUS 0x8014 88 #define PCIE_GLOBAL_INT_CAUSE 0x801c 89 #define PCIE_GLOBAL_INT_MASK 0x8020 90 #define PCIE_GLOBAL_INT_MASK_INT_A (1 << 9) 91 #define PCIE_GLOBAL_INT_MASK_INT_B (1 << 10) 92 #define PCIE_GLOBAL_INT_MASK_INT_C (1 << 11) 93 #define PCIE_GLOBAL_INT_MASK_INT_D (1 << 12) 94 #define PCIE_ARCACHE_TRC 0x8050 95 #define PCIE_ARCACHE_TRC_DEFAULT 0x3511 96 #define PCIE_AWCACHE_TRC 0x8054 97 #define PCIE_AWCACHE_TRC_DEFAULT 0x5311 98 #define PCIE_ARUSER 0x805c 99 #define PCIE_AWUSER 0x8060 100 #define PCIE_AXUSER_DOMAIN_MASK (0x3 << 4) 101 #define PCIE_AXUSER_DOMAIN_INNER_SHARABLE (0x1 << 4) 102 #define PCIE_AXUSER_DOMAIN_OUTER_SHARABLE (0x2 << 4) 103 104 /* i.MX8MQ registers */ 105 #define PCIE_RC_LCR 0x7c 106 #define PCIE_RC_LCR_MAX_LINK_SPEEDS_GEN1 0x1 107 #define PCIE_RC_LCR_MAX_LINK_SPEEDS_GEN2 0x2 108 #define PCIE_RC_LCR_MAX_LINK_SPEEDS_MASK 0xf 109 #define PCIE_RC_LCR_L1EL_MASK (0x7 << 15) 110 #define PCIE_RC_LCR_L1EL_64US (0x6 << 15) 111 112 #define IOMUXC_GPR12 0x30 113 #define IMX8MQ_GPR_PCIE2_DEVICE_TYPE_MASK (0xf << 8) 114 #define IMX8MQ_GPR_PCIE2_DEVICE_TYPE_RC (0x4 << 8) 115 #define IMX8MQ_GPR_PCIE1_DEVICE_TYPE_MASK (0xf << 12) 116 #define IMX8MQ_GPR_PCIE1_DEVICE_TYPE_RC (0x4 << 12) 117 #define IOMUXC_GPR14 0x38 118 #define IOMUXC_GPR16 0x40 119 #define IMX8MQ_GPR_PCIE_REF_USE_PAD (1 << 9) 120 #define IMX8MQ_GPR_PCIE_CLK_REQ_OVERRIDE_EN (1 << 10) 121 #define IMX8MQ_GPR_PCIE_CLK_REQ_OVERRIDE (1 << 11) 122 #define IMX8MM_GPR_PCIE_SSC_EN (1 << 16) 123 #define IMX8MM_GPR_PCIE_POWER_OFF (1 << 17) 124 #define IMX8MM_GPR_PCIE_CMN_RST (1 << 18) 125 #define IMX8MM_GPR_PCIE_AUX_EN (1 << 19) 126 #define IMX8MM_GPR_PCIE_REF_CLK_MASK (0x3 << 24) 127 #define IMX8MM_GPR_PCIE_REF_CLK_PLL (0x3 << 24) 128 #define IMX8MM_GPR_PCIE_REF_CLK_EXT (0x2 << 24) 129 130 #define IMX8MM_PCIE_PHY_CMN_REG62 0x188 131 #define IMX8MM_PCIE_PHY_CMN_REG62_PLL_CLK_OUT 0x08 132 #define IMX8MM_PCIE_PHY_CMN_REG64 0x190 133 #define IMX8MM_PCIE_PHY_CMN_REG64_AUX_RX_TX_TERM 0x8c 134 #define IMX8MM_PCIE_PHY_CMN_REG75 0x1d4 135 #define IMX8MM_PCIE_PHY_CMN_REG75_PLL_DONE 0x3 136 #define IMX8MM_PCIE_PHY_TRSV_REG5 0x414 137 #define IMX8MM_PCIE_PHY_TRSV_REG5_GEN1_DEEMP 0x2d 138 #define IMX8MM_PCIE_PHY_TRSV_REG6 0x418 139 #define IMX8MM_PCIE_PHY_TRSV_REG6_GEN2_DEEMP 0xf 140 141 #define ANATOP_PLLOUT_CTL 0x74 142 #define ANATOP_PLLOUT_CTL_CKE (1 << 4) 143 #define ANATOP_PLLOUT_CTL_SEL_SYSPLL1 0xb 144 #define ANATOP_PLLOUT_CTL_SEL_MASK 0xf 145 #define ANATOP_PLLOUT_DIV 0x7c 146 #define ANATOP_PLLOUT_DIV_SYSPLL1 0x7 147 148 #define HREAD4(sc, reg) \ 149 (bus_space_read_4((sc)->sc_iot, (sc)->sc_ioh, (reg))) 150 #define HWRITE4(sc, reg, val) \ 151 bus_space_write_4((sc)->sc_iot, (sc)->sc_ioh, (reg), (val)) 152 #define HSET4(sc, reg, bits) \ 153 HWRITE4((sc), (reg), HREAD4((sc), (reg)) | (bits)) 154 #define HCLR4(sc, reg, bits) \ 155 HWRITE4((sc), (reg), HREAD4((sc), (reg)) & ~(bits)) 156 157 struct dwpcie_range { 158 uint32_t flags; 159 uint64_t pci_base; 160 uint64_t phys_base; 161 uint64_t size; 162 }; 163 164 struct dwpcie_softc { 165 struct device sc_dev; 166 bus_space_tag_t sc_iot; 167 bus_space_handle_t sc_ioh; 168 bus_space_handle_t sc_cfg0_ioh; 169 bus_space_handle_t sc_cfg1_ioh; 170 171 bus_addr_t sc_cfg0_base; 172 bus_size_t sc_cfg0_size; 173 bus_addr_t sc_cfg1_base; 174 bus_size_t sc_cfg1_size; 175 bus_addr_t sc_io_base; 176 bus_addr_t sc_io_bus_addr; 177 bus_size_t sc_io_size; 178 bus_addr_t sc_mem_base; 179 bus_addr_t sc_mem_bus_addr; 180 bus_size_t sc_mem_size; 181 182 int sc_node; 183 int sc_acells; 184 int sc_scells; 185 int sc_pacells; 186 int sc_pscells; 187 struct dwpcie_range *sc_ranges; 188 int sc_nranges; 189 190 struct bus_space sc_bus_iot; 191 struct bus_space sc_bus_memt; 192 193 struct arm64_pci_chipset sc_pc; 194 int sc_bus; 195 196 int sc_num_viewport; 197 bus_addr_t sc_atu_base; 198 int sc_atu_unroll; 199 200 void *sc_ih; 201 }; 202 203 int dwpcie_match(struct device *, void *, void *); 204 void dwpcie_attach(struct device *, struct device *, void *); 205 206 struct cfattach dwpcie_ca = { 207 sizeof (struct dwpcie_softc), dwpcie_match, dwpcie_attach 208 }; 209 210 struct cfdriver dwpcie_cd = { 211 NULL, "dwpcie", DV_DULL 212 }; 213 214 int 215 dwpcie_match(struct device *parent, void *match, void *aux) 216 { 217 struct fdt_attach_args *faa = aux; 218 219 return (OF_is_compatible(faa->fa_node, "marvell,armada8k-pcie") || 220 OF_is_compatible(faa->fa_node, "fsl,imx8mm-pcie") || 221 OF_is_compatible(faa->fa_node, "fsl,imx8mq-pcie")); 222 } 223 224 void dwpcie_atu_config(struct dwpcie_softc *, int, int, 225 uint64_t, uint64_t, uint64_t); 226 void dwpcie_link_config(struct dwpcie_softc *); 227 int dwpcie_link_up(struct dwpcie_softc *); 228 229 int dwpcie_armada8k_init(struct dwpcie_softc *); 230 int dwpcie_armada8k_link_up(struct dwpcie_softc *); 231 int dwpcie_armada8k_intr(void *); 232 233 int dwpcie_imx8mq_init(struct dwpcie_softc *); 234 int dwpcie_imx8mq_intr(void *); 235 236 void dwpcie_attach_hook(struct device *, struct device *, 237 struct pcibus_attach_args *); 238 int dwpcie_bus_maxdevs(void *, int); 239 pcitag_t dwpcie_make_tag(void *, int, int, int); 240 void dwpcie_decompose_tag(void *, pcitag_t, int *, int *, int *); 241 int dwpcie_conf_size(void *, pcitag_t); 242 pcireg_t dwpcie_conf_read(void *, pcitag_t, int); 243 void dwpcie_conf_write(void *, pcitag_t, int, pcireg_t); 244 245 int dwpcie_intr_map(struct pci_attach_args *, pci_intr_handle_t *); 246 const char *dwpcie_intr_string(void *, pci_intr_handle_t); 247 void *dwpcie_intr_establish(void *, pci_intr_handle_t, int, 248 struct cpu_info *, int (*)(void *), void *, char *); 249 void dwpcie_intr_disestablish(void *, void *); 250 251 int dwpcie_bs_iomap(bus_space_tag_t, bus_addr_t, bus_size_t, int, 252 bus_space_handle_t *); 253 int dwpcie_bs_memmap(bus_space_tag_t, bus_addr_t, bus_size_t, int, 254 bus_space_handle_t *); 255 256 void 257 dwpcie_attach(struct device *parent, struct device *self, void *aux) 258 { 259 struct dwpcie_softc *sc = (struct dwpcie_softc *)self; 260 struct fdt_attach_args *faa = aux; 261 struct pcibus_attach_args pba; 262 bus_addr_t iobase, iolimit; 263 bus_addr_t membase, memlimit; 264 uint32_t bus_range[2]; 265 uint32_t *ranges; 266 int i, j, nranges, rangeslen; 267 pcireg_t bir, blr, csr; 268 int error = 0; 269 270 if (faa->fa_nreg < 2) { 271 printf(": no registers\n"); 272 return; 273 } 274 275 sc->sc_iot = faa->fa_iot; 276 sc->sc_node = faa->fa_node; 277 278 sc->sc_acells = OF_getpropint(sc->sc_node, "#address-cells", 279 faa->fa_acells); 280 sc->sc_scells = OF_getpropint(sc->sc_node, "#size-cells", 281 faa->fa_scells); 282 sc->sc_pacells = faa->fa_acells; 283 sc->sc_pscells = faa->fa_scells; 284 285 rangeslen = OF_getproplen(sc->sc_node, "ranges"); 286 if (rangeslen <= 0 || (rangeslen % sizeof(uint32_t)) || 287 (rangeslen / sizeof(uint32_t)) % (sc->sc_acells + 288 sc->sc_pacells + sc->sc_scells)) { 289 printf(": invalid ranges property\n"); 290 return; 291 } 292 293 ranges = malloc(rangeslen, M_TEMP, M_WAITOK); 294 OF_getpropintarray(sc->sc_node, "ranges", ranges, 295 rangeslen); 296 297 nranges = (rangeslen / sizeof(uint32_t)) / 298 (sc->sc_acells + sc->sc_pacells + sc->sc_scells); 299 sc->sc_ranges = mallocarray(nranges, 300 sizeof(struct dwpcie_range), M_TEMP, M_WAITOK); 301 sc->sc_nranges = nranges; 302 303 for (i = 0, j = 0; i < sc->sc_nranges; i++) { 304 sc->sc_ranges[i].flags = ranges[j++]; 305 sc->sc_ranges[i].pci_base = ranges[j++]; 306 if (sc->sc_acells - 1 == 2) { 307 sc->sc_ranges[i].pci_base <<= 32; 308 sc->sc_ranges[i].pci_base |= ranges[j++]; 309 } 310 sc->sc_ranges[i].phys_base = ranges[j++]; 311 if (sc->sc_pacells == 2) { 312 sc->sc_ranges[i].phys_base <<= 32; 313 sc->sc_ranges[i].phys_base |= ranges[j++]; 314 } 315 sc->sc_ranges[i].size = ranges[j++]; 316 if (sc->sc_scells == 2) { 317 sc->sc_ranges[i].size <<= 32; 318 sc->sc_ranges[i].size |= ranges[j++]; 319 } 320 } 321 322 free(ranges, M_TEMP, rangeslen); 323 324 if (bus_space_map(sc->sc_iot, faa->fa_reg[0].addr, 325 faa->fa_reg[0].size, 0, &sc->sc_ioh)) { 326 free(sc->sc_ranges, M_TEMP, sc->sc_nranges * 327 sizeof(struct dwpcie_range)); 328 printf(": can't map ctrl registers\n"); 329 return; 330 } 331 332 sc->sc_cfg0_base = faa->fa_reg[1].addr; 333 sc->sc_cfg0_size = faa->fa_reg[1].size / 2; 334 sc->sc_cfg0_base = faa->fa_reg[1].addr + sc->sc_cfg0_size; 335 sc->sc_cfg1_size = sc->sc_cfg0_size; 336 337 if (bus_space_map(sc->sc_iot, sc->sc_cfg0_base, 338 sc->sc_cfg1_size, 0, &sc->sc_cfg0_ioh)) { 339 bus_space_unmap(sc->sc_iot, sc->sc_ioh, faa->fa_reg[0].size); 340 free(sc->sc_ranges, M_TEMP, sc->sc_nranges * 341 sizeof(struct dwpcie_range)); 342 printf(": can't map config registers\n"); 343 return; 344 } 345 346 if (bus_space_map(sc->sc_iot, sc->sc_cfg1_base, 347 sc->sc_cfg1_size, 0, &sc->sc_cfg1_ioh)) { 348 bus_space_unmap(sc->sc_iot, sc->sc_cfg0_ioh, sc->sc_cfg0_size); 349 bus_space_unmap(sc->sc_iot, sc->sc_ioh, faa->fa_reg[0].size); 350 free(sc->sc_ranges, M_TEMP, sc->sc_nranges * 351 sizeof(struct dwpcie_range)); 352 printf(": can't map config registers\n"); 353 return; 354 } 355 356 sc->sc_num_viewport = OF_getpropint(sc->sc_node, "num-viewport", 2); 357 358 printf("\n"); 359 360 pinctrl_byname(sc->sc_node, "default"); 361 362 clock_set_assigned(sc->sc_node); 363 364 if (OF_is_compatible(sc->sc_node, "marvell,armada8k-pcie")) 365 error = dwpcie_armada8k_init(sc); 366 if (OF_is_compatible(sc->sc_node, "fsl,imx8mm-pcie") || 367 OF_is_compatible(sc->sc_node, "fsl,imx8mq-pcie")) 368 error = dwpcie_imx8mq_init(sc); 369 if (error != 0) { 370 bus_space_unmap(sc->sc_iot, sc->sc_cfg1_ioh, sc->sc_cfg1_size); 371 bus_space_unmap(sc->sc_iot, sc->sc_cfg0_ioh, sc->sc_cfg0_size); 372 bus_space_unmap(sc->sc_iot, sc->sc_ioh, faa->fa_reg[0].size); 373 free(sc->sc_ranges, M_TEMP, sc->sc_nranges * 374 sizeof(struct dwpcie_range)); 375 printf("%s: can't initialize hardware\n", 376 sc->sc_dev.dv_xname); 377 return; 378 } 379 380 if (HREAD4(sc, IATU_VIEWPORT) == 0xffffffff) { 381 sc->sc_atu_base = 0x300000; 382 sc->sc_atu_unroll = 1; 383 } 384 385 /* Set up address translation for I/O space. */ 386 sc->sc_io_bus_addr = sc->sc_mem_bus_addr = -1; 387 for (i = 0; i < sc->sc_nranges; i++) { 388 if ((sc->sc_ranges[i].flags & 0x03000000) == 0x01000000 && 389 sc->sc_ranges[i].size > 0) { 390 sc->sc_io_base = sc->sc_ranges[i].phys_base; 391 sc->sc_io_bus_addr = sc->sc_ranges[i].pci_base; 392 sc->sc_io_size = sc->sc_ranges[i].size; 393 } 394 if ((sc->sc_ranges[i].flags & 0x03000000) == 0x02000000 && 395 sc->sc_ranges[i].size > 0) { 396 sc->sc_mem_base = sc->sc_ranges[i].phys_base; 397 sc->sc_mem_bus_addr = sc->sc_ranges[i].pci_base; 398 sc->sc_mem_size = sc->sc_ranges[i].size; 399 } 400 } 401 402 dwpcie_atu_config(sc, IATU_VIEWPORT_INDEX0, 403 IATU_REGION_CTRL_1_TYPE_MEM, sc->sc_mem_base, 404 sc->sc_mem_bus_addr, sc->sc_mem_size); 405 if (sc->sc_num_viewport > 2) 406 dwpcie_atu_config(sc, IATU_VIEWPORT_INDEX2, 407 IATU_REGION_CTRL_1_TYPE_IO, sc->sc_io_base, 408 sc->sc_io_bus_addr, sc->sc_io_size); 409 410 /* Enable modification of read-only bits. */ 411 HSET4(sc, MISC_CONTROL_1, MISC_CONTROL_1_DBI_RO_WR_EN); 412 413 /* A Root Port is a PCI-PCI Bridge. */ 414 HWRITE4(sc, PCI_CLASS_REG, 415 PCI_CLASS_BRIDGE << PCI_CLASS_SHIFT | 416 PCI_SUBCLASS_BRIDGE_PCI << PCI_SUBCLASS_SHIFT); 417 418 /* Clear BAR as U-Boot seems to leave garbage in it. */ 419 HWRITE4(sc, PCI_MAPREG_START, PCI_MAPREG_MEM_TYPE_64BIT); 420 HWRITE4(sc, PCI_MAPREG_START + 4, 0); 421 422 /* Make sure read-only bits are write-protected. */ 423 HCLR4(sc, MISC_CONTROL_1, MISC_CONTROL_1_DBI_RO_WR_EN); 424 425 /* Set up bus range. */ 426 if (OF_getpropintarray(sc->sc_node, "bus-range", bus_range, 427 sizeof(bus_range)) != sizeof(bus_range) || 428 bus_range[0] >= 32 || bus_range[1] >= 32) { 429 bus_range[0] = 0; 430 bus_range[1] = 31; 431 } 432 sc->sc_bus = bus_range[0]; 433 434 /* Initialize bus range. */ 435 bir = bus_range[0]; 436 bir |= ((bus_range[0] + 1) << 8); 437 bir |= (bus_range[1] << 16); 438 HWRITE4(sc, PPB_REG_BUSINFO, bir); 439 440 /* Initialize I/O window. */ 441 iobase = sc->sc_io_bus_addr; 442 iolimit = iobase + sc->sc_io_size - 1; 443 blr = iolimit & PPB_IO_MASK; 444 blr |= (iobase >> PPB_IO_SHIFT); 445 HWRITE4(sc, PPB_REG_IOSTATUS, blr); 446 blr = (iobase & 0xffff0000) >> 16; 447 blr |= iolimit & 0xffff0000; 448 HWRITE4(sc, PPB_REG_IO_HI, blr); 449 450 /* Initialize memory mapped I/O window. */ 451 membase = sc->sc_mem_bus_addr; 452 memlimit = membase + sc->sc_mem_size - 1; 453 blr = memlimit & PPB_MEM_MASK; 454 blr |= (membase >> PPB_MEM_SHIFT); 455 HWRITE4(sc, PPB_REG_MEM, blr); 456 457 /* Reset prefetchable memory mapped I/O window. */ 458 HWRITE4(sc, PPB_REG_PREFMEM, 0x0000ffff); 459 HWRITE4(sc, PPB_REG_PREFBASE_HI32, 0); 460 HWRITE4(sc, PPB_REG_PREFLIM_HI32, 0); 461 462 csr = PCI_COMMAND_MASTER_ENABLE; 463 if (iolimit > iobase) 464 csr |= PCI_COMMAND_IO_ENABLE; 465 if (memlimit > membase) 466 csr |= PCI_COMMAND_MEM_ENABLE; 467 HWRITE4(sc, PCI_COMMAND_STATUS_REG, csr); 468 469 memcpy(&sc->sc_bus_iot, sc->sc_iot, sizeof(sc->sc_bus_iot)); 470 sc->sc_bus_iot.bus_private = sc; 471 sc->sc_bus_iot._space_map = dwpcie_bs_iomap; 472 memcpy(&sc->sc_bus_memt, sc->sc_iot, sizeof(sc->sc_bus_memt)); 473 sc->sc_bus_memt.bus_private = sc; 474 sc->sc_bus_memt._space_map = dwpcie_bs_memmap; 475 476 sc->sc_pc.pc_conf_v = sc; 477 sc->sc_pc.pc_attach_hook = dwpcie_attach_hook; 478 sc->sc_pc.pc_bus_maxdevs = dwpcie_bus_maxdevs; 479 sc->sc_pc.pc_make_tag = dwpcie_make_tag; 480 sc->sc_pc.pc_decompose_tag = dwpcie_decompose_tag; 481 sc->sc_pc.pc_conf_size = dwpcie_conf_size; 482 sc->sc_pc.pc_conf_read = dwpcie_conf_read; 483 sc->sc_pc.pc_conf_write = dwpcie_conf_write; 484 485 sc->sc_pc.pc_intr_v = sc; 486 sc->sc_pc.pc_intr_map = dwpcie_intr_map; 487 sc->sc_pc.pc_intr_map_msi = _pci_intr_map_msi; 488 sc->sc_pc.pc_intr_map_msix = _pci_intr_map_msix; 489 sc->sc_pc.pc_intr_string = dwpcie_intr_string; 490 sc->sc_pc.pc_intr_establish = dwpcie_intr_establish; 491 sc->sc_pc.pc_intr_disestablish = dwpcie_intr_disestablish; 492 493 memset(&pba, 0, sizeof(pba)); 494 pba.pba_busname = "pci"; 495 pba.pba_iot = &sc->sc_bus_iot; 496 pba.pba_memt = &sc->sc_bus_memt; 497 pba.pba_dmat = faa->fa_dmat; 498 pba.pba_pc = &sc->sc_pc; 499 pba.pba_domain = pci_ndomains++; 500 pba.pba_bus = sc->sc_bus; 501 if (OF_is_compatible(faa->fa_node, "marvell,armada8k-pcie")) 502 pba.pba_flags |= PCI_FLAGS_MSI_ENABLED; 503 504 config_found(self, &pba, NULL); 505 } 506 507 void 508 dwpcie_link_config(struct dwpcie_softc *sc) 509 { 510 uint32_t mode, width, reg; 511 int lanes; 512 513 lanes = OF_getpropint(sc->sc_node, "num-lanes", 0); 514 515 switch (lanes) { 516 case 1: 517 mode = PCIE_PORT_LINK_CTRL_LANES_1; 518 width = PCIE_LINK_WIDTH_SPEED_CTRL_LANES_1; 519 break; 520 case 2: 521 mode = PCIE_PORT_LINK_CTRL_LANES_2; 522 width = PCIE_LINK_WIDTH_SPEED_CTRL_LANES_2; 523 break; 524 case 4: 525 mode = PCIE_PORT_LINK_CTRL_LANES_4; 526 width = PCIE_LINK_WIDTH_SPEED_CTRL_LANES_4; 527 break; 528 case 8: 529 mode = PCIE_PORT_LINK_CTRL_LANES_8; 530 width = PCIE_LINK_WIDTH_SPEED_CTRL_LANES_8; 531 break; 532 default: 533 printf("%s: %d lanes not supported\n", __func__, lanes); 534 return; 535 } 536 537 reg = HREAD4(sc, PCIE_PORT_LINK_CTRL); 538 reg &= ~PCIE_PORT_LINK_CTRL_LANES_MASK; 539 reg |= mode; 540 HWRITE4(sc, PCIE_PORT_LINK_CTRL, reg); 541 542 reg = HREAD4(sc, PCIE_LINK_WIDTH_SPEED_CTRL); 543 reg &= ~PCIE_LINK_WIDTH_SPEED_CTRL_LANES_MASK; 544 reg |= width; 545 HWRITE4(sc, PCIE_LINK_WIDTH_SPEED_CTRL, reg); 546 547 reg = HREAD4(sc, PCIE_LINK_WIDTH_SPEED_CTRL); 548 reg |= PCIE_LINK_WIDTH_SPEED_CTRL_CHANGE; 549 HWRITE4(sc, PCIE_LINK_WIDTH_SPEED_CTRL, reg); 550 } 551 552 int 553 dwpcie_armada8k_init(struct dwpcie_softc *sc) 554 { 555 uint32_t reg; 556 int timo; 557 558 clock_enable_all(sc->sc_node); 559 560 dwpcie_link_config(sc); 561 562 if (!dwpcie_armada8k_link_up(sc)) { 563 reg = HREAD4(sc, PCIE_GLOBAL_CTRL); 564 reg &= ~PCIE_GLOBAL_CTRL_APP_LTSSM_EN; 565 HWRITE4(sc, PCIE_GLOBAL_CTRL, reg); 566 } 567 568 /* Enable Root Complex mode. */ 569 reg = HREAD4(sc, PCIE_GLOBAL_CTRL); 570 reg &= ~PCIE_GLOBAL_CTRL_DEVICE_TYPE_MASK; 571 reg |= PCIE_GLOBAL_CTRL_DEVICE_TYPE_RC; 572 HWRITE4(sc, PCIE_GLOBAL_CTRL, reg); 573 574 HWRITE4(sc, PCIE_ARCACHE_TRC, PCIE_ARCACHE_TRC_DEFAULT); 575 HWRITE4(sc, PCIE_AWCACHE_TRC, PCIE_AWCACHE_TRC_DEFAULT); 576 reg = HREAD4(sc, PCIE_ARUSER); 577 reg &= ~PCIE_AXUSER_DOMAIN_MASK; 578 reg |= PCIE_AXUSER_DOMAIN_OUTER_SHARABLE; 579 HWRITE4(sc, PCIE_ARUSER, reg); 580 reg = HREAD4(sc, PCIE_AWUSER); 581 reg &= ~PCIE_AXUSER_DOMAIN_MASK; 582 reg |= PCIE_AXUSER_DOMAIN_OUTER_SHARABLE; 583 HWRITE4(sc, PCIE_AWUSER, reg); 584 585 if (!dwpcie_armada8k_link_up(sc)) { 586 reg = HREAD4(sc, PCIE_GLOBAL_CTRL); 587 reg |= PCIE_GLOBAL_CTRL_APP_LTSSM_EN; 588 HWRITE4(sc, PCIE_GLOBAL_CTRL, reg); 589 } 590 591 for (timo = 40; timo > 0; timo--) { 592 if (dwpcie_armada8k_link_up(sc)) 593 break; 594 delay(1000); 595 } 596 if (timo == 0) 597 return ETIMEDOUT; 598 599 sc->sc_ih = fdt_intr_establish(sc->sc_node, IPL_AUDIO | IPL_MPSAFE, 600 dwpcie_armada8k_intr, sc, sc->sc_dev.dv_xname); 601 602 /* Unmask INTx interrupts. */ 603 HWRITE4(sc, PCIE_GLOBAL_INT_MASK, 604 PCIE_GLOBAL_INT_MASK_INT_A | PCIE_GLOBAL_INT_MASK_INT_B | 605 PCIE_GLOBAL_INT_MASK_INT_C | PCIE_GLOBAL_INT_MASK_INT_D); 606 607 return 0; 608 } 609 610 int 611 dwpcie_armada8k_link_up(struct dwpcie_softc *sc) 612 { 613 uint32_t reg, mask; 614 615 mask = PCIE_GLOBAL_STATUS_RDLH_LINK_UP; 616 mask |= PCIE_GLOBAL_STATUS_PHY_LINK_UP; 617 reg = HREAD4(sc, PCIE_GLOBAL_STATUS); 618 return ((reg & mask) == mask); 619 } 620 621 int 622 dwpcie_armada8k_intr(void *arg) 623 { 624 struct dwpcie_softc *sc = arg; 625 uint32_t cause; 626 627 /* Acknowledge interrupts. */ 628 cause = HREAD4(sc, PCIE_GLOBAL_INT_CAUSE); 629 HWRITE4(sc, PCIE_GLOBAL_INT_CAUSE, cause); 630 631 /* INTx interrupt, so not really ours. */ 632 return 0; 633 } 634 635 int 636 dwpcie_imx8mq_init(struct dwpcie_softc *sc) 637 { 638 uint32_t *clkreq_gpio, *disable_gpio, *reset_gpio; 639 ssize_t clkreq_gpiolen, disable_gpiolen, reset_gpiolen; 640 struct regmap *anatop, *gpr, *phy; 641 uint32_t off, reg; 642 int error, timo; 643 644 if (OF_is_compatible(sc->sc_node, "fsl,imx8mm-pcie")) { 645 anatop = regmap_bycompatible("fsl,imx8mm-anatop"); 646 gpr = regmap_bycompatible("fsl,imx8mm-iomuxc-gpr"); 647 phy = regmap_bycompatible("fsl,imx7d-pcie-phy"); 648 KASSERT(phy != NULL); 649 } else { 650 anatop = regmap_bycompatible("fsl,imx8mq-anatop"); 651 gpr = regmap_bycompatible("fsl,imx8mq-iomuxc-gpr"); 652 } 653 KASSERT(anatop != NULL); 654 KASSERT(gpr != NULL); 655 656 clkreq_gpiolen = OF_getproplen(sc->sc_node, "clkreq-gpio"); 657 disable_gpiolen = OF_getproplen(sc->sc_node, "disable-gpio"); 658 reset_gpiolen = OF_getproplen(sc->sc_node, "reset-gpio"); 659 660 if (clkreq_gpiolen > 0) { 661 clkreq_gpio = malloc(clkreq_gpiolen, M_TEMP, M_WAITOK); 662 OF_getpropintarray(sc->sc_node, "clkreq-gpio", clkreq_gpio, 663 clkreq_gpiolen); 664 gpio_controller_config_pin(clkreq_gpio, GPIO_CONFIG_OUTPUT); 665 gpio_controller_set_pin(clkreq_gpio, 1); 666 } 667 668 if (disable_gpiolen > 0) { 669 disable_gpio = malloc(disable_gpiolen, M_TEMP, M_WAITOK); 670 OF_getpropintarray(sc->sc_node, "disable-gpio", disable_gpio, 671 disable_gpiolen); 672 gpio_controller_config_pin(disable_gpio, GPIO_CONFIG_OUTPUT); 673 gpio_controller_set_pin(disable_gpio, 0); 674 } 675 676 if (reset_gpiolen > 0) { 677 reset_gpio = malloc(reset_gpiolen, M_TEMP, M_WAITOK); 678 OF_getpropintarray(sc->sc_node, "reset-gpio", reset_gpio, 679 reset_gpiolen); 680 gpio_controller_config_pin(reset_gpio, GPIO_CONFIG_OUTPUT); 681 gpio_controller_set_pin(reset_gpio, 1); 682 } 683 684 power_domain_enable(sc->sc_node); 685 reset_assert(sc->sc_node, "pciephy"); 686 reset_assert(sc->sc_node, "apps"); 687 688 reg = regmap_read_4(gpr, IOMUXC_GPR12); 689 if (OF_getpropint(sc->sc_node, "ctrl-id", 0) == 0) { 690 off = IOMUXC_GPR14; 691 reg &= ~IMX8MQ_GPR_PCIE1_DEVICE_TYPE_MASK; 692 reg |= IMX8MQ_GPR_PCIE1_DEVICE_TYPE_RC; 693 } else { 694 off = IOMUXC_GPR16; 695 reg &= ~IMX8MQ_GPR_PCIE2_DEVICE_TYPE_MASK; 696 reg |= IMX8MQ_GPR_PCIE2_DEVICE_TYPE_RC; 697 } 698 regmap_write_4(gpr, IOMUXC_GPR12, reg); 699 700 if (OF_is_compatible(sc->sc_node, "fsl,imx8mm-pcie")) { 701 if (OF_getproplen(sc->sc_node, "ext_osc") == 0 || 702 OF_getpropint(sc->sc_node, "ext_osc", 0)) { 703 reg = regmap_read_4(gpr, off); 704 reg &= ~(IMX8MQ_GPR_PCIE_REF_USE_PAD | 705 IMX8MM_GPR_PCIE_SSC_EN | 706 IMX8MM_GPR_PCIE_POWER_OFF | 707 IMX8MM_GPR_PCIE_REF_CLK_MASK); 708 reg |= (IMX8MM_GPR_PCIE_AUX_EN | 709 IMX8MM_GPR_PCIE_REF_CLK_EXT); 710 regmap_write_4(gpr, off, reg); 711 delay(100); 712 reg = regmap_read_4(gpr, off); 713 reg |= IMX8MM_GPR_PCIE_CMN_RST; 714 regmap_write_4(gpr, off, reg); 715 delay(200); 716 } else { 717 reg = regmap_read_4(gpr, off); 718 reg &= ~(IMX8MQ_GPR_PCIE_REF_USE_PAD | 719 IMX8MM_GPR_PCIE_SSC_EN | 720 IMX8MM_GPR_PCIE_POWER_OFF | 721 IMX8MM_GPR_PCIE_REF_CLK_MASK); 722 reg |= (IMX8MM_GPR_PCIE_AUX_EN | 723 IMX8MM_GPR_PCIE_REF_CLK_PLL); 724 regmap_write_4(gpr, off, reg); 725 delay(100); 726 regmap_write_4(phy, IMX8MM_PCIE_PHY_CMN_REG62, 727 IMX8MM_PCIE_PHY_CMN_REG62_PLL_CLK_OUT); 728 regmap_write_4(phy, IMX8MM_PCIE_PHY_CMN_REG64, 729 IMX8MM_PCIE_PHY_CMN_REG64_AUX_RX_TX_TERM); 730 reg = regmap_read_4(gpr, off); 731 reg |= IMX8MM_GPR_PCIE_CMN_RST; 732 regmap_write_4(gpr, off, reg); 733 delay(200); 734 regmap_write_4(phy, IMX8MM_PCIE_PHY_TRSV_REG5, 735 IMX8MM_PCIE_PHY_TRSV_REG5_GEN1_DEEMP); 736 regmap_write_4(phy, IMX8MM_PCIE_PHY_TRSV_REG6, 737 IMX8MM_PCIE_PHY_TRSV_REG6_GEN2_DEEMP); 738 } 739 } else { 740 if (OF_getproplen(sc->sc_node, "ext_osc") == 0 || 741 OF_getpropint(sc->sc_node, "ext_osc", 0)) { 742 reg = regmap_read_4(gpr, off); 743 reg |= IMX8MQ_GPR_PCIE_REF_USE_PAD; 744 regmap_write_4(gpr, off, reg); 745 } else { 746 reg = regmap_read_4(gpr, off); 747 reg &= ~IMX8MQ_GPR_PCIE_REF_USE_PAD; 748 regmap_write_4(gpr, off, reg); 749 750 regmap_write_4(anatop, ANATOP_PLLOUT_CTL, 751 ANATOP_PLLOUT_CTL_CKE | 752 ANATOP_PLLOUT_CTL_SEL_SYSPLL1); 753 regmap_write_4(anatop, ANATOP_PLLOUT_DIV, 754 ANATOP_PLLOUT_DIV_SYSPLL1); 755 } 756 } 757 758 clock_enable(sc->sc_node, "pcie_phy"); 759 clock_enable(sc->sc_node, "pcie_bus"); 760 clock_enable(sc->sc_node, "pcie"); 761 clock_enable(sc->sc_node, "pcie_aux"); 762 763 /* Allow clocks to stabilize. */ 764 delay(200); 765 766 if (reset_gpiolen > 0) { 767 gpio_controller_set_pin(reset_gpio, 1); 768 delay(100000); 769 gpio_controller_set_pin(reset_gpio, 0); 770 } 771 772 reset_deassert(sc->sc_node, "pciephy"); 773 774 if (OF_is_compatible(sc->sc_node, "fsl,imx8mm-pcie")) { 775 for (timo = 2000; timo > 0; timo--) { 776 if (regmap_read_4(phy, IMX8MM_PCIE_PHY_CMN_REG75) == 777 IMX8MM_PCIE_PHY_CMN_REG75_PLL_DONE) 778 break; 779 delay(10); 780 } 781 if (timo == 0) { 782 error = ETIMEDOUT; 783 goto err; 784 } 785 } 786 787 reg = HREAD4(sc, 0x100000 + PCIE_RC_LCR); 788 reg &= ~PCIE_RC_LCR_L1EL_MASK; 789 reg |= PCIE_RC_LCR_L1EL_64US; 790 HWRITE4(sc, 0x100000 + PCIE_RC_LCR, reg); 791 792 dwpcie_link_config(sc); 793 794 reg = HREAD4(sc, PCIE_RC_LCR); 795 reg &= ~PCIE_RC_LCR_MAX_LINK_SPEEDS_MASK; 796 reg |= PCIE_RC_LCR_MAX_LINK_SPEEDS_GEN1; 797 HWRITE4(sc, PCIE_RC_LCR, reg); 798 799 reset_deassert(sc->sc_node, "apps"); 800 801 for (timo = 20000; timo > 0; timo--) { 802 if (dwpcie_link_up(sc)) 803 break; 804 delay(10); 805 } 806 if (timo == 0) { 807 error = ETIMEDOUT; 808 goto err; 809 } 810 811 if (OF_getpropint(sc->sc_node, "fsl,max-link-speed", 1) >= 2) { 812 reg = HREAD4(sc, PCIE_RC_LCR); 813 reg &= ~PCIE_RC_LCR_MAX_LINK_SPEEDS_MASK; 814 reg |= PCIE_RC_LCR_MAX_LINK_SPEEDS_GEN2; 815 HWRITE4(sc, PCIE_RC_LCR, reg); 816 817 reg = HREAD4(sc, PCIE_LINK_WIDTH_SPEED_CTRL); 818 reg |= PCIE_LINK_WIDTH_SPEED_CTRL_CHANGE; 819 HWRITE4(sc, PCIE_LINK_WIDTH_SPEED_CTRL, reg); 820 821 for (timo = 20000; timo > 0; timo--) { 822 if (dwpcie_link_up(sc)) 823 break; 824 delay(10); 825 } 826 if (timo == 0) { 827 error = ETIMEDOUT; 828 goto err; 829 } 830 } 831 832 sc->sc_ih = fdt_intr_establish(sc->sc_node, IPL_AUDIO | IPL_MPSAFE, 833 dwpcie_imx8mq_intr, sc, sc->sc_dev.dv_xname); 834 835 /* Unmask INTx interrupts. */ 836 HWRITE4(sc, PCIE_GLOBAL_INT_MASK, 837 PCIE_GLOBAL_INT_MASK_INT_A | PCIE_GLOBAL_INT_MASK_INT_B | 838 PCIE_GLOBAL_INT_MASK_INT_C | PCIE_GLOBAL_INT_MASK_INT_D); 839 840 error = 0; 841 err: 842 if (clkreq_gpiolen > 0) 843 free(clkreq_gpio, M_TEMP, clkreq_gpiolen); 844 if (disable_gpiolen > 0) 845 free(disable_gpio, M_TEMP, disable_gpiolen); 846 if (reset_gpiolen > 0) 847 free(reset_gpio, M_TEMP, reset_gpiolen); 848 return error; 849 } 850 851 int 852 dwpcie_imx8mq_intr(void *arg) 853 { 854 struct dwpcie_softc *sc = arg; 855 uint32_t cause; 856 857 /* Acknowledge interrupts. */ 858 cause = HREAD4(sc, PCIE_GLOBAL_INT_CAUSE); 859 HWRITE4(sc, PCIE_GLOBAL_INT_CAUSE, cause); 860 861 /* INTx interrupt, so not really ours. */ 862 return 0; 863 } 864 865 void 866 dwpcie_atu_config(struct dwpcie_softc *sc, int index, int type, 867 uint64_t cpu_addr, uint64_t pci_addr, uint64_t size) 868 { 869 uint32_t reg, off; 870 int timo; 871 872 off = sc->sc_atu_base + IATU_OFFSET_UNROLL(index); 873 if (!sc->sc_atu_unroll) { 874 off = IATU_OFFSET_VIEWPORT; 875 HWRITE4(sc, IATU_VIEWPORT, index); 876 } 877 878 HWRITE4(sc, off + IATU_LWR_BASE_ADDR, cpu_addr); 879 HWRITE4(sc, off + IATU_UPPER_BASE_ADDR, cpu_addr >> 32); 880 HWRITE4(sc, off + IATU_LIMIT_ADDR, cpu_addr + size - 1); 881 HWRITE4(sc, off + IATU_LWR_TARGET_ADDR, pci_addr); 882 HWRITE4(sc, off + IATU_UPPER_TARGET_ADDR, pci_addr >> 32); 883 HWRITE4(sc, off + IATU_REGION_CTRL_1, type); 884 HWRITE4(sc, off + IATU_REGION_CTRL_2, IATU_REGION_CTRL_2_REGION_EN); 885 886 for (timo = 5; timo > 0; timo--) { 887 reg = HREAD4(sc, off + IATU_REGION_CTRL_2); 888 if (reg & IATU_REGION_CTRL_2_REGION_EN) 889 break; 890 delay(9000); 891 } 892 if (timo == 0) 893 printf("%s:%d: timeout\n", __func__, __LINE__); 894 } 895 896 int 897 dwpcie_link_up(struct dwpcie_softc *sc) 898 { 899 uint32_t reg; 900 901 reg = HREAD4(sc, PCIE_PHY_DEBUG_R1); 902 if ((reg & PCIE_PHY_DEBUG_R1_XMLH_LINK_UP) != 0 && 903 (reg & PCIE_PHY_DEBUG_R1_XMLH_LINK_IN_TRAINING) == 0) 904 return 1; 905 return 0; 906 } 907 908 void 909 dwpcie_attach_hook(struct device *parent, struct device *self, 910 struct pcibus_attach_args *pba) 911 { 912 } 913 914 int 915 dwpcie_bus_maxdevs(void *v, int bus) 916 { 917 struct dwpcie_softc *sc = v; 918 919 if (bus == sc->sc_bus || bus == sc->sc_bus + 1) 920 return 1; 921 return 32; 922 } 923 924 pcitag_t 925 dwpcie_make_tag(void *v, int bus, int device, int function) 926 { 927 return ((bus << 24) | (device << 19) | (function << 16)); 928 } 929 930 void 931 dwpcie_decompose_tag(void *v, pcitag_t tag, int *bp, int *dp, int *fp) 932 { 933 if (bp != NULL) 934 *bp = (tag >> 24) & 0xff; 935 if (dp != NULL) 936 *dp = (tag >> 19) & 0x1f; 937 if (fp != NULL) 938 *fp = (tag >> 16) & 0x7; 939 } 940 941 int 942 dwpcie_conf_size(void *v, pcitag_t tag) 943 { 944 return PCIE_CONFIG_SPACE_SIZE; 945 } 946 947 pcireg_t 948 dwpcie_conf_read(void *v, pcitag_t tag, int reg) 949 { 950 struct dwpcie_softc *sc = v; 951 int bus, dev, fn; 952 uint32_t ret; 953 954 dwpcie_decompose_tag(sc, tag, &bus, &dev, &fn); 955 if (bus == sc->sc_bus) { 956 KASSERT(dev == 0); 957 return HREAD4(sc, tag | reg); 958 } 959 960 if (bus == sc->sc_bus + 1) { 961 dwpcie_atu_config(sc, IATU_VIEWPORT_INDEX1, 962 IATU_REGION_CTRL_1_TYPE_CFG0, 963 sc->sc_cfg0_base, tag, sc->sc_cfg0_size); 964 ret = bus_space_read_4(sc->sc_iot, sc->sc_cfg0_ioh, reg); 965 } else { 966 dwpcie_atu_config(sc, IATU_VIEWPORT_INDEX1, 967 IATU_REGION_CTRL_1_TYPE_CFG1, 968 sc->sc_cfg1_base, tag, sc->sc_cfg1_size); 969 ret = bus_space_read_4(sc->sc_iot, sc->sc_cfg1_ioh, reg); 970 } 971 if (sc->sc_num_viewport <= 2) 972 dwpcie_atu_config(sc, IATU_VIEWPORT_INDEX1, 973 IATU_REGION_CTRL_1_TYPE_IO, sc->sc_io_base, 974 sc->sc_io_bus_addr, sc->sc_io_size); 975 976 return ret; 977 } 978 979 void 980 dwpcie_conf_write(void *v, pcitag_t tag, int reg, pcireg_t data) 981 { 982 struct dwpcie_softc *sc = v; 983 int bus, dev, fn; 984 985 dwpcie_decompose_tag(sc, tag, &bus, &dev, &fn); 986 if (bus == sc->sc_bus) { 987 KASSERT(dev == 0); 988 HWRITE4(sc, tag | reg, data); 989 return; 990 } 991 992 if (bus == sc->sc_bus + 1) { 993 dwpcie_atu_config(sc, IATU_VIEWPORT_INDEX1, 994 IATU_REGION_CTRL_1_TYPE_CFG0, 995 sc->sc_cfg0_base, tag, sc->sc_cfg0_size); 996 bus_space_write_4(sc->sc_iot, sc->sc_cfg0_ioh, reg, data); 997 } else { 998 dwpcie_atu_config(sc, IATU_VIEWPORT_INDEX1, 999 IATU_REGION_CTRL_1_TYPE_CFG1, 1000 sc->sc_cfg1_base, tag, sc->sc_cfg1_size); 1001 bus_space_write_4(sc->sc_iot, sc->sc_cfg1_ioh, reg, data); 1002 } 1003 if (sc->sc_num_viewport <= 2) 1004 dwpcie_atu_config(sc, IATU_VIEWPORT_INDEX1, 1005 IATU_REGION_CTRL_1_TYPE_IO, sc->sc_io_base, 1006 sc->sc_io_bus_addr, sc->sc_io_size); 1007 } 1008 1009 int 1010 dwpcie_intr_map(struct pci_attach_args *pa, pci_intr_handle_t *ihp) 1011 { 1012 int pin = pa->pa_rawintrpin; 1013 1014 if (pin == 0 || pin > PCI_INTERRUPT_PIN_MAX) 1015 return -1; 1016 1017 if (pa->pa_tag == 0) 1018 return -1; 1019 1020 ihp->ih_pc = pa->pa_pc; 1021 ihp->ih_tag = pa->pa_intrtag; 1022 ihp->ih_intrpin = pa->pa_intrpin; 1023 ihp->ih_type = PCI_INTX; 1024 1025 return 0; 1026 } 1027 1028 const char * 1029 dwpcie_intr_string(void *v, pci_intr_handle_t ih) 1030 { 1031 switch (ih.ih_type) { 1032 case PCI_MSI: 1033 return "msi"; 1034 case PCI_MSIX: 1035 return "msix"; 1036 } 1037 1038 return "intx"; 1039 } 1040 1041 void * 1042 dwpcie_intr_establish(void *v, pci_intr_handle_t ih, int level, 1043 struct cpu_info *ci, int (*func)(void *), void *arg, char *name) 1044 { 1045 struct dwpcie_softc *sc = v; 1046 void *cookie; 1047 1048 KASSERT(ih.ih_type != PCI_NONE); 1049 1050 if (ih.ih_type != PCI_INTX) { 1051 uint64_t addr, data; 1052 1053 /* Assume hardware passes Requester ID as sideband data. */ 1054 data = pci_requester_id(ih.ih_pc, ih.ih_tag); 1055 cookie = fdt_intr_establish_msi_cpu(sc->sc_node, &addr, 1056 &data, level, ci, func, arg, (void *)name); 1057 if (cookie == NULL) 1058 return NULL; 1059 1060 /* TODO: translate address to the PCI device's view */ 1061 1062 if (ih.ih_type == PCI_MSIX) { 1063 pci_msix_enable(ih.ih_pc, ih.ih_tag, 1064 &sc->sc_bus_memt, ih.ih_intrpin, addr, data); 1065 } else 1066 pci_msi_enable(ih.ih_pc, ih.ih_tag, addr, data); 1067 } else { 1068 int bus, dev, fn; 1069 uint32_t reg[4]; 1070 1071 dwpcie_decompose_tag(sc, ih.ih_tag, &bus, &dev, &fn); 1072 1073 reg[0] = bus << 16 | dev << 11 | fn << 8; 1074 reg[1] = reg[2] = 0; 1075 reg[3] = ih.ih_intrpin; 1076 1077 cookie = fdt_intr_establish_imap_cpu(sc->sc_node, reg, 1078 sizeof(reg), level, ci, func, arg, name); 1079 } 1080 1081 return cookie; 1082 } 1083 1084 void 1085 dwpcie_intr_disestablish(void *v, void *cookie) 1086 { 1087 panic("%s", __func__); 1088 } 1089 1090 int 1091 dwpcie_bs_iomap(bus_space_tag_t t, bus_addr_t addr, bus_size_t size, 1092 int flags, bus_space_handle_t *bshp) 1093 { 1094 struct dwpcie_softc *sc = t->bus_private; 1095 int i; 1096 1097 for (i = 0; i < sc->sc_nranges; i++) { 1098 uint64_t pci_start = sc->sc_ranges[i].pci_base; 1099 uint64_t pci_end = pci_start + sc->sc_ranges[i].size; 1100 uint64_t phys_start = sc->sc_ranges[i].phys_base; 1101 1102 if ((sc->sc_ranges[i].flags & 0x03000000) == 0x01000000 && 1103 addr >= pci_start && addr + size <= pci_end) { 1104 return bus_space_map(sc->sc_iot, 1105 addr - pci_start + phys_start, size, flags, bshp); 1106 } 1107 } 1108 1109 return ENXIO; 1110 } 1111 1112 int 1113 dwpcie_bs_memmap(bus_space_tag_t t, bus_addr_t addr, bus_size_t size, 1114 int flags, bus_space_handle_t *bshp) 1115 { 1116 struct dwpcie_softc *sc = t->bus_private; 1117 int i; 1118 1119 for (i = 0; i < sc->sc_nranges; i++) { 1120 uint64_t pci_start = sc->sc_ranges[i].pci_base; 1121 uint64_t pci_end = pci_start + sc->sc_ranges[i].size; 1122 uint64_t phys_start = sc->sc_ranges[i].phys_base; 1123 1124 if ((sc->sc_ranges[i].flags & 0x03000000) == 0x02000000 && 1125 addr >= pci_start && addr + size <= pci_end) { 1126 return bus_space_map(sc->sc_iot, 1127 addr - pci_start + phys_start, size, flags, bshp); 1128 } 1129 } 1130 1131 return ENXIO; 1132 } 1133