clock-sh7372.c 21.8 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
/*
 * SH7372 clock framework support
 *
 * Copyright (C) 2010 Magnus Damm
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/io.h>
#include <linux/sh_clk.h>
23
#include <linux/clkdev.h>
24
#include <mach/clock.h>
25 26 27
#include <mach/common.h>

/* SH7372 registers */
28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57
#define FRQCRA		IOMEM(0xe6150000)
#define FRQCRB		IOMEM(0xe6150004)
#define FRQCRC		IOMEM(0xe61500e0)
#define FRQCRD		IOMEM(0xe61500e4)
#define VCLKCR1		IOMEM(0xe6150008)
#define VCLKCR2		IOMEM(0xe615000c)
#define VCLKCR3		IOMEM(0xe615001c)
#define FMSICKCR	IOMEM(0xe6150010)
#define FMSOCKCR	IOMEM(0xe6150014)
#define FSIACKCR	IOMEM(0xe6150018)
#define FSIBCKCR	IOMEM(0xe6150090)
#define SUBCKCR		IOMEM(0xe6150080)
#define SPUCKCR		IOMEM(0xe6150084)
#define VOUCKCR		IOMEM(0xe6150088)
#define HDMICKCR	IOMEM(0xe6150094)
#define DSITCKCR	IOMEM(0xe6150060)
#define DSI0PCKCR	IOMEM(0xe6150064)
#define DSI1PCKCR	IOMEM(0xe6150098)
#define PLLC01CR	IOMEM(0xe6150028)
#define PLLC2CR		IOMEM(0xe615002c)
#define RMSTPCR0	IOMEM(0xe6150110)
#define RMSTPCR1	IOMEM(0xe6150114)
#define RMSTPCR2	IOMEM(0xe6150118)
#define RMSTPCR3	IOMEM(0xe615011c)
#define RMSTPCR4	IOMEM(0xe6150120)
#define SMSTPCR0	IOMEM(0xe6150130)
#define SMSTPCR1	IOMEM(0xe6150134)
#define SMSTPCR2	IOMEM(0xe6150138)
#define SMSTPCR3	IOMEM(0xe615013c)
#define SMSTPCR4	IOMEM(0xe6150140)
58

59 60 61
#define FSIDIVA		0xFE1F8000
#define FSIDIVB		0xFE1F8008

62
/* Platforms must set frequency on their DV_CLKI pin */
63
struct clk sh7372_dv_clki_clk = {
64 65
};

66 67 68 69 70 71 72 73 74
/* Fixed 32 KHz root clock from EXTALR pin */
static struct clk r_clk = {
	.rate           = 32768,
};

/*
 * 26MHz default rate for the EXTAL1 root input clock.
 * If needed, reset this with clk_set_rate() from the platform code.
 */
75
struct clk sh7372_extal1_clk = {
76
	.rate		= 26000000,
77 78 79 80 81 82
};

/*
 * 48MHz default rate for the EXTAL2 root input clock.
 * If needed, reset this with clk_set_rate() from the platform code.
 */
83
struct clk sh7372_extal2_clk = {
84 85 86
	.rate		= 48000000,
};

87
SH_CLK_RATIO(div2, 1, 2);
88

89 90 91 92
SH_FIXED_RATIO_CLKg(sh7372_dv_clki_div2_clk,	sh7372_dv_clki_clk,	div2);
SH_FIXED_RATIO_CLK(extal1_div2_clk,		sh7372_extal1_clk,	div2);
SH_FIXED_RATIO_CLK(extal2_div2_clk,		sh7372_extal2_clk,	div2);
SH_FIXED_RATIO_CLK(extal2_div4_clk,		extal2_div2_clk,	div2);
93 94 95 96 97 98 99 100 101 102 103 104

/* PLLC0 and PLLC1 */
static unsigned long pllc01_recalc(struct clk *clk)
{
	unsigned long mult = 1;

	if (__raw_readl(PLLC01CR) & (1 << 14))
		mult = (((__raw_readl(clk->enable_reg) >> 24) & 0x3f) + 1) * 2;

	return clk->parent->rate * mult;
}

105
static struct sh_clk_ops pllc01_clk_ops = {
106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123
	.recalc		= pllc01_recalc,
};

static struct clk pllc0_clk = {
	.ops		= &pllc01_clk_ops,
	.flags		= CLK_ENABLE_ON_INIT,
	.parent		= &extal1_div2_clk,
	.enable_reg	= (void __iomem *)FRQCRC,
};

static struct clk pllc1_clk = {
	.ops		= &pllc01_clk_ops,
	.flags		= CLK_ENABLE_ON_INIT,
	.parent		= &extal1_div2_clk,
	.enable_reg	= (void __iomem *)FRQCRA,
};

/* Divide PLLC1 by two */
124
SH_FIXED_RATIO_CLK(pllc1_div2_clk,	pllc1_clk,	div2);
125 126

/* PLLC2 */
127 128 129 130 131

/* Indices are important - they are the actual src selecting values */
static struct clk *pllc2_parent[] = {
	[0] = &extal1_div2_clk,
	[1] = &extal2_div2_clk,
132
	[2] = &sh7372_dv_clki_div2_clk,
133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155
};

/* Only multipliers 20 * 2 to 46 * 2 are valid, last entry for CPUFREQ_TABLE_END */
static struct cpufreq_frequency_table pllc2_freq_table[29];

static void pllc2_table_rebuild(struct clk *clk)
{
	int i;

	/* Initialise PLLC2 frequency table */
	for (i = 0; i < ARRAY_SIZE(pllc2_freq_table) - 2; i++) {
		pllc2_freq_table[i].frequency = clk->parent->rate * (i + 20) * 2;
		pllc2_freq_table[i].index = i;
	}

	/* This is a special entry - switching PLL off makes it a repeater */
	pllc2_freq_table[i].frequency = clk->parent->rate;
	pllc2_freq_table[i].index = i;

	pllc2_freq_table[++i].frequency = CPUFREQ_TABLE_END;
	pllc2_freq_table[i].index = i;
}

156 157 158 159
static unsigned long pllc2_recalc(struct clk *clk)
{
	unsigned long mult = 1;

160 161 162 163 164 165
	pllc2_table_rebuild(clk);

	/*
	 * If the PLL is off, mult == 1, clk->rate will be updated in
	 * pllc2_enable().
	 */
166 167 168 169 170 171
	if (__raw_readl(PLLC2CR) & (1 << 31))
		mult = (((__raw_readl(PLLC2CR) >> 24) & 0x3f) + 1) * 2;

	return clk->parent->rate * mult;
}

172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198
static long pllc2_round_rate(struct clk *clk, unsigned long rate)
{
	return clk_rate_table_round(clk, clk->freq_table, rate);
}

static int pllc2_enable(struct clk *clk)
{
	int i;

	__raw_writel(__raw_readl(PLLC2CR) | 0x80000000, PLLC2CR);

	for (i = 0; i < 100; i++)
		if (__raw_readl(PLLC2CR) & 0x80000000) {
			clk->rate = pllc2_recalc(clk);
			return 0;
		}

	pr_err("%s(): timeout!\n", __func__);

	return -ETIMEDOUT;
}

static void pllc2_disable(struct clk *clk)
{
	__raw_writel(__raw_readl(PLLC2CR) & ~0x80000000, PLLC2CR);
}

199
static int pllc2_set_rate(struct clk *clk, unsigned long rate)
200 201 202 203 204 205 206 207
{
	unsigned long value;
	int idx;

	idx = clk_rate_table_find(clk, clk->freq_table, rate);
	if (idx < 0)
		return idx;

208 209
	if (rate == clk->parent->rate)
		return -EINVAL;
210 211 212

	value = __raw_readl(PLLC2CR) & ~(0x3f << 24);

213 214 215
	__raw_writel(value | ((idx + 19) << 24), PLLC2CR);

	clk->rate = clk->freq_table[idx].frequency;
216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249

	return 0;
}

static int pllc2_set_parent(struct clk *clk, struct clk *parent)
{
	u32 value;
	int ret, i;

	if (!clk->parent_table || !clk->parent_num)
		return -EINVAL;

	/* Search the parent */
	for (i = 0; i < clk->parent_num; i++)
		if (clk->parent_table[i] == parent)
			break;

	if (i == clk->parent_num)
		return -ENODEV;

	ret = clk_reparent(clk, parent);
	if (ret < 0)
		return ret;

	value = __raw_readl(PLLC2CR) & ~(3 << 6);

	__raw_writel(value | (i << 6), PLLC2CR);

	/* Rebiuld the frequency table */
	pllc2_table_rebuild(clk);

	return 0;
}

250
static struct sh_clk_ops pllc2_clk_ops = {
251
	.recalc		= pllc2_recalc,
252 253 254 255 256
	.round_rate	= pllc2_round_rate,
	.set_rate	= pllc2_set_rate,
	.enable		= pllc2_enable,
	.disable	= pllc2_disable,
	.set_parent	= pllc2_set_parent,
257 258
};

259
struct clk sh7372_pllc2_clk = {
260 261
	.ops		= &pllc2_clk_ops,
	.parent		= &extal1_div2_clk,
262
	.freq_table	= pllc2_freq_table,
263
	.nr_freqs	= ARRAY_SIZE(pllc2_freq_table) - 1,
264 265
	.parent_table	= pllc2_parent,
	.parent_num	= ARRAY_SIZE(pllc2_parent),
266 267
};

268
/* External input clock (pin name: FSIACK/FSIBCK ) */
269
static struct clk fsiack_clk = {
270 271
};

