diff options
author | Tony Lindgren <tony@atomide.com> | 2012-11-06 20:06:37 -0500 |
---|---|---|
committer | Tony Lindgren <tony@atomide.com> | 2012-11-06 20:06:37 -0500 |
commit | 46bf4a562207c5ebd24e1dde5e5ee326cd3d6b91 (patch) | |
tree | d44b14736a46cd0d4270460fd6590a6d07c40730 | |
parent | b197adabbd2f71c966b4bd89cca5a54a2def03e2 (diff) | |
parent | df7cded30ced539d3b4e6bae9f3011d98c069d41 (diff) |
Merge tag 'for_3.8-pm-voltage' of git://git.kernel.org/pub/scm/linux/kernel/git/khilman/linux-omap-pm into omap-for-v3.8/pm
OMAP voltage layer updates towards supporting auto-retention/auto-off
-rw-r--r-- | arch/arm/mach-omap2/control.h | 1 | ||||
-rw-r--r-- | arch/arm/mach-omap2/omap_opp_data.h | 9 | ||||
-rw-r--r-- | arch/arm/mach-omap2/omap_twl.c | 73 | ||||
-rw-r--r-- | arch/arm/mach-omap2/opp4xxx_data.c | 98 | ||||
-rw-r--r-- | arch/arm/mach-omap2/pm.c | 30 | ||||
-rw-r--r-- | arch/arm/mach-omap2/pm.h | 10 | ||||
-rw-r--r-- | arch/arm/mach-omap2/vc.c | 451 | ||||
-rw-r--r-- | arch/arm/mach-omap2/vc.h | 8 | ||||
-rw-r--r-- | arch/arm/mach-omap2/vc3xxx_data.c | 22 | ||||
-rw-r--r-- | arch/arm/mach-omap2/vc44xx_data.c | 28 | ||||
-rw-r--r-- | arch/arm/mach-omap2/voltage.h | 44 | ||||
-rw-r--r-- | arch/arm/mach-omap2/voltagedomains3xxx_data.c | 5 | ||||
-rw-r--r-- | arch/arm/mach-omap2/voltagedomains44xx_data.c | 23 | ||||
-rw-r--r-- | arch/arm/mach-omap2/vp.c | 6 | ||||
-rw-r--r-- | arch/arm/mach-omap2/vp.h | 7 | ||||
-rw-r--r-- | arch/arm/mach-omap2/vp3xxx_data.c | 10 | ||||
-rw-r--r-- | arch/arm/mach-omap2/vp44xx_data.c | 15 |
17 files changed, 725 insertions, 115 deletions
diff --git a/arch/arm/mach-omap2/control.h b/arch/arm/mach-omap2/control.h index a89e8256fd0e..d236257626bf 100644 --- a/arch/arm/mach-omap2/control.h +++ b/arch/arm/mach-omap2/control.h | |||
@@ -201,6 +201,7 @@ | |||
201 | #define OMAP44XX_CONTROL_FUSE_MPU_OPPNITRO 0x249 | 201 | #define OMAP44XX_CONTROL_FUSE_MPU_OPPNITRO 0x249 |
202 | #define OMAP44XX_CONTROL_FUSE_CORE_OPP50 0x254 | 202 | #define OMAP44XX_CONTROL_FUSE_CORE_OPP50 0x254 |
203 | #define OMAP44XX_CONTROL_FUSE_CORE_OPP100 0x257 | 203 | #define OMAP44XX_CONTROL_FUSE_CORE_OPP100 0x257 |
204 | #define OMAP44XX_CONTROL_FUSE_CORE_OPP100OV 0x25A | ||
204 | 205 | ||
205 | /* AM35XX only CONTROL_GENERAL register offsets */ | 206 | /* AM35XX only CONTROL_GENERAL register offsets */ |
206 | #define AM35XX_CONTROL_MSUSPENDMUX_6 (OMAP2_CONTROL_GENERAL + 0x0038) | 207 | #define AM35XX_CONTROL_MSUSPENDMUX_6 (OMAP2_CONTROL_GENERAL + 0x0038) |
diff --git a/arch/arm/mach-omap2/omap_opp_data.h b/arch/arm/mach-omap2/omap_opp_data.h index c784c12f98a1..18a750e296a8 100644 --- a/arch/arm/mach-omap2/omap_opp_data.h +++ b/arch/arm/mach-omap2/omap_opp_data.h | |||
@@ -89,8 +89,11 @@ extern struct omap_volt_data omap34xx_vddcore_volt_data[]; | |||
89 | extern struct omap_volt_data omap36xx_vddmpu_volt_data[]; | 89 | extern struct omap_volt_data omap36xx_vddmpu_volt_data[]; |
90 | extern struct omap_volt_data omap36xx_vddcore_volt_data[]; | 90 | extern struct omap_volt_data omap36xx_vddcore_volt_data[]; |
91 | 91 | ||
92 | extern struct omap_volt_data omap44xx_vdd_mpu_volt_data[]; | 92 | extern struct omap_volt_data omap443x_vdd_mpu_volt_data[]; |
93 | extern struct omap_volt_data omap44xx_vdd_iva_volt_data[]; | 93 | extern struct omap_volt_data omap443x_vdd_iva_volt_data[]; |
94 | extern struct omap_volt_data omap44xx_vdd_core_volt_data[]; | 94 | extern struct omap_volt_data omap443x_vdd_core_volt_data[]; |
95 | extern struct omap_volt_data omap446x_vdd_mpu_volt_data[]; | ||
96 | extern struct omap_volt_data omap446x_vdd_iva_volt_data[]; | ||
97 | extern struct omap_volt_data omap446x_vdd_core_volt_data[]; | ||
95 | 98 | ||
96 | #endif /* __ARCH_ARM_MACH_OMAP2_OMAP_OPP_DATA_H */ | 99 | #endif /* __ARCH_ARM_MACH_OMAP2_OMAP_OPP_DATA_H */ |
diff --git a/arch/arm/mach-omap2/omap_twl.c b/arch/arm/mach-omap2/omap_twl.c index f515a1a056d5..7ff9667d9761 100644 --- a/arch/arm/mach-omap2/omap_twl.c +++ b/arch/arm/mach-omap2/omap_twl.c | |||
@@ -30,16 +30,6 @@ | |||
30 | #define OMAP3_VP_VSTEPMAX_VSTEPMAX 0x04 | 30 | #define OMAP3_VP_VSTEPMAX_VSTEPMAX 0x04 |
31 | #define OMAP3_VP_VLIMITTO_TIMEOUT_US 200 | 31 | #define OMAP3_VP_VLIMITTO_TIMEOUT_US 200 |
32 | 32 | ||
33 | #define OMAP3430_VP1_VLIMITTO_VDDMIN 0x14 | ||
34 | #define OMAP3430_VP1_VLIMITTO_VDDMAX 0x42 | ||
35 | #define OMAP3430_VP2_VLIMITTO_VDDMIN 0x18 | ||
36 | #define OMAP3430_VP2_VLIMITTO_VDDMAX 0x2c | ||
37 | |||
38 | #define OMAP3630_VP1_VLIMITTO_VDDMIN 0x18 | ||
39 | #define OMAP3630_VP1_VLIMITTO_VDDMAX 0x3c | ||
40 | #define OMAP3630_VP2_VLIMITTO_VDDMIN 0x18 | ||
41 | #define OMAP3630_VP2_VLIMITTO_VDDMAX 0x30 | ||
42 | |||
43 | #define OMAP4_SRI2C_SLAVE_ADDR 0x12 | 33 | #define OMAP4_SRI2C_SLAVE_ADDR 0x12 |
44 | #define OMAP4_VDD_MPU_SR_VOLT_REG 0x55 | 34 | #define OMAP4_VDD_MPU_SR_VOLT_REG 0x55 |
45 | #define OMAP4_VDD_MPU_SR_CMD_REG 0x56 | 35 | #define OMAP4_VDD_MPU_SR_CMD_REG 0x56 |
@@ -53,13 +43,6 @@ | |||
53 | #define OMAP4_VP_VSTEPMAX_VSTEPMAX 0x04 | 43 | #define OMAP4_VP_VSTEPMAX_VSTEPMAX 0x04 |
54 | #define OMAP4_VP_VLIMITTO_TIMEOUT_US 200 | 44 | #define OMAP4_VP_VLIMITTO_TIMEOUT_US 200 |
55 | 45 | ||
56 | #define OMAP4_VP_MPU_VLIMITTO_VDDMIN 0xA | ||
57 | #define OMAP4_VP_MPU_VLIMITTO_VDDMAX 0x39 | ||
58 | #define OMAP4_VP_IVA_VLIMITTO_VDDMIN 0xA | ||
59 | #define OMAP4_VP_IVA_VLIMITTO_VDDMAX 0x2D | ||
60 | #define OMAP4_VP_CORE_VLIMITTO_VDDMIN 0xA | ||
61 | #define OMAP4_VP_CORE_VLIMITTO_VDDMAX 0x28 | ||
62 | |||
63 | static bool is_offset_valid; | 46 | static bool is_offset_valid; |
64 | static u8 smps_offset; | 47 | static u8 smps_offset; |
65 | /* | 48 | /* |
@@ -158,16 +141,11 @@ static u8 twl6030_uv_to_vsel(unsigned long uv) | |||
158 | static struct omap_voltdm_pmic omap3_mpu_pmic = { | 141 | static struct omap_voltdm_pmic omap3_mpu_pmic = { |
159 | .slew_rate = 4000, | 142 | .slew_rate = 4000, |
160 | .step_size = 12500, | 143 | .step_size = 12500, |
161 | .on_volt = 1200000, | ||
162 | .onlp_volt = 1000000, | ||
163 | .ret_volt = 975000, | ||
164 | .off_volt = 600000, | ||
165 | .volt_setup_time = 0xfff, | ||
166 | .vp_erroroffset = OMAP3_VP_CONFIG_ERROROFFSET, | 144 | .vp_erroroffset = OMAP3_VP_CONFIG_ERROROFFSET, |
167 | .vp_vstepmin = OMAP3_VP_VSTEPMIN_VSTEPMIN, | 145 | .vp_vstepmin = OMAP3_VP_VSTEPMIN_VSTEPMIN, |
168 | .vp_vstepmax = OMAP3_VP_VSTEPMAX_VSTEPMAX, | 146 | .vp_vstepmax = OMAP3_VP_VSTEPMAX_VSTEPMAX, |
169 | .vp_vddmin = OMAP3430_VP1_VLIMITTO_VDDMIN, | 147 | .vddmin = 600000, |
170 | .vp_vddmax = OMAP3430_VP1_VLIMITTO_VDDMAX, | 148 | .vddmax = 1450000, |
171 | .vp_timeout_us = OMAP3_VP_VLIMITTO_TIMEOUT_US, | 149 | .vp_timeout_us = OMAP3_VP_VLIMITTO_TIMEOUT_US, |
172 | .i2c_slave_addr = OMAP3_SRI2C_SLAVE_ADDR, | 150 | .i2c_slave_addr = OMAP3_SRI2C_SLAVE_ADDR, |
173 | .volt_reg_addr = OMAP3_VDD_MPU_SR_CONTROL_REG, | 151 | .volt_reg_addr = OMAP3_VDD_MPU_SR_CONTROL_REG, |
@@ -179,16 +157,11 @@ static struct omap_voltdm_pmic omap3_mpu_pmic = { | |||
179 | static struct omap_voltdm_pmic omap3_core_pmic = { | 157 | static struct omap_voltdm_pmic omap3_core_pmic = { |
180 | .slew_rate = 4000, | 158 | .slew_rate = 4000, |
181 | .step_size = 12500, | 159 | .step_size = 12500, |
182 | .on_volt = 1200000, | ||
183 | .onlp_volt = 1000000, | ||
184 | .ret_volt = 975000, | ||
185 | .off_volt = 600000, | ||
186 | .volt_setup_time = 0xfff, | ||
187 | .vp_erroroffset = OMAP3_VP_CONFIG_ERROROFFSET, | 160 | .vp_erroroffset = OMAP3_VP_CONFIG_ERROROFFSET, |
188 | .vp_vstepmin = OMAP3_VP_VSTEPMIN_VSTEPMIN, | 161 | .vp_vstepmin = OMAP3_VP_VSTEPMIN_VSTEPMIN, |
189 | .vp_vstepmax = OMAP3_VP_VSTEPMAX_VSTEPMAX, | 162 | .vp_vstepmax = OMAP3_VP_VSTEPMAX_VSTEPMAX, |
190 | .vp_vddmin = OMAP3430_VP2_VLIMITTO_VDDMIN, | 163 | .vddmin = 600000, |
191 | .vp_vddmax = OMAP3430_VP2_VLIMITTO_VDDMAX, | 164 | .vddmax = 1450000, |
192 | .vp_timeout_us = OMAP3_VP_VLIMITTO_TIMEOUT_US, | 165 | .vp_timeout_us = OMAP3_VP_VLIMITTO_TIMEOUT_US, |
193 | .i2c_slave_addr = OMAP3_SRI2C_SLAVE_ADDR, | 166 | .i2c_slave_addr = OMAP3_SRI2C_SLAVE_ADDR, |
194 | .volt_reg_addr = OMAP3_VDD_CORE_SR_CONTROL_REG, | 167 | .volt_reg_addr = OMAP3_VDD_CORE_SR_CONTROL_REG, |
@@ -200,21 +173,17 @@ static struct omap_voltdm_pmic omap3_core_pmic = { | |||
200 | static struct omap_voltdm_pmic omap4_mpu_pmic = { | 173 | static struct omap_voltdm_pmic omap4_mpu_pmic = { |
201 | .slew_rate = 4000, | 174 | .slew_rate = 4000, |
202 | .step_size = 12660, | 175 | .step_size = 12660, |
203 | .on_volt = 1375000, | ||
204 | .onlp_volt = 1375000, | ||
205 | .ret_volt = 830000, | ||
206 | .off_volt = 0, | ||
207 | .volt_setup_time = 0, | ||
208 | .vp_erroroffset = OMAP4_VP_CONFIG_ERROROFFSET, | 176 | .vp_erroroffset = OMAP4_VP_CONFIG_ERROROFFSET, |
209 | .vp_vstepmin = OMAP4_VP_VSTEPMIN_VSTEPMIN, | 177 | .vp_vstepmin = OMAP4_VP_VSTEPMIN_VSTEPMIN, |
210 | .vp_vstepmax = OMAP4_VP_VSTEPMAX_VSTEPMAX, | 178 | .vp_vstepmax = OMAP4_VP_VSTEPMAX_VSTEPMAX, |
211 | .vp_vddmin = OMAP4_VP_MPU_VLIMITTO_VDDMIN, | 179 | .vddmin = 0, |
212 | .vp_vddmax = OMAP4_VP_MPU_VLIMITTO_VDDMAX, | 180 | .vddmax = 2100000, |
213 | .vp_timeout_us = OMAP4_VP_VLIMITTO_TIMEOUT_US, | 181 | .vp_timeout_us = OMAP4_VP_VLIMITTO_TIMEOUT_US, |
214 | .i2c_slave_addr = OMAP4_SRI2C_SLAVE_ADDR, | 182 | .i2c_slave_addr = OMAP4_SRI2C_SLAVE_ADDR, |
215 | .volt_reg_addr = OMAP4_VDD_MPU_SR_VOLT_REG, | 183 | .volt_reg_addr = OMAP4_VDD_MPU_SR_VOLT_REG, |
216 | .cmd_reg_addr = OMAP4_VDD_MPU_SR_CMD_REG, | 184 | .cmd_reg_addr = OMAP4_VDD_MPU_SR_CMD_REG, |
217 | .i2c_high_speed = true, | 185 | .i2c_high_speed = true, |
186 | .i2c_pad_load = 3, | ||
218 | .vsel_to_uv = twl6030_vsel_to_uv, | 187 | .vsel_to_uv = twl6030_vsel_to_uv, |
219 | .uv_to_vsel = twl6030_uv_to_vsel, | 188 | .uv_to_vsel = twl6030_uv_to_vsel, |
220 | }; | 189 | }; |
@@ -222,21 +191,17 @@ static struct omap_voltdm_pmic omap4_mpu_pmic = { | |||
222 | static struct omap_voltdm_pmic omap4_iva_pmic = { | 191 | static struct omap_voltdm_pmic omap4_iva_pmic = { |
223 | .slew_rate = 4000, | 192 | .slew_rate = 4000, |
224 | .step_size = 12660, | 193 | .step_size = 12660, |
225 | .on_volt = 1188000, | ||
226 | .onlp_volt = 1188000, | ||
227 | .ret_volt = 830000, | ||
228 | .off_volt = 0, | ||
229 | .volt_setup_time = 0, | ||
230 | .vp_erroroffset = OMAP4_VP_CONFIG_ERROROFFSET, | 194 | .vp_erroroffset = OMAP4_VP_CONFIG_ERROROFFSET, |
231 | .vp_vstepmin = OMAP4_VP_VSTEPMIN_VSTEPMIN, | 195 | .vp_vstepmin = OMAP4_VP_VSTEPMIN_VSTEPMIN, |
232 | .vp_vstepmax = OMAP4_VP_VSTEPMAX_VSTEPMAX, | 196 | .vp_vstepmax = OMAP4_VP_VSTEPMAX_VSTEPMAX, |
233 | .vp_vddmin = OMAP4_VP_IVA_VLIMITTO_VDDMIN, | 197 | .vddmin = 0, |
234 | .vp_vddmax = OMAP4_VP_IVA_VLIMITTO_VDDMAX, | 198 | .vddmax = 2100000, |
235 | .vp_timeout_us = OMAP4_VP_VLIMITTO_TIMEOUT_US, | 199 | .vp_timeout_us = OMAP4_VP_VLIMITTO_TIMEOUT_US, |
236 | .i2c_slave_addr = OMAP4_SRI2C_SLAVE_ADDR, | 200 | .i2c_slave_addr = OMAP4_SRI2C_SLAVE_ADDR, |
237 | .volt_reg_addr = OMAP4_VDD_IVA_SR_VOLT_REG, | 201 | .volt_reg_addr = OMAP4_VDD_IVA_SR_VOLT_REG, |
238 | .cmd_reg_addr = OMAP4_VDD_IVA_SR_CMD_REG, | 202 | .cmd_reg_addr = OMAP4_VDD_IVA_SR_CMD_REG, |
239 | .i2c_high_speed = true, | 203 | .i2c_high_speed = true, |
204 | .i2c_pad_load = 3, | ||
240 | .vsel_to_uv = twl6030_vsel_to_uv, | 205 | .vsel_to_uv = twl6030_vsel_to_uv, |
241 | .uv_to_vsel = twl6030_uv_to_vsel, | 206 | .uv_to_vsel = twl6030_uv_to_vsel, |
242 | }; | 207 | }; |
@@ -244,20 +209,17 @@ static struct omap_voltdm_pmic omap4_iva_pmic = { | |||
244 | static struct omap_voltdm_pmic omap4_core_pmic = { | 209 | static struct omap_voltdm_pmic omap4_core_pmic = { |
245 | .slew_rate = 4000, | 210 | .slew_rate = 4000, |
246 | .step_size = 12660, | 211 | .step_size = 12660, |
247 | .on_volt = 1200000, | ||
248 | .onlp_volt = 1200000, | ||
249 | .ret_volt = 830000, | ||
250 | .off_volt = 0, | ||
251 | .volt_setup_time = 0, | ||
252 | .vp_erroroffset = OMAP4_VP_CONFIG_ERROROFFSET, | 212 | .vp_erroroffset = OMAP4_VP_CONFIG_ERROROFFSET, |
253 | .vp_vstepmin = OMAP4_VP_VSTEPMIN_VSTEPMIN, | 213 | .vp_vstepmin = OMAP4_VP_VSTEPMIN_VSTEPMIN, |
254 | .vp_vstepmax = OMAP4_VP_VSTEPMAX_VSTEPMAX, | 214 | .vp_vstepmax = OMAP4_VP_VSTEPMAX_VSTEPMAX, |
255 | .vp_vddmin = OMAP4_VP_CORE_VLIMITTO_VDDMIN, | 215 | .vddmin = 0, |
256 | .vp_vddmax = OMAP4_VP_CORE_VLIMITTO_VDDMAX, | 216 | .vddmax = 2100000, |
257 | .vp_timeout_us = OMAP4_VP_VLIMITTO_TIMEOUT_US, | 217 | .vp_timeout_us = OMAP4_VP_VLIMITTO_TIMEOUT_US, |
258 | .i2c_slave_addr = OMAP4_SRI2C_SLAVE_ADDR, | 218 | .i2c_slave_addr = OMAP4_SRI2C_SLAVE_ADDR, |
259 | .volt_reg_addr = OMAP4_VDD_CORE_SR_VOLT_REG, | 219 | .volt_reg_addr = OMAP4_VDD_CORE_SR_VOLT_REG, |
260 | .cmd_reg_addr = OMAP4_VDD_CORE_SR_CMD_REG, | 220 | .cmd_reg_addr = OMAP4_VDD_CORE_SR_CMD_REG, |
221 | .i2c_high_speed = true, | ||
222 | .i2c_pad_load = 3, | ||
261 | .vsel_to_uv = twl6030_vsel_to_uv, | 223 | .vsel_to_uv = twl6030_vsel_to_uv, |
262 | .uv_to_vsel = twl6030_uv_to_vsel, | 224 | .uv_to_vsel = twl6030_uv_to_vsel, |
263 | }; | 225 | }; |
@@ -288,13 +250,6 @@ int __init omap3_twl_init(void) | |||
288 | if (!cpu_is_omap34xx()) | 250 | if (!cpu_is_omap34xx()) |
289 | return -ENODEV; | 251 | return -ENODEV; |
290 | 252 | ||
291 | if (cpu_is_omap3630()) { | ||
292 | omap3_mpu_pmic.vp_vddmin = OMAP3630_VP1_VLIMITTO_VDDMIN; | ||
293 | omap3_mpu_pmic.vp_vddmax = OMAP3630_VP1_VLIMITTO_VDDMAX; | ||
294 | omap3_core_pmic.vp_vddmin = OMAP3630_VP2_VLIMITTO_VDDMIN; | ||
295 | omap3_core_pmic.vp_vddmax = OMAP3630_VP2_VLIMITTO_VDDMAX; | ||
296 | } | ||
297 | |||
298 | /* | 253 | /* |
299 | * The smartreflex bit on twl4030 specifies if the setting of voltage | 254 | * The smartreflex bit on twl4030 specifies if the setting of voltage |
300 | * is done over the I2C_SR path. Since this setting is independent of | 255 | * is done over the I2C_SR path. Since this setting is independent of |
diff --git a/arch/arm/mach-omap2/opp4xxx_data.c b/arch/arm/mach-omap2/opp4xxx_data.c index a9fd6d5fe79e..d470b728e720 100644 --- a/arch/arm/mach-omap2/opp4xxx_data.c +++ b/arch/arm/mach-omap2/opp4xxx_data.c | |||
@@ -1,7 +1,7 @@ | |||
1 | /* | 1 | /* |
2 | * OMAP4 OPP table definitions. | 2 | * OMAP4 OPP table definitions. |
3 | * | 3 | * |
4 | * Copyright (C) 2010 Texas Instruments Incorporated - http://www.ti.com/ | 4 | * Copyright (C) 2010-2012 Texas Instruments Incorporated - http://www.ti.com/ |
5 | * Nishanth Menon | 5 | * Nishanth Menon |
6 | * Kevin Hilman | 6 | * Kevin Hilman |
7 | * Thara Gopinath | 7 | * Thara Gopinath |
@@ -35,7 +35,7 @@ | |||
35 | #define OMAP4430_VDD_MPU_OPPTURBO_UV 1313000 | 35 | #define OMAP4430_VDD_MPU_OPPTURBO_UV 1313000 |
36 | #define OMAP4430_VDD_MPU_OPPNITRO_UV 1375000 | 36 | #define OMAP4430_VDD_MPU_OPPNITRO_UV 1375000 |
37 | 37 | ||
38 | struct omap_volt_data omap44xx_vdd_mpu_volt_data[] = { | 38 | struct omap_volt_data omap443x_vdd_mpu_volt_data[] = { |
39 | VOLT_DATA_DEFINE(OMAP4430_VDD_MPU_OPP50_UV, OMAP44XX_CONTROL_FUSE_MPU_OPP50, 0xf4, 0x0c), | 39 | VOLT_DATA_DEFINE(OMAP4430_VDD_MPU_OPP50_UV, OMAP44XX_CONTROL_FUSE_MPU_OPP50, 0xf4, 0x0c), |
40 | VOLT_DATA_DEFINE(OMAP4430_VDD_MPU_OPP100_UV, OMAP44XX_CONTROL_FUSE_MPU_OPP100, 0xf9, 0x16), | 40 | VOLT_DATA_DEFINE(OMAP4430_VDD_MPU_OPP100_UV, OMAP44XX_CONTROL_FUSE_MPU_OPP100, 0xf9, 0x16), |
41 | VOLT_DATA_DEFINE(OMAP4430_VDD_MPU_OPPTURBO_UV, OMAP44XX_CONTROL_FUSE_MPU_OPPTURBO, 0xfa, 0x23), | 41 | VOLT_DATA_DEFINE(OMAP4430_VDD_MPU_OPPTURBO_UV, OMAP44XX_CONTROL_FUSE_MPU_OPPTURBO, 0xfa, 0x23), |
@@ -47,7 +47,7 @@ struct omap_volt_data omap44xx_vdd_mpu_volt_data[] = { | |||
47 | #define OMAP4430_VDD_IVA_OPP100_UV 1188000 | 47 | #define OMAP4430_VDD_IVA_OPP100_UV 1188000 |
48 | #define OMAP4430_VDD_IVA_OPPTURBO_UV 1300000 | 48 | #define OMAP4430_VDD_IVA_OPPTURBO_UV 1300000 |
49 | 49 | ||
50 | struct omap_volt_data omap44xx_vdd_iva_volt_data[] = { | 50 | struct omap_volt_data omap443x_vdd_iva_volt_data[] = { |
51 | VOLT_DATA_DEFINE(OMAP4430_VDD_IVA_OPP50_UV, OMAP44XX_CONTROL_FUSE_IVA_OPP50, 0xf4, 0x0c), | 51 | VOLT_DATA_DEFINE(OMAP4430_VDD_IVA_OPP50_UV, OMAP44XX_CONTROL_FUSE_IVA_OPP50, 0xf4, 0x0c), |
52 | VOLT_DATA_DEFINE(OMAP4430_VDD_IVA_OPP100_UV, OMAP44XX_CONTROL_FUSE_IVA_OPP100, 0xf9, 0x16), | 52 | VOLT_DATA_DEFINE(OMAP4430_VDD_IVA_OPP100_UV, OMAP44XX_CONTROL_FUSE_IVA_OPP100, 0xf9, 0x16), |
53 | VOLT_DATA_DEFINE(OMAP4430_VDD_IVA_OPPTURBO_UV, OMAP44XX_CONTROL_FUSE_IVA_OPPTURBO, 0xfa, 0x23), | 53 | VOLT_DATA_DEFINE(OMAP4430_VDD_IVA_OPPTURBO_UV, OMAP44XX_CONTROL_FUSE_IVA_OPPTURBO, 0xfa, 0x23), |
@@ -57,14 +57,14 @@ struct omap_volt_data omap44xx_vdd_iva_volt_data[] = { | |||
57 | #define OMAP4430_VDD_CORE_OPP50_UV 1025000 | 57 | #define OMAP4430_VDD_CORE_OPP50_UV 1025000 |
58 | #define OMAP4430_VDD_CORE_OPP100_UV 1200000 | 58 | #define OMAP4430_VDD_CORE_OPP100_UV 1200000 |
59 | 59 | ||
60 | struct omap_volt_data omap44xx_vdd_core_volt_data[] = { | 60 | struct omap_volt_data omap443x_vdd_core_volt_data[] = { |
61 | VOLT_DATA_DEFINE(OMAP4430_VDD_CORE_OPP50_UV, OMAP44XX_CONTROL_FUSE_CORE_OPP50, 0xf4, 0x0c), | 61 | VOLT_DATA_DEFINE(OMAP4430_VDD_CORE_OPP50_UV, OMAP44XX_CONTROL_FUSE_CORE_OPP50, 0xf4, 0x0c), |
62 | VOLT_DATA_DEFINE(OMAP4430_VDD_CORE_OPP100_UV, OMAP44XX_CONTROL_FUSE_CORE_OPP100, 0xf9, 0x16), | 62 | VOLT_DATA_DEFINE(OMAP4430_VDD_CORE_OPP100_UV, OMAP44XX_CONTROL_FUSE_CORE_OPP100, 0xf9, 0x16), |
63 | VOLT_DATA_DEFINE(0, 0, 0, 0), | 63 | VOLT_DATA_DEFINE(0, 0, 0, 0), |
64 | }; | 64 | }; |
65 | 65 | ||
66 | 66 | ||
67 | static struct omap_opp_def __initdata omap44xx_opp_def_list[] = { | 67 | static struct omap_opp_def __initdata omap443x_opp_def_list[] = { |
68 | /* MPU OPP1 - OPP50 */ | 68 | /* MPU OPP1 - OPP50 */ |
69 | OPP_INITIALIZER("mpu", true, 300000000, OMAP4430_VDD_MPU_OPP50_UV), | 69 | OPP_INITIALIZER("mpu", true, 300000000, OMAP4430_VDD_MPU_OPP50_UV), |
70 | /* MPU OPP2 - OPP100 */ | 70 | /* MPU OPP2 - OPP100 */ |
@@ -86,6 +86,82 @@ static struct omap_opp_def __initdata omap44xx_opp_def_list[] = { | |||
86 | /* TODO: add DSP, aess, fdif, gpu */ | 86 | /* TODO: add DSP, aess, fdif, gpu */ |
87 | }; | 87 | }; |
88 | 88 | ||
89 | #define OMAP4460_VDD_MPU_OPP50_UV 1025000 | ||
90 | #define OMAP4460_VDD_MPU_OPP100_UV 1200000 | ||
91 | #define OMAP4460_VDD_MPU_OPPTURBO_UV 1313000 | ||
92 | #define OMAP4460_VDD_MPU_OPPNITRO_UV 1375000 | ||
93 | |||
94 | struct omap_volt_data omap446x_vdd_mpu_volt_data[] = { | ||
95 | VOLT_DATA_DEFINE(OMAP4460_VDD_MPU_OPP50_UV, OMAP44XX_CONTROL_FUSE_MPU_OPP50, 0xf4, 0x0c), | ||
96 | VOLT_DATA_DEFINE(OMAP4460_VDD_MPU_OPP100_UV, OMAP44XX_CONTROL_FUSE_MPU_OPP100, 0xf9, 0x16), | ||
97 | VOLT_DATA_DEFINE(OMAP4460_VDD_MPU_OPPTURBO_UV, OMAP44XX_CONTROL_FUSE_MPU_OPPTURBO, 0xfa, 0x23), | ||
98 | VOLT_DATA_DEFINE(OMAP4460_VDD_MPU_OPPNITRO_UV, OMAP44XX_CONTROL_FUSE_MPU_OPPNITRO, 0xfa, 0x27), | ||
99 | VOLT_DATA_DEFINE(0, 0, 0, 0), | ||
100 | }; | ||
101 | |||
102 | #define OMAP4460_VDD_IVA_OPP50_UV 1025000 | ||
103 | #define OMAP4460_VDD_IVA_OPP100_UV 1200000 | ||
104 | #define OMAP4460_VDD_IVA_OPPTURBO_UV 1313000 | ||
105 | #define OMAP4460_VDD_IVA_OPPNITRO_UV 1375000 | ||
106 | |||
107 | struct omap_volt_data omap446x_vdd_iva_volt_data[] = { | ||
108 | VOLT_DATA_DEFINE(OMAP4460_VDD_IVA_OPP50_UV, OMAP44XX_CONTROL_FUSE_IVA_OPP50, 0xf4, 0x0c), | ||
109 | VOLT_DATA_DEFINE(OMAP4460_VDD_IVA_OPP100_UV, OMAP44XX_CONTROL_FUSE_IVA_OPP100, 0xf9, 0x16), | ||
110 | VOLT_DATA_DEFINE(OMAP4460_VDD_IVA_OPPTURBO_UV, OMAP44XX_CONTROL_FUSE_IVA_OPPTURBO, 0xfa, 0x23), | ||
111 | VOLT_DATA_DEFINE(OMAP4460_VDD_IVA_OPPNITRO_UV, OMAP44XX_CONTROL_FUSE_IVA_OPPNITRO, 0xfa, 0x23), | ||
112 | VOLT_DATA_DEFINE(0, 0, 0, 0), | ||
113 | }; | ||
114 | |||
115 | #define OMAP4460_VDD_CORE_OPP50_UV 1025000 | ||
116 | #define OMAP4460_VDD_CORE_OPP100_UV 1200000 | ||
117 | #define OMAP4460_VDD_CORE_OPP100_OV_UV 1250000 | ||
118 | |||
119 | struct omap_volt_data omap446x_vdd_core_volt_data[] = { | ||
120 | VOLT_DATA_DEFINE(OMAP4460_VDD_CORE_OPP50_UV, OMAP44XX_CONTROL_FUSE_CORE_OPP50, 0xf4, 0x0c), | ||
121 | VOLT_DATA_DEFINE(OMAP4460_VDD_CORE_OPP100_UV, OMAP44XX_CONTROL_FUSE_CORE_OPP100, 0xf9, 0x16), | ||
122 | VOLT_DATA_DEFINE(OMAP4460_VDD_CORE_OPP100_OV_UV, OMAP44XX_CONTROL_FUSE_CORE_OPP100OV, 0xf9, 0x16), | ||
123 | VOLT_DATA_DEFINE(0, 0, 0, 0), | ||
124 | }; | ||
125 | |||
126 | static struct omap_opp_def __initdata omap446x_opp_def_list[] = { | ||
127 | /* MPU OPP1 - OPP50 */ | ||
128 | OPP_INITIALIZER("mpu", true, 350000000, OMAP4460_VDD_MPU_OPP50_UV), | ||
129 | /* MPU OPP2 - OPP100 */ | ||
130 | OPP_INITIALIZER("mpu", true, 700000000, OMAP4460_VDD_MPU_OPP100_UV), | ||
131 | /* MPU OPP3 - OPP-Turbo */ | ||
132 | OPP_INITIALIZER("mpu", true, 920000000, OMAP4460_VDD_MPU_OPPTURBO_UV), | ||
133 | /* | ||
134 | * MPU OPP4 - OPP-Nitro + Disabled as the reference schematics | ||
135 | * recommends TPS623631 - confirm and enable the opp in board file | ||
136 | * XXX: May be we should enable these based on mpu capability and | ||
137 | * Exception board files disable it... | ||
138 | */ | ||
139 | OPP_INITIALIZER("mpu", false, 1200000000, OMAP4460_VDD_MPU_OPPNITRO_UV), | ||
140 | /* MPU OPP4 - OPP-Nitro SpeedBin */ | ||
141 | OPP_INITIALIZER("mpu", false, 1500000000, OMAP4460_VDD_MPU_OPPNITRO_UV), | ||
142 | /* L3 OPP1 - OPP50 */ | ||
143 | OPP_INITIALIZER("l3_main_1", true, 100000000, OMAP4460_VDD_CORE_OPP50_UV), | ||
144 | /* L3 OPP2 - OPP100 */ | ||
145 | OPP_INITIALIZER("l3_main_1", true, 200000000, OMAP4460_VDD_CORE_OPP100_UV), | ||
146 | /* IVA OPP1 - OPP50 */ | ||
147 | OPP_INITIALIZER("iva", true, 133000000, OMAP4460_VDD_IVA_OPP50_UV), | ||
148 | /* IVA OPP2 - OPP100 */ | ||
149 | OPP_INITIALIZER("iva", true, 266100000, OMAP4460_VDD_IVA_OPP100_UV), | ||
150 | /* | ||
151 | * IVA OPP3 - OPP-Turbo + Disabled as the reference schematics | ||
152 | * recommends Phoenix VCORE2 which can supply only 600mA - so the ones | ||
153 | * above this OPP frequency, even though OMAP is capable, should be | ||
154 | * enabled by board file which is sure of the chip power capability | ||
155 | */ | ||
156 | OPP_INITIALIZER("iva", false, 332000000, OMAP4460_VDD_IVA_OPPTURBO_UV), | ||
157 | /* IVA OPP4 - OPP-Nitro */ | ||
158 | OPP_INITIALIZER("iva", false, 430000000, OMAP4460_VDD_IVA_OPPNITRO_UV), | ||
159 | /* IVA OPP5 - OPP-Nitro SpeedBin*/ | ||
160 | OPP_INITIALIZER("iva", false, 500000000, OMAP4460_VDD_IVA_OPPNITRO_UV), | ||
161 | |||
162 | /* TODO: add DSP, aess, fdif, gpu */ | ||
163 | }; | ||
164 | |||
89 | /** | 165 | /** |
90 | * omap4_opp_init() - initialize omap4 opp table | 166 | * omap4_opp_init() - initialize omap4 opp table |
91 | */ | 167 | */ |
@@ -93,12 +169,12 @@ int __init omap4_opp_init(void) | |||
93 | { | 169 | { |
94 | int r = -ENODEV; | 170 | int r = -ENODEV; |
95 | 171 | ||
96 | if (!cpu_is_omap443x()) | 172 | if (cpu_is_omap443x()) |
97 | return r; | 173 | r = omap_init_opp_table(omap443x_opp_def_list, |
98 | 174 | ARRAY_SIZE(omap443x_opp_def_list)); | |
99 | r = omap_init_opp_table(omap44xx_opp_def_list, | 175 | else if (cpu_is_omap446x()) |
100 | ARRAY_SIZE(omap44xx_opp_def_list)); | 176 | r = omap_init_opp_table(omap446x_opp_def_list, |
101 | 177 | ARRAY_SIZE(omap446x_opp_def_list)); | |
102 | return r; | 178 | return r; |
103 | } | 179 | } |
104 | device_initcall(omap4_opp_init); | 180 | device_initcall(omap4_opp_init); |
diff --git a/arch/arm/mach-omap2/pm.c b/arch/arm/mach-omap2/pm.c index ea61c32957bd..109a02e02d72 100644 --- a/arch/arm/mach-omap2/pm.c +++ b/arch/arm/mach-omap2/pm.c | |||
@@ -39,6 +39,36 @@ static struct omap_device_pm_latency *pm_lats; | |||
39 | */ | 39 | */ |
40 | int (*omap_pm_suspend)(void); | 40 | int (*omap_pm_suspend)(void); |
41 | 41 | ||
42 | /** | ||
43 | * struct omap2_oscillator - Describe the board main oscillator latencies | ||
44 | * @startup_time: oscillator startup latency | ||
45 | * @shutdown_time: oscillator shutdown latency | ||
46 | */ | ||
47 | struct omap2_oscillator { | ||
48 | u32 startup_time; | ||
49 | u32 shutdown_time; | ||
50 | }; | ||
51 | |||
52 | static struct omap2_oscillator oscillator = { | ||
53 | .startup_time = ULONG_MAX, | ||
54 | .shutdown_time = ULONG_MAX, | ||
55 | }; | ||
56 | |||
57 | void omap_pm_setup_oscillator(u32 tstart, u32 tshut) | ||
58 | { | ||
59 | oscillator.startup_time = tstart; | ||
60 | oscillator.shutdown_time = tshut; | ||
61 | } | ||
62 | |||
63 | void omap_pm_get_oscillator(u32 *tstart, u32 *tshut) | ||
64 | { | ||
65 | if (!tstart || !tshut) | ||
66 | return; | ||
67 | |||
68 | *tstart = oscillator.startup_time; | ||
69 | *tshut = oscillator.shutdown_time; | ||
70 | } | ||
71 | |||
42 | static int __init _init_omap_device(char *name) | 72 | static int __init _init_omap_device(char *name) |
43 | { | 73 | { |
44 | struct omap_hwmod *oh; | 74 | struct omap_hwmod *oh; |
diff --git a/arch/arm/mach-omap2/pm.h b/arch/arm/mach-omap2/pm.h index 67d66131cfa7..4db7b238a0d5 100644 --- a/arch/arm/mach-omap2/pm.h +++ b/arch/arm/mach-omap2/pm.h | |||
@@ -129,4 +129,14 @@ static inline int omap4_twl_init(void) | |||
129 | } | 129 | } |
130 | #endif | 130 | #endif |
131 | 131 | ||
132 | #ifdef CONFIG_PM | ||
133 | extern void omap_pm_setup_oscillator(u32 tstart, u32 tshut); | ||
134 | extern void omap_pm_get_oscillator(u32 *tstart, u32 *tshut); | ||
135 | extern void omap_pm_setup_sr_i2c_pcb_length(u32 mm); | ||
136 | #else | ||
137 | static inline void omap_pm_setup_oscillator(u32 tstart, u32 tshut) { } | ||
138 | static inline void omap_pm_get_oscillator(u32 *tstart, u32 *tshut) { } | ||
139 | static inline void omap_pm_setup_sr_i2c_pcb_length(u32 mm) { } | ||
140 | #endif | ||
141 | |||
132 | #endif | 142 | #endif |
diff --git a/arch/arm/mach-omap2/vc.c b/arch/arm/mach-omap2/vc.c index 880249b17012..687aa86c0d5e 100644 --- a/arch/arm/mach-omap2/vc.c +++ b/arch/arm/mach-omap2/vc.c | |||
@@ -11,13 +11,20 @@ | |||
11 | #include <linux/delay.h> | 11 | #include <linux/delay.h> |
12 | #include <linux/init.h> | 12 | #include <linux/init.h> |
13 | #include <linux/bug.h> | 13 | #include <linux/bug.h> |
14 | #include <linux/io.h> | ||
14 | 15 | ||
16 | #include <asm/div64.h> | ||
17 | |||
18 | #include "iomap.h" | ||
15 | #include "soc.h" | 19 | #include "soc.h" |
16 | #include "voltage.h" | 20 | #include "voltage.h" |
17 | #include "vc.h" | 21 | #include "vc.h" |
18 | #include "prm-regbits-34xx.h" | 22 | #include "prm-regbits-34xx.h" |
19 | #include "prm-regbits-44xx.h" | 23 | #include "prm-regbits-44xx.h" |
20 | #include "prm44xx.h" | 24 | #include "prm44xx.h" |
25 | #include "pm.h" | ||
26 | #include "scrm44xx.h" | ||
27 | #include "control.h" | ||
21 | 28 | ||
22 | /** | 29 | /** |
23 | * struct omap_vc_channel_cfg - describe the cfg_channel bitfield | 30 | * struct omap_vc_channel_cfg - describe the cfg_channel bitfield |
@@ -63,6 +70,9 @@ static struct omap_vc_channel_cfg vc_mutant_channel_cfg = { | |||
63 | }; | 70 | }; |
64 | 71 | ||
65 | static struct omap_vc_channel_cfg *vc_cfg_bits; | 72 | static struct omap_vc_channel_cfg *vc_cfg_bits; |
73 | |||
74 | /* Default I2C trace length on pcb, 6.3cm. Used for capacitance calculations. */ | ||
75 | static u32 sr_i2c_pcb_length = 63; | ||
66 | #define CFG_CHANNEL_MASK 0x1f | 76 | #define CFG_CHANNEL_MASK 0x1f |
67 | 77 | ||
68 | /** | 78 | /** |
@@ -135,6 +145,8 @@ int omap_vc_pre_scale(struct voltagedomain *voltdm, | |||
135 | vc_cmdval |= (*target_vsel << vc->common->cmd_on_shift); | 145 | vc_cmdval |= (*target_vsel << vc->common->cmd_on_shift); |
136 | voltdm->write(vc_cmdval, vc->cmdval_reg); | 146 | voltdm->write(vc_cmdval, vc->cmdval_reg); |
137 | 147 | ||
148 | voltdm->vc_param->on = target_volt; | ||
149 | |||
138 | omap_vp_update_errorgain(voltdm, target_volt); | 150 | omap_vp_update_errorgain(voltdm, target_volt); |
139 | 151 | ||
140 | return 0; | 152 | return 0; |
@@ -202,46 +214,389 @@ int omap_vc_bypass_scale(struct voltagedomain *voltdm, | |||
202 | return 0; | 214 | return 0; |
203 | } | 215 | } |
204 | 216 | ||
205 | static void __init omap3_vfsm_init(struct voltagedomain *voltdm) | 217 | /* Convert microsecond value to number of 32kHz clock cycles */ |
218 | static inline u32 omap_usec_to_32k(u32 usec) | ||
219 | { | ||
220 | return DIV_ROUND_UP_ULL(32768ULL * (u64)usec, 1000000ULL); | ||
221 | } | ||
222 | |||
223 | /* Set oscillator setup time for omap3 */ | ||
224 | static void omap3_set_clksetup(u32 usec, struct voltagedomain *voltdm) | ||
225 | { | ||
226 | voltdm->write(omap_usec_to_32k(usec), OMAP3_PRM_CLKSETUP_OFFSET); | ||
227 | } | ||
228 | |||
229 | /** | ||
230 | * omap3_set_i2c_timings - sets i2c sleep timings for a channel | ||
231 | * @voltdm: channel to configure | ||
232 | * @off_mode: select whether retention or off mode values used | ||
233 | * | ||
234 | * Calculates and sets up voltage controller to use I2C based | ||
235 | * voltage scaling for sleep modes. This can be used for either off mode | ||
236 | * or retention. Off mode has additionally an option to use sys_off_mode | ||
237 | * pad, which uses a global signal to program the whole power IC to | ||
238 | * off-mode. | ||
239 | */ | ||
240 | static void omap3_set_i2c_timings(struct voltagedomain *voltdm, bool off_mode) | ||
206 | { | 241 | { |
242 | unsigned long voltsetup1; | ||
243 | u32 tgt_volt; | ||
244 | |||
245 | /* | ||
246 | * Oscillator is shut down only if we are using sys_off_mode pad, | ||
247 | * thus we set a minimal setup time here | ||
248 | */ | ||
249 | omap3_set_clksetup(1, voltdm); | ||
250 | |||
251 | if (off_mode) | ||
252 | tgt_volt = voltdm->vc_param->off; | ||
253 | else | ||
254 | tgt_volt = voltdm->vc_param->ret; | ||
255 | |||
256 | voltsetup1 = (voltdm->vc_param->on - tgt_volt) / | ||
257 | voltdm->pmic->slew_rate; | ||
258 | |||
259 | voltsetup1 = voltsetup1 * voltdm->sys_clk.rate / 8 / 1000000 + 1; | ||
260 | |||
261 | voltdm->rmw(voltdm->vfsm->voltsetup_mask, | ||
262 | voltsetup1 << __ffs(voltdm->vfsm->voltsetup_mask), | ||
263 | voltdm->vfsm->voltsetup_reg); | ||
264 | |||
207 | /* | 265 | /* |
208 | * Voltage Manager FSM parameters init | 266 | * pmic is not controlling the voltage scaling during retention, |
209 | * XXX This data should be passed in from the board file | 267 | * thus set voltsetup2 to 0 |
210 | */ | 268 | */ |
211 | voltdm->write(OMAP3_CLKSETUP, OMAP3_PRM_CLKSETUP_OFFSET); | 269 | voltdm->write(0, OMAP3_PRM_VOLTSETUP2_OFFSET); |
212 | voltdm->write(OMAP3_VOLTOFFSET, OMAP3_PRM_VOLTOFFSET_OFFSET); | ||
213 | voltdm->write(OMAP3_VOLTSETUP2, OMAP3_PRM_VOLTSETUP2_OFFSET); | ||
214 | } | 270 | } |
215 | 271 | ||
216 | static void __init omap3_vc_init_channel(struct voltagedomain *voltdm) | 272 | /** |
273 | * omap3_set_off_timings - sets off-mode timings for a channel | ||
274 | * @voltdm: channel to configure | ||
275 | * | ||
276 | * Calculates and sets up off-mode timings for a channel. Off-mode | ||
277 | * can use either I2C based voltage scaling, or alternatively | ||
278 | * sys_off_mode pad can be used to send a global command to power IC. | ||
279 | * This function first checks which mode is being used, and calls | ||
280 | * omap3_set_i2c_timings() if the system is using I2C control mode. | ||
281 | * sys_off_mode has the additional benefit that voltages can be | ||
282 | * scaled to zero volt level with TWL4030 / TWL5030, I2C can only | ||
283 | * scale to 600mV. | ||
284 | */ | ||
285 | static void omap3_set_off_timings(struct voltagedomain *voltdm) | ||
217 | { | 286 | { |
218 | static bool is_initialized; | 287 | unsigned long clksetup; |
288 | unsigned long voltsetup2; | ||
289 | unsigned long voltsetup2_old; | ||
290 | u32 val; | ||
291 | u32 tstart, tshut; | ||
219 | 292 | ||
220 | if (is_initialized) | 293 | /* check if sys_off_mode is used to control off-mode voltages */ |
294 | val = voltdm->read(OMAP3_PRM_VOLTCTRL_OFFSET); | ||
295 | if (!(val & OMAP3430_SEL_OFF_MASK)) { | ||
296 | /* No, omap is controlling them over I2C */ | ||
297 | omap3_set_i2c_timings(voltdm, true); | ||
221 | return; | 298 | return; |
299 | } | ||
300 | |||
301 | omap_pm_get_oscillator(&tstart, &tshut); | ||
302 | omap3_set_clksetup(tstart, voltdm); | ||
303 | |||
304 | clksetup = voltdm->read(OMAP3_PRM_CLKSETUP_OFFSET); | ||
305 | |||
306 | /* voltsetup 2 in us */ | ||
307 | voltsetup2 = voltdm->vc_param->on / voltdm->pmic->slew_rate; | ||
308 | |||
309 | /* convert to 32k clk cycles */ | ||
310 | voltsetup2 = DIV_ROUND_UP(voltsetup2 * 32768, 1000000); | ||
311 | |||
312 | voltsetup2_old = voltdm->read(OMAP3_PRM_VOLTSETUP2_OFFSET); | ||
313 | |||
314 | /* | ||
315 | * Update voltsetup2 if higher than current value (needed because | ||
316 | * we have multiple channels with different ramp times), also | ||
317 | * update voltoffset always to value recommended by TRM | ||
318 | */ | ||
319 | if (voltsetup2 > voltsetup2_old) { | ||
320 | voltdm->write(voltsetup2, OMAP3_PRM_VOLTSETUP2_OFFSET); | ||
321 | voltdm->write(clksetup - voltsetup2, | ||
322 | OMAP3_PRM_VOLTOFFSET_OFFSET); | ||
323 | } else | ||
324 | voltdm->write(clksetup - voltsetup2_old, | ||
325 | OMAP3_PRM_VOLTOFFSET_OFFSET); | ||
326 | |||
327 | /* | ||
328 | * omap is not controlling voltage scaling during off-mode, | ||
329 | * thus set voltsetup1 to 0 | ||
330 | */ | ||
331 | voltdm->rmw(voltdm->vfsm->voltsetup_mask, 0, | ||
332 | voltdm->vfsm->voltsetup_reg); | ||
333 | |||
334 | /* voltoffset must be clksetup minus voltsetup2 according to TRM */ | ||
335 | voltdm->write(clksetup - voltsetup2, OMAP3_PRM_VOLTOFFSET_OFFSET); | ||
336 | } | ||
337 | |||
338 | static void __init omap3_vc_init_channel(struct voltagedomain *voltdm) | ||
339 | { | ||
340 | omap3_set_off_timings(voltdm); | ||
341 | } | ||
342 | |||
343 | /** | ||
344 | * omap4_calc_volt_ramp - calculates voltage ramping delays on omap4 | ||
345 | * @voltdm: channel to calculate values for | ||
346 | * @voltage_diff: voltage difference in microvolts | ||
347 | * | ||
348 | * Calculates voltage ramp prescaler + counter values for a voltage | ||
349 | * difference on omap4. Returns a field value suitable for writing to | ||
350 | * VOLTSETUP register for a channel in following format: | ||
351 | * bits[8:9] prescaler ... bits[0:5] counter. See OMAP4 TRM for reference. | ||
352 | */ | ||
353 | static u32 omap4_calc_volt_ramp(struct voltagedomain *voltdm, u32 voltage_diff) | ||
354 | { | ||
355 | u32 prescaler; | ||
356 | u32 cycles; | ||
357 | u32 time; | ||
358 | |||
359 | time = voltage_diff / voltdm->pmic->slew_rate; | ||
360 | |||
361 | cycles = voltdm->sys_clk.rate / 1000 * time / 1000; | ||
362 | |||
363 | cycles /= 64; | ||
364 | prescaler = 0; | ||
365 | |||
366 | /* shift to next prescaler until no overflow */ | ||
367 | |||
368 | /* scale for div 256 = 64 * 4 */ | ||
369 | if (cycles > 63) { | ||
370 | cycles /= 4; | ||
371 | prescaler++; | ||
372 | } | ||
373 | |||
374 | /* scale for div 512 = 256 * 2 */ | ||
375 | if (cycles > 63) { | ||
376 | cycles /= 2; | ||
377 | prescaler++; | ||
378 | } | ||
379 | |||
380 | /* scale for div 2048 = 512 * 4 */ | ||
381 | if (cycles > 63) { | ||
382 | cycles /= 4; | ||
383 | prescaler++; | ||
384 | } | ||
385 | |||
386 | /* check for overflow => invalid ramp time */ | ||
387 | if (cycles > 63) { | ||
388 | pr_warn("%s: invalid setuptime for vdd_%s\n", __func__, | ||
389 | voltdm->name); | ||
390 | return 0; | ||
391 | } | ||
392 | |||
393 | cycles++; | ||
222 | 394 | ||
223 | omap3_vfsm_init(voltdm); | 395 | return (prescaler << OMAP4430_RAMP_UP_PRESCAL_SHIFT) | |
396 | (cycles << OMAP4430_RAMP_UP_COUNT_SHIFT); | ||
397 | } | ||
398 | |||
399 | /** | ||
400 | * omap4_usec_to_val_scrm - convert microsecond value to SCRM module bitfield | ||
401 | * @usec: microseconds | ||
402 | * @shift: number of bits to shift left | ||
403 | * @mask: bitfield mask | ||
404 | * | ||
405 | * Converts microsecond value to OMAP4 SCRM bitfield. Bitfield is | ||
406 | * shifted to requested position, and checked agains the mask value. | ||
407 | * If larger, forced to the max value of the field (i.e. the mask itself.) | ||
408 | * Returns the SCRM bitfield value. | ||
409 | */ | ||
410 | static u32 omap4_usec_to_val_scrm(u32 usec, int shift, u32 mask) | ||
411 | { | ||
412 | u32 val; | ||
413 | |||
414 | val = omap_usec_to_32k(usec) << shift; | ||
224 | 415 | ||
225 | is_initialized = true; | 416 | /* Check for overflow, if yes, force to max value */ |
417 | if (val > mask) | ||
418 | val = mask; | ||
419 | |||
420 | return val; | ||
226 | } | 421 | } |
227 | 422 | ||
423 | /** | ||
424 | * omap4_set_timings - set voltage ramp timings for a channel | ||
425 | * @voltdm: channel to configure | ||
426 | * @off_mode: whether off-mode values are used | ||
427 | * | ||
428 | * Calculates and sets the voltage ramp up / down values for a channel. | ||
429 | */ | ||
430 | static void omap4_set_timings(struct voltagedomain *voltdm, bool off_mode) | ||
431 | { | ||
432 | u32 val; | ||
433 | u32 ramp; | ||
434 | int offset; | ||
435 | u32 tstart, tshut; | ||
436 | |||
437 | if (off_mode) { | ||
438 | ramp = omap4_calc_volt_ramp(voltdm, | ||
439 | voltdm->vc_param->on - voltdm->vc_param->off); | ||
440 | offset = voltdm->vfsm->voltsetup_off_reg; | ||
441 | } else { | ||
442 | ramp = omap4_calc_volt_ramp(voltdm, | ||
443 | voltdm->vc_param->on - voltdm->vc_param->ret); | ||
444 | offset = voltdm->vfsm->voltsetup_reg; | ||
445 | } | ||
446 | |||
447 | if (!ramp) | ||
448 | return; | ||
449 | |||
450 | val = voltdm->read(offset); | ||
451 | |||
452 | val |= ramp << OMAP4430_RAMP_DOWN_COUNT_SHIFT; | ||
453 | |||
454 | val |= ramp << OMAP4430_RAMP_UP_COUNT_SHIFT; | ||
455 | |||
456 | voltdm->write(val, offset); | ||
457 | |||
458 | omap_pm_get_oscillator(&tstart, &tshut); | ||
459 | |||
460 | val = omap4_usec_to_val_scrm(tstart, OMAP4_SETUPTIME_SHIFT, | ||
461 | OMAP4_SETUPTIME_MASK); | ||
462 | val |= omap4_usec_to_val_scrm(tshut, OMAP4_DOWNTIME_SHIFT, | ||
463 | OMAP4_DOWNTIME_MASK); | ||
464 | |||
465 | __raw_writel(val, OMAP4_SCRM_CLKSETUPTIME); | ||
466 | } | ||
228 | 467 | ||
229 | /* OMAP4 specific voltage init functions */ | 468 | /* OMAP4 specific voltage init functions */ |
230 | static void __init omap4_vc_init_channel(struct voltagedomain *voltdm) | 469 | static void __init omap4_vc_init_channel(struct voltagedomain *voltdm) |
231 | { | 470 | { |
232 | static bool is_initialized; | 471 | omap4_set_timings(voltdm, true); |
233 | u32 vc_val; | 472 | omap4_set_timings(voltdm, false); |
473 | } | ||
474 | |||
475 | struct i2c_init_data { | ||
476 | u8 loadbits; | ||
477 | u8 load; | ||
478 | u8 hsscll_38_4; | ||
479 | u8 hsscll_26; | ||
480 | u8 hsscll_19_2; | ||
481 | u8 hsscll_16_8; | ||
482 | u8 hsscll_12; | ||
483 | }; | ||
234 | 484 | ||
235 | if (is_initialized) | 485 | static const __initdata struct i2c_init_data omap4_i2c_timing_data[] = { |
486 | { | ||
487 | .load = 50, | ||
488 | .loadbits = 0x3, | ||
489 | .hsscll_38_4 = 13, | ||
490 | .hsscll_26 = 11, | ||
491 | .hsscll_19_2 = 9, | ||
492 | .hsscll_16_8 = 9, | ||
493 | .hsscll_12 = 8, | ||
494 | }, | ||
495 | { | ||
496 | .load = 25, | ||
497 | .loadbits = 0x2, | ||
498 | .hsscll_38_4 = 13, | ||
499 | .hsscll_26 = 11, | ||
500 | .hsscll_19_2 = 9, | ||
501 | .hsscll_16_8 = 9, | ||
502 | .hsscll_12 = 8, | ||
503 | }, | ||
504 | { | ||
505 | .load = 12, | ||
506 | .loadbits = 0x1, | ||
507 | .hsscll_38_4 = 11, | ||
508 | .hsscll_26 = 10, | ||
509 | .hsscll_19_2 = 9, | ||
510 | .hsscll_16_8 = 9, | ||
511 | .hsscll_12 = 8, | ||
512 | }, | ||
513 | { | ||
514 | .load = 0, | ||
515 | .loadbits = 0x0, | ||
516 | .hsscll_38_4 = 12, | ||
517 | .hsscll_26 = 10, | ||
518 | .hsscll_19_2 = 9, | ||
519 | .hsscll_16_8 = 8, | ||
520 | .hsscll_12 = 8, | ||
521 | }, | ||
522 | }; | ||
523 | |||
524 | /** | ||
525 | * omap4_vc_i2c_timing_init - sets up board I2C timing parameters | ||
526 | * @voltdm: voltagedomain pointer to get data from | ||
527 | * | ||
528 | * Use PMIC + board supplied settings for calculating the total I2C | ||
529 | * channel capacitance and set the timing parameters based on this. | ||
530 | * Pre-calculated values are provided in data tables, as it is not | ||
531 | * too straightforward to calculate these runtime. | ||
532 | */ | ||
533 | static void __init omap4_vc_i2c_timing_init(struct voltagedomain *voltdm) | ||
534 | { | ||
535 | u32 capacitance; | ||
536 | u32 val; | ||
537 | u16 hsscll; | ||
538 | const struct i2c_init_data *i2c_data; | ||
539 | |||
540 | if (!voltdm->pmic->i2c_high_speed) { | ||
541 | pr_warn("%s: only high speed supported!\n", __func__); | ||
236 | return; | 542 | return; |
543 | } | ||
544 | |||
545 | /* PCB trace capacitance, 0.125pF / mm => mm / 8 */ | ||
546 | capacitance = DIV_ROUND_UP(sr_i2c_pcb_length, 8); | ||
547 | |||
548 | /* OMAP pad capacitance */ | ||
549 | capacitance += 4; | ||
550 | |||
551 | /* PMIC pad capacitance */ | ||
552 | capacitance += voltdm->pmic->i2c_pad_load; | ||
553 | |||
554 | /* Search for capacitance match in the table */ | ||
555 | i2c_data = omap4_i2c_timing_data; | ||
556 | |||
557 | while (i2c_data->load > capacitance) | ||
558 | i2c_data++; | ||
559 | |||
560 | /* Select proper values based on sysclk frequency */ | ||
561 | switch (voltdm->sys_clk.rate) { | ||
562 | case 38400000: | ||
563 | hsscll = i2c_data->hsscll_38_4; | ||
564 | break; | ||
565 | case 26000000: | ||
566 | hsscll = i2c_data->hsscll_26; | ||
567 | break; | ||
568 | case 19200000: | ||
569 | hsscll = i2c_data->hsscll_19_2; | ||
570 | break; | ||
571 | case 16800000: | ||
572 | hsscll = i2c_data->hsscll_16_8; | ||
573 | break; | ||
574 | case 12000000: | ||
575 | hsscll = i2c_data->hsscll_12; | ||
576 | break; | ||
577 | default: | ||
578 | pr_warn("%s: unsupported sysclk rate: %d!\n", __func__, | ||
579 | voltdm->sys_clk.rate); | ||
580 | return; | ||
581 | } | ||
237 | 582 | ||
238 | /* XXX These are magic numbers and do not belong! */ | 583 | /* Loadbits define pull setup for the I2C channels */ |
239 | vc_val = (0x60 << OMAP4430_SCLL_SHIFT | 0x26 << OMAP4430_SCLH_SHIFT); | 584 | val = i2c_data->loadbits << 25 | i2c_data->loadbits << 29; |
240 | voltdm->write(vc_val, OMAP4_PRM_VC_CFG_I2C_CLK_OFFSET); | ||
241 | 585 | ||
242 | is_initialized = true; | 586 | /* Write to SYSCTRL_PADCONF_WKUP_CTRL_I2C_2 to setup I2C pull */ |
587 | __raw_writel(val, OMAP2_L4_IO_ADDRESS(OMAP4_CTRL_MODULE_PAD_WKUP + | ||
588 | OMAP4_CTRL_MODULE_PAD_WKUP_CONTROL_I2C_2)); | ||
589 | |||
590 | /* HSSCLH can always be zero */ | ||
591 | val = hsscll << OMAP4430_HSSCLL_SHIFT; | ||
592 | val |= (0x28 << OMAP4430_SCLL_SHIFT | 0x2c << OMAP4430_SCLH_SHIFT); | ||
593 | |||
594 | /* Write setup times to I2C config register */ | ||
595 | voltdm->write(val, OMAP4_PRM_VC_CFG_I2C_CLK_OFFSET); | ||
243 | } | 596 | } |
244 | 597 | ||
598 | |||
599 | |||
245 | /** | 600 | /** |
246 | * omap_vc_i2c_init - initialize I2C interface to PMIC | 601 | * omap_vc_i2c_init - initialize I2C interface to PMIC |
247 | * @voltdm: voltage domain containing VC data | 602 | * @voltdm: voltage domain containing VC data |
@@ -281,9 +636,49 @@ static void __init omap_vc_i2c_init(struct voltagedomain *voltdm) | |||
281 | mcode << __ffs(vc->common->i2c_mcode_mask), | 636 | mcode << __ffs(vc->common->i2c_mcode_mask), |
282 | vc->common->i2c_cfg_reg); | 637 | vc->common->i2c_cfg_reg); |
283 | 638 | ||
639 | if (cpu_is_omap44xx()) | ||
640 | omap4_vc_i2c_timing_init(voltdm); | ||
641 | |||
284 | initialized = true; | 642 | initialized = true; |
285 | } | 643 | } |
286 | 644 | ||
645 | /** | ||
646 | * omap_vc_calc_vsel - calculate vsel value for a channel | ||
647 | * @voltdm: channel to calculate value for | ||
648 | * @uvolt: microvolt value to convert to vsel | ||
649 | * | ||
650 | * Converts a microvolt value to vsel value for the used PMIC. | ||
651 | * This checks whether the microvolt value is out of bounds, and | ||
652 | * adjusts the value accordingly. If unsupported value detected, | ||
653 | * warning is thrown. | ||
654 | */ | ||
655 | static u8 omap_vc_calc_vsel(struct voltagedomain *voltdm, u32 uvolt) | ||
656 | { | ||
657 | if (voltdm->pmic->vddmin > uvolt) | ||
658 | uvolt = voltdm->pmic->vddmin; | ||
659 | if (voltdm->pmic->vddmax < uvolt) { | ||
660 | WARN(1, "%s: voltage not supported by pmic: %u vs max %u\n", | ||
661 | __func__, uvolt, voltdm->pmic->vddmax); | ||
662 | /* Lets try maximum value anyway */ | ||
663 | uvolt = voltdm->pmic->vddmax; | ||
664 | } | ||
665 | |||
666 | return voltdm->pmic->uv_to_vsel(uvolt); | ||
667 | } | ||
668 | |||
669 | /** | ||
670 | * omap_pm_setup_sr_i2c_pcb_length - set length of SR I2C traces on PCB | ||
671 | * @mm: length of the PCB trace in millimetres | ||
672 | * | ||
673 | * Sets the PCB trace length for the I2C channel. By default uses 63mm. | ||
674 | * This is needed for properly calculating the capacitance value for | ||
675 | * the PCB trace, and for setting the SR I2C channel timing parameters. | ||
676 | */ | ||
677 | void __init omap_pm_setup_sr_i2c_pcb_length(u32 mm) | ||
678 | { | ||
679 | sr_i2c_pcb_length = mm; | ||
680 | } | ||
681 | |||
287 | void __init omap_vc_init_channel(struct voltagedomain *voltdm) | 682 | void __init omap_vc_init_channel(struct voltagedomain *voltdm) |
288 | { | 683 | { |
289 | struct omap_vc_channel *vc = voltdm->vc; | 684 | struct omap_vc_channel *vc = voltdm->vc; |
@@ -311,7 +706,6 @@ void __init omap_vc_init_channel(struct voltagedomain *voltdm) | |||
311 | vc->i2c_slave_addr = voltdm->pmic->i2c_slave_addr; | 706 | vc->i2c_slave_addr = voltdm->pmic->i2c_slave_addr; |
312 | vc->volt_reg_addr = voltdm->pmic->volt_reg_addr; | 707 | vc->volt_reg_addr = voltdm->pmic->volt_reg_addr; |
313 | vc->cmd_reg_addr = voltdm->pmic->cmd_reg_addr; | 708 | vc->cmd_reg_addr = voltdm->pmic->cmd_reg_addr; |
314 | vc->setup_time = voltdm->pmic->volt_setup_time; | ||
315 | 709 | ||
316 | /* Configure the i2c slave address for this VC */ | 710 | /* Configure the i2c slave address for this VC */ |
317 | voltdm->rmw(vc->smps_sa_mask, | 711 | voltdm->rmw(vc->smps_sa_mask, |
@@ -331,14 +725,18 @@ void __init omap_vc_init_channel(struct voltagedomain *voltdm) | |||
331 | voltdm->rmw(vc->smps_cmdra_mask, | 725 | voltdm->rmw(vc->smps_cmdra_mask, |
332 | vc->cmd_reg_addr << __ffs(vc->smps_cmdra_mask), | 726 | vc->cmd_reg_addr << __ffs(vc->smps_cmdra_mask), |
333 | vc->smps_cmdra_reg); | 727 | vc->smps_cmdra_reg); |
334 | vc->cfg_channel |= vc_cfg_bits->rac | vc_cfg_bits->racen; | 728 | vc->cfg_channel |= vc_cfg_bits->rac; |
335 | } | 729 | } |
336 | 730 | ||
731 | if (vc->cmd_reg_addr == vc->volt_reg_addr) | ||
732 | vc->cfg_channel |= vc_cfg_bits->racen; | ||
733 | |||
337 | /* Set up the on, inactive, retention and off voltage */ | 734 | /* Set up the on, inactive, retention and off voltage */ |
338 | on_vsel = voltdm->pmic->uv_to_vsel(voltdm->pmic->on_volt); | 735 | on_vsel = omap_vc_calc_vsel(voltdm, voltdm->vc_param->on); |
339 | onlp_vsel = voltdm->pmic->uv_to_vsel(voltdm->pmic->onlp_volt); | 736 | onlp_vsel = omap_vc_calc_vsel(voltdm, voltdm->vc_param->onlp); |
340 | ret_vsel = voltdm->pmic->uv_to_vsel(voltdm->pmic->ret_volt); | 737 | ret_vsel = omap_vc_calc_vsel(voltdm, voltdm->vc_param->ret); |
341 | off_vsel = voltdm->pmic->uv_to_vsel(voltdm->pmic->off_volt); | 738 | off_vsel = omap_vc_calc_vsel(voltdm, voltdm->vc_param->off); |
739 | |||
342 | val = ((on_vsel << vc->common->cmd_on_shift) | | 740 | val = ((on_vsel << vc->common->cmd_on_shift) | |
343 | (onlp_vsel << vc->common->cmd_onlp_shift) | | 741 | (onlp_vsel << vc->common->cmd_onlp_shift) | |
344 | (ret_vsel << vc->common->cmd_ret_shift) | | 742 | (ret_vsel << vc->common->cmd_ret_shift) | |
@@ -349,11 +747,6 @@ void __init omap_vc_init_channel(struct voltagedomain *voltdm) | |||
349 | /* Channel configuration */ | 747 | /* Channel configuration */ |
350 | omap_vc_config_channel(voltdm); | 748 | omap_vc_config_channel(voltdm); |
351 | 749 | ||
352 | /* Configure the setup times */ | ||
353 | voltdm->rmw(voltdm->vfsm->voltsetup_mask, | ||
354 | vc->setup_time << __ffs(voltdm->vfsm->voltsetup_mask), | ||
355 | voltdm->vfsm->voltsetup_reg); | ||
356 | |||
357 | omap_vc_i2c_init(voltdm); | 750 | omap_vc_i2c_init(voltdm); |
358 | 751 | ||
359 | if (cpu_is_omap34xx()) | 752 | if (cpu_is_omap34xx()) |
diff --git a/arch/arm/mach-omap2/vc.h b/arch/arm/mach-omap2/vc.h index 478bf6b432c4..91c8d75bf2ea 100644 --- a/arch/arm/mach-omap2/vc.h +++ b/arch/arm/mach-omap2/vc.h | |||
@@ -86,7 +86,6 @@ struct omap_vc_channel { | |||
86 | u16 i2c_slave_addr; | 86 | u16 i2c_slave_addr; |
87 | u16 volt_reg_addr; | 87 | u16 volt_reg_addr; |
88 | u16 cmd_reg_addr; | 88 | u16 cmd_reg_addr; |
89 | u16 setup_time; | ||
90 | u8 cfg_channel; | 89 | u8 cfg_channel; |
91 | bool i2c_high_speed; | 90 | bool i2c_high_speed; |
92 | 91 | ||
@@ -111,6 +110,13 @@ extern struct omap_vc_channel omap4_vc_mpu; | |||
111 | extern struct omap_vc_channel omap4_vc_iva; | 110 | extern struct omap_vc_channel omap4_vc_iva; |
112 | extern struct omap_vc_channel omap4_vc_core; | 111 | extern struct omap_vc_channel omap4_vc_core; |
113 | 112 | ||
113 | extern struct omap_vc_param omap3_mpu_vc_data; | ||
114 | extern struct omap_vc_param omap3_core_vc_data; | ||
115 | |||
116 | extern struct omap_vc_param omap4_mpu_vc_data; | ||
117 | extern struct omap_vc_param omap4_iva_vc_data; | ||
118 | extern struct omap_vc_param omap4_core_vc_data; | ||
119 | |||
114 | void omap_vc_init_channel(struct voltagedomain *voltdm); | 120 | void omap_vc_init_channel(struct voltagedomain *voltdm); |
115 | int omap_vc_pre_scale(struct voltagedomain *voltdm, | 121 | int omap_vc_pre_scale(struct voltagedomain *voltdm, |
116 | unsigned long target_volt, | 122 | unsigned long target_volt, |
diff --git a/arch/arm/mach-omap2/vc3xxx_data.c b/arch/arm/mach-omap2/vc3xxx_data.c index 5d8eaf31569c..75bc4aa22b3a 100644 --- a/arch/arm/mach-omap2/vc3xxx_data.c +++ b/arch/arm/mach-omap2/vc3xxx_data.c | |||
@@ -71,3 +71,25 @@ struct omap_vc_channel omap3_vc_core = { | |||
71 | .smps_cmdra_mask = OMAP3430_CMDRA1_MASK, | 71 | .smps_cmdra_mask = OMAP3430_CMDRA1_MASK, |
72 | .cfg_channel_sa_shift = OMAP3430_PRM_VC_SMPS_SA_SA1_SHIFT, | 72 | .cfg_channel_sa_shift = OMAP3430_PRM_VC_SMPS_SA_SA1_SHIFT, |
73 | }; | 73 | }; |
74 | |||
75 | /* | ||
76 | * Voltage levels for different operating modes: on, sleep, retention and off | ||
77 | */ | ||
78 | #define OMAP3_ON_VOLTAGE_UV 1200000 | ||
79 | #define OMAP3_ONLP_VOLTAGE_UV 1000000 | ||
80 | #define OMAP3_RET_VOLTAGE_UV 975000 | ||
81 | #define OMAP3_OFF_VOLTAGE_UV 600000 | ||
82 | |||
83 | struct omap_vc_param omap3_mpu_vc_data = { | ||
84 | .on = OMAP3_ON_VOLTAGE_UV, | ||
85 | .onlp = OMAP3_ONLP_VOLTAGE_UV, | ||
86 | .ret = OMAP3_RET_VOLTAGE_UV, | ||
87 | .off = OMAP3_OFF_VOLTAGE_UV, | ||
88 | }; | ||
89 | |||
90 | struct omap_vc_param omap3_core_vc_data = { | ||
91 | .on = OMAP3_ON_VOLTAGE_UV, | ||
92 | .onlp = OMAP3_ONLP_VOLTAGE_UV, | ||
93 | .ret = OMAP3_RET_VOLTAGE_UV, | ||
94 | .off = OMAP3_OFF_VOLTAGE_UV, | ||
95 | }; | ||
diff --git a/arch/arm/mach-omap2/vc44xx_data.c b/arch/arm/mach-omap2/vc44xx_data.c index d70b930f2739..085e5d6a04fd 100644 --- a/arch/arm/mach-omap2/vc44xx_data.c +++ b/arch/arm/mach-omap2/vc44xx_data.c | |||
@@ -87,3 +87,31 @@ struct omap_vc_channel omap4_vc_core = { | |||
87 | .cfg_channel_sa_shift = OMAP4430_SA_VDD_CORE_L_SHIFT, | 87 | .cfg_channel_sa_shift = OMAP4430_SA_VDD_CORE_L_SHIFT, |
88 | }; | 88 | }; |
89 | 89 | ||
90 | /* | ||
91 | * Voltage levels for different operating modes: on, sleep, retention and off | ||
92 | */ | ||
93 | #define OMAP4_ON_VOLTAGE_UV 1375000 | ||
94 | #define OMAP4_ONLP_VOLTAGE_UV 1375000 | ||
95 | #define OMAP4_RET_VOLTAGE_UV 837500 | ||
96 | #define OMAP4_OFF_VOLTAGE_UV 0 | ||
97 | |||
98 | struct omap_vc_param omap4_mpu_vc_data = { | ||
99 | .on = OMAP4_ON_VOLTAGE_UV, | ||
100 | .onlp = OMAP4_ONLP_VOLTAGE_UV, | ||
101 | .ret = OMAP4_RET_VOLTAGE_UV, | ||
102 | .off = OMAP4_OFF_VOLTAGE_UV, | ||
103 | }; | ||
104 | |||
105 | struct omap_vc_param omap4_iva_vc_data = { | ||
106 | .on = OMAP4_ON_VOLTAGE_UV, | ||
107 | .onlp = OMAP4_ONLP_VOLTAGE_UV, | ||
108 | .ret = OMAP4_RET_VOLTAGE_UV, | ||
109 | .off = OMAP4_OFF_VOLTAGE_UV, | ||
110 | }; | ||
111 | |||
112 | struct omap_vc_param omap4_core_vc_data = { | ||
113 | .on = OMAP4_ON_VOLTAGE_UV, | ||
114 | .onlp = OMAP4_ONLP_VOLTAGE_UV, | ||
115 | .ret = OMAP4_RET_VOLTAGE_UV, | ||
116 | .off = OMAP4_OFF_VOLTAGE_UV, | ||
117 | }; | ||
diff --git a/arch/arm/mach-omap2/voltage.h b/arch/arm/mach-omap2/voltage.h index 7283b7ed7de8..a0ce4f10ff13 100644 --- a/arch/arm/mach-omap2/voltage.h +++ b/arch/arm/mach-omap2/voltage.h | |||
@@ -40,12 +40,14 @@ struct powerdomain; | |||
40 | * data | 40 | * data |
41 | * @voltsetup_mask: SETUP_TIME* bitmask in the PRM_VOLTSETUP* register | 41 | * @voltsetup_mask: SETUP_TIME* bitmask in the PRM_VOLTSETUP* register |
42 | * @voltsetup_reg: register offset of PRM_VOLTSETUP from PRM base | 42 | * @voltsetup_reg: register offset of PRM_VOLTSETUP from PRM base |
43 | * @voltsetup_off_reg: register offset of PRM_VOLTSETUP_OFF from PRM base | ||
43 | * | 44 | * |
44 | * XXX What about VOLTOFFSET/VOLTCTRL? | 45 | * XXX What about VOLTOFFSET/VOLTCTRL? |
45 | */ | 46 | */ |
46 | struct omap_vfsm_instance { | 47 | struct omap_vfsm_instance { |
47 | u32 voltsetup_mask; | 48 | u32 voltsetup_mask; |
48 | u8 voltsetup_reg; | 49 | u8 voltsetup_reg; |
50 | u8 voltsetup_off_reg; | ||
49 | }; | 51 | }; |
50 | 52 | ||
51 | /** | 53 | /** |
@@ -74,6 +76,8 @@ struct voltagedomain { | |||
74 | const struct omap_vfsm_instance *vfsm; | 76 | const struct omap_vfsm_instance *vfsm; |
75 | struct omap_vp_instance *vp; | 77 | struct omap_vp_instance *vp; |
76 | struct omap_voltdm_pmic *pmic; | 78 | struct omap_voltdm_pmic *pmic; |
79 | struct omap_vp_param *vp_param; | ||
80 | struct omap_vc_param *vc_param; | ||
77 | 81 | ||
78 | /* VC/VP register access functions: SoC specific */ | 82 | /* VC/VP register access functions: SoC specific */ |
79 | u32 (*read) (u8 offset); | 83 | u32 (*read) (u8 offset); |
@@ -92,6 +96,24 @@ struct voltagedomain { | |||
92 | struct omap_volt_data *volt_data; | 96 | struct omap_volt_data *volt_data; |
93 | }; | 97 | }; |
94 | 98 | ||
99 | /* Min and max voltages from OMAP perspective */ | ||
100 | #define OMAP3430_VP1_VLIMITTO_VDDMIN 850000 | ||
101 | #define OMAP3430_VP1_VLIMITTO_VDDMAX 1425000 | ||
102 | #define OMAP3430_VP2_VLIMITTO_VDDMIN 900000 | ||
103 | #define OMAP3430_VP2_VLIMITTO_VDDMAX 1150000 | ||
104 | |||
105 | #define OMAP3630_VP1_VLIMITTO_VDDMIN 900000 | ||
106 | #define OMAP3630_VP1_VLIMITTO_VDDMAX 1350000 | ||
107 | #define OMAP3630_VP2_VLIMITTO_VDDMIN 900000 | ||
108 | #define OMAP3630_VP2_VLIMITTO_VDDMAX 1200000 | ||
109 | |||
110 | #define OMAP4_VP_MPU_VLIMITTO_VDDMIN 830000 | ||
111 | #define OMAP4_VP_MPU_VLIMITTO_VDDMAX 1410000 | ||
112 | #define OMAP4_VP_IVA_VLIMITTO_VDDMIN 830000 | ||
113 | #define OMAP4_VP_IVA_VLIMITTO_VDDMAX 1260000 | ||
114 | #define OMAP4_VP_CORE_VLIMITTO_VDDMIN 830000 | ||
115 | #define OMAP4_VP_CORE_VLIMITTO_VDDMAX 1200000 | ||
116 | |||
95 | /** | 117 | /** |
96 | * struct omap_voltdm_pmic - PMIC specific data required by voltage driver. | 118 | * struct omap_voltdm_pmic - PMIC specific data required by voltage driver. |
97 | * @slew_rate: PMIC slew rate (in uv/us) | 119 | * @slew_rate: PMIC slew rate (in uv/us) |
@@ -107,26 +129,34 @@ struct voltagedomain { | |||
107 | struct omap_voltdm_pmic { | 129 | struct omap_voltdm_pmic { |
108 | int slew_rate; | 130 | int slew_rate; |
109 | int step_size; | 131 | int step_size; |
110 | u32 on_volt; | ||
111 | u32 onlp_volt; | ||
112 | u32 ret_volt; | ||
113 | u32 off_volt; | ||
114 | u16 volt_setup_time; | ||
115 | u16 i2c_slave_addr; | 132 | u16 i2c_slave_addr; |
116 | u16 volt_reg_addr; | 133 | u16 volt_reg_addr; |
117 | u16 cmd_reg_addr; | 134 | u16 cmd_reg_addr; |
118 | u8 vp_erroroffset; | 135 | u8 vp_erroroffset; |
119 | u8 vp_vstepmin; | 136 | u8 vp_vstepmin; |
120 | u8 vp_vstepmax; | 137 | u8 vp_vstepmax; |
121 | u8 vp_vddmin; | 138 | u32 vddmin; |
122 | u8 vp_vddmax; | 139 | u32 vddmax; |
123 | u8 vp_timeout_us; | 140 | u8 vp_timeout_us; |
124 | bool i2c_high_speed; | 141 | bool i2c_high_speed; |
142 | u32 i2c_pad_load; | ||
125 | u8 i2c_mcode; | 143 | u8 i2c_mcode; |
126 | unsigned long (*vsel_to_uv) (const u8 vsel); | 144 | unsigned long (*vsel_to_uv) (const u8 vsel); |
127 | u8 (*uv_to_vsel) (unsigned long uV); | 145 | u8 (*uv_to_vsel) (unsigned long uV); |
128 | }; | 146 | }; |
129 | 147 | ||
148 | struct omap_vp_param { | ||
149 | u32 vddmax; | ||
150 | u32 vddmin; | ||
151 | }; | ||
152 | |||
153 | struct omap_vc_param { | ||
154 | u32 on; | ||
155 | u32 onlp; | ||
156 | u32 ret; | ||
157 | u32 off; | ||
158 | }; | ||
159 | |||
130 | void omap_voltage_get_volttable(struct voltagedomain *voltdm, | 160 | void omap_voltage_get_volttable(struct voltagedomain *voltdm, |
131 | struct omap_volt_data **volt_data); | 161 | struct omap_volt_data **volt_data); |
132 | struct omap_volt_data *omap_voltage_get_voltdata(struct voltagedomain *voltdm, | 162 | struct omap_volt_data *omap_voltage_get_voltdata(struct voltagedomain *voltdm, |
diff --git a/arch/arm/mach-omap2/voltagedomains3xxx_data.c b/arch/arm/mach-omap2/voltagedomains3xxx_data.c index 63afbfed3cbc..261bb7cb4e60 100644 --- a/arch/arm/mach-omap2/voltagedomains3xxx_data.c +++ b/arch/arm/mach-omap2/voltagedomains3xxx_data.c | |||
@@ -117,6 +117,11 @@ void __init omap3xxx_voltagedomains_init(void) | |||
117 | } | 117 | } |
118 | #endif | 118 | #endif |
119 | 119 | ||
120 | omap3_voltdm_mpu.vp_param = &omap3_mpu_vp_data; | ||
121 | omap3_voltdm_core.vp_param = &omap3_core_vp_data; | ||
122 | omap3_voltdm_mpu.vc_param = &omap3_mpu_vc_data; | ||
123 | omap3_voltdm_core.vc_param = &omap3_core_vc_data; | ||
124 | |||
120 | if (soc_is_am35xx()) | 125 | if (soc_is_am35xx()) |
121 | voltdms = voltagedomains_am35xx; | 126 | voltdms = voltagedomains_am35xx; |
122 | else | 127 | else |
diff --git a/arch/arm/mach-omap2/voltagedomains44xx_data.c b/arch/arm/mach-omap2/voltagedomains44xx_data.c index c3115f6853d4..b893c8e6f88f 100644 --- a/arch/arm/mach-omap2/voltagedomains44xx_data.c +++ b/arch/arm/mach-omap2/voltagedomains44xx_data.c | |||
@@ -34,14 +34,17 @@ | |||
34 | 34 | ||
35 | static const struct omap_vfsm_instance omap4_vdd_mpu_vfsm = { | 35 | static const struct omap_vfsm_instance omap4_vdd_mpu_vfsm = { |
36 | .voltsetup_reg = OMAP4_PRM_VOLTSETUP_MPU_RET_SLEEP_OFFSET, | 36 | .voltsetup_reg = OMAP4_PRM_VOLTSETUP_MPU_RET_SLEEP_OFFSET, |
37 | .voltsetup_off_reg = OMAP4_PRM_VOLTSETUP_MPU_OFF_OFFSET, | ||
37 | }; | 38 | }; |
38 | 39 | ||
39 | static const struct omap_vfsm_instance omap4_vdd_iva_vfsm = { | 40 | static const struct omap_vfsm_instance omap4_vdd_iva_vfsm = { |
40 | .voltsetup_reg = OMAP4_PRM_VOLTSETUP_IVA_RET_SLEEP_OFFSET, | 41 | .voltsetup_reg = OMAP4_PRM_VOLTSETUP_IVA_RET_SLEEP_OFFSET, |
42 | .voltsetup_off_reg = OMAP4_PRM_VOLTSETUP_IVA_OFF_OFFSET, | ||
41 | }; | 43 | }; |
42 | 44 | ||
43 | static const struct omap_vfsm_instance omap4_vdd_core_vfsm = { | 45 | static const struct omap_vfsm_instance omap4_vdd_core_vfsm = { |
44 | .voltsetup_reg = OMAP4_PRM_VOLTSETUP_CORE_RET_SLEEP_OFFSET, | 46 | .voltsetup_reg = OMAP4_PRM_VOLTSETUP_CORE_RET_SLEEP_OFFSET, |
47 | .voltsetup_off_reg = OMAP4_PRM_VOLTSETUP_CORE_OFF_OFFSET, | ||
45 | }; | 48 | }; |
46 | 49 | ||
47 | static struct voltagedomain omap4_voltdm_mpu = { | 50 | static struct voltagedomain omap4_voltdm_mpu = { |
@@ -101,11 +104,25 @@ void __init omap44xx_voltagedomains_init(void) | |||
101 | * for the currently-running IC | 104 | * for the currently-running IC |
102 | */ | 105 | */ |
103 | #ifdef CONFIG_PM_OPP | 106 | #ifdef CONFIG_PM_OPP |
104 | omap4_voltdm_mpu.volt_data = omap44xx_vdd_mpu_volt_data; | 107 | if (cpu_is_omap443x()) { |
105 | omap4_voltdm_iva.volt_data = omap44xx_vdd_iva_volt_data; | 108 | omap4_voltdm_mpu.volt_data = omap443x_vdd_mpu_volt_data; |
106 | omap4_voltdm_core.volt_data = omap44xx_vdd_core_volt_data; | 109 | omap4_voltdm_iva.volt_data = omap443x_vdd_iva_volt_data; |
110 | omap4_voltdm_core.volt_data = omap443x_vdd_core_volt_data; | ||
111 | } else if (cpu_is_omap446x()) { | ||
112 | omap4_voltdm_mpu.volt_data = omap446x_vdd_mpu_volt_data; | ||
113 | omap4_voltdm_iva.volt_data = omap446x_vdd_iva_volt_data; | ||
114 | omap4_voltdm_core.volt_data = omap446x_vdd_core_volt_data; | ||
115 | } | ||
107 | #endif | 116 | #endif |
108 | 117 | ||
118 | omap4_voltdm_mpu.vp_param = &omap4_mpu_vp_data; | ||
119 | omap4_voltdm_iva.vp_param = &omap4_iva_vp_data; | ||
120 | omap4_voltdm_core.vp_param = &omap4_core_vp_data; | ||
121 | |||
122 | omap4_voltdm_mpu.vc_param = &omap4_mpu_vc_data; | ||
123 | omap4_voltdm_iva.vc_param = &omap4_iva_vc_data; | ||
124 | omap4_voltdm_core.vc_param = &omap4_core_vc_data; | ||
125 | |||
109 | for (i = 0; voltdm = voltagedomains_omap4[i], voltdm; i++) | 126 | for (i = 0; voltdm = voltagedomains_omap4[i], voltdm; i++) |
110 | voltdm->sys_clk.name = sys_clk_name; | 127 | voltdm->sys_clk.name = sys_clk_name; |
111 | 128 | ||
diff --git a/arch/arm/mach-omap2/vp.c b/arch/arm/mach-omap2/vp.c index 6e9fe8574315..a3c30655aa30 100644 --- a/arch/arm/mach-omap2/vp.c +++ b/arch/arm/mach-omap2/vp.c | |||
@@ -58,8 +58,10 @@ void __init omap_vp_init(struct voltagedomain *voltdm) | |||
58 | sys_clk_rate = voltdm->sys_clk.rate / 1000; | 58 | sys_clk_rate = voltdm->sys_clk.rate / 1000; |
59 | 59 | ||
60 | timeout = (sys_clk_rate * voltdm->pmic->vp_timeout_us) / 1000; | 60 | timeout = (sys_clk_rate * voltdm->pmic->vp_timeout_us) / 1000; |
61 | vddmin = voltdm->pmic->vp_vddmin; | 61 | vddmin = max(voltdm->vp_param->vddmin, voltdm->pmic->vddmin); |
62 | vddmax = voltdm->pmic->vp_vddmax; | 62 | vddmax = min(voltdm->vp_param->vddmax, voltdm->pmic->vddmax); |
63 | vddmin = voltdm->pmic->uv_to_vsel(vddmin); | ||
64 | vddmax = voltdm->pmic->uv_to_vsel(vddmax); | ||
63 | 65 | ||
64 | waittime = DIV_ROUND_UP(voltdm->pmic->step_size * sys_clk_rate, | 66 | waittime = DIV_ROUND_UP(voltdm->pmic->step_size * sys_clk_rate, |
65 | 1000 * voltdm->pmic->slew_rate); | 67 | 1000 * voltdm->pmic->slew_rate); |
diff --git a/arch/arm/mach-omap2/vp.h b/arch/arm/mach-omap2/vp.h index 7c155d248aa3..0fdf7080e4a6 100644 --- a/arch/arm/mach-omap2/vp.h +++ b/arch/arm/mach-omap2/vp.h | |||
@@ -117,6 +117,13 @@ extern struct omap_vp_instance omap4_vp_mpu; | |||
117 | extern struct omap_vp_instance omap4_vp_iva; | 117 | extern struct omap_vp_instance omap4_vp_iva; |
118 | extern struct omap_vp_instance omap4_vp_core; | 118 | extern struct omap_vp_instance omap4_vp_core; |
119 | 119 | ||
120 | extern struct omap_vp_param omap3_mpu_vp_data; | ||
121 | extern struct omap_vp_param omap3_core_vp_data; | ||
122 | |||
123 | extern struct omap_vp_param omap4_mpu_vp_data; | ||
124 | extern struct omap_vp_param omap4_iva_vp_data; | ||
125 | extern struct omap_vp_param omap4_core_vp_data; | ||
126 | |||
120 | void omap_vp_init(struct voltagedomain *voltdm); | 127 | void omap_vp_init(struct voltagedomain *voltdm); |
121 | void omap_vp_enable(struct voltagedomain *voltdm); | 128 | void omap_vp_enable(struct voltagedomain *voltdm); |
122 | void omap_vp_disable(struct voltagedomain *voltdm); | 129 | void omap_vp_disable(struct voltagedomain *voltdm); |
diff --git a/arch/arm/mach-omap2/vp3xxx_data.c b/arch/arm/mach-omap2/vp3xxx_data.c index bd89f80089f5..1914e026245e 100644 --- a/arch/arm/mach-omap2/vp3xxx_data.c +++ b/arch/arm/mach-omap2/vp3xxx_data.c | |||
@@ -77,3 +77,13 @@ struct omap_vp_instance omap3_vp_core = { | |||
77 | .vstatus = OMAP3_PRM_VP2_STATUS_OFFSET, | 77 | .vstatus = OMAP3_PRM_VP2_STATUS_OFFSET, |
78 | .voltage = OMAP3_PRM_VP2_VOLTAGE_OFFSET, | 78 | .voltage = OMAP3_PRM_VP2_VOLTAGE_OFFSET, |
79 | }; | 79 | }; |
80 | |||
81 | struct omap_vp_param omap3_mpu_vp_data = { | ||
82 | .vddmin = OMAP3430_VP1_VLIMITTO_VDDMIN, | ||
83 | .vddmax = OMAP3430_VP1_VLIMITTO_VDDMAX, | ||
84 | }; | ||
85 | |||
86 | struct omap_vp_param omap3_core_vp_data = { | ||
87 | .vddmin = OMAP3430_VP2_VLIMITTO_VDDMIN, | ||
88 | .vddmax = OMAP3430_VP2_VLIMITTO_VDDMAX, | ||
89 | }; | ||
diff --git a/arch/arm/mach-omap2/vp44xx_data.c b/arch/arm/mach-omap2/vp44xx_data.c index 8c031d16879e..e62f6b018beb 100644 --- a/arch/arm/mach-omap2/vp44xx_data.c +++ b/arch/arm/mach-omap2/vp44xx_data.c | |||
@@ -87,3 +87,18 @@ struct omap_vp_instance omap4_vp_core = { | |||
87 | .vstatus = OMAP4_PRM_VP_CORE_STATUS_OFFSET, | 87 | .vstatus = OMAP4_PRM_VP_CORE_STATUS_OFFSET, |
88 | .voltage = OMAP4_PRM_VP_CORE_VOLTAGE_OFFSET, | 88 | .voltage = OMAP4_PRM_VP_CORE_VOLTAGE_OFFSET, |
89 | }; | 89 | }; |
90 | |||
91 | struct omap_vp_param omap4_mpu_vp_data = { | ||
92 | .vddmin = OMAP4_VP_MPU_VLIMITTO_VDDMIN, | ||
93 | .vddmax = OMAP4_VP_MPU_VLIMITTO_VDDMAX, | ||
94 | }; | ||
95 | |||
96 | struct omap_vp_param omap4_iva_vp_data = { | ||
97 | .vddmin = OMAP4_VP_IVA_VLIMITTO_VDDMIN, | ||
98 | .vddmax = OMAP4_VP_IVA_VLIMITTO_VDDMAX, | ||
99 | }; | ||
100 | |||
101 | struct omap_vp_param omap4_core_vp_data = { | ||
102 | .vddmin = OMAP4_VP_CORE_VLIMITTO_VDDMIN, | ||
103 | .vddmax = OMAP4_VP_CORE_VLIMITTO_VDDMAX, | ||
104 | }; | ||