2 * Copyright (C) 2013 Boris BREZILLON <b.brezillon@overkiz.com>
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.
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>
20 #define SLOW_CLOCK_FREQ 32768
22 #define MAINFRDY_TIMEOUT (((MAINF_DIV + 1) * USEC_PER_SEC) / \
24 #define MAINF_LOOP_MIN_WAIT (USEC_PER_SEC / SLOW_CLOCK_FREQ)
25 #define MAINF_LOOP_MAX_WAIT MAINFRDY_TIMEOUT
27 #define MOR_KEY_MASK (0xff << 16)
31 struct regmap
*regmap
;
34 #define to_clk_main_osc(hw) container_of(hw, struct clk_main_osc, hw)
36 struct clk_main_rc_osc
{
38 struct regmap
*regmap
;
39 unsigned long frequency
;
40 unsigned long accuracy
;
43 #define to_clk_main_rc_osc(hw) container_of(hw, struct clk_main_rc_osc, hw)
45 struct clk_rm9200_main
{
47 struct regmap
*regmap
;
50 #define to_clk_rm9200_main(hw) container_of(hw, struct clk_rm9200_main, hw)
52 struct clk_sam9x5_main
{
54 struct regmap
*regmap
;
58 #define to_clk_sam9x5_main(hw) container_of(hw, struct clk_sam9x5_main, hw)
60 static inline bool clk_main_osc_ready(struct regmap
*regmap
)
64 regmap_read(regmap
, AT91_PMC_SR
, &status
);
66 return status
& AT91_PMC_MOSCS
;
69 static int clk_main_osc_prepare(struct clk_hw
*hw
)
71 struct clk_main_osc
*osc
= to_clk_main_osc(hw
);
72 struct regmap
*regmap
= osc
->regmap
;
75 regmap_read(regmap
, AT91_CKGR_MOR
, &tmp
);
78 if (tmp
& AT91_PMC_OSCBYPASS
)
81 if (!(tmp
& AT91_PMC_MOSCEN
)) {
82 tmp
|= AT91_PMC_MOSCEN
| AT91_PMC_KEY
;
83 regmap_write(regmap
, AT91_CKGR_MOR
, tmp
);
86 while (!clk_main_osc_ready(regmap
))
92 static void clk_main_osc_unprepare(struct clk_hw
*hw
)
94 struct clk_main_osc
*osc
= to_clk_main_osc(hw
);
95 struct regmap
*regmap
= osc
->regmap
;
98 regmap_read(regmap
, AT91_CKGR_MOR
, &tmp
);
99 if (tmp
& AT91_PMC_OSCBYPASS
)
102 if (!(tmp
& AT91_PMC_MOSCEN
))
105 tmp
&= ~(AT91_PMC_KEY
| AT91_PMC_MOSCEN
);
106 regmap_write(regmap
, AT91_CKGR_MOR
, tmp
| AT91_PMC_KEY
);
109 static int clk_main_osc_is_prepared(struct clk_hw
*hw
)
111 struct clk_main_osc
*osc
= to_clk_main_osc(hw
);
112 struct regmap
*regmap
= osc
->regmap
;
115 regmap_read(regmap
, AT91_CKGR_MOR
, &tmp
);
116 if (tmp
& AT91_PMC_OSCBYPASS
)
119 regmap_read(regmap
, AT91_PMC_SR
, &status
);
121 return (status
& AT91_PMC_MOSCS
) && (tmp
& AT91_PMC_MOSCEN
);
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
,
130 struct clk_hw
* __init
131 at91_clk_register_main_osc(struct regmap
*regmap
,
133 const char *parent_name
,
136 struct clk_main_osc
*osc
;
137 struct clk_init_data init
;
141 if (!name
|| !parent_name
)
142 return ERR_PTR(-EINVAL
);
144 osc
= kzalloc(sizeof(*osc
), GFP_KERNEL
);
146 return ERR_PTR(-ENOMEM
);
149 init
.ops
= &main_osc_ops
;
150 init
.parent_names
= &parent_name
;
151 init
.num_parents
= 1;
152 init
.flags
= CLK_IGNORE_UNUSED
;
154 osc
->hw
.init
= &init
;
155 osc
->regmap
= regmap
;
158 regmap_update_bits(regmap
,
159 AT91_CKGR_MOR
, MOR_KEY_MASK
|
161 AT91_PMC_OSCBYPASS
| AT91_PMC_KEY
);
164 ret
= clk_hw_register(NULL
, &osc
->hw
);
173 static bool clk_main_rc_osc_ready(struct regmap
*regmap
)
177 regmap_read(regmap
, AT91_PMC_SR
, &status
);
179 return status
& AT91_PMC_MOSCRCS
;
182 static int clk_main_rc_osc_prepare(struct clk_hw
*hw
)
184 struct clk_main_rc_osc
*osc
= to_clk_main_rc_osc(hw
);
185 struct regmap
*regmap
= osc
->regmap
;
188 regmap_read(regmap
, AT91_CKGR_MOR
, &mor
);
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
);
195 while (!clk_main_rc_osc_ready(regmap
))
201 static void clk_main_rc_osc_unprepare(struct clk_hw
*hw
)
203 struct clk_main_rc_osc
*osc
= to_clk_main_rc_osc(hw
);
204 struct regmap
*regmap
= osc
->regmap
;
207 regmap_read(regmap
, AT91_CKGR_MOR
, &mor
);
209 if (!(mor
& AT91_PMC_MOSCRCEN
))
212 regmap_update_bits(regmap
, AT91_CKGR_MOR
,
213 MOR_KEY_MASK
| AT91_PMC_MOSCRCEN
, AT91_PMC_KEY
);
216 static int clk_main_rc_osc_is_prepared(struct clk_hw
*hw
)
218 struct clk_main_rc_osc
*osc
= to_clk_main_rc_osc(hw
);
219 struct regmap
*regmap
= osc
->regmap
;
220 unsigned int mor
, status
;
222 regmap_read(regmap
, AT91_CKGR_MOR
, &mor
);
223 regmap_read(regmap
, AT91_PMC_SR
, &status
);
225 return (mor
& AT91_PMC_MOSCRCEN
) && (status
& AT91_PMC_MOSCRCS
);
228 static unsigned long clk_main_rc_osc_recalc_rate(struct clk_hw
*hw
,
229 unsigned long parent_rate
)
231 struct clk_main_rc_osc
*osc
= to_clk_main_rc_osc(hw
);
233 return osc
->frequency
;
236 static unsigned long clk_main_rc_osc_recalc_accuracy(struct clk_hw
*hw
,
237 unsigned long parent_acc
)
239 struct clk_main_rc_osc
*osc
= to_clk_main_rc_osc(hw
);
241 return osc
->accuracy
;
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
,
252 struct clk_hw
* __init
253 at91_clk_register_main_rc_osc(struct regmap
*regmap
,
255 u32 frequency
, u32 accuracy
)
257 struct clk_main_rc_osc
*osc
;
258 struct clk_init_data init
;
262 if (!name
|| !frequency
)
263 return ERR_PTR(-EINVAL
);
265 osc
= kzalloc(sizeof(*osc
), GFP_KERNEL
);
267 return ERR_PTR(-ENOMEM
);
270 init
.ops
= &main_rc_osc_ops
;
271 init
.parent_names
= NULL
;
272 init
.num_parents
= 0;
273 init
.flags
= CLK_IGNORE_UNUSED
;
275 osc
->hw
.init
= &init
;
276 osc
->regmap
= regmap
;
277 osc
->frequency
= frequency
;
278 osc
->accuracy
= accuracy
;
281 ret
= clk_hw_register(NULL
, hw
);
290 static int clk_main_probe_frequency(struct regmap
*regmap
)
292 unsigned long prep_time
, timeout
;
295 timeout
= jiffies
+ usecs_to_jiffies(MAINFRDY_TIMEOUT
);
298 regmap_read(regmap
, AT91_CKGR_MCFR
, &mcfr
);
299 if (mcfr
& AT91_PMC_MAINRDY
)
301 usleep_range(MAINF_LOOP_MIN_WAIT
, MAINF_LOOP_MAX_WAIT
);
302 } while (time_before(prep_time
, timeout
));
307 static unsigned long clk_main_recalc_rate(struct regmap
*regmap
,
308 unsigned long parent_rate
)
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
))
320 return ((mcfr
& AT91_PMC_MAINF
) * SLOW_CLOCK_FREQ
) / MAINF_DIV
;
323 static int clk_rm9200_main_prepare(struct clk_hw
*hw
)
325 struct clk_rm9200_main
*clkmain
= to_clk_rm9200_main(hw
);
327 return clk_main_probe_frequency(clkmain
->regmap
);
330 static int clk_rm9200_main_is_prepared(struct clk_hw
*hw
)
332 struct clk_rm9200_main
*clkmain
= to_clk_rm9200_main(hw
);
335 regmap_read(clkmain
->regmap
, AT91_CKGR_MCFR
, &status
);
337 return status
& AT91_PMC_MAINRDY
? 1 : 0;
340 static unsigned long clk_rm9200_main_recalc_rate(struct clk_hw
*hw
,
341 unsigned long parent_rate
)
343 struct clk_rm9200_main
*clkmain
= to_clk_rm9200_main(hw
);
345 return clk_main_recalc_rate(clkmain
->regmap
, parent_rate
);
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
,
354 struct clk_hw
* __init
355 at91_clk_register_rm9200_main(struct regmap
*regmap
,
357 const char *parent_name
)
359 struct clk_rm9200_main
*clkmain
;
360 struct clk_init_data init
;
365 return ERR_PTR(-EINVAL
);
368 return ERR_PTR(-EINVAL
);
370 clkmain
= kzalloc(sizeof(*clkmain
), GFP_KERNEL
);
372 return ERR_PTR(-ENOMEM
);
375 init
.ops
= &rm9200_main_ops
;
376 init
.parent_names
= &parent_name
;
377 init
.num_parents
= 1;
380 clkmain
->hw
.init
= &init
;
381 clkmain
->regmap
= regmap
;
384 ret
= clk_hw_register(NULL
, &clkmain
->hw
);
393 static inline bool clk_sam9x5_main_ready(struct regmap
*regmap
)
397 regmap_read(regmap
, AT91_PMC_SR
, &status
);
399 return status
& AT91_PMC_MOSCSELS
? 1 : 0;
402 static int clk_sam9x5_main_prepare(struct clk_hw
*hw
)
404 struct clk_sam9x5_main
*clkmain
= to_clk_sam9x5_main(hw
);
405 struct regmap
*regmap
= clkmain
->regmap
;
407 while (!clk_sam9x5_main_ready(regmap
))
410 return clk_main_probe_frequency(regmap
);
413 static int clk_sam9x5_main_is_prepared(struct clk_hw
*hw
)
415 struct clk_sam9x5_main
*clkmain
= to_clk_sam9x5_main(hw
);
417 return clk_sam9x5_main_ready(clkmain
->regmap
);
420 static unsigned long clk_sam9x5_main_recalc_rate(struct clk_hw
*hw
,
421 unsigned long parent_rate
)
423 struct clk_sam9x5_main
*clkmain
= to_clk_sam9x5_main(hw
);
425 return clk_main_recalc_rate(clkmain
->regmap
, parent_rate
);
428 static int clk_sam9x5_main_set_parent(struct clk_hw
*hw
, u8 index
)
430 struct clk_sam9x5_main
*clkmain
= to_clk_sam9x5_main(hw
);
431 struct regmap
*regmap
= clkmain
->regmap
;
437 regmap_read(regmap
, AT91_CKGR_MOR
, &tmp
);
438 tmp
&= ~MOR_KEY_MASK
;
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
);
445 while (!clk_sam9x5_main_ready(regmap
))
451 static u8
clk_sam9x5_main_get_parent(struct clk_hw
*hw
)
453 struct clk_sam9x5_main
*clkmain
= to_clk_sam9x5_main(hw
);
456 regmap_read(clkmain
->regmap
, AT91_CKGR_MOR
, &status
);
458 return status
& AT91_PMC_MOSCEN
? 1 : 0;
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
,
469 struct clk_hw
* __init
470 at91_clk_register_sam9x5_main(struct regmap
*regmap
,
472 const char **parent_names
,
475 struct clk_sam9x5_main
*clkmain
;
476 struct clk_init_data init
;
482 return ERR_PTR(-EINVAL
);
484 if (!parent_names
|| !num_parents
)
485 return ERR_PTR(-EINVAL
);
487 clkmain
= kzalloc(sizeof(*clkmain
), GFP_KERNEL
);
489 return ERR_PTR(-ENOMEM
);
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
;
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;
503 ret
= clk_hw_register(NULL
, &clkmain
->hw
);