• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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>
23 #include <linux/clkdev.h>
24 #include <asm/processor.h>
25 #include "clock.h"
26 #include "common.h"
27 
28 #define FRQCRA		IOMEM(0xe6150000)
29 #define FRQCRB		IOMEM(0xe6150004)
30 #define FRQCRD		IOMEM(0xe61500e4)
31 #define VCLKCR1		IOMEM(0xe6150008)
32 #define VCLKCR2		IOMEM(0xe615000C)
33 #define VCLKCR3		IOMEM(0xe615001C)
34 #define ZBCKCR		IOMEM(0xe6150010)
35 #define FLCKCR		IOMEM(0xe6150014)
36 #define SD0CKCR		IOMEM(0xe6150074)
37 #define SD1CKCR		IOMEM(0xe6150078)
38 #define SD2CKCR		IOMEM(0xe615007C)
39 #define FSIACKCR	IOMEM(0xe6150018)
40 #define FSIBCKCR	IOMEM(0xe6150090)
41 #define SUBCKCR		IOMEM(0xe6150080)
42 #define SPUACKCR	IOMEM(0xe6150084)
43 #define SPUVCKCR	IOMEM(0xe6150094)
44 #define MSUCKCR		IOMEM(0xe6150088)
45 #define HSICKCR		IOMEM(0xe615008C)
46 #define MFCK1CR		IOMEM(0xe6150098)
47 #define MFCK2CR		IOMEM(0xe615009C)
48 #define DSITCKCR	IOMEM(0xe6150060)
49 #define DSI0PCKCR	IOMEM(0xe6150064)
50 #define DSI1PCKCR	IOMEM(0xe6150068)
51 #define DSI0PHYCR	0xe615006C
52 #define DSI1PHYCR	0xe6150070
53 #define PLLECR		IOMEM(0xe61500d0)
54 #define PLL0CR		IOMEM(0xe61500d8)
55 #define PLL1CR		IOMEM(0xe6150028)
56 #define PLL2CR		IOMEM(0xe615002c)
57 #define PLL3CR		IOMEM(0xe61500dc)
58 #define SMSTPCR0	IOMEM(0xe6150130)
59 #define SMSTPCR1	IOMEM(0xe6150134)
60 #define SMSTPCR2	IOMEM(0xe6150138)
61 #define SMSTPCR3	IOMEM(0xe615013c)
62 #define SMSTPCR4	IOMEM(0xe6150140)
63 #define SMSTPCR5	IOMEM(0xe6150144)
64 #define CKSCR		IOMEM(0xe61500c0)
65 
66 /* Fixed 32 KHz root clock from EXTALR pin */
67 static struct clk r_clk = {
68 	.rate           = 32768,
69 };
70 
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  */
75 struct 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  */
83 struct clk sh73a0_extal2_clk = {
84 	.rate		= 48000000,
85 };
86 
87 static struct sh_clk_ops main_clk_ops = {
88 	.recalc		= followparent_recalc,
89 };
90 
91 /* Main clock */
92 static struct clk main_clk = {
93 	/* .parent wll be set on sh73a0_clock_init() */
94 	.ops		= &main_clk_ops,
95 };
96 
97 /* PLL0, PLL1, PLL2, PLL3 */
pll_recalc(struct clk * clk)98 static unsigned long pll_recalc(struct clk *clk)
99 {
100 	unsigned long mult = 1;
101 
102 	if (__raw_readl(PLLECR) & (1 << clk->enable_bit)) {
103 		mult = (((__raw_readl(clk->enable_reg) >> 24) & 0x3f) + 1);
104 		/* handle CFG bit for PLL1 and PLL2 */
105 		switch (clk->enable_bit) {
106 		case 1:
107 		case 2:
108 			if (__raw_readl(clk->enable_reg) & (1 << 20))
109 				mult *= 2;
110 		}
111 	}
112 
113 	return clk->parent->rate * mult;
114 }
115 
116 static struct sh_clk_ops pll_clk_ops = {
117 	.recalc		= pll_recalc,
118 };
119 
120 static struct clk pll0_clk = {
121 	.ops		= &pll_clk_ops,
122 	.flags		= CLK_ENABLE_ON_INIT,
123 	.parent		= &main_clk,
124 	.enable_reg	= (void __iomem *)PLL0CR,
125 	.enable_bit	= 0,
126 };
127 
128 static struct clk pll1_clk = {
129 	.ops		= &pll_clk_ops,
130 	.flags		= CLK_ENABLE_ON_INIT,
131 	.parent		= &main_clk,
132 	.enable_reg	= (void __iomem *)PLL1CR,
133 	.enable_bit	= 1,
134 };
135 
136 static struct clk pll2_clk = {
137 	.ops		= &pll_clk_ops,
138 	.flags		= CLK_ENABLE_ON_INIT,
139 	.parent		= &main_clk,
140 	.enable_reg	= (void __iomem *)PLL2CR,
141 	.enable_bit	= 2,
142 };
143 
144 static struct clk pll3_clk = {
145 	.ops		= &pll_clk_ops,
146 	.flags		= CLK_ENABLE_ON_INIT,
147 	.parent		= &main_clk,
148 	.enable_reg	= (void __iomem *)PLL3CR,
149 	.enable_bit	= 3,
150 };
151 
152 /* A fixed divide block */
153 SH_CLK_RATIO(div2,  1, 2);
154 SH_CLK_RATIO(div7,  1, 7);
155 SH_CLK_RATIO(div13, 1, 13);
156 
157 SH_FIXED_RATIO_CLK(extal1_div2_clk,	sh73a0_extal1_clk,	div2);
158 SH_FIXED_RATIO_CLK(extal2_div2_clk,	sh73a0_extal2_clk,	div2);
159 SH_FIXED_RATIO_CLK(main_div2_clk,	main_clk,		div2);
160 SH_FIXED_RATIO_CLK(pll1_div2_clk,	pll1_clk,		div2);
161 SH_FIXED_RATIO_CLK(pll1_div7_clk,	pll1_clk,		div7);
162 SH_FIXED_RATIO_CLK(pll1_div13_clk,	pll1_clk,		div13);
163 
164 /* External input clock */
165 struct clk sh73a0_extcki_clk = {
166 };
167 
168 struct clk sh73a0_extalr_clk = {
169 };
170 
171 static struct clk *main_clks[] = {
172 	&r_clk,
173 	&sh73a0_extal1_clk,
174 	&sh73a0_extal2_clk,
175 	&extal1_div2_clk,
176 	&extal2_div2_clk,
177 	&main_clk,
178 	&main_div2_clk,
179 	&pll0_clk,
180 	&pll1_clk,
181 	&pll2_clk,
182 	&pll3_clk,
183 	&pll1_div2_clk,
184 	&pll1_div7_clk,
185 	&pll1_div13_clk,
186 	&sh73a0_extcki_clk,
187 	&sh73a0_extalr_clk,
188 };
189 
frqcr_kick(void)190 static int frqcr_kick(void)
191 {
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 }
204 
div4_kick(struct clk * clk)205 static void div4_kick(struct clk *clk)
206 {
207 	frqcr_kick();
208 }
209 
210 static int divisors[] = { 2, 3, 4, 6, 8, 12, 16, 18,
211 			  24, 0, 36, 48, 7 };
212 
213 static struct clk_div_mult_table div4_div_mult_table = {
214 	.divisors = divisors,
215 	.nr_divisors = ARRAY_SIZE(divisors),
216 };
217 
218 static struct clk_div4_table div4_table = {
219 	.div_mult_table = &div4_div_mult_table,
220 	.kick = div4_kick,
221 };
222 
223 enum { DIV4_I, DIV4_ZG, DIV4_M3, DIV4_B, DIV4_M1, DIV4_M2,
224 	DIV4_Z, DIV4_ZX, DIV4_HP, DIV4_NR };
225 
226 #define DIV4(_reg, _bit, _mask, _flags) \
227 	SH_CLK_DIV4(&pll1_clk, _reg, _bit, _mask, _flags)
228 
229 static struct clk div4_clks[DIV4_NR] = {
230 	[DIV4_I] = DIV4(FRQCRA, 20, 0xdff, CLK_ENABLE_ON_INIT),
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 	 */
236 	[DIV4_ZG] = SH_CLK_DIV4(&pll0_clk, FRQCRA, 16, 0xd7f, CLK_ENABLE_ON_INIT),
237 	[DIV4_M3] = DIV4(FRQCRA, 12, 0x1dff, CLK_ENABLE_ON_INIT),
238 	[DIV4_B] = DIV4(FRQCRA, 8, 0xdff, CLK_ENABLE_ON_INIT),
239 	[DIV4_M1] = DIV4(FRQCRA, 4, 0x1dff, 0),
240 	[DIV4_M2] = DIV4(FRQCRA, 0, 0x1dff, 0),
241 	[DIV4_Z] = SH_CLK_DIV4(&pll0_clk, FRQCRB, 24, 0x97f, 0),
242 	[DIV4_ZX] = DIV4(FRQCRB, 12, 0xdff, 0),
243 	[DIV4_HP] = DIV4(FRQCRB, 4, 0xdff, 0),
244 };
245 
twd_recalc(struct clk * clk)246 static unsigned long twd_recalc(struct clk *clk)
247 {
248 	return clk_get_rate(clk->parent) / 4;
249 }
250 
251 static struct sh_clk_ops twd_clk_ops = {
252 	.recalc = twd_recalc,
253 };
254 
255 static struct clk twd_clk = {
256 	.parent = &div4_clks[DIV4_Z],
257 	.ops = &twd_clk_ops,
258 };
259 
260 static struct sh_clk_ops zclk_ops, kicker_ops;
261 static const struct sh_clk_ops *div4_clk_ops;
262 
zclk_set_rate(struct clk * clk,unsigned long rate)263 static 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 */
277 		ret = div4_clk_ops->set_rate(clk, rate / 2);
278 		if (!ret)
279 			ret = frqcr_kick();
280 		if (ret > 0)
281 			ret = 0;
282 	} else {
283 		/* Enable the divider */
284 		__raw_writel(__raw_readl(FRQCRB) | (1 << 28), FRQCRB);
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 			 */
292 			ret = div4_clk_ops->set_rate(clk, rate);
293 		if (ret < 0)
294 			goto esetrate;
295 	}
296 
297 esetrate:
298 	__clk_put(clk->parent);
299 	return ret;
300 }
301 
zclk_round_rate(struct clk * clk,unsigned long rate)302 static long zclk_round_rate(struct clk *clk, unsigned long rate)
303 {
304 	unsigned long div_freq = div4_clk_ops->round_rate(clk, rate),
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 
zclk_recalc(struct clk * clk)313 static 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 	 */
319 	unsigned long div_freq = div4_clk_ops->recalc(clk);
320 
321 	if (__raw_readl(FRQCRB) & (1 << 28))
322 		return div_freq;
323 
324 	return clk_get_rate(clk->parent);
325 }
326 
kicker_set_rate(struct clk * clk,unsigned long rate)327 static int kicker_set_rate(struct clk *clk, unsigned long rate)
328 {
329 	if (__raw_readl(FRQCRB) & (1 << 31))
330 		return -EBUSY;
331 
332 	return div4_clk_ops->set_rate(clk, rate);
333 }
334 
div4_clk_extend(void)335 static void div4_clk_extend(void)
336 {
337 	int i;
338 
339 	div4_clk_ops = div4_clks[0].ops;
340 
341 	/* Add a kicker-busy check before changing the rate */
342 	kicker_ops = *div4_clk_ops;
343 	/* We extend the DIV4 clock with a 1:1 pass-through case */
344 	zclk_ops = *div4_clk_ops;
345 
346 	kicker_ops.set_rate = kicker_set_rate;
347 	zclk_ops.set_rate = zclk_set_rate;
348 	zclk_ops.round_rate = zclk_round_rate;
349 	zclk_ops.recalc = zclk_recalc;
350 
351 	for (i = 0; i < DIV4_NR; i++)
352 		div4_clks[i].ops = i == DIV4_Z ? &zclk_ops : &kicker_ops;
353 }
354 
355 enum { DIV6_VCK1, DIV6_VCK2, DIV6_VCK3, DIV6_ZB1,
356 	DIV6_FLCTL, DIV6_SDHI0, DIV6_SDHI1, DIV6_SDHI2,
357 	DIV6_FSIA, DIV6_FSIB, DIV6_SUB,
358 	DIV6_SPUA, DIV6_SPUV, DIV6_MSU,
359 	DIV6_HSI,  DIV6_MFG1, DIV6_MFG2,
360 	DIV6_DSIT, DIV6_DSI0P, DIV6_DSI1P,
361 	DIV6_NR };
362 
363 static struct clk *vck_parent[8] = {
364 	[0] = &pll1_div2_clk,
365 	[1] = &pll2_clk,
366 	[2] = &sh73a0_extcki_clk,
367 	[3] = &sh73a0_extal2_clk,
368 	[4] = &main_div2_clk,
369 	[5] = &sh73a0_extalr_clk,
370 	[6] = &main_clk,
371 };
372 
373 static struct clk *pll_parent[4] = {
374 	[0] = &pll1_div2_clk,
375 	[1] = &pll2_clk,
376 	[2] = &pll1_div13_clk,
377 };
378 
379 static struct clk *hsi_parent[4] = {
380 	[0] = &pll1_div2_clk,
381 	[1] = &pll2_clk,
382 	[2] = &pll1_div7_clk,
383 };
384 
385 static struct clk *pll_extal2_parent[] = {
386 	[0] = &pll1_div2_clk,
387 	[1] = &pll2_clk,
388 	[2] = &sh73a0_extal2_clk,
389 	[3] = &sh73a0_extal2_clk,
390 };
391 
392 static struct clk *dsi_parent[8] = {
393 	[0] = &pll1_div2_clk,
394 	[1] = &pll2_clk,
395 	[2] = &main_clk,
396 	[3] = &sh73a0_extal2_clk,
397 	[4] = &sh73a0_extcki_clk,
398 };
399 
400 static struct clk div6_clks[DIV6_NR] = {
401 	[DIV6_VCK1] = SH_CLK_DIV6_EXT(VCLKCR1, 0,
402 			vck_parent, ARRAY_SIZE(vck_parent), 12, 3),
403 	[DIV6_VCK2] = SH_CLK_DIV6_EXT(VCLKCR2, 0,
404 			vck_parent, ARRAY_SIZE(vck_parent), 12, 3),
405 	[DIV6_VCK3] = SH_CLK_DIV6_EXT(VCLKCR3, 0,
406 			vck_parent, ARRAY_SIZE(vck_parent), 12, 3),
407 	[DIV6_ZB1] = SH_CLK_DIV6_EXT(ZBCKCR, CLK_ENABLE_ON_INIT,
408 			pll_parent, ARRAY_SIZE(pll_parent), 7, 1),
409 	[DIV6_FLCTL] = SH_CLK_DIV6_EXT(FLCKCR, 0,
410 			pll_parent, ARRAY_SIZE(pll_parent), 7, 1),
411 	[DIV6_SDHI0] = SH_CLK_DIV6_EXT(SD0CKCR, 0,
412 			pll_parent, ARRAY_SIZE(pll_parent), 6, 2),
413 	[DIV6_SDHI1] = SH_CLK_DIV6_EXT(SD1CKCR, 0,
414 			pll_parent, ARRAY_SIZE(pll_parent), 6, 2),
415 	[DIV6_SDHI2] = SH_CLK_DIV6_EXT(SD2CKCR, 0,
416 			pll_parent, ARRAY_SIZE(pll_parent), 6, 2),
417 	[DIV6_FSIA] = SH_CLK_DIV6_EXT(FSIACKCR, 0,
418 			pll_parent, ARRAY_SIZE(pll_parent), 6, 1),
419 	[DIV6_FSIB] = SH_CLK_DIV6_EXT(FSIBCKCR, 0,
420 			pll_parent, ARRAY_SIZE(pll_parent), 6, 1),
421 	[DIV6_SUB] = SH_CLK_DIV6_EXT(SUBCKCR, 0,
422 			pll_extal2_parent, ARRAY_SIZE(pll_extal2_parent), 6, 2),
423 	[DIV6_SPUA] = SH_CLK_DIV6_EXT(SPUACKCR, 0,
424 			pll_extal2_parent, ARRAY_SIZE(pll_extal2_parent), 6, 2),
425 	[DIV6_SPUV] = SH_CLK_DIV6_EXT(SPUVCKCR, 0,
426 			pll_extal2_parent, ARRAY_SIZE(pll_extal2_parent), 6, 2),
427 	[DIV6_MSU] = SH_CLK_DIV6_EXT(MSUCKCR, 0,
428 			pll_parent, ARRAY_SIZE(pll_parent), 7, 1),
429 	[DIV6_HSI] = SH_CLK_DIV6_EXT(HSICKCR, 0,
430 			hsi_parent, ARRAY_SIZE(hsi_parent), 6, 2),
431 	[DIV6_MFG1] = SH_CLK_DIV6_EXT(MFCK1CR, 0,
432 			pll_parent, ARRAY_SIZE(pll_parent), 7, 1),
433 	[DIV6_MFG2] = SH_CLK_DIV6_EXT(MFCK2CR, 0,
434 			pll_parent, ARRAY_SIZE(pll_parent), 7, 1),
435 	[DIV6_DSIT] = SH_CLK_DIV6_EXT(DSITCKCR, 0,
436 			pll_parent, ARRAY_SIZE(pll_parent), 7, 1),
437 	[DIV6_DSI0P] = SH_CLK_DIV6_EXT(DSI0PCKCR, 0,
438 			dsi_parent, ARRAY_SIZE(dsi_parent), 12, 3),
439 	[DIV6_DSI1P] = SH_CLK_DIV6_EXT(DSI1PCKCR, 0,
440 			dsi_parent, ARRAY_SIZE(dsi_parent), 12, 3),
441 };
442 
443 /* DSI DIV */
dsiphy_recalc(struct clk * clk)444 static 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 
dsiphy_round_rate(struct clk * clk,unsigned long rate)466 static long dsiphy_round_rate(struct clk *clk, unsigned long rate)
467 {
468 	return clk_rate_mult_range_round(clk, 12, 33, rate);
469 }
470 
dsiphy_disable(struct clk * clk)471 static 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 
dsiphy_enable(struct clk * clk)481 static 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 
dsiphy_set_rate(struct clk * clk,unsigned long rate)497 static 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 
516 static struct sh_clk_ops dsiphy_clk_ops = {
517 	.recalc		= dsiphy_recalc,
518 	.round_rate	= dsiphy_round_rate,
519 	.set_rate	= dsiphy_set_rate,
520 	.enable		= dsiphy_enable,
521 	.disable	= dsiphy_disable,
522 };
523 
524 static struct clk_mapping dsi0phy_clk_mapping = {
525 	.phys	= DSI0PHYCR,
526 	.len	= 4,
527 };
528 
529 static struct clk_mapping dsi1phy_clk_mapping = {
530 	.phys	= DSI1PHYCR,
531 	.len	= 4,
532 };
533 
534 static struct clk dsi0phy_clk = {
535 	.ops		= &dsiphy_clk_ops,
536 	.parent		= &div6_clks[DIV6_DSI0P], /* late install */
537 	.mapping	= &dsi0phy_clk_mapping,
538 };
539 
540 static struct clk dsi1phy_clk = {
541 	.ops		= &dsiphy_clk_ops,
542 	.parent		= &div6_clks[DIV6_DSI1P], /* late install */
543 	.mapping	= &dsi1phy_clk_mapping,
544 };
545 
546 static struct clk *late_main_clks[] = {
547 	&dsi0phy_clk,
548 	&dsi1phy_clk,
549 	&twd_clk,
550 };
551 
552 enum { MSTP001,
553 	MSTP129, MSTP128, MSTP127, MSTP126, MSTP125, MSTP118, MSTP116, MSTP112, MSTP100,
554 	MSTP219, MSTP218, MSTP217,
555 	MSTP207, MSTP206, MSTP204, MSTP203, MSTP202, MSTP201, MSTP200,
556 	MSTP331, MSTP329, MSTP328, MSTP325, MSTP323, MSTP322,
557 	MSTP314, MSTP313, MSTP312, MSTP311,
558 	MSTP304, MSTP303, MSTP302, MSTP301, MSTP300,
559 	MSTP411, MSTP410, MSTP403,
560 	MSTP_NR };
561 
562 #define MSTP(_parent, _reg, _bit, _flags) \
563 	SH_CLK_MSTP32(_parent, _reg, _bit, _flags)
564 
565 static struct clk mstp_clks[MSTP_NR] = {
566 	[MSTP001] = MSTP(&div4_clks[DIV4_HP], SMSTPCR0, 1, 0), /* IIC2 */
567 	[MSTP129] = MSTP(&div4_clks[DIV4_B], SMSTPCR1, 29, 0), /* CEU1 */
568 	[MSTP128] = MSTP(&div4_clks[DIV4_B], SMSTPCR1, 28, 0), /* CSI2-RX1 */
569 	[MSTP127] = MSTP(&div4_clks[DIV4_B], SMSTPCR1, 27, 0), /* CEU0 */
570 	[MSTP126] = MSTP(&div4_clks[DIV4_B], SMSTPCR1, 26, 0), /* CSI2-RX0 */
571 	[MSTP125] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR1, 25, 0), /* TMU0 */
572 	[MSTP118] = MSTP(&div4_clks[DIV4_B], SMSTPCR1, 18, 0), /* DSITX0 */
573 	[MSTP116] = MSTP(&div4_clks[DIV4_HP], SMSTPCR1, 16, 0), /* IIC0 */
574 	[MSTP112] = MSTP(&div4_clks[DIV4_ZG], SMSTPCR1, 12, 0), /* SGX */
575 	[MSTP100] = MSTP(&div4_clks[DIV4_B], SMSTPCR1, 0, 0), /* LCDC0 */
576 	[MSTP219] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR2, 19, 0), /* SCIFA7 */
577 	[MSTP218] = MSTP(&div4_clks[DIV4_HP], SMSTPCR2, 18, 0), /* SY-DMAC */
578 	[MSTP217] = MSTP(&div4_clks[DIV4_HP], SMSTPCR2, 17, 0), /* MP-DMAC */
579 	[MSTP207] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR2, 7, 0), /* SCIFA5 */
580 	[MSTP206] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR2, 6, 0), /* SCIFB */
581 	[MSTP204] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR2, 4, 0), /* SCIFA0 */
582 	[MSTP203] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR2, 3, 0), /* SCIFA1 */
583 	[MSTP202] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR2, 2, 0), /* SCIFA2 */
584 	[MSTP201] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR2, 1, 0), /* SCIFA3 */
585 	[MSTP200] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR2, 0, 0), /* SCIFA4 */
586 	[MSTP331] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR3, 31, 0), /* SCIFA6 */
587 	[MSTP329] = MSTP(&r_clk, SMSTPCR3, 29, 0), /* CMT10 */
588 	[MSTP328] = MSTP(&div4_clks[DIV4_HP], SMSTPCR3, 28, 0), /*FSI*/
589 	[MSTP325] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR3, 25, 0), /* IrDA */
590 	[MSTP323] = MSTP(&div4_clks[DIV4_HP], SMSTPCR3, 23, 0), /* IIC1 */
591 	[MSTP322] = MSTP(&div4_clks[DIV4_HP], SMSTPCR3, 22, 0), /* USB */
592 	[MSTP314] = MSTP(&div6_clks[DIV6_SDHI0], SMSTPCR3, 14, 0), /* SDHI0 */
593 	[MSTP313] = MSTP(&div6_clks[DIV6_SDHI1], SMSTPCR3, 13, 0), /* SDHI1 */
594 	[MSTP312] = MSTP(&div4_clks[DIV4_HP], SMSTPCR3, 12, 0), /* MMCIF0 */
595 	[MSTP311] = MSTP(&div6_clks[DIV6_SDHI2], SMSTPCR3, 11, 0), /* SDHI2 */
596 	[MSTP304] = MSTP(&main_div2_clk, SMSTPCR3, 4, 0), /* TPU0 */
597 	[MSTP303] = MSTP(&main_div2_clk, SMSTPCR3, 3, 0), /* TPU1 */
598 	[MSTP302] = MSTP(&main_div2_clk, SMSTPCR3, 2, 0), /* TPU2 */
599 	[MSTP301] = MSTP(&main_div2_clk, SMSTPCR3, 1, 0), /* TPU3 */
600 	[MSTP300] = MSTP(&main_div2_clk, SMSTPCR3, 0, 0), /* TPU4 */
601 	[MSTP411] = MSTP(&div4_clks[DIV4_HP], SMSTPCR4, 11, 0), /* IIC3 */
602 	[MSTP410] = MSTP(&div4_clks[DIV4_HP], SMSTPCR4, 10, 0), /* IIC4 */
603 	[MSTP403] = MSTP(&r_clk, SMSTPCR4, 3, 0), /* KEYSC */
604 };
605 
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  */
613 static struct clk_lookup lookups[] = {
614 	/* main clocks */
615 	CLKDEV_CON_ID("r_clk", &r_clk),
616 	CLKDEV_DEV_ID("smp_twd", &twd_clk), /* smp_twd */
617 
618 	/* DIV4 clocks */
619 	CLKDEV_DEV_ID("cpu0", &div4_clks[DIV4_Z]),
620 
621 	/* DIV6 clocks */
622 	CLKDEV_CON_ID("vck1_clk", &div6_clks[DIV6_VCK1]),
623 	CLKDEV_CON_ID("vck2_clk", &div6_clks[DIV6_VCK2]),
624 	CLKDEV_CON_ID("vck3_clk", &div6_clks[DIV6_VCK3]),
625 	CLKDEV_CON_ID("sdhi0_clk", &div6_clks[DIV6_SDHI0]),
626 	CLKDEV_CON_ID("sdhi1_clk", &div6_clks[DIV6_SDHI1]),
627 	CLKDEV_CON_ID("sdhi2_clk", &div6_clks[DIV6_SDHI2]),
628 
629 	/* MSTP32 clocks */
630 	CLKDEV_DEV_ID("i2c-sh_mobile.2", &mstp_clks[MSTP001]), /* I2C2 */
631 	CLKDEV_DEV_ID("e6824000.i2c", &mstp_clks[MSTP001]), /* I2C2 */
632 	CLKDEV_DEV_ID("sh_mobile_ceu.1", &mstp_clks[MSTP129]), /* CEU1 */
633 	CLKDEV_DEV_ID("sh-mobile-csi2.1", &mstp_clks[MSTP128]), /* CSI2-RX1 */
634 	CLKDEV_DEV_ID("sh_mobile_ceu.0", &mstp_clks[MSTP127]), /* CEU0 */
635 	CLKDEV_DEV_ID("sh-mobile-csi2.0", &mstp_clks[MSTP126]), /* CSI2-RX0 */
636 	CLKDEV_DEV_ID("sh-mipi-dsi.0", &mstp_clks[MSTP118]), /* DSITX */
637 	CLKDEV_DEV_ID("i2c-sh_mobile.0", &mstp_clks[MSTP116]), /* I2C0 */
638 	CLKDEV_DEV_ID("e6820000.i2c", &mstp_clks[MSTP116]), /* I2C0 */
639 	CLKDEV_DEV_ID("sh_mobile_lcdc_fb.0", &mstp_clks[MSTP100]), /* LCDC0 */
640 	CLKDEV_DEV_ID("sh-sci.7", &mstp_clks[MSTP219]), /* SCIFA7 */
641 	CLKDEV_DEV_ID("e6cd0000.serial", &mstp_clks[MSTP219]), /* SCIFA7 */
642 	CLKDEV_DEV_ID("sh-dma-engine.0", &mstp_clks[MSTP218]), /* SY-DMAC */
643 	CLKDEV_DEV_ID("sh-dma-engine.1", &mstp_clks[MSTP217]), /* MP-DMAC */
644 	CLKDEV_DEV_ID("sh-sci.5", &mstp_clks[MSTP207]), /* SCIFA5 */
645 	CLKDEV_DEV_ID("e6cb0000.serial", &mstp_clks[MSTP207]), /* SCIFA5 */
646 	CLKDEV_DEV_ID("sh-sci.8", &mstp_clks[MSTP206]), /* SCIFB */
647 	CLKDEV_DEV_ID("e6c3000.serial", &mstp_clks[MSTP206]), /* SCIFB */
648 	CLKDEV_DEV_ID("sh-sci.0", &mstp_clks[MSTP204]), /* SCIFA0 */
649 	CLKDEV_DEV_ID("e6c40000.serial", &mstp_clks[MSTP204]), /* SCIFA0 */
650 	CLKDEV_DEV_ID("sh-sci.1", &mstp_clks[MSTP203]), /* SCIFA1 */
651 	CLKDEV_DEV_ID("e6c50000.serial", &mstp_clks[MSTP203]), /* SCIFA1 */
652 	CLKDEV_DEV_ID("sh-sci.2", &mstp_clks[MSTP202]), /* SCIFA2 */
653 	CLKDEV_DEV_ID("e6c60000.serial", &mstp_clks[MSTP202]), /* SCIFA2 */
654 	CLKDEV_DEV_ID("sh-sci.3", &mstp_clks[MSTP201]), /* SCIFA3 */
655 	CLKDEV_DEV_ID("e6c70000.serial", &mstp_clks[MSTP201]), /* SCIFA3 */
656 	CLKDEV_DEV_ID("sh-sci.4", &mstp_clks[MSTP200]), /* SCIFA4 */
657 	CLKDEV_DEV_ID("e6c80000.serial", &mstp_clks[MSTP200]), /* SCIFA4 */
658 	CLKDEV_DEV_ID("sh-sci.6", &mstp_clks[MSTP331]), /* SCIFA6 */
659 	CLKDEV_DEV_ID("e6cc0000.serial", &mstp_clks[MSTP331]), /* SCIFA6 */
660 	CLKDEV_DEV_ID("sh_fsi2", &mstp_clks[MSTP328]), /* FSI */
661 	CLKDEV_DEV_ID("ec230000.sound", &mstp_clks[MSTP328]), /* FSI */
662 	CLKDEV_DEV_ID("sh_irda.0", &mstp_clks[MSTP325]), /* IrDA */
663 	CLKDEV_DEV_ID("i2c-sh_mobile.1", &mstp_clks[MSTP323]), /* I2C1 */
664 	CLKDEV_DEV_ID("e6822000.i2c", &mstp_clks[MSTP323]), /* I2C1 */
665 	CLKDEV_DEV_ID("renesas_usbhs", &mstp_clks[MSTP322]), /* USB */
666 	CLKDEV_DEV_ID("sh_mobile_sdhi.0", &mstp_clks[MSTP314]), /* SDHI0 */
667 	CLKDEV_DEV_ID("ee100000.sd", &mstp_clks[MSTP314]), /* SDHI0 */
668 	CLKDEV_DEV_ID("sh_mobile_sdhi.1", &mstp_clks[MSTP313]), /* SDHI1 */
669 	CLKDEV_DEV_ID("ee120000.sd", &mstp_clks[MSTP313]), /* SDHI1 */
670 	CLKDEV_DEV_ID("sh_mmcif.0", &mstp_clks[MSTP312]), /* MMCIF0 */
671 	CLKDEV_DEV_ID("e6bd0000.mmc", &mstp_clks[MSTP312]), /* MMCIF0 */
672 	CLKDEV_DEV_ID("sh_mobile_sdhi.2", &mstp_clks[MSTP311]), /* SDHI2 */
673 	CLKDEV_DEV_ID("ee140000.sd", &mstp_clks[MSTP311]), /* SDHI2 */
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 */
679 	CLKDEV_DEV_ID("i2c-sh_mobile.3", &mstp_clks[MSTP411]), /* I2C3 */
680 	CLKDEV_DEV_ID("e6826000.i2c", &mstp_clks[MSTP411]), /* I2C3 */
681 	CLKDEV_DEV_ID("i2c-sh_mobile.4", &mstp_clks[MSTP410]), /* I2C4 */
682 	CLKDEV_DEV_ID("e6828000.i2c", &mstp_clks[MSTP410]), /* I2C4 */
683 	CLKDEV_DEV_ID("sh_keysc.0", &mstp_clks[MSTP403]), /* KEYSC */
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),
692 	CLKDEV_ICK_ID("fck", "sh-cmt-48.1", &mstp_clks[MSTP329]), /* CMT1 */
693 	CLKDEV_ICK_ID("fck", "e6138000.timer", &mstp_clks[MSTP329]), /* CMT1 */
694 	CLKDEV_ICK_ID("fck", "sh-tmu.0", &mstp_clks[MSTP125]), /* TMU0 */
695 };
696 
sh73a0_clock_init(void)697 void __init sh73a0_clock_init(void)
698 {
699 	int k, ret = 0;
700 
701 	/* Set SDHI clocks to a known state */
702 	__raw_writel(0x108, SD0CKCR);
703 	__raw_writel(0x108, SD1CKCR);
704 	__raw_writel(0x108, SD2CKCR);
705 
706 	/* detect main clock parent */
707 	switch ((__raw_readl(CKSCR) >> 28) & 0x03) {
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 
722 	for (k = 0; !ret && (k < ARRAY_SIZE(main_clks)); k++)
723 		ret = clk_register(main_clks[k]);
724 
725 	if (!ret) {
726 		ret = sh_clk_div4_register(div4_clks, DIV4_NR, &div4_table);
727 		if (!ret)
728 			div4_clk_extend();
729 	}
730 
731 	if (!ret)
732 		ret = sh_clk_div6_reparent_register(div6_clks, DIV6_NR);
733 
734 	if (!ret)
735 		ret = sh_clk_mstp_register(mstp_clks, MSTP_NR);
736 
737 	for (k = 0; !ret && (k < ARRAY_SIZE(late_main_clks)); k++)
738 		ret = clk_register(late_main_clks[k]);
739 
740 	clkdev_add_table(lookups, ARRAY_SIZE(lookups));
741 
742 	if (!ret)
743 		shmobile_clk_init();
744 	else
745 		panic("failed to setup sh73a0 clocks\n");
746 }
747