Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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: Ansuel Smith <ansuelsmth@gmail.com>
Reviewed-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
Signed-off-by: Bjorn Andersson <bjorn.andersson@linaro.org>
Link: https://lore.kernel.org/r/20220430054458.31321-4-ansuelsmth@gmail.com

authored by

Ansuel Smith and committed by
Bjorn Andersson
898d0d64 df83d2c9

+25
+16
drivers/clk/qcom/clk-krait.c
··· 18 18 static DEFINE_SPINLOCK(krait_clock_reg_lock); 19 19 20 20 #define LPL_SHIFT 8 21 + #define SECCLKAGD BIT(4) 22 + 21 23 static void __krait_mux_set_sel(struct krait_mux_clk *mux, int sel) 22 24 { 23 25 unsigned long flags; 24 26 u32 regval; 25 27 26 28 spin_lock_irqsave(&krait_clock_reg_lock, flags); 29 + 27 30 regval = krait_get_l2_indirect_reg(mux->offset); 31 + 32 + /* apq/ipq8064 Errata: disable sec_src clock gating during switch. */ 33 + if (mux->disable_sec_src_gating) { 34 + regval |= SECCLKAGD; 35 + krait_set_l2_indirect_reg(mux->offset, regval); 36 + } 37 + 28 38 regval &= ~(mux->mask << mux->shift); 29 39 regval |= (sel & mux->mask) << mux->shift; 30 40 if (mux->lpl) { ··· 42 32 regval |= (sel & mux->mask) << (mux->shift + LPL_SHIFT); 43 33 } 44 34 krait_set_l2_indirect_reg(mux->offset, regval); 35 + 36 + /* apq/ipq8064 Errata: re-enabled sec_src clock gating. */ 37 + if (mux->disable_sec_src_gating) { 38 + regval &= ~SECCLKAGD; 39 + krait_set_l2_indirect_reg(mux->offset, regval); 40 + } 45 41 46 42 /* Wait for switch to complete. */ 47 43 mb();
+1
drivers/clk/qcom/clk-krait.h
··· 15 15 u8 safe_sel; 16 16 u8 old_index; 17 17 bool reparent; 18 + bool disable_sec_src_gating; 18 19 19 20 struct clk_hw hw; 20 21 struct notifier_block clk_nb;
+8
drivers/clk/qcom/krait-cc.c
··· 139 139 mux->hw.init = &init; 140 140 mux->safe_sel = 0; 141 141 142 + /* Checking for qcom,krait-cc-v1 or qcom,krait-cc-v2 is not 143 + * enough to limit this to apq/ipq8064. Directly check machine 144 + * compatible to correctly handle this errata. 145 + */ 146 + if (of_machine_is_compatible("qcom,ipq8064") || 147 + of_machine_is_compatible("qcom,apq8064")) 148 + mux->disable_sec_src_gating = true; 149 + 142 150 init.name = kasprintf(GFP_KERNEL, "krait%s_sec_mux", s); 143 151 if (!init.name) 144 152 return -ENOMEM;