aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm/mach-s3c2410/clock.c
diff options
context:
space:
mode:
authorBen Dooks <ben-linux@fluff.org>2006-03-20 12:10:07 -0500
committerRussell King <rmk+kernel@arm.linux.org.uk>2006-03-21 17:06:05 -0500
commit3fc3e1c0640887f883c28330e9d35145d23b2696 (patch)
tree94a98fb93f5f742d0d984a84934bf9cb90315119 /arch/arm/mach-s3c2410/clock.c
parenta08ceff2a98e09cb14afefdd9276714b85c945f7 (diff)
[ARM] 3333/1: S3C2XX - add dclk and clkout clock support
Patch from Ben Dooks Add enable and set_parent calls for the dclk and clkout clocks. Signed-off-by: Ben Dooks <ben-linux@fluff.org> Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
Diffstat (limited to 'arch/arm/mach-s3c2410/clock.c')
-rw-r--r--arch/arm/mach-s3c2410/clock.c94
1 files changed, 93 insertions, 1 deletions
diff --git a/arch/arm/mach-s3c2410/clock.c b/arch/arm/mach-s3c2410/clock.c
index 773b7aec3e99..e205a6316b08 100644
--- a/arch/arm/mach-s3c2410/clock.c
+++ b/arch/arm/mach-s3c2410/clock.c
@@ -45,6 +45,7 @@
45#include <asm/io.h> 45#include <asm/io.h>
46 46
47#include <asm/arch/regs-clock.h> 47#include <asm/arch/regs-clock.h>
48#include <asm/arch/regs-gpio.h>
48 49
49#include "clock.h" 50#include "clock.h"
50#include "cpu.h" 51#include "cpu.h"
@@ -285,24 +286,115 @@ static struct clk clk_p = {
285 286
286/* clocks that could be registered by external code */ 287/* clocks that could be registered by external code */
287 288
289static int s3c24xx_dclk_enable(struct clk *clk, int enable)
290{
291 unsigned long dclkcon = __raw_readl(S3C2410_DCLKCON);
292
293 if (enable)
294 dclkcon |= clk->ctrlbit;
295 else
296 dclkcon &= ~clk->ctrlbit;
297
298 __raw_writel(dclkcon, S3C2410_DCLKCON);
299
300 return 0;
301}
302
303static int s3c24xx_dclk_setparent(struct clk *clk, struct clk *parent)
304{
305 unsigned long dclkcon;
306 unsigned int uclk;
307
308 if (parent == &clk_upll)
309 uclk = 1;
310 else if (parent == &clk_p)
311 uclk = 0;
312 else
313 return -EINVAL;
314
315 clk->parent = parent;
316
317 dclkcon = __raw_readl(S3C2410_DCLKCON);
318
319 if (clk->ctrlbit == S3C2410_DCLKCON_DCLK0EN) {
320 if (uclk)
321 dclkcon |= S3C2410_DCLKCON_DCLK0_UCLK;
322 else
323 dclkcon &= ~S3C2410_DCLKCON_DCLK0_UCLK;
324 } else {
325 if (uclk)
326 dclkcon |= S3C2410_DCLKCON_DCLK1_UCLK;
327 else
328 dclkcon &= ~S3C2410_DCLKCON_DCLK1_UCLK;
329 }
330
331 __raw_writel(dclkcon, S3C2410_DCLKCON);
332
333 return 0;
334}
335
336
337static int s3c24xx_clkout_setparent(struct clk *clk, struct clk *parent)
338{
339 unsigned long mask;
340 unsigned long source;
341
342 /* calculate the MISCCR setting for the clock */
343
344 if (parent == &clk_xtal)
345 source = S3C2410_MISCCR_CLK0_MPLL;
346 else if (parent == &clk_upll)
347 source = S3C2410_MISCCR_CLK0_UPLL;
348 else if (parent == &clk_f)
349 source = S3C2410_MISCCR_CLK0_FCLK;
350 else if (parent == &clk_p)
351 source = S3C2410_MISCCR_CLK0_PCLK;
352 else if (clk == &s3c24xx_clkout0 && parent == &s3c24xx_dclk0)
353 source = S3C2410_MISCCR_CLK0_DCLK0;
354 else if (clk == &s3c24xx_clkout1 && parent == &s3c24xx_dclk1)
355 source = S3C2410_MISCCR_CLK0_DCLK0;
356 else
357 return -EINVAL;
358
359 if (clk == &s3c24xx_dclk0)
360 mask = S3C2410_MISCCR_CLK0_MASK;
361 else {
362 source <<= 4;
363 mask = S3C2410_MISCCR_CLK1_MASK;
364 }
365
366 s3c2410_modify_misccr(mask, source);
367 return 0;
368}
369
370/* external clock definitions */
371
288struct clk s3c24xx_dclk0 = { 372struct clk s3c24xx_dclk0 = {
289 .name = "dclk0", 373 .name = "dclk0",
290 .id = -1, 374 .id = -1,
375 .ctrlbit = S3C2410_DCLKCON_DCLK0EN,
376 .enable = s3c24xx_dclk_enable,
377 .set_parent = s3c24xx_dclk_setparent,
291}; 378};
292 379
293struct clk s3c24xx_dclk1 = { 380struct clk s3c24xx_dclk1 = {
294 .name = "dclk1", 381 .name = "dclk1",
295 .id = -1, 382 .id = -1,
383 .ctrlbit = S3C2410_DCLKCON_DCLK0EN,
384 .enable = s3c24xx_dclk_enable,
385 .set_parent = s3c24xx_dclk_setparent,
296}; 386};
297 387
298struct clk s3c24xx_clkout0 = { 388struct clk s3c24xx_clkout0 = {
299 .name = "clkout0", 389 .name = "clkout0",
300 .id = -1, 390 .id = -1,
391 .set_parent = s3c24xx_clkout_setparent,
301}; 392};
302 393
303struct clk s3c24xx_clkout1 = { 394struct clk s3c24xx_clkout1 = {
304 .name = "clkout1", 395 .name = "clkout1",
305 .id = -1, 396 .id = -1,
397 .set_parent = s3c24xx_clkout_setparent,
306}; 398};
307 399
308struct clk s3c24xx_uclk = { 400struct clk s3c24xx_uclk = {
@@ -423,7 +515,7 @@ int s3c24xx_register_clock(struct clk *clk)
423 515
424 /* if this is a standard clock, set the usage state */ 516 /* if this is a standard clock, set the usage state */
425 517
426 if (clk->ctrlbit) { 518 if (clk->ctrlbit && clk->enable == s3c24xx_clkcon_enable) {
427 unsigned long clkcon = __raw_readl(S3C2410_CLKCON); 519 unsigned long clkcon = __raw_readl(S3C2410_CLKCON);
428 520
429 clk->usage = (clkcon & clk->ctrlbit) ? 1 : 0; 521 clk->usage = (clkcon & clk->ctrlbit) ? 1 : 0;