1
2
3
4
5
6
7
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
30struct 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
37struct 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
46struct 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
53struct 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
61static 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
70static 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
93static 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
110static 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
125static 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
131static struct clk_hw * __init
132at91_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
174static 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}
196CLK_OF_DECLARE(at91rm9200_clk_main_osc, "atmel,at91rm9200-clk-main-osc",
197 of_at91rm9200_clk_main_osc_setup);
198
199static 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
208static 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
227static 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
242static 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
254static 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
262static 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
270static 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
278static struct clk_hw * __init
279at91_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
316static 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}
338CLK_OF_DECLARE(at91sam9x5_clk_main_rc_osc, "atmel,at91sam9x5-clk-main-rc-osc",
339 of_at91sam9x5_clk_main_rc_osc_setup);
340
341
342static 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
359static 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
375static 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
382static 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
392static 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
400static 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
406static struct clk_hw * __init
407at91_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
445static 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}
465CLK_OF_DECLARE(at91rm9200_clk_main, "atmel,at91rm9200-clk-main",
466 of_at91rm9200_clk_main_setup);
467
468static 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
477static 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
488static 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
495static 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
503static 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
526static 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
536static 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
544static struct clk_hw * __init
545at91_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
587static 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}
613CLK_OF_DECLARE(at91sam9x5_clk_main, "atmel,at91sam9x5-clk-main",
614 of_at91sam9x5_clk_main_setup);
615