diff options
author | Paul Walmsley <paul@pwsan.com> | 2012-10-21 03:01:11 -0400 |
---|---|---|
committer | Paul Walmsley <paul@pwsan.com> | 2012-10-21 03:01:11 -0400 |
commit | 4bd5259e53accda0fe295d3b25da348f4d5f4b09 (patch) | |
tree | 6ddacb5a75a8eda93916eaa917775ac36b561b81 | |
parent | ff4ae5d9319b86f940e410e92659c50f9879ff46 (diff) |
ARM: OMAP2/3: clockdomain/PRM/CM: move the low-level clockdomain functions into PRM/CM
Move the low-level SoC-specific clockdomain control functions into
cm*.c and prm*.c. For example, OMAP2xxx low-level clockdomain
functions go into cm2xxx.c. Then remove the unnecessary
clockdomain*xxx*.c files.
The objective is to centralize low-level CM and PRM register accesses
into the cm*.[ch] and prm*.[ch] files, and then to export an OMAP
SoC-independent API to higher-level OMAP power management code.
Signed-off-by: Paul Walmsley <paul@pwsan.com>
Cc: Rajendra Nayak <rnayak@ti.com>
Cc: Vaibhav Hiremath <hvaibhav@ti.com>
Acked-by: Rajendra Nayak <rnayak@ti.com>
Reviewed-by: Russ Dill <Russ.Dill@ti.com>
Acked-by: Santosh Shilimkar <santosh.shilimkar@ti.com>
-rw-r--r-- | arch/arm/mach-omap2/Makefile | 5 | ||||
-rw-r--r-- | arch/arm/mach-omap2/clockdomain2xxx_3xxx.c | 340 | ||||
-rw-r--r-- | arch/arm/mach-omap2/clockdomain33xx.c | 74 | ||||
-rw-r--r-- | arch/arm/mach-omap2/clockdomain44xx.c | 151 | ||||
-rw-r--r-- | arch/arm/mach-omap2/cm2xxx.c | 89 | ||||
-rw-r--r-- | arch/arm/mach-omap2/cm2xxx_3xxx.h | 12 | ||||
-rw-r--r-- | arch/arm/mach-omap2/cm33xx.c | 56 | ||||
-rw-r--r-- | arch/arm/mach-omap2/cm3xxx.c | 174 | ||||
-rw-r--r-- | arch/arm/mach-omap2/cminst44xx.c | 142 | ||||
-rw-r--r-- | arch/arm/mach-omap2/prm2xxx.c | 17 | ||||
-rw-r--r-- | arch/arm/mach-omap2/prm2xxx.h | 6 | ||||
-rw-r--r-- | arch/arm/mach-omap2/prm2xxx_3xxx.c | 43 | ||||
-rw-r--r-- | arch/arm/mach-omap2/prm2xxx_3xxx.h | 8 |
13 files changed, 543 insertions, 574 deletions
diff --git a/arch/arm/mach-omap2/Makefile b/arch/arm/mach-omap2/Makefile index 56a33869c8b2..3751d56853ef 100644 --- a/arch/arm/mach-omap2/Makefile +++ b/arch/arm/mach-omap2/Makefile | |||
@@ -133,22 +133,17 @@ obj-$(CONFIG_SOC_OMAP5) += $(powerdomain-common) | |||
133 | # PRCM clockdomain control | 133 | # PRCM clockdomain control |
134 | clockdomain-common += clockdomain.o | 134 | clockdomain-common += clockdomain.o |
135 | obj-$(CONFIG_ARCH_OMAP2) += $(clockdomain-common) | 135 | obj-$(CONFIG_ARCH_OMAP2) += $(clockdomain-common) |
136 | obj-$(CONFIG_ARCH_OMAP2) += clockdomain2xxx_3xxx.o | ||
137 | obj-$(CONFIG_ARCH_OMAP2) += clockdomains2xxx_3xxx_data.o | 136 | obj-$(CONFIG_ARCH_OMAP2) += clockdomains2xxx_3xxx_data.o |
138 | obj-$(CONFIG_SOC_OMAP2420) += clockdomains2420_data.o | 137 | obj-$(CONFIG_SOC_OMAP2420) += clockdomains2420_data.o |
139 | obj-$(CONFIG_SOC_OMAP2430) += clockdomains2430_data.o | 138 | obj-$(CONFIG_SOC_OMAP2430) += clockdomains2430_data.o |
140 | obj-$(CONFIG_ARCH_OMAP3) += $(clockdomain-common) | 139 | obj-$(CONFIG_ARCH_OMAP3) += $(clockdomain-common) |
141 | obj-$(CONFIG_ARCH_OMAP3) += clockdomain2xxx_3xxx.o | ||
142 | obj-$(CONFIG_ARCH_OMAP3) += clockdomains2xxx_3xxx_data.o | 140 | obj-$(CONFIG_ARCH_OMAP3) += clockdomains2xxx_3xxx_data.o |
143 | obj-$(CONFIG_ARCH_OMAP3) += clockdomains3xxx_data.o | 141 | obj-$(CONFIG_ARCH_OMAP3) += clockdomains3xxx_data.o |
144 | obj-$(CONFIG_ARCH_OMAP4) += $(clockdomain-common) | 142 | obj-$(CONFIG_ARCH_OMAP4) += $(clockdomain-common) |
145 | obj-$(CONFIG_ARCH_OMAP4) += clockdomain44xx.o | ||
146 | obj-$(CONFIG_ARCH_OMAP4) += clockdomains44xx_data.o | 143 | obj-$(CONFIG_ARCH_OMAP4) += clockdomains44xx_data.o |
147 | obj-$(CONFIG_SOC_AM33XX) += $(clockdomain-common) | 144 | obj-$(CONFIG_SOC_AM33XX) += $(clockdomain-common) |
148 | obj-$(CONFIG_SOC_AM33XX) += clockdomain33xx.o | ||
149 | obj-$(CONFIG_SOC_AM33XX) += clockdomains33xx_data.o | 145 | obj-$(CONFIG_SOC_AM33XX) += clockdomains33xx_data.o |
150 | obj-$(CONFIG_SOC_OMAP5) += $(clockdomain-common) | 146 | obj-$(CONFIG_SOC_OMAP5) += $(clockdomain-common) |
151 | obj-$(CONFIG_SOC_OMAP5) += clockdomain44xx.o | ||
152 | 147 | ||
153 | # Clock framework | 148 | # Clock framework |
154 | obj-$(CONFIG_ARCH_OMAP2) += $(clock-common) clock2xxx.o | 149 | obj-$(CONFIG_ARCH_OMAP2) += $(clock-common) clock2xxx.o |
diff --git a/arch/arm/mach-omap2/clockdomain2xxx_3xxx.c b/arch/arm/mach-omap2/clockdomain2xxx_3xxx.c deleted file mode 100644 index 658487c34cb2..000000000000 --- a/arch/arm/mach-omap2/clockdomain2xxx_3xxx.c +++ /dev/null | |||
@@ -1,340 +0,0 @@ | |||
1 | /* | ||
2 | * OMAP2 and OMAP3 clockdomain control | ||
3 | * | ||
4 | * Copyright (C) 2008-2010 Texas Instruments, Inc. | ||
5 | * Copyright (C) 2008-2010 Nokia Corporation | ||
6 | * | ||
7 | * Derived from mach-omap2/clockdomain.c written by Paul Walmsley | ||
8 | * Rajendra Nayak <rnayak@ti.com> | ||
9 | * | ||
10 | * This program is free software; you can redistribute it and/or modify | ||
11 | * it under the terms of the GNU General Public License version 2 as | ||
12 | * published by the Free Software Foundation. | ||
13 | */ | ||
14 | |||
15 | #include <linux/types.h> | ||
16 | #include <plat/prcm.h> | ||
17 | #include "prm.h" | ||
18 | #include "prm2xxx_3xxx.h" | ||
19 | #include "cm.h" | ||
20 | #include "cm2xxx.h" | ||
21 | #include "cm3xxx.h" | ||
22 | #include "cm-regbits-24xx.h" | ||
23 | #include "cm-regbits-34xx.h" | ||
24 | #include "prm-regbits-24xx.h" | ||
25 | #include "clockdomain.h" | ||
26 | |||
27 | static int omap2_clkdm_add_wkdep(struct clockdomain *clkdm1, | ||
28 | struct clockdomain *clkdm2) | ||
29 | { | ||
30 | omap2_prm_set_mod_reg_bits((1 << clkdm2->dep_bit), | ||
31 | clkdm1->pwrdm.ptr->prcm_offs, PM_WKDEP); | ||
32 | return 0; | ||
33 | } | ||
34 | |||
35 | static int omap2_clkdm_del_wkdep(struct clockdomain *clkdm1, | ||
36 | struct clockdomain *clkdm2) | ||
37 | { | ||
38 | omap2_prm_clear_mod_reg_bits((1 << clkdm2->dep_bit), | ||
39 | clkdm1->pwrdm.ptr->prcm_offs, PM_WKDEP); | ||
40 | return 0; | ||
41 | } | ||
42 | |||
43 | static int omap2_clkdm_read_wkdep(struct clockdomain *clkdm1, | ||
44 | struct clockdomain *clkdm2) | ||
45 | { | ||
46 | return omap2_prm_read_mod_bits_shift(clkdm1->pwrdm.ptr->prcm_offs, | ||
47 | PM_WKDEP, (1 << clkdm2->dep_bit)); | ||
48 | } | ||
49 | |||
50 | static int omap2_clkdm_clear_all_wkdeps(struct clockdomain *clkdm) | ||
51 | { | ||
52 | struct clkdm_dep *cd; | ||
53 | u32 mask = 0; | ||
54 | |||
55 | for (cd = clkdm->wkdep_srcs; cd && cd->clkdm_name; cd++) { | ||
56 | if (!cd->clkdm) | ||
57 | continue; /* only happens if data is erroneous */ | ||
58 | |||
59 | /* PRM accesses are slow, so minimize them */ | ||
60 | mask |= 1 << cd->clkdm->dep_bit; | ||
61 | atomic_set(&cd->wkdep_usecount, 0); | ||
62 | } | ||
63 | |||
64 | omap2_prm_clear_mod_reg_bits(mask, clkdm->pwrdm.ptr->prcm_offs, | ||
65 | PM_WKDEP); | ||
66 | return 0; | ||
67 | } | ||
68 | |||
69 | static int omap3_clkdm_add_sleepdep(struct clockdomain *clkdm1, | ||
70 | struct clockdomain *clkdm2) | ||
71 | { | ||
72 | omap2_cm_set_mod_reg_bits((1 << clkdm2->dep_bit), | ||
73 | clkdm1->pwrdm.ptr->prcm_offs, | ||
74 | OMAP3430_CM_SLEEPDEP); | ||
75 | return 0; | ||
76 | } | ||
77 | |||
78 | static int omap3_clkdm_del_sleepdep(struct clockdomain *clkdm1, | ||
79 | struct clockdomain *clkdm2) | ||
80 | { | ||
81 | omap2_cm_clear_mod_reg_bits((1 << clkdm2->dep_bit), | ||
82 | clkdm1->pwrdm.ptr->prcm_offs, | ||
83 | OMAP3430_CM_SLEEPDEP); | ||
84 | return 0; | ||
85 | } | ||
86 | |||
87 | static int omap3_clkdm_read_sleepdep(struct clockdomain *clkdm1, | ||
88 | struct clockdomain *clkdm2) | ||
89 | { | ||
90 | return omap2_prm_read_mod_bits_shift(clkdm1->pwrdm.ptr->prcm_offs, | ||
91 | OMAP3430_CM_SLEEPDEP, (1 << clkdm2->dep_bit)); | ||
92 | } | ||
93 | |||
94 | static int omap3_clkdm_clear_all_sleepdeps(struct clockdomain *clkdm) | ||
95 | { | ||
96 | struct clkdm_dep *cd; | ||
97 | u32 mask = 0; | ||
98 | |||
99 | for (cd = clkdm->sleepdep_srcs; cd && cd->clkdm_name; cd++) { | ||
100 | if (!cd->clkdm) | ||
101 | continue; /* only happens if data is erroneous */ | ||
102 | |||
103 | /* PRM accesses are slow, so minimize them */ | ||
104 | mask |= 1 << cd->clkdm->dep_bit; | ||
105 | atomic_set(&cd->sleepdep_usecount, 0); | ||
106 | } | ||
107 | omap2_prm_clear_mod_reg_bits(mask, clkdm->pwrdm.ptr->prcm_offs, | ||
108 | OMAP3430_CM_SLEEPDEP); | ||
109 | return 0; | ||
110 | } | ||
111 | |||
112 | static int omap2_clkdm_sleep(struct clockdomain *clkdm) | ||
113 | { | ||
114 | omap2_cm_set_mod_reg_bits(OMAP24XX_FORCESTATE_MASK, | ||
115 | clkdm->pwrdm.ptr->prcm_offs, | ||
116 | OMAP2_PM_PWSTCTRL); | ||
117 | return 0; | ||
118 | } | ||
119 | |||
120 | static int omap2_clkdm_wakeup(struct clockdomain *clkdm) | ||
121 | { | ||
122 | omap2_cm_clear_mod_reg_bits(OMAP24XX_FORCESTATE_MASK, | ||
123 | clkdm->pwrdm.ptr->prcm_offs, | ||
124 | OMAP2_PM_PWSTCTRL); | ||
125 | return 0; | ||
126 | } | ||
127 | |||
128 | static void omap2_clkdm_allow_idle(struct clockdomain *clkdm) | ||
129 | { | ||
130 | if (atomic_read(&clkdm->usecount) > 0) | ||
131 | _clkdm_add_autodeps(clkdm); | ||
132 | |||
133 | omap2xxx_cm_clkdm_enable_hwsup(clkdm->pwrdm.ptr->prcm_offs, | ||
134 | clkdm->clktrctrl_mask); | ||
135 | } | ||
136 | |||
137 | static void omap2_clkdm_deny_idle(struct clockdomain *clkdm) | ||
138 | { | ||
139 | omap2xxx_cm_clkdm_disable_hwsup(clkdm->pwrdm.ptr->prcm_offs, | ||
140 | clkdm->clktrctrl_mask); | ||
141 | |||
142 | if (atomic_read(&clkdm->usecount) > 0) | ||
143 | _clkdm_del_autodeps(clkdm); | ||
144 | } | ||
145 | |||
146 | static void _enable_hwsup(struct clockdomain *clkdm) | ||
147 | { | ||
148 | if (cpu_is_omap24xx()) | ||
149 | omap2xxx_cm_clkdm_enable_hwsup(clkdm->pwrdm.ptr->prcm_offs, | ||
150 | clkdm->clktrctrl_mask); | ||
151 | else if (cpu_is_omap34xx()) | ||
152 | omap3xxx_cm_clkdm_enable_hwsup(clkdm->pwrdm.ptr->prcm_offs, | ||
153 | clkdm->clktrctrl_mask); | ||
154 | } | ||
155 | |||
156 | static void _disable_hwsup(struct clockdomain *clkdm) | ||
157 | { | ||
158 | if (cpu_is_omap24xx()) | ||
159 | omap2xxx_cm_clkdm_disable_hwsup(clkdm->pwrdm.ptr->prcm_offs, | ||
160 | clkdm->clktrctrl_mask); | ||
161 | else if (cpu_is_omap34xx()) | ||
162 | omap3xxx_cm_clkdm_disable_hwsup(clkdm->pwrdm.ptr->prcm_offs, | ||
163 | clkdm->clktrctrl_mask); | ||
164 | } | ||
165 | |||
166 | static int omap3_clkdm_sleep(struct clockdomain *clkdm) | ||
167 | { | ||
168 | omap3xxx_cm_clkdm_force_sleep(clkdm->pwrdm.ptr->prcm_offs, | ||
169 | clkdm->clktrctrl_mask); | ||
170 | return 0; | ||
171 | } | ||
172 | |||
173 | static int omap3_clkdm_wakeup(struct clockdomain *clkdm) | ||
174 | { | ||
175 | omap3xxx_cm_clkdm_force_wakeup(clkdm->pwrdm.ptr->prcm_offs, | ||
176 | clkdm->clktrctrl_mask); | ||
177 | return 0; | ||
178 | } | ||
179 | |||
180 | static int omap2xxx_clkdm_clk_enable(struct clockdomain *clkdm) | ||
181 | { | ||
182 | bool hwsup = false; | ||
183 | |||
184 | if (!clkdm->clktrctrl_mask) | ||
185 | return 0; | ||
186 | |||
187 | hwsup = omap3xxx_cm_is_clkdm_in_hwsup(clkdm->pwrdm.ptr->prcm_offs, | ||
188 | clkdm->clktrctrl_mask); | ||
189 | |||
190 | if (hwsup) { | ||
191 | /* Disable HW transitions when we are changing deps */ | ||
192 | _disable_hwsup(clkdm); | ||
193 | _clkdm_add_autodeps(clkdm); | ||
194 | _enable_hwsup(clkdm); | ||
195 | } else { | ||
196 | if (clkdm->flags & CLKDM_CAN_FORCE_WAKEUP) | ||
197 | omap2_clkdm_wakeup(clkdm); | ||
198 | } | ||
199 | |||
200 | return 0; | ||
201 | } | ||
202 | |||
203 | static int omap2xxx_clkdm_clk_disable(struct clockdomain *clkdm) | ||
204 | { | ||
205 | bool hwsup = false; | ||
206 | |||
207 | if (!clkdm->clktrctrl_mask) | ||
208 | return 0; | ||
209 | |||
210 | hwsup = omap3xxx_cm_is_clkdm_in_hwsup(clkdm->pwrdm.ptr->prcm_offs, | ||
211 | clkdm->clktrctrl_mask); | ||
212 | |||
213 | if (hwsup) { | ||
214 | /* Disable HW transitions when we are changing deps */ | ||
215 | _disable_hwsup(clkdm); | ||
216 | _clkdm_del_autodeps(clkdm); | ||
217 | _enable_hwsup(clkdm); | ||
218 | } else { | ||
219 | if (clkdm->flags & CLKDM_CAN_FORCE_SLEEP) | ||
220 | omap2_clkdm_sleep(clkdm); | ||
221 | } | ||
222 | |||
223 | return 0; | ||
224 | } | ||
225 | |||
226 | static void omap3_clkdm_allow_idle(struct clockdomain *clkdm) | ||
227 | { | ||
228 | if (atomic_read(&clkdm->usecount) > 0) | ||
229 | _clkdm_add_autodeps(clkdm); | ||
230 | |||
231 | omap3xxx_cm_clkdm_enable_hwsup(clkdm->pwrdm.ptr->prcm_offs, | ||
232 | clkdm->clktrctrl_mask); | ||
233 | } | ||
234 | |||
235 | static void omap3_clkdm_deny_idle(struct clockdomain *clkdm) | ||
236 | { | ||
237 | omap3xxx_cm_clkdm_disable_hwsup(clkdm->pwrdm.ptr->prcm_offs, | ||
238 | clkdm->clktrctrl_mask); | ||
239 | |||
240 | if (atomic_read(&clkdm->usecount) > 0) | ||
241 | _clkdm_del_autodeps(clkdm); | ||
242 | } | ||
243 | |||
244 | static int omap3xxx_clkdm_clk_enable(struct clockdomain *clkdm) | ||
245 | { | ||
246 | bool hwsup = false; | ||
247 | |||
248 | if (!clkdm->clktrctrl_mask) | ||
249 | return 0; | ||
250 | |||
251 | /* | ||
252 | * The CLKDM_MISSING_IDLE_REPORTING flag documentation has | ||
253 | * more details on the unpleasant problem this is working | ||
254 | * around | ||
255 | */ | ||
256 | if ((clkdm->flags & CLKDM_MISSING_IDLE_REPORTING) && | ||
257 | (clkdm->flags & CLKDM_CAN_FORCE_WAKEUP)) { | ||
258 | omap3_clkdm_wakeup(clkdm); | ||
259 | return 0; | ||
260 | } | ||
261 | |||
262 | hwsup = omap2xxx_cm_is_clkdm_in_hwsup(clkdm->pwrdm.ptr->prcm_offs, | ||
263 | clkdm->clktrctrl_mask); | ||
264 | |||
265 | if (hwsup) { | ||
266 | /* Disable HW transitions when we are changing deps */ | ||
267 | _disable_hwsup(clkdm); | ||
268 | _clkdm_add_autodeps(clkdm); | ||
269 | _enable_hwsup(clkdm); | ||
270 | } else { | ||
271 | if (clkdm->flags & CLKDM_CAN_FORCE_WAKEUP) | ||
272 | omap3_clkdm_wakeup(clkdm); | ||
273 | } | ||
274 | |||
275 | return 0; | ||
276 | } | ||
277 | |||
278 | static int omap3xxx_clkdm_clk_disable(struct clockdomain *clkdm) | ||
279 | { | ||
280 | bool hwsup = false; | ||
281 | |||
282 | if (!clkdm->clktrctrl_mask) | ||
283 | return 0; | ||
284 | |||
285 | /* | ||
286 | * The CLKDM_MISSING_IDLE_REPORTING flag documentation has | ||
287 | * more details on the unpleasant problem this is working | ||
288 | * around | ||
289 | */ | ||
290 | if (clkdm->flags & CLKDM_MISSING_IDLE_REPORTING && | ||
291 | !(clkdm->flags & CLKDM_CAN_FORCE_SLEEP)) { | ||
292 | _enable_hwsup(clkdm); | ||
293 | return 0; | ||
294 | } | ||
295 | |||
296 | hwsup = omap2xxx_cm_is_clkdm_in_hwsup(clkdm->pwrdm.ptr->prcm_offs, | ||
297 | clkdm->clktrctrl_mask); | ||
298 | |||
299 | if (hwsup) { | ||
300 | /* Disable HW transitions when we are changing deps */ | ||
301 | _disable_hwsup(clkdm); | ||
302 | _clkdm_del_autodeps(clkdm); | ||
303 | _enable_hwsup(clkdm); | ||
304 | } else { | ||
305 | if (clkdm->flags & CLKDM_CAN_FORCE_SLEEP) | ||
306 | omap3_clkdm_sleep(clkdm); | ||
307 | } | ||
308 | |||
309 | return 0; | ||
310 | } | ||
311 | |||
312 | struct clkdm_ops omap2_clkdm_operations = { | ||
313 | .clkdm_add_wkdep = omap2_clkdm_add_wkdep, | ||
314 | .clkdm_del_wkdep = omap2_clkdm_del_wkdep, | ||
315 | .clkdm_read_wkdep = omap2_clkdm_read_wkdep, | ||
316 | .clkdm_clear_all_wkdeps = omap2_clkdm_clear_all_wkdeps, | ||
317 | .clkdm_sleep = omap2_clkdm_sleep, | ||
318 | .clkdm_wakeup = omap2_clkdm_wakeup, | ||
319 | .clkdm_allow_idle = omap2_clkdm_allow_idle, | ||
320 | .clkdm_deny_idle = omap2_clkdm_deny_idle, | ||
321 | .clkdm_clk_enable = omap2xxx_clkdm_clk_enable, | ||
322 | .clkdm_clk_disable = omap2xxx_clkdm_clk_disable, | ||
323 | }; | ||
324 | |||
325 | struct clkdm_ops omap3_clkdm_operations = { | ||
326 | .clkdm_add_wkdep = omap2_clkdm_add_wkdep, | ||
327 | .clkdm_del_wkdep = omap2_clkdm_del_wkdep, | ||
328 | .clkdm_read_wkdep = omap2_clkdm_read_wkdep, | ||
329 | .clkdm_clear_all_wkdeps = omap2_clkdm_clear_all_wkdeps, | ||
330 | .clkdm_add_sleepdep = omap3_clkdm_add_sleepdep, | ||
331 | .clkdm_del_sleepdep = omap3_clkdm_del_sleepdep, | ||
332 | .clkdm_read_sleepdep = omap3_clkdm_read_sleepdep, | ||
333 | .clkdm_clear_all_sleepdeps = omap3_clkdm_clear_all_sleepdeps, | ||
334 | .clkdm_sleep = omap3_clkdm_sleep, | ||
335 | .clkdm_wakeup = omap3_clkdm_wakeup, | ||
336 | .clkdm_allow_idle = omap3_clkdm_allow_idle, | ||
337 | .clkdm_deny_idle = omap3_clkdm_deny_idle, | ||
338 | .clkdm_clk_enable = omap3xxx_clkdm_clk_enable, | ||
339 | .clkdm_clk_disable = omap3xxx_clkdm_clk_disable, | ||
340 | }; | ||
diff --git a/arch/arm/mach-omap2/clockdomain33xx.c b/arch/arm/mach-omap2/clockdomain33xx.c deleted file mode 100644 index aca6388fad76..000000000000 --- a/arch/arm/mach-omap2/clockdomain33xx.c +++ /dev/null | |||
@@ -1,74 +0,0 @@ | |||
1 | /* | ||
2 | * AM33XX clockdomain control | ||
3 | * | ||
4 | * Copyright (C) 2011-2012 Texas Instruments Incorporated - http://www.ti.com/ | ||
5 | * Vaibhav Hiremath <hvaibhav@ti.com> | ||
6 | * | ||
7 | * Derived from mach-omap2/clockdomain44xx.c written by Rajendra Nayak | ||
8 | * | ||
9 | * This program is free software; you can redistribute it and/or | ||
10 | * modify it under the terms of the GNU General Public License as | ||
11 | * published by the Free Software Foundation version 2. | ||
12 | * | ||
13 | * This program is distributed "as is" WITHOUT ANY WARRANTY of any | ||
14 | * kind, whether express or implied; without even the implied warranty | ||
15 | * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
16 | * GNU General Public License for more details. | ||
17 | */ | ||
18 | |||
19 | #include <linux/kernel.h> | ||
20 | |||
21 | #include "clockdomain.h" | ||
22 | #include "cm33xx.h" | ||
23 | |||
24 | |||
25 | static int am33xx_clkdm_sleep(struct clockdomain *clkdm) | ||
26 | { | ||
27 | am33xx_cm_clkdm_force_sleep(clkdm->cm_inst, clkdm->clkdm_offs); | ||
28 | return 0; | ||
29 | } | ||
30 | |||
31 | static int am33xx_clkdm_wakeup(struct clockdomain *clkdm) | ||
32 | { | ||
33 | am33xx_cm_clkdm_force_wakeup(clkdm->cm_inst, clkdm->clkdm_offs); | ||
34 | return 0; | ||
35 | } | ||
36 | |||
37 | static void am33xx_clkdm_allow_idle(struct clockdomain *clkdm) | ||
38 | { | ||
39 | am33xx_cm_clkdm_enable_hwsup(clkdm->cm_inst, clkdm->clkdm_offs); | ||
40 | } | ||
41 | |||
42 | static void am33xx_clkdm_deny_idle(struct clockdomain *clkdm) | ||
43 | { | ||
44 | am33xx_cm_clkdm_disable_hwsup(clkdm->cm_inst, clkdm->clkdm_offs); | ||
45 | } | ||
46 | |||
47 | static int am33xx_clkdm_clk_enable(struct clockdomain *clkdm) | ||
48 | { | ||
49 | if (clkdm->flags & CLKDM_CAN_FORCE_WAKEUP) | ||
50 | return am33xx_clkdm_wakeup(clkdm); | ||
51 | |||
52 | return 0; | ||
53 | } | ||
54 | |||
55 | static int am33xx_clkdm_clk_disable(struct clockdomain *clkdm) | ||
56 | { | ||
57 | bool hwsup = false; | ||
58 | |||
59 | hwsup = am33xx_cm_is_clkdm_in_hwsup(clkdm->cm_inst, clkdm->clkdm_offs); | ||
60 | |||
61 | if (!hwsup && (clkdm->flags & CLKDM_CAN_FORCE_SLEEP)) | ||
62 | am33xx_clkdm_sleep(clkdm); | ||
63 | |||
64 | return 0; | ||
65 | } | ||
66 | |||
67 | struct clkdm_ops am33xx_clkdm_operations = { | ||
68 | .clkdm_sleep = am33xx_clkdm_sleep, | ||
69 | .clkdm_wakeup = am33xx_clkdm_wakeup, | ||
70 | .clkdm_allow_idle = am33xx_clkdm_allow_idle, | ||
71 | .clkdm_deny_idle = am33xx_clkdm_deny_idle, | ||
72 | .clkdm_clk_enable = am33xx_clkdm_clk_enable, | ||
73 | .clkdm_clk_disable = am33xx_clkdm_clk_disable, | ||
74 | }; | ||
diff --git a/arch/arm/mach-omap2/clockdomain44xx.c b/arch/arm/mach-omap2/clockdomain44xx.c deleted file mode 100644 index 6fc6155625bc..000000000000 --- a/arch/arm/mach-omap2/clockdomain44xx.c +++ /dev/null | |||
@@ -1,151 +0,0 @@ | |||
1 | /* | ||
2 | * OMAP4 clockdomain control | ||
3 | * | ||
4 | * Copyright (C) 2008-2010 Texas Instruments, Inc. | ||
5 | * Copyright (C) 2008-2010 Nokia Corporation | ||
6 | * | ||
7 | * Derived from mach-omap2/clockdomain.c written by Paul Walmsley | ||
8 | * Rajendra Nayak <rnayak@ti.com> | ||
9 | * | ||
10 | * This program is free software; you can redistribute it and/or modify | ||
11 | * it under the terms of the GNU General Public License version 2 as | ||
12 | * published by the Free Software Foundation. | ||
13 | */ | ||
14 | |||
15 | #include <linux/kernel.h> | ||
16 | #include "clockdomain.h" | ||
17 | #include "cminst44xx.h" | ||
18 | #include "cm44xx.h" | ||
19 | |||
20 | static int omap4_clkdm_add_wkup_sleep_dep(struct clockdomain *clkdm1, | ||
21 | struct clockdomain *clkdm2) | ||
22 | { | ||
23 | omap4_cminst_set_inst_reg_bits((1 << clkdm2->dep_bit), | ||
24 | clkdm1->prcm_partition, | ||
25 | clkdm1->cm_inst, clkdm1->clkdm_offs + | ||
26 | OMAP4_CM_STATICDEP); | ||
27 | return 0; | ||
28 | } | ||
29 | |||
30 | static int omap4_clkdm_del_wkup_sleep_dep(struct clockdomain *clkdm1, | ||
31 | struct clockdomain *clkdm2) | ||
32 | { | ||
33 | omap4_cminst_clear_inst_reg_bits((1 << clkdm2->dep_bit), | ||
34 | clkdm1->prcm_partition, | ||
35 | clkdm1->cm_inst, clkdm1->clkdm_offs + | ||
36 | OMAP4_CM_STATICDEP); | ||
37 | return 0; | ||
38 | } | ||
39 | |||
40 | static int omap4_clkdm_read_wkup_sleep_dep(struct clockdomain *clkdm1, | ||
41 | struct clockdomain *clkdm2) | ||
42 | { | ||
43 | return omap4_cminst_read_inst_reg_bits(clkdm1->prcm_partition, | ||
44 | clkdm1->cm_inst, clkdm1->clkdm_offs + | ||
45 | OMAP4_CM_STATICDEP, | ||
46 | (1 << clkdm2->dep_bit)); | ||
47 | } | ||
48 | |||
49 | static int omap4_clkdm_clear_all_wkup_sleep_deps(struct clockdomain *clkdm) | ||
50 | { | ||
51 | struct clkdm_dep *cd; | ||
52 | u32 mask = 0; | ||
53 | |||
54 | if (!clkdm->prcm_partition) | ||
55 | return 0; | ||
56 | |||
57 | for (cd = clkdm->wkdep_srcs; cd && cd->clkdm_name; cd++) { | ||
58 | if (!cd->clkdm) | ||
59 | continue; /* only happens if data is erroneous */ | ||
60 | |||
61 | mask |= 1 << cd->clkdm->dep_bit; | ||
62 | atomic_set(&cd->wkdep_usecount, 0); | ||
63 | } | ||
64 | |||
65 | omap4_cminst_clear_inst_reg_bits(mask, clkdm->prcm_partition, | ||
66 | clkdm->cm_inst, clkdm->clkdm_offs + | ||
67 | OMAP4_CM_STATICDEP); | ||
68 | return 0; | ||
69 | } | ||
70 | |||
71 | static int omap4_clkdm_sleep(struct clockdomain *clkdm) | ||
72 | { | ||
73 | omap4_cminst_clkdm_enable_hwsup(clkdm->prcm_partition, | ||
74 | clkdm->cm_inst, clkdm->clkdm_offs); | ||
75 | return 0; | ||
76 | } | ||
77 | |||
78 | static int omap4_clkdm_wakeup(struct clockdomain *clkdm) | ||
79 | { | ||
80 | omap4_cminst_clkdm_force_wakeup(clkdm->prcm_partition, | ||
81 | clkdm->cm_inst, clkdm->clkdm_offs); | ||
82 | return 0; | ||
83 | } | ||
84 | |||
85 | static void omap4_clkdm_allow_idle(struct clockdomain *clkdm) | ||
86 | { | ||
87 | omap4_cminst_clkdm_enable_hwsup(clkdm->prcm_partition, | ||
88 | clkdm->cm_inst, clkdm->clkdm_offs); | ||
89 | } | ||
90 | |||
91 | static void omap4_clkdm_deny_idle(struct clockdomain *clkdm) | ||
92 | { | ||
93 | if (clkdm->flags & CLKDM_CAN_FORCE_WAKEUP) | ||
94 | omap4_clkdm_wakeup(clkdm); | ||
95 | else | ||
96 | omap4_cminst_clkdm_disable_hwsup(clkdm->prcm_partition, | ||
97 | clkdm->cm_inst, | ||
98 | clkdm->clkdm_offs); | ||
99 | } | ||
100 | |||
101 | static int omap4_clkdm_clk_enable(struct clockdomain *clkdm) | ||
102 | { | ||
103 | if (clkdm->flags & CLKDM_CAN_FORCE_WAKEUP) | ||
104 | return omap4_clkdm_wakeup(clkdm); | ||
105 | |||
106 | return 0; | ||
107 | } | ||
108 | |||
109 | static int omap4_clkdm_clk_disable(struct clockdomain *clkdm) | ||
110 | { | ||
111 | bool hwsup = false; | ||
112 | |||
113 | if (!clkdm->prcm_partition) | ||
114 | return 0; | ||
115 | |||
116 | /* | ||
117 | * The CLKDM_MISSING_IDLE_REPORTING flag documentation has | ||
118 | * more details on the unpleasant problem this is working | ||
119 | * around | ||
120 | */ | ||
121 | if (clkdm->flags & CLKDM_MISSING_IDLE_REPORTING && | ||
122 | !(clkdm->flags & CLKDM_CAN_FORCE_SLEEP)) { | ||
123 | omap4_clkdm_allow_idle(clkdm); | ||
124 | return 0; | ||
125 | } | ||
126 | |||
127 | hwsup = omap4_cminst_is_clkdm_in_hwsup(clkdm->prcm_partition, | ||
128 | clkdm->cm_inst, clkdm->clkdm_offs); | ||
129 | |||
130 | if (!hwsup && (clkdm->flags & CLKDM_CAN_FORCE_SLEEP)) | ||
131 | omap4_clkdm_sleep(clkdm); | ||
132 | |||
133 | return 0; | ||
134 | } | ||
135 | |||
136 | struct clkdm_ops omap4_clkdm_operations = { | ||
137 | .clkdm_add_wkdep = omap4_clkdm_add_wkup_sleep_dep, | ||
138 | .clkdm_del_wkdep = omap4_clkdm_del_wkup_sleep_dep, | ||
139 | .clkdm_read_wkdep = omap4_clkdm_read_wkup_sleep_dep, | ||
140 | .clkdm_clear_all_wkdeps = omap4_clkdm_clear_all_wkup_sleep_deps, | ||
141 | .clkdm_add_sleepdep = omap4_clkdm_add_wkup_sleep_dep, | ||
142 | .clkdm_del_sleepdep = omap4_clkdm_del_wkup_sleep_dep, | ||
143 | .clkdm_read_sleepdep = omap4_clkdm_read_wkup_sleep_dep, | ||
144 | .clkdm_clear_all_sleepdeps = omap4_clkdm_clear_all_wkup_sleep_deps, | ||
145 | .clkdm_sleep = omap4_clkdm_sleep, | ||
146 | .clkdm_wakeup = omap4_clkdm_wakeup, | ||
147 | .clkdm_allow_idle = omap4_clkdm_allow_idle, | ||
148 | .clkdm_deny_idle = omap4_clkdm_deny_idle, | ||
149 | .clkdm_clk_enable = omap4_clkdm_clk_enable, | ||
150 | .clkdm_clk_disable = omap4_clkdm_clk_disable, | ||
151 | }; | ||
diff --git a/arch/arm/mach-omap2/cm2xxx.c b/arch/arm/mach-omap2/cm2xxx.c index 051349370711..64165013daf9 100644 --- a/arch/arm/mach-omap2/cm2xxx.c +++ b/arch/arm/mach-omap2/cm2xxx.c | |||
@@ -2,8 +2,9 @@ | |||
2 | * OMAP2xxx CM module functions | 2 | * OMAP2xxx CM module functions |
3 | * | 3 | * |
4 | * Copyright (C) 2009 Nokia Corporation | 4 | * Copyright (C) 2009 Nokia Corporation |
5 | * Copyright (C) 2012 Texas Instruments, Inc. | 5 | * Copyright (C) 2008-2010, 2012 Texas Instruments, Inc. |
6 | * Paul Walmsley | 6 | * Paul Walmsley |
7 | * Rajendra Nayak <rnayak@ti.com> | ||
7 | * | 8 | * |
8 | * This program is free software; you can redistribute it and/or modify | 9 | * This program is free software; you can redistribute it and/or modify |
9 | * it under the terms of the GNU General Public License version 2 as | 10 | * it under the terms of the GNU General Public License version 2 as |
@@ -20,9 +21,11 @@ | |||
20 | #include "soc.h" | 21 | #include "soc.h" |
21 | #include "iomap.h" | 22 | #include "iomap.h" |
22 | #include "common.h" | 23 | #include "common.h" |
24 | #include "prm2xxx.h" | ||
23 | #include "cm.h" | 25 | #include "cm.h" |
24 | #include "cm2xxx.h" | 26 | #include "cm2xxx.h" |
25 | #include "cm-regbits-24xx.h" | 27 | #include "cm-regbits-24xx.h" |
28 | #include "clockdomain.h" | ||
26 | 29 | ||
27 | /* CM_AUTOIDLE_PLL.AUTO_* bit values for DPLLs */ | 30 | /* CM_AUTOIDLE_PLL.AUTO_* bit values for DPLLs */ |
28 | #define DPLL_AUTOIDLE_DISABLE 0x0 | 31 | #define DPLL_AUTOIDLE_DISABLE 0x0 |
@@ -166,3 +169,87 @@ int omap2xxx_cm_wait_module_ready(s16 prcm_mod, u8 idlest_id, u8 idlest_shift) | |||
166 | 169 | ||
167 | return (i < MAX_MODULE_READY_TIME) ? 0 : -EBUSY; | 170 | return (i < MAX_MODULE_READY_TIME) ? 0 : -EBUSY; |
168 | } | 171 | } |
172 | |||
173 | /* Clockdomain low-level functions */ | ||
174 | |||
175 | static void omap2xxx_clkdm_allow_idle(struct clockdomain *clkdm) | ||
176 | { | ||
177 | if (atomic_read(&clkdm->usecount) > 0) | ||
178 | _clkdm_add_autodeps(clkdm); | ||
179 | |||
180 | omap2xxx_cm_clkdm_enable_hwsup(clkdm->pwrdm.ptr->prcm_offs, | ||
181 | clkdm->clktrctrl_mask); | ||
182 | } | ||
183 | |||
184 | static void omap2xxx_clkdm_deny_idle(struct clockdomain *clkdm) | ||
185 | { | ||
186 | omap2xxx_cm_clkdm_disable_hwsup(clkdm->pwrdm.ptr->prcm_offs, | ||
187 | clkdm->clktrctrl_mask); | ||
188 | |||
189 | if (atomic_read(&clkdm->usecount) > 0) | ||
190 | _clkdm_del_autodeps(clkdm); | ||
191 | } | ||
192 | |||
193 | static int omap2xxx_clkdm_clk_enable(struct clockdomain *clkdm) | ||
194 | { | ||
195 | bool hwsup = false; | ||
196 | |||
197 | if (!clkdm->clktrctrl_mask) | ||
198 | return 0; | ||
199 | |||
200 | hwsup = omap2xxx_cm_is_clkdm_in_hwsup(clkdm->pwrdm.ptr->prcm_offs, | ||
201 | clkdm->clktrctrl_mask); | ||
202 | |||
203 | if (hwsup) { | ||
204 | /* Disable HW transitions when we are changing deps */ | ||
205 | omap2xxx_cm_clkdm_disable_hwsup(clkdm->pwrdm.ptr->prcm_offs, | ||
206 | clkdm->clktrctrl_mask); | ||
207 | _clkdm_add_autodeps(clkdm); | ||
208 | omap2xxx_cm_clkdm_enable_hwsup(clkdm->pwrdm.ptr->prcm_offs, | ||
209 | clkdm->clktrctrl_mask); | ||
210 | } else { | ||
211 | if (clkdm->flags & CLKDM_CAN_FORCE_WAKEUP) | ||
212 | omap2xxx_clkdm_wakeup(clkdm); | ||
213 | } | ||
214 | |||
215 | return 0; | ||
216 | } | ||
217 | |||
218 | static int omap2xxx_clkdm_clk_disable(struct clockdomain *clkdm) | ||
219 | { | ||
220 | bool hwsup = false; | ||
221 | |||
222 | if (!clkdm->clktrctrl_mask) | ||
223 | return 0; | ||
224 | |||
225 | hwsup = omap2xxx_cm_is_clkdm_in_hwsup(clkdm->pwrdm.ptr->prcm_offs, | ||
226 | clkdm->clktrctrl_mask); | ||
227 | |||
228 | if (hwsup) { | ||
229 | /* Disable HW transitions when we are changing deps */ | ||
230 | omap2xxx_cm_clkdm_disable_hwsup(clkdm->pwrdm.ptr->prcm_offs, | ||
231 | clkdm->clktrctrl_mask); | ||
232 | _clkdm_del_autodeps(clkdm); | ||
233 | omap2xxx_cm_clkdm_enable_hwsup(clkdm->pwrdm.ptr->prcm_offs, | ||
234 | clkdm->clktrctrl_mask); | ||
235 | } else { | ||
236 | if (clkdm->flags & CLKDM_CAN_FORCE_SLEEP) | ||
237 | omap2xxx_clkdm_sleep(clkdm); | ||
238 | } | ||
239 | |||
240 | return 0; | ||
241 | } | ||
242 | |||
243 | struct clkdm_ops omap2_clkdm_operations = { | ||
244 | .clkdm_add_wkdep = omap2_clkdm_add_wkdep, | ||
245 | .clkdm_del_wkdep = omap2_clkdm_del_wkdep, | ||
246 | .clkdm_read_wkdep = omap2_clkdm_read_wkdep, | ||
247 | .clkdm_clear_all_wkdeps = omap2_clkdm_clear_all_wkdeps, | ||
248 | .clkdm_sleep = omap2xxx_clkdm_sleep, | ||
249 | .clkdm_wakeup = omap2xxx_clkdm_wakeup, | ||
250 | .clkdm_allow_idle = omap2xxx_clkdm_allow_idle, | ||
251 | .clkdm_deny_idle = omap2xxx_clkdm_deny_idle, | ||
252 | .clkdm_clk_enable = omap2xxx_clkdm_clk_enable, | ||
253 | .clkdm_clk_disable = omap2xxx_clkdm_clk_disable, | ||
254 | }; | ||
255 | |||
diff --git a/arch/arm/mach-omap2/cm2xxx_3xxx.h b/arch/arm/mach-omap2/cm2xxx_3xxx.h index 865d332f6fb1..0e26bb1bf7e2 100644 --- a/arch/arm/mach-omap2/cm2xxx_3xxx.h +++ b/arch/arm/mach-omap2/cm2xxx_3xxx.h | |||
@@ -74,6 +74,18 @@ static inline u32 omap2_cm_rmw_mod_reg_bits(u32 mask, u32 bits, s16 module, | |||
74 | return v; | 74 | return v; |
75 | } | 75 | } |
76 | 76 | ||
77 | /* Read a CM register, AND it, and shift the result down to bit 0 */ | ||
78 | static inline u32 omap2_cm_read_mod_bits_shift(s16 domain, s16 idx, u32 mask) | ||
79 | { | ||
80 | u32 v; | ||
81 | |||
82 | v = omap2_cm_read_mod_reg(domain, idx); | ||
83 | v &= mask; | ||
84 | v >>= __ffs(mask); | ||
85 | |||
86 | return v; | ||
87 | } | ||
88 | |||
77 | static inline u32 omap2_cm_set_mod_reg_bits(u32 bits, s16 module, s16 idx) | 89 | static inline u32 omap2_cm_set_mod_reg_bits(u32 bits, s16 module, s16 idx) |
78 | { | 90 | { |
79 | return omap2_cm_rmw_mod_reg_bits(bits, bits, module, idx); | 91 | return omap2_cm_rmw_mod_reg_bits(bits, bits, module, idx); |
diff --git a/arch/arm/mach-omap2/cm33xx.c b/arch/arm/mach-omap2/cm33xx.c index 13f56eafef03..9b3bcff127ff 100644 --- a/arch/arm/mach-omap2/cm33xx.c +++ b/arch/arm/mach-omap2/cm33xx.c | |||
@@ -24,6 +24,7 @@ | |||
24 | 24 | ||
25 | #include <plat/common.h> | 25 | #include <plat/common.h> |
26 | 26 | ||
27 | #include "clockdomain.h" | ||
27 | #include "cm.h" | 28 | #include "cm.h" |
28 | #include "cm33xx.h" | 29 | #include "cm33xx.h" |
29 | #include "cm-regbits-34xx.h" | 30 | #include "cm-regbits-34xx.h" |
@@ -311,3 +312,58 @@ void am33xx_cm_module_disable(u16 inst, s16 cdoffs, u16 clkctrl_offs) | |||
311 | v &= ~AM33XX_MODULEMODE_MASK; | 312 | v &= ~AM33XX_MODULEMODE_MASK; |
312 | am33xx_cm_write_reg(v, inst, clkctrl_offs); | 313 | am33xx_cm_write_reg(v, inst, clkctrl_offs); |
313 | } | 314 | } |
315 | |||
316 | /* | ||
317 | * Clockdomain low-level functions | ||
318 | */ | ||
319 | |||
320 | static int am33xx_clkdm_sleep(struct clockdomain *clkdm) | ||
321 | { | ||
322 | am33xx_cm_clkdm_force_sleep(clkdm->cm_inst, clkdm->clkdm_offs); | ||
323 | return 0; | ||
324 | } | ||
325 | |||
326 | static int am33xx_clkdm_wakeup(struct clockdomain *clkdm) | ||
327 | { | ||
328 | am33xx_cm_clkdm_force_wakeup(clkdm->cm_inst, clkdm->clkdm_offs); | ||
329 | return 0; | ||
330 | } | ||
331 | |||
332 | static void am33xx_clkdm_allow_idle(struct clockdomain *clkdm) | ||
333 | { | ||
334 | am33xx_cm_clkdm_enable_hwsup(clkdm->cm_inst, clkdm->clkdm_offs); | ||
335 | } | ||
336 | |||
337 | static void am33xx_clkdm_deny_idle(struct clockdomain *clkdm) | ||
338 | { | ||
339 | am33xx_cm_clkdm_disable_hwsup(clkdm->cm_inst, clkdm->clkdm_offs); | ||
340 | } | ||
341 | |||
342 | static int am33xx_clkdm_clk_enable(struct clockdomain *clkdm) | ||
343 | { | ||
344 | if (clkdm->flags & CLKDM_CAN_FORCE_WAKEUP) | ||
345 | return am33xx_clkdm_wakeup(clkdm); | ||
346 | |||
347 | return 0; | ||
348 | } | ||
349 | |||
350 | static int am33xx_clkdm_clk_disable(struct clockdomain *clkdm) | ||
351 | { | ||
352 | bool hwsup = false; | ||
353 | |||
354 | hwsup = am33xx_cm_is_clkdm_in_hwsup(clkdm->cm_inst, clkdm->clkdm_offs); | ||
355 | |||
356 | if (!hwsup && (clkdm->flags & CLKDM_CAN_FORCE_SLEEP)) | ||
357 | am33xx_clkdm_sleep(clkdm); | ||
358 | |||
359 | return 0; | ||
360 | } | ||
361 | |||
362 | struct clkdm_ops am33xx_clkdm_operations = { | ||
363 | .clkdm_sleep = am33xx_clkdm_sleep, | ||
364 | .clkdm_wakeup = am33xx_clkdm_wakeup, | ||
365 | .clkdm_allow_idle = am33xx_clkdm_allow_idle, | ||
366 | .clkdm_deny_idle = am33xx_clkdm_deny_idle, | ||
367 | .clkdm_clk_enable = am33xx_clkdm_clk_enable, | ||
368 | .clkdm_clk_disable = am33xx_clkdm_clk_disable, | ||
369 | }; | ||
diff --git a/arch/arm/mach-omap2/cm3xxx.c b/arch/arm/mach-omap2/cm3xxx.c index 8f92c56e2254..8b03ec2f4394 100644 --- a/arch/arm/mach-omap2/cm3xxx.c +++ b/arch/arm/mach-omap2/cm3xxx.c | |||
@@ -1,9 +1,10 @@ | |||
1 | /* | 1 | /* |
2 | * OMAP2/3 CM module functions | 2 | * OMAP3xxx CM module functions |
3 | * | 3 | * |
4 | * Copyright (C) 2009 Nokia Corporation | 4 | * Copyright (C) 2009 Nokia Corporation |
5 | * Copyright (C) 2012 Texas Instruments, Inc. | 5 | * Copyright (C) 2008-2010, 2012 Texas Instruments, Inc. |
6 | * Paul Walmsley | 6 | * Paul Walmsley |
7 | * Rajendra Nayak <rnayak@ti.com> | ||
7 | * | 8 | * |
8 | * This program is free software; you can redistribute it and/or modify | 9 | * This program is free software; you can redistribute it and/or modify |
9 | * it under the terms of the GNU General Public License version 2 as | 10 | * it under the terms of the GNU General Public License version 2 as |
@@ -20,9 +21,11 @@ | |||
20 | #include "soc.h" | 21 | #include "soc.h" |
21 | #include "iomap.h" | 22 | #include "iomap.h" |
22 | #include "common.h" | 23 | #include "common.h" |
24 | #include "prm2xxx_3xxx.h" | ||
23 | #include "cm.h" | 25 | #include "cm.h" |
24 | #include "cm3xxx.h" | 26 | #include "cm3xxx.h" |
25 | #include "cm-regbits-34xx.h" | 27 | #include "cm-regbits-34xx.h" |
28 | #include "clockdomain.h" | ||
26 | 29 | ||
27 | static const u8 omap3xxx_cm_idlest_offs[] = { | 30 | static const u8 omap3xxx_cm_idlest_offs[] = { |
28 | CM_IDLEST1, CM_IDLEST2, OMAP2430_CM_IDLEST3 | 31 | CM_IDLEST1, CM_IDLEST2, OMAP2430_CM_IDLEST3 |
@@ -107,6 +110,173 @@ int omap3xxx_cm_wait_module_ready(s16 prcm_mod, u8 idlest_id, u8 idlest_shift) | |||
107 | return (i < MAX_MODULE_READY_TIME) ? 0 : -EBUSY; | 110 | return (i < MAX_MODULE_READY_TIME) ? 0 : -EBUSY; |
108 | } | 111 | } |
109 | 112 | ||
113 | /* Clockdomain low-level operations */ | ||
114 | |||
115 | static int omap3xxx_clkdm_add_sleepdep(struct clockdomain *clkdm1, | ||
116 | struct clockdomain *clkdm2) | ||
117 | { | ||
118 | omap2_cm_set_mod_reg_bits((1 << clkdm2->dep_bit), | ||
119 | clkdm1->pwrdm.ptr->prcm_offs, | ||
120 | OMAP3430_CM_SLEEPDEP); | ||
121 | return 0; | ||
122 | } | ||
123 | |||
124 | static int omap3xxx_clkdm_del_sleepdep(struct clockdomain *clkdm1, | ||
125 | struct clockdomain *clkdm2) | ||
126 | { | ||
127 | omap2_cm_clear_mod_reg_bits((1 << clkdm2->dep_bit), | ||
128 | clkdm1->pwrdm.ptr->prcm_offs, | ||
129 | OMAP3430_CM_SLEEPDEP); | ||
130 | return 0; | ||
131 | } | ||
132 | |||
133 | static int omap3xxx_clkdm_read_sleepdep(struct clockdomain *clkdm1, | ||
134 | struct clockdomain *clkdm2) | ||
135 | { | ||
136 | return omap2_cm_read_mod_bits_shift(clkdm1->pwrdm.ptr->prcm_offs, | ||
137 | OMAP3430_CM_SLEEPDEP, | ||
138 | (1 << clkdm2->dep_bit)); | ||
139 | } | ||
140 | |||
141 | static int omap3xxx_clkdm_clear_all_sleepdeps(struct clockdomain *clkdm) | ||
142 | { | ||
143 | struct clkdm_dep *cd; | ||
144 | u32 mask = 0; | ||
145 | |||
146 | for (cd = clkdm->sleepdep_srcs; cd && cd->clkdm_name; cd++) { | ||
147 | if (!cd->clkdm) | ||
148 | continue; /* only happens if data is erroneous */ | ||
149 | |||
150 | mask |= 1 << cd->clkdm->dep_bit; | ||
151 | atomic_set(&cd->sleepdep_usecount, 0); | ||
152 | } | ||
153 | omap2_cm_clear_mod_reg_bits(mask, clkdm->pwrdm.ptr->prcm_offs, | ||
154 | OMAP3430_CM_SLEEPDEP); | ||
155 | return 0; | ||
156 | } | ||
157 | |||
158 | static int omap3xxx_clkdm_sleep(struct clockdomain *clkdm) | ||
159 | { | ||
160 | omap3xxx_cm_clkdm_force_sleep(clkdm->pwrdm.ptr->prcm_offs, | ||
161 | clkdm->clktrctrl_mask); | ||
162 | return 0; | ||
163 | } | ||
164 | |||
165 | static int omap3xxx_clkdm_wakeup(struct clockdomain *clkdm) | ||
166 | { | ||
167 | omap3xxx_cm_clkdm_force_wakeup(clkdm->pwrdm.ptr->prcm_offs, | ||
168 | clkdm->clktrctrl_mask); | ||
169 | return 0; | ||
170 | } | ||
171 | |||
172 | static void omap3xxx_clkdm_allow_idle(struct clockdomain *clkdm) | ||
173 | { | ||
174 | if (atomic_read(&clkdm->usecount) > 0) | ||
175 | _clkdm_add_autodeps(clkdm); | ||
176 | |||
177 | omap3xxx_cm_clkdm_enable_hwsup(clkdm->pwrdm.ptr->prcm_offs, | ||
178 | clkdm->clktrctrl_mask); | ||
179 | } | ||
180 | |||
181 | static void omap3xxx_clkdm_deny_idle(struct clockdomain *clkdm) | ||
182 | { | ||
183 | omap3xxx_cm_clkdm_disable_hwsup(clkdm->pwrdm.ptr->prcm_offs, | ||
184 | clkdm->clktrctrl_mask); | ||
185 | |||
186 | if (atomic_read(&clkdm->usecount) > 0) | ||
187 | _clkdm_del_autodeps(clkdm); | ||
188 | } | ||
189 | |||
190 | static int omap3xxx_clkdm_clk_enable(struct clockdomain *clkdm) | ||
191 | { | ||
192 | bool hwsup = false; | ||
193 | |||
194 | if (!clkdm->clktrctrl_mask) | ||
195 | return 0; | ||
196 | |||
197 | /* | ||
198 | * The CLKDM_MISSING_IDLE_REPORTING flag documentation has | ||
199 | * more details on the unpleasant problem this is working | ||
200 | * around | ||
201 | */ | ||
202 | if ((clkdm->flags & CLKDM_MISSING_IDLE_REPORTING) && | ||
203 | (clkdm->flags & CLKDM_CAN_FORCE_WAKEUP)) { | ||
204 | omap3xxx_clkdm_wakeup(clkdm); | ||
205 | return 0; | ||
206 | } | ||
207 | |||
208 | hwsup = omap3xxx_cm_is_clkdm_in_hwsup(clkdm->pwrdm.ptr->prcm_offs, | ||
209 | clkdm->clktrctrl_mask); | ||
210 | |||
211 | if (hwsup) { | ||
212 | /* Disable HW transitions when we are changing deps */ | ||
213 | omap3xxx_cm_clkdm_disable_hwsup(clkdm->pwrdm.ptr->prcm_offs, | ||
214 | clkdm->clktrctrl_mask); | ||
215 | _clkdm_add_autodeps(clkdm); | ||
216 | omap3xxx_cm_clkdm_enable_hwsup(clkdm->pwrdm.ptr->prcm_offs, | ||
217 | clkdm->clktrctrl_mask); | ||
218 | } else { | ||
219 | if (clkdm->flags & CLKDM_CAN_FORCE_WAKEUP) | ||
220 | omap3xxx_clkdm_wakeup(clkdm); | ||
221 | } | ||
222 | |||
223 | return 0; | ||
224 | } | ||
225 | |||
226 | static int omap3xxx_clkdm_clk_disable(struct clockdomain *clkdm) | ||
227 | { | ||
228 | bool hwsup = false; | ||
229 | |||
230 | if (!clkdm->clktrctrl_mask) | ||
231 | return 0; | ||
232 | |||
233 | /* | ||
234 | * The CLKDM_MISSING_IDLE_REPORTING flag documentation has | ||
235 | * more details on the unpleasant problem this is working | ||
236 | * around | ||
237 | */ | ||
238 | if (clkdm->flags & CLKDM_MISSING_IDLE_REPORTING && | ||
239 | !(clkdm->flags & CLKDM_CAN_FORCE_SLEEP)) { | ||
240 | omap3xxx_cm_clkdm_enable_hwsup(clkdm->pwrdm.ptr->prcm_offs, | ||
241 | clkdm->clktrctrl_mask); | ||
242 | return 0; | ||
243 | } | ||
244 | |||
245 | hwsup = omap3xxx_cm_is_clkdm_in_hwsup(clkdm->pwrdm.ptr->prcm_offs, | ||
246 | clkdm->clktrctrl_mask); | ||
247 | |||
248 | if (hwsup) { | ||
249 | /* Disable HW transitions when we are changing deps */ | ||
250 | omap3xxx_cm_clkdm_disable_hwsup(clkdm->pwrdm.ptr->prcm_offs, | ||
251 | clkdm->clktrctrl_mask); | ||
252 | _clkdm_del_autodeps(clkdm); | ||
253 | omap3xxx_cm_clkdm_enable_hwsup(clkdm->pwrdm.ptr->prcm_offs, | ||
254 | clkdm->clktrctrl_mask); | ||
255 | } else { | ||
256 | if (clkdm->flags & CLKDM_CAN_FORCE_SLEEP) | ||
257 | omap3xxx_clkdm_sleep(clkdm); | ||
258 | } | ||
259 | |||
260 | return 0; | ||
261 | } | ||
262 | |||
263 | struct clkdm_ops omap3_clkdm_operations = { | ||
264 | .clkdm_add_wkdep = omap2_clkdm_add_wkdep, | ||
265 | .clkdm_del_wkdep = omap2_clkdm_del_wkdep, | ||
266 | .clkdm_read_wkdep = omap2_clkdm_read_wkdep, | ||
267 | .clkdm_clear_all_wkdeps = omap2_clkdm_clear_all_wkdeps, | ||
268 | .clkdm_add_sleepdep = omap3xxx_clkdm_add_sleepdep, | ||
269 | .clkdm_del_sleepdep = omap3xxx_clkdm_del_sleepdep, | ||
270 | .clkdm_read_sleepdep = omap3xxx_clkdm_read_sleepdep, | ||
271 | .clkdm_clear_all_sleepdeps = omap3xxx_clkdm_clear_all_sleepdeps, | ||
272 | .clkdm_sleep = omap3xxx_clkdm_sleep, | ||
273 | .clkdm_wakeup = omap3xxx_clkdm_wakeup, | ||
274 | .clkdm_allow_idle = omap3xxx_clkdm_allow_idle, | ||
275 | .clkdm_deny_idle = omap3xxx_clkdm_deny_idle, | ||
276 | .clkdm_clk_enable = omap3xxx_clkdm_clk_enable, | ||
277 | .clkdm_clk_disable = omap3xxx_clkdm_clk_disable, | ||
278 | }; | ||
279 | |||
110 | /* | 280 | /* |
111 | * Context save/restore code - OMAP3 only | 281 | * Context save/restore code - OMAP3 only |
112 | */ | 282 | */ |
diff --git a/arch/arm/mach-omap2/cminst44xx.c b/arch/arm/mach-omap2/cminst44xx.c index 1894015ff04b..7f9a464f01e9 100644 --- a/arch/arm/mach-omap2/cminst44xx.c +++ b/arch/arm/mach-omap2/cminst44xx.c | |||
@@ -2,8 +2,9 @@ | |||
2 | * OMAP4 CM instance functions | 2 | * OMAP4 CM instance functions |
3 | * | 3 | * |
4 | * Copyright (C) 2009 Nokia Corporation | 4 | * Copyright (C) 2009 Nokia Corporation |
5 | * Copyright (C) 2011 Texas Instruments, Inc. | 5 | * Copyright (C) 2008-2011 Texas Instruments, Inc. |
6 | * Paul Walmsley | 6 | * Paul Walmsley |
7 | * Rajendra Nayak <rnayak@ti.com> | ||
7 | * | 8 | * |
8 | * This program is free software; you can redistribute it and/or modify | 9 | * This program is free software; you can redistribute it and/or modify |
9 | * it under the terms of the GNU General Public License version 2 as | 10 | * it under the terms of the GNU General Public License version 2 as |
@@ -22,6 +23,7 @@ | |||
22 | 23 | ||
23 | #include "iomap.h" | 24 | #include "iomap.h" |
24 | #include "common.h" | 25 | #include "common.h" |
26 | #include "clockdomain.h" | ||
25 | #include "cm.h" | 27 | #include "cm.h" |
26 | #include "cm1_44xx.h" | 28 | #include "cm1_44xx.h" |
27 | #include "cm2_44xx.h" | 29 | #include "cm2_44xx.h" |
@@ -343,3 +345,141 @@ void omap4_cminst_module_disable(u8 part, u16 inst, s16 cdoffs, | |||
343 | v &= ~OMAP4430_MODULEMODE_MASK; | 345 | v &= ~OMAP4430_MODULEMODE_MASK; |
344 | omap4_cminst_write_inst_reg(v, part, inst, clkctrl_offs); | 346 | omap4_cminst_write_inst_reg(v, part, inst, clkctrl_offs); |
345 | } | 347 | } |
348 | |||
349 | /* | ||
350 | * Clockdomain low-level functions | ||
351 | */ | ||
352 | |||
353 | static int omap4_clkdm_add_wkup_sleep_dep(struct clockdomain *clkdm1, | ||
354 | struct clockdomain *clkdm2) | ||
355 | { | ||
356 | omap4_cminst_set_inst_reg_bits((1 << clkdm2->dep_bit), | ||
357 | clkdm1->prcm_partition, | ||
358 | clkdm1->cm_inst, clkdm1->clkdm_offs + | ||
359 | OMAP4_CM_STATICDEP); | ||
360 | return 0; | ||
361 | } | ||
362 | |||
363 | static int omap4_clkdm_del_wkup_sleep_dep(struct clockdomain *clkdm1, | ||
364 | struct clockdomain *clkdm2) | ||
365 | { | ||
366 | omap4_cminst_clear_inst_reg_bits((1 << clkdm2->dep_bit), | ||
367 | clkdm1->prcm_partition, | ||
368 | clkdm1->cm_inst, clkdm1->clkdm_offs + | ||
369 | OMAP4_CM_STATICDEP); | ||
370 | return 0; | ||
371 | } | ||
372 | |||
373 | static int omap4_clkdm_read_wkup_sleep_dep(struct clockdomain *clkdm1, | ||
374 | struct clockdomain *clkdm2) | ||
375 | { | ||
376 | return omap4_cminst_read_inst_reg_bits(clkdm1->prcm_partition, | ||
377 | clkdm1->cm_inst, | ||
378 | clkdm1->clkdm_offs + | ||
379 | OMAP4_CM_STATICDEP, | ||
380 | (1 << clkdm2->dep_bit)); | ||
381 | } | ||
382 | |||
383 | static int omap4_clkdm_clear_all_wkup_sleep_deps(struct clockdomain *clkdm) | ||
384 | { | ||
385 | struct clkdm_dep *cd; | ||
386 | u32 mask = 0; | ||
387 | |||
388 | if (!clkdm->prcm_partition) | ||
389 | return 0; | ||
390 | |||
391 | for (cd = clkdm->wkdep_srcs; cd && cd->clkdm_name; cd++) { | ||
392 | if (!cd->clkdm) | ||
393 | continue; /* only happens if data is erroneous */ | ||
394 | |||
395 | mask |= 1 << cd->clkdm->dep_bit; | ||
396 | atomic_set(&cd->wkdep_usecount, 0); | ||
397 | } | ||
398 | |||
399 | omap4_cminst_clear_inst_reg_bits(mask, clkdm->prcm_partition, | ||
400 | clkdm->cm_inst, clkdm->clkdm_offs + | ||
401 | OMAP4_CM_STATICDEP); | ||
402 | return 0; | ||
403 | } | ||
404 | |||
405 | static int omap4_clkdm_sleep(struct clockdomain *clkdm) | ||
406 | { | ||
407 | omap4_cminst_clkdm_enable_hwsup(clkdm->prcm_partition, | ||
408 | clkdm->cm_inst, clkdm->clkdm_offs); | ||
409 | return 0; | ||
410 | } | ||
411 | |||
412 | static int omap4_clkdm_wakeup(struct clockdomain *clkdm) | ||
413 | { | ||
414 | omap4_cminst_clkdm_force_wakeup(clkdm->prcm_partition, | ||
415 | clkdm->cm_inst, clkdm->clkdm_offs); | ||
416 | return 0; | ||
417 | } | ||
418 | |||
419 | static void omap4_clkdm_allow_idle(struct clockdomain *clkdm) | ||
420 | { | ||
421 | omap4_cminst_clkdm_enable_hwsup(clkdm->prcm_partition, | ||
422 | clkdm->cm_inst, clkdm->clkdm_offs); | ||
423 | } | ||
424 | |||
425 | static void omap4_clkdm_deny_idle(struct clockdomain *clkdm) | ||
426 | { | ||
427 | if (clkdm->flags & CLKDM_CAN_FORCE_WAKEUP) | ||
428 | omap4_clkdm_wakeup(clkdm); | ||
429 | else | ||
430 | omap4_cminst_clkdm_disable_hwsup(clkdm->prcm_partition, | ||
431 | clkdm->cm_inst, | ||
432 | clkdm->clkdm_offs); | ||
433 | } | ||
434 | |||
435 | static int omap4_clkdm_clk_enable(struct clockdomain *clkdm) | ||
436 | { | ||
437 | if (clkdm->flags & CLKDM_CAN_FORCE_WAKEUP) | ||
438 | return omap4_clkdm_wakeup(clkdm); | ||
439 | |||
440 | return 0; | ||
441 | } | ||
442 | |||
443 | static int omap4_clkdm_clk_disable(struct clockdomain *clkdm) | ||
444 | { | ||
445 | bool hwsup = false; | ||
446 | |||
447 | if (!clkdm->prcm_partition) | ||
448 | return 0; | ||
449 | |||
450 | /* | ||
451 | * The CLKDM_MISSING_IDLE_REPORTING flag documentation has | ||
452 | * more details on the unpleasant problem this is working | ||
453 | * around | ||
454 | */ | ||
455 | if (clkdm->flags & CLKDM_MISSING_IDLE_REPORTING && | ||
456 | !(clkdm->flags & CLKDM_CAN_FORCE_SLEEP)) { | ||
457 | omap4_clkdm_allow_idle(clkdm); | ||
458 | return 0; | ||
459 | } | ||
460 | |||
461 | hwsup = omap4_cminst_is_clkdm_in_hwsup(clkdm->prcm_partition, | ||
462 | clkdm->cm_inst, clkdm->clkdm_offs); | ||
463 | |||
464 | if (!hwsup && (clkdm->flags & CLKDM_CAN_FORCE_SLEEP)) | ||
465 | omap4_clkdm_sleep(clkdm); | ||
466 | |||
467 | return 0; | ||
468 | } | ||
469 | |||
470 | struct clkdm_ops omap4_clkdm_operations = { | ||
471 | .clkdm_add_wkdep = omap4_clkdm_add_wkup_sleep_dep, | ||
472 | .clkdm_del_wkdep = omap4_clkdm_del_wkup_sleep_dep, | ||
473 | .clkdm_read_wkdep = omap4_clkdm_read_wkup_sleep_dep, | ||
474 | .clkdm_clear_all_wkdeps = omap4_clkdm_clear_all_wkup_sleep_deps, | ||
475 | .clkdm_add_sleepdep = omap4_clkdm_add_wkup_sleep_dep, | ||
476 | .clkdm_del_sleepdep = omap4_clkdm_del_wkup_sleep_dep, | ||
477 | .clkdm_read_sleepdep = omap4_clkdm_read_wkup_sleep_dep, | ||
478 | .clkdm_clear_all_sleepdeps = omap4_clkdm_clear_all_wkup_sleep_deps, | ||
479 | .clkdm_sleep = omap4_clkdm_sleep, | ||
480 | .clkdm_wakeup = omap4_clkdm_wakeup, | ||
481 | .clkdm_allow_idle = omap4_clkdm_allow_idle, | ||
482 | .clkdm_deny_idle = omap4_clkdm_deny_idle, | ||
483 | .clkdm_clk_enable = omap4_clkdm_clk_enable, | ||
484 | .clkdm_clk_disable = omap4_clkdm_clk_disable, | ||
485 | }; | ||
diff --git a/arch/arm/mach-omap2/prm2xxx.c b/arch/arm/mach-omap2/prm2xxx.c index 218ef6a1f11e..9cdb4e5e3d80 100644 --- a/arch/arm/mach-omap2/prm2xxx.c +++ b/arch/arm/mach-omap2/prm2xxx.c | |||
@@ -24,10 +24,27 @@ | |||
24 | 24 | ||
25 | #include "vp.h" | 25 | #include "vp.h" |
26 | #include "powerdomain.h" | 26 | #include "powerdomain.h" |
27 | #include "clockdomain.h" | ||
27 | #include "prm2xxx.h" | 28 | #include "prm2xxx.h" |
28 | #include "cm2xxx_3xxx.h" | 29 | #include "cm2xxx_3xxx.h" |
29 | #include "prm-regbits-24xx.h" | 30 | #include "prm-regbits-24xx.h" |
30 | 31 | ||
32 | int omap2xxx_clkdm_sleep(struct clockdomain *clkdm) | ||
33 | { | ||
34 | omap2_prm_set_mod_reg_bits(OMAP24XX_FORCESTATE_MASK, | ||
35 | clkdm->pwrdm.ptr->prcm_offs, | ||
36 | OMAP2_PM_PWSTCTRL); | ||
37 | return 0; | ||
38 | } | ||
39 | |||
40 | int omap2xxx_clkdm_wakeup(struct clockdomain *clkdm) | ||
41 | { | ||
42 | omap2_prm_clear_mod_reg_bits(OMAP24XX_FORCESTATE_MASK, | ||
43 | clkdm->pwrdm.ptr->prcm_offs, | ||
44 | OMAP2_PM_PWSTCTRL); | ||
45 | return 0; | ||
46 | } | ||
47 | |||
31 | struct pwrdm_ops omap2_pwrdm_operations = { | 48 | struct pwrdm_ops omap2_pwrdm_operations = { |
32 | .pwrdm_set_next_pwrst = omap2_pwrdm_set_next_pwrst, | 49 | .pwrdm_set_next_pwrst = omap2_pwrdm_set_next_pwrst, |
33 | .pwrdm_read_next_pwrst = omap2_pwrdm_read_next_pwrst, | 50 | .pwrdm_read_next_pwrst = omap2_pwrdm_read_next_pwrst, |
diff --git a/arch/arm/mach-omap2/prm2xxx.h b/arch/arm/mach-omap2/prm2xxx.h index 6490e1a580e8..6d76716a1ea5 100644 --- a/arch/arm/mach-omap2/prm2xxx.h +++ b/arch/arm/mach-omap2/prm2xxx.h | |||
@@ -119,4 +119,10 @@ | |||
119 | #define OMAP24XX_PRCM_IRQSTATUS_IVA 0x00f8 | 119 | #define OMAP24XX_PRCM_IRQSTATUS_IVA 0x00f8 |
120 | #define OMAP24XX_PRCM_IRQENABLE_IVA 0x00fc | 120 | #define OMAP24XX_PRCM_IRQENABLE_IVA 0x00fc |
121 | 121 | ||
122 | #ifndef __ASSEMBLER__ | ||
123 | /* Function prototypes */ | ||
124 | extern int omap2xxx_clkdm_sleep(struct clockdomain *clkdm); | ||
125 | extern int omap2xxx_clkdm_wakeup(struct clockdomain *clkdm); | ||
126 | #endif | ||
127 | |||
122 | #endif | 128 | #endif |
diff --git a/arch/arm/mach-omap2/prm2xxx_3xxx.c b/arch/arm/mach-omap2/prm2xxx_3xxx.c index bdddf5ca67c4..30517f5af707 100644 --- a/arch/arm/mach-omap2/prm2xxx_3xxx.c +++ b/arch/arm/mach-omap2/prm2xxx_3xxx.c | |||
@@ -20,6 +20,7 @@ | |||
20 | #include "powerdomain.h" | 20 | #include "powerdomain.h" |
21 | #include "prm2xxx_3xxx.h" | 21 | #include "prm2xxx_3xxx.h" |
22 | #include "prm-regbits-24xx.h" | 22 | #include "prm-regbits-24xx.h" |
23 | #include "clockdomain.h" | ||
23 | 24 | ||
24 | /** | 25 | /** |
25 | * omap2_prm_is_hardreset_asserted - read the HW reset line state of | 26 | * omap2_prm_is_hardreset_asserted - read the HW reset line state of |
@@ -208,3 +209,45 @@ int omap2_pwrdm_wait_transition(struct powerdomain *pwrdm) | |||
208 | return 0; | 209 | return 0; |
209 | } | 210 | } |
210 | 211 | ||
212 | int omap2_clkdm_add_wkdep(struct clockdomain *clkdm1, | ||
213 | struct clockdomain *clkdm2) | ||
214 | { | ||
215 | omap2_prm_set_mod_reg_bits((1 << clkdm2->dep_bit), | ||
216 | clkdm1->pwrdm.ptr->prcm_offs, PM_WKDEP); | ||
217 | return 0; | ||
218 | } | ||
219 | |||
220 | int omap2_clkdm_del_wkdep(struct clockdomain *clkdm1, | ||
221 | struct clockdomain *clkdm2) | ||
222 | { | ||
223 | omap2_prm_clear_mod_reg_bits((1 << clkdm2->dep_bit), | ||
224 | clkdm1->pwrdm.ptr->prcm_offs, PM_WKDEP); | ||
225 | return 0; | ||
226 | } | ||
227 | |||
228 | int omap2_clkdm_read_wkdep(struct clockdomain *clkdm1, | ||
229 | struct clockdomain *clkdm2) | ||
230 | { | ||
231 | return omap2_prm_read_mod_bits_shift(clkdm1->pwrdm.ptr->prcm_offs, | ||
232 | PM_WKDEP, (1 << clkdm2->dep_bit)); | ||
233 | } | ||
234 | |||
235 | int omap2_clkdm_clear_all_wkdeps(struct clockdomain *clkdm) | ||
236 | { | ||
237 | struct clkdm_dep *cd; | ||
238 | u32 mask = 0; | ||
239 | |||
240 | for (cd = clkdm->wkdep_srcs; cd && cd->clkdm_name; cd++) { | ||
241 | if (!cd->clkdm) | ||
242 | continue; /* only happens if data is erroneous */ | ||
243 | |||
244 | /* PRM accesses are slow, so minimize them */ | ||
245 | mask |= 1 << cd->clkdm->dep_bit; | ||
246 | atomic_set(&cd->wkdep_usecount, 0); | ||
247 | } | ||
248 | |||
249 | omap2_prm_clear_mod_reg_bits(mask, clkdm->pwrdm.ptr->prcm_offs, | ||
250 | PM_WKDEP); | ||
251 | return 0; | ||
252 | } | ||
253 | |||
diff --git a/arch/arm/mach-omap2/prm2xxx_3xxx.h b/arch/arm/mach-omap2/prm2xxx_3xxx.h index 706b0262f3f0..22a405a1543b 100644 --- a/arch/arm/mach-omap2/prm2xxx_3xxx.h +++ b/arch/arm/mach-omap2/prm2xxx_3xxx.h | |||
@@ -116,6 +116,14 @@ extern int omap2_pwrdm_read_mem_retst(struct powerdomain *pwrdm, u8 bank); | |||
116 | extern int omap2_pwrdm_set_logic_retst(struct powerdomain *pwrdm, u8 pwrst); | 116 | extern int omap2_pwrdm_set_logic_retst(struct powerdomain *pwrdm, u8 pwrst); |
117 | extern int omap2_pwrdm_wait_transition(struct powerdomain *pwrdm); | 117 | extern int omap2_pwrdm_wait_transition(struct powerdomain *pwrdm); |
118 | 118 | ||
119 | extern int omap2_clkdm_add_wkdep(struct clockdomain *clkdm1, | ||
120 | struct clockdomain *clkdm2); | ||
121 | extern int omap2_clkdm_del_wkdep(struct clockdomain *clkdm1, | ||
122 | struct clockdomain *clkdm2); | ||
123 | extern int omap2_clkdm_read_wkdep(struct clockdomain *clkdm1, | ||
124 | struct clockdomain *clkdm2); | ||
125 | extern int omap2_clkdm_clear_all_wkdeps(struct clockdomain *clkdm); | ||
126 | |||
119 | #endif /* __ASSEMBLER */ | 127 | #endif /* __ASSEMBLER */ |
120 | 128 | ||
121 | /* | 129 | /* |