ARM: OMAP2+: PRM: split PRM functions into OMAP2, OMAP3-specific files
[linux-block.git] / arch / arm / mach-omap2 / prm3xxx.c
CommitLineData
139563ad
PW
1/*
2 * OMAP3xxx PRM module functions
3 *
4 * Copyright (C) 2010-2012 Texas Instruments, Inc.
5 * Copyright (C) 2010 Nokia Corporation
6 * BenoƮt Cousson
7 * Paul Walmsley
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License version 2 as
11 * published by the Free Software Foundation.
12 */
13
14#include <linux/kernel.h>
15#include <linux/errno.h>
16#include <linux/err.h>
17#include <linux/io.h>
18#include <linux/irq.h>
19
20#include "common.h"
21#include <plat/cpu.h>
22#include <plat/prcm.h>
23
24#include "vp.h"
25
26#include "prm3xxx.h"
27#include "cm2xxx_3xxx.h"
28#include "prm-regbits-34xx.h"
29
30static const struct omap_prcm_irq omap3_prcm_irqs[] = {
31 OMAP_PRCM_IRQ("wkup", 0, 0),
32 OMAP_PRCM_IRQ("io", 9, 1),
33};
34
35static struct omap_prcm_irq_setup omap3_prcm_irq_setup = {
36 .ack = OMAP3_PRM_IRQSTATUS_MPU_OFFSET,
37 .mask = OMAP3_PRM_IRQENABLE_MPU_OFFSET,
38 .nr_regs = 1,
39 .irqs = omap3_prcm_irqs,
40 .nr_irqs = ARRAY_SIZE(omap3_prcm_irqs),
41 .irq = 11 + OMAP_INTC_START,
42 .read_pending_irqs = &omap3xxx_prm_read_pending_irqs,
43 .ocp_barrier = &omap3xxx_prm_ocp_barrier,
44 .save_and_clear_irqen = &omap3xxx_prm_save_and_clear_irqen,
45 .restore_irqen = &omap3xxx_prm_restore_irqen,
46};
47
48/* PRM VP */
49
50/*
51 * struct omap3_vp - OMAP3 VP register access description.
52 * @tranxdone_status: VP_TRANXDONE_ST bitmask in PRM_IRQSTATUS_MPU reg
53 */
54struct omap3_vp {
55 u32 tranxdone_status;
56};
57
58static struct omap3_vp omap3_vp[] = {
59 [OMAP3_VP_VDD_MPU_ID] = {
60 .tranxdone_status = OMAP3430_VP1_TRANXDONE_ST_MASK,
61 },
62 [OMAP3_VP_VDD_CORE_ID] = {
63 .tranxdone_status = OMAP3430_VP2_TRANXDONE_ST_MASK,
64 },
65};
66
67#define MAX_VP_ID ARRAY_SIZE(omap3_vp);
68
69u32 omap3_prm_vp_check_txdone(u8 vp_id)
70{
71 struct omap3_vp *vp = &omap3_vp[vp_id];
72 u32 irqstatus;
73
74 irqstatus = omap2_prm_read_mod_reg(OCP_MOD,
75 OMAP3_PRM_IRQSTATUS_MPU_OFFSET);
76 return irqstatus & vp->tranxdone_status;
77}
78
79void omap3_prm_vp_clear_txdone(u8 vp_id)
80{
81 struct omap3_vp *vp = &omap3_vp[vp_id];
82
83 omap2_prm_write_mod_reg(vp->tranxdone_status,
84 OCP_MOD, OMAP3_PRM_IRQSTATUS_MPU_OFFSET);
85}
86
87u32 omap3_prm_vcvp_read(u8 offset)
88{
89 return omap2_prm_read_mod_reg(OMAP3430_GR_MOD, offset);
90}
91
92void omap3_prm_vcvp_write(u32 val, u8 offset)
93{
94 omap2_prm_write_mod_reg(val, OMAP3430_GR_MOD, offset);
95}
96
97u32 omap3_prm_vcvp_rmw(u32 mask, u32 bits, u8 offset)
98{
99 return omap2_prm_rmw_mod_reg_bits(mask, bits, OMAP3430_GR_MOD, offset);
100}
101
102/**
103 * omap3xxx_prm_read_pending_irqs - read pending PRM MPU IRQs into @events
104 * @events: ptr to a u32, preallocated by caller
105 *
106 * Read PRM_IRQSTATUS_MPU bits, AND'ed with the currently-enabled PRM
107 * MPU IRQs, and store the result into the u32 pointed to by @events.
108 * No return value.
109 */
110void omap3xxx_prm_read_pending_irqs(unsigned long *events)
111{
112 u32 mask, st;
113
114 /* XXX Can the mask read be avoided (e.g., can it come from RAM?) */
115 mask = omap2_prm_read_mod_reg(OCP_MOD, OMAP3_PRM_IRQENABLE_MPU_OFFSET);
116 st = omap2_prm_read_mod_reg(OCP_MOD, OMAP3_PRM_IRQSTATUS_MPU_OFFSET);
117
118 events[0] = mask & st;
119}
120
121/**
122 * omap3xxx_prm_ocp_barrier - force buffered MPU writes to the PRM to complete
123 *
124 * Force any buffered writes to the PRM IP block to complete. Needed
125 * by the PRM IRQ handler, which reads and writes directly to the IP
126 * block, to avoid race conditions after acknowledging or clearing IRQ
127 * bits. No return value.
128 */
129void omap3xxx_prm_ocp_barrier(void)
130{
131 omap2_prm_read_mod_reg(OCP_MOD, OMAP3_PRM_REVISION_OFFSET);
132}
133
134/**
135 * omap3xxx_prm_save_and_clear_irqen - save/clear PRM_IRQENABLE_MPU reg
136 * @saved_mask: ptr to a u32 array to save IRQENABLE bits
137 *
138 * Save the PRM_IRQENABLE_MPU register to @saved_mask. @saved_mask
139 * must be allocated by the caller. Intended to be used in the PRM
140 * interrupt handler suspend callback. The OCP barrier is needed to
141 * ensure the write to disable PRM interrupts reaches the PRM before
142 * returning; otherwise, spurious interrupts might occur. No return
143 * value.
144 */
145void omap3xxx_prm_save_and_clear_irqen(u32 *saved_mask)
146{
147 saved_mask[0] = omap2_prm_read_mod_reg(OCP_MOD,
148 OMAP3_PRM_IRQENABLE_MPU_OFFSET);
149 omap2_prm_write_mod_reg(0, OCP_MOD, OMAP3_PRM_IRQENABLE_MPU_OFFSET);
150
151 /* OCP barrier */
152 omap2_prm_read_mod_reg(OCP_MOD, OMAP3_PRM_REVISION_OFFSET);
153}
154
155/**
156 * omap3xxx_prm_restore_irqen - set PRM_IRQENABLE_MPU register from args
157 * @saved_mask: ptr to a u32 array of IRQENABLE bits saved previously
158 *
159 * Restore the PRM_IRQENABLE_MPU register from @saved_mask. Intended
160 * to be used in the PRM interrupt handler resume callback to restore
161 * values saved by omap3xxx_prm_save_and_clear_irqen(). No OCP
162 * barrier should be needed here; any pending PRM interrupts will fire
163 * once the writes reach the PRM. No return value.
164 */
165void omap3xxx_prm_restore_irqen(u32 *saved_mask)
166{
167 omap2_prm_write_mod_reg(saved_mask[0], OCP_MOD,
168 OMAP3_PRM_IRQENABLE_MPU_OFFSET);
169}
170
171/**
172 * omap3xxx_prm_reconfigure_io_chain - clear latches and reconfigure I/O chain
173 *
174 * Clear any previously-latched I/O wakeup events and ensure that the
175 * I/O wakeup gates are aligned with the current mux settings. Works
176 * by asserting WUCLKIN, waiting for WUCLKOUT to be asserted, and then
177 * deasserting WUCLKIN and clearing the ST_IO_CHAIN WKST bit. No
178 * return value.
179 */
180void omap3xxx_prm_reconfigure_io_chain(void)
181{
182 int i = 0;
183
184 omap2_prm_set_mod_reg_bits(OMAP3430_EN_IO_CHAIN_MASK, WKUP_MOD,
185 PM_WKEN);
186
187 omap_test_timeout(omap2_prm_read_mod_reg(WKUP_MOD, PM_WKST) &
188 OMAP3430_ST_IO_CHAIN_MASK,
189 MAX_IOPAD_LATCH_TIME, i);
190 if (i == MAX_IOPAD_LATCH_TIME)
191 pr_warn("PRM: I/O chain clock line assertion timed out\n");
192
193 omap2_prm_clear_mod_reg_bits(OMAP3430_EN_IO_CHAIN_MASK, WKUP_MOD,
194 PM_WKEN);
195
196 omap2_prm_set_mod_reg_bits(OMAP3430_ST_IO_CHAIN_MASK, WKUP_MOD,
197 PM_WKST);
198
199 omap2_prm_read_mod_reg(WKUP_MOD, PM_WKST);
200}
201
202/**
203 * omap3xxx_prm_enable_io_wakeup - enable wakeup events from I/O wakeup latches
204 *
205 * Activates the I/O wakeup event latches and allows events logged by
206 * those latches to signal a wakeup event to the PRCM. For I/O
207 * wakeups to occur, WAKEUPENABLE bits must be set in the pad mux
208 * registers, and omap3xxx_prm_reconfigure_io_chain() must be called.
209 * No return value.
210 */
211static void __init omap3xxx_prm_enable_io_wakeup(void)
212{
213 if (omap3_has_io_wakeup())
214 omap2_prm_set_mod_reg_bits(OMAP3430_EN_IO_MASK, WKUP_MOD,
215 PM_WKEN);
216}
217
218static int __init omap3xxx_prm_init(void)
219{
220 int ret;
221
222 if (!cpu_is_omap34xx())
223 return 0;
224
225 omap3xxx_prm_enable_io_wakeup();
226 ret = omap_prcm_register_chain_handler(&omap3_prcm_irq_setup);
227 if (!ret)
228 irq_set_status_flags(omap_prcm_event_to_irq("io"),
229 IRQ_NOAUTOEN);
230
231 return ret;
232}
233subsys_initcall(omap3xxx_prm_init);