ARM: shmobile: r8a7779: Cleanup header file
[deliverable/linux.git] / arch / arm / mach-shmobile / clock-sh73a0.c
CommitLineData
6d9598e2
MD
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.
6d9598e2
MD
14 */
15#include <linux/init.h>
16#include <linux/kernel.h>
17#include <linux/io.h>
18#include <linux/sh_clk.h>
6ef9f6fd 19#include <linux/clkdev.h>
7653c318 20#include <asm/processor.h>
ad6ffa0b 21#include "clock.h"
fd44aa5e 22#include "common.h"
6d9598e2 23
0a4b04dc
AB
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)
f6d84f4a
MD
47#define DSI0PHYCR 0xe615006C
48#define DSI1PHYCR 0xe6150070
0a4b04dc
AB
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)
6d9598e2
MD
61
62/* Fixed 32 KHz root clock from EXTALR pin */
63static struct clk r_clk = {
64 .rate = 32768,
65};
66
f6d84f4a
MD
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 */
71struct 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 */
79struct clk sh73a0_extal2_clk = {
80 .rate = 48000000,
81};
82
7bcda508 83static struct sh_clk_ops main_clk_ops = {
f6d84f4a
MD
84 .recalc = followparent_recalc,
85};
86
87/* Main clock */
88static struct clk main_clk = {
891cab3e 89 /* .parent wll be set on sh73a0_clock_init() */
f6d84f4a
MD
90 .ops = &main_clk_ops,
91};
92
93/* PLL0, PLL1, PLL2, PLL3 */
94static unsigned long pll_recalc(struct clk *clk)
95{
96 unsigned long mult = 1;
97
71fc5099 98 if (__raw_readl(PLLECR) & (1 << clk->enable_bit)) {
f6d84f4a 99 mult = (((__raw_readl(clk->enable_reg) >> 24) & 0x3f) + 1);
71fc5099
MD
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 }
f6d84f4a
MD
108
109 return clk->parent->rate * mult;
110}
111
7bcda508 112static struct sh_clk_ops pll_clk_ops = {
f6d84f4a
MD
113 .recalc = pll_recalc,
114};
115
116static 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,
6d9598e2
MD
122};
123
f6d84f4a
MD
124static 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
132static 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
140static 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
891cab3e
KM
148/* A fixed divide block */
149SH_CLK_RATIO(div2, 1, 2);
150SH_CLK_RATIO(div7, 1, 7);
151SH_CLK_RATIO(div13, 1, 13);
d4775356 152
891cab3e
KM
153SH_FIXED_RATIO_CLK(extal1_div2_clk, sh73a0_extal1_clk, div2);
154SH_FIXED_RATIO_CLK(extal2_div2_clk, sh73a0_extal2_clk, div2);
155SH_FIXED_RATIO_CLK(main_div2_clk, main_clk, div2);
156SH_FIXED_RATIO_CLK(pll1_div2_clk, pll1_clk, div2);
157SH_FIXED_RATIO_CLK(pll1_div7_clk, pll1_clk, div7);
158SH_FIXED_RATIO_CLK(pll1_div13_clk, pll1_clk, div13);
d4775356
KM
159
160/* External input clock */
161struct clk sh73a0_extcki_clk = {
162};
163
164struct clk sh73a0_extalr_clk = {
165};
166
6d9598e2
MD
167static struct clk *main_clks[] = {
168 &r_clk,
f6d84f4a
MD
169 &sh73a0_extal1_clk,
170 &sh73a0_extal2_clk,
171 &extal1_div2_clk,
172 &extal2_div2_clk,
173 &main_clk,
d4775356 174 &main_div2_clk,
f6d84f4a
MD
175 &pll0_clk,
176 &pll1_clk,
177 &pll2_clk,
178 &pll3_clk,
179 &pll1_div2_clk,
d4775356
KM
180 &pll1_div7_clk,
181 &pll1_div13_clk,
182 &sh73a0_extcki_clk,
183 &sh73a0_extalr_clk,
f6d84f4a
MD
184};
185
7653c318 186static int frqcr_kick(void)
f6d84f4a 187{
7653c318
GL
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}
f6d84f4a 200
7653c318
GL
201static void div4_kick(struct clk *clk)
202{
203 frqcr_kick();
f6d84f4a
MD
204}
205
206static int divisors[] = { 2, 3, 4, 6, 8, 12, 16, 18,
c070c203 207 24, 0, 36, 48, 7 };
f6d84f4a
MD
208
209static struct clk_div_mult_table div4_div_mult_table = {
210 .divisors = divisors,
211 .nr_divisors = ARRAY_SIZE(divisors),
212};
213
214static struct clk_div4_table div4_table = {
215 .div_mult_table = &div4_div_mult_table,
216 .kick = div4_kick,
217};
218
219enum { DIV4_I, DIV4_ZG, DIV4_M3, DIV4_B, DIV4_M1, DIV4_M2,
1f7ccd88 220 DIV4_Z, DIV4_ZX, DIV4_HP, DIV4_NR };
f6d84f4a
MD
221
222#define DIV4(_reg, _bit, _mask, _flags) \
223 SH_CLK_DIV4(&pll1_clk, _reg, _bit, _mask, _flags)
224
225static struct clk div4_clks[DIV4_NR] = {
bf519bfb 226 [DIV4_I] = DIV4(FRQCRA, 20, 0xdff, CLK_ENABLE_ON_INIT),
73107925
GL
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 */
8a444474 232 [DIV4_ZG] = SH_CLK_DIV4(&pll0_clk, FRQCRA, 16, 0xd7f, CLK_ENABLE_ON_INIT),
bf519bfb
KM
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),
8a444474 237 [DIV4_Z] = SH_CLK_DIV4(&pll0_clk, FRQCRB, 24, 0x97f, 0),
bf519bfb
KM
238 [DIV4_ZX] = DIV4(FRQCRB, 12, 0xdff, 0),
239 [DIV4_HP] = DIV4(FRQCRB, 4, 0xdff, 0),
f6d84f4a
MD
240};
241
fe7aa82d
GL
242static unsigned long twd_recalc(struct clk *clk)
243{
244 return clk_get_rate(clk->parent) / 4;
245}
246
247static struct sh_clk_ops twd_clk_ops = {
248 .recalc = twd_recalc,
249};
250
251static struct clk twd_clk = {
252 .parent = &div4_clks[DIV4_Z],
253 .ops = &twd_clk_ops,
254};
255
413bfd0e 256static struct sh_clk_ops zclk_ops, kicker_ops;
3b207a45 257static const struct sh_clk_ops *div4_clk_ops;
73107925
GL
258
259static 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 */
3b207a45 273 ret = div4_clk_ops->set_rate(clk, rate / 2);
73107925
GL
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 */
3b207a45 288 ret = div4_clk_ops->set_rate(clk, rate);
73107925
GL
289 if (ret < 0)
290 goto esetrate;
291 }
292
293esetrate:
294 __clk_put(clk->parent);
295 return ret;
296}
297
298static long zclk_round_rate(struct clk *clk, unsigned long rate)
299{
3b207a45 300 unsigned long div_freq = div4_clk_ops->round_rate(clk, rate),
73107925
GL
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
309static 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 */
3b207a45 315 unsigned long div_freq = div4_clk_ops->recalc(clk);
73107925
GL
316
317 if (__raw_readl(FRQCRB) & (1 << 28))
318 return div_freq;
319
320 return clk_get_rate(clk->parent);
321}
322
413bfd0e 323static int kicker_set_rate(struct clk *clk, unsigned long rate)
73107925 324{
413bfd0e
GL
325 if (__raw_readl(FRQCRB) & (1 << 31))
326 return -EBUSY;
327
328 return div4_clk_ops->set_rate(clk, rate);
329}
330
331static void div4_clk_extend(void)
332{
333 int i;
334
335 div4_clk_ops = div4_clks[0].ops;
3b207a45 336
413bfd0e
GL
337 /* Add a kicker-busy check before changing the rate */
338 kicker_ops = *div4_clk_ops;
73107925 339 /* We extend the DIV4 clock with a 1:1 pass-through case */
3b207a45
GL
340 zclk_ops = *div4_clk_ops;
341
413bfd0e 342 kicker_ops.set_rate = kicker_set_rate;
3b207a45
GL
343 zclk_ops.set_rate = zclk_set_rate;
344 zclk_ops.round_rate = zclk_round_rate;
345 zclk_ops.recalc = zclk_recalc;
346
413bfd0e
GL
347 for (i = 0; i < DIV4_NR; i++)
348 div4_clks[i].ops = i == DIV4_Z ? &zclk_ops : &kicker_ops;
73107925
GL
349}
350
f6d84f4a
MD
351enum { 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
d4775356
KM
359static 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
369static struct clk *pll_parent[4] = {
370 [0] = &pll1_div2_clk,
371 [1] = &pll2_clk,
372 [2] = &pll1_div13_clk,
373};
374
375static struct clk *hsi_parent[4] = {
376 [0] = &pll1_div2_clk,
377 [1] = &pll2_clk,
378 [2] = &pll1_div7_clk,
379};
380
381static 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
388static 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
f6d84f4a 396static struct clk div6_clks[DIV6_NR] = {
d4775356
KM
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),
ca371d28 403 [DIV6_ZB1] = SH_CLK_DIV6_EXT(ZBCKCR, CLK_ENABLE_ON_INIT,
d4775356
KM
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),
6d9598e2
MD
437};
438
f5948bac
KM
439/* DSI DIV */
440static 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
462static long dsiphy_round_rate(struct clk *clk, unsigned long rate)
463{
464 return clk_rate_mult_range_round(clk, 12, 33, rate);
465}
466
467static 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
477static 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
493static 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
7bcda508 512static struct sh_clk_ops dsiphy_clk_ops = {
f5948bac
KM
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
520static struct clk_mapping dsi0phy_clk_mapping = {
521 .phys = DSI0PHYCR,
522 .len = 4,
523};
524
525static struct clk_mapping dsi1phy_clk_mapping = {
526 .phys = DSI1PHYCR,
527 .len = 4,
528};
529
530static struct clk dsi0phy_clk = {
531 .ops = &dsiphy_clk_ops,
532 .parent = &div6_clks[DIV6_DSI0P], /* late install */
533 .mapping = &dsi0phy_clk_mapping,
534};
535
536static struct clk dsi1phy_clk = {
537 .ops = &dsiphy_clk_ops,
538 .parent = &div6_clks[DIV6_DSI1P], /* late install */
539 .mapping = &dsi1phy_clk_mapping,
540};
541
542static struct clk *late_main_clks[] = {
543 &dsi0phy_clk,
544 &dsi1phy_clk,
fe7aa82d 545 &twd_clk,
f5948bac
KM
546};
547
f6d84f4a 548enum { MSTP001,
73107925 549 MSTP129, MSTP128, MSTP127, MSTP126, MSTP125, MSTP118, MSTP116, MSTP112, MSTP100,
832290b2 550 MSTP219, MSTP218, MSTP217,
f6d84f4a 551 MSTP207, MSTP206, MSTP204, MSTP203, MSTP202, MSTP201, MSTP200,
12a7cfef 552 MSTP331, MSTP329, MSTP328, MSTP325, MSTP323, MSTP322,
681e1b3e 553 MSTP314, MSTP313, MSTP312, MSTP311,
b885966f 554 MSTP304, MSTP303, MSTP302, MSTP301, MSTP300,
696d6e17 555 MSTP411, MSTP410, MSTP403,
2f472ae6 556 MSTP508,
6d9598e2
MD
557 MSTP_NR };
558
559#define MSTP(_parent, _reg, _bit, _flags) \
560 SH_CLK_MSTP32(_parent, _reg, _bit, _flags)
561
562static struct clk mstp_clks[MSTP_NR] = {
f6d84f4a 563 [MSTP001] = MSTP(&div4_clks[DIV4_HP], SMSTPCR0, 1, 0), /* IIC2 */
ad054cbd
MD
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 */
5010f3db 568 [MSTP125] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR1, 25, 0), /* TMU0 */
170c7ab5 569 [MSTP118] = MSTP(&div4_clks[DIV4_B], SMSTPCR1, 18, 0), /* DSITX0 */
f6d84f4a 570 [MSTP116] = MSTP(&div4_clks[DIV4_HP], SMSTPCR1, 16, 0), /* IIC0 */
73107925 571 [MSTP112] = MSTP(&div4_clks[DIV4_ZG], SMSTPCR1, 12, 0), /* SGX */
170c7ab5 572 [MSTP100] = MSTP(&div4_clks[DIV4_B], SMSTPCR1, 0, 0), /* LCDC0 */
f6d84f4a 573 [MSTP219] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR2, 19, 0), /* SCIFA7 */
32103c7b 574 [MSTP218] = MSTP(&div4_clks[DIV4_HP], SMSTPCR2, 18, 0), /* SY-DMAC */
832290b2 575 [MSTP217] = MSTP(&div4_clks[DIV4_HP], SMSTPCR2, 17, 0), /* MP-DMAC */
f6d84f4a
MD
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 */
6d9598e2 584 [MSTP329] = MSTP(&r_clk, SMSTPCR3, 29, 0), /* CMT10 */
ea7e1a5a 585 [MSTP328] = MSTP(&div4_clks[DIV4_HP], SMSTPCR3, 28, 0), /*FSI*/
5a1b70a4 586 [MSTP325] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR3, 25, 0), /* IrDA */
f6d84f4a 587 [MSTP323] = MSTP(&div4_clks[DIV4_HP], SMSTPCR3, 23, 0), /* IIC1 */
12a7cfef 588 [MSTP322] = MSTP(&div4_clks[DIV4_HP], SMSTPCR3, 22, 0), /* USB */
fb66c523
MD
589 [MSTP314] = MSTP(&div6_clks[DIV6_SDHI0], SMSTPCR3, 14, 0), /* SDHI0 */
590 [MSTP313] = MSTP(&div6_clks[DIV6_SDHI1], SMSTPCR3, 13, 0), /* SDHI1 */
6bf45a10 591 [MSTP312] = MSTP(&div4_clks[DIV4_HP], SMSTPCR3, 12, 0), /* MMCIF0 */
fb66c523 592 [MSTP311] = MSTP(&div6_clks[DIV6_SDHI2], SMSTPCR3, 11, 0), /* SDHI2 */
b885966f 593 [MSTP304] = MSTP(&main_div2_clk, SMSTPCR3, 4, 0), /* TPU0 */
33661c9e
MD
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 */
f6d84f4a
MD
598 [MSTP411] = MSTP(&div4_clks[DIV4_HP], SMSTPCR4, 11, 0), /* IIC3 */
599 [MSTP410] = MSTP(&div4_clks[DIV4_HP], SMSTPCR4, 10, 0), /* IIC4 */
019c4ae3 600 [MSTP403] = MSTP(&r_clk, SMSTPCR4, 3, 0), /* KEYSC */
2f472ae6 601 [MSTP508] = MSTP(&div4_clks[DIV4_HP], SMSTPCR5, 8, 0), /* INTCA0 */
6d9598e2
MD
602};
603
48609533
SH
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 */
6d9598e2 611static struct clk_lookup lookups[] = {
f6d84f4a
MD
612 /* main clocks */
613 CLKDEV_CON_ID("r_clk", &r_clk),
fe7aa82d 614 CLKDEV_DEV_ID("smp_twd", &twd_clk), /* smp_twd */
f6d84f4a 615
73107925 616 /* DIV4 clocks */
e4a6a29d 617 CLKDEV_DEV_ID("cpu0", &div4_clks[DIV4_Z]),
73107925 618
170c7ab5 619 /* DIV6 clocks */
ad054cbd
MD
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]),
fb66c523
MD
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]),
170c7ab5 626
6d9598e2 627 /* MSTP32 clocks */
696d6e17 628 CLKDEV_DEV_ID("i2c-sh_mobile.2", &mstp_clks[MSTP001]), /* I2C2 */
48609533 629 CLKDEV_DEV_ID("e6824000.i2c", &mstp_clks[MSTP001]), /* I2C2 */
ad054cbd
MD
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 */
170c7ab5 634 CLKDEV_DEV_ID("sh-mipi-dsi.0", &mstp_clks[MSTP118]), /* DSITX */
ad054cbd 635 CLKDEV_DEV_ID("i2c-sh_mobile.0", &mstp_clks[MSTP116]), /* I2C0 */
48609533 636 CLKDEV_DEV_ID("e6820000.i2c", &mstp_clks[MSTP116]), /* I2C0 */
ad054cbd 637 CLKDEV_DEV_ID("sh_mobile_lcdc_fb.0", &mstp_clks[MSTP100]), /* LCDC0 */
6d9598e2 638 CLKDEV_DEV_ID("sh-sci.7", &mstp_clks[MSTP219]), /* SCIFA7 */
ff4ce48e 639 CLKDEV_DEV_ID("e6cd0000.serial", &mstp_clks[MSTP219]), /* SCIFA7 */
32103c7b 640 CLKDEV_DEV_ID("sh-dma-engine.0", &mstp_clks[MSTP218]), /* SY-DMAC */
832290b2 641 CLKDEV_DEV_ID("sh-dma-engine.1", &mstp_clks[MSTP217]), /* MP-DMAC */
6d9598e2 642 CLKDEV_DEV_ID("sh-sci.5", &mstp_clks[MSTP207]), /* SCIFA5 */
ff4ce48e 643 CLKDEV_DEV_ID("e6cb0000.serial", &mstp_clks[MSTP207]), /* SCIFA5 */
6d9598e2 644 CLKDEV_DEV_ID("sh-sci.8", &mstp_clks[MSTP206]), /* SCIFB */
2c3758b0 645 CLKDEV_DEV_ID("e6c3000.serial", &mstp_clks[MSTP206]), /* SCIFB */
6d9598e2 646 CLKDEV_DEV_ID("sh-sci.0", &mstp_clks[MSTP204]), /* SCIFA0 */
ff4ce48e 647 CLKDEV_DEV_ID("e6c40000.serial", &mstp_clks[MSTP204]), /* SCIFA0 */
6d9598e2 648 CLKDEV_DEV_ID("sh-sci.1", &mstp_clks[MSTP203]), /* SCIFA1 */
ff4ce48e 649 CLKDEV_DEV_ID("e6c50000.serial", &mstp_clks[MSTP203]), /* SCIFA1 */
6d9598e2 650 CLKDEV_DEV_ID("sh-sci.2", &mstp_clks[MSTP202]), /* SCIFA2 */
ff4ce48e 651 CLKDEV_DEV_ID("e6c60000.serial", &mstp_clks[MSTP202]), /* SCIFA2 */
6d9598e2 652 CLKDEV_DEV_ID("sh-sci.3", &mstp_clks[MSTP201]), /* SCIFA3 */
ff4ce48e 653 CLKDEV_DEV_ID("e6c70000.serial", &mstp_clks[MSTP201]), /* SCIFA3 */
6d9598e2 654 CLKDEV_DEV_ID("sh-sci.4", &mstp_clks[MSTP200]), /* SCIFA4 */
ff4ce48e 655 CLKDEV_DEV_ID("e6c80000.serial", &mstp_clks[MSTP200]), /* SCIFA4 */
6d9598e2 656 CLKDEV_DEV_ID("sh-sci.6", &mstp_clks[MSTP331]), /* SCIFA6 */
ff4ce48e 657 CLKDEV_DEV_ID("e6cc0000.serial", &mstp_clks[MSTP331]), /* SCIFA6 */
ea7e1a5a 658 CLKDEV_DEV_ID("sh_fsi2", &mstp_clks[MSTP328]), /* FSI */
e1c98c5d 659 CLKDEV_DEV_ID("ec230000.sound", &mstp_clks[MSTP328]), /* FSI */
a33bb8a2 660 CLKDEV_DEV_ID("sh_irda.0", &mstp_clks[MSTP325]), /* IrDA */
b028f94b 661 CLKDEV_DEV_ID("i2c-sh_mobile.1", &mstp_clks[MSTP323]), /* I2C1 */
48609533 662 CLKDEV_DEV_ID("e6822000.i2c", &mstp_clks[MSTP323]), /* I2C1 */
12a7cfef 663 CLKDEV_DEV_ID("renesas_usbhs", &mstp_clks[MSTP322]), /* USB */
fb66c523 664 CLKDEV_DEV_ID("sh_mobile_sdhi.0", &mstp_clks[MSTP314]), /* SDHI0 */
33f6be3b 665 CLKDEV_DEV_ID("ee100000.sd", &mstp_clks[MSTP314]), /* SDHI0 */
fb66c523 666 CLKDEV_DEV_ID("sh_mobile_sdhi.1", &mstp_clks[MSTP313]), /* SDHI1 */
33f6be3b 667 CLKDEV_DEV_ID("ee120000.sd", &mstp_clks[MSTP313]), /* SDHI1 */
6bf45a10 668 CLKDEV_DEV_ID("sh_mmcif.0", &mstp_clks[MSTP312]), /* MMCIF0 */
33f6be3b 669 CLKDEV_DEV_ID("e6bd0000.mmc", &mstp_clks[MSTP312]), /* MMCIF0 */
fb66c523 670 CLKDEV_DEV_ID("sh_mobile_sdhi.2", &mstp_clks[MSTP311]), /* SDHI2 */
33f6be3b 671 CLKDEV_DEV_ID("ee140000.sd", &mstp_clks[MSTP311]), /* SDHI2 */
b885966f
LP
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 */
b028f94b 677 CLKDEV_DEV_ID("i2c-sh_mobile.3", &mstp_clks[MSTP411]), /* I2C3 */
48609533 678 CLKDEV_DEV_ID("e6826000.i2c", &mstp_clks[MSTP411]), /* I2C3 */
b028f94b 679 CLKDEV_DEV_ID("i2c-sh_mobile.4", &mstp_clks[MSTP410]), /* I2C4 */
48609533 680 CLKDEV_DEV_ID("e6828000.i2c", &mstp_clks[MSTP410]), /* I2C4 */
019c4ae3 681 CLKDEV_DEV_ID("sh_keysc.0", &mstp_clks[MSTP403]), /* KEYSC */
2f472ae6
GU
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 */
99b7835e
KM
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),
652256fd 698 CLKDEV_ICK_ID("fck", "sh-cmt-48.1", &mstp_clks[MSTP329]), /* CMT1 */
a0f7e749 699 CLKDEV_ICK_ID("fck", "e6138000.timer", &mstp_clks[MSTP329]), /* CMT1 */
3df592bc 700 CLKDEV_ICK_ID("fck", "sh-tmu.0", &mstp_clks[MSTP125]), /* TMU0 */
6d9598e2
MD
701};
702
703void __init sh73a0_clock_init(void)
704{
705 int k, ret = 0;
706
fb66c523
MD
707 /* Set SDHI clocks to a known state */
708 __raw_writel(0x108, SD0CKCR);
709 __raw_writel(0x108, SD1CKCR);
710 __raw_writel(0x108, SD2CKCR);
711
f6d84f4a 712 /* detect main clock parent */
86d84083 713 switch ((__raw_readl(CKSCR) >> 28) & 0x03) {
f6d84f4a
MD
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
6d9598e2
MD
728 for (k = 0; !ret && (k < ARRAY_SIZE(main_clks)); k++)
729 ret = clk_register(main_clks[k]);
730
73107925 731 if (!ret) {
f6d84f4a 732 ret = sh_clk_div4_register(div4_clks, DIV4_NR, &div4_table);
73107925 733 if (!ret)
413bfd0e 734 div4_clk_extend();
73107925 735 }
f6d84f4a
MD
736
737 if (!ret)
d4775356 738 ret = sh_clk_div6_reparent_register(div6_clks, DIV6_NR);
f6d84f4a 739
6d9598e2 740 if (!ret)
64e9de2f 741 ret = sh_clk_mstp_register(mstp_clks, MSTP_NR);
6d9598e2 742
f5948bac
KM
743 for (k = 0; !ret && (k < ARRAY_SIZE(late_main_clks)); k++)
744 ret = clk_register(late_main_clks[k]);
745
6d9598e2
MD
746 clkdev_add_table(lookups, ARRAY_SIZE(lookups));
747
748 if (!ret)
6b6a4c06 749 shmobile_clk_init();
6d9598e2
MD
750 else
751 panic("failed to setup sh73a0 clocks\n");
752}
This page took 0.24527 seconds and 5 git commands to generate.