1 /*
2  * SH7372 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 /* SH7372 registers */
27 #define FRQCRA		0xe6150000
28 #define FRQCRB		0xe6150004
29 #define FRQCRC		0xe61500e0
30 #define FRQCRD		0xe61500e4
31 #define VCLKCR1		0xe6150008
32 #define VCLKCR2		0xe615000c
33 #define VCLKCR3		0xe615001c
34 #define FMSICKCR	0xe6150010
35 #define FMSOCKCR	0xe6150014
36 #define FSIACKCR	0xe6150018
37 #define FSIBCKCR	0xe6150090
38 #define SUBCKCR		0xe6150080
39 #define SPUCKCR		0xe6150084
40 #define VOUCKCR		0xe6150088
41 #define HDMICKCR	0xe6150094
42 #define DSITCKCR	0xe6150060
43 #define DSI0PCKCR	0xe6150064
44 #define DSI1PCKCR	0xe6150098
45 #define PLLC01CR	0xe6150028
46 #define PLLC2CR		0xe615002c
47 #define RMSTPCR0	0xe6150110
48 #define RMSTPCR1	0xe6150114
49 #define RMSTPCR2	0xe6150118
50 #define RMSTPCR3	0xe615011c
51 #define RMSTPCR4	0xe6150120
52 #define SMSTPCR0	0xe6150130
53 #define SMSTPCR1	0xe6150134
54 #define SMSTPCR2	0xe6150138
55 #define SMSTPCR3	0xe615013c
56 #define SMSTPCR4	0xe6150140
57 
58 #define FSIDIVA		0xFE1F8000
59 #define FSIDIVB		0xFE1F8008
60 
61 /* Platforms must set frequency on their DV_CLKI pin */
62 struct clk sh7372_dv_clki_clk = {
63 };
64 
65 /* Fixed 32 KHz root clock from EXTALR pin */
66 static struct clk r_clk = {
67 	.rate           = 32768,
68 };
69 
70 /*
71  * 26MHz default rate for the EXTAL1 root input clock.
72  * If needed, reset this with clk_set_rate() from the platform code.
73  */
74 struct clk sh7372_extal1_clk = {
75 	.rate		= 26000000,
76 };
77 
78 /*
79  * 48MHz default rate for the EXTAL2 root input clock.
80  * If needed, reset this with clk_set_rate() from the platform code.
81  */
82 struct clk sh7372_extal2_clk = {
83 	.rate		= 48000000,
84 };
85 
86 /* A fixed divide-by-2 block */
div2_recalc(struct clk * clk)87 static unsigned long div2_recalc(struct clk *clk)
88 {
89 	return clk->parent->rate / 2;
90 }
91 
92 static struct clk_ops div2_clk_ops = {
93 	.recalc		= div2_recalc,
94 };
95 
96 /* Divide dv_clki by two */
97 struct clk sh7372_dv_clki_div2_clk = {
98 	.ops		= &div2_clk_ops,
99 	.parent		= &sh7372_dv_clki_clk,
100 };
101 
102 /* Divide extal1 by two */
103 static struct clk extal1_div2_clk = {
104 	.ops		= &div2_clk_ops,
105 	.parent		= &sh7372_extal1_clk,
106 };
107 
108 /* Divide extal2 by two */
109 static struct clk extal2_div2_clk = {
110 	.ops		= &div2_clk_ops,
111 	.parent		= &sh7372_extal2_clk,
112 };
113 
114 /* Divide extal2 by four */
115 static struct clk extal2_div4_clk = {
116 	.ops		= &div2_clk_ops,
117 	.parent		= &extal2_div2_clk,
118 };
119 
120 /* PLLC0 and PLLC1 */
pllc01_recalc(struct clk * clk)121 static unsigned long pllc01_recalc(struct clk *clk)
122 {
123 	unsigned long mult = 1;
124 
125 	if (__raw_readl(PLLC01CR) & (1 << 14))
126 		mult = (((__raw_readl(clk->enable_reg) >> 24) & 0x3f) + 1) * 2;
127 
128 	return clk->parent->rate * mult;
129 }
130 
131 static struct clk_ops pllc01_clk_ops = {
132 	.recalc		= pllc01_recalc,
133 };
134 
135 static struct clk pllc0_clk = {
136 	.ops		= &pllc01_clk_ops,
137 	.flags		= CLK_ENABLE_ON_INIT,
138 	.parent		= &extal1_div2_clk,
139 	.enable_reg	= (void __iomem *)FRQCRC,
140 };
141 
142 static struct clk pllc1_clk = {
143 	.ops		= &pllc01_clk_ops,
144 	.flags		= CLK_ENABLE_ON_INIT,
145 	.parent		= &extal1_div2_clk,
146 	.enable_reg	= (void __iomem *)FRQCRA,
147 };
148 
149 /* Divide PLLC1 by two */
150 static struct clk pllc1_div2_clk = {
151 	.ops		= &div2_clk_ops,
152 	.parent		= &pllc1_clk,
153 };
154 
155 /* PLLC2 */
156 
157 /* Indices are important - they are the actual src selecting values */
158 static struct clk *pllc2_parent[] = {
159 	[0] = &extal1_div2_clk,
160 	[1] = &extal2_div2_clk,
161 	[2] = &sh7372_dv_clki_div2_clk,
162 };
163 
164 /* Only multipliers 20 * 2 to 46 * 2 are valid, last entry for CPUFREQ_TABLE_END */
165 static struct cpufreq_frequency_table pllc2_freq_table[29];
166 
pllc2_table_rebuild(struct clk * clk)167 static void pllc2_table_rebuild(struct clk *clk)
168 {
169 	int i;
170 
171 	/* Initialise PLLC2 frequency table */
172 	for (i = 0; i < ARRAY_SIZE(pllc2_freq_table) - 2; i++) {
173 		pllc2_freq_table[i].frequency = clk->parent->rate * (i + 20) * 2;
174 		pllc2_freq_table[i].index = i;
175 	}
176 
177 	/* This is a special entry - switching PLL off makes it a repeater */
178 	pllc2_freq_table[i].frequency = clk->parent->rate;
179 	pllc2_freq_table[i].index = i;
180 
181 	pllc2_freq_table[++i].frequency = CPUFREQ_TABLE_END;
182 	pllc2_freq_table[i].index = i;
183 }
184 
pllc2_recalc(struct clk * clk)185 static unsigned long pllc2_recalc(struct clk *clk)
186 {
187 	unsigned long mult = 1;
188 
189 	pllc2_table_rebuild(clk);
190 
191 	/*
192 	 * If the PLL is off, mult == 1, clk->rate will be updated in
193 	 * pllc2_enable().
194 	 */
195 	if (__raw_readl(PLLC2CR) & (1 << 31))
196 		mult = (((__raw_readl(PLLC2CR) >> 24) & 0x3f) + 1) * 2;
197 
198 	return clk->parent->rate * mult;
199 }
200 
pllc2_round_rate(struct clk * clk,unsigned long rate)201 static long pllc2_round_rate(struct clk *clk, unsigned long rate)
202 {
203 	return clk_rate_table_round(clk, clk->freq_table, rate);
204 }
205 
pllc2_enable(struct clk * clk)206 static int pllc2_enable(struct clk *clk)
207 {
208 	int i;
209 
210 	__raw_writel(__raw_readl(PLLC2CR) | 0x80000000, PLLC2CR);
211 
212 	for (i = 0; i < 100; i++)
213 		if (__raw_readl(PLLC2CR) & 0x80000000) {
214 			clk->rate = pllc2_recalc(clk);
215 			return 0;
216 		}
217 
218 	pr_err("%s(): timeout!\n", __func__);
219 
220 	return -ETIMEDOUT;
221 }
222 
pllc2_disable(struct clk * clk)223 static void pllc2_disable(struct clk *clk)
224 {
225 	__raw_writel(__raw_readl(PLLC2CR) & ~0x80000000, PLLC2CR);
226 }
227 
pllc2_set_rate(struct clk * clk,unsigned long rate)228 static int pllc2_set_rate(struct clk *clk, unsigned long rate)
229 {
230 	unsigned long value;
231 	int idx;
232 
233 	idx = clk_rate_table_find(clk, clk->freq_table, rate);
234 	if (idx < 0)
235 		return idx;
236 
237 	if (rate == clk->parent->rate)
238 		return -EINVAL;
239 
240 	value = __raw_readl(PLLC2CR) & ~(0x3f << 24);
241 
242 	__raw_writel(value | ((idx + 19) << 24), PLLC2CR);
243 
244 	clk->rate = clk->freq_table[idx].frequency;
245 
246 	return 0;
247 }
248 
pllc2_set_parent(struct clk * clk,struct clk * parent)249 static int pllc2_set_parent(struct clk *clk, struct clk *parent)
250 {
251 	u32 value;
252 	int ret, i;
253 
254 	if (!clk->parent_table || !clk->parent_num)
255 		return -EINVAL;
256 
257 	/* Search the parent */
258 	for (i = 0; i < clk->parent_num; i++)
259 		if (clk->parent_table[i] == parent)
260 			break;
261 
262 	if (i == clk->parent_num)
263 		return -ENODEV;
264 
265 	ret = clk_reparent(clk, parent);
266 	if (ret < 0)
267 		return ret;
268 
269 	value = __raw_readl(PLLC2CR) & ~(3 << 6);
270 
271 	__raw_writel(value | (i << 6), PLLC2CR);
272 
273 	/* Rebiuld the frequency table */
274 	pllc2_table_rebuild(clk);
275 
276 	return 0;
277 }
278 
279 static struct clk_ops pllc2_clk_ops = {
280 	.recalc		= pllc2_recalc,
281 	.round_rate	= pllc2_round_rate,
282 	.set_rate	= pllc2_set_rate,
283 	.enable		= pllc2_enable,
284 	.disable	= pllc2_disable,
285 	.set_parent	= pllc2_set_parent,
286 };
287 
288 struct clk sh7372_pllc2_clk = {
289 	.ops		= &pllc2_clk_ops,
290 	.parent		= &extal1_div2_clk,
291 	.freq_table	= pllc2_freq_table,
292 	.nr_freqs	= ARRAY_SIZE(pllc2_freq_table) - 1,
293 	.parent_table	= pllc2_parent,
294 	.parent_num	= ARRAY_SIZE(pllc2_parent),
295 };
296 
297 /* External input clock (pin name: FSIACK/FSIBCK ) */
298 struct clk sh7372_fsiack_clk = {
299 };
300 
301 struct clk sh7372_fsibck_clk = {
302 };
303 
304 static struct clk *main_clks[] = {
305 	&sh7372_dv_clki_clk,
306 	&r_clk,
307 	&sh7372_extal1_clk,
308 	&sh7372_extal2_clk,
309 	&sh7372_dv_clki_div2_clk,
310 	&extal1_div2_clk,
311 	&extal2_div2_clk,
312 	&extal2_div4_clk,
313 	&pllc0_clk,
314 	&pllc1_clk,
315 	&pllc1_div2_clk,
316 	&sh7372_pllc2_clk,
317 	&sh7372_fsiack_clk,
318 	&sh7372_fsibck_clk,
319 };
320 
div4_kick(struct clk * clk)321 static void div4_kick(struct clk *clk)
322 {
323 	unsigned long value;
324 
325 	/* set KICK bit in FRQCRB to update hardware setting */
326 	value = __raw_readl(FRQCRB);
327 	value |= (1 << 31);
328 	__raw_writel(value, FRQCRB);
329 }
330 
331 static int divisors[] = { 2, 3, 4, 6, 8, 12, 16, 18,
332 			  24, 32, 36, 48, 0, 72, 96, 0 };
333 
334 static struct clk_div_mult_table div4_div_mult_table = {
335 	.divisors = divisors,
336 	.nr_divisors = ARRAY_SIZE(divisors),
337 };
338 
339 static struct clk_div4_table div4_table = {
340 	.div_mult_table = &div4_div_mult_table,
341 	.kick = div4_kick,
342 };
343 
344 enum { DIV4_I, DIV4_ZG, DIV4_B, DIV4_M1, DIV4_CSIR,
345        DIV4_ZTR, DIV4_ZT, DIV4_ZX, DIV4_HP,
346        DIV4_ISPB, DIV4_S, DIV4_ZB, DIV4_ZB3, DIV4_CP,
347        DIV4_DDRP, DIV4_NR };
348 
349 #define DIV4(_reg, _bit, _mask, _flags) \
350   SH_CLK_DIV4(&pllc1_clk, _reg, _bit, _mask, _flags)
351 
352 static struct clk div4_clks[DIV4_NR] = {
353 	[DIV4_I] = DIV4(FRQCRA, 20, 0x6fff, CLK_ENABLE_ON_INIT),
354 	[DIV4_ZG] = DIV4(FRQCRA, 16, 0x6fff, CLK_ENABLE_ON_INIT),
355 	[DIV4_B] = DIV4(FRQCRA, 8, 0x6fff, CLK_ENABLE_ON_INIT),
356 	[DIV4_M1] = DIV4(FRQCRA, 4, 0x6fff, CLK_ENABLE_ON_INIT),
357 	[DIV4_CSIR] = DIV4(FRQCRA, 0, 0x6fff, 0),
358 	[DIV4_ZTR] = DIV4(FRQCRB, 20, 0x6fff, 0),
359 	[DIV4_ZT] = DIV4(FRQCRB, 16, 0x6fff, 0),
360 	[DIV4_ZX] = DIV4(FRQCRB, 12, 0x6fff, 0),
361 	[DIV4_HP] = DIV4(FRQCRB, 4, 0x6fff, 0),
362 	[DIV4_ISPB] = DIV4(FRQCRC, 20, 0x6fff, 0),
363 	[DIV4_S] = DIV4(FRQCRC, 12, 0x6fff, 0),
364 	[DIV4_ZB] = DIV4(FRQCRC, 8, 0x6fff, 0),
365 	[DIV4_ZB3] = DIV4(FRQCRC, 4, 0x6fff, 0),
366 	[DIV4_CP] = DIV4(FRQCRC, 0, 0x6fff, 0),
367 	[DIV4_DDRP] = DIV4(FRQCRD, 0, 0x677c, 0),
368 };
369 
370 enum { DIV6_VCK1, DIV6_VCK2, DIV6_VCK3, DIV6_FMSI, DIV6_FMSO,
371        DIV6_SUB, DIV6_SPU,
372        DIV6_VOU, DIV6_DSIT, DIV6_DSI0P, DIV6_DSI1P,
373        DIV6_NR };
374 
375 static struct clk div6_clks[DIV6_NR] = {
376 	[DIV6_VCK1] = SH_CLK_DIV6(&pllc1_div2_clk, VCLKCR1, 0),
377 	[DIV6_VCK2] = SH_CLK_DIV6(&pllc1_div2_clk, VCLKCR2, 0),
378 	[DIV6_VCK3] = SH_CLK_DIV6(&pllc1_div2_clk, VCLKCR3, 0),
379 	[DIV6_FMSI] = SH_CLK_DIV6(&pllc1_div2_clk, FMSICKCR, 0),
380 	[DIV6_FMSO] = SH_CLK_DIV6(&pllc1_div2_clk, FMSOCKCR, 0),
381 	[DIV6_SUB] = SH_CLK_DIV6(&sh7372_extal2_clk, SUBCKCR, 0),
382 	[DIV6_SPU] = SH_CLK_DIV6(&pllc1_div2_clk, SPUCKCR, 0),
383 	[DIV6_VOU] = SH_CLK_DIV6(&pllc1_div2_clk, VOUCKCR, 0),
384 	[DIV6_DSIT] = SH_CLK_DIV6(&pllc1_div2_clk, DSITCKCR, 0),
385 	[DIV6_DSI0P] = SH_CLK_DIV6(&pllc1_div2_clk, DSI0PCKCR, 0),
386 	[DIV6_DSI1P] = SH_CLK_DIV6(&pllc1_div2_clk, DSI1PCKCR, 0),
387 };
388 
389 enum { DIV6_HDMI, DIV6_FSIA, DIV6_FSIB, DIV6_REPARENT_NR };
390 
391 /* Indices are important - they are the actual src selecting values */
392 static struct clk *hdmi_parent[] = {
393 	[0] = &pllc1_div2_clk,
394 	[1] = &sh7372_pllc2_clk,
395 	[2] = &sh7372_dv_clki_clk,
396 	[3] = NULL,	/* pllc2_div4 not implemented yet */
397 };
398 
399 static struct clk *fsiackcr_parent[] = {
400 	[0] = &pllc1_div2_clk,
401 	[1] = &sh7372_pllc2_clk,
402 	[2] = &sh7372_fsiack_clk, /* external input for FSI A */
403 	[3] = NULL,	/* setting prohibited */
404 };
405 
406 static struct clk *fsibckcr_parent[] = {
407 	[0] = &pllc1_div2_clk,
408 	[1] = &sh7372_pllc2_clk,
409 	[2] = &sh7372_fsibck_clk, /* external input for FSI B */
410 	[3] = NULL,	/* setting prohibited */
411 };
412 
413 static struct clk div6_reparent_clks[DIV6_REPARENT_NR] = {
414 	[DIV6_HDMI] = SH_CLK_DIV6_EXT(HDMICKCR, 0,
415 				      hdmi_parent, ARRAY_SIZE(hdmi_parent), 6, 2),
416 	[DIV6_FSIA] = SH_CLK_DIV6_EXT(FSIACKCR, 0,
417 				      fsiackcr_parent, ARRAY_SIZE(fsiackcr_parent), 6, 2),
418 	[DIV6_FSIB] = SH_CLK_DIV6_EXT(FSIBCKCR, 0,
419 				      fsibckcr_parent, ARRAY_SIZE(fsibckcr_parent), 6, 2),
420 };
421 
422 /* FSI DIV */
fsidiv_recalc(struct clk * clk)423 static unsigned long fsidiv_recalc(struct clk *clk)
424 {
425 	unsigned long value;
426 
427 	value = __raw_readl(clk->mapping->base);
428 
429 	value >>= 16;
430 	if (value < 2)
431 		return 0;
432 
433 	return clk->parent->rate / value;
434 }
435 
fsidiv_round_rate(struct clk * clk,unsigned long rate)436 static long fsidiv_round_rate(struct clk *clk, unsigned long rate)
437 {
438 	return clk_rate_div_range_round(clk, 2, 0xffff, rate);
439 }
440 
fsidiv_disable(struct clk * clk)441 static void fsidiv_disable(struct clk *clk)
442 {
443 	__raw_writel(0, clk->mapping->base);
444 }
445 
fsidiv_enable(struct clk * clk)446 static int fsidiv_enable(struct clk *clk)
447 {
448 	unsigned long value;
449 
450 	value  = __raw_readl(clk->mapping->base) >> 16;
451 	if (value < 2)
452 		return -EIO;
453 
454 	__raw_writel((value << 16) | 0x3, clk->mapping->base);
455 
456 	return 0;
457 }
458 
fsidiv_set_rate(struct clk * clk,unsigned long rate)459 static int fsidiv_set_rate(struct clk *clk, unsigned long rate)
460 {
461 	int idx;
462 
463 	idx = (clk->parent->rate / rate) & 0xffff;
464 	if (idx < 2)
465 		return -EINVAL;
466 
467 	__raw_writel(idx << 16, clk->mapping->base);
468 	return 0;
469 }
470 
471 static struct clk_ops fsidiv_clk_ops = {
472 	.recalc		= fsidiv_recalc,
473 	.round_rate	= fsidiv_round_rate,
474 	.set_rate	= fsidiv_set_rate,
475 	.enable		= fsidiv_enable,
476 	.disable	= fsidiv_disable,
477 };
478 
479 static struct clk_mapping fsidiva_clk_mapping = {
480 	.phys	= FSIDIVA,
481 	.len	= 8,
482 };
483 
484 struct clk sh7372_fsidiva_clk = {
485 	.ops		= &fsidiv_clk_ops,
486 	.parent		= &div6_reparent_clks[DIV6_FSIA], /* late install */
487 	.mapping	= &fsidiva_clk_mapping,
488 };
489 
490 static struct clk_mapping fsidivb_clk_mapping = {
491 	.phys	= FSIDIVB,
492 	.len	= 8,
493 };
494 
495 struct clk sh7372_fsidivb_clk = {
496 	.ops		= &fsidiv_clk_ops,
497 	.parent		= &div6_reparent_clks[DIV6_FSIB],  /* late install */
498 	.mapping	= &fsidivb_clk_mapping,
499 };
500 
501 static struct clk *late_main_clks[] = {
502 	&sh7372_fsidiva_clk,
503 	&sh7372_fsidivb_clk,
504 };
505 
506 enum { MSTP001, MSTP000,
507        MSTP131, MSTP130,
508        MSTP129, MSTP128, MSTP127, MSTP126, MSTP125,
509        MSTP118, MSTP117, MSTP116, MSTP113,
510        MSTP106, MSTP101, MSTP100,
511        MSTP223,
512        MSTP218, MSTP217, MSTP216, MSTP214, MSTP208, MSTP207,
513        MSTP206, MSTP205, MSTP204, MSTP203, MSTP202, MSTP201, MSTP200,
514        MSTP328, MSTP323, MSTP322, MSTP314, MSTP313, MSTP312,
515        MSTP423, MSTP415, MSTP413, MSTP411, MSTP410, MSTP407, MSTP406,
516        MSTP405, MSTP404, MSTP403, MSTP400,
517        MSTP_NR };
518 
519 #define MSTP(_parent, _reg, _bit, _flags) \
520   SH_CLK_MSTP32(_parent, _reg, _bit, _flags)
521 
522 static struct clk mstp_clks[MSTP_NR] = {
523 	[MSTP001] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR0, 1, 0), /* IIC2 */
524 	[MSTP000] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR0, 0, 0), /* MSIOF0 */
525 	[MSTP131] = MSTP(&div4_clks[DIV4_B], SMSTPCR1, 31, 0), /* VEU3 */
526 	[MSTP130] = MSTP(&div4_clks[DIV4_B], SMSTPCR1, 30, 0), /* VEU2 */
527 	[MSTP129] = MSTP(&div4_clks[DIV4_B], SMSTPCR1, 29, 0), /* VEU1 */
528 	[MSTP128] = MSTP(&div4_clks[DIV4_B], SMSTPCR1, 28, 0), /* VEU0 */
529 	[MSTP127] = MSTP(&div4_clks[DIV4_B], SMSTPCR1, 27, 0), /* CEU */
530 	[MSTP126] = MSTP(&div4_clks[DIV4_B], SMSTPCR1, 26, 0), /* CSI2 */
531 	[MSTP125] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR1, 25, 0), /* TMU0 */
532 	[MSTP118] = MSTP(&div4_clks[DIV4_B], SMSTPCR1, 18, 0), /* DSITX */
533 	[MSTP117] = MSTP(&div4_clks[DIV4_B], SMSTPCR1, 17, 0), /* LCDC1 */
534 	[MSTP116] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR1, 16, 0), /* IIC0 */
535 	[MSTP113] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR1, 13, 0), /* MERAM */
536 	[MSTP106] = MSTP(&div4_clks[DIV4_B], SMSTPCR1, 6, 0), /* JPU */
537 	[MSTP101] = MSTP(&div4_clks[DIV4_M1], SMSTPCR1, 1, 0), /* VPU */
538 	[MSTP100] = MSTP(&div4_clks[DIV4_B], SMSTPCR1, 0, 0), /* LCDC0 */
539 	[MSTP223] = MSTP(&div6_clks[DIV6_SPU], SMSTPCR2, 23, 0), /* SPU2 */
540 	[MSTP218] = MSTP(&div4_clks[DIV4_HP], SMSTPCR2, 18, 0), /* DMAC1 */
541 	[MSTP217] = MSTP(&div4_clks[DIV4_HP], SMSTPCR2, 17, 0), /* DMAC2 */
542 	[MSTP216] = MSTP(&div4_clks[DIV4_HP], SMSTPCR2, 16, 0), /* DMAC3 */
543 	[MSTP214] = MSTP(&div4_clks[DIV4_HP], SMSTPCR2, 14, 0), /* USBDMAC */
544 	[MSTP208] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR2, 8, 0), /* MSIOF1 */
545 	[MSTP207] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR2, 7, 0), /* SCIFA5 */
546 	[MSTP206] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR2, 6, 0), /* SCIFB */
547 	[MSTP205] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR2, 5, 0), /* MSIOF2 */
548 	[MSTP204] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR2, 4, 0), /* SCIFA0 */
549 	[MSTP203] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR2, 3, 0), /* SCIFA1 */
550 	[MSTP202] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR2, 2, 0), /* SCIFA2 */
551 	[MSTP201] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR2, 1, 0), /* SCIFA3 */
552 	[MSTP200] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR2, 0, 0), /* SCIFA4 */
553 	[MSTP328] = MSTP(&div6_clks[DIV6_SPU], SMSTPCR3, 28, 0), /* FSI2 */
554 	[MSTP323] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR3, 23, 0), /* IIC1 */
555 	[MSTP322] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR3, 22, 0), /* USB0 */
556 	[MSTP314] = MSTP(&div4_clks[DIV4_HP], SMSTPCR3, 14, 0), /* SDHI0 */
557 	[MSTP313] = MSTP(&div4_clks[DIV4_HP], SMSTPCR3, 13, 0), /* SDHI1 */
558 	[MSTP312] = MSTP(&div4_clks[DIV4_HP], SMSTPCR3, 12, 0), /* MMC */
559 	[MSTP423] = MSTP(&div4_clks[DIV4_B], SMSTPCR4, 23, 0), /* DSITX1 */
560 	[MSTP415] = MSTP(&div4_clks[DIV4_HP], SMSTPCR4, 15, 0), /* SDHI2 */
561 	[MSTP413] = MSTP(&pllc1_div2_clk, SMSTPCR4, 13, 0), /* HDMI */
562 	[MSTP411] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR4, 11, 0), /* IIC3 */
563 	[MSTP410] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR4, 10, 0), /* IIC4 */
564 	[MSTP407] = MSTP(&div4_clks[DIV4_HP], SMSTPCR4, 7, 0), /* USB-DMAC1 */
565 	[MSTP406] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR4, 6, 0), /* USB1 */
566 	[MSTP405] = MSTP(&r_clk, SMSTPCR4, 5, 0), /* CMT4 */
567 	[MSTP404] = MSTP(&r_clk, SMSTPCR4, 4, 0), /* CMT3 */
568 	[MSTP403] = MSTP(&r_clk, SMSTPCR4, 3, 0), /* KEYSC */
569 	[MSTP400] = MSTP(&r_clk, SMSTPCR4, 0, 0), /* CMT2 */
570 };
571 
572 static struct clk_lookup lookups[] = {
573 	/* main clocks */
574 	CLKDEV_CON_ID("dv_clki_div2_clk", &sh7372_dv_clki_div2_clk),
575 	CLKDEV_CON_ID("r_clk", &r_clk),
576 	CLKDEV_CON_ID("extal1", &sh7372_extal1_clk),
577 	CLKDEV_CON_ID("extal2", &sh7372_extal2_clk),
578 	CLKDEV_CON_ID("extal1_div2_clk", &extal1_div2_clk),
579 	CLKDEV_CON_ID("extal2_div2_clk", &extal2_div2_clk),
580 	CLKDEV_CON_ID("extal2_div4_clk", &extal2_div4_clk),
581 	CLKDEV_CON_ID("pllc0_clk", &pllc0_clk),
582 	CLKDEV_CON_ID("pllc1_clk", &pllc1_clk),
583 	CLKDEV_CON_ID("pllc1_div2_clk", &pllc1_div2_clk),
584 	CLKDEV_CON_ID("pllc2_clk", &sh7372_pllc2_clk),
585 
586 	/* DIV4 clocks */
587 	CLKDEV_CON_ID("i_clk", &div4_clks[DIV4_I]),
588 	CLKDEV_CON_ID("zg_clk", &div4_clks[DIV4_ZG]),
589 	CLKDEV_CON_ID("b_clk", &div4_clks[DIV4_B]),
590 	CLKDEV_CON_ID("m1_clk", &div4_clks[DIV4_M1]),
591 	CLKDEV_CON_ID("csir_clk", &div4_clks[DIV4_CSIR]),
592 	CLKDEV_CON_ID("ztr_clk", &div4_clks[DIV4_ZTR]),
593 	CLKDEV_CON_ID("zt_clk", &div4_clks[DIV4_ZT]),
594 	CLKDEV_CON_ID("zx_clk", &div4_clks[DIV4_ZX]),
595 	CLKDEV_CON_ID("hp_clk", &div4_clks[DIV4_HP]),
596 	CLKDEV_CON_ID("ispb_clk", &div4_clks[DIV4_ISPB]),
597 	CLKDEV_CON_ID("s_clk", &div4_clks[DIV4_S]),
598 	CLKDEV_CON_ID("zb_clk", &div4_clks[DIV4_ZB]),
599 	CLKDEV_CON_ID("zb3_clk", &div4_clks[DIV4_ZB3]),
600 	CLKDEV_CON_ID("cp_clk", &div4_clks[DIV4_CP]),
601 	CLKDEV_CON_ID("ddrp_clk", &div4_clks[DIV4_DDRP]),
602 
603 	/* DIV6 clocks */
604 	CLKDEV_CON_ID("vck1_clk", &div6_clks[DIV6_VCK1]),
605 	CLKDEV_CON_ID("vck2_clk", &div6_clks[DIV6_VCK2]),
606 	CLKDEV_CON_ID("vck3_clk", &div6_clks[DIV6_VCK3]),
607 	CLKDEV_CON_ID("fmsi_clk", &div6_clks[DIV6_FMSI]),
608 	CLKDEV_CON_ID("fmso_clk", &div6_clks[DIV6_FMSO]),
609 	CLKDEV_CON_ID("sub_clk", &div6_clks[DIV6_SUB]),
610 	CLKDEV_CON_ID("spu_clk", &div6_clks[DIV6_SPU]),
611 	CLKDEV_CON_ID("vou_clk", &div6_clks[DIV6_VOU]),
612 	CLKDEV_CON_ID("hdmi_clk", &div6_reparent_clks[DIV6_HDMI]),
613 	CLKDEV_ICK_ID("dsit_clk", "sh-mipi-dsi.0", &div6_clks[DIV6_DSIT]),
614 	CLKDEV_ICK_ID("dsit_clk", "sh-mipi-dsi.1", &div6_clks[DIV6_DSIT]),
615 	CLKDEV_ICK_ID("dsip_clk", "sh-mipi-dsi.0", &div6_clks[DIV6_DSI0P]),
616 	CLKDEV_ICK_ID("dsip_clk", "sh-mipi-dsi.1", &div6_clks[DIV6_DSI1P]),
617 
618 	/* MSTP32 clocks */
619 	CLKDEV_DEV_ID("i2c-sh_mobile.2", &mstp_clks[MSTP001]), /* IIC2 */
620 	CLKDEV_DEV_ID("spi_sh_msiof.0", &mstp_clks[MSTP000]), /* MSIOF0 */
621 	CLKDEV_DEV_ID("uio_pdrv_genirq.4", &mstp_clks[MSTP131]), /* VEU3 */
622 	CLKDEV_DEV_ID("uio_pdrv_genirq.3", &mstp_clks[MSTP130]), /* VEU2 */
623 	CLKDEV_DEV_ID("uio_pdrv_genirq.2", &mstp_clks[MSTP129]), /* VEU1 */
624 	CLKDEV_DEV_ID("uio_pdrv_genirq.1", &mstp_clks[MSTP128]), /* VEU0 */
625 	CLKDEV_DEV_ID("sh_mobile_ceu.0", &mstp_clks[MSTP127]), /* CEU */
626 	CLKDEV_DEV_ID("sh-mobile-csi2.0", &mstp_clks[MSTP126]), /* CSI2 */
627 	CLKDEV_DEV_ID("sh_tmu.0", &mstp_clks[MSTP125]), /* TMU00 */
628 	CLKDEV_DEV_ID("sh_tmu.1", &mstp_clks[MSTP125]), /* TMU01 */
629 	CLKDEV_DEV_ID("sh-mipi-dsi.0", &mstp_clks[MSTP118]), /* DSITX0 */
630 	CLKDEV_DEV_ID("sh_mobile_lcdc_fb.1", &mstp_clks[MSTP117]), /* LCDC1 */
631 	CLKDEV_DEV_ID("i2c-sh_mobile.0", &mstp_clks[MSTP116]), /* IIC0 */
632 	CLKDEV_DEV_ID("sh_mobile_meram.0", &mstp_clks[MSTP113]), /* MERAM */
633 	CLKDEV_DEV_ID("uio_pdrv_genirq.5", &mstp_clks[MSTP106]), /* JPU */
634 	CLKDEV_DEV_ID("uio_pdrv_genirq.0", &mstp_clks[MSTP101]), /* VPU */
635 	CLKDEV_DEV_ID("sh_mobile_lcdc_fb.0", &mstp_clks[MSTP100]), /* LCDC0 */
636 	CLKDEV_DEV_ID("uio_pdrv_genirq.6", &mstp_clks[MSTP223]), /* SPU2DSP0 */
637 	CLKDEV_DEV_ID("uio_pdrv_genirq.7", &mstp_clks[MSTP223]), /* SPU2DSP1 */
638 	CLKDEV_DEV_ID("sh-dma-engine.0", &mstp_clks[MSTP218]), /* DMAC1 */
639 	CLKDEV_DEV_ID("sh-dma-engine.1", &mstp_clks[MSTP217]), /* DMAC2 */
640 	CLKDEV_DEV_ID("sh-dma-engine.2", &mstp_clks[MSTP216]), /* DMAC3 */
641 	CLKDEV_DEV_ID("sh-dma-engine.3", &mstp_clks[MSTP214]), /* USB-DMAC0 */
642 	CLKDEV_DEV_ID("spi_sh_msiof.1", &mstp_clks[MSTP208]), /* MSIOF1 */
643 	CLKDEV_DEV_ID("sh-sci.5", &mstp_clks[MSTP207]), /* SCIFA5 */
644 	CLKDEV_DEV_ID("sh-sci.6", &mstp_clks[MSTP206]), /* SCIFB */
645 	CLKDEV_DEV_ID("spi_sh_msiof.2", &mstp_clks[MSTP205]), /* MSIOF2 */
646 	CLKDEV_DEV_ID("sh-sci.0", &mstp_clks[MSTP204]), /* SCIFA0 */
647 	CLKDEV_DEV_ID("sh-sci.1", &mstp_clks[MSTP203]), /* SCIFA1 */
648 	CLKDEV_DEV_ID("sh-sci.2", &mstp_clks[MSTP202]), /* SCIFA2 */
649 	CLKDEV_DEV_ID("sh-sci.3", &mstp_clks[MSTP201]), /* SCIFA3 */
650 	CLKDEV_DEV_ID("sh-sci.4", &mstp_clks[MSTP200]), /* SCIFA4 */
651 	CLKDEV_DEV_ID("sh_fsi2", &mstp_clks[MSTP328]), /* FSI2 */
652 	CLKDEV_DEV_ID("i2c-sh_mobile.1", &mstp_clks[MSTP323]), /* IIC1 */
653 	CLKDEV_DEV_ID("r8a66597_hcd.0", &mstp_clks[MSTP322]), /* USB0 */
654 	CLKDEV_DEV_ID("r8a66597_udc.0", &mstp_clks[MSTP322]), /* USB0 */
655 	CLKDEV_DEV_ID("renesas_usbhs.0", &mstp_clks[MSTP322]), /* USB0 */
656 	CLKDEV_DEV_ID("sh_mobile_sdhi.0", &mstp_clks[MSTP314]), /* SDHI0 */
657 	CLKDEV_DEV_ID("sh_mobile_sdhi.1", &mstp_clks[MSTP313]), /* SDHI1 */
658 	CLKDEV_DEV_ID("sh_mmcif.0", &mstp_clks[MSTP312]), /* MMC */
659 	CLKDEV_DEV_ID("sh-mipi-dsi.1", &mstp_clks[MSTP423]), /* DSITX1 */
660 	CLKDEV_DEV_ID("sh_mobile_sdhi.2", &mstp_clks[MSTP415]), /* SDHI2 */
661 	CLKDEV_DEV_ID("sh-mobile-hdmi", &mstp_clks[MSTP413]), /* HDMI */
662 	CLKDEV_DEV_ID("i2c-sh_mobile.3", &mstp_clks[MSTP411]), /* IIC3 */
663 	CLKDEV_DEV_ID("i2c-sh_mobile.4", &mstp_clks[MSTP410]), /* IIC4 */
664 	CLKDEV_DEV_ID("sh-dma-engine.4", &mstp_clks[MSTP407]), /* USB-DMAC1 */
665 	CLKDEV_DEV_ID("r8a66597_hcd.1", &mstp_clks[MSTP406]), /* USB1 */
666 	CLKDEV_DEV_ID("r8a66597_udc.1", &mstp_clks[MSTP406]), /* USB1 */
667 	CLKDEV_DEV_ID("renesas_usbhs.1", &mstp_clks[MSTP406]), /* USB1 */
668 	CLKDEV_DEV_ID("sh_cmt.4", &mstp_clks[MSTP405]), /* CMT4 */
669 	CLKDEV_DEV_ID("sh_cmt.3", &mstp_clks[MSTP404]), /* CMT3 */
670 	CLKDEV_DEV_ID("sh_keysc.0", &mstp_clks[MSTP403]), /* KEYSC */
671 	CLKDEV_DEV_ID("sh_cmt.2", &mstp_clks[MSTP400]), /* CMT2 */
672 
673 	CLKDEV_ICK_ID("hdmi", "sh_mobile_lcdc_fb.1",
674 		      &div6_reparent_clks[DIV6_HDMI]),
675 	CLKDEV_ICK_ID("ick", "sh-mobile-hdmi", &div6_reparent_clks[DIV6_HDMI]),
676 	CLKDEV_ICK_ID("icka", "sh_fsi2", &div6_reparent_clks[DIV6_FSIA]),
677 	CLKDEV_ICK_ID("ickb", "sh_fsi2", &div6_reparent_clks[DIV6_FSIB]),
678 	CLKDEV_ICK_ID("spu2", "sh_fsi2", &mstp_clks[MSTP223]),
679 };
680 
sh7372_clock_init(void)681 void __init sh7372_clock_init(void)
682 {
683 	int k, ret = 0;
684 
685 	/* make sure MSTP bits on the RT/SH4AL-DSP side are off */
686 	__raw_writel(0xe4ef8087, RMSTPCR0);
687 	__raw_writel(0xffffffff, RMSTPCR1);
688 	__raw_writel(0x37c7f7ff, RMSTPCR2);
689 	__raw_writel(0xffffffff, RMSTPCR3);
690 	__raw_writel(0xffe0fffd, RMSTPCR4);
691 
692 	for (k = 0; !ret && (k < ARRAY_SIZE(main_clks)); k++)
693 		ret = clk_register(main_clks[k]);
694 
695 	if (!ret)
696 		ret = sh_clk_div4_register(div4_clks, DIV4_NR, &div4_table);
697 
698 	if (!ret)
699 		ret = sh_clk_div6_register(div6_clks, DIV6_NR);
700 
701 	if (!ret)
702 		ret = sh_clk_div6_reparent_register(div6_reparent_clks, DIV6_REPARENT_NR);
703 
704 	if (!ret)
705 		ret = sh_clk_mstp32_register(mstp_clks, MSTP_NR);
706 
707 	for (k = 0; !ret && (k < ARRAY_SIZE(late_main_clks)); k++)
708 		ret = clk_register(late_main_clks[k]);
709 
710 	clkdev_add_table(lookups, ARRAY_SIZE(lookups));
711 
712 	if (!ret)
713 		clk_init();
714 	else
715 		panic("failed to setup sh7372 clocks\n");
716 
717 }
718