aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm/mach-omap2
diff options
context:
space:
mode:
authorPaul Walmsley <paul@pwsan.com>2012-12-28 04:10:44 -0500
committerPaul Walmsley <paul@pwsan.com>2013-01-02 14:07:16 -0500
commit7e7fff8254e318cede06a1a8c55b0d86dd4d8c5b (patch)
tree38ad0446026932ed55ae1af167dae17c0a417f3a /arch/arm/mach-omap2
parentcfef4b2723d525a6588c4c55b42f9b98be27937f (diff)
ARM: OMAP2/3: PRM: fix bogus OMAP2xxx powerstate return values
On OMAP2xxx chips, the register bitfields for the PM_PWSTCTRL_*.POWERSTATE and PM_PWSTST_*.LASTSTATEENTERED are different than those used on OMAP3/4. The order is reversed. So, for example, on OMAP2xxx, 0x0 indicates 'ON'; but on OMAP3/4, 0x0 indicates 'OFF'. Similarly, on OMAP2xxx, 0x3 indicates 'OFF', but on OMAP3/4, 0x3 indicates 'ON'. To fix this, we treat the OMAP3/4 values as the powerdomain API values, and create new low-level powerdomain functions for the OMAP2xxx chips which translate between the OMAP2xxx values and the OMAP3/4 values. Without this patch, the conversion of the OMAP2xxx PM code to the functional powerstate code results in a non-booting kernel. Signed-off-by: Paul Walmsley <paul@pwsan.com>
Diffstat (limited to 'arch/arm/mach-omap2')
-rw-r--r--arch/arm/mach-omap2/prm2xxx.c88
-rw-r--r--arch/arm/mach-omap2/prm2xxx_3xxx.c22
-rw-r--r--arch/arm/mach-omap2/prm3xxx.c28
3 files changed, 110 insertions, 28 deletions
diff --git a/arch/arm/mach-omap2/prm2xxx.c b/arch/arm/mach-omap2/prm2xxx.c
index faeab18696df..00cd4fcbda0f 100644
--- a/arch/arm/mach-omap2/prm2xxx.c
+++ b/arch/arm/mach-omap2/prm2xxx.c
@@ -29,6 +29,14 @@
29#include "prm-regbits-24xx.h" 29#include "prm-regbits-24xx.h"
30 30
31/* 31/*
32 * OMAP24xx PM_PWSTCTRL_*.POWERSTATE and PM_PWSTST_*.LASTSTATEENTERED bits -
33 * these are reversed from the bits used on OMAP3+
34 */
35#define OMAP24XX_PWRDM_POWER_ON 0x0
36#define OMAP24XX_PWRDM_POWER_RET 0x1
37#define OMAP24XX_PWRDM_POWER_OFF 0x3
38
39/*
32 * omap2xxx_prm_reset_src_map - map from bits in the PRM_RSTST_WKUP 40 * omap2xxx_prm_reset_src_map - map from bits in the PRM_RSTST_WKUP
33 * hardware register (which are specific to the OMAP2xxx SoCs) to 41 * hardware register (which are specific to the OMAP2xxx SoCs) to
34 * reset source ID bit shifts (which is an OMAP SoC-independent 42 * reset source ID bit shifts (which is an OMAP SoC-independent
@@ -69,6 +77,34 @@ static u32 omap2xxx_prm_read_reset_sources(void)
69} 77}
70 78
71/** 79/**
80 * omap2xxx_pwrst_to_common_pwrst - convert OMAP2xxx pwrst to common pwrst
81 * @omap2xxx_pwrst: OMAP2xxx hardware power state to convert
82 *
83 * Return the common power state bits corresponding to the OMAP2xxx
84 * hardware power state bits @omap2xxx_pwrst, or -EINVAL upon error.
85 */
86static int omap2xxx_pwrst_to_common_pwrst(u8 omap2xxx_pwrst)
87{
88 u8 pwrst;
89
90 switch (omap2xxx_pwrst) {
91 case OMAP24XX_PWRDM_POWER_OFF:
92 pwrst = PWRDM_POWER_OFF;
93 break;
94 case OMAP24XX_PWRDM_POWER_RET:
95 pwrst = PWRDM_POWER_RET;
96 break;
97 case OMAP24XX_PWRDM_POWER_ON:
98 pwrst = PWRDM_POWER_ON;
99 break;
100 default:
101 return -EINVAL;
102 }
103
104 return pwrst;
105}
106
107/**
72 * omap2xxx_prm_dpll_reset - use DPLL reset to reboot the OMAP SoC 108 * omap2xxx_prm_dpll_reset - use DPLL reset to reboot the OMAP SoC
73 * 109 *
74 * Set the DPLL reset bit, which should reboot the SoC. This is the 110 * Set the DPLL reset bit, which should reboot the SoC. This is the
@@ -98,10 +134,56 @@ int omap2xxx_clkdm_wakeup(struct clockdomain *clkdm)
98 return 0; 134 return 0;
99} 135}
100 136
137static int omap2xxx_pwrdm_set_next_pwrst(struct powerdomain *pwrdm, u8 pwrst)
138{
139 u8 omap24xx_pwrst;
140
141 switch (pwrst) {
142 case PWRDM_POWER_OFF:
143 omap24xx_pwrst = OMAP24XX_PWRDM_POWER_OFF;
144 break;
145 case PWRDM_POWER_RET:
146 omap24xx_pwrst = OMAP24XX_PWRDM_POWER_RET;
147 break;
148 case PWRDM_POWER_ON:
149 omap24xx_pwrst = OMAP24XX_PWRDM_POWER_ON;
150 break;
151 default:
152 return -EINVAL;
153 }
154
155 omap2_prm_rmw_mod_reg_bits(OMAP_POWERSTATE_MASK,
156 (omap24xx_pwrst << OMAP_POWERSTATE_SHIFT),
157 pwrdm->prcm_offs, OMAP2_PM_PWSTCTRL);
158 return 0;
159}
160
161static int omap2xxx_pwrdm_read_next_pwrst(struct powerdomain *pwrdm)
162{
163 u8 omap2xxx_pwrst;
164
165 omap2xxx_pwrst = omap2_prm_read_mod_bits_shift(pwrdm->prcm_offs,
166 OMAP2_PM_PWSTCTRL,
167 OMAP_POWERSTATE_MASK);
168
169 return omap2xxx_pwrst_to_common_pwrst(omap2xxx_pwrst);
170}
171
172static int omap2xxx_pwrdm_read_pwrst(struct powerdomain *pwrdm)
173{
174 u8 omap2xxx_pwrst;
175
176 omap2xxx_pwrst = omap2_prm_read_mod_bits_shift(pwrdm->prcm_offs,
177 OMAP2_PM_PWSTST,
178 OMAP_POWERSTATEST_MASK);
179
180 return omap2xxx_pwrst_to_common_pwrst(omap2xxx_pwrst);
181}
182
101struct pwrdm_ops omap2_pwrdm_operations = { 183struct pwrdm_ops omap2_pwrdm_operations = {
102 .pwrdm_set_next_pwrst = omap2_pwrdm_set_next_pwrst, 184 .pwrdm_set_next_pwrst = omap2xxx_pwrdm_set_next_pwrst,
103 .pwrdm_read_next_pwrst = omap2_pwrdm_read_next_pwrst, 185 .pwrdm_read_next_pwrst = omap2xxx_pwrdm_read_next_pwrst,
104 .pwrdm_read_pwrst = omap2_pwrdm_read_pwrst, 186 .pwrdm_read_pwrst = omap2xxx_pwrdm_read_pwrst,
105 .pwrdm_set_logic_retst = omap2_pwrdm_set_logic_retst, 187 .pwrdm_set_logic_retst = omap2_pwrdm_set_logic_retst,
106 .pwrdm_set_mem_onst = omap2_pwrdm_set_mem_onst, 188 .pwrdm_set_mem_onst = omap2_pwrdm_set_mem_onst,
107 .pwrdm_set_mem_retst = omap2_pwrdm_set_mem_retst, 189 .pwrdm_set_mem_retst = omap2_pwrdm_set_mem_retst,
diff --git a/arch/arm/mach-omap2/prm2xxx_3xxx.c b/arch/arm/mach-omap2/prm2xxx_3xxx.c
index 30517f5af707..a3e121f94a86 100644
--- a/arch/arm/mach-omap2/prm2xxx_3xxx.c
+++ b/arch/arm/mach-omap2/prm2xxx_3xxx.c
@@ -103,28 +103,6 @@ int omap2_prm_deassert_hardreset(s16 prm_mod, u8 rst_shift, u8 st_shift)
103/* Powerdomain low-level functions */ 103/* Powerdomain low-level functions */
104 104
105/* Common functions across OMAP2 and OMAP3 */ 105/* Common functions across OMAP2 and OMAP3 */
106int omap2_pwrdm_set_next_pwrst(struct powerdomain *pwrdm, u8 pwrst)
107{
108 omap2_prm_rmw_mod_reg_bits(OMAP_POWERSTATE_MASK,
109 (pwrst << OMAP_POWERSTATE_SHIFT),
110 pwrdm->prcm_offs, OMAP2_PM_PWSTCTRL);
111 return 0;
112}
113
114int omap2_pwrdm_read_next_pwrst(struct powerdomain *pwrdm)
115{
116 return omap2_prm_read_mod_bits_shift(pwrdm->prcm_offs,
117 OMAP2_PM_PWSTCTRL,
118 OMAP_POWERSTATE_MASK);
119}
120
121int omap2_pwrdm_read_pwrst(struct powerdomain *pwrdm)
122{
123 return omap2_prm_read_mod_bits_shift(pwrdm->prcm_offs,
124 OMAP2_PM_PWSTST,
125 OMAP_POWERSTATEST_MASK);
126}
127
128int omap2_pwrdm_set_mem_onst(struct powerdomain *pwrdm, u8 bank, 106int omap2_pwrdm_set_mem_onst(struct powerdomain *pwrdm, u8 bank,
129 u8 pwrst) 107 u8 pwrst)
130{ 108{
diff --git a/arch/arm/mach-omap2/prm3xxx.c b/arch/arm/mach-omap2/prm3xxx.c
index db198d058584..4d43474d7455 100644
--- a/arch/arm/mach-omap2/prm3xxx.c
+++ b/arch/arm/mach-omap2/prm3xxx.c
@@ -278,6 +278,28 @@ static u32 omap3xxx_prm_read_reset_sources(void)
278 278
279/* Powerdomain low-level functions */ 279/* Powerdomain low-level functions */
280 280
281static int omap3_pwrdm_set_next_pwrst(struct powerdomain *pwrdm, u8 pwrst)
282{
283 omap2_prm_rmw_mod_reg_bits(OMAP_POWERSTATE_MASK,
284 (pwrst << OMAP_POWERSTATE_SHIFT),
285 pwrdm->prcm_offs, OMAP2_PM_PWSTCTRL);
286 return 0;
287}
288
289static int omap3_pwrdm_read_next_pwrst(struct powerdomain *pwrdm)
290{
291 return omap2_prm_read_mod_bits_shift(pwrdm->prcm_offs,
292 OMAP2_PM_PWSTCTRL,
293 OMAP_POWERSTATE_MASK);
294}
295
296static int omap3_pwrdm_read_pwrst(struct powerdomain *pwrdm)
297{
298 return omap2_prm_read_mod_bits_shift(pwrdm->prcm_offs,
299 OMAP2_PM_PWSTST,
300 OMAP_POWERSTATEST_MASK);
301}
302
281/* Applicable only for OMAP3. Not supported on OMAP2 */ 303/* Applicable only for OMAP3. Not supported on OMAP2 */
282static int omap3_pwrdm_read_prev_pwrst(struct powerdomain *pwrdm) 304static int omap3_pwrdm_read_prev_pwrst(struct powerdomain *pwrdm)
283{ 305{
@@ -356,9 +378,9 @@ static int omap3_pwrdm_disable_hdwr_sar(struct powerdomain *pwrdm)
356} 378}
357 379
358struct pwrdm_ops omap3_pwrdm_operations = { 380struct pwrdm_ops omap3_pwrdm_operations = {
359 .pwrdm_set_next_pwrst = omap2_pwrdm_set_next_pwrst, 381 .pwrdm_set_next_pwrst = omap3_pwrdm_set_next_pwrst,
360 .pwrdm_read_next_pwrst = omap2_pwrdm_read_next_pwrst, 382 .pwrdm_read_next_pwrst = omap3_pwrdm_read_next_pwrst,
361 .pwrdm_read_pwrst = omap2_pwrdm_read_pwrst, 383 .pwrdm_read_pwrst = omap3_pwrdm_read_pwrst,
362 .pwrdm_read_prev_pwrst = omap3_pwrdm_read_prev_pwrst, 384 .pwrdm_read_prev_pwrst = omap3_pwrdm_read_prev_pwrst,
363 .pwrdm_set_logic_retst = omap2_pwrdm_set_logic_retst, 385 .pwrdm_set_logic_retst = omap2_pwrdm_set_logic_retst,
364 .pwrdm_read_logic_pwrst = omap3_pwrdm_read_logic_pwrst, 386 .pwrdm_read_logic_pwrst = omap3_pwrdm_read_logic_pwrst,