Mirror only - Please move to https://github.com/immortalwrt/immortalwrt
修訂 | 8d9dfac2bd2cdee042cdeb03c9cf3f8f54b99c91 (tree) |
---|---|
時間 | 2022-10-12 04:28:46 |
作者 | Christian Marangi <ansuelsmth@gmai...> |
Commiter | Christian Marangi |
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>
@@ -0,0 +1,33 @@ | ||
1 | +From 2acc3260050cf17d72ec5fb7a00cd91cf53ef5b6 Mon Sep 17 00:00:00 2001 | |
2 | +From: Christian Marangi <ansuelsmth@gmail.com> | |
3 | +Date: Fri, 23 Sep 2022 18:42:29 +0200 | |
4 | +Subject: [PATCH 1/4] clk: qcom: clk-krait: fix wrong div2 functions | |
5 | + | |
6 | +Currently div2 value is applied to the wrong bits. This is caused by a | |
7 | +bug in the code where the shift is done only for lpl, for anything | |
8 | +else the mask is not shifted to the correct bits. | |
9 | + | |
10 | +Fix this by correctly shift if lpl is not supported. | |
11 | + | |
12 | +Fixes: 4d7dc77babfe ("clk: qcom: Add support for Krait clocks") | |
13 | +Signed-off-by: Christian Marangi <ansuelsmth@gmail.com> | |
14 | +--- | |
15 | + drivers/clk/qcom/clk-krait.c | 2 ++ | |
16 | + 1 file changed, 2 insertions(+) | |
17 | + | |
18 | +diff --git a/drivers/clk/qcom/clk-krait.c b/drivers/clk/qcom/clk-krait.c | |
19 | +index 45da736bd5f4..293a9dfa7151 100644 | |
20 | +--- a/drivers/clk/qcom/clk-krait.c | |
21 | ++++ b/drivers/clk/qcom/clk-krait.c | |
22 | +@@ -114,6 +114,8 @@ static int krait_div2_set_rate(struct clk_hw *hw, unsigned long rate, | |
23 | + | |
24 | + if (d->lpl) | |
25 | + mask = mask << (d->shift + LPL_SHIFT) | mask << d->shift; | |
26 | ++ else | |
27 | ++ mask <<= d->shift; | |
28 | + | |
29 | + spin_lock_irqsave(&krait_clock_reg_lock, flags); | |
30 | + val = krait_get_l2_indirect_reg(d->offset); | |
31 | +-- | |
32 | +2.37.2 | |
33 | + |
@@ -0,0 +1,165 @@ | ||
1 | +From 908c361b3c3a139eb3e6a798cb620a6da7514d5c Mon Sep 17 00:00:00 2001 | |
2 | +From: Christian Marangi <ansuelsmth@gmail.com> | |
3 | +Date: Fri, 23 Sep 2022 19:05:39 +0200 | |
4 | +Subject: [PATCH 2/4] clk: qcom: clk-krait: generilize div functions | |
5 | + | |
6 | +Generilize div functions and remove hardcode to a divisor of 2. | |
7 | +This is just a cleanup and permit to make it more clear the settings of | |
8 | +the devisor when used by the krait-cc driver. | |
9 | + | |
10 | +Signed-off-by: Christian Marangi <ansuelsmth@gmail.com> | |
11 | +--- | |
12 | + drivers/clk/qcom/clk-krait.c | 57 ++++++++++++++++++++---------------- | |
13 | + drivers/clk/qcom/clk-krait.h | 11 ++++--- | |
14 | + drivers/clk/qcom/krait-cc.c | 7 +++-- | |
15 | + 3 files changed, 42 insertions(+), 33 deletions(-) | |
16 | + | |
17 | +diff --git a/drivers/clk/qcom/clk-krait.c b/drivers/clk/qcom/clk-krait.c | |
18 | +index 293a9dfa7151..1d40dd1acb0f 100644 | |
19 | +--- a/drivers/clk/qcom/clk-krait.c | |
20 | ++++ b/drivers/clk/qcom/clk-krait.c | |
21 | +@@ -97,53 +97,58 @@ const struct clk_ops krait_mux_clk_ops = { | |
22 | + EXPORT_SYMBOL_GPL(krait_mux_clk_ops); | |
23 | + | |
24 | + /* The divider can divide by 2, 4, 6 and 8. But we only really need div-2. */ | |
25 | +-static long krait_div2_round_rate(struct clk_hw *hw, unsigned long rate, | |
26 | ++static long krait_div_round_rate(struct clk_hw *hw, unsigned long rate, | |
27 | + unsigned long *parent_rate) | |
28 | + { | |
29 | +- *parent_rate = clk_hw_round_rate(clk_hw_get_parent(hw), rate * 2); | |
30 | +- return DIV_ROUND_UP(*parent_rate, 2); | |
31 | ++ struct krait_div_clk *d = to_krait_div_clk(hw); | |
32 | ++ | |
33 | ++ *parent_rate = clk_hw_round_rate(clk_hw_get_parent(hw), | |
34 | ++ rate * d->divisor); | |
35 | ++ | |
36 | ++ return DIV_ROUND_UP(*parent_rate, d->divisor); | |
37 | + } | |
38 | + | |
39 | +-static int krait_div2_set_rate(struct clk_hw *hw, unsigned long rate, | |
40 | ++static int krait_div_set_rate(struct clk_hw *hw, unsigned long rate, | |
41 | + unsigned long parent_rate) | |
42 | + { | |
43 | +- struct krait_div2_clk *d = to_krait_div2_clk(hw); | |
44 | ++ struct krait_div_clk *d = to_krait_div_clk(hw); | |
45 | ++ u8 div_val = krait_div_to_val(d->divisor); | |
46 | + unsigned long flags; | |
47 | +- u32 val; | |
48 | +- u32 mask = BIT(d->width) - 1; | |
49 | +- | |
50 | +- if (d->lpl) | |
51 | +- mask = mask << (d->shift + LPL_SHIFT) | mask << d->shift; | |
52 | +- else | |
53 | +- mask <<= d->shift; | |
54 | ++ u32 regval; | |
55 | + | |
56 | + spin_lock_irqsave(&krait_clock_reg_lock, flags); | |
57 | +- val = krait_get_l2_indirect_reg(d->offset); | |
58 | +- val &= ~mask; | |
59 | +- krait_set_l2_indirect_reg(d->offset, val); | |
60 | ++ regval = krait_get_l2_indirect_reg(d->offset); | |
61 | ++ | |
62 | ++ regval &= ~(d->mask << d->shift); | |
63 | ++ regval |= (div_val & d->mask) << d->shift; | |
64 | ++ | |
65 | ++ if (d->lpl) { | |
66 | ++ regval &= ~(d->mask << (d->shift + LPL_SHIFT)); | |
67 | ++ regval |= (div_val & d->mask) << (d->shift + LPL_SHIFT); | |
68 | ++ } | |
69 | ++ | |
70 | ++ krait_set_l2_indirect_reg(d->offset, regval); | |
71 | + spin_unlock_irqrestore(&krait_clock_reg_lock, flags); | |
72 | + | |
73 | + return 0; | |
74 | + } | |
75 | + | |
76 | + static unsigned long | |
77 | +-krait_div2_recalc_rate(struct clk_hw *hw, unsigned long parent_rate) | |
78 | ++krait_div_recalc_rate(struct clk_hw *hw, unsigned long parent_rate) | |
79 | + { | |
80 | +- struct krait_div2_clk *d = to_krait_div2_clk(hw); | |
81 | +- u32 mask = BIT(d->width) - 1; | |
82 | ++ struct krait_div_clk *d = to_krait_div_clk(hw); | |
83 | + u32 div; | |
84 | + | |
85 | + div = krait_get_l2_indirect_reg(d->offset); | |
86 | + div >>= d->shift; | |
87 | +- div &= mask; | |
88 | +- div = (div + 1) * 2; | |
89 | ++ div &= d->mask; | |
90 | + | |
91 | +- return DIV_ROUND_UP(parent_rate, div); | |
92 | ++ return DIV_ROUND_UP(parent_rate, krait_val_to_div(div)); | |
93 | + } | |
94 | + | |
95 | +-const struct clk_ops krait_div2_clk_ops = { | |
96 | +- .round_rate = krait_div2_round_rate, | |
97 | +- .set_rate = krait_div2_set_rate, | |
98 | +- .recalc_rate = krait_div2_recalc_rate, | |
99 | ++const struct clk_ops krait_div_clk_ops = { | |
100 | ++ .round_rate = krait_div_round_rate, | |
101 | ++ .set_rate = krait_div_set_rate, | |
102 | ++ .recalc_rate = krait_div_recalc_rate, | |
103 | + }; | |
104 | +-EXPORT_SYMBOL_GPL(krait_div2_clk_ops); | |
105 | ++EXPORT_SYMBOL_GPL(krait_div_clk_ops); | |
106 | +diff --git a/drivers/clk/qcom/clk-krait.h b/drivers/clk/qcom/clk-krait.h | |
107 | +index f930538c539e..94c798f8e834 100644 | |
108 | +--- a/drivers/clk/qcom/clk-krait.h | |
109 | ++++ b/drivers/clk/qcom/clk-krait.h | |
110 | +@@ -25,17 +25,20 @@ struct krait_mux_clk { | |
111 | + | |
112 | + extern const struct clk_ops krait_mux_clk_ops; | |
113 | + | |
114 | +-struct krait_div2_clk { | |
115 | ++struct krait_div_clk { | |
116 | + u32 offset; | |
117 | +- u8 width; | |
118 | ++ u32 mask; | |
119 | ++ u8 divisor; | |
120 | + u32 shift; | |
121 | + bool lpl; | |
122 | + | |
123 | + struct clk_hw hw; | |
124 | + }; | |
125 | + | |
126 | +-#define to_krait_div2_clk(_hw) container_of(_hw, struct krait_div2_clk, hw) | |
127 | ++#define to_krait_div_clk(_hw) container_of(_hw, struct krait_div_clk, hw) | |
128 | ++#define krait_div_to_val(_div) ((_div) / 2) - 1 | |
129 | ++#define krait_val_to_div(_val) ((_val) + 1) * 2 | |
130 | + | |
131 | +-extern const struct clk_ops krait_div2_clk_ops; | |
132 | ++extern const struct clk_ops krait_div_clk_ops; | |
133 | + | |
134 | + #endif | |
135 | +diff --git a/drivers/clk/qcom/krait-cc.c b/drivers/clk/qcom/krait-cc.c | |
136 | +index 90dee71e7c38..949657186fdb 100644 | |
137 | +--- a/drivers/clk/qcom/krait-cc.c | |
138 | ++++ b/drivers/clk/qcom/krait-cc.c | |
139 | +@@ -76,11 +76,11 @@ static int krait_notifier_register(struct device *dev, struct clk *clk, | |
140 | + static struct clk * | |
141 | + krait_add_div(struct device *dev, int id, const char *s, unsigned int offset) | |
142 | + { | |
143 | +- struct krait_div2_clk *div; | |
144 | ++ struct krait_div_clk *div; | |
145 | + static struct clk_parent_data p_data[1]; | |
146 | + struct clk_init_data init = { | |
147 | + .num_parents = ARRAY_SIZE(p_data), | |
148 | +- .ops = &krait_div2_clk_ops, | |
149 | ++ .ops = &krait_div_clk_ops, | |
150 | + .flags = CLK_SET_RATE_PARENT, | |
151 | + }; | |
152 | + struct clk *clk; | |
153 | +@@ -90,7 +90,8 @@ krait_add_div(struct device *dev, int id, const char *s, unsigned int offset) | |
154 | + if (!div) | |
155 | + return ERR_PTR(-ENOMEM); | |
156 | + | |
157 | +- div->width = 2; | |
158 | ++ div->mask = 0x3; | |
159 | ++ div->divisor = 2; | |
160 | + div->shift = 6; | |
161 | + div->lpl = id >= 0; | |
162 | + div->offset = offset; | |
163 | +-- | |
164 | +2.37.2 | |
165 | + |