ipq806x: 5.15: add clk krait fixes/improvement patch
Add various krait fixes patch that correctly bringup mux and cpu clocks. Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
This commit is contained in:
parent
ecf1abe5bf
commit
8d9dfac2bd
|
@ -0,0 +1,33 @@
|
|||
From 2acc3260050cf17d72ec5fb7a00cd91cf53ef5b6 Mon Sep 17 00:00:00 2001
|
||||
From: Christian Marangi <ansuelsmth@gmail.com>
|
||||
Date: Fri, 23 Sep 2022 18:42:29 +0200
|
||||
Subject: [PATCH 1/4] clk: qcom: clk-krait: fix wrong div2 functions
|
||||
|
||||
Currently div2 value is applied to the wrong bits. This is caused by a
|
||||
bug in the code where the shift is done only for lpl, for anything
|
||||
else the mask is not shifted to the correct bits.
|
||||
|
||||
Fix this by correctly shift if lpl is not supported.
|
||||
|
||||
Fixes: 4d7dc77babfe ("clk: qcom: Add support for Krait clocks")
|
||||
Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
|
||||
---
|
||||
drivers/clk/qcom/clk-krait.c | 2 ++
|
||||
1 file changed, 2 insertions(+)
|
||||
|
||||
diff --git a/drivers/clk/qcom/clk-krait.c b/drivers/clk/qcom/clk-krait.c
|
||||
index 45da736bd5f4..293a9dfa7151 100644
|
||||
--- a/drivers/clk/qcom/clk-krait.c
|
||||
+++ b/drivers/clk/qcom/clk-krait.c
|
||||
@@ -114,6 +114,8 @@ static int krait_div2_set_rate(struct clk_hw *hw, unsigned long rate,
|
||||
|
||||
if (d->lpl)
|
||||
mask = mask << (d->shift + LPL_SHIFT) | mask << d->shift;
|
||||
+ else
|
||||
+ mask <<= d->shift;
|
||||
|
||||
spin_lock_irqsave(&krait_clock_reg_lock, flags);
|
||||
val = krait_get_l2_indirect_reg(d->offset);
|
||||
--
|
||||
2.37.2
|
||||
|
|
@ -0,0 +1,165 @@
|
|||
From 908c361b3c3a139eb3e6a798cb620a6da7514d5c Mon Sep 17 00:00:00 2001
|
||||
From: Christian Marangi <ansuelsmth@gmail.com>
|
||||
Date: Fri, 23 Sep 2022 19:05:39 +0200
|
||||
Subject: [PATCH 2/4] clk: qcom: clk-krait: generilize div functions
|
||||
|
||||
Generilize div functions and remove hardcode to a divisor of 2.
|
||||
This is just a cleanup and permit to make it more clear the settings of
|
||||
the devisor when used by the krait-cc driver.
|
||||
|
||||
Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
|
||||
---
|
||||
drivers/clk/qcom/clk-krait.c | 57 ++++++++++++++++++++----------------
|
||||
drivers/clk/qcom/clk-krait.h | 11 ++++---
|
||||
drivers/clk/qcom/krait-cc.c | 7 +++--
|
||||
3 files changed, 42 insertions(+), 33 deletions(-)
|
||||
|
||||
diff --git a/drivers/clk/qcom/clk-krait.c b/drivers/clk/qcom/clk-krait.c
|
||||
index 293a9dfa7151..1d40dd1acb0f 100644
|
||||
--- a/drivers/clk/qcom/clk-krait.c
|
||||
+++ b/drivers/clk/qcom/clk-krait.c
|
||||
@@ -97,53 +97,58 @@ const struct clk_ops krait_mux_clk_ops = {
|
||||
EXPORT_SYMBOL_GPL(krait_mux_clk_ops);
|
||||
|
||||
/* The divider can divide by 2, 4, 6 and 8. But we only really need div-2. */
|
||||
-static long krait_div2_round_rate(struct clk_hw *hw, unsigned long rate,
|
||||
+static long krait_div_round_rate(struct clk_hw *hw, unsigned long rate,
|
||||
unsigned long *parent_rate)
|
||||
{
|
||||
- *parent_rate = clk_hw_round_rate(clk_hw_get_parent(hw), rate * 2);
|
||||
- return DIV_ROUND_UP(*parent_rate, 2);
|
||||
+ struct krait_div_clk *d = to_krait_div_clk(hw);
|
||||
+
|
||||
+ *parent_rate = clk_hw_round_rate(clk_hw_get_parent(hw),
|
||||
+ rate * d->divisor);
|
||||
+
|
||||
+ return DIV_ROUND_UP(*parent_rate, d->divisor);
|
||||
}
|
||||
|
||||
-static int krait_div2_set_rate(struct clk_hw *hw, unsigned long rate,
|
||||
+static int krait_div_set_rate(struct clk_hw *hw, unsigned long rate,
|
||||
unsigned long parent_rate)
|
||||
{
|
||||
- struct krait_div2_clk *d = to_krait_div2_clk(hw);
|
||||
+ struct krait_div_clk *d = to_krait_div_clk(hw);
|
||||
+ u8 div_val = krait_div_to_val(d->divisor);
|
||||
unsigned long flags;
|
||||
- u32 val;
|
||||
- u32 mask = BIT(d->width) - 1;
|
||||
-
|
||||
- if (d->lpl)
|
||||
- mask = mask << (d->shift + LPL_SHIFT) | mask << d->shift;
|
||||
- else
|
||||
- mask <<= d->shift;
|
||||
+ u32 regval;
|
||||
|
||||
spin_lock_irqsave(&krait_clock_reg_lock, flags);
|
||||
- val = krait_get_l2_indirect_reg(d->offset);
|
||||
- val &= ~mask;
|
||||
- krait_set_l2_indirect_reg(d->offset, val);
|
||||
+ regval = krait_get_l2_indirect_reg(d->offset);
|
||||
+
|
||||
+ regval &= ~(d->mask << d->shift);
|
||||
+ regval |= (div_val & d->mask) << d->shift;
|
||||
+
|
||||
+ if (d->lpl) {
|
||||
+ regval &= ~(d->mask << (d->shift + LPL_SHIFT));
|
||||
+ regval |= (div_val & d->mask) << (d->shift + LPL_SHIFT);
|
||||
+ }
|
||||
+
|
||||
+ krait_set_l2_indirect_reg(d->offset, regval);
|
||||
spin_unlock_irqrestore(&krait_clock_reg_lock, flags);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static unsigned long
|
||||
-krait_div2_recalc_rate(struct clk_hw *hw, unsigned long parent_rate)
|
||||
+krait_div_recalc_rate(struct clk_hw *hw, unsigned long parent_rate)
|
||||
{
|
||||
- struct krait_div2_clk *d = to_krait_div2_clk(hw);
|
||||
- u32 mask = BIT(d->width) - 1;
|
||||
+ struct krait_div_clk *d = to_krait_div_clk(hw);
|
||||
u32 div;
|
||||
|
||||
div = krait_get_l2_indirect_reg(d->offset);
|
||||
div >>= d->shift;
|
||||
- div &= mask;
|
||||
- div = (div + 1) * 2;
|
||||
+ div &= d->mask;
|
||||
|
||||
- return DIV_ROUND_UP(parent_rate, div);
|
||||
+ return DIV_ROUND_UP(parent_rate, krait_val_to_div(div));
|
||||
}
|
||||
|
||||
-const struct clk_ops krait_div2_clk_ops = {
|
||||
- .round_rate = krait_div2_round_rate,
|
||||
- .set_rate = krait_div2_set_rate,
|
||||
- .recalc_rate = krait_div2_recalc_rate,
|
||||
+const struct clk_ops krait_div_clk_ops = {
|
||||
+ .round_rate = krait_div_round_rate,
|
||||
+ .set_rate = krait_div_set_rate,
|
||||
+ .recalc_rate = krait_div_recalc_rate,
|
||||
};
|
||||
-EXPORT_SYMBOL_GPL(krait_div2_clk_ops);
|
||||
+EXPORT_SYMBOL_GPL(krait_div_clk_ops);
|
||||
diff --git a/drivers/clk/qcom/clk-krait.h b/drivers/clk/qcom/clk-krait.h
|
||||
index f930538c539e..94c798f8e834 100644
|
||||
--- a/drivers/clk/qcom/clk-krait.h
|
||||
+++ b/drivers/clk/qcom/clk-krait.h
|
||||
@@ -25,17 +25,20 @@ struct krait_mux_clk {
|
||||
|
||||
extern const struct clk_ops krait_mux_clk_ops;
|
||||
|
||||
-struct krait_div2_clk {
|
||||
+struct krait_div_clk {
|
||||
u32 offset;
|
||||
- u8 width;
|
||||
+ u32 mask;
|
||||
+ u8 divisor;
|
||||
u32 shift;
|
||||
bool lpl;
|
||||
|
||||
struct clk_hw hw;
|
||||
};
|
||||
|
||||
-#define to_krait_div2_clk(_hw) container_of(_hw, struct krait_div2_clk, hw)
|
||||
+#define to_krait_div_clk(_hw) container_of(_hw, struct krait_div_clk, hw)
|
||||
+#define krait_div_to_val(_div) ((_div) / 2) - 1
|
||||
+#define krait_val_to_div(_val) ((_val) + 1) * 2
|
||||
|
||||
-extern const struct clk_ops krait_div2_clk_ops;
|
||||
+extern const struct clk_ops krait_div_clk_ops;
|
||||
|
||||
#endif
|
||||
diff --git a/drivers/clk/qcom/krait-cc.c b/drivers/clk/qcom/krait-cc.c
|
||||
index 90dee71e7c38..949657186fdb 100644
|
||||
--- a/drivers/clk/qcom/krait-cc.c
|
||||
+++ b/drivers/clk/qcom/krait-cc.c
|
||||
@@ -76,11 +76,11 @@ static int krait_notifier_register(struct device *dev, struct clk *clk,
|
||||
static struct clk *
|
||||
krait_add_div(struct device *dev, int id, const char *s, unsigned int offset)
|
||||
{
|
||||
- struct krait_div2_clk *div;
|
||||
+ struct krait_div_clk *div;
|
||||
static struct clk_parent_data p_data[1];
|
||||
struct clk_init_data init = {
|
||||
.num_parents = ARRAY_SIZE(p_data),
|
||||
- .ops = &krait_div2_clk_ops,
|
||||
+ .ops = &krait_div_clk_ops,
|
||||
.flags = CLK_SET_RATE_PARENT,
|
||||
};
|
||||
struct clk *clk;
|
||||
@@ -90,7 +90,8 @@ krait_add_div(struct device *dev, int id, const char *s, unsigned int offset)
|
||||
if (!div)
|
||||
return ERR_PTR(-ENOMEM);
|
||||
|
||||
- div->width = 2;
|
||||
+ div->mask = 0x3;
|
||||
+ div->divisor = 2;
|
||||
div->shift = 6;
|
||||
div->lpl = id >= 0;
|
||||
div->offset = offset;
|
||||
--
|
||||
2.37.2
|
||||
|
Loading…
Reference in New Issue