Linux Audio

Check our new training course

Loading...
v3.5.6
  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 */
 62struct clk sh7372_dv_clki_clk = {
 63};
 64
 65/* Fixed 32 KHz root clock from EXTALR pin */
 66static 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 */
 74struct 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 */
 82struct clk sh7372_extal2_clk = {
 83	.rate		= 48000000,
 84};
 85
 86/* A fixed divide-by-2 block */
 87static unsigned long div2_recalc(struct clk *clk)
 88{
 89	return clk->parent->rate / 2;
 90}
 91
 92static struct sh_clk_ops div2_clk_ops = {
 93	.recalc		= div2_recalc,
 94};
 95
 96/* Divide dv_clki by two */
 97struct clk sh7372_dv_clki_div2_clk = {
 98	.ops		= &div2_clk_ops,
 99	.parent		= &sh7372_dv_clki_clk,
100};
101
102/* Divide extal1 by two */
103static struct clk extal1_div2_clk = {
104	.ops		= &div2_clk_ops,
105	.parent		= &sh7372_extal1_clk,
106};
107
108/* Divide extal2 by two */
109static struct clk extal2_div2_clk = {
110	.ops		= &div2_clk_ops,
111	.parent		= &sh7372_extal2_clk,
112};
113
114/* Divide extal2 by four */
115static struct clk extal2_div4_clk = {
116	.ops		= &div2_clk_ops,
117	.parent		= &extal2_div2_clk,
118};
119
120/* PLLC0 and PLLC1 */
121static 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
131static struct sh_clk_ops pllc01_clk_ops = {
132	.recalc		= pllc01_recalc,
133};
134
135static 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
142static 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 */
150static 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 */
158static 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 */
165static struct cpufreq_frequency_table pllc2_freq_table[29];
166
167static 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
185static 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
201static long pllc2_round_rate(struct clk *clk, unsigned long rate)
202{
203	return clk_rate_table_round(clk, clk->freq_table, rate);
204}
205
206static 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
223static void pllc2_disable(struct clk *clk)
224{
225	__raw_writel(__raw_readl(PLLC2CR) & ~0x80000000, PLLC2CR);
226}
227
228static 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
249static 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
279static struct sh_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
288struct 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 ) */
298struct clk sh7372_fsiack_clk = {
299};
300
301struct clk sh7372_fsibck_clk = {
302};
303
304static 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
321static 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
331static int divisors[] = { 2, 3, 4, 6, 8, 12, 16, 18,
332			  24, 32, 36, 48, 0, 72, 96, 0 };
333
334static struct clk_div_mult_table div4_div_mult_table = {
335	.divisors = divisors,
336	.nr_divisors = ARRAY_SIZE(divisors),
337};
338
339static struct clk_div4_table div4_table = {
340	.div_mult_table = &div4_div_mult_table,
341	.kick = div4_kick,
342};
343
344enum { 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
352static 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
370enum { 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
375static 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
389enum { DIV6_HDMI, DIV6_FSIA, DIV6_FSIB, DIV6_REPARENT_NR };
390
391/* Indices are important - they are the actual src selecting values */
392static 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
399static 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
406static 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
413static 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 */
423static 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
436static long fsidiv_round_rate(struct clk *clk, unsigned long rate)
437{
438	return clk_rate_div_range_round(clk, 2, 0xffff, rate);
439}
440
441static void fsidiv_disable(struct clk *clk)
442{
443	__raw_writel(0, clk->mapping->base);
444}
445
446static 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
459static 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
471static struct sh_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
479static struct clk_mapping fsidiva_clk_mapping = {
480	.phys	= FSIDIVA,
481	.len	= 8,
482};
483
484struct 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
490static struct clk_mapping fsidivb_clk_mapping = {
491	.phys	= FSIDIVB,
492	.len	= 8,
493};
494
495struct 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
501static struct clk *late_main_clks[] = {
502	&sh7372_fsidiva_clk,
503	&sh7372_fsidivb_clk,
504};
505
506enum { 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, MSTP315, 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
522static 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	[MSTP315] = MSTP(&div4_clks[DIV4_HP], SMSTPCR3, 15, 0), /* FLCTL*/
557	[MSTP314] = MSTP(&div4_clks[DIV4_HP], SMSTPCR3, 14, 0), /* SDHI0 */
558	[MSTP313] = MSTP(&div4_clks[DIV4_HP], SMSTPCR3, 13, 0), /* SDHI1 */
559	[MSTP312] = MSTP(&div4_clks[DIV4_HP], SMSTPCR3, 12, 0), /* MMC */
560	[MSTP423] = MSTP(&div4_clks[DIV4_B], SMSTPCR4, 23, 0), /* DSITX1 */
561	[MSTP415] = MSTP(&div4_clks[DIV4_HP], SMSTPCR4, 15, 0), /* SDHI2 */
562	[MSTP413] = MSTP(&pllc1_div2_clk, SMSTPCR4, 13, 0), /* HDMI */
563	[MSTP411] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR4, 11, 0), /* IIC3 */
564	[MSTP410] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR4, 10, 0), /* IIC4 */
565	[MSTP407] = MSTP(&div4_clks[DIV4_HP], SMSTPCR4, 7, 0), /* USB-DMAC1 */
566	[MSTP406] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR4, 6, 0), /* USB1 */
567	[MSTP405] = MSTP(&r_clk, SMSTPCR4, 5, 0), /* CMT4 */
568	[MSTP404] = MSTP(&r_clk, SMSTPCR4, 4, 0), /* CMT3 */
569	[MSTP403] = MSTP(&r_clk, SMSTPCR4, 3, 0), /* KEYSC */
570	[MSTP400] = MSTP(&r_clk, SMSTPCR4, 0, 0), /* CMT2 */
571};
572
573static struct clk_lookup lookups[] = {
574	/* main clocks */
575	CLKDEV_CON_ID("dv_clki_div2_clk", &sh7372_dv_clki_div2_clk),
576	CLKDEV_CON_ID("r_clk", &r_clk),
577	CLKDEV_CON_ID("extal1", &sh7372_extal1_clk),
578	CLKDEV_CON_ID("extal2", &sh7372_extal2_clk),
579	CLKDEV_CON_ID("extal1_div2_clk", &extal1_div2_clk),
580	CLKDEV_CON_ID("extal2_div2_clk", &extal2_div2_clk),
581	CLKDEV_CON_ID("extal2_div4_clk", &extal2_div4_clk),
582	CLKDEV_CON_ID("pllc0_clk", &pllc0_clk),
583	CLKDEV_CON_ID("pllc1_clk", &pllc1_clk),
584	CLKDEV_CON_ID("pllc1_div2_clk", &pllc1_div2_clk),
585	CLKDEV_CON_ID("pllc2_clk", &sh7372_pllc2_clk),
586
587	/* DIV4 clocks */
588	CLKDEV_CON_ID("i_clk", &div4_clks[DIV4_I]),
589	CLKDEV_CON_ID("zg_clk", &div4_clks[DIV4_ZG]),
590	CLKDEV_CON_ID("b_clk", &div4_clks[DIV4_B]),
591	CLKDEV_CON_ID("m1_clk", &div4_clks[DIV4_M1]),
592	CLKDEV_CON_ID("csir_clk", &div4_clks[DIV4_CSIR]),
593	CLKDEV_CON_ID("ztr_clk", &div4_clks[DIV4_ZTR]),
594	CLKDEV_CON_ID("zt_clk", &div4_clks[DIV4_ZT]),
595	CLKDEV_CON_ID("zx_clk", &div4_clks[DIV4_ZX]),
596	CLKDEV_CON_ID("hp_clk", &div4_clks[DIV4_HP]),
597	CLKDEV_CON_ID("ispb_clk", &div4_clks[DIV4_ISPB]),
598	CLKDEV_CON_ID("s_clk", &div4_clks[DIV4_S]),
599	CLKDEV_CON_ID("zb_clk", &div4_clks[DIV4_ZB]),
600	CLKDEV_CON_ID("zb3_clk", &div4_clks[DIV4_ZB3]),
601	CLKDEV_CON_ID("cp_clk", &div4_clks[DIV4_CP]),
602	CLKDEV_CON_ID("ddrp_clk", &div4_clks[DIV4_DDRP]),
603
604	/* DIV6 clocks */
605	CLKDEV_CON_ID("vck1_clk", &div6_clks[DIV6_VCK1]),
606	CLKDEV_CON_ID("vck2_clk", &div6_clks[DIV6_VCK2]),
607	CLKDEV_CON_ID("vck3_clk", &div6_clks[DIV6_VCK3]),
608	CLKDEV_CON_ID("fmsi_clk", &div6_clks[DIV6_FMSI]),
609	CLKDEV_CON_ID("fmso_clk", &div6_clks[DIV6_FMSO]),
610	CLKDEV_CON_ID("sub_clk", &div6_clks[DIV6_SUB]),
611	CLKDEV_CON_ID("spu_clk", &div6_clks[DIV6_SPU]),
612	CLKDEV_CON_ID("vou_clk", &div6_clks[DIV6_VOU]),
613	CLKDEV_CON_ID("hdmi_clk", &div6_reparent_clks[DIV6_HDMI]),
614	CLKDEV_ICK_ID("dsit_clk", "sh-mipi-dsi.0", &div6_clks[DIV6_DSIT]),
615	CLKDEV_ICK_ID("dsit_clk", "sh-mipi-dsi.1", &div6_clks[DIV6_DSIT]),
616	CLKDEV_ICK_ID("dsip_clk", "sh-mipi-dsi.0", &div6_clks[DIV6_DSI0P]),
617	CLKDEV_ICK_ID("dsip_clk", "sh-mipi-dsi.1", &div6_clks[DIV6_DSI1P]),
618
619	/* MSTP32 clocks */
620	CLKDEV_DEV_ID("i2c-sh_mobile.2", &mstp_clks[MSTP001]), /* IIC2 */
621	CLKDEV_DEV_ID("spi_sh_msiof.0", &mstp_clks[MSTP000]), /* MSIOF0 */
622	CLKDEV_DEV_ID("uio_pdrv_genirq.4", &mstp_clks[MSTP131]), /* VEU3 */
623	CLKDEV_DEV_ID("uio_pdrv_genirq.3", &mstp_clks[MSTP130]), /* VEU2 */
624	CLKDEV_DEV_ID("uio_pdrv_genirq.2", &mstp_clks[MSTP129]), /* VEU1 */
625	CLKDEV_DEV_ID("uio_pdrv_genirq.1", &mstp_clks[MSTP128]), /* VEU0 */
626	CLKDEV_DEV_ID("sh_mobile_ceu.0", &mstp_clks[MSTP127]), /* CEU */
627	CLKDEV_DEV_ID("sh-mobile-csi2.0", &mstp_clks[MSTP126]), /* CSI2 */
628	CLKDEV_DEV_ID("sh_tmu.0", &mstp_clks[MSTP125]), /* TMU00 */
629	CLKDEV_DEV_ID("sh_tmu.1", &mstp_clks[MSTP125]), /* TMU01 */
630	CLKDEV_DEV_ID("sh-mipi-dsi.0", &mstp_clks[MSTP118]), /* DSITX0 */
631	CLKDEV_DEV_ID("sh_mobile_lcdc_fb.1", &mstp_clks[MSTP117]), /* LCDC1 */
632	CLKDEV_DEV_ID("i2c-sh_mobile.0", &mstp_clks[MSTP116]), /* IIC0 */
633	CLKDEV_DEV_ID("sh_mobile_meram.0", &mstp_clks[MSTP113]), /* MERAM */
634	CLKDEV_DEV_ID("uio_pdrv_genirq.5", &mstp_clks[MSTP106]), /* JPU */
635	CLKDEV_DEV_ID("uio_pdrv_genirq.0", &mstp_clks[MSTP101]), /* VPU */
636	CLKDEV_DEV_ID("sh_mobile_lcdc_fb.0", &mstp_clks[MSTP100]), /* LCDC0 */
637	CLKDEV_DEV_ID("uio_pdrv_genirq.6", &mstp_clks[MSTP223]), /* SPU2DSP0 */
638	CLKDEV_DEV_ID("uio_pdrv_genirq.7", &mstp_clks[MSTP223]), /* SPU2DSP1 */
639	CLKDEV_DEV_ID("sh-dma-engine.0", &mstp_clks[MSTP218]), /* DMAC1 */
640	CLKDEV_DEV_ID("sh-dma-engine.1", &mstp_clks[MSTP217]), /* DMAC2 */
641	CLKDEV_DEV_ID("sh-dma-engine.2", &mstp_clks[MSTP216]), /* DMAC3 */
642	CLKDEV_DEV_ID("sh-dma-engine.3", &mstp_clks[MSTP214]), /* USB-DMAC0 */
643	CLKDEV_DEV_ID("spi_sh_msiof.1", &mstp_clks[MSTP208]), /* MSIOF1 */
644	CLKDEV_DEV_ID("sh-sci.5", &mstp_clks[MSTP207]), /* SCIFA5 */
645	CLKDEV_DEV_ID("sh-sci.6", &mstp_clks[MSTP206]), /* SCIFB */
646	CLKDEV_DEV_ID("spi_sh_msiof.2", &mstp_clks[MSTP205]), /* MSIOF2 */
647	CLKDEV_DEV_ID("sh-sci.0", &mstp_clks[MSTP204]), /* SCIFA0 */
648	CLKDEV_DEV_ID("sh-sci.1", &mstp_clks[MSTP203]), /* SCIFA1 */
649	CLKDEV_DEV_ID("sh-sci.2", &mstp_clks[MSTP202]), /* SCIFA2 */
650	CLKDEV_DEV_ID("sh-sci.3", &mstp_clks[MSTP201]), /* SCIFA3 */
651	CLKDEV_DEV_ID("sh-sci.4", &mstp_clks[MSTP200]), /* SCIFA4 */
652	CLKDEV_DEV_ID("sh_fsi2", &mstp_clks[MSTP328]), /* FSI2 */
653	CLKDEV_DEV_ID("i2c-sh_mobile.1", &mstp_clks[MSTP323]), /* IIC1 */
654	CLKDEV_DEV_ID("r8a66597_hcd.0", &mstp_clks[MSTP322]), /* USB0 */
655	CLKDEV_DEV_ID("r8a66597_udc.0", &mstp_clks[MSTP322]), /* USB0 */
656	CLKDEV_DEV_ID("renesas_usbhs.0", &mstp_clks[MSTP322]), /* USB0 */
657	CLKDEV_DEV_ID("sh_flctl.0", &mstp_clks[MSTP315]), /* FLCTL */
658	CLKDEV_DEV_ID("sh_mobile_sdhi.0", &mstp_clks[MSTP314]), /* SDHI0 */
659	CLKDEV_DEV_ID("sh_mobile_sdhi.1", &mstp_clks[MSTP313]), /* SDHI1 */
660	CLKDEV_DEV_ID("sh_mmcif.0", &mstp_clks[MSTP312]), /* MMC */
661	CLKDEV_DEV_ID("sh-mipi-dsi.1", &mstp_clks[MSTP423]), /* DSITX1 */
662	CLKDEV_DEV_ID("sh_mobile_sdhi.2", &mstp_clks[MSTP415]), /* SDHI2 */
663	CLKDEV_DEV_ID("sh-mobile-hdmi", &mstp_clks[MSTP413]), /* HDMI */
664	CLKDEV_DEV_ID("i2c-sh_mobile.3", &mstp_clks[MSTP411]), /* IIC3 */
665	CLKDEV_DEV_ID("i2c-sh_mobile.4", &mstp_clks[MSTP410]), /* IIC4 */
666	CLKDEV_DEV_ID("sh-dma-engine.4", &mstp_clks[MSTP407]), /* USB-DMAC1 */
667	CLKDEV_DEV_ID("r8a66597_hcd.1", &mstp_clks[MSTP406]), /* USB1 */
668	CLKDEV_DEV_ID("r8a66597_udc.1", &mstp_clks[MSTP406]), /* USB1 */
669	CLKDEV_DEV_ID("renesas_usbhs.1", &mstp_clks[MSTP406]), /* USB1 */
670	CLKDEV_DEV_ID("sh_cmt.4", &mstp_clks[MSTP405]), /* CMT4 */
671	CLKDEV_DEV_ID("sh_cmt.3", &mstp_clks[MSTP404]), /* CMT3 */
672	CLKDEV_DEV_ID("sh_keysc.0", &mstp_clks[MSTP403]), /* KEYSC */
673	CLKDEV_DEV_ID("sh_cmt.2", &mstp_clks[MSTP400]), /* CMT2 */
674
675	CLKDEV_ICK_ID("hdmi", "sh_mobile_lcdc_fb.1",
676		      &div6_reparent_clks[DIV6_HDMI]),
677	CLKDEV_ICK_ID("ick", "sh-mobile-hdmi", &div6_reparent_clks[DIV6_HDMI]),
678	CLKDEV_ICK_ID("icka", "sh_fsi2", &div6_reparent_clks[DIV6_FSIA]),
679	CLKDEV_ICK_ID("ickb", "sh_fsi2", &div6_reparent_clks[DIV6_FSIB]),
680	CLKDEV_ICK_ID("spu2", "sh_fsi2", &mstp_clks[MSTP223]),
681};
682
683void __init sh7372_clock_init(void)
684{
685	int k, ret = 0;
686
687	/* make sure MSTP bits on the RT/SH4AL-DSP side are off */
688	__raw_writel(0xe4ef8087, RMSTPCR0);
689	__raw_writel(0xffffffff, RMSTPCR1);
690	__raw_writel(0x37c7f7ff, RMSTPCR2);
691	__raw_writel(0xffffffff, RMSTPCR3);
692	__raw_writel(0xffe0fffd, RMSTPCR4);
693
694	for (k = 0; !ret && (k < ARRAY_SIZE(main_clks)); k++)
695		ret = clk_register(main_clks[k]);
696
697	if (!ret)
698		ret = sh_clk_div4_register(div4_clks, DIV4_NR, &div4_table);
699
700	if (!ret)
701		ret = sh_clk_div6_register(div6_clks, DIV6_NR);
702
703	if (!ret)
704		ret = sh_clk_div6_reparent_register(div6_reparent_clks, DIV6_REPARENT_NR);
705
706	if (!ret)
707		ret = sh_clk_mstp32_register(mstp_clks, MSTP_NR);
708
709	for (k = 0; !ret && (k < ARRAY_SIZE(late_main_clks)); k++)
710		ret = clk_register(late_main_clks[k]);
711
712	clkdev_add_table(lookups, ARRAY_SIZE(lookups));
713
714	if (!ret)
715		shmobile_clk_init();
716	else
717		panic("failed to setup sh7372 clocks\n");
718
719}
v3.1
  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 */
 62struct clk sh7372_dv_clki_clk = {
 63};
 64
 65/* Fixed 32 KHz root clock from EXTALR pin */
 66static 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 */
 74struct 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 */
 82struct clk sh7372_extal2_clk = {
 83	.rate		= 48000000,
 84};
 85
 86/* A fixed divide-by-2 block */
 87static unsigned long div2_recalc(struct clk *clk)
 88{
 89	return clk->parent->rate / 2;
 90}
 91
 92static struct clk_ops div2_clk_ops = {
 93	.recalc		= div2_recalc,
 94};
 95
 96/* Divide dv_clki by two */
 97struct clk sh7372_dv_clki_div2_clk = {
 98	.ops		= &div2_clk_ops,
 99	.parent		= &sh7372_dv_clki_clk,
100};
101
102/* Divide extal1 by two */
103static struct clk extal1_div2_clk = {
104	.ops		= &div2_clk_ops,
105	.parent		= &sh7372_extal1_clk,
106};
107
108/* Divide extal2 by two */
109static struct clk extal2_div2_clk = {
110	.ops		= &div2_clk_ops,
111	.parent		= &sh7372_extal2_clk,
112};
113
114/* Divide extal2 by four */
115static struct clk extal2_div4_clk = {
116	.ops		= &div2_clk_ops,
117	.parent		= &extal2_div2_clk,
118};
119
120/* PLLC0 and PLLC1 */
121static 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
131static struct clk_ops pllc01_clk_ops = {
132	.recalc		= pllc01_recalc,
133};
134
135static 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
142static 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 */
150static 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 */
158static 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 */
165static struct cpufreq_frequency_table pllc2_freq_table[29];
166
167static 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
185static 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
201static long pllc2_round_rate(struct clk *clk, unsigned long rate)
202{
203	return clk_rate_table_round(clk, clk->freq_table, rate);
204}
205
206static 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
223static void pllc2_disable(struct clk *clk)
224{
225	__raw_writel(__raw_readl(PLLC2CR) & ~0x80000000, PLLC2CR);
226}
227
228static 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
249static 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
279static 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
288struct 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 ) */
298struct clk sh7372_fsiack_clk = {
299};
300
301struct clk sh7372_fsibck_clk = {
302};
303
304static 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
321static 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
331static int divisors[] = { 2, 3, 4, 6, 8, 12, 16, 18,
332			  24, 32, 36, 48, 0, 72, 96, 0 };
333
334static struct clk_div_mult_table div4_div_mult_table = {
335	.divisors = divisors,
336	.nr_divisors = ARRAY_SIZE(divisors),
337};
338
339static struct clk_div4_table div4_table = {
340	.div_mult_table = &div4_div_mult_table,
341	.kick = div4_kick,
342};
343
344enum { 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
352static 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
370enum { 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
375static 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
389enum { DIV6_HDMI, DIV6_FSIA, DIV6_FSIB, DIV6_REPARENT_NR };
390
391/* Indices are important - they are the actual src selecting values */
392static 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
399static 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
406static 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
413static struct clk div6_reparent_clks[DIV6_REPARENT_NR] = {
414	[DIV6_HDMI] = SH_CLK_DIV6_EXT(&pllc1_div2_clk, HDMICKCR, 0,
415				      hdmi_parent, ARRAY_SIZE(hdmi_parent), 6, 2),
416	[DIV6_FSIA] = SH_CLK_DIV6_EXT(&pllc1_div2_clk, FSIACKCR, 0,
417				      fsiackcr_parent, ARRAY_SIZE(fsiackcr_parent), 6, 2),
418	[DIV6_FSIB] = SH_CLK_DIV6_EXT(&pllc1_div2_clk, FSIBCKCR, 0,
419				      fsibckcr_parent, ARRAY_SIZE(fsibckcr_parent), 6, 2),
420};
421
422/* FSI DIV */
423static 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
436static long fsidiv_round_rate(struct clk *clk, unsigned long rate)
437{
438	return clk_rate_div_range_round(clk, 2, 0xffff, rate);
439}
440
441static void fsidiv_disable(struct clk *clk)
442{
443	__raw_writel(0, clk->mapping->base);
444}
445
446static 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
459static 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
471static 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
479static struct clk_mapping sh7372_fsidiva_clk_mapping = {
480	.phys	= FSIDIVA,
481	.len	= 8,
482};
483
484struct clk sh7372_fsidiva_clk = {
485	.ops		= &fsidiv_clk_ops,
486	.parent		= &div6_reparent_clks[DIV6_FSIA], /* late install */
487	.mapping	= &sh7372_fsidiva_clk_mapping,
488};
489
490static struct clk_mapping sh7372_fsidivb_clk_mapping = {
491	.phys	= FSIDIVB,
492	.len	= 8,
493};
494
495struct clk sh7372_fsidivb_clk = {
496	.ops		= &fsidiv_clk_ops,
497	.parent		= &div6_reparent_clks[DIV6_FSIB],  /* late install */
498	.mapping	= &sh7372_fsidivb_clk_mapping,
499};
500
501static struct clk *late_main_clks[] = {
502	&sh7372_fsidiva_clk,
503	&sh7372_fsidivb_clk,
504};
505
506enum { 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
522static 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
572static 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("dsi0p_clk", "sh-mipi-dsi.0", &div6_clks[DIV6_DSI0P]),
616	CLKDEV_ICK_ID("dsi1p_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
681void __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}