xref: /linux/drivers/clk/at91/sckc.c (revision e814f3fd16acfb7f9966773953de8f740a1e3202)
1 // SPDX-License-Identifier: GPL-2.0-or-later
2 /*
3  * drivers/clk/at91/sckc.c
4  *
5  *  Copyright (C) 2013 Boris BREZILLON <b.brezillon@overkiz.com>
6  */
7 
8 #include <linux/clk-provider.h>
9 #include <linux/clkdev.h>
10 #include <linux/delay.h>
11 #include <linux/of.h>
12 #include <linux/of_address.h>
13 #include <linux/io.h>
14 
15 #include <dt-bindings/clock/at91.h>
16 
17 #define SLOW_CLOCK_FREQ		32768
18 #define SLOWCK_SW_CYCLES	5
19 #define SLOWCK_SW_TIME_USEC	((SLOWCK_SW_CYCLES * USEC_PER_SEC) / \
20 				 SLOW_CLOCK_FREQ)
21 
22 #define	AT91_SCKC_CR			0x00
23 
24 struct clk_slow_bits {
25 	u32 cr_rcen;
26 	u32 cr_osc32en;
27 	u32 cr_osc32byp;
28 	u32 cr_oscsel;
29 };
30 
31 struct clk_slow_osc {
32 	struct clk_hw hw;
33 	void __iomem *sckcr;
34 	const struct clk_slow_bits *bits;
35 	unsigned long startup_usec;
36 };
37 
38 #define to_clk_slow_osc(hw) container_of(hw, struct clk_slow_osc, hw)
39 
40 struct clk_sama5d4_slow_osc {
41 	struct clk_hw hw;
42 	void __iomem *sckcr;
43 	const struct clk_slow_bits *bits;
44 	unsigned long startup_usec;
45 	bool prepared;
46 };
47 
48 #define to_clk_sama5d4_slow_osc(hw) container_of(hw, struct clk_sama5d4_slow_osc, hw)
49 
50 struct clk_slow_rc_osc {
51 	struct clk_hw hw;
52 	void __iomem *sckcr;
53 	const struct clk_slow_bits *bits;
54 	unsigned long frequency;
55 	unsigned long accuracy;
56 	unsigned long startup_usec;
57 };
58 
59 #define to_clk_slow_rc_osc(hw) container_of(hw, struct clk_slow_rc_osc, hw)
60 
61 struct clk_sam9x5_slow {
62 	struct clk_hw hw;
63 	void __iomem *sckcr;
64 	const struct clk_slow_bits *bits;
65 	u8 parent;
66 };
67 
68 #define to_clk_sam9x5_slow(hw) container_of(hw, struct clk_sam9x5_slow, hw)
69 
70 static int clk_slow_osc_prepare(struct clk_hw *hw)
71 {
72 	struct clk_slow_osc *osc = to_clk_slow_osc(hw);
73 	void __iomem *sckcr = osc->sckcr;
74 	u32 tmp = readl(sckcr);
75 
76 	if (tmp & (osc->bits->cr_osc32byp | osc->bits->cr_osc32en))
77 		return 0;
78 
79 	writel(tmp | osc->bits->cr_osc32en, sckcr);
80 
81 	if (system_state < SYSTEM_RUNNING)
82 		udelay(osc->startup_usec);
83 	else
84 		usleep_range(osc->startup_usec, osc->startup_usec + 1);
85 
86 	return 0;
87 }
88 
89 static void clk_slow_osc_unprepare(struct clk_hw *hw)
90 {
91 	struct clk_slow_osc *osc = to_clk_slow_osc(hw);
92 	void __iomem *sckcr = osc->sckcr;
93 	u32 tmp = readl(sckcr);
94 
95 	if (tmp & osc->bits->cr_osc32byp)
96 		return;
97 
98 	writel(tmp & ~osc->bits->cr_osc32en, sckcr);
99 }
100 
101 static int clk_slow_osc_is_prepared(struct clk_hw *hw)
102 {
103 	struct clk_slow_osc *osc = to_clk_slow_osc(hw);
104 	void __iomem *sckcr = osc->sckcr;
105 	u32 tmp = readl(sckcr);
106 
107 	if (tmp & osc->bits->cr_osc32byp)
108 		return 1;
109 
110 	return !!(tmp & osc->bits->cr_osc32en);
111 }
112 
113 static const struct clk_ops slow_osc_ops = {
114 	.prepare = clk_slow_osc_prepare,
115 	.unprepare = clk_slow_osc_unprepare,
116 	.is_prepared = clk_slow_osc_is_prepared,
117 };
118 
119 static struct clk_hw * __init
120 at91_clk_register_slow_osc(void __iomem *sckcr,
121 			   const char *name,
122 			   const struct clk_parent_data *parent_data,
123 			   unsigned long startup,
124 			   bool bypass,
125 			   const struct clk_slow_bits *bits)
126 {
127 	struct clk_slow_osc *osc;
128 	struct clk_hw *hw;
129 	struct clk_init_data init = {};
130 	int ret;
131 
132 	if (!sckcr || !name || !parent_data)
133 		return ERR_PTR(-EINVAL);
134 
135 	osc = kzalloc(sizeof(*osc), GFP_KERNEL);
136 	if (!osc)
137 		return ERR_PTR(-ENOMEM);
138 
139 	init.name = name;
140 	init.ops = &slow_osc_ops;
141 	init.parent_data = parent_data;
142 	init.num_parents = 1;
143 	init.flags = CLK_IGNORE_UNUSED;
144 
145 	osc->hw.init = &init;
146 	osc->sckcr = sckcr;
147 	osc->startup_usec = startup;
148 	osc->bits = bits;
149 
150 	if (bypass)
151 		writel((readl(sckcr) & ~osc->bits->cr_osc32en) |
152 					osc->bits->cr_osc32byp, sckcr);
153 
154 	hw = &osc->hw;
155 	ret = clk_hw_register(NULL, &osc->hw);
156 	if (ret) {
157 		kfree(osc);
158 		hw = ERR_PTR(ret);
159 	}
160 
161 	return hw;
162 }
163 
164 static void at91_clk_unregister_slow_osc(struct clk_hw *hw)
165 {
166 	struct clk_slow_osc *osc = to_clk_slow_osc(hw);
167 
168 	clk_hw_unregister(hw);
169 	kfree(osc);
170 }
171 
172 static unsigned long clk_slow_rc_osc_recalc_rate(struct clk_hw *hw,
173 						 unsigned long parent_rate)
174 {
175 	struct clk_slow_rc_osc *osc = to_clk_slow_rc_osc(hw);
176 
177 	return osc->frequency;
178 }
179 
180 static unsigned long clk_slow_rc_osc_recalc_accuracy(struct clk_hw *hw,
181 						     unsigned long parent_acc)
182 {
183 	struct clk_slow_rc_osc *osc = to_clk_slow_rc_osc(hw);
184 
185 	return osc->accuracy;
186 }
187 
188 static int clk_slow_rc_osc_prepare(struct clk_hw *hw)
189 {
190 	struct clk_slow_rc_osc *osc = to_clk_slow_rc_osc(hw);
191 	void __iomem *sckcr = osc->sckcr;
192 
193 	writel(readl(sckcr) | osc->bits->cr_rcen, sckcr);
194 
195 	if (system_state < SYSTEM_RUNNING)
196 		udelay(osc->startup_usec);
197 	else
198 		usleep_range(osc->startup_usec, osc->startup_usec + 1);
199 
200 	return 0;
201 }
202 
203 static void clk_slow_rc_osc_unprepare(struct clk_hw *hw)
204 {
205 	struct clk_slow_rc_osc *osc = to_clk_slow_rc_osc(hw);
206 	void __iomem *sckcr = osc->sckcr;
207 
208 	writel(readl(sckcr) & ~osc->bits->cr_rcen, sckcr);
209 }
210 
211 static int clk_slow_rc_osc_is_prepared(struct clk_hw *hw)
212 {
213 	struct clk_slow_rc_osc *osc = to_clk_slow_rc_osc(hw);
214 
215 	return !!(readl(osc->sckcr) & osc->bits->cr_rcen);
216 }
217 
218 static const struct clk_ops slow_rc_osc_ops = {
219 	.prepare = clk_slow_rc_osc_prepare,
220 	.unprepare = clk_slow_rc_osc_unprepare,
221 	.is_prepared = clk_slow_rc_osc_is_prepared,
222 	.recalc_rate = clk_slow_rc_osc_recalc_rate,
223 	.recalc_accuracy = clk_slow_rc_osc_recalc_accuracy,
224 };
225 
226 static struct clk_hw * __init
227 at91_clk_register_slow_rc_osc(void __iomem *sckcr,
228 			      const char *name,
229 			      unsigned long frequency,
230 			      unsigned long accuracy,
231 			      unsigned long startup,
232 			      const struct clk_slow_bits *bits)
233 {
234 	struct clk_slow_rc_osc *osc;
235 	struct clk_hw *hw;
236 	struct clk_init_data init;
237 	int ret;
238 
239 	if (!sckcr || !name)
240 		return ERR_PTR(-EINVAL);
241 
242 	osc = kzalloc(sizeof(*osc), GFP_KERNEL);
243 	if (!osc)
244 		return ERR_PTR(-ENOMEM);
245 
246 	init.name = name;
247 	init.ops = &slow_rc_osc_ops;
248 	init.parent_names = NULL;
249 	init.num_parents = 0;
250 	init.flags = CLK_IGNORE_UNUSED;
251 
252 	osc->hw.init = &init;
253 	osc->sckcr = sckcr;
254 	osc->bits = bits;
255 	osc->frequency = frequency;
256 	osc->accuracy = accuracy;
257 	osc->startup_usec = startup;
258 
259 	hw = &osc->hw;
260 	ret = clk_hw_register(NULL, &osc->hw);
261 	if (ret) {
262 		kfree(osc);
263 		hw = ERR_PTR(ret);
264 	}
265 
266 	return hw;
267 }
268 
269 static void at91_clk_unregister_slow_rc_osc(struct clk_hw *hw)
270 {
271 	struct clk_slow_rc_osc *osc = to_clk_slow_rc_osc(hw);
272 
273 	clk_hw_unregister(hw);
274 	kfree(osc);
275 }
276 
277 static int clk_sam9x5_slow_set_parent(struct clk_hw *hw, u8 index)
278 {
279 	struct clk_sam9x5_slow *slowck = to_clk_sam9x5_slow(hw);
280 	void __iomem *sckcr = slowck->sckcr;
281 	u32 tmp;
282 
283 	if (index > 1)
284 		return -EINVAL;
285 
286 	tmp = readl(sckcr);
287 
288 	if ((!index && !(tmp & slowck->bits->cr_oscsel)) ||
289 	    (index && (tmp & slowck->bits->cr_oscsel)))
290 		return 0;
291 
292 	if (index)
293 		tmp |= slowck->bits->cr_oscsel;
294 	else
295 		tmp &= ~slowck->bits->cr_oscsel;
296 
297 	writel(tmp, sckcr);
298 
299 	if (system_state < SYSTEM_RUNNING)
300 		udelay(SLOWCK_SW_TIME_USEC);
301 	else
302 		usleep_range(SLOWCK_SW_TIME_USEC, SLOWCK_SW_TIME_USEC + 1);
303 
304 	return 0;
305 }
306 
307 static u8 clk_sam9x5_slow_get_parent(struct clk_hw *hw)
308 {
309 	struct clk_sam9x5_slow *slowck = to_clk_sam9x5_slow(hw);
310 
311 	return !!(readl(slowck->sckcr) & slowck->bits->cr_oscsel);
312 }
313 
314 static const struct clk_ops sam9x5_slow_ops = {
315 	.determine_rate = clk_hw_determine_rate_no_reparent,
316 	.set_parent = clk_sam9x5_slow_set_parent,
317 	.get_parent = clk_sam9x5_slow_get_parent,
318 };
319 
320 static struct clk_hw * __init
321 at91_clk_register_sam9x5_slow(void __iomem *sckcr,
322 			      const char *name,
323 			      const struct clk_hw **parent_hws,
324 			      int num_parents,
325 			      const struct clk_slow_bits *bits)
326 {
327 	struct clk_sam9x5_slow *slowck;
328 	struct clk_hw *hw;
329 	struct clk_init_data init = {};
330 	int ret;
331 
332 	if (!sckcr || !name || !parent_hws || !num_parents)
333 		return ERR_PTR(-EINVAL);
334 
335 	slowck = kzalloc(sizeof(*slowck), GFP_KERNEL);
336 	if (!slowck)
337 		return ERR_PTR(-ENOMEM);
338 
339 	init.name = name;
340 	init.ops = &sam9x5_slow_ops;
341 	init.parent_hws = parent_hws;
342 	init.num_parents = num_parents;
343 	init.flags = 0;
344 
345 	slowck->hw.init = &init;
346 	slowck->sckcr = sckcr;
347 	slowck->bits = bits;
348 	slowck->parent = !!(readl(sckcr) & slowck->bits->cr_oscsel);
349 
350 	hw = &slowck->hw;
351 	ret = clk_hw_register(NULL, &slowck->hw);
352 	if (ret) {
353 		kfree(slowck);
354 		hw = ERR_PTR(ret);
355 	}
356 
357 	return hw;
358 }
359 
360 static void at91_clk_unregister_sam9x5_slow(struct clk_hw *hw)
361 {
362 	struct clk_sam9x5_slow *slowck = to_clk_sam9x5_slow(hw);
363 
364 	clk_hw_unregister(hw);
365 	kfree(slowck);
366 }
367 
368 static void __init at91sam9x5_sckc_register(struct device_node *np,
369 					    unsigned int rc_osc_startup_us,
370 					    const struct clk_slow_bits *bits)
371 {
372 	void __iomem *regbase = of_iomap(np, 0);
373 	struct device_node *child = NULL;
374 	const char *xtal_name;
375 	struct clk_hw *slow_rc, *slow_osc, *slowck;
376 	static struct clk_parent_data parent_data = {
377 		.name = "slow_xtal",
378 	};
379 	const struct clk_hw *parent_hws[2];
380 	bool bypass;
381 	int ret;
382 
383 	if (!regbase)
384 		return;
385 
386 	slow_rc = at91_clk_register_slow_rc_osc(regbase, "slow_rc_osc",
387 						32768, 50000000,
388 						rc_osc_startup_us, bits);
389 	if (IS_ERR(slow_rc))
390 		return;
391 
392 	xtal_name = of_clk_get_parent_name(np, 0);
393 	if (!xtal_name) {
394 		/* DT backward compatibility */
395 		child = of_get_compatible_child(np, "atmel,at91sam9x5-clk-slow-osc");
396 		if (!child)
397 			goto unregister_slow_rc;
398 
399 		xtal_name = of_clk_get_parent_name(child, 0);
400 		bypass = of_property_read_bool(child, "atmel,osc-bypass");
401 
402 		child =  of_get_compatible_child(np, "atmel,at91sam9x5-clk-slow");
403 	} else {
404 		bypass = of_property_read_bool(np, "atmel,osc-bypass");
405 	}
406 
407 	if (!xtal_name)
408 		goto unregister_slow_rc;
409 
410 	parent_data.fw_name = xtal_name;
411 
412 	slow_osc = at91_clk_register_slow_osc(regbase, "slow_osc",
413 					      &parent_data, 1200000, bypass, bits);
414 	if (IS_ERR(slow_osc))
415 		goto unregister_slow_rc;
416 
417 	parent_hws[0] = slow_rc;
418 	parent_hws[1] = slow_osc;
419 	slowck = at91_clk_register_sam9x5_slow(regbase, "slowck", parent_hws,
420 					       2, bits);
421 	if (IS_ERR(slowck))
422 		goto unregister_slow_osc;
423 
424 	/* DT backward compatibility */
425 	if (child)
426 		ret = of_clk_add_hw_provider(child, of_clk_hw_simple_get,
427 					     slowck);
428 	else
429 		ret = of_clk_add_hw_provider(np, of_clk_hw_simple_get, slowck);
430 
431 	if (WARN_ON(ret))
432 		goto unregister_slowck;
433 
434 	return;
435 
436 unregister_slowck:
437 	at91_clk_unregister_sam9x5_slow(slowck);
438 unregister_slow_osc:
439 	at91_clk_unregister_slow_osc(slow_osc);
440 unregister_slow_rc:
441 	at91_clk_unregister_slow_rc_osc(slow_rc);
442 }
443 
444 static const struct clk_slow_bits at91sam9x5_bits = {
445 	.cr_rcen = BIT(0),
446 	.cr_osc32en = BIT(1),
447 	.cr_osc32byp = BIT(2),
448 	.cr_oscsel = BIT(3),
449 };
450 
451 static void __init of_at91sam9x5_sckc_setup(struct device_node *np)
452 {
453 	at91sam9x5_sckc_register(np, 75, &at91sam9x5_bits);
454 }
455 CLK_OF_DECLARE(at91sam9x5_clk_sckc, "atmel,at91sam9x5-sckc",
456 	       of_at91sam9x5_sckc_setup);
457 
458 static void __init of_sama5d3_sckc_setup(struct device_node *np)
459 {
460 	at91sam9x5_sckc_register(np, 500, &at91sam9x5_bits);
461 }
462 CLK_OF_DECLARE(sama5d3_clk_sckc, "atmel,sama5d3-sckc",
463 	       of_sama5d3_sckc_setup);
464 
465 static const struct clk_slow_bits at91sam9x60_bits = {
466 	.cr_osc32en = BIT(1),
467 	.cr_osc32byp = BIT(2),
468 	.cr_oscsel = BIT(24),
469 };
470 
471 static void __init of_sam9x60_sckc_setup(struct device_node *np)
472 {
473 	void __iomem *regbase = of_iomap(np, 0);
474 	struct clk_hw_onecell_data *clk_data;
475 	struct clk_hw *slow_rc, *slow_osc, *hw;
476 	const char *xtal_name;
477 	const struct clk_hw *parent_hws[2];
478 	static struct clk_parent_data parent_data = {
479 		.name = "slow_xtal",
480 	};
481 	bool bypass;
482 	int ret;
483 
484 	if (!regbase)
485 		return;
486 
487 	slow_rc = clk_hw_register_fixed_rate_with_accuracy(NULL, "slow_rc_osc",
488 							   NULL, 0, 32768,
489 							   93750000);
490 	if (IS_ERR(slow_rc))
491 		return;
492 
493 	xtal_name = of_clk_get_parent_name(np, 0);
494 	if (!xtal_name)
495 		goto unregister_slow_rc;
496 
497 	parent_data.fw_name = xtal_name;
498 	bypass = of_property_read_bool(np, "atmel,osc-bypass");
499 	slow_osc = at91_clk_register_slow_osc(regbase, "slow_osc",
500 					      &parent_data, 5000000, bypass,
501 					      &at91sam9x60_bits);
502 	if (IS_ERR(slow_osc))
503 		goto unregister_slow_rc;
504 
505 	clk_data = kzalloc(struct_size(clk_data, hws, 2), GFP_KERNEL);
506 	if (!clk_data)
507 		goto unregister_slow_osc;
508 
509 	/* MD_SLCK and TD_SLCK. */
510 	clk_data->num = 2;
511 	hw = clk_hw_register_fixed_rate_parent_hw(NULL, "md_slck", slow_rc,
512 						  0, 32768);
513 	if (IS_ERR(hw))
514 		goto clk_data_free;
515 	clk_data->hws[SCKC_MD_SLCK] = hw;
516 
517 	parent_hws[0] = slow_rc;
518 	parent_hws[1] = slow_osc;
519 	hw = at91_clk_register_sam9x5_slow(regbase, "td_slck", parent_hws,
520 					   2, &at91sam9x60_bits);
521 	if (IS_ERR(hw))
522 		goto unregister_md_slck;
523 	clk_data->hws[SCKC_TD_SLCK] = hw;
524 
525 	ret = of_clk_add_hw_provider(np, of_clk_hw_onecell_get, clk_data);
526 	if (WARN_ON(ret))
527 		goto unregister_td_slck;
528 
529 	return;
530 
531 unregister_td_slck:
532 	at91_clk_unregister_sam9x5_slow(clk_data->hws[SCKC_TD_SLCK]);
533 unregister_md_slck:
534 	clk_hw_unregister(clk_data->hws[SCKC_MD_SLCK]);
535 clk_data_free:
536 	kfree(clk_data);
537 unregister_slow_osc:
538 	at91_clk_unregister_slow_osc(slow_osc);
539 unregister_slow_rc:
540 	clk_hw_unregister(slow_rc);
541 }
542 CLK_OF_DECLARE(sam9x60_clk_sckc, "microchip,sam9x60-sckc",
543 	       of_sam9x60_sckc_setup);
544 
545 static int clk_sama5d4_slow_osc_prepare(struct clk_hw *hw)
546 {
547 	struct clk_sama5d4_slow_osc *osc = to_clk_sama5d4_slow_osc(hw);
548 
549 	if (osc->prepared)
550 		return 0;
551 
552 	/*
553 	 * Assume that if it has already been selected (for example by the
554 	 * bootloader), enough time has already passed.
555 	 */
556 	if ((readl(osc->sckcr) & osc->bits->cr_oscsel)) {
557 		osc->prepared = true;
558 		return 0;
559 	}
560 
561 	if (system_state < SYSTEM_RUNNING)
562 		udelay(osc->startup_usec);
563 	else
564 		usleep_range(osc->startup_usec, osc->startup_usec + 1);
565 	osc->prepared = true;
566 
567 	return 0;
568 }
569 
570 static int clk_sama5d4_slow_osc_is_prepared(struct clk_hw *hw)
571 {
572 	struct clk_sama5d4_slow_osc *osc = to_clk_sama5d4_slow_osc(hw);
573 
574 	return osc->prepared;
575 }
576 
577 static const struct clk_ops sama5d4_slow_osc_ops = {
578 	.prepare = clk_sama5d4_slow_osc_prepare,
579 	.is_prepared = clk_sama5d4_slow_osc_is_prepared,
580 };
581 
582 static const struct clk_slow_bits at91sama5d4_bits = {
583 	.cr_oscsel = BIT(3),
584 };
585 
586 static void __init of_sama5d4_sckc_setup(struct device_node *np)
587 {
588 	void __iomem *regbase = of_iomap(np, 0);
589 	struct clk_hw *slow_rc, *slowck;
590 	struct clk_sama5d4_slow_osc *osc;
591 	struct clk_init_data init = {};
592 	const char *xtal_name;
593 	const struct clk_hw *parent_hws[2];
594 	static struct clk_parent_data parent_data = {
595 		.name = "slow_xtal",
596 	};
597 	int ret;
598 
599 	if (!regbase)
600 		return;
601 
602 	slow_rc = clk_hw_register_fixed_rate_with_accuracy(NULL,
603 							   "slow_rc_osc",
604 							   NULL, 0, 32768,
605 							   250000000);
606 	if (IS_ERR(slow_rc))
607 		return;
608 
609 	xtal_name = of_clk_get_parent_name(np, 0);
610 	if (!xtal_name)
611 		goto unregister_slow_rc;
612 	parent_data.fw_name = xtal_name;
613 
614 	osc = kzalloc(sizeof(*osc), GFP_KERNEL);
615 	if (!osc)
616 		goto unregister_slow_rc;
617 
618 	init.name = "slow_osc";
619 	init.ops = &sama5d4_slow_osc_ops;
620 	init.parent_data = &parent_data;
621 	init.num_parents = 1;
622 	init.flags = CLK_IGNORE_UNUSED;
623 
624 	osc->hw.init = &init;
625 	osc->sckcr = regbase;
626 	osc->startup_usec = 1200000;
627 	osc->bits = &at91sama5d4_bits;
628 
629 	ret = clk_hw_register(NULL, &osc->hw);
630 	if (ret)
631 		goto free_slow_osc_data;
632 
633 	parent_hws[0] = slow_rc;
634 	parent_hws[1] = &osc->hw;
635 	slowck = at91_clk_register_sam9x5_slow(regbase, "slowck",
636 					       parent_hws, 2,
637 					       &at91sama5d4_bits);
638 	if (IS_ERR(slowck))
639 		goto unregister_slow_osc;
640 
641 	ret = of_clk_add_hw_provider(np, of_clk_hw_simple_get, slowck);
642 	if (WARN_ON(ret))
643 		goto unregister_slowck;
644 
645 	return;
646 
647 unregister_slowck:
648 	at91_clk_unregister_sam9x5_slow(slowck);
649 unregister_slow_osc:
650 	clk_hw_unregister(&osc->hw);
651 free_slow_osc_data:
652 	kfree(osc);
653 unregister_slow_rc:
654 	clk_hw_unregister(slow_rc);
655 }
656 CLK_OF_DECLARE(sama5d4_clk_sckc, "atmel,sama5d4-sckc",
657 	       of_sama5d4_sckc_setup);
658