ARM: 5628/1: ep93xx: Introduce Pulse Width Modulator (PWM) driver
[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
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 /* DMA Clocks */
80 static struct clk clk_m2p0 = {
81         .enable_reg     = EP93XX_SYSCON_PWRCNT,
82         .enable_mask    = EP93XX_SYSCON_PWRCNT_DMA_M2P0,
83 };
84 static struct clk clk_m2p1 = {
85         .enable_reg     = EP93XX_SYSCON_PWRCNT,
86         .enable_mask    = EP93XX_SYSCON_PWRCNT_DMA_M2P1,
87 };
88 static struct clk clk_m2p2 = {
89         .enable_reg     = EP93XX_SYSCON_PWRCNT,
90         .enable_mask    = EP93XX_SYSCON_PWRCNT_DMA_M2P2,
91 };
92 static struct clk clk_m2p3 = {
93         .enable_reg     = EP93XX_SYSCON_PWRCNT,
94         .enable_mask    = EP93XX_SYSCON_PWRCNT_DMA_M2P3,
95 };
96 static struct clk clk_m2p4 = {
97         .enable_reg     = EP93XX_SYSCON_PWRCNT,
98         .enable_mask    = EP93XX_SYSCON_PWRCNT_DMA_M2P4,
99 };
100 static struct clk clk_m2p5 = {
101         .enable_reg     = EP93XX_SYSCON_PWRCNT,
102         .enable_mask    = EP93XX_SYSCON_PWRCNT_DMA_M2P5,
103 };
104 static struct clk clk_m2p6 = {
105         .enable_reg     = EP93XX_SYSCON_PWRCNT,
106         .enable_mask    = EP93XX_SYSCON_PWRCNT_DMA_M2P6,
107 };
108 static struct clk clk_m2p7 = {
109         .enable_reg     = EP93XX_SYSCON_PWRCNT,
110         .enable_mask    = EP93XX_SYSCON_PWRCNT_DMA_M2P7,
111 };
112 static struct clk clk_m2p8 = {
113         .enable_reg     = EP93XX_SYSCON_PWRCNT,
114         .enable_mask    = EP93XX_SYSCON_PWRCNT_DMA_M2P8,
115 };
116 static struct clk clk_m2p9 = {
117         .enable_reg     = EP93XX_SYSCON_PWRCNT,
118         .enable_mask    = EP93XX_SYSCON_PWRCNT_DMA_M2P9,
119 };
120 static struct clk clk_m2m0 = {
121         .enable_reg     = EP93XX_SYSCON_PWRCNT,
122         .enable_mask    = EP93XX_SYSCON_PWRCNT_DMA_M2M0,
123 };
124 static struct clk clk_m2m1 = {
125         .enable_reg     = EP93XX_SYSCON_PWRCNT,
126         .enable_mask    = EP93XX_SYSCON_PWRCNT_DMA_M2M1,
127 };
128
129 #define INIT_CK(dev,con,ck)                                     \
130         { .dev_id = dev, .con_id = con, .clk = ck }
131
132 static struct clk_lookup clocks[] = {
133         INIT_CK("apb:uart1",            NULL,           &clk_uart1),
134         INIT_CK("apb:uart2",            NULL,           &clk_uart2),
135         INIT_CK("apb:uart3",            NULL,           &clk_uart3),
136         INIT_CK(NULL,                   "pll1",         &clk_pll1),
137         INIT_CK(NULL,                   "fclk",         &clk_f),
138         INIT_CK(NULL,                   "hclk",         &clk_h),
139         INIT_CK(NULL,                   "pclk",         &clk_p),
140         INIT_CK(NULL,                   "pll2",         &clk_pll2),
141         INIT_CK("ep93xx-ohci",          NULL,           &clk_usb_host),
142         INIT_CK("ep93xx-keypad",        NULL,           &clk_keypad),
143         INIT_CK(NULL,                   "pwm_clk",      &clk_pwm),
144         INIT_CK(NULL,                   "m2p0",         &clk_m2p0),
145         INIT_CK(NULL,                   "m2p1",         &clk_m2p1),
146         INIT_CK(NULL,                   "m2p2",         &clk_m2p2),
147         INIT_CK(NULL,                   "m2p3",         &clk_m2p3),
148         INIT_CK(NULL,                   "m2p4",         &clk_m2p4),
149         INIT_CK(NULL,                   "m2p5",         &clk_m2p5),
150         INIT_CK(NULL,                   "m2p6",         &clk_m2p6),
151         INIT_CK(NULL,                   "m2p7",         &clk_m2p7),
152         INIT_CK(NULL,                   "m2p8",         &clk_m2p8),
153         INIT_CK(NULL,                   "m2p9",         &clk_m2p9),
154         INIT_CK(NULL,                   "m2m0",         &clk_m2m0),
155         INIT_CK(NULL,                   "m2m1",         &clk_m2m1),
156 };
157
158
159 int clk_enable(struct clk *clk)
160 {
161         if (!clk->users++ && clk->enable_reg) {
162                 u32 value;
163
164                 value = __raw_readl(clk->enable_reg);
165                 value |= clk->enable_mask;
166                 if (clk->sw_locked)
167                         ep93xx_syscon_swlocked_write(value, clk->enable_reg);
168                 else
169                         __raw_writel(value, clk->enable_reg);
170         }
171
172         return 0;
173 }
174 EXPORT_SYMBOL(clk_enable);
175
176 void clk_disable(struct clk *clk)
177 {
178         if (!--clk->users && clk->enable_reg) {
179                 u32 value;
180
181                 value = __raw_readl(clk->enable_reg);
182                 value &= ~clk->enable_mask;
183                 if (clk->sw_locked)
184                         ep93xx_syscon_swlocked_write(value, clk->enable_reg);
185                 else
186                         __raw_writel(value, clk->enable_reg);
187         }
188 }
189 EXPORT_SYMBOL(clk_disable);
190
191 static unsigned long get_uart_rate(struct clk *clk)
192 {
193         u32 value;
194
195         value = __raw_readl(EP93XX_SYSCON_PWRCNT);
196         if (value & EP93XX_SYSCON_PWRCNT_UARTBAUD)
197                 return EP93XX_EXT_CLK_RATE;
198         else
199                 return EP93XX_EXT_CLK_RATE / 2;
200 }
201
202 unsigned long clk_get_rate(struct clk *clk)
203 {
204         if (clk->get_rate)
205                 return clk->get_rate(clk);
206
207         return clk->rate;
208 }
209 EXPORT_SYMBOL(clk_get_rate);
210
211 static int set_keytchclk_rate(struct clk *clk, unsigned long rate)
212 {
213         u32 val;
214         u32 div_bit;
215
216         val = __raw_readl(clk->enable_reg);
217
218         /*
219          * The Key Matrix and ADC clocks are configured using the same
220          * System Controller register.  The clock used will be either
221          * 1/4 or 1/16 the external clock rate depending on the
222          * EP93XX_SYSCON_KEYTCHCLKDIV_KDIV/EP93XX_SYSCON_KEYTCHCLKDIV_ADIV
223          * bit being set or cleared.
224          */
225         div_bit = clk->enable_mask >> 15;
226
227         if (rate == EP93XX_KEYTCHCLK_DIV4)
228                 val |= div_bit;
229         else if (rate == EP93XX_KEYTCHCLK_DIV16)
230                 val &= ~div_bit;
231         else
232                 return -EINVAL;
233
234         ep93xx_syscon_swlocked_write(val, clk->enable_reg);
235         clk->rate = rate;
236         return 0;
237 }
238
239 int clk_set_rate(struct clk *clk, unsigned long rate)
240 {
241         if (clk->set_rate)
242                 return clk->set_rate(clk, rate);
243
244         return -EINVAL;
245 }
246 EXPORT_SYMBOL(clk_set_rate);
247
248
249 static char fclk_divisors[] = { 1, 2, 4, 8, 16, 1, 1, 1 };
250 static char hclk_divisors[] = { 1, 2, 4, 5, 6, 8, 16, 32 };
251 static char pclk_divisors[] = { 1, 2, 4, 8 };
252
253 /*
254  * PLL rate = 14.7456 MHz * (X1FBD + 1) * (X2FBD + 1) / (X2IPD + 1) / 2^PS
255  */
256 static unsigned long calc_pll_rate(u32 config_word)
257 {
258         unsigned long long rate;
259         int i;
260
261         rate = EP93XX_EXT_CLK_RATE;
262         rate *= ((config_word >> 11) & 0x1f) + 1;               /* X1FBD */
263         rate *= ((config_word >> 5) & 0x3f) + 1;                /* X2FBD */
264         do_div(rate, (config_word & 0x1f) + 1);                 /* X2IPD */
265         for (i = 0; i < ((config_word >> 16) & 3); i++)         /* PS */
266                 rate >>= 1;
267
268         return (unsigned long)rate;
269 }
270
271 static void __init ep93xx_dma_clock_init(void)
272 {
273         clk_m2p0.rate = clk_h.rate;
274         clk_m2p1.rate = clk_h.rate;
275         clk_m2p2.rate = clk_h.rate;
276         clk_m2p3.rate = clk_h.rate;
277         clk_m2p4.rate = clk_h.rate;
278         clk_m2p5.rate = clk_h.rate;
279         clk_m2p6.rate = clk_h.rate;
280         clk_m2p7.rate = clk_h.rate;
281         clk_m2p8.rate = clk_h.rate;
282         clk_m2p9.rate = clk_h.rate;
283         clk_m2m0.rate = clk_h.rate;
284         clk_m2m1.rate = clk_h.rate;
285 }
286
287 static int __init ep93xx_clock_init(void)
288 {
289         u32 value;
290         int i;
291
292         value = __raw_readl(EP93XX_SYSCON_CLOCK_SET1);
293         if (!(value & 0x00800000)) {                    /* PLL1 bypassed?  */
294                 clk_pll1.rate = EP93XX_EXT_CLK_RATE;
295         } else {
296                 clk_pll1.rate = calc_pll_rate(value);
297         }
298         clk_f.rate = clk_pll1.rate / fclk_divisors[(value >> 25) & 0x7];
299         clk_h.rate = clk_pll1.rate / hclk_divisors[(value >> 20) & 0x7];
300         clk_p.rate = clk_h.rate / pclk_divisors[(value >> 18) & 0x3];
301         ep93xx_dma_clock_init();
302
303         value = __raw_readl(EP93XX_SYSCON_CLOCK_SET2);
304         if (!(value & 0x00080000)) {                    /* PLL2 bypassed?  */
305                 clk_pll2.rate = EP93XX_EXT_CLK_RATE;
306         } else if (value & 0x00040000) {                /* PLL2 enabled?  */
307                 clk_pll2.rate = calc_pll_rate(value);
308         } else {
309                 clk_pll2.rate = 0;
310         }
311         clk_usb_host.rate = clk_pll2.rate / (((value >> 28) & 0xf) + 1);
312
313         printk(KERN_INFO "ep93xx: PLL1 running at %ld MHz, PLL2 at %ld MHz\n",
314                 clk_pll1.rate / 1000000, clk_pll2.rate / 1000000);
315         printk(KERN_INFO "ep93xx: FCLK %ld MHz, HCLK %ld MHz, PCLK %ld MHz\n",
316                 clk_f.rate / 1000000, clk_h.rate / 1000000,
317                 clk_p.rate / 1000000);
318
319         for (i = 0; i < ARRAY_SIZE(clocks); i++)
320                 clkdev_add(&clocks[i]);
321         return 0;
322 }
323 arch_initcall(ep93xx_clock_init);