Merge branch 'perf-core-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git...
[pandora-kernel.git] / arch / arm / plat-spear / clock.c
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/err.h>
16 #include <linux/io.h>
17 #include <linux/list.h>
18 #include <linux/module.h>
19 #include <linux/spinlock.h>
20 #include <mach/misc_regs.h>
21 #include <plat/clock.h>
22
23 static DEFINE_SPINLOCK(clocks_lock);
24 static LIST_HEAD(root_clks);
25
26 static void propagate_rate(struct list_head *);
27
28 static 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
46 static 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 */
63 static struct clkops generic_clkops = {
64         .enable = generic_clk_enable,
65         .disable = generic_clk_disable,
66 };
67
68 /*
69  * clk_enable - inform the system when the clock source should be running.
70  * @clk: clock source
71  *
72  * If the clock can not be enabled/disabled, this should return success.
73  *
74  * Returns success (0) or negative errno.
75  */
76 int clk_enable(struct clk *clk)
77 {
78         unsigned long flags;
79         int ret = 0;
80
81         if (!clk || IS_ERR(clk))
82                 return -EFAULT;
83
84         spin_lock_irqsave(&clocks_lock, flags);
85         if (clk->usage_count == 0) {
86                 if (clk->ops && clk->ops->enable)
87                         ret = clk->ops->enable(clk);
88         }
89         clk->usage_count++;
90         spin_unlock_irqrestore(&clocks_lock, flags);
91
92         return ret;
93 }
94 EXPORT_SYMBOL(clk_enable);
95
96 /*
97  * clk_disable - inform the system when the clock source is no longer required.
98  * @clk: clock source
99  *
100  * Inform the system that a clock source is no longer required by
101  * a driver and may be shut down.
102  *
103  * Implementation detail: if the clock source is shared between
104  * multiple drivers, clk_enable() calls must be balanced by the
105  * same number of clk_disable() calls for the clock source to be
106  * disabled.
107  */
108 void clk_disable(struct clk *clk)
109 {
110         unsigned long flags;
111
112         if (!clk || IS_ERR(clk))
113                 return;
114
115         WARN_ON(clk->usage_count == 0);
116
117         spin_lock_irqsave(&clocks_lock, flags);
118         clk->usage_count--;
119         if (clk->usage_count == 0) {
120                 if (clk->ops && clk->ops->disable)
121                         clk->ops->disable(clk);
122         }
123         spin_unlock_irqrestore(&clocks_lock, flags);
124 }
125 EXPORT_SYMBOL(clk_disable);
126
127 /**
128  * clk_get_rate - obtain the current clock rate (in Hz) for a clock source.
129  *               This is only valid once the clock source has been enabled.
130  * @clk: clock source
131  */
132 unsigned long clk_get_rate(struct clk *clk)
133 {
134         unsigned long flags, rate;
135
136         spin_lock_irqsave(&clocks_lock, flags);
137         rate = clk->rate;
138         spin_unlock_irqrestore(&clocks_lock, flags);
139
140         return rate;
141 }
142 EXPORT_SYMBOL(clk_get_rate);
143
144 /**
145  * clk_set_parent - set the parent clock source for this clock
146  * @clk: clock source
147  * @parent: parent clock source
148  *
149  * Returns success (0) or negative errno.
150  */
151 int clk_set_parent(struct clk *clk, struct clk *parent)
152 {
153         int i, found = 0, val = 0;
154         unsigned long flags;
155
156         if (!clk || IS_ERR(clk) || !parent || IS_ERR(parent))
157                 return -EFAULT;
158         if (clk->usage_count)
159                 return -EBUSY;
160         if (!clk->pclk_sel)
161                 return -EPERM;
162         if (clk->pclk == parent)
163                 return 0;
164
165         for (i = 0; i < clk->pclk_sel->pclk_count; i++) {
166                 if (clk->pclk_sel->pclk_info[i].pclk == parent) {
167                         found = 1;
168                         break;
169                 }
170         }
171
172         if (!found)
173                 return -EINVAL;
174
175         spin_lock_irqsave(&clocks_lock, flags);
176         /* reflect parent change in hardware */
177         val = readl(clk->pclk_sel->pclk_sel_reg);
178         val &= ~(clk->pclk_sel->pclk_sel_mask << clk->pclk_sel_shift);
179         val |= clk->pclk_sel->pclk_info[i].pclk_mask << clk->pclk_sel_shift;
180         writel(val, clk->pclk_sel->pclk_sel_reg);
181         spin_unlock_irqrestore(&clocks_lock, flags);
182
183         /* reflect parent change in software */
184         clk->recalc(clk);
185         propagate_rate(&clk->children);
186         return 0;
187 }
188 EXPORT_SYMBOL(clk_set_parent);
189
190 /* registers clock in platform clock framework */
191 void clk_register(struct clk_lookup *cl)
192 {
193         struct clk *clk = cl->clk;
194         unsigned long flags;
195
196         if (!clk || IS_ERR(clk))
197                 return;
198
199         spin_lock_irqsave(&clocks_lock, flags);
200
201         INIT_LIST_HEAD(&clk->children);
202         if (clk->flags & ALWAYS_ENABLED)
203                 clk->ops = NULL;
204         else if (!clk->ops)
205                 clk->ops = &generic_clkops;
206
207         /* root clock don't have any parents */
208         if (!clk->pclk && !clk->pclk_sel) {
209                 list_add(&clk->sibling, &root_clks);
210                 /* add clocks with only one parent to parent's children list */
211         } else if (clk->pclk && !clk->pclk_sel) {
212                 list_add(&clk->sibling, &clk->pclk->children);
213         } else {
214                 /* add clocks with > 1 parent to 1st parent's children list */
215                 list_add(&clk->sibling,
216                          &clk->pclk_sel->pclk_info[0].pclk->children);
217         }
218         spin_unlock_irqrestore(&clocks_lock, flags);
219
220         /* add clock to arm clockdev framework */
221         clkdev_add(cl);
222 }
223
224 /**
225  * propagate_rate - recalculate and propagate all clocks in list head
226  *
227  * Recalculates all root clocks in list head, which if the clock's .recalc is
228  * set correctly, should also propagate their rates.
229  */
230 static void propagate_rate(struct list_head *lhead)
231 {
232         struct clk *clkp, *_temp;
233
234         list_for_each_entry_safe(clkp, _temp, lhead, sibling) {
235                 if (clkp->recalc)
236                         clkp->recalc(clkp);
237                 propagate_rate(&clkp->children);
238         }
239 }
240
241 /* returns current programmed clocks clock info structure */
242 static struct pclk_info *pclk_info_get(struct clk *clk)
243 {
244         unsigned int mask, i;
245         unsigned long flags;
246         struct pclk_info *info = NULL;
247
248         spin_lock_irqsave(&clocks_lock, flags);
249         mask = (readl(clk->pclk_sel->pclk_sel_reg) >> clk->pclk_sel_shift)
250                         & clk->pclk_sel->pclk_sel_mask;
251
252         for (i = 0; i < clk->pclk_sel->pclk_count; i++) {
253                 if (clk->pclk_sel->pclk_info[i].pclk_mask == mask)
254                         info = &clk->pclk_sel->pclk_info[i];
255         }
256         spin_unlock_irqrestore(&clocks_lock, flags);
257
258         return info;
259 }
260
261 /*
262  * Set pclk as cclk's parent and add clock sibling node to current parents
263  * children list
264  */
265 static void change_parent(struct clk *cclk, struct clk *pclk)
266 {
267         unsigned long flags;
268
269         spin_lock_irqsave(&clocks_lock, flags);
270         list_del(&cclk->sibling);
271         list_add(&cclk->sibling, &pclk->children);
272
273         cclk->pclk = pclk;
274         spin_unlock_irqrestore(&clocks_lock, flags);
275 }
276
277 /*
278  * calculates current programmed rate of pll1
279  *
280  * In normal mode
281  * rate = (2 * M[15:8] * Fin)/(N * 2^P)
282  *
283  * In Dithered mode
284  * rate = (2 * M[15:0] * Fin)/(256 * N * 2^P)
285  */
286 void pll1_clk_recalc(struct clk *clk)
287 {
288         struct pll_clk_config *config = clk->private_data;
289         unsigned int num = 2, den = 0, val, mode = 0;
290         unsigned long flags;
291
292         spin_lock_irqsave(&clocks_lock, flags);
293         mode = (readl(config->mode_reg) >> PLL_MODE_SHIFT) &
294                 PLL_MODE_MASK;
295
296         val = readl(config->cfg_reg);
297         /* calculate denominator */
298         den = (val >> PLL_DIV_P_SHIFT) & PLL_DIV_P_MASK;
299         den = 1 << den;
300         den *= (val >> PLL_DIV_N_SHIFT) & PLL_DIV_N_MASK;
301
302         /* calculate numerator & denominator */
303         if (!mode) {
304                 /* Normal mode */
305                 num *= (val >> PLL_NORM_FDBK_M_SHIFT) & PLL_NORM_FDBK_M_MASK;
306         } else {
307                 /* Dithered mode */
308                 num *= (val >> PLL_DITH_FDBK_M_SHIFT) & PLL_DITH_FDBK_M_MASK;
309                 den *= 256;
310         }
311
312         clk->rate = (((clk->pclk->rate/10000) * num) / den) * 10000;
313         spin_unlock_irqrestore(&clocks_lock, flags);
314 }
315
316 /* calculates current programmed rate of ahb or apb bus */
317 void bus_clk_recalc(struct clk *clk)
318 {
319         struct bus_clk_config *config = clk->private_data;
320         unsigned int div;
321         unsigned long flags;
322
323         spin_lock_irqsave(&clocks_lock, flags);
324         div = ((readl(config->reg) >> config->shift) & config->mask) + 1;
325         clk->rate = (unsigned long)clk->pclk->rate / div;
326         spin_unlock_irqrestore(&clocks_lock, flags);
327 }
328
329 /*
330  * calculates current programmed rate of auxiliary synthesizers
331  * used by: UART, FIRDA
332  *
333  * Fout from synthesizer can be given from two equations:
334  * Fout1 = (Fin * X/Y)/2
335  * Fout2 = Fin * X/Y
336  *
337  * Selection of eqn 1 or 2 is programmed in register
338  */
339 void aux_clk_recalc(struct clk *clk)
340 {
341         struct aux_clk_config *config = clk->private_data;
342         struct pclk_info *pclk_info = NULL;
343         unsigned int num = 1, den = 1, val, eqn;
344         unsigned long flags;
345
346         /* get current programmed parent */
347         pclk_info = pclk_info_get(clk);
348         if (!pclk_info) {
349                 spin_lock_irqsave(&clocks_lock, flags);
350                 clk->pclk = NULL;
351                 clk->rate = 0;
352                 spin_unlock_irqrestore(&clocks_lock, flags);
353                 return;
354         }
355
356         change_parent(clk, pclk_info->pclk);
357
358         spin_lock_irqsave(&clocks_lock, flags);
359         if (pclk_info->scalable) {
360                 val = readl(config->synth_reg);
361
362                 eqn = (val >> AUX_EQ_SEL_SHIFT) & AUX_EQ_SEL_MASK;
363                 if (eqn == AUX_EQ1_SEL)
364                         den *= 2;
365
366                 /* calculate numerator */
367                 num = (val >> AUX_XSCALE_SHIFT) & AUX_XSCALE_MASK;
368
369                 /* calculate denominator */
370                 den *= (val >> AUX_YSCALE_SHIFT) & AUX_YSCALE_MASK;
371                 val = (((clk->pclk->rate/10000) * num) / den) * 10000;
372         } else
373                 val = clk->pclk->rate;
374
375         clk->rate = val;
376         spin_unlock_irqrestore(&clocks_lock, flags);
377 }
378
379 /*
380  * calculates current programmed rate of gpt synthesizers
381  * Fout from synthesizer can be given from below equations:
382  * Fout= Fin/((2 ^ (N+1)) * (M+1))
383  */
384 void gpt_clk_recalc(struct clk *clk)
385 {
386         struct aux_clk_config *config = clk->private_data;
387         struct pclk_info *pclk_info = NULL;
388         unsigned int div = 1, val;
389         unsigned long flags;
390
391         pclk_info = pclk_info_get(clk);
392         if (!pclk_info) {
393                 spin_lock_irqsave(&clocks_lock, flags);
394                 clk->pclk = NULL;
395                 clk->rate = 0;
396                 spin_unlock_irqrestore(&clocks_lock, flags);
397                 return;
398         }
399
400         change_parent(clk, pclk_info->pclk);
401
402         spin_lock_irqsave(&clocks_lock, flags);
403         if (pclk_info->scalable) {
404                 val = readl(config->synth_reg);
405                 div += (val >> GPT_MSCALE_SHIFT) & GPT_MSCALE_MASK;
406                 div *= 1 << (((val >> GPT_NSCALE_SHIFT) & GPT_NSCALE_MASK) + 1);
407         }
408
409         clk->rate = (unsigned long)clk->pclk->rate / div;
410         spin_unlock_irqrestore(&clocks_lock, flags);
411 }
412
413 /*
414  * Used for clocks that always have same value as the parent clock divided by a
415  * fixed divisor
416  */
417 void follow_parent(struct clk *clk)
418 {
419         unsigned long flags;
420
421         spin_lock_irqsave(&clocks_lock, flags);
422         clk->rate = clk->pclk->rate;
423         spin_unlock_irqrestore(&clocks_lock, flags);
424 }
425
426 /**
427  * recalc_root_clocks - recalculate and propagate all root clocks
428  *
429  * Recalculates all root clocks (clocks with no parent), which if the
430  * clock's .recalc is set correctly, should also propagate their rates.
431  */
432 void recalc_root_clocks(void)
433 {
434         propagate_rate(&root_clks);
435 }