272
static struct clk fsibck_clk = {
273 274
};

275
static struct clk *main_clks[] = {
276
	&sh7372_dv_clki_clk,
277
	&r_clk,
278 279
	&sh7372_extal1_clk,
	&sh7372_extal2_clk,
280
	&sh7372_dv_clki_div2_clk,
281 282 283 284 285 286
	&extal1_div2_clk,
	&extal2_div2_clk,
	&extal2_div4_clk,
	&pllc0_clk,
	&pllc1_clk,
	&pllc1_div2_clk,
287
	&sh7372_pllc2_clk,
288 289
	&fsiack_clk,
	&fsibck_clk,
290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315
};

static void div4_kick(struct clk *clk)
{
	unsigned long value;

	/* set KICK bit in FRQCRB to update hardware setting */
	value = __raw_readl(FRQCRB);
	value |= (1 << 31);
	__raw_writel(value, FRQCRB);
}

static int divisors[] = { 2, 3, 4, 6, 8, 12, 16, 18,
			  24, 32, 36, 48, 0, 72, 96, 0 };

static struct clk_div_mult_table div4_div_mult_table = {
	.divisors = divisors,
	.nr_divisors = ARRAY_SIZE(divisors),
};

static struct clk_div4_table div4_table = {
	.div_mult_table = &div4_div_mult_table,
	.kick = div4_kick,
};

enum { DIV4_I, DIV4_ZG, DIV4_B, DIV4_M1, DIV4_CSIR,
316
       DIV4_ZX, DIV4_HP,
317 318 319 320 321 322
       DIV4_ISPB, DIV4_S, DIV4_ZB, DIV4_ZB3, DIV4_CP,
       DIV4_DDRP, DIV4_NR };

#define DIV4(_reg, _bit, _mask, _flags) \
  SH_CLK_DIV4(&pllc1_clk, _reg, _bit, _mask, _flags)

323
static struct clk div4_clks[DIV4_NR] = {
324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339
	[DIV4_I] = DIV4(FRQCRA, 20, 0x6fff, CLK_ENABLE_ON_INIT),
	[DIV4_ZG] = DIV4(FRQCRA, 16, 0x6fff, CLK_ENABLE_ON_INIT),
	[DIV4_B] = DIV4(FRQCRA, 8, 0x6fff, CLK_ENABLE_ON_INIT),
	[DIV4_M1] = DIV4(FRQCRA, 4, 0x6fff, CLK_ENABLE_ON_INIT),
	[DIV4_CSIR] = DIV4(FRQCRA, 0, 0x6fff, 0),
	[DIV4_ZX] = DIV4(FRQCRB, 12, 0x6fff, 0),
	[DIV4_HP] = DIV4(FRQCRB, 4, 0x6fff, 0),
	[DIV4_ISPB] = DIV4(FRQCRC, 20, 0x6fff, 0),
	[DIV4_S] = DIV4(FRQCRC, 12, 0x6fff, 0),
	[DIV4_ZB] = DIV4(FRQCRC, 8, 0x6fff, 0),
	[DIV4_ZB3] = DIV4(FRQCRC, 4, 0x6fff, 0),
	[DIV4_CP] = DIV4(FRQCRC, 0, 0x6fff, 0),
	[DIV4_DDRP] = DIV4(FRQCRD, 0, 0x677c, 0),
};

enum { DIV6_VCK1, DIV6_VCK2, DIV6_VCK3, DIV6_FMSI, DIV6_FMSO,
340
       DIV6_SUB, DIV6_SPU,
341
       DIV6_VOU, DIV6_DSIT, DIV6_DSI0P, DIV6_DSI1P,
342 343
       DIV6_NR };

344
static struct clk div6_clks[DIV6_NR] = {
345 346 347 348 349
	[DIV6_VCK1] = SH_CLK_DIV6(&pllc1_div2_clk, VCLKCR1, 0),
	[DIV6_VCK2] = SH_CLK_DIV6(&pllc1_div2_clk, VCLKCR2, 0),
	[DIV6_VCK3] = SH_CLK_DIV6(&pllc1_div2_clk, VCLKCR3, 0),
	[DIV6_FMSI] = SH_CLK_DIV6(&pllc1_div2_clk, FMSICKCR, 0),
	[DIV6_FMSO] = SH_CLK_DIV6(&pllc1_div2_clk, FMSOCKCR, 0),
350
	[DIV6_SUB] = SH_CLK_DIV6(&sh7372_extal2_clk, SUBCKCR, 0),
351 352 353 354 355 356 357
	[DIV6_SPU] = SH_CLK_DIV6(&pllc1_div2_clk, SPUCKCR, 0),
	[DIV6_VOU] = SH_CLK_DIV6(&pllc1_div2_clk, VOUCKCR, 0),
	[DIV6_DSIT] = SH_CLK_DIV6(&pllc1_div2_clk, DSITCKCR, 0),
	[DIV6_DSI0P] = SH_CLK_DIV6(&pllc1_div2_clk, DSI0PCKCR, 0),
	[DIV6_DSI1P] = SH_CLK_DIV6(&pllc1_div2_clk, DSI1PCKCR, 0),
};

