Source-Changes-HG archive

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

[src/trunk]: src/sys/arch/arm/imx Add support for imx6qp-pcie.



details:   https://anonhg.NetBSD.org/src/rev/8c00f70431b8
branches:  trunk
changeset: 965148:8c00f70431b8
user:      hkenken <hkenken%NetBSD.org@localhost>
date:      Mon Sep 02 01:28:41 2019 +0000

description:
Add support for imx6qp-pcie.

+ Add vpcie-supply support
+ Add ext_osc support

Tested on SABRESD i.MX 6QP.

diffstat:

 sys/arch/arm/imx/fdt/imx6_pcie.c |   58 ++++++++++++++++++++--
 sys/arch/arm/imx/imx6_ccm.c      |    6 +-
 sys/arch/arm/imx/imx6_iomuxreg.h |    3 +-
 sys/arch/arm/imx/imxpcie.c       |  100 +++++++++++++++++++++++++-------------
 sys/arch/arm/imx/imxpciereg.h    |   15 +++++-
 sys/arch/arm/imx/imxpcievar.h    |    7 ++-
 6 files changed, 143 insertions(+), 46 deletions(-)

diffs (truncated from 355 to 300 lines):

diff -r b5818c9afa5c -r 8c00f70431b8 sys/arch/arm/imx/fdt/imx6_pcie.c
--- a/sys/arch/arm/imx/fdt/imx6_pcie.c  Mon Sep 02 00:51:48 2019 +0000
+++ b/sys/arch/arm/imx/fdt/imx6_pcie.c  Mon Sep 02 01:28:41 2019 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: imx6_pcie.c,v 1.3 2019/08/19 03:45:51 hkenken Exp $    */
+/*     $NetBSD: imx6_pcie.c,v 1.4 2019/09/02 01:28:41 hkenken Exp $    */
 /*-
  * Copyright (c) 2019 Genetec Corporation.  All rights reserved.
  * Written by Hashimoto Kenichi for Genetec Corporation.
@@ -25,7 +25,7 @@
  * SUCH DAMAGE.
  */
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: imx6_pcie.c,v 1.3 2019/08/19 03:45:51 hkenken Exp $");
+__KERNEL_RCSID(0, "$NetBSD: imx6_pcie.c,v 1.4 2019/09/02 01:28:41 hkenken Exp $");
 
 #include "opt_pci.h"
 #include "opt_fdt.h"
@@ -69,6 +69,7 @@
        struct imxpcie_softc sc_imxpcie;
 
        struct fdtbus_gpio_pin  *sc_pin_reset;
+       struct fdtbus_regulator *sc_reg_vpcie;
 };
 
 static int imx6_pcie_match(device_t, cfdata_t, void *);
@@ -89,9 +90,10 @@
 CFATTACH_DECL_NEW(imxpcie_fdt, sizeof(struct imxpcie_fdt_softc),
     imx6_pcie_match, imx6_pcie_attach, NULL, NULL);
 
