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