aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm/mach-omap2/clock.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/arm/mach-omap2/clock.c')
-rw-r--r--arch/arm/mach-omap2/clock.c57
1 files changed, 44 insertions, 13 deletions
diff --git a/arch/arm/mach-omap2/clock.c b/arch/arm/mach-omap2/clock.c
index c7c5d31e9082..591581a66532 100644
--- a/arch/arm/mach-omap2/clock.c
+++ b/arch/arm/mach-omap2/clock.c
@@ -26,7 +26,6 @@
26#include <linux/clk-private.h> 26#include <linux/clk-private.h>
27#include <asm/cpu.h> 27#include <asm/cpu.h>
28 28
29
30#include <trace/events/power.h> 29#include <trace/events/power.h>
31 30
32#include "soc.h" 31#include "soc.h"
@@ -56,6 +55,31 @@ u16 cpu_mask;
56static bool clkdm_control = true; 55static bool clkdm_control = true;
57 56
58static LIST_HEAD(clk_hw_omap_clocks); 57static LIST_HEAD(clk_hw_omap_clocks);
58void __iomem *clk_memmaps[CLK_MAX_MEMMAPS];
59
60void omap2_clk_writel(u32 val, struct clk_hw_omap *clk, void __iomem *reg)
61{
62 if (clk->flags & MEMMAP_ADDRESSING) {
63 struct clk_omap_reg *r = (struct clk_omap_reg *)&reg;
64 writel_relaxed(val, clk_memmaps[r->index] + r->offset);
65 } else {
66 writel_relaxed(val, reg);
67 }
68}
69
70u32 omap2_clk_readl(struct clk_hw_omap *clk, void __iomem *reg)
71{
72 u32 val;
73
74 if (clk->flags & MEMMAP_ADDRESSING) {
75 struct clk_omap_reg *r = (struct clk_omap_reg *)&reg;
76 val = readl_relaxed(clk_memmaps[r->index] + r->offset);
77 } else {
78 val = readl_relaxed(reg);
79 }
80
81 return val;
82}
59 83
60/* 84/*
61 * Used for clocks that have the same value as the parent clock, 85 * Used for clocks that have the same value as the parent clock,
@@ -87,6 +111,7 @@ unsigned long omap_fixed_divisor_recalc(struct clk_hw *hw,
87 111
88/** 112/**
89 * _wait_idlest_generic - wait for a module to leave the idle state 113 * _wait_idlest_generic - wait for a module to leave the idle state
114 * @clk: module clock to wait for (needed for register offsets)
90 * @reg: virtual address of module IDLEST register 115 * @reg: virtual address of module IDLEST register
91 * @mask: value to mask against to determine if the module is active 116 * @mask: value to mask against to determine if the module is active
92 * @idlest: idle state indicator (0 or 1) for the clock 117 * @idlest: idle state indicator (0 or 1) for the clock
@@ -98,14 +123,14 @@ unsigned long omap_fixed_divisor_recalc(struct clk_hw *hw,
98 * elapsed. XXX Deprecated - should be moved into drivers for the 123 * elapsed. XXX Deprecated - should be moved into drivers for the
99 * individual IP block that the IDLEST register exists in. 124 * individual IP block that the IDLEST register exists in.
100 */ 125 */
101static int _wait_idlest_generic(void __iomem *reg, u32 mask, u8 idlest, 126static int _wait_idlest_generic(struct clk_hw_omap *clk, void __iomem *reg,
102 const char *name) 127 u32 mask, u8 idlest, const char *name)
103{ 128{
104 int i = 0, ena = 0; 129 int i = 0, ena = 0;
105 130
106 ena = (idlest) ? 0 : mask; 131 ena = (idlest) ? 0 : mask;
107 132
108 omap_test_timeout(((__raw_readl(reg) & mask) == ena), 133 omap_test_timeout(((omap2_clk_readl(clk, reg) & mask) == ena),
109 MAX_MODULE_ENABLE_WAIT, i); 134 MAX_MODULE_ENABLE_WAIT, i);
110 135
111 if (i < MAX_MODULE_ENABLE_WAIT) 136 if (i < MAX_MODULE_ENABLE_WAIT)
@@ -138,7 +163,7 @@ static void _omap2_module_wait_ready(struct clk_hw_omap *clk)
138 /* Not all modules have multiple clocks that their IDLEST depends on */ 163 /* Not all modules have multiple clocks that their IDLEST depends on */
139 if (clk->ops->find_companion) { 164 if (clk->ops->find_companion) {
140 clk->ops->find_companion(clk, &companion_reg, &other_bit); 165 clk->ops->find_companion(clk, &companion_reg, &other_bit);
141 if (!(__raw_readl(companion_reg) & (1 << other_bit))) 166 if (!(omap2_clk_readl(clk, companion_reg) & (1 << other_bit)))
142 return; 167 return;
143 } 168 }
144 169
@@ -146,8 +171,8 @@ static void _omap2_module_wait_ready(struct clk_hw_omap *clk)
146 r = cm_split_idlest_reg(idlest_reg, &prcm_mod, &idlest_reg_id); 171 r = cm_split_idlest_reg(idlest_reg, &prcm_mod, &idlest_reg_id);
147 if (r) { 172 if (r) {
148 /* IDLEST register not in the CM module */ 173 /* IDLEST register not in the CM module */
149 _wait_idlest_generic(idlest_reg, (1 << idlest_bit), idlest_val, 174 _wait_idlest_generic(clk, idlest_reg, (1 << idlest_bit),
150 __clk_get_name(clk->hw.clk)); 175 idlest_val, __clk_get_name(clk->hw.clk));
151 } else { 176 } else {
152 cm_wait_module_ready(prcm_mod, idlest_reg_id, idlest_bit); 177 cm_wait_module_ready(prcm_mod, idlest_reg_id, idlest_bit);
153 }; 178 };
@@ -309,13 +334,13 @@ int omap2_dflt_clk_enable(struct clk_hw *hw)
309 } 334 }
310 335
311 /* FIXME should not have INVERT_ENABLE bit here */ 336 /* FIXME should not have INVERT_ENABLE bit here */
312 v = __raw_readl(clk->enable_reg); 337 v = omap2_clk_readl(clk, clk->enable_reg);
313 if (clk->flags & INVERT_ENABLE) 338 if (clk->flags & INVERT_ENABLE)
314 v &= ~(1 << clk->enable_bit); 339 v &= ~(1 << clk->enable_bit);
315 else 340 else
316 v |= (1 << clk->enable_bit); 341 v |= (1 << clk->enable_bit);
317 __raw_writel(v, clk->enable_reg); 342 omap2_clk_writel(v, clk, clk->enable_reg);
318 v = __raw_readl(clk->enable_reg); /* OCP barrier */ 343 v = omap2_clk_readl(clk, clk->enable_reg); /* OCP barrier */
319 344
320 if (clk->ops && clk->ops->find_idlest) 345 if (clk->ops && clk->ops->find_idlest)
321 _omap2_module_wait_ready(clk); 346 _omap2_module_wait_ready(clk);
@@ -353,12 +378,12 @@ void omap2_dflt_clk_disable(struct clk_hw *hw)
353 return; 378 return;
354 } 379 }
355 380
356 v = __raw_readl(clk->enable_reg); 381 v = omap2_clk_readl(clk, clk->enable_reg);
357 if (clk->flags & INVERT_ENABLE) 382 if (clk->flags & INVERT_ENABLE)
358 v |= (1 << clk->enable_bit); 383 v |= (1 << clk->enable_bit);
359 else 384 else
360 v &= ~(1 << clk->enable_bit); 385 v &= ~(1 << clk->enable_bit);
361 __raw_writel(v, clk->enable_reg); 386 omap2_clk_writel(v, clk, clk->enable_reg);
362 /* No OCP barrier needed here since it is a disable operation */ 387 /* No OCP barrier needed here since it is a disable operation */
363 388
364 if (clkdm_control && clk->clkdm) 389 if (clkdm_control && clk->clkdm)
@@ -454,7 +479,7 @@ int omap2_dflt_clk_is_enabled(struct clk_hw *hw)
454 struct clk_hw_omap *clk = to_clk_hw_omap(hw); 479 struct clk_hw_omap *clk = to_clk_hw_omap(hw);
455 u32 v; 480 u32 v;
456 481
457 v = __raw_readl(clk->enable_reg); 482 v = omap2_clk_readl(clk, clk->enable_reg);
458 483
459 if (clk->flags & INVERT_ENABLE) 484 if (clk->flags & INVERT_ENABLE)
460 v ^= BIT(clk->enable_bit); 485 v ^= BIT(clk->enable_bit);
@@ -520,6 +545,9 @@ int omap2_clk_enable_autoidle_all(void)
520 list_for_each_entry(c, &clk_hw_omap_clocks, node) 545 list_for_each_entry(c, &clk_hw_omap_clocks, node)
521 if (c->ops && c->ops->allow_idle) 546 if (c->ops && c->ops->allow_idle)
522 c->ops->allow_idle(c); 547 c->ops->allow_idle(c);
548
549 of_ti_clk_allow_autoidle_all();
550
523 return 0; 551 return 0;
524} 552}
525 553
@@ -539,6 +567,9 @@ int omap2_clk_disable_autoidle_all(void)
539 list_for_each_entry(c, &clk_hw_omap_clocks, node) 567 list_for_each_entry(c, &clk_hw_omap_clocks, node)
540 if (c->ops && c->ops->deny_idle) 568 if (c->ops && c->ops->deny_idle)
541 c->ops->deny_idle(c); 569 c->ops->deny_idle(c);
570
571 of_ti_clk_deny_autoidle_all();
572
542 return 0; 573 return 0;
543} 574}
544 575