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 <mach/common.h>
25 
26 #define FRQCRA		0xe6150000
27 #define FRQCRB		0xe6150004
28 #define FRQCRD		0xe61500e4
29 #define VCLKCR1		0xe6150008
30 #define VCLKCR2		0xe615000C
31 #define VCLKCR3		0xe615001C
32 #define ZBCKCR		0xe6150010
33 #define FLCKCR		0xe6150014
34 #define SD0CKCR		0xe6150074
35 #define SD1CKCR		0xe6150078
36 #define SD2CKCR		0xe615007C
37 #define FSIACKCR	0xe6150018
38 #define FSIBCKCR	0xe6150090
39 #define SUBCKCR		0xe6150080
40 #define SPUACKCR	0xe6150084
41 #define SPUVCKCR	0xe6150094
42 #define MSUCKCR		0xe6150088
43 #define HSICKCR		0xe615008C
44 #define MFCK1CR		0xe6150098
45 #define MFCK2CR		0xe615009C
46 #define DSITCKCR	0xe6150060
47 #define DSI0PCKCR	0xe6150064
48 #define DSI1PCKCR	0xe6150068
49 #define DSI0PHYCR	0xe615006C
50 #define DSI1PHYCR	0xe6150070
51 #define PLLECR		0xe61500d0
52 #define PLL0CR		0xe61500d8
53 #define PLL1CR		0xe6150028
54 #define PLL2CR		0xe615002c
55 #define PLL3CR		0xe61500dc
56 #define SMSTPCR0	0xe6150130
57 #define SMSTPCR1	0xe6150134
58 #define SMSTPCR2	0xe6150138
59 #define SMSTPCR3	0xe615013c
60 #define SMSTPCR4	0xe6150140
61 #define SMSTPCR5	0xe6150144
62 #define CKSCR		0xe61500c0
63 
64 /* Fixed 32 KHz root clock from EXTALR pin */
65 static struct clk r_clk = {
66 	.rate           = 32768,
67 };
68 
69 /*
70  * 26MHz default rate for the EXTAL1 root input clock.
71  * If needed, reset this with clk_set_rate() from the platform code.
72  */
73 struct clk sh73a0_extal1_clk = {
74 	.rate		= 26000000,
75 };
76 
77 /*
78  * 48MHz default rate for the EXTAL2 root input clock.
79  * If needed, reset this with clk_set_rate() from the platform code.
80  */
81 struct clk sh73a0_extal2_clk = {
82 	.rate		= 48000000,
83 };
84 
85 /* A fixed divide-by-2 block */
div2_recalc(struct clk * clk)86 static unsigned long div2_recalc(struct clk *clk)
87 {
88 	return clk->parent->rate / 2;
89 }
90 
91 static struct clk_ops div2_clk_ops = {
92 	.recalc		= div2_recalc,
93 };
94 
div7_recalc(struct clk * clk)95 static unsigned long div7_recalc(struct clk *clk)
96 {
97 	return clk->parent->rate / 7;
98 }
99 
100 static struct clk_ops div7_clk_ops = {
101 	.recalc		= div7_recalc,
102 };
103 
div13_recalc(struct clk * clk)104 static unsigned long div13_recalc(struct clk *clk)
105 {
106 	return clk->parent->rate / 13;
107 }
108 
109 static struct clk_ops div13_clk_ops = {
110 	.recalc		= div13_recalc,
111 };
112 
113 /* Divide extal1 by two */
114 static struct clk extal1_div2_clk = {
115 	.ops		= &div2_clk_ops,
116 	.parent		= &sh73a0_extal1_clk,
117 };
118 
119 /* Divide extal2 by two */
120 static struct clk extal2_div2_clk = {
121 	.ops		= &div2_clk_ops,
122 	.parent		= &sh73a0_extal2_clk,
123 };
124 
125 static struct clk_ops main_clk_ops = {
126 	.recalc		= followparent_recalc,
127 };
128 
129 /* Main clock */
130 static struct clk main_clk = {
131 	.ops		= &main_clk_ops,
132 };
133 
134 /* Divide Main clock by two */
135 static struct clk main_div2_clk = {
136 	.ops		= &div2_clk_ops,
137 	.parent		= &main_clk,
138 };
139 
140 /* PLL0, PLL1, PLL2, PLL3 */
pll_recalc(struct clk * clk)141 static unsigned long pll_recalc(struct clk *clk)
142 {
143 	unsigned long mult = 1;
144 
145 	if (__raw_readl(PLLECR) & (1 << clk->enable_bit)) {
146 		mult = (((__raw_readl(clk->enable_reg) >> 24) & 0x3f) + 1);
147 		/* handle CFG bit for PLL1 and PLL2 */
148 		switch (clk->enable_bit) {
149 		case 1:
150 		case 2:
151 			if (__raw_readl(clk->enable_reg) & (1 << 20))
152 				mult *= 2;
153 		}
154 	}
155 
156 	return clk->parent->rate * mult;
157 }
158 
159 static struct clk_ops pll_clk_ops = {
160 	.recalc		= pll_recalc,
161 };
162 
163 static struct clk pll0_clk = {
164 	.ops		= &pll_clk_ops,
165 	.flags		= CLK_ENABLE_ON_INIT,
166 	.parent		= &main_clk,
167 	.enable_reg	= (void __iomem *)PLL0CR,
168 	.enable_bit	= 0,
169 };
170 
171 static struct clk pll1_clk = {
172 	.ops		= &pll_clk_ops,
173 	.flags		= CLK_ENABLE_ON_INIT,
174 	.parent		= &main_clk,
175 	.enable_reg	= (void __iomem *)PLL1CR,
176 	.enable_bit	= 1,
177 };
178 
179 static struct clk pll2_clk = {
180 	.ops		= &pll_clk_ops,
181 	.flags		= CLK_ENABLE_ON_INIT,
182 	.parent		= &main_clk,
183 	.enable_reg	= (void __iomem *)PLL2CR,
184 	.enable_bit	= 2,
185 };
186 
187 static struct clk pll3_clk = {
188 	.ops		= &pll_clk_ops,
189 	.flags		= CLK_ENABLE_ON_INIT,
190 	.parent		= &main_clk,
191 	.enable_reg	= (void __iomem *)PLL3CR,
192 	.enable_bit	= 3,
193 };
194 
195 /* Divide PLL */
196 static struct clk pll1_div2_clk = {
197 	.ops		= &div2_clk_ops,
198 	.parent		= &pll1_clk,
199 };
200 
201 static struct clk pll1_div7_clk = {
202 	.ops		= &div7_clk_ops,
203 	.parent		= &pll1_clk,
204 };
205 
206 static struct clk pll1_div13_clk = {
207 	.ops		= &div13_clk_ops,
208 	.parent		= &pll1_clk,
209 };
210 
211 /* External input clock */
212 struct clk sh73a0_extcki_clk = {
213 };
214 
215 struct clk sh73a0_extalr_clk = {
216 };
217 
218 static struct clk *main_clks[] = {
219 	&r_clk,
220 	&sh73a0_extal1_clk,
221 	&sh73a0_extal2_clk,
222 	&extal1_div2_clk,
223 	&extal2_div2_clk,
224 	&main_clk,
225 	&main_div2_clk,
226 	&pll0_clk,
227 	&pll1_clk,
228 	&pll2_clk,
229 	&pll3_clk,
230 	&pll1_div2_clk,
231 	&pll1_div7_clk,
232 	&pll1_div13_clk,
233 	&sh73a0_extcki_clk,
234 	&sh73a0_extalr_clk,
235 };
236 
div4_kick(struct clk * clk)237 static void div4_kick(struct clk *clk)
238 {
239 	unsigned long value;
240 
241 	/* set KICK bit in FRQCRB to update hardware setting */
242 	value = __raw_readl(FRQCRB);
243 	value |= (1 << 31);
244 	__raw_writel(value, FRQCRB);
245 }
246 
247 static int divisors[] = { 2, 3, 4, 6, 8, 12, 16, 18,
248 			  24, 0, 36, 48, 7 };
249 
250 static struct clk_div_mult_table div4_div_mult_table = {
251 	.divisors = divisors,
252 	.nr_divisors = ARRAY_SIZE(divisors),
253 };
254 
255 static struct clk_div4_table div4_table = {
256 	.div_mult_table = &div4_div_mult_table,
257 	.kick = div4_kick,
258 };
259 
260 enum { DIV4_I, DIV4_ZG, DIV4_M3, DIV4_B, DIV4_M1, DIV4_M2,
261 	DIV4_Z, DIV4_ZTR, DIV4_ZT, DIV4_ZX, DIV4_HP, DIV4_NR };
262 
263 #define DIV4(_reg, _bit, _mask, _flags) \
264 	SH_CLK_DIV4(&pll1_clk, _reg, _bit, _mask, _flags)
265 
266 static struct clk div4_clks[DIV4_NR] = {
267 	[DIV4_I] = DIV4(FRQCRA, 20, 0xfff, CLK_ENABLE_ON_INIT),
268 	[DIV4_ZG] = DIV4(FRQCRA, 16, 0xbff, CLK_ENABLE_ON_INIT),
269 	[DIV4_M3] = DIV4(FRQCRA, 12, 0xfff, CLK_ENABLE_ON_INIT),
270 	[DIV4_B] = DIV4(FRQCRA, 8, 0xfff, CLK_ENABLE_ON_INIT),
271 	[DIV4_M1] = DIV4(FRQCRA, 4, 0xfff, 0),
272 	[DIV4_M2] = DIV4(FRQCRA, 0, 0xfff, 0),
273 	[DIV4_Z] = DIV4(FRQCRB, 24, 0xbff, 0),
274 	[DIV4_ZTR] = DIV4(FRQCRB, 20, 0xfff, 0),
275 	[DIV4_ZT] = DIV4(FRQCRB, 16, 0xfff, 0),
276 	[DIV4_ZX] = DIV4(FRQCRB, 12, 0xfff, 0),
277 	[DIV4_HP] = DIV4(FRQCRB, 4, 0xfff, 0),
278 };
279 
280 enum { DIV6_VCK1, DIV6_VCK2, DIV6_VCK3, DIV6_ZB1,
281 	DIV6_FLCTL, DIV6_SDHI0, DIV6_SDHI1, DIV6_SDHI2,
282 	DIV6_FSIA, DIV6_FSIB, DIV6_SUB,
283 	DIV6_SPUA, DIV6_SPUV, DIV6_MSU,
284 	DIV6_HSI,  DIV6_MFG1, DIV6_MFG2,
285 	DIV6_DSIT, DIV6_DSI0P, DIV6_DSI1P,
286 	DIV6_NR };
287 
288 static struct clk *vck_parent[8] = {
289 	[0] = &pll1_div2_clk,
290 	[1] = &pll2_clk,
291 	[2] = &sh73a0_extcki_clk,
292 	[3] = &sh73a0_extal2_clk,
293 	[4] = &main_div2_clk,
294 	[5] = &sh73a0_extalr_clk,
295 	[6] = &main_clk,
296 };
297 
298 static struct clk *pll_parent[4] = {
299 	[0] = &pll1_div2_clk,
300 	[1] = &pll2_clk,
301 	[2] = &pll1_div13_clk,
302 };
303 
304 static struct clk *hsi_parent[4] = {
305 	[0] = &pll1_div2_clk,
306 	[1] = &pll2_clk,
307 	[2] = &pll1_div7_clk,
308 };
309 
310 static struct clk *pll_extal2_parent[] = {
311 	[0] = &pll1_div2_clk,
312 	[1] = &pll2_clk,
313 	[2] = &sh73a0_extal2_clk,
314 	[3] = &sh73a0_extal2_clk,
315 };
316 
317 static struct clk *dsi_parent[8] = {
318 	[0] = &pll1_div2_clk,
319 	[1] = &pll2_clk,
320 	[2] = &main_clk,
321 	[3] = &sh73a0_extal2_clk,
322 	[4] = &sh73a0_extcki_clk,
323 };
324 
325 static struct clk div6_clks[DIV6_NR] = {
326 	[DIV6_VCK1] = SH_CLK_DIV6_EXT(VCLKCR1, 0,
327 			vck_parent, ARRAY_SIZE(vck_parent), 12, 3),
328 	[DIV6_VCK2] = SH_CLK_DIV6_EXT(VCLKCR2, 0,
329 			vck_parent, ARRAY_SIZE(vck_parent), 12, 3),
330 	[DIV6_VCK3] = SH_CLK_DIV6_EXT(VCLKCR3, 0,
331 			vck_parent, ARRAY_SIZE(vck_parent), 12, 3),
332 	[DIV6_ZB1] = SH_CLK_DIV6_EXT(ZBCKCR, CLK_ENABLE_ON_INIT,
333 			pll_parent, ARRAY_SIZE(pll_parent), 7, 1),
334 	[DIV6_FLCTL] = SH_CLK_DIV6_EXT(FLCKCR, 0,
335 			pll_parent, ARRAY_SIZE(pll_parent), 7, 1),
336 	[DIV6_SDHI0] = SH_CLK_DIV6_EXT(SD0CKCR, 0,
337 			pll_parent, ARRAY_SIZE(pll_parent), 6, 2),
338 	[DIV6_SDHI1] = SH_CLK_DIV6_EXT(SD1CKCR, 0,
339 			pll_parent, ARRAY_SIZE(pll_parent), 6, 2),
340 	[DIV6_SDHI2] = SH_CLK_DIV6_EXT(SD2CKCR, 0,
341 			pll_parent, ARRAY_SIZE(pll_parent), 6, 2),
342 	[DIV6_FSIA] = SH_CLK_DIV6_EXT(FSIACKCR, 0,
343 			pll_parent, ARRAY_SIZE(pll_parent), 6, 1),
344 	[DIV6_FSIB] = SH_CLK_DIV6_EXT(FSIBCKCR, 0,
345 			pll_parent, ARRAY_SIZE(pll_parent), 6, 1),
346 	[DIV6_SUB] = SH_CLK_DIV6_EXT(SUBCKCR, 0,
347 			pll_extal2_parent, ARRAY_SIZE(pll_extal2_parent), 6, 2),
348 	[DIV6_SPUA] = SH_CLK_DIV6_EXT(SPUACKCR, 0,
349 			pll_extal2_parent, ARRAY_SIZE(pll_extal2_parent), 6, 2),
350 	[DIV6_SPUV] = SH_CLK_DIV6_EXT(SPUVCKCR, 0,
351 			pll_extal2_parent, ARRAY_SIZE(pll_extal2_parent), 6, 2),
352 	[DIV6_MSU] = SH_CLK_DIV6_EXT(MSUCKCR, 0,
353 			pll_parent, ARRAY_SIZE(pll_parent), 7, 1),
354 	[DIV6_HSI] = SH_CLK_DIV6_EXT(HSICKCR, 0,
355 			hsi_parent, ARRAY_SIZE(hsi_parent), 6, 2),
356 	[DIV6_MFG1] = SH_CLK_DIV6_EXT(MFCK1CR, 0,
357 			pll_parent, ARRAY_SIZE(pll_parent), 7, 1),
358 	[DIV6_MFG2] = SH_CLK_DIV6_EXT(MFCK2CR, 0,
359 			pll_parent, ARRAY_SIZE(pll_parent), 7, 1),
360 	[DIV6_DSIT] = SH_CLK_DIV6_EXT(DSITCKCR, 0,
361 			pll_parent, ARRAY_SIZE(pll_parent), 7, 1),
362 	[DIV6_DSI0P] = SH_CLK_DIV6_EXT(DSI0PCKCR, 0,
363 			dsi_parent, ARRAY_SIZE(dsi_parent), 12, 3),
364 	[DIV6_DSI1P] = SH_CLK_DIV6_EXT(DSI1PCKCR, 0,
365 			dsi_parent, ARRAY_SIZE(dsi_parent), 12, 3),
366 };
367 
368 /* DSI DIV */
dsiphy_recalc(struct clk * clk)369 static unsigned long dsiphy_recalc(struct clk *clk)
370 {
371 	u32 value;
372 
373 	value = __raw_readl(clk->mapping->base);
374 
375 	/* FIXME */
376 	if (!(value & 0x000B8000))
377 		return clk->parent->rate;
378 
379 	value &= 0x3f;
380 	value += 1;
381 
382 	if ((value < 12) ||
383 	    (value > 33)) {
384 		pr_err("DSIPHY has wrong value (%d)", value);
385 		return 0;
386 	}
387 
388 	return clk->parent->rate / value;
389 }
390 
dsiphy_round_rate(struct clk * clk,unsigned long rate)391 static long dsiphy_round_rate(struct clk *clk, unsigned long rate)
392 {
393 	return clk_rate_mult_range_round(clk, 12, 33, rate);
394 }
395 
dsiphy_disable(struct clk * clk)396 static void dsiphy_disable(struct clk *clk)
397 {
398 	u32 value;
399 
400 	value = __raw_readl(clk->mapping->base);
401 	value &= ~0x000B8000;
402 
403 	__raw_writel(value , clk->mapping->base);
404 }
405 
dsiphy_enable(struct clk * clk)406 static int dsiphy_enable(struct clk *clk)
407 {
408 	u32 value;
409 	int multi;
410 
411 	value = __raw_readl(clk->mapping->base);
412 	multi = (value & 0x3f) + 1;
413 
414 	if ((multi < 12) || (multi > 33))
415 		return -EIO;
416 
417 	__raw_writel(value | 0x000B8000, clk->mapping->base);
418 
419 	return 0;
420 }
421 
dsiphy_set_rate(struct clk * clk,unsigned long rate)422 static int dsiphy_set_rate(struct clk *clk, unsigned long rate)
423 {
424 	u32 value;
425 	int idx;
426 
427 	idx = rate / clk->parent->rate;
428 	if ((idx < 12) || (idx > 33))
429 		return -EINVAL;
430 
431 	idx += -1;
432 
433 	value = __raw_readl(clk->mapping->base);
434 	value = (value & ~0x3f) + idx;
435 
436 	__raw_writel(value, clk->mapping->base);
437 
438 	return 0;
439 }
440 
441 static struct clk_ops dsiphy_clk_ops = {
442 	.recalc		= dsiphy_recalc,
443 	.round_rate	= dsiphy_round_rate,
444 	.set_rate	= dsiphy_set_rate,
445 	.enable		= dsiphy_enable,
446 	.disable	= dsiphy_disable,
447 };
448 
449 static struct clk_mapping dsi0phy_clk_mapping = {
450 	.phys	= DSI0PHYCR,
451 	.len	= 4,
452 };
453 
454 static struct clk_mapping dsi1phy_clk_mapping = {
455 	.phys	= DSI1PHYCR,
456 	.len	= 4,
457 };
458 
459 static struct clk dsi0phy_clk = {
460 	.ops		= &dsiphy_clk_ops,
461 	.parent		= &div6_clks[DIV6_DSI0P], /* late install */
462 	.mapping	= &dsi0phy_clk_mapping,
463 };
464 
465 static struct clk dsi1phy_clk = {
466 	.ops		= &dsiphy_clk_ops,
467 	.parent		= &div6_clks[DIV6_DSI1P], /* late install */
468 	.mapping	= &dsi1phy_clk_mapping,
469 };
470 
471 static struct clk *late_main_clks[] = {
472 	&dsi0phy_clk,
473 	&dsi1phy_clk,
474 };
475 
476 enum { MSTP001,
477 	MSTP129, MSTP128, MSTP127, MSTP126, MSTP125, MSTP118, MSTP116, MSTP100,
478 	MSTP219,
479 	MSTP207, MSTP206, MSTP204, MSTP203, MSTP202, MSTP201, MSTP200,
480 	MSTP331, MSTP329, MSTP325, MSTP323, MSTP318,
481 	MSTP314, MSTP313, MSTP312, MSTP311,
482 	MSTP303, MSTP302, MSTP301, MSTP300,
483 	MSTP411, MSTP410, MSTP403,
484 	MSTP_NR };
485 
486 #define MSTP(_parent, _reg, _bit, _flags) \
487 	SH_CLK_MSTP32(_parent, _reg, _bit, _flags)
488 
489 static struct clk mstp_clks[MSTP_NR] = {
490 	[MSTP001] = MSTP(&div4_clks[DIV4_HP], SMSTPCR0, 1, 0), /* IIC2 */
491 	[MSTP129] = MSTP(&div4_clks[DIV4_B], SMSTPCR1, 29, 0), /* CEU1 */
492 	[MSTP128] = MSTP(&div4_clks[DIV4_B], SMSTPCR1, 28, 0), /* CSI2-RX1 */
493 	[MSTP127] = MSTP(&div4_clks[DIV4_B], SMSTPCR1, 27, 0), /* CEU0 */
494 	[MSTP126] = MSTP(&div4_clks[DIV4_B], SMSTPCR1, 26, 0), /* CSI2-RX0 */
495 	[MSTP125] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR1, 25, 0), /* TMU0 */
496 	[MSTP118] = MSTP(&div4_clks[DIV4_B], SMSTPCR1, 18, 0), /* DSITX0 */
497 	[MSTP116] = MSTP(&div4_clks[DIV4_HP], SMSTPCR1, 16, 0), /* IIC0 */
498 	[MSTP100] = MSTP(&div4_clks[DIV4_B], SMSTPCR1, 0, 0), /* LCDC0 */
499 	[MSTP219] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR2, 19, 0), /* SCIFA7 */
500 	[MSTP207] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR2, 7, 0), /* SCIFA5 */
501 	[MSTP206] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR2, 6, 0), /* SCIFB */
502 	[MSTP204] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR2, 4, 0), /* SCIFA0 */
503 	[MSTP203] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR2, 3, 0), /* SCIFA1 */
504 	[MSTP202] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR2, 2, 0), /* SCIFA2 */
505 	[MSTP201] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR2, 1, 0), /* SCIFA3 */
506 	[MSTP200] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR2, 0, 0), /* SCIFA4 */
507 	[MSTP331] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR3, 31, 0), /* SCIFA6 */
508 	[MSTP329] = MSTP(&r_clk, SMSTPCR3, 29, 0), /* CMT10 */
509 	[MSTP325] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR3, 25, 0), /* IrDA */
510 	[MSTP323] = MSTP(&div4_clks[DIV4_HP], SMSTPCR3, 23, 0), /* IIC1 */
511 	[MSTP318] = MSTP(&div4_clks[DIV4_HP], SMSTPCR3, 18, 0), /* SY-DMAC */
512 	[MSTP314] = MSTP(&div6_clks[DIV6_SDHI0], SMSTPCR3, 14, 0), /* SDHI0 */
513 	[MSTP313] = MSTP(&div6_clks[DIV6_SDHI1], SMSTPCR3, 13, 0), /* SDHI1 */
514 	[MSTP312] = MSTP(&div4_clks[DIV4_HP], SMSTPCR3, 12, 0), /* MMCIF0 */
515 	[MSTP311] = MSTP(&div6_clks[DIV6_SDHI2], SMSTPCR3, 11, 0), /* SDHI2 */
516 	[MSTP303] = MSTP(&main_div2_clk, SMSTPCR3, 3, 0), /* TPU1 */
517 	[MSTP302] = MSTP(&main_div2_clk, SMSTPCR3, 2, 0), /* TPU2 */
518 	[MSTP301] = MSTP(&main_div2_clk, SMSTPCR3, 1, 0), /* TPU3 */
519 	[MSTP300] = MSTP(&main_div2_clk, SMSTPCR3, 0, 0), /* TPU4 */
520 	[MSTP411] = MSTP(&div4_clks[DIV4_HP], SMSTPCR4, 11, 0), /* IIC3 */
521 	[MSTP410] = MSTP(&div4_clks[DIV4_HP], SMSTPCR4, 10, 0), /* IIC4 */
522 	[MSTP403] = MSTP(&r_clk, SMSTPCR4, 3, 0), /* KEYSC */
523 };
524 
525 static struct clk_lookup lookups[] = {
526 	/* main clocks */
527 	CLKDEV_CON_ID("r_clk", &r_clk),
528 
529 	/* DIV6 clocks */
530 	CLKDEV_CON_ID("vck1_clk", &div6_clks[DIV6_VCK1]),
531 	CLKDEV_CON_ID("vck2_clk", &div6_clks[DIV6_VCK2]),
532 	CLKDEV_CON_ID("vck3_clk", &div6_clks[DIV6_VCK3]),
533 	CLKDEV_CON_ID("sdhi0_clk", &div6_clks[DIV6_SDHI0]),
534 	CLKDEV_CON_ID("sdhi1_clk", &div6_clks[DIV6_SDHI1]),
535 	CLKDEV_CON_ID("sdhi2_clk", &div6_clks[DIV6_SDHI2]),
536 	CLKDEV_ICK_ID("dsit_clk", "sh-mipi-dsi.0", &div6_clks[DIV6_DSIT]),
537 	CLKDEV_ICK_ID("dsit_clk", "sh-mipi-dsi.1", &div6_clks[DIV6_DSIT]),
538 	CLKDEV_ICK_ID("dsip_clk", "sh-mipi-dsi.0", &div6_clks[DIV6_DSI0P]),
539 	CLKDEV_ICK_ID("dsip_clk", "sh-mipi-dsi.1", &div6_clks[DIV6_DSI1P]),
540 	CLKDEV_ICK_ID("dsiphy_clk", "sh-mipi-dsi.0", &dsi0phy_clk),
541 	CLKDEV_ICK_ID("dsiphy_clk", "sh-mipi-dsi.1", &dsi1phy_clk),
542 
543 	/* MSTP32 clocks */
544 	CLKDEV_DEV_ID("i2c-sh_mobile.2", &mstp_clks[MSTP001]), /* I2C2 */
545 	CLKDEV_DEV_ID("sh_mobile_ceu.1", &mstp_clks[MSTP129]), /* CEU1 */
546 	CLKDEV_DEV_ID("sh-mobile-csi2.1", &mstp_clks[MSTP128]), /* CSI2-RX1 */
547 	CLKDEV_DEV_ID("sh_mobile_ceu.0", &mstp_clks[MSTP127]), /* CEU0 */
548 	CLKDEV_DEV_ID("sh-mobile-csi2.0", &mstp_clks[MSTP126]), /* CSI2-RX0 */
549 	CLKDEV_DEV_ID("sh_tmu.0", &mstp_clks[MSTP125]), /* TMU00 */
550 	CLKDEV_DEV_ID("sh_tmu.1", &mstp_clks[MSTP125]), /* TMU01 */
551 	CLKDEV_DEV_ID("sh-mipi-dsi.0", &mstp_clks[MSTP118]), /* DSITX */
552 	CLKDEV_DEV_ID("i2c-sh_mobile.0", &mstp_clks[MSTP116]), /* I2C0 */
553 	CLKDEV_DEV_ID("sh_mobile_lcdc_fb.0", &mstp_clks[MSTP100]), /* LCDC0 */
554 	CLKDEV_DEV_ID("sh-sci.7", &mstp_clks[MSTP219]), /* SCIFA7 */
555 	CLKDEV_DEV_ID("sh-sci.5", &mstp_clks[MSTP207]), /* SCIFA5 */
556 	CLKDEV_DEV_ID("sh-sci.8", &mstp_clks[MSTP206]), /* SCIFB */
557 	CLKDEV_DEV_ID("sh-sci.0", &mstp_clks[MSTP204]), /* SCIFA0 */
558 	CLKDEV_DEV_ID("sh-sci.1", &mstp_clks[MSTP203]), /* SCIFA1 */
559 	CLKDEV_DEV_ID("sh-sci.2", &mstp_clks[MSTP202]), /* SCIFA2 */
560 	CLKDEV_DEV_ID("sh-sci.3", &mstp_clks[MSTP201]), /* SCIFA3 */
561 	CLKDEV_DEV_ID("sh-sci.4", &mstp_clks[MSTP200]), /* SCIFA4 */
562 	CLKDEV_DEV_ID("sh-sci.6", &mstp_clks[MSTP331]), /* SCIFA6 */
563 	CLKDEV_DEV_ID("sh_cmt.10", &mstp_clks[MSTP329]), /* CMT10 */
564 	CLKDEV_DEV_ID("sh_irda.0", &mstp_clks[MSTP325]), /* IrDA */
565 	CLKDEV_DEV_ID("i2c-sh_mobile.1", &mstp_clks[MSTP323]), /* I2C1 */
566 	CLKDEV_DEV_ID("sh-dma-engine.0", &mstp_clks[MSTP318]), /* SY-DMAC */
567 	CLKDEV_DEV_ID("sh_mobile_sdhi.0", &mstp_clks[MSTP314]), /* SDHI0 */
568 	CLKDEV_DEV_ID("sh_mobile_sdhi.1", &mstp_clks[MSTP313]), /* SDHI1 */
569 	CLKDEV_DEV_ID("sh_mmcif.0", &mstp_clks[MSTP312]), /* MMCIF0 */
570 	CLKDEV_DEV_ID("sh_mobile_sdhi.2", &mstp_clks[MSTP311]), /* SDHI2 */
571 	CLKDEV_DEV_ID("leds-renesas-tpu.12", &mstp_clks[MSTP303]), /* TPU1 */
572 	CLKDEV_DEV_ID("leds-renesas-tpu.21", &mstp_clks[MSTP302]), /* TPU2 */
573 	CLKDEV_DEV_ID("leds-renesas-tpu.30", &mstp_clks[MSTP301]), /* TPU3 */
574 	CLKDEV_DEV_ID("leds-renesas-tpu.41", &mstp_clks[MSTP300]), /* TPU4 */
575 	CLKDEV_DEV_ID("i2c-sh_mobile.3", &mstp_clks[MSTP411]), /* I2C3 */
576 	CLKDEV_DEV_ID("i2c-sh_mobile.4", &mstp_clks[MSTP410]), /* I2C4 */
577 	CLKDEV_DEV_ID("sh_keysc.0", &mstp_clks[MSTP403]), /* KEYSC */
578 };
579 
sh73a0_clock_init(void)580 void __init sh73a0_clock_init(void)
581 {
582 	int k, ret = 0;
583 
584 	/* Set SDHI clocks to a known state */
585 	__raw_writel(0x108, SD0CKCR);
586 	__raw_writel(0x108, SD1CKCR);
587 	__raw_writel(0x108, SD2CKCR);
588 
589 	/* detect main clock parent */
590 	switch ((__raw_readl(CKSCR) >> 28) & 0x03) {
591 	case 0:
592 		main_clk.parent = &sh73a0_extal1_clk;
593 		break;
594 	case 1:
595 		main_clk.parent = &extal1_div2_clk;
596 		break;
597 	case 2:
598 		main_clk.parent = &sh73a0_extal2_clk;
599 		break;
600 	case 3:
601 		main_clk.parent = &extal2_div2_clk;
602 		break;
603 	}
604 
605 	for (k = 0; !ret && (k < ARRAY_SIZE(main_clks)); k++)
606 		ret = clk_register(main_clks[k]);
607 
608 	if (!ret)
609 		ret = sh_clk_div4_register(div4_clks, DIV4_NR, &div4_table);
610 
611 	if (!ret)
612 		ret = sh_clk_div6_reparent_register(div6_clks, DIV6_NR);
613 
614 	if (!ret)
615 		ret = sh_clk_mstp32_register(mstp_clks, MSTP_NR);
616 
617 	for (k = 0; !ret && (k < ARRAY_SIZE(late_main_clks)); k++)
618 		ret = clk_register(late_main_clks[k]);
619 
620 	clkdev_add_table(lookups, ARRAY_SIZE(lookups));
621 
622 	if (!ret)
623 		clk_init();
624 	else
625 		panic("failed to setup sh73a0 clocks\n");
626 }
627