diff options
author | Ranjani Vaidyanathan-RA5478 <Ranjani.Vaidyanathan@freescale.com> | 2010-04-27 11:04:37 -0500 |
---|---|---|
committer | Alejandro Gonzalez <alex.gonzalez@digi.com> | 2010-05-25 11:20:26 +0200 |
commit | 71b9acc6131c4ac2cf4d4a94180ce9c010c875b4 (patch) | |
tree | b5cb81429a74294ac313e353e78265a907acdf96 | |
parent | 2ee51538f7ab45f4f0184930c3afdfbce5820d66 (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.c | 10 | ||||
-rw-r--r-- | arch/arm/mach-mx5/clock.c | 67 |
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)); |