Merge tag 'fscache-fixes-20140917' of git://git.kernel.org/pub/scm/linux/kernel/git...
[linux-2.6-block.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>
ad6ffa0b 25#include "clock.h"
fd44aa5e 26#include "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
413bfd0e 260static struct sh_clk_ops zclk_ops, kicker_ops;
3b207a45 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
413bfd0e 327static int kicker_set_rate(struct clk *clk, unsigned long rate)
73107925 328{
413bfd0e
GL
329 if (__raw_readl(FRQCRB) & (1 << 31))
330 return -EBUSY;
331
332 return div4_clk_ops->set_rate(clk, rate);
333}
334
335static void div4_clk_extend(void)
336{
337 int i;
338
339 div4_clk_ops = div4_clks[0].ops;
3b207a45 340
413bfd0e
GL
341 /* Add a kicker-busy check before changing the rate */
342 kicker_ops = *div4_clk_ops;
73107925 343 /* We extend the DIV4 clock with a 1:1 pass-through case */
3b207a45
GL
344 zclk_ops = *div4_clk_ops;
345
413bfd0e 346 kicker_ops.set_rate = kicker_set_rate;
3b207a45
GL
347 zclk_ops.set_rate = zclk_set_rate;
348 zclk_ops.round_rate = zclk_round_rate;
349 zclk_ops.recalc = zclk_recalc;
350
413bfd0e
GL
351 for (i = 0; i < DIV4_NR; i++)
352 div4_clks[i].ops = i == DIV4_Z ? &zclk_ops : &kicker_ops;
73107925
GL
353}
354
f6d84f4a
MD
355enum { 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 };
362
d4775356
KM
363static 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,
371};
372
373static struct clk *pll_parent[4] = {
374 [0] = &pll1_div2_clk,
375 [1] = &pll2_clk,
376 [2] = &pll1_div13_clk,
377};
378
379static struct clk *hsi_parent[4] = {
380 [0] = &pll1_div2_clk,
381 [1] = &pll2_clk,
382 [2] = &pll1_div7_clk,
383};
384
385static struct clk *pll_extal2_parent[] = {
386 [0] = &pll1_div2_clk,
387 [1] = &pll2_clk,
388 [2] = &sh73a0_extal2_clk,
389 [3] = &sh73a0_extal2_clk,
390};
391
392static 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,
398};
399
f6d84f4a 400static struct clk div6_clks[DIV6_NR] = {
d4775356
KM
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),
ca371d28 407 [DIV6_ZB1] = SH_CLK_DIV6_EXT(ZBCKCR, CLK_ENABLE_ON_INIT,
d4775356
KM
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),
6d9598e2
MD
441};
442
f5948bac
KM
443/* DSI DIV */
444static unsigned long dsiphy_recalc(struct clk *clk)
445{
446 u32 value;
447
448 value = __raw_readl(clk->mapping->base);
449
450 /* FIXME */
451 if (!(value & 0x000B8000))
452 return clk->parent->rate;
453
454 value &= 0x3f;
455 value += 1;
456
457 if ((value < 12) ||
458 (value > 33)) {
459 pr_err("DSIPHY has wrong value (%d)", value);
460 return 0;
461 }
462
463 return clk->parent->rate / value;
464}
465
466static long dsiphy_round_rate(struct clk *clk, unsigned long rate)
467{
468 return clk_rate_mult_range_round(clk, 12, 33, rate);
469}
470
471static void dsiphy_disable(struct clk *clk)
472{
473 u32 value;
474
475 value = __raw_readl(clk->mapping->base);
476 value &= ~0x000B8000;
477
478 __raw_writel(value , clk->mapping->base);
479}
480
481static int dsiphy_enable(struct clk *clk)
482{
483 u32 value;
484 int multi;
485
486 value = __raw_readl(clk->mapping->base);
487 multi = (value & 0x3f) + 1;
488
489 if ((multi < 12) || (multi > 33))
490 return -EIO;
491
492 __raw_writel(value | 0x000B8000, clk->mapping->base);
493
494 return 0;
495}
496
497static int dsiphy_set_rate(struct clk *clk, unsigned long rate)
498{
499 u32 value;
500 int idx;
501
502 idx = rate / clk->parent->rate;
503 if ((idx < 12) || (idx > 33))
504 return -EINVAL;
505
506 idx += -1;
507
508 value = __raw_readl(clk->mapping->base);
509 value = (value & ~0x3f) + idx;
510
511 __raw_writel(value, clk->mapping->base);
512
513 return 0;
514}
515
7bcda508 516static struct sh_clk_ops dsiphy_clk_ops = {
f5948bac
KM
517 .recalc = dsiphy_recalc,
518 .round_rate = dsiphy_round_rate,
519 .set_rate = dsiphy_set_rate,
520 .enable = dsiphy_enable,
521 .disable = dsiphy_disable,
522};
523
524static struct clk_mapping dsi0phy_clk_mapping = {
525 .phys = DSI0PHYCR,
526 .len = 4,
527};
528
529static struct clk_mapping dsi1phy_clk_mapping = {
530 .phys = DSI1PHYCR,
531 .len = 4,
532};
533
534static struct clk dsi0phy_clk = {
535 .ops = &dsiphy_clk_ops,
536 .parent = &div6_clks[DIV6_DSI0P], /* late install */
537 .mapping = &dsi0phy_clk_mapping,
538};
539
540static struct clk dsi1phy_clk = {
541 .ops = &dsiphy_clk_ops,
542 .parent = &div6_clks[DIV6_DSI1P], /* late install */
543 .mapping = &dsi1phy_clk_mapping,
544};
545
546static struct clk *late_main_clks[] = {
547 &dsi0phy_clk,
548 &dsi1phy_clk,
fe7aa82d 549 &twd_clk,
f5948bac
KM
550};
551
f6d84f4a 552enum { MSTP001,
73107925 553 MSTP129, MSTP128, MSTP127, MSTP126, MSTP125, MSTP118, MSTP116, MSTP112, MSTP100,
832290b2 554 MSTP219, MSTP218, MSTP217,
f6d84f4a 555 MSTP207, MSTP206, MSTP204, MSTP203, MSTP202, MSTP201, MSTP200,
12a7cfef 556 MSTP331, MSTP329, MSTP328, MSTP325, MSTP323, MSTP322,
681e1b3e 557 MSTP314, MSTP313, MSTP312, MSTP311,
b885966f 558 MSTP304, MSTP303, MSTP302, MSTP301, MSTP300,
696d6e17 559 MSTP411, MSTP410, MSTP403,
6d9598e2
MD
560 MSTP_NR };
561
562#define MSTP(_parent, _reg, _bit, _flags) \
563 SH_CLK_MSTP32(_parent, _reg, _bit, _flags)
564
565static struct clk mstp_clks[MSTP_NR] = {
f6d84f4a 566 [MSTP001] = MSTP(&div4_clks[DIV4_HP], SMSTPCR0, 1, 0), /* IIC2 */
ad054cbd
MD
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 */
5010f3db 571 [MSTP125] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR1, 25, 0), /* TMU0 */
170c7ab5 572 [MSTP118] = MSTP(&div4_clks[DIV4_B], SMSTPCR1, 18, 0), /* DSITX0 */
f6d84f4a 573 [MSTP116] = MSTP(&div4_clks[DIV4_HP], SMSTPCR1, 16, 0), /* IIC0 */
73107925 574 [MSTP112] = MSTP(&div4_clks[DIV4_ZG], SMSTPCR1, 12, 0), /* SGX */
170c7ab5 575 [MSTP100] = MSTP(&div4_clks[DIV4_B], SMSTPCR1, 0, 0), /* LCDC0 */
f6d84f4a 576 [MSTP219] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR2, 19, 0), /* SCIFA7 */
32103c7b 577 [MSTP218] = MSTP(&div4_clks[DIV4_HP], SMSTPCR2, 18, 0), /* SY-DMAC */
832290b2 578 [MSTP217] = MSTP(&div4_clks[DIV4_HP], SMSTPCR2, 17, 0), /* MP-DMAC */
f6d84f4a
MD
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 */
6d9598e2 587 [MSTP329] = MSTP(&r_clk, SMSTPCR3, 29, 0), /* CMT10 */
ea7e1a5a 588 [MSTP328] = MSTP(&div4_clks[DIV4_HP], SMSTPCR3, 28, 0), /*FSI*/
5a1b70a4 589 [MSTP325] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR3, 25, 0), /* IrDA */
f6d84f4a 590 [MSTP323] = MSTP(&div4_clks[DIV4_HP], SMSTPCR3, 23, 0), /* IIC1 */
12a7cfef 591 [MSTP322] = MSTP(&div4_clks[DIV4_HP], SMSTPCR3, 22, 0), /* USB */
fb66c523
MD
592 [MSTP314] = MSTP(&div6_clks[DIV6_SDHI0], SMSTPCR3, 14, 0), /* SDHI0 */
593 [MSTP313] = MSTP(&div6_clks[DIV6_SDHI1], SMSTPCR3, 13, 0), /* SDHI1 */
6bf45a10 594 [MSTP312] = MSTP(&div4_clks[DIV4_HP], SMSTPCR3, 12, 0), /* MMCIF0 */
fb66c523 595 [MSTP311] = MSTP(&div6_clks[DIV6_SDHI2], SMSTPCR3, 11, 0), /* SDHI2 */
b885966f 596 [MSTP304] = MSTP(&main_div2_clk, SMSTPCR3, 4, 0), /* TPU0 */
33661c9e
MD
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 */
f6d84f4a
MD
601 [MSTP411] = MSTP(&div4_clks[DIV4_HP], SMSTPCR4, 11, 0), /* IIC3 */
602 [MSTP410] = MSTP(&div4_clks[DIV4_HP], SMSTPCR4, 10, 0), /* IIC4 */
019c4ae3 603 [MSTP403] = MSTP(&r_clk, SMSTPCR4, 3, 0), /* KEYSC */
6d9598e2
MD
604};
605
48609533
SH
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.
612 */
6d9598e2 613static struct clk_lookup lookups[] = {
f6d84f4a
MD
614 /* main clocks */
615 CLKDEV_CON_ID("r_clk", &r_clk),
fe7aa82d 616 CLKDEV_DEV_ID("smp_twd", &twd_clk), /* smp_twd */
f6d84f4a 617
73107925 618 /* DIV4 clocks */
e4a6a29d 619 CLKDEV_DEV_ID("cpu0", &div4_clks[DIV4_Z]),
73107925 620
170c7ab5 621 /* DIV6 clocks */
ad054cbd
MD
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]),
fb66c523
MD
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]),
170c7ab5 628
6d9598e2 629 /* MSTP32 clocks */
696d6e17 630 CLKDEV_DEV_ID("i2c-sh_mobile.2", &mstp_clks[MSTP001]), /* I2C2 */
48609533 631 CLKDEV_DEV_ID("e6824000.i2c", &mstp_clks[MSTP001]), /* I2C2 */
ad054cbd
MD
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 */
170c7ab5 636 CLKDEV_DEV_ID("sh-mipi-dsi.0", &mstp_clks[MSTP118]), /* DSITX */
ad054cbd 637 CLKDEV_DEV_ID("i2c-sh_mobile.0", &mstp_clks[MSTP116]), /* I2C0 */
48609533 638 CLKDEV_DEV_ID("e6820000.i2c", &mstp_clks[MSTP116]), /* I2C0 */
ad054cbd 639 CLKDEV_DEV_ID("sh_mobile_lcdc_fb.0", &mstp_clks[MSTP100]), /* LCDC0 */
6d9598e2 640 CLKDEV_DEV_ID("sh-sci.7", &mstp_clks[MSTP219]), /* SCIFA7 */
ff4ce48e 641 CLKDEV_DEV_ID("e6cd0000.serial", &mstp_clks[MSTP219]), /* SCIFA7 */
32103c7b 642 CLKDEV_DEV_ID("sh-dma-engine.0", &mstp_clks[MSTP218]), /* SY-DMAC */
832290b2 643 CLKDEV_DEV_ID("sh-dma-engine.1", &mstp_clks[MSTP217]), /* MP-DMAC */
6d9598e2 644 CLKDEV_DEV_ID("sh-sci.5", &mstp_clks[MSTP207]), /* SCIFA5 */
ff4ce48e 645 CLKDEV_DEV_ID("e6cb0000.serial", &mstp_clks[MSTP207]), /* SCIFA5 */
6d9598e2 646 CLKDEV_DEV_ID("sh-sci.8", &mstp_clks[MSTP206]), /* SCIFB */
2c3758b0 647 CLKDEV_DEV_ID("e6c3000.serial", &mstp_clks[MSTP206]), /* SCIFB */
6d9598e2 648 CLKDEV_DEV_ID("sh-sci.0", &mstp_clks[MSTP204]), /* SCIFA0 */
ff4ce48e 649 CLKDEV_DEV_ID("e6c40000.serial", &mstp_clks[MSTP204]), /* SCIFA0 */
6d9598e2 650 CLKDEV_DEV_ID("sh-sci.1", &mstp_clks[MSTP203]), /* SCIFA1 */
ff4ce48e 651 CLKDEV_DEV_ID("e6c50000.serial", &mstp_clks[MSTP203]), /* SCIFA1 */
6d9598e2 652 CLKDEV_DEV_ID("sh-sci.2", &mstp_clks[MSTP202]), /* SCIFA2 */
ff4ce48e 653 CLKDEV_DEV_ID("e6c60000.serial", &mstp_clks[MSTP202]), /* SCIFA2 */
6d9598e2 654 CLKDEV_DEV_ID("sh-sci.3", &mstp_clks[MSTP201]), /* SCIFA3 */
ff4ce48e 655 CLKDEV_DEV_ID("e6c70000.serial", &mstp_clks[MSTP201]), /* SCIFA3 */
6d9598e2 656 CLKDEV_DEV_ID("sh-sci.4", &mstp_clks[MSTP200]), /* SCIFA4 */
ff4ce48e 657 CLKDEV_DEV_ID("e6c80000.serial", &mstp_clks[MSTP200]), /* SCIFA4 */
6d9598e2 658 CLKDEV_DEV_ID("sh-sci.6", &mstp_clks[MSTP331]), /* SCIFA6 */
ff4ce48e 659 CLKDEV_DEV_ID("e6cc0000.serial", &mstp_clks[MSTP331]), /* SCIFA6 */
ea7e1a5a 660 CLKDEV_DEV_ID("sh_fsi2", &mstp_clks[MSTP328]), /* FSI */
e1c98c5d 661 CLKDEV_DEV_ID("ec230000.sound", &mstp_clks[MSTP328]), /* FSI */
a33bb8a2 662 CLKDEV_DEV_ID("sh_irda.0", &mstp_clks[MSTP325]), /* IrDA */
b028f94b 663 CLKDEV_DEV_ID("i2c-sh_mobile.1", &mstp_clks[MSTP323]), /* I2C1 */
48609533 664 CLKDEV_DEV_ID("e6822000.i2c", &mstp_clks[MSTP323]), /* I2C1 */
12a7cfef 665 CLKDEV_DEV_ID("renesas_usbhs", &mstp_clks[MSTP322]), /* USB */
fb66c523 666 CLKDEV_DEV_ID("sh_mobile_sdhi.0", &mstp_clks[MSTP314]), /* SDHI0 */
33f6be3b 667 CLKDEV_DEV_ID("ee100000.sd", &mstp_clks[MSTP314]), /* SDHI0 */
fb66c523 668 CLKDEV_DEV_ID("sh_mobile_sdhi.1", &mstp_clks[MSTP313]), /* SDHI1 */
33f6be3b 669 CLKDEV_DEV_ID("ee120000.sd", &mstp_clks[MSTP313]), /* SDHI1 */
6bf45a10 670 CLKDEV_DEV_ID("sh_mmcif.0", &mstp_clks[MSTP312]), /* MMCIF0 */
33f6be3b 671 CLKDEV_DEV_ID("e6bd0000.mmc", &mstp_clks[MSTP312]), /* MMCIF0 */
fb66c523 672 CLKDEV_DEV_ID("sh_mobile_sdhi.2", &mstp_clks[MSTP311]), /* SDHI2 */
33f6be3b 673 CLKDEV_DEV_ID("ee140000.sd", &mstp_clks[MSTP311]), /* SDHI2 */
b885966f
LP
674 CLKDEV_DEV_ID("renesas-tpu-pwm.0", &mstp_clks[MSTP304]), /* TPU0 */
675 CLKDEV_DEV_ID("renesas-tpu-pwm.1", &mstp_clks[MSTP303]), /* TPU1 */
676 CLKDEV_DEV_ID("renesas-tpu-pwm.2", &mstp_clks[MSTP302]), /* TPU2 */
677 CLKDEV_DEV_ID("renesas-tpu-pwm.3", &mstp_clks[MSTP301]), /* TPU3 */
678 CLKDEV_DEV_ID("renesas-tpu-pwm.4", &mstp_clks[MSTP300]), /* TPU4 */
b028f94b 679 CLKDEV_DEV_ID("i2c-sh_mobile.3", &mstp_clks[MSTP411]), /* I2C3 */
48609533 680 CLKDEV_DEV_ID("e6826000.i2c", &mstp_clks[MSTP411]), /* I2C3 */
b028f94b 681 CLKDEV_DEV_ID("i2c-sh_mobile.4", &mstp_clks[MSTP410]), /* I2C4 */
48609533 682 CLKDEV_DEV_ID("e6828000.i2c", &mstp_clks[MSTP410]), /* I2C4 */
019c4ae3 683 CLKDEV_DEV_ID("sh_keysc.0", &mstp_clks[MSTP403]), /* KEYSC */
99b7835e
KM
684
685 /* ICK */
686 CLKDEV_ICK_ID("dsit_clk", "sh-mipi-dsi.0", &div6_clks[DIV6_DSIT]),
687 CLKDEV_ICK_ID("dsit_clk", "sh-mipi-dsi.1", &div6_clks[DIV6_DSIT]),
688 CLKDEV_ICK_ID("dsip_clk", "sh-mipi-dsi.0", &div6_clks[DIV6_DSI0P]),
689 CLKDEV_ICK_ID("dsip_clk", "sh-mipi-dsi.1", &div6_clks[DIV6_DSI1P]),
690 CLKDEV_ICK_ID("dsiphy_clk", "sh-mipi-dsi.0", &dsi0phy_clk),
691 CLKDEV_ICK_ID("dsiphy_clk", "sh-mipi-dsi.1", &dsi1phy_clk),
652256fd 692 CLKDEV_ICK_ID("fck", "sh-cmt-48.1", &mstp_clks[MSTP329]), /* CMT1 */
a0f7e749 693 CLKDEV_ICK_ID("fck", "e6138000.timer", &mstp_clks[MSTP329]), /* CMT1 */
3df592bc 694 CLKDEV_ICK_ID("fck", "sh-tmu.0", &mstp_clks[MSTP125]), /* TMU0 */
6d9598e2
MD
695};
696
697void __init sh73a0_clock_init(void)
698{
699 int k, ret = 0;
700
fb66c523
MD
701 /* Set SDHI clocks to a known state */
702 __raw_writel(0x108, SD0CKCR);
703 __raw_writel(0x108, SD1CKCR);
704 __raw_writel(0x108, SD2CKCR);
705
f6d84f4a 706 /* detect main clock parent */
86d84083 707 switch ((__raw_readl(CKSCR) >> 28) & 0x03) {
f6d84f4a
MD
708 case 0:
709 main_clk.parent = &sh73a0_extal1_clk;
710 break;
711 case 1:
712 main_clk.parent = &extal1_div2_clk;
713 break;
714 case 2:
715 main_clk.parent = &sh73a0_extal2_clk;
716 break;
717 case 3:
718 main_clk.parent = &extal2_div2_clk;
719 break;
720 }
721
6d9598e2
MD
722 for (k = 0; !ret && (k < ARRAY_SIZE(main_clks)); k++)
723 ret = clk_register(main_clks[k]);
724
73107925 725 if (!ret) {
f6d84f4a 726 ret = sh_clk_div4_register(div4_clks, DIV4_NR, &div4_table);
73107925 727 if (!ret)
413bfd0e 728 div4_clk_extend();
73107925 729 }
f6d84f4a
MD
730
731 if (!ret)
d4775356 732 ret = sh_clk_div6_reparent_register(div6_clks, DIV6_NR);
f6d84f4a 733
6d9598e2 734 if (!ret)
64e9de2f 735 ret = sh_clk_mstp_register(mstp_clks, MSTP_NR);
6d9598e2 736
f5948bac
KM
737 for (k = 0; !ret && (k < ARRAY_SIZE(late_main_clks)); k++)
738 ret = clk_register(late_main_clks[k]);
739
6d9598e2
MD
740 clkdev_add_table(lookups, ARRAY_SIZE(lookups));
741
742 if (!ret)
6b6a4c06 743 shmobile_clk_init();
6d9598e2
MD
744 else
745 panic("failed to setup sh73a0 clocks\n");
746}