clock-sh7372.c 21.6 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
/*
 * 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.
 */
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/io.h>
#include <linux/sh_clk.h>
19
#include <linux/clkdev.h>
M
Magnus Damm 已提交
20
#include "clock.h"
M
Magnus Damm 已提交
21
#include "common.h"
22 23

/* SH7372 registers */
24 25 26 27 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
#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)
54

55 56 57
#define FSIDIVA		0xFE1F8000
#define FSIDIVB		0xFE1F8008

58
/* Platforms must set frequency on their DV_CLKI pin */
59
struct clk sh7372_dv_clki_clk = {
60 61
};

62 63 64 65 66 67 68 69 70
/* 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.
 */
71
struct clk sh7372_extal1_clk = {
72
	.rate		= 26000000,
73 74 75 76 77 78
};

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

83
SH_CLK_RATIO(div2, 1, 2);
84

85 86 87 88
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);
89 90 91 92 93 94 95 96 97 98 99 100

/* 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;
}

101
static struct sh_clk_ops pllc01_clk_ops = {
102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119
	.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 */
120
SH_FIXED_RATIO_CLK(pllc1_div2_clk,	pllc1_clk,	div2);
121 122

/* PLLC2 */
123 124 125 126 127

/* Indices are important - they are the actual src selecting values */
static struct clk *pllc2_parent[] = {
	[0] = &extal1_div2_clk,
	[1] = &extal2_div2_clk,
128
	[2] = &sh7372_dv_clki_div2_clk,
129 130 131 132 133 134 135 136 137 138 139 140
};

/* 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;
141
		pllc2_freq_table[i].driver_data = i;
142 143 144 145
	}

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

	pllc2_freq_table[++i].frequency = CPUFREQ_TABLE_END;
149
	pllc2_freq_table[i].driver_data = i;
150 151
}

152 153 154 155
static unsigned long pllc2_recalc(struct clk *clk)
{
	unsigned long mult = 1;

156 157 158 159 160 161
	pllc2_table_rebuild(clk);

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

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

168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194
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);
}

195
static int pllc2_set_rate(struct clk *clk, unsigned long rate)
196 197 198 199 200 201 202 203
{
	unsigned long value;
	int idx;

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

204 205
	if (rate == clk->parent->rate)
		return -EINVAL;
206 207 208

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

209 210 211
	__raw_writel(value | ((idx + 19) << 24), PLLC2CR);

	clk->rate = clk->freq_table[idx].frequency;
212 213 214 215 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

	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;
}

246
static struct sh_clk_ops pllc2_clk_ops = {
247
	.recalc		= pllc2_recalc,
248 249 250 251 252
	.round_rate	= pllc2_round_rate,
	.set_rate	= pllc2_set_rate,
	.enable		= pllc2_enable,
	.disable	= pllc2_disable,
	.set_parent	= pllc2_set_parent,
253 254
};

255
struct clk sh7372_pllc2_clk = {
256 257
	.ops		= &pllc2_clk_ops,
	.parent		= &extal1_div2_clk,
258
	.freq_table	= pllc2_freq_table,
259
	.nr_freqs	= ARRAY_SIZE(pllc2_freq_table) - 1,
260 261
	.parent_table	= pllc2_parent,
	.parent_num	= ARRAY_SIZE(pllc2_parent),
262 263
};

264
/* External input clock (pin name: FSIACK/FSIBCK ) */
265
static struct clk fsiack_clk = {
266 267
};

268
static struct clk fsibck_clk = {
269 270
};

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

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,
312
       DIV4_ZX, DIV4_HP,
313 314 315 316 317 318
       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)

319
static struct clk div4_clks[DIV4_NR] = {
320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335
	[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,
336
       DIV6_SUB, DIV6_SPU,
337
       DIV6_VOU, DIV6_DSIT, DIV6_DSI0P, DIV6_DSI1P,
338 339
       DIV6_NR };

340
static struct clk div6_clks[DIV6_NR] = {
341 342 343 344 345
	[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),
346
	[DIV6_SUB] = SH_CLK_DIV6(&sh7372_extal2_clk, SUBCKCR, 0),
347 348 349 350 351 352 353
	[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),
};

354
enum { DIV6_HDMI, DIV6_FSIA, DIV6_FSIB, DIV6_REPARENT_NR };
355 356 357 358

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

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

static struct clk *fsibckcr_parent[] = {
	[0] = &pllc1_div2_clk,
	[1] = &sh7372_pllc2_clk,
374
	[2] = &fsibck_clk, /* external input for FSI B */
375 376 377
	[3] = NULL,	/* setting prohibited */
};

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

387
/* FSI DIV */
388
enum { FSIDIV_A, FSIDIV_B, FSIDIV_REPARENT_NR };
389

390 391 392
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]),
393 394
};

