Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/sys/arch/arm Enable RK3399 PCIe.



details:   https://anonhg.NetBSD.org/src/rev/ecf91982ec8b
branches:  trunk
changeset: 451928:ecf91982ec8b
user:      jmcneill <jmcneill%NetBSD.org@localhost>
date:      Wed Jun 12 10:13:44 2019 +0000

description:
Enable RK3399 PCIe.

diffstat:

 sys/arch/arm/dts/rk3399-rockpro64.dts |  44 ++++++++++++++++++++++++-
 sys/arch/arm/fdt/pcihost_fdt.c        |  50 ++++++++++++++++++----------
 sys/arch/arm/fdt/pcihost_fdtvar.h     |   7 +++-
 sys/arch/arm/rockchip/rk3399_pcie.c   |  61 ++++++++++++++++++----------------
 4 files changed, 113 insertions(+), 49 deletions(-)

diffs (truncated from 343 to 300 lines):

diff -r 5d979d8238c4 -r ecf91982ec8b sys/arch/arm/dts/rk3399-rockpro64.dts
--- a/sys/arch/arm/dts/rk3399-rockpro64.dts     Wed Jun 12 10:09:26 2019 +0000
+++ b/sys/arch/arm/dts/rk3399-rockpro64.dts     Wed Jun 12 10:13:44 2019 +0000
@@ -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 <jmcneill%invisible.ca@localhost>
@@ -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";
+};
diff -r 5d979d8238c4 -r ecf91982ec8b sys/arch/arm/fdt/pcihost_fdt.c
--- a/sys/arch/arm/fdt/pcihost_fdt.c    Wed Jun 12 10:09:26 2019 +0000
+++ b/sys/arch/arm/fdt/pcihost_fdt.c    Wed Jun 12 10:13:44 2019 +0000
@@ -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 <jmcneill%invisible.ca@localhost>
@@ -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 @@
        }
        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 @@
        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 @@
        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 @@
        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 @@
         * 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 @@
                        /* 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 @@
                                    "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;
diff -r 5d979d8238c4 -r ecf91982ec8b sys/arch/arm/fdt/pcihost_fdtvar.h
--- a/sys/arch/arm/fdt/pcihost_fdtvar.h Wed Jun 12 10:09:26 2019 +0000
+++ b/sys/arch/arm/fdt/pcihost_fdtvar.h Wed Jun 12 10:13:44 2019 +0000
@@ -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 <jmcneill%invisible.ca@localhost>
@@ -77,6 +77,11 @@
 
        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 *);
diff -r 5d979d8238c4 -r ecf91982ec8b sys/arch/arm/rockchip/rk3399_pcie.c
--- a/sys/arch/arm/rockchip/rk3399_pcie.c       Wed Jun 12 10:09:26 2019 +0000
+++ b/sys/arch/arm/rockchip/rk3399_pcie.c       Wed Jun 12 10:13:44 2019 +0000
@@ -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 <kettenis%openbsd.org@localhost>
  *
@@ -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 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 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 @@
        /* 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 @@
                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 @@
                    &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 @@
 static void
 rkpcie_atr_init(struct rkpcie_softc *sc)



Home | Main Index | Thread Index | Old Index