358
enum { DIV6_HDMI, DIV6_FSIA, DIV6_FSIB, DIV6_REPARENT_NR };
359 360 361 362

/* Indices are important - they are the actual src selecting values */
static struct clk *hdmi_parent[] = {
	[0] = &pllc1_div2_clk,
363 364
	[1] = &sh7372_pllc2_clk,
	[2] = &sh7372_dv_clki_clk,
365 366 367
	[3] = NULL,	/* pllc2_div4 not implemented yet */
};

368 369 370
static struct clk *fsiackcr_parent[] = {
	[0] = &pllc1_div2_clk,
	[1] = &sh7372_pllc2_clk,
371
	[2] = &fsiack_clk, /* external input for FSI A */
372 373 374 375 376 377
	[3] = NULL,	/* setting prohibited */
};

static struct clk *fsibckcr_parent[] = {
	[0] = &pllc1_div2_clk,
	[1] = &sh7372_pllc2_clk,
378
	[2] = &fsibck_clk, /* external input for FSI B */
379 380 381
	[3] = NULL,	/* setting prohibited */
};

382
static struct clk div6_reparent_clks[DIV6_REPARENT_NR] = {
383
	[DIV6_HDMI] = SH_CLK_DIV6_EXT(HDMICKCR, 0,
384
				      hdmi_parent, ARRAY_SIZE(hdmi_parent), 6, 2),
385
	[DIV6_FSIA] = SH_CLK_DIV6_EXT(FSIACKCR, 0,
386
				      fsiackcr_parent, ARRAY_SIZE(fsiackcr_parent), 6, 2),
387
	[DIV6_FSIB] = SH_CLK_DIV6_EXT(FSIBCKCR, 0,
388
				      fsibckcr_parent, ARRAY_SIZE(fsibckcr_parent), 6, 2),
389 390
};

391
/* FSI DIV */
392
enum { FSIDIV_A, FSIDIV_B, FSIDIV_REPARENT_NR };
393

394 395 396
static struct clk fsidivs[] = {
	[FSIDIV_A] = SH_CLK_FSIDIV(FSIDIVA, &div6_reparent_clks[DIV6_FSIA]),
	[FSIDIV_B] = SH_CLK_FSIDIV(FSIDIVB, &div6_reparent_clks[DIV6_FSIB]),
397 398
};

399
enum { MSTP001, MSTP000,
400
       MSTP131, MSTP130,
401
       MSTP129, MSTP128, MSTP127, MSTP126, MSTP125,
D
Damian 已提交
402
       MSTP118, MSTP117, MSTP116, MSTP113,
403
       MSTP106, MSTP101, MSTP100,
404
       MSTP223,
405 406
       MSTP218, MSTP217, MSTP216, MSTP214, MSTP208, MSTP207,
       MSTP206, MSTP205, MSTP204, MSTP203, MSTP202, MSTP201, MSTP200,
407
	MSTP328, MSTP323, MSTP322, MSTP315, MSTP314, MSTP313, MSTP312,
408
       MSTP423, MSTP415, MSTP413, MSTP411, MSTP410, MSTP407, MSTP406,
409
       MSTP405, MSTP404, MSTP403, MSTP400,
410 411 412 413 414 415 416
       MSTP_NR };

#define MSTP(_parent, _reg, _bit, _flags) \
  SH_CLK_MSTP32(_parent, _reg, _bit, _flags)

static struct clk mstp_clks[MSTP_NR] = {
	[MSTP001] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR0, 1, 0), /* IIC2 */
417
	[MSTP000] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR0, 0, 0), /* MSIOF0 */
418 419 420 421
	[MSTP131] = MSTP(&div4_clks[DIV4_B], SMSTPCR1, 31, 0), /* VEU3 */
	[MSTP130] = MSTP(&div4_clks[DIV4_B], SMSTPCR1, 30, 0), /* VEU2 */
	[MSTP129] = MSTP(&div4_clks[DIV4_B], SMSTPCR1, 29, 0), /* VEU1 */
	[MSTP128] = MSTP(&div4_clks[DIV4_B], SMSTPCR1, 28, 0), /* VEU0 */
422 423
	[MSTP127] = MSTP(&div4_clks[DIV4_B], SMSTPCR1, 27, 0), /* CEU */
	[MSTP126] = MSTP(&div4_clks[DIV4_B], SMSTPCR1, 26, 0), /* CSI2 */
424
	[MSTP125] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR1, 25, 0), /* TMU0 */
