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 Fixed bug when using PCIe external clock.



details:   https://anonhg.NetBSD.org/src/rev/878ef1bb7f61
branches:  trunk
changeset: 464667:878ef1bb7f61
user:      hkenken <hkenken%NetBSD.org@localhost>
date:      Wed Oct 16 11:16:30 2019 +0000

description:
Fixed bug when using PCIe external clock.

diffstat:

 sys/arch/arm/imx/fdt/imx6_pcie.c |  28 ++++----------
 sys/arch/arm/imx/imx6_pcie.c     |  22 +++++-----
 sys/arch/arm/imx/imxpcie.c       |  76 ++++++++++++++++++++++++---------------
 sys/arch/arm/imx/imxpciereg.h    |  28 +++++++-------
 sys/arch/arm/imx/imxpcievar.h    |   8 ++--
 5 files changed, 83 insertions(+), 79 deletions(-)

diffs (truncated from 325 to 300 lines):

diff -r 772efcbce5e5 -r 878ef1bb7f61 sys/arch/arm/imx/fdt/imx6_pcie.c
--- a/sys/arch/arm/imx/fdt/imx6_pcie.c  Wed Oct 16 07:42:22 2019 +0000
+++ b/sys/arch/arm/imx/fdt/imx6_pcie.c  Wed Oct 16 11:16:30 2019 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: imx6_pcie.c,v 1.4 2019/09/02 01:28:41 hkenken Exp $    */
+/*     $NetBSD: imx6_pcie.c,v 1.5 2019/10/16 11:16:30 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.4 2019/09/02 01:28:41 hkenken Exp $");
+__KERNEL_RCSID(0, "$NetBSD: imx6_pcie.c,v 1.5 2019/10/16 11:16:30 hkenken Exp $");
 
 #include "opt_pci.h"
 #include "opt_fdt.h"
@@ -158,18 +158,18 @@
                return;
        }
 
-       sc->sc_clk_pcie_axi = fdtbus_clock_get(phandle, "pcie");
-       if (sc->sc_clk_pcie_axi == NULL) {
+       sc->sc_clk_pcie = fdtbus_clock_get(phandle, "pcie");
+       if (sc->sc_clk_pcie == NULL) {
                aprint_error(": couldn't get clock pcie_axi\n");
                return;
        }
-       sc->sc_clk_lvds1_gate = fdtbus_clock_get(phandle, "pcie_bus");
-       if (sc->sc_clk_lvds1_gate == NULL) {
+       sc->sc_clk_pcie_bus = fdtbus_clock_get(phandle, "pcie_bus");
+       if (sc->sc_clk_pcie_bus == NULL) {
                aprint_error(": couldn't get clock lvds1_gate\n");
                return;
        }
-       sc->sc_clk_pcie_ref = fdtbus_clock_get(phandle, "pcie_phy");
-       if (sc->sc_clk_pcie_ref == NULL) {
+       sc->sc_clk_pcie_phy = fdtbus_clock_get(phandle, "pcie_phy");
+       if (sc->sc_clk_pcie_phy == NULL) {
                aprint_error(": couldn't get clock pcie_ref\n");
                return;
        }
@@ -198,18 +198,6 @@
                        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;
diff -r 772efcbce5e5 -r 878ef1bb7f61 sys/arch/arm/imx/imx6_pcie.c
--- a/sys/arch/arm/imx/imx6_pcie.c      Wed Oct 16 07:42:22 2019 +0000
+++ b/sys/arch/arm/imx/imx6_pcie.c      Wed Oct 16 11:16:30 2019 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: imx6_pcie.c,v 1.13 2019/07/27 08:02:04 skrll Exp $     */
+/*     $NetBSD: imx6_pcie.c,v 1.14 2019/10/16 11:16:30 hkenken Exp $   */
 
 /*
  * Copyright (c) 2016  Genetec Corporation.  All rights reserved.
@@ -31,7 +31,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: imx6_pcie.c,v 1.13 2019/07/27 08:02:04 skrll Exp $");
+__KERNEL_RCSID(0, "$NetBSD: imx6_pcie.c,v 1.14 2019/10/16 11:16:30 hkenken Exp $");
 
 #include "opt_pci.h"
 
@@ -151,19 +151,19 @@
        imx6_set_gpio(self, "imxpcie-reset-gpio", &ipsc->sc_gpio_reset,
            &ipsc->sc_gpio_reset_active, GPIO_PIN_OUTPUT);
 
-       sc->sc_clk_pcie_axi = imx6_get_clock("pcie_axi");
-       if (sc->sc_clk_pcie_axi == NULL) {
-               aprint_error(": couldn't get clock pcie_axi\n");
+       sc->sc_clk_pcie = imx6_get_clock("pcie_axi");
+       if (sc->sc_clk_pcie == NULL) {
+               aprint_error(": couldn't get clock pcie\n");
                return;
        }
-       sc->sc_clk_lvds1_gate = imx6_get_clock("lvds1_gate");
-       if (sc->sc_clk_lvds1_gate == NULL) {
-               aprint_error(": couldn't get clock lvds1_gate\n");
+       sc->sc_clk_pcie_bus = imx6_get_clock("lvds1_gate");
+       if (sc->sc_clk_pcie_bus == NULL) {
+               aprint_error(": couldn't get clock pcie_bus\n");
                return;
        }
-       sc->sc_clk_pcie_ref = imx6_get_clock("pcie_ref_125m");
-       if (sc->sc_clk_pcie_ref == NULL) {
-               aprint_error(": couldn't get clock pcie_ref\n");
+       sc->sc_clk_pcie_phy = imx6_get_clock("pcie_ref_125m");
+       if (sc->sc_clk_pcie_phy == NULL) {
+               aprint_error(": couldn't get clock pcie_phy\n");
                return;
        }
 
diff -r 772efcbce5e5 -r 878ef1bb7f61 sys/arch/arm/imx/imxpcie.c
--- a/sys/arch/arm/imx/imxpcie.c        Wed Oct 16 07:42:22 2019 +0000
+++ b/sys/arch/arm/imx/imxpcie.c        Wed Oct 16 11:16:30 2019 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: imxpcie.c,v 1.2 2019/09/02 01:28:41 hkenken Exp $      */
+/*     $NetBSD: imxpcie.c,v 1.3 2019/10/16 11:16:30 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.2 2019/09/02 01:28:41 hkenken Exp $");
+__KERNEL_RCSID(0, "$NetBSD: imxpcie.c,v 1.3 2019/10/16 11:16:30 hkenken Exp $");
 
 #include "opt_pci.h"
 #include "opt_fdt.h"
@@ -133,6 +133,7 @@
        v |= __SHIFTIN(20, IOMUX_GPR8_PCS_TX_DEEMPH_GEN1);
        sc->sc_gpr_write(sc, IOMUX_GPR8, v);
 
+       v = sc->sc_gpr_read(sc, IOMUX_GPR12);
        v &= ~IOMUX_GPR12_DEVICE_TYPE;
        v |= IOMUX_GPR12_DEVICE_TYPE_PCIE_RC;
        sc->sc_gpr_write(sc, IOMUX_GPR12, v);
@@ -244,12 +245,12 @@
 static int
 imxpcie_assert_core_reset(struct imxpcie_softc *sc)
 {
+       uint32_t gpr1 = sc->sc_gpr_read(sc, IOMUX_GPR1);
+
        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);
 
                /* already enabled by bootloader */
