xref: /rk3399_rockchip-uboot/drivers/clk/clk-uclass.c (revision fcdd83d4455871c49a93236c3f1cb964727f8c0c)
1 /*
2  * Copyright (C) 2015 Google, Inc
3  * Written by Simon Glass <sjg@chromium.org>
4  * Copyright (c) 2016, NVIDIA CORPORATION.
5  * Copyright (c) 2018, Theobroma Systems Design und Consulting GmbH
6  *
7  * SPDX-License-Identifier:	GPL-2.0+
8  */
9 
10 #include <common.h>
11 #include <clk.h>
12 #include <clk-uclass.h>
13 #include <dm.h>
14 #include <dm/device-internal.h>
15 #include <dm/read.h>
16 #include <dt-structs.h>
17 #include <errno.h>
18 
19 static inline const struct clk_ops *clk_dev_ops(struct udevice *dev)
20 {
21 	return (const struct clk_ops *)dev->driver->ops;
22 }
23 
24 #if CONFIG_IS_ENABLED(OF_CONTROL)
25 # if CONFIG_IS_ENABLED(OF_PLATDATA)
26 int clk_get_by_index_platdata(struct udevice *dev, int index,
27 			      struct phandle_1_arg *cells, struct clk *clk)
28 {
29 	int ret;
30 
31 	if (index != 0)
32 		return -ENOSYS;
33 	ret = uclass_get_device(UCLASS_CLK, 0, &clk->dev);
34 	if (ret)
35 		return ret;
36 	clk->id = cells[0].arg[0];
37 
38 	return 0;
39 }
40 # else
41 static int clk_of_xlate_default(struct clk *clk,
42 				struct ofnode_phandle_args *args)
43 {
44 	debug("%s(clk=%p)\n", __func__, clk);
45 
46 	if (args->args_count > 1) {
47 		debug("Invaild args_count: %d\n", args->args_count);
48 		return -EINVAL;
49 	}
50 
51 	if (args->args_count)
52 		clk->id = args->args[0];
53 	else
54 		clk->id = 0;
55 
56 	return 0;
57 }
58 
59 static int clk_get_by_indexed_prop(struct udevice *dev, const char *prop_name,
60 				   int index, struct clk *clk)
61 {
62 	int ret;
63 	struct ofnode_phandle_args args;
64 	struct udevice *dev_clk;
65 	const struct clk_ops *ops;
66 
67 	debug("%s(dev=%p, index=%d, clk=%p)\n", __func__, dev, index, clk);
68 
69 	assert(clk);
70 	clk->dev = NULL;
71 
72 	ret = dev_read_phandle_with_args(dev, prop_name, "#clock-cells", 0,
73 					 index, &args);
74 	if (ret) {
75 		debug("%s: fdtdec_parse_phandle_with_args failed: err=%d\n",
76 		      __func__, ret);
77 		return ret;
78 	}
79 
80 	ret = uclass_get_device_by_ofnode(UCLASS_CLK, args.node, &dev_clk);
81 	if (ret) {
82 		debug("%s: uclass_get_device_by_of_offset failed: err=%d\n",
83 		      __func__, ret);
84 		return ret;
85 	}
86 
87 	clk->dev = dev_clk;
88 
89 	ops = clk_dev_ops(dev_clk);
90 
91 	if (ops->of_xlate)
92 		ret = ops->of_xlate(clk, &args);
93 	else
94 		ret = clk_of_xlate_default(clk, &args);
95 	if (ret) {
96 		debug("of_xlate() failed: %d\n", ret);
97 		return ret;
98 	}
99 
100 	return clk_request(dev_clk, clk);
101 }
102 
103 int clk_get_by_index(struct udevice *dev, int index, struct clk *clk)
104 {
105 	return clk_get_by_indexed_prop(dev, "clocks", index, clk);
106 }
107 
108 int clk_get_bulk(struct udevice *dev, struct clk_bulk *bulk)
109 {
110 	int i, ret, err, count;
111 
112 	bulk->count = 0;
113 
114 	count = dev_count_phandle_with_args(dev, "clocks", "#clock-cells");
115 	if (!count)
116 		return 0;
117 
118 	bulk->clks = devm_kcalloc(dev, count, sizeof(struct clk), GFP_KERNEL);
119 	if (!bulk->clks)
120 		return -ENOMEM;
121 
122 	for (i = 0; i < count; i++) {
123 		ret = clk_get_by_index(dev, i, &bulk->clks[i]);
124 		if (ret < 0)
125 			goto bulk_get_err;
126 
127 		++bulk->count;
128 	}
129 
130 	return 0;
131 
132 bulk_get_err:
133 	err = clk_release_all(bulk->clks, bulk->count);
134 	if (err)
135 		debug("%s: could release all clocks for %p\n",
136 		      __func__, dev);
137 
138 	return ret;
139 }
140 
141 static int clk_set_default_parents(struct udevice *dev)
142 {
143 	struct clk clk, parent_clk;
144 	int index;
145 	int num_parents;
146 	int ret;
147 
148 	num_parents = dev_count_phandle_with_args(dev, "assigned-clock-parents",
149 						  "#clock-cells");
150 	if (num_parents < 0) {
151 		debug("%s: could not read assigned-clock-parents for %p\n",
152 		      __func__, dev);
153 		return 0;
154 	}
155 
156 	for (index = 0; index < num_parents; index++) {
157 		ret = clk_get_by_indexed_prop(dev, "assigned-clock-parents",
158 					      index, &parent_clk);
159 		if (ret) {
160 			debug("%s: could not get parent clock %d for %s\n",
161 			      __func__, index, dev_read_name(dev));
162 			return ret;
163 		}
164 
165 		ret = clk_get_by_indexed_prop(dev, "assigned-clocks",
166 					      index, &clk);
167 		if (ret) {
168 			debug("%s: could not get assigned clock %d for %s\n",
169 			      __func__, index, dev_read_name(dev));
170 			return ret;
171 		}
172 
173 		ret = clk_set_parent(&clk, &parent_clk);
174 
175 		/*
176 		 * Not all drivers may support clock-reparenting (as of now).
177 		 * Ignore errors due to this.
178 		 */
179 		if (ret == -ENOSYS)
180 			continue;
181 
182 		if (ret) {
183 			debug("%s: failed to reparent clock %d for %s\n",
184 			      __func__, index, dev_read_name(dev));
185 			return ret;
186 		}
187 	}
188 
189 	return 0;
190 }
191 
192 static int clk_set_default_rates(struct udevice *dev)
193 {
194 	struct clk clk;
195 	int index;
196 	int num_rates;
197 	int size;
198 	int ret = 0;
199 	u32 *rates = NULL;
200 
201 	size = dev_read_size(dev, "assigned-clock-rates");
202 	if (size < 0)
203 		return 0;
204 
205 	num_rates = size / sizeof(u32);
206 	rates = calloc(num_rates, sizeof(u32));
207 	if (!rates)
208 		return -ENOMEM;
209 
210 	ret = dev_read_u32_array(dev, "assigned-clock-rates", rates, num_rates);
211 	if (ret)
212 		goto fail;
213 
214 	for (index = 0; index < num_rates; index++) {
215 		ret = clk_get_by_indexed_prop(dev, "assigned-clocks",
216 					      index, &clk);
217 		if (ret) {
218 			debug("%s: could not get assigned clock %d for %s\n",
219 			      __func__, index, dev_read_name(dev));
220 			continue;
221 		}
222 
223 		ret = clk_set_rate(&clk, rates[index]);
224 		if (ret < 0) {
225 			debug("%s: failed to set rate on clock %d for %s\n",
226 			      __func__, index, dev_read_name(dev));
227 			continue;
228 		}
229 	}
230 
231 fail:
232 	free(rates);
233 	return ret;
234 }
235 
236 int clk_set_defaults(struct udevice *dev)
237 {
238 	int ret;
239 
240 	/* If this is running pre-reloc state, don't take any action. */
241 	if (!(gd->flags & GD_FLG_RELOC))
242 		return 0;
243 
244 	debug("%s(%s)\n", __func__, dev_read_name(dev));
245 
246 	ret = clk_set_default_parents(dev);
247 	if (ret)
248 		return ret;
249 
250 	ret = clk_set_default_rates(dev);
251 	if (ret < 0)
252 		return ret;
253 
254 	return 0;
255 }
256 # endif /* OF_PLATDATA */
257 
258 int clk_get_by_name(struct udevice *dev, const char *name, struct clk *clk)
259 {
260 	int index;
261 
262 	debug("%s(dev=%p, name=%s, clk=%p)\n", __func__, dev, name, clk);
263 	clk->dev = NULL;
264 
265 	index = dev_read_stringlist_search(dev, "clock-names", name);
266 	if (index < 0) {
267 		debug("fdt_stringlist_search() failed: %d\n", index);
268 		return index;
269 	}
270 
271 	return clk_get_by_index(dev, index, clk);
272 }
273 
274 int clk_release_all(struct clk *clk, int count)
275 {
276 	int i, ret;
277 
278 	for (i = 0; i < count; i++) {
279 		debug("%s(clk[%d]=%p)\n", __func__, i, &clk[i]);
280 
281 		/* check if clock has been previously requested */
282 		if (!clk[i].dev)
283 			continue;
284 
285 		ret = clk_disable(&clk[i]);
286 		if (ret && ret != -ENOSYS)
287 			return ret;
288 
289 		ret = clk_free(&clk[i]);
290 		if (ret && ret != -ENOSYS)
291 			return ret;
292 	}
293 
294 	return 0;
295 }
296 
297 #endif /* OF_CONTROL */
298 
299 int clk_request(struct udevice *dev, struct clk *clk)
300 {
301 	const struct clk_ops *ops = clk_dev_ops(dev);
302 
303 	debug("%s(dev=%p, clk=%p)\n", __func__, dev, clk);
304 
305 	clk->dev = dev;
306 
307 	if (!ops->request)
308 		return 0;
309 
310 	return ops->request(clk);
311 }
312 
313 int clk_free(struct clk *clk)
314 {
315 	const struct clk_ops *ops = clk_dev_ops(clk->dev);
316 
317 	debug("%s(clk=%p)\n", __func__, clk);
318 
319 	if (!ops->free)
320 		return 0;
321 
322 	return ops->free(clk);
323 }
324 
325 ulong clk_get_rate(struct clk *clk)
326 {
327 	const struct clk_ops *ops = clk_dev_ops(clk->dev);
328 
329 	debug("%s(clk=%p)\n", __func__, clk);
330 
331 	if (!ops->get_rate)
332 		return -ENOSYS;
333 
334 	return ops->get_rate(clk);
335 }
336 
337 ulong clk_set_rate(struct clk *clk, ulong rate)
338 {
339 	const struct clk_ops *ops = clk_dev_ops(clk->dev);
340 
341 	debug("%s(clk=%p, rate=%lu)\n", __func__, clk, rate);
342 
343 	if (!ops->set_rate)
344 		return -ENOSYS;
345 
346 	return ops->set_rate(clk, rate);
347 }
348 
349 int clk_get_phase(struct clk *clk)
350 {
351 	const struct clk_ops *ops = clk_dev_ops(clk->dev);
352 
353 	if (!ops->get_phase)
354 		return -ENOSYS;
355 
356 	return ops->get_phase(clk);
357 }
358 
359 int clk_set_phase(struct clk *clk, int degrees)
360 {
361 	const struct clk_ops *ops = clk_dev_ops(clk->dev);
362 
363 	if (!ops->set_phase)
364 		return -ENOSYS;
365 
366 	return ops->set_phase(clk, degrees);
367 }
368 
369 int clk_set_parent(struct clk *clk, struct clk *parent)
370 {
371 	const struct clk_ops *ops = clk_dev_ops(clk->dev);
372 
373 	debug("%s(clk=%p, parent=%p)\n", __func__, clk, parent);
374 
375 	if (!ops->set_parent)
376 		return -ENOSYS;
377 
378 	return ops->set_parent(clk, parent);
379 }
380 
381 int clk_enable(struct clk *clk)
382 {
383 	const struct clk_ops *ops = clk_dev_ops(clk->dev);
384 
385 	debug("%s(clk=%p)\n", __func__, clk);
386 
387 	if (!ops->enable)
388 		return -ENOSYS;
389 
390 	return ops->enable(clk);
391 }
392 
393 int clk_enable_bulk(struct clk_bulk *bulk)
394 {
395 	int i, ret;
396 
397 	for (i = 0; i < bulk->count; i++) {
398 		ret = clk_enable(&bulk->clks[i]);
399 		if (ret < 0 && ret != -ENOSYS)
400 			return ret;
401 	}
402 
403 	return 0;
404 }
405 
406 int clk_disable(struct clk *clk)
407 {
408 	const struct clk_ops *ops = clk_dev_ops(clk->dev);
409 
410 	debug("%s(clk=%p)\n", __func__, clk);
411 
412 	if (!ops->disable)
413 		return -ENOSYS;
414 
415 	return ops->disable(clk);
416 }
417 
418 int clk_disable_bulk(struct clk_bulk *bulk)
419 {
420 	int i, ret;
421 
422 	for (i = 0; i < bulk->count; i++) {
423 		ret = clk_disable(&bulk->clks[i]);
424 		if (ret < 0 && ret != -ENOSYS)
425 			return ret;
426 	}
427 
428 	return 0;
429 }
430 
431 int clks_probe(void)
432 {
433 	struct udevice *dev;
434 	struct uclass *uc;
435 	int ret;
436 
437 	ret = uclass_get(UCLASS_CLK, &uc);
438 	if (ret)
439 		return ret;
440 
441 	uclass_foreach_dev(dev, uc) {
442 		ret = device_probe(dev);
443 		if (ret)
444 			printf("%s - probe failed: %d\n", dev->name, ret);
445 	}
446 
447 	return 0;
448 }
449 
450 UCLASS_DRIVER(clk) = {
451 	.id		= UCLASS_CLK,
452 	.name		= "clk",
453 };
454