Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save lategoodbye/4db0ad08d1c23dfac51115d206ecbd7a to your computer and use it in GitHub Desktop.
Save lategoodbye/4db0ad08d1c23dfac51115d206ecbd7a to your computer and use it in GitHub Desktop.
Try to fix the bit errors on MX28 SSP2
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