Commit 898d0d64 authored by Ansuel Smith's avatar Ansuel Smith Committed by Bjorn Andersson

clk: qcom: clk-krait: add apq/ipq8064 errata workaround

Add apq/ipq8064 errata workaround where the sec_src clock gating needs to
be disabled during switching. krait-cc compatible is not enough to
handle this and limit this workaround to apq/ipq8064. We check machine
compatible to handle this.
Signed-off-by: default avatarAnsuel Smith <ansuelsmth@gmail.com>
Reviewed-by: default avatarDmitry Baryshkov <dmitry.baryshkov@linaro.org>
Signed-off-by: default avatarBjorn Andersson <bjorn.andersson@linaro.org>
Link: https://lore.kernel.org/r/20220430054458.31321-4-ansuelsmth@gmail.com
parent df83d2c9
...@@ -18,13 +18,23 @@ ...@@ -18,13 +18,23 @@
static DEFINE_SPINLOCK(krait_clock_reg_lock); static DEFINE_SPINLOCK(krait_clock_reg_lock);
#define LPL_SHIFT 8 #define LPL_SHIFT 8
#define SECCLKAGD BIT(4)
static void __krait_mux_set_sel(struct krait_mux_clk *mux, int sel) static void __krait_mux_set_sel(struct krait_mux_clk *mux, int sel)
{ {
unsigned long flags; unsigned long flags;
u32 regval; u32 regval;
spin_lock_irqsave(&krait_clock_reg_lock, flags); spin_lock_irqsave(&krait_clock_reg_lock, flags);
regval = krait_get_l2_indirect_reg(mux->offset); regval = krait_get_l2_indirect_reg(mux->offset);
/* apq/ipq8064 Errata: disable sec_src clock gating during switch. */
if (mux->disable_sec_src_gating) {
regval |= SECCLKAGD;
krait_set_l2_indirect_reg(mux->offset, regval);
}
regval &= ~(mux->mask << mux->shift); regval &= ~(mux->mask << mux->shift);
regval |= (sel & mux->mask) << mux->shift; regval |= (sel & mux->mask) << mux->shift;
if (mux->lpl) { if (mux->lpl) {
...@@ -33,6 +43,12 @@ static void __krait_mux_set_sel(struct krait_mux_clk *mux, int sel) ...@@ -33,6 +43,12 @@ static void __krait_mux_set_sel(struct krait_mux_clk *mux, int sel)
} }
krait_set_l2_indirect_reg(mux->offset, regval); krait_set_l2_indirect_reg(mux->offset, regval);
/* apq/ipq8064 Errata: re-enabled sec_src clock gating. */
if (mux->disable_sec_src_gating) {
regval &= ~SECCLKAGD;
krait_set_l2_indirect_reg(mux->offset, regval);
}
/* Wait for switch to complete. */ /* Wait for switch to complete. */
mb(); mb();
udelay(1); udelay(1);
......
...@@ -15,6 +15,7 @@ struct krait_mux_clk { ...@@ -15,6 +15,7 @@ struct krait_mux_clk {
u8 safe_sel; u8 safe_sel;
u8 old_index; u8 old_index;
bool reparent; bool reparent;
bool disable_sec_src_gating;
struct clk_hw hw; struct clk_hw hw;
struct notifier_block clk_nb; struct notifier_block clk_nb;
......
...@@ -139,6 +139,14 @@ krait_add_sec_mux(struct device *dev, int id, const char *s, ...@@ -139,6 +139,14 @@ krait_add_sec_mux(struct device *dev, int id, const char *s,
mux->hw.init = &init; mux->hw.init = &init;
mux->safe_sel = 0; mux->safe_sel = 0;
/* Checking for qcom,krait-cc-v1 or qcom,krait-cc-v2 is not
* enough to limit this to apq/ipq8064. Directly check machine
* compatible to correctly handle this errata.
*/
if (of_machine_is_compatible("qcom,ipq8064") ||
of_machine_is_compatible("qcom,apq8064"))
mux->disable_sec_src_gating = true;
init.name = kasprintf(GFP_KERNEL, "krait%s_sec_mux", s); init.name = kasprintf(GFP_KERNEL, "krait%s_sec_mux", s);
if (!init.name) if (!init.name)
return -ENOMEM; return -ENOMEM;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment