1 /*
2  * R8A7740 processor support
3  *
4  * Copyright (C) 2011  Renesas Solutions Corp.
5  * Copyright (C) 2011  Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
6  *
7  * This program is free software; you can redistribute it and/or modify
8  * it under the terms of the GNU General Public License as published by
9  * the Free Software Foundation; either version 2 of the License
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  */
16 #include <linux/init.h>
17 #include <linux/kernel.h>
18 #include <linux/io.h>
19 #include <linux/sh_clk.h>
20 #include <linux/clkdev.h>
21 
22 #include "clock.h"
23 #include "common.h"
24 #include "r8a7740.h"
25 
26 /*
27  *        |  MDx  |  XTAL1/EXTAL1   |  System   | EXTALR |
28  *  Clock |-------+-----------------+  clock    | 32.768 |   RCLK
29  *  Mode  | 2/1/0 | src         MHz |  source   |  KHz   |  source
30  * -------+-------+-----------------+-----------+--------+----------
31  *    0   | 0 0 0 | External  20~50 | XTAL1     |    O   |  EXTALR
32  *    1   | 0 0 1 | Crystal   20~30 | XTAL1     |    O   |  EXTALR
33  *    2   | 0 1 0 | External  40~50 | XTAL1 / 2 |    O   |  EXTALR
34  *    3   | 0 1 1 | Crystal   40~50 | XTAL1 / 2 |    O   |  EXTALR
35  *    4   | 1 0 0 | External  20~50 | XTAL1     |    x   |  XTAL1 / 1024
36  *    5   | 1 0 1 | Crystal   20~30 | XTAL1     |    x   |  XTAL1 / 1024
37  *    6   | 1 1 0 | External  40~50 | XTAL1 / 2 |    x   |  XTAL1 / 2048
38  *    7   | 1 1 1 | Crystal   40~50 | XTAL1 / 2 |    x   |  XTAL1 / 2048
39  */
40 
41 /* CPG registers */
42 #define FRQCRA		IOMEM(0xe6150000)
43 #define FRQCRB		IOMEM(0xe6150004)
44 #define VCLKCR1		IOMEM(0xE6150008)
45 #define VCLKCR2		IOMEM(0xE615000c)
46 #define FRQCRC		IOMEM(0xe61500e0)
47 #define FSIACKCR	IOMEM(0xe6150018)
48 #define PLLC01CR	IOMEM(0xe6150028)
49 
50 #define SUBCKCR		IOMEM(0xe6150080)
51 #define USBCKCR		IOMEM(0xe615008c)
52 
53 #define MSTPSR0		IOMEM(0xe6150030)
54 #define MSTPSR1		IOMEM(0xe6150038)
55 #define MSTPSR2		IOMEM(0xe6150040)
56 #define MSTPSR3		IOMEM(0xe6150048)
57 #define MSTPSR4		IOMEM(0xe615004c)
58 #define FSIBCKCR	IOMEM(0xe6150090)
59 #define HDMICKCR	IOMEM(0xe6150094)
60 #define SMSTPCR0	IOMEM(0xe6150130)
61 #define SMSTPCR1	IOMEM(0xe6150134)
62 #define SMSTPCR2	IOMEM(0xe6150138)
63 #define SMSTPCR3	IOMEM(0xe615013c)
64 #define SMSTPCR4	IOMEM(0xe6150140)
65 
66 #define FSIDIVA		IOMEM(0xFE1F8000)
67 #define FSIDIVB		IOMEM(0xFE1F8008)
68 
69 /* Fixed 32 KHz root clock from EXTALR pin */
70 static struct clk extalr_clk = {
71 	.rate	= 32768,
72 };
73 
74 /*
75  * 25MHz default rate for the EXTAL1 root input clock.
76  * If needed, reset this with clk_set_rate() from the platform code.
77  */
78 static struct clk extal1_clk = {
79 	.rate	= 25000000,
80 };
81 
82 /*
83  * 48MHz default rate for the EXTAL2 root input clock.
84  * If needed, reset this with clk_set_rate() from the platform code.
85  */
86 static struct clk extal2_clk = {
87 	.rate	= 48000000,
88 };
89 
90 /*
91  * 27MHz default rate for the DV_CLKI root input clock.
92  * If needed, reset this with clk_set_rate() from the platform code.
93  */
94 static struct clk dv_clk = {
95 	.rate	= 27000000,
96 };
97 
98 SH_CLK_RATIO(div2,	1, 2);
99 SH_CLK_RATIO(div1k,	1, 1024);
100 
101 SH_FIXED_RATIO_CLK(extal1_div2_clk,	extal1_clk,		div2);
102 SH_FIXED_RATIO_CLK(extal1_div1024_clk,	extal1_clk,		div1k);
103 SH_FIXED_RATIO_CLK(extal1_div2048_clk,	extal1_div2_clk,	div1k);
104 SH_FIXED_RATIO_CLK(extal2_div2_clk,	extal2_clk,		div2);
105 
106 static struct sh_clk_ops followparent_clk_ops = {
107 	.recalc	= followparent_recalc,
108 };
109 
110 /* Main clock */
111 static struct clk system_clk = {
112 	.ops	= &followparent_clk_ops,
113 };
114 
115 SH_FIXED_RATIO_CLK(system_div2_clk, system_clk,	div2);
116 
117 /* r_clk */
118 static struct clk r_clk = {
119 	.ops	= &followparent_clk_ops,
120 };
121 
122 /* PLLC0/PLLC1 */
pllc01_recalc(struct clk * clk)123 static unsigned long pllc01_recalc(struct clk *clk)
124 {
125 	unsigned long mult = 1;
126 
127 	if (__raw_readl(PLLC01CR) & (1 << 14))
128 		mult = ((__raw_readl(clk->enable_reg) >> 24) & 0x7f) + 1;
129 
130 	return clk->parent->rate * mult;
131 }
132 
133 static struct sh_clk_ops pllc01_clk_ops = {
134 	.recalc		= pllc01_recalc,
135 };
136 
137 static struct clk pllc0_clk = {
138 	.ops		= &pllc01_clk_ops,
139 	.flags		= CLK_ENABLE_ON_INIT,
140 	.parent		= &system_clk,
141 	.enable_reg	= (void __iomem *)FRQCRC,
142 };
143 
144 static struct clk pllc1_clk = {
145 	.ops		= &pllc01_clk_ops,
146 	.flags		= CLK_ENABLE_ON_INIT,
147 	.parent		= &system_div2_clk,
148 	.enable_reg	= (void __iomem *)FRQCRA,
149 };
150 
151 /* PLLC1 / 2 */
152 SH_FIXED_RATIO_CLK(pllc1_div2_clk, pllc1_clk, div2);
153 
154 /* USB clock */
155 /*
156  * USBCKCR is controlling usb24 clock
157  * bit[7] : parent clock
158  * bit[6] : clock divide rate
159  * And this bit[7] is used as a "usb24s" from other devices.
160  * (Video clock / Sub clock / SPU clock)
161  * You can controll this clock as a below.
162  *
163  * struct clk *usb24	= clk_get(dev,  "usb24");
164  * struct clk *usb24s	= clk_get(NULL, "usb24s");
165  * struct clk *system	= clk_get(NULL, "system_clk");
166  * int rate = clk_get_rate(system);
167  *
168  * clk_set_parent(usb24s, system);  // for bit[7]
169  * clk_set_rate(usb24, rate / 2);   // for bit[6]
170  */
171 static struct clk *usb24s_parents[] = {
172 	[0] = &system_clk,
173 	[1] = &extal2_clk
174 };
175 
usb24s_enable(struct clk * clk)176 static int usb24s_enable(struct clk *clk)
177 {
178 	__raw_writel(__raw_readl(USBCKCR) & ~(1 << 8), USBCKCR);
179 
180 	return 0;
181 }
182 
usb24s_disable(struct clk * clk)183 static void usb24s_disable(struct clk *clk)
184 {
185 	__raw_writel(__raw_readl(USBCKCR) | (1 << 8), USBCKCR);
186 }
187 
usb24s_set_parent(struct clk * clk,struct clk * parent)188 static int usb24s_set_parent(struct clk *clk, struct clk *parent)
189 {
190 	int i, ret;
191 	u32 val;
192 
193 	if (!clk->parent_table || !clk->parent_num)
194 		return -EINVAL;
195 
196 	/* Search the parent */
197 	for (i = 0; i < clk->parent_num; i++)
198 		if (clk->parent_table[i] == parent)
199 			break;
200 
201 	if (i == clk->parent_num)
202 		return -ENODEV;
203 
204 	ret = clk_reparent(clk, parent);
205 	if (ret < 0)
206 		return ret;
207 
208 	val = __raw_readl(USBCKCR);
209 	val &= ~(1 << 7);
210 	val |= i << 7;
211 	__raw_writel(val, USBCKCR);
212 
213 	return 0;
214 }
215 
216 static struct sh_clk_ops usb24s_clk_ops = {
217 	.recalc		= followparent_recalc,
218 	.enable		= usb24s_enable,
219 	.disable	= usb24s_disable,
220 	.set_parent	= usb24s_set_parent,
221 };
222 
223 static struct clk usb24s_clk = {
224 	.ops		= &usb24s_clk_ops,
225 	.parent_table	= usb24s_parents,
226 	.parent_num	= ARRAY_SIZE(usb24s_parents),
227 	.parent		= &system_clk,
228 };
229 
usb24_recalc(struct clk * clk)230 static unsigned long usb24_recalc(struct clk *clk)
231 {
232 	return clk->parent->rate /
233 		((__raw_readl(USBCKCR) & (1 << 6)) ? 1 : 2);
234 };
235 
usb24_set_rate(struct clk * clk,unsigned long rate)236 static int usb24_set_rate(struct clk *clk, unsigned long rate)
237 {
238 	u32 val;
239 
240 	/* closer to which ? parent->rate or parent->rate/2 */
241 	val = __raw_readl(USBCKCR);
242 	val &= ~(1 << 6);
243 	val |= (rate > (clk->parent->rate / 4) * 3) << 6;
244 	__raw_writel(val, USBCKCR);
245 
246 	return 0;
247 }
248 
249 static struct sh_clk_ops usb24_clk_ops = {
250 	.recalc		= usb24_recalc,
251 	.set_rate	= usb24_set_rate,
252 };
253 
254 static struct clk usb24_clk = {
255 	.ops		= &usb24_clk_ops,
256 	.parent		= &usb24s_clk,
257 };
258 
259 /* External FSIACK/FSIBCK clock */
260 static struct clk fsiack_clk = {
261 };
262 
263 static struct clk fsibck_clk = {
264 };
265 
266 static struct clk *main_clks[] = {
267 	&extalr_clk,
268 	&extal1_clk,
269 	&extal2_clk,
270 	&extal1_div2_clk,
271 	&extal1_div1024_clk,
272 	&extal1_div2048_clk,
273 	&extal2_div2_clk,
274 	&dv_clk,
275 	&system_clk,
276 	&system_div2_clk,
277 	&r_clk,
278 	&pllc0_clk,
279 	&pllc1_clk,
280 	&pllc1_div2_clk,
281 	&usb24s_clk,
282 	&usb24_clk,
283 	&fsiack_clk,
284 	&fsibck_clk,
285 };
286 
287 /* DIV4 clocks */
div4_kick(struct clk * clk)288 static void div4_kick(struct clk *clk)
289 {
290 	unsigned long value;
291 
292 	/* set KICK bit in FRQCRB to update hardware setting */
293 	value = __raw_readl(FRQCRB);
294 	value |= (1 << 31);
295 	__raw_writel(value, FRQCRB);
296 }
297 
298 static int divisors[] = { 2, 3, 4, 6, 8, 12, 16, 18,
299 			  24, 32, 36, 48, 0, 72, 96, 0 };
300 
301 static struct clk_div_mult_table div4_div_mult_table = {
302 	.divisors = divisors,
303 	.nr_divisors = ARRAY_SIZE(divisors),
304 };
305 
306 static struct clk_div4_table div4_table = {
307 	.div_mult_table = &div4_div_mult_table,
308 	.kick = div4_kick,
309 };
310 
311 enum {
312 	DIV4_I, DIV4_ZG, DIV4_B, DIV4_M1, DIV4_HP,
313 	DIV4_HPP, DIV4_USBP, DIV4_S, DIV4_ZB, DIV4_M3, DIV4_CP,
314 	DIV4_NR
315 };
316 
317 static struct clk div4_clks[DIV4_NR] = {
318 	[DIV4_I]	= SH_CLK_DIV4(&pllc1_clk, FRQCRA, 20, 0x6fff, CLK_ENABLE_ON_INIT),
319 	[DIV4_ZG]	= SH_CLK_DIV4(&pllc1_clk, FRQCRA, 16, 0x6fff, CLK_ENABLE_ON_INIT),
320 	[DIV4_B]	= SH_CLK_DIV4(&pllc1_clk, FRQCRA,  8, 0x6fff, CLK_ENABLE_ON_INIT),
321 	[DIV4_M1]	= SH_CLK_DIV4(&pllc1_clk, FRQCRA,  4, 0x6fff, CLK_ENABLE_ON_INIT),
322 	[DIV4_HP]	= SH_CLK_DIV4(&pllc1_clk, FRQCRB,  4, 0x6fff, 0),
323 	[DIV4_HPP]	= SH_CLK_DIV4(&pllc1_clk, FRQCRC, 20, 0x6fff, 0),
324 	[DIV4_USBP]	= SH_CLK_DIV4(&pllc1_clk, FRQCRC, 16, 0x6fff, 0),
325 	[DIV4_S]	= SH_CLK_DIV4(&pllc1_clk, FRQCRC, 12, 0x6fff, 0),
326 	[DIV4_ZB]	= SH_CLK_DIV4(&pllc1_clk, FRQCRC,  8, 0x6fff, 0),
327 	[DIV4_M3]	= SH_CLK_DIV4(&pllc1_clk, FRQCRC,  4, 0x6fff, 0),
328 	[DIV4_CP]	= SH_CLK_DIV4(&pllc1_clk, FRQCRC,  0, 0x6fff, 0),
329 };
330 
331 /* DIV6 reparent */
332 enum {
333 	DIV6_HDMI,
334 	DIV6_VCLK1, DIV6_VCLK2,
335 	DIV6_FSIA, DIV6_FSIB,
336 	DIV6_REPARENT_NR,
337 };
338 
339 static struct clk *hdmi_parent[] = {
340 	[0] = &pllc1_div2_clk,
341 	[1] = &system_clk,
342 	[2] = &dv_clk
343 };
344 
345 static struct clk *vclk_parents[8] = {
346 	[0] = &pllc1_div2_clk,
347 	[2] = &dv_clk,
348 	[3] = &usb24s_clk,
349 	[4] = &extal1_div2_clk,
350 	[5] = &extalr_clk,
351 };
352 
353 static struct clk *fsia_parents[] = {
354 	[0] = &pllc1_div2_clk,
355 	[1] = &fsiack_clk, /* external clock */
356 };
357 
358 static struct clk *fsib_parents[] = {
359 	[0] = &pllc1_div2_clk,
360 	[1] = &fsibck_clk, /* external clock */
361 };
362 
363 static struct clk div6_reparent_clks[DIV6_REPARENT_NR] = {
364 	[DIV6_HDMI] = SH_CLK_DIV6_EXT(HDMICKCR, 0,
365 				      hdmi_parent, ARRAY_SIZE(hdmi_parent), 6, 2),
366 	[DIV6_VCLK1] = SH_CLK_DIV6_EXT(VCLKCR1, 0,
367 				       vclk_parents, ARRAY_SIZE(vclk_parents), 12, 3),
368 	[DIV6_VCLK2] = SH_CLK_DIV6_EXT(VCLKCR2, 0,
369 				       vclk_parents, ARRAY_SIZE(vclk_parents), 12, 3),
370 	[DIV6_FSIA] = SH_CLK_DIV6_EXT(FSIACKCR, 0,
371 				      fsia_parents, ARRAY_SIZE(fsia_parents), 6, 2),
372 	[DIV6_FSIB] = SH_CLK_DIV6_EXT(FSIBCKCR, 0,
373 				      fsib_parents, ARRAY_SIZE(fsib_parents), 6, 2),
374 };
375 
376 /* DIV6 clocks */
377 enum {
378 	DIV6_SUB,
379 	DIV6_NR
380 };
381 
382 static struct clk div6_clks[DIV6_NR] = {
383 	[DIV6_SUB]	= SH_CLK_DIV6(&pllc1_div2_clk, SUBCKCR, 0),
384 };
385 
386 /* HDMI1/2 clock */
hdmi12_recalc(struct clk * clk)387 static unsigned long hdmi12_recalc(struct clk *clk)
388 {
389 	u32 val = __raw_readl(HDMICKCR);
390 	int shift = (int)clk->priv;
391 
392 	val >>= shift;
393 	val &= 0x3;
394 
395 	return clk->parent->rate / (1 << val);
396 };
397 
hdmi12_set_rate(struct clk * clk,unsigned long rate)398 static int hdmi12_set_rate(struct clk *clk, unsigned long rate)
399 {
400 	u32 val, mask;
401 	int i, shift;
402 
403 	for (i = 0; i < 3; i++)
404 		if (rate == clk->parent->rate / (1 << i))
405 			goto find;
406 	return -ENODEV;
407 
408 find:
409 	shift = (int)clk->priv;
410 
411 	val = __raw_readl(HDMICKCR);
412 	mask = ~(0x3 << shift);
413 	val = (val & mask) | i << shift;
414 	__raw_writel(val, HDMICKCR);
415 
416 	return 0;
417 };
418 
419 static struct sh_clk_ops hdmi12_clk_ops = {
420 	.recalc		= hdmi12_recalc,
421 	.set_rate	= hdmi12_set_rate,
422 };
423 
424 static struct clk hdmi1_clk = {
425 	.ops		= &hdmi12_clk_ops,
426 	.priv		= (void *)9,
427 	.parent		= &div6_reparent_clks[DIV6_HDMI],  /* late install */
428 };
429 
430 static struct clk hdmi2_clk = {
431 	.ops		= &hdmi12_clk_ops,
432 	.priv		= (void *)11,
433 	.parent		= &div6_reparent_clks[DIV6_HDMI], /* late install */
434 };
435 
436 static struct clk *late_main_clks[] = {
437 	&hdmi1_clk,
438 	&hdmi2_clk,
439 };
440 
441 /* FSI DIV */
442 enum { FSIDIV_A, FSIDIV_B, FSIDIV_REPARENT_NR };
443 
444 static struct clk fsidivs[] = {
445 	[FSIDIV_A] = SH_CLK_FSIDIV(FSIDIVA, &div6_reparent_clks[DIV6_FSIA]),
446 	[FSIDIV_B] = SH_CLK_FSIDIV(FSIDIVB, &div6_reparent_clks[DIV6_FSIB]),
447 };
448 
449 /* MSTP */
450 enum {
451 	MSTP128, MSTP127, MSTP125,
452 	MSTP116, MSTP111, MSTP100, MSTP117,
453 
454 	MSTP230, MSTP229,
455 	MSTP222,
456 	MSTP218, MSTP217, MSTP216, MSTP214,
457 	MSTP207, MSTP206, MSTP204, MSTP203, MSTP202, MSTP201, MSTP200,
458 
459 	MSTP329, MSTP328, MSTP323, MSTP320,
460 	MSTP314, MSTP313, MSTP312,
461 	MSTP309, MSTP304,
462 
463 	MSTP416, MSTP415, MSTP407, MSTP406,
464 
465 	MSTP_NR
466 };
467 
468 static struct clk mstp_clks[MSTP_NR] = {
469 	[MSTP128] = SH_CLK_MSTP32(&div4_clks[DIV4_S],	SMSTPCR1, 28, 0), /* CEU21 */
470 	[MSTP127] = SH_CLK_MSTP32(&div4_clks[DIV4_S],	SMSTPCR1, 27, 0), /* CEU20 */
471 	[MSTP125] = SH_CLK_MSTP32(&div6_clks[DIV6_SUB],	SMSTPCR1, 25, 0), /* TMU0 */
472 	[MSTP117] = SH_CLK_MSTP32(&div4_clks[DIV4_B],	SMSTPCR1, 17, 0), /* LCDC1 */
473 	[MSTP116] = SH_CLK_MSTP32(&div4_clks[DIV4_HPP],	SMSTPCR1, 16, 0), /* IIC0 */
474 	[MSTP111] = SH_CLK_MSTP32(&div6_clks[DIV6_SUB],	SMSTPCR1, 11, 0), /* TMU1 */
475 	[MSTP100] = SH_CLK_MSTP32(&div4_clks[DIV4_B],	SMSTPCR1,  0, 0), /* LCDC0 */
476 
477 	[MSTP230] = SH_CLK_MSTP32(&div6_clks[DIV6_SUB],	SMSTPCR2, 30, 0), /* SCIFA6 */
478 	[MSTP229] = SH_CLK_MSTP32(&div4_clks[DIV4_HP],	SMSTPCR2, 29, 0), /* INTCA */
479 	[MSTP222] = SH_CLK_MSTP32(&div6_clks[DIV6_SUB],	SMSTPCR2, 22, 0), /* SCIFA7 */
480 	[MSTP218] = SH_CLK_MSTP32(&div4_clks[DIV4_HP],  SMSTPCR2, 18, 0), /* DMAC1 */
481 	[MSTP217] = SH_CLK_MSTP32(&div4_clks[DIV4_HP],  SMSTPCR2, 17, 0), /* DMAC2 */
482 	[MSTP216] = SH_CLK_MSTP32(&div4_clks[DIV4_HP],  SMSTPCR2, 16, 0), /* DMAC3 */
483 	[MSTP214] = SH_CLK_MSTP32(&div4_clks[DIV4_HP],  SMSTPCR2, 14, 0), /* USBDMAC */
484 	[MSTP207] = SH_CLK_MSTP32(&div6_clks[DIV6_SUB],	SMSTPCR2,  7, 0), /* SCIFA5 */
485 	[MSTP206] = SH_CLK_MSTP32(&div6_clks[DIV6_SUB],	SMSTPCR2,  6, 0), /* SCIFB */
486 	[MSTP204] = SH_CLK_MSTP32(&div6_clks[DIV6_SUB],	SMSTPCR2,  4, 0), /* SCIFA0 */
487 	[MSTP203] = SH_CLK_MSTP32(&div6_clks[DIV6_SUB],	SMSTPCR2,  3, 0), /* SCIFA1 */
488 	[MSTP202] = SH_CLK_MSTP32(&div6_clks[DIV6_SUB],	SMSTPCR2,  2, 0), /* SCIFA2 */
489 	[MSTP201] = SH_CLK_MSTP32(&div6_clks[DIV6_SUB],	SMSTPCR2,  1, 0), /* SCIFA3 */
490 	[MSTP200] = SH_CLK_MSTP32(&div6_clks[DIV6_SUB],	SMSTPCR2,  0, 0), /* SCIFA4 */
491 
492 	[MSTP329] = SH_CLK_MSTP32(&r_clk,		SMSTPCR3, 29, 0), /* CMT10 */
493 	[MSTP328] = SH_CLK_MSTP32(&div4_clks[DIV4_HP],	SMSTPCR3, 28, 0), /* FSI */
494 	[MSTP323] = SH_CLK_MSTP32(&div6_clks[DIV6_SUB],	SMSTPCR3, 23, 0), /* IIC1 */
495 	[MSTP320] = SH_CLK_MSTP32(&div4_clks[DIV4_HP],	SMSTPCR3, 20, 0), /* USBF */
496 	[MSTP314] = SH_CLK_MSTP32(&div4_clks[DIV4_HP],	SMSTPCR3, 14, 0), /* SDHI0 */
497 	[MSTP313] = SH_CLK_MSTP32(&div4_clks[DIV4_HP],	SMSTPCR3, 13, 0), /* SDHI1 */
498 	[MSTP312] = SH_CLK_MSTP32(&div4_clks[DIV4_HP],	SMSTPCR3, 12, 0), /* MMC */
499 	[MSTP309] = SH_CLK_MSTP32(&div4_clks[DIV4_HP],	SMSTPCR3,  9, 0), /* GEther */
500 	[MSTP304] = SH_CLK_MSTP32(&div4_clks[DIV4_CP],	SMSTPCR3,  4, 0), /* TPU0 */
501 
502 	[MSTP416] = SH_CLK_MSTP32(&div4_clks[DIV4_HP],	SMSTPCR4, 16, 0), /* USBHOST */
503 	[MSTP415] = SH_CLK_MSTP32(&div4_clks[DIV4_HP],	SMSTPCR4, 15, 0), /* SDHI2 */
504 	[MSTP407] = SH_CLK_MSTP32(&div4_clks[DIV4_HP],	SMSTPCR4,  7, 0), /* USB-Func */
505 	[MSTP406] = SH_CLK_MSTP32(&div4_clks[DIV4_HP],	SMSTPCR4,  6, 0), /* USB Phy */
506 };
507 
508 static struct clk_lookup lookups[] = {
509 	/* main clocks */
510 	CLKDEV_CON_ID("extalr",			&extalr_clk),
511 	CLKDEV_CON_ID("extal1",			&extal1_clk),
512 	CLKDEV_CON_ID("extal2",			&extal2_clk),
513 	CLKDEV_CON_ID("extal1_div2",		&extal1_div2_clk),
514 	CLKDEV_CON_ID("extal1_div1024",		&extal1_div1024_clk),
515 	CLKDEV_CON_ID("extal1_div2048",		&extal1_div2048_clk),
516 	CLKDEV_CON_ID("extal2_div2",		&extal2_div2_clk),
517 	CLKDEV_CON_ID("dv_clk",			&dv_clk),
518 	CLKDEV_CON_ID("system_clk",		&system_clk),
519 	CLKDEV_CON_ID("system_div2_clk",	&system_div2_clk),
520 	CLKDEV_CON_ID("r_clk",			&r_clk),
521 	CLKDEV_CON_ID("pllc0_clk",		&pllc0_clk),
522 	CLKDEV_CON_ID("pllc1_clk",		&pllc1_clk),
523 	CLKDEV_CON_ID("pllc1_div2_clk",		&pllc1_div2_clk),
524 	CLKDEV_CON_ID("usb24s",			&usb24s_clk),
525 	CLKDEV_CON_ID("hdmi1",			&hdmi1_clk),
526 	CLKDEV_CON_ID("hdmi2",			&hdmi2_clk),
527 	CLKDEV_CON_ID("video1",			&div6_reparent_clks[DIV6_VCLK1]),
528 	CLKDEV_CON_ID("video2",			&div6_reparent_clks[DIV6_VCLK2]),
529 	CLKDEV_CON_ID("fsiack",			&fsiack_clk),
530 	CLKDEV_CON_ID("fsibck",			&fsibck_clk),
531 
532 	/* DIV4 clocks */
533 	CLKDEV_CON_ID("i_clk",			&div4_clks[DIV4_I]),
534 	CLKDEV_CON_ID("zg_clk",			&div4_clks[DIV4_ZG]),
535 	CLKDEV_CON_ID("b_clk",			&div4_clks[DIV4_B]),
536 	CLKDEV_CON_ID("m1_clk",			&div4_clks[DIV4_M1]),
537 	CLKDEV_CON_ID("hp_clk",			&div4_clks[DIV4_HP]),
538 	CLKDEV_CON_ID("hpp_clk",		&div4_clks[DIV4_HPP]),
539 	CLKDEV_CON_ID("s_clk",			&div4_clks[DIV4_S]),
540 	CLKDEV_CON_ID("zb_clk",			&div4_clks[DIV4_ZB]),
541 	CLKDEV_CON_ID("m3_clk",			&div4_clks[DIV4_M3]),
542 	CLKDEV_CON_ID("cp_clk",			&div4_clks[DIV4_CP]),
543 
544 	/* DIV6 clocks */
545 	CLKDEV_CON_ID("sub_clk",		&div6_clks[DIV6_SUB]),
546 
547 	/* MSTP32 clocks */
548 	CLKDEV_DEV_ID("sh_mobile_lcdc_fb.0",	&mstp_clks[MSTP100]),
549 	CLKDEV_DEV_ID("i2c-sh_mobile.0",	&mstp_clks[MSTP116]),
550 	CLKDEV_DEV_ID("fff20000.i2c",		&mstp_clks[MSTP116]),
551 	CLKDEV_DEV_ID("sh_mobile_lcdc_fb.1",	&mstp_clks[MSTP117]),
552 	CLKDEV_DEV_ID("sh_mobile_ceu.0",	&mstp_clks[MSTP127]),
553 	CLKDEV_DEV_ID("sh_mobile_ceu.1",	&mstp_clks[MSTP128]),
554 
555 	CLKDEV_DEV_ID("sh-sci.4",		&mstp_clks[MSTP200]),
556 	CLKDEV_DEV_ID("e6c80000.serial",	&mstp_clks[MSTP200]),
557 	CLKDEV_DEV_ID("sh-sci.3",		&mstp_clks[MSTP201]),
558 	CLKDEV_DEV_ID("e6c70000.serial",	&mstp_clks[MSTP201]),
559 	CLKDEV_DEV_ID("sh-sci.2",		&mstp_clks[MSTP202]),
560 	CLKDEV_DEV_ID("e6c60000.serial",	&mstp_clks[MSTP202]),
561 	CLKDEV_DEV_ID("sh-sci.1",		&mstp_clks[MSTP203]),
562 	CLKDEV_DEV_ID("e6c50000.serial",	&mstp_clks[MSTP203]),
563 	CLKDEV_DEV_ID("sh-sci.0",		&mstp_clks[MSTP204]),
564 	CLKDEV_DEV_ID("e6c40000.serial",	&mstp_clks[MSTP204]),
565 	CLKDEV_DEV_ID("sh-sci.8",		&mstp_clks[MSTP206]),
566 	CLKDEV_DEV_ID("e6c30000.serial",	&mstp_clks[MSTP206]),
567 	CLKDEV_DEV_ID("sh-sci.5",		&mstp_clks[MSTP207]),
568 	CLKDEV_DEV_ID("e6cb0000.serial",	&mstp_clks[MSTP207]),
569 	CLKDEV_DEV_ID("sh-dma-engine.3",	&mstp_clks[MSTP214]),
570 	CLKDEV_DEV_ID("sh-dma-engine.2",	&mstp_clks[MSTP216]),
571 	CLKDEV_DEV_ID("sh-dma-engine.1",	&mstp_clks[MSTP217]),
572 	CLKDEV_DEV_ID("sh-dma-engine.0",	&mstp_clks[MSTP218]),
573 	CLKDEV_DEV_ID("sh-sci.7",		&mstp_clks[MSTP222]),
574 	CLKDEV_DEV_ID("e6cd0000.serial",	&mstp_clks[MSTP222]),
575 	CLKDEV_DEV_ID("renesas_intc_irqpin.0",	&mstp_clks[MSTP229]),
576 	CLKDEV_DEV_ID("renesas_intc_irqpin.1",	&mstp_clks[MSTP229]),
577 	CLKDEV_DEV_ID("renesas_intc_irqpin.2",	&mstp_clks[MSTP229]),
578 	CLKDEV_DEV_ID("renesas_intc_irqpin.3",	&mstp_clks[MSTP229]),
579 	CLKDEV_DEV_ID("sh-sci.6",		&mstp_clks[MSTP230]),
580 	CLKDEV_DEV_ID("e6cc0000.serial",	&mstp_clks[MSTP230]),
581 
582 	CLKDEV_DEV_ID("sh_fsi2",		&mstp_clks[MSTP328]),
583 	CLKDEV_DEV_ID("fe1f0000.sound",		&mstp_clks[MSTP328]),
584 	CLKDEV_DEV_ID("i2c-sh_mobile.1",	&mstp_clks[MSTP323]),
585 	CLKDEV_DEV_ID("e6c20000.i2c",		&mstp_clks[MSTP323]),
586 	CLKDEV_DEV_ID("renesas_usbhs",		&mstp_clks[MSTP320]),
587 	CLKDEV_DEV_ID("sh_mobile_sdhi.0",	&mstp_clks[MSTP314]),
588 	CLKDEV_DEV_ID("e6850000.sd",		&mstp_clks[MSTP314]),
589 	CLKDEV_DEV_ID("sh_mobile_sdhi.1",	&mstp_clks[MSTP313]),
590 	CLKDEV_DEV_ID("e6860000.sd",		&mstp_clks[MSTP313]),
591 	CLKDEV_DEV_ID("sh_mmcif",		&mstp_clks[MSTP312]),
592 	CLKDEV_DEV_ID("e6bd0000.mmc",		&mstp_clks[MSTP312]),
593 	CLKDEV_DEV_ID("r8a7740-gether",		&mstp_clks[MSTP309]),
594 	CLKDEV_DEV_ID("e9a00000.ethernet",	&mstp_clks[MSTP309]),
595 	CLKDEV_DEV_ID("renesas-tpu-pwm",	&mstp_clks[MSTP304]),
596 	CLKDEV_DEV_ID("e6600000.pwm",		&mstp_clks[MSTP304]),
597 
598 	CLKDEV_DEV_ID("sh_mobile_sdhi.2",	&mstp_clks[MSTP415]),
599 	CLKDEV_DEV_ID("e6870000.sd",		&mstp_clks[MSTP415]),
600 
601 	/* ICK */
602 	CLKDEV_ICK_ID("fck",	"sh-tmu.1",		&mstp_clks[MSTP111]),
603 	CLKDEV_ICK_ID("fck",	"fff90000.timer",	&mstp_clks[MSTP111]),
604 	CLKDEV_ICK_ID("fck",	"sh-tmu.0",		&mstp_clks[MSTP125]),
605 	CLKDEV_ICK_ID("fck",	"fff80000.timer",	&mstp_clks[MSTP125]),
606 	CLKDEV_ICK_ID("fck",	"sh-cmt-48.1",		&mstp_clks[MSTP329]),
607 	CLKDEV_ICK_ID("fck",	"e6138000.timer",	&mstp_clks[MSTP329]),
608 	CLKDEV_ICK_ID("host",	"renesas_usbhs",	&mstp_clks[MSTP416]),
609 	CLKDEV_ICK_ID("func",	"renesas_usbhs",	&mstp_clks[MSTP407]),
610 	CLKDEV_ICK_ID("phy",	"renesas_usbhs",	&mstp_clks[MSTP406]),
611 	CLKDEV_ICK_ID("pci",	"renesas_usbhs",	&div4_clks[DIV4_USBP]),
612 	CLKDEV_ICK_ID("usb24",	"renesas_usbhs",	&usb24_clk),
613 	CLKDEV_ICK_ID("ick",	"sh-mobile-hdmi",	&div6_reparent_clks[DIV6_HDMI]),
614 
615 	CLKDEV_ICK_ID("icka", "sh_fsi2",	&div6_reparent_clks[DIV6_FSIA]),
616 	CLKDEV_ICK_ID("ickb", "sh_fsi2",	&div6_reparent_clks[DIV6_FSIB]),
617 	CLKDEV_ICK_ID("diva", "sh_fsi2",	&fsidivs[FSIDIV_A]),
618 	CLKDEV_ICK_ID("divb", "sh_fsi2",	&fsidivs[FSIDIV_B]),
619 	CLKDEV_ICK_ID("xcka", "sh_fsi2",	&fsiack_clk),
620 	CLKDEV_ICK_ID("xckb", "sh_fsi2",	&fsibck_clk),
621 };
622 
r8a7740_clock_init(u8 md_ck)623 void __init r8a7740_clock_init(u8 md_ck)
624 {
625 	int k, ret = 0;
626 
627 	/* detect system clock parent */
628 	if (md_ck & MD_CK1)
629 		system_clk.parent = &extal1_div2_clk;
630 	else
631 		system_clk.parent = &extal1_clk;
632 
633 	/* detect RCLK parent */
634 	switch (md_ck & (MD_CK2 | MD_CK1)) {
635 	case MD_CK2 | MD_CK1:
636 		r_clk.parent = &extal1_div2048_clk;
637 		break;
638 	case MD_CK2:
639 		r_clk.parent = &extal1_div1024_clk;
640 		break;
641 	case MD_CK1:
642 	default:
643 		r_clk.parent = &extalr_clk;
644 		break;
645 	}
646 
647 	for (k = 0; !ret && (k < ARRAY_SIZE(main_clks)); k++)
648 		ret = clk_register(main_clks[k]);
649 
650 	if (!ret)
651 		ret = sh_clk_div4_register(div4_clks, DIV4_NR, &div4_table);
652 
653 	if (!ret)
654 		ret = sh_clk_div6_register(div6_clks, DIV6_NR);
655 
656 	if (!ret)
657 		ret = sh_clk_div6_reparent_register(div6_reparent_clks,
658 						    DIV6_REPARENT_NR);
659 
660 	if (!ret)
661 		ret = sh_clk_mstp_register(mstp_clks, MSTP_NR);
662 
663 	for (k = 0; !ret && (k < ARRAY_SIZE(late_main_clks)); k++)
664 		ret = clk_register(late_main_clks[k]);
665 
666 	if (!ret)
667 		ret = sh_clk_fsidiv_register(fsidivs, FSIDIV_REPARENT_NR);
668 
669 	clkdev_add_table(lookups, ARRAY_SIZE(lookups));
670 
671 	if (!ret)
672 		shmobile_clk_init();
673 	else
674 		panic("failed to setup r8a7740 clocks\n");
675 }
676