Linux Kernel  3.7.1
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
prm2xxx_3xxx.c
Go to the documentation of this file.
1 /*
2  * OMAP2/3 PRM module functions
3  *
4  * Copyright (C) 2010-2011 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 <plat/prcm.h>
21 
22 #include "soc.h"
23 #include "common.h"
24 #include "vp.h"
25 
26 #include "prm2xxx_3xxx.h"
27 #include "cm2xxx_3xxx.h"
28 #include "prm-regbits-24xx.h"
29 #include "prm-regbits-34xx.h"
30 
31 static const struct omap_prcm_irq omap3_prcm_irqs[] = {
32  OMAP_PRCM_IRQ("wkup", 0, 0),
33  OMAP_PRCM_IRQ("io", 9, 1),
34 };
35 
36 static struct omap_prcm_irq_setup omap3_prcm_irq_setup = {
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 
50 {
51  return __raw_readl(prm_base + module + idx);
52 }
53 
55 {
56  __raw_writel(val, prm_base + module + idx);
57 }
58 
59 /* Read-modify-write a register in a PRM module. Caller must lock */
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 */
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 
85 {
86  return omap2_prm_rmw_mod_reg_bits(bits, bits, module, idx);
87 }
88 
90 {
91  return omap2_prm_rmw_mod_reg_bits(bits, 0x0, module, idx);
92 }
93 
94 
106 {
107  if (!(cpu_is_omap24xx() || cpu_is_omap34xx()))
108  return -EINVAL;
109 
111  (1 << shift));
112 }
113 
126 int omap2_prm_assert_hardreset(s16 prm_mod, u8 shift)
127 {
128  u32 mask;
129 
130  if (!(cpu_is_omap24xx() || cpu_is_omap34xx()))
131  return -EINVAL;
132 
133  mask = 1 << shift;
134  omap2_prm_rmw_mod_reg_bits(mask, mask, prm_mod, OMAP2_RM_RSTCTRL);
135 
136  return 0;
137 }
138 
154 int omap2_prm_deassert_hardreset(s16 prm_mod, u8 rst_shift, u8 st_shift)
155 {
156  u32 rst, st;
157  int c;
158 
159  if (!(cpu_is_omap24xx() || cpu_is_omap34xx()))
160  return -EINVAL;
161 
162  rst = 1 << rst_shift;
163  st = 1 << st_shift;
164 
165  /* Check the current status to avoid de-asserting the line twice */
166  if (omap2_prm_read_mod_bits_shift(prm_mod, OMAP2_RM_RSTCTRL, rst) == 0)
167  return -EEXIST;
168 
169  /* Clear the reset status by writing 1 to the status bit */
170  omap2_prm_rmw_mod_reg_bits(0xffffffff, st, prm_mod, OMAP2_RM_RSTST);
171  /* de-assert the reset control line */
173  /* wait the status to be set */
174  omap_test_timeout(omap2_prm_read_mod_bits_shift(prm_mod, OMAP2_RM_RSTST,
175  st),
177 
178  return (c == MAX_MODULE_HARDRESET_WAIT) ? -EBUSY : 0;
179 }
180 
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  */
187 struct omap3_vp {
189 };
190 
191 static struct omap3_vp omap3_vp[] = {
192  [OMAP3_VP_VDD_MPU_ID] = {
194  },
196  .tranxdone_status = OMAP3430_VP2_TRANXDONE_ST_MASK,
197  },
198 };
199 
200 #define MAX_VP_ID ARRAY_SIZE(omap3_vp);
201 
203 {
204  struct omap3_vp *vp = &omap3_vp[vp_id];
205  u32 irqstatus;
206 
207  irqstatus = omap2_prm_read_mod_reg(OCP_MOD,
209  return irqstatus & vp->tranxdone_status;
210 }
211 
213 {
214  struct omap3_vp *vp = &omap3_vp[vp_id];
215 
218 }
219 
221 {
222  return omap2_prm_read_mod_reg(OMAP3430_GR_MOD, offset);
223 }
224 
226 {
228 }
229 
231 {
232  return omap2_prm_rmw_mod_reg_bits(mask, bits, OMAP3430_GR_MOD, offset);
233 }
234 
244 {
245  u32 mask, st;
246 
247  /* XXX Can the mask read be avoided (e.g., can it come from RAM?) */
250 
251  events[0] = mask & st;
252 }
253 
263 {
265 }
266 
279 {
280  saved_mask[0] = omap2_prm_read_mod_reg(OCP_MOD,
283 
284  /* OCP barrier */
286 }
287 
299 {
300  omap2_prm_write_mod_reg(saved_mask[0], OCP_MOD,
302 }
303 
314 {
315  int i = 0;
316 
318  PM_WKEN);
319 
320  omap_test_timeout(omap2_prm_read_mod_reg(WKUP_MOD, PM_WKST) &
323  if (i == MAX_IOPAD_LATCH_TIME)
324  pr_warn("PRM: I/O chain clock line assertion timed out\n");
325 
327  PM_WKEN);
328 
329  omap2_prm_set_mod_reg_bits(OMAP3430_ST_IO_CHAIN_MASK, WKUP_MOD,
330  PM_WKST);
331 
333 }
334 
344 static void __init omap3xxx_prm_enable_io_wakeup(void)
345 {
346  if (omap3_has_io_wakeup())
348  PM_WKEN);
349 }
350 
351 static 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 }
365 subsys_initcall(omap3xxx_prcm_init);