blob: 7e7ab606dc494a6ff5e00cfdc1dedf8f4efc2455 [file] [log] [blame]
viresh kumar8c0236f2010-04-01 12:30:46 +01001/*
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>
viresh kumaraf89fd82011-02-16 07:40:39 +010015#include <linux/clk.h>
viresh kumar8c0236f2010-04-01 12:30:46 +010016#include <linux/err.h>
17#include <linux/io.h>
18#include <linux/list.h>
19#include <linux/module.h>
20#include <linux/spinlock.h>
viresh kumar8c0236f2010-04-01 12:30:46 +010021#include <plat/clock.h>
22
23static DEFINE_SPINLOCK(clocks_lock);
24static LIST_HEAD(root_clks);
25
viresh kumaraf89fd82011-02-16 07:40:39 +010026static void propagate_rate(struct clk *, int on_init);
viresh kumar8c0236f2010-04-01 12:30:46 +010027
28static int generic_clk_enable(struct clk *clk)
29{
30 unsigned int val;
31
32 if (!clk->en_reg)
33 return -EFAULT;
34
35 val = readl(clk->en_reg);
36 if (unlikely(clk->flags & RESET_TO_ENABLE))
37 val &= ~(1 << clk->en_reg_bit);
38 else
39 val |= 1 << clk->en_reg_bit;
40
41 writel(val, clk->en_reg);
42
43 return 0;
44}
45
46static void generic_clk_disable(struct clk *clk)
47{
48 unsigned int val;
49
50 if (!clk->en_reg)
51 return;
52
53 val = readl(clk->en_reg);
54 if (unlikely(clk->flags & RESET_TO_ENABLE))
55 val |= 1 << clk->en_reg_bit;
56 else
57 val &= ~(1 << clk->en_reg_bit);
58
59 writel(val, clk->en_reg);
60}
61
62/* generic clk ops */
63static struct clkops generic_clkops = {
64 .enable = generic_clk_enable,
65 .disable = generic_clk_disable,
66};
67
viresh kumaraf89fd82011-02-16 07:40:39 +010068/* returns current programmed clocks clock info structure */
69static struct pclk_info *pclk_info_get(struct clk *clk)
70{
71 unsigned int val, i;
72 struct pclk_info *info = NULL;
73
74 val = (readl(clk->pclk_sel->pclk_sel_reg) >> clk->pclk_sel_shift)
75 & clk->pclk_sel->pclk_sel_mask;
76
77 for (i = 0; i < clk->pclk_sel->pclk_count; i++) {
78 if (clk->pclk_sel->pclk_info[i].pclk_val == val)
79 info = &clk->pclk_sel->pclk_info[i];
80 }
81
82 return info;
83}
84
85/*
86 * Set Update pclk, and pclk_info of clk and add clock sibling node to current
87 * parents children list
88 */
89static void clk_reparent(struct clk *clk, struct pclk_info *pclk_info)
90{
91 unsigned long flags;
92
93 spin_lock_irqsave(&clocks_lock, flags);
94 list_del(&clk->sibling);
95 list_add(&clk->sibling, &pclk_info->pclk->children);
96
97 clk->pclk = pclk_info->pclk;
98 spin_unlock_irqrestore(&clocks_lock, flags);
99}
100
101static void do_clk_disable(struct clk *clk)
102{
103 if (!clk)
104 return;
105
106 if (!clk->usage_count) {
107 WARN_ON(1);
108 return;
109 }
110
111 clk->usage_count--;
112
113 if (clk->usage_count == 0) {
114 /*
115 * Surely, there are no active childrens or direct users
116 * of this clock
117 */
118 if (clk->pclk)
119 do_clk_disable(clk->pclk);
120
121 if (clk->ops && clk->ops->disable)
122 clk->ops->disable(clk);
123 }
124}
125
126static int do_clk_enable(struct clk *clk)
127{
128 int ret = 0;
129
130 if (!clk)
131 return -EFAULT;
132
133 if (clk->usage_count == 0) {
134 if (clk->pclk) {
135 ret = do_clk_enable(clk->pclk);
136 if (ret)
137 goto err;
138 }
139 if (clk->ops && clk->ops->enable) {
140 ret = clk->ops->enable(clk);
141 if (ret) {
142 if (clk->pclk)
143 do_clk_disable(clk->pclk);
144 goto err;
145 }
146 }
147 /*
148 * Since the clock is going to be used for the first
149 * time please reclac
150 */
151 if (clk->recalc) {
152 ret = clk->recalc(clk);
153 if (ret)
154 goto err;
155 }
156 }
157 clk->usage_count++;
158err:
159 return ret;
160}
161
viresh kumar8c0236f2010-04-01 12:30:46 +0100162/*
163 * clk_enable - inform the system when the clock source should be running.
164 * @clk: clock source
165 *
166 * If the clock can not be enabled/disabled, this should return success.
167 *
168 * Returns success (0) or negative errno.
169 */
170int clk_enable(struct clk *clk)
171{
172 unsigned long flags;
173 int ret = 0;
174
viresh kumar8c0236f2010-04-01 12:30:46 +0100175 spin_lock_irqsave(&clocks_lock, flags);
viresh kumaraf89fd82011-02-16 07:40:39 +0100176 ret = do_clk_enable(clk);
viresh kumar8c0236f2010-04-01 12:30:46 +0100177 spin_unlock_irqrestore(&clocks_lock, flags);
viresh kumar8c0236f2010-04-01 12:30:46 +0100178 return ret;
179}
180EXPORT_SYMBOL(clk_enable);
181
182/*
183 * clk_disable - inform the system when the clock source is no longer required.
184 * @clk: clock source
185 *
186 * Inform the system that a clock source is no longer required by
187 * a driver and may be shut down.
188 *
189 * Implementation detail: if the clock source is shared between
190 * multiple drivers, clk_enable() calls must be balanced by the
191 * same number of clk_disable() calls for the clock source to be
192 * disabled.
193 */
194void clk_disable(struct clk *clk)
195{
196 unsigned long flags;
197
viresh kumar8c0236f2010-04-01 12:30:46 +0100198 spin_lock_irqsave(&clocks_lock, flags);
viresh kumaraf89fd82011-02-16 07:40:39 +0100199 do_clk_disable(clk);
viresh kumar8c0236f2010-04-01 12:30:46 +0100200 spin_unlock_irqrestore(&clocks_lock, flags);
201}
202EXPORT_SYMBOL(clk_disable);
203
204/**
205 * clk_get_rate - obtain the current clock rate (in Hz) for a clock source.
206 * This is only valid once the clock source has been enabled.
207 * @clk: clock source
208 */
209unsigned long clk_get_rate(struct clk *clk)
210{
211 unsigned long flags, rate;
212
213 spin_lock_irqsave(&clocks_lock, flags);
214 rate = clk->rate;
215 spin_unlock_irqrestore(&clocks_lock, flags);
216
217 return rate;
218}
219EXPORT_SYMBOL(clk_get_rate);
220
221/**
222 * clk_set_parent - set the parent clock source for this clock
223 * @clk: clock source
224 * @parent: parent clock source
225 *
226 * Returns success (0) or negative errno.
227 */
228int clk_set_parent(struct clk *clk, struct clk *parent)
229{
230 int i, found = 0, val = 0;
231 unsigned long flags;
232
viresh kumaraf89fd82011-02-16 07:40:39 +0100233 if (!clk || !parent)
viresh kumar8c0236f2010-04-01 12:30:46 +0100234 return -EFAULT;
viresh kumar8c0236f2010-04-01 12:30:46 +0100235 if (clk->pclk == parent)
236 return 0;
viresh kumaraf89fd82011-02-16 07:40:39 +0100237 if (!clk->pclk_sel)
238 return -EPERM;
viresh kumar8c0236f2010-04-01 12:30:46 +0100239
viresh kumaraf89fd82011-02-16 07:40:39 +0100240 /* check if requested parent is in clk parent list */
viresh kumar8c0236f2010-04-01 12:30:46 +0100241 for (i = 0; i < clk->pclk_sel->pclk_count; i++) {
242 if (clk->pclk_sel->pclk_info[i].pclk == parent) {
243 found = 1;
244 break;
245 }
246 }
247
248 if (!found)
249 return -EINVAL;
250
251 spin_lock_irqsave(&clocks_lock, flags);
252 /* reflect parent change in hardware */
253 val = readl(clk->pclk_sel->pclk_sel_reg);
254 val &= ~(clk->pclk_sel->pclk_sel_mask << clk->pclk_sel_shift);
viresh kumaraf89fd82011-02-16 07:40:39 +0100255 val |= clk->pclk_sel->pclk_info[i].pclk_val << clk->pclk_sel_shift;
viresh kumar8c0236f2010-04-01 12:30:46 +0100256 writel(val, clk->pclk_sel->pclk_sel_reg);
257 spin_unlock_irqrestore(&clocks_lock, flags);
258
259 /* reflect parent change in software */
viresh kumaraf89fd82011-02-16 07:40:39 +0100260 clk_reparent(clk, &clk->pclk_sel->pclk_info[i]);
261
262 propagate_rate(clk, 0);
viresh kumar8c0236f2010-04-01 12:30:46 +0100263 return 0;
264}
265EXPORT_SYMBOL(clk_set_parent);
266
viresh kumarcf285432011-02-16 07:40:31 +0100267/**
268 * clk_set_rate - set the clock rate for a clock source
269 * @clk: clock source
270 * @rate: desired clock rate in Hz
271 *
272 * Returns success (0) or negative errno.
273 */
274int clk_set_rate(struct clk *clk, unsigned long rate)
275{
viresh kumaraf89fd82011-02-16 07:40:39 +0100276 unsigned long flags;
277 int ret = -EINVAL;
278
279 if (!clk || !rate)
280 return -EFAULT;
281
282 if (clk->set_rate) {
283 spin_lock_irqsave(&clocks_lock, flags);
284 ret = clk->set_rate(clk, rate);
285 if (!ret)
286 /* if successful -> propagate */
287 propagate_rate(clk, 0);
288 spin_unlock_irqrestore(&clocks_lock, flags);
289 } else if (clk->pclk) {
290 u32 mult = clk->div_factor ? clk->div_factor : 1;
291 ret = clk_set_rate(clk->pclk, mult * rate);
292 }
293
294 return ret;
viresh kumarcf285432011-02-16 07:40:31 +0100295}
296EXPORT_SYMBOL(clk_set_rate);
297
viresh kumar8c0236f2010-04-01 12:30:46 +0100298/* registers clock in platform clock framework */
299void clk_register(struct clk_lookup *cl)
300{
viresh kumaraf89fd82011-02-16 07:40:39 +0100301 struct clk *clk;
viresh kumar8c0236f2010-04-01 12:30:46 +0100302 unsigned long flags;
303
viresh kumaraf89fd82011-02-16 07:40:39 +0100304 if (!cl || !cl->clk)
viresh kumar8c0236f2010-04-01 12:30:46 +0100305 return;
viresh kumaraf89fd82011-02-16 07:40:39 +0100306 clk = cl->clk;
viresh kumar8c0236f2010-04-01 12:30:46 +0100307
308 spin_lock_irqsave(&clocks_lock, flags);
309
310 INIT_LIST_HEAD(&clk->children);
311 if (clk->flags & ALWAYS_ENABLED)
312 clk->ops = NULL;
313 else if (!clk->ops)
314 clk->ops = &generic_clkops;
315
316 /* root clock don't have any parents */
317 if (!clk->pclk && !clk->pclk_sel) {
318 list_add(&clk->sibling, &root_clks);
viresh kumar8c0236f2010-04-01 12:30:46 +0100319 } else if (clk->pclk && !clk->pclk_sel) {
viresh kumaraf89fd82011-02-16 07:40:39 +0100320 /* add clocks with only one parent to parent's children list */
viresh kumar8c0236f2010-04-01 12:30:46 +0100321 list_add(&clk->sibling, &clk->pclk->children);
322 } else {
viresh kumaraf89fd82011-02-16 07:40:39 +0100323 /* clocks with more than one parent */
324 struct pclk_info *pclk_info;
325
326 pclk_info = pclk_info_get(clk);
327 if (!pclk_info) {
328 pr_err("CLKDEV: invalid pclk info of clk with"
329 " %s dev_id and %s con_id\n",
330 cl->dev_id, cl->con_id);
331 } else {
332 clk->pclk = pclk_info->pclk;
333 list_add(&clk->sibling, &pclk_info->pclk->children);
334 }
viresh kumar8c0236f2010-04-01 12:30:46 +0100335 }
viresh kumaraf89fd82011-02-16 07:40:39 +0100336
viresh kumar8c0236f2010-04-01 12:30:46 +0100337 spin_unlock_irqrestore(&clocks_lock, flags);
338
339 /* add clock to arm clockdev framework */
340 clkdev_add(cl);
341}
342
343/**
viresh kumaraf89fd82011-02-16 07:40:39 +0100344 * propagate_rate - recalculate and propagate all clocks to children
345 * @pclk: parent clock required to be propogated
346 * @on_init: flag for enabling clocks which are ENABLED_ON_INIT.
viresh kumar8c0236f2010-04-01 12:30:46 +0100347 *
viresh kumaraf89fd82011-02-16 07:40:39 +0100348 * Recalculates all children clocks
viresh kumar8c0236f2010-04-01 12:30:46 +0100349 */
viresh kumaraf89fd82011-02-16 07:40:39 +0100350void propagate_rate(struct clk *pclk, int on_init)
viresh kumar8c0236f2010-04-01 12:30:46 +0100351{
viresh kumaraf89fd82011-02-16 07:40:39 +0100352 struct clk *clk, *_temp;
353 int ret = 0;
viresh kumar8c0236f2010-04-01 12:30:46 +0100354
viresh kumaraf89fd82011-02-16 07:40:39 +0100355 list_for_each_entry_safe(clk, _temp, &pclk->children, sibling) {
356 if (clk->recalc) {
357 ret = clk->recalc(clk);
358 /*
359 * recalc will return error if clk out is not programmed
360 * In this case configure default rate.
361 */
362 if (ret && clk->set_rate)
363 clk->set_rate(clk, 0);
364 }
365 propagate_rate(clk, on_init);
366
367 if (!on_init)
368 continue;
369
370 /* Enable clks enabled on init, in software view */
371 if (clk->flags & ENABLED_ON_INIT)
372 do_clk_enable(clk);
viresh kumar8c0236f2010-04-01 12:30:46 +0100373 }
374}
375
viresh kumaraf89fd82011-02-16 07:40:39 +0100376/**
377 * round_rate_index - return closest programmable rate index in rate_config tbl
378 * @clk: ptr to clock structure
379 * @drate: desired rate
380 * @rate: final rate will be returned in this variable only.
381 *
382 * Finds index in rate_config for highest clk rate which is less than
383 * requested rate. If there is no clk rate lesser than requested rate then
384 * -EINVAL is returned. This routine assumes that rate_config is written
385 * in incrementing order of clk rates.
386 * If drate passed is zero then default rate is programmed.
387 */
388static int
389round_rate_index(struct clk *clk, unsigned long drate, unsigned long *rate)
viresh kumar8c0236f2010-04-01 12:30:46 +0100390{
viresh kumaraf89fd82011-02-16 07:40:39 +0100391 unsigned long tmp = 0, prev_rate = 0;
392 int index;
viresh kumar8c0236f2010-04-01 12:30:46 +0100393
viresh kumaraf89fd82011-02-16 07:40:39 +0100394 if (!clk->calc_rate)
395 return -EFAULT;
viresh kumar8c0236f2010-04-01 12:30:46 +0100396
viresh kumaraf89fd82011-02-16 07:40:39 +0100397 if (!drate)
398 return -EINVAL;
399
400 /*
401 * This loops ends on two conditions:
402 * - as soon as clk is found with rate greater than requested rate.
403 * - if all clks in rate_config are smaller than requested rate.
404 */
405 for (index = 0; index < clk->rate_config.count; index++) {
406 prev_rate = tmp;
407 tmp = clk->calc_rate(clk, index);
408 if (drate < tmp) {
409 index--;
410 break;
411 }
viresh kumar8c0236f2010-04-01 12:30:46 +0100412 }
viresh kumaraf89fd82011-02-16 07:40:39 +0100413 /* return if can't find suitable clock */
414 if (index < 0) {
415 index = -EINVAL;
416 *rate = 0;
417 } else if (index == clk->rate_config.count) {
418 /* program with highest clk rate possible */
419 index = clk->rate_config.count - 1;
420 *rate = tmp;
421 } else
422 *rate = prev_rate;
viresh kumar8c0236f2010-04-01 12:30:46 +0100423
viresh kumaraf89fd82011-02-16 07:40:39 +0100424 return index;
viresh kumar8c0236f2010-04-01 12:30:46 +0100425}
426
viresh kumaraf89fd82011-02-16 07:40:39 +0100427/**
428 * clk_round_rate - adjust a rate to the exact rate a clock can provide
429 * @clk: clock source
430 * @rate: desired clock rate in Hz
431 *
432 * Returns rounded clock rate in Hz, or negative errno.
433 */
434long clk_round_rate(struct clk *clk, unsigned long drate)
435{
436 long rate = 0;
437 int index;
438
439 /*
440 * propagate call to parent who supports calc_rate. Similar approach is
441 * used in clk_set_rate.
442 */
443 if (!clk->calc_rate) {
444 u32 mult;
445 if (!clk->pclk)
446 return clk->rate;
447
448 mult = clk->div_factor ? clk->div_factor : 1;
449 return clk_round_rate(clk->pclk, mult * drate) / mult;
450 }
451
452 index = round_rate_index(clk, drate, &rate);
453 if (index >= 0)
454 return rate;
455 else
456 return index;
457}
458EXPORT_SYMBOL(clk_round_rate);
459
460/*All below functions are called with lock held */
461
viresh kumar8c0236f2010-04-01 12:30:46 +0100462/*
viresh kumaraf89fd82011-02-16 07:40:39 +0100463 * Calculates pll clk rate for specific value of mode, m, n and p
464 *
465 * In normal mode
466 * rate = (2 * M[15:8] * Fin)/(N * 2^P)
467 *
468 * In Dithered mode
469 * rate = (2 * M[15:0] * Fin)/(256 * N * 2^P)
viresh kumar8c0236f2010-04-01 12:30:46 +0100470 */
viresh kumaraf89fd82011-02-16 07:40:39 +0100471unsigned long pll_calc_rate(struct clk *clk, int index)
viresh kumar8c0236f2010-04-01 12:30:46 +0100472{
viresh kumaraf89fd82011-02-16 07:40:39 +0100473 unsigned long rate = clk->pclk->rate;
474 struct pll_rate_tbl *tbls = clk->rate_config.tbls;
475 unsigned int mode;
viresh kumar8c0236f2010-04-01 12:30:46 +0100476
viresh kumaraf89fd82011-02-16 07:40:39 +0100477 mode = tbls[index].mode ? 256 : 1;
478 return (((2 * rate / 10000) * tbls[index].m) /
479 (mode * tbls[index].n * (1 << tbls[index].p))) * 10000;
viresh kumar8c0236f2010-04-01 12:30:46 +0100480}
481
482/*
483 * calculates current programmed rate of pll1
484 *
485 * In normal mode
486 * rate = (2 * M[15:8] * Fin)/(N * 2^P)
487 *
488 * In Dithered mode
489 * rate = (2 * M[15:0] * Fin)/(256 * N * 2^P)
490 */
viresh kumaraf89fd82011-02-16 07:40:39 +0100491int pll_clk_recalc(struct clk *clk)
viresh kumar8c0236f2010-04-01 12:30:46 +0100492{
493 struct pll_clk_config *config = clk->private_data;
494 unsigned int num = 2, den = 0, val, mode = 0;
viresh kumar8c0236f2010-04-01 12:30:46 +0100495
viresh kumarcf285432011-02-16 07:40:31 +0100496 mode = (readl(config->mode_reg) >> config->masks->mode_shift) &
497 config->masks->mode_mask;
viresh kumar8c0236f2010-04-01 12:30:46 +0100498
499 val = readl(config->cfg_reg);
500 /* calculate denominator */
viresh kumarcf285432011-02-16 07:40:31 +0100501 den = (val >> config->masks->div_p_shift) & config->masks->div_p_mask;
viresh kumar8c0236f2010-04-01 12:30:46 +0100502 den = 1 << den;
viresh kumarcf285432011-02-16 07:40:31 +0100503 den *= (val >> config->masks->div_n_shift) & config->masks->div_n_mask;
viresh kumar8c0236f2010-04-01 12:30:46 +0100504
505 /* calculate numerator & denominator */
506 if (!mode) {
507 /* Normal mode */
viresh kumarcf285432011-02-16 07:40:31 +0100508 num *= (val >> config->masks->norm_fdbk_m_shift) &
509 config->masks->norm_fdbk_m_mask;
viresh kumar8c0236f2010-04-01 12:30:46 +0100510 } else {
511 /* Dithered mode */
viresh kumarcf285432011-02-16 07:40:31 +0100512 num *= (val >> config->masks->dith_fdbk_m_shift) &
513 config->masks->dith_fdbk_m_mask;
viresh kumar8c0236f2010-04-01 12:30:46 +0100514 den *= 256;
515 }
516
viresh kumaraf89fd82011-02-16 07:40:39 +0100517 if (!den)
518 return -EINVAL;
519
viresh kumar8c0236f2010-04-01 12:30:46 +0100520 clk->rate = (((clk->pclk->rate/10000) * num) / den) * 10000;
viresh kumaraf89fd82011-02-16 07:40:39 +0100521 return 0;
522}
523
524/*
525 * Configures new clock rate of pll
526 */
527int pll_clk_set_rate(struct clk *clk, unsigned long desired_rate)
528{
529 struct pll_rate_tbl *tbls = clk->rate_config.tbls;
530 struct pll_clk_config *config = clk->private_data;
531 unsigned long val, rate;
532 int i;
533
534 i = round_rate_index(clk, desired_rate, &rate);
535 if (i < 0)
536 return i;
537
538 val = readl(config->mode_reg) &
539 ~(config->masks->mode_mask << config->masks->mode_shift);
540 val |= (tbls[i].mode & config->masks->mode_mask) <<
541 config->masks->mode_shift;
542 writel(val, config->mode_reg);
543
544 val = readl(config->cfg_reg) &
545 ~(config->masks->div_p_mask << config->masks->div_p_shift);
546 val |= (tbls[i].p & config->masks->div_p_mask) <<
547 config->masks->div_p_shift;
548 val &= ~(config->masks->div_n_mask << config->masks->div_n_shift);
549 val |= (tbls[i].n & config->masks->div_n_mask) <<
550 config->masks->div_n_shift;
551 val &= ~(config->masks->dith_fdbk_m_mask <<
552 config->masks->dith_fdbk_m_shift);
553 if (tbls[i].mode)
554 val |= (tbls[i].m & config->masks->dith_fdbk_m_mask) <<
555 config->masks->dith_fdbk_m_shift;
556 else
557 val |= (tbls[i].m & config->masks->norm_fdbk_m_mask) <<
558 config->masks->norm_fdbk_m_shift;
559
560 writel(val, config->cfg_reg);
561
562 clk->rate = rate;
563
564 return 0;
565}
566
567/*
568 * Calculates ahb, apb clk rate for specific value of div
569 */
570unsigned long bus_calc_rate(struct clk *clk, int index)
571{
572 unsigned long rate = clk->pclk->rate;
573 struct bus_rate_tbl *tbls = clk->rate_config.tbls;
574
575 return rate / (tbls[index].div + 1);
viresh kumar8c0236f2010-04-01 12:30:46 +0100576}
577
578/* calculates current programmed rate of ahb or apb bus */
viresh kumaraf89fd82011-02-16 07:40:39 +0100579int bus_clk_recalc(struct clk *clk)
viresh kumar8c0236f2010-04-01 12:30:46 +0100580{
581 struct bus_clk_config *config = clk->private_data;
582 unsigned int div;
viresh kumar8c0236f2010-04-01 12:30:46 +0100583
viresh kumarcf285432011-02-16 07:40:31 +0100584 div = ((readl(config->reg) >> config->masks->shift) &
585 config->masks->mask) + 1;
viresh kumaraf89fd82011-02-16 07:40:39 +0100586
587 if (!div)
588 return -EINVAL;
589
viresh kumar8c0236f2010-04-01 12:30:46 +0100590 clk->rate = (unsigned long)clk->pclk->rate / div;
viresh kumaraf89fd82011-02-16 07:40:39 +0100591 return 0;
592}
593
594/* Configures new clock rate of AHB OR APB bus */
595int bus_clk_set_rate(struct clk *clk, unsigned long desired_rate)
596{
597 struct bus_rate_tbl *tbls = clk->rate_config.tbls;
598 struct bus_clk_config *config = clk->private_data;
599 unsigned long val, rate;
600 int i;
601
602 i = round_rate_index(clk, desired_rate, &rate);
603 if (i < 0)
604 return i;
605
606 val = readl(config->reg) &
607 ~(config->masks->mask << config->masks->shift);
608 val |= (tbls[i].div & config->masks->mask) << config->masks->shift;
609 writel(val, config->reg);
610
611 clk->rate = rate;
612
613 return 0;
614}
615
616/*
617 * gives rate for different values of eq, x and y
618 *
619 * Fout from synthesizer can be given from two equations:
620 * Fout1 = (Fin * X/Y)/2 EQ1
621 * Fout2 = Fin * X/Y EQ2
622 */
623unsigned long aux_calc_rate(struct clk *clk, int index)
624{
625 unsigned long rate = clk->pclk->rate;
626 struct aux_rate_tbl *tbls = clk->rate_config.tbls;
627 u8 eq = tbls[index].eq ? 1 : 2;
628
629 return (((rate/10000) * tbls[index].xscale) /
630 (tbls[index].yscale * eq)) * 10000;
viresh kumar8c0236f2010-04-01 12:30:46 +0100631}
632
633/*
634 * calculates current programmed rate of auxiliary synthesizers
635 * used by: UART, FIRDA
636 *
637 * Fout from synthesizer can be given from two equations:
638 * Fout1 = (Fin * X/Y)/2
639 * Fout2 = Fin * X/Y
640 *
641 * Selection of eqn 1 or 2 is programmed in register
642 */
viresh kumaraf89fd82011-02-16 07:40:39 +0100643int aux_clk_recalc(struct clk *clk)
viresh kumar8c0236f2010-04-01 12:30:46 +0100644{
645 struct aux_clk_config *config = clk->private_data;
viresh kumar8c0236f2010-04-01 12:30:46 +0100646 unsigned int num = 1, den = 1, val, eqn;
viresh kumar8c0236f2010-04-01 12:30:46 +0100647
viresh kumaraf89fd82011-02-16 07:40:39 +0100648 val = readl(config->synth_reg);
viresh kumar8c0236f2010-04-01 12:30:46 +0100649
viresh kumaraf89fd82011-02-16 07:40:39 +0100650 eqn = (val >> config->masks->eq_sel_shift) &
651 config->masks->eq_sel_mask;
652 if (eqn == config->masks->eq1_mask)
653 den *= 2;
viresh kumar8c0236f2010-04-01 12:30:46 +0100654
viresh kumaraf89fd82011-02-16 07:40:39 +0100655 /* calculate numerator */
656 num = (val >> config->masks->xscale_sel_shift) &
657 config->masks->xscale_sel_mask;
viresh kumar8c0236f2010-04-01 12:30:46 +0100658
viresh kumaraf89fd82011-02-16 07:40:39 +0100659 /* calculate denominator */
660 den *= (val >> config->masks->yscale_sel_shift) &
661 config->masks->yscale_sel_mask;
viresh kumar8c0236f2010-04-01 12:30:46 +0100662
viresh kumaraf89fd82011-02-16 07:40:39 +0100663 if (!den)
664 return -EINVAL;
viresh kumar8c0236f2010-04-01 12:30:46 +0100665
viresh kumaraf89fd82011-02-16 07:40:39 +0100666 clk->rate = (((clk->pclk->rate/10000) * num) / den) * 10000;
667 return 0;
668}
viresh kumar8c0236f2010-04-01 12:30:46 +0100669
viresh kumaraf89fd82011-02-16 07:40:39 +0100670/* Configures new clock rate of auxiliary synthesizers used by: UART, FIRDA*/
671int aux_clk_set_rate(struct clk *clk, unsigned long desired_rate)
672{
673 struct aux_rate_tbl *tbls = clk->rate_config.tbls;
674 struct aux_clk_config *config = clk->private_data;
675 unsigned long val, rate;
676 int i;
677
678 i = round_rate_index(clk, desired_rate, &rate);
679 if (i < 0)
680 return i;
681
682 val = readl(config->synth_reg) &
683 ~(config->masks->eq_sel_mask << config->masks->eq_sel_shift);
684 val |= (tbls[i].eq & config->masks->eq_sel_mask) <<
685 config->masks->eq_sel_shift;
686 val &= ~(config->masks->xscale_sel_mask <<
687 config->masks->xscale_sel_shift);
688 val |= (tbls[i].xscale & config->masks->xscale_sel_mask) <<
689 config->masks->xscale_sel_shift;
690 val &= ~(config->masks->yscale_sel_mask <<
691 config->masks->yscale_sel_shift);
692 val |= (tbls[i].yscale & config->masks->yscale_sel_mask) <<
693 config->masks->yscale_sel_shift;
694 writel(val, config->synth_reg);
695
696 clk->rate = rate;
697
698 return 0;
699}
700
701/*
702 * Calculates gpt clk rate for different values of mscale and nscale
703 *
704 * Fout= Fin/((2 ^ (N+1)) * (M+1))
705 */
706unsigned long gpt_calc_rate(struct clk *clk, int index)
707{
708 unsigned long rate = clk->pclk->rate;
709 struct gpt_rate_tbl *tbls = clk->rate_config.tbls;
710
711 return rate / ((1 << (tbls[index].nscale + 1)) *
712 (tbls[index].mscale + 1));
viresh kumar8c0236f2010-04-01 12:30:46 +0100713}
714
715/*
716 * calculates current programmed rate of gpt synthesizers
717 * Fout from synthesizer can be given from below equations:
718 * Fout= Fin/((2 ^ (N+1)) * (M+1))
719 */
viresh kumaraf89fd82011-02-16 07:40:39 +0100720int gpt_clk_recalc(struct clk *clk)
viresh kumar8c0236f2010-04-01 12:30:46 +0100721{
viresh kumarcf285432011-02-16 07:40:31 +0100722 struct gpt_clk_config *config = clk->private_data;
viresh kumar8c0236f2010-04-01 12:30:46 +0100723 unsigned int div = 1, val;
viresh kumar8c0236f2010-04-01 12:30:46 +0100724
viresh kumaraf89fd82011-02-16 07:40:39 +0100725 val = readl(config->synth_reg);
726 div += (val >> config->masks->mscale_sel_shift) &
727 config->masks->mscale_sel_mask;
728 div *= 1 << (((val >> config->masks->nscale_sel_shift) &
729 config->masks->nscale_sel_mask) + 1);
viresh kumar8c0236f2010-04-01 12:30:46 +0100730
viresh kumaraf89fd82011-02-16 07:40:39 +0100731 if (!div)
732 return -EINVAL;
viresh kumar8c0236f2010-04-01 12:30:46 +0100733
734 clk->rate = (unsigned long)clk->pclk->rate / div;
viresh kumaraf89fd82011-02-16 07:40:39 +0100735 return 0;
736}
737
738/* Configures new clock rate of gptiliary synthesizers used by: UART, FIRDA*/
739int gpt_clk_set_rate(struct clk *clk, unsigned long desired_rate)
740{
741 struct gpt_rate_tbl *tbls = clk->rate_config.tbls;
742 struct gpt_clk_config *config = clk->private_data;
743 unsigned long val, rate;
744 int i;
745
746 i = round_rate_index(clk, desired_rate, &rate);
747 if (i < 0)
748 return i;
749
750 val = readl(config->synth_reg) & ~(config->masks->mscale_sel_mask <<
751 config->masks->mscale_sel_shift);
752 val |= (tbls[i].mscale & config->masks->mscale_sel_mask) <<
753 config->masks->mscale_sel_shift;
754 val &= ~(config->masks->nscale_sel_mask <<
755 config->masks->nscale_sel_shift);
756 val |= (tbls[i].nscale & config->masks->nscale_sel_mask) <<
757 config->masks->nscale_sel_shift;
758 writel(val, config->synth_reg);
759
760 clk->rate = rate;
761
762 return 0;
763}
764
765/*
766 * Calculates clcd clk rate for different values of div
767 *
768 * Fout from synthesizer can be given from below equation:
769 * Fout= Fin/2*div (division factor)
770 * div is 17 bits:-
771 * 0-13 (fractional part)
772 * 14-16 (integer part)
773 * To calculate Fout we left shift val by 14 bits and divide Fin by
774 * complete div (including fractional part) and then right shift the
775 * result by 14 places.
776 */
777unsigned long clcd_calc_rate(struct clk *clk, int index)
778{
779 unsigned long rate = clk->pclk->rate;
780 struct clcd_rate_tbl *tbls = clk->rate_config.tbls;
781
782 rate /= 1000;
783 rate <<= 12;
784 rate /= (2 * tbls[index].div);
785 rate >>= 12;
786 rate *= 1000;
787
788 return rate;
789}
790
791/*
792 * calculates current programmed rate of clcd synthesizer
793 * Fout from synthesizer can be given from below equation:
794 * Fout= Fin/2*div (division factor)
795 * div is 17 bits:-
796 * 0-13 (fractional part)
797 * 14-16 (integer part)
798 * To calculate Fout we left shift val by 14 bits and divide Fin by
799 * complete div (including fractional part) and then right shift the
800 * result by 14 places.
801 */
802int clcd_clk_recalc(struct clk *clk)
803{
804 struct clcd_clk_config *config = clk->private_data;
805 unsigned int div = 1;
806 unsigned long prate;
807 unsigned int val;
808
809 val = readl(config->synth_reg);
810 div = (val >> config->masks->div_factor_shift) &
811 config->masks->div_factor_mask;
812
813 if (!div)
814 return -EINVAL;
815
816 prate = clk->pclk->rate / 1000; /* first level division, make it KHz */
817
818 clk->rate = (((unsigned long)prate << 12) / (2 * div)) >> 12;
819 clk->rate *= 1000;
820 return 0;
821}
822
823/* Configures new clock rate of auxiliary synthesizers used by: UART, FIRDA*/
824int clcd_clk_set_rate(struct clk *clk, unsigned long desired_rate)
825{
826 struct clcd_rate_tbl *tbls = clk->rate_config.tbls;
827 struct clcd_clk_config *config = clk->private_data;
828 unsigned long val, rate;
829 int i;
830
831 i = round_rate_index(clk, desired_rate, &rate);
832 if (i < 0)
833 return i;
834
835 val = readl(config->synth_reg) & ~(config->masks->div_factor_mask <<
836 config->masks->div_factor_shift);
837 val |= (tbls[i].div & config->masks->div_factor_mask) <<
838 config->masks->div_factor_shift;
839 writel(val, config->synth_reg);
840
841 clk->rate = rate;
842
843 return 0;
viresh kumar8c0236f2010-04-01 12:30:46 +0100844}
845
846/*
viresh kumarcf285432011-02-16 07:40:31 +0100847 * Used for clocks that always have value as the parent clock divided by a
viresh kumar8c0236f2010-04-01 12:30:46 +0100848 * fixed divisor
849 */
viresh kumaraf89fd82011-02-16 07:40:39 +0100850int follow_parent(struct clk *clk)
viresh kumar8c0236f2010-04-01 12:30:46 +0100851{
viresh kumarcf285432011-02-16 07:40:31 +0100852 unsigned int div_factor = (clk->div_factor < 1) ? 1 : clk->div_factor;
viresh kumar8c0236f2010-04-01 12:30:46 +0100853
viresh kumarcf285432011-02-16 07:40:31 +0100854 clk->rate = clk->pclk->rate/div_factor;
viresh kumaraf89fd82011-02-16 07:40:39 +0100855 return 0;
viresh kumar8c0236f2010-04-01 12:30:46 +0100856}
857
858/**
859 * recalc_root_clocks - recalculate and propagate all root clocks
860 *
861 * Recalculates all root clocks (clocks with no parent), which if the
862 * clock's .recalc is set correctly, should also propagate their rates.
863 */
864void recalc_root_clocks(void)
865{
viresh kumaraf89fd82011-02-16 07:40:39 +0100866 struct clk *pclk;
867 unsigned long flags;
868 int ret = 0;
869
870 spin_lock_irqsave(&clocks_lock, flags);
871 list_for_each_entry(pclk, &root_clks, sibling) {
872 if (pclk->recalc) {
873 ret = pclk->recalc(pclk);
874 /*
875 * recalc will return error if clk out is not programmed
876 * In this case configure default clock.
877 */
878 if (ret && pclk->set_rate)
879 pclk->set_rate(pclk, 0);
880 }
881 propagate_rate(pclk, 1);
882 /* Enable clks enabled on init, in software view */
883 if (pclk->flags & ENABLED_ON_INIT)
884 do_clk_enable(pclk);
885 }
886 spin_unlock_irqrestore(&clocks_lock, flags);
viresh kumar8c0236f2010-04-01 12:30:46 +0100887}