diff mbox

[U-Boot,V2,2/4] ARM: mx6: Add PCI express clock configuration

Message ID 1386996929-7085-2-git-send-email-marex@denx.de
State Superseded
Headers show

Commit Message

Marek Vasut Dec. 14, 2013, 4:55 a.m. UTC
Split the SATA clock enabling function and add PCI express clock
enabling function. The SATA clock enabling function starts up the
100MHz SATA reference PLL in ENET_PLL register, but the code can
be re-used to enable the 125MHz PCIe reference in ENET_PLL, so pull
this code into separate function. Moreover, add the PCIe clock
enabling code.

Signed-off-by: Marek Vasut <marex@denx.de>
Cc: Albert Aribaud <albert.u.boot@aribaud.net>
Cc: Eric Nelson <eric.nelson@boundarydevices.com>
Cc: Fabio Estevam <fabio.estevam@freescale.com>
Cc: Stefano Babic <sbabic@denx.de>
---
 arch/arm/cpu/armv7/mx6/clock.c        | 75 ++++++++++++++++++++++++++++++-----
 arch/arm/include/asm/arch-mx6/clock.h |  1 +
 2 files changed, 66 insertions(+), 10 deletions(-)

V2: Drop the clock teardown function, it is not needed. Instead, fix a patch
    for the Linux kernel to handle running link.

Comments

Jagan Teki Dec. 14, 2013, 5:20 a.m. UTC | #1
On Sat, Dec 14, 2013 at 10:25 AM, Marek Vasut <marex@denx.de> wrote:
> Split the SATA clock enabling function and add PCI express clock
> enabling function. The SATA clock enabling function starts up the
> 100MHz SATA reference PLL in ENET_PLL register, but the code can
> be re-used to enable the 125MHz PCIe reference in ENET_PLL, so pull
> this code into separate function. Moreover, add the PCIe clock
> enabling code.
>
> Signed-off-by: Marek Vasut <marex@denx.de>
> Cc: Albert Aribaud <albert.u.boot@aribaud.net>
> Cc: Eric Nelson <eric.nelson@boundarydevices.com>
> Cc: Fabio Estevam <fabio.estevam@freescale.com>
> Cc: Stefano Babic <sbabic@denx.de>
> ---
>  arch/arm/cpu/armv7/mx6/clock.c        | 75 ++++++++++++++++++++++++++++++-----
>  arch/arm/include/asm/arch-mx6/clock.h |  1 +
>  2 files changed, 66 insertions(+), 10 deletions(-)
>
> V2: Drop the clock teardown function, it is not needed. Instead, fix a patch
>     for the Linux kernel to handle running link.
>
> diff --git a/arch/arm/cpu/armv7/mx6/clock.c b/arch/arm/cpu/armv7/mx6/clock.c
> index 873d9d0..b25a954 100644
> --- a/arch/arm/cpu/armv7/mx6/clock.c
> +++ b/arch/arm/cpu/armv7/mx6/clock.c
> @@ -404,17 +404,12 @@ u32 imx_get_fecclk(void)
>         return decode_pll(PLL_ENET, MXC_HCLK);
>  }
>
> -int enable_sata_clock(void)
> +static int enable_enet_pll(uint32_t en)
>  {
> -       u32 reg = 0;
> -       s32 timeout = 100000;
>         struct mxc_ccm_reg *const imx_ccm
>                 = (struct mxc_ccm_reg *) CCM_BASE_ADDR;
> -
> -       /* Enable sata clock */
> -       reg = readl(&imx_ccm->CCGR5); /* CCGR5 */
> -       reg |= MXC_CCM_CCGR5_SATA_MASK;
> -       writel(reg, &imx_ccm->CCGR5);
> +       s32 timeout = 100000;
> +       u32 reg = 0;
>
>         /* Enable PLLs */
>         reg = readl(&imx_ccm->analog_pll_enet);
> @@ -429,10 +424,70 @@ int enable_sata_clock(void)
>                 return -EIO;
>         reg &= ~BM_ANADIG_PLL_SYS_BYPASS;
>         writel(reg, &imx_ccm->analog_pll_enet);
> -       reg |= BM_ANADIG_PLL_ENET_ENABLE_SATA;
> +       reg |= en;
>         writel(reg, &imx_ccm->analog_pll_enet);
> +       return 0;
> +}
>
> -       return 0 ;
> +static void ungate_sata_clock(void)
> +{
> +       struct mxc_ccm_reg *const imx_ccm =
> +               (struct mxc_ccm_reg *) CCM_BASE_ADDR;
Try to delete the space after a cast

> +
> +       /* Enable SATA clock. */
> +       setbits_le32(&imx_ccm->CCGR5, MXC_CCM_CCGR5_SATA_MASK);
> +}
> +
> +static void ungate_pcie_clock(void)
> +{
> +       struct mxc_ccm_reg *const imx_ccm =
> +               (struct mxc_ccm_reg *) CCM_BASE_ADDR;
<< same >>
diff mbox

Patch

diff --git a/arch/arm/cpu/armv7/mx6/clock.c b/arch/arm/cpu/armv7/mx6/clock.c
index 873d9d0..b25a954 100644
--- a/arch/arm/cpu/armv7/mx6/clock.c
+++ b/arch/arm/cpu/armv7/mx6/clock.c
@@ -404,17 +404,12 @@  u32 imx_get_fecclk(void)
 	return decode_pll(PLL_ENET, MXC_HCLK);
 }
 
