2 * arch/arm/plat-spear/clock.c
4 * Clock framework for SPEAr platform
6 * Copyright (C) 2009 ST Microelectronics
7 * Viresh Kumar<viresh.kumar@st.com>
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.
14 #include <linux/bug.h>
15 #include <linux/err.h>
17 #include <linux/list.h>
18 #include <linux/module.h>
19 #include <linux/spinlock.h>
20 #include <plat/clock.h>
22 static DEFINE_SPINLOCK(clocks_lock
);
23 static LIST_HEAD(root_clks
);
25 static void propagate_rate(struct list_head
*);
27 static int generic_clk_enable(struct clk
*clk
)
34 val
= readl(clk
->en_reg
);
35 if (unlikely(clk
->flags
& RESET_TO_ENABLE
))
36 val
&= ~(1 << clk
->en_reg_bit
);
38 val
|= 1 << clk
->en_reg_bit
;
40 writel(val
, clk
->en_reg
);
45 static void generic_clk_disable(struct clk
*clk
)
52 val
= readl(clk
->en_reg
);
53 if (unlikely(clk
->flags
& RESET_TO_ENABLE
))
54 val
|= 1 << clk
->en_reg_bit
;
56 val
&= ~(1 << clk
->en_reg_bit
);
58 writel(val
, clk
->en_reg
);
62 static struct clkops generic_clkops
= {
63 .enable
= generic_clk_enable
,
64 .disable
= generic_clk_disable
,
68 * clk_enable - inform the system when the clock source should be running.
71 * If the clock can not be enabled/disabled, this should return success.
73 * Returns success (0) or negative errno.
75 int clk_enable(struct clk
*clk
)
80 if (!clk
|| IS_ERR(clk
))
83 spin_lock_irqsave(&clocks_lock
, flags
);
84 if (clk
->usage_count
== 0) {
85 if (clk
->ops
&& clk
->ops
->enable
)
86 ret
= clk
->ops
->enable(clk
);
89 spin_unlock_irqrestore(&clocks_lock
, flags
);
93 EXPORT_SYMBOL(clk_enable
);
96 * clk_disable - inform the system when the clock source is no longer required.
99 * Inform the system that a clock source is no longer required by
100 * a driver and may be shut down.
102 * Implementation detail: if the clock source is shared between
103 * multiple drivers, clk_enable() calls must be balanced by the
104 * same number of clk_disable() calls for the clock source to be
107 void clk_disable(struct clk
*clk
)
111 if (!clk
|| IS_ERR(clk
))
114 WARN_ON(clk
->usage_count
== 0);
116 spin_lock_irqsave(&clocks_lock
, flags
);
118 if (clk
->usage_count
== 0) {
119 if (clk
->ops
&& clk
->ops
->disable
)
120 clk
->ops
->disable(clk
);
122 spin_unlock_irqrestore(&clocks_lock
, flags
);
124 EXPORT_SYMBOL(clk_disable
);
127 * clk_get_rate - obtain the current clock rate (in Hz) for a clock source.
128 * This is only valid once the clock source has been enabled.
131 unsigned long clk_get_rate(struct clk
*clk
)
133 unsigned long flags
, rate
;
135 spin_lock_irqsave(&clocks_lock
, flags
);
137 spin_unlock_irqrestore(&clocks_lock
, flags
);
141 EXPORT_SYMBOL(clk_get_rate
);
144 * clk_set_parent - set the parent clock source for this clock
146 * @parent: parent clock source
148 * Returns success (0) or negative errno.
150 int clk_set_parent(struct clk
*clk
, struct clk
*parent
)
152 int i
, found
= 0, val
= 0;
155 if (!clk
|| IS_ERR(clk
) || !parent
|| IS_ERR(parent
))
157 if (clk
->usage_count
)
161 if (clk
->pclk
== parent
)
164 for (i
= 0; i
< clk
->pclk_sel
->pclk_count
; i
++) {
165 if (clk
->pclk_sel
->pclk_info
[i
].pclk
== parent
) {
174 spin_lock_irqsave(&clocks_lock
, flags
);
175 /* reflect parent change in hardware */
176 val
= readl(clk
->pclk_sel
->pclk_sel_reg
);
177 val
&= ~(clk
->pclk_sel
->pclk_sel_mask
<< clk
->pclk_sel_shift
);
178 val
|= clk
->pclk_sel
->pclk_info
[i
].pclk_mask
<< clk
->pclk_sel_shift
;
179 writel(val
, clk
->pclk_sel
->pclk_sel_reg
);
180 spin_unlock_irqrestore(&clocks_lock
, flags
);
182 /* reflect parent change in software */
184 propagate_rate(&clk
->children
);
187 EXPORT_SYMBOL(clk_set_parent
);
190 * clk_set_rate - set the clock rate for a clock source
192 * @rate: desired clock rate in Hz
194 * Returns success (0) or negative errno.
196 int clk_set_rate(struct clk
*clk
, unsigned long rate
)
201 EXPORT_SYMBOL(clk_set_rate
);
203 /* registers clock in platform clock framework */
204 void clk_register(struct clk_lookup
*cl
)
206 struct clk
*clk
= cl
->clk
;
209 if (!clk
|| IS_ERR(clk
))
212 spin_lock_irqsave(&clocks_lock
, flags
);
214 INIT_LIST_HEAD(&clk
->children
);
215 if (clk
->flags
& ALWAYS_ENABLED
)
218 clk
->ops
= &generic_clkops
;
220 /* root clock don't have any parents */
221 if (!clk
->pclk
&& !clk
->pclk_sel
) {
222 list_add(&clk
->sibling
, &root_clks
);
223 /* add clocks with only one parent to parent's children list */
224 } else if (clk
->pclk
&& !clk
->pclk_sel
) {
225 list_add(&clk
->sibling
, &clk
->pclk
->children
);
227 /* add clocks with > 1 parent to 1st parent's children list */
228 clk
->pclk
= clk
->pclk_sel
->pclk_info
[0].pclk
;
229 list_add(&clk
->sibling
,
230 &clk
->pclk_sel
->pclk_info
[0].pclk
->children
);
232 spin_unlock_irqrestore(&clocks_lock
, flags
);
234 /* add clock to arm clockdev framework */
239 * propagate_rate - recalculate and propagate all clocks in list head
241 * Recalculates all root clocks in list head, which if the clock's .recalc is
242 * set correctly, should also propagate their rates.
244 static void propagate_rate(struct list_head
*lhead
)
246 struct clk
*clkp
, *_temp
;
248 list_for_each_entry_safe(clkp
, _temp
, lhead
, sibling
) {
251 propagate_rate(&clkp
->children
);
255 /* returns current programmed clocks clock info structure */
256 static struct pclk_info
*pclk_info_get(struct clk
*clk
)
258 unsigned int mask
, i
;
260 struct pclk_info
*info
= NULL
;
262 spin_lock_irqsave(&clocks_lock
, flags
);
263 mask
= (readl(clk
->pclk_sel
->pclk_sel_reg
) >> clk
->pclk_sel_shift
)
264 & clk
->pclk_sel
->pclk_sel_mask
;
266 for (i
= 0; i
< clk
->pclk_sel
->pclk_count
; i
++) {
267 if (clk
->pclk_sel
->pclk_info
[i
].pclk_mask
== mask
)
268 info
= &clk
->pclk_sel
->pclk_info
[i
];
270 spin_unlock_irqrestore(&clocks_lock
, flags
);
276 * Set pclk as cclk's parent and add clock sibling node to current parents
279 static void change_parent(struct clk
*cclk
, struct clk
*pclk
)
283 spin_lock_irqsave(&clocks_lock
, flags
);
284 list_del(&cclk
->sibling
);
285 list_add(&cclk
->sibling
, &pclk
->children
);
288 spin_unlock_irqrestore(&clocks_lock
, flags
);
292 * calculates current programmed rate of pll1
295 * rate = (2 * M[15:8] * Fin)/(N * 2^P)
298 * rate = (2 * M[15:0] * Fin)/(256 * N * 2^P)
300 void pll_clk_recalc(struct clk
*clk
)
302 struct pll_clk_config
*config
= clk
->private_data
;
303 unsigned int num
= 2, den
= 0, val
, mode
= 0;
306 spin_lock_irqsave(&clocks_lock
, flags
);
307 mode
= (readl(config
->mode_reg
) >> config
->masks
->mode_shift
) &
308 config
->masks
->mode_mask
;
310 val
= readl(config
->cfg_reg
);
311 /* calculate denominator */
312 den
= (val
>> config
->masks
->div_p_shift
) & config
->masks
->div_p_mask
;
314 den
*= (val
>> config
->masks
->div_n_shift
) & config
->masks
->div_n_mask
;
316 /* calculate numerator & denominator */
319 num
*= (val
>> config
->masks
->norm_fdbk_m_shift
) &
320 config
->masks
->norm_fdbk_m_mask
;
323 num
*= (val
>> config
->masks
->dith_fdbk_m_shift
) &
324 config
->masks
->dith_fdbk_m_mask
;
328 clk
->rate
= (((clk
->pclk
->rate
/10000) * num
) / den
) * 10000;
329 spin_unlock_irqrestore(&clocks_lock
, flags
);
332 /* calculates current programmed rate of ahb or apb bus */
333 void bus_clk_recalc(struct clk
*clk
)
335 struct bus_clk_config
*config
= clk
->private_data
;
339 spin_lock_irqsave(&clocks_lock
, flags
);
340 div
= ((readl(config
->reg
) >> config
->masks
->shift
) &
341 config
->masks
->mask
) + 1;
342 clk
->rate
= (unsigned long)clk
->pclk
->rate
/ div
;
343 spin_unlock_irqrestore(&clocks_lock
, flags
);
347 * calculates current programmed rate of auxiliary synthesizers
348 * used by: UART, FIRDA
350 * Fout from synthesizer can be given from two equations:
351 * Fout1 = (Fin * X/Y)/2
354 * Selection of eqn 1 or 2 is programmed in register
356 void aux_clk_recalc(struct clk
*clk
)
358 struct aux_clk_config
*config
= clk
->private_data
;
359 struct pclk_info
*pclk_info
= NULL
;
360 unsigned int num
= 1, den
= 1, val
, eqn
;
363 /* get current programmed parent */
364 pclk_info
= pclk_info_get(clk
);
366 spin_lock_irqsave(&clocks_lock
, flags
);
369 spin_unlock_irqrestore(&clocks_lock
, flags
);
373 change_parent(clk
, pclk_info
->pclk
);
375 spin_lock_irqsave(&clocks_lock
, flags
);
376 if (pclk_info
->scalable
) {
377 val
= readl(config
->synth_reg
);
379 eqn
= (val
>> config
->masks
->eq_sel_shift
) &
380 config
->masks
->eq_sel_mask
;
381 if (eqn
== config
->masks
->eq1_mask
)
384 /* calculate numerator */
385 num
= (val
>> config
->masks
->xscale_sel_shift
) &
386 config
->masks
->xscale_sel_mask
;
388 /* calculate denominator */
389 den
*= (val
>> config
->masks
->yscale_sel_shift
) &
390 config
->masks
->yscale_sel_mask
;
391 val
= (((clk
->pclk
->rate
/10000) * num
) / den
) * 10000;
393 val
= clk
->pclk
->rate
;
396 spin_unlock_irqrestore(&clocks_lock
, flags
);
400 * calculates current programmed rate of gpt synthesizers
401 * Fout from synthesizer can be given from below equations:
402 * Fout= Fin/((2 ^ (N+1)) * (M+1))
404 void gpt_clk_recalc(struct clk
*clk
)
406 struct gpt_clk_config
*config
= clk
->private_data
;
407 struct pclk_info
*pclk_info
= NULL
;
408 unsigned int div
= 1, val
;
411 pclk_info
= pclk_info_get(clk
);
413 spin_lock_irqsave(&clocks_lock
, flags
);
416 spin_unlock_irqrestore(&clocks_lock
, flags
);
420 change_parent(clk
, pclk_info
->pclk
);
422 spin_lock_irqsave(&clocks_lock
, flags
);
423 if (pclk_info
->scalable
) {
424 val
= readl(config
->synth_reg
);
425 div
+= (val
>> config
->masks
->mscale_sel_shift
) &
426 config
->masks
->mscale_sel_mask
;
427 div
*= 1 << (((val
>> config
->masks
->nscale_sel_shift
) &
428 config
->masks
->nscale_sel_mask
) + 1);
431 clk
->rate
= (unsigned long)clk
->pclk
->rate
/ div
;
432 spin_unlock_irqrestore(&clocks_lock
, flags
);
436 * Used for clocks that always have value as the parent clock divided by a
439 void follow_parent(struct clk
*clk
)
442 unsigned int div_factor
= (clk
->div_factor
< 1) ? 1 : clk
->div_factor
;
444 spin_lock_irqsave(&clocks_lock
, flags
);
445 clk
->rate
= clk
->pclk
->rate
/div_factor
;
446 spin_unlock_irqrestore(&clocks_lock
, flags
);
450 * recalc_root_clocks - recalculate and propagate all root clocks
452 * Recalculates all root clocks (clocks with no parent), which if the
453 * clock's .recalc is set correctly, should also propagate their rates.
455 void recalc_root_clocks(void)
457 propagate_rate(&root_clks
);