Created
May 7, 2017 11:45
-
-
Save lategoodbye/4db0ad08d1c23dfac51115d206ecbd7a to your computer and use it in GitHub Desktop.
Try to fix the bit errors on MX28 SSP2
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
diff --git a/drivers/clk/mxs/clk-div.c b/drivers/clk/mxs/clk-div.c | |
index f75e989..f3a8d827 100644 | |
--- a/drivers/clk/mxs/clk-div.c | |
+++ b/drivers/clk/mxs/clk-div.c | |
@@ -58,11 +58,30 @@ static int clk_div_set_rate(struct clk_hw *hw, unsigned long rate, | |
unsigned long parent_rate) | |
{ | |
struct clk_div *div = to_clk_div(hw); | |
+ u32 val; | |
int ret; | |
+ if (!strcmp(clk_hw_get_name(hw), "ssp0_div") || | |
+ !strcmp(clk_hw_get_name(hw), "ssp1_div") || | |
+ !strcmp(clk_hw_get_name(hw), "ssp2_div") || | |
+ !strcmp(clk_hw_get_name(hw), "ssp3_div")) { | |
+ val = readl_relaxed(div->reg); | |
+ if (val & (1 << 31)) { | |
+ trace_printk("Cannot to set %pC: gated\n", hw->clk); | |
+ return -EINVAL; | |
+ } | |
+ if (val & (1 << div->busy)) { | |
+ trace_printk("Cannot to set %pC: busy\n", hw->clk); | |
+ return -EBUSY; | |
+ } | |
+ } | |
+ | |
ret = div->ops->set_rate(&div->divider.hw, rate, parent_rate); | |
- if (!ret) | |
+ if (!ret) { | |
ret = mxs_clk_wait(div->reg, div->busy); | |
+ if (ret) | |
+ trace_printk("Failed to set %pC at %lu\n", hw->clk, rate); | |
+ } | |
return ret; | |
} | |
diff --git a/drivers/clk/mxs/clk-frac.c b/drivers/clk/mxs/clk-frac.c | |
index f8dd10f..8739421 100644 | |
--- a/drivers/clk/mxs/clk-frac.c | |
+++ b/drivers/clk/mxs/clk-frac.c | |
@@ -83,6 +83,7 @@ static int clk_frac_set_rate(struct clk_hw *hw, unsigned long rate, | |
unsigned long flags; | |
u32 div, val; | |
u64 tmp; | |
+ int ret; | |
if (rate > parent_rate) | |
return -EINVAL; | |
@@ -104,7 +105,12 @@ static int clk_frac_set_rate(struct clk_hw *hw, unsigned long rate, | |
spin_unlock_irqrestore(&mxs_lock, flags); | |
- return mxs_clk_wait(frac->reg, frac->busy); | |
+ ret = mxs_clk_wait(frac->reg, frac->busy); | |
+ | |
+ if (ret) | |
+ trace_printk("Failed to set %pC at %lu\n", hw->clk, rate); | |
+ | |
+ return ret; | |
} | |
static struct clk_ops clk_frac_ops = { | |
diff --git a/drivers/clk/mxs/clk-imx28.c b/drivers/clk/mxs/clk-imx28.c | |
index 6b572b7..d9eafc4 100644 | |
--- a/drivers/clk/mxs/clk-imx28.c | |
+++ b/drivers/clk/mxs/clk-imx28.c | |
@@ -110,19 +110,28 @@ static void __init clk_misc_init(void) | |
writel_relaxed(val, ENET); | |
/* | |
- * Source ssp clock from ref_io than ref_xtal, | |
- * as ref_xtal only provides 24 MHz as maximum. | |
- */ | |
- writel_relaxed(0xf << BP_CLKSEQ_BYPASS_SSP0, CLKSEQ + CLR); | |
- | |
- /* | |
* 480 MHz seems too high to be ssp clock source directly, | |
* so set frac0 to get a 288 MHz ref_io0 and ref_io1. | |
*/ | |
val = readl_relaxed(FRAC0); | |
- val &= ~((0x3f << BP_FRAC0_IO0FRAC) | (0x3f << BP_FRAC0_IO1FRAC)); | |
- val |= (30 << BP_FRAC0_IO0FRAC) | (30 << BP_FRAC0_IO1FRAC); | |
+ val &= ~(0x3f << BP_FRAC0_IO0FRAC); | |
+ val |= 30 << BP_FRAC0_IO0FRAC; | |
writel_relaxed(val, FRAC0); | |
+ | |
+ cpu_relax(); | |
+ | |
+ val = readl_relaxed(FRAC0); | |
+ val &= ~(0x3f << BP_FRAC0_IO1FRAC); | |
+ val |= 30 << BP_FRAC0_IO1FRAC; | |
+ writel_relaxed(val, FRAC0); | |
+ | |
+ cpu_relax(); | |
+ | |
+ /* | |
+ * Source ssp clock from ref_io than ref_xtal, | |
+ * as ref_xtal only provides 24 MHz as maximum. | |
+ */ | |
+ writel_relaxed(0xf << BP_CLKSEQ_BYPASS_SSP0, CLKSEQ + CLR); | |
} | |
static const char *const sel_cpu[] __initconst = { "ref_cpu", "ref_xtal", }; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment