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>
18 #include <linux/sh_clk.h>
19 #include <linux/clkdev.h>
20 #include <asm/processor.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 = {
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 = {
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 = {
83 static struct sh_clk_ops main_clk_ops = {
84 .recalc = followparent_recalc,
88 static struct clk main_clk = {
89 /* .parent wll be set on sh73a0_clock_init() */
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) {
104 if (__raw_readl(clk->enable_reg) & (1 << 20))
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 = {
118 .flags = CLK_ENABLE_ON_INIT,
120 .enable_reg = (void __iomem *)PLL0CR,
124 static struct clk pll1_clk = {
126 .flags = CLK_ENABLE_ON_INIT,
128 .enable_reg = (void __iomem *)PLL1CR,
132 static struct clk pll2_clk = {
134 .flags = CLK_ENABLE_ON_INIT,
136 .enable_reg = (void __iomem *)PLL2CR,
140 static struct clk pll3_clk = {
142 .flags = CLK_ENABLE_ON_INIT,
144 .enable_reg = (void __iomem *)PLL3CR,
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[] = {
186 static int frqcr_kick(void)
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))
201 static void div4_kick(struct clk *clk)
206 static int divisors[] = { 2, 3, 4, 6, 8, 12, 16, 18,
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,
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],
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)
263 if (!clk->parent || !__clk_get(clk->parent))
266 if (readl(FRQCRB) & (1 << 31))
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);
279 /* Enable the divider */
280 __raw_writel(__raw_readl(FRQCRB) | (1 << 28), FRQCRB);
285 * set the divider - call the DIV4 method, it will kick
288 ret = div4_clk_ops->set_rate(clk, rate);
294 __clk_put(clk->parent);
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)
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))
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))
328 return div4_clk_ops->set_rate(clk, rate);
331 static void div4_clk_extend(void)
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,
359 static struct clk *vck_parent[8] = {
360 [0] = &pll1_div2_clk,
362 [2] = &sh73a0_extcki_clk,
363 [3] = &sh73a0_extal2_clk,
364 [4] = &main_div2_clk,
365 [5] = &sh73a0_extalr_clk,
369 static struct clk *pll_parent[4] = {
370 [0] = &pll1_div2_clk,
372 [2] = &pll1_div13_clk,
375 static struct clk *hsi_parent[4] = {
376 [0] = &pll1_div2_clk,
378 [2] = &pll1_div7_clk,
381 static struct clk *pll_extal2_parent[] = {
382 [0] = &pll1_div2_clk,
384 [2] = &sh73a0_extal2_clk,
385 [3] = &sh73a0_extal2_clk,
388 static struct clk *dsi_parent[8] = {
389 [0] = &pll1_div2_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),
440 static unsigned long dsiphy_recalc(struct clk *clk)
444 value = __raw_readl(clk->mapping->base);
447 if (!(value & 0x000B8000))
448 return clk->parent->rate;
455 pr_err("DSIPHY has wrong value (%d)", value);
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)
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)
482 value = __raw_readl(clk->mapping->base);
483 multi = (value & 0x3f) + 1;
485 if ((multi < 12) || (multi > 33))
488 __raw_writel(value | 0x000B8000, clk->mapping->base);
493 static int dsiphy_set_rate(struct clk *clk, unsigned long rate)
498 idx = rate / clk->parent->rate;
499 if ((idx < 12) || (idx > 33))
504 value = __raw_readl(clk->mapping->base);
505 value = (value & ~0x3f) + idx;
507 __raw_writel(value, clk->mapping->base);
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 = {
525 static struct clk_mapping dsi1phy_clk_mapping = {
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[] = {
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,
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[] = {
613 CLKDEV_CON_ID("r_clk", &r_clk),
614 CLKDEV_DEV_ID("smp_twd", &twd_clk), /* smp_twd */
617 CLKDEV_DEV_ID("cpu0", &div4_clks[DIV4_Z]),
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]),
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 */
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)
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) {
715 main_clk.parent = &sh73a0_extal1_clk;
718 main_clk.parent = &extal1_div2_clk;
721 main_clk.parent = &sh73a0_extal2_clk;
724 main_clk.parent = &extal2_div2_clk;
728 for (k = 0; !ret && (k < ARRAY_SIZE(main_clks)); k++)
729 ret = clk_register(main_clks[k]);
732 ret = sh_clk_div4_register(div4_clks, DIV4_NR, &div4_table);
738 ret = sh_clk_div6_reparent_register(div6_clks, DIV6_NR);
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));
751 panic("failed to setup sh73a0 clocks\n");