Linux 4.1.18
[linux/fpc-iii.git] / arch / arm / mach-shmobile / clock-sh73a0.c
blob3855fb024fdbb1ca7aecd9780ed9e42533927879
1 /*
2 * sh73a0 clock framework support
4 * Copyright (C) 2010 Magnus Damm
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
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.
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"
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)
62 /* Fixed 32 KHz root clock from EXTALR pin */
63 static struct clk r_clk = {
64 .rate = 32768,
68 * 26MHz default rate for the EXTAL1 root input clock.
69 * If needed, reset this with clk_set_rate() from the platform code.
71 struct clk sh73a0_extal1_clk = {
72 .rate = 26000000,
76 * 48MHz default rate for the EXTAL2 root input clock.
77 * If needed, reset this with clk_set_rate() from the platform code.
79 struct clk sh73a0_extal2_clk = {
80 .rate = 48000000,
83 static struct sh_clk_ops main_clk_ops = {
84 .recalc = followparent_recalc,
87 /* Main clock */
88 static struct clk main_clk = {
89 /* .parent wll be set on sh73a0_clock_init() */
90 .ops = &main_clk_ops,
93 /* PLL0, PLL1, PLL2, PLL3 */
94 static unsigned long pll_recalc(struct clk *clk)
96 unsigned long mult = 1;
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;
109 return clk->parent->rate * mult;
112 static struct sh_clk_ops pll_clk_ops = {
113 .recalc = pll_recalc,
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,
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,
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,
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,
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);
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);
160 /* External input clock */
161 struct clk sh73a0_extcki_clk = {
164 struct clk sh73a0_extalr_clk = {
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,
186 static int frqcr_kick(void)
188 int i;
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;
198 return -ETIMEDOUT;
201 static void div4_kick(struct clk *clk)
203 frqcr_kick();
206 static int divisors[] = { 2, 3, 4, 6, 8, 12, 16, 18,
207 24, 0, 36, 48, 7 };
209 static struct clk_div_mult_table div4_div_mult_table = {
210 .divisors = divisors,
211 .nr_divisors = ARRAY_SIZE(divisors),
214 static struct clk_div4_table div4_table = {
215 .div_mult_table = &div4_div_mult_table,
216 .kick = div4_kick,
219 enum { DIV4_I, DIV4_ZG, DIV4_M3, DIV4_B, DIV4_M1, DIV4_M2,
220 DIV4_Z, DIV4_ZX, DIV4_HP, DIV4_NR };
222 #define DIV4(_reg, _bit, _mask, _flags) \
223 SH_CLK_DIV4(&pll1_clk, _reg, _bit, _mask, _flags)
225 static struct clk div4_clks[DIV4_NR] = {
226 [DIV4_I] = DIV4(FRQCRA, 20, 0xdff, CLK_ENABLE_ON_INIT),
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.
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),
242 static unsigned long twd_recalc(struct clk *clk)
244 return clk_get_rate(clk->parent) / 4;
247 static struct sh_clk_ops twd_clk_ops = {
248 .recalc = twd_recalc,
251 static struct clk twd_clk = {
252 .parent = &div4_clks[DIV4_Z],
253 .ops = &twd_clk_ops,
256 static struct sh_clk_ops zclk_ops, kicker_ops;
257 static const struct sh_clk_ops *div4_clk_ops;
259 static int zclk_set_rate(struct clk *clk, unsigned long rate)
261 int ret;
263 if (!clk->parent || !__clk_get(clk->parent))
264 return -ENODEV;
266 if (readl(FRQCRB) & (1 << 31))
267 return -EBUSY;
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);
282 ret = frqcr_kick();
283 if (ret >= 0)
285 * set the divider - call the DIV4 method, it will kick
286 * FRQCRB too
288 ret = div4_clk_ops->set_rate(clk, rate);
289 if (ret < 0)
290 goto esetrate;
293 esetrate:
294 __clk_put(clk->parent);
295 return ret;
298 static long zclk_round_rate(struct clk *clk, unsigned long rate)
300 unsigned long div_freq = div4_clk_ops->round_rate(clk, rate),
301 parent_freq = clk_get_rate(clk->parent);
303 if (rate > div_freq && abs(parent_freq - rate) < rate - div_freq)
304 return parent_freq;
306 return div_freq;
309 static unsigned long zclk_recalc(struct clk *clk)
312 * Must recalculate frequencies in case PLL0 has been changed, even if
313 * the divisor is unused ATM!
315 unsigned long div_freq = div4_clk_ops->recalc(clk);
317 if (__raw_readl(FRQCRB) & (1 << 28))
318 return div_freq;
320 return clk_get_rate(clk->parent);
323 static int kicker_set_rate(struct clk *clk, unsigned long rate)
325 if (__raw_readl(FRQCRB) & (1 << 31))
326 return -EBUSY;
328 return div4_clk_ops->set_rate(clk, rate);
331 static void div4_clk_extend(void)
333 int i;
335 div4_clk_ops = div4_clks[0].ops;
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;
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;
347 for (i = 0; i < DIV4_NR; i++)
348 div4_clks[i].ops = i == DIV4_Z ? &zclk_ops : &kicker_ops;
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 };
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,
369 static struct clk *pll_parent[4] = {
370 [0] = &pll1_div2_clk,
371 [1] = &pll2_clk,
372 [2] = &pll1_div13_clk,
375 static struct clk *hsi_parent[4] = {
376 [0] = &pll1_div2_clk,
377 [1] = &pll2_clk,
378 [2] = &pll1_div7_clk,
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,
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,
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),
439 /* DSI DIV */
440 static unsigned long dsiphy_recalc(struct clk *clk)
442 u32 value;
444 value = __raw_readl(clk->mapping->base);
446 /* FIXME */
447 if (!(value & 0x000B8000))
448 return clk->parent->rate;
450 value &= 0x3f;
451 value += 1;
453 if ((value < 12) ||
454 (value > 33)) {
455 pr_err("DSIPHY has wrong value (%d)", value);
456 return 0;
459 return clk->parent->rate / value;
462 static long dsiphy_round_rate(struct clk *clk, unsigned long rate)
464 return clk_rate_mult_range_round(clk, 12, 33, rate);
467 static void dsiphy_disable(struct clk *clk)
469 u32 value;
471 value = __raw_readl(clk->mapping->base);
472 value &= ~0x000B8000;
474 __raw_writel(value , clk->mapping->base);
477 static int dsiphy_enable(struct clk *clk)
479 u32 value;
480 int multi;
482 value = __raw_readl(clk->mapping->base);
483 multi = (value & 0x3f) + 1;
485 if ((multi < 12) || (multi > 33))
486 return -EIO;
488 __raw_writel(value | 0x000B8000, clk->mapping->base);
490 return 0;
493 static int dsiphy_set_rate(struct clk *clk, unsigned long rate)
495 u32 value;
496 int idx;
498 idx = rate / clk->parent->rate;
499 if ((idx < 12) || (idx > 33))
500 return -EINVAL;
502 idx += -1;
504 value = __raw_readl(clk->mapping->base);
505 value = (value & ~0x3f) + idx;
507 __raw_writel(value, clk->mapping->base);
509 return 0;
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,
520 static struct clk_mapping dsi0phy_clk_mapping = {
521 .phys = DSI0PHYCR,
522 .len = 4,
525 static struct clk_mapping dsi1phy_clk_mapping = {
526 .phys = DSI1PHYCR,
527 .len = 4,
530 static struct clk dsi0phy_clk = {
531 .ops = &dsiphy_clk_ops,
532 .parent = &div6_clks[DIV6_DSI0P], /* late install */
533 .mapping = &dsi0phy_clk_mapping,
536 static struct clk dsi1phy_clk = {
537 .ops = &dsiphy_clk_ops,
538 .parent = &div6_clks[DIV6_DSI1P], /* late install */
539 .mapping = &dsi1phy_clk_mapping,
542 static struct clk *late_main_clks[] = {
543 &dsi0phy_clk,
544 &dsi1phy_clk,
545 &twd_clk,
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 };
559 #define MSTP(_parent, _reg, _bit, _flags) \
560 SH_CLK_MSTP32(_parent, _reg, _bit, _flags)
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 */
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.
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 */
616 /* DIV4 clocks */
617 CLKDEV_DEV_ID("cpu0", &div4_clks[DIV4_Z]),
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]),
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 */
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 */
703 void __init sh73a0_clock_init(void)
705 int k, ret = 0;
707 /* Set SDHI clocks to a known state */
708 __raw_writel(0x108, SD0CKCR);
709 __raw_writel(0x108, SD1CKCR);
710 __raw_writel(0x108, SD2CKCR);
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;
728 for (k = 0; !ret && (k < ARRAY_SIZE(main_clks)); k++)
729 ret = clk_register(main_clks[k]);
731 if (!ret) {
732 ret = sh_clk_div4_register(div4_clks, DIV4_NR, &div4_table);
733 if (!ret)
734 div4_clk_extend();
737 if (!ret)
738 ret = sh_clk_div6_reparent_register(div6_clks, DIV6_NR);
740 if (!ret)
741 ret = sh_clk_mstp_register(mstp_clks, MSTP_NR);
743 for (k = 0; !ret && (k < ARRAY_SIZE(late_main_clks)); k++)
744 ret = clk_register(late_main_clks[k]);
746 clkdev_add_table(lookups, ARRAY_SIZE(lookups));
748 if (!ret)
749 shmobile_clk_init();
750 else
751 panic("failed to setup sh73a0 clocks\n");