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