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);