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 <[email protected]>
@@ -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;