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