Merge branch 'l2x0-pull-rmk' of git://dev.omapzoom.org/pub/scm/santosh/kernel-omap4...
[pandora-kernel.git] / arch / arm / mach-shmobile / clock-sh7372.c
1 /*
2  * SH7372 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 <mach/common.h>
24 #include <asm/clkdev.h>
25
26 /* SH7372 registers */
27 #define FRQCRA          0xe6150000
28 #define FRQCRB          0xe6150004
29 #define FRQCRC          0xe61500e0
30 #define FRQCRD          0xe61500e4
31 #define VCLKCR1         0xe6150008
32 #define VCLKCR2         0xe615000c
33 #define VCLKCR3         0xe615001c
34 #define FMSICKCR        0xe6150010
35 #define FMSOCKCR        0xe6150014
36 #define FSIACKCR        0xe6150018
37 #define FSIBCKCR        0xe6150090
38 #define SUBCKCR         0xe6150080
39 #define SPUCKCR         0xe6150084
40 #define VOUCKCR         0xe6150088
41 #define HDMICKCR        0xe6150094
42 #define DSITCKCR        0xe6150060
43 #define DSI0PCKCR       0xe6150064
44 #define DSI1PCKCR       0xe6150098
45 #define PLLC01CR        0xe6150028
46 #define PLLC2CR         0xe615002c
47 #define SMSTPCR0        0xe6150130
48 #define SMSTPCR1        0xe6150134
49 #define SMSTPCR2        0xe6150138
50 #define SMSTPCR3        0xe615013c
51 #define SMSTPCR4        0xe6150140
52
53 /* Platforms must set frequency on their DV_CLKI pin */
54 struct clk dv_clki_clk = {
55 };
56
57 /* Fixed 32 KHz root clock from EXTALR pin */
58 static struct clk r_clk = {
59         .rate           = 32768,
60 };
61
62 /*
63  * 26MHz default rate for the EXTAL1 root input clock.
64  * If needed, reset this with clk_set_rate() from the platform code.
65  */
66 struct clk sh7372_extal1_clk = {
67         .rate           = 26000000,
68 };
69
70 /*
71  * 48MHz default rate for the EXTAL2 root input clock.
72  * If needed, reset this with clk_set_rate() from the platform code.
73  */
74 struct clk sh7372_extal2_clk = {
75         .rate           = 48000000,
76 };
77
78 /* A fixed divide-by-2 block */
79 static unsigned long div2_recalc(struct clk *clk)
80 {
81         return clk->parent->rate / 2;
82 }
83
84 static struct clk_ops div2_clk_ops = {
85         .recalc         = div2_recalc,
86 };
87
88 /* Divide dv_clki by two */
89 struct clk dv_clki_div2_clk = {
90         .ops            = &div2_clk_ops,
91         .parent         = &dv_clki_clk,
92 };
93
94 /* Divide extal1 by two */
95 static struct clk extal1_div2_clk = {
96         .ops            = &div2_clk_ops,
97         .parent         = &sh7372_extal1_clk,
98 };
99
100 /* Divide extal2 by two */
101 static struct clk extal2_div2_clk = {
102         .ops            = &div2_clk_ops,
103         .parent         = &sh7372_extal2_clk,
104 };
105
106 /* Divide extal2 by four */
107 static struct clk extal2_div4_clk = {
108         .ops            = &div2_clk_ops,
109         .parent         = &extal2_div2_clk,
110 };
111
112 /* PLLC0 and PLLC1 */
113 static unsigned long pllc01_recalc(struct clk *clk)
114 {
115         unsigned long mult = 1;
116
117         if (__raw_readl(PLLC01CR) & (1 << 14))
118                 mult = (((__raw_readl(clk->enable_reg) >> 24) & 0x3f) + 1) * 2;
119
120         return clk->parent->rate * mult;
121 }
122
123 static struct clk_ops pllc01_clk_ops = {
124         .recalc         = pllc01_recalc,
125 };
126
127 static struct clk pllc0_clk = {
128         .ops            = &pllc01_clk_ops,
129         .flags          = CLK_ENABLE_ON_INIT,
130         .parent         = &extal1_div2_clk,
131         .enable_reg     = (void __iomem *)FRQCRC,
132 };
133
134 static struct clk pllc1_clk = {
135         .ops            = &pllc01_clk_ops,
136         .flags          = CLK_ENABLE_ON_INIT,
137         .parent         = &extal1_div2_clk,
138         .enable_reg     = (void __iomem *)FRQCRA,
139 };
140
141 /* Divide PLLC1 by two */
142 static struct clk pllc1_div2_clk = {
143         .ops            = &div2_clk_ops,
144         .parent         = &pllc1_clk,
145 };
146
147 /* PLLC2 */
148
149 /* Indices are important - they are the actual src selecting values */
150 static struct clk *pllc2_parent[] = {
151         [0] = &extal1_div2_clk,
152         [1] = &extal2_div2_clk,
153         [2] = &dv_clki_div2_clk,
154 };
155
156 /* Only multipliers 20 * 2 to 46 * 2 are valid, last entry for CPUFREQ_TABLE_END */
157 static struct cpufreq_frequency_table pllc2_freq_table[29];
158
159 static void pllc2_table_rebuild(struct clk *clk)
160 {
161         int i;
162
163         /* Initialise PLLC2 frequency table */
164         for (i = 0; i < ARRAY_SIZE(pllc2_freq_table) - 2; i++) {
165                 pllc2_freq_table[i].frequency = clk->parent->rate * (i + 20) * 2;
166                 pllc2_freq_table[i].index = i;
167         }
168
169         /* This is a special entry - switching PLL off makes it a repeater */
170         pllc2_freq_table[i].frequency = clk->parent->rate;
171         pllc2_freq_table[i].index = i;
172
173         pllc2_freq_table[++i].frequency = CPUFREQ_TABLE_END;
174         pllc2_freq_table[i].index = i;
175 }
176
177 static unsigned long pllc2_recalc(struct clk *clk)
178 {
179         unsigned long mult = 1;
180
181         pllc2_table_rebuild(clk);
182
183         /*
184          * If the PLL is off, mult == 1, clk->rate will be updated in
185          * pllc2_enable().
186          */
187         if (__raw_readl(PLLC2CR) & (1 << 31))
188                 mult = (((__raw_readl(PLLC2CR) >> 24) & 0x3f) + 1) * 2;
189
190         return clk->parent->rate * mult;
191 }
192
193 static long pllc2_round_rate(struct clk *clk, unsigned long rate)
194 {
195         return clk_rate_table_round(clk, clk->freq_table, rate);
196 }
197
198 static int pllc2_enable(struct clk *clk)
199 {
200         int i;
201
202         __raw_writel(__raw_readl(PLLC2CR) | 0x80000000, PLLC2CR);
203
204         for (i = 0; i < 100; i++)
205                 if (__raw_readl(PLLC2CR) & 0x80000000) {
206                         clk->rate = pllc2_recalc(clk);
207                         return 0;
208                 }
209
210         pr_err("%s(): timeout!\n", __func__);
211
212         return -ETIMEDOUT;
213 }
214
215 static void pllc2_disable(struct clk *clk)
216 {
217         __raw_writel(__raw_readl(PLLC2CR) & ~0x80000000, PLLC2CR);
218 }
219
220 static int pllc2_set_rate(struct clk *clk,
221                           unsigned long rate, int algo_id)
222 {
223         unsigned long value;
224         int idx;
225
226         idx = clk_rate_table_find(clk, clk->freq_table, rate);
227         if (idx < 0)
228                 return idx;
229
230         if (rate == clk->parent->rate) {
231                 pllc2_disable(clk);
232                 return 0;
233         }
234
235         value = __raw_readl(PLLC2CR) & ~(0x3f << 24);
236
237         if (value & 0x80000000)
238                 pllc2_disable(clk);
239
240         __raw_writel((value & ~0x80000000) | ((idx + 19) << 24), PLLC2CR);
241
242         if (value & 0x80000000)
243                 return pllc2_enable(clk);
244
245         return 0;
246 }
247
248 static int pllc2_set_parent(struct clk *clk, struct clk *parent)
249 {
250         u32 value;
251         int ret, i;
252
253         if (!clk->parent_table || !clk->parent_num)
254                 return -EINVAL;
255
256         /* Search the parent */
257         for (i = 0; i < clk->parent_num; i++)
258                 if (clk->parent_table[i] == parent)
259                         break;
260
261         if (i == clk->parent_num)
262                 return -ENODEV;
263
264         ret = clk_reparent(clk, parent);
265         if (ret < 0)
266                 return ret;
267
268         value = __raw_readl(PLLC2CR) & ~(3 << 6);
269
270         __raw_writel(value | (i << 6), PLLC2CR);
271
272         /* Rebiuld the frequency table */
273         pllc2_table_rebuild(clk);
274
275         return 0;
276 }
277
278 static struct clk_ops pllc2_clk_ops = {
279         .recalc         = pllc2_recalc,
280         .round_rate     = pllc2_round_rate,
281         .set_rate       = pllc2_set_rate,
282         .enable         = pllc2_enable,
283         .disable        = pllc2_disable,
284         .set_parent     = pllc2_set_parent,
285 };
286
287 struct clk pllc2_clk = {
288         .ops            = &pllc2_clk_ops,
289         .parent         = &extal1_div2_clk,
290         .freq_table     = pllc2_freq_table,
291         .parent_table   = pllc2_parent,
292         .parent_num     = ARRAY_SIZE(pllc2_parent),
293 };
294
295 static struct clk *main_clks[] = {
296         &dv_clki_clk,
297         &r_clk,
298         &sh7372_extal1_clk,
299         &sh7372_extal2_clk,
300         &dv_clki_div2_clk,
301         &extal1_div2_clk,
302         &extal2_div2_clk,
303         &extal2_div4_clk,
304         &pllc0_clk,
305         &pllc1_clk,
306         &pllc1_div2_clk,
307         &pllc2_clk,
308 };
309
310 static void div4_kick(struct clk *clk)
311 {
312         unsigned long value;
313
314         /* set KICK bit in FRQCRB to update hardware setting */
315         value = __raw_readl(FRQCRB);
316         value |= (1 << 31);
317         __raw_writel(value, FRQCRB);
318 }
319
320 static int divisors[] = { 2, 3, 4, 6, 8, 12, 16, 18,
321                           24, 32, 36, 48, 0, 72, 96, 0 };
322
323 static struct clk_div_mult_table div4_div_mult_table = {
324         .divisors = divisors,
325         .nr_divisors = ARRAY_SIZE(divisors),
326 };
327
328 static struct clk_div4_table div4_table = {
329         .div_mult_table = &div4_div_mult_table,
330         .kick = div4_kick,
331 };
332
333 enum { DIV4_I, DIV4_ZG, DIV4_B, DIV4_M1, DIV4_CSIR,
334        DIV4_ZTR, DIV4_ZT, DIV4_ZX, DIV4_HP,
335        DIV4_ISPB, DIV4_S, DIV4_ZB, DIV4_ZB3, DIV4_CP,
336        DIV4_DDRP, DIV4_NR };
337
338 #define DIV4(_reg, _bit, _mask, _flags) \
339   SH_CLK_DIV4(&pllc1_clk, _reg, _bit, _mask, _flags)
340
341 static struct clk div4_clks[DIV4_NR] = {
342         [DIV4_I] = DIV4(FRQCRA, 20, 0x6fff, CLK_ENABLE_ON_INIT),
343         [DIV4_ZG] = DIV4(FRQCRA, 16, 0x6fff, CLK_ENABLE_ON_INIT),
344         [DIV4_B] = DIV4(FRQCRA, 8, 0x6fff, CLK_ENABLE_ON_INIT),
345         [DIV4_M1] = DIV4(FRQCRA, 4, 0x6fff, CLK_ENABLE_ON_INIT),
346         [DIV4_CSIR] = DIV4(FRQCRA, 0, 0x6fff, 0),
347         [DIV4_ZTR] = DIV4(FRQCRB, 20, 0x6fff, 0),
348         [DIV4_ZT] = DIV4(FRQCRB, 16, 0x6fff, 0),
349         [DIV4_ZX] = DIV4(FRQCRB, 12, 0x6fff, 0),
350         [DIV4_HP] = DIV4(FRQCRB, 4, 0x6fff, 0),
351         [DIV4_ISPB] = DIV4(FRQCRC, 20, 0x6fff, 0),
352         [DIV4_S] = DIV4(FRQCRC, 12, 0x6fff, 0),
353         [DIV4_ZB] = DIV4(FRQCRC, 8, 0x6fff, 0),
354         [DIV4_ZB3] = DIV4(FRQCRC, 4, 0x6fff, 0),
355         [DIV4_CP] = DIV4(FRQCRC, 0, 0x6fff, 0),
356         [DIV4_DDRP] = DIV4(FRQCRD, 0, 0x677c, 0),
357 };
358
359 enum { DIV6_VCK1, DIV6_VCK2, DIV6_VCK3, DIV6_FMSI, DIV6_FMSO,
360        DIV6_FSIA, DIV6_FSIB, DIV6_SUB, DIV6_SPU,
361        DIV6_VOU, DIV6_DSIT, DIV6_DSI0P, DIV6_DSI1P,
362        DIV6_NR };
363
364 static struct clk div6_clks[DIV6_NR] = {
365         [DIV6_VCK1] = SH_CLK_DIV6(&pllc1_div2_clk, VCLKCR1, 0),
366         [DIV6_VCK2] = SH_CLK_DIV6(&pllc1_div2_clk, VCLKCR2, 0),
367         [DIV6_VCK3] = SH_CLK_DIV6(&pllc1_div2_clk, VCLKCR3, 0),
368         [DIV6_FMSI] = SH_CLK_DIV6(&pllc1_div2_clk, FMSICKCR, 0),
369         [DIV6_FMSO] = SH_CLK_DIV6(&pllc1_div2_clk, FMSOCKCR, 0),
370         [DIV6_FSIA] = SH_CLK_DIV6(&pllc1_div2_clk, FSIACKCR, 0),
371         [DIV6_FSIB] = SH_CLK_DIV6(&pllc1_div2_clk, FSIBCKCR, 0),
372         [DIV6_SUB] = SH_CLK_DIV6(&sh7372_extal2_clk, SUBCKCR, 0),
373         [DIV6_SPU] = SH_CLK_DIV6(&pllc1_div2_clk, SPUCKCR, 0),
374         [DIV6_VOU] = SH_CLK_DIV6(&pllc1_div2_clk, VOUCKCR, 0),
375         [DIV6_DSIT] = SH_CLK_DIV6(&pllc1_div2_clk, DSITCKCR, 0),
376         [DIV6_DSI0P] = SH_CLK_DIV6(&pllc1_div2_clk, DSI0PCKCR, 0),
377         [DIV6_DSI1P] = SH_CLK_DIV6(&pllc1_div2_clk, DSI1PCKCR, 0),
378 };
379
380 enum { DIV6_HDMI, DIV6_REPARENT_NR };
381
382 /* Indices are important - they are the actual src selecting values */
383 static struct clk *hdmi_parent[] = {
384         [0] = &pllc1_div2_clk,
385         [1] = &pllc2_clk,
386         [2] = &dv_clki_clk,
387         [3] = NULL,     /* pllc2_div4 not implemented yet */
388 };
389
390 static struct clk div6_reparent_clks[DIV6_REPARENT_NR] = {
391         [DIV6_HDMI] = SH_CLK_DIV6_EXT(&pllc1_div2_clk, HDMICKCR, 0,
392                                       hdmi_parent, ARRAY_SIZE(hdmi_parent), 6, 2),
393 };
394
395 enum { MSTP001,
396        MSTP131, MSTP130,
397        MSTP129, MSTP128, MSTP127, MSTP126,
398        MSTP118, MSTP117, MSTP116,
399        MSTP106, MSTP101, MSTP100,
400        MSTP223,
401        MSTP207, MSTP206, MSTP204, MSTP203, MSTP202, MSTP201, MSTP200,
402        MSTP329, MSTP328, MSTP323, MSTP322, MSTP314, MSTP313, MSTP312,
403        MSTP415, MSTP413, MSTP411, MSTP410, MSTP406, MSTP403,
404        MSTP_NR };
405
406 #define MSTP(_parent, _reg, _bit, _flags) \
407   SH_CLK_MSTP32(_parent, _reg, _bit, _flags)
408
409 static struct clk mstp_clks[MSTP_NR] = {
410         [MSTP001] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR0, 1, 0), /* IIC2 */
411         [MSTP131] = MSTP(&div4_clks[DIV4_B], SMSTPCR1, 31, 0), /* VEU3 */
412         [MSTP130] = MSTP(&div4_clks[DIV4_B], SMSTPCR1, 30, 0), /* VEU2 */
413         [MSTP129] = MSTP(&div4_clks[DIV4_B], SMSTPCR1, 29, 0), /* VEU1 */
414         [MSTP128] = MSTP(&div4_clks[DIV4_B], SMSTPCR1, 28, 0), /* VEU0 */
415         [MSTP127] = MSTP(&div4_clks[DIV4_B], SMSTPCR1, 27, 0), /* CEU */
416         [MSTP126] = MSTP(&div4_clks[DIV4_B], SMSTPCR1, 26, 0), /* CSI2 */
417         [MSTP118] = MSTP(&div4_clks[DIV4_B], SMSTPCR1, 18, 0), /* DSITX */
418         [MSTP117] = MSTP(&div4_clks[DIV4_B], SMSTPCR1, 17, 0), /* LCDC1 */
419         [MSTP116] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR1, 16, 0), /* IIC0 */
420         [MSTP106] = MSTP(&div4_clks[DIV4_B], SMSTPCR1, 6, 0), /* JPU */
421         [MSTP101] = MSTP(&div4_clks[DIV4_M1], SMSTPCR1, 1, 0), /* VPU */
422         [MSTP100] = MSTP(&div4_clks[DIV4_B], SMSTPCR1, 0, 0), /* LCDC0 */
423         [MSTP223] = MSTP(&div6_clks[DIV6_SPU], SMSTPCR2, 23, 0), /* SPU2 */
424         [MSTP207] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR2, 7, 0), /* SCIFA5 */
425         [MSTP206] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR2, 6, 0), /* SCIFB */
426         [MSTP204] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR2, 4, 0), /* SCIFA0 */
427         [MSTP203] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR2, 3, 0), /* SCIFA1 */
428         [MSTP202] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR2, 2, 0), /* SCIFA2 */
429         [MSTP201] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR2, 1, 0), /* SCIFA3 */
430         [MSTP200] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR2, 0, 0), /* SCIFA4 */
431         [MSTP329] = MSTP(&r_clk, SMSTPCR3, 29, 0), /* CMT10 */
432         [MSTP328] = MSTP(&div6_clks[DIV6_SPU], SMSTPCR3, 28, 0), /* FSIA */
433         [MSTP323] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR3, 23, 0), /* IIC1 */
434         [MSTP322] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR3, 22, 0), /* USB0 */
435         [MSTP314] = MSTP(&div4_clks[DIV4_HP], SMSTPCR3, 14, 0), /* SDHI0 */
436         [MSTP313] = MSTP(&div4_clks[DIV4_HP], SMSTPCR3, 13, 0), /* SDHI1 */
437         [MSTP312] = MSTP(&div4_clks[DIV4_HP], SMSTPCR3, 12, 0), /* MMC */
438         [MSTP415] = MSTP(&div4_clks[DIV4_HP], SMSTPCR4, 15, 0), /* SDHI2 */
439         [MSTP413] = MSTP(&pllc1_div2_clk, SMSTPCR4, 13, 0), /* HDMI */
440         [MSTP411] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR4, 11, 0), /* IIC3 */
441         [MSTP410] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR4, 10, 0), /* IIC4 */
442         [MSTP406] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR4, 6, 0), /* USB1 */
443         [MSTP403] = MSTP(&r_clk, SMSTPCR4, 3, 0), /* KEYSC */
444 };
445
446 #define CLKDEV_CON_ID(_id, _clk) { .con_id = _id, .clk = _clk }
447 #define CLKDEV_DEV_ID(_id, _clk) { .dev_id = _id, .clk = _clk }
448
449 static struct clk_lookup lookups[] = {
450         /* main clocks */
451         CLKDEV_CON_ID("dv_clki_div2_clk", &dv_clki_div2_clk),
452         CLKDEV_CON_ID("r_clk", &r_clk),
453         CLKDEV_CON_ID("extal1", &sh7372_extal1_clk),
454         CLKDEV_CON_ID("extal2", &sh7372_extal2_clk),
455         CLKDEV_CON_ID("extal1_div2_clk", &extal1_div2_clk),
456         CLKDEV_CON_ID("extal2_div2_clk", &extal2_div2_clk),
457         CLKDEV_CON_ID("extal2_div4_clk", &extal2_div4_clk),
458         CLKDEV_CON_ID("pllc0_clk", &pllc0_clk),
459         CLKDEV_CON_ID("pllc1_clk", &pllc1_clk),
460         CLKDEV_CON_ID("pllc1_div2_clk", &pllc1_div2_clk),
461         CLKDEV_CON_ID("pllc2_clk", &pllc2_clk),
462
463         /* DIV4 clocks */
464         CLKDEV_CON_ID("i_clk", &div4_clks[DIV4_I]),
465         CLKDEV_CON_ID("zg_clk", &div4_clks[DIV4_ZG]),
466         CLKDEV_CON_ID("b_clk", &div4_clks[DIV4_B]),
467         CLKDEV_CON_ID("m1_clk", &div4_clks[DIV4_M1]),
468         CLKDEV_CON_ID("csir_clk", &div4_clks[DIV4_CSIR]),
469         CLKDEV_CON_ID("ztr_clk", &div4_clks[DIV4_ZTR]),
470         CLKDEV_CON_ID("zt_clk", &div4_clks[DIV4_ZT]),
471         CLKDEV_CON_ID("zx_clk", &div4_clks[DIV4_ZX]),
472         CLKDEV_CON_ID("hp_clk", &div4_clks[DIV4_HP]),
473         CLKDEV_CON_ID("ispb_clk", &div4_clks[DIV4_ISPB]),
474         CLKDEV_CON_ID("s_clk", &div4_clks[DIV4_S]),
475         CLKDEV_CON_ID("zb_clk", &div4_clks[DIV4_ZB]),
476         CLKDEV_CON_ID("zb3_clk", &div4_clks[DIV4_ZB3]),
477         CLKDEV_CON_ID("cp_clk", &div4_clks[DIV4_CP]),
478         CLKDEV_CON_ID("ddrp_clk", &div4_clks[DIV4_DDRP]),
479
480         /* DIV6 clocks */
481         CLKDEV_CON_ID("vck1_clk", &div6_clks[DIV6_VCK1]),
482         CLKDEV_CON_ID("vck2_clk", &div6_clks[DIV6_VCK2]),
483         CLKDEV_CON_ID("vck3_clk", &div6_clks[DIV6_VCK3]),
484         CLKDEV_CON_ID("fmsi_clk", &div6_clks[DIV6_FMSI]),
485         CLKDEV_CON_ID("fmso_clk", &div6_clks[DIV6_FMSO]),
486         CLKDEV_CON_ID("fsia_clk", &div6_clks[DIV6_FSIA]),
487         CLKDEV_CON_ID("fsib_clk", &div6_clks[DIV6_FSIB]),
488         CLKDEV_CON_ID("sub_clk", &div6_clks[DIV6_SUB]),
489         CLKDEV_CON_ID("spu_clk", &div6_clks[DIV6_SPU]),
490         CLKDEV_CON_ID("vou_clk", &div6_clks[DIV6_VOU]),
491         CLKDEV_CON_ID("hdmi_clk", &div6_reparent_clks[DIV6_HDMI]),
492         CLKDEV_CON_ID("dsit_clk", &div6_clks[DIV6_DSIT]),
493         CLKDEV_CON_ID("dsi0p_clk", &div6_clks[DIV6_DSI0P]),
494         CLKDEV_CON_ID("dsi1p_clk", &div6_clks[DIV6_DSI1P]),
495
496         /* MSTP32 clocks */
497         CLKDEV_DEV_ID("i2c-sh_mobile.2", &mstp_clks[MSTP001]), /* IIC2 */
498         CLKDEV_DEV_ID("uio_pdrv_genirq.4", &mstp_clks[MSTP131]), /* VEU3 */
499         CLKDEV_DEV_ID("uio_pdrv_genirq.3", &mstp_clks[MSTP130]), /* VEU2 */
500         CLKDEV_DEV_ID("uio_pdrv_genirq.2", &mstp_clks[MSTP129]), /* VEU1 */
501         CLKDEV_DEV_ID("uio_pdrv_genirq.1", &mstp_clks[MSTP128]), /* VEU0 */
502         CLKDEV_DEV_ID("sh_mobile_ceu.0", &mstp_clks[MSTP127]), /* CEU */
503         CLKDEV_DEV_ID("sh-mobile-csi2.0", &mstp_clks[MSTP126]), /* CSI2 */
504         CLKDEV_DEV_ID("sh-mipi-dsi.0", &mstp_clks[MSTP118]), /* DSITX */
505         CLKDEV_DEV_ID("sh_mobile_lcdc_fb.1", &mstp_clks[MSTP117]), /* LCDC1 */
506         CLKDEV_DEV_ID("i2c-sh_mobile.0", &mstp_clks[MSTP116]), /* IIC0 */
507         CLKDEV_DEV_ID("uio_pdrv_genirq.5", &mstp_clks[MSTP106]), /* JPU */
508         CLKDEV_DEV_ID("uio_pdrv_genirq.0", &mstp_clks[MSTP101]), /* VPU */
509         CLKDEV_DEV_ID("sh_mobile_lcdc_fb.0", &mstp_clks[MSTP100]), /* LCDC0 */
510         CLKDEV_DEV_ID("uio_pdrv_genirq.6", &mstp_clks[MSTP223]), /* SPU2DSP0 */
511         CLKDEV_DEV_ID("uio_pdrv_genirq.7", &mstp_clks[MSTP223]), /* SPU2DSP1 */
512         CLKDEV_DEV_ID("sh-sci.5", &mstp_clks[MSTP207]), /* SCIFA5 */
513         CLKDEV_DEV_ID("sh-sci.6", &mstp_clks[MSTP206]), /* SCIFB */
514         CLKDEV_DEV_ID("sh-sci.0", &mstp_clks[MSTP204]), /* SCIFA0 */
515         CLKDEV_DEV_ID("sh-sci.1", &mstp_clks[MSTP203]), /* SCIFA1 */
516         CLKDEV_DEV_ID("sh-sci.2", &mstp_clks[MSTP202]), /* SCIFA2 */
517         CLKDEV_DEV_ID("sh-sci.3", &mstp_clks[MSTP201]), /* SCIFA3 */
518         CLKDEV_DEV_ID("sh-sci.4", &mstp_clks[MSTP200]), /* SCIFA4 */
519         CLKDEV_CON_ID("cmt1", &mstp_clks[MSTP329]), /* CMT10 */
520         CLKDEV_DEV_ID("sh_fsi2", &mstp_clks[MSTP328]), /* FSI2 */
521         CLKDEV_DEV_ID("i2c-sh_mobile.1", &mstp_clks[MSTP323]), /* IIC1 */
522         CLKDEV_DEV_ID("r8a66597_hcd.0", &mstp_clks[MSTP323]), /* USB0 */
523         CLKDEV_DEV_ID("r8a66597_udc.0", &mstp_clks[MSTP323]), /* USB0 */
524         CLKDEV_DEV_ID("sh_mobile_sdhi.0", &mstp_clks[MSTP314]), /* SDHI0 */
525         CLKDEV_DEV_ID("sh_mobile_sdhi.1", &mstp_clks[MSTP313]), /* SDHI1 */
526         CLKDEV_DEV_ID("sh_mmcif.0", &mstp_clks[MSTP312]), /* MMC */
527         CLKDEV_DEV_ID("sh_mobile_sdhi.2", &mstp_clks[MSTP415]), /* SDHI2 */
528         CLKDEV_DEV_ID("sh-mobile-hdmi", &mstp_clks[MSTP413]), /* HDMI */
529         CLKDEV_DEV_ID("i2c-sh_mobile.3", &mstp_clks[MSTP411]), /* IIC3 */
530         CLKDEV_DEV_ID("i2c-sh_mobile.4", &mstp_clks[MSTP410]), /* IIC4 */
531         CLKDEV_DEV_ID("r8a66597_hcd.1", &mstp_clks[MSTP406]), /* USB1 */
532         CLKDEV_DEV_ID("r8a66597_udc.1", &mstp_clks[MSTP406]), /* USB1 */
533         CLKDEV_DEV_ID("sh_keysc.0", &mstp_clks[MSTP403]), /* KEYSC */
534         {.con_id = "ick", .dev_id = "sh-mobile-hdmi", .clk = &div6_reparent_clks[DIV6_HDMI]},
535 };
536
537 void __init sh7372_clock_init(void)
538 {
539         int k, ret = 0;
540
541         for (k = 0; !ret && (k < ARRAY_SIZE(main_clks)); k++)
542                 ret = clk_register(main_clks[k]);
543
544         if (!ret)
545                 ret = sh_clk_div4_register(div4_clks, DIV4_NR, &div4_table);
546
547         if (!ret)
548                 ret = sh_clk_div6_register(div6_clks, DIV6_NR);
549
550         if (!ret)
551                 ret = sh_clk_div6_reparent_register(div6_reparent_clks, DIV6_NR);
552
553         if (!ret)
554                 ret = sh_clk_mstp32_register(mstp_clks, MSTP_NR);
555
556         clkdev_add_table(lookups, ARRAY_SIZE(lookups));
557
558         if (!ret)
559                 clk_init();
560         else
561                 panic("failed to setup sh7372 clocks\n");
562
563 }