aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm/mach-omap2/prm2xxx_3xxx.c
diff options
context:
space:
mode:
authorPaul Walmsley <paul@pwsan.com>2012-10-21 03:01:10 -0400
committerPaul Walmsley <paul@pwsan.com>2012-10-21 03:01:10 -0400
commit139563ad27e7baad7935b8113940f0d804cf513b (patch)
treef367d3813f1fb83773782537ad658f3cf3bb0508 /arch/arm/mach-omap2/prm2xxx_3xxx.c
parent7a0c19337c38a1ffa7587272e7784e6431e78eaa (diff)
ARM: OMAP2+: PRM: split PRM functions into OMAP2, OMAP3-specific files
Move OMAP3xxx-specific PRM functions & macros into prm3xxx.[ch] and OMAP2xxx-specific macros into prm2xxx.h. (prm2xxx.c will be created by a subsequent patch when it's needed.) Move basic PRM register access functions into static inline functions in prm2xxx_3xxx.h, leaving only OMAP2/3 hardreset functions in prm2xxx_3xxx.c. Also clarify the initcall function naming to reinforce that this code is specifically for the PRM IP block. This is in preparation for the upcoming powerdomain series and the upcoming move of this code to drivers/. Signed-off-by: Paul Walmsley <paul@pwsan.com> Reviewed-by: Russ Dill <Russ.Dill@ti.com> Acked-by: Santosh Shilimkar <santosh.shilimkar@ti.com>
Diffstat (limited to 'arch/arm/mach-omap2/prm2xxx_3xxx.c')
-rw-r--r--arch/arm/mach-omap2/prm2xxx_3xxx.c265
1 files changed, 0 insertions, 265 deletions
diff --git a/arch/arm/mach-omap2/prm2xxx_3xxx.c b/arch/arm/mach-omap2/prm2xxx_3xxx.c
index 9529984d8d2b..0d6cc543987d 100644
--- a/arch/arm/mach-omap2/prm2xxx_3xxx.c
+++ b/arch/arm/mach-omap2/prm2xxx_3xxx.c
@@ -15,82 +15,11 @@
15#include <linux/errno.h> 15#include <linux/errno.h>
16#include <linux/err.h> 16#include <linux/err.h>
17#include <linux/io.h> 17#include <linux/io.h>
18#include <linux/irq.h>
19 18
20#include <plat/prcm.h>
21
22#include "soc.h"
23#include "common.h" 19#include "common.h"
24#include "vp.h"
25 20
26#include "prm2xxx_3xxx.h" 21#include "prm2xxx_3xxx.h"
27#include "cm2xxx_3xxx.h"
28#include "prm-regbits-24xx.h" 22#include "prm-regbits-24xx.h"
29#include "prm-regbits-34xx.h"
30
31static const struct omap_prcm_irq omap3_prcm_irqs[] = {
32 OMAP_PRCM_IRQ("wkup", 0, 0),
33 OMAP_PRCM_IRQ("io", 9, 1),
34};
35
36static struct omap_prcm_irq_setup omap3_prcm_irq_setup = {
37 .ack = OMAP3_PRM_IRQSTATUS_MPU_OFFSET,
38 .mask = OMAP3_PRM_IRQENABLE_MPU_OFFSET,
39 .nr_regs = 1,
40 .irqs = omap3_prcm_irqs,
41 .nr_irqs = ARRAY_SIZE(omap3_prcm_irqs),
42 .irq = 11 + OMAP_INTC_START,
43 .read_pending_irqs = &omap3xxx_prm_read_pending_irqs,
44 .ocp_barrier = &omap3xxx_prm_ocp_barrier,
45 .save_and_clear_irqen = &omap3xxx_prm_save_and_clear_irqen,
46 .restore_irqen = &omap3xxx_prm_restore_irqen,
47};
48
49u32 omap2_prm_read_mod_reg(s16 module, u16 idx)
50{
51 return __raw_readl(prm_base + module + idx);
52}
53
54void omap2_prm_write_mod_reg(u32 val, s16 module, u16 idx)
55{
56 __raw_writel(val, prm_base + module + idx);
57}
58
59/* Read-modify-write a register in a PRM module. Caller must lock */
60u32 omap2_prm_rmw_mod_reg_bits(u32 mask, u32 bits, s16 module, s16 idx)
61{
62 u32 v;
63
64 v = omap2_prm_read_mod_reg(module, idx);
65 v &= ~mask;
66 v |= bits;
67 omap2_prm_write_mod_reg(v, module, idx);
68
69 return v;
70}
71
72/* Read a PRM register, AND it, and shift the result down to bit 0 */
73u32 omap2_prm_read_mod_bits_shift(s16 domain, s16 idx, u32 mask)
74{
75 u32 v;
76
77 v = omap2_prm_read_mod_reg(domain, idx);
78 v &= mask;
79 v >>= __ffs(mask);
80
81 return v;
82}
83
84u32 omap2_prm_set_mod_reg_bits(u32 bits, s16 module, s16 idx)
85{
86 return omap2_prm_rmw_mod_reg_bits(bits, bits, module, idx);
87}
88
89u32 omap2_prm_clear_mod_reg_bits(u32 bits, s16 module, s16 idx)
90{
91 return omap2_prm_rmw_mod_reg_bits(bits, 0x0, module, idx);
92}
93
94 23
95/** 24/**
96 * omap2_prm_is_hardreset_asserted - read the HW reset line state of 25 * omap2_prm_is_hardreset_asserted - read the HW reset line state of
@@ -104,9 +33,6 @@ u32 omap2_prm_clear_mod_reg_bits(u32 bits, s16 module, s16 idx)
104 */ 33 */
105int omap2_prm_is_hardreset_asserted(s16 prm_mod, u8 shift) 34int omap2_prm_is_hardreset_asserted(s16 prm_mod, u8 shift)
106{ 35{
107 if (!(cpu_is_omap24xx() || cpu_is_omap34xx()))
108 return -EINVAL;
109
110 return omap2_prm_read_mod_bits_shift(prm_mod, OMAP2_RM_RSTCTRL, 36 return omap2_prm_read_mod_bits_shift(prm_mod, OMAP2_RM_RSTCTRL,
111 (1 << shift)); 37 (1 << shift));
112} 38}
@@ -127,9 +53,6 @@ int omap2_prm_assert_hardreset(s16 prm_mod, u8 shift)
127{ 53{
128 u32 mask; 54 u32 mask;
129 55
130 if (!(cpu_is_omap24xx() || cpu_is_omap34xx()))
131 return -EINVAL;
132
133 mask = 1 << shift; 56 mask = 1 << shift;
134 omap2_prm_rmw_mod_reg_bits(mask, mask, prm_mod, OMAP2_RM_RSTCTRL); 57 omap2_prm_rmw_mod_reg_bits(mask, mask, prm_mod, OMAP2_RM_RSTCTRL);
135 58
@@ -156,9 +79,6 @@ int omap2_prm_deassert_hardreset(s16 prm_mod, u8 rst_shift, u8 st_shift)
156 u32 rst, st; 79 u32 rst, st;
157 int c; 80 int c;
158 81
159 if (!(cpu_is_omap24xx() || cpu_is_omap34xx()))
160 return -EINVAL;
161
162 rst = 1 << rst_shift; 82 rst = 1 << rst_shift;
163 st = 1 << st_shift; 83 st = 1 << st_shift;
164 84
@@ -178,188 +98,3 @@ int omap2_prm_deassert_hardreset(s16 prm_mod, u8 rst_shift, u8 st_shift)
178 return (c == MAX_MODULE_HARDRESET_WAIT) ? -EBUSY : 0; 98 return (c == MAX_MODULE_HARDRESET_WAIT) ? -EBUSY : 0;
179} 99}
180 100
181/* PRM VP */
182
183/*
184 * struct omap3_vp - OMAP3 VP register access description.
185 * @tranxdone_status: VP_TRANXDONE_ST bitmask in PRM_IRQSTATUS_MPU reg
186 */
187struct omap3_vp {
188 u32 tranxdone_status;
189};
190
191static struct omap3_vp omap3_vp[] = {
192 [OMAP3_VP_VDD_MPU_ID] = {
193 .tranxdone_status = OMAP3430_VP1_TRANXDONE_ST_MASK,
194 },
195 [OMAP3_VP_VDD_CORE_ID] = {
196 .tranxdone_status = OMAP3430_VP2_TRANXDONE_ST_MASK,
197 },
198};
199
200#define MAX_VP_ID ARRAY_SIZE(omap3_vp);
201
202u32 omap3_prm_vp_check_txdone(u8 vp_id)
203{
204 struct omap3_vp *vp = &omap3_vp[vp_id];
205 u32 irqstatus;
206
207 irqstatus = omap2_prm_read_mod_reg(OCP_MOD,
208 OMAP3_PRM_IRQSTATUS_MPU_OFFSET);
209 return irqstatus & vp->tranxdone_status;
210}
211
212void omap3_prm_vp_clear_txdone(u8 vp_id)
213{
214 struct omap3_vp *vp = &omap3_vp[vp_id];
215
216 omap2_prm_write_mod_reg(vp->tranxdone_status,
217 OCP_MOD, OMAP3_PRM_IRQSTATUS_MPU_OFFSET);
218}
219
220u32 omap3_prm_vcvp_read(u8 offset)
221{
222 return omap2_prm_read_mod_reg(OMAP3430_GR_MOD, offset);
223}
224
225void omap3_prm_vcvp_write(u32 val, u8 offset)
226{
227 omap2_prm_write_mod_reg(val, OMAP3430_GR_MOD, offset);
228}
229
230u32 omap3_prm_vcvp_rmw(u32 mask, u32 bits, u8 offset)
231{
232 return omap2_prm_rmw_mod_reg_bits(mask, bits, OMAP3430_GR_MOD, offset);
233}
234
235/**
236 * omap3xxx_prm_read_pending_irqs - read pending PRM MPU IRQs into @events
237 * @events: ptr to a u32, preallocated by caller
238 *
239 * Read PRM_IRQSTATUS_MPU bits, AND'ed with the currently-enabled PRM
240 * MPU IRQs, and store the result into the u32 pointed to by @events.
241 * No return value.
242 */
243void omap3xxx_prm_read_pending_irqs(unsigned long *events)
244{
245 u32 mask, st;
246
247 /* XXX Can the mask read be avoided (e.g., can it come from RAM?) */
248 mask = omap2_prm_read_mod_reg(OCP_MOD, OMAP3_PRM_IRQENABLE_MPU_OFFSET);
249 st = omap2_prm_read_mod_reg(OCP_MOD, OMAP3_PRM_IRQSTATUS_MPU_OFFSET);
250
251 events[0] = mask & st;
252}
253
254/**
255 * omap3xxx_prm_ocp_barrier - force buffered MPU writes to the PRM to complete
256 *
257 * Force any buffered writes to the PRM IP block to complete. Needed
258 * by the PRM IRQ handler, which reads and writes directly to the IP
259 * block, to avoid race conditions after acknowledging or clearing IRQ
260 * bits. No return value.
261 */
262void omap3xxx_prm_ocp_barrier(void)
263{
264 omap2_prm_read_mod_reg(OCP_MOD, OMAP3_PRM_REVISION_OFFSET);
265}
266
267/**
268 * omap3xxx_prm_save_and_clear_irqen - save/clear PRM_IRQENABLE_MPU reg
269 * @saved_mask: ptr to a u32 array to save IRQENABLE bits
270 *
271 * Save the PRM_IRQENABLE_MPU register to @saved_mask. @saved_mask
272 * must be allocated by the caller. Intended to be used in the PRM
273 * interrupt handler suspend callback. The OCP barrier is needed to
274 * ensure the write to disable PRM interrupts reaches the PRM before
275 * returning; otherwise, spurious interrupts might occur. No return
276 * value.
277 */
278void omap3xxx_prm_save_and_clear_irqen(u32 *saved_mask)
279{
280 saved_mask[0] = omap2_prm_read_mod_reg(OCP_MOD,
281 OMAP3_PRM_IRQENABLE_MPU_OFFSET);
282 omap2_prm_write_mod_reg(0, OCP_MOD, OMAP3_PRM_IRQENABLE_MPU_OFFSET);
283
284 /* OCP barrier */
285 omap2_prm_read_mod_reg(OCP_MOD, OMAP3_PRM_REVISION_OFFSET);
286}
287
288/**
289 * omap3xxx_prm_restore_irqen - set PRM_IRQENABLE_MPU register from args
290 * @saved_mask: ptr to a u32 array of IRQENABLE bits saved previously
291 *
292 * Restore the PRM_IRQENABLE_MPU register from @saved_mask. Intended
293 * to be used in the PRM interrupt handler resume callback to restore
294 * values saved by omap3xxx_prm_save_and_clear_irqen(). No OCP
295 * barrier should be needed here; any pending PRM interrupts will fire
296 * once the writes reach the PRM. No return value.
297 */
298void omap3xxx_prm_restore_irqen(u32 *saved_mask)
299{
300 omap2_prm_write_mod_reg(saved_mask[0], OCP_MOD,
301 OMAP3_PRM_IRQENABLE_MPU_OFFSET);
302}
303
304/**
305 * omap3xxx_prm_reconfigure_io_chain - clear latches and reconfigure I/O chain
306 *
307 * Clear any previously-latched I/O wakeup events and ensure that the
308 * I/O wakeup gates are aligned with the current mux settings. Works
309 * by asserting WUCLKIN, waiting for WUCLKOUT to be asserted, and then
310 * deasserting WUCLKIN and clearing the ST_IO_CHAIN WKST bit. No
311 * return value.
312 */
313void omap3xxx_prm_reconfigure_io_chain(void)
314{
315 int i = 0;
316
317 omap2_prm_set_mod_reg_bits(OMAP3430_EN_IO_CHAIN_MASK, WKUP_MOD,
318 PM_WKEN);
319
320 omap_test_timeout(omap2_prm_read_mod_reg(WKUP_MOD, PM_WKST) &
321 OMAP3430_ST_IO_CHAIN_MASK,
322 MAX_IOPAD_LATCH_TIME, i);
323 if (i == MAX_IOPAD_LATCH_TIME)
324 pr_warn("PRM: I/O chain clock line assertion timed out\n");
325
326 omap2_prm_clear_mod_reg_bits(OMAP3430_EN_IO_CHAIN_MASK, WKUP_MOD,
327 PM_WKEN);
328
329 omap2_prm_set_mod_reg_bits(OMAP3430_ST_IO_CHAIN_MASK, WKUP_MOD,
330 PM_WKST);
331
332 omap2_prm_read_mod_reg(WKUP_MOD, PM_WKST);
333}
334
335/**
336 * omap3xxx_prm_enable_io_wakeup - enable wakeup events from I/O wakeup latches
337 *
338 * Activates the I/O wakeup event latches and allows events logged by
339 * those latches to signal a wakeup event to the PRCM. For I/O
340 * wakeups to occur, WAKEUPENABLE bits must be set in the pad mux
341 * registers, and omap3xxx_prm_reconfigure_io_chain() must be called.
342 * No return value.
343 */
344static void __init omap3xxx_prm_enable_io_wakeup(void)
345{
346 if (omap3_has_io_wakeup())
347 omap2_prm_set_mod_reg_bits(OMAP3430_EN_IO_MASK, WKUP_MOD,
348 PM_WKEN);
349}
350
351static int __init omap3xxx_prcm_init(void)
352{
353 int ret = 0;
354
355 if (cpu_is_omap34xx()) {
356 omap3xxx_prm_enable_io_wakeup();
357 ret = omap_prcm_register_chain_handler(&omap3_prcm_irq_setup);
358 if (!ret)
359 irq_set_status_flags(omap_prcm_event_to_irq("io"),
360 IRQ_NOAUTOEN);
361 }
362
363 return ret;
364}
365subsys_initcall(omap3xxx_prcm_init);