summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFrank Li <Frank.Li@freescale.com>2010-05-08 11:47:40 +0800
committerFrank Li <Frank.Li@freescale.com>2010-05-08 12:06:14 +0800
commitb6645c2facc50ac1d2024c543359caa04d7f9ac4 (patch)
treec36894a0e96408b14de67e26b833f8d74182ac0f
parentecef5c763b5dcf1b4fe70a6f68b91c4d4b6ea718 (diff)
ENGR00123293 iMX23 fix ssp clock is too slow
bypass bit set to wrong possition. So ssp alays use xtal. mmc use ssp module divider instead of ssp clock source Signed-off-by: Frank Li <Frank.Li@freescale.com>
-rw-r--r--arch/arm/mach-mx23/clock.c22
-rw-r--r--arch/arm/mach-mx23/device.c6
2 files changed, 23 insertions, 5 deletions
diff --git a/arch/arm/mach-mx23/clock.c b/arch/arm/mach-mx23/clock.c
index 333016c62f83..3edc90ffe9e9 100644
--- a/arch/arm/mach-mx23/clock.c
+++ b/arch/arm/mach-mx23/clock.c
@@ -145,6 +145,16 @@ static int local_clk_enable(struct clk *clk)
}
+static bool mx23_is_clk_enabled(struct clk *clk)
+{
+ if (clk->enable_reg)
+ return (__raw_readl(clk->enable_reg) &
+ clk->enable_bits) ? 0 : 1;
+ else
+ return (clk->ref & CLK_EN_MASK) ? 1 : 0;
+}
+
+
static int mx23_raw_enable(struct clk *clk)
{
unsigned int reg;
@@ -1113,7 +1123,7 @@ static struct clk emi_clk = {
.busy_bits = 28,
.xtal_busy_bits = 29,
.bypass_reg = CLKCTRL_BASE_ADDR + HW_CLKCTRL_CLKSEQ,
- .bypass_bits = 7,
+ .bypass_bits = 6,
};
static unsigned long ssp_get_rate(struct clk *clk);
@@ -1122,8 +1132,11 @@ static int ssp_set_rate(struct clk *clk, unsigned long rate)
{
int ret = -EINVAL;
u32 reg, div;
+ bool is_clk_enable;
- local_clk_enable(clk);
+ is_clk_enable = mx23_is_clk_enabled(clk);
+ if (!is_clk_enable)
+ local_clk_enable(clk);
/* if the desired clock can be sourced from ref_xtal,
* use ref_xtal to save power
@@ -1149,7 +1162,8 @@ static int ssp_set_rate(struct clk *clk, unsigned long rate)
ret = clk_busy_wait(clk);
out:
- local_clk_disable(clk);
+ if (!is_clk_enable)
+ local_clk_disable(clk);
if (ret != 0)
printk(KERN_ERR "%s: error %d\n", __func__, ret);
@@ -1208,7 +1222,7 @@ static struct clk ssp_clk = {
.scale_reg = CLKCTRL_BASE_ADDR + HW_CLKCTRL_SSP,
.scale_bits = 0,
.bypass_reg = CLKCTRL_BASE_ADDR + HW_CLKCTRL_CLKSEQ,
- .bypass_bits = 3,
+ .bypass_bits = 5,
.set_rate = ssp_set_rate,
.set_parent = ssp_set_parent,
.set_sys_dependent_parent = ssp_set_sys_dependent_parent,
diff --git a/arch/arm/mach-mx23/device.c b/arch/arm/mach-mx23/device.c
index 9eb25857d972..814c4ef59266 100644
--- a/arch/arm/mach-mx23/device.c
+++ b/arch/arm/mach-mx23/device.c
@@ -613,7 +613,11 @@ static struct mxs_mmc_platform_data mx23_mmc0_data = {
.hw_release = mxs_mmc_hw_release_mmc0,
.get_wp = mxs_mmc_get_wp_mmc0,
.cmd_pullup = mxs_mmc_cmd_pullup_mmc0,
- .setclock = mxs_mmc_setclock_mmc0,
+ /*
+ Don't change ssp clock because ssp1 and ssp2 share one ssp clock source
+ ssp module have own divider.
+ .setclock = mxs_mmc_setclock_mmc0,
+ */
.caps = MMC_CAP_4_BIT_DATA,
.min_clk = 400000,
.max_clk = 48000000,