Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/sys/arch/arm Add RK3399 PCIe host bridge support.
details: https://anonhg.NetBSD.org/src/rev/78efbd6d0934
branches: trunk
changeset: 449430:78efbd6d0934
user: jakllsch <jakllsch%NetBSD.org@localhost>
date: Thu Mar 07 00:35:22 2019 +0000
description:
Add RK3399 PCIe host bridge support.
Not enabled yet due to occasional hangs during boot, and needing
__BUS_SPACE_HAS_PROBING_METHODS enabled.
Uses slightly non-standard DT bindings to avoid suboptimality of the
Linux binding. This allows for much more flexibility and efficency
in allotment of the limited apertures into PCI spaces.
diffstat:
sys/arch/arm/dts/rk3399-rockpro64.dts | 48 ++
sys/arch/arm/rockchip/files.rockchip | 12 +-
sys/arch/arm/rockchip/rk3399_pcie.c | 695 ++++++++++++++++++++++++++++++++
sys/arch/arm/rockchip/rk3399_pcie_phy.c | 268 ++++++++++++
4 files changed, 1022 insertions(+), 1 deletions(-)
diffs (truncated from 1069 to 300 lines):
diff -r 90bc446f2b1d -r 78efbd6d0934 sys/arch/arm/dts/rk3399-rockpro64.dts
--- a/sys/arch/arm/dts/rk3399-rockpro64.dts Wed Mar 06 19:36:59 2019 +0000
+++ b/sys/arch/arm/dts/rk3399-rockpro64.dts Thu Mar 07 00:35:22 2019 +0000
@@ -85,6 +85,18 @@
regulator-max-microvolt = <12000000>;
};
+ 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";
+ vin-supply = <&dc_12v>;
+ };
+
vcc1v8_s0: vcc1v8-s0 {
compatible = "regulator-fixed";
regulator-name = "vcc1v8_s0";
@@ -852,6 +864,18 @@
<1 14 RK_FUNC_GPIO &pcfg_pull_down>;
};
};
+
+ 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>;
+ };
+ };
};
&cluster0_opp {
@@ -872,6 +896,30 @@
};
};
+&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>;
+ max-link-speed = <2>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pcie_clkreqn>;
+ vpcie3v3-supply = <&vcc3v3_pcie>;
+ status = "okay";
+ bus-range = <0 3>;
+ 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 */
+ >;
+};
+
&spi1 {
status = "okay";
diff -r 90bc446f2b1d -r 78efbd6d0934 sys/arch/arm/rockchip/files.rockchip
--- a/sys/arch/arm/rockchip/files.rockchip Wed Mar 06 19:36:59 2019 +0000
+++ b/sys/arch/arm/rockchip/files.rockchip Thu Mar 07 00:35:22 2019 +0000
@@ -1,4 +1,4 @@
-# $NetBSD: files.rockchip,v 1.15 2018/08/12 16:48:04 jmcneill Exp $
+# $NetBSD: files.rockchip,v 1.16 2019/03/07 00:35:22 jakllsch Exp $
#
# Configuration info for Rockchip family SoCs
#
@@ -53,6 +53,16 @@
attach awge at fdt with rk_gmac
file arch/arm/rockchip/rk_gmac.c rk_gmac
+# PCIe PHY
+device rkpciephy
+attach rkpciephy at fdt
+file arch/arm/rockchip/rk3399_pcie_phy.c rkpciephy
+
+# PCIe host
+device rkpcie: pcibus, pcihost_fdt
+attach rkpcie at fdt
+file arch/arm/rockchip/rk3399_pcie.c rkpcie
+
# SOC parameters
defflag opt_soc.h SOC_ROCKCHIP
defflag opt_soc.h SOC_RK3328: SOC_ROCKCHIP
diff -r 90bc446f2b1d -r 78efbd6d0934 sys/arch/arm/rockchip/rk3399_pcie.c
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sys/arch/arm/rockchip/rk3399_pcie.c Thu Mar 07 00:35:22 2019 +0000
@@ -0,0 +1,695 @@
+/* $NetBSD: rk3399_pcie.c,v 1.1 2019/03/07 00:35:22 jakllsch Exp $ */
+/*
+ * Copyright (c) 2018 Mark Kettenis <kettenis%openbsd.org@localhost>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include <sys/cdefs.h>
+
+__KERNEL_RCSID(1, "$NetBSD: rk3399_pcie.c,v 1.1 2019/03/07 00:35:22 jakllsch Exp $");
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/bitops.h>
+#include <sys/device.h>
+#include <sys/extent.h>
+#include <sys/kmem.h>
+
+#include <machine/intr.h>
+#include <sys/bus.h>
+#include <dev/fdt/fdtvar.h>
+#include <dev/fdt/syscon.h>
+#include <arm/cpufunc.h>
+
+#include <dev/pci/pcidevs.h>
+#include <dev/pci/pcireg.h>
+#include <dev/pci/pcivar.h>
+#include <dev/pci/pciconf.h>
+
+#include <arm/fdt/pcihost_fdtvar.h>
+#include <sys/gpio.h>
+
+#define SETREG(m, v) ((m)<<16|__SHIFTIN((v), (m)))
+#define GETREG(m, v) (__SHIFTOUT((v), (m)))
+
+/* APB region */
+#define PCIE_CLIENT_BASE 0x000000
+#define PCIE_CLIENT_BASIC_STRAP_CONF 0x0000
+#define PCBSC_PCIE_GEN_SEL __BIT(7)
+#define PCBSC_PGS_GEN1 SETREG(PCBSC_PCIE_GEN_SEL, 0)
+#define PCBSC_PGS_GEN2 SETREG(PCBSC_PCIE_GEN_SEL, 1)
+#define PCBSC_MODE_SELECT __BIT(6)
+#define PCBSC_MS_ENDPOINT SETREG(PCBSC_MODE_SELECT, 0)
+#define PCBSC_MS_ROOTPORT SETREG(PCBSC_MODE_SELECT, 1)
+#define PCBSC_LANE_COUNT __BITS(5,4)
+#define PCBSC_LC(x) SETREG(PCBSC_LANE_COUNT, ilog2(x)) /* valid for x1,2,4 */
+#define PCBSC_ARI_EN SETREG(__BIT(3), 1) /* Alternate Routing ID Enable */
+#define PCBSC_SR_IOV_EN SETREG(__BIT(2), 1)
+#define PCBSC_LINK_TRAIN_EN SETREG(__BIT(1), 1)
+#define PCBSC_CONF_EN SETREG(__BIT(0), 1) /* Config enable */
+#define PCIE_CLIENT_DEBUG_OUT_0 0x003c
+#define PCIE_CLIENT_DEBUG_OUT_1 0x0040
+#define PCIE_CLIENT_BASIC_STATUS0 0x0044
+#define PCIE_CLIENT_BASIC_STATUS1 0x0048
+#define PCBS1_LINK_ST(x) (u_int)__SHIFTOUT((x), __BITS(21,20))
+#define PCBS1_LS_NO_RECV 0 /* no receivers */
+#define PCBS1_LS_TRAINING 1 /* link training */
+#define PCBS1_LS_DL_INIT 2 /* link up, DL init progressing */
+#define PCBS1_LS_DL_DONE 3 /* link up, DL init complete */
+#define PCIE_CLIENT_INT_MASK 0x004c
+#define PCIM_INTx_MASK(x) SETREG(__BIT((x)+5), 1)
+#define PCIM_INTx_ENAB(x) SETREG(__BIT((x)+5), 0)
+
+#define PCIE_CORE_BASE 0x800000
+#define PCIE_RC_NORMAL_BASE (PCIE_CORE_BASE + 0x00000)
+
+#define PCIE_LM_BASE 0x900000
+#define PCIE_LM_CORE_CTRL (PCIE_LM_BASE + 0x00)
+#define PCIE_CORE_PL_CONF_SPEED_5G 0x00000008
+#define PCIE_CORE_PL_CONF_SPEED_MASK 0x00000018
+#define PCIE_CORE_PL_CONF_LANE_MASK 0x00000006
+#define PCIE_CORE_PL_CONF_LANE_SHIFT 1
+#define PCIE_LM_PLC1 (PCIE_LM_BASE + 0x04)
+#define PCIE_LM_PLC1_FTS_MASK __BITS(23, 8)
+#define PCIE_LM_VENDOR_ID (PCIE_LM_BASE + 0x44)
+#define PCIE_LM_LINKWIDTH (PCIE_LM_BASE + 0x50)
+#define PCIE_LM_LANEMAP (PCIE_LM_BASE + 0x200)
+#define PCIE_LM_DEBUG_MUX_CONTROL (PCIE_LM_BASE + 0x208)
+#define PCIE_LM_RCBAR (PCIE_LM_BASE + 0x300)
+#define PCIE_LM_RCBARPME __BIT(17)
+#define PCIE_LM_RCBARPMS __BIT(18)
+#define PCIE_LM_RCBARPIE __BIT(19)
+#define PCIE_LM_RCBARPIS __BIT(20)
+
+#define PCIE_RC_BASE 0xa00000
+#define PCIE_RC_CONFIG_DCSR (PCIE_RC_BASE + 0x0c0 + PCIE_DCSR)
+#define PCIE_RC_PCIE_LCAP (PCIE_RC_BASE + 0x0c0 + PCIE_LCAP)
+#define PCIE_RC_CONFIG_LCSR (PCIE_RC_BASE + 0x0c0 + PCIE_LCSR)
+#define PCIE_RC_CONFIG_THP_CAP (PCIE_RC_BASE + 0x274)
+#define PCIE_RC_CONFIG_THP_CAP_NEXT_MASK __BITS(31, 20)
+
+
+#define PCIE_ATR_BASE 0xc00000
+#define PCIE_ATR_OB_ADDR0(i) (PCIE_ATR_BASE + 0x000 + (i) * 0x20)
+#define PCIE_ATR_OB_ADDR1(i) (PCIE_ATR_BASE + 0x004 + (i) * 0x20)
+#define PCIE_ATR_OB_DESC0(i) (PCIE_ATR_BASE + 0x008 + (i) * 0x20)
+#define PCIE_ATR_OB_DESC1(i) (PCIE_ATR_BASE + 0x00c + (i) * 0x20)
+#define PCIE_ATR_IB_ADDR0(i) (PCIE_ATR_BASE + 0x800 + (i) * 0x8)
+#define PCIE_ATR_IB_ADDR1(i) (PCIE_ATR_BASE + 0x804 + (i) * 0x8)
+#define PCIE_ATR_HDR_MEM 0x2
+#define PCIE_ATR_HDR_IO 0x6
+#define PCIE_ATR_HDR_CFG_TYPE0 0xa
+#define PCIE_ATR_HDR_CFG_TYPE1 0xb
+#define PCIE_ATR_HDR_RID __BIT(23)
+
+/* AXI region */
+#define PCIE_ATR_OB_REGION0_SIZE (32 * 1024 * 1024)
+#define PCIE_ATR_OB_REGION_SIZE (1 * 1024 * 1024)
+
+#define HREAD4(sc, reg) \
+ (bus_space_read_4((sc)->sc_iot, (sc)->sc_ioh, (reg)))
+#define HWRITE4(sc, reg, val) \
+ bus_space_write_4((sc)->sc_iot, (sc)->sc_ioh, (reg), (val))
+
+struct rkpcie_softc {
+ struct pcihost_softc sc_phsc;
+ bus_space_tag_t sc_iot;
+ bus_space_handle_t sc_ioh;
+ bus_space_handle_t sc_bus_cfgh[32];
+ bus_addr_t sc_axi_addr;
+ bus_addr_t sc_apb_addr;
+ bus_size_t sc_axi_size;
+ bus_size_t sc_apb_size;
+
+ struct extent *sc_regionex;
+};
+
+static int rkpcie_match(device_t, cfdata_t, void *);
+static void rkpcie_attach(device_t, device_t, void *);
+
+CFATTACH_DECL_NEW(rkpcie, sizeof(struct rkpcie_softc),
+ rkpcie_match, rkpcie_attach, NULL, NULL);
+
+static int
+rkpcie_match(device_t parent, cfdata_t cf, void *aux)
+{
+ const char * const compatible[] = {
+ "rockchip,rk3399-pcie",
+ NULL
+ };
+ struct fdt_attach_args *faa = aux;
+
+ return of_match_compatible(faa->faa_phandle, compatible);
+}
+
+static void rkpcie_atr_init(struct rkpcie_softc *);
+
+static int rkpcie_bus_maxdevs(void *, int);
+static pcitag_t rkpcie_make_tag(void *, int, int, int);
+static void rkpcie_decompose_tag(void *, pcitag_t, int *, int *, int *);
+static pcireg_t rkpcie_conf_read(void *, pcitag_t, int);
+static void rkpcie_conf_write(void *, pcitag_t, int, pcireg_t);
+static int rkpcie_conf_hook(void *, int, int, int, pcireg_t);
+
+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)
+{
+ for (u_int i = 0; i < 4; i++) {
+ struct clk * clk = fdtbus_clock_get_index(phandle, i);
+ if (clk == NULL)
+ continue;
+ if (clk_enable(clk) != 0)
+ continue;
+ }
+}
+
+static inline void
+clock_enable(int phandle, const char *name)
+{
+ struct clk * clk = fdtbus_clock_get(phandle, name);
Home |
Main Index |
Thread Index |
Old Index