clock.c 11.9 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12
/*
 * arch/arm/mach-ep93xx/clock.c
 * Clock control for Cirrus EP93xx chips.
 *
 * Copyright (C) 2006 Lennert Buytenhek <buytenh@wantstofly.org>
 *
 * 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, or (at
 * your option) any later version.
 */

13 14
#define pr_fmt(fmt) "ep93xx " KBUILD_MODNAME ": " fmt

15 16 17
#include <linux/kernel.h>
#include <linux/clk.h>
#include <linux/err.h>
18
#include <linux/module.h>
19
#include <linux/string.h>
20
#include <linux/io.h>
21 22 23
#include <linux/spinlock.h>

#include <mach/hardware.h>
24 25

#include <asm/clkdev.h>
26 27
#include <asm/div64.h>

28

29
struct clk {
30
	struct clk	*parent;
31 32
	unsigned long	rate;
	int		users;
33
	int		sw_locked;
34
	void __iomem	*enable_reg;
35
	u32		enable_mask;
36 37

	unsigned long	(*get_rate)(struct clk *clk);
38
	int		(*set_rate)(struct clk *clk, unsigned long rate);
39 40
};

41 42 43

static unsigned long get_uart_rate(struct clk *clk);

44
static int set_keytchclk_rate(struct clk *clk, unsigned long rate);
45
static int set_div_rate(struct clk *clk, unsigned long rate);
46

47 48 49 50

static struct clk clk_xtali = {
	.rate		= EP93XX_EXT_CLK_RATE,
};
51
static struct clk clk_uart1 = {
52
	.parent		= &clk_xtali,
53
	.sw_locked	= 1,
54 55
	.enable_reg	= EP93XX_SYSCON_DEVCFG,
	.enable_mask	= EP93XX_SYSCON_DEVCFG_U1EN,
56 57 58
	.get_rate	= get_uart_rate,
};
static struct clk clk_uart2 = {
59
	.parent		= &clk_xtali,
60
	.sw_locked	= 1,
61 62
	.enable_reg	= EP93XX_SYSCON_DEVCFG,
	.enable_mask	= EP93XX_SYSCON_DEVCFG_U2EN,
63 64 65
	.get_rate	= get_uart_rate,
};
static struct clk clk_uart3 = {
66
	.parent		= &clk_xtali,
67
	.sw_locked	= 1,
68 69
	.enable_reg	= EP93XX_SYSCON_DEVCFG,
	.enable_mask	= EP93XX_SYSCON_DEVCFG_U3EN,
70
	.get_rate	= get_uart_rate,
71
};
72 73 74 75 76 77 78 79 80 81 82 83 84 85 86
static struct clk clk_pll1 = {
	.parent		= &clk_xtali,
};
static struct clk clk_f = {
	.parent		= &clk_pll1,
};
static struct clk clk_h = {
	.parent		= &clk_pll1,
};
static struct clk clk_p = {
	.parent		= &clk_pll1,
};
static struct clk clk_pll2 = {
	.parent		= &clk_xtali,
};
87
static struct clk clk_usb_host = {
88
	.parent		= &clk_pll2,
89 90
	.enable_reg	= EP93XX_SYSCON_PWRCNT,
	.enable_mask	= EP93XX_SYSCON_PWRCNT_USH_EN,
91
};
92
static struct clk clk_keypad = {
93
	.parent		= &clk_xtali,
94 95 96 97 98
	.sw_locked	= 1,
	.enable_reg	= EP93XX_SYSCON_KEYTCHCLKDIV,
	.enable_mask	= EP93XX_SYSCON_KEYTCHCLKDIV_KEN,
	.set_rate	= set_keytchclk_rate,
};
99
static struct clk clk_pwm = {
100
	.parent		= &clk_xtali,
101 102
	.rate		= EP93XX_EXT_CLK_RATE,
};
103

104 105 106 107 108 109 110
static struct clk clk_video = {
	.sw_locked	= 1,
	.enable_reg     = EP93XX_SYSCON_VIDCLKDIV,
	.enable_mask    = EP93XX_SYSCON_CLKDIV_ENABLE,
	.set_rate	= set_div_rate,
};

