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:
Christian Marangi 2022-09-23 19:35:35 +02:00
parent ecf1abe5bf
commit 8d9dfac2bd
No known key found for this signature in database
GPG Key ID: AC001D09ADBFEAD7
2 changed files with 198 additions and 0 deletions

View File

@ -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

View File

@ -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