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