111 112
/* DMA Clocks */
static struct clk clk_m2p0 = {
113
	.parent		= &clk_h,
114 115
	.enable_reg	= EP93XX_SYSCON_PWRCNT,
	.enable_mask	= EP93XX_SYSCON_PWRCNT_DMA_M2P0,
116 117
};
static struct clk clk_m2p1 = {
118
	.parent		= &clk_h,
119 120
	.enable_reg	= EP93XX_SYSCON_PWRCNT,
	.enable_mask	= EP93XX_SYSCON_PWRCNT_DMA_M2P1,
121 122
};
static struct clk clk_m2p2 = {
123
	.parent		= &clk_h,
124 125
	.enable_reg	= EP93XX_SYSCON_PWRCNT,
	.enable_mask	= EP93XX_SYSCON_PWRCNT_DMA_M2P2,
126 127
};
static struct clk clk_m2p3 = {
128
	.parent		= &clk_h,
129 130
	.enable_reg	= EP93XX_SYSCON_PWRCNT,
	.enable_mask	= EP93XX_SYSCON_PWRCNT_DMA_M2P3,
131 132
};
static struct clk clk_m2p4 = {
133
	.parent		= &clk_h,
134 135
	.enable_reg	= EP93XX_SYSCON_PWRCNT,
	.enable_mask	= EP93XX_SYSCON_PWRCNT_DMA_M2P4,
136 137
};
static struct clk clk_m2p5 = {
138
	.parent		= &clk_h,
139 140
	.enable_reg	= EP93XX_SYSCON_PWRCNT,
	.enable_mask	= EP93XX_SYSCON_PWRCNT_DMA_M2P5,
141 142
};
static struct clk clk_m2p6 = {
143
	.parent		= &clk_h,
144 145
	.enable_reg	= EP93XX_SYSCON_PWRCNT,
	.enable_mask	= EP93XX_SYSCON_PWRCNT_DMA_M2P6,
146 147
};
static struct clk clk_m2p7 = {
148
	.parent		= &clk_h,
149 150
	.enable_reg	= EP93XX_SYSCON_PWRCNT,
	.enable_mask	= EP93XX_SYSCON_PWRCNT_DMA_M2P7,
151 152
};
static struct clk clk_m2p8 = {
153
	.parent		= &clk_h,
154 155
	.enable_reg	= EP93XX_SYSCON_PWRCNT,
	.enable_mask	= EP93XX_SYSCON_PWRCNT_DMA_M2P8,
156 157
};
static struct clk clk_m2p9 = {
158
	.parent		= &clk_h,
159 160
	.enable_reg	= EP93XX_SYSCON_PWRCNT,
	.enable_mask	= EP93XX_SYSCON_PWRCNT_DMA_M2P9,
161 162
};
static struct clk clk_m2m0 = {
163
	.parent		= &clk_h,
164 165
	.enable_reg	= EP93XX_SYSCON_PWRCNT,
	.enable_mask	= EP93XX_SYSCON_PWRCNT_DMA_M2M0,
166 167
};
static struct clk clk_m2m1 = {
168
	.parent		= &clk_h,
169 170
	.enable_reg	= EP93XX_SYSCON_PWRCNT,
	.enable_mask	= EP93XX_SYSCON_PWRCNT_DMA_M2M1,
171 172
};

173 174 175 176
#define INIT_CK(dev,con,ck)					\
	{ .dev_id = dev, .con_id = con, .clk = ck }

