356659d9c083ccb06bc4079a65af1bba7cec4b80
[openwrt/openwrt.git] / target / linux / ipq806x / patches-6.6 / 122-05-clk-qcom-clk-krait-generilize-div-functions.patch
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 --- a/drivers/clk/qcom/clk-krait.c
18 +++ b/drivers/clk/qcom/clk-krait.c
19 @@ -97,53 +97,57 @@ const struct clk_ops krait_mux_clk_ops =
20 EXPORT_SYMBOL_GPL(krait_mux_clk_ops);
21
22 /* The divider can divide by 2, 4, 6 and 8. But we only really need div-2. */
23 -static int krait_div2_determine_rate(struct clk_hw *hw, struct clk_rate_request *req)
24 +static int krait_div_determine_rate(struct clk_hw *hw, struct clk_rate_request *req)
25 {
26 - req->best_parent_rate = clk_hw_round_rate(clk_hw_get_parent(hw), req->rate * 2);
27 - req->rate = DIV_ROUND_UP(req->best_parent_rate, 2);
28 + struct krait_div_clk *d = to_krait_div_clk(hw);
29 +
30 + req->best_parent_rate = clk_hw_round_rate(clk_hw_get_parent(hw),
31 + req->rate * d->divisor);
32 + req->rate = DIV_ROUND_UP(req->best_parent_rate, d->divisor);
33 return 0;
34 }
35
36 -static int krait_div2_set_rate(struct clk_hw *hw, unsigned long rate,
37 +static int krait_div_set_rate(struct clk_hw *hw, unsigned long rate,
38 unsigned long parent_rate)
39 {
40 - struct krait_div2_clk *d = to_krait_div2_clk(hw);
41 + struct krait_div_clk *d = to_krait_div_clk(hw);
42 + u8 div_val = krait_div_to_val(d->divisor);
43 unsigned long flags;
44 - u32 val;
45 - u32 mask = BIT(d->width) - 1;
46 -
47 - if (d->lpl)
48 - mask = mask << (d->shift + LPL_SHIFT) | mask << d->shift;
49 - else
50 - mask <<= d->shift;
51 + u32 regval;
52
53 spin_lock_irqsave(&krait_clock_reg_lock, flags);
54 - val = krait_get_l2_indirect_reg(d->offset);
55 - val &= ~mask;
56 - krait_set_l2_indirect_reg(d->offset, val);
57 + regval = krait_get_l2_indirect_reg(d->offset);
58 +
59 + regval &= ~(d->mask << d->shift);
60 + regval |= (div_val & d->mask) << d->shift;
61 +
62 + if (d->lpl) {
63 + regval &= ~(d->mask << (d->shift + LPL_SHIFT));
64 + regval |= (div_val & d->mask) << (d->shift + LPL_SHIFT);
65 + }
66 +
67 + krait_set_l2_indirect_reg(d->offset, regval);
68 spin_unlock_irqrestore(&krait_clock_reg_lock, flags);
69
70 return 0;
71 }
72
73 static unsigned long
74 -krait_div2_recalc_rate(struct clk_hw *hw, unsigned long parent_rate)
75 +krait_div_recalc_rate(struct clk_hw *hw, unsigned long parent_rate)
76 {
77 - struct krait_div2_clk *d = to_krait_div2_clk(hw);
78 - u32 mask = BIT(d->width) - 1;
79 + struct krait_div_clk *d = to_krait_div_clk(hw);
80 u32 div;
81
82 div = krait_get_l2_indirect_reg(d->offset);
83 div >>= d->shift;
84 - div &= mask;
85 - div = (div + 1) * 2;
86 + div &= d->mask;
87
88 - return DIV_ROUND_UP(parent_rate, div);
89 + return DIV_ROUND_UP(parent_rate, krait_val_to_div(div));
90 }
91
92 -const struct clk_ops krait_div2_clk_ops = {
93 - .determine_rate = krait_div2_determine_rate,
94 - .set_rate = krait_div2_set_rate,
95 - .recalc_rate = krait_div2_recalc_rate,
96 +const struct clk_ops krait_div_clk_ops = {
97 + .determine_rate = krait_div_determine_rate,
98 + .set_rate = krait_div_set_rate,
99 + .recalc_rate = krait_div_recalc_rate,
100 };
101 -EXPORT_SYMBOL_GPL(krait_div2_clk_ops);
102 +EXPORT_SYMBOL_GPL(krait_div_clk_ops);
103 --- a/drivers/clk/qcom/clk-krait.h
104 +++ b/drivers/clk/qcom/clk-krait.h
105 @@ -25,17 +25,20 @@ struct krait_mux_clk {
106
107 extern const struct clk_ops krait_mux_clk_ops;
108
109 -struct krait_div2_clk {
110 +struct krait_div_clk {
111 u32 offset;
112 - u8 width;
113 + u32 mask;
114 + u8 divisor;
115 u32 shift;
116 bool lpl;
117
118 struct clk_hw hw;
119 };
120
121 -#define to_krait_div2_clk(_hw) container_of(_hw, struct krait_div2_clk, hw)
122 +#define to_krait_div_clk(_hw) container_of(_hw, struct krait_div_clk, hw)
123 +#define krait_div_to_val(_div) ((_div) / 2) - 1
124 +#define krait_val_to_div(_val) ((_val) + 1) * 2
125
126 -extern const struct clk_ops krait_div2_clk_ops;
127 +extern const struct clk_ops krait_div_clk_ops;
128
129 #endif
130 --- a/drivers/clk/qcom/krait-cc.c
131 +++ b/drivers/clk/qcom/krait-cc.c
132 @@ -86,11 +86,11 @@ static int krait_notifier_register(struc
133 static struct clk_hw *
134 krait_add_div(struct device *dev, int id, const char *s, unsigned int offset)
135 {
136 - struct krait_div2_clk *div;
137 + struct krait_div_clk *div;
138 static struct clk_parent_data p_data[1];
139 struct clk_init_data init = {
140 .num_parents = ARRAY_SIZE(p_data),
141 - .ops = &krait_div2_clk_ops,
142 + .ops = &krait_div_clk_ops,
143 .flags = CLK_SET_RATE_PARENT,
144 };
145 struct clk_hw *clk;
146 @@ -101,7 +101,8 @@ krait_add_div(struct device *dev, int id
147 if (!div)
148 return ERR_PTR(-ENOMEM);
149
150 - div->width = 2;
151 + div->mask = 0x3;
152 + div->divisor = 2;
153 div->shift = 6;
154 div->lpl = id >= 0;
155 div->offset = offset;