Module Name: src Committed By: jmcneill Date: Wed Jun 12 10:13:45 UTC 2019
Modified Files: src/sys/arch/arm/dts: rk3399-rockpro64.dts src/sys/arch/arm/fdt: pcihost_fdt.c pcihost_fdtvar.h src/sys/arch/arm/rockchip: rk3399_pcie.c Log Message: Enable RK3399 PCIe. To generate a diff of this commit: cvs rdiff -u -r1.5 -r1.6 src/sys/arch/arm/dts/rk3399-rockpro64.dts cvs rdiff -u -r1.8 -r1.9 src/sys/arch/arm/fdt/pcihost_fdt.c cvs rdiff -u -r1.1 -r1.2 src/sys/arch/arm/fdt/pcihost_fdtvar.h cvs rdiff -u -r1.1 -r1.2 src/sys/arch/arm/rockchip/rk3399_pcie.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/sys/arch/arm/dts/rk3399-rockpro64.dts diff -u src/sys/arch/arm/dts/rk3399-rockpro64.dts:1.5 src/sys/arch/arm/dts/rk3399-rockpro64.dts:1.6 --- src/sys/arch/arm/dts/rk3399-rockpro64.dts:1.5 Wed May 1 10:43:55 2019 +++ src/sys/arch/arm/dts/rk3399-rockpro64.dts Wed Jun 12 10:13:44 2019 @@ -1,4 +1,4 @@ -/* $NetBSD: rk3399-rockpro64.dts,v 1.5 2019/05/01 10:43:55 jmcneill Exp $ */ +/* $NetBSD: rk3399-rockpro64.dts,v 1.6 2019/06/12 10:13:44 jmcneill Exp $ */ /*- * Copyright (c) 2019 Jared McNeill <jmcne...@invisible.ca> @@ -35,8 +35,50 @@ pwms = <&pwm1 0 40000 0>; cooling-levels = <0 150 195 240>; }; + + vcc3v3_pcie: vcc3v3-pcie-regulator { + compatible = "regulator-fixed"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + enable-active-high; + gpio = <&gpio1 RK_PD0 GPIO_ACTIVE_HIGH>; + pinctrl-names = "default"; + pinctrl-0 = <&pcie_pwr_en>; + regulator-name = "vcc3v3_pcie"; + }; +}; + +&pinctrl { + pcie { + pcie_pwr_en: pcie-pwr-en { + rockchip,pins = + <1 RK_PD0 RK_FUNC_GPIO &pcfg_pull_none>; + }; + + pcie_clkreqn: pci-clkreqn { + rockchip,pins = + <2 RK_PD2 RK_FUNC_2 &pcfg_pull_none>; + }; + }; }; &pwm1 { status = "okay"; }; + +&pcie_phy { + status = "okay"; +}; + +&pcie0 { + assigned-clocks = <&cru SCLK_PCIEPHY_REF>; + assigned-clock-parents = <&cru SCLK_PCIEPHY_REF100M>; + assigned-clock-rates = <100000000>; + + ep-gpios = <&gpio2 RK_PD4 GPIO_ACTIVE_HIGH>; + num-lanes = <4>; + pinctrl-names = "default"; + pinctrl-0 = <&pcie_clkreqn>; + vpcie3v3-supply = <&vcc3v3_pcie>; + status = "okay"; +}; Index: src/sys/arch/arm/fdt/pcihost_fdt.c diff -u src/sys/arch/arm/fdt/pcihost_fdt.c:1.8 src/sys/arch/arm/fdt/pcihost_fdt.c:1.9 --- src/sys/arch/arm/fdt/pcihost_fdt.c:1.8 Thu Feb 28 00:47:10 2019 +++ src/sys/arch/arm/fdt/pcihost_fdt.c Wed Jun 12 10:13:44 2019 @@ -1,4 +1,4 @@ -/* $NetBSD: pcihost_fdt.c,v 1.8 2019/02/28 00:47:10 jakllsch Exp $ */ +/* $NetBSD: pcihost_fdt.c,v 1.9 2019/06/12 10:13:44 jmcneill Exp $ */ /*- * Copyright (c) 2018 Jared D. McNeill <jmcne...@invisible.ca> @@ -27,7 +27,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: pcihost_fdt.c,v 1.8 2019/02/28 00:47:10 jakllsch Exp $"); +__KERNEL_RCSID(0, "$NetBSD: pcihost_fdt.c,v 1.9 2019/06/12 10:13:44 jmcneill Exp $"); #include <sys/param.h> #include <sys/bus.h> @@ -136,6 +136,13 @@ pcihost_attach(device_t parent, device_t } sc->sc_type = of_search_compatible(sc->sc_phandle, compat_data)->data; +#ifdef __HAVE_PCI_MSI_MSIX + if (sc->sc_type == PCIHOST_ECAM) { + sc->sc_pci_flags |= PCI_FLAGS_MSI_OKAY; + sc->sc_pci_flags |= PCI_FLAGS_MSIX_OKAY; + } +#endif + aprint_naive("\n"); aprint_normal(": Generic PCI host controller\n"); @@ -178,14 +185,7 @@ pcihost_init2(struct pcihost_softc *sc) pba.pba_flags = PCI_FLAGS_MRL_OKAY | PCI_FLAGS_MRM_OKAY | PCI_FLAGS_MWI_OKAY | - PCI_FLAGS_IO_OKAY | - PCI_FLAGS_MEM_OKAY; -#ifdef __HAVE_PCI_MSI_MSIX - if (sc->sc_type == PCIHOST_ECAM) { - pba.pba_flags |= PCI_FLAGS_MSI_OKAY | - PCI_FLAGS_MSIX_OKAY; - } -#endif + sc->sc_pci_flags; pba.pba_iot = &sc->sc_io.bst; pba.pba_memt = &sc->sc_mem.bst; pba.pba_dmat = sc->sc_dmat; @@ -228,6 +228,7 @@ pcihost_config(struct pcihost_softc *sc) const u_int *ranges; u_int probe_only; int error, len; + bool swap; struct pcih_bus_space * const pibs = &sc->sc_io; pibs->bst = *sc->sc_bst; @@ -249,10 +250,17 @@ pcihost_config(struct pcihost_softc *sc) if (probe_only) return 0; - ranges = fdtbus_get_prop(sc->sc_phandle, "ranges", &len); - if (ranges == NULL) { - aprint_error_dev(sc->sc_dev, "missing 'ranges' property\n"); - return EINVAL; + if (sc->sc_pci_ranges != NULL) { + ranges = sc->sc_pci_ranges; + len = sc->sc_pci_ranges_cells * 4; + swap = false; + } else { + ranges = fdtbus_get_prop(sc->sc_phandle, "ranges", &len); + if (ranges == NULL) { + aprint_error_dev(sc->sc_dev, "missing 'ranges' property\n"); + return EINVAL; + } + swap = true; } /* @@ -263,10 +271,14 @@ pcihost_config(struct pcihost_softc *sc) * Total size for each entry is 28 bytes (7 cells). */ while (len >= 28) { - const uint32_t phys_hi = be32dec(&ranges[0]); - const uint64_t bus_phys = be64dec(&ranges[1]); - const uint64_t cpu_phys = be64dec(&ranges[3]); - const uint64_t size = be64dec(&ranges[5]); +#define DECODE32(x,o) (swap ? be32dec(&(x)[o]) : (x)[o]) +#define DECODE64(x,o) (swap ? be64dec(&(x)[o]) : (((uint64_t)((x)[(o)+0]) << 32) + (x)[(o)+1])) + const uint32_t phys_hi = DECODE32(ranges, 0); + const uint64_t bus_phys = DECODE64(ranges, 1); + const uint64_t cpu_phys = DECODE64(ranges, 3); + const uint64_t size = DECODE64(ranges, 5); +#undef DECODE32 +#undef DECODE64 len -= 28; ranges += 7; @@ -294,6 +306,7 @@ pcihost_config(struct pcihost_softc *sc) /* reserve a PC-like legacy IO ports range, perhaps for access to VGA registers */ if (bus_phys == 0 && size >= 0x10000) extent_alloc_region(ioext, 0, 0x1000, EX_WAITOK); + sc->sc_pci_flags |= PCI_FLAGS_IO_OKAY; break; case PHYS_HI_SPACE_MEM64: /* FALLTHROUGH */ @@ -327,6 +340,7 @@ pcihost_config(struct pcihost_softc *sc) "MMIO (%d-bit non-prefetchable): 0x%" PRIx64 "+0x%" PRIx64 "@0x%" PRIx64 "\n", is64 ? 64 : 32, bus_phys, size, cpu_phys); } + sc->sc_pci_flags |= PCI_FLAGS_MEM_OKAY; break; default: break; Index: src/sys/arch/arm/fdt/pcihost_fdtvar.h diff -u src/sys/arch/arm/fdt/pcihost_fdtvar.h:1.1 src/sys/arch/arm/fdt/pcihost_fdtvar.h:1.2 --- src/sys/arch/arm/fdt/pcihost_fdtvar.h:1.1 Thu Feb 28 00:47:10 2019 +++ src/sys/arch/arm/fdt/pcihost_fdtvar.h Wed Jun 12 10:13:44 2019 @@ -1,4 +1,4 @@ -/* $NetBSD: pcihost_fdtvar.h,v 1.1 2019/02/28 00:47:10 jakllsch Exp $ */ +/* $NetBSD: pcihost_fdtvar.h,v 1.2 2019/06/12 10:13:44 jmcneill Exp $ */ /*- * Copyright (c) 2018 Jared D. McNeill <jmcne...@invisible.ca> @@ -77,6 +77,11 @@ struct pcihost_softc { struct pcih_bus_space sc_io; struct pcih_bus_space sc_mem; + + int sc_pci_flags; + + const u_int *sc_pci_ranges; + u_int sc_pci_ranges_cells; }; void pcihost_init2(struct pcihost_softc *); Index: src/sys/arch/arm/rockchip/rk3399_pcie.c diff -u src/sys/arch/arm/rockchip/rk3399_pcie.c:1.1 src/sys/arch/arm/rockchip/rk3399_pcie.c:1.2 --- src/sys/arch/arm/rockchip/rk3399_pcie.c:1.1 Thu Mar 7 00:35:22 2019 +++ src/sys/arch/arm/rockchip/rk3399_pcie.c Wed Jun 12 10:13:44 2019 @@ -1,4 +1,4 @@ -/* $NetBSD: rk3399_pcie.c,v 1.1 2019/03/07 00:35:22 jakllsch Exp $ */ +/* $NetBSD: rk3399_pcie.c,v 1.2 2019/06/12 10:13:44 jmcneill Exp $ */ /* * Copyright (c) 2018 Mark Kettenis <kette...@openbsd.org> * @@ -17,7 +17,7 @@ #include <sys/cdefs.h> -__KERNEL_RCSID(1, "$NetBSD: rk3399_pcie.c,v 1.1 2019/03/07 00:35:22 jakllsch Exp $"); +__KERNEL_RCSID(1, "$NetBSD: rk3399_pcie.c,v 1.2 2019/06/12 10:13:44 jmcneill Exp $"); #include <sys/param.h> #include <sys/systm.h> @@ -135,6 +135,17 @@ struct rkpcie_softc { struct extent *sc_regionex; }; +/* + * XXX ignore DT ranges and use our own for now + */ +static const uint32_t rk3399_pcie_bus_range[] = { 0, 3 }; +static const uint32_t rk3399_pcie_ranges[] = { + 0xc3000000, 0x0, 0xf8000000, 0x0, 0xf8000000, 0x0, 0x2000000, /* 32M region 0, prefmem */ + 0x82000000, 0x0, 0xfa000000, 0x0, 0xfa000000, 0x0, 0x1c00000, /* 28M regions 1-28, mem */ + 0x81000000, 0x0, 0x00000000, 0x0, 0xfbc00000, 0x0, 0x0100000, /* 1M region 29, i/o */ + 0x00010000, 0x0, 0x00000000, 0x0, 0xfbd00000, 0x0, 0x0300000, /* 3M regions 30-32, config */ +}; + static int rkpcie_match(device_t, cfdata_t, void *); static void rkpcie_attach(device_t, device_t, void *); @@ -164,22 +175,6 @@ static int rkpcie_conf_hook(void *, int, static struct fdtbus_interrupt_controller_func rkpcie_intrfuncs; -static inline int -OF_getpropintarray(int handle, const char *prop, uint32_t *buf, int buflen) -{ - int len; - int i; - - len = OF_getprop(handle, prop, buf, buflen); - if (len < 0 || (len % sizeof(uint32_t))) - return -1; - - for (i = 0; i < len / sizeof(uint32_t); i++) - buf[i] = be32toh(buf[i]); - - return len; -} - static inline void clock_enable_all(int phandle) { @@ -428,14 +423,23 @@ again: /* Create extents for our address space. */ sc->sc_regionex = extent_create("rkpcie", sc->sc_axi_addr, sc->sc_axi_addr - 1 + 64 * 1048576, NULL, 0, EX_WAITOK); + if (sc->sc_regionex == NULL) { + aprint_error_dev(self, "extent_create failed\n"); + return; + } /* Set up bus range. */ +#if notyet if (OF_getpropintarray(phandle, "bus-range", bus_range, sizeof(bus_range)) != sizeof(bus_range) || bus_range[0] >= 32 || bus_range[1] >= 32) { bus_range[0] = 0; bus_range[1] = 31; } +#else + bus_range[0] = rk3399_pcie_bus_range[0]; + bus_range[1] = rk3399_pcie_bus_range[1]; +#endif sc->sc_phsc.sc_bus_min = bus_range[0]; sc->sc_phsc.sc_bus_max = bus_range[1]; @@ -444,6 +448,9 @@ again: return; } + sc->sc_phsc.sc_pci_ranges = rk3399_pcie_ranges; + sc->sc_phsc.sc_pci_ranges_cells = __arraycount(rk3399_pcie_ranges); + /* Configure Address Translation. */ rkpcie_atr_init(sc); @@ -451,6 +458,9 @@ again: &rkpcie_intrfuncs); sc->sc_phsc.sc_type = PCIHOST_ECAM; +#if notyet + sc->sc_phsc.sc_pci_flags |= PCI_FLAGS_MSI_OKAY; +#endif pcihost_init(&sc->sc_phsc.sc_pc, sc); sc->sc_phsc.sc_pc.pc_bus_maxdevs = rkpcie_bus_maxdevs; sc->sc_phsc.sc_pc.pc_make_tag = rkpcie_make_tag; @@ -464,25 +474,20 @@ again: static void rkpcie_atr_init(struct rkpcie_softc *sc) { - uint32_t *ranges = NULL; struct extent * const ex = sc->sc_regionex; bus_addr_t aaddr; bus_addr_t addr; bus_size_t size, offset; uint32_t type; - int len, region; - int i; + int region, i; /* get root bus's config space out of the APB space */ bus_space_subregion(sc->sc_iot, sc->sc_ioh, PCIE_RC_NORMAL_BASE, PCI_EXTCONF_SIZE * 8, &sc->sc_bus_cfgh[0]); - len = OF_getproplen(sc->sc_phsc.sc_phandle, "ranges"); - if (len <= 0 || (len % (7 * sizeof(uint32_t))) != 0) - goto fail; - ranges = kmem_zalloc(len, KM_SLEEP); - OF_getpropintarray(sc->sc_phsc.sc_phandle, "ranges", ranges, len); + const uint32_t *ranges = sc->sc_phsc.sc_pci_ranges; + const int ranges_cells = sc->sc_phsc.sc_pci_ranges_cells; - for (i = 0; i < len / sizeof(uint32_t); i += 7) { + for (i = 0; i < ranges_cells; i += 7) { /* Handle IO and MMIO. */ switch (ranges[i] & 0x03000000) { case 0x00000000: @@ -556,7 +561,6 @@ rkpcie_atr_init(struct rkpcie_softc *sc) size -= regionsize; } } - kmem_free(ranges, len); /* Passthrought inbound translations unmodified. */ HWRITE4(sc, PCIE_ATR_IB_ADDR0(2), 32 - 1); @@ -567,7 +571,6 @@ rkpcie_atr_init(struct rkpcie_softc *sc) fail: extent_print(ex); device_printf(sc->sc_phsc.sc_dev, "can't map ranges\n"); - kmem_free(ranges, len); } int