static struct clk_lookup clocks[] = {
177
	INIT_CK(NULL,			"xtali",	&clk_xtali),
178 179 180 181 182 183 184 185 186 187
	INIT_CK("apb:uart1",		NULL,		&clk_uart1),
	INIT_CK("apb:uart2",		NULL,		&clk_uart2),
	INIT_CK("apb:uart3",		NULL,		&clk_uart3),
	INIT_CK(NULL,			"pll1",		&clk_pll1),
	INIT_CK(NULL,			"fclk",		&clk_f),
	INIT_CK(NULL,			"hclk",		&clk_h),
	INIT_CK(NULL,			"pclk",		&clk_p),
	INIT_CK(NULL,			"pll2",		&clk_pll2),
	INIT_CK("ep93xx-ohci",		NULL,		&clk_usb_host),
	INIT_CK("ep93xx-keypad",	NULL,		&clk_keypad),
188
	INIT_CK("ep93xx-fb",		NULL,		&clk_video),
189
	INIT_CK(NULL,			"pwm_clk",	&clk_pwm),
190 191 192 193 194 195 196 197 198 199 200 201
	INIT_CK(NULL,			"m2p0",		&clk_m2p0),
	INIT_CK(NULL,			"m2p1",		&clk_m2p1),
	INIT_CK(NULL,			"m2p2",		&clk_m2p2),
	INIT_CK(NULL,			"m2p3",		&clk_m2p3),
	INIT_CK(NULL,			"m2p4",		&clk_m2p4),
	INIT_CK(NULL,			"m2p5",		&clk_m2p5),
	INIT_CK(NULL,			"m2p6",		&clk_m2p6),
	INIT_CK(NULL,			"m2p7",		&clk_m2p7),
	INIT_CK(NULL,			"m2p8",		&clk_m2p8),
	INIT_CK(NULL,			"m2p9",		&clk_m2p9),
	INIT_CK(NULL,			"m2m0",		&clk_m2m0),
	INIT_CK(NULL,			"m2m1",		&clk_m2m1),
202 203
};

204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223
static DEFINE_SPINLOCK(clk_lock);

static void __clk_enable(struct clk *clk)
{
	if (!clk->users++) {
		if (clk->parent)
			__clk_enable(clk->parent);

		if (clk->enable_reg) {
			u32 v;

			v = __raw_readl(clk->enable_reg);
			v |= clk->enable_mask;
			if (clk->sw_locked)
				ep93xx_syscon_swlocked_write(v, clk->enable_reg);
			else
				__raw_writel(v, clk->enable_reg);
		}
	}
}
224 225 226

int clk_enable(struct clk *clk)
{
227
	unsigned long flags;
228

229 230 231 232 233 234
	if (!clk)
		return -EINVAL;

	spin_lock_irqsave(&clk_lock, flags);
	__clk_enable(clk);
	spin_unlock_irqrestore(&clk_lock, flags);
235 236 237

	return 0;
}
238
EXPORT_SYMBOL(clk_enable);
239

240
static void __clk_disable(struct clk *clk)
241
{
242 243 244 245 246 247 248 249 250 251 252
	if (!--clk->users) {
		if (clk->enable_reg) {
			u32 v;

			v = __raw_readl(clk->enable_reg);
			v &= ~clk->enable_mask;
			if (clk->sw_locked)
				ep93xx_syscon_swlocked_write(v, clk->enable_reg);
			else
				__raw_writel(v, clk->enable_reg);
		}
253

254 255
		if (clk->parent)
			__clk_disable(clk->parent);
256 257
	}
}
258 259 260 261 262 263 264 265 266 267 268 269

void clk_disable(struct clk *clk)
{
	unsigned long flags;

	if (!clk)
		return;

	spin_lock_irqsave(&clk_lock, flags);
	__clk_disable(clk);
	spin_unlock_irqrestore(&clk_lock, flags);
}
270
EXPORT_SYMBOL(clk_disable);
271

272 273
static unsigned long get_uart_rate(struct clk *clk)
{
274
	unsigned long rate = clk_get_rate(clk->parent);
275 276
	u32 value;

277 278
	value = __raw_readl(EP93XX_SYSCON_PWRCNT);
	if (value & EP93XX_SYSCON_PWRCNT_UARTBAUD)
279
		return rate;
280
	else
281
		return rate / 2;
282 283
}

284 285
unsigned long clk_get_rate(struct clk *clk)
{
286 287 288
	if (clk->get_rate)
		return clk->get_rate(clk);

289 290
	return clk->rate;
}
291
EXPORT_SYMBOL(clk_get_rate);
292

