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