Merge remote branch 'nouveau/drm-nouveau-next' of /ssd/git/drm-nouveau-next into...
[pandora-kernel.git] / arch / arm / mach-shmobile / clock-sh7367.c
1 /*
2  * SH7367 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; 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., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  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 /* SH7367 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 SCLKACR    0xe6150010
34 #define SCLKBCR    0xe6150014
35 #define SUBUSBCKCR 0xe6158080
36 #define SPUCKCR    0xe6150084
37 #define MSUCKCR    0xe6150088
38 #define MVI3CKCR   0xe6150090
39 #define VOUCKCR    0xe6150094
40 #define MFCK1CR    0xe6150098
41 #define MFCK2CR    0xe615009C
42 #define PLLC1CR    0xe6150028
43 #define PLLC2CR    0xe615002C
44 #define RTMSTPCR0  0xe6158030
45 #define RTMSTPCR2  0xe6158038
46 #define SYMSTPCR0  0xe6158040
47 #define SYMSTPCR2  0xe6158048
48 #define CMMSTPCR0  0xe615804c
49
50 /* Fixed 32 KHz root clock from EXTALR pin */
51 static struct clk r_clk = {
52         .rate           = 32768,
53 };
54
55 /*
56  * 26MHz default rate for the EXTALB1 root input clock.
57  * If needed, reset this with clk_set_rate() from the platform code.
58  */
59 struct clk sh7367_extalb1_clk = {
60         .rate           = 26666666,
61 };
62
63 /*
64  * 48MHz default rate for the EXTAL2 root input clock.
65  * If needed, reset this with clk_set_rate() from the platform code.
66  */
67 struct clk sh7367_extal2_clk = {
68         .rate           = 48000000,
69 };
70
71 /* A fixed divide-by-2 block */
72 static unsigned long div2_recalc(struct clk *clk)
73 {
74         return clk->parent->rate / 2;
75 }
76
77 static struct clk_ops div2_clk_ops = {
78         .recalc         = div2_recalc,
79 };
80
81 /* Divide extalb1 by two */
82 static struct clk extalb1_div2_clk = {
83         .ops            = &div2_clk_ops,
84         .parent         = &sh7367_extalb1_clk,
85 };
86
87 /* Divide extal2 by two */
88 static struct clk extal2_div2_clk = {
89         .ops            = &div2_clk_ops,
90         .parent         = &sh7367_extal2_clk,
91 };
92
93 /* PLLC1 */
94 static unsigned long pllc1_recalc(struct clk *clk)
95 {
96         unsigned long mult = 1;
97
98         if (__raw_readl(PLLC1CR) & (1 << 14))
99                 mult = (((__raw_readl(RTFRQCR) >> 24) & 0x3f) + 1) * 2;
100
101         return clk->parent->rate * mult;
102 }
103
104 static struct clk_ops pllc1_clk_ops = {
105         .recalc         = pllc1_recalc,
106 };
107
108 static struct clk pllc1_clk = {
109         .ops            = &pllc1_clk_ops,
110         .flags          = CLK_ENABLE_ON_INIT,
111         .parent         = &extalb1_div2_clk,
112 };
113
114 /* Divide PLLC1 by two */
115 static struct clk pllc1_div2_clk = {
116         .ops            = &div2_clk_ops,
117         .parent         = &pllc1_clk,
118 };
119
120 /* PLLC2 */
121 static unsigned long pllc2_recalc(struct clk *clk)
122 {
123         unsigned long mult = 1;
124
125         if (__raw_readl(PLLC2CR) & (1 << 31))
126                 mult = (((__raw_readl(PLLC2CR) >> 24) & 0x3f) + 1) * 2;
127
128         return clk->parent->rate * mult;
129 }
130
131 static struct clk_ops pllc2_clk_ops = {
132         .recalc         = pllc2_recalc,
133 };
134
135 static struct clk pllc2_clk = {
136         .ops            = &pllc2_clk_ops,
137         .flags          = CLK_ENABLE_ON_INIT,
138         .parent         = &extalb1_div2_clk,
139 };
140
141 static struct clk *main_clks[] = {
142         &r_clk,
143         &sh7367_extalb1_clk,
144         &sh7367_extal2_clk,
145         &extalb1_div2_clk,
146         &extal2_div2_clk,
147         &pllc1_clk,
148         &pllc1_div2_clk,
149         &pllc2_clk,
150 };
151
152 static void div4_kick(struct clk *clk)
153 {
154         unsigned long value;
155
156         /* set KICK bit in SYFRQCR to update hardware setting */
157         value = __raw_readl(SYFRQCR);
158         value |= (1 << 31);
159         __raw_writel(value, SYFRQCR);
160 }
161
162 static int divisors[] = { 2, 3, 4, 6, 8, 12, 16, 18,
163                           24, 32, 36, 48, 0, 72, 0, 0 };
164
165 static struct clk_div_mult_table div4_div_mult_table = {
166         .divisors = divisors,
167         .nr_divisors = ARRAY_SIZE(divisors),
168 };
169
170 static struct clk_div4_table div4_table = {
171         .div_mult_table = &div4_div_mult_table,
172         .kick = div4_kick,
173 };
174
175 enum { DIV4_I, DIV4_G, DIV4_S, DIV4_B,
176        DIV4_ZX, DIV4_ZT, DIV4_Z, DIV4_ZD, DIV4_HP,
177        DIV4_ZS, DIV4_ZB, DIV4_ZB3, DIV4_CP, DIV4_NR };
178
179 #define DIV4(_reg, _bit, _mask, _flags) \
180   SH_CLK_DIV4(&pllc1_clk, _reg, _bit, _mask, _flags)
181
182 static struct clk div4_clks[DIV4_NR] = {
183         [DIV4_I] = DIV4(RTFRQCR, 20, 0x6fff, CLK_ENABLE_ON_INIT),
184         [DIV4_G] = DIV4(RTFRQCR, 16, 0x6fff, CLK_ENABLE_ON_INIT),
185         [DIV4_S] = DIV4(RTFRQCR, 12, 0x6fff, CLK_ENABLE_ON_INIT),
186         [DIV4_B] = DIV4(RTFRQCR, 8, 0x6fff, CLK_ENABLE_ON_INIT),
187         [DIV4_ZX] = DIV4(SYFRQCR, 20, 0x6fff, 0),
188         [DIV4_ZT] = DIV4(SYFRQCR, 16, 0x6fff, 0),
189         [DIV4_Z] = DIV4(SYFRQCR, 12, 0x6fff, 0),
190         [DIV4_ZD] = DIV4(SYFRQCR, 8, 0x6fff, 0),
191         [DIV4_HP] = DIV4(SYFRQCR, 4, 0x6fff, 0),
192         [DIV4_ZS] = DIV4(CMFRQCR, 12, 0x6fff, 0),
193         [DIV4_ZB] = DIV4(CMFRQCR, 8, 0x6fff, 0),
194         [DIV4_ZB3] = DIV4(CMFRQCR, 4, 0x6fff, 0),
195         [DIV4_CP] = DIV4(CMFRQCR, 0, 0x6fff, 0),
196 };
197
198 enum { DIV6_SUB, DIV6_SIUA, DIV6_SIUB, DIV6_MSU, DIV6_SPU,
199        DIV6_MVI3, DIV6_MF1, DIV6_MF2,
200        DIV6_VCK1, DIV6_VCK2, DIV6_VCK3, DIV6_VOU,
201        DIV6_NR };
202
203 static struct clk div6_clks[DIV6_NR] = {
204         [DIV6_SUB] = SH_CLK_DIV6(&sh7367_extal2_clk, SUBUSBCKCR, 0),
205         [DIV6_SIUA] = SH_CLK_DIV6(&pllc1_div2_clk, SCLKACR, 0),
206         [DIV6_SIUB] = SH_CLK_DIV6(&pllc1_div2_clk, SCLKBCR, 0),
207         [DIV6_MSU] = SH_CLK_DIV6(&pllc1_div2_clk, MSUCKCR, 0),
208         [DIV6_SPU] = SH_CLK_DIV6(&pllc1_div2_clk, SPUCKCR, 0),
209         [DIV6_MVI3] = SH_CLK_DIV6(&pllc1_div2_clk, MVI3CKCR, 0),
210         [DIV6_MF1] = SH_CLK_DIV6(&pllc1_div2_clk, MFCK1CR, 0),
211         [DIV6_MF2] = SH_CLK_DIV6(&pllc1_div2_clk, MFCK2CR, 0),
212         [DIV6_VCK1] = SH_CLK_DIV6(&pllc1_div2_clk, VCLKCR1, 0),
213         [DIV6_VCK2] = SH_CLK_DIV6(&pllc1_div2_clk, VCLKCR2, 0),
214         [DIV6_VCK3] = SH_CLK_DIV6(&pllc1_div2_clk, VCLKCR3, 0),
215         [DIV6_VOU] = SH_CLK_DIV6(&pllc1_div2_clk, VOUCKCR, 0),
216 };
217
218 enum { RTMSTP001,
219        RTMSTP231, RTMSTP230, RTMSTP229, RTMSTP228, RTMSTP226,
220        RTMSTP216, RTMSTP206, RTMSTP205, RTMSTP201,
221        SYMSTP023, SYMSTP007, SYMSTP006, SYMSTP004,
222        SYMSTP003, SYMSTP002, SYMSTP001, SYMSTP000,
223        SYMSTP231, SYMSTP229, SYMSTP225, SYMSTP223, SYMSTP222,
224        SYMSTP215, SYMSTP214, SYMSTP213, SYMSTP211,
225        CMMSTP003,
226        MSTP_NR };
227
228 #define MSTP(_parent, _reg, _bit, _flags) \
229   SH_CLK_MSTP32(_parent, _reg, _bit, _flags)
230
231 static struct clk mstp_clks[MSTP_NR] = {
232         [RTMSTP001] = MSTP(&div6_clks[DIV6_SUB], RTMSTPCR0, 1, 0), /* IIC2 */
233         [RTMSTP231] = MSTP(&div4_clks[DIV4_B], RTMSTPCR2, 31, 0), /* VEU3 */
234         [RTMSTP230] = MSTP(&div4_clks[DIV4_B], RTMSTPCR2, 30, 0), /* VEU2 */
235         [RTMSTP229] = MSTP(&div4_clks[DIV4_B], RTMSTPCR2, 29, 0), /* VEU1 */
236         [RTMSTP228] = MSTP(&div4_clks[DIV4_B], RTMSTPCR2, 28, 0), /* VEU0 */
237         [RTMSTP226] = MSTP(&div4_clks[DIV4_B], RTMSTPCR2, 26, 0), /* VEU2H */
238         [RTMSTP216] = MSTP(&div6_clks[DIV6_SUB], RTMSTPCR2, 16, 0), /* IIC0 */
239         [RTMSTP206] = MSTP(&div4_clks[DIV4_B], RTMSTPCR2, 6, 0), /* JPU */
240         [RTMSTP205] = MSTP(&div6_clks[DIV6_VOU], RTMSTPCR2, 5, 0), /* VOU */
241         [RTMSTP201] = MSTP(&div4_clks[DIV4_B], RTMSTPCR2, 1, 0), /* VPU */
242         [SYMSTP023] = MSTP(&div6_clks[DIV6_SPU], SYMSTPCR0, 23, 0), /* SPU1 */
243         [SYMSTP007] = MSTP(&div6_clks[DIV6_SUB], SYMSTPCR0, 7, 0), /* SCIFA5 */
244         [SYMSTP006] = MSTP(&div6_clks[DIV6_SUB], SYMSTPCR0, 6, 0), /* SCIFB */
245         [SYMSTP004] = MSTP(&div6_clks[DIV6_SUB], SYMSTPCR0, 4, 0), /* SCIFA0 */
246         [SYMSTP003] = MSTP(&div6_clks[DIV6_SUB], SYMSTPCR0, 3, 0), /* SCIFA1 */
247         [SYMSTP002] = MSTP(&div6_clks[DIV6_SUB], SYMSTPCR0, 2, 0), /* SCIFA2 */
248         [SYMSTP001] = MSTP(&div6_clks[DIV6_SUB], SYMSTPCR0, 1, 0), /* SCIFA3 */
249         [SYMSTP000] = MSTP(&div6_clks[DIV6_SUB], SYMSTPCR0, 0, 0), /* SCIFA4 */
250         [SYMSTP231] = MSTP(&div6_clks[DIV6_SUB], SYMSTPCR2, 31, 0), /* SIU */
251         [SYMSTP229] = MSTP(&r_clk, SYMSTPCR2, 29, 0), /* CMT10 */
252         [SYMSTP225] = MSTP(&div6_clks[DIV6_SUB], SYMSTPCR2, 25, 0), /* IRDA */
253         [SYMSTP223] = MSTP(&div6_clks[DIV6_SUB], SYMSTPCR2, 23, 0), /* IIC1 */
254         [SYMSTP222] = MSTP(&div6_clks[DIV6_SUB], SYMSTPCR2, 22, 0), /* USBHS */
255         [SYMSTP215] = MSTP(&div4_clks[DIV4_HP], SYMSTPCR2, 15, 0), /* FLCTL */
256         [SYMSTP214] = MSTP(&div4_clks[DIV4_HP], SYMSTPCR2, 14, 0), /* SDHI0 */
257         [SYMSTP213] = MSTP(&div4_clks[DIV4_HP], SYMSTPCR2, 13, 0), /* SDHI1 */
258         [SYMSTP211] = MSTP(&div4_clks[DIV4_HP], SYMSTPCR2, 11, 0), /* SDHI2 */
259         [CMMSTP003] = MSTP(&r_clk, CMMSTPCR0, 3, 0), /* KEYSC */
260 };
261
262 #define CLKDEV_CON_ID(_id, _clk) { .con_id = _id, .clk = _clk }
263 #define CLKDEV_DEV_ID(_id, _clk) { .dev_id = _id, .clk = _clk }
264
265 static struct clk_lookup lookups[] = {
266         /* main clocks */
267         CLKDEV_CON_ID("r_clk", &r_clk),
268         CLKDEV_CON_ID("extalb1", &sh7367_extalb1_clk),
269         CLKDEV_CON_ID("extal2", &sh7367_extal2_clk),
270         CLKDEV_CON_ID("extalb1_div2_clk", &extalb1_div2_clk),
271         CLKDEV_CON_ID("extal2_div2_clk", &extal2_div2_clk),
272         CLKDEV_CON_ID("pllc1_clk", &pllc1_clk),
273         CLKDEV_CON_ID("pllc1_div2_clk", &pllc1_div2_clk),
274         CLKDEV_CON_ID("pllc2_clk", &pllc2_clk),
275
276         /* DIV4 clocks */
277         CLKDEV_CON_ID("i_clk", &div4_clks[DIV4_I]),
278         CLKDEV_CON_ID("g_clk", &div4_clks[DIV4_G]),
279         CLKDEV_CON_ID("b_clk", &div4_clks[DIV4_B]),
280         CLKDEV_CON_ID("zx_clk", &div4_clks[DIV4_ZX]),
281         CLKDEV_CON_ID("zt_clk", &div4_clks[DIV4_ZT]),
282         CLKDEV_CON_ID("z_clk", &div4_clks[DIV4_Z]),
283         CLKDEV_CON_ID("zd_clk", &div4_clks[DIV4_ZD]),
284         CLKDEV_CON_ID("hp_clk", &div4_clks[DIV4_HP]),
285         CLKDEV_CON_ID("zs_clk", &div4_clks[DIV4_ZS]),
286         CLKDEV_CON_ID("zb_clk", &div4_clks[DIV4_ZB]),
287         CLKDEV_CON_ID("zb3_clk", &div4_clks[DIV4_ZB3]),
288         CLKDEV_CON_ID("cp_clk", &div4_clks[DIV4_CP]),
289
290         /* DIV6 clocks */
291         CLKDEV_CON_ID("sub_clk", &div6_clks[DIV6_SUB]),
292         CLKDEV_CON_ID("siua_clk", &div6_clks[DIV6_SIUA]),
293         CLKDEV_CON_ID("siub_clk", &div6_clks[DIV6_SIUB]),
294         CLKDEV_CON_ID("msu_clk", &div6_clks[DIV6_MSU]),
295         CLKDEV_CON_ID("spu_clk", &div6_clks[DIV6_SPU]),
296         CLKDEV_CON_ID("mvi3_clk", &div6_clks[DIV6_MVI3]),
297         CLKDEV_CON_ID("mf1_clk", &div6_clks[DIV6_MF1]),
298         CLKDEV_CON_ID("mf2_clk", &div6_clks[DIV6_MF2]),
299         CLKDEV_CON_ID("vck1_clk", &div6_clks[DIV6_VCK1]),
300         CLKDEV_CON_ID("vck2_clk", &div6_clks[DIV6_VCK2]),
301         CLKDEV_CON_ID("vck3_clk", &div6_clks[DIV6_VCK3]),
302         CLKDEV_CON_ID("vou_clk", &div6_clks[DIV6_VOU]),
303
304         /* MSTP32 clocks */
305         CLKDEV_DEV_ID("i2c-sh_mobile.2", &mstp_clks[RTMSTP001]), /* IIC2 */
306         CLKDEV_DEV_ID("uio_pdrv_genirq.4", &mstp_clks[RTMSTP231]), /* VEU3 */
307         CLKDEV_DEV_ID("uio_pdrv_genirq.3", &mstp_clks[RTMSTP230]), /* VEU2 */
308         CLKDEV_DEV_ID("uio_pdrv_genirq.2", &mstp_clks[RTMSTP229]), /* VEU1 */
309         CLKDEV_DEV_ID("uio_pdrv_genirq.1", &mstp_clks[RTMSTP228]), /* VEU0 */
310         CLKDEV_DEV_ID("uio_pdrv_genirq.5", &mstp_clks[RTMSTP226]), /* VEU2H */
311         CLKDEV_DEV_ID("i2c-sh_mobile.0", &mstp_clks[RTMSTP216]), /* IIC0 */
312         CLKDEV_DEV_ID("uio_pdrv_genirq.6", &mstp_clks[RTMSTP206]), /* JPU */
313         CLKDEV_DEV_ID("sh-vou", &mstp_clks[RTMSTP205]), /* VOU */
314         CLKDEV_DEV_ID("uio_pdrv_genirq.0", &mstp_clks[RTMSTP201]), /* VPU */
315         CLKDEV_DEV_ID("uio_pdrv_genirq.7", &mstp_clks[SYMSTP023]), /* SPU1 */
316         CLKDEV_DEV_ID("sh-sci.5", &mstp_clks[SYMSTP007]), /* SCIFA5 */
317         CLKDEV_DEV_ID("sh-sci.6", &mstp_clks[SYMSTP006]), /* SCIFB */
318         CLKDEV_DEV_ID("sh-sci.0", &mstp_clks[SYMSTP004]), /* SCIFA0 */
319         CLKDEV_DEV_ID("sh-sci.1", &mstp_clks[SYMSTP003]), /* SCIFA1 */
320         CLKDEV_DEV_ID("sh-sci.2", &mstp_clks[SYMSTP002]), /* SCIFA2 */
321         CLKDEV_DEV_ID("sh-sci.3", &mstp_clks[SYMSTP001]), /* SCIFA3 */
322         CLKDEV_DEV_ID("sh-sci.4", &mstp_clks[SYMSTP000]), /* SCIFA4 */
323         CLKDEV_DEV_ID("sh_siu", &mstp_clks[SYMSTP231]), /* SIU */
324         CLKDEV_DEV_ID("sh_cmt.10", &mstp_clks[SYMSTP229]), /* CMT10 */
325         CLKDEV_DEV_ID("sh_irda", &mstp_clks[SYMSTP225]), /* IRDA */
326         CLKDEV_DEV_ID("i2c-sh_mobile.1", &mstp_clks[SYMSTP223]), /* IIC1 */
327         CLKDEV_DEV_ID("r8a66597_hcd.0", &mstp_clks[SYMSTP222]), /* USBHS */
328         CLKDEV_DEV_ID("r8a66597_udc.0", &mstp_clks[SYMSTP222]), /* USBHS */
329         CLKDEV_DEV_ID("sh_flctl", &mstp_clks[SYMSTP215]), /* FLCTL */
330         CLKDEV_DEV_ID("sh_mobile_sdhi.0", &mstp_clks[SYMSTP214]), /* SDHI0 */
331         CLKDEV_DEV_ID("sh_mobile_sdhi.1", &mstp_clks[SYMSTP213]), /* SDHI1 */
332         CLKDEV_DEV_ID("sh_mobile_sdhi.2", &mstp_clks[SYMSTP211]), /* SDHI2 */
333         CLKDEV_DEV_ID("sh_keysc.0", &mstp_clks[CMMSTP003]), /* KEYSC */
334 };
335
336 void __init sh7367_clock_init(void)
337 {
338         int k, ret = 0;
339
340         for (k = 0; !ret && (k < ARRAY_SIZE(main_clks)); k++)
341                 ret = clk_register(main_clks[k]);
342
343         if (!ret)
344                 ret = sh_clk_div4_register(div4_clks, DIV4_NR, &div4_table);
345
346         if (!ret)
347                 ret = sh_clk_div6_register(div6_clks, DIV6_NR);
348
349         if (!ret)
350                 ret = sh_clk_mstp32_register(mstp_clks, MSTP_NR);
351
352         clkdev_add_table(lookups, ARRAY_SIZE(lookups));
353
354         if (!ret)
355                 clk_init();
356         else
357                 panic("failed to setup sh7367 clocks\n");
358 }