-static const char * const compatible[] = {
-       "fsl,imx6q-pcie",
-       NULL
+static const struct of_compat_data compat_data[] = {
+       { "fsl,imx6q-pcie",     false },
+       { "fsl,imx6qp-pcie",    true },
+       { NULL }
 };
 
 static int
@@ -99,7 +101,7 @@
 {
        struct fdt_attach_args * const faa = aux;
 
-       return of_match_compatible(faa->faa_phandle, compatible);
+       return of_match_compat_data(faa->faa_phandle, compat_data);
 }
 
 static void
@@ -125,6 +127,7 @@
        sc->sc_gpr_read = imx6_pcie_gpr_read;
        sc->sc_gpr_write = imx6_pcie_gpr_write;
        sc->sc_reset = imx6_pcie_reset;
+       sc->sc_have_sw_reset = of_search_compatible(phandle, compat_data)->data;
 
        if (fdtbus_get_reg_byname(phandle, "dbi", &addr, &size) != 0) {
                aprint_error(": couldn't get registers\n");
@@ -171,6 +174,49 @@
                return;
        }
 
+       if (of_hasprop(phandle, "vpcie-supply")) {
+               ifsc->sc_reg_vpcie = fdtbus_regulator_acquire(phandle, "vpcie-supply");
+               if (ifsc->sc_reg_vpcie == NULL) {
+                       aprint_error(": couldn't acquire regulator\n");
+                       return;
+               }
+               aprint_normal_dev(self, "regulator On\n");
+               fdtbus_regulator_enable(ifsc->sc_reg_vpcie);
+       }
+
+       if (of_hasprop(phandle, "ext_osc")) {
+               aprint_normal_dev(self, "Use external OSC\n");
+               sc->sc_ext_osc = true;
+
+               sc->sc_clk_pcie_ext = fdtbus_clock_get(phandle, "pcie_ext");
+               if (sc->sc_clk_pcie_ext == NULL) {
+                       aprint_error(": couldn't get clock pcie_ext\n");
+                       return;
+               }
+               sc->sc_clk_pcie_ext_src = fdtbus_clock_get(phandle, "pcie_ext_src");
+               if (sc->sc_clk_pcie_ext_src == NULL) {
+                       aprint_error(": couldn't get clock pcie_ext_src\n");
+                       return;
+               }
+
+               struct clk *clk_lvds1_in = imx6_get_clock("lvds1_in");
+               if (clk_lvds1_in == NULL) {
+                       aprint_error(": couldn't get clock lvds1_in\n");
+                       return;
+               }
+               int error = clk_set_parent(sc->sc_clk_pcie_ext_src, clk_lvds1_in);
+               if (error) {
+                       aprint_error_dev(sc->sc_dev,
+                           "couldn't set '%s' parent to '%s': %d\n",
+                           sc->sc_clk_pcie_ext_src->name, clk_lvds1_in->name, error);
+               }
+       } else {
+               sc->sc_ext_osc = false;
+               sc->sc_clk_pcie_ext = NULL;
+               sc->sc_clk_pcie_ext_src = NULL;
+       }
+
+
        TAILQ_INIT(&sc->sc_intrs);
        mutex_init(&sc->sc_lock, MUTEX_DEFAULT, IPL_VM);
 
diff -r b5818c9afa5c -r 8c00f70431b8 sys/arch/arm/imx/imx6_ccm.c
--- a/sys/arch/arm/imx/imx6_ccm.c       Mon Sep 02 00:51:48 2019 +0000
+++ b/sys/arch/arm/imx/imx6_ccm.c       Mon Sep 02 01:28:41 2019 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: imx6_ccm.c,v 1.13 2019/07/30 11:11:15 hkenken Exp $    */
+/*     $NetBSD: imx6_ccm.c,v 1.14 2019/09/02 01:28:41 hkenken Exp $    */
 
 /*
  * Copyright (c) 2010-2012, 2014  Genetec Corporation.  All rights reserved.
@@ -30,7 +30,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: imx6_ccm.c,v 1.13 2019/07/30 11:11:15 hkenken Exp $");
+__KERNEL_RCSID(0, "$NetBSD: imx6_ccm.c,v 1.14 2019/09/02 01:28:41 hkenken Exp $");
 
 #include "opt_cputypes.h"
 
@@ -886,6 +886,8 @@
 
        CLK_GATE_EXCLUSIVE("lvds1_gate", "lvds1_sel", CCM_ANALOG, MISC1, LVDS_CLK1_OBEN, LVDS_CLK1_IBEN),
        CLK_GATE_EXCLUSIVE("lvds2_gate", "lvds2_sel", CCM_ANALOG, MISC1, LVDS_CLK2_OBEN, LVDS_CLK2_IBEN),
+       CLK_GATE_EXCLUSIVE("lvds1_in", "anaclk1", CCM_ANALOG, MISC1, LVDS_CLK1_IBEN, LVDS_CLK1_OBEN),
+       CLK_GATE_EXCLUSIVE("lvds2_in", "anaclk2", CCM_ANALOG, MISC1, LVDS_CLK2_IBEN, LVDS_CLK2_OBEN),
 };
 
 static struct imx6_clk *imx6_clk_find(const char *);
diff -r b5818c9afa5c -r 8c00f70431b8 sys/arch/arm/imx/imx6_iomuxreg.h
--- a/sys/arch/arm/imx/imx6_iomuxreg.h  Mon Sep 02 00:51:48 2019 +0000
+++ b/sys/arch/arm/imx/imx6_iomuxreg.h  Mon Sep 02 01:28:41 2019 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: imx6_iomuxreg.h,v 1.5 2019/07/22 11:44:01 hkenken Exp $        */
+/*     $NetBSD: imx6_iomuxreg.h,v 1.6 2019/09/02 01:28:41 hkenken Exp $        */
 
 /*
  * Copyright (c) 2014 Ryo Shimizu <ryo%nerv.org@localhost>
@@ -33,6 +33,7 @@
 #define IOMUX_GPR1                                     0x00000004
 #define  IOMUX_GPR1_CFG_L1_CLK_REMOVAL_EN      __BIT(31)
 #define  IOMUX_GPR1_APP_CLK_REQ_N              __BIT(30)
+#define  IOMUX_GPR1_PCIE_SW_RST                        __BIT(29)
 #define  IOMUX_GPR1_APP_REQ_EXIT_L1            __BIT(28)
 #define  IOMUX_GPR1_APP_READY_ENTR_L23         __BIT(27)
 #define  IOMUX_GPR1_APP_REQ_ENTR_L1            __BIT(26)
diff -r b5818c9afa5c -r 8c00f70431b8 sys/arch/arm/imx/imxpcie.c
--- a/sys/arch/arm/imx/imxpcie.c        Mon Sep 02 00:51:48 2019 +0000
+++ b/sys/arch/arm/imx/imxpcie.c        Mon Sep 02 01:28:41 2019 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: imxpcie.c,v 1.1 2019/07/24 12:33:18 hkenken Exp $      */
+/*     $NetBSD: imxpcie.c,v 1.2 2019/09/02 01:28:41 hkenken Exp $      */
 
 /*
  * Copyright (c) 2019  Genetec Corporation.  All rights reserved.
@@ -31,7 +31,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: imxpcie.c,v 1.1 2019/07/24 12:33:18 hkenken Exp $");
+__KERNEL_RCSID(0, "$NetBSD: imxpcie.c,v 1.2 2019/09/02 01:28:41 hkenken Exp $");
 
 #include "opt_pci.h"
 #include "opt_fdt.h"
@@ -244,33 +244,31 @@
 static int
 imxpcie_assert_core_reset(struct imxpcie_softc *sc)
 {
-       uint32_t gpr1;
-       uint32_t gpr12;
-
-       gpr1 = sc->sc_gpr_read(sc, IOMUX_GPR1);
-       gpr12 = sc->sc_gpr_read(sc, IOMUX_GPR12);
-
-       /* already enabled by bootloader */
-       if ((gpr1 & IOMUX_GPR1_REF_SSP_EN) &&
-           (gpr12 & IOMUX_GPR12_APP_LTSSM_ENABLE)) {
-               uint32_t v = PCIE_READ(sc, PCIE_PL_PFLR);
-               v &= ~PCIE_PL_PFLR_LINK_STATE;
-               v |= PCIE_PL_PFLR_FORCE_LINK;
-               PCIE_WRITE(sc, PCIE_PL_PFLR, v);
+       if (sc->sc_have_sw_reset) {
+               uint32_t gpr1 = sc->sc_gpr_read(sc, IOMUX_GPR1);
+               gpr1 |= IOMUX_GPR1_PCIE_SW_RST;
+               sc->sc_gpr_write(sc, IOMUX_GPR1, gpr1);
+       } else {
+               uint32_t gpr1 = sc->sc_gpr_read(sc, IOMUX_GPR1);
+               uint32_t gpr12 = sc->sc_gpr_read(sc, IOMUX_GPR12);
 
-               gpr12 &= ~IOMUX_GPR12_APP_LTSSM_ENABLE;
-               sc->sc_gpr_write(sc, IOMUX_GPR12, gpr12);
-       }
+               /* already enabled by bootloader */
+               if ((gpr1 & IOMUX_GPR1_REF_SSP_EN) &&
+                   (gpr12 & IOMUX_GPR12_APP_LTSSM_ENABLE)) {
+                       uint32_t v = PCIE_READ(sc, PCIE_PL_PFLR);
+                       v &= ~PCIE_PL_PFLR_LINK_STATE;
+                       v |= PCIE_PL_PFLR_FORCE_LINK;
+                       PCIE_WRITE(sc, PCIE_PL_PFLR, v);
 
-#if defined(IMX6DQP)
-       gpr1 |= IOMUX_GPR1_PCIE_SW_RST;
-       sc->sc_gpr_write(sc, IOMUX_GPR1, gpr1);
-#endif
+                       gpr12 &= ~IOMUX_GPR12_APP_LTSSM_ENABLE;
+                       sc->sc_gpr_write(sc, IOMUX_GPR12, gpr12);
+               }
 
-       gpr1 |= IOMUX_GPR1_TEST_POWERDOWN;
-       sc->sc_gpr_write(sc, IOMUX_GPR1, gpr1);
-       gpr1 &= ~IOMUX_GPR1_REF_SSP_EN;
-       sc->sc_gpr_write(sc, IOMUX_GPR1, gpr1);
+               gpr1 |= IOMUX_GPR1_TEST_POWERDOWN;
+               sc->sc_gpr_write(sc, IOMUX_GPR1, gpr1);
+               gpr1 &= ~IOMUX_GPR1_REF_SSP_EN;
+               sc->sc_gpr_write(sc, IOMUX_GPR1, gpr1);
+       }
 
        return 0;
 }