395
enum { MSTP001, MSTP000,
396
       MSTP131, MSTP130,
397
       MSTP129, MSTP128, MSTP127, MSTP126, MSTP125,
D
Damian 已提交
398
       MSTP118, MSTP117, MSTP116, MSTP113,
399
       MSTP106, MSTP101, MSTP100,
400
       MSTP223,
401 402
       MSTP218, MSTP217, MSTP216, MSTP214, MSTP208, MSTP207,
       MSTP206, MSTP205, MSTP204, MSTP203, MSTP202, MSTP201, MSTP200,
403
	MSTP328, MSTP323, MSTP322, MSTP315, MSTP314, MSTP313, MSTP312,
404
       MSTP423, MSTP415, MSTP413, MSTP411, MSTP410, MSTP407, MSTP406,
405
       MSTP405, MSTP404, MSTP403, MSTP400,
406 407 408 409 410 411 412
       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 */
413
	[MSTP000] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR0, 0, 0), /* MSIOF0 */
414 415 416 417
	[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 */
418 419
	[MSTP127] = MSTP(&div4_clks[DIV4_B], SMSTPCR1, 27, 0), /* CEU */
	[MSTP126] = MSTP(&div4_clks[DIV4_B], SMSTPCR1, 26, 0), /* CSI2 */
420
	[MSTP125] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR1, 25, 0), /* TMU0 */
421 422
	[MSTP118] = MSTP(&div4_clks[DIV4_B], SMSTPCR1, 18, 0), /* DSITX */
	[MSTP117] = MSTP(&div4_clks[DIV4_B], SMSTPCR1, 17, 0), /* LCDC1 */
423
	[MSTP116] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR1, 16, 0), /* IIC0 */
D
Damian 已提交
424
	[MSTP113] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR1, 13, 0), /* MERAM */
425 426
	[MSTP106] = MSTP(&div4_clks[DIV4_B], SMSTPCR1, 6, 0), /* JPU */
	[MSTP101] = MSTP(&div4_clks[DIV4_M1], SMSTPCR1, 1, 0), /* VPU */
427
	[MSTP100] = MSTP(&div4_clks[DIV4_B], SMSTPCR1, 0, 0), /* LCDC0 */
428
	[MSTP223] = MSTP(&div6_clks[DIV6_SPU], SMSTPCR2, 23, 0), /* SPU2 */
429 430 431
	[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 */
432
	[MSTP214] = MSTP(&div4_clks[DIV4_HP], SMSTPCR2, 14, 0), /* USBDMAC */
433
	[MSTP208] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR2, 8, 0), /* MSIOF1 */
434 435
	[MSTP207] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR2, 7, 0), /* SCIFA5 */
	[MSTP206] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR2, 6, 0), /* SCIFB */
436
	[MSTP205] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR2, 5, 0), /* MSIOF2 */
437 438 439 440 441
	[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 */
442
	[MSTP328] = MSTP(&div6_clks[DIV6_SPU], SMSTPCR3, 28, 0), /* FSI2 */
443 444
	[MSTP323] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR3, 23, 0), /* IIC1 */
	[MSTP322] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR3, 22, 0), /* USB0 */
445
	[MSTP315] = MSTP(&div4_clks[DIV4_HP], SMSTPCR3, 15, 0), /* FLCTL*/
446 447
	[MSTP314] = MSTP(&div4_clks[DIV4_HP], SMSTPCR3, 14, 0), /* SDHI0 */
	[MSTP313] = MSTP(&div4_clks[DIV4_HP], SMSTPCR3, 13, 0), /* SDHI1 */
448
	[MSTP312] = MSTP(&div4_clks[DIV4_HP], SMSTPCR3, 12, 0), /* MMC */
449
	[MSTP423] = MSTP(&div4_clks[DIV4_B], SMSTPCR4, 23, 0), /* DSITX1 */
450
	[MSTP415] = MSTP(&div4_clks[DIV4_HP], SMSTPCR4, 15, 0), /* SDHI2 */
451
	[MSTP413] = MSTP(&pllc1_div2_clk, SMSTPCR4, 13, 0), /* HDMI */
452 453
	[MSTP411] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR4, 11, 0), /* IIC3 */
	[MSTP410] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR4, 10, 0), /* IIC4 */
454
	[MSTP407] = MSTP(&div4_clks[DIV4_HP], SMSTPCR4, 7, 0), /* USB-DMAC1 */
455
	[MSTP406] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR4, 6, 0), /* USB1 */
456 457
	[MSTP405] = MSTP(&r_clk, SMSTPCR4, 5, 0), /* CMT4 */
	[MSTP404] = MSTP(&r_clk, SMSTPCR4, 4, 0), /* CMT3 */