425 426
	[MSTP118] = MSTP(&div4_clks[DIV4_B], SMSTPCR1, 18, 0), /* DSITX */
	[MSTP117] = MSTP(&div4_clks[DIV4_B], SMSTPCR1, 17, 0), /* LCDC1 */
427
	[MSTP116] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR1, 16, 0), /* IIC0 */
D
Damian 已提交
428
	[MSTP113] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR1, 13, 0), /* MERAM */
429 430
	[MSTP106] = MSTP(&div4_clks[DIV4_B], SMSTPCR1, 6, 0), /* JPU */
	[MSTP101] = MSTP(&div4_clks[DIV4_M1], SMSTPCR1, 1, 0), /* VPU */
431
	[MSTP100] = MSTP(&div4_clks[DIV4_B], SMSTPCR1, 0, 0), /* LCDC0 */
432
	[MSTP223] = MSTP(&div6_clks[DIV6_SPU], SMSTPCR2, 23, 0), /* SPU2 */
433 434 435
	[MSTP218] = MSTP(&div4_clks[DIV4_HP], SMSTPCR2, 18, 0), /* DMAC1 */
	[MSTP217] = MSTP(&div4_clks[DIV4_HP], SMSTPCR2, 17, 0), /* DMAC2 */
	[MSTP216] = MSTP(&div4_clks[DIV4_HP], SMSTPCR2, 16, 0), /* DMAC3 */
436
	[MSTP214] = MSTP(&div4_clks[DIV4_HP], SMSTPCR2, 14, 0), /* USBDMAC */
437
	[MSTP208] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR2, 8, 0), /* MSIOF1 */
438 439
	[MSTP207] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR2, 7, 0), /* SCIFA5 */
	[MSTP206] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR2, 6, 0), /* SCIFB */
440
	[MSTP205] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR2, 5, 0), /* MSIOF2 */
441 442 443 444 445
	[MSTP204] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR2, 4, 0), /* SCIFA0 */
	[MSTP203] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR2, 3, 0), /* SCIFA1 */
	[MSTP202] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR2, 2, 0), /* SCIFA2 */
	[MSTP201] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR2, 1, 0), /* SCIFA3 */
	[MSTP200] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR2, 0, 0), /* SCIFA4 */
446
	[MSTP328] = MSTP(&div6_clks[DIV6_SPU], SMSTPCR3, 28, 0), /* FSI2 */
447 448
	[MSTP323] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR3, 23, 0), /* IIC1 */
	[MSTP322] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR3, 22, 0), /* USB0 */
449
	[MSTP315] = MSTP(&div4_clks[DIV4_HP], SMSTPCR3, 15, 0), /* FLCTL*/
450 451
	[MSTP314] = MSTP(&div4_clks[DIV4_HP], SMSTPCR3, 14, 0), /* SDHI0 */
	[MSTP313] = MSTP(&div4_clks[DIV4_HP], SMSTPCR3, 13, 0), /* SDHI1 */
452
	[MSTP312] = MSTP(&div4_clks[DIV4_HP], SMSTPCR3, 12, 0), /* MMC */
453
	[MSTP423] = MSTP(&div4_clks[DIV4_B], SMSTPCR4, 23, 0), /* DSITX1 */
454
	[MSTP415] = MSTP(&div4_clks[DIV4_HP], SMSTPCR4, 15, 0), /* SDHI2 */
455
	[MSTP413] = MSTP(&pllc1_div2_clk, SMSTPCR4, 13, 0), /* HDMI */
456 457
	[MSTP411] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR4, 11, 0), /* IIC3 */
	[MSTP410] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR4, 10, 0), /* IIC4 */
458
	[MSTP407] = MSTP(&div4_clks[DIV4_HP], SMSTPCR4, 7, 0), /* USB-DMAC1 */
459
	[MSTP406] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR4, 6, 0), /* USB1 */
460 461
	[MSTP405] = MSTP(&r_clk, SMSTPCR4, 5, 0), /* CMT4 */
	[MSTP404] = MSTP(&r_clk, SMSTPCR4, 4, 0), /* CMT3 */
462
	[MSTP403] = MSTP(&r_clk, SMSTPCR4, 3, 0), /* KEYSC */
463
	[MSTP400] = MSTP(&r_clk, SMSTPCR4, 0, 0), /* CMT2 */
464 465 466 467
};

