ARM: shmobile: sh73a0: do not overwrite all div4 clock operations
[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.
14 *
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
18 */
19#include <linux/init.h>
20#include <linux/kernel.h>
21#include <linux/io.h>
22#include <linux/sh_clk.h>
6ef9f6fd 23#include <linux/clkdev.h>
7653c318 24#include <asm/processor.h>
891cab3e 25#include <mach/clock.h>
6d9598e2 26#include <mach/common.h>
6d9598e2 27
0a4b04dc
AB
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)
f6d84f4a
MD
51#define DSI0PHYCR 0xe615006C
52#define DSI1PHYCR 0xe6150070
0a4b04dc
AB
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)
6d9598e2
MD
65
66/* Fixed 32 KHz root clock from EXTALR pin */
67static struct clk r_clk = {
68 .rate = 32768,
69};
70
f6d84f4a
MD
71/*
72 * 26MHz default rate for the EXTAL1 root input clock.
73 * If needed, reset this with clk_set_rate() from the platform code.
74 */
75struct clk sh73a0_extal1_clk = {
76 .rate = 26000000,
77};
78
79/*
80 * 48MHz default rate for the EXTAL2 root input clock.
81 * If needed, reset this with clk_set_rate() from the platform code.
82 */
83struct clk sh73a0_extal2_clk = {
84 .rate = 48000000,
85};
86
7bcda508 87static struct sh_clk_ops main_clk_ops = {
f6d84f4a
MD
88 .recalc = followparent_recalc,
89};
90
91/* Main clock */
92static struct clk main_clk = {
891cab3e 93 /* .parent wll be set on sh73a0_clock_init() */
f6d84f4a
MD
94 .ops = &main_clk_ops,
95};
96
97/* PLL0, PLL1, PLL2, PLL3 */
98static unsigned long pll_recalc(struct clk *clk)
99{
100 unsigned long mult = 1;
101
71fc5099 102 if (__raw_readl(PLLECR) & (1 << clk->enable_bit)) {
f6d84f4a 103 mult = (((__raw_readl(clk->enable_reg) >> 24) & 0x3f) + 1);
71fc5099
MD
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;
110 }
111 }
f6d84f4a
MD
112
113 return clk->parent->rate * mult;
114}
115
7bcda508 116static struct sh_clk_ops pll_clk_ops = {
f6d84f4a
MD
117 .recalc = pll_recalc,
118};
119
120static 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,
6d9598e2
MD
126};
127
f6d84f4a
MD
128static 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,
134};
135
136static 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,
142};
143
144static 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,
150};
151
891cab3e
KM
152/* A fixed divide block */
153SH_CLK_RATIO(div2, 1, 2);
154SH_CLK_RATIO(div7, 1, 7);
155SH_CLK_RATIO(div13, 1, 13);
d4775356 156
891cab3e
KM
157SH_FIXED_RATIO_CLK(extal1_div2_clk, sh73a0_extal1_clk, div2);
158SH_FIXED_RATIO_CLK(extal2_div2_clk, sh73a0_extal2_clk, div2);
159SH_FIXED_RATIO_CLK(main_div2_clk, main_clk, div2);
160SH_FIXED_RATIO_CLK(pll1_div2_clk, pll1_clk, div2);
161SH_FIXED_RATIO_CLK(pll1_div7_clk, pll1_clk, div7);
162SH_FIXED_RATIO_CLK(pll1_div13_clk, pll1_clk, div13);
d4775356
KM
163
164/* External input clock */
165struct clk sh73a0_extcki_clk = {
166};
167
168struct clk sh73a0_extalr_clk = {
169};
170
6d9598e2
MD
171static struct clk *main_clks[] = {
172 &r_clk,
f6d84f4a
MD
173 &sh73a0_extal1_clk,
174 &sh73a0_extal2_clk,
175 &extal1_div2_clk,
176 &extal2_div2_clk,
177 &main_clk,
d4775356 178 &main_div2_clk,
f6d84f4a
MD
179 &pll0_clk,
180 &pll1_clk,
181 &pll2_clk,
182 &pll3_clk,
183 &pll1_div2_clk,
d4775356
KM
184 &pll1_div7_clk,
185 &pll1_div13_clk,
186 &sh73a0_extcki_clk,
187 &sh73a0_extalr_clk,
f6d84f4a
MD
188};
189
7653c318 190static int frqcr_kick(void)
f6d84f4a 191{
7653c318
GL
192 int i;
193
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;
201
202 return -ETIMEDOUT;
203}
f6d84f4a 204
7653c318
GL
205static void div4_kick(struct clk *clk)
206{
207 frqcr_kick();
f6d84f4a
MD
208}
209
210static int divisors[] = { 2, 3, 4, 6, 8, 12, 16, 18,
c070c203 211 24, 0, 36, 48, 7 };
f6d84f4a
MD
212
213static struct clk_div_mult_table div4_div_mult_table = {
214 .divisors = divisors,
215 .nr_divisors = ARRAY_SIZE(divisors),
216};
217
218static struct clk_div4_table div4_table = {
219 .div_mult_table = &div4_div_mult_table,
220 .kick = div4_kick,
221};
222
223enum { DIV4_I, DIV4_ZG, DIV4_M3, DIV4_B, DIV4_M1, DIV4_M2,
1f7ccd88 224 DIV4_Z, DIV4_ZX, DIV4_HP, DIV4_NR };
f6d84f4a
MD
225
226#define DIV4(_reg, _bit, _mask, _flags) \
227 SH_CLK_DIV4(&pll1_clk, _reg, _bit, _mask, _flags)
228
229static struct clk div4_clks[DIV4_NR] = {
bf519bfb 230 [DIV4_I] = DIV4(FRQCRA, 20, 0xdff, CLK_ENABLE_ON_INIT),
73107925
GL
231 /*
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.
235 */
8a444474 236 [DIV4_ZG] = SH_CLK_DIV4(&pll0_clk, FRQCRA, 16, 0xd7f, CLK_ENABLE_ON_INIT),
bf519bfb
KM
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),
8a444474 241 [DIV4_Z] = SH_CLK_DIV4(&pll0_clk, FRQCRB, 24, 0x97f, 0),
bf519bfb
KM
242 [DIV4_ZX] = DIV4(FRQCRB, 12, 0xdff, 0),
243 [DIV4_HP] = DIV4(FRQCRB, 4, 0xdff, 0),
f6d84f4a
MD
244};
245
fe7aa82d
GL
246static unsigned long twd_recalc(struct clk *clk)
247{
248 return clk_get_rate(clk->parent) / 4;
249}
250
251static struct sh_clk_ops twd_clk_ops = {
252 .recalc = twd_recalc,
253};
254
255static struct clk twd_clk = {
256 .parent = &div4_clks[DIV4_Z],
257 .ops = &twd_clk_ops,
258};
259
3b207a45
GL
260static struct sh_clk_ops zclk_ops;
261static const struct sh_clk_ops *div4_clk_ops;
73107925
GL
262
263static int zclk_set_rate(struct clk *clk, unsigned long rate)
264{
265 int ret;
266
267 if (!clk->parent || !__clk_get(clk->parent))
268 return -ENODEV;
269
270 if (readl(FRQCRB) & (1 << 31))
271 return -EBUSY;
272
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 */
3b207a45 277 ret = div4_clk_ops->set_rate(clk, rate / 2);
73107925
GL
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);
285
286 ret = frqcr_kick();
287 if (ret >= 0)
288 /*
289 * set the divider - call the DIV4 method, it will kick
290 * FRQCRB too
291 */
3b207a45 292 ret = div4_clk_ops->set_rate(clk, rate);
73107925
GL
293 if (ret < 0)
294 goto esetrate;
295 }
296
297esetrate:
298 __clk_put(clk->parent);
299 return ret;
300}
301
302static long zclk_round_rate(struct clk *clk, unsigned long rate)
303{
3b207a45 304 unsigned long div_freq = div4_clk_ops->round_rate(clk, rate),
73107925
GL
305 parent_freq = clk_get_rate(clk->parent);
306
307 if (rate > div_freq && abs(parent_freq - rate) < rate - div_freq)
308 return parent_freq;
309
310 return div_freq;
311}
312
313static unsigned long zclk_recalc(struct clk *clk)
314{
315 /*
316 * Must recalculate frequencies in case PLL0 has been changed, even if
317 * the divisor is unused ATM!
318 */
3b207a45 319 unsigned long div_freq = div4_clk_ops->recalc(clk);
73107925
GL
320
321 if (__raw_readl(FRQCRB) & (1 << 28))
322 return div_freq;
323
324 return clk_get_rate(clk->parent);
325}
326
327static void zclk_extend(void)
328{
3b207a45
GL
329 div4_clk_ops = div4_clks[DIV4_Z].ops;
330
73107925 331 /* We extend the DIV4 clock with a 1:1 pass-through case */
3b207a45
GL
332 zclk_ops = *div4_clk_ops;
333
334 zclk_ops.set_rate = zclk_set_rate;
335 zclk_ops.round_rate = zclk_round_rate;
336 zclk_ops.recalc = zclk_recalc;
337
338 div4_clks[DIV4_Z].ops = &zclk_ops;
73107925
GL
339}
340
f6d84f4a
MD
341enum { DIV6_VCK1, DIV6_VCK2, DIV6_VCK3, DIV6_ZB1,
342 DIV6_FLCTL, DIV6_SDHI0, DIV6_SDHI1, DIV6_SDHI2,
343 DIV6_FSIA, DIV6_FSIB, DIV6_SUB,
344 DIV6_SPUA, DIV6_SPUV, DIV6_MSU,
345 DIV6_HSI, DIV6_MFG1, DIV6_MFG2,
346 DIV6_DSIT, DIV6_DSI0P, DIV6_DSI1P,
347 DIV6_NR };
348
d4775356
KM
349static struct clk *vck_parent[8] = {
350 [0] = &pll1_div2_clk,
351 [1] = &pll2_clk,
352 [2] = &sh73a0_extcki_clk,
353 [3] = &sh73a0_extal2_clk,
354 [4] = &main_div2_clk,
355 [5] = &sh73a0_extalr_clk,
356 [6] = &main_clk,
357};
358
359static struct clk *pll_parent[4] = {
360 [0] = &pll1_div2_clk,
361 [1] = &pll2_clk,
362 [2] = &pll1_div13_clk,
363};
364
365static struct clk *hsi_parent[4] = {
366 [0] = &pll1_div2_clk,
367 [1] = &pll2_clk,
368 [2] = &pll1_div7_clk,
369};
370
371static struct clk *pll_extal2_parent[] = {
372 [0] = &pll1_div2_clk,
373 [1] = &pll2_clk,
374 [2] = &sh73a0_extal2_clk,
375 [3] = &sh73a0_extal2_clk,
376};
377
378static struct clk *dsi_parent[8] = {
379 [0] = &pll1_div2_clk,
380 [1] = &pll2_clk,
381 [2] = &main_clk,
382 [3] = &sh73a0_extal2_clk,
383 [4] = &sh73a0_extcki_clk,
384};
385
f6d84f4a 386static struct clk div6_clks[DIV6_NR] = {
d4775356
KM
387 [DIV6_VCK1] = SH_CLK_DIV6_EXT(VCLKCR1, 0,
388 vck_parent, ARRAY_SIZE(vck_parent), 12, 3),
389 [DIV6_VCK2] = SH_CLK_DIV6_EXT(VCLKCR2, 0,
390 vck_parent, ARRAY_SIZE(vck_parent), 12, 3),
391 [DIV6_VCK3] = SH_CLK_DIV6_EXT(VCLKCR3, 0,
392 vck_parent, ARRAY_SIZE(vck_parent), 12, 3),
ca371d28 393 [DIV6_ZB1] = SH_CLK_DIV6_EXT(ZBCKCR, CLK_ENABLE_ON_INIT,
d4775356
KM
394 pll_parent, ARRAY_SIZE(pll_parent), 7, 1),
395 [DIV6_FLCTL] = SH_CLK_DIV6_EXT(FLCKCR, 0,
396 pll_parent, ARRAY_SIZE(pll_parent), 7, 1),
397 [DIV6_SDHI0] = SH_CLK_DIV6_EXT(SD0CKCR, 0,
398 pll_parent, ARRAY_SIZE(pll_parent), 6, 2),
399 [DIV6_SDHI1] = SH_CLK_DIV6_EXT(SD1CKCR, 0,
400 pll_parent, ARRAY_SIZE(pll_parent), 6, 2),
401 [DIV6_SDHI2] = SH_CLK_DIV6_EXT(SD2CKCR, 0,
402 pll_parent, ARRAY_SIZE(pll_parent), 6, 2),
403 [DIV6_FSIA] = SH_CLK_DIV6_EXT(FSIACKCR, 0,
404 pll_parent, ARRAY_SIZE(pll_parent), 6, 1),
405 [DIV6_FSIB] = SH_CLK_DIV6_EXT(FSIBCKCR, 0,
406 pll_parent, ARRAY_SIZE(pll_parent), 6, 1),
407 [DIV6_SUB] = SH_CLK_DIV6_EXT(SUBCKCR, 0,
408 pll_extal2_parent, ARRAY_SIZE(pll_extal2_parent), 6, 2),
409 [DIV6_SPUA] = SH_CLK_DIV6_EXT(SPUACKCR, 0,
410 pll_extal2_parent, ARRAY_SIZE(pll_extal2_parent), 6, 2),
411 [DIV6_SPUV] = SH_CLK_DIV6_EXT(SPUVCKCR, 0,
412 pll_extal2_parent, ARRAY_SIZE(pll_extal2_parent), 6, 2),
413 [DIV6_MSU] = SH_CLK_DIV6_EXT(MSUCKCR, 0,
414 pll_parent, ARRAY_SIZE(pll_parent), 7, 1),
415 [DIV6_HSI] = SH_CLK_DIV6_EXT(HSICKCR, 0,
416 hsi_parent, ARRAY_SIZE(hsi_parent), 6, 2),
417 [DIV6_MFG1] = SH_CLK_DIV6_EXT(MFCK1CR, 0,
418 pll_parent, ARRAY_SIZE(pll_parent), 7, 1),
419 [DIV6_MFG2] = SH_CLK_DIV6_EXT(MFCK2CR, 0,
420 pll_parent, ARRAY_SIZE(pll_parent), 7, 1),
421 [DIV6_DSIT] = SH_CLK_DIV6_EXT(DSITCKCR, 0,
422 pll_parent, ARRAY_SIZE(pll_parent), 7, 1),
423 [DIV6_DSI0P] = SH_CLK_DIV6_EXT(DSI0PCKCR, 0,
424 dsi_parent, ARRAY_SIZE(dsi_parent), 12, 3),
425 [DIV6_DSI1P] = SH_CLK_DIV6_EXT(DSI1PCKCR, 0,
426 dsi_parent, ARRAY_SIZE(dsi_parent), 12, 3),
6d9598e2
MD
427};
428
f5948bac
KM
429/* DSI DIV */
430static unsigned long dsiphy_recalc(struct clk *clk)
431{
432 u32 value;
433
434 value = __raw_readl(clk->mapping->base);
435
436 /* FIXME */
437 if (!(value & 0x000B8000))
438 return clk->parent->rate;
439
440 value &= 0x3f;
441 value += 1;
442
443 if ((value < 12) ||
444 (value > 33)) {
445 pr_err("DSIPHY has wrong value (%d)", value);
446 return 0;
447 }
448
449 return clk->parent->rate / value;
450}
451
452static long dsiphy_round_rate(struct clk *clk, unsigned long rate)
453{
454 return clk_rate_mult_range_round(clk, 12, 33, rate);
455}
456
457static void dsiphy_disable(struct clk *clk)
458{
459 u32 value;
460
461 value = __raw_readl(clk->mapping->base);
462 value &= ~0x000B8000;
463
464 __raw_writel(value , clk->mapping->base);
465}
466
467static int dsiphy_enable(struct clk *clk)
468{
469 u32 value;
470 int multi;
471
472 value = __raw_readl(clk->mapping->base);
473 multi = (value & 0x3f) + 1;
474
475 if ((multi < 12) || (multi > 33))
476 return -EIO;
477
478 __raw_writel(value | 0x000B8000, clk->mapping->base);
479
480 return 0;
481}
482
483static int dsiphy_set_rate(struct clk *clk, unsigned long rate)
484{
485 u32 value;
486 int idx;
487
488 idx = rate / clk->parent->rate;
489 if ((idx < 12) || (idx > 33))
490 return -EINVAL;
491
492 idx += -1;
493
494 value = __raw_readl(clk->mapping->base);
495 value = (value & ~0x3f) + idx;
496
497 __raw_writel(value, clk->mapping->base);
498
499 return 0;
500}
501
7bcda508 502static struct sh_clk_ops dsiphy_clk_ops = {
f5948bac
KM
503 .recalc = dsiphy_recalc,
504 .round_rate = dsiphy_round_rate,
505 .set_rate = dsiphy_set_rate,
506 .enable = dsiphy_enable,
507 .disable = dsiphy_disable,
508};
509
510static struct clk_mapping dsi0phy_clk_mapping = {
511 .phys = DSI0PHYCR,
512 .len = 4,
513};
514
515static struct clk_mapping dsi1phy_clk_mapping = {
516 .phys = DSI1PHYCR,
517 .len = 4,
518};
519
520static struct clk dsi0phy_clk = {
521 .ops = &dsiphy_clk_ops,
522 .parent = &div6_clks[DIV6_DSI0P], /* late install */
523 .mapping = &dsi0phy_clk_mapping,
524};
525
526static struct clk dsi1phy_clk = {
527 .ops = &dsiphy_clk_ops,
528 .parent = &div6_clks[DIV6_DSI1P], /* late install */
529 .mapping = &dsi1phy_clk_mapping,
530};
531
532static struct clk *late_main_clks[] = {
533 &dsi0phy_clk,
534 &dsi1phy_clk,
fe7aa82d 535 &twd_clk,
f5948bac
KM
536};
537
f6d84f4a 538enum { MSTP001,
73107925 539 MSTP129, MSTP128, MSTP127, MSTP126, MSTP125, MSTP118, MSTP116, MSTP112, MSTP100,
832290b2 540 MSTP219, MSTP218, MSTP217,
f6d84f4a 541 MSTP207, MSTP206, MSTP204, MSTP203, MSTP202, MSTP201, MSTP200,
12a7cfef 542 MSTP331, MSTP329, MSTP328, MSTP325, MSTP323, MSTP322,
681e1b3e 543 MSTP314, MSTP313, MSTP312, MSTP311,
33661c9e 544 MSTP303, MSTP302, MSTP301, MSTP300,
696d6e17 545 MSTP411, MSTP410, MSTP403,
6d9598e2
MD
546 MSTP_NR };
547
548#define MSTP(_parent, _reg, _bit, _flags) \
549 SH_CLK_MSTP32(_parent, _reg, _bit, _flags)
550
551static struct clk mstp_clks[MSTP_NR] = {
f6d84f4a 552 [MSTP001] = MSTP(&div4_clks[DIV4_HP], SMSTPCR0, 1, 0), /* IIC2 */
ad054cbd
MD
553 [MSTP129] = MSTP(&div4_clks[DIV4_B], SMSTPCR1, 29, 0), /* CEU1 */
554 [MSTP128] = MSTP(&div4_clks[DIV4_B], SMSTPCR1, 28, 0), /* CSI2-RX1 */
555 [MSTP127] = MSTP(&div4_clks[DIV4_B], SMSTPCR1, 27, 0), /* CEU0 */
556 [MSTP126] = MSTP(&div4_clks[DIV4_B], SMSTPCR1, 26, 0), /* CSI2-RX0 */
5010f3db 557 [MSTP125] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR1, 25, 0), /* TMU0 */
170c7ab5 558 [MSTP118] = MSTP(&div4_clks[DIV4_B], SMSTPCR1, 18, 0), /* DSITX0 */
f6d84f4a 559 [MSTP116] = MSTP(&div4_clks[DIV4_HP], SMSTPCR1, 16, 0), /* IIC0 */
73107925 560 [MSTP112] = MSTP(&div4_clks[DIV4_ZG], SMSTPCR1, 12, 0), /* SGX */
170c7ab5 561 [MSTP100] = MSTP(&div4_clks[DIV4_B], SMSTPCR1, 0, 0), /* LCDC0 */
f6d84f4a 562 [MSTP219] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR2, 19, 0), /* SCIFA7 */
32103c7b 563 [MSTP218] = MSTP(&div4_clks[DIV4_HP], SMSTPCR2, 18, 0), /* SY-DMAC */
832290b2 564 [MSTP217] = MSTP(&div4_clks[DIV4_HP], SMSTPCR2, 17, 0), /* MP-DMAC */
f6d84f4a
MD
565 [MSTP207] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR2, 7, 0), /* SCIFA5 */
566 [MSTP206] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR2, 6, 0), /* SCIFB */
567 [MSTP204] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR2, 4, 0), /* SCIFA0 */
568 [MSTP203] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR2, 3, 0), /* SCIFA1 */
569 [MSTP202] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR2, 2, 0), /* SCIFA2 */
570 [MSTP201] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR2, 1, 0), /* SCIFA3 */
571 [MSTP200] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR2, 0, 0), /* SCIFA4 */
572 [MSTP331] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR3, 31, 0), /* SCIFA6 */
6d9598e2 573 [MSTP329] = MSTP(&r_clk, SMSTPCR3, 29, 0), /* CMT10 */
ea7e1a5a 574 [MSTP328] = MSTP(&div4_clks[DIV4_HP], SMSTPCR3, 28, 0), /*FSI*/
5a1b70a4 575 [MSTP325] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR3, 25, 0), /* IrDA */
f6d84f4a 576 [MSTP323] = MSTP(&div4_clks[DIV4_HP], SMSTPCR3, 23, 0), /* IIC1 */
12a7cfef 577 [MSTP322] = MSTP(&div4_clks[DIV4_HP], SMSTPCR3, 22, 0), /* USB */
fb66c523
MD
578 [MSTP314] = MSTP(&div6_clks[DIV6_SDHI0], SMSTPCR3, 14, 0), /* SDHI0 */
579 [MSTP313] = MSTP(&div6_clks[DIV6_SDHI1], SMSTPCR3, 13, 0), /* SDHI1 */
6bf45a10 580 [MSTP312] = MSTP(&div4_clks[DIV4_HP], SMSTPCR3, 12, 0), /* MMCIF0 */
fb66c523 581 [MSTP311] = MSTP(&div6_clks[DIV6_SDHI2], SMSTPCR3, 11, 0), /* SDHI2 */
33661c9e
MD
582 [MSTP303] = MSTP(&main_div2_clk, SMSTPCR3, 3, 0), /* TPU1 */
583 [MSTP302] = MSTP(&main_div2_clk, SMSTPCR3, 2, 0), /* TPU2 */
584 [MSTP301] = MSTP(&main_div2_clk, SMSTPCR3, 1, 0), /* TPU3 */
585 [MSTP300] = MSTP(&main_div2_clk, SMSTPCR3, 0, 0), /* TPU4 */
f6d84f4a
MD
586 [MSTP411] = MSTP(&div4_clks[DIV4_HP], SMSTPCR4, 11, 0), /* IIC3 */
587 [MSTP410] = MSTP(&div4_clks[DIV4_HP], SMSTPCR4, 10, 0), /* IIC4 */
019c4ae3 588 [MSTP403] = MSTP(&r_clk, SMSTPCR4, 3, 0), /* KEYSC */
6d9598e2
MD
589};
590
48609533
SH
591/* The lookups structure below includes duplicate entries for some clocks
592 * with alternate names.
593 * - The traditional name used when a device is initialised with platform data
594 * - The name used when a device is initialised using device tree
595 * The longer-term aim is to remove these duplicates, and indeed the
596 * lookups table entirely, by describing clocks using device tree.
597 */
6d9598e2 598static struct clk_lookup lookups[] = {
f6d84f4a
MD
599 /* main clocks */
600 CLKDEV_CON_ID("r_clk", &r_clk),
fe7aa82d 601 CLKDEV_DEV_ID("smp_twd", &twd_clk), /* smp_twd */
f6d84f4a 602
73107925
GL
603 /* DIV4 clocks */
604 CLKDEV_DEV_ID("cpufreq-cpu0", &div4_clks[DIV4_Z]),
605
170c7ab5 606 /* DIV6 clocks */
ad054cbd
MD
607 CLKDEV_CON_ID("vck1_clk", &div6_clks[DIV6_VCK1]),
608 CLKDEV_CON_ID("vck2_clk", &div6_clks[DIV6_VCK2]),
609 CLKDEV_CON_ID("vck3_clk", &div6_clks[DIV6_VCK3]),
fb66c523
MD
610 CLKDEV_CON_ID("sdhi0_clk", &div6_clks[DIV6_SDHI0]),
611 CLKDEV_CON_ID("sdhi1_clk", &div6_clks[DIV6_SDHI1]),
612 CLKDEV_CON_ID("sdhi2_clk", &div6_clks[DIV6_SDHI2]),
170c7ab5
MD
613 CLKDEV_ICK_ID("dsit_clk", "sh-mipi-dsi.0", &div6_clks[DIV6_DSIT]),
614 CLKDEV_ICK_ID("dsit_clk", "sh-mipi-dsi.1", &div6_clks[DIV6_DSIT]),
9250741e
KM
615 CLKDEV_ICK_ID("dsip_clk", "sh-mipi-dsi.0", &div6_clks[DIV6_DSI0P]),
616 CLKDEV_ICK_ID("dsip_clk", "sh-mipi-dsi.1", &div6_clks[DIV6_DSI1P]),
f5948bac
KM
617 CLKDEV_ICK_ID("dsiphy_clk", "sh-mipi-dsi.0", &dsi0phy_clk),
618 CLKDEV_ICK_ID("dsiphy_clk", "sh-mipi-dsi.1", &dsi1phy_clk),
170c7ab5 619
6d9598e2 620 /* MSTP32 clocks */
696d6e17 621 CLKDEV_DEV_ID("i2c-sh_mobile.2", &mstp_clks[MSTP001]), /* I2C2 */
48609533 622 CLKDEV_DEV_ID("e6824000.i2c", &mstp_clks[MSTP001]), /* I2C2 */
ad054cbd
MD
623 CLKDEV_DEV_ID("sh_mobile_ceu.1", &mstp_clks[MSTP129]), /* CEU1 */
624 CLKDEV_DEV_ID("sh-mobile-csi2.1", &mstp_clks[MSTP128]), /* CSI2-RX1 */
625 CLKDEV_DEV_ID("sh_mobile_ceu.0", &mstp_clks[MSTP127]), /* CEU0 */
626 CLKDEV_DEV_ID("sh-mobile-csi2.0", &mstp_clks[MSTP126]), /* CSI2-RX0 */
5010f3db
MD
627 CLKDEV_DEV_ID("sh_tmu.0", &mstp_clks[MSTP125]), /* TMU00 */
628 CLKDEV_DEV_ID("sh_tmu.1", &mstp_clks[MSTP125]), /* TMU01 */
170c7ab5 629 CLKDEV_DEV_ID("sh-mipi-dsi.0", &mstp_clks[MSTP118]), /* DSITX */
ad054cbd 630 CLKDEV_DEV_ID("i2c-sh_mobile.0", &mstp_clks[MSTP116]), /* I2C0 */
48609533 631 CLKDEV_DEV_ID("e6820000.i2c", &mstp_clks[MSTP116]), /* I2C0 */
ad054cbd 632 CLKDEV_DEV_ID("sh_mobile_lcdc_fb.0", &mstp_clks[MSTP100]), /* LCDC0 */
6d9598e2 633 CLKDEV_DEV_ID("sh-sci.7", &mstp_clks[MSTP219]), /* SCIFA7 */
32103c7b 634 CLKDEV_DEV_ID("sh-dma-engine.0", &mstp_clks[MSTP218]), /* SY-DMAC */
832290b2 635 CLKDEV_DEV_ID("sh-dma-engine.1", &mstp_clks[MSTP217]), /* MP-DMAC */
6d9598e2
MD
636 CLKDEV_DEV_ID("sh-sci.5", &mstp_clks[MSTP207]), /* SCIFA5 */
637 CLKDEV_DEV_ID("sh-sci.8", &mstp_clks[MSTP206]), /* SCIFB */
638 CLKDEV_DEV_ID("sh-sci.0", &mstp_clks[MSTP204]), /* SCIFA0 */
639 CLKDEV_DEV_ID("sh-sci.1", &mstp_clks[MSTP203]), /* SCIFA1 */
640 CLKDEV_DEV_ID("sh-sci.2", &mstp_clks[MSTP202]), /* SCIFA2 */
641 CLKDEV_DEV_ID("sh-sci.3", &mstp_clks[MSTP201]), /* SCIFA3 */
642 CLKDEV_DEV_ID("sh-sci.4", &mstp_clks[MSTP200]), /* SCIFA4 */
643 CLKDEV_DEV_ID("sh-sci.6", &mstp_clks[MSTP331]), /* SCIFA6 */
644 CLKDEV_DEV_ID("sh_cmt.10", &mstp_clks[MSTP329]), /* CMT10 */
ea7e1a5a 645 CLKDEV_DEV_ID("sh_fsi2", &mstp_clks[MSTP328]), /* FSI */
a33bb8a2 646 CLKDEV_DEV_ID("sh_irda.0", &mstp_clks[MSTP325]), /* IrDA */
b028f94b 647 CLKDEV_DEV_ID("i2c-sh_mobile.1", &mstp_clks[MSTP323]), /* I2C1 */
48609533 648 CLKDEV_DEV_ID("e6822000.i2c", &mstp_clks[MSTP323]), /* I2C1 */
12a7cfef 649 CLKDEV_DEV_ID("renesas_usbhs", &mstp_clks[MSTP322]), /* USB */
fb66c523 650 CLKDEV_DEV_ID("sh_mobile_sdhi.0", &mstp_clks[MSTP314]), /* SDHI0 */
df2ddd7b 651 CLKDEV_DEV_ID("ee100000.sdhi", &mstp_clks[MSTP314]), /* SDHI0 */
fb66c523 652 CLKDEV_DEV_ID("sh_mobile_sdhi.1", &mstp_clks[MSTP313]), /* SDHI1 */
df2ddd7b 653 CLKDEV_DEV_ID("ee120000.sdhi", &mstp_clks[MSTP313]), /* SDHI1 */
6bf45a10 654 CLKDEV_DEV_ID("sh_mmcif.0", &mstp_clks[MSTP312]), /* MMCIF0 */
93301f5d 655 CLKDEV_DEV_ID("e6bd0000.mmcif", &mstp_clks[MSTP312]), /* MMCIF0 */
fb66c523 656 CLKDEV_DEV_ID("sh_mobile_sdhi.2", &mstp_clks[MSTP311]), /* SDHI2 */
df2ddd7b 657 CLKDEV_DEV_ID("ee140000.sdhi", &mstp_clks[MSTP311]), /* SDHI2 */
33661c9e
MD
658 CLKDEV_DEV_ID("leds-renesas-tpu.12", &mstp_clks[MSTP303]), /* TPU1 */
659 CLKDEV_DEV_ID("leds-renesas-tpu.21", &mstp_clks[MSTP302]), /* TPU2 */
660 CLKDEV_DEV_ID("leds-renesas-tpu.30", &mstp_clks[MSTP301]), /* TPU3 */
661 CLKDEV_DEV_ID("leds-renesas-tpu.41", &mstp_clks[MSTP300]), /* TPU4 */
b028f94b 662 CLKDEV_DEV_ID("i2c-sh_mobile.3", &mstp_clks[MSTP411]), /* I2C3 */
48609533 663 CLKDEV_DEV_ID("e6826000.i2c", &mstp_clks[MSTP411]), /* I2C3 */
b028f94b 664 CLKDEV_DEV_ID("i2c-sh_mobile.4", &mstp_clks[MSTP410]), /* I2C4 */
48609533 665 CLKDEV_DEV_ID("e6828000.i2c", &mstp_clks[MSTP410]), /* I2C4 */
019c4ae3 666 CLKDEV_DEV_ID("sh_keysc.0", &mstp_clks[MSTP403]), /* KEYSC */
6d9598e2
MD
667};
668
669void __init sh73a0_clock_init(void)
670{
671 int k, ret = 0;
672
fb66c523
MD
673 /* Set SDHI clocks to a known state */
674 __raw_writel(0x108, SD0CKCR);
675 __raw_writel(0x108, SD1CKCR);
676 __raw_writel(0x108, SD2CKCR);
677
f6d84f4a 678 /* detect main clock parent */
86d84083 679 switch ((__raw_readl(CKSCR) >> 28) & 0x03) {
f6d84f4a
MD
680 case 0:
681 main_clk.parent = &sh73a0_extal1_clk;
682 break;
683 case 1:
684 main_clk.parent = &extal1_div2_clk;
685 break;
686 case 2:
687 main_clk.parent = &sh73a0_extal2_clk;
688 break;
689 case 3:
690 main_clk.parent = &extal2_div2_clk;
691 break;
692 }
693
6d9598e2
MD
694 for (k = 0; !ret && (k < ARRAY_SIZE(main_clks)); k++)
695 ret = clk_register(main_clks[k]);
696
73107925 697 if (!ret) {
f6d84f4a 698 ret = sh_clk_div4_register(div4_clks, DIV4_NR, &div4_table);
73107925
GL
699 if (!ret)
700 zclk_extend();
701 }
f6d84f4a
MD
702
703 if (!ret)
d4775356 704 ret = sh_clk_div6_reparent_register(div6_clks, DIV6_NR);
f6d84f4a 705
6d9598e2 706 if (!ret)
64e9de2f 707 ret = sh_clk_mstp_register(mstp_clks, MSTP_NR);
6d9598e2 708
f5948bac
KM
709 for (k = 0; !ret && (k < ARRAY_SIZE(late_main_clks)); k++)
710 ret = clk_register(late_main_clks[k]);
711
6d9598e2
MD
712 clkdev_add_table(lookups, ARRAY_SIZE(lookups));
713
714 if (!ret)
6b6a4c06 715 shmobile_clk_init();
6d9598e2
MD
716 else
717 panic("failed to setup sh73a0 clocks\n");
718}
This page took 0.178155 seconds and 5 git commands to generate.