diff options
Diffstat (limited to 'arch/arm/mach-omap2/clock.c')
-rw-r--r-- | arch/arm/mach-omap2/clock.c | 57 |
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; | |||
56 | static bool clkdm_control = true; | 55 | static bool clkdm_control = true; |
57 | 56 | ||
58 | static LIST_HEAD(clk_hw_omap_clocks); | 57 | static LIST_HEAD(clk_hw_omap_clocks); |
58 | void __iomem *clk_memmaps[CLK_MAX_MEMMAPS]; | ||
59 | |||
60 | void 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 *)® | ||
64 | writel_relaxed(val, clk_memmaps[r->index] + r->offset); | ||
65 | } else { | ||
66 | writel_relaxed(val, reg); | ||
67 | } | ||
68 | } | ||
69 | |||
70 | u32 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 *)® | ||
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 | */ |
101 | static int _wait_idlest_generic(void __iomem *reg, u32 mask, u8 idlest, | 126 | static 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 | ||