[U-Boot] [PATCH v2 14/14] mx5/6 clocks: Fix SDHC clocks

Benoît Thébaudeau benoit.thebaudeau at advansee.com
Thu Sep 27 22:24:37 CEST 2012


The i.MX5 eSDHC clocks were considered as coming from the IPG clock although
they have dedicated clock paths.

Also, on i.MX5/6, each SDHC instance has a dedicated clock, so gd->sdhc_clk must
be set accordingly. This is good for the case only a single SDHC instance is
used (initialization made with fsl_esdhc_mmc_init()). A future patch will fix
the multi-instance use case (initialization made directly with
fsl_esdhc_initialize()).

Signed-off-by: Benoît Thébaudeau <benoit.thebaudeau at advansee.com>
Cc: Stefano Babic <sbabic at denx.de>
Cc: Eric Bénard <eric at eukrea.com>
Cc: Otavio Salvador <otavio at ossystems.com.br>
---
This patch supersedes http://patchwork.ozlabs.org/patch/177410/ .
Changes for v2:
 - Consequences from the previous cleanup patches.
 - Add detailed description.
 - Differentiate SDHC instances for gd->sdhc_clk.

 .../arch/arm/cpu/armv7/mx5/clock.c                 |   46 ++++++++++++++++++++
 .../arch/arm/imx-common/speed.c                    |   18 +++++++-
 .../arch/arm/include/asm/arch-mx5/clock.h          |    4 ++
 3 files changed, 67 insertions(+), 1 deletion(-)

diff --git u-boot-imx-e1eb75b.orig/arch/arm/cpu/armv7/mx5/clock.c u-boot-imx-e1eb75b/arch/arm/cpu/armv7/mx5/clock.c
index 3a60f8b..25362dc 100644
--- u-boot-imx-e1eb75b.orig/arch/arm/cpu/armv7/mx5/clock.c
+++ u-boot-imx-e1eb75b/arch/arm/cpu/armv7/mx5/clock.c
@@ -389,6 +389,44 @@ static u32 imx_get_cspiclk(void)
 	return ret_val;
 }
 
