]>
Commit | Line | Data |
---|---|---|
8c0236fc VK |
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> | |
af89fd81 | 15 | #include <linux/clk.h> |
4b9502e1 | 16 | #include <linux/debugfs.h> |
8c0236fc VK |
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> | |
8c0236fc VK |
22 | #include <plat/clock.h> |
23 | ||
24 | static DEFINE_SPINLOCK(clocks_lock); | |
25 | static LIST_HEAD(root_clks); | |
4b9502e1 SH |
26 | #ifdef CONFIG_DEBUG_FS |
27 | static LIST_HEAD(clocks); | |
28 | #endif | |
8c0236fc | 29 | |
af89fd81 | 30 | static void propagate_rate(struct clk *, int on_init); |
4b9502e1 SH |
31 | #ifdef CONFIG_DEBUG_FS |
32 | static int clk_debugfs_reparent(struct clk *); | |
33 | #endif | |
8c0236fc VK |
34 | |
35 | static 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 | ||
53 | static 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 */ | |
70 | static struct clkops generic_clkops = { | |
71 | .enable = generic_clk_enable, | |
72 | .disable = generic_clk_disable, | |
73 | }; | |
74 | ||
af89fd81 VK |
75 | /* returns current programmed clocks clock info structure */ |
76 | static 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 | */ | |
96 | static 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); | |
4b9502e1 SH |
106 | |
107 | #ifdef CONFIG_DEBUG_FS | |
108 | clk_debugfs_reparent(clk); | |
109 | #endif | |
af89fd81 VK |
110 | } |
111 | ||
112 | static 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 | ||
137 | static 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++; | |
169 | err: | |
170 | return ret; | |
171 | } | |
172 | ||
8c0236fc VK |
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 | */ | |
181 | int clk_enable(struct clk *clk) | |
182 | { | |
183 | unsigned long flags; | |
184 | int ret = 0; | |
185 | ||
8c0236fc | 186 | spin_lock_irqsave(&clocks_lock, flags); |
af89fd81 | 187 | ret = do_clk_enable(clk); |
8c0236fc | 188 | spin_unlock_irqrestore(&clocks_lock, flags); |
8c0236fc VK |
189 | return ret; |
190 | } | |
191 | EXPORT_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 | */ | |
205 | void clk_disable(struct clk *clk) | |
206 | { | |
207 | unsigned long flags; | |
208 | ||
8c0236fc | 209 | spin_lock_irqsave(&clocks_lock, flags); |
af89fd81 | 210 | do_clk_disable(clk); |
8c0236fc VK |
211 | spin_unlock_irqrestore(&clocks_lock, flags); |
212 | } | |
213 | EXPORT_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 | */ | |
220 | unsigned 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 | } | |
230 | EXPORT_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 | */ | |
239 | int clk_set_parent(struct clk *clk, struct clk *parent) | |
240 | { | |
241 | int i, found = 0, val = 0; | |
242 | unsigned long flags; | |
243 | ||
af89fd81 | 244 | if (!clk || !parent) |
8c0236fc | 245 | return -EFAULT; |
8c0236fc VK |
246 | if (clk->pclk == parent) |
247 | return 0; | |
af89fd81 VK |
248 | if (!clk->pclk_sel) |
249 | return -EPERM; | |
8c0236fc | 250 | |
af89fd81 | 251 | /* check if requested parent is in clk parent list */ |
8c0236fc VK |
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); | |
af89fd81 | 266 | val |= clk->pclk_sel->pclk_info[i].pclk_val << clk->pclk_sel_shift; |
8c0236fc VK |
267 | writel(val, clk->pclk_sel->pclk_sel_reg); |
268 | spin_unlock_irqrestore(&clocks_lock, flags); | |
269 | ||
270 | /* reflect parent change in software */ | |
af89fd81 VK |
271 | clk_reparent(clk, &clk->pclk_sel->pclk_info[i]); |
272 | ||
273 | propagate_rate(clk, 0); | |
8c0236fc VK |
274 | return 0; |
275 | } | |
276 | EXPORT_SYMBOL(clk_set_parent); | |
277 | ||
cf285434 VK |
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 | */ | |
285 | int clk_set_rate(struct clk *clk, unsigned long rate) | |
286 | { | |
af89fd81 VK |
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; | |
cf285434 VK |
306 | } |
307 | EXPORT_SYMBOL(clk_set_rate); | |
308 | ||
8c0236fc VK |
309 | /* registers clock in platform clock framework */ |
310 | void clk_register(struct clk_lookup *cl) | |
311 | { | |
af89fd81 | 312 | struct clk *clk; |
8c0236fc VK |
313 | unsigned long flags; |
314 | ||
af89fd81 | 315 | if (!cl || !cl->clk) |
8c0236fc | 316 | return; |
af89fd81 | 317 | clk = cl->clk; |
8c0236fc VK |
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); | |
8c0236fc | 330 | } else if (clk->pclk && !clk->pclk_sel) { |
af89fd81 | 331 | /* add clocks with only one parent to parent's children list */ |
8c0236fc VK |
332 | list_add(&clk->sibling, &clk->pclk->children); |
333 | } else { | |
af89fd81 VK |
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 | } | |
8c0236fc | 346 | } |
af89fd81 | 347 | |
8c0236fc VK |
348 | spin_unlock_irqrestore(&clocks_lock, flags); |
349 | ||
4b9502e1 SH |
350 | /* debugfs specific */ |
351 | #ifdef CONFIG_DEBUG_FS | |
352 | list_add(&clk->node, &clocks); | |
353 | clk->cl = cl; | |
354 | #endif | |
355 | ||
8c0236fc VK |
356 | /* add clock to arm clockdev framework */ |
357 | clkdev_add(cl); | |
358 | } | |
359 | ||
360 | /** | |
af89fd81 VK |
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. | |
8c0236fc | 364 | * |
af89fd81 | 365 | * Recalculates all children clocks |
8c0236fc | 366 | */ |
af89fd81 | 367 | void propagate_rate(struct clk *pclk, int on_init) |
8c0236fc | 368 | { |
af89fd81 VK |
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; | |
8c0236fc | 386 | |
af89fd81 VK |
387 | /* Enable clks enabled on init, in software view */ |
388 | if (clk->flags & ENABLED_ON_INIT) | |
389 | do_clk_enable(clk); | |
8c0236fc VK |
390 | } |
391 | } | |
392 | ||
af89fd81 VK |
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 | */ | |
405 | static int | |
406 | round_rate_index(struct clk *clk, unsigned long drate, unsigned long *rate) | |
8c0236fc | 407 | { |
af89fd81 VK |
408 | unsigned long tmp = 0, prev_rate = 0; |
409 | int index; | |
8c0236fc | 410 | |
af89fd81 VK |
411 | if (!clk->calc_rate) |
412 | return -EFAULT; | |
8c0236fc | 413 | |
af89fd81 VK |
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 | } | |
8c0236fc | 429 | } |
af89fd81 VK |
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; | |
8c0236fc | 440 | |
af89fd81 | 441 | return index; |
8c0236fc VK |
442 | } |
443 | ||
af89fd81 VK |
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. | |
8c0236fc | 450 | */ |
af89fd81 | 451 | long clk_round_rate(struct clk *clk, unsigned long drate) |
8c0236fc | 452 | { |
af89fd81 VK |
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 | } | |
8c0236fc | 468 | |
af89fd81 VK |
469 | index = round_rate_index(clk, drate, &rate); |
470 | if (index >= 0) | |
471 | return rate; | |
472 | else | |
473 | return index; | |
474 | } | |
475 | EXPORT_SYMBOL(clk_round_rate); | |
8c0236fc | 476 | |
af89fd81 VK |
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 | */ | |
488 | unsigned 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; | |
8c0236fc VK |
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 | */ | |
af89fd81 | 508 | int pll_clk_recalc(struct clk *clk) |
8c0236fc VK |
509 | { |
510 | struct pll_clk_config *config = clk->private_data; | |
511 | unsigned int num = 2, den = 0, val, mode = 0; | |
8c0236fc | 512 | |
cf285434 VK |
513 | mode = (readl(config->mode_reg) >> config->masks->mode_shift) & |
514 | config->masks->mode_mask; | |
8c0236fc VK |
515 | |
516 | val = readl(config->cfg_reg); | |
517 | /* calculate denominator */ | |
cf285434 | 518 | den = (val >> config->masks->div_p_shift) & config->masks->div_p_mask; |
8c0236fc | 519 | den = 1 << den; |
cf285434 | 520 | den *= (val >> config->masks->div_n_shift) & config->masks->div_n_mask; |
8c0236fc VK |
521 | |
522 | /* calculate numerator & denominator */ | |
523 | if (!mode) { | |
524 | /* Normal mode */ | |
cf285434 VK |
525 | num *= (val >> config->masks->norm_fdbk_m_shift) & |
526 | config->masks->norm_fdbk_m_mask; | |
8c0236fc VK |
527 | } else { |
528 | /* Dithered mode */ | |
cf285434 VK |
529 | num *= (val >> config->masks->dith_fdbk_m_shift) & |
530 | config->masks->dith_fdbk_m_mask; | |
8c0236fc VK |
531 | den *= 256; |
532 | } | |
533 | ||
af89fd81 VK |
534 | if (!den) |
535 | return -EINVAL; | |
536 | ||
8c0236fc | 537 | clk->rate = (((clk->pclk->rate/10000) * num) / den) * 10000; |
af89fd81 VK |
538 | return 0; |
539 | } | |
540 | ||
541 | /* | |
542 | * Configures new clock rate of pll | |
543 | */ | |
544 | int 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 | */ | |
587 | unsigned 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); | |
8c0236fc VK |
593 | } |
594 | ||
595 | /* calculates current programmed rate of ahb or apb bus */ | |
af89fd81 | 596 | int bus_clk_recalc(struct clk *clk) |
8c0236fc VK |
597 | { |
598 | struct bus_clk_config *config = clk->private_data; | |
599 | unsigned int div; | |
8c0236fc | 600 | |
cf285434 VK |
601 | div = ((readl(config->reg) >> config->masks->shift) & |
602 | config->masks->mask) + 1; | |
af89fd81 VK |
603 | |
604 | if (!div) | |
605 | return -EINVAL; | |
606 | ||
8c0236fc | 607 | clk->rate = (unsigned long)clk->pclk->rate / div; |
af89fd81 VK |
608 | return 0; |
609 | } | |
610 | ||
611 | /* Configures new clock rate of AHB OR APB bus */ | |
612 | int 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 | */ | |
640 | unsigned 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; | |
8c0236fc VK |
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 | */ | |
af89fd81 | 660 | int aux_clk_recalc(struct clk *clk) |
8c0236fc VK |
661 | { |
662 | struct aux_clk_config *config = clk->private_data; | |
8c0236fc | 663 | unsigned int num = 1, den = 1, val, eqn; |
8c0236fc | 664 | |
af89fd81 | 665 | val = readl(config->synth_reg); |
8c0236fc | 666 | |
af89fd81 VK |
667 | eqn = (val >> config->masks->eq_sel_shift) & |
668 | config->masks->eq_sel_mask; | |
669 | if (eqn == config->masks->eq1_mask) | |
670 | den *= 2; | |
8c0236fc | 671 | |
af89fd81 VK |
672 | /* calculate numerator */ |
673 | num = (val >> config->masks->xscale_sel_shift) & | |
674 | config->masks->xscale_sel_mask; | |
8c0236fc | 675 | |
af89fd81 VK |
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*/ | |
688 | int 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 | */ | |
723 | unsigned 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)); | |
8c0236fc VK |
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 | */ | |
af89fd81 | 737 | int gpt_clk_recalc(struct clk *clk) |
8c0236fc | 738 | { |
cf285434 | 739 | struct gpt_clk_config *config = clk->private_data; |
8c0236fc | 740 | unsigned int div = 1, val; |
8c0236fc | 741 | |
af89fd81 VK |
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); | |
8c0236fc | 747 | |
af89fd81 VK |
748 | if (!div) |
749 | return -EINVAL; | |
8c0236fc VK |
750 | |
751 | clk->rate = (unsigned long)clk->pclk->rate / div; | |
af89fd81 VK |
752 | return 0; |
753 | } | |
754 | ||
755 | /* Configures new clock rate of gptiliary synthesizers used by: UART, FIRDA*/ | |
756 | int 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 | */ | |
794 | unsigned 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 | */ | |
819 | int 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*/ | |
841 | int 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; | |
8c0236fc VK |
861 | } |
862 | ||
863 | /* | |
cf285434 | 864 | * Used for clocks that always have value as the parent clock divided by a |
8c0236fc VK |
865 | * fixed divisor |
866 | */ | |
af89fd81 | 867 | int follow_parent(struct clk *clk) |
8c0236fc | 868 | { |
cf285434 | 869 | unsigned int div_factor = (clk->div_factor < 1) ? 1 : clk->div_factor; |
8c0236fc | 870 | |
cf285434 | 871 | clk->rate = clk->pclk->rate/div_factor; |
af89fd81 | 872 | return 0; |
8c0236fc VK |
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 | */ | |
881 | void recalc_root_clocks(void) | |
882 | { | |
af89fd81 VK |
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); | |
8c0236fc | 904 | } |
4b9502e1 | 905 | |
b997f6e2 VK |
906 | void __init clk_init(void) |
907 | { | |
908 | recalc_root_clocks(); | |
909 | } | |
910 | ||
4b9502e1 SH |
911 | #ifdef CONFIG_DEBUG_FS |
912 | /* | |
913 | * debugfs support to trace clock tree hierarchy and attributes | |
914 | */ | |
915 | static struct dentry *clk_debugfs_root; | |
916 | static int clk_debugfs_register_one(struct clk *c) | |
917 | { | |
918 | int err; | |
12520c43 | 919 | struct dentry *d; |
4b9502e1 SH |
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 | ||
953 | err_out: | |
12520c43 | 954 | debugfs_remove_recursive(c->dent); |
4b9502e1 SH |
955 | return err; |
956 | } | |
957 | ||
958 | static 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 | ||
977 | static 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; | |
994 | err_out: | |
995 | debugfs_remove_recursive(clk_debugfs_root); | |
996 | return err; | |
997 | } | |
998 | late_initcall(clk_debugfs_init); | |
999 | ||
1000 | static 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 */ |