Merge branch 'driver-core-next' of git://git.kernel.org/pub/scm/linux/kernel/git...
[pandora-kernel.git] / arch / arm / mach-shmobile / clock-sh7377.c
1 /*
2  * SH7377 clock framework support
3  *
4  * Copyright (C) 2010 Magnus Damm
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2 of the License
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with this program; if not, write to the Free Software
17  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
18  */
19 #include <linux/init.h>
20 #include <linux/kernel.h>
21 #include <linux/io.h>
22 #include <linux/sh_clk.h>
23 #include <linux/clkdev.h>
24 #include <mach/common.h>
25
26 /* SH7377 registers */
27 #define RTFRQCR    0xe6150000
28 #define SYFRQCR    0xe6150004
29 #define CMFRQCR    0xe61500E0
30 #define VCLKCR1    0xe6150008
31 #define VCLKCR2    0xe615000C
32 #define VCLKCR3    0xe615001C
33 #define FMSICKCR   0xe6150010
34 #define FMSOCKCR   0xe6150014
35 #define FSICKCR    0xe6150018
36 #define PLLC1CR    0xe6150028
37 #define PLLC2CR    0xe615002C
38 #define SUBUSBCKCR 0xe6150080
39 #define SPUCKCR    0xe6150084
40 #define MSUCKCR    0xe6150088
41 #define MVI3CKCR   0xe6150090
42 #define HDMICKCR   0xe6150094
43 #define MFCK1CR    0xe6150098
44 #define MFCK2CR    0xe615009C
45 #define DSITCKCR   0xe6150060
46 #define DSIPCKCR   0xe6150064
47 #define SMSTPCR0   0xe6150130
48 #define SMSTPCR1   0xe6150134
49 #define SMSTPCR2   0xe6150138
50 #define SMSTPCR3   0xe615013C
51 #define SMSTPCR4   0xe6150140
52
53 /* Fixed 32 KHz root clock from EXTALR pin */
54 static struct clk r_clk = {
55         .rate           = 32768,
56 };
57
58 /*
59  * 26MHz default rate for the EXTALC1 root input clock.
60  * If needed, reset this with clk_set_rate() from the platform code.
61  */
62 struct clk sh7377_extalc1_clk = {
63         .rate           = 26666666,
64 };
65
66 /*
67  * 48MHz default rate for the EXTAL2 root input clock.
68  * If needed, reset this with clk_set_rate() from the platform code.
69  */
70 struct clk sh7377_extal2_clk = {
71         .rate           = 48000000,
72 };
73
74 /* A fixed divide-by-2 block */
75 static unsigned long div2_recalc(struct clk *clk)
76 {
77         return clk->parent->rate / 2;
78 }
79
80 static struct clk_ops div2_clk_ops = {
81         .recalc         = div2_recalc,
82 };
83
84 /* Divide extalc1 by two */
85 static struct clk extalc1_div2_clk = {
86         .ops            = &div2_clk_ops,
87         .parent         = &sh7377_extalc1_clk,
88 };
89
90 /* Divide extal2 by two */
91 static struct clk extal2_div2_clk = {
92         .ops            = &div2_clk_ops,
93         .parent         = &sh7377_extal2_clk,
94 };
95
96 /* Divide extal2 by four */
97 static struct clk extal2_div4_clk = {
98         .ops            = &div2_clk_ops,
99         .parent         = &extal2_div2_clk,
100 };
101
102 /* PLLC1 */
103 static unsigned long pllc1_recalc(struct clk *clk)
104 {
105         unsigned long mult = 1;
106
107         if (__raw_readl(PLLC1CR) & (1 << 14))
108                 mult = (((__raw_readl(RTFRQCR) >> 24) & 0x3f) + 1) * 2;
109
110         return clk->parent->rate * mult;
111 }
112
113 static struct clk_ops pllc1_clk_ops = {
114         .recalc         = pllc1_recalc,
115 };
116
117 static struct clk pllc1_clk = {
118         .ops            = &pllc1_clk_ops,
119         .flags          = CLK_ENABLE_ON_INIT,
120         .parent         = &extalc1_div2_clk,
121 };
122
123 /* Divide PLLC1 by two */
124 static struct clk pllc1_div2_clk = {
125         .ops            = &div2_clk_ops,
126         .parent         = &pllc1_clk,
127 };
128
129 /* PLLC2 */
130 static unsigned long pllc2_recalc(struct clk *clk)
131 {
132         unsigned long mult = 1;
133
134         if (__raw_readl(PLLC2CR) & (1 << 31))
135                 mult = (((__raw_readl(PLLC2CR) >> 24) & 0x3f) + 1) * 2;
136
137         return clk->parent->rate * mult;
138 }
139
140 static struct clk_ops pllc2_clk_ops = {
141         .recalc         = pllc2_recalc,
142 };
143
144 static struct clk pllc2_clk = {
145         .ops            = &pllc2_clk_ops,
146         .flags          = CLK_ENABLE_ON_INIT,
147         .parent         = &extalc1_div2_clk,
148 };
149
150 static struct clk *main_clks[] = {
151         &r_clk,
152         &sh7377_extalc1_clk,
153         &sh7377_extal2_clk,
154         &extalc1_div2_clk,
155         &extal2_div2_clk,
156         &extal2_div4_clk,
157         &pllc1_clk,
158         &pllc1_div2_clk,
159         &pllc2_clk,
160 };
161
162 static void div4_kick(struct clk *clk)
163 {
164         unsigned long value;
165
166         /* set KICK bit in SYFRQCR to update hardware setting */
167         value = __raw_readl(SYFRQCR);
168         value |= (1 << 31);
169         __raw_writel(value, SYFRQCR);
170 }
171
172 static int divisors[] = { 2, 3, 4, 6, 8, 12, 16, 18,
173                           24, 32, 36, 48, 0, 72, 96, 0 };
174
175 static struct clk_div_mult_table div4_div_mult_table = {
176         .divisors = divisors,
177         .nr_divisors = ARRAY_SIZE(divisors),
178 };
179
180 static struct clk_div4_table div4_table = {
181         .div_mult_table = &div4_div_mult_table,
182         .kick = div4_kick,
183 };
184
185 enum { DIV4_I, DIV4_ZG, DIV4_B, DIV4_M1, DIV4_CSIR,
186        DIV4_ZTR, DIV4_ZT, DIV4_Z, DIV4_HP,
187        DIV4_ZS, DIV4_ZB, DIV4_ZB3, DIV4_CP, DIV4_NR };
188
189 #define DIV4(_reg, _bit, _mask, _flags) \
190   SH_CLK_DIV4(&pllc1_clk, _reg, _bit, _mask, _flags)
191
192 static struct clk div4_clks[DIV4_NR] = {
193         [DIV4_I] = DIV4(RTFRQCR, 20, 0x6fff, CLK_ENABLE_ON_INIT),
194         [DIV4_ZG] = DIV4(RTFRQCR, 16, 0x6fff, CLK_ENABLE_ON_INIT),
195         [DIV4_B] = DIV4(RTFRQCR, 8, 0x6fff, CLK_ENABLE_ON_INIT),
196         [DIV4_M1] = DIV4(RTFRQCR, 4, 0x6fff, CLK_ENABLE_ON_INIT),
197         [DIV4_CSIR] = DIV4(RTFRQCR, 0, 0x6fff, 0),
198         [DIV4_ZTR] = DIV4(SYFRQCR, 20, 0x6fff, 0),
199         [DIV4_ZT] = DIV4(SYFRQCR, 16, 0x6fff, 0),
200         [DIV4_Z] = DIV4(SYFRQCR, 12, 0x6fff, 0),
201         [DIV4_HP] = DIV4(SYFRQCR, 4, 0x6fff, 0),
202         [DIV4_ZS] = DIV4(CMFRQCR, 12, 0x6fff, 0),
203         [DIV4_ZB] = DIV4(CMFRQCR, 8, 0x6fff, 0),
204         [DIV4_ZB3] = DIV4(CMFRQCR, 4, 0x6fff, 0),
205         [DIV4_CP] = DIV4(CMFRQCR, 0, 0x6fff, 0),
206 };
207
208 enum { DIV6_VCK1, DIV6_VCK2, DIV6_VCK3, DIV6_FMSI, DIV6_FMSO,
209        DIV6_FSI, DIV6_SUB, DIV6_SPU, DIV6_MSU, DIV6_MVI3, DIV6_HDMI,
210        DIV6_MF1, DIV6_MF2, DIV6_DSIT, DIV6_DSIP,
211        DIV6_NR };
212
213 static struct clk div6_clks[] = {
214         [DIV6_VCK1] = SH_CLK_DIV6(&pllc1_div2_clk, VCLKCR1, 0),
215         [DIV6_VCK2] = SH_CLK_DIV6(&pllc1_div2_clk, VCLKCR2, 0),
216         [DIV6_VCK3] = SH_CLK_DIV6(&pllc1_div2_clk, VCLKCR3, 0),
217         [DIV6_FMSI] = SH_CLK_DIV6(&pllc1_div2_clk, FMSICKCR, 0),
218         [DIV6_FMSO] = SH_CLK_DIV6(&pllc1_div2_clk, FMSOCKCR, 0),
219         [DIV6_FSI] = SH_CLK_DIV6(&pllc1_div2_clk, FSICKCR, 0),
220         [DIV6_SUB] = SH_CLK_DIV6(&sh7377_extal2_clk, SUBUSBCKCR, 0),
221         [DIV6_SPU] = SH_CLK_DIV6(&pllc1_div2_clk, SPUCKCR, 0),
222         [DIV6_MSU] = SH_CLK_DIV6(&pllc1_div2_clk, MSUCKCR, 0),
223         [DIV6_MVI3] = SH_CLK_DIV6(&pllc1_div2_clk, MVI3CKCR, 0),
224         [DIV6_HDMI] = SH_CLK_DIV6(&pllc1_div2_clk, HDMICKCR, 0),
225         [DIV6_MF1] = SH_CLK_DIV6(&pllc1_div2_clk, MFCK1CR, 0),
226         [DIV6_MF2] = SH_CLK_DIV6(&pllc1_div2_clk, MFCK2CR, 0),
227         [DIV6_DSIT] = SH_CLK_DIV6(&pllc1_div2_clk, DSITCKCR, 0),
228         [DIV6_DSIP] = SH_CLK_DIV6(&pllc1_div2_clk, DSIPCKCR, 0),
229 };
230
231 enum { MSTP001,
232        MSTP131, MSTP130, MSTP129, MSTP128, MSTP116, MSTP106, MSTP101,
233        MSTP223, MSTP207, MSTP206, MSTP204, MSTP203, MSTP202, MSTP201, MSTP200,
234        MSTP331, MSTP329, MSTP325, MSTP323, MSTP322,
235        MSTP315, MSTP314, MSTP313,
236        MSTP403,
237        MSTP_NR };
238
239 #define MSTP(_parent, _reg, _bit, _flags) \
240   SH_CLK_MSTP32(_parent, _reg, _bit, _flags)
241
242 static struct clk mstp_clks[] = {
243         [MSTP001] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR0, 1, 0), /* IIC2 */
244         [MSTP131] = MSTP(&div4_clks[DIV4_B], SMSTPCR1, 31, 0), /* VEU3 */
245         [MSTP130] = MSTP(&div4_clks[DIV4_B], SMSTPCR1, 30, 0), /* VEU2 */
246         [MSTP129] = MSTP(&div4_clks[DIV4_B], SMSTPCR1, 29, 0), /* VEU1 */
247         [MSTP128] = MSTP(&div4_clks[DIV4_B], SMSTPCR1, 28, 0), /* VEU0 */
248         [MSTP116] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR1, 16, 0), /* IIC0 */
249         [MSTP106] = MSTP(&div4_clks[DIV4_B], SMSTPCR1, 6, 0), /* JPU */
250         [MSTP101] = MSTP(&div4_clks[DIV4_M1], SMSTPCR1, 1, 0), /* VPU */
251         [MSTP223] = MSTP(&div6_clks[DIV6_SPU], SMSTPCR2, 23, 0), /* SPU2 */
252         [MSTP207] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR2, 7, 0), /* SCIFA5 */
253         [MSTP206] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR2, 6, 0), /* SCIFB */
254         [MSTP204] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR2, 4, 0), /* SCIFA0 */
255         [MSTP203] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR2, 3, 0), /* SCIFA1 */
256         [MSTP202] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR2, 2, 0), /* SCIFA2 */
257         [MSTP201] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR2, 1, 0), /* SCIFA3 */
258         [MSTP200] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR2, 0, 0), /* SCIFA4 */
259         [MSTP331] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR3, 31, 0), /* SCIFA6 */
260         [MSTP329] = MSTP(&r_clk, SMSTPCR3, 29, 0), /* CMT10 */
261         [MSTP325] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR3, 25, 0), /* IRDA */
262         [MSTP323] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR3, 23, 0), /* IIC1 */
263         [MSTP322] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR3, 22, 0), /* USB0 */
264         [MSTP315] = MSTP(&div4_clks[DIV4_HP], SMSTPCR3, 15, 0), /* FLCTL */
265         [MSTP314] = MSTP(&div4_clks[DIV4_HP], SMSTPCR3, 14, 0), /* SDHI0 */
266         [MSTP313] = MSTP(&div4_clks[DIV4_HP], SMSTPCR3, 13, 0), /* SDHI1 */
267         [MSTP403] = MSTP(&r_clk, SMSTPCR4, 3, 0), /* KEYSC */
268 };
269
270 #define CLKDEV_CON_ID(_id, _clk) { .con_id = _id, .clk = _clk }
271 #define CLKDEV_DEV_ID(_id, _clk) { .dev_id = _id, .clk = _clk }
272
273 static struct clk_lookup lookups[] = {
274         /* main clocks */
275         CLKDEV_CON_ID("r_clk", &r_clk),
276         CLKDEV_CON_ID("extalc1", &sh7377_extalc1_clk),
277         CLKDEV_CON_ID("extal2", &sh7377_extal2_clk),
278         CLKDEV_CON_ID("extalc1_div2_clk", &extalc1_div2_clk),
279         CLKDEV_CON_ID("extal2_div2_clk", &extal2_div2_clk),
280         CLKDEV_CON_ID("extal2_div4_clk", &extal2_div4_clk),
281         CLKDEV_CON_ID("pllc1_clk", &pllc1_clk),
282         CLKDEV_CON_ID("pllc1_div2_clk", &pllc1_div2_clk),
283         CLKDEV_CON_ID("pllc2_clk", &pllc2_clk),
284
285         /* DIV4 clocks */
286         CLKDEV_CON_ID("i_clk", &div4_clks[DIV4_I]),
287         CLKDEV_CON_ID("zg_clk", &div4_clks[DIV4_ZG]),
288         CLKDEV_CON_ID("b_clk", &div4_clks[DIV4_B]),
289         CLKDEV_CON_ID("m1_clk", &div4_clks[DIV4_M1]),
290         CLKDEV_CON_ID("csir_clk", &div4_clks[DIV4_CSIR]),
291         CLKDEV_CON_ID("ztr_clk", &div4_clks[DIV4_ZTR]),
292         CLKDEV_CON_ID("zt_clk", &div4_clks[DIV4_ZT]),
293         CLKDEV_CON_ID("z_clk", &div4_clks[DIV4_Z]),
294         CLKDEV_CON_ID("hp_clk", &div4_clks[DIV4_HP]),
295         CLKDEV_CON_ID("zs_clk", &div4_clks[DIV4_ZS]),
296         CLKDEV_CON_ID("zb_clk", &div4_clks[DIV4_ZB]),
297         CLKDEV_CON_ID("zb3_clk", &div4_clks[DIV4_ZB3]),
298         CLKDEV_CON_ID("cp_clk", &div4_clks[DIV4_CP]),
299
300         /* DIV6 clocks */
301         CLKDEV_CON_ID("vck1_clk", &div6_clks[DIV6_VCK1]),
302         CLKDEV_CON_ID("vck2_clk", &div6_clks[DIV6_VCK2]),
303         CLKDEV_CON_ID("vck3_clk", &div6_clks[DIV6_VCK3]),
304         CLKDEV_CON_ID("fmsi_clk", &div6_clks[DIV6_FMSI]),
305         CLKDEV_CON_ID("fmso_clk", &div6_clks[DIV6_FMSO]),
306         CLKDEV_CON_ID("fsi_clk", &div6_clks[DIV6_FSI]),
307         CLKDEV_CON_ID("sub_clk", &div6_clks[DIV6_SUB]),
308         CLKDEV_CON_ID("spu_clk", &div6_clks[DIV6_SPU]),
309         CLKDEV_CON_ID("msu_clk", &div6_clks[DIV6_MSU]),
310         CLKDEV_CON_ID("mvi3_clk", &div6_clks[DIV6_MVI3]),
311         CLKDEV_CON_ID("hdmi_clk", &div6_clks[DIV6_HDMI]),
312         CLKDEV_CON_ID("mf1_clk", &div6_clks[DIV6_MF1]),
313         CLKDEV_CON_ID("mf2_clk", &div6_clks[DIV6_MF2]),
314         CLKDEV_CON_ID("dsit_clk", &div6_clks[DIV6_DSIT]),
315         CLKDEV_CON_ID("dsip_clk", &div6_clks[DIV6_DSIP]),
316
317         /* MSTP32 clocks */
318         CLKDEV_DEV_ID("i2c-sh_mobile.2", &mstp_clks[MSTP001]), /* IIC2 */
319         CLKDEV_DEV_ID("uio_pdrv_genirq.4", &mstp_clks[MSTP131]), /* VEU3 */
320         CLKDEV_DEV_ID("uio_pdrv_genirq.3", &mstp_clks[MSTP130]), /* VEU2 */
321         CLKDEV_DEV_ID("uio_pdrv_genirq.2", &mstp_clks[MSTP129]), /* VEU1 */
322         CLKDEV_DEV_ID("uio_pdrv_genirq.1", &mstp_clks[MSTP128]), /* VEU0 */
323         CLKDEV_DEV_ID("i2c-sh_mobile.0", &mstp_clks[MSTP116]), /* IIC0 */
324         CLKDEV_DEV_ID("uio_pdrv_genirq.5", &mstp_clks[MSTP106]), /* JPU */
325         CLKDEV_DEV_ID("uio_pdrv_genirq.0", &mstp_clks[MSTP101]), /* VPU */
326         CLKDEV_DEV_ID("uio_pdrv_genirq.6", &mstp_clks[MSTP223]), /* SPU2DSP0 */
327         CLKDEV_DEV_ID("uio_pdrv_genirq.7", &mstp_clks[MSTP223]), /* SPU2DSP1 */
328         CLKDEV_DEV_ID("sh-sci.5", &mstp_clks[MSTP207]), /* SCIFA5 */
329         CLKDEV_DEV_ID("sh-sci.7", &mstp_clks[MSTP206]), /* SCIFB */
330         CLKDEV_DEV_ID("sh-sci.0", &mstp_clks[MSTP204]), /* SCIFA0 */
331         CLKDEV_DEV_ID("sh-sci.1", &mstp_clks[MSTP203]), /* SCIFA1 */
332         CLKDEV_DEV_ID("sh-sci.2", &mstp_clks[MSTP202]), /* SCIFA2 */
333         CLKDEV_DEV_ID("sh-sci.3", &mstp_clks[MSTP201]), /* SCIFA3 */
334         CLKDEV_DEV_ID("sh-sci.4", &mstp_clks[MSTP200]), /* SCIFA4 */
335         CLKDEV_DEV_ID("sh-sci.6", &mstp_clks[MSTP331]), /* SCIFA6 */
336         CLKDEV_DEV_ID("sh_cmt.10", &mstp_clks[MSTP329]), /* CMT10 */
337         CLKDEV_DEV_ID("sh_irda", &mstp_clks[MSTP325]), /* IRDA */
338         CLKDEV_DEV_ID("i2c-sh_mobile.1", &mstp_clks[MSTP323]), /* IIC1 */
339         CLKDEV_DEV_ID("r8a66597_hcd.0", &mstp_clks[MSTP322]), /* USBHS */
340         CLKDEV_DEV_ID("r8a66597_udc.0", &mstp_clks[MSTP322]), /* USBHS */
341         CLKDEV_DEV_ID("sh_flctl", &mstp_clks[MSTP315]), /* FLCTL */
342         CLKDEV_DEV_ID("sh_mobile_sdhi.0", &mstp_clks[MSTP314]), /* SDHI0 */
343         CLKDEV_DEV_ID("sh_mobile_sdhi.1", &mstp_clks[MSTP313]), /* SDHI1 */
344         CLKDEV_DEV_ID("sh_keysc.0", &mstp_clks[MSTP403]), /* KEYSC */
345 };
346
347 void __init sh7377_clock_init(void)
348 {
349         int k, ret = 0;
350
351         for (k = 0; !ret && (k < ARRAY_SIZE(main_clks)); k++)
352                 ret = clk_register(main_clks[k]);
353
354         if (!ret)
355                 ret = sh_clk_div4_register(div4_clks, DIV4_NR, &div4_table);
356
357         if (!ret)
358                 ret = sh_clk_div6_register(div6_clks, DIV6_NR);
359
360         if (!ret)
361                 ret = sh_clk_mstp32_register(mstp_clks, MSTP_NR);
362
363         clkdev_add_table(lookups, ARRAY_SIZE(lookups));
364
365         if (!ret)
366                 clk_init();
367         else
368                 panic("failed to setup sh7377 clocks\n");
369 }