293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320
static int set_keytchclk_rate(struct clk *clk, unsigned long rate)
{
	u32 val;
	u32 div_bit;

	val = __raw_readl(clk->enable_reg);

	/*
	 * The Key Matrix and ADC clocks are configured using the same
	 * System Controller register.  The clock used will be either
	 * 1/4 or 1/16 the external clock rate depending on the
	 * EP93XX_SYSCON_KEYTCHCLKDIV_KDIV/EP93XX_SYSCON_KEYTCHCLKDIV_ADIV
	 * bit being set or cleared.
	 */
	div_bit = clk->enable_mask >> 15;

	if (rate == EP93XX_KEYTCHCLK_DIV4)
		val |= div_bit;
	else if (rate == EP93XX_KEYTCHCLK_DIV16)
		val &= ~div_bit;
	else
		return -EINVAL;

	ep93xx_syscon_swlocked_write(val, clk->enable_reg);
	clk->rate = rate;
	return 0;
}

321 322
static int calc_clk_div(struct clk *clk, unsigned long rate,
			int *psel, int *esel, int *pdiv, int *div)
323
{
324 325
	struct clk *mclk;
	unsigned long max_rate, actual_rate, mclk_rate, rate_err = -1;
326 327 328 329
	int i, found = 0, __div = 0, __pdiv = 0;

	/* Don't exceed the maximum rate */
	max_rate = max(max(clk_pll1.rate / 4, clk_pll2.rate / 4),
330
		       clk_xtali.rate / 4);
331 332 333 334 335 336 337 338 339 340 341 342 343
	rate = min(rate, max_rate);

	/*
	 * Try the two pll's and the external clock
	 * Because the valid predividers are 2, 2.5 and 3, we multiply
	 * all the clocks by 2 to avoid floating point math.
	 *
	 * This is based on the algorithm in the ep93xx raster guide:
	 * http://be-a-maverick.com/en/pubs/appNote/AN269REV1.pdf
	 *
	 */
	for (i = 0; i < 3; i++) {
		if (i == 0)
344
			mclk = &clk_xtali;
345
		else if (i == 1)
346 347 348 349
			mclk = &clk_pll1;
		else
			mclk = &clk_pll2;
		mclk_rate = mclk->rate * 2;
350 351 352 353 354 355 356 357 358 359 360 361 362 363

		/* Try each predivider value */
		for (__pdiv = 4; __pdiv <= 6; __pdiv++) {
			__div = mclk_rate / (rate * __pdiv);
			if (__div < 2 || __div > 127)
				continue;

			actual_rate = mclk_rate / (__pdiv * __div);

			if (!found || abs(actual_rate - rate) < rate_err) {
				*pdiv = __pdiv - 3;
				*div = __div;
				*psel = (i == 2);
				*esel = (i != 0);
364 365
				clk->parent = mclk;
				clk->rate = actual_rate;
366 367 368 369 370 371 372
				rate_err = abs(actual_rate - rate);
				found = 1;
			}
		}
	}

	if (!found)
373
		return -EINVAL;
374

375
	return 0;
376 377 378 379
}

static int set_div_rate(struct clk *clk, unsigned long rate)
{
380
	int err, psel = 0, esel = 0, pdiv = 0, div = 0;
381 382
	u32 val;

383 384 385
	err = calc_clk_div(clk, rate, &psel, &esel, &pdiv, &div);
	if (err)
		return err;
386 387 388 389 390 391 392 393 394 395 396 397 398

	/* Clear the esel, psel, pdiv and div bits */
	val = __raw_readl(clk->enable_reg);
	val &= ~0x7fff;

	/* Set the new esel, psel, pdiv and div bits for the new clock rate */
	val |= (esel ? EP93XX_SYSCON_CLKDIV_ESEL : 0) |
		(psel ? EP93XX_SYSCON_CLKDIV_PSEL : 0) |
		(pdiv << EP93XX_SYSCON_CLKDIV_PDIV_SHIFT) | div;
	ep93xx_syscon_swlocked_write(val, clk->enable_reg);
	return 0;
}

399 400 401 402 403 404 405 406 407
int clk_set_rate(struct clk *clk, unsigned long rate)
{
	if (clk->set_rate)
		return clk->set_rate(clk, rate);

	return -EINVAL;
}
EXPORT_SYMBOL(clk_set_rate);

