Module Name: src Committed By: hkenken Date: Wed Oct 16 11:16:31 UTC 2019
Modified Files: src/sys/arch/arm/imx: imx6_pcie.c imxpcie.c imxpciereg.h imxpcievar.h src/sys/arch/arm/imx/fdt: imx6_pcie.c Log Message: Fixed bug when using PCIe external clock. To generate a diff of this commit: cvs rdiff -u -r1.13 -r1.14 src/sys/arch/arm/imx/imx6_pcie.c cvs rdiff -u -r1.2 -r1.3 src/sys/arch/arm/imx/imxpcie.c \ src/sys/arch/arm/imx/imxpciereg.h src/sys/arch/arm/imx/imxpcievar.h cvs rdiff -u -r1.4 -r1.5 src/sys/arch/arm/imx/fdt/imx6_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/imx/imx6_pcie.c diff -u src/sys/arch/arm/imx/imx6_pcie.c:1.13 src/sys/arch/arm/imx/imx6_pcie.c:1.14 --- src/sys/arch/arm/imx/imx6_pcie.c:1.13 Sat Jul 27 08:02:04 2019 +++ src/sys/arch/arm/imx/imx6_pcie.c Wed Oct 16 11:16:30 2019 @@ -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_pcie_attach(device_t parent, device 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; } Index: src/sys/arch/arm/imx/imxpcie.c diff -u src/sys/arch/arm/imx/imxpcie.c:1.2 src/sys/arch/arm/imx/imxpcie.c:1.3 --- src/sys/arch/arm/imx/imxpcie.c:1.2 Mon Sep 2 01:28:41 2019 +++ src/sys/arch/arm/imx/imxpcie.c Wed Oct 16 11:16:30 2019 @@ -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 @@ imxpcie_init_phy(struct imxpcie_softc *s 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 @@ imxpcie_phy_read(struct imxpcie_softc *s 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,13 +264,13 @@ imxpcie_assert_core_reset(struct imxpcie 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 @@ imxpcie_deassert_core_reset(struct imxpc { 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,25 +328,41 @@ imxpcie_deassert_core_reset(struct imxpc 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); + 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)); - delay(5 * 1000); + 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; } + 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_CLKDIV2; + val |= __SHIFTIN(div, REF_CLKDIV2); + val |= ATEOVRD_EN; + imxpcie_phy_write(sc, PCIE_PHY_ATEOVRD, val); + return 0; } Index: src/sys/arch/arm/imx/imxpciereg.h diff -u src/sys/arch/arm/imx/imxpciereg.h:1.2 src/sys/arch/arm/imx/imxpciereg.h:1.3 --- src/sys/arch/arm/imx/imxpciereg.h:1.2 Mon Sep 2 01:28:41 2019 +++ src/sys/arch/arm/imx/imxpciereg.h Wed Oct 16 11:16:30 2019 @@ -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 <r...@nerv.org> @@ -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) #define PCIE_PHY_SSC_OVRD_IN 0x0013 #define PCIE_PHY_BS_OVRD_IN 0x0014 #define PCIE_PHY_LEVEL_OVRD_IN 0x0015 Index: src/sys/arch/arm/imx/imxpcievar.h diff -u src/sys/arch/arm/imx/imxpcievar.h:1.2 src/sys/arch/arm/imx/imxpcievar.h:1.3 --- src/sys/arch/arm/imx/imxpcievar.h:1.2 Mon Sep 2 01:28:41 2019 +++ src/sys/arch/arm/imx/imxpcievar.h Wed Oct 16 11:16:30 2019 @@ -1,4 +1,4 @@ -/* $NetBSD: imxpcievar.h,v 1.2 2019/09/02 01:28:41 hkenken Exp $ */ +/* $NetBSD: imxpcievar.h,v 1.3 2019/10/16 11:16:30 hkenken Exp $ */ /* * Copyright (c) 2019 Genetec Corporation. All rights reserved. @@ -51,9 +51,9 @@ struct imxpcie_softc { kmutex_t sc_lock; u_int sc_intrgen; - struct clk *sc_clk_pcie_axi; - struct clk *sc_clk_lvds1_gate; - struct clk *sc_clk_pcie_ref; + struct clk *sc_clk_pcie; + struct clk *sc_clk_pcie_bus; + struct clk *sc_clk_pcie_phy; struct clk *sc_clk_pcie_ext; struct clk *sc_clk_pcie_ext_src; bool sc_ext_osc; Index: src/sys/arch/arm/imx/fdt/imx6_pcie.c diff -u src/sys/arch/arm/imx/fdt/imx6_pcie.c:1.4 src/sys/arch/arm/imx/fdt/imx6_pcie.c:1.5 --- src/sys/arch/arm/imx/fdt/imx6_pcie.c:1.4 Mon Sep 2 01:28:41 2019 +++ src/sys/arch/arm/imx/fdt/imx6_pcie.c Wed Oct 16 11:16:30 2019 @@ -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 @@ imx6_pcie_attach(device_t parent, device 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 @@ imx6_pcie_attach(device_t parent, device 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;