Merge branch 'for-linus' of git://git.infradead.org/users/eparis/notify
[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 sh7372_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 sh7372_dv_clki_div2_clk = {
90         .ops            = &div2_clk_ops,
91         .parent         = &sh7372_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] = &sh7372_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 sh7372_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 /* External input clock (pin name: FSIACK/FSIBCK ) */
296 struct clk sh7372_fsiack_clk = {
297 };
298
299 struct clk sh7372_fsibck_clk = {
300 };
301
302 static struct clk *main_clks[] = {
303         &sh7372_dv_clki_clk,
304         &r_clk,
305         &sh7372_extal1_clk,
306         &sh7372_extal2_clk,
307         &sh7372_dv_clki_div2_clk,
308         &extal1_div2_clk,
309         &extal2_div2_clk,
310         &extal2_div4_clk,
311         &pllc0_clk,
312         &pllc1_clk,
313         &pllc1_div2_clk,
314         &sh7372_pllc2_clk,
315         &sh7372_fsiack_clk,
316         &sh7372_fsibck_clk,
317 };
318
319 static void div4_kick(struct clk *clk)
320 {
321         unsigned long value;
322
323         /* set KICK bit in FRQCRB to update hardware setting */
324         value = __raw_readl(FRQCRB);
325         value |= (1 << 31);
326         __raw_writel(value, FRQCRB);
327 }
328
329 static int divisors[] = { 2, 3, 4, 6, 8, 12, 16, 18,
330                           24, 32, 36, 48, 0, 72, 96, 0 };
331
332 static struct clk_div_mult_table div4_div_mult_table = {
333         .divisors = divisors,
334         .nr_divisors = ARRAY_SIZE(divisors),
335 };
336
337 static struct clk_div4_table div4_table = {
338         .div_mult_table = &div4_div_mult_table,
339         .kick = div4_kick,
340 };
341
342 enum { DIV4_I, DIV4_ZG, DIV4_B, DIV4_M1, DIV4_CSIR,
343        DIV4_ZTR, DIV4_ZT, DIV4_ZX, DIV4_HP,
344        DIV4_ISPB, DIV4_S, DIV4_ZB, DIV4_ZB3, DIV4_CP,
345        DIV4_DDRP, DIV4_NR };
346
347 #define DIV4(_reg, _bit, _mask, _flags) \
348   SH_CLK_DIV4(&pllc1_clk, _reg, _bit, _mask, _flags)
349
350 static struct clk div4_clks[DIV4_NR] = {
351         [DIV4_I] = DIV4(FRQCRA, 20, 0x6fff, CLK_ENABLE_ON_INIT),
352         [DIV4_ZG] = DIV4(FRQCRA, 16, 0x6fff, CLK_ENABLE_ON_INIT),
353         [DIV4_B] = DIV4(FRQCRA, 8, 0x6fff, CLK_ENABLE_ON_INIT),
354         [DIV4_M1] = DIV4(FRQCRA, 4, 0x6fff, CLK_ENABLE_ON_INIT),
355         [DIV4_CSIR] = DIV4(FRQCRA, 0, 0x6fff, 0),
356         [DIV4_ZTR] = DIV4(FRQCRB, 20, 0x6fff, 0),
357         [DIV4_ZT] = DIV4(FRQCRB, 16, 0x6fff, 0),
358         [DIV4_ZX] = DIV4(FRQCRB, 12, 0x6fff, 0),
359         [DIV4_HP] = DIV4(FRQCRB, 4, 0x6fff, 0),
360         [DIV4_ISPB] = DIV4(FRQCRC, 20, 0x6fff, 0),
361         [DIV4_S] = DIV4(FRQCRC, 12, 0x6fff, 0),
362         [DIV4_ZB] = DIV4(FRQCRC, 8, 0x6fff, 0),
363         [DIV4_ZB3] = DIV4(FRQCRC, 4, 0x6fff, 0),
364         [DIV4_CP] = DIV4(FRQCRC, 0, 0x6fff, 0),
365         [DIV4_DDRP] = DIV4(FRQCRD, 0, 0x677c, 0),
366 };
367
368 enum { DIV6_VCK1, DIV6_VCK2, DIV6_VCK3, DIV6_FMSI, DIV6_FMSO,
369        DIV6_SUB, DIV6_SPU,
370        DIV6_VOU, DIV6_DSIT, DIV6_DSI0P, DIV6_DSI1P,
371        DIV6_NR };
372
373 static struct clk div6_clks[DIV6_NR] = {
374         [DIV6_VCK1] = SH_CLK_DIV6(&pllc1_div2_clk, VCLKCR1, 0),
375         [DIV6_VCK2] = SH_CLK_DIV6(&pllc1_div2_clk, VCLKCR2, 0),
376         [DIV6_VCK3] = SH_CLK_DIV6(&pllc1_div2_clk, VCLKCR3, 0),
377         [DIV6_FMSI] = SH_CLK_DIV6(&pllc1_div2_clk, FMSICKCR, 0),
378         [DIV6_FMSO] = SH_CLK_DIV6(&pllc1_div2_clk, FMSOCKCR, 0),
379         [DIV6_SUB] = SH_CLK_DIV6(&sh7372_extal2_clk, SUBCKCR, 0),
380         [DIV6_SPU] = SH_CLK_DIV6(&pllc1_div2_clk, SPUCKCR, 0),
381         [DIV6_VOU] = SH_CLK_DIV6(&pllc1_div2_clk, VOUCKCR, 0),
382         [DIV6_DSIT] = SH_CLK_DIV6(&pllc1_div2_clk, DSITCKCR, 0),
383         [DIV6_DSI0P] = SH_CLK_DIV6(&pllc1_div2_clk, DSI0PCKCR, 0),
384         [DIV6_DSI1P] = SH_CLK_DIV6(&pllc1_div2_clk, DSI1PCKCR, 0),
385 };
386
387 enum { DIV6_HDMI, DIV6_FSIA, DIV6_FSIB, DIV6_REPARENT_NR };
388
389 /* Indices are important - they are the actual src selecting values */
390 static struct clk *hdmi_parent[] = {
391         [0] = &pllc1_div2_clk,
392         [1] = &sh7372_pllc2_clk,
393         [2] = &sh7372_dv_clki_clk,
394         [3] = NULL,     /* pllc2_div4 not implemented yet */
395 };
396
397 static struct clk *fsiackcr_parent[] = {
398         [0] = &pllc1_div2_clk,
399         [1] = &sh7372_pllc2_clk,
400         [2] = &sh7372_fsiack_clk, /* external input for FSI A */
401         [3] = NULL,     /* setting prohibited */
402 };
403
404 static struct clk *fsibckcr_parent[] = {
405         [0] = &pllc1_div2_clk,
406         [1] = &sh7372_pllc2_clk,
407         [2] = &sh7372_fsibck_clk, /* external input for FSI B */
408         [3] = NULL,     /* setting prohibited */
409 };
410
411 static struct clk div6_reparent_clks[DIV6_REPARENT_NR] = {
412         [DIV6_HDMI] = SH_CLK_DIV6_EXT(&pllc1_div2_clk, HDMICKCR, 0,
413                                       hdmi_parent, ARRAY_SIZE(hdmi_parent), 6, 2),
414         [DIV6_FSIA] = SH_CLK_DIV6_EXT(&pllc1_div2_clk, FSIACKCR, 0,
415                                       fsiackcr_parent, ARRAY_SIZE(fsiackcr_parent), 6, 2),
416         [DIV6_FSIB] = SH_CLK_DIV6_EXT(&pllc1_div2_clk, FSIBCKCR, 0,
417                                       fsibckcr_parent, ARRAY_SIZE(fsibckcr_parent), 6, 2),
418 };
419
420 enum { MSTP001,
421        MSTP131, MSTP130,
422        MSTP129, MSTP128, MSTP127, MSTP126, MSTP125,
423        MSTP118, MSTP117, MSTP116,
424        MSTP106, MSTP101, MSTP100,
425        MSTP223,
426        MSTP207, MSTP206, MSTP204, MSTP203, MSTP202, MSTP201, MSTP200,
427        MSTP329, MSTP328, MSTP323, MSTP322, MSTP314, MSTP313, MSTP312,
428        MSTP415, MSTP413, MSTP411, MSTP410, MSTP406, MSTP403,
429        MSTP_NR };
430
431 #define MSTP(_parent, _reg, _bit, _flags) \
432   SH_CLK_MSTP32(_parent, _reg, _bit, _flags)
433
434 static struct clk mstp_clks[MSTP_NR] = {
435         [MSTP001] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR0, 1, 0), /* IIC2 */
436         [MSTP131] = MSTP(&div4_clks[DIV4_B], SMSTPCR1, 31, 0), /* VEU3 */
437         [MSTP130] = MSTP(&div4_clks[DIV4_B], SMSTPCR1, 30, 0), /* VEU2 */
438         [MSTP129] = MSTP(&div4_clks[DIV4_B], SMSTPCR1, 29, 0), /* VEU1 */
439         [MSTP128] = MSTP(&div4_clks[DIV4_B], SMSTPCR1, 28, 0), /* VEU0 */
440         [MSTP127] = MSTP(&div4_clks[DIV4_B], SMSTPCR1, 27, 0), /* CEU */
441         [MSTP126] = MSTP(&div4_clks[DIV4_B], SMSTPCR1, 26, 0), /* CSI2 */
442         [MSTP125] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR1, 25, 0), /* TMU0 */
443         [MSTP118] = MSTP(&div4_clks[DIV4_B], SMSTPCR1, 18, 0), /* DSITX */
444         [MSTP117] = MSTP(&div4_clks[DIV4_B], SMSTPCR1, 17, 0), /* LCDC1 */
445         [MSTP116] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR1, 16, 0), /* IIC0 */
446         [MSTP106] = MSTP(&div4_clks[DIV4_B], SMSTPCR1, 6, 0), /* JPU */
447         [MSTP101] = MSTP(&div4_clks[DIV4_M1], SMSTPCR1, 1, 0), /* VPU */
448         [MSTP100] = MSTP(&div4_clks[DIV4_B], SMSTPCR1, 0, 0), /* LCDC0 */
449         [MSTP223] = MSTP(&div6_clks[DIV6_SPU], SMSTPCR2, 23, 0), /* SPU2 */
450         [MSTP207] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR2, 7, 0), /* SCIFA5 */
451         [MSTP206] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR2, 6, 0), /* SCIFB */
452         [MSTP204] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR2, 4, 0), /* SCIFA0 */
453         [MSTP203] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR2, 3, 0), /* SCIFA1 */
454         [MSTP202] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR2, 2, 0), /* SCIFA2 */
455         [MSTP201] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR2, 1, 0), /* SCIFA3 */
456         [MSTP200] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR2, 0, 0), /* SCIFA4 */
457         [MSTP329] = MSTP(&r_clk, SMSTPCR3, 29, 0), /* CMT10 */
458         [MSTP328] = MSTP(&div6_clks[DIV6_SPU], SMSTPCR3, 28, 0), /* FSI2 */
459         [MSTP323] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR3, 23, 0), /* IIC1 */
460         [MSTP322] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR3, 22, 0), /* USB0 */
461         [MSTP314] = MSTP(&div4_clks[DIV4_HP], SMSTPCR3, 14, 0), /* SDHI0 */
462         [MSTP313] = MSTP(&div4_clks[DIV4_HP], SMSTPCR3, 13, 0), /* SDHI1 */
463         [MSTP312] = MSTP(&div4_clks[DIV4_HP], SMSTPCR3, 12, 0), /* MMC */
464         [MSTP415] = MSTP(&div4_clks[DIV4_HP], SMSTPCR4, 15, 0), /* SDHI2 */
465         [MSTP413] = MSTP(&pllc1_div2_clk, SMSTPCR4, 13, 0), /* HDMI */
466         [MSTP411] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR4, 11, 0), /* IIC3 */
467         [MSTP410] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR4, 10, 0), /* IIC4 */
468         [MSTP406] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR4, 6, 0), /* USB1 */
469         [MSTP403] = MSTP(&r_clk, SMSTPCR4, 3, 0), /* KEYSC */
470 };
471
472 #define CLKDEV_CON_ID(_id, _clk) { .con_id = _id, .clk = _clk }
473 #define CLKDEV_DEV_ID(_id, _clk) { .dev_id = _id, .clk = _clk }
474 #define CLKDEV_ICK_ID(_cid, _did, _clk) { .con_id = _cid, .dev_id = _did, .clk = _clk }
475
476 static struct clk_lookup lookups[] = {
477         /* main clocks */
478         CLKDEV_CON_ID("dv_clki_div2_clk", &sh7372_dv_clki_div2_clk),
479         CLKDEV_CON_ID("r_clk", &r_clk),
480         CLKDEV_CON_ID("extal1", &sh7372_extal1_clk),
481         CLKDEV_CON_ID("extal2", &sh7372_extal2_clk),
482         CLKDEV_CON_ID("extal1_div2_clk", &extal1_div2_clk),
483         CLKDEV_CON_ID("extal2_div2_clk", &extal2_div2_clk),
484         CLKDEV_CON_ID("extal2_div4_clk", &extal2_div4_clk),
485         CLKDEV_CON_ID("pllc0_clk", &pllc0_clk),
486         CLKDEV_CON_ID("pllc1_clk", &pllc1_clk),
487         CLKDEV_CON_ID("pllc1_div2_clk", &pllc1_div2_clk),
488         CLKDEV_CON_ID("pllc2_clk", &sh7372_pllc2_clk),
489
490         /* DIV4 clocks */
491         CLKDEV_CON_ID("i_clk", &div4_clks[DIV4_I]),
492         CLKDEV_CON_ID("zg_clk", &div4_clks[DIV4_ZG]),
493         CLKDEV_CON_ID("b_clk", &div4_clks[DIV4_B]),
494         CLKDEV_CON_ID("m1_clk", &div4_clks[DIV4_M1]),
495         CLKDEV_CON_ID("csir_clk", &div4_clks[DIV4_CSIR]),
496         CLKDEV_CON_ID("ztr_clk", &div4_clks[DIV4_ZTR]),
497         CLKDEV_CON_ID("zt_clk", &div4_clks[DIV4_ZT]),
498         CLKDEV_CON_ID("zx_clk", &div4_clks[DIV4_ZX]),
499         CLKDEV_CON_ID("hp_clk", &div4_clks[DIV4_HP]),
500         CLKDEV_CON_ID("ispb_clk", &div4_clks[DIV4_ISPB]),
501         CLKDEV_CON_ID("s_clk", &div4_clks[DIV4_S]),
502         CLKDEV_CON_ID("zb_clk", &div4_clks[DIV4_ZB]),
503         CLKDEV_CON_ID("zb3_clk", &div4_clks[DIV4_ZB3]),
504         CLKDEV_CON_ID("cp_clk", &div4_clks[DIV4_CP]),
505         CLKDEV_CON_ID("ddrp_clk", &div4_clks[DIV4_DDRP]),
506
507         /* DIV6 clocks */
508         CLKDEV_CON_ID("vck1_clk", &div6_clks[DIV6_VCK1]),
509         CLKDEV_CON_ID("vck2_clk", &div6_clks[DIV6_VCK2]),
510         CLKDEV_CON_ID("vck3_clk", &div6_clks[DIV6_VCK3]),
511         CLKDEV_CON_ID("fmsi_clk", &div6_clks[DIV6_FMSI]),
512         CLKDEV_CON_ID("fmso_clk", &div6_clks[DIV6_FMSO]),
513         CLKDEV_CON_ID("fsia_clk", &div6_reparent_clks[DIV6_FSIA]),
514         CLKDEV_CON_ID("fsib_clk", &div6_reparent_clks[DIV6_FSIB]),
515         CLKDEV_CON_ID("sub_clk", &div6_clks[DIV6_SUB]),
516         CLKDEV_CON_ID("spu_clk", &div6_clks[DIV6_SPU]),
517         CLKDEV_CON_ID("vou_clk", &div6_clks[DIV6_VOU]),
518         CLKDEV_CON_ID("hdmi_clk", &div6_reparent_clks[DIV6_HDMI]),
519         CLKDEV_CON_ID("dsit_clk", &div6_clks[DIV6_DSIT]),
520         CLKDEV_CON_ID("dsi0p_clk", &div6_clks[DIV6_DSI0P]),
521         CLKDEV_CON_ID("dsi1p_clk", &div6_clks[DIV6_DSI1P]),
522
523         /* MSTP32 clocks */
524         CLKDEV_DEV_ID("i2c-sh_mobile.2", &mstp_clks[MSTP001]), /* IIC2 */
525         CLKDEV_DEV_ID("uio_pdrv_genirq.4", &mstp_clks[MSTP131]), /* VEU3 */
526         CLKDEV_DEV_ID("uio_pdrv_genirq.3", &mstp_clks[MSTP130]), /* VEU2 */
527         CLKDEV_DEV_ID("uio_pdrv_genirq.2", &mstp_clks[MSTP129]), /* VEU1 */
528         CLKDEV_DEV_ID("uio_pdrv_genirq.1", &mstp_clks[MSTP128]), /* VEU0 */
529         CLKDEV_DEV_ID("sh_mobile_ceu.0", &mstp_clks[MSTP127]), /* CEU */
530         CLKDEV_DEV_ID("sh-mobile-csi2.0", &mstp_clks[MSTP126]), /* CSI2 */
531         CLKDEV_DEV_ID("sh_tmu.0", &mstp_clks[MSTP125]), /* TMU00 */
532         CLKDEV_DEV_ID("sh_tmu.1", &mstp_clks[MSTP125]), /* TMU01 */
533         CLKDEV_DEV_ID("sh-mipi-dsi.0", &mstp_clks[MSTP118]), /* DSITX */
534         CLKDEV_DEV_ID("sh_mobile_lcdc_fb.1", &mstp_clks[MSTP117]), /* LCDC1 */
535         CLKDEV_DEV_ID("i2c-sh_mobile.0", &mstp_clks[MSTP116]), /* IIC0 */
536         CLKDEV_DEV_ID("uio_pdrv_genirq.5", &mstp_clks[MSTP106]), /* JPU */
537         CLKDEV_DEV_ID("uio_pdrv_genirq.0", &mstp_clks[MSTP101]), /* VPU */
538         CLKDEV_DEV_ID("sh_mobile_lcdc_fb.0", &mstp_clks[MSTP100]), /* LCDC0 */
539         CLKDEV_DEV_ID("uio_pdrv_genirq.6", &mstp_clks[MSTP223]), /* SPU2DSP0 */
540         CLKDEV_DEV_ID("uio_pdrv_genirq.7", &mstp_clks[MSTP223]), /* SPU2DSP1 */
541         CLKDEV_DEV_ID("sh-sci.5", &mstp_clks[MSTP207]), /* SCIFA5 */
542         CLKDEV_DEV_ID("sh-sci.6", &mstp_clks[MSTP206]), /* SCIFB */
543         CLKDEV_DEV_ID("sh-sci.0", &mstp_clks[MSTP204]), /* SCIFA0 */
544         CLKDEV_DEV_ID("sh-sci.1", &mstp_clks[MSTP203]), /* SCIFA1 */
545         CLKDEV_DEV_ID("sh-sci.2", &mstp_clks[MSTP202]), /* SCIFA2 */
546         CLKDEV_DEV_ID("sh-sci.3", &mstp_clks[MSTP201]), /* SCIFA3 */
547         CLKDEV_DEV_ID("sh-sci.4", &mstp_clks[MSTP200]), /* SCIFA4 */
548         CLKDEV_DEV_ID("sh_cmt.10", &mstp_clks[MSTP329]), /* CMT10 */
549         CLKDEV_DEV_ID("sh_fsi2", &mstp_clks[MSTP328]), /* FSI2 */
550         CLKDEV_DEV_ID("i2c-sh_mobile.1", &mstp_clks[MSTP323]), /* IIC1 */
551         CLKDEV_DEV_ID("r8a66597_hcd.0", &mstp_clks[MSTP323]), /* USB0 */
552         CLKDEV_DEV_ID("r8a66597_udc.0", &mstp_clks[MSTP323]), /* USB0 */
553         CLKDEV_DEV_ID("sh_mobile_sdhi.0", &mstp_clks[MSTP314]), /* SDHI0 */
554         CLKDEV_DEV_ID("sh_mobile_sdhi.1", &mstp_clks[MSTP313]), /* SDHI1 */
555         CLKDEV_DEV_ID("sh_mmcif.0", &mstp_clks[MSTP312]), /* MMC */
556         CLKDEV_DEV_ID("sh_mobile_sdhi.2", &mstp_clks[MSTP415]), /* SDHI2 */
557         CLKDEV_DEV_ID("sh-mobile-hdmi", &mstp_clks[MSTP413]), /* HDMI */
558         CLKDEV_DEV_ID("i2c-sh_mobile.3", &mstp_clks[MSTP411]), /* IIC3 */
559         CLKDEV_DEV_ID("i2c-sh_mobile.4", &mstp_clks[MSTP410]), /* IIC4 */
560         CLKDEV_DEV_ID("r8a66597_hcd.1", &mstp_clks[MSTP406]), /* USB1 */
561         CLKDEV_DEV_ID("r8a66597_udc.1", &mstp_clks[MSTP406]), /* USB1 */
562         CLKDEV_DEV_ID("sh_keysc.0", &mstp_clks[MSTP403]), /* KEYSC */
563
564         CLKDEV_ICK_ID("ick", "sh-mobile-hdmi", &div6_reparent_clks[DIV6_HDMI]),
565         CLKDEV_ICK_ID("icka", "sh_fsi2", &div6_reparent_clks[DIV6_FSIA]),
566         CLKDEV_ICK_ID("ickb", "sh_fsi2", &div6_reparent_clks[DIV6_FSIB]),
567 };
568
569 void __init sh7372_clock_init(void)
570 {
571         int k, ret = 0;
572
573         for (k = 0; !ret && (k < ARRAY_SIZE(main_clks)); k++)
574                 ret = clk_register(main_clks[k]);
575
576         if (!ret)
577                 ret = sh_clk_div4_register(div4_clks, DIV4_NR, &div4_table);
578
579         if (!ret)
580                 ret = sh_clk_div6_register(div6_clks, DIV6_NR);
581
582         if (!ret)
583                 ret = sh_clk_div6_reparent_register(div6_reparent_clks, DIV6_REPARENT_NR);
584
585         if (!ret)
586                 ret = sh_clk_mstp32_register(mstp_clks, MSTP_NR);
587
588         clkdev_add_table(lookups, ARRAY_SIZE(lookups));
589
590         if (!ret)
591                 clk_init();
592         else
593                 panic("failed to setup sh7372 clocks\n");
594
595 }