Adding support for MOXA ART SoC. Testing port of linux-2.6.32.60-moxart.
[linux-3.6.7-moxart.git] / arch / arm / mach-omap2 / powerdomain33xx.c
blob67c5663899b6415f978320628346289bfa2d6b14
1 /*
2 * AM33XX Powerdomain control
4 * Copyright (C) 2011-2012 Texas Instruments Incorporated - http://www.ti.com/
6 * Derived from mach-omap2/powerdomain44xx.c written by Rajendra Nayak
7 * <rnayak@ti.com>
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.
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.
19 #include <linux/io.h>
20 #include <linux/errno.h>
21 #include <linux/delay.h>
23 #include <plat/prcm.h>
25 #include "powerdomain.h"
26 #include "prm33xx.h"
27 #include "prm-regbits-33xx.h"
30 static int am33xx_pwrdm_set_next_pwrst(struct powerdomain *pwrdm, u8 pwrst)
32 am33xx_prm_rmw_reg_bits(OMAP_POWERSTATE_MASK,
33 (pwrst << OMAP_POWERSTATE_SHIFT),
34 pwrdm->prcm_offs, pwrdm->pwrstctrl_offs);
35 return 0;
38 static int am33xx_pwrdm_read_next_pwrst(struct powerdomain *pwrdm)
40 u32 v;
42 v = am33xx_prm_read_reg(pwrdm->prcm_offs, pwrdm->pwrstctrl_offs);
43 v &= OMAP_POWERSTATE_MASK;
44 v >>= OMAP_POWERSTATE_SHIFT;
46 return v;
49 static int am33xx_pwrdm_read_pwrst(struct powerdomain *pwrdm)
51 u32 v;
53 v = am33xx_prm_read_reg(pwrdm->prcm_offs, pwrdm->pwrstst_offs);
54 v &= OMAP_POWERSTATEST_MASK;
55 v >>= OMAP_POWERSTATEST_SHIFT;
57 return v;
60 static int am33xx_pwrdm_read_prev_pwrst(struct powerdomain *pwrdm)
62 u32 v;
64 v = am33xx_prm_read_reg(pwrdm->prcm_offs, pwrdm->pwrstst_offs);
65 v &= AM33XX_LASTPOWERSTATEENTERED_MASK;
66 v >>= AM33XX_LASTPOWERSTATEENTERED_SHIFT;
68 return v;
71 static int am33xx_pwrdm_set_lowpwrstchange(struct powerdomain *pwrdm)
73 am33xx_prm_rmw_reg_bits(AM33XX_LOWPOWERSTATECHANGE_MASK,
74 (1 << AM33XX_LOWPOWERSTATECHANGE_SHIFT),
75 pwrdm->prcm_offs, pwrdm->pwrstctrl_offs);
76 return 0;
79 static int am33xx_pwrdm_clear_all_prev_pwrst(struct powerdomain *pwrdm)
81 am33xx_prm_rmw_reg_bits(AM33XX_LASTPOWERSTATEENTERED_MASK,
82 AM33XX_LASTPOWERSTATEENTERED_MASK,
83 pwrdm->prcm_offs, pwrdm->pwrstst_offs);
84 return 0;
87 static int am33xx_pwrdm_set_logic_retst(struct powerdomain *pwrdm, u8 pwrst)
89 u32 m;
91 m = pwrdm->logicretstate_mask;
92 if (!m)
93 return -EINVAL;
95 am33xx_prm_rmw_reg_bits(m, (pwrst << __ffs(m)),
96 pwrdm->prcm_offs, pwrdm->pwrstctrl_offs);
98 return 0;
101 static int am33xx_pwrdm_read_logic_pwrst(struct powerdomain *pwrdm)
103 u32 v;
105 v = am33xx_prm_read_reg(pwrdm->prcm_offs, pwrdm->pwrstst_offs);
106 v &= AM33XX_LOGICSTATEST_MASK;
107 v >>= AM33XX_LOGICSTATEST_SHIFT;
109 return v;
112 static int am33xx_pwrdm_read_logic_retst(struct powerdomain *pwrdm)
114 u32 v, m;
116 m = pwrdm->logicretstate_mask;
117 if (!m)
118 return -EINVAL;
120 v = am33xx_prm_read_reg(pwrdm->prcm_offs, pwrdm->pwrstctrl_offs);
121 v &= m;
122 v >>= __ffs(m);
124 return v;
127 static int am33xx_pwrdm_set_mem_onst(struct powerdomain *pwrdm, u8 bank,
128 u8 pwrst)
130 u32 m;
132 m = pwrdm->mem_on_mask[bank];
133 if (!m)
134 return -EINVAL;
136 am33xx_prm_rmw_reg_bits(m, (pwrst << __ffs(m)),
137 pwrdm->prcm_offs, pwrdm->pwrstctrl_offs);
139 return 0;
142 static int am33xx_pwrdm_set_mem_retst(struct powerdomain *pwrdm, u8 bank,
143 u8 pwrst)
145 u32 m;
147 m = pwrdm->mem_ret_mask[bank];
148 if (!m)
149 return -EINVAL;
151 am33xx_prm_rmw_reg_bits(m, (pwrst << __ffs(m)),
152 pwrdm->prcm_offs, pwrdm->pwrstctrl_offs);
154 return 0;
157 static int am33xx_pwrdm_read_mem_pwrst(struct powerdomain *pwrdm, u8 bank)
159 u32 m, v;
161 m = pwrdm->mem_pwrst_mask[bank];
162 if (!m)
163 return -EINVAL;
165 v = am33xx_prm_read_reg(pwrdm->prcm_offs, pwrdm->pwrstst_offs);
166 v &= m;
167 v >>= __ffs(m);
169 return v;
172 static int am33xx_pwrdm_read_mem_retst(struct powerdomain *pwrdm, u8 bank)
174 u32 m, v;
176 m = pwrdm->mem_retst_mask[bank];
177 if (!m)
178 return -EINVAL;
180 v = am33xx_prm_read_reg(pwrdm->prcm_offs, pwrdm->pwrstctrl_offs);
181 v &= m;
182 v >>= __ffs(m);
184 return v;
187 static int am33xx_pwrdm_wait_transition(struct powerdomain *pwrdm)
189 u32 c = 0;
192 * REVISIT: pwrdm_wait_transition() may be better implemented
193 * via a callback and a periodic timer check -- how long do we expect
194 * powerdomain transitions to take?
197 /* XXX Is this udelay() value meaningful? */
198 while ((am33xx_prm_read_reg(pwrdm->prcm_offs, pwrdm->pwrstst_offs)
199 & OMAP_INTRANSITION_MASK) &&
200 (c++ < PWRDM_TRANSITION_BAILOUT))
201 udelay(1);
203 if (c > PWRDM_TRANSITION_BAILOUT) {
204 pr_err("powerdomain: %s: waited too long to complete transition\n",
205 pwrdm->name);
206 return -EAGAIN;
209 pr_debug("powerdomain: completed transition in %d loops\n", c);
211 return 0;
214 struct pwrdm_ops am33xx_pwrdm_operations = {
215 .pwrdm_set_next_pwrst = am33xx_pwrdm_set_next_pwrst,
216 .pwrdm_read_next_pwrst = am33xx_pwrdm_read_next_pwrst,
217 .pwrdm_read_pwrst = am33xx_pwrdm_read_pwrst,
218 .pwrdm_read_prev_pwrst = am33xx_pwrdm_read_prev_pwrst,
219 .pwrdm_set_logic_retst = am33xx_pwrdm_set_logic_retst,
220 .pwrdm_read_logic_pwrst = am33xx_pwrdm_read_logic_pwrst,
221 .pwrdm_read_logic_retst = am33xx_pwrdm_read_logic_retst,
222 .pwrdm_clear_all_prev_pwrst = am33xx_pwrdm_clear_all_prev_pwrst,
223 .pwrdm_set_lowpwrstchange = am33xx_pwrdm_set_lowpwrstchange,
224 .pwrdm_read_mem_pwrst = am33xx_pwrdm_read_mem_pwrst,
225 .pwrdm_read_mem_retst = am33xx_pwrdm_read_mem_retst,
226 .pwrdm_set_mem_onst = am33xx_pwrdm_set_mem_onst,
227 .pwrdm_set_mem_retst = am33xx_pwrdm_set_mem_retst,
228 .pwrdm_wait_transition = am33xx_pwrdm_wait_transition,