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