Merge branch 'fix/hda' into topic/hda
[sfrench/cifs-2.6.git] / arch / arm / mach-ep93xx / clock.c
1 /*
2  * arch/arm/mach-ep93xx/clock.c
3  * Clock control for Cirrus EP93xx chips.
4  *
5  * Copyright (C) 2006 Lennert Buytenhek <buytenh@wantstofly.org>
6  *
7  * This program is free software; you can redistribute it and/or modify
8  * it under the terms of the GNU General Public License as published by
9  * the Free Software Foundation; either version 2 of the License, or (at
10  * your option) any later version.
11  */
12
13 #include <linux/kernel.h>
14 #include <linux/clk.h>
15 #include <linux/err.h>
16 #include <linux/module.h>
17 #include <linux/string.h>
18 #include <linux/io.h>
19
20 #include <asm/clkdev.h>
21 #include <asm/div64.h>
22 #include <mach/hardware.h>
23
24
25 struct clk {
26         unsigned long   rate;
27         int             users;
28         int             sw_locked;
29         void __iomem    *enable_reg;
30         u32             enable_mask;
31
32         unsigned long   (*get_rate)(struct clk *clk);
33         int             (*set_rate)(struct clk *clk, unsigned long rate);
34 };
35
36
37 static unsigned long get_uart_rate(struct clk *clk);
38
39 static int set_keytchclk_rate(struct clk *clk, unsigned long rate);
40 static int set_div_rate(struct clk *clk, unsigned long rate);
41
42 static struct clk clk_uart1 = {
43         .sw_locked      = 1,
44         .enable_reg     = EP93XX_SYSCON_DEVCFG,
45         .enable_mask    = EP93XX_SYSCON_DEVCFG_U1EN,
46         .get_rate       = get_uart_rate,
47 };
48 static struct clk clk_uart2 = {
49         .sw_locked      = 1,
50         .enable_reg     = EP93XX_SYSCON_DEVCFG,
51         .enable_mask    = EP93XX_SYSCON_DEVCFG_U2EN,
52         .get_rate       = get_uart_rate,
53 };
54 static struct clk clk_uart3 = {
55         .sw_locked      = 1,
56         .enable_reg     = EP93XX_SYSCON_DEVCFG,
57         .enable_mask    = EP93XX_SYSCON_DEVCFG_U3EN,
58         .get_rate       = get_uart_rate,
59 };
60 static struct clk clk_pll1;
61 static struct clk clk_f;
62 static struct clk clk_h;
63 static struct clk clk_p;
64 static struct clk clk_pll2;
65 static struct clk clk_usb_host = {
66         .enable_reg     = EP93XX_SYSCON_PWRCNT,
67         .enable_mask    = EP93XX_SYSCON_PWRCNT_USH_EN,
68 };
69 static struct clk clk_keypad = {
70         .sw_locked      = 1,
71         .enable_reg     = EP93XX_SYSCON_KEYTCHCLKDIV,
72         .enable_mask    = EP93XX_SYSCON_KEYTCHCLKDIV_KEN,
73         .set_rate       = set_keytchclk_rate,
74 };
75 static struct clk clk_pwm = {
76         .rate           = EP93XX_EXT_CLK_RATE,
77 };
78
79 static struct clk clk_video = {
80         .sw_locked      = 1,
81         .enable_reg     = EP93XX_SYSCON_VIDCLKDIV,
82         .enable_mask    = EP93XX_SYSCON_CLKDIV_ENABLE,
83         .set_rate       = set_div_rate,
84 };
85
86 /* DMA Clocks */
87 static struct clk clk_m2p0 = {
88         .enable_reg     = EP93XX_SYSCON_PWRCNT,
89         .enable_mask    = EP93XX_SYSCON_PWRCNT_DMA_M2P0,
90 };
91 static struct clk clk_m2p1 = {
92         .enable_reg     = EP93XX_SYSCON_PWRCNT,
93         .enable_mask    = EP93XX_SYSCON_PWRCNT_DMA_M2P1,
94 };
95 static struct clk clk_m2p2 = {
96         .enable_reg     = EP93XX_SYSCON_PWRCNT,
97         .enable_mask    = EP93XX_SYSCON_PWRCNT_DMA_M2P2,
98 };
99 static struct clk clk_m2p3 = {
100         .enable_reg     = EP93XX_SYSCON_PWRCNT,
101         .enable_mask    = EP93XX_SYSCON_PWRCNT_DMA_M2P3,
102 };
103 static struct clk clk_m2p4 = {
104         .enable_reg     = EP93XX_SYSCON_PWRCNT,
105         .enable_mask    = EP93XX_SYSCON_PWRCNT_DMA_M2P4,
106 };
107 static struct clk clk_m2p5 = {
108         .enable_reg     = EP93XX_SYSCON_PWRCNT,
109         .enable_mask    = EP93XX_SYSCON_PWRCNT_DMA_M2P5,
110 };
111 static struct clk clk_m2p6 = {
112         .enable_reg     = EP93XX_SYSCON_PWRCNT,
113         .enable_mask    = EP93XX_SYSCON_PWRCNT_DMA_M2P6,
114 };
115 static struct clk clk_m2p7 = {
116         .enable_reg     = EP93XX_SYSCON_PWRCNT,
117         .enable_mask    = EP93XX_SYSCON_PWRCNT_DMA_M2P7,
118 };
119 static struct clk clk_m2p8 = {
120         .enable_reg     = EP93XX_SYSCON_PWRCNT,
121         .enable_mask    = EP93XX_SYSCON_PWRCNT_DMA_M2P8,
122 };
123 static struct clk clk_m2p9 = {
124         .enable_reg     = EP93XX_SYSCON_PWRCNT,
125         .enable_mask    = EP93XX_SYSCON_PWRCNT_DMA_M2P9,
126 };
127 static struct clk clk_m2m0 = {
128         .enable_reg     = EP93XX_SYSCON_PWRCNT,
129         .enable_mask    = EP93XX_SYSCON_PWRCNT_DMA_M2M0,
130 };
131 static struct clk clk_m2m1 = {
132         .enable_reg     = EP93XX_SYSCON_PWRCNT,
133         .enable_mask    = EP93XX_SYSCON_PWRCNT_DMA_M2M1,
134 };
135
136 #define INIT_CK(dev,con,ck)                                     \
137         { .dev_id = dev, .con_id = con, .clk = ck }
138
139 static struct clk_lookup clocks[] = {
140         INIT_CK("apb:uart1",            NULL,           &clk_uart1),
141         INIT_CK("apb:uart2",            NULL,           &clk_uart2),
142         INIT_CK("apb:uart3",            NULL,           &clk_uart3),
143         INIT_CK(NULL,                   "pll1",         &clk_pll1),
144         INIT_CK(NULL,                   "fclk",         &clk_f),
145         INIT_CK(NULL,                   "hclk",         &clk_h),
146         INIT_CK(NULL,                   "pclk",         &clk_p),
147         INIT_CK(NULL,                   "pll2",         &clk_pll2),
148         INIT_CK("ep93xx-ohci",          NULL,           &clk_usb_host),
149         INIT_CK("ep93xx-keypad",        NULL,           &clk_keypad),
150         INIT_CK("ep93xx-fb",            NULL,           &clk_video),
151         INIT_CK(NULL,                   "pwm_clk",      &clk_pwm),
152         INIT_CK(NULL,                   "m2p0",         &clk_m2p0),
153         INIT_CK(NULL,                   "m2p1",         &clk_m2p1),
154         INIT_CK(NULL,                   "m2p2",         &clk_m2p2),
155         INIT_CK(NULL,                   "m2p3",         &clk_m2p3),
156         INIT_CK(NULL,                   "m2p4",         &clk_m2p4),
157         INIT_CK(NULL,                   "m2p5",         &clk_m2p5),
158         INIT_CK(NULL,                   "m2p6",         &clk_m2p6),
159         INIT_CK(NULL,                   "m2p7",         &clk_m2p7),
160         INIT_CK(NULL,                   "m2p8",         &clk_m2p8),
161         INIT_CK(NULL,                   "m2p9",         &clk_m2p9),
162         INIT_CK(NULL,                   "m2m0",         &clk_m2m0),
163         INIT_CK(NULL,                   "m2m1",         &clk_m2m1),
164 };
165
166
167 int clk_enable(struct clk *clk)
168 {
169         if (!clk->users++ && clk->enable_reg) {
170                 u32 value;
171
172                 value = __raw_readl(clk->enable_reg);
173                 value |= clk->enable_mask;
174                 if (clk->sw_locked)
175                         ep93xx_syscon_swlocked_write(value, clk->enable_reg);
176                 else
177                         __raw_writel(value, clk->enable_reg);
178         }
179
180         return 0;
181 }
182 EXPORT_SYMBOL(clk_enable);
183
184 void clk_disable(struct clk *clk)
185 {
186         if (!--clk->users && clk->enable_reg) {
187                 u32 value;
188
189                 value = __raw_readl(clk->enable_reg);
190                 value &= ~clk->enable_mask;
191                 if (clk->sw_locked)
192                         ep93xx_syscon_swlocked_write(value, clk->enable_reg);
193                 else
194                         __raw_writel(value, clk->enable_reg);
195         }
196 }
197 EXPORT_SYMBOL(clk_disable);
198
199 static unsigned long get_uart_rate(struct clk *clk)
200 {
201         u32 value;
202
203         value = __raw_readl(EP93XX_SYSCON_PWRCNT);
204         if (value & EP93XX_SYSCON_PWRCNT_UARTBAUD)
205                 return EP93XX_EXT_CLK_RATE;
206         else
207                 return EP93XX_EXT_CLK_RATE / 2;
208 }
209
210 unsigned long clk_get_rate(struct clk *clk)
211 {
212         if (clk->get_rate)
213                 return clk->get_rate(clk);
214
215         return clk->rate;
216 }
217 EXPORT_SYMBOL(clk_get_rate);
218
219 static int set_keytchclk_rate(struct clk *clk, unsigned long rate)
220 {
221         u32 val;
222         u32 div_bit;
223
224         val = __raw_readl(clk->enable_reg);
225
226         /*
227          * The Key Matrix and ADC clocks are configured using the same
228          * System Controller register.  The clock used will be either
229          * 1/4 or 1/16 the external clock rate depending on the
230          * EP93XX_SYSCON_KEYTCHCLKDIV_KDIV/EP93XX_SYSCON_KEYTCHCLKDIV_ADIV
231          * bit being set or cleared.
232          */
233         div_bit = clk->enable_mask >> 15;
234
235         if (rate == EP93XX_KEYTCHCLK_DIV4)
236                 val |= div_bit;
237         else if (rate == EP93XX_KEYTCHCLK_DIV16)
238                 val &= ~div_bit;
239         else
240                 return -EINVAL;
241
242         ep93xx_syscon_swlocked_write(val, clk->enable_reg);
243         clk->rate = rate;
244         return 0;
245 }
246
247 static unsigned long calc_clk_div(unsigned long rate, int *psel, int *esel,
248                                   int *pdiv, int *div)
249 {
250         unsigned long max_rate, best_rate = 0,
251                 actual_rate = 0, mclk_rate = 0, rate_err = -1;
252         int i, found = 0, __div = 0, __pdiv = 0;
253
254         /* Don't exceed the maximum rate */
255         max_rate = max(max(clk_pll1.rate / 4, clk_pll2.rate / 4),
256                        (unsigned long)EP93XX_EXT_CLK_RATE / 4);
257         rate = min(rate, max_rate);
258
259         /*
260          * Try the two pll's and the external clock
261          * Because the valid predividers are 2, 2.5 and 3, we multiply
262          * all the clocks by 2 to avoid floating point math.
263          *
264          * This is based on the algorithm in the ep93xx raster guide:
265          * http://be-a-maverick.com/en/pubs/appNote/AN269REV1.pdf
266          *
267          */
268         for (i = 0; i < 3; i++) {
269                 if (i == 0)
270                         mclk_rate = EP93XX_EXT_CLK_RATE * 2;
271                 else if (i == 1)
272                         mclk_rate = clk_pll1.rate * 2;
273                 else if (i == 2)
274                         mclk_rate = clk_pll2.rate * 2;
275
276                 /* Try each predivider value */
277                 for (__pdiv = 4; __pdiv <= 6; __pdiv++) {
278                         __div = mclk_rate / (rate * __pdiv);
279                         if (__div < 2 || __div > 127)
280                                 continue;
281
282                         actual_rate = mclk_rate / (__pdiv * __div);
283
284                         if (!found || abs(actual_rate - rate) < rate_err) {
285                                 *pdiv = __pdiv - 3;
286                                 *div = __div;
287                                 *psel = (i == 2);
288                                 *esel = (i != 0);
289                                 best_rate = actual_rate;
290                                 rate_err = abs(actual_rate - rate);
291                                 found = 1;
292                         }
293                 }
294         }
295
296         if (!found)
297                 return 0;
298
299         return best_rate;
300 }
301
302 static int set_div_rate(struct clk *clk, unsigned long rate)
303 {
304         unsigned long actual_rate;
305         int psel = 0, esel = 0, pdiv = 0, div = 0;
306         u32 val;
307
308         actual_rate = calc_clk_div(rate, &psel, &esel, &pdiv, &div);
309         if (actual_rate == 0)
310                 return -EINVAL;
311         clk->rate = actual_rate;
312
313         /* Clear the esel, psel, pdiv and div bits */
314         val = __raw_readl(clk->enable_reg);
315         val &= ~0x7fff;
316
317         /* Set the new esel, psel, pdiv and div bits for the new clock rate */
318         val |= (esel ? EP93XX_SYSCON_CLKDIV_ESEL : 0) |
319                 (psel ? EP93XX_SYSCON_CLKDIV_PSEL : 0) |
320                 (pdiv << EP93XX_SYSCON_CLKDIV_PDIV_SHIFT) | div;
321         ep93xx_syscon_swlocked_write(val, clk->enable_reg);
322         return 0;
323 }
324
325 int clk_set_rate(struct clk *clk, unsigned long rate)
326 {
327         if (clk->set_rate)
328                 return clk->set_rate(clk, rate);
329
330         return -EINVAL;
331 }
332 EXPORT_SYMBOL(clk_set_rate);
333
334
335 static char fclk_divisors[] = { 1, 2, 4, 8, 16, 1, 1, 1 };
336 static char hclk_divisors[] = { 1, 2, 4, 5, 6, 8, 16, 32 };
337 static char pclk_divisors[] = { 1, 2, 4, 8 };
338
339 /*
340  * PLL rate = 14.7456 MHz * (X1FBD + 1) * (X2FBD + 1) / (X2IPD + 1) / 2^PS
341  */
342 static unsigned long calc_pll_rate(u32 config_word)
343 {
344         unsigned long long rate;
345         int i;
346
347         rate = EP93XX_EXT_CLK_RATE;
348         rate *= ((config_word >> 11) & 0x1f) + 1;               /* X1FBD */
349         rate *= ((config_word >> 5) & 0x3f) + 1;                /* X2FBD */
350         do_div(rate, (config_word & 0x1f) + 1);                 /* X2IPD */
351         for (i = 0; i < ((config_word >> 16) & 3); i++)         /* PS */
352                 rate >>= 1;
353
354         return (unsigned long)rate;
355 }
356
357 static void __init ep93xx_dma_clock_init(void)
358 {
359         clk_m2p0.rate = clk_h.rate;
360         clk_m2p1.rate = clk_h.rate;
361         clk_m2p2.rate = clk_h.rate;
362         clk_m2p3.rate = clk_h.rate;
363         clk_m2p4.rate = clk_h.rate;
364         clk_m2p5.rate = clk_h.rate;
365         clk_m2p6.rate = clk_h.rate;
366         clk_m2p7.rate = clk_h.rate;
367         clk_m2p8.rate = clk_h.rate;
368         clk_m2p9.rate = clk_h.rate;
369         clk_m2m0.rate = clk_h.rate;
370         clk_m2m1.rate = clk_h.rate;
371 }
372
373 static int __init ep93xx_clock_init(void)
374 {
375         u32 value;
376         int i;
377
378         value = __raw_readl(EP93XX_SYSCON_CLOCK_SET1);
379         if (!(value & 0x00800000)) {                    /* PLL1 bypassed?  */
380                 clk_pll1.rate = EP93XX_EXT_CLK_RATE;
381         } else {
382                 clk_pll1.rate = calc_pll_rate(value);
383         }
384         clk_f.rate = clk_pll1.rate / fclk_divisors[(value >> 25) & 0x7];
385         clk_h.rate = clk_pll1.rate / hclk_divisors[(value >> 20) & 0x7];
386         clk_p.rate = clk_h.rate / pclk_divisors[(value >> 18) & 0x3];
387         ep93xx_dma_clock_init();
388
389         value = __raw_readl(EP93XX_SYSCON_CLOCK_SET2);
390         if (!(value & 0x00080000)) {                    /* PLL2 bypassed?  */
391                 clk_pll2.rate = EP93XX_EXT_CLK_RATE;
392         } else if (value & 0x00040000) {                /* PLL2 enabled?  */
393                 clk_pll2.rate = calc_pll_rate(value);
394         } else {
395                 clk_pll2.rate = 0;
396         }
397         clk_usb_host.rate = clk_pll2.rate / (((value >> 28) & 0xf) + 1);
398
399         printk(KERN_INFO "ep93xx: PLL1 running at %ld MHz, PLL2 at %ld MHz\n",
400                 clk_pll1.rate / 1000000, clk_pll2.rate / 1000000);
401         printk(KERN_INFO "ep93xx: FCLK %ld MHz, HCLK %ld MHz, PCLK %ld MHz\n",
402                 clk_f.rate / 1000000, clk_h.rate / 1000000,
403                 clk_p.rate / 1000000);
404
405         for (i = 0; i < ARRAY_SIZE(clocks); i++)
406                 clkdev_add(&clocks[i]);
407         return 0;
408 }
409 arch_initcall(ep93xx_clock_init);