Linux Audio

Check our new training course

Linux debugging, profiling, tracing and performance analysis training

Apr 14-17, 2025
Register
Loading...
Note: File does not exist in v4.6.
  1/*
  2 * sh73a0 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#define FRQCRA		0xe6150000
 27#define FRQCRB		0xe6150004
 28#define FRQCRD		0xe61500e4
 29#define VCLKCR1		0xe6150008
 30#define VCLKCR2		0xe615000C
 31#define VCLKCR3		0xe615001C
 32#define ZBCKCR		0xe6150010
 33#define FLCKCR		0xe6150014
 34#define SD0CKCR		0xe6150074
 35#define SD1CKCR		0xe6150078
 36#define SD2CKCR		0xe615007C
 37#define FSIACKCR	0xe6150018
 38#define FSIBCKCR	0xe6150090
 39#define SUBCKCR		0xe6150080
 40#define SPUACKCR	0xe6150084
 41#define SPUVCKCR	0xe6150094
 42#define MSUCKCR		0xe6150088
 43#define HSICKCR		0xe615008C
 44#define MFCK1CR		0xe6150098
 45#define MFCK2CR		0xe615009C
 46#define DSITCKCR	0xe6150060
 47#define DSI0PCKCR	0xe6150064
 48#define DSI1PCKCR	0xe6150068
 49#define DSI0PHYCR	0xe615006C
 50#define DSI1PHYCR	0xe6150070
 51#define PLLECR		0xe61500d0
 52#define PLL0CR		0xe61500d8
 53#define PLL1CR		0xe6150028
 54#define PLL2CR		0xe615002c
 55#define PLL3CR		0xe61500dc
 56#define SMSTPCR0	0xe6150130
 57#define SMSTPCR1	0xe6150134
 58#define SMSTPCR2	0xe6150138
 59#define SMSTPCR3	0xe615013c
 60#define SMSTPCR4	0xe6150140
 61#define SMSTPCR5	0xe6150144
 62#define CKSCR		0xe61500c0
 63
 64/* Fixed 32 KHz root clock from EXTALR pin */
 65static struct clk r_clk = {
 66	.rate           = 32768,
 67};
 68
 69/*
 70 * 26MHz default rate for the EXTAL1 root input clock.
 71 * If needed, reset this with clk_set_rate() from the platform code.
 72 */
 73struct clk sh73a0_extal1_clk = {
 74	.rate		= 26000000,
 75};
 76
 77/*
 78 * 48MHz default rate for the EXTAL2 root input clock.
 79 * If needed, reset this with clk_set_rate() from the platform code.
 80 */
 81struct clk sh73a0_extal2_clk = {
 82	.rate		= 48000000,
 83};
 84
 85/* A fixed divide-by-2 block */
 86static unsigned long div2_recalc(struct clk *clk)
 87{
 88	return clk->parent->rate / 2;
 89}
 90
 91static struct sh_clk_ops div2_clk_ops = {
 92	.recalc		= div2_recalc,
 93};
 94
 95static unsigned long div7_recalc(struct clk *clk)
 96{
 97	return clk->parent->rate / 7;
 98}
 99
