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