]> git.kernelconcepts.de Git - karo-tx-linux.git/blob - arch/arm/mach-shmobile/clock-sh73a0.c
module: Fix locking in symbol_put_addr()
[karo-tx-linux.git] / arch / arm / mach-shmobile / clock-sh73a0.c
1 /*
2  * sh73a0 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 <asm/processor.h>
21 #include "clock.h"
22 #include "common.h"
23
24 #define FRQCRA          IOMEM(0xe6150000)
25 #define FRQCRB          IOMEM(0xe6150004)
26 #define FRQCRD          IOMEM(0xe61500e4)
27 #define VCLKCR1         IOMEM(0xe6150008)
28 #define VCLKCR2         IOMEM(0xe615000C)
29 #define VCLKCR3         IOMEM(0xe615001C)
30 #define ZBCKCR          IOMEM(0xe6150010)
31 #define FLCKCR          IOMEM(0xe6150014)
32 #define SD0CKCR         IOMEM(0xe6150074)
33 #define SD1CKCR         IOMEM(0xe6150078)
34 #define SD2CKCR         IOMEM(0xe615007C)
35 #define FSIACKCR        IOMEM(0xe6150018)
36 #define FSIBCKCR        IOMEM(0xe6150090)
37 #define SUBCKCR         IOMEM(0xe6150080)
38 #define SPUACKCR        IOMEM(0xe6150084)
39 #define SPUVCKCR        IOMEM(0xe6150094)
40 #define MSUCKCR         IOMEM(0xe6150088)
41 #define HSICKCR         IOMEM(0xe615008C)
42 #define MFCK1CR         IOMEM(0xe6150098)
43 #define MFCK2CR         IOMEM(0xe615009C)
44 #define DSITCKCR        IOMEM(0xe6150060)
45 #define DSI0PCKCR       IOMEM(0xe6150064)
46 #define DSI1PCKCR       IOMEM(0xe6150068)
47 #define DSI0PHYCR       0xe615006C
48 #define DSI1PHYCR       0xe6150070
49 #define PLLECR          IOMEM(0xe61500d0)
50 #define PLL0CR          IOMEM(0xe61500d8)
51 #define PLL1CR          IOMEM(0xe6150028)
52 #define PLL2CR          IOMEM(0xe615002c)
53 #define PLL3CR          IOMEM(0xe61500dc)
54 #define SMSTPCR0        IOMEM(0xe6150130)
55 #define SMSTPCR1        IOMEM(0xe6150134)
56 #define SMSTPCR2        IOMEM(0xe6150138)
57 #define SMSTPCR3        IOMEM(0xe615013c)
58 #define SMSTPCR4        IOMEM(0xe6150140)
59 #define SMSTPCR5        IOMEM(0xe6150144)
60 #define CKSCR           IOMEM(0xe61500c0)
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 sh73a0_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 sh73a0_extal2_clk = {
80         .rate           = 48000000,
81 };
82
83 static struct sh_clk_ops main_clk_ops = {
84         .recalc         = followparent_recalc,
85 };
86
87 /* Main clock */
88 static struct clk main_clk = {
89         /* .parent wll be set on sh73a0_clock_init() */
90         .ops            = &main_clk_ops,
91 };
92
93 /* PLL0, PLL1, PLL2, PLL3 */
94 static unsigned long pll_recalc(struct clk *clk)
95 {
96         unsigned long mult = 1;
97
98         if (__raw_readl(PLLECR) & (1 << clk->enable_bit)) {
99                 mult = (((__raw_readl(clk->enable_reg) >> 24) & 0x3f) + 1);
100                 /* handle CFG bit for PLL1 and PLL2 */
101                 switch (clk->enable_bit) {
102                 case 1:
103                 case 2:
104                         if (__raw_readl(clk->enable_reg) & (1 << 20))
105                                 mult *= 2;
106                 }
107         }
108
109         return clk->parent->rate * mult;
110 }
111
112 static struct sh_clk_ops pll_clk_ops = {
113         .recalc         = pll_recalc,
114 };
115
116 static struct clk pll0_clk = {
117         .ops            = &pll_clk_ops,
118         .flags          = CLK_ENABLE_ON_INIT,
119         .parent         = &main_clk,
120         .enable_reg     = (void __iomem *)PLL0CR,
121         .enable_bit     = 0,
122 };
123
124 static struct clk pll1_clk = {
125         .ops            = &pll_clk_ops,
126         .flags          = CLK_ENABLE_ON_INIT,
127         .parent         = &main_clk,
128         .enable_reg     = (void __iomem *)PLL1CR,
129         .enable_bit     = 1,
130 };
131
132 static struct clk pll2_clk = {
133         .ops            = &pll_clk_ops,
134         .flags          = CLK_ENABLE_ON_INIT,
135         .parent         = &main_clk,
136         .enable_reg     = (void __iomem *)PLL2CR,
137         .enable_bit     = 2,
138 };
139
140 static struct clk pll3_clk = {
141         .ops            = &pll_clk_ops,
142         .flags          = CLK_ENABLE_ON_INIT,
143         .parent         = &main_clk,
144         .enable_reg     = (void __iomem *)PLL3CR,
145         .enable_bit     = 3,
146 };
147
148 /* A fixed divide block */
149 SH_CLK_RATIO(div2,  1, 2);
150 SH_CLK_RATIO(div7,  1, 7);
151 SH_CLK_RATIO(div13, 1, 13);
152
153 SH_FIXED_RATIO_CLK(extal1_div2_clk,     sh73a0_extal1_clk,      div2);
154 SH_FIXED_RATIO_CLK(extal2_div2_clk,     sh73a0_extal2_clk,      div2);
155 SH_FIXED_RATIO_CLK(main_div2_clk,       main_clk,               div2);
156 SH_FIXED_RATIO_CLK(pll1_div2_clk,       pll1_clk,               div2);
157 SH_FIXED_RATIO_CLK(pll1_div7_clk,       pll1_clk,               div7);
158 SH_FIXED_RATIO_CLK(pll1_div13_clk,      pll1_clk,               div13);
159
160 /* External input clock */
161 struct clk sh73a0_extcki_clk = {
162 };
163
164 struct clk sh73a0_extalr_clk = {
165 };
166
167 static struct clk *main_clks[] = {
168         &r_clk,
169         &sh73a0_extal1_clk,
170         &sh73a0_extal2_clk,
171         &extal1_div2_clk,
172         &extal2_div2_clk,
173         &main_clk,
174         &main_div2_clk,
175         &pll0_clk,
176         &pll1_clk,
177         &pll2_clk,
178         &pll3_clk,
179         &pll1_div2_clk,
180         &pll1_div7_clk,
181         &pll1_div13_clk,
182         &sh73a0_extcki_clk,
183         &sh73a0_extalr_clk,
184 };
185
186 static int frqcr_kick(void)
187 {
188         int i;
189
190         /* set KICK bit in FRQCRB to update hardware setting, check success */
191         __raw_writel(__raw_readl(FRQCRB) | (1 << 31), FRQCRB);
192         for (i = 1000; i; i--)
193                 if (__raw_readl(FRQCRB) & (1 << 31))
194                         cpu_relax();
195                 else
196                         return i;
197
198         return -ETIMEDOUT;
199 }
200
201 static void div4_kick(struct clk *clk)
202 {
203         frqcr_kick();
204 }
205
206 static int divisors[] = { 2, 3, 4, 6, 8, 12, 16, 18,
207                           24, 0, 36, 48, 7 };
208
209 static struct clk_div_mult_table div4_div_mult_table = {
210         .divisors = divisors,
211         .nr_divisors = ARRAY_SIZE(divisors),
212 };
213
214 static struct clk_div4_table div4_table = {
215         .div_mult_table = &div4_div_mult_table,
216         .kick = div4_kick,
217 };
218
219 enum { DIV4_I, DIV4_ZG, DIV4_M3, DIV4_B, DIV4_M1, DIV4_M2,
220         DIV4_Z, DIV4_ZX, DIV4_HP, DIV4_NR };
221
222 #define DIV4(_reg, _bit, _mask, _flags) \
223         SH_CLK_DIV4(&pll1_clk, _reg, _bit, _mask, _flags)
224
225 static struct clk div4_clks[DIV4_NR] = {
226         [DIV4_I] = DIV4(FRQCRA, 20, 0xdff, CLK_ENABLE_ON_INIT),
227         /*
228          * ZG clock is dividing PLL0 frequency to supply SGX. Make sure not to
229          * exceed maximum frequencies of 201.5MHz for VDD_DVFS=1.175 and
230          * 239.2MHz for VDD_DVFS=1.315V.
231          */
232         [DIV4_ZG] = SH_CLK_DIV4(&pll0_clk, FRQCRA, 16, 0xd7f, CLK_ENABLE_ON_INIT),
233         [DIV4_M3] = DIV4(FRQCRA, 12, 0x1dff, CLK_ENABLE_ON_INIT),
234         [DIV4_B] = DIV4(FRQCRA, 8, 0xdff, CLK_ENABLE_ON_INIT),
235         [DIV4_M1] = DIV4(FRQCRA, 4, 0x1dff, 0),
236         [DIV4_M2] = DIV4(FRQCRA, 0, 0x1dff, 0),
237         [DIV4_Z] = SH_CLK_DIV4(&pll0_clk, FRQCRB, 24, 0x97f, 0),
238         [DIV4_ZX] = DIV4(FRQCRB, 12, 0xdff, 0),
239         [DIV4_HP] = DIV4(FRQCRB, 4, 0xdff, 0),
240 };
241
242 static unsigned long twd_recalc(struct clk *clk)
243 {
244         return clk_get_rate(clk->parent) / 4;
245 }
246
247 static struct sh_clk_ops twd_clk_ops = {
248         .recalc = twd_recalc,
249 };
250
251 static struct clk twd_clk = {
252         .parent = &div4_clks[DIV4_Z],
253         .ops = &twd_clk_ops,
254 };
255
256 static struct sh_clk_ops zclk_ops, kicker_ops;
257 static const struct sh_clk_ops *div4_clk_ops;
258
259 static int zclk_set_rate(struct clk *clk, unsigned long rate)
260 {
261         int ret;
262
263         if (!clk->parent || !__clk_get(clk->parent))
264                 return -ENODEV;
265
266         if (readl(FRQCRB) & (1 << 31))
267                 return -EBUSY;
268
269         if (rate == clk_get_rate(clk->parent)) {
270                 /* 1:1 - switch off divider */
271                 __raw_writel(__raw_readl(FRQCRB) & ~(1 << 28), FRQCRB);
272                 /* nullify the divider to prepare for the next time */
273                 ret = div4_clk_ops->set_rate(clk, rate / 2);
274                 if (!ret)
275                         ret = frqcr_kick();
276                 if (ret > 0)
277                         ret = 0;
278         } else {
279                 /* Enable the divider */
280                 __raw_writel(__raw_readl(FRQCRB) | (1 << 28), FRQCRB);
281
282                 ret = frqcr_kick();
283                 if (ret >= 0)
284                         /*
285                          * set the divider - call the DIV4 method, it will kick
286                          * FRQCRB too
287                          */
288                         ret = div4_clk_ops->set_rate(clk, rate);
289                 if (ret < 0)
290                         goto esetrate;
291         }
292
293 esetrate:
294         __clk_put(clk->parent);
295         return ret;
296 }
297
298 static long zclk_round_rate(struct clk *clk, unsigned long rate)
299 {
300         unsigned long div_freq = div4_clk_ops->round_rate(clk, rate),
301                 parent_freq = clk_get_rate(clk->parent);
302
303         if (rate > div_freq && abs(parent_freq - rate) < rate - div_freq)
304                 return parent_freq;
305
306         return div_freq;
307 }
308
309 static unsigned long zclk_recalc(struct clk *clk)
310 {
311         /*
312          * Must recalculate frequencies in case PLL0 has been changed, even if
313          * the divisor is unused ATM!
314          */
315         unsigned long div_freq = div4_clk_ops->recalc(clk);
316
317         if (__raw_readl(FRQCRB) & (1 << 28))
318                 return div_freq;
319
320         return clk_get_rate(clk->parent);
321 }
322
323 static int kicker_set_rate(struct clk *clk, unsigned long rate)
324 {
325         if (__raw_readl(FRQCRB) & (1 << 31))
326                 return -EBUSY;
327
328         return div4_clk_ops->set_rate(clk, rate);
329 }
330
331 static void div4_clk_extend(void)
332 {
333         int i;
334
335         div4_clk_ops = div4_clks[0].ops;
336
337         /* Add a kicker-busy check before changing the rate */
338         kicker_ops = *div4_clk_ops;
339         /* We extend the DIV4 clock with a 1:1 pass-through case */
340         zclk_ops = *div4_clk_ops;
341
342         kicker_ops.set_rate = kicker_set_rate;
343         zclk_ops.set_rate = zclk_set_rate;
344         zclk_ops.round_rate = zclk_round_rate;
345         zclk_ops.recalc = zclk_recalc;
346
347         for (i = 0; i < DIV4_NR; i++)
348                 div4_clks[i].ops = i == DIV4_Z ? &zclk_ops : &kicker_ops;
349 }
350
351 enum { DIV6_VCK1, DIV6_VCK2, DIV6_VCK3, DIV6_ZB1,
352         DIV6_FLCTL, DIV6_SDHI0, DIV6_SDHI1, DIV6_SDHI2,
353         DIV6_FSIA, DIV6_FSIB, DIV6_SUB,
354         DIV6_SPUA, DIV6_SPUV, DIV6_MSU,
355         DIV6_HSI,  DIV6_MFG1, DIV6_MFG2,
356         DIV6_DSIT, DIV6_DSI0P, DIV6_DSI1P,
357         DIV6_NR };
358
359 static struct clk *vck_parent[8] = {
360         [0] = &pll1_div2_clk,
361         [1] = &pll2_clk,
362         [2] = &sh73a0_extcki_clk,
363         [3] = &sh73a0_extal2_clk,
364         [4] = &main_div2_clk,
365         [5] = &sh73a0_extalr_clk,
366         [6] = &main_clk,
367 };
368
369 static struct clk *pll_parent[4] = {
370         [0] = &pll1_div2_clk,
371         [1] = &pll2_clk,
372         [2] = &pll1_div13_clk,
373 };
374
375 static struct clk *hsi_parent[4] = {
376         [0] = &pll1_div2_clk,
377         [1] = &pll2_clk,
378         [2] = &pll1_div7_clk,
379 };
380
381 static struct clk *pll_extal2_parent[] = {
382         [0] = &pll1_div2_clk,
383         [1] = &pll2_clk,
384         [2] = &sh73a0_extal2_clk,
385         [3] = &sh73a0_extal2_clk,
386 };
387
388 static struct clk *dsi_parent[8] = {
389         [0] = &pll1_div2_clk,
390         [1] = &pll2_clk,
391         [2] = &main_clk,
392         [3] = &sh73a0_extal2_clk,
393         [4] = &sh73a0_extcki_clk,
394 };
395
396 static struct clk div6_clks[DIV6_NR] = {
397         [DIV6_VCK1] = SH_CLK_DIV6_EXT(VCLKCR1, 0,
398                         vck_parent, ARRAY_SIZE(vck_parent), 12, 3),
399         [DIV6_VCK2] = SH_CLK_DIV6_EXT(VCLKCR2, 0,
400                         vck_parent, ARRAY_SIZE(vck_parent), 12, 3),
401         [DIV6_VCK3] = SH_CLK_DIV6_EXT(VCLKCR3, 0,
402                         vck_parent, ARRAY_SIZE(vck_parent), 12, 3),
403         [DIV6_ZB1] = SH_CLK_DIV6_EXT(ZBCKCR, CLK_ENABLE_ON_INIT,
404                         pll_parent, ARRAY_SIZE(pll_parent), 7, 1),
405         [DIV6_FLCTL] = SH_CLK_DIV6_EXT(FLCKCR, 0,
406                         pll_parent, ARRAY_SIZE(pll_parent), 7, 1),
407         [DIV6_SDHI0] = SH_CLK_DIV6_EXT(SD0CKCR, 0,
408                         pll_parent, ARRAY_SIZE(pll_parent), 6, 2),
409         [DIV6_SDHI1] = SH_CLK_DIV6_EXT(SD1CKCR, 0,
410                         pll_parent, ARRAY_SIZE(pll_parent), 6, 2),
411         [DIV6_SDHI2] = SH_CLK_DIV6_EXT(SD2CKCR, 0,
412                         pll_parent, ARRAY_SIZE(pll_parent), 6, 2),
413         [DIV6_FSIA] = SH_CLK_DIV6_EXT(FSIACKCR, 0,
414                         pll_parent, ARRAY_SIZE(pll_parent), 6, 1),
415         [DIV6_FSIB] = SH_CLK_DIV6_EXT(FSIBCKCR, 0,
416                         pll_parent, ARRAY_SIZE(pll_parent), 6, 1),
417         [DIV6_SUB] = SH_CLK_DIV6_EXT(SUBCKCR, 0,
418                         pll_extal2_parent, ARRAY_SIZE(pll_extal2_parent), 6, 2),
419         [DIV6_SPUA] = SH_CLK_DIV6_EXT(SPUACKCR, 0,
420                         pll_extal2_parent, ARRAY_SIZE(pll_extal2_parent), 6, 2),
421         [DIV6_SPUV] = SH_CLK_DIV6_EXT(SPUVCKCR, 0,
422                         pll_extal2_parent, ARRAY_SIZE(pll_extal2_parent), 6, 2),
423         [DIV6_MSU] = SH_CLK_DIV6_EXT(MSUCKCR, 0,
424                         pll_parent, ARRAY_SIZE(pll_parent), 7, 1),
425         [DIV6_HSI] = SH_CLK_DIV6_EXT(HSICKCR, 0,
426                         hsi_parent, ARRAY_SIZE(hsi_parent), 6, 2),
427         [DIV6_MFG1] = SH_CLK_DIV6_EXT(MFCK1CR, 0,
428                         pll_parent, ARRAY_SIZE(pll_parent), 7, 1),
429         [DIV6_MFG2] = SH_CLK_DIV6_EXT(MFCK2CR, 0,
430                         pll_parent, ARRAY_SIZE(pll_parent), 7, 1),
431         [DIV6_DSIT] = SH_CLK_DIV6_EXT(DSITCKCR, 0,
432                         pll_parent, ARRAY_SIZE(pll_parent), 7, 1),
433         [DIV6_DSI0P] = SH_CLK_DIV6_EXT(DSI0PCKCR, 0,
434                         dsi_parent, ARRAY_SIZE(dsi_parent), 12, 3),
435         [DIV6_DSI1P] = SH_CLK_DIV6_EXT(DSI1PCKCR, 0,
436                         dsi_parent, ARRAY_SIZE(dsi_parent), 12, 3),
437 };
438
439 /* DSI DIV */
440 static unsigned long dsiphy_recalc(struct clk *clk)
441 {
442         u32 value;
443
444         value = __raw_readl(clk->mapping->base);
445
446         /* FIXME */
447         if (!(value & 0x000B8000))
448                 return clk->parent->rate;
449
450         value &= 0x3f;
451         value += 1;
452
453         if ((value < 12) ||
454             (value > 33)) {
455                 pr_err("DSIPHY has wrong value (%d)", value);
456                 return 0;
457         }
458
459         return clk->parent->rate / value;
460 }
461
462 static long dsiphy_round_rate(struct clk *clk, unsigned long rate)
463 {
464         return clk_rate_mult_range_round(clk, 12, 33, rate);
465 }
466
467 static void dsiphy_disable(struct clk *clk)
468 {
469         u32 value;
470
471         value = __raw_readl(clk->mapping->base);
472         value &= ~0x000B8000;
473
474         __raw_writel(value , clk->mapping->base);
475 }
476
477 static int dsiphy_enable(struct clk *clk)
478 {
479         u32 value;
480         int multi;
481
482         value = __raw_readl(clk->mapping->base);
483         multi = (value & 0x3f) + 1;
484
485         if ((multi < 12) || (multi > 33))
486                 return -EIO;
487
488         __raw_writel(value | 0x000B8000, clk->mapping->base);
489
490         return 0;
491 }
492
493 static int dsiphy_set_rate(struct clk *clk, unsigned long rate)
494 {
495         u32 value;
496         int idx;
497
498         idx = rate / clk->parent->rate;
499         if ((idx < 12) || (idx > 33))
500                 return -EINVAL;
501
502         idx += -1;
503
504         value = __raw_readl(clk->mapping->base);
505         value = (value & ~0x3f) + idx;
506
507         __raw_writel(value, clk->mapping->base);
508
509         return 0;
510 }
511
512 static struct sh_clk_ops dsiphy_clk_ops = {
513         .recalc         = dsiphy_recalc,
514         .round_rate     = dsiphy_round_rate,
515         .set_rate       = dsiphy_set_rate,
516         .enable         = dsiphy_enable,
517         .disable        = dsiphy_disable,
518 };
519
520 static struct clk_mapping dsi0phy_clk_mapping = {
521         .phys   = DSI0PHYCR,
522         .len    = 4,
523 };
524
525 static struct clk_mapping dsi1phy_clk_mapping = {
526         .phys   = DSI1PHYCR,
527         .len    = 4,
528 };
529
530 static struct clk dsi0phy_clk = {
531         .ops            = &dsiphy_clk_ops,
532         .parent         = &div6_clks[DIV6_DSI0P], /* late install */
533         .mapping        = &dsi0phy_clk_mapping,
534 };
535
536 static struct clk dsi1phy_clk = {
537         .ops            = &dsiphy_clk_ops,
538         .parent         = &div6_clks[DIV6_DSI1P], /* late install */
539         .mapping        = &dsi1phy_clk_mapping,
540 };
541
542 static struct clk *late_main_clks[] = {
543         &dsi0phy_clk,
544         &dsi1phy_clk,
545         &twd_clk,
546 };
547
548 enum { MSTP001,
549         MSTP129, MSTP128, MSTP127, MSTP126, MSTP125, MSTP118, MSTP116, MSTP112, MSTP100,
550         MSTP219, MSTP218, MSTP217,
551         MSTP207, MSTP206, MSTP204, MSTP203, MSTP202, MSTP201, MSTP200,
552         MSTP331, MSTP329, MSTP328, MSTP325, MSTP323, MSTP322,
553         MSTP314, MSTP313, MSTP312, MSTP311,
554         MSTP304, MSTP303, MSTP302, MSTP301, MSTP300,
555         MSTP411, MSTP410, MSTP403,
556         MSTP508,
557         MSTP_NR };
558
559 #define MSTP(_parent, _reg, _bit, _flags) \
560         SH_CLK_MSTP32(_parent, _reg, _bit, _flags)
561
562 static struct clk mstp_clks[MSTP_NR] = {
563         [MSTP001] = MSTP(&div4_clks[DIV4_HP], SMSTPCR0, 1, 0), /* IIC2 */
564         [MSTP129] = MSTP(&div4_clks[DIV4_B], SMSTPCR1, 29, 0), /* CEU1 */
565         [MSTP128] = MSTP(&div4_clks[DIV4_B], SMSTPCR1, 28, 0), /* CSI2-RX1 */
566         [MSTP127] = MSTP(&div4_clks[DIV4_B], SMSTPCR1, 27, 0), /* CEU0 */
567         [MSTP126] = MSTP(&div4_clks[DIV4_B], SMSTPCR1, 26, 0), /* CSI2-RX0 */
568         [MSTP125] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR1, 25, 0), /* TMU0 */
569         [MSTP118] = MSTP(&div4_clks[DIV4_B], SMSTPCR1, 18, 0), /* DSITX0 */
570         [MSTP116] = MSTP(&div4_clks[DIV4_HP], SMSTPCR1, 16, 0), /* IIC0 */
571         [MSTP112] = MSTP(&div4_clks[DIV4_ZG], SMSTPCR1, 12, 0), /* SGX */
572         [MSTP100] = MSTP(&div4_clks[DIV4_B], SMSTPCR1, 0, 0), /* LCDC0 */
573         [MSTP219] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR2, 19, 0), /* SCIFA7 */
574         [MSTP218] = MSTP(&div4_clks[DIV4_HP], SMSTPCR2, 18, 0), /* SY-DMAC */
575         [MSTP217] = MSTP(&div4_clks[DIV4_HP], SMSTPCR2, 17, 0), /* MP-DMAC */
576         [MSTP207] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR2, 7, 0), /* SCIFA5 */
577         [MSTP206] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR2, 6, 0), /* SCIFB */
578         [MSTP204] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR2, 4, 0), /* SCIFA0 */
579         [MSTP203] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR2, 3, 0), /* SCIFA1 */
580         [MSTP202] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR2, 2, 0), /* SCIFA2 */
581         [MSTP201] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR2, 1, 0), /* SCIFA3 */
582         [MSTP200] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR2, 0, 0), /* SCIFA4 */
583         [MSTP331] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR3, 31, 0), /* SCIFA6 */
584         [MSTP329] = MSTP(&r_clk, SMSTPCR3, 29, 0), /* CMT10 */
585         [MSTP328] = MSTP(&div4_clks[DIV4_HP], SMSTPCR3, 28, 0), /*FSI*/
586         [MSTP325] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR3, 25, 0), /* IrDA */
587         [MSTP323] = MSTP(&div4_clks[DIV4_HP], SMSTPCR3, 23, 0), /* IIC1 */
588         [MSTP322] = MSTP(&div4_clks[DIV4_HP], SMSTPCR3, 22, 0), /* USB */
589         [MSTP314] = MSTP(&div6_clks[DIV6_SDHI0], SMSTPCR3, 14, 0), /* SDHI0 */
590         [MSTP313] = MSTP(&div6_clks[DIV6_SDHI1], SMSTPCR3, 13, 0), /* SDHI1 */
591         [MSTP312] = MSTP(&div4_clks[DIV4_HP], SMSTPCR3, 12, 0), /* MMCIF0 */
592         [MSTP311] = MSTP(&div6_clks[DIV6_SDHI2], SMSTPCR3, 11, 0), /* SDHI2 */
593         [MSTP304] = MSTP(&main_div2_clk, SMSTPCR3, 4, 0), /* TPU0 */
594         [MSTP303] = MSTP(&main_div2_clk, SMSTPCR3, 3, 0), /* TPU1 */
595         [MSTP302] = MSTP(&main_div2_clk, SMSTPCR3, 2, 0), /* TPU2 */
596         [MSTP301] = MSTP(&main_div2_clk, SMSTPCR3, 1, 0), /* TPU3 */
597         [MSTP300] = MSTP(&main_div2_clk, SMSTPCR3, 0, 0), /* TPU4 */
598         [MSTP411] = MSTP(&div4_clks[DIV4_HP], SMSTPCR4, 11, 0), /* IIC3 */
599         [MSTP410] = MSTP(&div4_clks[DIV4_HP], SMSTPCR4, 10, 0), /* IIC4 */
600         [MSTP403] = MSTP(&r_clk, SMSTPCR4, 3, 0), /* KEYSC */
601         [MSTP508] = MSTP(&div4_clks[DIV4_HP], SMSTPCR5, 8, 0), /* INTCA0 */
602 };
603
604 /* The lookups structure below includes duplicate entries for some clocks
605  * with alternate names.
606  * - The traditional name used when a device is initialised with platform data
607  * - The name used when a device is initialised using device tree
608  * The longer-term aim is to remove these duplicates, and indeed the
609  * lookups table entirely, by describing clocks using device tree.
610  */
611 static struct clk_lookup lookups[] = {
612         /* main clocks */
613         CLKDEV_CON_ID("r_clk", &r_clk),
614         CLKDEV_DEV_ID("smp_twd", &twd_clk), /* smp_twd */
615
616         /* DIV4 clocks */
617         CLKDEV_DEV_ID("cpu0", &div4_clks[DIV4_Z]),
618
619         /* DIV6 clocks */
620         CLKDEV_CON_ID("vck1_clk", &div6_clks[DIV6_VCK1]),
621         CLKDEV_CON_ID("vck2_clk", &div6_clks[DIV6_VCK2]),
622         CLKDEV_CON_ID("vck3_clk", &div6_clks[DIV6_VCK3]),
623         CLKDEV_CON_ID("sdhi0_clk", &div6_clks[DIV6_SDHI0]),
624         CLKDEV_CON_ID("sdhi1_clk", &div6_clks[DIV6_SDHI1]),
625         CLKDEV_CON_ID("sdhi2_clk", &div6_clks[DIV6_SDHI2]),
626
627         /* MSTP32 clocks */
628         CLKDEV_DEV_ID("i2c-sh_mobile.2", &mstp_clks[MSTP001]), /* I2C2 */
629         CLKDEV_DEV_ID("e6824000.i2c", &mstp_clks[MSTP001]), /* I2C2 */
630         CLKDEV_DEV_ID("sh_mobile_ceu.1", &mstp_clks[MSTP129]), /* CEU1 */
631         CLKDEV_DEV_ID("sh-mobile-csi2.1", &mstp_clks[MSTP128]), /* CSI2-RX1 */
632         CLKDEV_DEV_ID("sh_mobile_ceu.0", &mstp_clks[MSTP127]), /* CEU0 */
633         CLKDEV_DEV_ID("sh-mobile-csi2.0", &mstp_clks[MSTP126]), /* CSI2-RX0 */
634         CLKDEV_DEV_ID("sh-mipi-dsi.0", &mstp_clks[MSTP118]), /* DSITX */
635         CLKDEV_DEV_ID("i2c-sh_mobile.0", &mstp_clks[MSTP116]), /* I2C0 */
636         CLKDEV_DEV_ID("e6820000.i2c", &mstp_clks[MSTP116]), /* I2C0 */
637         CLKDEV_DEV_ID("sh_mobile_lcdc_fb.0", &mstp_clks[MSTP100]), /* LCDC0 */
638         CLKDEV_DEV_ID("sh-sci.7", &mstp_clks[MSTP219]), /* SCIFA7 */
639         CLKDEV_DEV_ID("e6cd0000.serial", &mstp_clks[MSTP219]), /* SCIFA7 */
640         CLKDEV_DEV_ID("sh-dma-engine.0", &mstp_clks[MSTP218]), /* SY-DMAC */
641         CLKDEV_DEV_ID("sh-dma-engine.1", &mstp_clks[MSTP217]), /* MP-DMAC */
642         CLKDEV_DEV_ID("sh-sci.5", &mstp_clks[MSTP207]), /* SCIFA5 */
643         CLKDEV_DEV_ID("e6cb0000.serial", &mstp_clks[MSTP207]), /* SCIFA5 */
644         CLKDEV_DEV_ID("sh-sci.8", &mstp_clks[MSTP206]), /* SCIFB */
645         CLKDEV_DEV_ID("e6c3000.serial", &mstp_clks[MSTP206]), /* SCIFB */
646         CLKDEV_DEV_ID("sh-sci.0", &mstp_clks[MSTP204]), /* SCIFA0 */
647         CLKDEV_DEV_ID("e6c40000.serial", &mstp_clks[MSTP204]), /* SCIFA0 */
648         CLKDEV_DEV_ID("sh-sci.1", &mstp_clks[MSTP203]), /* SCIFA1 */
649         CLKDEV_DEV_ID("e6c50000.serial", &mstp_clks[MSTP203]), /* SCIFA1 */
650         CLKDEV_DEV_ID("sh-sci.2", &mstp_clks[MSTP202]), /* SCIFA2 */
651         CLKDEV_DEV_ID("e6c60000.serial", &mstp_clks[MSTP202]), /* SCIFA2 */
652         CLKDEV_DEV_ID("sh-sci.3", &mstp_clks[MSTP201]), /* SCIFA3 */
653         CLKDEV_DEV_ID("e6c70000.serial", &mstp_clks[MSTP201]), /* SCIFA3 */
654         CLKDEV_DEV_ID("sh-sci.4", &mstp_clks[MSTP200]), /* SCIFA4 */
655         CLKDEV_DEV_ID("e6c80000.serial", &mstp_clks[MSTP200]), /* SCIFA4 */
656         CLKDEV_DEV_ID("sh-sci.6", &mstp_clks[MSTP331]), /* SCIFA6 */
657         CLKDEV_DEV_ID("e6cc0000.serial", &mstp_clks[MSTP331]), /* SCIFA6 */
658         CLKDEV_DEV_ID("sh_fsi2", &mstp_clks[MSTP328]), /* FSI */
659         CLKDEV_DEV_ID("ec230000.sound", &mstp_clks[MSTP328]), /* FSI */
660         CLKDEV_DEV_ID("sh_irda.0", &mstp_clks[MSTP325]), /* IrDA */
661         CLKDEV_DEV_ID("i2c-sh_mobile.1", &mstp_clks[MSTP323]), /* I2C1 */
662         CLKDEV_DEV_ID("e6822000.i2c", &mstp_clks[MSTP323]), /* I2C1 */
663         CLKDEV_DEV_ID("renesas_usbhs", &mstp_clks[MSTP322]), /* USB */
664         CLKDEV_DEV_ID("sh_mobile_sdhi.0", &mstp_clks[MSTP314]), /* SDHI0 */
665         CLKDEV_DEV_ID("ee100000.sd", &mstp_clks[MSTP314]), /* SDHI0 */
666         CLKDEV_DEV_ID("sh_mobile_sdhi.1", &mstp_clks[MSTP313]), /* SDHI1 */
667         CLKDEV_DEV_ID("ee120000.sd", &mstp_clks[MSTP313]), /* SDHI1 */
668         CLKDEV_DEV_ID("sh_mmcif.0", &mstp_clks[MSTP312]), /* MMCIF0 */
669         CLKDEV_DEV_ID("e6bd0000.mmc", &mstp_clks[MSTP312]), /* MMCIF0 */
670         CLKDEV_DEV_ID("sh_mobile_sdhi.2", &mstp_clks[MSTP311]), /* SDHI2 */
671         CLKDEV_DEV_ID("ee140000.sd", &mstp_clks[MSTP311]), /* SDHI2 */
672         CLKDEV_DEV_ID("renesas-tpu-pwm.0", &mstp_clks[MSTP304]), /* TPU0 */
673         CLKDEV_DEV_ID("renesas-tpu-pwm.1", &mstp_clks[MSTP303]), /* TPU1 */
674         CLKDEV_DEV_ID("renesas-tpu-pwm.2", &mstp_clks[MSTP302]), /* TPU2 */
675         CLKDEV_DEV_ID("renesas-tpu-pwm.3", &mstp_clks[MSTP301]), /* TPU3 */
676         CLKDEV_DEV_ID("renesas-tpu-pwm.4", &mstp_clks[MSTP300]), /* TPU4 */
677         CLKDEV_DEV_ID("i2c-sh_mobile.3", &mstp_clks[MSTP411]), /* I2C3 */
678         CLKDEV_DEV_ID("e6826000.i2c", &mstp_clks[MSTP411]), /* I2C3 */
679         CLKDEV_DEV_ID("i2c-sh_mobile.4", &mstp_clks[MSTP410]), /* I2C4 */
680         CLKDEV_DEV_ID("e6828000.i2c", &mstp_clks[MSTP410]), /* I2C4 */
681         CLKDEV_DEV_ID("sh_keysc.0", &mstp_clks[MSTP403]), /* KEYSC */
682         CLKDEV_DEV_ID("renesas_intc_irqpin.0",  &mstp_clks[MSTP508]), /* INTCA0 */
683         CLKDEV_DEV_ID("e6900000.irqpin",        &mstp_clks[MSTP508]), /* INTCA0 */
684         CLKDEV_DEV_ID("renesas_intc_irqpin.1",  &mstp_clks[MSTP508]), /* INTCA0 */
685         CLKDEV_DEV_ID("e6900004.irqpin",        &mstp_clks[MSTP508]), /* INTCA0 */
686         CLKDEV_DEV_ID("renesas_intc_irqpin.2",  &mstp_clks[MSTP508]), /* INTCA0 */
687         CLKDEV_DEV_ID("e6900008.irqpin",        &mstp_clks[MSTP508]), /* INTCA0 */
688         CLKDEV_DEV_ID("renesas_intc_irqpin.3",  &mstp_clks[MSTP508]), /* INTCA0 */
689         CLKDEV_DEV_ID("e690000c.irqpin",        &mstp_clks[MSTP508]), /* INTCA0 */
690
691         /* ICK */
692         CLKDEV_ICK_ID("dsit_clk", "sh-mipi-dsi.0", &div6_clks[DIV6_DSIT]),
693         CLKDEV_ICK_ID("dsit_clk", "sh-mipi-dsi.1", &div6_clks[DIV6_DSIT]),
694         CLKDEV_ICK_ID("dsip_clk", "sh-mipi-dsi.0", &div6_clks[DIV6_DSI0P]),
695         CLKDEV_ICK_ID("dsip_clk", "sh-mipi-dsi.1", &div6_clks[DIV6_DSI1P]),
696         CLKDEV_ICK_ID("dsiphy_clk", "sh-mipi-dsi.0", &dsi0phy_clk),
697         CLKDEV_ICK_ID("dsiphy_clk", "sh-mipi-dsi.1", &dsi1phy_clk),
698         CLKDEV_ICK_ID("fck", "sh-cmt-48.1", &mstp_clks[MSTP329]), /* CMT1 */
699         CLKDEV_ICK_ID("fck", "e6138000.timer", &mstp_clks[MSTP329]), /* CMT1 */
700         CLKDEV_ICK_ID("fck", "sh-tmu.0", &mstp_clks[MSTP125]), /* TMU0 */
701 };
702
703 void __init sh73a0_clock_init(void)
704 {
705         int k, ret = 0;
706
707         /* Set SDHI clocks to a known state */
708         __raw_writel(0x108, SD0CKCR);
709         __raw_writel(0x108, SD1CKCR);
710         __raw_writel(0x108, SD2CKCR);
711
712         /* detect main clock parent */
713         switch ((__raw_readl(CKSCR) >> 28) & 0x03) {
714         case 0:
715                 main_clk.parent = &sh73a0_extal1_clk;
716                 break;
717         case 1:
718                 main_clk.parent = &extal1_div2_clk;
719                 break;
720         case 2:
721                 main_clk.parent = &sh73a0_extal2_clk;
722                 break;
723         case 3:
724                 main_clk.parent = &extal2_div2_clk;
725                 break;
726         }
727
728         for (k = 0; !ret && (k < ARRAY_SIZE(main_clks)); k++)
729                 ret = clk_register(main_clks[k]);
730
731         if (!ret) {
732                 ret = sh_clk_div4_register(div4_clks, DIV4_NR, &div4_table);
733                 if (!ret)
734                         div4_clk_extend();
735         }
736
737         if (!ret)
738                 ret = sh_clk_div6_reparent_register(div6_clks, DIV6_NR);
739
740         if (!ret)
741                 ret = sh_clk_mstp_register(mstp_clks, MSTP_NR);
742
743         for (k = 0; !ret && (k < ARRAY_SIZE(late_main_clks)); k++)
744                 ret = clk_register(late_main_clks[k]);
745
746         clkdev_add_table(lookups, ARRAY_SIZE(lookups));
747
748         if (!ret)
749                 shmobile_clk_init();
750         else
751                 panic("failed to setup sh73a0 clocks\n");
752 }