100static struct sh_clk_ops div7_clk_ops = {
101	.recalc		= div7_recalc,
102};
103
104static unsigned long div13_recalc(struct clk *clk)
105{
106	return clk->parent->rate / 13;
107}
108
109static struct sh_clk_ops div13_clk_ops = {
110	.recalc		= div13_recalc,
111};
112
113/* Divide extal1 by two */
114static struct clk extal1_div2_clk = {
115	.ops		= &div2_clk_ops,
116	.parent		= &sh73a0_extal1_clk,
117};
118
119/* Divide extal2 by two */
120static struct clk extal2_div2_clk = {
121	.ops		= &div2_clk_ops,
122	.parent		= &sh73a0_extal2_clk,
123};
124
125static struct sh_clk_ops main_clk_ops = {
126	.recalc		= followparent_recalc,
127};
128
129/* Main clock */
130static struct clk main_clk = {
131	.ops		= &main_clk_ops,
132};
133
134/* Divide Main clock by two */
135static struct clk main_div2_clk = {
136	.ops		= &div2_clk_ops,
137	.parent		= &main_clk,
138};
139
140/* PLL0, PLL1, PLL2, PLL3 */
141static unsigned long pll_recalc(struct clk *clk)
142{
143	unsigned long mult = 1;
144
145	if (__raw_readl(PLLECR) & (1 << clk->enable_bit)) {
146		mult = (((__raw_readl(clk->enable_reg) >> 24) & 0x3f) + 1);
147		/* handle CFG bit for PLL1 and PLL2 */
148		switch (clk->enable_bit) {
149		case 1:
150		case 2:
151			if (__raw_readl(clk->enable_reg) & (1 << 20))
152				mult *= 2;
153		}
154	}
155
156	return clk->parent->rate * mult;
157}
158
159static struct sh_clk_ops pll_clk_ops = {
160	.recalc		= pll_recalc,
161};
162
163static struct clk pll0_clk = {
164	.ops		= &pll_clk_ops,
165	.flags		= CLK_ENABLE_ON_INIT,
166	.parent		= &main_clk,
167	.enable_reg	= (void __iomem *)PLL0CR,
168	.enable_bit	= 0,
169};
170
171static struct clk pll1_clk = {
172	.ops		= &pll_clk_ops,
173	.flags		= CLK_ENABLE_ON_INIT,
174	.parent		= &main_clk,
175	.enable_reg	= (void __iomem *)PLL1CR,
176	.enable_bit	= 1,
177};
178
179static struct clk pll2_clk = {
180	.ops		= &pll_clk_ops,
181	.flags		= CLK_ENABLE_ON_INIT,
182	.parent		= &main_clk,
183	.enable_reg	= (void __iomem *)PLL2CR,
184	.enable_bit	= 2,
185};
186
187static struct clk pll3_clk = {
188	.ops		= &pll_clk_ops,
189	.flags		= CLK_ENABLE_ON_INIT,
190	.parent		= &main_clk,
191	.enable_reg	= (void __iomem *)PLL3CR,
192	.enable_bit	= 3,
193};
194
195/* Divide PLL */
196static struct clk pll1_div2_clk = {
197	.ops		= &div2_clk_ops,
198	.parent		= &pll1_clk,
199};
200
201static struct clk pll1_div7_clk = {
202	.ops		= &div7_clk_ops,
203	.parent		= &pll1_clk,
204};
205
206static struct clk pll1_div13_clk = {
207	.ops		= &div13_clk_ops,
208	.parent		= &pll1_clk,
209};
210
211/* External input clock */
212struct clk sh73a0_extcki_clk = {
213};
214
215struct clk sh73a0_extalr_clk = {
216};
217
218static struct clk *main_clks[] = {
219	&r_clk,
220	&sh73a0_extal1_clk,
221	&sh73a0_extal2_clk,
222	&extal1_div2_clk,
223	&extal2_div2_clk,
224	&main_clk,
225	&main_div2_clk,
226	&pll0_clk,
227	&pll1_clk,
228	&pll2_clk,
229	&pll3_clk,
230	&pll1_div2_clk,
231	&pll1_div7_clk,
232	&pll1_div13_clk,
233	&sh73a0_extcki_clk,
234	&sh73a0_extalr_clk,
235};
236
237static void div4_kick(struct clk *clk)
238{
239	unsigned long value;
240
241	/* set KICK bit in FRQCRB to update hardware setting */
242	value = __raw_readl(FRQCRB);
243	value |= (1 << 31);
244	__raw_writel(value, FRQCRB);
245}
246
247static int divisors[] = { 2, 3, 4, 6, 8, 12, 16, 18,
248			  24, 0, 36, 48, 7 };
249
250static struct clk_div_mult_table div4_div_mult_table = {
251	.divisors = divisors,
252	.nr_divisors = ARRAY_SIZE(divisors),
253};
254
255static struct clk_div4_table div4_table = {
256	.div_mult_table = &div4_div_mult_table,
257	.kick = div4_kick,
258};
259
260enum { DIV4_I, DIV4_ZG, DIV4_M3, DIV4_B, DIV4_M1, DIV4_M2,
261	DIV4_Z, DIV4_ZTR, DIV4_ZT, DIV4_ZX, DIV4_HP, DIV4_NR };
262
263#define DIV4(_reg, _bit, _mask, _flags) \
264	SH_CLK_DIV4(&pll1_clk, _reg, _bit, _mask, _flags)
265
266static struct clk div4_clks[DIV4_NR] = {
267	[DIV4_I] = DIV4(FRQCRA, 20, 0xfff, CLK_ENABLE_ON_INIT),
268	[DIV4_ZG] = DIV4(FRQCRA, 16, 0xbff, CLK_ENABLE_ON_INIT),
269	[DIV4_M3] = DIV4(FRQCRA, 12, 0xfff, CLK_ENABLE_ON_INIT),
270	[DIV4_B] = DIV4(FRQCRA, 8, 0xfff, CLK_ENABLE_ON_INIT),
271	[DIV4_M1] = DIV4(FRQCRA, 4, 0xfff, 0),
272	[DIV4_M2] = DIV4(FRQCRA, 0, 0xfff, 0),
273	[DIV4_Z] = DIV4(FRQCRB, 24, 0xbff, 0),
274	[DIV4_ZTR] = DIV4(FRQCRB, 20, 0xfff, 0),
275	[DIV4_ZT] = DIV4(FRQCRB, 16, 0xfff, 0),
276	[DIV4_ZX] = DIV4(FRQCRB, 12, 0xfff, 0),
277	[DIV4_HP] = DIV4(FRQCRB, 4, 0xfff, 0),
278};
279
280enum { DIV6_VCK1, DIV6_VCK2, DIV6_VCK3, DIV6_ZB1,
281	DIV6_FLCTL, DIV6_SDHI0, DIV6_SDHI1, DIV6_SDHI2,
282	DIV6_FSIA, DIV6_FSIB, DIV6_SUB,
283	DIV6_SPUA, DIV6_SPUV, DIV6_MSU,
284	DIV6_HSI,  DIV6_MFG1, DIV6_MFG2,
285	DIV6_DSIT, DIV6_DSI0P, DIV6_DSI1P,
286	DIV6_NR };
287
288static struct clk *vck_parent[8] = {
289	[0] = &pll1_div2_clk,
290	[1] = &pll2_clk,
291	[2] = &sh73a0_extcki_clk,
292	[3] = &sh73a0_extal2_clk,
293	[4] = &main_div2_clk,
294	[5] = &sh73a0_extalr_clk,
295	[6] = &main_clk,
296};
297
298static struct clk *pll_parent[4] = {
299	[0] = &pll1_div2_clk,
300	[1] = &pll2_clk,
301	[2] = &pll1_div13_clk,
302};
303
304static struct clk *hsi_parent[4] = {
305	[0] = &pll1_div2_clk,
306	[1] = &pll2_clk,
307	[2] = &pll1_div7_clk,
308};
309
310static struct clk *pll_extal2_parent[] = {
311	[0] = &pll1_div2_clk,
312	[1] = &pll2_clk,
313	[2] = &sh73a0_extal2_clk,
314	[3] = &sh73a0_extal2_clk,
315};
316
317static struct clk *dsi_parent[8] = {
318	[0] = &pll1_div2_clk,
319	[1] = &pll2_clk,
320	[2] = &main_clk,
321	[3] = &sh73a0_extal2_clk,
322	[4] = &sh73a0_extcki_clk,
323};
324
325static struct clk div6_clks[DIV6_NR] = {
326	[DIV6_VCK1] = SH_CLK_DIV6_EXT(VCLKCR1, 0,
327			vck_parent, ARRAY_SIZE(vck_parent), 12, 3),
328	[DIV6_VCK2] = SH_CLK_DIV6_EXT(VCLKCR2, 0,
329			vck_parent, ARRAY_SIZE(vck_parent), 12, 3),
330	[DIV6_VCK3] = SH_CLK_DIV6_EXT(VCLKCR3, 0,
331			vck_parent, ARRAY_SIZE(vck_parent), 12, 3),
332	[DIV6_ZB1] = SH_CLK_DIV6_EXT(ZBCKCR, CLK_ENABLE_ON_INIT,
333			pll_parent, ARRAY_SIZE(pll_parent), 7, 1),
334	[DIV6_FLCTL] = SH_CLK_DIV6_EXT(FLCKCR, 0,
335			pll_parent, ARRAY_SIZE(pll_parent), 7, 1),
336	[DIV6_SDHI0] = SH_CLK_DIV6_EXT(SD0CKCR, 0,
337			pll_parent, ARRAY_SIZE(pll_parent), 6, 2),
338	[DIV6_SDHI1] = SH_CLK_DIV6_EXT(SD1CKCR, 0,
339			pll_parent, ARRAY_SIZE(pll_parent), 6, 2),
340	[DIV6_SDHI2] = SH_CLK_DIV6_EXT(SD2CKCR, 0,
341			pll_parent, ARRAY_SIZE(pll_parent), 6, 2),
342	[DIV6_FSIA] = SH_CLK_DIV6_EXT(FSIACKCR, 0,
343			pll_parent, ARRAY_SIZE(pll_parent), 6, 1),
344	[DIV6_FSIB] = SH_CLK_DIV6_EXT(FSIBCKCR, 0,
345			pll_parent, ARRAY_SIZE(pll_parent), 6, 1),
346	[DIV6_SUB] = SH_CLK_DIV6_EXT(SUBCKCR, 0,
347			pll_extal2_parent, ARRAY_SIZE(pll_extal2_parent), 6, 2),
348	[DIV6_SPUA] = SH_CLK_DIV6_EXT(SPUACKCR, 0,
349			pll_extal2_parent, ARRAY_SIZE(pll_extal2_parent), 6, 2),
350	[DIV6_SPUV] = SH_CLK_DIV6_EXT(SPUVCKCR, 0,
351			pll_extal2_parent, ARRAY_SIZE(pll_extal2_parent), 6, 2),
352	[DIV6_MSU] = SH_CLK_DIV6_EXT(MSUCKCR, 0,
353			pll_parent, ARRAY_SIZE(pll_parent), 7, 1),
354	[DIV6_HSI] = SH_CLK_DIV6_EXT(HSICKCR, 0,
355			hsi_parent, ARRAY_SIZE(hsi_parent), 6, 2),
356	[DIV6_MFG1] = SH_CLK_DIV6_EXT(MFCK1CR, 0,
357			pll_parent, ARRAY_SIZE(pll_parent), 7, 1),
358	[DIV6_MFG2] = SH_CLK_DIV6_EXT(MFCK2CR, 0,
359			pll_parent, ARRAY_SIZE(pll_parent), 7, 1),
360	[DIV6_DSIT] = SH_CLK_DIV6_EXT(DSITCKCR, 0,
361			pll_parent, ARRAY_SIZE(pll_parent), 7, 1),
362	[DIV6_DSI0P] = SH_CLK_DIV6_EXT(DSI0PCKCR, 0,
363			dsi_parent, ARRAY_SIZE(dsi_parent), 12, 3),
364	[DIV6_DSI1P] = SH_CLK_DIV6_EXT(DSI1PCKCR, 0,
365			dsi_parent, ARRAY_SIZE(dsi_parent), 12, 3),
366};
367
368/* DSI DIV */
369static unsigned long dsiphy_recalc(struct clk *clk)
370{
371	u32 value;
372
373	value = __raw_readl(clk->mapping->base);
374
375	/* FIXME */
376	if (!(value & 0x000B8000))
377		return clk->parent->rate;
378
379	value &= 0x3f;
380	value += 1;
381
382	if ((value < 12) ||
383	    (value > 33)) {
384		pr_err("DSIPHY has wrong value (%d)", value);
385		return 0;
386	}
387
388	return clk->parent->rate / value;
389}
390
391static long dsiphy_round_rate(struct clk *clk, unsigned long rate)
392{
393	return clk_rate_mult_range_round(clk, 12, 33, rate);
394}
395
396static void dsiphy_disable(struct clk *clk)
397{
398	u32 value;
399
400	value = __raw_readl(clk->mapping->base);
401	value &= ~0x000B8000;
402
403	__raw_writel(value , clk->mapping->base);
404}
405
406static int dsiphy_enable(struct clk *clk)
407{
408	u32 value;
409	int multi;
410
411	value = __raw_readl(clk->mapping->base);
412	multi = (value & 0x3f) + 1;
413
414	if ((multi < 12) || (multi > 33))
415		return -EIO;
416
417	__raw_writel(value | 0x000B8000, clk->mapping->base);
418
419	return 0;
420}
421
422static int dsiphy_set_rate(struct clk *clk, unsigned long rate)
423{
424	u32 value;
425	int idx;
426
427	idx = rate / clk->parent->rate;
428	if ((idx < 12) || (idx > 33))
429		return -EINVAL;
430
431	idx += -1;
432
433	value = __raw_readl(clk->mapping->base);
434	value = (value & ~0x3f) + idx;
435
436	__raw_writel(value, clk->mapping->base);
437
438	return 0;
439}
440
441static struct sh_clk_ops dsiphy_clk_ops = {
442	.recalc		= dsiphy_recalc,
443	.round_rate	= dsiphy_round_rate,
444	.set_rate	= dsiphy_set_rate,
445	.enable		= dsiphy_enable,
446	.disable	= dsiphy_disable,
447};
448
449static struct clk_mapping dsi0phy_clk_mapping = {
450	.phys	= DSI0PHYCR,
451	.len	= 4,
452};
453
454static struct clk_mapping dsi1phy_clk_mapping = {
455	.phys	= DSI1PHYCR,
456	.len	= 4,
457};
458
459static struct clk dsi0phy_clk = {
460	.ops		= &dsiphy_clk_ops,
461	.parent		= &div6_clks[DIV6_DSI0P], /* late install */
462	.mapping	= &dsi0phy_clk_mapping,
463};
464
465static struct clk dsi1phy_clk = {
466	.ops		= &dsiphy_clk_ops,
467	.parent		= &div6_clks[DIV6_DSI1P], /* late install */
468	.mapping	= &dsi1phy_clk_mapping,
469};
470
471static struct clk *late_main_clks[] = {
472	&dsi0phy_clk,
473	&dsi1phy_clk,
474};
475
476enum { MSTP001,
477	MSTP129, MSTP128, MSTP127, MSTP126, MSTP125, MSTP118, MSTP116, MSTP100,
478	MSTP219, MSTP218,
479	MSTP207, MSTP206, MSTP204, MSTP203, MSTP202, MSTP201, MSTP200,
480	MSTP331, MSTP329, MSTP325, MSTP323,
481	MSTP314, MSTP313, MSTP312, MSTP311,
482	MSTP303, MSTP302, MSTP301, MSTP300,
483	MSTP411, MSTP410, MSTP403,
484	MSTP_NR };
485
486#define MSTP(_parent, _reg, _bit, _flags) \
487	SH_CLK_MSTP32(_parent, _reg, _bit, _flags)
488
489static struct clk mstp_clks[MSTP_NR] = {
490	[MSTP001] = MSTP(&div4_clks[DIV4_HP], SMSTPCR0, 1, 0), /* IIC2 */
491	[MSTP129] = MSTP(&div4_clks[DIV4_B], SMSTPCR1, 29, 0), /* CEU1 */
492	[MSTP128] = MSTP(&div4_clks[DIV4_B], SMSTPCR1, 28, 0), /* CSI2-RX1 */
493	[MSTP127] = MSTP(&div4_clks[DIV4_B], SMSTPCR1, 27, 0), /* CEU0 */
494	[MSTP126] = MSTP(&div4_clks[DIV4_B], SMSTPCR1, 26, 0), /* CSI2-RX0 */
495	[MSTP125] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR1, 25, 0), /* TMU0 */
496	[MSTP118] = MSTP(&div4_clks[DIV4_B], SMSTPCR1, 18, 0), /* DSITX0 */
497	[MSTP116] = MSTP(&div4_clks[DIV4_HP], SMSTPCR1, 16, 0), /* IIC0 */
498	[MSTP100] = MSTP(&div4_clks[DIV4_B], SMSTPCR1, 0, 0), /* LCDC0 */
499	[MSTP219] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR2, 19, 0), /* SCIFA7 */
500	[MSTP218] = MSTP(&div4_clks[DIV4_HP], SMSTPCR2, 18, 0), /* SY-DMAC */
501	[MSTP207] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR2, 7, 0), /* SCIFA5 */
502	[MSTP206] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR2, 6, 0), /* SCIFB */
503	[MSTP204] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR2, 4, 0), /* SCIFA0 */
504	[MSTP203] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR2, 3, 0), /* SCIFA1 */
505	[MSTP202] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR2, 2, 0), /* SCIFA2 */
506	[MSTP201] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR2, 1, 0), /* SCIFA3 */
507	[MSTP200] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR2, 0, 0), /* SCIFA4 */
508	[MSTP331] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR3, 31, 0), /* SCIFA6 */
509	[MSTP329] = MSTP(&r_clk, SMSTPCR3, 29, 0), /* CMT10 */
510	[MSTP325] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR3, 25, 0), /* IrDA */
511	[MSTP323] = MSTP(&div4_clks[DIV4_HP], SMSTPCR3, 23, 0), /* IIC1 */
512	[MSTP314] = MSTP(&div6_clks[DIV6_SDHI0], SMSTPCR3, 14, 0), /* SDHI0 */
513	[MSTP313] = MSTP(&div6_clks[DIV6_SDHI1], SMSTPCR3, 13, 0), /* SDHI1 */
514	[MSTP312] = MSTP(&div4_clks[DIV4_HP], SMSTPCR3, 12, 0), /* MMCIF0 */
515	[MSTP311] = MSTP(&div6_clks[DIV6_SDHI2], SMSTPCR3, 11, 0), /* SDHI2 */
516	[MSTP303] = MSTP(&main_div2_clk, SMSTPCR3, 3, 0), /* TPU1 */
517	[MSTP302] = MSTP(&main_div2_clk, SMSTPCR3, 2, 0), /* TPU2 */
518	[MSTP301] = MSTP(&main_div2_clk, SMSTPCR3, 1, 0), /* TPU3 */
519	[MSTP300] = MSTP(&main_div2_clk, SMSTPCR3, 0, 0), /* TPU4 */
520	[MSTP411] = MSTP(&div4_clks[DIV4_HP], SMSTPCR4, 11, 0), /* IIC3 */
521	[MSTP410] = MSTP(&div4_clks[DIV4_HP], SMSTPCR4, 10, 0), /* IIC4 */
522	[MSTP403] = MSTP(&r_clk, SMSTPCR4, 3, 0), /* KEYSC */
523};
524
525static struct clk_lookup lookups[] = {
526	/* main clocks */
527	CLKDEV_CON_ID("r_clk", &r_clk),
528
529	/* DIV6 clocks */
530	CLKDEV_CON_ID("vck1_clk", &div6_clks[DIV6_VCK1]),
531	CLKDEV_CON_ID("vck2_clk", &div6_clks[DIV6_VCK2]),
532	CLKDEV_CON_ID("vck3_clk", &div6_clks[DIV6_VCK3]),
533	CLKDEV_CON_ID("sdhi0_clk", &div6_clks[DIV6_SDHI0]),
534	CLKDEV_CON_ID("sdhi1_clk", &div6_clks[DIV6_SDHI1]),
535	CLKDEV_CON_ID("sdhi2_clk", &div6_clks[DIV6_SDHI2]),
536	CLKDEV_ICK_ID("dsit_clk", "sh-mipi-dsi.0", &div6_clks[DIV6_DSIT]),
537	CLKDEV_ICK_ID("dsit_clk", "sh-mipi-dsi.1", &div6_clks[DIV6_DSIT]),
538	CLKDEV_ICK_ID("dsip_clk", "sh-mipi-dsi.0", &div6_clks[DIV6_DSI0P]),
539	CLKDEV_ICK_ID("dsip_clk", "sh-mipi-dsi.1", &div6_clks[DIV6_DSI1P]),
540	CLKDEV_ICK_ID("dsiphy_clk", "sh-mipi-dsi.0", &dsi0phy_clk),
541	CLKDEV_ICK_ID("dsiphy_clk", "sh-mipi-dsi.1", &dsi1phy_clk),
542
543	/* MSTP32 clocks */
544	CLKDEV_DEV_ID("i2c-sh_mobile.2", &mstp_clks[MSTP001]), /* I2C2 */
545	CLKDEV_DEV_ID("sh_mobile_ceu.1", &mstp_clks[MSTP129]), /* CEU1 */
546	CLKDEV_DEV_ID("sh-mobile-csi2.1", &mstp_clks[MSTP128]), /* CSI2-RX1 */
547	CLKDEV_DEV_ID("sh_mobile_ceu.0", &mstp_clks[MSTP127]), /* CEU0 */
548	CLKDEV_DEV_ID("sh-mobile-csi2.0", &mstp_clks[MSTP126]), /* CSI2-RX0 */
549	CLKDEV_DEV_ID("sh_tmu.0", &mstp_clks[MSTP125]), /* TMU00 */
550	CLKDEV_DEV_ID("sh_tmu.1", &mstp_clks[MSTP125]), /* TMU01 */
551	CLKDEV_DEV_ID("sh-mipi-dsi.0", &mstp_clks[MSTP118]), /* DSITX */
552	CLKDEV_DEV_ID("i2c-sh_mobile.0", &mstp_clks[MSTP116]), /* I2C0 */
553	CLKDEV_DEV_ID("sh_mobile_lcdc_fb.0", &mstp_clks[MSTP100]), /* LCDC0 */
554	CLKDEV_DEV_ID("sh-sci.7", &mstp_clks[MSTP219]), /* SCIFA7 */
555	CLKDEV_DEV_ID("sh-dma-engine.0", &mstp_clks[MSTP218]), /* SY-DMAC */
556	CLKDEV_DEV_ID("sh-sci.5", &mstp_clks[MSTP207]), /* SCIFA5 */
557	CLKDEV_DEV_ID("sh-sci.8", &mstp_clks[MSTP206]), /* SCIFB */
558	CLKDEV_DEV_ID("sh-sci.0", &mstp_clks[MSTP204]), /* SCIFA0 */
559	CLKDEV_DEV_ID("sh-sci.1", &mstp_clks[MSTP203]), /* SCIFA1 */
560	CLKDEV_DEV_ID("sh-sci.2", &mstp_clks[MSTP202]), /* SCIFA2 */
561	CLKDEV_DEV_ID("sh-sci.3", &mstp_clks[MSTP201]), /* SCIFA3 */
562	CLKDEV_DEV_ID("sh-sci.4", &mstp_clks[MSTP200]), /* SCIFA4 */
563	CLKDEV_DEV_ID("sh-sci.6", &mstp_clks[MSTP331]), /* SCIFA6 */
564	CLKDEV_DEV_ID("sh_cmt.10", &mstp_clks[MSTP329]), /* CMT10 */
565	CLKDEV_DEV_ID("sh_irda.0", &mstp_clks[MSTP325]), /* IrDA */
566	CLKDEV_DEV_ID("i2c-sh_mobile.1", &mstp_clks[MSTP323]), /* I2C1 */
567	CLKDEV_DEV_ID("sh_mobile_sdhi.0", &mstp_clks[MSTP314]), /* SDHI0 */
568	CLKDEV_DEV_ID("sh_mobile_sdhi.1", &mstp_clks[MSTP313]), /* SDHI1 */
569	CLKDEV_DEV_ID("sh_mmcif.0", &mstp_clks[MSTP312]), /* MMCIF0 */
570	CLKDEV_DEV_ID("sh_mobile_sdhi.2", &mstp_clks[MSTP311]), /* SDHI2 */
571	CLKDEV_DEV_ID("leds-renesas-tpu.12", &mstp_clks[MSTP303]), /* TPU1 */
572	CLKDEV_DEV_ID("leds-renesas-tpu.21", &mstp_clks[MSTP302]), /* TPU2 */
573	CLKDEV_DEV_ID("leds-renesas-tpu.30", &mstp_clks[MSTP301]), /* TPU3 */
574	CLKDEV_DEV_ID("leds-renesas-tpu.41", &mstp_clks[MSTP300]), /* TPU4 */
575	CLKDEV_DEV_ID("i2c-sh_mobile.3", &mstp_clks[MSTP411]), /* I2C3 */
576	CLKDEV_DEV_ID("i2c-sh_mobile.4", &mstp_clks[MSTP410]), /* I2C4 */
577	CLKDEV_DEV_ID("sh_keysc.0", &mstp_clks[MSTP403]), /* KEYSC */
578};
579
580void __init sh73a0_clock_init(void)
581{
582	int k, ret = 0;
583
584	/* Set SDHI clocks to a known state */
585	__raw_writel(0x108, SD0CKCR);
586	__raw_writel(0x108, SD1CKCR);
587	__raw_writel(0x108, SD2CKCR);
588
589	/* detect main clock parent */
590	switch ((__raw_readl(CKSCR) >> 28) & 0x03) {
591	case 0:
592		main_clk.parent = &sh73a0_extal1_clk;
593		break;
594	case 1:
595		main_clk.parent = &extal1_div2_clk;
596		break;
597	case 2:
598		main_clk.parent = &sh73a0_extal2_clk;
599		break;
600	case 3:
601		main_clk.parent = &extal2_div2_clk;
602		break;
603	}
604
605	for (k = 0; !ret && (k < ARRAY_SIZE(main_clks)); k++)
606		ret = clk_register(main_clks[k]);
607
608	if (!ret)
609		ret = sh_clk_div4_register(div4_clks, DIV4_NR, &div4_table);
610
611	if (!ret)
612		ret = sh_clk_div6_reparent_register(div6_clks, DIV6_NR);
613
614	if (!ret)
615		ret = sh_clk_mstp32_register(mstp_clks, MSTP_NR);
616
617	for (k = 0; !ret && (k < ARRAY_SIZE(late_main_clks)); k++)
618		ret = clk_register(late_main_clks[k]);
619
620	clkdev_add_table(lookups, ARRAY_SIZE(lookups));
621
622	if (!ret)
623		shmobile_clk_init();
624	else
625		panic("failed to setup sh73a0 clocks\n");
626}