408 409 410 411 412 413 414 415 416 417 418 419 420

static char fclk_divisors[] = { 1, 2, 4, 8, 16, 1, 1, 1 };
static char hclk_divisors[] = { 1, 2, 4, 5, 6, 8, 16, 32 };
static char pclk_divisors[] = { 1, 2, 4, 8 };

/*
 * PLL rate = 14.7456 MHz * (X1FBD + 1) * (X2FBD + 1) / (X2IPD + 1) / 2^PS
 */
static unsigned long calc_pll_rate(u32 config_word)
{
	unsigned long long rate;
	int i;

421
	rate = clk_xtali.rate;
422 423 424 425 426 427 428 429 430
	rate *= ((config_word >> 11) & 0x1f) + 1;		/* X1FBD */
	rate *= ((config_word >> 5) & 0x3f) + 1;		/* X2FBD */
	do_div(rate, (config_word & 0x1f) + 1);			/* X2IPD */
	for (i = 0; i < ((config_word >> 16) & 3); i++)		/* PS */
		rate >>= 1;

	return (unsigned long)rate;
}

431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446
static void __init ep93xx_dma_clock_init(void)
{
	clk_m2p0.rate = clk_h.rate;
	clk_m2p1.rate = clk_h.rate;
	clk_m2p2.rate = clk_h.rate;
	clk_m2p3.rate = clk_h.rate;
	clk_m2p4.rate = clk_h.rate;
	clk_m2p5.rate = clk_h.rate;
	clk_m2p6.rate = clk_h.rate;
	clk_m2p7.rate = clk_h.rate;
	clk_m2p8.rate = clk_h.rate;
	clk_m2p9.rate = clk_h.rate;
	clk_m2m0.rate = clk_h.rate;
	clk_m2m1.rate = clk_h.rate;
}

447
static int __init ep93xx_clock_init(void)
448 449
{
	u32 value;
450
	int i;
451

452 453 454
	/* Determine the bootloader configured pll1 rate */
	value = __raw_readl(EP93XX_SYSCON_CLKSET1);
	if (!(value & EP93XX_SYSCON_CLKSET1_NBYP1))
455
		clk_pll1.rate = clk_xtali.rate;
456
	else
457
		clk_pll1.rate = calc_pll_rate(value);
458 459

	/* Initialize the pll1 derived clocks */
460 461 462
	clk_f.rate = clk_pll1.rate / fclk_divisors[(value >> 25) & 0x7];
	clk_h.rate = clk_pll1.rate / hclk_divisors[(value >> 20) & 0x7];
	clk_p.rate = clk_h.rate / pclk_divisors[(value >> 18) & 0x3];
463
	ep93xx_dma_clock_init();
464

465
	/* Determine the bootloader configured pll2 rate */
466
	value = __raw_readl(EP93XX_SYSCON_CLOCK_SET2);
467
	if (!(value & EP93XX_SYSCON_CLKSET2_NBYP2))
468
		clk_pll2.rate = clk_xtali.rate;
469
	else if (value & EP93XX_SYSCON_CLKSET2_PLL2_EN)
470
		clk_pll2.rate = calc_pll_rate(value);
471
	else
472
		clk_pll2.rate = 0;
473 474

	/* Initialize the pll2 derived clocks */
475 476
	clk_usb_host.rate = clk_pll2.rate / (((value >> 28) & 0xf) + 1);

477
	pr_info("PLL1 running at %ld MHz, PLL2 at %ld MHz\n",
478
		clk_pll1.rate / 1000000, clk_pll2.rate / 1000000);
479
	pr_info("FCLK %ld MHz, HCLK %ld MHz, PCLK %ld MHz\n",
480 481
		clk_f.rate / 1000000, clk_h.rate / 1000000,
		clk_p.rate / 1000000);
482

483 484
	for (i = 0; i < ARRAY_SIZE(clocks); i++)
		clkdev_add(&clocks[i]);
485
	return 0;
486
}
487
arch_initcall(ep93xx_clock_init);