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

Reply via email to