diff options
author | Paul Walmsley <paul@pwsan.com> | 2012-10-29 22:56:29 -0400 |
---|---|---|
committer | Paul Walmsley <paul@pwsan.com> | 2012-11-08 14:33:08 -0500 |
commit | c4ceedcb18cf7a06059482a3a1828b9aad9f78cf (patch) | |
tree | e9b5e9bb75aa84ea70159fa68e103a69518a1eee /arch/arm/mach-omap2/clock.c | |
parent | b6ffa05091978c68e94d2802200f2aaa06a598d9 (diff) |
ARM: OMAP2+: CM/clock: convert _omap2_module_wait_ready() to use SoC-independent CM functions
Convert the OMAP clock code's _omap2_module_wait_ready() to use
SoC-independent CM functions that are provided by the CM code, rather
than using a deprecated function from mach-omap2/prcm.c.
This facilitates the future conversion of the CM code to a driver, and
also removes a mach-omap2/prcm.c user. mach-omap2/prcm.c will be removed
by a subsequent patch.
Some modules have IDLEST registers that aren't in the CM module, such
as the AM3517 IDLEST bits. So we also need a fallback function for
these non-CM odd cases. Create a temporary one in mach-omap2/clock.c,
intended to exist until the SCM drivers are ready.
Signed-off-by: Paul Walmsley <paul@pwsan.com>
Tested-by: Vaibhav Hiremath <hvaibhav@ti.com>
Diffstat (limited to 'arch/arm/mach-omap2/clock.c')
-rw-r--r-- | arch/arm/mach-omap2/clock.c | 56 |
1 files changed, 53 insertions, 3 deletions
diff --git a/arch/arm/mach-omap2/clock.c b/arch/arm/mach-omap2/clock.c index 9205ea7d8dde..2fe57d65d0f1 100644 --- a/arch/arm/mach-omap2/clock.c +++ b/arch/arm/mach-omap2/clock.c | |||
@@ -33,10 +33,18 @@ | |||
33 | #include "soc.h" | 33 | #include "soc.h" |
34 | #include "clockdomain.h" | 34 | #include "clockdomain.h" |
35 | #include "clock.h" | 35 | #include "clock.h" |
36 | #include "cm.h" | ||
36 | #include "cm2xxx.h" | 37 | #include "cm2xxx.h" |
37 | #include "cm3xxx.h" | 38 | #include "cm3xxx.h" |
38 | #include "cm-regbits-24xx.h" | 39 | #include "cm-regbits-24xx.h" |
39 | #include "cm-regbits-34xx.h" | 40 | #include "cm-regbits-34xx.h" |
41 | #include "common.h" | ||
42 | |||
43 | /* | ||
44 | * MAX_MODULE_ENABLE_WAIT: maximum of number of microseconds to wait | ||
45 | * for a module to indicate that it is no longer in idle | ||
46 | */ | ||
47 | #define MAX_MODULE_ENABLE_WAIT 100000 | ||
40 | 48 | ||
41 | u16 cpu_mask; | 49 | u16 cpu_mask; |
42 | 50 | ||
@@ -58,6 +66,40 @@ static DEFINE_SPINLOCK(clockfw_lock); | |||
58 | 66 | ||
59 | /* Private functions */ | 67 | /* Private functions */ |
60 | 68 | ||
69 | |||
70 | /** | ||
71 | * _wait_idlest_generic - wait for a module to leave the idle state | ||
72 | * @reg: virtual address of module IDLEST register | ||
73 | * @mask: value to mask against to determine if the module is active | ||
74 | * @idlest: idle state indicator (0 or 1) for the clock | ||
75 | * @name: name of the clock (for printk) | ||
76 | * | ||
77 | * Wait for a module to leave idle, where its idle-status register is | ||
78 | * not inside the CM module. Returns 1 if the module left idle | ||
79 | * promptly, or 0 if the module did not leave idle before the timeout | ||
80 | * elapsed. XXX Deprecated - should be moved into drivers for the | ||
81 | * individual IP block that the IDLEST register exists in. | ||
82 | */ | ||
83 | static int _wait_idlest_generic(void __iomem *reg, u32 mask, u8 idlest, | ||
84 | const char *name) | ||
85 | { | ||
86 | int i = 0, ena = 0; | ||
87 | |||
88 | ena = (idlest) ? 0 : mask; | ||
89 | |||
90 | omap_test_timeout(((__raw_readl(reg) & mask) == ena), | ||
91 | MAX_MODULE_ENABLE_WAIT, i); | ||
92 | |||
93 | if (i < MAX_MODULE_ENABLE_WAIT) | ||
94 | pr_debug("omap clock: module associated with clock %s ready after %d loops\n", | ||
95 | name, i); | ||
96 | else | ||
97 | pr_err("omap clock: module associated with clock %s didn't enable in %d tries\n", | ||
98 | name, MAX_MODULE_ENABLE_WAIT); | ||
99 | |||
100 | return (i < MAX_MODULE_ENABLE_WAIT) ? 1 : 0; | ||
101 | }; | ||
102 | |||
61 | /** | 103 | /** |
62 | * _omap2_module_wait_ready - wait for an OMAP module to leave IDLE | 104 | * _omap2_module_wait_ready - wait for an OMAP module to leave IDLE |
63 | * @clk: struct clk * belonging to the module | 105 | * @clk: struct clk * belonging to the module |
@@ -71,7 +113,9 @@ static DEFINE_SPINLOCK(clockfw_lock); | |||
71 | static void _omap2_module_wait_ready(struct clk *clk) | 113 | static void _omap2_module_wait_ready(struct clk *clk) |
72 | { | 114 | { |
73 | void __iomem *companion_reg, *idlest_reg; | 115 | void __iomem *companion_reg, *idlest_reg; |
74 | u8 other_bit, idlest_bit, idlest_val; | 116 | u8 other_bit, idlest_bit, idlest_val, idlest_reg_id; |
117 | s16 prcm_mod; | ||
118 | int r; | ||
75 | 119 | ||
76 | /* Not all modules have multiple clocks that their IDLEST depends on */ | 120 | /* Not all modules have multiple clocks that their IDLEST depends on */ |
77 | if (clk->ops->find_companion) { | 121 | if (clk->ops->find_companion) { |
@@ -82,8 +126,14 @@ static void _omap2_module_wait_ready(struct clk *clk) | |||
82 | 126 | ||
83 | clk->ops->find_idlest(clk, &idlest_reg, &idlest_bit, &idlest_val); | 127 | clk->ops->find_idlest(clk, &idlest_reg, &idlest_bit, &idlest_val); |
84 | 128 | ||
85 | omap2_cm_wait_idlest(idlest_reg, (1 << idlest_bit), idlest_val, | 129 | r = cm_split_idlest_reg(idlest_reg, &prcm_mod, &idlest_reg_id); |
86 | __clk_get_name(clk)); | 130 | if (r) { |
131 | /* IDLEST register not in the CM module */ | ||
132 | _wait_idlest_generic(idlest_reg, (1 << idlest_bit), idlest_val, | ||
133 | clk->name); | ||
134 | } else { | ||
135 | cm_wait_module_ready(prcm_mod, idlest_reg_id, idlest_bit); | ||
136 | }; | ||
87 | } | 137 | } |
88 | 138 | ||
89 | /* Public functions */ | 139 | /* Public functions */ |