static struct clk_lookup lookups[] = {
	/* main clocks */
468
	CLKDEV_CON_ID("dv_clki_div2_clk", &sh7372_dv_clki_div2_clk),
469
	CLKDEV_CON_ID("r_clk", &r_clk),
470 471
	CLKDEV_CON_ID("extal1", &sh7372_extal1_clk),
	CLKDEV_CON_ID("extal2", &sh7372_extal2_clk),
472 473 474 475 476 477
	CLKDEV_CON_ID("extal1_div2_clk", &extal1_div2_clk),
	CLKDEV_CON_ID("extal2_div2_clk", &extal2_div2_clk),
	CLKDEV_CON_ID("extal2_div4_clk", &extal2_div4_clk),
	CLKDEV_CON_ID("pllc0_clk", &pllc0_clk),
	CLKDEV_CON_ID("pllc1_clk", &pllc1_clk),
	CLKDEV_CON_ID("pllc1_div2_clk", &pllc1_div2_clk),
478
	CLKDEV_CON_ID("pllc2_clk", &sh7372_pllc2_clk),
479 480
	CLKDEV_CON_ID("fsiack", &fsiack_clk),
	CLKDEV_CON_ID("fsibck", &fsibck_clk),
481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505

	/* DIV4 clocks */
	CLKDEV_CON_ID("i_clk", &div4_clks[DIV4_I]),
	CLKDEV_CON_ID("zg_clk", &div4_clks[DIV4_ZG]),
	CLKDEV_CON_ID("b_clk", &div4_clks[DIV4_B]),
	CLKDEV_CON_ID("m1_clk", &div4_clks[DIV4_M1]),
	CLKDEV_CON_ID("csir_clk", &div4_clks[DIV4_CSIR]),
	CLKDEV_CON_ID("zx_clk", &div4_clks[DIV4_ZX]),
	CLKDEV_CON_ID("hp_clk", &div4_clks[DIV4_HP]),
	CLKDEV_CON_ID("ispb_clk", &div4_clks[DIV4_ISPB]),
	CLKDEV_CON_ID("s_clk", &div4_clks[DIV4_S]),
	CLKDEV_CON_ID("zb_clk", &div4_clks[DIV4_ZB]),
	CLKDEV_CON_ID("zb3_clk", &div4_clks[DIV4_ZB3]),
	CLKDEV_CON_ID("cp_clk", &div4_clks[DIV4_CP]),
	CLKDEV_CON_ID("ddrp_clk", &div4_clks[DIV4_DDRP]),

	/* DIV6 clocks */
	CLKDEV_CON_ID("vck1_clk", &div6_clks[DIV6_VCK1]),
	CLKDEV_CON_ID("vck2_clk", &div6_clks[DIV6_VCK2]),
	CLKDEV_CON_ID("vck3_clk", &div6_clks[DIV6_VCK3]),
	CLKDEV_CON_ID("fmsi_clk", &div6_clks[DIV6_FMSI]),
	CLKDEV_CON_ID("fmso_clk", &div6_clks[DIV6_FMSO]),
	CLKDEV_CON_ID("sub_clk", &div6_clks[DIV6_SUB]),
	CLKDEV_CON_ID("spu_clk", &div6_clks[DIV6_SPU]),
	CLKDEV_CON_ID("vou_clk", &div6_clks[DIV6_VOU]),
506
	CLKDEV_CON_ID("hdmi_clk", &div6_reparent_clks[DIV6_HDMI]),
507 508
	CLKDEV_ICK_ID("dsit_clk", "sh-mipi-dsi.0", &div6_clks[DIV6_DSIT]),
	CLKDEV_ICK_ID("dsit_clk", "sh-mipi-dsi.1", &div6_clks[DIV6_DSIT]),
509 510
	CLKDEV_ICK_ID("dsip_clk", "sh-mipi-dsi.0", &div6_clks[DIV6_DSI0P]),
	CLKDEV_ICK_ID("dsip_clk", "sh-mipi-dsi.1", &div6_clks[DIV6_DSI1P]),
511 512 513