458
	[MSTP403] = MSTP(&r_clk, SMSTPCR4, 3, 0), /* KEYSC */
459
	[MSTP400] = MSTP(&r_clk, SMSTPCR4, 0, 0), /* CMT2 */
460 461 462 463
};

static struct clk_lookup lookups[] = {
	/* main clocks */
464
	CLKDEV_CON_ID("dv_clki_div2_clk", &sh7372_dv_clki_div2_clk),
465
	CLKDEV_CON_ID("r_clk", &r_clk),
466 467
	CLKDEV_CON_ID("extal1", &sh7372_extal1_clk),
	CLKDEV_CON_ID("extal2", &sh7372_extal2_clk),
468 469 470 471 472 473
	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),
474
	CLKDEV_CON_ID("pllc2_clk", &sh7372_pllc2_clk),
475 476
	CLKDEV_CON_ID("fsiack", &fsiack_clk),
	CLKDEV_CON_ID("fsibck", &fsibck_clk),
477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501

	/* 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]),
502
	CLKDEV_CON_ID("hdmi_clk", &div6_reparent_clks[DIV6_HDMI]),
503 504 505

	/* MSTP32 clocks */
	CLKDEV_DEV_ID("i2c-sh_mobile.2", &mstp_clks[MSTP001]), /* IIC2 */
506
	CLKDEV_DEV_ID("fff30000.i2c", &mstp_clks[MSTP001]), /* IIC2 */
507
	CLKDEV_DEV_ID("spi_sh_msiof.0", &mstp_clks[MSTP000]), /* MSIOF0 */
508 509 510 511
	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 */
512 513
	CLKDEV_DEV_ID("sh_mobile_ceu.0", &mstp_clks[MSTP127]), /* CEU */
	CLKDEV_DEV_ID("sh-mobile-csi2.0", &mstp_clks[MSTP126]), /* CSI2 */
514
	CLKDEV_DEV_ID("sh-mipi-dsi.0", &mstp_clks[MSTP118]), /* DSITX0 */
515
	CLKDEV_DEV_ID("sh_mobile_lcdc_fb.1", &mstp_clks[MSTP117]), /* LCDC1 */
516
	CLKDEV_DEV_ID("i2c-sh_mobile.0", &mstp_clks[MSTP116]), /* IIC0 */
517
	CLKDEV_DEV_ID("fff20000.i2c", &mstp_clks[MSTP116]), /* IIC0 */
D
Damian 已提交
518
	CLKDEV_DEV_ID("sh_mobile_meram.0", &mstp_clks[MSTP113]), /* MERAM */
519 520
	CLKDEV_DEV_ID("uio_pdrv_genirq.5", &mstp_clks[MSTP106]), /* JPU */
	CLKDEV_DEV_ID("uio_pdrv_genirq.0", &mstp_clks[MSTP101]), /* VPU */
521
	CLKDEV_DEV_ID("sh_mobile_lcdc_fb.0", &mstp_clks[MSTP100]), /* LCDC0 */
522 523
	CLKDEV_DEV_ID("uio_pdrv_genirq.6", &mstp_clks[MSTP223]), /* SPU2DSP0 */
	CLKDEV_DEV_ID("uio_pdrv_genirq.7", &mstp_clks[MSTP223]), /* SPU2DSP1 */
524 525 526
	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 */
527
	CLKDEV_DEV_ID("sh-dma-engine.3", &mstp_clks[MSTP214]), /* USB-DMAC0 */
528
	CLKDEV_DEV_ID("spi_sh_msiof.1", &mstp_clks[MSTP208]), /* MSIOF1 */
529 530
	CLKDEV_DEV_ID("sh-sci.5", &mstp_clks[MSTP207]), /* SCIFA5 */
	CLKDEV_DEV_ID("sh-sci.6", &mstp_clks[MSTP206]), /* SCIFB */
531
	CLKDEV_DEV_ID("spi_sh_msiof.2", &mstp_clks[MSTP205]), /* MSIOF2 */
532 533 534 535 536
	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 */
537
	CLKDEV_DEV_ID("sh_fsi2", &mstp_clks[MSTP328]), /* FSI2 */
538
	CLKDEV_DEV_ID("i2c-sh_mobile.1", &mstp_clks[MSTP323]), /* IIC1 */
539
	CLKDEV_DEV_ID("e6c20000.i2c", &mstp_clks[MSTP323]), /* IIC1 */
540 541
	CLKDEV_DEV_ID("r8a66597_hcd.0", &mstp_clks[MSTP322]), /* USB0 */
	CLKDEV_DEV_ID("r8a66597_udc.0", &mstp_clks[MSTP322]), /* USB0 */
542
	CLKDEV_DEV_ID("renesas_usbhs.0", &mstp_clks[MSTP322]), /* USB0 */
