Merge branch 'kbuild' of git://git.kernel.org/pub/scm/linux/kernel/git/mmarek/kbuild-2.6
[pandora-kernel.git] / arch / arm / mach-omap2 / powerdomain44xx.c
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 };