blob: 3855fb024fdbb1ca7aecd9780ed9e42533927879 [file] [log] [blame]
Magnus Damm6d9598e2010-11-17 10:59:31 +00001/*
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.
Magnus Damm6d9598e2010-11-17 10:59:31 +000014 */
15#include <linux/init.h>
16#include <linux/kernel.h>
17#include <linux/io.h>
18#include <linux/sh_clk.h>
Paul Mundt6ef9f6f2011-01-07 11:49:49 +090019#include <linux/clkdev.h>
Guennadi Liakhovetski7653c312013-02-28 13:21:58 +010020#include <asm/processor.h>
Magnus Dammad6ffa02014-06-17 16:47:21 +090021#include "clock.h"
Magnus Dammfd44aa52014-06-17 16:47:37 +090022#include "common.h"
Magnus Damm6d9598e2010-11-17 10:59:31 +000023
Arnd Bergmann0a4b04d2012-09-14 20:08:08 +000024#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)
Magnus Dammf6d84f42010-12-03 07:22:31 +000047#define DSI0PHYCR 0xe615006C
48#define DSI1PHYCR 0xe6150070
Arnd Bergmann0a4b04d2012-09-14 20:08:08 +000049#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)
Magnus Damm6d9598e2010-11-17 10:59:31 +000061
62/* Fixed 32 KHz root clock from EXTALR pin */
63static struct clk r_clk = {
64 .rate = 32768,
65};
66
Magnus Dammf6d84f42010-12-03 07:22:31 +000067/*
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,
Magnus Damm6d9598e2010-11-17 10:59:31 +000073};
74
Magnus Dammf6d84f42010-12-03 07:22:31 +000075/*
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
Magnus Damm7bcda502012-02-29 22:16:52 +090083static struct sh_clk_ops main_clk_ops = {
Magnus Dammf6d84f42010-12-03 07:22:31 +000084 .recalc = followparent_recalc,
85};
86
87/* Main clock */
88static struct clk main_clk = {
Kuninori Morimoto891cab32013-03-27 00:56:14 -070089 /* .parent wll be set on sh73a0_clock_init() */
Magnus Dammf6d84f42010-12-03 07:22:31 +000090 .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
Magnus Damm71fc5092011-01-20 08:11:11 +000098 if (__raw_readl(PLLECR) & (1 << clk->enable_bit)) {
Magnus Dammf6d84f42010-12-03 07:22:31 +000099 mult = (((__raw_readl(clk->enable_reg) >> 24) & 0x3f) + 1);
Magnus Damm71fc5092011-01-20 08:11:11 +0000100 /* 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 }
Magnus Dammf6d84f42010-12-03 07:22:31 +0000108
109 return clk->parent->rate * mult;
110}
111
Magnus Damm7bcda502012-02-29 22:16:52 +0900112static struct sh_clk_ops pll_clk_ops = {
Magnus Dammf6d84f42010-12-03 07:22:31 +0000113 .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,
122};
123
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
Kuninori Morimoto891cab32013-03-27 00:56:14 -0700148/* A fixed divide block */
149SH_CLK_RATIO(div2, 1, 2);
150SH_CLK_RATIO(div7, 1, 7);
151SH_CLK_RATIO(div13, 1, 13);
Yoshii Takashib028f942010-11-19 13:20:45 +0000152
Kuninori Morimoto891cab32013-03-27 00:56:14 -0700153SH_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);
Kuninori Morimotod4775352011-12-05 22:29:15 -0800159
160/* External input clock */
161struct clk sh73a0_extcki_clk = {
162};
163
164struct clk sh73a0_extalr_clk = {
165};
166
Magnus Damm6d9598e2010-11-17 10:59:31 +0000167static struct clk *main_clks[] = {
168 &r_clk,
Magnus Dammf6d84f42010-12-03 07:22:31 +0000169 &sh73a0_extal1_clk,
170 &sh73a0_extal2_clk,
171 &extal1_div2_clk,
172 &extal2_div2_clk,
173 &main_clk,
Kuninori Morimotod4775352011-12-05 22:29:15 -0800174 &main_div2_clk,
Magnus Dammf6d84f42010-12-03 07:22:31 +0000175 &pll0_clk,
176 &pll1_clk,
177 &pll2_clk,
178 &pll3_clk,
179 &pll1_div2_clk,
Kuninori Morimotod4775352011-12-05 22:29:15 -0800180 &pll1_div7_clk,
181 &pll1_div13_clk,
182 &sh73a0_extcki_clk,
183 &sh73a0_extalr_clk,
Magnus Damm6d9598e2010-11-17 10:59:31 +0000184};
185
Guennadi Liakhovetski7653c312013-02-28 13:21:58 +0100186static int frqcr_kick(void)
187{
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}
200
Magnus Dammf6d84f42010-12-03 07:22:31 +0000201static void div4_kick(struct clk *clk)
202{
Guennadi Liakhovetski7653c312013-02-28 13:21:58 +0100203 frqcr_kick();
Magnus Dammf6d84f42010-12-03 07:22:31 +0000204}
205
206static int divisors[] = { 2, 3, 4, 6, 8, 12, 16, 18,
Takashi YOSHIIc070c202010-12-22 14:15:08 +0000207 24, 0, 36, 48, 7 };
Magnus Dammf6d84f42010-12-03 07:22:31 +0000208
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,
Kuninori Morimoto1f7ccd82013-03-27 00:55:07 -0700220 DIV4_Z, DIV4_ZX, DIV4_HP, DIV4_NR };
Magnus Dammf6d84f42010-12-03 07:22:31 +0000221
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] = {
Kuninori Morimotobf519bfb2012-12-04 17:43:29 -0800226 [DIV4_I] = DIV4(FRQCRA, 20, 0xdff, CLK_ENABLE_ON_INIT),
Guennadi Liakhovetski73107922013-04-05 12:00:36 +0200227 /*
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 */
Guennadi Liakhovetski8a444472013-02-22 18:17:51 +0100232 [DIV4_ZG] = SH_CLK_DIV4(&pll0_clk, FRQCRA, 16, 0xd7f, CLK_ENABLE_ON_INIT),
Kuninori Morimotobf519bfb2012-12-04 17:43:29 -0800233 [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),
Guennadi Liakhovetski8a444472013-02-22 18:17:51 +0100237 [DIV4_Z] = SH_CLK_DIV4(&pll0_clk, FRQCRB, 24, 0x97f, 0),
Kuninori Morimotobf519bfb2012-12-04 17:43:29 -0800238 [DIV4_ZX] = DIV4(FRQCRB, 12, 0xdff, 0),
239 [DIV4_HP] = DIV4(FRQCRB, 4, 0xdff, 0),
Magnus Dammf6d84f42010-12-03 07:22:31 +0000240};
241
Guennadi Liakhovetskife7aa822013-03-07 20:00:48 +0100242static 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
Guennadi Liakhovetski413bfd02013-05-23 00:10:00 +0200256static struct sh_clk_ops zclk_ops, kicker_ops;
Guennadi Liakhovetski3b207a42013-05-23 00:09:36 +0200257static const struct sh_clk_ops *div4_clk_ops;
Guennadi Liakhovetski73107922013-04-05 12:00:36 +0200258
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 */
Guennadi Liakhovetski3b207a42013-05-23 00:09:36 +0200273 ret = div4_clk_ops->set_rate(clk, rate / 2);
Guennadi Liakhovetski73107922013-04-05 12:00:36 +0200274 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 */
Guennadi Liakhovetski3b207a42013-05-23 00:09:36 +0200288 ret = div4_clk_ops->set_rate(clk, rate);
Guennadi Liakhovetski73107922013-04-05 12:00:36 +0200289 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{
Guennadi Liakhovetski3b207a42013-05-23 00:09:36 +0200300 unsigned long div_freq = div4_clk_ops->round_rate(clk, rate),
Guennadi Liakhovetski73107922013-04-05 12:00:36 +0200301 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 */
Guennadi Liakhovetski3b207a42013-05-23 00:09:36 +0200315 unsigned long div_freq = div4_clk_ops->recalc(clk);
Guennadi Liakhovetski73107922013-04-05 12:00:36 +0200316
317 if (__raw_readl(FRQCRB) & (1 << 28))
318 return div_freq;
319
320 return clk_get_rate(clk->parent);
321}
322
Guennadi Liakhovetski413bfd02013-05-23 00:10:00 +0200323static int kicker_set_rate(struct clk *clk, unsigned long rate)
Guennadi Liakhovetski73107922013-04-05 12:00:36 +0200324{
Guennadi Liakhovetski413bfd02013-05-23 00:10:00 +0200325 if (__raw_readl(FRQCRB) & (1 << 31))
326 return -EBUSY;
Guennadi Liakhovetski3b207a42013-05-23 00:09:36 +0200327
Guennadi Liakhovetski413bfd02013-05-23 00:10:00 +0200328 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;
336
337 /* Add a kicker-busy check before changing the rate */
338 kicker_ops = *div4_clk_ops;
Guennadi Liakhovetski73107922013-04-05 12:00:36 +0200339 /* We extend the DIV4 clock with a 1:1 pass-through case */
Guennadi Liakhovetski3b207a42013-05-23 00:09:36 +0200340 zclk_ops = *div4_clk_ops;
341
Guennadi Liakhovetski413bfd02013-05-23 00:10:00 +0200342 kicker_ops.set_rate = kicker_set_rate;
Guennadi Liakhovetski3b207a42013-05-23 00:09:36 +0200343 zclk_ops.set_rate = zclk_set_rate;
344 zclk_ops.round_rate = zclk_round_rate;
345 zclk_ops.recalc = zclk_recalc;
346
Guennadi Liakhovetski413bfd02013-05-23 00:10:00 +0200347 for (i = 0; i < DIV4_NR; i++)
348 div4_clks[i].ops = i == DIV4_Z ? &zclk_ops : &kicker_ops;
Guennadi Liakhovetski73107922013-04-05 12:00:36 +0200349}
350
Magnus Dammf6d84f42010-12-03 07:22:31 +0000351enum { 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
Kuninori Morimotod4775352011-12-05 22:29:15 -0800359static 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
Magnus Dammf6d84f42010-12-03 07:22:31 +0000396static struct clk div6_clks[DIV6_NR] = {
Kuninori Morimotod4775352011-12-05 22:29:15 -0800397 [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),
Paul Mundtca371d22012-01-09 11:12:55 +0900403 [DIV6_ZB1] = SH_CLK_DIV6_EXT(ZBCKCR, CLK_ENABLE_ON_INIT,
Kuninori Morimotod4775352011-12-05 22:29:15 -0800404 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),
Magnus Dammf6d84f42010-12-03 07:22:31 +0000437};
438
Kuninori Morimotof5948ba2012-01-22 21:10:02 -0800439/* 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
Magnus Damm7bcda502012-02-29 22:16:52 +0900512static struct sh_clk_ops dsiphy_clk_ops = {
Kuninori Morimotof5948ba2012-01-22 21:10:02 -0800513 .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,
Guennadi Liakhovetskife7aa822013-03-07 20:00:48 +0100545 &twd_clk,
Kuninori Morimotof5948ba2012-01-22 21:10:02 -0800546};
547
Magnus Dammf6d84f42010-12-03 07:22:31 +0000548enum { MSTP001,
Guennadi Liakhovetski73107922013-04-05 12:00:36 +0200549 MSTP129, MSTP128, MSTP127, MSTP126, MSTP125, MSTP118, MSTP116, MSTP112, MSTP100,
Kuninori Morimoto832290b2012-06-25 03:39:20 -0700550 MSTP219, MSTP218, MSTP217,
Magnus Dammf6d84f42010-12-03 07:22:31 +0000551 MSTP207, MSTP206, MSTP204, MSTP203, MSTP202, MSTP201, MSTP200,
Kuninori Morimoto12a7cfe2012-06-25 03:34:49 -0700552 MSTP331, MSTP329, MSTP328, MSTP325, MSTP323, MSTP322,
Magnus Damm681e1b32011-05-24 10:37:16 +0000553 MSTP314, MSTP313, MSTP312, MSTP311,
Laurent Pinchartb8859662013-07-16 12:32:06 +0200554 MSTP304, MSTP303, MSTP302, MSTP301, MSTP300,
Kuninori Morimoto696d6e12010-11-24 07:41:14 +0000555 MSTP411, MSTP410, MSTP403,
Geert Uytterhoeven2f472ae2014-11-19 16:26:59 +0100556 MSTP508,
Magnus Damm6d9598e2010-11-17 10:59:31 +0000557 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] = {
Magnus Dammf6d84f42010-12-03 07:22:31 +0000563 [MSTP001] = MSTP(&div4_clks[DIV4_HP], SMSTPCR0, 1, 0), /* IIC2 */
Magnus Dammad054cb2011-01-28 10:04:25 +0000564 [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 */
Magnus Damm5010f3d2010-12-21 08:40:59 +0000568 [MSTP125] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR1, 25, 0), /* TMU0 */
Magnus Damm170c7ab2011-01-20 08:41:03 +0000569 [MSTP118] = MSTP(&div4_clks[DIV4_B], SMSTPCR1, 18, 0), /* DSITX0 */
Magnus Dammf6d84f42010-12-03 07:22:31 +0000570 [MSTP116] = MSTP(&div4_clks[DIV4_HP], SMSTPCR1, 16, 0), /* IIC0 */
Guennadi Liakhovetski73107922013-04-05 12:00:36 +0200571 [MSTP112] = MSTP(&div4_clks[DIV4_ZG], SMSTPCR1, 12, 0), /* SGX */
Magnus Damm170c7ab2011-01-20 08:41:03 +0000572 [MSTP100] = MSTP(&div4_clks[DIV4_B], SMSTPCR1, 0, 0), /* LCDC0 */
Magnus Dammf6d84f42010-12-03 07:22:31 +0000573 [MSTP219] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR2, 19, 0), /* SCIFA7 */
Kuninori Morimoto32103c72012-06-20 11:30:25 +0200574 [MSTP218] = MSTP(&div4_clks[DIV4_HP], SMSTPCR2, 18, 0), /* SY-DMAC */
Kuninori Morimoto832290b2012-06-25 03:39:20 -0700575 [MSTP217] = MSTP(&div4_clks[DIV4_HP], SMSTPCR2, 17, 0), /* MP-DMAC */
Magnus Dammf6d84f42010-12-03 07:22:31 +0000576 [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 */
Magnus Damm6d9598e2010-11-17 10:59:31 +0000584 [MSTP329] = MSTP(&r_clk, SMSTPCR3, 29, 0), /* CMT10 */
Kuninori Morimotoea7e1a52012-06-12 02:43:40 -0700585 [MSTP328] = MSTP(&div4_clks[DIV4_HP], SMSTPCR3, 28, 0), /*FSI*/
Magnus Damm5a1b70a2011-01-18 08:48:17 +0000586 [MSTP325] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR3, 25, 0), /* IrDA */
Magnus Dammf6d84f42010-12-03 07:22:31 +0000587 [MSTP323] = MSTP(&div4_clks[DIV4_HP], SMSTPCR3, 23, 0), /* IIC1 */
Kuninori Morimoto12a7cfe2012-06-25 03:34:49 -0700588 [MSTP322] = MSTP(&div4_clks[DIV4_HP], SMSTPCR3, 22, 0), /* USB */
Magnus Dammfb66c522011-05-23 05:10:36 +0000589 [MSTP314] = MSTP(&div6_clks[DIV6_SDHI0], SMSTPCR3, 14, 0), /* SDHI0 */
590 [MSTP313] = MSTP(&div6_clks[DIV6_SDHI1], SMSTPCR3, 13, 0), /* SDHI1 */
Takashi YOSHII6bf45a102010-12-22 06:35:30 +0000591 [MSTP312] = MSTP(&div4_clks[DIV4_HP], SMSTPCR3, 12, 0), /* MMCIF0 */
Magnus Dammfb66c522011-05-23 05:10:36 +0000592 [MSTP311] = MSTP(&div6_clks[DIV6_SDHI2], SMSTPCR3, 11, 0), /* SDHI2 */
Laurent Pinchartb8859662013-07-16 12:32:06 +0200593 [MSTP304] = MSTP(&main_div2_clk, SMSTPCR3, 4, 0), /* TPU0 */
Magnus Damm33661c92011-11-22 15:44:58 +0900594 [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 */
Magnus Dammf6d84f42010-12-03 07:22:31 +0000598 [MSTP411] = MSTP(&div4_clks[DIV4_HP], SMSTPCR4, 11, 0), /* IIC3 */
599 [MSTP410] = MSTP(&div4_clks[DIV4_HP], SMSTPCR4, 10, 0), /* IIC4 */
Magnus Damm019c4ae2010-12-22 06:14:05 +0000600 [MSTP403] = MSTP(&r_clk, SMSTPCR4, 3, 0), /* KEYSC */
Geert Uytterhoeven2f472ae2014-11-19 16:26:59 +0100601 [MSTP508] = MSTP(&div4_clks[DIV4_HP], SMSTPCR5, 8, 0), /* INTCA0 */
Magnus Damm6d9598e2010-11-17 10:59:31 +0000602};
603
Simon Horman48609532012-11-21 22:00:15 +0900604/* 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 */
Magnus Damm6d9598e2010-11-17 10:59:31 +0000611static struct clk_lookup lookups[] = {
Magnus Dammf6d84f42010-12-03 07:22:31 +0000612 /* main clocks */
613 CLKDEV_CON_ID("r_clk", &r_clk),
Guennadi Liakhovetskife7aa822013-03-07 20:00:48 +0100614 CLKDEV_DEV_ID("smp_twd", &twd_clk), /* smp_twd */
Magnus Dammf6d84f42010-12-03 07:22:31 +0000615
Guennadi Liakhovetski73107922013-04-05 12:00:36 +0200616 /* DIV4 clocks */
Sudeep KarkadaNageshae4a6a292013-09-10 18:59:49 +0100617 CLKDEV_DEV_ID("cpu0", &div4_clks[DIV4_Z]),
Guennadi Liakhovetski73107922013-04-05 12:00:36 +0200618
Magnus Damm170c7ab2011-01-20 08:41:03 +0000619 /* DIV6 clocks */
Magnus Dammad054cb2011-01-28 10:04:25 +0000620 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]),
Magnus Dammfb66c522011-05-23 05:10:36 +0000623 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]),
Magnus Damm170c7ab2011-01-20 08:41:03 +0000626
Magnus Damm6d9598e2010-11-17 10:59:31 +0000627 /* MSTP32 clocks */
Kuninori Morimoto696d6e12010-11-24 07:41:14 +0000628 CLKDEV_DEV_ID("i2c-sh_mobile.2", &mstp_clks[MSTP001]), /* I2C2 */
Simon Horman48609532012-11-21 22:00:15 +0900629 CLKDEV_DEV_ID("e6824000.i2c", &mstp_clks[MSTP001]), /* I2C2 */
Magnus Dammad054cb2011-01-28 10:04:25 +0000630 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 */
Magnus Damm170c7ab2011-01-20 08:41:03 +0000634 CLKDEV_DEV_ID("sh-mipi-dsi.0", &mstp_clks[MSTP118]), /* DSITX */
Magnus Dammad054cb2011-01-28 10:04:25 +0000635 CLKDEV_DEV_ID("i2c-sh_mobile.0", &mstp_clks[MSTP116]), /* I2C0 */
Simon Horman48609532012-11-21 22:00:15 +0900636 CLKDEV_DEV_ID("e6820000.i2c", &mstp_clks[MSTP116]), /* I2C0 */
Magnus Dammad054cb2011-01-28 10:04:25 +0000637 CLKDEV_DEV_ID("sh_mobile_lcdc_fb.0", &mstp_clks[MSTP100]), /* LCDC0 */
Magnus Damm6d9598e2010-11-17 10:59:31 +0000638 CLKDEV_DEV_ID("sh-sci.7", &mstp_clks[MSTP219]), /* SCIFA7 */
Simon Hormanff4ce482014-07-07 09:54:50 +0200639 CLKDEV_DEV_ID("e6cd0000.serial", &mstp_clks[MSTP219]), /* SCIFA7 */
Kuninori Morimoto32103c72012-06-20 11:30:25 +0200640 CLKDEV_DEV_ID("sh-dma-engine.0", &mstp_clks[MSTP218]), /* SY-DMAC */
Kuninori Morimoto832290b2012-06-25 03:39:20 -0700641 CLKDEV_DEV_ID("sh-dma-engine.1", &mstp_clks[MSTP217]), /* MP-DMAC */
Magnus Damm6d9598e2010-11-17 10:59:31 +0000642 CLKDEV_DEV_ID("sh-sci.5", &mstp_clks[MSTP207]), /* SCIFA5 */
Simon Hormanff4ce482014-07-07 09:54:50 +0200643 CLKDEV_DEV_ID("e6cb0000.serial", &mstp_clks[MSTP207]), /* SCIFA5 */
Magnus Damm6d9598e2010-11-17 10:59:31 +0000644 CLKDEV_DEV_ID("sh-sci.8", &mstp_clks[MSTP206]), /* SCIFB */
Simon Horman2c3758b2014-07-16 09:11:21 +0900645 CLKDEV_DEV_ID("e6c3000.serial", &mstp_clks[MSTP206]), /* SCIFB */
Magnus Damm6d9598e2010-11-17 10:59:31 +0000646 CLKDEV_DEV_ID("sh-sci.0", &mstp_clks[MSTP204]), /* SCIFA0 */
Simon Hormanff4ce482014-07-07 09:54:50 +0200647 CLKDEV_DEV_ID("e6c40000.serial", &mstp_clks[MSTP204]), /* SCIFA0 */
Magnus Damm6d9598e2010-11-17 10:59:31 +0000648 CLKDEV_DEV_ID("sh-sci.1", &mstp_clks[MSTP203]), /* SCIFA1 */
Simon Hormanff4ce482014-07-07 09:54:50 +0200649 CLKDEV_DEV_ID("e6c50000.serial", &mstp_clks[MSTP203]), /* SCIFA1 */
Magnus Damm6d9598e2010-11-17 10:59:31 +0000650 CLKDEV_DEV_ID("sh-sci.2", &mstp_clks[MSTP202]), /* SCIFA2 */
Simon Hormanff4ce482014-07-07 09:54:50 +0200651 CLKDEV_DEV_ID("e6c60000.serial", &mstp_clks[MSTP202]), /* SCIFA2 */
Magnus Damm6d9598e2010-11-17 10:59:31 +0000652 CLKDEV_DEV_ID("sh-sci.3", &mstp_clks[MSTP201]), /* SCIFA3 */
Simon Hormanff4ce482014-07-07 09:54:50 +0200653 CLKDEV_DEV_ID("e6c70000.serial", &mstp_clks[MSTP201]), /* SCIFA3 */
Magnus Damm6d9598e2010-11-17 10:59:31 +0000654 CLKDEV_DEV_ID("sh-sci.4", &mstp_clks[MSTP200]), /* SCIFA4 */
Simon Hormanff4ce482014-07-07 09:54:50 +0200655 CLKDEV_DEV_ID("e6c80000.serial", &mstp_clks[MSTP200]), /* SCIFA4 */
Magnus Damm6d9598e2010-11-17 10:59:31 +0000656 CLKDEV_DEV_ID("sh-sci.6", &mstp_clks[MSTP331]), /* SCIFA6 */
Simon Hormanff4ce482014-07-07 09:54:50 +0200657 CLKDEV_DEV_ID("e6cc0000.serial", &mstp_clks[MSTP331]), /* SCIFA6 */
Kuninori Morimotoea7e1a52012-06-12 02:43:40 -0700658 CLKDEV_DEV_ID("sh_fsi2", &mstp_clks[MSTP328]), /* FSI */
Kuninori Morimotoe1c98c52013-12-04 17:32:42 -0800659 CLKDEV_DEV_ID("ec230000.sound", &mstp_clks[MSTP328]), /* FSI */
Kuninori Morimotoa33bb8a2011-01-14 11:00:41 +0000660 CLKDEV_DEV_ID("sh_irda.0", &mstp_clks[MSTP325]), /* IrDA */
Yoshii Takashib028f942010-11-19 13:20:45 +0000661 CLKDEV_DEV_ID("i2c-sh_mobile.1", &mstp_clks[MSTP323]), /* I2C1 */
Simon Horman48609532012-11-21 22:00:15 +0900662 CLKDEV_DEV_ID("e6822000.i2c", &mstp_clks[MSTP323]), /* I2C1 */
Kuninori Morimoto12a7cfe2012-06-25 03:34:49 -0700663 CLKDEV_DEV_ID("renesas_usbhs", &mstp_clks[MSTP322]), /* USB */
Magnus Dammfb66c522011-05-23 05:10:36 +0000664 CLKDEV_DEV_ID("sh_mobile_sdhi.0", &mstp_clks[MSTP314]), /* SDHI0 */
Kuninori Morimoto33f6be32013-10-21 19:36:22 -0700665 CLKDEV_DEV_ID("ee100000.sd", &mstp_clks[MSTP314]), /* SDHI0 */
Magnus Dammfb66c522011-05-23 05:10:36 +0000666 CLKDEV_DEV_ID("sh_mobile_sdhi.1", &mstp_clks[MSTP313]), /* SDHI1 */
Kuninori Morimoto33f6be32013-10-21 19:36:22 -0700667 CLKDEV_DEV_ID("ee120000.sd", &mstp_clks[MSTP313]), /* SDHI1 */
Takashi YOSHII6bf45a102010-12-22 06:35:30 +0000668 CLKDEV_DEV_ID("sh_mmcif.0", &mstp_clks[MSTP312]), /* MMCIF0 */
Kuninori Morimoto33f6be32013-10-21 19:36:22 -0700669 CLKDEV_DEV_ID("e6bd0000.mmc", &mstp_clks[MSTP312]), /* MMCIF0 */
Magnus Dammfb66c522011-05-23 05:10:36 +0000670 CLKDEV_DEV_ID("sh_mobile_sdhi.2", &mstp_clks[MSTP311]), /* SDHI2 */
Kuninori Morimoto33f6be32013-10-21 19:36:22 -0700671 CLKDEV_DEV_ID("ee140000.sd", &mstp_clks[MSTP311]), /* SDHI2 */
Laurent Pinchartb8859662013-07-16 12:32:06 +0200672 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 */
Yoshii Takashib028f942010-11-19 13:20:45 +0000677 CLKDEV_DEV_ID("i2c-sh_mobile.3", &mstp_clks[MSTP411]), /* I2C3 */
Simon Horman48609532012-11-21 22:00:15 +0900678 CLKDEV_DEV_ID("e6826000.i2c", &mstp_clks[MSTP411]), /* I2C3 */
Yoshii Takashib028f942010-11-19 13:20:45 +0000679 CLKDEV_DEV_ID("i2c-sh_mobile.4", &mstp_clks[MSTP410]), /* I2C4 */
Simon Horman48609532012-11-21 22:00:15 +0900680 CLKDEV_DEV_ID("e6828000.i2c", &mstp_clks[MSTP410]), /* I2C4 */
Magnus Damm019c4ae2010-12-22 06:14:05 +0000681 CLKDEV_DEV_ID("sh_keysc.0", &mstp_clks[MSTP403]), /* KEYSC */
Geert Uytterhoeven2f472ae2014-11-19 16:26:59 +0100682 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 */
Kuninori Morimoto99b78352013-11-19 01:04:57 -0800690
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),
Laurent Pinchart652256f2014-04-23 13:15:10 +0200698 CLKDEV_ICK_ID("fck", "sh-cmt-48.1", &mstp_clks[MSTP329]), /* CMT1 */
Simon Hormana0f7e742014-07-07 09:54:53 +0200699 CLKDEV_ICK_ID("fck", "e6138000.timer", &mstp_clks[MSTP329]), /* CMT1 */
Laurent Pinchart3df592b2014-04-23 13:15:17 +0200700 CLKDEV_ICK_ID("fck", "sh-tmu.0", &mstp_clks[MSTP125]), /* TMU0 */
Magnus Damm6d9598e2010-11-17 10:59:31 +0000701};
702
703void __init sh73a0_clock_init(void)
704{
705 int k, ret = 0;
706
Magnus Dammfb66c522011-05-23 05:10:36 +0000707 /* Set SDHI clocks to a known state */
708 __raw_writel(0x108, SD0CKCR);
709 __raw_writel(0x108, SD1CKCR);
710 __raw_writel(0x108, SD2CKCR);
711
Magnus Dammf6d84f42010-12-03 07:22:31 +0000712 /* detect main clock parent */
Kuninori Morimoto86d84082011-08-26 07:27:45 +0000713 switch ((__raw_readl(CKSCR) >> 28) & 0x03) {
Magnus Dammf6d84f42010-12-03 07:22:31 +0000714 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
Magnus Damm6d9598e2010-11-17 10:59:31 +0000728 for (k = 0; !ret && (k < ARRAY_SIZE(main_clks)); k++)
729 ret = clk_register(main_clks[k]);
730
Guennadi Liakhovetski73107922013-04-05 12:00:36 +0200731 if (!ret) {
Magnus Dammf6d84f42010-12-03 07:22:31 +0000732 ret = sh_clk_div4_register(div4_clks, DIV4_NR, &div4_table);
Guennadi Liakhovetski73107922013-04-05 12:00:36 +0200733 if (!ret)
Guennadi Liakhovetski413bfd02013-05-23 00:10:00 +0200734 div4_clk_extend();
Guennadi Liakhovetski73107922013-04-05 12:00:36 +0200735 }
Magnus Dammf6d84f42010-12-03 07:22:31 +0000736
737 if (!ret)
Kuninori Morimotod4775352011-12-05 22:29:15 -0800738 ret = sh_clk_div6_reparent_register(div6_clks, DIV6_NR);
Magnus Dammf6d84f42010-12-03 07:22:31 +0000739
740 if (!ret)
Nobuhiro Iwamatsu64e9de22012-06-27 09:59:00 +0900741 ret = sh_clk_mstp_register(mstp_clks, MSTP_NR);
Magnus Damm6d9598e2010-11-17 10:59:31 +0000742
Kuninori Morimotof5948ba2012-01-22 21:10:02 -0800743 for (k = 0; !ret && (k < ARRAY_SIZE(late_main_clks)); k++)
744 ret = clk_register(late_main_clks[k]);
745
Magnus Damm6d9598e2010-11-17 10:59:31 +0000746 clkdev_add_table(lookups, ARRAY_SIZE(lookups));
747
748 if (!ret)
Magnus Damm6b6a4c02012-02-29 21:41:30 +0900749 shmobile_clk_init();
Magnus Damm6d9598e2010-11-17 10:59:31 +0000750 else
751 panic("failed to setup sh73a0 clocks\n");
752}