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