diff options
author | Tony Lindgren <tony@atomide.com> | 2014-09-08 18:04:24 -0400 |
---|---|---|
committer | Tony Lindgren <tony@atomide.com> | 2014-09-08 18:04:24 -0400 |
commit | d7eb67f7fef9c046f27a975118da2324de65a90c (patch) | |
tree | d6ddda513ae56e6a4d56b087b10c7f1faa11ecb0 | |
parent | 9a15fff05b702c3ea29ae64db0d3ff0355431eab (diff) | |
parent | 3e6a1c945950140926dd6e2cc667893de0a7fe3b (diff) |
Merge branch 'pull/v3.18/powerdomain-fixes' of https://github.com/nmenon/linux-2.6-playground into omap-for-v3.18/fixes-not-urgent
-rw-r--r-- | arch/arm/mach-omap2/omap-mpuss-lowpower.c | 4 | ||||
-rw-r--r-- | arch/arm/mach-omap2/pm44xx.c | 9 | ||||
-rw-r--r-- | arch/arm/mach-omap2/powerdomain.c | 79 | ||||
-rw-r--r-- | arch/arm/mach-omap2/powerdomain.h | 4 | ||||
-rw-r--r-- | arch/arm/mach-omap2/powerdomains54xx_data.c | 12 | ||||
-rw-r--r-- | arch/arm/mach-omap2/powerdomains7xx_data.c | 14 |
6 files changed, 106 insertions, 16 deletions
diff --git a/arch/arm/mach-omap2/omap-mpuss-lowpower.c b/arch/arm/mach-omap2/omap-mpuss-lowpower.c index 4001325f90fb..e9cdacfe1923 100644 --- a/arch/arm/mach-omap2/omap-mpuss-lowpower.c +++ b/arch/arm/mach-omap2/omap-mpuss-lowpower.c | |||
@@ -298,6 +298,10 @@ int omap4_hotplug_cpu(unsigned int cpu, unsigned int power_state) | |||
298 | if (omap_rev() == OMAP4430_REV_ES1_0) | 298 | if (omap_rev() == OMAP4430_REV_ES1_0) |
299 | return -ENXIO; | 299 | return -ENXIO; |
300 | 300 | ||
301 | /* Use the achievable power state for the domain */ | ||
302 | power_state = pwrdm_get_valid_lp_state(pm_info->pwrdm, | ||
303 | false, power_state); | ||
304 | |||
301 | if (power_state == PWRDM_POWER_OFF) | 305 | if (power_state == PWRDM_POWER_OFF) |
302 | cpu_state = 1; | 306 | cpu_state = 1; |
303 | 307 | ||
diff --git a/arch/arm/mach-omap2/pm44xx.c b/arch/arm/mach-omap2/pm44xx.c index 0dda6cf8b855..0bfce38a744a 100644 --- a/arch/arm/mach-omap2/pm44xx.c +++ b/arch/arm/mach-omap2/pm44xx.c | |||
@@ -29,6 +29,7 @@ u16 pm44xx_errata; | |||
29 | struct power_state { | 29 | struct power_state { |
30 | struct powerdomain *pwrdm; | 30 | struct powerdomain *pwrdm; |
31 | u32 next_state; | 31 | u32 next_state; |
32 | u32 next_logic_state; | ||
32 | #ifdef CONFIG_SUSPEND | 33 | #ifdef CONFIG_SUSPEND |
33 | u32 saved_state; | 34 | u32 saved_state; |
34 | u32 saved_logic_state; | 35 | u32 saved_logic_state; |
@@ -54,7 +55,7 @@ static int omap4_pm_suspend(void) | |||
54 | /* Set targeted power domain states by suspend */ | 55 | /* Set targeted power domain states by suspend */ |
55 | list_for_each_entry(pwrst, &pwrst_list, node) { | 56 | list_for_each_entry(pwrst, &pwrst_list, node) { |
56 | omap_set_pwrdm_state(pwrst->pwrdm, pwrst->next_state); | 57 | omap_set_pwrdm_state(pwrst->pwrdm, pwrst->next_state); |
57 | pwrdm_set_logic_retst(pwrst->pwrdm, PWRDM_POWER_OFF); | 58 | pwrdm_set_logic_retst(pwrst->pwrdm, pwrst->next_logic_state); |
58 | } | 59 | } |
59 | 60 | ||
60 | /* | 61 | /* |
@@ -120,7 +121,11 @@ static int __init pwrdms_setup(struct powerdomain *pwrdm, void *unused) | |||
120 | return -ENOMEM; | 121 | return -ENOMEM; |
121 | 122 | ||
122 | pwrst->pwrdm = pwrdm; | 123 | pwrst->pwrdm = pwrdm; |
123 | pwrst->next_state = PWRDM_POWER_RET; | 124 | pwrst->next_state = pwrdm_get_valid_lp_state(pwrdm, false, |
125 | PWRDM_POWER_RET); | ||
126 | pwrst->next_logic_state = pwrdm_get_valid_lp_state(pwrdm, true, | ||
127 | PWRDM_POWER_OFF); | ||
128 | |||
124 | list_add(&pwrst->node, &pwrst_list); | 129 | list_add(&pwrst->node, &pwrst_list); |
125 | 130 | ||
126 | return omap_set_pwrdm_state(pwrst->pwrdm, pwrst->next_state); | 131 | return omap_set_pwrdm_state(pwrst->pwrdm, pwrst->next_state); |
diff --git a/arch/arm/mach-omap2/powerdomain.c b/arch/arm/mach-omap2/powerdomain.c index faebd5f076af..7fb033eca0a5 100644 --- a/arch/arm/mach-omap2/powerdomain.c +++ b/arch/arm/mach-omap2/powerdomain.c | |||
@@ -546,7 +546,8 @@ int pwrdm_for_each_clkdm(struct powerdomain *pwrdm, | |||
546 | return -EINVAL; | 546 | return -EINVAL; |
547 | 547 | ||
548 | for (i = 0; i < PWRDM_MAX_CLKDMS && !ret; i++) | 548 | for (i = 0; i < PWRDM_MAX_CLKDMS && !ret; i++) |
549 | ret = (*fn)(pwrdm, pwrdm->pwrdm_clkdms[i]); | 549 | if (pwrdm->pwrdm_clkdms[i]) |
550 | ret = (*fn)(pwrdm, pwrdm->pwrdm_clkdms[i]); | ||
550 | 551 | ||
551 | return ret; | 552 | return ret; |
552 | } | 553 | } |
@@ -1080,6 +1081,82 @@ int pwrdm_post_transition(struct powerdomain *pwrdm) | |||
1080 | } | 1081 | } |
1081 | 1082 | ||
1082 | /** | 1083 | /** |
1084 | * pwrdm_get_valid_lp_state() - Find best match deep power state | ||
1085 | * @pwrdm: power domain for which we want to find best match | ||
1086 | * @is_logic_state: Are we looking for logic state match here? Should | ||
1087 | * be one of PWRDM_xxx macro values | ||
1088 | * @req_state: requested power state | ||
1089 | * | ||
1090 | * Returns: closest match for requested power state. default fallback | ||
1091 | * is RET for logic state and ON for power state. | ||
1092 | * | ||
1093 | * This does a search from the power domain data looking for the | ||
1094 | * closest valid power domain state that the hardware can achieve. | ||
1095 | * PRCM definitions for PWRSTCTRL allows us to program whatever | ||
1096 | * configuration we'd like, and PRCM will actually attempt such | ||
1097 | * a transition, however if the powerdomain does not actually support it, | ||
1098 | * we endup with a hung system. The valid power domain states are already | ||
1099 | * available in our powerdomain data files. So this function tries to do | ||
1100 | * the following: | ||
1101 | * a) find if we have an exact match to the request - no issues. | ||
1102 | * b) else find if a deeper power state is possible. | ||
1103 | * c) failing which, it tries to find closest higher power state for the | ||
1104 | * request. | ||
1105 | */ | ||
1106 | u8 pwrdm_get_valid_lp_state(struct powerdomain *pwrdm, | ||
1107 | bool is_logic_state, u8 req_state) | ||
1108 | { | ||
1109 | u8 pwrdm_states = is_logic_state ? pwrdm->pwrsts_logic_ret : | ||
1110 | pwrdm->pwrsts; | ||
1111 | /* For logic, ret is highest and others, ON is highest */ | ||
1112 | u8 default_pwrst = is_logic_state ? PWRDM_POWER_RET : PWRDM_POWER_ON; | ||
1113 | u8 new_pwrst; | ||
1114 | bool found; | ||
1115 | |||
1116 | /* If it is already supported, nothing to search */ | ||
1117 | if (pwrdm_states & BIT(req_state)) | ||
1118 | return req_state; | ||
1119 | |||
1120 | if (!req_state) | ||
1121 | goto up_search; | ||
1122 | |||
1123 | /* | ||
1124 | * So, we dont have a exact match | ||
1125 | * Can we get a deeper power state match? | ||
1126 | */ | ||
1127 | new_pwrst = req_state - 1; | ||
1128 | found = true; | ||
1129 | while (!(pwrdm_states & BIT(new_pwrst))) { | ||
1130 | /* No match even at OFF? Not available */ | ||
1131 | if (new_pwrst == PWRDM_POWER_OFF) { | ||
1132 | found = false; | ||
1133 | break; | ||
1134 | } | ||
1135 | new_pwrst--; | ||
1136 | } | ||
1137 | |||
1138 | if (found) | ||
1139 | goto done; | ||
1140 | |||
1141 | up_search: | ||
1142 | /* OK, no deeper ones, can we get a higher match? */ | ||
1143 | new_pwrst = req_state + 1; | ||
1144 | while (!(pwrdm_states & BIT(new_pwrst))) { | ||
1145 | if (new_pwrst > PWRDM_POWER_ON) { | ||
1146 | WARN(1, "powerdomain: %s: Fix max powerstate to ON\n", | ||
1147 | pwrdm->name); | ||
1148 | return PWRDM_POWER_ON; | ||
1149 | } | ||
1150 | |||
1151 | if (new_pwrst == default_pwrst) | ||
1152 | break; | ||
1153 | new_pwrst++; | ||
1154 | } | ||
1155 | done: | ||
1156 | return new_pwrst; | ||
1157 | } | ||
1158 | |||
1159 | /** | ||
1083 | * omap_set_pwrdm_state - change a powerdomain's current power state | 1160 | * omap_set_pwrdm_state - change a powerdomain's current power state |
1084 | * @pwrdm: struct powerdomain * to change the power state of | 1161 | * @pwrdm: struct powerdomain * to change the power state of |
1085 | * @pwrst: power state to change to | 1162 | * @pwrst: power state to change to |
diff --git a/arch/arm/mach-omap2/powerdomain.h b/arch/arm/mach-omap2/powerdomain.h index f4727117f6cc..11bd4dd7d8d6 100644 --- a/arch/arm/mach-omap2/powerdomain.h +++ b/arch/arm/mach-omap2/powerdomain.h | |||
@@ -39,6 +39,7 @@ | |||
39 | #define PWRSTS_OFF_RET (PWRSTS_OFF | PWRSTS_RET) | 39 | #define PWRSTS_OFF_RET (PWRSTS_OFF | PWRSTS_RET) |
40 | #define PWRSTS_RET_ON (PWRSTS_RET | PWRSTS_ON) | 40 | #define PWRSTS_RET_ON (PWRSTS_RET | PWRSTS_ON) |
41 | #define PWRSTS_OFF_RET_ON (PWRSTS_OFF_RET | PWRSTS_ON) | 41 | #define PWRSTS_OFF_RET_ON (PWRSTS_OFF_RET | PWRSTS_ON) |
42 | #define PWRSTS_INA_ON (PWRSTS_INACTIVE | PWRSTS_ON) | ||
42 | 43 | ||
43 | 44 | ||
44 | /* | 45 | /* |
@@ -219,6 +220,9 @@ struct voltagedomain *pwrdm_get_voltdm(struct powerdomain *pwrdm); | |||
219 | 220 | ||
220 | int pwrdm_get_mem_bank_count(struct powerdomain *pwrdm); | 221 | int pwrdm_get_mem_bank_count(struct powerdomain *pwrdm); |
221 | 222 | ||
223 | u8 pwrdm_get_valid_lp_state(struct powerdomain *pwrdm, | ||
224 | bool is_logic_state, u8 req_state); | ||
225 | |||
222 | int pwrdm_set_next_pwrst(struct powerdomain *pwrdm, u8 pwrst); | 226 | int pwrdm_set_next_pwrst(struct powerdomain *pwrdm, u8 pwrst); |
223 | int pwrdm_read_next_pwrst(struct powerdomain *pwrdm); | 227 | int pwrdm_read_next_pwrst(struct powerdomain *pwrdm); |
224 | int pwrdm_read_pwrst(struct powerdomain *pwrdm); | 228 | int pwrdm_read_pwrst(struct powerdomain *pwrdm); |
diff --git a/arch/arm/mach-omap2/powerdomains54xx_data.c b/arch/arm/mach-omap2/powerdomains54xx_data.c index ce1d752af991..60d7ed8ef8ca 100644 --- a/arch/arm/mach-omap2/powerdomains54xx_data.c +++ b/arch/arm/mach-omap2/powerdomains54xx_data.c | |||
@@ -35,7 +35,7 @@ static struct powerdomain core_54xx_pwrdm = { | |||
35 | .prcm_offs = OMAP54XX_PRM_CORE_INST, | 35 | .prcm_offs = OMAP54XX_PRM_CORE_INST, |
36 | .prcm_partition = OMAP54XX_PRM_PARTITION, | 36 | .prcm_partition = OMAP54XX_PRM_PARTITION, |
37 | .pwrsts = PWRSTS_RET_ON, | 37 | .pwrsts = PWRSTS_RET_ON, |
38 | .pwrsts_logic_ret = PWRSTS_OFF_RET, | 38 | .pwrsts_logic_ret = PWRSTS_RET, |
39 | .banks = 5, | 39 | .banks = 5, |
40 | .pwrsts_mem_ret = { | 40 | .pwrsts_mem_ret = { |
41 | [0] = PWRSTS_OFF_RET, /* core_nret_bank */ | 41 | [0] = PWRSTS_OFF_RET, /* core_nret_bank */ |
@@ -107,8 +107,8 @@ static struct powerdomain cpu0_54xx_pwrdm = { | |||
107 | .voltdm = { .name = "mpu" }, | 107 | .voltdm = { .name = "mpu" }, |
108 | .prcm_offs = OMAP54XX_PRCM_MPU_PRM_C0_INST, | 108 | .prcm_offs = OMAP54XX_PRCM_MPU_PRM_C0_INST, |
109 | .prcm_partition = OMAP54XX_PRCM_MPU_PARTITION, | 109 | .prcm_partition = OMAP54XX_PRCM_MPU_PARTITION, |
110 | .pwrsts = PWRSTS_OFF_RET_ON, | 110 | .pwrsts = PWRSTS_RET_ON, |
111 | .pwrsts_logic_ret = PWRSTS_OFF_RET, | 111 | .pwrsts_logic_ret = PWRSTS_RET, |
112 | .banks = 1, | 112 | .banks = 1, |
113 | .pwrsts_mem_ret = { | 113 | .pwrsts_mem_ret = { |
114 | [0] = PWRSTS_OFF_RET, /* cpu0_l1 */ | 114 | [0] = PWRSTS_OFF_RET, /* cpu0_l1 */ |
@@ -124,8 +124,8 @@ static struct powerdomain cpu1_54xx_pwrdm = { | |||
124 | .voltdm = { .name = "mpu" }, | 124 | .voltdm = { .name = "mpu" }, |
125 | .prcm_offs = OMAP54XX_PRCM_MPU_PRM_C1_INST, | 125 | .prcm_offs = OMAP54XX_PRCM_MPU_PRM_C1_INST, |
126 | .prcm_partition = OMAP54XX_PRCM_MPU_PARTITION, | 126 | .prcm_partition = OMAP54XX_PRCM_MPU_PARTITION, |
127 | .pwrsts = PWRSTS_OFF_RET_ON, | 127 | .pwrsts = PWRSTS_RET_ON, |
128 | .pwrsts_logic_ret = PWRSTS_OFF_RET, | 128 | .pwrsts_logic_ret = PWRSTS_RET, |
129 | .banks = 1, | 129 | .banks = 1, |
130 | .pwrsts_mem_ret = { | 130 | .pwrsts_mem_ret = { |
131 | [0] = PWRSTS_OFF_RET, /* cpu1_l1 */ | 131 | [0] = PWRSTS_OFF_RET, /* cpu1_l1 */ |
@@ -158,7 +158,7 @@ static struct powerdomain mpu_54xx_pwrdm = { | |||
158 | .prcm_offs = OMAP54XX_PRM_MPU_INST, | 158 | .prcm_offs = OMAP54XX_PRM_MPU_INST, |
159 | .prcm_partition = OMAP54XX_PRM_PARTITION, | 159 | .prcm_partition = OMAP54XX_PRM_PARTITION, |
160 | .pwrsts = PWRSTS_RET_ON, | 160 | .pwrsts = PWRSTS_RET_ON, |
161 | .pwrsts_logic_ret = PWRSTS_OFF_RET, | 161 | .pwrsts_logic_ret = PWRSTS_RET, |
162 | .banks = 2, | 162 | .banks = 2, |
163 | .pwrsts_mem_ret = { | 163 | .pwrsts_mem_ret = { |
164 | [0] = PWRSTS_OFF_RET, /* mpu_l2 */ | 164 | [0] = PWRSTS_OFF_RET, /* mpu_l2 */ |
diff --git a/arch/arm/mach-omap2/powerdomains7xx_data.c b/arch/arm/mach-omap2/powerdomains7xx_data.c index 48151d1cfde0..287a2037aa16 100644 --- a/arch/arm/mach-omap2/powerdomains7xx_data.c +++ b/arch/arm/mach-omap2/powerdomains7xx_data.c | |||
@@ -160,8 +160,8 @@ static struct powerdomain core_7xx_pwrdm = { | |||
160 | .name = "core_pwrdm", | 160 | .name = "core_pwrdm", |
161 | .prcm_offs = DRA7XX_PRM_CORE_INST, | 161 | .prcm_offs = DRA7XX_PRM_CORE_INST, |
162 | .prcm_partition = DRA7XX_PRM_PARTITION, | 162 | .prcm_partition = DRA7XX_PRM_PARTITION, |
163 | .pwrsts = PWRSTS_RET_ON, | 163 | .pwrsts = PWRSTS_INA_ON, |
164 | .pwrsts_logic_ret = PWRSTS_OFF_RET, | 164 | .pwrsts_logic_ret = PWRSTS_RET, |
165 | .banks = 5, | 165 | .banks = 5, |
166 | .pwrsts_mem_ret = { | 166 | .pwrsts_mem_ret = { |
167 | [0] = PWRSTS_OFF_RET, /* core_nret_bank */ | 167 | [0] = PWRSTS_OFF_RET, /* core_nret_bank */ |
@@ -193,8 +193,8 @@ static struct powerdomain cpu0_7xx_pwrdm = { | |||
193 | .name = "cpu0_pwrdm", | 193 | .name = "cpu0_pwrdm", |
194 | .prcm_offs = DRA7XX_MPU_PRCM_PRM_C0_INST, | 194 | .prcm_offs = DRA7XX_MPU_PRCM_PRM_C0_INST, |
195 | .prcm_partition = DRA7XX_MPU_PRCM_PARTITION, | 195 | .prcm_partition = DRA7XX_MPU_PRCM_PARTITION, |
196 | .pwrsts = PWRSTS_OFF_RET_ON, | 196 | .pwrsts = PWRSTS_RET_ON, |
197 | .pwrsts_logic_ret = PWRSTS_OFF_RET, | 197 | .pwrsts_logic_ret = PWRSTS_RET, |
198 | .banks = 1, | 198 | .banks = 1, |
199 | .pwrsts_mem_ret = { | 199 | .pwrsts_mem_ret = { |
200 | [0] = PWRSTS_OFF_RET, /* cpu0_l1 */ | 200 | [0] = PWRSTS_OFF_RET, /* cpu0_l1 */ |
@@ -209,8 +209,8 @@ static struct powerdomain cpu1_7xx_pwrdm = { | |||
209 | .name = "cpu1_pwrdm", | 209 | .name = "cpu1_pwrdm", |
210 | .prcm_offs = DRA7XX_MPU_PRCM_PRM_C1_INST, | 210 | .prcm_offs = DRA7XX_MPU_PRCM_PRM_C1_INST, |
211 | .prcm_partition = DRA7XX_MPU_PRCM_PARTITION, | 211 | .prcm_partition = DRA7XX_MPU_PRCM_PARTITION, |
212 | .pwrsts = PWRSTS_OFF_RET_ON, | 212 | .pwrsts = PWRSTS_RET_ON, |
213 | .pwrsts_logic_ret = PWRSTS_OFF_RET, | 213 | .pwrsts_logic_ret = PWRSTS_RET, |
214 | .banks = 1, | 214 | .banks = 1, |
215 | .pwrsts_mem_ret = { | 215 | .pwrsts_mem_ret = { |
216 | [0] = PWRSTS_OFF_RET, /* cpu1_l1 */ | 216 | [0] = PWRSTS_OFF_RET, /* cpu1_l1 */ |
@@ -243,7 +243,7 @@ static struct powerdomain mpu_7xx_pwrdm = { | |||
243 | .prcm_offs = DRA7XX_PRM_MPU_INST, | 243 | .prcm_offs = DRA7XX_PRM_MPU_INST, |
244 | .prcm_partition = DRA7XX_PRM_PARTITION, | 244 | .prcm_partition = DRA7XX_PRM_PARTITION, |
245 | .pwrsts = PWRSTS_RET_ON, | 245 | .pwrsts = PWRSTS_RET_ON, |
246 | .pwrsts_logic_ret = PWRSTS_OFF_RET, | 246 | .pwrsts_logic_ret = PWRSTS_RET, |
247 | .banks = 2, | 247 | .banks = 2, |
248 | .pwrsts_mem_ret = { | 248 | .pwrsts_mem_ret = { |
249 | [0] = PWRSTS_OFF_RET, /* mpu_l2 */ | 249 | [0] = PWRSTS_OFF_RET, /* mpu_l2 */ |