543
	CLKDEV_DEV_ID("sh_flctl.0", &mstp_clks[MSTP315]), /* FLCTL */
544
	CLKDEV_DEV_ID("sh_mobile_sdhi.0", &mstp_clks[MSTP314]), /* SDHI0 */
545
	CLKDEV_DEV_ID("e6850000.sdhi", &mstp_clks[MSTP314]), /* SDHI0 */
546
	CLKDEV_DEV_ID("sh_mobile_sdhi.1", &mstp_clks[MSTP313]), /* SDHI1 */
547
	CLKDEV_DEV_ID("e6860000.sdhi", &mstp_clks[MSTP313]), /* SDHI1 */
548
	CLKDEV_DEV_ID("sh_mmcif.0", &mstp_clks[MSTP312]), /* MMC */
549
	CLKDEV_DEV_ID("e6bd0000.mmcif", &mstp_clks[MSTP312]), /* MMC */
550
	CLKDEV_DEV_ID("sh-mipi-dsi.1", &mstp_clks[MSTP423]), /* DSITX1 */
551
	CLKDEV_DEV_ID("sh_mobile_sdhi.2", &mstp_clks[MSTP415]), /* SDHI2 */
552
	CLKDEV_DEV_ID("e6870000.sdhi", &mstp_clks[MSTP415]), /* SDHI2 */
553
	CLKDEV_DEV_ID("sh-mobile-hdmi", &mstp_clks[MSTP413]), /* HDMI */
554
	CLKDEV_DEV_ID("i2c-sh_mobile.3", &mstp_clks[MSTP411]), /* IIC3 */
555
	CLKDEV_DEV_ID("e6d20000.i2c", &mstp_clks[MSTP411]), /* IIC3 */
556
	CLKDEV_DEV_ID("i2c-sh_mobile.4", &mstp_clks[MSTP410]), /* IIC4 */
557
	CLKDEV_DEV_ID("e6d30000.i2c", &mstp_clks[MSTP410]), /* IIC4 */
558
	CLKDEV_DEV_ID("sh-dma-engine.4", &mstp_clks[MSTP407]), /* USB-DMAC1 */
559 560
	CLKDEV_DEV_ID("r8a66597_hcd.1", &mstp_clks[MSTP406]), /* USB1 */
	CLKDEV_DEV_ID("r8a66597_udc.1", &mstp_clks[MSTP406]), /* USB1 */
561
	CLKDEV_DEV_ID("renesas_usbhs.1", &mstp_clks[MSTP406]), /* USB1 */
562
	CLKDEV_DEV_ID("sh_keysc.0", &mstp_clks[MSTP403]), /* KEYSC */
563

564 565 566 567 568
	/* ICK */
	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]),
	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]),
569 570
	CLKDEV_ICK_ID("hdmi", "sh_mobile_lcdc_fb.1",
		      &div6_reparent_clks[DIV6_HDMI]),
571 572 573
	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]),
574
	CLKDEV_ICK_ID("fck", "sh-tmu.0", &mstp_clks[MSTP125]), /* TMU0 */
575
	CLKDEV_ICK_ID("spu2", "sh_fsi2", &mstp_clks[MSTP223]),
576 577 578
	CLKDEV_ICK_ID("fck", "sh-cmt-32-fast.4", &mstp_clks[MSTP405]), /* CMT4 */
	CLKDEV_ICK_ID("fck", "sh-cmt-32-fast.3", &mstp_clks[MSTP404]), /* CMT3 */
	CLKDEV_ICK_ID("fck", "sh-cmt-32-fast.2", &mstp_clks[MSTP400]), /* CMT2 */
579 580
	CLKDEV_ICK_ID("diva", "sh_fsi2", &fsidivs[FSIDIV_A]),
	CLKDEV_ICK_ID("divb", "sh_fsi2", &fsidivs[FSIDIV_B]),
581 582
	CLKDEV_ICK_ID("xcka", "sh_fsi2", &fsiack_clk),
	CLKDEV_ICK_ID("xckb", "sh_fsi2", &fsibck_clk),
583 584 585 586 587 588
};

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

589 590 591 592 593 594 595
	/* 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);

596 597 598 599 600 601 602 603 604
	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);

605
	if (!ret)
606
		ret = sh_clk_div6_reparent_register(div6_reparent_clks, DIV6_REPARENT_NR);
607

608
	if (!ret)
609
		ret = sh_clk_mstp_register(mstp_clks, MSTP_NR);
610

611 612
	if (!ret)
		ret = sh_clk_fsidiv_register(fsidivs, FSIDIV_REPARENT_NR);
613

614 615 616
	clkdev_add_table(lookups, ARRAY_SIZE(lookups));

	if (!ret)
617
		shmobile_clk_init();
618 619 620
	else
		panic("failed to setup sh7372 clocks\n");
}