	/* MSTP32 clocks */
	CLKDEV_DEV_ID("i2c-sh_mobile.2", &mstp_clks[MSTP001]), /* IIC2 */
514
	CLKDEV_DEV_ID("fff30000.i2c", &mstp_clks[MSTP001]), /* IIC2 */
515
	CLKDEV_DEV_ID("spi_sh_msiof.0", &mstp_clks[MSTP000]), /* MSIOF0 */
516 517 518 519
	CLKDEV_DEV_ID("uio_pdrv_genirq.4", &mstp_clks[MSTP131]), /* VEU3 */
	CLKDEV_DEV_ID("uio_pdrv_genirq.3", &mstp_clks[MSTP130]), /* VEU2 */
	CLKDEV_DEV_ID("uio_pdrv_genirq.2", &mstp_clks[MSTP129]), /* VEU1 */
	CLKDEV_DEV_ID("uio_pdrv_genirq.1", &mstp_clks[MSTP128]), /* VEU0 */
520 521
	CLKDEV_DEV_ID("sh_mobile_ceu.0", &mstp_clks[MSTP127]), /* CEU */
	CLKDEV_DEV_ID("sh-mobile-csi2.0", &mstp_clks[MSTP126]), /* CSI2 */
522 523
	CLKDEV_DEV_ID("sh_tmu.0", &mstp_clks[MSTP125]), /* TMU00 */
	CLKDEV_DEV_ID("sh_tmu.1", &mstp_clks[MSTP125]), /* TMU01 */
524
	CLKDEV_DEV_ID("sh-mipi-dsi.0", &mstp_clks[MSTP118]), /* DSITX0 */
525
	CLKDEV_DEV_ID("sh_mobile_lcdc_fb.1", &mstp_clks[MSTP117]), /* LCDC1 */
526
	CLKDEV_DEV_ID("i2c-sh_mobile.0", &mstp_clks[MSTP116]), /* IIC0 */
527
	CLKDEV_DEV_ID("fff20000.i2c", &mstp_clks[MSTP116]), /* IIC0 */
D
Damian 已提交
528
	CLKDEV_DEV_ID("sh_mobile_meram.0", &mstp_clks[MSTP113]), /* MERAM */
529 530
	CLKDEV_DEV_ID("uio_pdrv_genirq.5", &mstp_clks[MSTP106]), /* JPU */
	CLKDEV_DEV_ID("uio_pdrv_genirq.0", &mstp_clks[MSTP101]), /* VPU */
531
	CLKDEV_DEV_ID("sh_mobile_lcdc_fb.0", &mstp_clks[MSTP100]), /* LCDC0 */
532 533
	CLKDEV_DEV_ID("uio_pdrv_genirq.6", &mstp_clks[MSTP223]), /* SPU2DSP0 */
	CLKDEV_DEV_ID("uio_pdrv_genirq.7", &mstp_clks[MSTP223]), /* SPU2DSP1 */
534 535 536
	CLKDEV_DEV_ID("sh-dma-engine.0", &mstp_clks[MSTP218]), /* DMAC1 */
	CLKDEV_DEV_ID("sh-dma-engine.1", &mstp_clks[MSTP217]), /* DMAC2 */
	CLKDEV_DEV_ID("sh-dma-engine.2", &mstp_clks[MSTP216]), /* DMAC3 */
537
	CLKDEV_DEV_ID("sh-dma-engine.3", &mstp_clks[MSTP214]), /* USB-DMAC0 */
538
	CLKDEV_DEV_ID("spi_sh_msiof.1", &mstp_clks[MSTP208]), /* MSIOF1 */
539 540
	CLKDEV_DEV_ID("sh-sci.5", &mstp_clks[MSTP207]), /* SCIFA5 */
	CLKDEV_DEV_ID("sh-sci.6", &mstp_clks[MSTP206]), /* SCIFB */
541
	CLKDEV_DEV_ID("spi_sh_msiof.2", &mstp_clks[MSTP205]), /* MSIOF2 */
542 543 544 545 546
	CLKDEV_DEV_ID("sh-sci.0", &mstp_clks[MSTP204]), /* SCIFA0 */
	CLKDEV_DEV_ID("sh-sci.1", &mstp_clks[MSTP203]), /* SCIFA1 */
	CLKDEV_DEV_ID("sh-sci.2", &mstp_clks[MSTP202]), /* SCIFA2 */
	CLKDEV_DEV_ID("sh-sci.3", &mstp_clks[MSTP201]), /* SCIFA3 */
	CLKDEV_DEV_ID("sh-sci.4", &mstp_clks[MSTP200]), /* SCIFA4 */
547
	CLKDEV_DEV_ID("sh_fsi2", &mstp_clks[MSTP328]), /* FSI2 */
548
	CLKDEV_DEV_ID("i2c-sh_mobile.1", &mstp_clks[MSTP323]), /* IIC1 */
549
	CLKDEV_DEV_ID("e6c20000.i2c", &mstp_clks[MSTP323]), /* IIC1 */
550 551
	CLKDEV_DEV_ID("r8a66597_hcd.0", &mstp_clks[MSTP322]), /* USB0 */
	CLKDEV_DEV_ID("r8a66597_udc.0", &mstp_clks[MSTP322]), /* USB0 */
552
	CLKDEV_DEV_ID("renesas_usbhs.0", &mstp_clks[MSTP322]), /* USB0 */
553
	CLKDEV_DEV_ID("sh_flctl.0", &mstp_clks[MSTP315]), /* FLCTL */
554
	CLKDEV_DEV_ID("sh_mobile_sdhi.0", &mstp_clks[MSTP314]), /* SDHI0 */
555
	CLKDEV_DEV_ID("e6850000.sdhi", &mstp_clks[MSTP314]), /* SDHI0 */
556
	CLKDEV_DEV_ID("sh_mobile_sdhi.1", &mstp_clks[MSTP313]), /* SDHI1 */
557
	CLKDEV_DEV_ID("e6860000.sdhi", &mstp_clks[MSTP313]), /* SDHI1 */
558
	CLKDEV_DEV_ID("sh_mmcif.0", &mstp_clks[MSTP312]), /* MMC */
559
	CLKDEV_DEV_ID("e6bd0000.mmcif", &mstp_clks[MSTP312]), /* MMC */
560
	CLKDEV_DEV_ID("sh-mipi-dsi.1", &mstp_clks[MSTP423]), /* DSITX1 */
561
	CLKDEV_DEV_ID("sh_mobile_sdhi.2", &mstp_clks[MSTP415]), /* SDHI2 */
562
	CLKDEV_DEV_ID("e6870000.sdhi", &mstp_clks[MSTP415]), /* SDHI2 */
563
	CLKDEV_DEV_ID("sh-mobile-hdmi", &mstp_clks[MSTP413]), /* HDMI */
564
	CLKDEV_DEV_ID("i2c-sh_mobile.3", &mstp_clks[MSTP411]), /* IIC3 */
565
	CLKDEV_DEV_ID("e6d20000.i2c", &mstp_clks[MSTP411]), /* IIC3 */
566
	CLKDEV_DEV_ID("i2c-sh_mobile.4", &mstp_clks[MSTP410]), /* IIC4 */
567
	CLKDEV_DEV_ID("e6d30000.i2c", &mstp_clks[MSTP410]), /* IIC4 */
568
	CLKDEV_DEV_ID("sh-dma-engine.4", &mstp_clks[MSTP407]), /* USB-DMAC1 */
569 570
	CLKDEV_DEV_ID("r8a66597_hcd.1", &mstp_clks[MSTP406]), /* USB1 */
	CLKDEV_DEV_ID("r8a66597_udc.1", &mstp_clks[MSTP406]), /* USB1 */
571
	CLKDEV_DEV_ID("renesas_usbhs.1", &mstp_clks[MSTP406]), /* USB1 */
572 573
	CLKDEV_DEV_ID("sh_cmt.4", &mstp_clks[MSTP405]), /* CMT4 */
	CLKDEV_DEV_ID("sh_cmt.3", &mstp_clks[MSTP404]), /* CMT3 */
574
	CLKDEV_DEV_ID("sh_keysc.0", &mstp_clks[MSTP403]), /* KEYSC */
575
	CLKDEV_DEV_ID("sh_cmt.2", &mstp_clks[MSTP400]), /* CMT2 */
576

577 578
	CLKDEV_ICK_ID("hdmi", "sh_mobile_lcdc_fb.1",
		      &div6_reparent_clks[DIV6_HDMI]),
579 580 581
	CLKDEV_ICK_ID("ick", "sh-mobile-hdmi", &div6_reparent_clks[DIV6_HDMI]),
	CLKDEV_ICK_ID("icka", "sh_fsi2", &div6_reparent_clks[DIV6_FSIA]),
	CLKDEV_ICK_ID("ickb", "sh_fsi2", &div6_reparent_clks[DIV6_FSIB]),
582
	CLKDEV_ICK_ID("spu2", "sh_fsi2", &mstp_clks[MSTP223]),
583 584
	CLKDEV_ICK_ID("diva", "sh_fsi2", &fsidivs[FSIDIV_A]),
	CLKDEV_ICK_ID("divb", "sh_fsi2", &fsidivs[FSIDIV_B]),
585 586
	CLKDEV_ICK_ID("xcka", "sh_fsi2", &fsiack_clk),
	CLKDEV_ICK_ID("xckb", "sh_fsi2", &fsibck_clk),
587 588 589 590 591 592
};