@@ -263,12 +264,12 @@
                        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;
 }
@@ -278,29 +279,28 @@
 {
        int error;
 
-       error = clk_enable(sc->sc_clk_pcie_axi);
+       error = clk_enable(sc->sc_clk_pcie);
        if (error) {
-               aprint_error_dev(sc->sc_dev, "couldn't enable pcie_axi: %d\n", error);
+               aprint_error_dev(sc->sc_dev, "couldn't enable pcie: %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);
+               error = clk_enable(sc->sc_clk_pcie_bus);
                if (error) {
-                       aprint_error_dev(sc->sc_dev, "couldn't enable lvds1_gate: %d\n",
+                       aprint_error_dev(sc->sc_dev, "couldn't enable pcie_bus: %d\n",
                            error);
                        return error;
                }
        }
 
-       error = clk_enable(sc->sc_clk_pcie_ref);
+       error = clk_enable(sc->sc_clk_pcie_phy);
        if (error) {
                aprint_error_dev(sc->sc_dev, "couldn't enable pcie_ref: %d\n", error);
                return error;
@@ -328,24 +328,40 @@
                delay(200);
        }
 
-       if (sc->sc_ext_osc) {
-               delay(5 * 1000);
+       uint64_t rate;
+       if (sc->sc_ext_osc)
+               rate = clk_get_rate(sc->sc_clk_pcie_ext);
+       else
+               rate = clk_get_rate(sc->sc_clk_pcie_phy);
+       aprint_normal_dev(sc->sc_dev, "PCIe ref clk %d MHz\n", (int)(rate / 1000 / 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);
+       int mult;
+       int div;
+       if (rate == 100000000) {
+               mult = 25;
+               div = 0;
+       } else if (rate == 125000000) {
+               mult = 40;
+               div = 1;
+       } else if (rate == 200000000) {
+               mult = 25;
+               div = 1;
+       } else {
+               return -1;
+       }
 
-               delay(5 * 1000);
+       uint32_t val;
+       val = imxpcie_phy_read(sc, PCIE_PHY_MPLL_OVRD_IN_LO);
+       val &= ~MPLL_MULTIPLIER;
+       val |= __SHIFTIN(mult, MPLL_MULTIPLIER);
+       val |= MPLL_MULTIPLIER_OVRD;
+       imxpcie_phy_write(sc, PCIE_PHY_MPLL_OVRD_IN_LO, val);
 
-               val = imxpcie_phy_read(sc, PCIE_PHY_ATEOVRD);
-               val |= REF_USB2_EN;
-               imxpcie_phy_write(sc, PCIE_PHY_ATEOVRD, val);
-
-               delay(5 * 1000);
-       }
+       val = imxpcie_phy_read(sc, PCIE_PHY_ATEOVRD);
+       val &= ~REF_CLKDIV2;
+       val |= __SHIFTIN(div, REF_CLKDIV2);
+       val |= ATEOVRD_EN;
+       imxpcie_phy_write(sc, PCIE_PHY_ATEOVRD, val);
 
        return 0;
 }
diff -r 772efcbce5e5 -r 878ef1bb7f61 sys/arch/arm/imx/imxpciereg.h
--- a/sys/arch/arm/imx/imxpciereg.h     Wed Oct 16 07:42:22 2019 +0000
+++ b/sys/arch/arm/imx/imxpciereg.h     Wed Oct 16 11:16:30 2019 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: imxpciereg.h,v 1.2 2019/09/02 01:28:41 hkenken Exp $   */
+/*     $NetBSD: imxpciereg.h,v 1.3 2019/10/16 11:16:30 hkenken Exp $   */
 
 /*
  * Copyright (c) 2015 Ryo Shimizu <ryo%nerv.org@localhost>
@@ -220,21 +220,21 @@
 #define PCIE_PHY_SS_PHASE                      0x0005
 #define PCIE_PHY_SS_FREQ                       0x0006
 #define PCIE_PHY_ATEOVRD                       0x0010
-#define  ATEOVRD_EN            __BIT(3)
-#define  REF_USB2_EN           __BIT(2)
-#define  REF_CLKDIV2           __BIT(1)
+#define  ATEOVRD_EN                            __BIT(2)
+#define  REF_USB2_EN                           __BIT(1)
+#define  REF_CLKDIV2                           __BIT(0)
 #define PCIE_PHY_MPLL_OVRD_IN_LO               0x0011
 #define PCIE_PHY_MPLL_OVRD_IN_HI               0x0011
-#define  RES_ACK_IN_OVRD       __BIT(15)
-#define  RES_ACK_IN            __BIT(14)
-#define  RES_REQ_IN_OVRD       __BIT(13)
-#define  RES_REQ_IN            __BIT(12)
-#define  RTUNE_REQ_OVRD                __BIT(11)
-#define  RTUNE_REQ             __BIT(10)
-#define  MPLL_MULTIPLIER_OVRD  __BIT(9)
-#define  MPLL_MULTIPLIER       __BITS(8, 2)
-#define  MPLL_EN_OVRD          __BIT(1)
-#define  MPLL_EN               __BIT(0)
+#define  RES_ACK_IN_OVRD                       __BIT(15)
+#define  RES_ACK_IN                            __BIT(14)
+#define  RES_REQ_IN_OVRD                       __BIT(13)
+#define  RES_REQ_IN                            __BIT(12)
+#define  RTUNE_REQ_OVRD                                __BIT(11)
+#define  RTUNE_REQ                             __BIT(10)
+#define  MPLL_MULTIPLIER_OVRD                  __BIT(9)
+#define  MPLL_MULTIPLIER                       __BITS(8, 2)
+#define  MPLL_EN_OVRD                          __BIT(1)
+#define  MPLL_EN                               __BIT(0)



Home | Main Index | Thread Index | Old Index