Commit | Line | Data |
---|---|---|
f327e07b RN |
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> | |
6e01478a | 18 | |
f327e07b RN |
19 | #include <plat/powerdomain.h> |
20 | #include <plat/prcm.h> | |
d198b514 | 21 | #include "prm44xx.h" |
f327e07b RN |
22 | #include "prm-regbits-44xx.h" |
23 | #include "powerdomains.h" | |
24 | ||
25 | static int omap4_pwrdm_set_next_pwrst(struct powerdomain *pwrdm, u8 pwrst) | |
26 | { | |
27 | prm_rmw_mod_reg_bits(OMAP_POWERSTATE_MASK, | |
28 | (pwrst << OMAP_POWERSTATE_SHIFT), | |
29 | pwrdm->prcm_offs, OMAP4_PM_PWSTCTRL); | |
30 | return 0; | |
31 | } | |
32 | ||
33 | static int omap4_pwrdm_read_next_pwrst(struct powerdomain *pwrdm) | |
34 | { | |
35 | return prm_read_mod_bits_shift(pwrdm->prcm_offs, | |
36 | OMAP4_PM_PWSTCTRL, OMAP_POWERSTATE_MASK); | |
37 | } | |
38 | ||
39 | static int omap4_pwrdm_read_pwrst(struct powerdomain *pwrdm) | |
40 | { | |
41 | return prm_read_mod_bits_shift(pwrdm->prcm_offs, | |
42 | OMAP4_PM_PWSTST, OMAP_POWERSTATEST_MASK); | |
43 | } | |
44 | ||
45 | static int omap4_pwrdm_read_prev_pwrst(struct powerdomain *pwrdm) | |
46 | { | |
47 | return prm_read_mod_bits_shift(pwrdm->prcm_offs, OMAP4_PM_PWSTST, | |
48 | OMAP4430_LASTPOWERSTATEENTERED_MASK); | |
49 | } | |
50 | ||
9b7fc907 RN |
51 | static int omap4_pwrdm_set_lowpwrstchange(struct powerdomain *pwrdm) |
52 | { | |
53 | prm_rmw_mod_reg_bits(OMAP4430_LOWPOWERSTATECHANGE_MASK, | |
54 | (1 << OMAP4430_LOWPOWERSTATECHANGE_SHIFT), | |
55 | pwrdm->prcm_offs, OMAP4_PM_PWSTCTRL); | |
56 | return 0; | |
57 | } | |
58 | ||
4b4f62c4 SS |
59 | static int omap4_pwrdm_clear_all_prev_pwrst(struct powerdomain *pwrdm) |
60 | { | |
61 | prm_rmw_mod_reg_bits(OMAP4430_LASTPOWERSTATEENTERED_MASK, | |
62 | OMAP4430_LASTPOWERSTATEENTERED_MASK, | |
63 | pwrdm->prcm_offs, OMAP4_PM_PWSTST); | |
64 | return 0; | |
65 | } | |
66 | ||
12627578 RN |
67 | static int omap4_pwrdm_set_logic_retst(struct powerdomain *pwrdm, u8 pwrst) |
68 | { | |
69 | u32 v; | |
70 | ||
71 | v = pwrst << __ffs(OMAP4430_LOGICRETSTATE_MASK); | |
72 | prm_rmw_mod_reg_bits(OMAP4430_LOGICRETSTATE_MASK, v, | |
73 | pwrdm->prcm_offs, OMAP4_PM_PWSTCTRL); | |
74 | ||
75 | return 0; | |
76 | } | |
77 | ||
9b7fc907 RN |
78 | static int omap4_pwrdm_set_mem_onst(struct powerdomain *pwrdm, u8 bank, |
79 | u8 pwrst) | |
80 | { | |
81 | u32 m; | |
82 | ||
83 | m = omap2_pwrdm_get_mem_bank_onstate_mask(bank); | |
84 | ||
85 | prm_rmw_mod_reg_bits(m, (pwrst << __ffs(m)), pwrdm->prcm_offs, | |
86 | OMAP4_PM_PWSTCTRL); | |
87 | ||
88 | return 0; | |
89 | } | |
90 | ||
91 | static int omap4_pwrdm_set_mem_retst(struct powerdomain *pwrdm, u8 bank, | |
92 | u8 pwrst) | |
93 | { | |
94 | u32 m; | |
95 | ||
96 | m = omap2_pwrdm_get_mem_bank_retst_mask(bank); | |
97 | ||
98 | prm_rmw_mod_reg_bits(m, (pwrst << __ffs(m)), pwrdm->prcm_offs, | |
99 | OMAP4_PM_PWSTCTRL); | |
100 | ||
101 | return 0; | |
102 | } | |
103 | ||
12627578 RN |
104 | static int omap4_pwrdm_read_logic_pwrst(struct powerdomain *pwrdm) |
105 | { | |
106 | return prm_read_mod_bits_shift(pwrdm->prcm_offs, OMAP4_PM_PWSTST, | |
107 | OMAP4430_LOGICSTATEST_MASK); | |
108 | } | |
109 | ||
110 | static int omap4_pwrdm_read_logic_retst(struct powerdomain *pwrdm) | |
111 | { | |
112 | return prm_read_mod_bits_shift(pwrdm->prcm_offs, OMAP4_PM_PWSTCTRL, | |
113 | OMAP4430_LOGICRETSTATE_MASK); | |
114 | } | |
115 | ||
9b7fc907 RN |
116 | static int omap4_pwrdm_read_mem_pwrst(struct powerdomain *pwrdm, u8 bank) |
117 | { | |
118 | u32 m; | |
119 | ||
120 | m = omap2_pwrdm_get_mem_bank_stst_mask(bank); | |
121 | ||
122 | return prm_read_mod_bits_shift(pwrdm->prcm_offs, OMAP4_PM_PWSTST, m); | |
123 | } | |
124 | ||
125 | static int omap4_pwrdm_read_mem_retst(struct powerdomain *pwrdm, u8 bank) | |
126 | { | |
127 | u32 m; | |
128 | ||
129 | m = omap2_pwrdm_get_mem_bank_retst_mask(bank); | |
130 | ||
131 | return prm_read_mod_bits_shift(pwrdm->prcm_offs, OMAP4_PM_PWSTCTRL, m); | |
132 | } | |
133 | ||
134 | static int omap4_pwrdm_wait_transition(struct powerdomain *pwrdm) | |
135 | { | |
136 | u32 c = 0; | |
137 | ||
138 | /* | |
139 | * REVISIT: pwrdm_wait_transition() may be better implemented | |
140 | * via a callback and a periodic timer check -- how long do we expect | |
141 | * powerdomain transitions to take? | |
142 | */ | |
143 | ||
144 | /* XXX Is this udelay() value meaningful? */ | |
145 | while ((prm_read_mod_reg(pwrdm->prcm_offs, OMAP4_PM_PWSTST) & | |
146 | OMAP_INTRANSITION_MASK) && | |
147 | (c++ < PWRDM_TRANSITION_BAILOUT)) | |
148 | udelay(1); | |
149 | ||
150 | if (c > PWRDM_TRANSITION_BAILOUT) { | |
151 | printk(KERN_ERR "powerdomain: waited too long for " | |
152 | "powerdomain %s to complete transition\n", pwrdm->name); | |
153 | return -EAGAIN; | |
154 | } | |
155 | ||
156 | pr_debug("powerdomain: completed transition in %d loops\n", c); | |
157 | ||
158 | return 0; | |
159 | } | |
160 | ||
f327e07b RN |
161 | struct pwrdm_ops omap4_pwrdm_operations = { |
162 | .pwrdm_set_next_pwrst = omap4_pwrdm_set_next_pwrst, | |
163 | .pwrdm_read_next_pwrst = omap4_pwrdm_read_next_pwrst, | |
164 | .pwrdm_read_pwrst = omap4_pwrdm_read_pwrst, | |
165 | .pwrdm_read_prev_pwrst = omap4_pwrdm_read_prev_pwrst, | |
9b7fc907 | 166 | .pwrdm_set_lowpwrstchange = omap4_pwrdm_set_lowpwrstchange, |
4b4f62c4 | 167 | .pwrdm_clear_all_prev_pwrst = omap4_pwrdm_clear_all_prev_pwrst, |
12627578 RN |
168 | .pwrdm_set_logic_retst = omap4_pwrdm_set_logic_retst, |
169 | .pwrdm_read_logic_pwrst = omap4_pwrdm_read_logic_pwrst, | |
170 | .pwrdm_read_logic_retst = omap4_pwrdm_read_logic_retst, | |
9b7fc907 RN |
171 | .pwrdm_read_mem_pwrst = omap4_pwrdm_read_mem_pwrst, |
172 | .pwrdm_read_mem_retst = omap4_pwrdm_read_mem_retst, | |
173 | .pwrdm_set_mem_onst = omap4_pwrdm_set_mem_onst, | |
174 | .pwrdm_set_mem_retst = omap4_pwrdm_set_mem_retst, | |
175 | .pwrdm_wait_transition = omap4_pwrdm_wait_transition, | |
f327e07b | 176 | }; |