1 // SPDX-License-Identifier: GPL-2.0+
2 /*
3 * Copyright (C) 2020 Sean Anderson <seanga2@gmail.com>
4 */
5
6 #define LOG_CATEGORY UCLASS_CLK
7
8 #include <common.h>
9 #include <clk.h>
10 #include <clk-uclass.h>
11 #include <dm.h>
12 #include <log.h>
13 #include <kendryte/bypass.h>
14 #include <linux/clk-provider.h>
15 #include <linux/err.h>
16
17 #define CLK_K210_BYPASS "k210_clk_bypass"
18
19 /*
20 * This is a small driver to do a software bypass of a clock if hardware bypass
21 * is not working. I have tried to write this in a generic fashion, so that it
22 * could be potentially broken out of the kendryte code at some future date.
23 *
24 * Say you have the following clock configuration
25 *
26 * +---+ +---+
27 * |osc| |pll|
28 * +---+ +---+
29 * ^
30 * /|
31 * / |
32 * / |
33 * / |
34 * / |
35 * +---+ +---+
36 * |clk| |clk|
37 * +---+ +---+
38 *
39 * But the pll does not have a bypass, so when you configure the pll, the
40 * configuration needs to change to look like
41 *
42 * +---+ +---+
43 * |osc| |pll|
44 * +---+ +---+
45 * ^
46 * |\
47 * | \
48 * | \
49 * | \
50 * | \
51 * +---+ +---+
52 * |clk| |clk|
53 * +---+ +---+
54 *
55 * To set this up, create a bypass clock with bypassee=pll and alt=osc. When
56 * creating the child clocks, set their parent to the bypass clock. After
57 * creating all the children, call k210_bypass_setchildren().
58 */
59
k210_bypass_dobypass(struct k210_bypass * bypass)60 static int k210_bypass_dobypass(struct k210_bypass *bypass)
61 {
62 int ret, i;
63
64 /*
65 * If we already have saved parents, then the children are already
66 * bypassed
67 */
68 if (bypass->child_count && bypass->saved_parents[0])
69 return 0;
70
71 for (i = 0; i < bypass->child_count; i++) {
72 struct clk *child = bypass->children[i];
73 struct clk *parent = clk_get_parent(child);
74
75 if (IS_ERR(parent)) {
76 for (; i; i--)
77 bypass->saved_parents[i] = NULL;
78 return PTR_ERR(parent);
79 }
80 bypass->saved_parents[i] = parent;
81 }
82
83 for (i = 0; i < bypass->child_count; i++) {
84 struct clk *child = bypass->children[i];
85
86 ret = clk_set_parent(child, bypass->alt);
87 if (ret) {
88 for (; i; i--)
89 clk_set_parent(bypass->children[i],
90 bypass->saved_parents[i]);
91 for (i = 0; i < bypass->child_count; i++)
92 bypass->saved_parents[i] = NULL;
93 return ret;
94 }
95 }
96
97 return 0;
98 }
99
k210_bypass_unbypass(struct k210_bypass * bypass)100 static int k210_bypass_unbypass(struct k210_bypass *bypass)
101 {
102 int err, ret, i;
103
104 if (!bypass->child_count && !bypass->saved_parents[0]) {
105 log_warning("Cannot unbypass children; dobypass not called first\n");
106 return 0;
107 }
108
109 ret = 0;
110 for (i = 0; i < bypass->child_count; i++) {
111 err = clk_set_parent(bypass->children[i],
112 bypass->saved_parents[i]);
113 if (err)
114 ret = err;
115 bypass->saved_parents[i] = NULL;
116 }
117 return ret;
118 }
119
k210_bypass_get_rate(struct clk * clk)120 static ulong k210_bypass_get_rate(struct clk *clk)
121 {
122 struct k210_bypass *bypass = to_k210_bypass(clk);
123 const struct clk_ops *ops = bypass->bypassee_ops;
124
125 if (ops->get_rate)
126 return ops->get_rate(bypass->bypassee);
127 else
128 return clk_get_parent_rate(bypass->bypassee);
129 }
130
k210_bypass_set_rate(struct clk * clk,unsigned long rate)131 static ulong k210_bypass_set_rate(struct clk *clk, unsigned long rate)
132 {
133 int ret;
134 struct k210_bypass *bypass = to_k210_bypass(clk);
135 const struct clk_ops *ops = bypass->bypassee_ops;
136
137 /* Don't bother bypassing if we aren't going to set the rate */
138 if (!ops->set_rate)
139 return k210_bypass_get_rate(clk);
140
141 ret = k210_bypass_dobypass(bypass);
142 if (ret)
143 return ret;
144
145 ret = ops->set_rate(bypass->bypassee, rate);
146 if (ret < 0)
147 return ret;
148
149 return k210_bypass_unbypass(bypass);
150 }
151
k210_bypass_set_parent(struct clk * clk,struct clk * parent)152 static int k210_bypass_set_parent(struct clk *clk, struct clk *parent)
153 {
154 struct k210_bypass *bypass = to_k210_bypass(clk);
155 const struct clk_ops *ops = bypass->bypassee_ops;
156
157 if (ops->set_parent)
158 return ops->set_parent(bypass->bypassee, parent);
159 else
160 return -ENOTSUPP;
161 }
162
163 /*
164 * For these next two functions, do the bypassing even if there is no
165 * en-/-disable function, since the bypassing itself can be observed in between
166 * calls.
167 */
k210_bypass_enable(struct clk * clk)168 static int k210_bypass_enable(struct clk *clk)
169 {
170 int ret;
171 struct k210_bypass *bypass = to_k210_bypass(clk);
172 const struct clk_ops *ops = bypass->bypassee_ops;
173
174 ret = k210_bypass_dobypass(bypass);
175 if (ret)
176 return ret;
177
178 if (ops->enable)
179 ret = ops->enable(bypass->bypassee);
180 else
181 ret = 0;
182 if (ret)
183 return ret;
184
185 return k210_bypass_unbypass(bypass);
186 }
187
k210_bypass_disable(struct clk * clk)188 static int k210_bypass_disable(struct clk *clk)
189 {
190 int ret;
191 struct k210_bypass *bypass = to_k210_bypass(clk);
192 const struct clk_ops *ops = bypass->bypassee_ops;
193
194 ret = k210_bypass_dobypass(bypass);
195 if (ret)
196 return ret;
197
198 if (ops->disable)
199 return ops->disable(bypass->bypassee);
200 else
201 return 0;
202 }
203
204 static const struct clk_ops k210_bypass_ops = {
205 .get_rate = k210_bypass_get_rate,
206 .set_rate = k210_bypass_set_rate,
207 .set_parent = k210_bypass_set_parent,
208 .enable = k210_bypass_enable,
209 .disable = k210_bypass_disable,
210 };
211
k210_bypass_set_children(struct clk * clk,struct clk ** children,size_t child_count)212 int k210_bypass_set_children(struct clk *clk, struct clk **children,
213 size_t child_count)
214 {
215 struct k210_bypass *bypass = to_k210_bypass(clk);
216
217 kfree(bypass->saved_parents);
218 if (child_count) {
219 bypass->saved_parents =
220 kcalloc(child_count, sizeof(struct clk *), GFP_KERNEL);
221 if (!bypass->saved_parents)
222 return -ENOMEM;
223 }
224 bypass->child_count = child_count;
225 bypass->children = children;
226
227 return 0;
228 }
229
k210_register_bypass_struct(const char * name,const char * parent_name,struct k210_bypass * bypass)230 struct clk *k210_register_bypass_struct(const char *name,
231 const char *parent_name,
232 struct k210_bypass *bypass)
233 {
234 int ret;
235 struct clk *clk;
236
237 clk = &bypass->clk;
238
239 ret = clk_register(clk, CLK_K210_BYPASS, name, parent_name);
240 if (ret)
241 return ERR_PTR(ret);
242
243 bypass->bypassee->dev = clk->dev;
244 return clk;
245 }
246
k210_register_bypass(const char * name,const char * parent_name,struct clk * bypassee,const struct clk_ops * bypassee_ops,struct clk * alt)247 struct clk *k210_register_bypass(const char *name, const char *parent_name,
248 struct clk *bypassee,
249 const struct clk_ops *bypassee_ops,
250 struct clk *alt)
251 {
252 struct clk *clk;
253 struct k210_bypass *bypass;
254
255 bypass = kzalloc(sizeof(*bypass), GFP_KERNEL);
256 if (!bypass)
257 return ERR_PTR(-ENOMEM);
258
259 bypass->bypassee = bypassee;
260 bypass->bypassee_ops = bypassee_ops;
261 bypass->alt = alt;
262
263 clk = k210_register_bypass_struct(name, parent_name, bypass);
264 if (IS_ERR(clk))
265 kfree(bypass);
266 return clk;
267 }
268
269 U_BOOT_DRIVER(k210_bypass) = {
270 .name = CLK_K210_BYPASS,
271 .id = UCLASS_CLK,
272 .ops = &k210_bypass_ops,
273 };
274