s390/pgtable: fix ipte notify bit
[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          IOMEM(0xe6150000)
28 #define FRQCRB          IOMEM(0xe6150004)
29 #define FRQCRC          IOMEM(0xe61500e0)
30 #define FRQCRD          IOMEM(0xe61500e4)
31 #define VCLKCR1         IOMEM(0xe6150008)
32 #define VCLKCR2         IOMEM(0xe615000c)
33 #define VCLKCR3         IOMEM(0xe615001c)
34 #define FMSICKCR        IOMEM(0xe6150010)
35 #define FMSOCKCR        IOMEM(0xe6150014)
36 #define FSIACKCR        IOMEM(0xe6150018)
37 #define FSIBCKCR        IOMEM(0xe6150090)
38 #define SUBCKCR         IOMEM(0xe6150080)
39 #define SPUCKCR         IOMEM(0xe6150084)
40 #define VOUCKCR         IOMEM(0xe6150088)
41 #define HDMICKCR        IOMEM(0xe6150094)
42 #define DSITCKCR        IOMEM(0xe6150060)
43 #define DSI0PCKCR       IOMEM(0xe6150064)
44 #define DSI1PCKCR       IOMEM(0xe6150098)
45 #define PLLC01CR        IOMEM(0xe6150028)
46 #define PLLC2CR         IOMEM(0xe615002c)
47 #define RMSTPCR0        IOMEM(0xe6150110)
48 #define RMSTPCR1        IOMEM(0xe6150114)
49 #define RMSTPCR2        IOMEM(0xe6150118)
50 #define RMSTPCR3        IOMEM(0xe615011c)
51 #define RMSTPCR4        IOMEM(0xe6150120)
52 #define SMSTPCR0        IOMEM(0xe6150130)
53 #define SMSTPCR1        IOMEM(0xe6150134)
54 #define SMSTPCR2        IOMEM(0xe6150138)
55 #define SMSTPCR3        IOMEM(0xe615013c)
56 #define SMSTPCR4        IOMEM(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 sh_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 sh_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 sh_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 static struct clk fsiack_clk = {
299 };
300
301 static struct clk 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         &fsiack_clk,
318         &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] = &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] = &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(HDMICKCR, 0,
415                                       hdmi_parent, ARRAY_SIZE(hdmi_parent), 6, 2),
416         [DIV6_FSIA] = SH_CLK_DIV6_EXT(FSIACKCR, 0,
417                                       fsiackcr_parent, ARRAY_SIZE(fsiackcr_parent), 6, 2),
418         [DIV6_FSIB] = SH_CLK_DIV6_EXT(FSIBCKCR, 0,
419                                       fsibckcr_parent, ARRAY_SIZE(fsibckcr_parent), 6, 2),
420 };
421
422 /* FSI DIV */
423 enum { FSIDIV_A, FSIDIV_B, FSIDIV_REPARENT_NR };
424
425 static struct clk fsidivs[] = {
426         [FSIDIV_A] = SH_CLK_FSIDIV(FSIDIVA, &div6_reparent_clks[DIV6_FSIA]),
427         [FSIDIV_B] = SH_CLK_FSIDIV(FSIDIVB, &div6_reparent_clks[DIV6_FSIB]),
428 };
429
430 enum { MSTP001, MSTP000,
431        MSTP131, MSTP130,
432        MSTP129, MSTP128, MSTP127, MSTP126, MSTP125,
433        MSTP118, MSTP117, MSTP116, MSTP113,
434        MSTP106, MSTP101, MSTP100,
435        MSTP223,
436        MSTP218, MSTP217, MSTP216, MSTP214, MSTP208, MSTP207,
437        MSTP206, MSTP205, MSTP204, MSTP203, MSTP202, MSTP201, MSTP200,
438         MSTP328, MSTP323, MSTP322, MSTP315, MSTP314, MSTP313, MSTP312,
439        MSTP423, MSTP415, MSTP413, MSTP411, MSTP410, MSTP407, MSTP406,
440        MSTP405, MSTP404, MSTP403, MSTP400,
441        MSTP_NR };
442
443 #define MSTP(_parent, _reg, _bit, _flags) \
444   SH_CLK_MSTP32(_parent, _reg, _bit, _flags)
445
446 static struct clk mstp_clks[MSTP_NR] = {
447         [MSTP001] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR0, 1, 0), /* IIC2 */
448         [MSTP000] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR0, 0, 0), /* MSIOF0 */
449         [MSTP131] = MSTP(&div4_clks[DIV4_B], SMSTPCR1, 31, 0), /* VEU3 */
450         [MSTP130] = MSTP(&div4_clks[DIV4_B], SMSTPCR1, 30, 0), /* VEU2 */
451         [MSTP129] = MSTP(&div4_clks[DIV4_B], SMSTPCR1, 29, 0), /* VEU1 */
452         [MSTP128] = MSTP(&div4_clks[DIV4_B], SMSTPCR1, 28, 0), /* VEU0 */
453         [MSTP127] = MSTP(&div4_clks[DIV4_B], SMSTPCR1, 27, 0), /* CEU */
454         [MSTP126] = MSTP(&div4_clks[DIV4_B], SMSTPCR1, 26, 0), /* CSI2 */
455         [MSTP125] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR1, 25, 0), /* TMU0 */
456         [MSTP118] = MSTP(&div4_clks[DIV4_B], SMSTPCR1, 18, 0), /* DSITX */
457         [MSTP117] = MSTP(&div4_clks[DIV4_B], SMSTPCR1, 17, 0), /* LCDC1 */
458         [MSTP116] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR1, 16, 0), /* IIC0 */
459         [MSTP113] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR1, 13, 0), /* MERAM */
460         [MSTP106] = MSTP(&div4_clks[DIV4_B], SMSTPCR1, 6, 0), /* JPU */
461         [MSTP101] = MSTP(&div4_clks[DIV4_M1], SMSTPCR1, 1, 0), /* VPU */
462         [MSTP100] = MSTP(&div4_clks[DIV4_B], SMSTPCR1, 0, 0), /* LCDC0 */
463         [MSTP223] = MSTP(&div6_clks[DIV6_SPU], SMSTPCR2, 23, 0), /* SPU2 */
464         [MSTP218] = MSTP(&div4_clks[DIV4_HP], SMSTPCR2, 18, 0), /* DMAC1 */
465         [MSTP217] = MSTP(&div4_clks[DIV4_HP], SMSTPCR2, 17, 0), /* DMAC2 */
466         [MSTP216] = MSTP(&div4_clks[DIV4_HP], SMSTPCR2, 16, 0), /* DMAC3 */
467         [MSTP214] = MSTP(&div4_clks[DIV4_HP], SMSTPCR2, 14, 0), /* USBDMAC */
468         [MSTP208] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR2, 8, 0), /* MSIOF1 */
469         [MSTP207] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR2, 7, 0), /* SCIFA5 */
470         [MSTP206] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR2, 6, 0), /* SCIFB */
471         [MSTP205] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR2, 5, 0), /* MSIOF2 */
472         [MSTP204] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR2, 4, 0), /* SCIFA0 */
473         [MSTP203] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR2, 3, 0), /* SCIFA1 */
474         [MSTP202] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR2, 2, 0), /* SCIFA2 */
475         [MSTP201] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR2, 1, 0), /* SCIFA3 */
476         [MSTP200] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR2, 0, 0), /* SCIFA4 */
477         [MSTP328] = MSTP(&div6_clks[DIV6_SPU], SMSTPCR3, 28, 0), /* FSI2 */
478         [MSTP323] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR3, 23, 0), /* IIC1 */
479         [MSTP322] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR3, 22, 0), /* USB0 */
480         [MSTP315] = MSTP(&div4_clks[DIV4_HP], SMSTPCR3, 15, 0), /* FLCTL*/
481         [MSTP314] = MSTP(&div4_clks[DIV4_HP], SMSTPCR3, 14, 0), /* SDHI0 */
482         [MSTP313] = MSTP(&div4_clks[DIV4_HP], SMSTPCR3, 13, 0), /* SDHI1 */
483         [MSTP312] = MSTP(&div4_clks[DIV4_HP], SMSTPCR3, 12, 0), /* MMC */
484         [MSTP423] = MSTP(&div4_clks[DIV4_B], SMSTPCR4, 23, 0), /* DSITX1 */
485         [MSTP415] = MSTP(&div4_clks[DIV4_HP], SMSTPCR4, 15, 0), /* SDHI2 */
486         [MSTP413] = MSTP(&pllc1_div2_clk, SMSTPCR4, 13, 0), /* HDMI */
487         [MSTP411] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR4, 11, 0), /* IIC3 */
488         [MSTP410] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR4, 10, 0), /* IIC4 */
489         [MSTP407] = MSTP(&div4_clks[DIV4_HP], SMSTPCR4, 7, 0), /* USB-DMAC1 */
490         [MSTP406] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR4, 6, 0), /* USB1 */
491         [MSTP405] = MSTP(&r_clk, SMSTPCR4, 5, 0), /* CMT4 */
492         [MSTP404] = MSTP(&r_clk, SMSTPCR4, 4, 0), /* CMT3 */
493         [MSTP403] = MSTP(&r_clk, SMSTPCR4, 3, 0), /* KEYSC */
494         [MSTP400] = MSTP(&r_clk, SMSTPCR4, 0, 0), /* CMT2 */
495 };
496
497 static struct clk_lookup lookups[] = {
498         /* main clocks */
499         CLKDEV_CON_ID("dv_clki_div2_clk", &sh7372_dv_clki_div2_clk),
500         CLKDEV_CON_ID("r_clk", &r_clk),
501         CLKDEV_CON_ID("extal1", &sh7372_extal1_clk),
502         CLKDEV_CON_ID("extal2", &sh7372_extal2_clk),
503         CLKDEV_CON_ID("extal1_div2_clk", &extal1_div2_clk),
504         CLKDEV_CON_ID("extal2_div2_clk", &extal2_div2_clk),
505         CLKDEV_CON_ID("extal2_div4_clk", &extal2_div4_clk),
506         CLKDEV_CON_ID("pllc0_clk", &pllc0_clk),
507         CLKDEV_CON_ID("pllc1_clk", &pllc1_clk),
508         CLKDEV_CON_ID("pllc1_div2_clk", &pllc1_div2_clk),
509         CLKDEV_CON_ID("pllc2_clk", &sh7372_pllc2_clk),
510         CLKDEV_CON_ID("fsiack", &fsiack_clk),
511         CLKDEV_CON_ID("fsibck", &fsibck_clk),
512
513         /* DIV4 clocks */
514         CLKDEV_CON_ID("i_clk", &div4_clks[DIV4_I]),
515         CLKDEV_CON_ID("zg_clk", &div4_clks[DIV4_ZG]),
516         CLKDEV_CON_ID("b_clk", &div4_clks[DIV4_B]),
517         CLKDEV_CON_ID("m1_clk", &div4_clks[DIV4_M1]),
518         CLKDEV_CON_ID("csir_clk", &div4_clks[DIV4_CSIR]),
519         CLKDEV_CON_ID("ztr_clk", &div4_clks[DIV4_ZTR]),
520         CLKDEV_CON_ID("zt_clk", &div4_clks[DIV4_ZT]),
521         CLKDEV_CON_ID("zx_clk", &div4_clks[DIV4_ZX]),
522         CLKDEV_CON_ID("hp_clk", &div4_clks[DIV4_HP]),
523         CLKDEV_CON_ID("ispb_clk", &div4_clks[DIV4_ISPB]),
524         CLKDEV_CON_ID("s_clk", &div4_clks[DIV4_S]),
525         CLKDEV_CON_ID("zb_clk", &div4_clks[DIV4_ZB]),
526         CLKDEV_CON_ID("zb3_clk", &div4_clks[DIV4_ZB3]),
527         CLKDEV_CON_ID("cp_clk", &div4_clks[DIV4_CP]),
528         CLKDEV_CON_ID("ddrp_clk", &div4_clks[DIV4_DDRP]),
529
530         /* DIV6 clocks */
531         CLKDEV_CON_ID("vck1_clk", &div6_clks[DIV6_VCK1]),
532         CLKDEV_CON_ID("vck2_clk", &div6_clks[DIV6_VCK2]),
533         CLKDEV_CON_ID("vck3_clk", &div6_clks[DIV6_VCK3]),
534         CLKDEV_CON_ID("fmsi_clk", &div6_clks[DIV6_FMSI]),
535         CLKDEV_CON_ID("fmso_clk", &div6_clks[DIV6_FMSO]),
536         CLKDEV_CON_ID("sub_clk", &div6_clks[DIV6_SUB]),
537         CLKDEV_CON_ID("spu_clk", &div6_clks[DIV6_SPU]),
538         CLKDEV_CON_ID("vou_clk", &div6_clks[DIV6_VOU]),
539         CLKDEV_CON_ID("hdmi_clk", &div6_reparent_clks[DIV6_HDMI]),
540         CLKDEV_ICK_ID("dsit_clk", "sh-mipi-dsi.0", &div6_clks[DIV6_DSIT]),
541         CLKDEV_ICK_ID("dsit_clk", "sh-mipi-dsi.1", &div6_clks[DIV6_DSIT]),
542         CLKDEV_ICK_ID("dsip_clk", "sh-mipi-dsi.0", &div6_clks[DIV6_DSI0P]),
543         CLKDEV_ICK_ID("dsip_clk", "sh-mipi-dsi.1", &div6_clks[DIV6_DSI1P]),
544
545         /* MSTP32 clocks */
546         CLKDEV_DEV_ID("i2c-sh_mobile.2", &mstp_clks[MSTP001]), /* IIC2 */
547         CLKDEV_DEV_ID("fff30000.i2c", &mstp_clks[MSTP001]), /* IIC2 */
548         CLKDEV_DEV_ID("spi_sh_msiof.0", &mstp_clks[MSTP000]), /* MSIOF0 */
549         CLKDEV_DEV_ID("uio_pdrv_genirq.4", &mstp_clks[MSTP131]), /* VEU3 */
550         CLKDEV_DEV_ID("uio_pdrv_genirq.3", &mstp_clks[MSTP130]), /* VEU2 */
551         CLKDEV_DEV_ID("uio_pdrv_genirq.2", &mstp_clks[MSTP129]), /* VEU1 */
552         CLKDEV_DEV_ID("uio_pdrv_genirq.1", &mstp_clks[MSTP128]), /* VEU0 */
553         CLKDEV_DEV_ID("sh_mobile_ceu.0", &mstp_clks[MSTP127]), /* CEU */
554         CLKDEV_DEV_ID("sh-mobile-csi2.0", &mstp_clks[MSTP126]), /* CSI2 */
555         CLKDEV_DEV_ID("sh_tmu.0", &mstp_clks[MSTP125]), /* TMU00 */
556         CLKDEV_DEV_ID("sh_tmu.1", &mstp_clks[MSTP125]), /* TMU01 */
557         CLKDEV_DEV_ID("sh-mipi-dsi.0", &mstp_clks[MSTP118]), /* DSITX0 */
558         CLKDEV_DEV_ID("sh_mobile_lcdc_fb.1", &mstp_clks[MSTP117]), /* LCDC1 */
559         CLKDEV_DEV_ID("i2c-sh_mobile.0", &mstp_clks[MSTP116]), /* IIC0 */
560         CLKDEV_DEV_ID("fff20000.i2c", &mstp_clks[MSTP116]), /* IIC0 */
561         CLKDEV_DEV_ID("sh_mobile_meram.0", &mstp_clks[MSTP113]), /* MERAM */
562         CLKDEV_DEV_ID("uio_pdrv_genirq.5", &mstp_clks[MSTP106]), /* JPU */
563         CLKDEV_DEV_ID("uio_pdrv_genirq.0", &mstp_clks[MSTP101]), /* VPU */
564         CLKDEV_DEV_ID("sh_mobile_lcdc_fb.0", &mstp_clks[MSTP100]), /* LCDC0 */
565         CLKDEV_DEV_ID("uio_pdrv_genirq.6", &mstp_clks[MSTP223]), /* SPU2DSP0 */
566         CLKDEV_DEV_ID("uio_pdrv_genirq.7", &mstp_clks[MSTP223]), /* SPU2DSP1 */
567         CLKDEV_DEV_ID("sh-dma-engine.0", &mstp_clks[MSTP218]), /* DMAC1 */
568         CLKDEV_DEV_ID("sh-dma-engine.1", &mstp_clks[MSTP217]), /* DMAC2 */
569         CLKDEV_DEV_ID("sh-dma-engine.2", &mstp_clks[MSTP216]), /* DMAC3 */
570         CLKDEV_DEV_ID("sh-dma-engine.3", &mstp_clks[MSTP214]), /* USB-DMAC0 */
571         CLKDEV_DEV_ID("spi_sh_msiof.1", &mstp_clks[MSTP208]), /* MSIOF1 */
572         CLKDEV_DEV_ID("sh-sci.5", &mstp_clks[MSTP207]), /* SCIFA5 */
573         CLKDEV_DEV_ID("sh-sci.6", &mstp_clks[MSTP206]), /* SCIFB */
574         CLKDEV_DEV_ID("spi_sh_msiof.2", &mstp_clks[MSTP205]), /* MSIOF2 */
575         CLKDEV_DEV_ID("sh-sci.0", &mstp_clks[MSTP204]), /* SCIFA0 */
576         CLKDEV_DEV_ID("sh-sci.1", &mstp_clks[MSTP203]), /* SCIFA1 */
577         CLKDEV_DEV_ID("sh-sci.2", &mstp_clks[MSTP202]), /* SCIFA2 */
578         CLKDEV_DEV_ID("sh-sci.3", &mstp_clks[MSTP201]), /* SCIFA3 */
579         CLKDEV_DEV_ID("sh-sci.4", &mstp_clks[MSTP200]), /* SCIFA4 */
580         CLKDEV_DEV_ID("sh_fsi2", &mstp_clks[MSTP328]), /* FSI2 */
581         CLKDEV_DEV_ID("i2c-sh_mobile.1", &mstp_clks[MSTP323]), /* IIC1 */
582         CLKDEV_DEV_ID("e6c20000.i2c", &mstp_clks[MSTP323]), /* IIC1 */
583         CLKDEV_DEV_ID("r8a66597_hcd.0", &mstp_clks[MSTP322]), /* USB0 */
584         CLKDEV_DEV_ID("r8a66597_udc.0", &mstp_clks[MSTP322]), /* USB0 */
585         CLKDEV_DEV_ID("renesas_usbhs.0", &mstp_clks[MSTP322]), /* USB0 */
586         CLKDEV_DEV_ID("sh_flctl.0", &mstp_clks[MSTP315]), /* FLCTL */
587         CLKDEV_DEV_ID("sh_mobile_sdhi.0", &mstp_clks[MSTP314]), /* SDHI0 */
588         CLKDEV_DEV_ID("e6850000.sdhi", &mstp_clks[MSTP314]), /* SDHI0 */
589         CLKDEV_DEV_ID("sh_mobile_sdhi.1", &mstp_clks[MSTP313]), /* SDHI1 */
590         CLKDEV_DEV_ID("e6860000.sdhi", &mstp_clks[MSTP313]), /* SDHI1 */
591         CLKDEV_DEV_ID("sh_mmcif.0", &mstp_clks[MSTP312]), /* MMC */
592         CLKDEV_DEV_ID("e6bd0000.mmcif", &mstp_clks[MSTP312]), /* MMC */
593         CLKDEV_DEV_ID("sh-mipi-dsi.1", &mstp_clks[MSTP423]), /* DSITX1 */
594         CLKDEV_DEV_ID("sh_mobile_sdhi.2", &mstp_clks[MSTP415]), /* SDHI2 */
595         CLKDEV_DEV_ID("e6870000.sdhi", &mstp_clks[MSTP415]), /* SDHI2 */
596         CLKDEV_DEV_ID("sh-mobile-hdmi", &mstp_clks[MSTP413]), /* HDMI */
597         CLKDEV_DEV_ID("i2c-sh_mobile.3", &mstp_clks[MSTP411]), /* IIC3 */
598         CLKDEV_DEV_ID("e6d20000.i2c", &mstp_clks[MSTP411]), /* IIC3 */
599         CLKDEV_DEV_ID("i2c-sh_mobile.4", &mstp_clks[MSTP410]), /* IIC4 */
600         CLKDEV_DEV_ID("e6d30000.i2c", &mstp_clks[MSTP410]), /* IIC4 */
601         CLKDEV_DEV_ID("sh-dma-engine.4", &mstp_clks[MSTP407]), /* USB-DMAC1 */
602         CLKDEV_DEV_ID("r8a66597_hcd.1", &mstp_clks[MSTP406]), /* USB1 */
603         CLKDEV_DEV_ID("r8a66597_udc.1", &mstp_clks[MSTP406]), /* USB1 */
604         CLKDEV_DEV_ID("renesas_usbhs.1", &mstp_clks[MSTP406]), /* USB1 */
605         CLKDEV_DEV_ID("sh_cmt.4", &mstp_clks[MSTP405]), /* CMT4 */
606         CLKDEV_DEV_ID("sh_cmt.3", &mstp_clks[MSTP404]), /* CMT3 */
607         CLKDEV_DEV_ID("sh_keysc.0", &mstp_clks[MSTP403]), /* KEYSC */
608         CLKDEV_DEV_ID("sh_cmt.2", &mstp_clks[MSTP400]), /* CMT2 */
609
610         CLKDEV_ICK_ID("hdmi", "sh_mobile_lcdc_fb.1",
611                       &div6_reparent_clks[DIV6_HDMI]),
612         CLKDEV_ICK_ID("ick", "sh-mobile-hdmi", &div6_reparent_clks[DIV6_HDMI]),
613         CLKDEV_ICK_ID("icka", "sh_fsi2", &div6_reparent_clks[DIV6_FSIA]),
614         CLKDEV_ICK_ID("ickb", "sh_fsi2", &div6_reparent_clks[DIV6_FSIB]),
615         CLKDEV_ICK_ID("spu2", "sh_fsi2", &mstp_clks[MSTP223]),
616         CLKDEV_ICK_ID("diva", "sh_fsi2", &fsidivs[FSIDIV_A]),
617         CLKDEV_ICK_ID("divb", "sh_fsi2", &fsidivs[FSIDIV_B]),
618         CLKDEV_ICK_ID("xcka", "sh_fsi2", &fsiack_clk),
619         CLKDEV_ICK_ID("xckb", "sh_fsi2", &fsibck_clk),
620 };
621
622 void __init sh7372_clock_init(void)
623 {
624         int k, ret = 0;
625
626         /* make sure MSTP bits on the RT/SH4AL-DSP side are off */
627         __raw_writel(0xe4ef8087, RMSTPCR0);
628         __raw_writel(0xffffffff, RMSTPCR1);
629         __raw_writel(0x37c7f7ff, RMSTPCR2);
630         __raw_writel(0xffffffff, RMSTPCR3);
631         __raw_writel(0xffe0fffd, RMSTPCR4);
632
633         for (k = 0; !ret && (k < ARRAY_SIZE(main_clks)); k++)
634                 ret = clk_register(main_clks[k]);
635
636         if (!ret)
637                 ret = sh_clk_div4_register(div4_clks, DIV4_NR, &div4_table);
638
639         if (!ret)
640                 ret = sh_clk_div6_register(div6_clks, DIV6_NR);
641
642         if (!ret)
643                 ret = sh_clk_div6_reparent_register(div6_reparent_clks, DIV6_REPARENT_NR);
644
645         if (!ret)
646                 ret = sh_clk_mstp_register(mstp_clks, MSTP_NR);
647
648         if (!ret)
649                 ret = sh_clk_fsidiv_register(fsidivs, FSIDIV_REPARENT_NR);
650
651         clkdev_add_table(lookups, ARRAY_SIZE(lookups));
652
653         if (!ret)
654                 shmobile_clk_init();
655         else
656                 panic("failed to setup sh7372 clocks\n");
657
658 }