1 /* $NetBSD: jh7110_pcie.c,v 1.3 2026/09/20 11:00:33 skrll Exp $ */ 2 3 /*- 4 * Copyright (c) 2024 The NetBSD Foundation, Inc. 5 * All rights reserved. 6 * 7 * This code is derived from software contributed to The NetBSD Foundation 8 * by Nick Hudson 9 * 10 * Redistribution and use in source and binary forms, with or without 11 * modification, are permitted provided that the following conditions 12 * are met: 13 * 1. Redistributions of source code must retain the above copyright 14 * notice, this list of conditions and the following disclaimer. 15 * 2. Redistributions in binary form must reproduce the above copyright 16 * notice, this list of conditions and the following disclaimer in the 17 * documentation and/or other materials provided with the distribution. 18 * 19 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 20 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 21 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 23 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 29 * POSSIBILITY OF SUCH DAMAGE. 30 */ 31 32 #include <sys/cdefs.h> 33 __KERNEL_RCSID(0, "$NetBSD: jh7110_pcie.c,v 1.3 2026/09/20 11:00:33 skrll Exp $"); 34 35 #include <sys/param.h> 36 37 #include <sys/bitops.h> 38 #include <sys/kmem.h> 39 40 #include <dev/pci/pcivar.h> 41 #include <dev/pci/pciconf.h> 42 43 #include <dev/fdt/fdtvar.h> 44 #include <dev/fdt/pcihost_fdtvar.h> 45 #include <dev/fdt/syscon.h> 46 47 struct jh7110_pcie_irq { 48 struct jh7110_pcie_softc * 49 jpi_sc; 50 void *jpi_arg; 51 int (*jpi_fn)(void *); 52 int jpi_mpsafe; 53 }; 54 55 struct jh7110_pcie_softc { 56 bus_space_tag_t sc_bst; 57 58 struct pcihost_softc sc_phsc; 59 60 bus_space_handle_t sc_apb_bsh; 61 bus_addr_t sc_apb_addr; 62 bus_size_t sc_apb_size; 63 64 bus_space_handle_t sc_cfg_bsh; 65 bus_addr_t sc_cfg_addr; 66 bus_size_t sc_cfg_size; 67 68 // syscon 69 const struct syscon * sc_syscon; 70 bus_size_t sc_stg_base; 71 72 struct fdtbus_gpio_pin *sc_perst_gpio; 73 74 // # pins 75 struct jh7110_pcie_irq *sc_irq[PCI_INTERRUPT_PIN_MAX]; 76 }; 77 78 #define RD4(sc, reg) \ 79 bus_space_read_4((sc)->sc_bst, (sc)->sc_apb_bsh, (reg)) 80 #define WR4(sc, reg, val) \ 81 bus_space_write_4((sc)->sc_bst, (sc)->sc_apb_bsh, (reg), (val)) 82 83 #define SET4(sc, off, mask) \ 84 WR4((sc), (off), RD4((sc), (off)) | (mask)) 85 #define CLR4(sc, off, mask) \ 86 WR4((sc), (off), RD4((sc), (off)) & ~(mask)) 87 #define UPD4(sc, off, clr, set) \ 88 WR4((sc), (off), (RD4((sc), (off)) & ~(clr)) | (set)) 89 90 #define JH7110_PCIE0_CFG_BASE 0x940000000UL 91 #define JH7110_PCIE1_CFG_BASE 0x9c0000000UL 92 93 /* PLDA register definitions */ 94 #define PLDA_GEN_SETTINGS 0x80 95 #define PLDA_GEN_RP_ENABLE 1 96 #define PLDA_PCI_IDS 0x9c 97 #define PLDA_PCI_IDS_REVISION_MASK __BITS( 7, 0) 98 #define PLDA_PCI_IDS_CLASSCODE_MASK __BITS(31, 8) 99 #define PLDA_MISC 0xb4 100 #define PLDA_MISC_PHYFUNC_DISABLE __BIT(15) 101 #define PLDA_WINROM 0xfc 102 #define PLDA_WINROM_PREF64SUPPORT __BIT(3) 103 104 #define PLDA_IMASK_LOCAL 0x180 105 #define PLDA_IMASK_INT_INTA __BIT(24) 106 #define PLDA_IMASK_INT_INTB __BIT(25) 107 #define PLDA_IMASK_INT_INTC __BIT(26) 108 #define PLDA_IMASK_INT_INTD __BIT(27) 109 #define PLDA_IMASK_INT_INTX __BITS(27, 24) 110 #define PLDA_IMASK_INT_MSI __BIT(28) 111 #define PLDA_ISTATUS_LOCAL 0x184 112 #define PLDA_ISTATUS_INT_INTA __BIT(24) 113 #define PLDA_ISTATUS_INT_INTB __BIT(25) 114 #define PLDA_ISTATUS_INT_INTC __BIT(26) 115 #define PLDA_ISTATUS_INT_INTD __BIT(27) 116 #define PLDA_ISTATUS_INT_INTX __BITS(27, 24) 117 #define PLDA_ISTATUS_INT_MSI __BIT(28) 118 #define PLDA_IMASK_HOST 0x188 119 #define PLDA_ISTATUS_HOST 0x18c 120 #define PLDA_IMSI_ADDR 0x190 121 #define PLDA_ISTATUS_MSI 0x194 122 #define PLDA_PMSG_SUPPORT_RX 0x3f0 123 #define PLDA_PMSG_LTR_SUPPORT __BIT(2) 124 125 /* PCIe Master table init defines */ 126 #define PLDA_ATR0_PCIE_WIN0_SRCADDR_PARAM 0x600 127 #define PLDA_ATR0_PCIE_ATR_SIZE 0x25 128 #define PLDA_ATR0_PCIE_ATR_SIZE_SHIFT 1 129 #define PLDA_ATR0_PCIE_WIN0_SRC_ADDR 0x604 130 #define PLDA_ATR0_PCIE_WIN0_TRSL_ADDR_LSB 0x608 131 #define PLDA_ATR0_PCIE_WIN0_TRSL_ADDR_UDW 0x60c 132 #define PLDA_ATR0_PCIE_WIN0_TRSL_PARAM 0x610 133 134 #define PLDA_ATR_AXI4_SLV0_SRC_ADDR_LO(n) (0x800 + (n) * 0x20) 135 #define PLDA_ATR_SIZE_SRC_MASK __BITS(31, 12) 136 #define PLDA_ATR_SIZE_MASK __BITS(6, 1) 137 #define PLDA_ATR_IMPL __BIT(0) 138 #define PLDA_ATR_AXI4_SLV0_SRC_ADDR_HI(n) (0x804 + (n) * 0x20) 139 #define PLDA_ATR_AXI4_SLV0_TRSL_ADDR_LO(n) (0x808 + (n) * 0x20) 140 #define PLDA_ATR_AXI4_SLV0_TRSL_ADDR_HI(n) (0x80c + (n) * 0x20) 141 #define PLDA_ATR_AXI4_SLV0_TRSL_PARAM(n) (0x810 + (n) * 0x20) 142 #define PLDA_TRSL_ID_PCIE_RX_TX 0 143 #define PLDA_TRSL_ID_PCIE_CONFIG 1 144 145 #define PCIE_FUNC_NUM 4 146 147 /* system control */ 148 #define STG_SYSCON_PCIE0_BASE 0x0048 149 #define STG_SYSCON_PCIE1_BASE 0x01f8 150 151 #define STG_SYSCON_AR_OFFSET 0x0078 152 #define STG_SYSCON_AXI4_SLVL_AR_MASK __BITS(22, 8) 153 #define STG_SYSCON_AXI4_SLVL_PHY_AR_MASK __BITS(20,17) 154 #define STG_SYSCON_AXI4_SLVL_PHY_AR(x) \ 155 __SHIFTIN((x), STG_SYSCON_AXI4_SLVL_PHY_AR_MASK) 156 157 #define STG_SYSCON_AW_OFFSET 0x007c 158 #define STG_SYSCON_CLKREQ __BIT(22) 159 #define STG_SYSCON_CKREF_SRC_MASK __BITS(19, 18) 160 #define STG_SYSCON_AXI4_SLVL_AW_MASK __BITS(14, 0) 161 #define STG_SYSCON_AXI4_SLVL_PHY_AW_MASK __BITS(12, 9) 162 #define STG_SYSCON_AXI4_SLVL_PHY_AW(x) \ 163 __SHIFTIN((x), STG_SYSCON_AXI4_SLVL_PHY_AW_MASK) 164 165 #define STG_SYSCON_RP_NEP_OFFSET 0x00e8 166 #define STG_SYSCON_K_RP_NEP __BIT(8) 167 168 #define STG_SYSCON_LNKSTA_OFFSET 0x0170 169 #define DATA_LINK_ACTIVE __BIT(5) 170 171 #define ECAM_BUS_MASK __BITS(27, 20) 172 #define ECAM_DEV_MASK __BITS(19, 15) 173 #define ECAM_FUNC_MASK __BITS(14, 12) 174 #define ECAM_OFFSET_MASK __BITS(11, 0) 175 176 static int 177 jh7110_pcie_bus_maxdevs(void *v, int bus) 178 { 179 struct pcihost_softc * const phsc = v; 180 181 if (bus >= phsc->sc_bus_min || bus <= phsc->sc_bus_max) 182 return 1; 183 return 0; 184 } 185 186 static pcitag_t 187 jh7110_pcie_make_tag(void *v, int bus, int dev, int fn) 188 { 189 // struct pcihost_softc * const phsc = v; 190 191 /* Return ECAM address. */ 192 return 193 __SHIFTIN(bus, ECAM_BUS_MASK) | 194 __SHIFTIN(dev, ECAM_DEV_MASK) | 195 __SHIFTIN(fn, ECAM_FUNC_MASK) | 196 0; 197 } 198 199 static void 200 jh7110_pcie_decompose_tag(void *v, pcitag_t tag, 201 int *busp, int *devp, int *fnp) 202 { 203 // struct pcihost_softc * const phsc = v; 204 205 if (busp != NULL) 206 *busp = __SHIFTOUT(tag, ECAM_BUS_MASK); 207 if (devp != NULL) 208 *devp = __SHIFTOUT(tag, ECAM_DEV_MASK); 209 if (fnp != NULL) 210 *fnp = __SHIFTOUT(tag, ECAM_FUNC_MASK); 211 } 212 213 static bool 214 jh7110_pcie_conf_ok(struct jh7110_pcie_softc *sc, 215 int bus, int dev, int fn, int offset) 216 { 217 218 /* Only one device on root port and the first subordinate port. */ 219 if (bus < 2 && dev < 1) 220 return true; 221 222 return false; 223 } 224 225 static pcireg_t 226 jh7110_pcie_conf_read(void *v, pcitag_t tag, int offset) 227 { 228 struct pcihost_softc * const phsc = v; 229 struct jh7110_pcie_softc * const sc = 230 container_of(phsc, struct jh7110_pcie_softc, sc_phsc); 231 int bus, dev, fn; 232 233 KASSERT(offset >= 0); 234 KASSERT(offset < PCI_EXTCONF_SIZE); 235 236 jh7110_pcie_decompose_tag(phsc, tag, &bus, &dev, &fn); 237 238 if (!jh7110_pcie_conf_ok(sc, bus, dev, fn, offset)) 239 return 0xffffffff; 240 241 bus_size_t reg = 242 __SHIFTIN(bus, ECAM_BUS_MASK) | 243 __SHIFTIN(dev, ECAM_DEV_MASK) | 244 __SHIFTIN(fn, ECAM_FUNC_MASK) | 245 offset; 246 247 return bus_space_read_4(sc->sc_bst, sc->sc_cfg_bsh, reg); 248 } 249 250 static void 251 jh7110_pcie_conf_write(void *v, pcitag_t tag, int offset, pcireg_t data) 252 { 253 struct pcihost_softc * const phsc = v; 254 struct jh7110_pcie_softc * const sc = 255 container_of(phsc, struct jh7110_pcie_softc, sc_phsc); 256 int bus, dev, fn; 257 258 KASSERT(offset >= 0); 259 KASSERT(offset < PCI_EXTCONF_SIZE); 260 261 jh7110_pcie_decompose_tag(phsc, tag, &bus, &dev, &fn); 262 263 if (!jh7110_pcie_conf_ok(sc, bus, dev, fn, offset)) 264 return; 265 266 bus_size_t reg = 267 __SHIFTIN(bus, ECAM_BUS_MASK) | 268 __SHIFTIN(dev, ECAM_DEV_MASK) | 269 __SHIFTIN(fn, ECAM_FUNC_MASK) | 270 offset; 271 272 bus_space_write_4(sc->sc_bst, sc->sc_cfg_bsh, reg, data); 273 } 274 275 /* INTx interrupt controller */ 276 static void * 277 jh7110_pcie_intx_establish(device_t dev, u_int *specifier, int ipl, int flags, 278 int (*func)(void *), void *arg, const char *xname) 279 { 280 struct jh7110_pcie_softc * const sc = device_private(dev); 281 const u_int mpsafe = (flags & FDT_INTR_MPSAFE) ? IST_MPSAFE : 0; 282 const u_int pin = be32toh(specifier[0]) - 1; 283 284 KASSERT((RD4(sc, PLDA_IMASK_LOCAL) & (PLDA_IMASK_INT_INTA << pin)) == 0); 285 286 struct jh7110_pcie_irq *jpi = sc->sc_irq[pin]; 287 if (jpi == NULL) { 288 jpi = kmem_alloc(sizeof(*jpi), KM_SLEEP); 289 jpi->jpi_sc = sc; 290 jpi->jpi_fn = func; 291 jpi->jpi_arg = arg; 292 jpi->jpi_mpsafe = mpsafe; 293 294 sc->sc_irq[pin] = jpi; 295 } else { 296 device_printf(dev, "shared interrupts not supported\n"); 297 return NULL; 298 } 299 300 /* Unmask the interrupt. */ 301 SET4(sc, PLDA_IMASK_LOCAL, (PLDA_IMASK_INT_INTA << pin)); 302 303 return jpi; 304 } 305 306 307 static void 308 jh7110_pcie_intx_disestablish(device_t dev, void *ih) 309 { 310 struct jh7110_pcie_softc * const sc = device_private(dev); 311 struct pcihost_softc * const phsc = &sc->sc_phsc; 312 313 device_printf(dev, "%s\n", __func__); 314 315 fdtbus_intr_disestablish(phsc->sc_phandle, ih); 316 } 317 318 static bool 319 jh7110_pcie_intx_string(device_t dev, u_int *specifier, char *buf, 320 size_t buflen) 321 { 322 struct jh7110_pcie_softc * const sc = device_private(dev); 323 struct pcihost_softc * const phsc = &sc->sc_phsc; 324 325 fdtbus_intr_str(phsc->sc_phandle, 0, buf, buflen); 326 327 return true; 328 } 329 330 static int 331 jh7110_pcie_intx_intr(struct jh7110_pcie_softc *sc, uint32_t status) 332 { 333 int handled = 0; 334 u_int pin; 335 336 CTASSERT(__arraycount(sc->sc_irq) == 4); 337 for (pin = 0; pin < __arraycount(sc->sc_irq); pin++) { 338 if ((status & (PLDA_IMASK_INT_INTA << pin)) == 0) 339 continue; 340 341 struct jh7110_pcie_irq *jpi = sc->sc_irq[pin]; 342 343 if (jpi == NULL) 344 continue; 345 346 if (!jpi->jpi_mpsafe) 347 KERNEL_LOCK(1, NULL); 348 handled |= jpi->jpi_fn(jpi->jpi_arg); 349 if (!jpi->jpi_mpsafe) 350 KERNEL_UNLOCK_ONE(NULL); 351 } 352 353 return handled; 354 } 355 356 357 static int 358 jh7110_pcie_intr(void *v) 359 { 360 struct jh7110_pcie_softc * const sc = v; 361 int handled = 0; 362 363 uint32_t status = RD4(sc, PLDA_ISTATUS_LOCAL); 364 if (status == 0) 365 return 0; 366 367 if (status & PLDA_ISTATUS_INT_INTX) 368 handled |= jh7110_pcie_intx_intr(sc, status); 369 370 WR4(sc, PLDA_ISTATUS_LOCAL, status); 371 372 return handled; 373 } 374 375 static struct fdtbus_interrupt_controller_func jh7110_pcie_intxfuncs = { 376 .establish = jh7110_pcie_intx_establish, 377 .disestablish = jh7110_pcie_intx_disestablish, 378 .intrstr = jh7110_pcie_intx_string, 379 }; 380 381 #define SCRD4(sc, off) syscon_read_4((sc), (off)) 382 #define SCWR4(sc, off, val) syscon_write_4((sc), (off), (val)) 383 384 #define SCSET4(sc, off, mask) \ 385 SCWR4((sc), (off), SCRD4((sc), (off)) | (mask)) 386 #define SCCLR4(sc, off, mask) \ 387 SCWR4((sc), (off), SCRD4((sc), (off)) & ~(mask)) 388 #define SCUPD4(sc, off, clr, set) \ 389 SCWR4((sc), (off), (SCRD4((sc), (off)) & ~(clr)) | (set)) 390 391 392 static int 393 jh7110_pcie_host_init(struct jh7110_pcie_softc *sc) 394 { 395 struct pcihost_softc * const phsc = &sc->sc_phsc; 396 397 syscon_lock(sc->sc_syscon); 398 SCSET4(sc->sc_syscon, sc->sc_stg_base + STG_SYSCON_RP_NEP_OFFSET, 399 STG_SYSCON_K_RP_NEP); 400 401 SCUPD4(sc->sc_syscon, sc->sc_stg_base + STG_SYSCON_AW_OFFSET, 402 STG_SYSCON_CKREF_SRC_MASK, 403 __SHIFTIN(2, STG_SYSCON_CKREF_SRC_MASK)); 404 405 SCSET4(sc->sc_syscon, sc->sc_stg_base + STG_SYSCON_AW_OFFSET, 406 STG_SYSCON_CLKREQ); 407 408 /* enable clocks */ 409 struct clk *clk; 410 fdtbus_clock_assign(phsc->sc_phandle); 411 for (u_int c = 0; 412 (clk = fdtbus_clock_get_index(phsc->sc_phandle, c)) != NULL; 413 c++) { 414 if (clk_enable(clk) != 0) { 415 aprint_error_dev(phsc->sc_dev, 416 "couldn't enable clock #%d\n", c); 417 return ENXIO; 418 } 419 } 420 /* de-assert resets */ 421 struct fdtbus_reset *rst; 422 for (u_int r = 0; 423 (rst = fdtbus_reset_get_index(phsc->sc_phandle, r)) != NULL; 424 r++) { 425 if (fdtbus_reset_deassert(rst) != 0) { 426 aprint_error_dev(phsc->sc_dev, 427 "couldn't de-assert reset #%d\n", r); 428 return ENXIO; 429 } 430 } 431 432 fdtbus_gpio_write(sc->sc_perst_gpio, 1); 433 434 /* Disable additional functions. */ 435 for (u_int i = 1; i < PCIE_FUNC_NUM; i++) { 436 437 SCUPD4(sc->sc_syscon, sc->sc_stg_base + STG_SYSCON_AR_OFFSET, 438 STG_SYSCON_AXI4_SLVL_AR_MASK, 439 __SHIFTIN(i, STG_SYSCON_AXI4_SLVL_PHY_AR_MASK)); 440 441 SCUPD4(sc->sc_syscon, sc->sc_stg_base + STG_SYSCON_AW_OFFSET, 442 STG_SYSCON_AXI4_SLVL_AW_MASK, 443 __SHIFTIN(i, STG_SYSCON_AXI4_SLVL_PHY_AW_MASK)); 444 445 SET4(sc, PLDA_MISC, PLDA_MISC_PHYFUNC_DISABLE); 446 } 447 448 SCCLR4(sc->sc_syscon, sc->sc_stg_base + STG_SYSCON_AR_OFFSET, 449 STG_SYSCON_AXI4_SLVL_AR_MASK); 450 451 SCCLR4(sc->sc_syscon, sc->sc_stg_base + STG_SYSCON_AW_OFFSET, 452 STG_SYSCON_AXI4_SLVL_AW_MASK); 453 454 /* Configure controller as root port. */ 455 UPD4(sc, PLDA_GEN_SETTINGS, PLDA_GEN_RP_ENABLE, PLDA_GEN_RP_ENABLE); 456 uint64_t base_addr = 0; 457 458 #define CONFIG_SPACE_ADDR_OFFSET 0x1000 459 460 SET4(sc, CONFIG_SPACE_ADDR_OFFSET + 0x10, BUS_ADDR_LO32(base_addr)); 461 SET4(sc, CONFIG_SPACE_ADDR_OFFSET + 0x14, BUS_ADDR_HI32(base_addr)); 462 463 /* Configure as PCI bridge. */ 464 UPD4(sc, PLDA_PCI_IDS, 465 PLDA_PCI_IDS_CLASSCODE_MASK, 466 PCI_CLASS_CODE(PCI_CLASS_BRIDGE, 467 PCI_SUBCLASS_BRIDGE_PCI, 468 PCI_INTERFACE_BRIDGE_PCI_PCI)); 469 470 /* Enable prefetchable memory windows. */ 471 SET4(sc, PLDA_WINROM, PLDA_WINROM_PREF64SUPPORT); 472 473 /* Disable LTR message forwarding. */ 474 CLR4(sc, PLDA_PMSG_SUPPORT_RX, PLDA_PMSG_LTR_SUPPORT); 475 476 /* 477 * PERST# must remain asserted for at least 100us after the 478 * reference clock becomes stable. But also has to remain 479 * active at least 100ms after power up. Since we may have 480 * just powered on the device, play it safe and use 100ms. 481 */ 482 delay(100 * 1000); 483 484 /* Deassert PERST#. */ 485 fdtbus_gpio_write(sc->sc_perst_gpio, 0); 486 487 /* Wait for link to come up. */ 488 uint32_t reg; 489 for (int timo = 100; timo > 0; timo--) { 490 reg = SCRD4(sc->sc_syscon, 491 sc->sc_stg_base + STG_SYSCON_LNKSTA_OFFSET); 492 if (reg & DATA_LINK_ACTIVE) 493 break; 494 delay(1000); 495 } 496 497 syscon_unlock(sc->sc_syscon); 498 499 if ((reg & DATA_LINK_ACTIVE) == 0) { 500 aprint_error_dev(phsc->sc_dev, "link not up\n"); 501 return ENXIO; 502 } 503 504 return 0; 505 } 506 507 static int 508 jh7110_pcie_atr_init(struct jh7110_pcie_softc *sc) 509 { 510 const uint32_t *ranges; 511 bus_addr_t phyaddr; // PADDR? 512 bus_addr_t pciaddr; 513 bus_size_t size; 514 515 WR4(sc, PLDA_ATR_AXI4_SLV0_SRC_ADDR_LO(0), 516 PLDA_ATR_IMPL | 517 __SHIFTIN(ilog2(sc->sc_cfg_size) - 1, PLDA_ATR_SIZE_MASK) | 518 BUS_ADDR_LO32(sc->sc_cfg_addr)); 519 WR4(sc, PLDA_ATR_AXI4_SLV0_SRC_ADDR_HI(0), BUS_ADDR_HI32(sc->sc_cfg_addr)); 520 WR4(sc, PLDA_ATR_AXI4_SLV0_TRSL_ADDR_LO(0), 0); 521 WR4(sc, PLDA_ATR_AXI4_SLV0_TRSL_ADDR_HI(0), 0); 522 WR4(sc, PLDA_ATR_AXI4_SLV0_TRSL_PARAM(0), PLDA_TRSL_ID_PCIE_CONFIG); 523 524 struct pcihost_softc * const phsc = &sc->sc_phsc; 525 int ranges_len; 526 ranges = fdtbus_get_prop(phsc->sc_phandle, "ranges", &ranges_len); 527 if (ranges == NULL) { 528 aprint_error_dev(phsc->sc_dev, 529 "couldn't find 'ranges' property\n"); 530 return ENXIO; 531 } 532 const int ranges_cells = ranges_len / sizeof(uint32_t); 533 534 for (u_int i = 0, n = 1; i < ranges_cells && n < 8; i += 7, n++) { 535 pciaddr = 536 __SHIFTIN(be32toh(ranges[i + 1]), __BITS(63, 32)) | 537 __SHIFTIN(be32toh(ranges[i + 2]), __BITS(31, 0)); 538 phyaddr = 539 __SHIFTIN(be32toh(ranges[i + 3]), __BITS(63, 32)) | 540 __SHIFTIN(be32toh(ranges[i + 4]), __BITS(31, 0)); 541 size = be32toh(ranges[i + 6]); 542 543 WR4(sc, PLDA_ATR_AXI4_SLV0_SRC_ADDR_LO(n), 544 PLDA_ATR_IMPL | 545 __SHIFTIN(ilog2(size) /* - 1 */, PLDA_ATR_SIZE_MASK) | 546 BUS_ADDR_LO32(phyaddr)); 547 WR4(sc, PLDA_ATR_AXI4_SLV0_SRC_ADDR_HI(n), BUS_ADDR_HI32(phyaddr)); 548 WR4(sc, PLDA_ATR_AXI4_SLV0_TRSL_ADDR_LO(n), BUS_ADDR_LO32(pciaddr)); 549 WR4(sc, PLDA_ATR_AXI4_SLV0_TRSL_ADDR_HI(n), BUS_ADDR_HI32(pciaddr)); 550 WR4(sc, PLDA_ATR_AXI4_SLV0_TRSL_PARAM(n), PLDA_TRSL_ID_PCIE_RX_TX); 551 } 552 553 uint32_t val; 554 val = RD4(sc, PLDA_ATR0_PCIE_WIN0_SRCADDR_PARAM); 555 val |= (PLDA_ATR0_PCIE_ATR_SIZE << PLDA_ATR0_PCIE_ATR_SIZE_SHIFT); 556 WR4(sc, PLDA_ATR0_PCIE_WIN0_SRCADDR_PARAM, val); 557 WR4(sc, PLDA_ATR0_PCIE_WIN0_SRC_ADDR, 0); 558 559 return 0; 560 } 561 562 /* Compat string(s) */ 563 static const struct device_compatible_entry compat_data[] = { 564 { .compat = "starfive,jh7110-pcie" }, 565 DEVICE_COMPAT_EOL 566 }; 567 568 569 static int 570 jh7110_pcie_match(device_t parent, cfdata_t cf, void *aux) 571 { 572 struct fdt_attach_args * const faa = aux; 573 574 return of_compatible_match(faa->faa_phandle, compat_data); 575 } 576 577 static void 578 jh7110_pcie_attach(device_t parent, device_t self, void *aux) 579 { 580 struct jh7110_pcie_softc * const sc = device_private(self); 581 struct pcihost_softc * const phsc = &sc->sc_phsc; 582 struct fdt_attach_args * const faa = aux; 583 const int phandle = faa->faa_phandle; 584 int error; 585 586 sc->sc_bst = faa->faa_bst; 587 588 phsc->sc_dev = self; 589 phsc->sc_bst = faa->faa_bst; 590 phsc->sc_pci_bst = faa->faa_bst; 591 phsc->sc_dmat = faa->faa_dmat; 592 phsc->sc_phandle = faa->faa_phandle; 593 594 /* Handle old and new binding names. */ 595 if (fdtbus_get_reg_byname(phandle, "apb", 596 &sc->sc_apb_addr, &sc->sc_apb_size) != 0) { 597 aprint_error(": couldn't get apb registers\n"); 598 return; 599 } 600 if (fdtbus_get_reg_byname(phandle, "cfg", 601 &sc->sc_cfg_addr, &sc->sc_cfg_size) != 0) { 602 aprint_error(": couldn't get cfg registers\n"); 603 return; 604 } 605 606 const int mapflags = 0 /*BUS_SPACE_MAP_NONPOSTED*/; 607 error = bus_space_map(sc->sc_bst, sc->sc_apb_addr, 608 sc->sc_apb_size, mapflags, &sc->sc_apb_bsh); 609 if (error) { 610 aprint_error(": can't map APB registers\n"); 611 return; 612 } 613 error = bus_space_map(sc->sc_bst, sc->sc_cfg_addr, 614 sc->sc_cfg_size, mapflags, &sc->sc_cfg_bsh); 615 if (error) { 616 aprint_error(": can't map CFG registers\n"); 617 return; 618 } 619 int len; 620 const char *stgsyscon = "starfive,stg-syscon"; 621 const u_int *stgsyscon_data = 622 fdtbus_get_prop(phandle, stgsyscon, &len); 623 if (stgsyscon_data == NULL) { 624 aprint_error(": couldn't get '%s' property\n", stgsyscon); 625 return; 626 } 627 628 if (len != 1 * sizeof(uint32_t)) { 629 aprint_error(": incorrect '%s' data (len = %u)\n", stgsyscon, 630 len); 631 return; 632 } 633 int syscon_phandle = 634 fdtbus_get_phandle_from_native(be32dec(&stgsyscon_data[0])); 635 636 sc->sc_syscon = fdtbus_syscon_lookup(syscon_phandle); 637 if (sc->sc_syscon == NULL) { 638 aprint_error(": couldn't get '%s' (%d)\n", stgsyscon, 639 syscon_phandle); 640 return; 641 } 642 643 sc->sc_perst_gpio = fdtbus_gpio_acquire(phandle, 644 "perst-gpios", GPIO_PIN_OUTPUT); 645 if (sc->sc_perst_gpio == NULL) { 646 aprint_error(": couldn't get 'perst-gpios'"); 647 return; 648 } 649 650 switch (sc->sc_cfg_addr) { 651 case JH7110_PCIE0_CFG_BASE: 652 sc->sc_stg_base = STG_SYSCON_PCIE0_BASE; 653 break; 654 case JH7110_PCIE1_CFG_BASE: 655 sc->sc_stg_base = STG_SYSCON_PCIE1_BASE; 656 break; 657 default: 658 aprint_error(": unknown controller at 0x%lx\n", 659 sc->sc_cfg_addr); 660 return; 661 } 662 663 aprint_naive("\n"); 664 aprint_normal(": PCIe\n"); 665 666 error = jh7110_pcie_host_init(sc); 667 if (error) { 668 /* error already printed */ 669 return; 670 } 671 672 /* Configure Address Translation. */ 673 error = jh7110_pcie_atr_init(sc); 674 if (error) { 675 676 } 677 678 /* Mask and acknowledge all interrupts. */ 679 WR4(sc, PLDA_IMASK_LOCAL, 0); 680 WR4(sc, PLDA_ISTATUS_LOCAL, 0xffffffff); 681 682 char intrstr[128]; 683 if (!fdtbus_intr_str(phandle, 0, intrstr, sizeof(intrstr))) { 684 aprint_error(": failed to decode interrupt\n"); 685 return; 686 } 687 void *ih = fdtbus_intr_establish_xname(phandle, 0, IPL_VM, 688 FDT_INTR_MPSAFE, jh7110_pcie_intr, sc, device_xname(self)); 689 if (ih == NULL) { 690 aprint_error_dev(self, "failed to establish interrupt on %s\n", 691 intrstr); 692 // XXXNH unwind 693 return; 694 } 695 aprint_normal_dev(self, "interrupting on %s\n", intrstr); 696 697 fdtbus_register_interrupt_controller(self, 698 OF_child(phsc->sc_phandle), &jh7110_pcie_intxfuncs); 699 700 phsc->sc_type = PCIHOST_ECAM; 701 pcihost_init(&phsc->sc_pc, phsc); 702 703 phsc->sc_pc.pc_bus_maxdevs = jh7110_pcie_bus_maxdevs; 704 phsc->sc_pc.pc_make_tag = jh7110_pcie_make_tag; 705 phsc->sc_pc.pc_decompose_tag = jh7110_pcie_decompose_tag; 706 phsc->sc_pc.pc_conf_read = jh7110_pcie_conf_read; 707 phsc->sc_pc.pc_conf_write = jh7110_pcie_conf_write; 708 709 pcihost_init2(phsc); 710 } 711 712 CFATTACH_DECL_NEW(jh7110_pcie, sizeof(struct jh7110_pcie_softc), 713 jh7110_pcie_match, jh7110_pcie_attach, NULL, NULL); 714