aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm/plat-spear
diff options
context:
space:
mode:
authorViresh Kumar <viresh.kumar@st.com>2012-04-09 23:32:35 -0400
committerArnd Bergmann <arnd@arndb.de>2012-05-12 15:44:12 -0400
commit5df33a62c4a028d6fc7f2dcc159827d09b7334b8 (patch)
treef4da61ce3bf14e9bf4a1dae3188109a6de34f708 /arch/arm/plat-spear
parentf8abc080d33e69dfa2c3dd0f84c31832e2679091 (diff)
SPEAr: Switch to common clock framework
SPEAr SoCs used its own clock framework since now. From now on they will move to use common clock framework. This patch updates existing SPEAr machine support to adapt for common clock framework. Signed-off-by: Viresh Kumar <viresh.kumar@st.com> Reviewed-by: Mike Turquette <mturquette@linaro.org> Acked-by: Arnd Bergmann <arnd@arndb.de>
Diffstat (limited to 'arch/arm/plat-spear')
-rw-r--r--arch/arm/plat-spear/Makefile2
-rw-r--r--arch/arm/plat-spear/clock.c1005
-rw-r--r--arch/arm/plat-spear/include/plat/clock.h249
3 files changed, 1 insertions, 1255 deletions
diff --git a/arch/arm/plat-spear/Makefile b/arch/arm/plat-spear/Makefile
index e0f2e5b9530c..8c0cb6a965a3 100644
--- a/arch/arm/plat-spear/Makefile
+++ b/arch/arm/plat-spear/Makefile
@@ -3,6 +3,6 @@
3# 3#
4 4
5# Common support 5# Common support
6obj-y := clock.o restart.o time.o 6obj-y := restart.o time.o
7 7
8obj-$(CONFIG_ARCH_SPEAR3XX) += shirq.o padmux.o 8obj-$(CONFIG_ARCH_SPEAR3XX) += shirq.o padmux.o
diff --git a/arch/arm/plat-spear/clock.c b/arch/arm/plat-spear/clock.c
deleted file mode 100644
index 67dd00381ea6..000000000000
--- a/arch/arm/plat-spear/clock.c
+++ /dev/null
@@ -1,1005 +0,0 @@
1/*
2 * arch/arm/plat-spear/clock.c
3 *
4 * Clock framework for SPEAr platform
5 *
6 * Copyright (C) 2009 ST Microelectronics
7 * Viresh Kumar<viresh.kumar@st.com>
8 *
9 * This file is licensed under the terms of the GNU General Public
10 * License version 2. This program is licensed "as is" without any
11 * warranty of any kind, whether express or implied.
12 */
13
14#include <linux/bug.h>
15#include <linux/clk.h>
16#include <linux/debugfs.h>
17#include <linux/err.h>
18#include <linux/io.h>
19#include <linux/list.h>
20#include <linux/module.h>
21#include <linux/spinlock.h>
22#include <plat/clock.h>
23
24static DEFINE_SPINLOCK(clocks_lock);
25static LIST_HEAD(root_clks);
26#ifdef CONFIG_DEBUG_FS
27static LIST_HEAD(clocks);
28#endif
29
30static void propagate_rate(struct clk *, int on_init);
31#ifdef CONFIG_DEBUG_FS
32static int clk_debugfs_reparent(struct clk *);
33#endif
34
35static int generic_clk_enable(struct clk *clk)
36{
37 unsigned int val;
38
39 if (!clk->en_reg)
40 return -EFAULT;
41
42 val = readl(clk->en_reg);
43 if (unlikely(clk->flags & RESET_TO_ENABLE))
44 val &= ~(1 << clk->en_reg_bit);
45 else
46 val |= 1 << clk->en_reg_bit;
47
48 writel(val, clk->en_reg);
49
50 return 0;
51}
52
53static void generic_clk_disable(struct clk *clk)
54{
55 unsigned int val;
56
57 if (!clk->en_reg)
58 return;
59
60 val = readl(clk->en_reg);
61 if (unlikely(clk->flags & RESET_TO_ENABLE))
62 val |= 1 << clk->en_reg_bit;
63 else
64 val &= ~(1 << clk->en_reg_bit);
65
66 writel(val, clk->en_reg);
67}
68
69/* generic clk ops */
70static struct clkops generic_clkops = {
71 .enable = generic_clk_enable,
72 .disable = generic_clk_disable,
73};
74
75/* returns current programmed clocks clock info structure */
76static struct pclk_info *pclk_info_get(struct clk *clk)
77{
78 unsigned int val, i;
79 struct pclk_info *info = NULL;
80
81 val = (readl(clk->pclk_sel->pclk_sel_reg) >> clk->pclk_sel_shift)
82 & clk->pclk_sel->pclk_sel_mask;
83
84 for (i = 0; i < clk->pclk_sel->pclk_count; i++) {
85 if (clk->pclk_sel->pclk_info[i].pclk_val == val)
86 info = &clk->pclk_sel->pclk_info[i];
87 }
88
89 return info;
90}
91
92/*
93 * Set Update pclk, and pclk_info of clk and add clock sibling node to current
94 * parents children list
95 */
96static void clk_reparent(struct clk *clk, struct pclk_info *pclk_info)
97{
98 unsigned long flags;
99
100 spin_lock_irqsave(&clocks_lock, flags);
101 list_del(&clk->sibling);
102 list_add(&clk->sibling, &pclk_info->pclk->children);
103
104 clk->pclk = pclk_info->pclk;
105 spin_unlock_irqrestore(&clocks_lock, flags);
106
107#ifdef CONFIG_DEBUG_FS
108 clk_debugfs_reparent(clk);
109#endif
110}
111
112static void do_clk_disable(struct clk *clk)
113{
114 if (!clk)
115 return;
116
117 if (!clk->usage_count) {
118 WARN_ON(1);
119 return;
120 }
121
122 clk->usage_count--;
123
124 if (clk->usage_count == 0) {
125 /*
126 * Surely, there are no active childrens or direct users
127 * of this clock
128 */
129 if (clk->pclk)
130 do_clk_disable(clk->pclk);
131
132 if (clk->ops && clk->ops->disable)
133 clk->ops->disable(clk);
134 }
135}
136
137static int do_clk_enable(struct clk *clk)
138{
139 int ret = 0;
140
141 if (!clk)
142 return -EFAULT;
143
144 if (clk->usage_count == 0) {
145 if (clk->pclk) {
146 ret = do_clk_enable(clk->pclk);
147 if (ret)
148 goto err;
149 }
150 if (clk->ops && clk->ops->enable) {
151 ret = clk->ops->enable(clk);
152 if (ret) {
153 if (clk->pclk)
154 do_clk_disable(clk->pclk);
155 goto err;
156 }
157 }
158 /*
159 * Since the clock is going to be used for the first
160 * time please reclac
161 */
162 if (clk->recalc) {
163 ret = clk->recalc(clk);
164 if (ret)
165 goto err;
166 }
167 }
168 clk->usage_count++;
169err:
170 return ret;
171}
172
173/*
174 * clk_enable - inform the system when the clock source should be running.
175 * @clk: clock source
176 *
177 * If the clock can not be enabled/disabled, this should return success.
178 *
179 * Returns success (0) or negative errno.
180 */
181int clk_enable(struct clk *clk)
182{
183 unsigned long flags;
184 int ret = 0;
185
186 spin_lock_irqsave(&clocks_lock, flags);
187 ret = do_clk_enable(clk);
188 spin_unlock_irqrestore(&clocks_lock, flags);
189 return ret;
190}
191EXPORT_SYMBOL(clk_enable);
192
193/*
194 * clk_disable - inform the system when the clock source is no longer required.
195 * @clk: clock source
196 *
197 * Inform the system that a clock source is no longer required by
198 * a driver and may be shut down.
199 *
200 * Implementation detail: if the clock source is shared between
201 * multiple drivers, clk_enable() calls must be balanced by the
202 * same number of clk_disable() calls for the clock source to be
203 * disabled.
204 */
205void clk_disable(struct clk *clk)
206{
207 unsigned long flags;
208
209 spin_lock_irqsave(&clocks_lock, flags);
210 do_clk_disable(clk);
211 spin_unlock_irqrestore(&clocks_lock, flags);
212}
213EXPORT_SYMBOL(clk_disable);
214
215/**
216 * clk_get_rate - obtain the current clock rate (in Hz) for a clock source.
217 * This is only valid once the clock source has been enabled.
218 * @clk: clock source
219 */
220unsigned long clk_get_rate(struct clk *clk)
221{
222 unsigned long flags, rate;
223
224 spin_lock_irqsave(&clocks_lock, flags);
225 rate = clk->rate;
226 spin_unlock_irqrestore(&clocks_lock, flags);
227
228 return rate;
229}
230EXPORT_SYMBOL(clk_get_rate);
231
232/**
233 * clk_set_parent - set the parent clock source for this clock
234 * @clk: clock source
235 * @parent: parent clock source
236 *
237 * Returns success (0) or negative errno.
238 */
239int clk_set_parent(struct clk *clk, struct clk *parent)
240{
241 int i, found = 0, val = 0;
242 unsigned long flags;
243
244 if (!clk || !parent)
245 return -EFAULT;
246 if (clk->pclk == parent)
247 return 0;
248 if (!clk->pclk_sel)
249 return -EPERM;
250
251 /* check if requested parent is in clk parent list */
252 for (i = 0; i < clk->pclk_sel->pclk_count; i++) {
253 if (clk->pclk_sel->pclk_info[i].pclk == parent) {
254 found = 1;
255 break;
256 }
257 }
258
259 if (!found)
260 return -EINVAL;
261
262 spin_lock_irqsave(&clocks_lock, flags);
263 /* reflect parent change in hardware */
264 val = readl(clk->pclk_sel->pclk_sel_reg);
265 val &= ~(clk->pclk_sel->pclk_sel_mask << clk->pclk_sel_shift);
266 val |= clk->pclk_sel->pclk_info[i].pclk_val << clk->pclk_sel_shift;
267 writel(val, clk->pclk_sel->pclk_sel_reg);
268 spin_unlock_irqrestore(&clocks_lock, flags);
269
270 /* reflect parent change in software */
271 clk_reparent(clk, &clk->pclk_sel->pclk_info[i]);
272
273 propagate_rate(clk, 0);
274 return 0;
275}
276EXPORT_SYMBOL(clk_set_parent);
277
278/**
279 * clk_set_rate - set the clock rate for a clock source
280 * @clk: clock source
281 * @rate: desired clock rate in Hz
282 *
283 * Returns success (0) or negative errno.
284 */
285int clk_set_rate(struct clk *clk, unsigned long rate)
286{
287 unsigned long flags;
288 int ret = -EINVAL;
289
290 if (!clk || !rate)
291 return -EFAULT;
292
293 if (clk->set_rate) {
294 spin_lock_irqsave(&clocks_lock, flags);
295 ret = clk->set_rate(clk, rate);
296 if (!ret)
297 /* if successful -> propagate */
298 propagate_rate(clk, 0);
299 spin_unlock_irqrestore(&clocks_lock, flags);
300 } else if (clk->pclk) {
301 u32 mult = clk->div_factor ? clk->div_factor : 1;
302 ret = clk_set_rate(clk->pclk, mult * rate);
303 }
304
305 return ret;
306}
307EXPORT_SYMBOL(clk_set_rate);
308
309/* registers clock in platform clock framework */
310void clk_register(struct clk_lookup *cl)
311{
312 struct clk *clk;
313 unsigned long flags;
314
315 if (!cl || !cl->clk)
316 return;
317 clk = cl->clk;
318
319 spin_lock_irqsave(&clocks_lock, flags);
320
321 INIT_LIST_HEAD(&clk->children);
322 if (clk->flags & ALWAYS_ENABLED)
323 clk->ops = NULL;
324 else if (!clk->ops)
325 clk->ops = &generic_clkops;
326
327 /* root clock don't have any parents */
328 if (!clk->pclk && !clk->pclk_sel) {
329 list_add(&clk->sibling, &root_clks);
330 } else if (clk->pclk && !clk->pclk_sel) {
331 /* add clocks with only one parent to parent's children list */
332 list_add(&clk->sibling, &clk->pclk->children);
333 } else {
334 /* clocks with more than one parent */
335 struct pclk_info *pclk_info;
336
337 pclk_info = pclk_info_get(clk);
338 if (!pclk_info) {
339 pr_err("CLKDEV: invalid pclk info of clk with"
340 " %s dev_id and %s con_id\n",
341 cl->dev_id, cl->con_id);
342 } else {
343 clk->pclk = pclk_info->pclk;
344 list_add(&clk->sibling, &pclk_info->pclk->children);
345 }
346 }
347
348 spin_unlock_irqrestore(&clocks_lock, flags);
349
350 /* debugfs specific */
351#ifdef CONFIG_DEBUG_FS
352 list_add(&clk->node, &clocks);
353 clk->cl = cl;
354#endif
355
356 /* add clock to arm clockdev framework */
357 clkdev_add(cl);
358}
359
360/**
361 * propagate_rate - recalculate and propagate all clocks to children
362 * @pclk: parent clock required to be propogated
363 * @on_init: flag for enabling clocks which are ENABLED_ON_INIT.
364 *
365 * Recalculates all children clocks
366 */
367void propagate_rate(struct clk *pclk, int on_init)
368{
369 struct clk *clk, *_temp;
370 int ret = 0;
371
372 list_for_each_entry_safe(clk, _temp, &pclk->children, sibling) {
373 if (clk->recalc) {
374 ret = clk->recalc(clk);
375 /*
376 * recalc will return error if clk out is not programmed
377 * In this case configure default rate.
378 */
379 if (ret && clk->set_rate)
380 clk->set_rate(clk, 0);
381 }
382 propagate_rate(clk, on_init);
383
384 if (!on_init)
385 continue;
386
387 /* Enable clks enabled on init, in software view */
388 if (clk->flags & ENABLED_ON_INIT)
389 do_clk_enable(clk);
390 }
391}
392
393/**
394 * round_rate_index - return closest programmable rate index in rate_config tbl
395 * @clk: ptr to clock structure
396 * @drate: desired rate
397 * @rate: final rate will be returned in this variable only.
398 *
399 * Finds index in rate_config for highest clk rate which is less than
400 * requested rate. If there is no clk rate lesser than requested rate then
401 * -EINVAL is returned. This routine assumes that rate_config is written
402 * in incrementing order of clk rates.
403 * If drate passed is zero then default rate is programmed.
404 */
405static int
406round_rate_index(struct clk *clk, unsigned long drate, unsigned long *rate)
407{
408 unsigned long tmp = 0, prev_rate = 0;
409 int index;
410
411 if (!clk->calc_rate)
412 return -EFAULT;
413
414 if (!drate)
415 return -EINVAL;
416
417 /*
418 * This loops ends on two conditions:
419 * - as soon as clk is found with rate greater than requested rate.
420 * - if all clks in rate_config are smaller than requested rate.
421 */
422 for (index = 0; index < clk->rate_config.count; index++) {
423 prev_rate = tmp;
424 tmp = clk->calc_rate(clk, index);
425 if (drate < tmp) {
426 index--;
427 break;
428 }
429 }
430 /* return if can't find suitable clock */
431 if (index < 0) {
432 index = -EINVAL;
433 *rate = 0;
434 } else if (index == clk->rate_config.count) {
435 /* program with highest clk rate possible */
436 index = clk->rate_config.count - 1;
437 *rate = tmp;
438 } else
439 *rate = prev_rate;
440
441 return index;
442}
443
444/**
445 * clk_round_rate - adjust a rate to the exact rate a clock can provide
446 * @clk: clock source
447 * @rate: desired clock rate in Hz
448 *
449 * Returns rounded clock rate in Hz, or negative errno.
450 */
451long clk_round_rate(struct clk *clk, unsigned long drate)
452{
453 long rate = 0;
454 int index;
455
456 /*
457 * propagate call to parent who supports calc_rate. Similar approach is
458 * used in clk_set_rate.
459 */
460 if (!clk->calc_rate) {
461 u32 mult;
462 if (!clk->pclk)
463 return clk->rate;
464
465 mult = clk->div_factor ? clk->div_factor : 1;
466 return clk_round_rate(clk->pclk, mult * drate) / mult;
467 }
468
469 index = round_rate_index(clk, drate, &rate);
470 if (index >= 0)
471 return rate;
472 else
473 return index;
474}
475EXPORT_SYMBOL(clk_round_rate);
476
477/*All below functions are called with lock held */
478
479/*
480 * Calculates pll clk rate for specific value of mode, m, n and p
481 *
482 * In normal mode
483 * rate = (2 * M[15:8] * Fin)/(N * 2^P)
484 *
485 * In Dithered mode
486 * rate = (2 * M[15:0] * Fin)/(256 * N * 2^P)
487 */
488unsigned long pll_calc_rate(struct clk *clk, int index)
489{
490 unsigned long rate = clk->pclk->rate;
491 struct pll_rate_tbl *tbls = clk->rate_config.tbls;
492 unsigned int mode;
493
494 mode = tbls[index].mode ? 256 : 1;
495 return (((2 * rate / 10000) * tbls[index].m) /
496 (mode * tbls[index].n * (1 << tbls[index].p))) * 10000;
497}
498
499/*
500 * calculates current programmed rate of pll1
501 *
502 * In normal mode
503 * rate = (2 * M[15:8] * Fin)/(N * 2^P)
504 *
505 * In Dithered mode
506 * rate = (2 * M[15:0] * Fin)/(256 * N * 2^P)
507 */
508int pll_clk_recalc(struct clk *clk)
509{
510 struct pll_clk_config *config = clk->private_data;
511 unsigned int num = 2, den = 0, val, mode = 0;
512
513 mode = (readl(config->mode_reg) >> config->masks->mode_shift) &
514 config->masks->mode_mask;
515
516 val = readl(config->cfg_reg);
517 /* calculate denominator */
518 den = (val >> config->masks->div_p_shift) & config->masks->div_p_mask;
519 den = 1 << den;
520 den *= (val >> config->masks->div_n_shift) & config->masks->div_n_mask;
521
522 /* calculate numerator & denominator */
523 if (!mode) {
524 /* Normal mode */
525 num *= (val >> config->masks->norm_fdbk_m_shift) &
526 config->masks->norm_fdbk_m_mask;
527 } else {
528 /* Dithered mode */
529 num *= (val >> config->masks->dith_fdbk_m_shift) &
530 config->masks->dith_fdbk_m_mask;
531 den *= 256;
532 }
533
534 if (!den)
535 return -EINVAL;
536
537 clk->rate = (((clk->pclk->rate/10000) * num) / den) * 10000;
538 return 0;
539}
540
541/*
542 * Configures new clock rate of pll
543 */
544int pll_clk_set_rate(struct clk *clk, unsigned long desired_rate)
545{
546 struct pll_rate_tbl *tbls = clk->rate_config.tbls;
547 struct pll_clk_config *config = clk->private_data;
548 unsigned long val, rate;
549 int i;
550
551 i = round_rate_index(clk, desired_rate, &rate);
552 if (i < 0)
553 return i;
554
555 val = readl(config->mode_reg) &
556 ~(config->masks->mode_mask << config->masks->mode_shift);
557 val |= (tbls[i].mode & config->masks->mode_mask) <<
558 config->masks->mode_shift;
559 writel(val, config->mode_reg);
560
561 val = readl(config->cfg_reg) &
562 ~(config->masks->div_p_mask << config->masks->div_p_shift);
563 val |= (tbls[i].p & config->masks->div_p_mask) <<
564 config->masks->div_p_shift;
565 val &= ~(config->masks->div_n_mask << config->masks->div_n_shift);
566 val |= (tbls[i].n & config->masks->div_n_mask) <<
567 config->masks->div_n_shift;
568 val &= ~(config->masks->dith_fdbk_m_mask <<
569 config->masks->dith_fdbk_m_shift);
570 if (tbls[i].mode)
571 val |= (tbls[i].m & config->masks->dith_fdbk_m_mask) <<
572 config->masks->dith_fdbk_m_shift;
573 else
574 val |= (tbls[i].m & config->masks->norm_fdbk_m_mask) <<
575 config->masks->norm_fdbk_m_shift;
576
577 writel(val, config->cfg_reg);
578
579 clk->rate = rate;
580
581 return 0;
582}
583
584/*
585 * Calculates ahb, apb clk rate for specific value of div
586 */
587unsigned long bus_calc_rate(struct clk *clk, int index)
588{
589 unsigned long rate = clk->pclk->rate;
590 struct bus_rate_tbl *tbls = clk->rate_config.tbls;
591
592 return rate / (tbls[index].div + 1);
593}
594
595/* calculates current programmed rate of ahb or apb bus */
596int bus_clk_recalc(struct clk *clk)
597{
598 struct bus_clk_config *config = clk->private_data;
599 unsigned int div;
600
601 div = ((readl(config->reg) >> config->masks->shift) &
602 config->masks->mask) + 1;
603
604 if (!div)
605 return -EINVAL;
606
607 clk->rate = (unsigned long)clk->pclk->rate / div;
608 return 0;
609}
610
611/* Configures new clock rate of AHB OR APB bus */
612int bus_clk_set_rate(struct clk *clk, unsigned long desired_rate)
613{
614 struct bus_rate_tbl *tbls = clk->rate_config.tbls;
615 struct bus_clk_config *config = clk->private_data;
616 unsigned long val, rate;
617 int i;
618
619 i = round_rate_index(clk, desired_rate, &rate);
620 if (i < 0)
621 return i;
622
623 val = readl(config->reg) &
624 ~(config->masks->mask << config->masks->shift);
625 val |= (tbls[i].div & config->masks->mask) << config->masks->shift;
626 writel(val, config->reg);
627
628 clk->rate = rate;
629
630 return 0;
631}
632
633/*
634 * gives rate for different values of eq, x and y
635 *
636 * Fout from synthesizer can be given from two equations:
637 * Fout1 = (Fin * X/Y)/2 EQ1
638 * Fout2 = Fin * X/Y EQ2
639 */
640unsigned long aux_calc_rate(struct clk *clk, int index)
641{
642 unsigned long rate = clk->pclk->rate;
643 struct aux_rate_tbl *tbls = clk->rate_config.tbls;
644 u8 eq = tbls[index].eq ? 1 : 2;
645
646 return (((rate/10000) * tbls[index].xscale) /
647 (tbls[index].yscale * eq)) * 10000;
648}
649
650/*
651 * calculates current programmed rate of auxiliary synthesizers
652 * used by: UART, FIRDA
653 *
654 * Fout from synthesizer can be given from two equations:
655 * Fout1 = (Fin * X/Y)/2
656 * Fout2 = Fin * X/Y
657 *
658 * Selection of eqn 1 or 2 is programmed in register
659 */
660int aux_clk_recalc(struct clk *clk)
661{
662 struct aux_clk_config *config = clk->private_data;
663 unsigned int num = 1, den = 1, val, eqn;
664
665 val = readl(config->synth_reg);
666
667 eqn = (val >> config->masks->eq_sel_shift) &
668 config->masks->eq_sel_mask;
669 if (eqn == config->masks->eq1_mask)
670 den *= 2;
671
672 /* calculate numerator */
673 num = (val >> config->masks->xscale_sel_shift) &
674 config->masks->xscale_sel_mask;
675
676 /* calculate denominator */
677 den *= (val >> config->masks->yscale_sel_shift) &
678 config->masks->yscale_sel_mask;
679
680 if (!den)
681 return -EINVAL;
682
683 clk->rate = (((clk->pclk->rate/10000) * num) / den) * 10000;
684 return 0;
685}
686
687/* Configures new clock rate of auxiliary synthesizers used by: UART, FIRDA*/
688int aux_clk_set_rate(struct clk *clk, unsigned long desired_rate)
689{
690 struct aux_rate_tbl *tbls = clk->rate_config.tbls;
691 struct aux_clk_config *config = clk->private_data;
692 unsigned long val, rate;
693 int i;
694
695 i = round_rate_index(clk, desired_rate, &rate);
696 if (i < 0)
697 return i;
698
699 val = readl(config->synth_reg) &
700 ~(config->masks->eq_sel_mask << config->masks->eq_sel_shift);
701 val |= (tbls[i].eq & config->masks->eq_sel_mask) <<
702 config->masks->eq_sel_shift;
703 val &= ~(config->masks->xscale_sel_mask <<
704 config->masks->xscale_sel_shift);
705 val |= (tbls[i].xscale & config->masks->xscale_sel_mask) <<
706 config->masks->xscale_sel_shift;
707 val &= ~(config->masks->yscale_sel_mask <<
708 config->masks->yscale_sel_shift);
709 val |= (tbls[i].yscale & config->masks->yscale_sel_mask) <<
710 config->masks->yscale_sel_shift;
711 writel(val, config->synth_reg);
712
713 clk->rate = rate;
714
715 return 0;
716}
717
718/*
719 * Calculates gpt clk rate for different values of mscale and nscale
720 *
721 * Fout= Fin/((2 ^ (N+1)) * (M+1))
722 */
723unsigned long gpt_calc_rate(struct clk *clk, int index)
724{
725 unsigned long rate = clk->pclk->rate;
726 struct gpt_rate_tbl *tbls = clk->rate_config.tbls;
727
728 return rate / ((1 << (tbls[index].nscale + 1)) *
729 (tbls[index].mscale + 1));
730}
731
732/*
733 * calculates current programmed rate of gpt synthesizers
734 * Fout from synthesizer can be given from below equations:
735 * Fout= Fin/((2 ^ (N+1)) * (M+1))
736 */
737int gpt_clk_recalc(struct clk *clk)
738{
739 struct gpt_clk_config *config = clk->private_data;
740 unsigned int div = 1, val;
741
742 val = readl(config->synth_reg);
743 div += (val >> config->masks->mscale_sel_shift) &
744 config->masks->mscale_sel_mask;
745 div *= 1 << (((val >> config->masks->nscale_sel_shift) &
746 config->masks->nscale_sel_mask) + 1);
747
748 if (!div)
749 return -EINVAL;
750
751 clk->rate = (unsigned long)clk->pclk->rate / div;
752 return 0;
753}
754
755/* Configures new clock rate of gptiliary synthesizers used by: UART, FIRDA*/
756int gpt_clk_set_rate(struct clk *clk, unsigned long desired_rate)
757{
758 struct gpt_rate_tbl *tbls = clk->rate_config.tbls;
759 struct gpt_clk_config *config = clk->private_data;
760 unsigned long val, rate;
761 int i;
762
763 i = round_rate_index(clk, desired_rate, &rate);
764 if (i < 0)
765 return i;
766
767 val = readl(config->synth_reg) & ~(config->masks->mscale_sel_mask <<
768 config->masks->mscale_sel_shift);
769 val |= (tbls[i].mscale & config->masks->mscale_sel_mask) <<
770 config->masks->mscale_sel_shift;
771 val &= ~(config->masks->nscale_sel_mask <<
772 config->masks->nscale_sel_shift);
773 val |= (tbls[i].nscale & config->masks->nscale_sel_mask) <<
774 config->masks->nscale_sel_shift;
775 writel(val, config->synth_reg);
776
777 clk->rate = rate;
778
779 return 0;
780}
781
782/*
783 * Calculates clcd clk rate for different values of div
784 *
785 * Fout from synthesizer can be given from below equation:
786 * Fout= Fin/2*div (division factor)
787 * div is 17 bits:-
788 * 0-13 (fractional part)
789 * 14-16 (integer part)
790 * To calculate Fout we left shift val by 14 bits and divide Fin by
791 * complete div (including fractional part) and then right shift the
792 * result by 14 places.
793 */
794unsigned long clcd_calc_rate(struct clk *clk, int index)
795{
796 unsigned long rate = clk->pclk->rate;
797 struct clcd_rate_tbl *tbls = clk->rate_config.tbls;
798
799 rate /= 1000;
800 rate <<= 12;
801 rate /= (2 * tbls[index].div);
802 rate >>= 12;
803 rate *= 1000;
804
805 return rate;
806}
807
808/*
809 * calculates current programmed rate of clcd synthesizer
810 * Fout from synthesizer can be given from below equation:
811 * Fout= Fin/2*div (division factor)
812 * div is 17 bits:-
813 * 0-13 (fractional part)
814 * 14-16 (integer part)
815 * To calculate Fout we left shift val by 14 bits and divide Fin by
816 * complete div (including fractional part) and then right shift the
817 * result by 14 places.
818 */
819int clcd_clk_recalc(struct clk *clk)
820{
821 struct clcd_clk_config *config = clk->private_data;
822 unsigned int div = 1;
823 unsigned long prate;
824 unsigned int val;
825
826 val = readl(config->synth_reg);
827 div = (val >> config->masks->div_factor_shift) &
828 config->masks->div_factor_mask;
829
830 if (!div)
831 return -EINVAL;
832
833 prate = clk->pclk->rate / 1000; /* first level division, make it KHz */
834
835 clk->rate = (((unsigned long)prate << 12) / (2 * div)) >> 12;
836 clk->rate *= 1000;
837 return 0;
838}
839
840/* Configures new clock rate of auxiliary synthesizers used by: UART, FIRDA*/
841int clcd_clk_set_rate(struct clk *clk, unsigned long desired_rate)
842{
843 struct clcd_rate_tbl *tbls = clk->rate_config.tbls;
844 struct clcd_clk_config *config = clk->private_data;
845 unsigned long val, rate;
846 int i;
847
848 i = round_rate_index(clk, desired_rate, &rate);
849 if (i < 0)
850 return i;
851
852 val = readl(config->synth_reg) & ~(config->masks->div_factor_mask <<
853 config->masks->div_factor_shift);
854 val |= (tbls[i].div & config->masks->div_factor_mask) <<
855 config->masks->div_factor_shift;
856 writel(val, config->synth_reg);
857
858 clk->rate = rate;
859
860 return 0;
861}
862
863/*
864 * Used for clocks that always have value as the parent clock divided by a
865 * fixed divisor
866 */
867int follow_parent(struct clk *clk)
868{
869 unsigned int div_factor = (clk->div_factor < 1) ? 1 : clk->div_factor;
870
871 clk->rate = clk->pclk->rate/div_factor;
872 return 0;
873}
874
875/**
876 * recalc_root_clocks - recalculate and propagate all root clocks
877 *
878 * Recalculates all root clocks (clocks with no parent), which if the
879 * clock's .recalc is set correctly, should also propagate their rates.
880 */
881void recalc_root_clocks(void)
882{
883 struct clk *pclk;
884 unsigned long flags;
885 int ret = 0;
886
887 spin_lock_irqsave(&clocks_lock, flags);
888 list_for_each_entry(pclk, &root_clks, sibling) {
889 if (pclk->recalc) {
890 ret = pclk->recalc(pclk);
891 /*
892 * recalc will return error if clk out is not programmed
893 * In this case configure default clock.
894 */
895 if (ret && pclk->set_rate)
896 pclk->set_rate(pclk, 0);
897 }
898 propagate_rate(pclk, 1);
899 /* Enable clks enabled on init, in software view */
900 if (pclk->flags & ENABLED_ON_INIT)
901 do_clk_enable(pclk);
902 }
903 spin_unlock_irqrestore(&clocks_lock, flags);
904}
905
906void __init clk_init(void)
907{
908 recalc_root_clocks();
909}
910
911#ifdef CONFIG_DEBUG_FS
912/*
913 * debugfs support to trace clock tree hierarchy and attributes
914 */
915static struct dentry *clk_debugfs_root;
916static int clk_debugfs_register_one(struct clk *c)
917{
918 int err;
919 struct dentry *d;
920 struct clk *pa = c->pclk;
921 char s[255];
922 char *p = s;
923
924 if (c) {
925 if (c->cl->con_id)
926 p += sprintf(p, "%s", c->cl->con_id);
927 if (c->cl->dev_id)
928 p += sprintf(p, "%s", c->cl->dev_id);
929 }
930 d = debugfs_create_dir(s, pa ? pa->dent : clk_debugfs_root);
931 if (!d)
932 return -ENOMEM;
933 c->dent = d;
934
935 d = debugfs_create_u32("usage_count", S_IRUGO, c->dent,
936 (u32 *)&c->usage_count);
937 if (!d) {
938 err = -ENOMEM;
939 goto err_out;
940 }
941 d = debugfs_create_u32("rate", S_IRUGO, c->dent, (u32 *)&c->rate);
942 if (!d) {
943 err = -ENOMEM;
944 goto err_out;
945 }
946 d = debugfs_create_x32("flags", S_IRUGO, c->dent, (u32 *)&c->flags);
947 if (!d) {
948 err = -ENOMEM;
949 goto err_out;
950 }
951 return 0;
952
953err_out:
954 debugfs_remove_recursive(c->dent);
955 return err;
956}
957
958static int clk_debugfs_register(struct clk *c)
959{
960 int err;
961 struct clk *pa = c->pclk;
962
963 if (pa && !pa->dent) {
964 err = clk_debugfs_register(pa);
965 if (err)
966 return err;
967 }
968
969 if (!c->dent) {
970 err = clk_debugfs_register_one(c);
971 if (err)
972 return err;
973 }
974 return 0;
975}
976
977static int __init clk_debugfs_init(void)
978{
979 struct clk *c;
980 struct dentry *d;
981 int err;
982
983 d = debugfs_create_dir("clock", NULL);
984 if (!d)
985 return -ENOMEM;
986 clk_debugfs_root = d;
987
988 list_for_each_entry(c, &clocks, node) {
989 err = clk_debugfs_register(c);
990 if (err)
991 goto err_out;
992 }
993 return 0;
994err_out:
995 debugfs_remove_recursive(clk_debugfs_root);
996 return err;
997}
998late_initcall(clk_debugfs_init);
999
1000static int clk_debugfs_reparent(struct clk *c)
1001{
1002 debugfs_remove(c->dent);
1003 return clk_debugfs_register_one(c);
1004}
1005#endif /* CONFIG_DEBUG_FS */
diff --git a/arch/arm/plat-spear/include/plat/clock.h b/arch/arm/plat-spear/include/plat/clock.h
deleted file mode 100644
index 0062bafef12d..000000000000
--- a/arch/arm/plat-spear/include/plat/clock.h
+++ /dev/null
@@ -1,249 +0,0 @@
1/*
2 * arch/arm/plat-spear/include/plat/clock.h
3 *
4 * Clock framework definitions for SPEAr platform
5 *
6 * Copyright (C) 2009 ST Microelectronics
7 * Viresh Kumar<viresh.kumar@st.com>
8 *
9 * This file is licensed under the terms of the GNU General Public
10 * License version 2. This program is licensed "as is" without any
11 * warranty of any kind, whether express or implied.
12 */
13
14#ifndef __PLAT_CLOCK_H
15#define __PLAT_CLOCK_H
16
17#include <linux/list.h>
18#include <linux/clkdev.h>
19#include <linux/types.h>
20
21/* clk structure flags */
22#define ALWAYS_ENABLED (1 << 0) /* clock always enabled */
23#define RESET_TO_ENABLE (1 << 1) /* reset register bit to enable clk */
24#define ENABLED_ON_INIT (1 << 2) /* clocks enabled at init */
25
26/**
27 * struct clkops - clock operations
28 * @enable: pointer to clock enable function
29 * @disable: pointer to clock disable function
30 */
31struct clkops {
32 int (*enable) (struct clk *);
33 void (*disable) (struct clk *);
34};
35
36/**
37 * struct pclk_info - parents info
38 * @pclk: pointer to parent clk
39 * @pclk_val: value to be written for selecting this parent
40 */
41struct pclk_info {
42 struct clk *pclk;
43 u8 pclk_val;
44};
45
46/**
47 * struct pclk_sel - parents selection configuration
48 * @pclk_info: pointer to array of parent clock info
49 * @pclk_count: number of parents
50 * @pclk_sel_reg: register for selecting a parent
51 * @pclk_sel_mask: mask for selecting parent (can be used to clear bits also)
52 */
53struct pclk_sel {
54 struct pclk_info *pclk_info;
55 u8 pclk_count;
56 void __iomem *pclk_sel_reg;
57 unsigned int pclk_sel_mask;
58};
59
60/**
61 * struct rate_config - clk rate configurations
62 * @tbls: array of device specific clk rate tables, in ascending order of rates
63 * @count: size of tbls array
64 * @default_index: default setting when originally disabled
65 */
66struct rate_config {
67 void *tbls;
68 u8 count;
69 u8 default_index;
70};
71
72/**
73 * struct clk - clock structure
74 * @usage_count: num of users who enabled this clock
75 * @flags: flags for clock properties
76 * @rate: programmed clock rate in Hz
77 * @en_reg: clk enable/disable reg
78 * @en_reg_bit: clk enable/disable bit
79 * @ops: clk enable/disable ops - generic_clkops selected if NULL
80 * @recalc: pointer to clock rate recalculate function
81 * @set_rate: pointer to clock set rate function
82 * @calc_rate: pointer to clock get rate function for index
83 * @rate_config: rate configuration information, used by set_rate
84 * @div_factor: division factor to parent clock.
85 * @pclk: current parent clk
86 * @pclk_sel: pointer to parent selection structure
87 * @pclk_sel_shift: register shift for selecting parent of this clock
88 * @children: list for childrens or this clock
89 * @sibling: node for list of clocks having same parents
90 * @private_data: clock specific private data
91 * @node: list to maintain clocks linearly
92 * @cl: clocklook up associated with this clock
93 * @dent: object for debugfs
94 */
95struct clk {
96 unsigned int usage_count;
97 unsigned int flags;
98 unsigned long rate;
99 void __iomem *en_reg;
100 u8 en_reg_bit;
101 const struct clkops *ops;
102 int (*recalc) (struct clk *);
103 int (*set_rate) (struct clk *, unsigned long rate);
104 unsigned long (*calc_rate)(struct clk *, int index);
105 struct rate_config rate_config;
106 unsigned int div_factor;
107
108 struct clk *pclk;
109 struct pclk_sel *pclk_sel;
110 unsigned int pclk_sel_shift;
111
112 struct list_head children;
113 struct list_head sibling;
114 void *private_data;
115#ifdef CONFIG_DEBUG_FS
116 struct list_head node;
117 struct clk_lookup *cl;
118 struct dentry *dent;
119#endif
120};
121
122/* pll configuration structure */
123struct pll_clk_masks {
124 u32 mode_mask;
125 u32 mode_shift;
126
127 u32 norm_fdbk_m_mask;
128 u32 norm_fdbk_m_shift;
129 u32 dith_fdbk_m_mask;
130 u32 dith_fdbk_m_shift;
131 u32 div_p_mask;
132 u32 div_p_shift;
133 u32 div_n_mask;
134 u32 div_n_shift;
135};
136
137struct pll_clk_config {
138 void __iomem *mode_reg;
139 void __iomem *cfg_reg;
140 struct pll_clk_masks *masks;
141};
142
143/* pll clk rate config structure */
144struct pll_rate_tbl {
145 u8 mode;
146 u16 m;
147 u8 n;
148 u8 p;
149};
150
151/* ahb and apb bus configuration structure */
152struct bus_clk_masks {
153 u32 mask;
154 u32 shift;
155};
156
157struct bus_clk_config {
158 void __iomem *reg;
159 struct bus_clk_masks *masks;
160};
161
162/* ahb and apb clk bus rate config structure */
163struct bus_rate_tbl {
164 u8 div;
165};
166
167/* Aux clk configuration structure: applicable to UART and FIRDA */
168struct aux_clk_masks {
169 u32 eq_sel_mask;
170 u32 eq_sel_shift;
171 u32 eq1_mask;
172 u32 eq2_mask;
173 u32 xscale_sel_mask;
174 u32 xscale_sel_shift;
175 u32 yscale_sel_mask;
176 u32 yscale_sel_shift;
177};
178
179struct aux_clk_config {
180 void __iomem *synth_reg;
181 struct aux_clk_masks *masks;
182};
183
184/* aux clk rate config structure */
185struct aux_rate_tbl {
186 u16 xscale;
187 u16 yscale;
188 u8 eq;
189};
190
191/* GPT clk configuration structure */
192struct gpt_clk_masks {
193 u32 mscale_sel_mask;
194 u32 mscale_sel_shift;
195 u32 nscale_sel_mask;
196 u32 nscale_sel_shift;
197};
198
199struct gpt_clk_config {
200 void __iomem *synth_reg;
201 struct gpt_clk_masks *masks;
202};
203
204/* gpt clk rate config structure */
205struct gpt_rate_tbl {
206 u16 mscale;
207 u16 nscale;
208};
209
210/* clcd clk configuration structure */
211struct clcd_synth_masks {
212 u32 div_factor_mask;
213 u32 div_factor_shift;
214};
215
216struct clcd_clk_config {
217 void __iomem *synth_reg;
218 struct clcd_synth_masks *masks;
219};
220
221/* clcd clk rate config structure */
222struct clcd_rate_tbl {
223 u16 div;
224};
225
226/* platform specific clock functions */
227void __init clk_init(void);
228void clk_register(struct clk_lookup *cl);
229void recalc_root_clocks(void);
230
231/* clock recalc & set rate functions */
232int follow_parent(struct clk *clk);
233unsigned long pll_calc_rate(struct clk *clk, int index);
234int pll_clk_recalc(struct clk *clk);
235int pll_clk_set_rate(struct clk *clk, unsigned long desired_rate);
236unsigned long bus_calc_rate(struct clk *clk, int index);
237int bus_clk_recalc(struct clk *clk);
238int bus_clk_set_rate(struct clk *clk, unsigned long desired_rate);
239unsigned long gpt_calc_rate(struct clk *clk, int index);
240int gpt_clk_recalc(struct clk *clk);
241int gpt_clk_set_rate(struct clk *clk, unsigned long desired_rate);
242unsigned long aux_calc_rate(struct clk *clk, int index);
243int aux_clk_recalc(struct clk *clk);
244int aux_clk_set_rate(struct clk *clk, unsigned long desired_rate);
245unsigned long clcd_calc_rate(struct clk *clk, int index);
246int clcd_clk_recalc(struct clk *clk);
247int clcd_clk_set_rate(struct clk *clk, unsigned long desired_rate);
248
249#endif /* __PLAT_CLOCK_H */