diff options
author | Tony Lindgren <tony@atomide.com> | 2010-12-22 14:32:24 -0500 |
---|---|---|
committer | Tony Lindgren <tony@atomide.com> | 2010-12-22 14:32:24 -0500 |
commit | 808601b75804475c9022f6375e76b7c62c99a10a (patch) | |
tree | 355a3100269e88460e36f251ef0ce2f1ed88d52e /arch/arm/mach-omap2/powerdomain44xx.c | |
parent | c10abbb26513f4ccff89c4d80912cb4d36fcd3e8 (diff) | |
parent | f17f9726c27c3921e00a5750e85070e6dd7e1ff7 (diff) |
Merge branch 'integration-2.6.38-for-tony' of git://git.pwsan.com/linux-2.6 into omap-for-linus
Diffstat (limited to 'arch/arm/mach-omap2/powerdomain44xx.c')
-rw-r--r-- | arch/arm/mach-omap2/powerdomain44xx.c | 225 |
1 files changed, 225 insertions, 0 deletions
diff --git a/arch/arm/mach-omap2/powerdomain44xx.c b/arch/arm/mach-omap2/powerdomain44xx.c new file mode 100644 index 000000000000..a7880af4b3d9 --- /dev/null +++ b/arch/arm/mach-omap2/powerdomain44xx.c | |||
@@ -0,0 +1,225 @@ | |||
1 | /* | ||
2 | * OMAP4 powerdomain control | ||
3 | * | ||
4 | * Copyright (C) 2009-2010 Texas Instruments, Inc. | ||
5 | * Copyright (C) 2007-2009 Nokia Corporation | ||
6 | * | ||
7 | * Derived from mach-omap2/powerdomain.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/io.h> | ||
16 | #include <linux/errno.h> | ||
17 | #include <linux/delay.h> | ||
18 | |||
19 | #include "powerdomain.h" | ||
20 | #include <plat/prcm.h> | ||
21 | #include "prm2xxx_3xxx.h" | ||
22 | #include "prm44xx.h" | ||
23 | #include "prminst44xx.h" | ||
24 | #include "prm-regbits-44xx.h" | ||
25 | |||
26 | static int omap4_pwrdm_set_next_pwrst(struct powerdomain *pwrdm, u8 pwrst) | ||
27 | { | ||
28 | omap4_prminst_rmw_inst_reg_bits(OMAP_POWERSTATE_MASK, | ||
29 | (pwrst << OMAP_POWERSTATE_SHIFT), | ||
30 | pwrdm->prcm_partition, | ||
31 | pwrdm->prcm_offs, OMAP4_PM_PWSTCTRL); | ||
32 | return 0; | ||
33 | } | ||
34 | |||
35 | static int omap4_pwrdm_read_next_pwrst(struct powerdomain *pwrdm) | ||
36 | { | ||
37 | u32 v; | ||
38 | |||
39 | v = omap4_prminst_read_inst_reg(pwrdm->prcm_partition, pwrdm->prcm_offs, | ||
40 | OMAP4_PM_PWSTCTRL); | ||
41 | v &= OMAP_POWERSTATE_MASK; | ||
42 | v >>= OMAP_POWERSTATE_SHIFT; | ||
43 | |||
44 | return v; | ||
45 | } | ||
46 | |||
47 | static int omap4_pwrdm_read_pwrst(struct powerdomain *pwrdm) | ||
48 | { | ||
49 | u32 v; | ||
50 | |||
51 | v = omap4_prminst_read_inst_reg(pwrdm->prcm_partition, pwrdm->prcm_offs, | ||
52 | OMAP4_PM_PWSTST); | ||
53 | v &= OMAP_POWERSTATEST_MASK; | ||
54 | v >>= OMAP_POWERSTATEST_SHIFT; | ||
55 | |||
56 | return v; | ||
57 | } | ||
58 | |||
59 | static int omap4_pwrdm_read_prev_pwrst(struct powerdomain *pwrdm) | ||
60 | { | ||
61 | u32 v; | ||
62 | |||
63 | v = omap4_prminst_read_inst_reg(pwrdm->prcm_partition, pwrdm->prcm_offs, | ||
64 | OMAP4_PM_PWSTST); | ||
65 | v &= OMAP4430_LASTPOWERSTATEENTERED_MASK; | ||
66 | v >>= OMAP4430_LASTPOWERSTATEENTERED_SHIFT; | ||
67 | |||
68 | return v; | ||
69 | } | ||
70 | |||
71 | static int omap4_pwrdm_set_lowpwrstchange(struct powerdomain *pwrdm) | ||
72 | { | ||
73 | omap4_prminst_rmw_inst_reg_bits(OMAP4430_LOWPOWERSTATECHANGE_MASK, | ||
74 | (1 << OMAP4430_LOWPOWERSTATECHANGE_SHIFT), | ||
75 | pwrdm->prcm_partition, | ||
76 | pwrdm->prcm_offs, OMAP4_PM_PWSTCTRL); | ||
77 | return 0; | ||
78 | } | ||
79 | |||
80 | static int omap4_pwrdm_clear_all_prev_pwrst(struct powerdomain *pwrdm) | ||
81 | { | ||
82 | omap4_prminst_rmw_inst_reg_bits(OMAP4430_LASTPOWERSTATEENTERED_MASK, | ||
83 | OMAP4430_LASTPOWERSTATEENTERED_MASK, | ||
84 | pwrdm->prcm_partition, | ||
85 | pwrdm->prcm_offs, OMAP4_PM_PWSTST); | ||
86 | return 0; | ||
87 | } | ||
88 | |||
89 | static int omap4_pwrdm_set_logic_retst(struct powerdomain *pwrdm, u8 pwrst) | ||
90 | { | ||
91 | u32 v; | ||
92 | |||
93 | v = pwrst << __ffs(OMAP4430_LOGICRETSTATE_MASK); | ||
94 | omap4_prminst_rmw_inst_reg_bits(OMAP4430_LOGICRETSTATE_MASK, v, | ||
95 | pwrdm->prcm_partition, pwrdm->prcm_offs, | ||
96 | OMAP4_PM_PWSTCTRL); | ||
97 | |||
98 | return 0; | ||
99 | } | ||
100 | |||
101 | static int omap4_pwrdm_set_mem_onst(struct powerdomain *pwrdm, u8 bank, | ||
102 | u8 pwrst) | ||
103 | { | ||
104 | u32 m; | ||
105 | |||
106 | m = omap2_pwrdm_get_mem_bank_onstate_mask(bank); | ||
107 | |||
108 | omap4_prminst_rmw_inst_reg_bits(m, (pwrst << __ffs(m)), | ||
109 | pwrdm->prcm_partition, pwrdm->prcm_offs, | ||
110 | OMAP4_PM_PWSTCTRL); | ||
111 | |||
112 | return 0; | ||
113 | } | ||
114 | |||
115 | static int omap4_pwrdm_set_mem_retst(struct powerdomain *pwrdm, u8 bank, | ||
116 | u8 pwrst) | ||
117 | { | ||
118 | u32 m; | ||
119 | |||
120 | m = omap2_pwrdm_get_mem_bank_retst_mask(bank); | ||
121 | |||
122 | omap4_prminst_rmw_inst_reg_bits(m, (pwrst << __ffs(m)), | ||
123 | pwrdm->prcm_partition, pwrdm->prcm_offs, | ||
124 | OMAP4_PM_PWSTCTRL); | ||
125 | |||
126 | return 0; | ||
127 | } | ||
128 | |||
129 | static int omap4_pwrdm_read_logic_pwrst(struct powerdomain *pwrdm) | ||
130 | { | ||
131 | u32 v; | ||
132 | |||
133 | v = omap4_prminst_read_inst_reg(pwrdm->prcm_partition, pwrdm->prcm_offs, | ||
134 | OMAP4_PM_PWSTST); | ||
135 | v &= OMAP4430_LOGICSTATEST_MASK; | ||
136 | v >>= OMAP4430_LOGICSTATEST_SHIFT; | ||
137 | |||
138 | return v; | ||
139 | } | ||
140 | |||
141 | static int omap4_pwrdm_read_logic_retst(struct powerdomain *pwrdm) | ||
142 | { | ||
143 | u32 v; | ||
144 | |||
145 | v = omap4_prminst_read_inst_reg(pwrdm->prcm_partition, pwrdm->prcm_offs, | ||
146 | OMAP4_PM_PWSTCTRL); | ||
147 | v &= OMAP4430_LOGICRETSTATE_MASK; | ||
148 | v >>= OMAP4430_LOGICRETSTATE_SHIFT; | ||
149 | |||
150 | return v; | ||
151 | } | ||
152 | |||
153 | static int omap4_pwrdm_read_mem_pwrst(struct powerdomain *pwrdm, u8 bank) | ||
154 | { | ||
155 | u32 m, v; | ||
156 | |||
157 | m = omap2_pwrdm_get_mem_bank_stst_mask(bank); | ||
158 | |||
159 | v = omap4_prminst_read_inst_reg(pwrdm->prcm_partition, pwrdm->prcm_offs, | ||
160 | OMAP4_PM_PWSTST); | ||
161 | v &= m; | ||
162 | v >>= __ffs(m); | ||
163 | |||
164 | return v; | ||
165 | } | ||
166 | |||
167 | static int omap4_pwrdm_read_mem_retst(struct powerdomain *pwrdm, u8 bank) | ||
168 | { | ||
169 | u32 m, v; | ||
170 | |||
171 | m = omap2_pwrdm_get_mem_bank_retst_mask(bank); | ||
172 | |||
173 | v = omap4_prminst_read_inst_reg(pwrdm->prcm_partition, pwrdm->prcm_offs, | ||
174 | OMAP4_PM_PWSTCTRL); | ||
175 | v &= m; | ||
176 | v >>= __ffs(m); | ||
177 | |||
178 | return v; | ||
179 | } | ||
180 | |||
181 | static int omap4_pwrdm_wait_transition(struct powerdomain *pwrdm) | ||
182 | { | ||
183 | u32 c = 0; | ||
184 | |||
185 | /* | ||
186 | * REVISIT: pwrdm_wait_transition() may be better implemented | ||
187 | * via a callback and a periodic timer check -- how long do we expect | ||
188 | * powerdomain transitions to take? | ||
189 | */ | ||
190 | |||
191 | /* XXX Is this udelay() value meaningful? */ | ||
192 | while ((omap4_prminst_read_inst_reg(pwrdm->prcm_partition, | ||
193 | pwrdm->prcm_offs, | ||
194 | OMAP4_PM_PWSTST) & | ||
195 | OMAP_INTRANSITION_MASK) && | ||
196 | (c++ < PWRDM_TRANSITION_BAILOUT)) | ||
197 | udelay(1); | ||
198 | |||
199 | if (c > PWRDM_TRANSITION_BAILOUT) { | ||
200 | printk(KERN_ERR "powerdomain: waited too long for " | ||
201 | "powerdomain %s to complete transition\n", pwrdm->name); | ||
202 | return -EAGAIN; | ||
203 | } | ||
204 | |||
205 | pr_debug("powerdomain: completed transition in %d loops\n", c); | ||
206 | |||
207 | return 0; | ||
208 | } | ||
209 | |||
210 | struct pwrdm_ops omap4_pwrdm_operations = { | ||
211 | .pwrdm_set_next_pwrst = omap4_pwrdm_set_next_pwrst, | ||
212 | .pwrdm_read_next_pwrst = omap4_pwrdm_read_next_pwrst, | ||
213 | .pwrdm_read_pwrst = omap4_pwrdm_read_pwrst, | ||
214 | .pwrdm_read_prev_pwrst = omap4_pwrdm_read_prev_pwrst, | ||
215 | .pwrdm_set_lowpwrstchange = omap4_pwrdm_set_lowpwrstchange, | ||
216 | .pwrdm_clear_all_prev_pwrst = omap4_pwrdm_clear_all_prev_pwrst, | ||
217 | .pwrdm_set_logic_retst = omap4_pwrdm_set_logic_retst, | ||
218 | .pwrdm_read_logic_pwrst = omap4_pwrdm_read_logic_pwrst, | ||
219 | .pwrdm_read_logic_retst = omap4_pwrdm_read_logic_retst, | ||
220 | .pwrdm_read_mem_pwrst = omap4_pwrdm_read_mem_pwrst, | ||
221 | .pwrdm_read_mem_retst = omap4_pwrdm_read_mem_retst, | ||
222 | .pwrdm_set_mem_onst = omap4_pwrdm_set_mem_onst, | ||
223 | .pwrdm_set_mem_retst = omap4_pwrdm_set_mem_retst, | ||
224 | .pwrdm_wait_transition = omap4_pwrdm_wait_transition, | ||
225 | }; | ||