xref: /linux/drivers/clk/at91/clk-main.c (revision e5c86679d5e864947a52fb31e45a425dea3e7fa9)
1 /*
2  *  Copyright (C) 2013 Boris BREZILLON <b.brezillon@overkiz.com>
3  *
4  * This program is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License as published by
6  * the Free Software Foundation; either version 2 of the License, or
7  * (at your option) any later version.
8  *
9  */
10 
11 #include <linux/clk-provider.h>
12 #include <linux/clkdev.h>
13 #include <linux/clk/at91_pmc.h>
14 #include <linux/delay.h>
15 #include <linux/of.h>
16 #include <linux/mfd/syscon.h>
17 #include <linux/regmap.h>
18 
19 #include "pmc.h"
20 
21 #define SLOW_CLOCK_FREQ		32768
22 #define MAINF_DIV		16
23 #define MAINFRDY_TIMEOUT	(((MAINF_DIV + 1) * USEC_PER_SEC) / \
24 				 SLOW_CLOCK_FREQ)
25 #define MAINF_LOOP_MIN_WAIT	(USEC_PER_SEC / SLOW_CLOCK_FREQ)
26 #define MAINF_LOOP_MAX_WAIT	MAINFRDY_TIMEOUT
27 
28 #define MOR_KEY_MASK		(0xff << 16)
29 
30 struct clk_main_osc {
31 	struct clk_hw hw;
32 	struct regmap *regmap;
33 };
34 
35 #define to_clk_main_osc(hw) container_of(hw, struct clk_main_osc, hw)
36 
37 struct clk_main_rc_osc {
38 	struct clk_hw hw;
39 	struct regmap *regmap;
40 	unsigned long frequency;
41 	unsigned long accuracy;
42 };
43 
44 #define to_clk_main_rc_osc(hw) container_of(hw, struct clk_main_rc_osc, hw)
45 
46 struct clk_rm9200_main {
47 	struct clk_hw hw;
48 	struct regmap *regmap;
49 };
50 
51 #define to_clk_rm9200_main(hw) container_of(hw, struct clk_rm9200_main, hw)
52 
53 struct clk_sam9x5_main {
54 	struct clk_hw hw;
55 	struct regmap *regmap;
56 	u8 parent;
57 };
58 
59 #define to_clk_sam9x5_main(hw) container_of(hw, struct clk_sam9x5_main, hw)
60 
61 static inline bool clk_main_osc_ready(struct regmap *regmap)
62 {
63 	unsigned int status;
64 
65 	regmap_read(regmap, AT91_PMC_SR, &status);
66 
67 	return status & AT91_PMC_MOSCS;
68 }
69 
70 static int clk_main_osc_prepare(struct clk_hw *hw)
71 {
72 	struct clk_main_osc *osc = to_clk_main_osc(hw);
73 	struct regmap *regmap = osc->regmap;
74 	u32 tmp;
75 
76 	regmap_read(regmap, AT91_CKGR_MOR, &tmp);
77 	tmp &= ~MOR_KEY_MASK;
78 
79 	if (tmp & AT91_PMC_OSCBYPASS)
80 		return 0;
81 
82 	if (!(tmp & AT91_PMC_MOSCEN)) {
83 		tmp |= AT91_PMC_MOSCEN | AT91_PMC_KEY;
84 		regmap_write(regmap, AT91_CKGR_MOR, tmp);
85 	}
86 
87 	while (!clk_main_osc_ready(regmap))
88 		cpu_relax();
89 
90 	return 0;
91 }
92 
93 static void clk_main_osc_unprepare(struct clk_hw *hw)
94 {
95 	struct clk_main_osc *osc = to_clk_main_osc(hw);
96 	struct regmap *regmap = osc->regmap;
97 	u32 tmp;
98 
99 	regmap_read(regmap, AT91_CKGR_MOR, &tmp);
100 	if (tmp & AT91_PMC_OSCBYPASS)
101 		return;
102 
103 	if (!(tmp & AT91_PMC_MOSCEN))
104 		return;
105 
106 	tmp &= ~(AT91_PMC_KEY | AT91_PMC_MOSCEN);
107 	regmap_write(regmap, AT91_CKGR_MOR, tmp | AT91_PMC_KEY);
108 }
109 
110 static int clk_main_osc_is_prepared(struct clk_hw *hw)
111 {
112 	struct clk_main_osc *osc = to_clk_main_osc(hw);
113 	struct regmap *regmap = osc->regmap;
114 	u32 tmp, status;
115 
116 	regmap_read(regmap, AT91_CKGR_MOR, &tmp);
117 	if (tmp & AT91_PMC_OSCBYPASS)
118 		return 1;
119 
120 	regmap_read(regmap, AT91_PMC_SR, &status);
121 
122 	return (status & AT91_PMC_MOSCS) && (tmp & AT91_PMC_MOSCEN);
123 }
124 
125 static const struct clk_ops main_osc_ops = {
126 	.prepare = clk_main_osc_prepare,
127 	.unprepare = clk_main_osc_unprepare,
128 	.is_prepared = clk_main_osc_is_prepared,
129 };
130 
131 static struct clk_hw * __init
132 at91_clk_register_main_osc(struct regmap *regmap,
133 			   const char *name,
134 			   const char *parent_name,
135 			   bool bypass)
136 {
137 	struct clk_main_osc *osc;
138 	struct clk_init_data init;
139 	struct clk_hw *hw;
140 	int ret;
141 
142 	if (!name || !parent_name)
143 		return ERR_PTR(-EINVAL);
144 
145 	osc = kzalloc(sizeof(*osc), GFP_KERNEL);
146 	if (!osc)
147 		return ERR_PTR(-ENOMEM);
148 
149 	init.name = name;
150 	init.ops = &main_osc_ops;
151 	init.parent_names = &parent_name;
152 	init.num_parents = 1;
153 	init.flags = CLK_IGNORE_UNUSED;
154 
155 	osc->hw.init = &init;
156 	osc->regmap = regmap;
157 
158 	if (bypass)
159 		regmap_update_bits(regmap,
160 				   AT91_CKGR_MOR, MOR_KEY_MASK |
161 				   AT91_PMC_MOSCEN,
162 				   AT91_PMC_OSCBYPASS | AT91_PMC_KEY);
163 
164 	hw = &osc->hw;
165 	ret = clk_hw_register(NULL, &osc->hw);
166 	if (ret) {
167 		kfree(osc);
168 		hw = ERR_PTR(ret);
169 	}
170 
171 	return hw;
172 }
173 
174 static void __init of_at91rm9200_clk_main_osc_setup(struct device_node *np)
175 {
176 	struct clk_hw *hw;
177 	const char *name = np->name;
178 	const char *parent_name;
179 	struct regmap *regmap;
180 	bool bypass;
181 
182 	of_property_read_string(np, "clock-output-names", &name);
183 	bypass = of_property_read_bool(np, "atmel,osc-bypass");
184 	parent_name = of_clk_get_parent_name(np, 0);
185 
186 	regmap = syscon_node_to_regmap(of_get_parent(np));
187 	if (IS_ERR(regmap))
188 		return;
189 
190 	hw = at91_clk_register_main_osc(regmap, name, parent_name, bypass);
191 	if (IS_ERR(hw))
192 		return;
193 
194 	of_clk_add_hw_provider(np, of_clk_hw_simple_get, hw);
195 }
196 CLK_OF_DECLARE(at91rm9200_clk_main_osc, "atmel,at91rm9200-clk-main-osc",
197 	       of_at91rm9200_clk_main_osc_setup);
198 
199 static bool clk_main_rc_osc_ready(struct regmap *regmap)
200 {
201 	unsigned int status;
202 
203 	regmap_read(regmap, AT91_PMC_SR, &status);
204 
205 	return status & AT91_PMC_MOSCRCS;
206 }
207 
208 static int clk_main_rc_osc_prepare(struct clk_hw *hw)
209 {
210 	struct clk_main_rc_osc *osc = to_clk_main_rc_osc(hw);
211 	struct regmap *regmap = osc->regmap;
212 	unsigned int mor;
213 
214 	regmap_read(regmap, AT91_CKGR_MOR, &mor);
215 
216 	if (!(mor & AT91_PMC_MOSCRCEN))
217 		regmap_update_bits(regmap, AT91_CKGR_MOR,
218 				   MOR_KEY_MASK | AT91_PMC_MOSCRCEN,
219 				   AT91_PMC_MOSCRCEN | AT91_PMC_KEY);
220 
221 	while (!clk_main_rc_osc_ready(regmap))
222 		cpu_relax();
223 
224 	return 0;
225 }
226 
227 static void clk_main_rc_osc_unprepare(struct clk_hw *hw)
228 {
229 	struct clk_main_rc_osc *osc = to_clk_main_rc_osc(hw);
230 	struct regmap *regmap = osc->regmap;
231 	unsigned int mor;
232 
233 	regmap_read(regmap, AT91_CKGR_MOR, &mor);
234 
235 	if (!(mor & AT91_PMC_MOSCRCEN))
236 		return;
237 
238 	regmap_update_bits(regmap, AT91_CKGR_MOR,
239 			   MOR_KEY_MASK | AT91_PMC_MOSCRCEN, AT91_PMC_KEY);
240 }
241 
242 static int clk_main_rc_osc_is_prepared(struct clk_hw *hw)
243 {
244 	struct clk_main_rc_osc *osc = to_clk_main_rc_osc(hw);
245 	struct regmap *regmap = osc->regmap;
246 	unsigned int mor, status;
247 
248 	regmap_read(regmap, AT91_CKGR_MOR, &mor);
249 	regmap_read(regmap, AT91_PMC_SR, &status);
250 
251 	return (mor & AT91_PMC_MOSCRCEN) && (status & AT91_PMC_MOSCRCS);
252 }
253 
254 static unsigned long clk_main_rc_osc_recalc_rate(struct clk_hw *hw,
255 						 unsigned long parent_rate)
256 {
257 	struct clk_main_rc_osc *osc = to_clk_main_rc_osc(hw);
258 
259 	return osc->frequency;
260 }
261 
262 static unsigned long clk_main_rc_osc_recalc_accuracy(struct clk_hw *hw,
263 						     unsigned long parent_acc)
264 {
265 	struct clk_main_rc_osc *osc = to_clk_main_rc_osc(hw);
266 
267 	return osc->accuracy;
268 }
269 
270 static const struct clk_ops main_rc_osc_ops = {
271 	.prepare = clk_main_rc_osc_prepare,
272 	.unprepare = clk_main_rc_osc_unprepare,
273 	.is_prepared = clk_main_rc_osc_is_prepared,
274 	.recalc_rate = clk_main_rc_osc_recalc_rate,
275 	.recalc_accuracy = clk_main_rc_osc_recalc_accuracy,
276 };
277 
278 static struct clk_hw * __init
279 at91_clk_register_main_rc_osc(struct regmap *regmap,
280 			      const char *name,
281 			      u32 frequency, u32 accuracy)
282 {
283 	struct clk_main_rc_osc *osc;
284 	struct clk_init_data init;
285 	struct clk_hw *hw;
286 	int ret;
287 
288 	if (!name || !frequency)
289 		return ERR_PTR(-EINVAL);
290 
291 	osc = kzalloc(sizeof(*osc), GFP_KERNEL);
292 	if (!osc)
293 		return ERR_PTR(-ENOMEM);
294 
295 	init.name = name;
296 	init.ops = &main_rc_osc_ops;
297 	init.parent_names = NULL;
298 	init.num_parents = 0;
299 	init.flags = CLK_IGNORE_UNUSED;
300 
301 	osc->hw.init = &init;
302 	osc->regmap = regmap;
303 	osc->frequency = frequency;
304 	osc->accuracy = accuracy;
305 
306 	hw = &osc->hw;
307 	ret = clk_hw_register(NULL, hw);
308 	if (ret) {
309 		kfree(osc);
310 		hw = ERR_PTR(ret);
311 	}
312 
313 	return hw;
314 }
315 
316 static void __init of_at91sam9x5_clk_main_rc_osc_setup(struct device_node *np)
317 {
318 	struct clk_hw *hw;
319 	u32 frequency = 0;
320 	u32 accuracy = 0;
321 	const char *name = np->name;
322 	struct regmap *regmap;
323 
324 	of_property_read_string(np, "clock-output-names", &name);
325 	of_property_read_u32(np, "clock-frequency", &frequency);
326 	of_property_read_u32(np, "clock-accuracy", &accuracy);
327 
328 	regmap = syscon_node_to_regmap(of_get_parent(np));
329 	if (IS_ERR(regmap))
330 		return;
331 
332 	hw = at91_clk_register_main_rc_osc(regmap, name, frequency, accuracy);
333 	if (IS_ERR(hw))
334 		return;
335 
336 	of_clk_add_hw_provider(np, of_clk_hw_simple_get, hw);
337 }
338 CLK_OF_DECLARE(at91sam9x5_clk_main_rc_osc, "atmel,at91sam9x5-clk-main-rc-osc",
339 	       of_at91sam9x5_clk_main_rc_osc_setup);
340 
341 
342 static int clk_main_probe_frequency(struct regmap *regmap)
343 {
344 	unsigned long prep_time, timeout;
345 	unsigned int mcfr;
346 
347 	timeout = jiffies + usecs_to_jiffies(MAINFRDY_TIMEOUT);
348 	do {
349 		prep_time = jiffies;
350 		regmap_read(regmap, AT91_CKGR_MCFR, &mcfr);
351 		if (mcfr & AT91_PMC_MAINRDY)
352 			return 0;
353 		usleep_range(MAINF_LOOP_MIN_WAIT, MAINF_LOOP_MAX_WAIT);
354 	} while (time_before(prep_time, timeout));
355 
356 	return -ETIMEDOUT;
357 }
358 
359 static unsigned long clk_main_recalc_rate(struct regmap *regmap,
360 					  unsigned long parent_rate)
361 {
362 	unsigned int mcfr;
363 
364 	if (parent_rate)
365 		return parent_rate;
366 
367 	pr_warn("Main crystal frequency not set, using approximate value\n");
368 	regmap_read(regmap, AT91_CKGR_MCFR, &mcfr);
369 	if (!(mcfr & AT91_PMC_MAINRDY))
370 		return 0;
371 
372 	return ((mcfr & AT91_PMC_MAINF) * SLOW_CLOCK_FREQ) / MAINF_DIV;
373 }
374 
375 static int clk_rm9200_main_prepare(struct clk_hw *hw)
376 {
377 	struct clk_rm9200_main *clkmain = to_clk_rm9200_main(hw);
378 
379 	return clk_main_probe_frequency(clkmain->regmap);
380 }
381 
382 static int clk_rm9200_main_is_prepared(struct clk_hw *hw)
383 {
384 	struct clk_rm9200_main *clkmain = to_clk_rm9200_main(hw);
385 	unsigned int status;
386 
387 	regmap_read(clkmain->regmap, AT91_CKGR_MCFR, &status);
388 
389 	return status & AT91_PMC_MAINRDY ? 1 : 0;
390 }
391 
392 static unsigned long clk_rm9200_main_recalc_rate(struct clk_hw *hw,
393 						 unsigned long parent_rate)
394 {
395 	struct clk_rm9200_main *clkmain = to_clk_rm9200_main(hw);
396 
397 	return clk_main_recalc_rate(clkmain->regmap, parent_rate);
398 }
399 
400 static const struct clk_ops rm9200_main_ops = {
401 	.prepare = clk_rm9200_main_prepare,
402 	.is_prepared = clk_rm9200_main_is_prepared,
403 	.recalc_rate = clk_rm9200_main_recalc_rate,
404 };
405 
406 static struct clk_hw * __init
407 at91_clk_register_rm9200_main(struct regmap *regmap,
408 			      const char *name,
409 			      const char *parent_name)
410 {
411 	struct clk_rm9200_main *clkmain;
412 	struct clk_init_data init;
413 	struct clk_hw *hw;
414 	int ret;
415 
416 	if (!name)
417 		return ERR_PTR(-EINVAL);
418 
419 	if (!parent_name)
420 		return ERR_PTR(-EINVAL);
421 
422 	clkmain = kzalloc(sizeof(*clkmain), GFP_KERNEL);
423 	if (!clkmain)
424 		return ERR_PTR(-ENOMEM);
425 
426 	init.name = name;
427 	init.ops = &rm9200_main_ops;
428 	init.parent_names = &parent_name;
429 	init.num_parents = 1;
430 	init.flags = 0;
431 
432 	clkmain->hw.init = &init;
433 	clkmain->regmap = regmap;
434 
435 	hw = &clkmain->hw;
436 	ret = clk_hw_register(NULL, &clkmain->hw);
437 	if (ret) {
438 		kfree(clkmain);
439 		hw = ERR_PTR(ret);
440 	}
441 
442 	return hw;
443 }
444 
445 static void __init of_at91rm9200_clk_main_setup(struct device_node *np)
446 {
447 	struct clk_hw *hw;
448 	const char *parent_name;
449 	const char *name = np->name;
450 	struct regmap *regmap;
451 
452 	parent_name = of_clk_get_parent_name(np, 0);
453 	of_property_read_string(np, "clock-output-names", &name);
454 
455 	regmap = syscon_node_to_regmap(of_get_parent(np));
456 	if (IS_ERR(regmap))
457 		return;
458 
459 	hw = at91_clk_register_rm9200_main(regmap, name, parent_name);
460 	if (IS_ERR(hw))
461 		return;
462 
463 	of_clk_add_hw_provider(np, of_clk_hw_simple_get, hw);
464 }
465 CLK_OF_DECLARE(at91rm9200_clk_main, "atmel,at91rm9200-clk-main",
466 	       of_at91rm9200_clk_main_setup);
467 
468 static inline bool clk_sam9x5_main_ready(struct regmap *regmap)
469 {
470 	unsigned int status;
471 
472 	regmap_read(regmap, AT91_PMC_SR, &status);
473 
474 	return status & AT91_PMC_MOSCSELS ? 1 : 0;
475 }
476 
477 static int clk_sam9x5_main_prepare(struct clk_hw *hw)
478 {
479 	struct clk_sam9x5_main *clkmain = to_clk_sam9x5_main(hw);
480 	struct regmap *regmap = clkmain->regmap;
481 
482 	while (!clk_sam9x5_main_ready(regmap))
483 		cpu_relax();
484 
485 	return clk_main_probe_frequency(regmap);
486 }
487 
488 static int clk_sam9x5_main_is_prepared(struct clk_hw *hw)
489 {
490 	struct clk_sam9x5_main *clkmain = to_clk_sam9x5_main(hw);
491 
492 	return clk_sam9x5_main_ready(clkmain->regmap);
493 }
494 
495 static unsigned long clk_sam9x5_main_recalc_rate(struct clk_hw *hw,
496 						 unsigned long parent_rate)
497 {
498 	struct clk_sam9x5_main *clkmain = to_clk_sam9x5_main(hw);
499 
500 	return clk_main_recalc_rate(clkmain->regmap, parent_rate);
501 }
502 
503 static int clk_sam9x5_main_set_parent(struct clk_hw *hw, u8 index)
504 {
505 	struct clk_sam9x5_main *clkmain = to_clk_sam9x5_main(hw);
506 	struct regmap *regmap = clkmain->regmap;
507 	unsigned int tmp;
508 
509 	if (index > 1)
510 		return -EINVAL;
511 
512 	regmap_read(regmap, AT91_CKGR_MOR, &tmp);
513 	tmp &= ~MOR_KEY_MASK;
514 
515 	if (index && !(tmp & AT91_PMC_MOSCSEL))
516 		regmap_write(regmap, AT91_CKGR_MOR, tmp | AT91_PMC_MOSCSEL);
517 	else if (!index && (tmp & AT91_PMC_MOSCSEL))
518 		regmap_write(regmap, AT91_CKGR_MOR, tmp & ~AT91_PMC_MOSCSEL);
519 
520 	while (!clk_sam9x5_main_ready(regmap))
521 		cpu_relax();
522 
523 	return 0;
524 }
525 
526 static u8 clk_sam9x5_main_get_parent(struct clk_hw *hw)
527 {
528 	struct clk_sam9x5_main *clkmain = to_clk_sam9x5_main(hw);
529 	unsigned int status;
530 
531 	regmap_read(clkmain->regmap, AT91_CKGR_MOR, &status);
532 
533 	return status & AT91_PMC_MOSCEN ? 1 : 0;
534 }
535 
536 static const struct clk_ops sam9x5_main_ops = {
537 	.prepare = clk_sam9x5_main_prepare,
538 	.is_prepared = clk_sam9x5_main_is_prepared,
539 	.recalc_rate = clk_sam9x5_main_recalc_rate,
540 	.set_parent = clk_sam9x5_main_set_parent,
541 	.get_parent = clk_sam9x5_main_get_parent,
542 };
543 
544 static struct clk_hw * __init
545 at91_clk_register_sam9x5_main(struct regmap *regmap,
546 			      const char *name,
547 			      const char **parent_names,
548 			      int num_parents)
549 {
550 	struct clk_sam9x5_main *clkmain;
551 	struct clk_init_data init;
552 	unsigned int status;
553 	struct clk_hw *hw;
554 	int ret;
555 
556 	if (!name)
557 		return ERR_PTR(-EINVAL);
558 
559 	if (!parent_names || !num_parents)
560 		return ERR_PTR(-EINVAL);
561 
562 	clkmain = kzalloc(sizeof(*clkmain), GFP_KERNEL);
563 	if (!clkmain)
564 		return ERR_PTR(-ENOMEM);
565 
566 	init.name = name;
567 	init.ops = &sam9x5_main_ops;
568 	init.parent_names = parent_names;
569 	init.num_parents = num_parents;
570 	init.flags = CLK_SET_PARENT_GATE;
571 
572 	clkmain->hw.init = &init;
573 	clkmain->regmap = regmap;
574 	regmap_read(clkmain->regmap, AT91_CKGR_MOR, &status);
575 	clkmain->parent = status & AT91_PMC_MOSCEN ? 1 : 0;
576 
577 	hw = &clkmain->hw;
578 	ret = clk_hw_register(NULL, &clkmain->hw);
579 	if (ret) {
580 		kfree(clkmain);
581 		hw = ERR_PTR(ret);
582 	}
583 
584 	return hw;
585 }
586 
587 static void __init of_at91sam9x5_clk_main_setup(struct device_node *np)
588 {
589 	struct clk_hw *hw;
590 	const char *parent_names[2];
591 	unsigned int num_parents;
592 	const char *name = np->name;
593 	struct regmap *regmap;
594 
595 	num_parents = of_clk_get_parent_count(np);
596 	if (num_parents == 0 || num_parents > 2)
597 		return;
598 
599 	of_clk_parent_fill(np, parent_names, num_parents);
600 	regmap = syscon_node_to_regmap(of_get_parent(np));
601 	if (IS_ERR(regmap))
602 		return;
603 
604 	of_property_read_string(np, "clock-output-names", &name);
605 
606 	hw = at91_clk_register_sam9x5_main(regmap, name, parent_names,
607 					    num_parents);
608 	if (IS_ERR(hw))
609 		return;
610 
611 	of_clk_add_hw_provider(np, of_clk_hw_simple_get, hw);
612 }
613 CLK_OF_DECLARE(at91sam9x5_clk_main, "atmel,at91sam9x5-clk-main",
614 	       of_at91sam9x5_clk_main_setup);
615