summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRanjani Vaidyanathan-RA5478 <Ranjani.Vaidyanathan@freescale.com>2010-04-27 11:04:37 -0500
committerAlejandro Gonzalez <alex.gonzalez@digi.com>2010-05-25 11:20:26 +0200
commit71b9acc6131c4ac2cf4d4a94180ce9c010c875b4 (patch)
treeb5cb81429a74294ac313e353e78265a907acdf96
parent2ee51538f7ab45f4f0184930c3afdfbce5820d66 (diff)
ENGR00122920: Fix failure to boot from MMC slot 0 on MX51.
Disabling PLL3 was causing failure to boot from MMC slot0. Move SDHC clocks to be sourced from PLL2 instead of PLL3. Signed-off-by: Ranjani Vaidyanathan-RA5478 <Ranjani.Vaidyanathan@freescale.com> Signed-off-by: Alejandro Gonzalez <alex.gonzalez@digi.com>
-rw-r--r--arch/arm/mach-mx5/bus_freq.c10
-rw-r--r--arch/arm/mach-mx5/clock.c67
2 files changed, 59 insertions, 18 deletions
diff --git a/arch/arm/mach-mx5/bus_freq.c b/arch/arm/mach-mx5/bus_freq.c
index cf957ea7ba54..4ab60ec6386d 100644
--- a/arch/arm/mach-mx5/bus_freq.c
+++ b/arch/arm/mach-mx5/bus_freq.c
@@ -114,6 +114,8 @@ int set_low_bus_freq(void)
/* Set PLL3 to 133Mhz if no-one is using it. */
if (clk_get_usecount(pll3) == 0) {
u32 pll3_rate = clk_get_rate(pll3);
+
+ clk_enable(pll3);
clk_set_rate(pll3, clk_round_rate(pll3, 133000000));
/* Set the parent of Periph_apm_clk to be PLL3 */
clk_set_parent(periph_apm_clk, pll3);
@@ -146,6 +148,8 @@ int set_low_bus_freq(void)
/* Set PLL3 back to original rate. */
clk_set_rate(pll3, clk_round_rate(pll3, pll3_rate));
+ clk_disable(pll3);
+
low_bus_freq_mode = 1;
high_bus_freq_mode = 0;
}
@@ -164,6 +168,8 @@ int set_high_bus_freq(int high_bus_freq)
/* Relock PLL3 to 133MHz */
if (clk_get_usecount(pll3) == 0) {
u32 pll3_rate = clk_get_rate(pll3);
+
+ clk_enable(pll3);
clk_set_rate(pll3,
clk_round_rate(pll3, 133000000));
clk_set_parent(periph_apm_clk, pll3);
@@ -184,16 +190,18 @@ int set_high_bus_freq(int high_bus_freq)
clk_enable(emi_garb_clk);
while (__raw_readl(MXC_CCM_CDHIPR) & 0x1F)
udelay(10);
- clk_disable(emi_garb_clk);
low_bus_freq_mode = 0;
high_bus_freq_mode = 1;
+ clk_disable(emi_garb_clk);
/*Set the main_bus_clk parent to be PLL2. */
clk_set_parent(main_bus_clk, pll2);
+
/* Relock PLL3 to its original rate */
clk_set_rate(pll3,
clk_round_rate(pll3, pll3_rate));
+ clk_disable(pll3);
}
/*Change the DDR freq to 200MHz*/
diff --git a/arch/arm/mach-mx5/clock.c b/arch/arm/mach-mx5/clock.c
index e6723f2c6f0e..7c6f614bf97f 100644
--- a/arch/arm/mach-mx5/clock.c
+++ b/arch/arm/mach-mx5/clock.c
@@ -116,7 +116,6 @@ static int _clk_enable(struct clk *clk)
else if (clk->flags & AHB_MED_SET_POINT)
lp_med_freq++;
-
return 0;
}
@@ -2817,24 +2816,22 @@ static int _clk_sdhc1_set_rate(struct clk *clk, unsigned long rate)
u32 div;
u32 pre, post;
- if (cpu_is_mx53()) {
- div = clk->parent->rate / rate;
+ div = clk->parent->rate / rate;
- if ((clk->parent->rate / div) != rate)
- return -EINVAL;
+ if ((clk->parent->rate / div) != rate)
+ return -EINVAL;
- __calc_pre_post_dividers(div, &pre, &post);
+ __calc_pre_post_dividers(div, &pre, &post);
- /* Set sdhc1 clock divider */
- reg = __raw_readl(MXC_CCM_CSCDR1) &
- ~(MXC_CCM_CSCDR1_ESDHC1_MSHC2_CLK_PRED_MASK |
- MXC_CCM_CSCDR1_ESDHC1_MSHC2_CLK_PODF_MASK);
- reg |= (post - 1) << MXC_CCM_CSCDR1_ESDHC1_MSHC2_CLK_PODF_OFFSET;
- reg |= (pre - 1) << MXC_CCM_CSCDR1_ESDHC1_MSHC2_CLK_PRED_OFFSET;
- __raw_writel(reg, MXC_CCM_CSCDR1);
+ /* Set sdhc1 clock divider */
+ reg = __raw_readl(MXC_CCM_CSCDR1) &
+ ~(MXC_CCM_CSCDR1_ESDHC1_MSHC2_CLK_PRED_MASK |
+ MXC_CCM_CSCDR1_ESDHC1_MSHC2_CLK_PODF_MASK);
+ reg |= (post - 1) << MXC_CCM_CSCDR1_ESDHC1_MSHC2_CLK_PODF_OFFSET;
+ reg |= (pre - 1) << MXC_CCM_CSCDR1_ESDHC1_MSHC2_CLK_PRED_OFFSET;
+ __raw_writel(reg, MXC_CCM_CSCDR1);
- clk->rate = rate;
- }
+ clk->rate = rate;
return 0;
}
@@ -2904,13 +2901,40 @@ static int _clk_esdhc2_set_parent(struct clk *clk, struct clk *parent)
reg |= MXC_CCM_CSCMR1_ESDHC2_CLK_SEL;
else
BUG();
-
}
-
__raw_writel(reg, MXC_CCM_CSCMR1);
return 0;
}
+static int _clk_esdhc2_set_rate(struct clk *clk, unsigned long rate)
+{
+ u32 reg;
+ u32 div;
+ u32 pre, post;
+
+ if (cpu_is_mx51()) {
+ div = clk->parent->rate / rate;
+
+ if ((clk->parent->rate / div) != rate)
+ return -EINVAL;
+
+ __calc_pre_post_dividers(div, &pre, &post);
+
+ /* Set sdhc1 clock divider */
+ reg = __raw_readl(MXC_CCM_CSCDR1) &
+ ~(MXC_CCM_CSCDR1_ESDHC2_MSHC2_CLK_PRED_MASK |
+ MXC_CCM_CSCDR1_ESDHC2_MSHC2_CLK_PODF_MASK);
+ reg |= (post - 1) <<
+ MXC_CCM_CSCDR1_ESDHC2_MSHC2_CLK_PODF_OFFSET;
+ reg |= (pre - 1) <<
+ MXC_CCM_CSCDR1_ESDHC2_MSHC2_CLK_PRED_OFFSET;
+ __raw_writel(reg, MXC_CCM_CSCDR1);
+
+ clk->rate = rate;
+ }
+ return 0;
+}
+
static struct clk esdhc2_clk[] = {
{
.name = "esdhc_clk",
@@ -4165,6 +4189,7 @@ int __init mx51_clocks_init(unsigned long ckil, unsigned long osc, unsigned long
/* Fix up clocks unique to MX51. */
esdhc2_clk[0].recalc = _clk_esdhc2_recalc;
+ esdhc2_clk[0].set_rate = _clk_esdhc2_set_rate;
clk_tree_init();
@@ -4238,6 +4263,13 @@ int __init mx51_clocks_init(unsigned long ckil, unsigned long osc, unsigned long
clk_enable(&cpu_clk);
+ /* Set SDHC parents to be PLL2 */
+ clk_set_parent(&esdhc1_clk[0], &pll2_sw_clk);
+ clk_set_parent(&esdhc2_clk[0], &pll2_sw_clk);
+
+ /* set SDHC root clock as 166.25MHZ*/
+ clk_set_rate(&esdhc1_clk[0], 166250000);
+ clk_set_rate(&esdhc2_clk[0], 166250000);
/* Initialise the parents to be axi_b, parents are set to
* axi_a when the clocks are enabled.
@@ -4403,6 +4435,7 @@ int __init mx51_clocks_init(unsigned long ckil, unsigned long osc, unsigned long
propagate_rate(&osc_clk);
propagate_rate(&pll1_sw_clk);
propagate_rate(&pll2_sw_clk);
+ propagate_rate(&pll3_sw_clk);
clk_set_parent(&emi_slow_clk, &ahb_clk);
clk_set_rate(&emi_slow_clk, clk_round_rate(&emi_slow_clk, 130000000));