-int enable_sata_clock(void)
+static int enable_enet_pll(uint32_t en)
 {
-	u32 reg = 0;
-	s32 timeout = 100000;
 	struct mxc_ccm_reg *const imx_ccm
 		= (struct mxc_ccm_reg *) CCM_BASE_ADDR;
-
-	/* Enable sata clock */
-	reg = readl(&imx_ccm->CCGR5); /* CCGR5 */
-	reg |= MXC_CCM_CCGR5_SATA_MASK;
-	writel(reg, &imx_ccm->CCGR5);
+	s32 timeout = 100000;
+	u32 reg = 0;
 
 	/* Enable PLLs */
 	reg = readl(&imx_ccm->analog_pll_enet);
@@ -429,10 +424,70 @@  int enable_sata_clock(void)
 		return -EIO;
 	reg &= ~BM_ANADIG_PLL_SYS_BYPASS;
 	writel(reg, &imx_ccm->analog_pll_enet);
-	reg |= BM_ANADIG_PLL_ENET_ENABLE_SATA;
+	reg |= en;
 	writel(reg, &imx_ccm->analog_pll_enet);
+	return 0;
+}
 
-	return 0 ;
+static void ungate_sata_clock(void)
+{
+	struct mxc_ccm_reg *const imx_ccm =
+		(struct mxc_ccm_reg *) CCM_BASE_ADDR;
+
+	/* Enable SATA clock. */
+	setbits_le32(&imx_ccm->CCGR5, MXC_CCM_CCGR5_SATA_MASK);
+}
+
+static void ungate_pcie_clock(void)
+{
+	struct mxc_ccm_reg *const imx_ccm =
+		(struct mxc_ccm_reg *) CCM_BASE_ADDR;
+
+	/* Enable PCIe clock. */
+	setbits_le32(&imx_ccm->CCGR4, MXC_CCM_CCGR4_PCIE_MASK);
+}
+
+int enable_sata_clock(void)
+{
+	ungate_sata_clock();
+	return enable_enet_pll(BM_ANADIG_PLL_ENET_ENABLE_SATA);
+}
+
+int enable_pcie_clock(void)
+{
+	struct anatop_regs *anatop_regs =
+		(struct anatop_regs *)ANATOP_BASE_ADDR;
+	struct mxc_ccm_reg *ccm_regs = (struct mxc_ccm_reg *)CCM_BASE_ADDR;
+
+	/*
+	 * Here be dragons!
+	 *
+	 * The register ANATOP_MISC1 is not documented in the Freescale
+	 * MX6RM. The register that is mapped in the ANATOP space and
+	 * marked as ANATOP_MISC1 is actually documented in the PMU section
+	 * of the datasheet as PMU_MISC1.
+	 *
+	 * Switch LVDS clock source to SATA (0xb), disable clock INPUT and
+	 * enable clock OUTPUT. This is important for PCI express link that
+	 * is clocked from the i.MX6.
+	 */
+#define ANADIG_ANA_MISC1_LVDSCLK1_IBEN		(1 << 12)
+#define ANADIG_ANA_MISC1_LVDSCLK1_OBEN		(1 << 10)
+#define ANADIG_ANA_MISC1_LVDS1_CLK_SEL_MASK	0x0000001F
+	clrsetbits_le32(&anatop_regs->ana_misc1,
+			ANADIG_ANA_MISC1_LVDSCLK1_IBEN |
+			ANADIG_ANA_MISC1_LVDS1_CLK_SEL_MASK,
+			ANADIG_ANA_MISC1_LVDSCLK1_OBEN | 0xb);
+
+	/* PCIe reference clock sourced from AXI. */
+	clrbits_le32(&ccm_regs->cbcmr, MXC_CCM_CBCMR_PCIE_AXI_CLK_SEL);
+
+	/* Party time! Ungate the clock to the PCIe. */
+	ungate_sata_clock();
+	ungate_pcie_clock();
+
+	return enable_enet_pll(BM_ANADIG_PLL_ENET_ENABLE_SATA |
+			       BM_ANADIG_PLL_ENET_ENABLE_PCIE);
 }
 
 unsigned int mxc_get_clock(enum mxc_clock clk)
diff --git a/arch/arm/include/asm/arch-mx6/clock.h b/arch/arm/include/asm/arch-mx6/clock.h
index 93f29a7..95b1270 100644
--- a/arch/arm/include/asm/arch-mx6/clock.h
+++ b/arch/arm/include/asm/arch-mx6/clock.h
@@ -48,6 +48,7 @@  unsigned int mxc_get_clock(enum mxc_clock clk);
 void enable_ocotp_clk(unsigned char enable);
 void enable_usboh3_clk(unsigned char enable);
 int enable_sata_clock(void);
+int enable_pcie_clock(void);
 int enable_i2c_clk(unsigned char enable, unsigned i2c_num);
 void enable_ipu_clock(void);
 int enable_fec_anatop_clock(void);