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