aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm/mach-davinci/clock.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/arm/mach-davinci/clock.c')
-rw-r--r--arch/arm/mach-davinci/clock.c93
1 files changed, 39 insertions, 54 deletions
diff --git a/arch/arm/mach-davinci/clock.c b/arch/arm/mach-davinci/clock.c
index baece65cb9c0..bf6218ee94e1 100644
--- a/arch/arm/mach-davinci/clock.c
+++ b/arch/arm/mach-davinci/clock.c
@@ -49,7 +49,8 @@ static void __clk_disable(struct clk *clk)
49{ 49{
50 if (WARN_ON(clk->usecount == 0)) 50 if (WARN_ON(clk->usecount == 0))
51 return; 51 return;
52 if (--clk->usecount == 0 && !(clk->flags & CLK_PLL)) 52 if (--clk->usecount == 0 && !(clk->flags & CLK_PLL) &&
53 (clk->flags & CLK_PSC))
53 davinci_psc_config(psc_domain(clk), clk->gpsc, clk->lpsc, 0); 54 davinci_psc_config(psc_domain(clk), clk->gpsc, clk->lpsc, 0);
54 if (clk->parent) 55 if (clk->parent)
55 __clk_disable(clk->parent); 56 __clk_disable(clk->parent);
@@ -124,9 +125,10 @@ int clk_set_rate(struct clk *clk, unsigned long rate)
124 if (clk == NULL || IS_ERR(clk)) 125 if (clk == NULL || IS_ERR(clk))
125 return ret; 126 return ret;
126 127
127 spin_lock_irqsave(&clockfw_lock, flags);
128 if (clk->set_rate) 128 if (clk->set_rate)
129 ret = clk->set_rate(clk, rate); 129 ret = clk->set_rate(clk, rate);
130
131 spin_lock_irqsave(&clockfw_lock, flags);
130 if (ret == 0) { 132 if (ret == 0) {
131 if (clk->recalc) 133 if (clk->recalc)
132 clk->rate = clk->recalc(clk); 134 clk->rate = clk->recalc(clk);
@@ -363,6 +365,7 @@ int davinci_set_pllrate(struct pll_data *pll, unsigned int prediv,
363{ 365{
364 u32 ctrl; 366 u32 ctrl;
365 unsigned int locktime; 367 unsigned int locktime;
368 unsigned long flags;
366 369
367 if (pll->base == NULL) 370 if (pll->base == NULL)
368 return -EINVAL; 371 return -EINVAL;
@@ -376,25 +379,23 @@ int davinci_set_pllrate(struct pll_data *pll, unsigned int prediv,
376 locktime = ((2000 * prediv) / 100); 379 locktime = ((2000 * prediv) / 100);
377 prediv = (prediv - 1) | PLLDIV_EN; 380 prediv = (prediv - 1) | PLLDIV_EN;
378 } else { 381 } else {
379 locktime = 20; 382 locktime = PLL_LOCK_TIME;
380 } 383 }
381 if (postdiv) 384 if (postdiv)
382 postdiv = (postdiv - 1) | PLLDIV_EN; 385 postdiv = (postdiv - 1) | PLLDIV_EN;
383 if (mult) 386 if (mult)
384 mult = mult - 1; 387 mult = mult - 1;
385 388
389 /* Protect against simultaneous calls to PLL setting seqeunce */
390 spin_lock_irqsave(&clockfw_lock, flags);
391
386 ctrl = __raw_readl(pll->base + PLLCTL); 392 ctrl = __raw_readl(pll->base + PLLCTL);
387 393
388 /* Switch the PLL to bypass mode */ 394 /* Switch the PLL to bypass mode */
389 ctrl &= ~(PLLCTL_PLLENSRC | PLLCTL_PLLEN); 395 ctrl &= ~(PLLCTL_PLLENSRC | PLLCTL_PLLEN);
390 __raw_writel(ctrl, pll->base + PLLCTL); 396 __raw_writel(ctrl, pll->base + PLLCTL);
391 397
392 /* 398 udelay(PLL_BYPASS_TIME);
393 * Wait for 4 OSCIN/CLKIN cycles to ensure that the PLLC has switched
394 * to bypass mode. Delay of 1us ensures we are good for all > 4MHz
395 * OSCIN/CLKIN inputs. Typically the input is ~25MHz.
396 */
397 udelay(1);
398 399
399 /* Reset and enable PLL */ 400 /* Reset and enable PLL */
400 ctrl &= ~(PLLCTL_PLLRST | PLLCTL_PLLDIS); 401 ctrl &= ~(PLLCTL_PLLRST | PLLCTL_PLLDIS);
@@ -408,11 +409,7 @@ int davinci_set_pllrate(struct pll_data *pll, unsigned int prediv,
408 if (pll->flags & PLL_HAS_POSTDIV) 409 if (pll->flags & PLL_HAS_POSTDIV)
409 __raw_writel(postdiv, pll->base + POSTDIV); 410 __raw_writel(postdiv, pll->base + POSTDIV);
410 411
411 /* 412 udelay(PLL_RESET_TIME);
412 * Wait for PLL to reset properly, OMAP-L138 datasheet says
413 * 'min' time = 125ns
414 */
415 udelay(1);
416 413
417 /* Bring PLL out of reset */ 414 /* Bring PLL out of reset */
418 ctrl |= PLLCTL_PLLRST; 415 ctrl |= PLLCTL_PLLRST;
@@ -424,17 +421,20 @@ int davinci_set_pllrate(struct pll_data *pll, unsigned int prediv,
424 ctrl |= PLLCTL_PLLEN; 421 ctrl |= PLLCTL_PLLEN;
425 __raw_writel(ctrl, pll->base + PLLCTL); 422 __raw_writel(ctrl, pll->base + PLLCTL);
426 423
424 spin_unlock_irqrestore(&clockfw_lock, flags);
425
427 return 0; 426 return 0;
428} 427}
429EXPORT_SYMBOL(davinci_set_pllrate); 428EXPORT_SYMBOL(davinci_set_pllrate);
430 429
431int __init davinci_clk_init(struct davinci_clk *clocks) 430int __init davinci_clk_init(struct clk_lookup *clocks)
432 { 431 {
433 struct davinci_clk *c; 432 struct clk_lookup *c;
434 struct clk *clk; 433 struct clk *clk;
434 size_t num_clocks = 0;
435 435
436 for (c = clocks; c->lk.clk; c++) { 436 for (c = clocks; c->clk; c++) {
437 clk = c->lk.clk; 437 clk = c->clk;
438 438
439 if (!clk->recalc) { 439 if (!clk->recalc) {
440 440
@@ -457,35 +457,23 @@ int __init davinci_clk_init(struct davinci_clk *clocks)
457 if (clk->lpsc) 457 if (clk->lpsc)
458 clk->flags |= CLK_PSC; 458 clk->flags |= CLK_PSC;
459 459
460 clkdev_add(&c->lk);
461 clk_register(clk); 460 clk_register(clk);
461 num_clocks++;
462 462
463 /* Turn on clocks that Linux doesn't otherwise manage */ 463 /* Turn on clocks that Linux doesn't otherwise manage */
464 if (clk->flags & ALWAYS_ENABLED) 464 if (clk->flags & ALWAYS_ENABLED)
465 clk_enable(clk); 465 clk_enable(clk);
466 } 466 }
467 467
468 return 0; 468 clkdev_add_table(clocks, num_clocks);
469}
470
471#ifdef CONFIG_PROC_FS
472#include <linux/proc_fs.h>
473#include <linux/seq_file.h>
474 469
475static void *davinci_ck_start(struct seq_file *m, loff_t *pos) 470 return 0;
476{
477 return *pos < 1 ? (void *)1 : NULL;
478} 471}
479 472
480static void *davinci_ck_next(struct seq_file *m, void *v, loff_t *pos) 473#ifdef CONFIG_DEBUG_FS
481{
482 ++*pos;
483 return NULL;
484}
485 474
486static void davinci_ck_stop(struct seq_file *m, void *v) 475#include <linux/debugfs.h>
487{ 476#include <linux/seq_file.h>
488}
489 477
490#define CLKNAME_MAX 10 /* longest clock name */ 478#define CLKNAME_MAX 10 /* longest clock name */
491#define NEST_DELTA 2 479#define NEST_DELTA 2
@@ -525,41 +513,38 @@ dump_clock(struct seq_file *s, unsigned nest, struct clk *parent)
525 513
526static int davinci_ck_show(struct seq_file *m, void *v) 514static int davinci_ck_show(struct seq_file *m, void *v)
527{ 515{
528 /* Show clock tree; we know the main oscillator is first. 516 struct clk *clk;
529 * We trust nonzero usecounts equate to PSC enables... 517
518 /*
519 * Show clock tree; We trust nonzero usecounts equate to PSC enables...
530 */ 520 */
531 mutex_lock(&clocks_mutex); 521 mutex_lock(&clocks_mutex);
532 if (!list_empty(&clocks)) 522 list_for_each_entry(clk, &clocks, node)
533 dump_clock(m, 0, list_first_entry(&clocks, struct clk, node)); 523 if (!clk->parent)
524 dump_clock(m, 0, clk);
534 mutex_unlock(&clocks_mutex); 525 mutex_unlock(&clocks_mutex);
535 526
536 return 0; 527 return 0;
537} 528}
538 529
539static const struct seq_operations davinci_ck_op = {
540 .start = davinci_ck_start,
541 .next = davinci_ck_next,
542 .stop = davinci_ck_stop,
543 .show = davinci_ck_show
544};
545
546static int davinci_ck_open(struct inode *inode, struct file *file) 530static int davinci_ck_open(struct inode *inode, struct file *file)
547{ 531{
548 return seq_open(file, &davinci_ck_op); 532 return single_open(file, davinci_ck_show, NULL);
549} 533}
550 534
551static const struct file_operations proc_davinci_ck_operations = { 535static const struct file_operations davinci_ck_operations = {
552 .open = davinci_ck_open, 536 .open = davinci_ck_open,
553 .read = seq_read, 537 .read = seq_read,
554 .llseek = seq_lseek, 538 .llseek = seq_lseek,
555 .release = seq_release, 539 .release = single_release,
556}; 540};
557 541
558static int __init davinci_ck_proc_init(void) 542static int __init davinci_clk_debugfs_init(void)
559{ 543{
560 proc_create("davinci_clocks", 0, NULL, &proc_davinci_ck_operations); 544 debugfs_create_file("davinci_clocks", S_IFREG | S_IRUGO, NULL, NULL,
545 &davinci_ck_operations);
561 return 0; 546 return 0;
562 547
563} 548}
564__initcall(davinci_ck_proc_init); 549device_initcall(davinci_clk_debugfs_init);
565#endif /* CONFIG_DEBUG_PROC_FS */ 550#endif /* CONFIG_DEBUG_FS */