aboutsummaryrefslogtreecommitdiffstats
path: root/target/linux/ipq806x/patches-5.15/122-05-clk-qcom-clk-krait-generilize-div-functions.patch
blob: a7c0f046c8421d9c0cb485344ce111c1111620b1 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
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(-)

--- 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);
--- 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
--- a/drivers/clk/qcom/krait-cc.c
+++ b/drivers/clk/qcom/krait-cc.c
@@ -86,11 +86,11 @@ static int krait_notifier_register(struc
 static struct clk_hw *
 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_hw *clk;
@@ -101,7 +101,8 @@ krait_add_div(struct device *dev, int id
 	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;