• Home
  • History
  • Annotate
  • Line#
  • Navigate
  • Raw
  • Download
  • only in /asuswrt-rt-n18u-9.0.0.4.380.2695/release/src-rt-6.x.4708/linux/linux-2.6/arch/arm/mach-shmobile/
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 <mach/common.h>
24#include <asm/clkdev.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 SMSTPCR0	0xe6150130
48#define SMSTPCR1	0xe6150134
49#define SMSTPCR2	0xe6150138
50#define SMSTPCR3	0xe615013c
51#define SMSTPCR4	0xe6150140
52
53/* Platforms must set frequency on their DV_CLKI pin */
54struct clk dv_clki_clk = {
55};
56
57/* Fixed 32 KHz root clock from EXTALR pin */
58static struct clk r_clk = {
59	.rate           = 32768,
60};
61
62/*
63 * 26MHz default rate for the EXTAL1 root input clock.
64 * If needed, reset this with clk_set_rate() from the platform code.
65 */
66struct clk sh7372_extal1_clk = {
67	.rate		= 26000000,
68};
69
70/*
71 * 48MHz default rate for the EXTAL2 root input clock.
72 * If needed, reset this with clk_set_rate() from the platform code.
73 */
74struct clk sh7372_extal2_clk = {
75	.rate		= 48000000,
76};
77
78/* A fixed divide-by-2 block */
79static unsigned long div2_recalc(struct clk *clk)
80{
81	return clk->parent->rate / 2;
82}
83
84static struct clk_ops div2_clk_ops = {
85	.recalc		= div2_recalc,
86};
87
88/* Divide dv_clki by two */
89struct clk dv_clki_div2_clk = {
90	.ops		= &div2_clk_ops,
91	.parent		= &dv_clki_clk,
92};
93
94/* Divide extal1 by two */
95static struct clk extal1_div2_clk = {
96	.ops		= &div2_clk_ops,
97	.parent		= &sh7372_extal1_clk,
98};
99
100/* Divide extal2 by two */
101static struct clk extal2_div2_clk = {
102	.ops		= &div2_clk_ops,
103	.parent		= &sh7372_extal2_clk,
104};
105
106/* Divide extal2 by four */
107static struct clk extal2_div4_clk = {
108	.ops		= &div2_clk_ops,
109	.parent		= &extal2_div2_clk,
110};
111
112/* PLLC0 and PLLC1 */
113static unsigned long pllc01_recalc(struct clk *clk)
114{
115	unsigned long mult = 1;
116
117	if (__raw_readl(PLLC01CR) & (1 << 14))
118		mult = (((__raw_readl(clk->enable_reg) >> 24) & 0x3f) + 1) * 2;
119
120	return clk->parent->rate * mult;
121}
122
123static struct clk_ops pllc01_clk_ops = {
124	.recalc		= pllc01_recalc,
125};
126
127static struct clk pllc0_clk = {
128	.ops		= &pllc01_clk_ops,
129	.flags		= CLK_ENABLE_ON_INIT,
130	.parent		= &extal1_div2_clk,
131	.enable_reg	= (void __iomem *)FRQCRC,
132};
133
134static struct clk pllc1_clk = {
135	.ops		= &pllc01_clk_ops,
136	.flags		= CLK_ENABLE_ON_INIT,
137	.parent		= &extal1_div2_clk,
138	.enable_reg	= (void __iomem *)FRQCRA,
139};
140
141/* Divide PLLC1 by two */
142static struct clk pllc1_div2_clk = {
143	.ops		= &div2_clk_ops,
144	.parent		= &pllc1_clk,
145};
146
147/* PLLC2 */
148
149/* Indices are important - they are the actual src selecting values */
150static struct clk *pllc2_parent[] = {
151	[0] = &extal1_div2_clk,
152	[1] = &extal2_div2_clk,
153	[2] = &dv_clki_div2_clk,
154};
155
156/* Only multipliers 20 * 2 to 46 * 2 are valid, last entry for CPUFREQ_TABLE_END */
157static struct cpufreq_frequency_table pllc2_freq_table[29];
158
159static void pllc2_table_rebuild(struct clk *clk)
160{
161	int i;
162
163	/* Initialise PLLC2 frequency table */
164	for (i = 0; i < ARRAY_SIZE(pllc2_freq_table) - 2; i++) {
165		pllc2_freq_table[i].frequency = clk->parent->rate * (i + 20) * 2;
166		pllc2_freq_table[i].index = i;
167	}
168
169	/* This is a special entry - switching PLL off makes it a repeater */
170	pllc2_freq_table[i].frequency = clk->parent->rate;
171	pllc2_freq_table[i].index = i;
172
173	pllc2_freq_table[++i].frequency = CPUFREQ_TABLE_END;
174	pllc2_freq_table[i].index = i;
175}
176
177static unsigned long pllc2_recalc(struct clk *clk)
178{
179	unsigned long mult = 1;
180
181	pllc2_table_rebuild(clk);
182
183	/*
184	 * If the PLL is off, mult == 1, clk->rate will be updated in
185	 * pllc2_enable().
186	 */
187	if (__raw_readl(PLLC2CR) & (1 << 31))
188		mult = (((__raw_readl(PLLC2CR) >> 24) & 0x3f) + 1) * 2;
189
190	return clk->parent->rate * mult;
191}
192
193static long pllc2_round_rate(struct clk *clk, unsigned long rate)
194{
195	return clk_rate_table_round(clk, clk->freq_table, rate);
196}
197
198static int pllc2_enable(struct clk *clk)
199{
200	int i;
201
202	__raw_writel(__raw_readl(PLLC2CR) | 0x80000000, PLLC2CR);
203
204	for (i = 0; i < 100; i++)
205		if (__raw_readl(PLLC2CR) & 0x80000000) {
206			clk->rate = pllc2_recalc(clk);
207			return 0;
208		}
209
210	pr_err("%s(): timeout!\n", __func__);
211
212	return -ETIMEDOUT;
213}
214
215static void pllc2_disable(struct clk *clk)
216{
217	__raw_writel(__raw_readl(PLLC2CR) & ~0x80000000, PLLC2CR);
218}
219
220static int pllc2_set_rate(struct clk *clk,
221			  unsigned long rate, int algo_id)
222{
223	unsigned long value;
224	int idx;
225
226	idx = clk_rate_table_find(clk, clk->freq_table, rate);
227	if (idx < 0)
228		return idx;
229
230	if (rate == clk->parent->rate) {
231		pllc2_disable(clk);
232		return 0;
233	}
234
235	value = __raw_readl(PLLC2CR) & ~(0x3f << 24);
236
237	if (value & 0x80000000)
238		pllc2_disable(clk);
239
240	__raw_writel((value & ~0x80000000) | ((idx + 19) << 24), PLLC2CR);
241
242	if (value & 0x80000000)
243		return pllc2_enable(clk);
244
245	return 0;
246}
247
248static int pllc2_set_parent(struct clk *clk, struct clk *parent)
249{
250	u32 value;
251	int ret, i;
252
253	if (!clk->parent_table || !clk->parent_num)
254		return -EINVAL;
255
256	/* Search the parent */
257	for (i = 0; i < clk->parent_num; i++)
258		if (clk->parent_table[i] == parent)
259			break;
260
261	if (i == clk->parent_num)
262		return -ENODEV;
263
264	ret = clk_reparent(clk, parent);
265	if (ret < 0)
266		return ret;
267
268	value = __raw_readl(PLLC2CR) & ~(3 << 6);
269
270	__raw_writel(value | (i << 6), PLLC2CR);
271
272	/* Rebiuld the frequency table */
273	pllc2_table_rebuild(clk);
274
275	return 0;
276}
277
278static struct clk_ops pllc2_clk_ops = {
279	.recalc		= pllc2_recalc,
280	.round_rate	= pllc2_round_rate,
281	.set_rate	= pllc2_set_rate,
282	.enable		= pllc2_enable,
283	.disable	= pllc2_disable,
284	.set_parent	= pllc2_set_parent,
285};
286
287struct clk pllc2_clk = {
288	.ops		= &pllc2_clk_ops,
289	.parent		= &extal1_div2_clk,
290	.freq_table	= pllc2_freq_table,
291	.parent_table	= pllc2_parent,
292	.parent_num	= ARRAY_SIZE(pllc2_parent),
293};
294
295static struct clk *main_clks[] = {
296	&dv_clki_clk,
297	&r_clk,
298	&sh7372_extal1_clk,
299	&sh7372_extal2_clk,
300	&dv_clki_div2_clk,
301	&extal1_div2_clk,
302	&extal2_div2_clk,
303	&extal2_div4_clk,
304	&pllc0_clk,
305	&pllc1_clk,
306	&pllc1_div2_clk,
307	&pllc2_clk,
308};
309
310static void div4_kick(struct clk *clk)
311{
312	unsigned long value;
313
314	/* set KICK bit in FRQCRB to update hardware setting */
315	value = __raw_readl(FRQCRB);
316	value |= (1 << 31);
317	__raw_writel(value, FRQCRB);
318}
319
320static int divisors[] = { 2, 3, 4, 6, 8, 12, 16, 18,
321			  24, 32, 36, 48, 0, 72, 96, 0 };
322
323static struct clk_div_mult_table div4_div_mult_table = {
324	.divisors = divisors,
325	.nr_divisors = ARRAY_SIZE(divisors),
326};
327
328static struct clk_div4_table div4_table = {
329	.div_mult_table = &div4_div_mult_table,
330	.kick = div4_kick,
331};
332
333enum { DIV4_I, DIV4_ZG, DIV4_B, DIV4_M1, DIV4_CSIR,
334       DIV4_ZTR, DIV4_ZT, DIV4_ZX, DIV4_HP,
335       DIV4_ISPB, DIV4_S, DIV4_ZB, DIV4_ZB3, DIV4_CP,
336       DIV4_DDRP, DIV4_NR };
337
338#define DIV4(_reg, _bit, _mask, _flags) \
339  SH_CLK_DIV4(&pllc1_clk, _reg, _bit, _mask, _flags)
340
341static struct clk div4_clks[DIV4_NR] = {
342	[DIV4_I] = DIV4(FRQCRA, 20, 0x6fff, CLK_ENABLE_ON_INIT),
343	[DIV4_ZG] = DIV4(FRQCRA, 16, 0x6fff, CLK_ENABLE_ON_INIT),
344	[DIV4_B] = DIV4(FRQCRA, 8, 0x6fff, CLK_ENABLE_ON_INIT),
345	[DIV4_M1] = DIV4(FRQCRA, 4, 0x6fff, CLK_ENABLE_ON_INIT),
346	[DIV4_CSIR] = DIV4(FRQCRA, 0, 0x6fff, 0),
347	[DIV4_ZTR] = DIV4(FRQCRB, 20, 0x6fff, 0),
348	[DIV4_ZT] = DIV4(FRQCRB, 16, 0x6fff, 0),
349	[DIV4_ZX] = DIV4(FRQCRB, 12, 0x6fff, 0),
350	[DIV4_HP] = DIV4(FRQCRB, 4, 0x6fff, 0),
351	[DIV4_ISPB] = DIV4(FRQCRC, 20, 0x6fff, 0),
352	[DIV4_S] = DIV4(FRQCRC, 12, 0x6fff, 0),
353	[DIV4_ZB] = DIV4(FRQCRC, 8, 0x6fff, 0),
354	[DIV4_ZB3] = DIV4(FRQCRC, 4, 0x6fff, 0),
355	[DIV4_CP] = DIV4(FRQCRC, 0, 0x6fff, 0),
356	[DIV4_DDRP] = DIV4(FRQCRD, 0, 0x677c, 0),
357};
358
359enum { DIV6_VCK1, DIV6_VCK2, DIV6_VCK3, DIV6_FMSI, DIV6_FMSO,
360       DIV6_FSIA, DIV6_FSIB, DIV6_SUB, DIV6_SPU,
361       DIV6_VOU, DIV6_DSIT, DIV6_DSI0P, DIV6_DSI1P,
362       DIV6_NR };
363
364static struct clk div6_clks[DIV6_NR] = {
365	[DIV6_VCK1] = SH_CLK_DIV6(&pllc1_div2_clk, VCLKCR1, 0),
366	[DIV6_VCK2] = SH_CLK_DIV6(&pllc1_div2_clk, VCLKCR2, 0),
367	[DIV6_VCK3] = SH_CLK_DIV6(&pllc1_div2_clk, VCLKCR3, 0),
368	[DIV6_FMSI] = SH_CLK_DIV6(&pllc1_div2_clk, FMSICKCR, 0),
369	[DIV6_FMSO] = SH_CLK_DIV6(&pllc1_div2_clk, FMSOCKCR, 0),
370	[DIV6_FSIA] = SH_CLK_DIV6(&pllc1_div2_clk, FSIACKCR, 0),
371	[DIV6_FSIB] = SH_CLK_DIV6(&pllc1_div2_clk, FSIBCKCR, 0),
372	[DIV6_SUB] = SH_CLK_DIV6(&sh7372_extal2_clk, SUBCKCR, 0),
373	[DIV6_SPU] = SH_CLK_DIV6(&pllc1_div2_clk, SPUCKCR, 0),
374	[DIV6_VOU] = SH_CLK_DIV6(&pllc1_div2_clk, VOUCKCR, 0),
375	[DIV6_DSIT] = SH_CLK_DIV6(&pllc1_div2_clk, DSITCKCR, 0),
376	[DIV6_DSI0P] = SH_CLK_DIV6(&pllc1_div2_clk, DSI0PCKCR, 0),
377	[DIV6_DSI1P] = SH_CLK_DIV6(&pllc1_div2_clk, DSI1PCKCR, 0),
378};
379
380enum { DIV6_HDMI, DIV6_REPARENT_NR };
381
382/* Indices are important - they are the actual src selecting values */
383static struct clk *hdmi_parent[] = {
384	[0] = &pllc1_div2_clk,
385	[1] = &pllc2_clk,
386	[2] = &dv_clki_clk,
387	[3] = NULL,	/* pllc2_div4 not implemented yet */
388};
389
390static struct clk div6_reparent_clks[DIV6_REPARENT_NR] = {
391	[DIV6_HDMI] = SH_CLK_DIV6_EXT(&pllc1_div2_clk, HDMICKCR, 0,
392				      hdmi_parent, ARRAY_SIZE(hdmi_parent), 6, 2),
393};
394
395enum { MSTP001,
396       MSTP131, MSTP130,
397       MSTP129, MSTP128, MSTP127, MSTP126,
398       MSTP118, MSTP117, MSTP116,
399       MSTP106, MSTP101, MSTP100,
400       MSTP223,
401       MSTP207, MSTP206, MSTP204, MSTP203, MSTP202, MSTP201, MSTP200,
402       MSTP329, MSTP328, MSTP323, MSTP322, MSTP314, MSTP313, MSTP312,
403       MSTP415, MSTP413, MSTP411, MSTP410, MSTP406, MSTP403,
404       MSTP_NR };
405
406#define MSTP(_parent, _reg, _bit, _flags) \
407  SH_CLK_MSTP32(_parent, _reg, _bit, _flags)
408
409static struct clk mstp_clks[MSTP_NR] = {
410	[MSTP001] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR0, 1, 0), /* IIC2 */
411	[MSTP131] = MSTP(&div4_clks[DIV4_B], SMSTPCR1, 31, 0), /* VEU3 */
412	[MSTP130] = MSTP(&div4_clks[DIV4_B], SMSTPCR1, 30, 0), /* VEU2 */
413	[MSTP129] = MSTP(&div4_clks[DIV4_B], SMSTPCR1, 29, 0), /* VEU1 */
414	[MSTP128] = MSTP(&div4_clks[DIV4_B], SMSTPCR1, 28, 0), /* VEU0 */
415	[MSTP127] = MSTP(&div4_clks[DIV4_B], SMSTPCR1, 27, 0), /* CEU */
416	[MSTP126] = MSTP(&div4_clks[DIV4_B], SMSTPCR1, 26, 0), /* CSI2 */
417	[MSTP118] = MSTP(&div4_clks[DIV4_B], SMSTPCR1, 18, 0), /* DSITX */
418	[MSTP117] = MSTP(&div4_clks[DIV4_B], SMSTPCR1, 17, 0), /* LCDC1 */
419	[MSTP116] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR1, 16, 0), /* IIC0 */
420	[MSTP106] = MSTP(&div4_clks[DIV4_B], SMSTPCR1, 6, 0), /* JPU */
421	[MSTP101] = MSTP(&div4_clks[DIV4_M1], SMSTPCR1, 1, 0), /* VPU */
422	[MSTP100] = MSTP(&div4_clks[DIV4_B], SMSTPCR1, 0, 0), /* LCDC0 */
423	[MSTP223] = MSTP(&div6_clks[DIV6_SPU], SMSTPCR2, 23, 0), /* SPU2 */
424	[MSTP207] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR2, 7, 0), /* SCIFA5 */
425	[MSTP206] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR2, 6, 0), /* SCIFB */
426	[MSTP204] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR2, 4, 0), /* SCIFA0 */
427	[MSTP203] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR2, 3, 0), /* SCIFA1 */
428	[MSTP202] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR2, 2, 0), /* SCIFA2 */
429	[MSTP201] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR2, 1, 0), /* SCIFA3 */
430	[MSTP200] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR2, 0, 0), /* SCIFA4 */
431	[MSTP329] = MSTP(&r_clk, SMSTPCR3, 29, 0), /* CMT10 */
432	[MSTP328] = MSTP(&div6_clks[DIV6_SPU], SMSTPCR3, 28, 0), /* FSIA */
433	[MSTP323] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR3, 23, 0), /* IIC1 */
434	[MSTP322] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR3, 22, 0), /* USB0 */
435	[MSTP314] = MSTP(&div4_clks[DIV4_HP], SMSTPCR3, 14, 0), /* SDHI0 */
436	[MSTP313] = MSTP(&div4_clks[DIV4_HP], SMSTPCR3, 13, 0), /* SDHI1 */
437	[MSTP312] = MSTP(&div4_clks[DIV4_HP], SMSTPCR3, 12, 0), /* MMC */
438	[MSTP415] = MSTP(&div4_clks[DIV4_HP], SMSTPCR4, 15, 0), /* SDHI2 */
439	[MSTP413] = MSTP(&pllc1_div2_clk, SMSTPCR4, 13, 0), /* HDMI */
440	[MSTP411] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR4, 11, 0), /* IIC3 */
441	[MSTP410] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR4, 10, 0), /* IIC4 */
442	[MSTP406] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR4, 6, 0), /* USB1 */
443	[MSTP403] = MSTP(&r_clk, SMSTPCR4, 3, 0), /* KEYSC */
444};
445
446#define CLKDEV_CON_ID(_id, _clk) { .con_id = _id, .clk = _clk }
447#define CLKDEV_DEV_ID(_id, _clk) { .dev_id = _id, .clk = _clk }
448
449static struct clk_lookup lookups[] = {
450	/* main clocks */
451	CLKDEV_CON_ID("dv_clki_div2_clk", &dv_clki_div2_clk),
452	CLKDEV_CON_ID("r_clk", &r_clk),
453	CLKDEV_CON_ID("extal1", &sh7372_extal1_clk),
454	CLKDEV_CON_ID("extal2", &sh7372_extal2_clk),
455	CLKDEV_CON_ID("extal1_div2_clk", &extal1_div2_clk),
456	CLKDEV_CON_ID("extal2_div2_clk", &extal2_div2_clk),
457	CLKDEV_CON_ID("extal2_div4_clk", &extal2_div4_clk),
458	CLKDEV_CON_ID("pllc0_clk", &pllc0_clk),
459	CLKDEV_CON_ID("pllc1_clk", &pllc1_clk),
460	CLKDEV_CON_ID("pllc1_div2_clk", &pllc1_div2_clk),
461	CLKDEV_CON_ID("pllc2_clk", &pllc2_clk),
462
463	/* DIV4 clocks */
464	CLKDEV_CON_ID("i_clk", &div4_clks[DIV4_I]),
465	CLKDEV_CON_ID("zg_clk", &div4_clks[DIV4_ZG]),
466	CLKDEV_CON_ID("b_clk", &div4_clks[DIV4_B]),
467	CLKDEV_CON_ID("m1_clk", &div4_clks[DIV4_M1]),
468	CLKDEV_CON_ID("csir_clk", &div4_clks[DIV4_CSIR]),
469	CLKDEV_CON_ID("ztr_clk", &div4_clks[DIV4_ZTR]),
470	CLKDEV_CON_ID("zt_clk", &div4_clks[DIV4_ZT]),
471	CLKDEV_CON_ID("zx_clk", &div4_clks[DIV4_ZX]),
472	CLKDEV_CON_ID("hp_clk", &div4_clks[DIV4_HP]),
473	CLKDEV_CON_ID("ispb_clk", &div4_clks[DIV4_ISPB]),
474	CLKDEV_CON_ID("s_clk", &div4_clks[DIV4_S]),
475	CLKDEV_CON_ID("zb_clk", &div4_clks[DIV4_ZB]),
476	CLKDEV_CON_ID("zb3_clk", &div4_clks[DIV4_ZB3]),
477	CLKDEV_CON_ID("cp_clk", &div4_clks[DIV4_CP]),
478	CLKDEV_CON_ID("ddrp_clk", &div4_clks[DIV4_DDRP]),
479
480	/* DIV6 clocks */
481	CLKDEV_CON_ID("vck1_clk", &div6_clks[DIV6_VCK1]),
482	CLKDEV_CON_ID("vck2_clk", &div6_clks[DIV6_VCK2]),
483	CLKDEV_CON_ID("vck3_clk", &div6_clks[DIV6_VCK3]),
484	CLKDEV_CON_ID("fmsi_clk", &div6_clks[DIV6_FMSI]),
485	CLKDEV_CON_ID("fmso_clk", &div6_clks[DIV6_FMSO]),
486	CLKDEV_CON_ID("fsia_clk", &div6_clks[DIV6_FSIA]),
487	CLKDEV_CON_ID("fsib_clk", &div6_clks[DIV6_FSIB]),
488	CLKDEV_CON_ID("sub_clk", &div6_clks[DIV6_SUB]),
489	CLKDEV_CON_ID("spu_clk", &div6_clks[DIV6_SPU]),
490	CLKDEV_CON_ID("vou_clk", &div6_clks[DIV6_VOU]),
491	CLKDEV_CON_ID("hdmi_clk", &div6_reparent_clks[DIV6_HDMI]),
492	CLKDEV_CON_ID("dsit_clk", &div6_clks[DIV6_DSIT]),
493	CLKDEV_CON_ID("dsi0p_clk", &div6_clks[DIV6_DSI0P]),
494	CLKDEV_CON_ID("dsi1p_clk", &div6_clks[DIV6_DSI1P]),
495
496	/* MSTP32 clocks */
497	CLKDEV_DEV_ID("i2c-sh_mobile.2", &mstp_clks[MSTP001]), /* IIC2 */
498	CLKDEV_DEV_ID("uio_pdrv_genirq.4", &mstp_clks[MSTP131]), /* VEU3 */
499	CLKDEV_DEV_ID("uio_pdrv_genirq.3", &mstp_clks[MSTP130]), /* VEU2 */
500	CLKDEV_DEV_ID("uio_pdrv_genirq.2", &mstp_clks[MSTP129]), /* VEU1 */
501	CLKDEV_DEV_ID("uio_pdrv_genirq.1", &mstp_clks[MSTP128]), /* VEU0 */
502	CLKDEV_DEV_ID("sh_mobile_ceu.0", &mstp_clks[MSTP127]), /* CEU */
503	CLKDEV_DEV_ID("sh-mobile-csi2.0", &mstp_clks[MSTP126]), /* CSI2 */
504	CLKDEV_DEV_ID("sh-mipi-dsi.0", &mstp_clks[MSTP118]), /* DSITX */
505	CLKDEV_DEV_ID("sh_mobile_lcdc_fb.1", &mstp_clks[MSTP117]), /* LCDC1 */
506	CLKDEV_DEV_ID("i2c-sh_mobile.0", &mstp_clks[MSTP116]), /* IIC0 */
507	CLKDEV_DEV_ID("uio_pdrv_genirq.5", &mstp_clks[MSTP106]), /* JPU */
508	CLKDEV_DEV_ID("uio_pdrv_genirq.0", &mstp_clks[MSTP101]), /* VPU */
509	CLKDEV_DEV_ID("sh_mobile_lcdc_fb.0", &mstp_clks[MSTP100]), /* LCDC0 */
510	CLKDEV_DEV_ID("uio_pdrv_genirq.6", &mstp_clks[MSTP223]), /* SPU2DSP0 */
511	CLKDEV_DEV_ID("uio_pdrv_genirq.7", &mstp_clks[MSTP223]), /* SPU2DSP1 */
512	CLKDEV_DEV_ID("sh-sci.5", &mstp_clks[MSTP207]), /* SCIFA5 */
513	CLKDEV_DEV_ID("sh-sci.6", &mstp_clks[MSTP206]), /* SCIFB */
514	CLKDEV_DEV_ID("sh-sci.0", &mstp_clks[MSTP204]), /* SCIFA0 */
515	CLKDEV_DEV_ID("sh-sci.1", &mstp_clks[MSTP203]), /* SCIFA1 */
516	CLKDEV_DEV_ID("sh-sci.2", &mstp_clks[MSTP202]), /* SCIFA2 */
517	CLKDEV_DEV_ID("sh-sci.3", &mstp_clks[MSTP201]), /* SCIFA3 */
518	CLKDEV_DEV_ID("sh-sci.4", &mstp_clks[MSTP200]), /* SCIFA4 */
519	CLKDEV_CON_ID("cmt1", &mstp_clks[MSTP329]), /* CMT10 */
520	CLKDEV_DEV_ID("sh_fsi2", &mstp_clks[MSTP328]), /* FSI2 */
521	CLKDEV_DEV_ID("i2c-sh_mobile.1", &mstp_clks[MSTP323]), /* IIC1 */
522	CLKDEV_DEV_ID("r8a66597_hcd.0", &mstp_clks[MSTP323]), /* USB0 */
523	CLKDEV_DEV_ID("r8a66597_udc.0", &mstp_clks[MSTP323]), /* USB0 */
524	CLKDEV_DEV_ID("sh_mobile_sdhi.0", &mstp_clks[MSTP314]), /* SDHI0 */
525	CLKDEV_DEV_ID("sh_mobile_sdhi.1", &mstp_clks[MSTP313]), /* SDHI1 */
526	CLKDEV_DEV_ID("sh_mmcif.0", &mstp_clks[MSTP312]), /* MMC */
527	CLKDEV_DEV_ID("sh_mobile_sdhi.2", &mstp_clks[MSTP415]), /* SDHI2 */
528	CLKDEV_DEV_ID("sh-mobile-hdmi", &mstp_clks[MSTP413]), /* HDMI */
529	CLKDEV_DEV_ID("i2c-sh_mobile.3", &mstp_clks[MSTP411]), /* IIC3 */
530	CLKDEV_DEV_ID("i2c-sh_mobile.4", &mstp_clks[MSTP410]), /* IIC4 */
531	CLKDEV_DEV_ID("r8a66597_hcd.1", &mstp_clks[MSTP406]), /* USB1 */
532	CLKDEV_DEV_ID("r8a66597_udc.1", &mstp_clks[MSTP406]), /* USB1 */
533	CLKDEV_DEV_ID("sh_keysc.0", &mstp_clks[MSTP403]), /* KEYSC */
534	{.con_id = "ick", .dev_id = "sh-mobile-hdmi", .clk = &div6_reparent_clks[DIV6_HDMI]},
535};
536
537void __init sh7372_clock_init(void)
538{
539	int k, ret = 0;
540
541	for (k = 0; !ret && (k < ARRAY_SIZE(main_clks)); k++)
542		ret = clk_register(main_clks[k]);
543
544	if (!ret)
545		ret = sh_clk_div4_register(div4_clks, DIV4_NR, &div4_table);
546
547	if (!ret)
548		ret = sh_clk_div6_register(div6_clks, DIV6_NR);
549
550	if (!ret)
551		ret = sh_clk_div6_reparent_register(div6_reparent_clks, DIV6_NR);
552
553	if (!ret)
554		ret = sh_clk_mstp32_register(mstp_clks, MSTP_NR);
555
556	clkdev_add_table(lookups, ARRAY_SIZE(lookups));
557
558	if (!ret)
559		clk_init();
560	else
561		panic("failed to setup sh7372 clocks\n");
562
563}
564