xref: /openbmc/linux/drivers/clk/at91/clk-main.c (revision 4bf3bd0f)
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/mfd/syscon.h>
16 #include <linux/regmap.h>
17 
18 #include "pmc.h"
19 
20 #define SLOW_CLOCK_FREQ		32768
21 #define MAINF_DIV		16
22 #define MAINFRDY_TIMEOUT	(((MAINF_DIV + 1) * USEC_PER_SEC) / \
23 				 SLOW_CLOCK_FREQ)
24 #define MAINF_LOOP_MIN_WAIT	(USEC_PER_SEC / SLOW_CLOCK_FREQ)
25 #define MAINF_LOOP_MAX_WAIT	MAINFRDY_TIMEOUT
26 
27 #define MOR_KEY_MASK		(0xff << 16)
28 
29 struct clk_main_osc {
30 	struct clk_hw hw;
31 	struct regmap *regmap;
32 };
33 
34 #define to_clk_main_osc(hw) container_of(hw, struct clk_main_osc, hw)
35 
36 struct clk_main_rc_osc {
37 	struct clk_hw hw;
38 	struct regmap *regmap;
39 	unsigned long frequency;
40 	unsigned long accuracy;
41 };
42 
43 #define to_clk_main_rc_osc(hw) container_of(hw, struct clk_main_rc_osc, hw)
44 
45 struct clk_rm9200_main {
46 	struct clk_hw hw;
47 	struct regmap *regmap;
48 };
49 
50 #define to_clk_rm9200_main(hw) container_of(hw, struct clk_rm9200_main, hw)
51 
52 struct clk_sam9x5_main {
53 	struct clk_hw hw;
54 	struct regmap *regmap;
55 	u8 parent;
56 };
57 
58 #define to_clk_sam9x5_main(hw) container_of(hw, struct clk_sam9x5_main, hw)
59 
60 static inline bool clk_main_osc_ready(struct regmap *regmap)
61 {
62 	unsigned int status;
63 
64 	regmap_read(regmap, AT91_PMC_SR, &status);
65 
66 	return status & AT91_PMC_MOSCS;
67 }
68 
69 static int clk_main_osc_prepare(struct clk_hw *hw)
70 {
71 	struct clk_main_osc *osc = to_clk_main_osc(hw);
72 	struct regmap *regmap = osc->regmap;
73 	u32 tmp;
74 
75 	regmap_read(regmap, AT91_CKGR_MOR, &tmp);
76 	tmp &= ~MOR_KEY_MASK;
77 
78 	if (tmp & AT91_PMC_OSCBYPASS)
79 		return 0;
80 
81 	if (!(tmp & AT91_PMC_MOSCEN)) {
82 		tmp |= AT91_PMC_MOSCEN | AT91_PMC_KEY;
83 		regmap_write(regmap, AT91_CKGR_MOR, tmp);
84 	}
85 
86 	while (!clk_main_osc_ready(regmap))
87 		cpu_relax();
88 
89 	return 0;
90 }
91 
92 static void clk_main_osc_unprepare(struct clk_hw *hw)
93 {
94 	struct clk_main_osc *osc = to_clk_main_osc(hw);
95 	struct regmap *regmap = osc->regmap;
96 	u32 tmp;
97 
98 	regmap_read(regmap, AT91_CKGR_MOR, &tmp);
99 	if (tmp & AT91_PMC_OSCBYPASS)
100 		return;
101 
102 	if (!(tmp & AT91_PMC_MOSCEN))
103 		return;
104 
105 	tmp &= ~(AT91_PMC_KEY | AT91_PMC_MOSCEN);
106 	regmap_write(regmap, AT91_CKGR_MOR, tmp | AT91_PMC_KEY);
107 }
108 
109 static int clk_main_osc_is_prepared(struct clk_hw *hw)
110 {
111 	struct clk_main_osc *osc = to_clk_main_osc(hw);
112 	struct regmap *regmap = osc->regmap;
113 	u32 tmp, status;
114 
115 	regmap_read(regmap, AT91_CKGR_MOR, &tmp);
116 	if (tmp & AT91_PMC_OSCBYPASS)
117 		return 1;
118 
119 	regmap_read(regmap, AT91_PMC_SR, &status);
120 
121 	return (status & AT91_PMC_MOSCS) && (tmp & AT91_PMC_MOSCEN);
122 }
123 
124 static const struct clk_ops main_osc_ops = {
125 	.prepare = clk_main_osc_prepare,
126 	.unprepare = clk_main_osc_unprepare,
127 	.is_prepared = clk_main_osc_is_prepared,
128 };
129 
130 struct clk_hw * __init
131 at91_clk_register_main_osc(struct regmap *regmap,
132 			   const char *name,
133 			   const char *parent_name,
134 			   bool bypass)
135 {
136 	struct clk_main_osc *osc;
137 	struct clk_init_data init;
138 	struct clk_hw *hw;
139 	int ret;
140 
141 	if (!name || !parent_name)
142 		return ERR_PTR(-EINVAL);
143 
144 	osc = kzalloc(sizeof(*osc), GFP_KERNEL);
145 	if (!osc)
146 		return ERR_PTR(-ENOMEM);
147 
148 	init.name = name;
149 	init.ops = &main_osc_ops;
150 	init.parent_names = &parent_name;
151 	init.num_parents = 1;
152 	init.flags = CLK_IGNORE_UNUSED;
153 
154 	osc->hw.init = &init;
155 	osc->regmap = regmap;
156 
157 	if (bypass)
158 		regmap_update_bits(regmap,
159 				   AT91_CKGR_MOR, MOR_KEY_MASK |
160 				   AT91_PMC_MOSCEN,
161 				   AT91_PMC_OSCBYPASS | AT91_PMC_KEY);
162 
163 	hw = &osc->hw;
164 	ret = clk_hw_register(NULL, &osc->hw);
165 	if (ret) {
166 		kfree(osc);
167 		hw = ERR_PTR(ret);
168 	}
169 
170 	return hw;
171 }
172 
173 static bool clk_main_rc_osc_ready(struct regmap *regmap)
174 {
175 	unsigned int status;
176 
177 	regmap_read(regmap, AT91_PMC_SR, &status);
178 
179 	return status & AT91_PMC_MOSCRCS;
180 }
181 
182 static int clk_main_rc_osc_prepare(struct clk_hw *hw)
183 {
184 	struct clk_main_rc_osc *osc = to_clk_main_rc_osc(hw);
185 	struct regmap *regmap = osc->regmap;
186 	unsigned int mor;
187 
188 	regmap_read(regmap, AT91_CKGR_MOR, &mor);
189 
190 	if (!(mor & AT91_PMC_MOSCRCEN))
191 		regmap_update_bits(regmap, AT91_CKGR_MOR,
192 				   MOR_KEY_MASK | AT91_PMC_MOSCRCEN,
193 				   AT91_PMC_MOSCRCEN | AT91_PMC_KEY);
194 
195 	while (!clk_main_rc_osc_ready(regmap))
196 		cpu_relax();
197 
198 	return 0;
199 }
200 
201 static void clk_main_rc_osc_unprepare(struct clk_hw *hw)
202 {
203 	struct clk_main_rc_osc *osc = to_clk_main_rc_osc(hw);
204 	struct regmap *regmap = osc->regmap;
205 	unsigned int mor;
206 
207 	regmap_read(regmap, AT91_CKGR_MOR, &mor);
208 
209 	if (!(mor & AT91_PMC_MOSCRCEN))
210 		return;
211 
212 	regmap_update_bits(regmap, AT91_CKGR_MOR,
213 			   MOR_KEY_MASK | AT91_PMC_MOSCRCEN, AT91_PMC_KEY);
214 }
215 
216 static int clk_main_rc_osc_is_prepared(struct clk_hw *hw)
217 {
218 	struct clk_main_rc_osc *osc = to_clk_main_rc_osc(hw);
219 	struct regmap *regmap = osc->regmap;
220 	unsigned int mor, status;
221 
222 	regmap_read(regmap, AT91_CKGR_MOR, &mor);
223 	regmap_read(regmap, AT91_PMC_SR, &status);
224 
225 	return (mor & AT91_PMC_MOSCRCEN) && (status & AT91_PMC_MOSCRCS);
226 }
227 
228 static unsigned long clk_main_rc_osc_recalc_rate(struct clk_hw *hw,
229 						 unsigned long parent_rate)
230 {
231 	struct clk_main_rc_osc *osc = to_clk_main_rc_osc(hw);
232 
233 	return osc->frequency;
234 }
235 
236 static unsigned long clk_main_rc_osc_recalc_accuracy(struct clk_hw *hw,
237 						     unsigned long parent_acc)
238 {
239 	struct clk_main_rc_osc *osc = to_clk_main_rc_osc(hw);
240 
241 	return osc->accuracy;
242 }
243 
244 static const struct clk_ops main_rc_osc_ops = {
245 	.prepare = clk_main_rc_osc_prepare,
246 	.unprepare = clk_main_rc_osc_unprepare,
247 	.is_prepared = clk_main_rc_osc_is_prepared,
248 	.recalc_rate = clk_main_rc_osc_recalc_rate,
249 	.recalc_accuracy = clk_main_rc_osc_recalc_accuracy,
250 };
251 
252 struct clk_hw * __init
253 at91_clk_register_main_rc_osc(struct regmap *regmap,
254 			      const char *name,
255 			      u32 frequency, u32 accuracy)
256 {
257 	struct clk_main_rc_osc *osc;
258 	struct clk_init_data init;
259 	struct clk_hw *hw;
260 	int ret;
261 
262 	if (!name || !frequency)
263 		return ERR_PTR(-EINVAL);
264 
265 	osc = kzalloc(sizeof(*osc), GFP_KERNEL);
266 	if (!osc)
267 		return ERR_PTR(-ENOMEM);
268 
269 	init.name = name;
270 	init.ops = &main_rc_osc_ops;
271 	init.parent_names = NULL;
272 	init.num_parents = 0;
273 	init.flags = CLK_IGNORE_UNUSED;
274 
275 	osc->hw.init = &init;
276 	osc->regmap = regmap;
277 	osc->frequency = frequency;
278 	osc->accuracy = accuracy;
279 
280 	hw = &osc->hw;
281 	ret = clk_hw_register(NULL, hw);
282 	if (ret) {
283 		kfree(osc);
284 		hw = ERR_PTR(ret);
285 	}
286 
287 	return hw;
288 }
289 
290 static int clk_main_probe_frequency(struct regmap *regmap)
291 {
292 	unsigned long prep_time, timeout;
293 	unsigned int mcfr;
294 
295 	timeout = jiffies + usecs_to_jiffies(MAINFRDY_TIMEOUT);
296 	do {
297 		prep_time = jiffies;
298 		regmap_read(regmap, AT91_CKGR_MCFR, &mcfr);
299 		if (mcfr & AT91_PMC_MAINRDY)
300 			return 0;
301 		usleep_range(MAINF_LOOP_MIN_WAIT, MAINF_LOOP_MAX_WAIT);
302 	} while (time_before(prep_time, timeout));
303 
304 	return -ETIMEDOUT;
305 }
306 
307 static unsigned long clk_main_recalc_rate(struct regmap *regmap,
308 					  unsigned long parent_rate)
309 {
310 	unsigned int mcfr;
311 
312 	if (parent_rate)
313 		return parent_rate;
314 
315 	pr_warn("Main crystal frequency not set, using approximate value\n");
316 	regmap_read(regmap, AT91_CKGR_MCFR, &mcfr);
317 	if (!(mcfr & AT91_PMC_MAINRDY))
318 		return 0;
319 
320 	return ((mcfr & AT91_PMC_MAINF) * SLOW_CLOCK_FREQ) / MAINF_DIV;
321 }
322 
323 static int clk_rm9200_main_prepare(struct clk_hw *hw)
324 {
325 	struct clk_rm9200_main *clkmain = to_clk_rm9200_main(hw);
326 
327 	return clk_main_probe_frequency(clkmain->regmap);
328 }
329 
330 static int clk_rm9200_main_is_prepared(struct clk_hw *hw)
331 {
332 	struct clk_rm9200_main *clkmain = to_clk_rm9200_main(hw);
333 	unsigned int status;
334 
335 	regmap_read(clkmain->regmap, AT91_CKGR_MCFR, &status);
336 
337 	return status & AT91_PMC_MAINRDY ? 1 : 0;
338 }
339 
340 static unsigned long clk_rm9200_main_recalc_rate(struct clk_hw *hw,
341 						 unsigned long parent_rate)
342 {
343 	struct clk_rm9200_main *clkmain = to_clk_rm9200_main(hw);
344 
345 	return clk_main_recalc_rate(clkmain->regmap, parent_rate);
346 }
347 
348 static const struct clk_ops rm9200_main_ops = {
349 	.prepare = clk_rm9200_main_prepare,
350 	.is_prepared = clk_rm9200_main_is_prepared,
351 	.recalc_rate = clk_rm9200_main_recalc_rate,
352 };
353 
354 struct clk_hw * __init
355 at91_clk_register_rm9200_main(struct regmap *regmap,
356 			      const char *name,
357 			      const char *parent_name)
358 {
359 	struct clk_rm9200_main *clkmain;
360 	struct clk_init_data init;
361 	struct clk_hw *hw;
362 	int ret;
363 
364 	if (!name)
365 		return ERR_PTR(-EINVAL);
366 
367 	if (!parent_name)
368 		return ERR_PTR(-EINVAL);
369 
370 	clkmain = kzalloc(sizeof(*clkmain), GFP_KERNEL);
371 	if (!clkmain)
372 		return ERR_PTR(-ENOMEM);
373 
374 	init.name = name;
375 	init.ops = &rm9200_main_ops;
376 	init.parent_names = &parent_name;
377 	init.num_parents = 1;
378 	init.flags = 0;
379 
380 	clkmain->hw.init = &init;
381 	clkmain->regmap = regmap;
382 
383 	hw = &clkmain->hw;
384 	ret = clk_hw_register(NULL, &clkmain->hw);
385 	if (ret) {
386 		kfree(clkmain);
387 		hw = ERR_PTR(ret);
388 	}
389 
390 	return hw;
391 }
392 
393 static inline bool clk_sam9x5_main_ready(struct regmap *regmap)
394 {
395 	unsigned int status;
396 
397 	regmap_read(regmap, AT91_PMC_SR, &status);
398 
399 	return status & AT91_PMC_MOSCSELS ? 1 : 0;
400 }
401 
402 static int clk_sam9x5_main_prepare(struct clk_hw *hw)
403 {
404 	struct clk_sam9x5_main *clkmain = to_clk_sam9x5_main(hw);
405 	struct regmap *regmap = clkmain->regmap;
406 
407 	while (!clk_sam9x5_main_ready(regmap))
408 		cpu_relax();
409 
410 	return clk_main_probe_frequency(regmap);
411 }
412 
413 static int clk_sam9x5_main_is_prepared(struct clk_hw *hw)
414 {
415 	struct clk_sam9x5_main *clkmain = to_clk_sam9x5_main(hw);
416 
417 	return clk_sam9x5_main_ready(clkmain->regmap);
418 }
419 
420 static unsigned long clk_sam9x5_main_recalc_rate(struct clk_hw *hw,
421 						 unsigned long parent_rate)
422 {
423 	struct clk_sam9x5_main *clkmain = to_clk_sam9x5_main(hw);
424 
425 	return clk_main_recalc_rate(clkmain->regmap, parent_rate);
426 }
427 
428 static int clk_sam9x5_main_set_parent(struct clk_hw *hw, u8 index)
429 {
430 	struct clk_sam9x5_main *clkmain = to_clk_sam9x5_main(hw);
431 	struct regmap *regmap = clkmain->regmap;
432 	unsigned int tmp;
433 
434 	if (index > 1)
435 		return -EINVAL;
436 
437 	regmap_read(regmap, AT91_CKGR_MOR, &tmp);
438 	tmp &= ~MOR_KEY_MASK;
439 
440 	if (index && !(tmp & AT91_PMC_MOSCSEL))
441 		regmap_write(regmap, AT91_CKGR_MOR, tmp | AT91_PMC_MOSCSEL);
442 	else if (!index && (tmp & AT91_PMC_MOSCSEL))
443 		regmap_write(regmap, AT91_CKGR_MOR, tmp & ~AT91_PMC_MOSCSEL);
444 
445 	while (!clk_sam9x5_main_ready(regmap))
446 		cpu_relax();
447 
448 	return 0;
449 }
450 
451 static u8 clk_sam9x5_main_get_parent(struct clk_hw *hw)
452 {
453 	struct clk_sam9x5_main *clkmain = to_clk_sam9x5_main(hw);
454 	unsigned int status;
455 
456 	regmap_read(clkmain->regmap, AT91_CKGR_MOR, &status);
457 
458 	return status & AT91_PMC_MOSCEN ? 1 : 0;
459 }
460 
461 static const struct clk_ops sam9x5_main_ops = {
462 	.prepare = clk_sam9x5_main_prepare,
463 	.is_prepared = clk_sam9x5_main_is_prepared,
464 	.recalc_rate = clk_sam9x5_main_recalc_rate,
465 	.set_parent = clk_sam9x5_main_set_parent,
466 	.get_parent = clk_sam9x5_main_get_parent,
467 };
468 
469 struct clk_hw * __init
470 at91_clk_register_sam9x5_main(struct regmap *regmap,
471 			      const char *name,
472 			      const char **parent_names,
473 			      int num_parents)
474 {
475 	struct clk_sam9x5_main *clkmain;
476 	struct clk_init_data init;
477 	unsigned int status;
478 	struct clk_hw *hw;
479 	int ret;
480 
481 	if (!name)
482 		return ERR_PTR(-EINVAL);
483 
484 	if (!parent_names || !num_parents)
485 		return ERR_PTR(-EINVAL);
486 
487 	clkmain = kzalloc(sizeof(*clkmain), GFP_KERNEL);
488 	if (!clkmain)
489 		return ERR_PTR(-ENOMEM);
490 
491 	init.name = name;
492 	init.ops = &sam9x5_main_ops;
493 	init.parent_names = parent_names;
494 	init.num_parents = num_parents;
495 	init.flags = CLK_SET_PARENT_GATE;
496 
497 	clkmain->hw.init = &init;
498 	clkmain->regmap = regmap;
499 	regmap_read(clkmain->regmap, AT91_CKGR_MOR, &status);
500 	clkmain->parent = status & AT91_PMC_MOSCEN ? 1 : 0;
501 
502 	hw = &clkmain->hw;
503 	ret = clk_hw_register(NULL, &clkmain->hw);
504 	if (ret) {
505 		kfree(clkmain);
506 		hw = ERR_PTR(ret);
507 	}
508 
509 	return hw;
510 }
511