+/*
+ * get esdhc clock rate.
+ */
+static u32 get_esdhc_clk(u32 port)
+{
+	u32 clk_sel = 0, pred = 0, podf = 0, freq = 0;
+	u32 cscmr1 = readl(&mxc_ccm->cscmr1);
+	u32 cscdr1 = readl(&mxc_ccm->cscdr1);
+
+	switch (port) {
+	case 0:
+		clk_sel = MXC_CCM_CSCMR1_ESDHC1_MSHC1_CLK_SEL_RD(cscmr1);
+		pred = MXC_CCM_CSCDR1_ESDHC1_MSHC1_CLK_PRED_RD(cscdr1);
+		podf = MXC_CCM_CSCDR1_ESDHC1_MSHC1_CLK_PODF_RD(cscdr1);
+		break;
+	case 1:
+		clk_sel = MXC_CCM_CSCMR1_ESDHC2_MSHC2_CLK_SEL_RD(cscmr1);
+		pred = MXC_CCM_CSCDR1_ESDHC2_MSHC2_CLK_PRED_RD(cscdr1);
+		podf = MXC_CCM_CSCDR1_ESDHC2_MSHC2_CLK_PODF_RD(cscdr1);
+		break;
+	case 2:
+		if (cscmr1 & MXC_CCM_CSCMR1_ESDHC3_CLK_SEL)
+			return get_esdhc_clk(1);
+		else
+			return get_esdhc_clk(0);
+	case 3:
+		if (cscmr1 & MXC_CCM_CSCMR1_ESDHC4_CLK_SEL)
+			return get_esdhc_clk(1);
+		else
+			return get_esdhc_clk(0);
+	default:
+		break;
+	}
+
+	freq = get_standard_pll_sel_clk(clk_sel) / ((pred + 1) * (podf + 1));
+	return freq;
+}
+
 static u32 get_axi_a_clk(void)
 {
 	u32 cbcdr = readl(&mxc_ccm->cbcdr);
@@ -471,6 +509,14 @@ unsigned int mxc_get_clock(enum mxc_clock clk)
 		return get_uart_clk();
 	case MXC_CSPI_CLK:
 		return imx_get_cspiclk();
+	case MXC_ESDHC_CLK:
+		return get_esdhc_clk(0);
+	case MXC_ESDHC2_CLK:
+		return get_esdhc_clk(1);
+	case MXC_ESDHC3_CLK:
+		return get_esdhc_clk(2);
+	case MXC_ESDHC4_CLK:
+		return get_esdhc_clk(3);
 	case MXC_FEC_CLK:
 		return get_ipg_clk();
 	case MXC_SATA_CLK:
diff --git u-boot-imx-e1eb75b.orig/arch/arm/imx-common/speed.c u-boot-imx-e1eb75b/arch/arm/imx-common/speed.c
index 80989c4..fbf4de3 100644
--- u-boot-imx-e1eb75b.orig/arch/arm/imx-common/speed.c
+++ u-boot-imx-e1eb75b/arch/arm/imx-common/speed.c
@@ -36,9 +36,25 @@ int get_clocks(void)
 {
 #ifdef CONFIG_FSL_ESDHC
 #ifdef CONFIG_FSL_USDHC
+#if CONFIG_SYS_FSL_ESDHC_ADDR == USDHC2_BASE_ADDR
+	gd->sdhc_clk = mxc_get_clock(MXC_ESDHC2_CLK);
+#elif CONFIG_SYS_FSL_ESDHC_ADDR == USDHC3_BASE_ADDR
+	gd->sdhc_clk = mxc_get_clock(MXC_ESDHC3_CLK);
+#elif CONFIG_SYS_FSL_ESDHC_ADDR == USDHC4_BASE_ADDR
+	gd->sdhc_clk = mxc_get_clock(MXC_ESDHC4_CLK);
+#else
 	gd->sdhc_clk = mxc_get_clock(MXC_ESDHC_CLK);
+#endif
+#else
+#if CONFIG_SYS_FSL_ESDHC_ADDR == MMC_SDHC2_BASE_ADDR
+	gd->sdhc_clk = mxc_get_clock(MXC_ESDHC2_CLK);
+#elif CONFIG_SYS_FSL_ESDHC_ADDR == MMC_SDHC3_BASE_ADDR
+	gd->sdhc_clk = mxc_get_clock(MXC_ESDHC3_CLK);
+#elif CONFIG_SYS_FSL_ESDHC_ADDR == MMC_SDHC4_BASE_ADDR
+	gd->sdhc_clk = mxc_get_clock(MXC_ESDHC4_CLK);
 #else
-	gd->sdhc_clk = mxc_get_clock(MXC_IPG_PERCLK);
+	gd->sdhc_clk = mxc_get_clock(MXC_ESDHC_CLK);
+#endif
 #endif
 #endif
 	return 0;
diff --git u-boot-imx-e1eb75b.orig/arch/arm/include/asm/arch-mx5/clock.h u-boot-imx-e1eb75b/arch/arm/include/asm/arch-mx5/clock.h
index e4ca417..fe0d168 100644
--- u-boot-imx-e1eb75b.orig/arch/arm/include/asm/arch-mx5/clock.h
+++ u-boot-imx-e1eb75b/arch/arm/include/asm/arch-mx5/clock.h
@@ -45,6 +45,10 @@ enum mxc_clock {
 	MXC_IPG_PERCLK,
 	MXC_UART_CLK,
 	MXC_CSPI_CLK,
+	MXC_ESDHC_CLK,
+	MXC_ESDHC2_CLK,
+	MXC_ESDHC3_CLK,
+	MXC_ESDHC4_CLK,
 	MXC_FEC_CLK,
 	MXC_SATA_CLK,
 	MXC_DDR_CLK,


More information about the U-Boot mailing list