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;

Reply via email to