Module Name:    src
Committed By:   hkenken
Date:           Mon Sep  2 01:28:41 UTC 2019

Modified Files:
        src/sys/arch/arm/imx: imx6_ccm.c imx6_iomuxreg.h imxpcie.c imxpciereg.h
            imxpcievar.h
        src/sys/arch/arm/imx/fdt: imx6_pcie.c

Log Message:
Add support for imx6qp-pcie.

+ Add vpcie-supply support
+ Add ext_osc support

Tested on SABRESD i.MX 6QP.


To generate a diff of this commit:
cvs rdiff -u -r1.13 -r1.14 src/sys/arch/arm/imx/imx6_ccm.c
cvs rdiff -u -r1.5 -r1.6 src/sys/arch/arm/imx/imx6_iomuxreg.h
cvs rdiff -u -r1.1 -r1.2 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.3 -r1.4 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_ccm.c
diff -u src/sys/arch/arm/imx/imx6_ccm.c:1.13 src/sys/arch/arm/imx/imx6_ccm.c:1.14
--- src/sys/arch/arm/imx/imx6_ccm.c:1.13	Tue Jul 30 11:11:15 2019
+++ src/sys/arch/arm/imx/imx6_ccm.c	Mon Sep  2 01:28:41 2019
@@ -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 @@ static struct imx6_clk imx6_clks[] = {
 
 	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 *);

Index: src/sys/arch/arm/imx/imx6_iomuxreg.h
diff -u src/sys/arch/arm/imx/imx6_iomuxreg.h:1.5 src/sys/arch/arm/imx/imx6_iomuxreg.h:1.6
--- src/sys/arch/arm/imx/imx6_iomuxreg.h:1.5	Mon Jul 22 11:44:01 2019
+++ src/sys/arch/arm/imx/imx6_iomuxreg.h	Mon Sep  2 01:28:41 2019
@@ -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 <r...@nerv.org>
@@ -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)

Index: src/sys/arch/arm/imx/imxpcie.c
diff -u src/sys/arch/arm/imx/imxpcie.c:1.1 src/sys/arch/arm/imx/imxpcie.c:1.2
--- src/sys/arch/arm/imx/imxpcie.c:1.1	Wed Jul 24 12:33:18 2019
+++ src/sys/arch/arm/imx/imxpcie.c	Mon Sep  2 01:28:41 2019
@@ -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,34 +244,32 @@ imxpcie_phy_read(struct imxpcie_softc *s
 static int
 imxpcie_assert_core_reset(struct imxpcie_softc *sc)
 {
-	uint32_t gpr1;
-	uint32_t gpr12;
+	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);
 
-	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);
 
-	/* 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);
+			gpr12 &= ~IOMUX_GPR12_APP_LTSSM_ENABLE;
+			sc->sc_gpr_write(sc, IOMUX_GPR12, gpr12);
+		}
 
-		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);
 	}
 
-#if defined(IMX6DQP)
-	gpr1 |= IOMUX_GPR1_PCIE_SW_RST;
-	sc->sc_gpr_write(sc, IOMUX_GPR1, gpr1);
-#endif
-
-	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 @@ imxpcie_deassert_core_reset(struct imxpc
 		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 @@ imxpcie_deassert_core_reset(struct imxpc
 
 	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 @@ imxpcie_deassert_core_reset(struct imxpc
 	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;
 }
 
Index: src/sys/arch/arm/imx/imxpciereg.h
diff -u src/sys/arch/arm/imx/imxpciereg.h:1.1 src/sys/arch/arm/imx/imxpciereg.h:1.2
--- src/sys/arch/arm/imx/imxpciereg.h:1.1	Wed Jul 24 12:33:18 2019
+++ src/sys/arch/arm/imx/imxpciereg.h	Mon Sep  2 01:28:41 2019
@@ -1,4 +1,4 @@
-/*	$NetBSD: imxpciereg.h,v 1.1 2019/07/24 12:33:18 hkenken Exp $	*/
+/*	$NetBSD: imxpciereg.h,v 1.2 2019/09/02 01:28:41 hkenken Exp $	*/
 
 /*
  * Copyright (c) 2015 Ryo Shimizu <r...@nerv.org>
@@ -220,8 +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 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 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.1 src/sys/arch/arm/imx/imxpcievar.h:1.2
--- src/sys/arch/arm/imx/imxpcievar.h:1.1	Wed Jul 24 12:33:18 2019
+++ src/sys/arch/arm/imx/imxpcievar.h	Mon Sep  2 01:28:41 2019
@@ -1,4 +1,4 @@
-/*	$NetBSD: imxpcievar.h,v 1.1 2019/07/24 12:33:18 hkenken Exp $	*/
+/*	$NetBSD: imxpcievar.h,v 1.2 2019/09/02 01:28:41 hkenken Exp $	*/
 
 /*
  * Copyright (c) 2019  Genetec Corporation.  All rights reserved.
@@ -54,12 +54,17 @@ struct imxpcie_softc {
 	struct clk *sc_clk_pcie_axi;
 	struct clk *sc_clk_lvds1_gate;
 	struct clk *sc_clk_pcie_ref;
+	struct clk *sc_clk_pcie_ext;
+	struct clk *sc_clk_pcie_ext_src;
+	bool sc_ext_osc;
 
 	void *sc_cookie;
 	void (* sc_pci_netbsd_configure)(void *);
 	uint32_t (* sc_gpr_read)(void *, uint32_t);
 	void (* sc_gpr_write)(void *, uint32_t, uint32_t);
 	void (* sc_reset)(void *);
+
+	bool sc_have_sw_reset;
 };
 
 struct imxpcie_ih {

Index: src/sys/arch/arm/imx/fdt/imx6_pcie.c
diff -u src/sys/arch/arm/imx/fdt/imx6_pcie.c:1.3 src/sys/arch/arm/imx/fdt/imx6_pcie.c:1.4
--- src/sys/arch/arm/imx/fdt/imx6_pcie.c:1.3	Mon Aug 19 03:45:51 2019
+++ src/sys/arch/arm/imx/fdt/imx6_pcie.c	Mon Sep  2 01:28:41 2019
@@ -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_fdt_softc {
 	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 @@ static void imx6_pcie_reset(void *);
 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 @@ imx6_pcie_match(device_t parent, cfdata_
 {
 	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 @@ imx6_pcie_attach(device_t parent, device
 	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 @@ imx6_pcie_attach(device_t parent, device
 		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);
 

Reply via email to