Merge branch 'msm-move-gpio' of git://codeaurora.org/quic/kernel/davidb/linux-msm...
[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 <linux/clkdev.h>
24 #include <mach/common.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 RMSTPCR0        0xe6150110
48 #define RMSTPCR1        0xe6150114
49 #define RMSTPCR2        0xe6150118
50 #define RMSTPCR3        0xe615011c
51 #define RMSTPCR4        0xe6150120
52 #define SMSTPCR0        0xe6150130
53 #define SMSTPCR1        0xe6150134
54 #define SMSTPCR2        0xe6150138
55 #define SMSTPCR3        0xe615013c
56 #define SMSTPCR4        0xe6150140
57
58 #define FSIDIVA         0xFE1F8000
59 #define FSIDIVB         0xFE1F8008
60
61 /* Platforms must set frequency on their DV_CLKI pin */
62 struct clk sh7372_dv_clki_clk = {
63 };
64
65 /* Fixed 32 KHz root clock from EXTALR pin */
66 static struct clk r_clk = {
67         .rate           = 32768,
68 };
69
70 /*
71  * 26MHz default rate for the EXTAL1 root input clock.
72  * If needed, reset this with clk_set_rate() from the platform code.
73  */
74 struct clk sh7372_extal1_clk = {
75         .rate           = 26000000,
76 };
77
78 /*
79  * 48MHz default rate for the EXTAL2 root input clock.
80  * If needed, reset this with clk_set_rate() from the platform code.
81  */
82 struct clk sh7372_extal2_clk = {
83         .rate           = 48000000,
84 };
85
86 /* A fixed divide-by-2 block */
87 static unsigned long div2_recalc(struct clk *clk)
88 {
89         return clk->parent->rate / 2;
90 }
91
92 static struct clk_ops div2_clk_ops = {
93         .recalc         = div2_recalc,
94 };
95
96 /* Divide dv_clki by two */
97 struct clk sh7372_dv_clki_div2_clk = {
98         .ops            = &div2_clk_ops,
99         .parent         = &sh7372_dv_clki_clk,
100 };
101
102 /* Divide extal1 by two */
103 static struct clk extal1_div2_clk = {
104         .ops            = &div2_clk_ops,
105         .parent         = &sh7372_extal1_clk,
106 };
107
108 /* Divide extal2 by two */
109 static struct clk extal2_div2_clk = {
110         .ops            = &div2_clk_ops,
111         .parent         = &sh7372_extal2_clk,
112 };
113
114 /* Divide extal2 by four */
115 static struct clk extal2_div4_clk = {
116         .ops            = &div2_clk_ops,
117         .parent         = &extal2_div2_clk,
118 };
119
120 /* PLLC0 and PLLC1 */
121 static unsigned long pllc01_recalc(struct clk *clk)
122 {
123         unsigned long mult = 1;
124
125         if (__raw_readl(PLLC01CR) & (1 << 14))
126                 mult = (((__raw_readl(clk->enable_reg) >> 24) & 0x3f) + 1) * 2;
127
128         return clk->parent->rate * mult;
129 }
130
131 static struct clk_ops pllc01_clk_ops = {
132         .recalc         = pllc01_recalc,
133 };
134
135 static struct clk pllc0_clk = {
136         .ops            = &pllc01_clk_ops,
137         .flags          = CLK_ENABLE_ON_INIT,
138         .parent         = &extal1_div2_clk,
139         .enable_reg     = (void __iomem *)FRQCRC,
140 };
141
142 static struct clk pllc1_clk = {
143         .ops            = &pllc01_clk_ops,
144         .flags          = CLK_ENABLE_ON_INIT,
145         .parent         = &extal1_div2_clk,
146         .enable_reg     = (void __iomem *)FRQCRA,
147 };
148
149 /* Divide PLLC1 by two */
150 static struct clk pllc1_div2_clk = {
151         .ops            = &div2_clk_ops,
152         .parent         = &pllc1_clk,
153 };
154
155 /* PLLC2 */
156
157 /* Indices are important - they are the actual src selecting values */
158 static struct clk *pllc2_parent[] = {
159         [0] = &extal1_div2_clk,
160         [1] = &extal2_div2_clk,
161         [2] = &sh7372_dv_clki_div2_clk,
162 };
163
164 /* Only multipliers 20 * 2 to 46 * 2 are valid, last entry for CPUFREQ_TABLE_END */
165 static struct cpufreq_frequency_table pllc2_freq_table[29];
166
167 static void pllc2_table_rebuild(struct clk *clk)
168 {
169         int i;
170
171         /* Initialise PLLC2 frequency table */
172         for (i = 0; i < ARRAY_SIZE(pllc2_freq_table) - 2; i++) {
173                 pllc2_freq_table[i].frequency = clk->parent->rate * (i + 20) * 2;
174                 pllc2_freq_table[i].index = i;
175         }
176
177         /* This is a special entry - switching PLL off makes it a repeater */
178         pllc2_freq_table[i].frequency = clk->parent->rate;
179         pllc2_freq_table[i].index = i;
180
181         pllc2_freq_table[++i].frequency = CPUFREQ_TABLE_END;
182         pllc2_freq_table[i].index = i;
183 }
184
185 static unsigned long pllc2_recalc(struct clk *clk)
186 {
187         unsigned long mult = 1;
188
189         pllc2_table_rebuild(clk);
190
191         /*
192          * If the PLL is off, mult == 1, clk->rate will be updated in
193          * pllc2_enable().
194          */
195         if (__raw_readl(PLLC2CR) & (1 << 31))
196                 mult = (((__raw_readl(PLLC2CR) >> 24) & 0x3f) + 1) * 2;
197
198         return clk->parent->rate * mult;
199 }
200
201 static long pllc2_round_rate(struct clk *clk, unsigned long rate)
202 {
203         return clk_rate_table_round(clk, clk->freq_table, rate);
204 }
205
206 static int pllc2_enable(struct clk *clk)
207 {
208         int i;
209
210         __raw_writel(__raw_readl(PLLC2CR) | 0x80000000, PLLC2CR);
211
212         for (i = 0; i < 100; i++)
213                 if (__raw_readl(PLLC2CR) & 0x80000000) {
214                         clk->rate = pllc2_recalc(clk);
215                         return 0;
216                 }
217
218         pr_err("%s(): timeout!\n", __func__);
219
220         return -ETIMEDOUT;
221 }
222
223 static void pllc2_disable(struct clk *clk)
224 {
225         __raw_writel(__raw_readl(PLLC2CR) & ~0x80000000, PLLC2CR);
226 }
227
228 static int pllc2_set_rate(struct clk *clk, unsigned long rate)
229 {
230         unsigned long value;
231         int idx;
232
233         idx = clk_rate_table_find(clk, clk->freq_table, rate);
234         if (idx < 0)
235                 return idx;
236
237         if (rate == clk->parent->rate)
238                 return -EINVAL;
239
240         value = __raw_readl(PLLC2CR) & ~(0x3f << 24);
241
242         __raw_writel(value | ((idx + 19) << 24), PLLC2CR);
243
244         clk->rate = clk->freq_table[idx].frequency;
245
246         return 0;
247 }
248
249 static int pllc2_set_parent(struct clk *clk, struct clk *parent)
250 {
251         u32 value;
252         int ret, i;
253
254         if (!clk->parent_table || !clk->parent_num)
255                 return -EINVAL;
256
257         /* Search the parent */
258         for (i = 0; i < clk->parent_num; i++)
259                 if (clk->parent_table[i] == parent)
260                         break;
261
262         if (i == clk->parent_num)
263                 return -ENODEV;
264
265         ret = clk_reparent(clk, parent);
266         if (ret < 0)
267                 return ret;
268
269         value = __raw_readl(PLLC2CR) & ~(3 << 6);
270
271         __raw_writel(value | (i << 6), PLLC2CR);
272
273         /* Rebiuld the frequency table */
274         pllc2_table_rebuild(clk);
275
276         return 0;
277 }
278
279 static struct clk_ops pllc2_clk_ops = {
280         .recalc         = pllc2_recalc,
281         .round_rate     = pllc2_round_rate,
282         .set_rate       = pllc2_set_rate,
283         .enable         = pllc2_enable,
284         .disable        = pllc2_disable,
285         .set_parent     = pllc2_set_parent,
286 };
287
288 struct clk sh7372_pllc2_clk = {
289         .ops            = &pllc2_clk_ops,
290         .parent         = &extal1_div2_clk,
291         .freq_table     = pllc2_freq_table,
292         .nr_freqs       = ARRAY_SIZE(pllc2_freq_table) - 1,
293         .parent_table   = pllc2_parent,
294         .parent_num     = ARRAY_SIZE(pllc2_parent),
295 };
296
297 /* External input clock (pin name: FSIACK/FSIBCK ) */
298 struct clk sh7372_fsiack_clk = {
299 };
300
301 struct clk sh7372_fsibck_clk = {
302 };
303
304 static struct clk *main_clks[] = {
305         &sh7372_dv_clki_clk,
306         &r_clk,
307         &sh7372_extal1_clk,
308         &sh7372_extal2_clk,
309         &sh7372_dv_clki_div2_clk,
310         &extal1_div2_clk,
311         &extal2_div2_clk,
312         &extal2_div4_clk,
313         &pllc0_clk,
314         &pllc1_clk,
315         &pllc1_div2_clk,
316         &sh7372_pllc2_clk,
317         &sh7372_fsiack_clk,
318         &sh7372_fsibck_clk,
319 };
320
321 static void div4_kick(struct clk *clk)
322 {
323         unsigned long value;
324
325         /* set KICK bit in FRQCRB to update hardware setting */
326         value = __raw_readl(FRQCRB);
327         value |= (1 << 31);
328         __raw_writel(value, FRQCRB);
329 }
330
331 static int divisors[] = { 2, 3, 4, 6, 8, 12, 16, 18,
332                           24, 32, 36, 48, 0, 72, 96, 0 };
333
334 static struct clk_div_mult_table div4_div_mult_table = {
335         .divisors = divisors,
336         .nr_divisors = ARRAY_SIZE(divisors),
337 };
338
339 static struct clk_div4_table div4_table = {
340         .div_mult_table = &div4_div_mult_table,
341         .kick = div4_kick,
342 };
343
344 enum { DIV4_I, DIV4_ZG, DIV4_B, DIV4_M1, DIV4_CSIR,
345        DIV4_ZTR, DIV4_ZT, DIV4_ZX, DIV4_HP,
346        DIV4_ISPB, DIV4_S, DIV4_ZB, DIV4_ZB3, DIV4_CP,
347        DIV4_DDRP, DIV4_NR };
348
349 #define DIV4(_reg, _bit, _mask, _flags) \
350   SH_CLK_DIV4(&pllc1_clk, _reg, _bit, _mask, _flags)
351
352 static struct clk div4_clks[DIV4_NR] = {
353         [DIV4_I] = DIV4(FRQCRA, 20, 0x6fff, CLK_ENABLE_ON_INIT),
354         [DIV4_ZG] = DIV4(FRQCRA, 16, 0x6fff, CLK_ENABLE_ON_INIT),
355         [DIV4_B] = DIV4(FRQCRA, 8, 0x6fff, CLK_ENABLE_ON_INIT),
356         [DIV4_M1] = DIV4(FRQCRA, 4, 0x6fff, CLK_ENABLE_ON_INIT),
357         [DIV4_CSIR] = DIV4(FRQCRA, 0, 0x6fff, 0),
358         [DIV4_ZTR] = DIV4(FRQCRB, 20, 0x6fff, 0),
359         [DIV4_ZT] = DIV4(FRQCRB, 16, 0x6fff, 0),
360         [DIV4_ZX] = DIV4(FRQCRB, 12, 0x6fff, 0),
361         [DIV4_HP] = DIV4(FRQCRB, 4, 0x6fff, 0),
362         [DIV4_ISPB] = DIV4(FRQCRC, 20, 0x6fff, 0),
363         [DIV4_S] = DIV4(FRQCRC, 12, 0x6fff, 0),
364         [DIV4_ZB] = DIV4(FRQCRC, 8, 0x6fff, 0),
365         [DIV4_ZB3] = DIV4(FRQCRC, 4, 0x6fff, 0),
366         [DIV4_CP] = DIV4(FRQCRC, 0, 0x6fff, 0),
367         [DIV4_DDRP] = DIV4(FRQCRD, 0, 0x677c, 0),
368 };
369
370 enum { DIV6_VCK1, DIV6_VCK2, DIV6_VCK3, DIV6_FMSI, DIV6_FMSO,
371        DIV6_SUB, DIV6_SPU,
372        DIV6_VOU, DIV6_DSIT, DIV6_DSI0P, DIV6_DSI1P,
373        DIV6_NR };
374
375 static struct clk div6_clks[DIV6_NR] = {
376         [DIV6_VCK1] = SH_CLK_DIV6(&pllc1_div2_clk, VCLKCR1, 0),
377         [DIV6_VCK2] = SH_CLK_DIV6(&pllc1_div2_clk, VCLKCR2, 0),
378         [DIV6_VCK3] = SH_CLK_DIV6(&pllc1_div2_clk, VCLKCR3, 0),
379         [DIV6_FMSI] = SH_CLK_DIV6(&pllc1_div2_clk, FMSICKCR, 0),
380         [DIV6_FMSO] = SH_CLK_DIV6(&pllc1_div2_clk, FMSOCKCR, 0),
381         [DIV6_SUB] = SH_CLK_DIV6(&sh7372_extal2_clk, SUBCKCR, 0),
382         [DIV6_SPU] = SH_CLK_DIV6(&pllc1_div2_clk, SPUCKCR, 0),
383         [DIV6_VOU] = SH_CLK_DIV6(&pllc1_div2_clk, VOUCKCR, 0),
384         [DIV6_DSIT] = SH_CLK_DIV6(&pllc1_div2_clk, DSITCKCR, 0),
385         [DIV6_DSI0P] = SH_CLK_DIV6(&pllc1_div2_clk, DSI0PCKCR, 0),
386         [DIV6_DSI1P] = SH_CLK_DIV6(&pllc1_div2_clk, DSI1PCKCR, 0),
387 };
388
389 enum { DIV6_HDMI, DIV6_FSIA, DIV6_FSIB, DIV6_REPARENT_NR };
390
391 /* Indices are important - they are the actual src selecting values */
392 static struct clk *hdmi_parent[] = {
393         [0] = &pllc1_div2_clk,
394         [1] = &sh7372_pllc2_clk,
395         [2] = &sh7372_dv_clki_clk,
396         [3] = NULL,     /* pllc2_div4 not implemented yet */
397 };
398
399 static struct clk *fsiackcr_parent[] = {
400         [0] = &pllc1_div2_clk,
401         [1] = &sh7372_pllc2_clk,
402         [2] = &sh7372_fsiack_clk, /* external input for FSI A */
403         [3] = NULL,     /* setting prohibited */
404 };
405
406 static struct clk *fsibckcr_parent[] = {
407         [0] = &pllc1_div2_clk,
408         [1] = &sh7372_pllc2_clk,
409         [2] = &sh7372_fsibck_clk, /* external input for FSI B */
410         [3] = NULL,     /* setting prohibited */
411 };
412
413 static struct clk div6_reparent_clks[DIV6_REPARENT_NR] = {
414         [DIV6_HDMI] = SH_CLK_DIV6_EXT(&pllc1_div2_clk, HDMICKCR, 0,
415                                       hdmi_parent, ARRAY_SIZE(hdmi_parent), 6, 2),
416         [DIV6_FSIA] = SH_CLK_DIV6_EXT(&pllc1_div2_clk, FSIACKCR, 0,
417                                       fsiackcr_parent, ARRAY_SIZE(fsiackcr_parent), 6, 2),
418         [DIV6_FSIB] = SH_CLK_DIV6_EXT(&pllc1_div2_clk, FSIBCKCR, 0,
419                                       fsibckcr_parent, ARRAY_SIZE(fsibckcr_parent), 6, 2),
420 };
421
422 /* FSI DIV */
423 static unsigned long fsidiv_recalc(struct clk *clk)
424 {
425         unsigned long value;
426
427         value = __raw_readl(clk->mapping->base);
428
429         value >>= 16;
430         if (value < 2)
431                 return 0;
432
433         return clk->parent->rate / value;
434 }
435
436 static long fsidiv_round_rate(struct clk *clk, unsigned long rate)
437 {
438         return clk_rate_div_range_round(clk, 2, 0xffff, rate);
439 }
440
441 static void fsidiv_disable(struct clk *clk)
442 {
443         __raw_writel(0, clk->mapping->base);
444 }
445
446 static int fsidiv_enable(struct clk *clk)
447 {
448         unsigned long value;
449
450         value  = __raw_readl(clk->mapping->base) >> 16;
451         if (value < 2)
452                 return -EIO;
453
454         __raw_writel((value << 16) | 0x3, clk->mapping->base);
455
456         return 0;
457 }
458
459 static int fsidiv_set_rate(struct clk *clk, unsigned long rate)
460 {
461         int idx;
462
463         idx = (clk->parent->rate / rate) & 0xffff;
464         if (idx < 2)
465                 return -EINVAL;
466
467         __raw_writel(idx << 16, clk->mapping->base);
468         return 0;
469 }
470
471 static struct clk_ops fsidiv_clk_ops = {
472         .recalc         = fsidiv_recalc,
473         .round_rate     = fsidiv_round_rate,
474         .set_rate       = fsidiv_set_rate,
475         .enable         = fsidiv_enable,
476         .disable        = fsidiv_disable,
477 };
478
479 static struct clk_mapping sh7372_fsidiva_clk_mapping = {
480         .phys   = FSIDIVA,
481         .len    = 8,
482 };
483
484 struct clk sh7372_fsidiva_clk = {
485         .ops            = &fsidiv_clk_ops,
486         .parent         = &div6_reparent_clks[DIV6_FSIA], /* late install */
487         .mapping        = &sh7372_fsidiva_clk_mapping,
488 };
489
490 static struct clk_mapping sh7372_fsidivb_clk_mapping = {
491         .phys   = FSIDIVB,
492         .len    = 8,
493 };
494
495 struct clk sh7372_fsidivb_clk = {
496         .ops            = &fsidiv_clk_ops,
497         .parent         = &div6_reparent_clks[DIV6_FSIB],  /* late install */
498         .mapping        = &sh7372_fsidivb_clk_mapping,
499 };
500
501 static struct clk *late_main_clks[] = {
502         &sh7372_fsidiva_clk,
503         &sh7372_fsidivb_clk,
504 };
505
506 enum { MSTP001,
507        MSTP131, MSTP130,
508        MSTP129, MSTP128, MSTP127, MSTP126, MSTP125,
509        MSTP118, MSTP117, MSTP116, MSTP113,
510        MSTP106, MSTP101, MSTP100,
511        MSTP223,
512        MSTP218, MSTP217, MSTP216,
513        MSTP207, MSTP206, MSTP204, MSTP203, MSTP202, MSTP201, MSTP200,
514        MSTP329, MSTP328, MSTP323, MSTP322, MSTP314, MSTP313, MSTP312,
515        MSTP423, MSTP415, MSTP413, MSTP411, MSTP410, MSTP406, MSTP403,
516        MSTP_NR };
517
518 #define MSTP(_parent, _reg, _bit, _flags) \
519   SH_CLK_MSTP32(_parent, _reg, _bit, _flags)
520
521 static struct clk mstp_clks[MSTP_NR] = {
522         [MSTP001] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR0, 1, 0), /* IIC2 */
523         [MSTP131] = MSTP(&div4_clks[DIV4_B], SMSTPCR1, 31, 0), /* VEU3 */
524         [MSTP130] = MSTP(&div4_clks[DIV4_B], SMSTPCR1, 30, 0), /* VEU2 */
525         [MSTP129] = MSTP(&div4_clks[DIV4_B], SMSTPCR1, 29, 0), /* VEU1 */
526         [MSTP128] = MSTP(&div4_clks[DIV4_B], SMSTPCR1, 28, 0), /* VEU0 */
527         [MSTP127] = MSTP(&div4_clks[DIV4_B], SMSTPCR1, 27, 0), /* CEU */
528         [MSTP126] = MSTP(&div4_clks[DIV4_B], SMSTPCR1, 26, 0), /* CSI2 */
529         [MSTP125] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR1, 25, 0), /* TMU0 */
530         [MSTP118] = MSTP(&div4_clks[DIV4_B], SMSTPCR1, 18, 0), /* DSITX */
531         [MSTP117] = MSTP(&div4_clks[DIV4_B], SMSTPCR1, 17, 0), /* LCDC1 */
532         [MSTP116] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR1, 16, 0), /* IIC0 */
533         [MSTP113] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR1, 13, 0), /* MERAM */
534         [MSTP106] = MSTP(&div4_clks[DIV4_B], SMSTPCR1, 6, 0), /* JPU */
535         [MSTP101] = MSTP(&div4_clks[DIV4_M1], SMSTPCR1, 1, 0), /* VPU */
536         [MSTP100] = MSTP(&div4_clks[DIV4_B], SMSTPCR1, 0, 0), /* LCDC0 */
537         [MSTP223] = MSTP(&div6_clks[DIV6_SPU], SMSTPCR2, 23, 0), /* SPU2 */
538         [MSTP218] = MSTP(&div4_clks[DIV4_HP], SMSTPCR2, 18, 0), /* DMAC1 */
539         [MSTP217] = MSTP(&div4_clks[DIV4_HP], SMSTPCR2, 17, 0), /* DMAC2 */
540         [MSTP216] = MSTP(&div4_clks[DIV4_HP], SMSTPCR2, 16, 0), /* DMAC3 */
541         [MSTP207] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR2, 7, 0), /* SCIFA5 */
542         [MSTP206] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR2, 6, 0), /* SCIFB */
543         [MSTP204] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR2, 4, 0), /* SCIFA0 */
544         [MSTP203] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR2, 3, 0), /* SCIFA1 */
545         [MSTP202] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR2, 2, 0), /* SCIFA2 */
546         [MSTP201] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR2, 1, 0), /* SCIFA3 */
547         [MSTP200] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR2, 0, 0), /* SCIFA4 */
548         [MSTP329] = MSTP(&r_clk, SMSTPCR3, 29, 0), /* CMT10 */
549         [MSTP328] = MSTP(&div6_clks[DIV6_SPU], SMSTPCR3, 28, 0), /* FSI2 */
550         [MSTP323] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR3, 23, 0), /* IIC1 */
551         [MSTP322] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR3, 22, 0), /* USB0 */
552         [MSTP314] = MSTP(&div4_clks[DIV4_HP], SMSTPCR3, 14, 0), /* SDHI0 */
553         [MSTP313] = MSTP(&div4_clks[DIV4_HP], SMSTPCR3, 13, 0), /* SDHI1 */
554         [MSTP312] = MSTP(&div4_clks[DIV4_HP], SMSTPCR3, 12, 0), /* MMC */
555         [MSTP423] = MSTP(&div4_clks[DIV4_B], SMSTPCR4, 23, 0), /* DSITX1 */
556         [MSTP415] = MSTP(&div4_clks[DIV4_HP], SMSTPCR4, 15, 0), /* SDHI2 */
557         [MSTP413] = MSTP(&pllc1_div2_clk, SMSTPCR4, 13, 0), /* HDMI */
558         [MSTP411] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR4, 11, 0), /* IIC3 */
559         [MSTP410] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR4, 10, 0), /* IIC4 */
560         [MSTP406] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR4, 6, 0), /* USB1 */
561         [MSTP403] = MSTP(&r_clk, SMSTPCR4, 3, 0), /* KEYSC */
562 };
563
564 #define CLKDEV_CON_ID(_id, _clk) { .con_id = _id, .clk = _clk }
565 #define CLKDEV_DEV_ID(_id, _clk) { .dev_id = _id, .clk = _clk }
566 #define CLKDEV_ICK_ID(_cid, _did, _clk) { .con_id = _cid, .dev_id = _did, .clk = _clk }
567
568 static struct clk_lookup lookups[] = {
569         /* main clocks */
570         CLKDEV_CON_ID("dv_clki_div2_clk", &sh7372_dv_clki_div2_clk),
571         CLKDEV_CON_ID("r_clk", &r_clk),
572         CLKDEV_CON_ID("extal1", &sh7372_extal1_clk),
573         CLKDEV_CON_ID("extal2", &sh7372_extal2_clk),
574         CLKDEV_CON_ID("extal1_div2_clk", &extal1_div2_clk),
575         CLKDEV_CON_ID("extal2_div2_clk", &extal2_div2_clk),
576         CLKDEV_CON_ID("extal2_div4_clk", &extal2_div4_clk),
577         CLKDEV_CON_ID("pllc0_clk", &pllc0_clk),
578         CLKDEV_CON_ID("pllc1_clk", &pllc1_clk),
579         CLKDEV_CON_ID("pllc1_div2_clk", &pllc1_div2_clk),
580         CLKDEV_CON_ID("pllc2_clk", &sh7372_pllc2_clk),
581
582         /* DIV4 clocks */
583         CLKDEV_CON_ID("i_clk", &div4_clks[DIV4_I]),
584         CLKDEV_CON_ID("zg_clk", &div4_clks[DIV4_ZG]),
585         CLKDEV_CON_ID("b_clk", &div4_clks[DIV4_B]),
586         CLKDEV_CON_ID("m1_clk", &div4_clks[DIV4_M1]),
587         CLKDEV_CON_ID("csir_clk", &div4_clks[DIV4_CSIR]),
588         CLKDEV_CON_ID("ztr_clk", &div4_clks[DIV4_ZTR]),
589         CLKDEV_CON_ID("zt_clk", &div4_clks[DIV4_ZT]),
590         CLKDEV_CON_ID("zx_clk", &div4_clks[DIV4_ZX]),
591         CLKDEV_CON_ID("hp_clk", &div4_clks[DIV4_HP]),
592         CLKDEV_CON_ID("ispb_clk", &div4_clks[DIV4_ISPB]),
593         CLKDEV_CON_ID("s_clk", &div4_clks[DIV4_S]),
594         CLKDEV_CON_ID("zb_clk", &div4_clks[DIV4_ZB]),
595         CLKDEV_CON_ID("zb3_clk", &div4_clks[DIV4_ZB3]),
596         CLKDEV_CON_ID("cp_clk", &div4_clks[DIV4_CP]),
597         CLKDEV_CON_ID("ddrp_clk", &div4_clks[DIV4_DDRP]),
598
599         /* DIV6 clocks */
600         CLKDEV_CON_ID("vck1_clk", &div6_clks[DIV6_VCK1]),
601         CLKDEV_CON_ID("vck2_clk", &div6_clks[DIV6_VCK2]),
602         CLKDEV_CON_ID("vck3_clk", &div6_clks[DIV6_VCK3]),
603         CLKDEV_CON_ID("fmsi_clk", &div6_clks[DIV6_FMSI]),
604         CLKDEV_CON_ID("fmso_clk", &div6_clks[DIV6_FMSO]),
605         CLKDEV_CON_ID("sub_clk", &div6_clks[DIV6_SUB]),
606         CLKDEV_CON_ID("spu_clk", &div6_clks[DIV6_SPU]),
607         CLKDEV_CON_ID("vou_clk", &div6_clks[DIV6_VOU]),
608         CLKDEV_CON_ID("hdmi_clk", &div6_reparent_clks[DIV6_HDMI]),
609         CLKDEV_ICK_ID("dsit_clk", "sh-mipi-dsi.0", &div6_clks[DIV6_DSIT]),
610         CLKDEV_ICK_ID("dsit_clk", "sh-mipi-dsi.1", &div6_clks[DIV6_DSIT]),
611         CLKDEV_ICK_ID("dsi0p_clk", "sh-mipi-dsi.0", &div6_clks[DIV6_DSI0P]),
612         CLKDEV_ICK_ID("dsi1p_clk", "sh-mipi-dsi.1", &div6_clks[DIV6_DSI1P]),
613
614         /* MSTP32 clocks */
615         CLKDEV_DEV_ID("i2c-sh_mobile.2", &mstp_clks[MSTP001]), /* IIC2 */
616         CLKDEV_DEV_ID("uio_pdrv_genirq.4", &mstp_clks[MSTP131]), /* VEU3 */
617         CLKDEV_DEV_ID("uio_pdrv_genirq.3", &mstp_clks[MSTP130]), /* VEU2 */
618         CLKDEV_DEV_ID("uio_pdrv_genirq.2", &mstp_clks[MSTP129]), /* VEU1 */
619         CLKDEV_DEV_ID("uio_pdrv_genirq.1", &mstp_clks[MSTP128]), /* VEU0 */
620         CLKDEV_DEV_ID("sh_mobile_ceu.0", &mstp_clks[MSTP127]), /* CEU */
621         CLKDEV_DEV_ID("sh-mobile-csi2.0", &mstp_clks[MSTP126]), /* CSI2 */
622         CLKDEV_DEV_ID("sh_tmu.0", &mstp_clks[MSTP125]), /* TMU00 */
623         CLKDEV_DEV_ID("sh_tmu.1", &mstp_clks[MSTP125]), /* TMU01 */
624         CLKDEV_DEV_ID("sh-mipi-dsi.0", &mstp_clks[MSTP118]), /* DSITX0 */
625         CLKDEV_DEV_ID("sh_mobile_lcdc_fb.1", &mstp_clks[MSTP117]), /* LCDC1 */
626         CLKDEV_DEV_ID("i2c-sh_mobile.0", &mstp_clks[MSTP116]), /* IIC0 */
627         CLKDEV_DEV_ID("sh_mobile_meram.0", &mstp_clks[MSTP113]), /* MERAM */
628         CLKDEV_DEV_ID("uio_pdrv_genirq.5", &mstp_clks[MSTP106]), /* JPU */
629         CLKDEV_DEV_ID("uio_pdrv_genirq.0", &mstp_clks[MSTP101]), /* VPU */
630         CLKDEV_DEV_ID("sh_mobile_lcdc_fb.0", &mstp_clks[MSTP100]), /* LCDC0 */
631         CLKDEV_DEV_ID("uio_pdrv_genirq.6", &mstp_clks[MSTP223]), /* SPU2DSP0 */
632         CLKDEV_DEV_ID("uio_pdrv_genirq.7", &mstp_clks[MSTP223]), /* SPU2DSP1 */
633         CLKDEV_DEV_ID("sh-dma-engine.0", &mstp_clks[MSTP218]), /* DMAC1 */
634         CLKDEV_DEV_ID("sh-dma-engine.1", &mstp_clks[MSTP217]), /* DMAC2 */
635         CLKDEV_DEV_ID("sh-dma-engine.2", &mstp_clks[MSTP216]), /* DMAC3 */
636         CLKDEV_DEV_ID("sh-sci.5", &mstp_clks[MSTP207]), /* SCIFA5 */
637         CLKDEV_DEV_ID("sh-sci.6", &mstp_clks[MSTP206]), /* SCIFB */
638         CLKDEV_DEV_ID("sh-sci.0", &mstp_clks[MSTP204]), /* SCIFA0 */
639         CLKDEV_DEV_ID("sh-sci.1", &mstp_clks[MSTP203]), /* SCIFA1 */
640         CLKDEV_DEV_ID("sh-sci.2", &mstp_clks[MSTP202]), /* SCIFA2 */
641         CLKDEV_DEV_ID("sh-sci.3", &mstp_clks[MSTP201]), /* SCIFA3 */
642         CLKDEV_DEV_ID("sh-sci.4", &mstp_clks[MSTP200]), /* SCIFA4 */
643         CLKDEV_DEV_ID("sh_cmt.10", &mstp_clks[MSTP329]), /* CMT10 */
644         CLKDEV_DEV_ID("sh_fsi2", &mstp_clks[MSTP328]), /* FSI2 */
645         CLKDEV_DEV_ID("i2c-sh_mobile.1", &mstp_clks[MSTP323]), /* IIC1 */
646         CLKDEV_DEV_ID("r8a66597_hcd.0", &mstp_clks[MSTP322]), /* USB0 */
647         CLKDEV_DEV_ID("r8a66597_udc.0", &mstp_clks[MSTP322]), /* USB0 */
648         CLKDEV_DEV_ID("renesas_usbhs.0", &mstp_clks[MSTP322]), /* USB0 */
649         CLKDEV_DEV_ID("sh_mobile_sdhi.0", &mstp_clks[MSTP314]), /* SDHI0 */
650         CLKDEV_DEV_ID("sh_mobile_sdhi.1", &mstp_clks[MSTP313]), /* SDHI1 */
651         CLKDEV_DEV_ID("sh_mmcif.0", &mstp_clks[MSTP312]), /* MMC */
652         CLKDEV_DEV_ID("sh-mipi-dsi.1", &mstp_clks[MSTP423]), /* DSITX1 */
653         CLKDEV_DEV_ID("sh_mobile_sdhi.2", &mstp_clks[MSTP415]), /* SDHI2 */
654         CLKDEV_DEV_ID("sh-mobile-hdmi", &mstp_clks[MSTP413]), /* HDMI */
655         CLKDEV_DEV_ID("i2c-sh_mobile.3", &mstp_clks[MSTP411]), /* IIC3 */
656         CLKDEV_DEV_ID("i2c-sh_mobile.4", &mstp_clks[MSTP410]), /* IIC4 */
657         CLKDEV_DEV_ID("r8a66597_hcd.1", &mstp_clks[MSTP406]), /* USB1 */
658         CLKDEV_DEV_ID("r8a66597_udc.1", &mstp_clks[MSTP406]), /* USB1 */
659         CLKDEV_DEV_ID("renesas_usbhs.1", &mstp_clks[MSTP406]), /* USB1 */
660         CLKDEV_DEV_ID("sh_keysc.0", &mstp_clks[MSTP403]), /* KEYSC */
661
662         CLKDEV_ICK_ID("ick", "sh-mobile-hdmi", &div6_reparent_clks[DIV6_HDMI]),
663         CLKDEV_ICK_ID("icka", "sh_fsi2", &div6_reparent_clks[DIV6_FSIA]),
664         CLKDEV_ICK_ID("ickb", "sh_fsi2", &div6_reparent_clks[DIV6_FSIB]),
665         CLKDEV_ICK_ID("spu2", "sh_fsi2", &mstp_clks[MSTP223]),
666 };
667
668 void __init sh7372_clock_init(void)
669 {
670         int k, ret = 0;
671
672         /* make sure MSTP bits on the RT/SH4AL-DSP side are off */
673         __raw_writel(0xe4ef8087, RMSTPCR0);
674         __raw_writel(0xffffffff, RMSTPCR1);
675         __raw_writel(0x37c7f7ff, RMSTPCR2);
676         __raw_writel(0xffffffff, RMSTPCR3);
677         __raw_writel(0xffe0fffd, RMSTPCR4);
678
679         for (k = 0; !ret && (k < ARRAY_SIZE(main_clks)); k++)
680                 ret = clk_register(main_clks[k]);
681
682         if (!ret)
683                 ret = sh_clk_div4_register(div4_clks, DIV4_NR, &div4_table);
684
685         if (!ret)
686                 ret = sh_clk_div6_register(div6_clks, DIV6_NR);
687
688         if (!ret)
689                 ret = sh_clk_div6_reparent_register(div6_reparent_clks, DIV6_REPARENT_NR);
690
691         if (!ret)
692                 ret = sh_clk_mstp32_register(mstp_clks, MSTP_NR);
693
694         for (k = 0; !ret && (k < ARRAY_SIZE(late_main_clks)); k++)
695                 ret = clk_register(late_main_clks[k]);
696
697         clkdev_add_table(lookups, ARRAY_SIZE(lookups));
698
699         if (!ret)
700                 clk_init();
701         else
702                 panic("failed to setup sh7372 clocks\n");
703
704 }