@@ -285,11 +283,23 @@
                aprint_error_dev(sc->sc_dev, "couldn't enable pcie_axi: %d\n", error);
                return error;
        }
-       error = clk_enable(sc->sc_clk_lvds1_gate);
-       if (error) {
-               aprint_error_dev(sc->sc_dev, "couldn't enable lvds1_gate: %d\n", error);
-               return error;
+
+       if (sc->sc_ext_osc) {
+               clk_set_parent(sc->sc_clk_pcie_ext, sc->sc_clk_pcie_ext_src);
+               error = clk_enable(sc->sc_clk_pcie_ext);
+               if (error) {
+                       aprint_error_dev(sc->sc_dev, "couldn't enable ext: %d\n", error);
+                       return error;
+               }
+       } else {
+               error = clk_enable(sc->sc_clk_lvds1_gate);
+               if (error) {
+                       aprint_error_dev(sc->sc_dev, "couldn't enable lvds1_gate: %d\n",
+                           error);
+                       return error;
+               }
        }
+
        error = clk_enable(sc->sc_clk_pcie_ref);
        if (error) {
                aprint_error_dev(sc->sc_dev, "couldn't enable pcie_ref: %d\n", error);
@@ -298,11 +308,6 @@
 
        uint32_t gpr1 = sc->sc_gpr_read(sc, IOMUX_GPR1);
 
-#if defined(IMX6DQP)
-       gpr1 &= ~IOMUX_GPR1_PCIE_SW_RST;
-       sc->sc_gpr_write(sc, IOMUX_GPR1, gpr1);
-#endif
-
        delay(50 * 1000);
 
        gpr1 &= ~IOMUX_GPR1_TEST_POWERDOWN;
@@ -317,6 +322,31 @@
        if (sc->sc_reset != NULL)
                sc->sc_reset(sc);
 
+       if (sc->sc_have_sw_reset) {
+               gpr1 &= ~IOMUX_GPR1_PCIE_SW_RST;
+               sc->sc_gpr_write(sc, IOMUX_GPR1, gpr1);
+               delay(200);
+       }
+
+       if (sc->sc_ext_osc) {
+               delay(5 * 1000);
+
+               uint32_t val;
+               val = imxpcie_phy_read(sc, PCIE_PHY_MPLL_OVRD_IN_LO);
+               val &= ~MPLL_MULTIPLIER;
+               val |= __SHIFTIN(0x19, MPLL_MULTIPLIER);
+               val |= MPLL_MULTIPLIER_OVRD;
+               imxpcie_phy_write(sc, PCIE_PHY_MPLL_OVRD_IN_LO, val);
+
+               delay(5 * 1000);
+
+               val = imxpcie_phy_read(sc, PCIE_PHY_ATEOVRD);
+               val |= REF_USB2_EN;
+               imxpcie_phy_write(sc, PCIE_PHY_ATEOVRD, val);
+
+               delay(5 * 1000);
+       }
+
        return 0;
 }
 
diff -r b5818c9afa5c -r 8c00f70431b8 sys/arch/arm/imx/imxpciereg.h
--- a/sys/arch/arm/imx/imxpciereg.h     Mon Sep 02 00:51:48 2019 +0000
+++ b/sys/arch/arm/imx/imxpciereg.h     Mon Sep 02 01:28:41 2019 +0000



Home | Main Index | Thread Index | Old Index