void __init sh7372_clock_init(void)
{
	int k, ret = 0;

593 594 595 596 597 598 599
	/* make sure MSTP bits on the RT/SH4AL-DSP side are off */
	__raw_writel(0xe4ef8087, RMSTPCR0);
	__raw_writel(0xffffffff, RMSTPCR1);
	__raw_writel(0x37c7f7ff, RMSTPCR2);
	__raw_writel(0xffffffff, RMSTPCR3);
	__raw_writel(0xffe0fffd, RMSTPCR4);

600 601 602 603 604 605 606 607 608
	for (k = 0; !ret && (k < ARRAY_SIZE(main_clks)); k++)
		ret = clk_register(main_clks[k]);

	if (!ret)
		ret = sh_clk_div4_register(div4_clks, DIV4_NR, &div4_table);

	if (!ret)
		ret = sh_clk_div6_register(div6_clks, DIV6_NR);

609
	if (!ret)
610
		ret = sh_clk_div6_reparent_register(div6_reparent_clks, DIV6_REPARENT_NR);
611

612
	if (!ret)
613
		ret = sh_clk_mstp_register(mstp_clks, MSTP_NR);
614

615 616
	if (!ret)
		ret = sh_clk_fsidiv_register(fsidivs, FSIDIV_REPARENT_NR);
617

618 619 620
	clkdev_add_table(lookups, ARRAY_SIZE(lookups));

	if (!ret)
621
		shmobile_clk_init();
622 623 624
	else
		panic("failed to setup sh7372 clocks\n");
}