2 * drivers/clk/at91/sckc.c
4 * Copyright (C) 2013 Boris BREZILLON <b.brezillon@overkiz.com>
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
13 #include <linux/clk-provider.h>
14 #include <linux/clkdev.h>
15 #include <linux/delay.h>
17 #include <linux/of_address.h>
20 #define SLOW_CLOCK_FREQ 32768
21 #define SLOWCK_SW_CYCLES 5
22 #define SLOWCK_SW_TIME_USEC ((SLOWCK_SW_CYCLES * USEC_PER_SEC) / \
25 #define AT91_SCKC_CR 0x00
27 struct clk_slow_bits {
37 const struct clk_slow_bits *bits;
38 unsigned long startup_usec;
41 #define to_clk_slow_osc(hw) container_of(hw, struct clk_slow_osc, hw)
43 struct clk_sama5d4_slow_osc {
46 const struct clk_slow_bits *bits;
47 unsigned long startup_usec;
51 #define to_clk_sama5d4_slow_osc(hw) container_of(hw, struct clk_sama5d4_slow_osc, hw)
53 struct clk_slow_rc_osc {
56 const struct clk_slow_bits *bits;
57 unsigned long frequency;
58 unsigned long accuracy;
59 unsigned long startup_usec;
62 #define to_clk_slow_rc_osc(hw) container_of(hw, struct clk_slow_rc_osc, hw)
64 struct clk_sam9x5_slow {
67 const struct clk_slow_bits *bits;
71 #define to_clk_sam9x5_slow(hw) container_of(hw, struct clk_sam9x5_slow, hw)
73 static int clk_slow_osc_prepare(struct clk_hw *hw)
75 struct clk_slow_osc *osc = to_clk_slow_osc(hw);
76 void __iomem *sckcr = osc->sckcr;
77 u32 tmp = readl(sckcr);
79 if (tmp & (osc->bits->cr_osc32byp | osc->bits->cr_osc32en))
82 writel(tmp | osc->bits->cr_osc32en, sckcr);
84 usleep_range(osc->startup_usec, osc->startup_usec + 1);
89 static void clk_slow_osc_unprepare(struct clk_hw *hw)
91 struct clk_slow_osc *osc = to_clk_slow_osc(hw);
92 void __iomem *sckcr = osc->sckcr;
93 u32 tmp = readl(sckcr);
95 if (tmp & osc->bits->cr_osc32byp)
98 writel(tmp & ~osc->bits->cr_osc32en, sckcr);
101 static int clk_slow_osc_is_prepared(struct clk_hw *hw)
103 struct clk_slow_osc *osc = to_clk_slow_osc(hw);
104 void __iomem *sckcr = osc->sckcr;
105 u32 tmp = readl(sckcr);
107 if (tmp & osc->bits->cr_osc32byp)
110 return !!(tmp & osc->bits->cr_osc32en);
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,
119 static struct clk_hw * __init
120 at91_clk_register_slow_osc(void __iomem *sckcr,
122 const char *parent_name,
123 unsigned long startup,
125 const struct clk_slow_bits *bits)
127 struct clk_slow_osc *osc;
129 struct clk_init_data init;
132 if (!sckcr || !name || !parent_name)
133 return ERR_PTR(-EINVAL);
135 osc = kzalloc(sizeof(*osc), GFP_KERNEL);
137 return ERR_PTR(-ENOMEM);
140 init.ops = &slow_osc_ops;
141 init.parent_names = &parent_name;
142 init.num_parents = 1;
143 init.flags = CLK_IGNORE_UNUSED;
145 osc->hw.init = &init;
147 osc->startup_usec = startup;
151 writel((readl(sckcr) & ~osc->bits->cr_osc32en) |
152 osc->bits->cr_osc32byp, sckcr);
155 ret = clk_hw_register(NULL, &osc->hw);
164 static unsigned long clk_slow_rc_osc_recalc_rate(struct clk_hw *hw,
165 unsigned long parent_rate)
167 struct clk_slow_rc_osc *osc = to_clk_slow_rc_osc(hw);
169 return osc->frequency;
172 static unsigned long clk_slow_rc_osc_recalc_accuracy(struct clk_hw *hw,
173 unsigned long parent_acc)
175 struct clk_slow_rc_osc *osc = to_clk_slow_rc_osc(hw);
177 return osc->accuracy;
180 static int clk_slow_rc_osc_prepare(struct clk_hw *hw)
182 struct clk_slow_rc_osc *osc = to_clk_slow_rc_osc(hw);
183 void __iomem *sckcr = osc->sckcr;
185 writel(readl(sckcr) | osc->bits->cr_rcen, sckcr);
187 usleep_range(osc->startup_usec, osc->startup_usec + 1);
192 static void clk_slow_rc_osc_unprepare(struct clk_hw *hw)
194 struct clk_slow_rc_osc *osc = to_clk_slow_rc_osc(hw);
195 void __iomem *sckcr = osc->sckcr;
197 writel(readl(sckcr) & ~osc->bits->cr_rcen, sckcr);
200 static int clk_slow_rc_osc_is_prepared(struct clk_hw *hw)
202 struct clk_slow_rc_osc *osc = to_clk_slow_rc_osc(hw);
204 return !!(readl(osc->sckcr) & osc->bits->cr_rcen);
207 static const struct clk_ops slow_rc_osc_ops = {
208 .prepare = clk_slow_rc_osc_prepare,
209 .unprepare = clk_slow_rc_osc_unprepare,
210 .is_prepared = clk_slow_rc_osc_is_prepared,
211 .recalc_rate = clk_slow_rc_osc_recalc_rate,
212 .recalc_accuracy = clk_slow_rc_osc_recalc_accuracy,
215 static struct clk_hw * __init
216 at91_clk_register_slow_rc_osc(void __iomem *sckcr,
218 unsigned long frequency,
219 unsigned long accuracy,
220 unsigned long startup,
221 const struct clk_slow_bits *bits)
223 struct clk_slow_rc_osc *osc;
225 struct clk_init_data init;
229 return ERR_PTR(-EINVAL);
231 osc = kzalloc(sizeof(*osc), GFP_KERNEL);
233 return ERR_PTR(-ENOMEM);
236 init.ops = &slow_rc_osc_ops;
237 init.parent_names = NULL;
238 init.num_parents = 0;
239 init.flags = CLK_IGNORE_UNUSED;
241 osc->hw.init = &init;
244 osc->frequency = frequency;
245 osc->accuracy = accuracy;
246 osc->startup_usec = startup;
249 ret = clk_hw_register(NULL, &osc->hw);
258 static int clk_sam9x5_slow_set_parent(struct clk_hw *hw, u8 index)
260 struct clk_sam9x5_slow *slowck = to_clk_sam9x5_slow(hw);
261 void __iomem *sckcr = slowck->sckcr;
269 if ((!index && !(tmp & slowck->bits->cr_oscsel)) ||
270 (index && (tmp & slowck->bits->cr_oscsel)))
274 tmp |= slowck->bits->cr_oscsel;
276 tmp &= ~slowck->bits->cr_oscsel;
280 usleep_range(SLOWCK_SW_TIME_USEC, SLOWCK_SW_TIME_USEC + 1);
285 static u8 clk_sam9x5_slow_get_parent(struct clk_hw *hw)
287 struct clk_sam9x5_slow *slowck = to_clk_sam9x5_slow(hw);
289 return !!(readl(slowck->sckcr) & slowck->bits->cr_oscsel);
292 static const struct clk_ops sam9x5_slow_ops = {
293 .set_parent = clk_sam9x5_slow_set_parent,
294 .get_parent = clk_sam9x5_slow_get_parent,
297 static struct clk_hw * __init
298 at91_clk_register_sam9x5_slow(void __iomem *sckcr,
300 const char **parent_names,
302 const struct clk_slow_bits *bits)
304 struct clk_sam9x5_slow *slowck;
306 struct clk_init_data init;
309 if (!sckcr || !name || !parent_names || !num_parents)
310 return ERR_PTR(-EINVAL);
312 slowck = kzalloc(sizeof(*slowck), GFP_KERNEL);
314 return ERR_PTR(-ENOMEM);
317 init.ops = &sam9x5_slow_ops;
318 init.parent_names = parent_names;
319 init.num_parents = num_parents;
322 slowck->hw.init = &init;
323 slowck->sckcr = sckcr;
325 slowck->parent = !!(readl(sckcr) & slowck->bits->cr_oscsel);
328 ret = clk_hw_register(NULL, &slowck->hw);
337 static void __init at91sam9x5_sckc_register(struct device_node *np,
338 unsigned int rc_osc_startup_us,
339 const struct clk_slow_bits *bits)
341 const char *parent_names[2] = { "slow_rc_osc", "slow_osc" };
342 void __iomem *regbase = of_iomap(np, 0);
343 struct device_node *child = NULL;
344 const char *xtal_name;
351 hw = at91_clk_register_slow_rc_osc(regbase, parent_names[0], 32768,
352 50000000, rc_osc_startup_us,
357 xtal_name = of_clk_get_parent_name(np, 0);
359 /* DT backward compatibility */
360 child = of_get_compatible_child(np, "atmel,at91sam9x5-clk-slow-osc");
364 xtal_name = of_clk_get_parent_name(child, 0);
365 bypass = of_property_read_bool(child, "atmel,osc-bypass");
367 child = of_get_compatible_child(np, "atmel,at91sam9x5-clk-slow");
369 bypass = of_property_read_bool(np, "atmel,osc-bypass");
375 hw = at91_clk_register_slow_osc(regbase, parent_names[1], xtal_name,
376 1200000, bypass, bits);
380 hw = at91_clk_register_sam9x5_slow(regbase, "slowck", parent_names, 2,
385 of_clk_add_hw_provider(np, of_clk_hw_simple_get, hw);
387 /* DT backward compatibility */
389 of_clk_add_hw_provider(child, of_clk_hw_simple_get, hw);
392 static const struct clk_slow_bits at91sam9x5_bits = {
394 .cr_osc32en = BIT(1),
395 .cr_osc32byp = BIT(2),
399 static void __init of_at91sam9x5_sckc_setup(struct device_node *np)
401 at91sam9x5_sckc_register(np, 75, &at91sam9x5_bits);
403 CLK_OF_DECLARE(at91sam9x5_clk_sckc, "atmel,at91sam9x5-sckc",
404 of_at91sam9x5_sckc_setup);
406 static void __init of_sama5d3_sckc_setup(struct device_node *np)
408 at91sam9x5_sckc_register(np, 500, &at91sam9x5_bits);
410 CLK_OF_DECLARE(sama5d3_clk_sckc, "atmel,sama5d3-sckc",
411 of_sama5d3_sckc_setup);
413 static const struct clk_slow_bits at91sam9x60_bits = {
414 .cr_osc32en = BIT(1),
415 .cr_osc32byp = BIT(2),
416 .cr_oscsel = BIT(24),
419 static void __init of_sam9x60_sckc_setup(struct device_node *np)
421 void __iomem *regbase = of_iomap(np, 0);
422 struct clk_hw_onecell_data *clk_data;
423 struct clk_hw *slow_rc, *slow_osc;
424 const char *xtal_name;
425 const char *parent_names[2] = { "slow_rc_osc", "slow_osc" };
432 slow_rc = clk_hw_register_fixed_rate(NULL, parent_names[0], NULL, 0,
437 xtal_name = of_clk_get_parent_name(np, 0);
439 goto unregister_slow_rc;
441 bypass = of_property_read_bool(np, "atmel,osc-bypass");
442 slow_osc = at91_clk_register_slow_osc(regbase, parent_names[1],
443 xtal_name, 5000000, bypass,
445 if (IS_ERR(slow_osc))
446 goto unregister_slow_rc;
448 clk_data = kzalloc(sizeof(*clk_data) + (2 * sizeof(struct clk_hw *)),
451 goto unregister_slow_osc;
453 /* MD_SLCK and TD_SLCK. */
455 clk_data->hws[0] = clk_hw_register_fixed_rate(NULL, "md_slck",
458 if (IS_ERR(clk_data->hws[0]))
461 clk_data->hws[1] = at91_clk_register_sam9x5_slow(regbase, "td_slck",
464 if (IS_ERR(clk_data->hws[1]))
465 goto unregister_md_slck;
467 ret = of_clk_add_hw_provider(np, of_clk_hw_onecell_get, clk_data);
469 goto unregister_td_slck;
474 clk_hw_unregister(clk_data->hws[1]);
476 clk_hw_unregister(clk_data->hws[0]);
480 clk_hw_unregister(slow_osc);
482 clk_hw_unregister(slow_rc);
484 CLK_OF_DECLARE(sam9x60_clk_sckc, "microchip,sam9x60-sckc",
485 of_sam9x60_sckc_setup);
487 static int clk_sama5d4_slow_osc_prepare(struct clk_hw *hw)
489 struct clk_sama5d4_slow_osc *osc = to_clk_sama5d4_slow_osc(hw);
495 * Assume that if it has already been selected (for example by the
496 * bootloader), enough time has aready passed.
498 if ((readl(osc->sckcr) & osc->bits->cr_oscsel)) {
499 osc->prepared = true;
503 usleep_range(osc->startup_usec, osc->startup_usec + 1);
504 osc->prepared = true;
509 static int clk_sama5d4_slow_osc_is_prepared(struct clk_hw *hw)
511 struct clk_sama5d4_slow_osc *osc = to_clk_sama5d4_slow_osc(hw);
513 return osc->prepared;
516 static const struct clk_ops sama5d4_slow_osc_ops = {
517 .prepare = clk_sama5d4_slow_osc_prepare,
518 .is_prepared = clk_sama5d4_slow_osc_is_prepared,
521 static const struct clk_slow_bits at91sama5d4_bits = {
525 static void __init of_sama5d4_sckc_setup(struct device_node *np)
527 void __iomem *regbase = of_iomap(np, 0);
529 struct clk_sama5d4_slow_osc *osc;
530 struct clk_init_data init;
531 const char *xtal_name;
532 const char *parent_names[2] = { "slow_rc_osc", "slow_osc" };
538 hw = clk_hw_register_fixed_rate_with_accuracy(NULL, parent_names[0],
544 xtal_name = of_clk_get_parent_name(np, 0);
546 osc = kzalloc(sizeof(*osc), GFP_KERNEL);
550 init.name = parent_names[1];
551 init.ops = &sama5d4_slow_osc_ops;
552 init.parent_names = &xtal_name;
553 init.num_parents = 1;
554 init.flags = CLK_IGNORE_UNUSED;
556 osc->hw.init = &init;
557 osc->sckcr = regbase;
558 osc->startup_usec = 1200000;
559 osc->bits = &at91sama5d4_bits;
562 ret = clk_hw_register(NULL, &osc->hw);
568 hw = at91_clk_register_sam9x5_slow(regbase, "slowck", parent_names, 2,
573 of_clk_add_hw_provider(np, of_clk_hw_simple_get, hw);
575 CLK_OF_DECLARE(sama5d4_clk_sckc, "atmel,sama5d4-sckc",
576 of_sama5d4_sckc_setup);