mirror of https://gitee.com/openkylin/linux.git
OMAP voltage layer updates towards supporting auto-retention/auto-off
-----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.11 (GNU/Linux) iQIcBAABAgAGBQJQmaAOAAoJEFk3GJrT+8ZlkuEP/0Kb0u/yz54BzH3WMSdtklMS Ylmo/gX9I5wUT4RpdBYQCU8L+1DKie8c7ZRJUKJoVBMyGtFkRfry9XBEyU8QamGH 8hTa1itQdal3V6o9q9ilc5W9HckBxKCY/K23VljgoJO/0RzjASfJ3RO6bf8jQKgs RnuRIO+uOev1QDbFSurVcHIPGLsz3m/WserXAxRajY4DJcKOyfJOk11z0hlADWaD 8SRRqeoV5oGzBXwd98I6QddngOxaE/Nr4jGvW9KwJG0fzDsV3hjd5RbFFVoU0ISo Dw0JhFsz7hQ36dXOV1z71BhcxYPNv2PFILlvpkn471DNlG524sc2Eh6to1sDVlDY cSR7hDylvf4Do2xyNUk/YgZwf6l5m/Bg/uJ5vrltcHO4uUhM5JFSeNfP9UBC3ups r6vJc73XuMCx58G5kuSprVHe4kIWJ8WT8zLjZ7YBk38EB9iYWF9zLVijyKY9fsoT qUlrwXsh49HML8k07mRWLF/w2LgomFA28prLzay/CnCv8LfSwA/SpWI42QKFy+Y2 cme57OkXDsMbAHDt6X1j5QH2HJ4aMhalfHiPbync5UobJx3nYvs1DeqLuqcqVbbD 5cwaTmFc4KcFqMhDeUujLmNofGOauvVm5R13A1cZrTF/U85SYxq4KuIX7FEC2n02 W0v+kAvCbY3nX0+0SMdj =mE28 -----END PGP SIGNATURE----- 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
This commit is contained in:
commit
46bf4a5622
|
@ -201,6 +201,7 @@
|
|||
#define OMAP44XX_CONTROL_FUSE_MPU_OPPNITRO 0x249
|
||||
#define OMAP44XX_CONTROL_FUSE_CORE_OPP50 0x254
|
||||
#define OMAP44XX_CONTROL_FUSE_CORE_OPP100 0x257
|
||||
#define OMAP44XX_CONTROL_FUSE_CORE_OPP100OV 0x25A
|
||||
|
||||
/* AM35XX only CONTROL_GENERAL register offsets */
|
||||
#define AM35XX_CONTROL_MSUSPENDMUX_6 (OMAP2_CONTROL_GENERAL + 0x0038)
|
||||
|
|
|
@ -89,8 +89,11 @@ extern struct omap_volt_data omap34xx_vddcore_volt_data[];
|
|||
extern struct omap_volt_data omap36xx_vddmpu_volt_data[];
|
||||
extern struct omap_volt_data omap36xx_vddcore_volt_data[];
|
||||
|
||||
extern struct omap_volt_data omap44xx_vdd_mpu_volt_data[];
|
||||
extern struct omap_volt_data omap44xx_vdd_iva_volt_data[];
|
||||
extern struct omap_volt_data omap44xx_vdd_core_volt_data[];
|
||||
extern struct omap_volt_data omap443x_vdd_mpu_volt_data[];
|
||||
extern struct omap_volt_data omap443x_vdd_iva_volt_data[];
|
||||
extern struct omap_volt_data omap443x_vdd_core_volt_data[];
|
||||
extern struct omap_volt_data omap446x_vdd_mpu_volt_data[];
|
||||
extern struct omap_volt_data omap446x_vdd_iva_volt_data[];
|
||||
extern struct omap_volt_data omap446x_vdd_core_volt_data[];
|
||||
|
||||
#endif /* __ARCH_ARM_MACH_OMAP2_OMAP_OPP_DATA_H */
|
||||
|
|
|
@ -30,16 +30,6 @@
|
|||
#define OMAP3_VP_VSTEPMAX_VSTEPMAX 0x04
|
||||
#define OMAP3_VP_VLIMITTO_TIMEOUT_US 200
|
||||
|
||||
#define OMAP3430_VP1_VLIMITTO_VDDMIN 0x14
|
||||
#define OMAP3430_VP1_VLIMITTO_VDDMAX 0x42
|
||||
#define OMAP3430_VP2_VLIMITTO_VDDMIN 0x18
|
||||
#define OMAP3430_VP2_VLIMITTO_VDDMAX 0x2c
|
||||
|
||||
#define OMAP3630_VP1_VLIMITTO_VDDMIN 0x18
|
||||
#define OMAP3630_VP1_VLIMITTO_VDDMAX 0x3c
|
||||
#define OMAP3630_VP2_VLIMITTO_VDDMIN 0x18
|
||||
#define OMAP3630_VP2_VLIMITTO_VDDMAX 0x30
|
||||
|
||||
#define OMAP4_SRI2C_SLAVE_ADDR 0x12
|
||||
#define OMAP4_VDD_MPU_SR_VOLT_REG 0x55
|
||||
#define OMAP4_VDD_MPU_SR_CMD_REG 0x56
|
||||
|
@ -53,13 +43,6 @@
|
|||
#define OMAP4_VP_VSTEPMAX_VSTEPMAX 0x04
|
||||
#define OMAP4_VP_VLIMITTO_TIMEOUT_US 200
|
||||
|
||||
#define OMAP4_VP_MPU_VLIMITTO_VDDMIN 0xA
|
||||
#define OMAP4_VP_MPU_VLIMITTO_VDDMAX 0x39
|
||||
#define OMAP4_VP_IVA_VLIMITTO_VDDMIN 0xA
|
||||
#define OMAP4_VP_IVA_VLIMITTO_VDDMAX 0x2D
|
||||
#define OMAP4_VP_CORE_VLIMITTO_VDDMIN 0xA
|
||||
#define OMAP4_VP_CORE_VLIMITTO_VDDMAX 0x28
|
||||
|
||||
static bool is_offset_valid;
|
||||
static u8 smps_offset;
|
||||
/*
|
||||
|
@ -158,16 +141,11 @@ static u8 twl6030_uv_to_vsel(unsigned long uv)
|
|||
static struct omap_voltdm_pmic omap3_mpu_pmic = {
|
||||
.slew_rate = 4000,
|
||||
.step_size = 12500,
|
||||
.on_volt = 1200000,
|
||||
.onlp_volt = 1000000,
|
||||
.ret_volt = 975000,
|
||||
.off_volt = 600000,
|
||||
.volt_setup_time = 0xfff,
|
||||
.vp_erroroffset = OMAP3_VP_CONFIG_ERROROFFSET,
|
||||
.vp_vstepmin = OMAP3_VP_VSTEPMIN_VSTEPMIN,
|
||||
.vp_vstepmax = OMAP3_VP_VSTEPMAX_VSTEPMAX,
|
||||
.vp_vddmin = OMAP3430_VP1_VLIMITTO_VDDMIN,
|
||||
.vp_vddmax = OMAP3430_VP1_VLIMITTO_VDDMAX,
|
||||
.vddmin = 600000,
|
||||
.vddmax = 1450000,
|
||||
.vp_timeout_us = OMAP3_VP_VLIMITTO_TIMEOUT_US,
|
||||
.i2c_slave_addr = OMAP3_SRI2C_SLAVE_ADDR,
|
||||
.volt_reg_addr = OMAP3_VDD_MPU_SR_CONTROL_REG,
|
||||
|
@ -179,16 +157,11 @@ static struct omap_voltdm_pmic omap3_mpu_pmic = {
|
|||
static struct omap_voltdm_pmic omap3_core_pmic = {
|
||||
.slew_rate = 4000,
|
||||
.step_size = 12500,
|
||||
.on_volt = 1200000,
|
||||
.onlp_volt = 1000000,
|
||||
.ret_volt = 975000,
|
||||
.off_volt = 600000,
|
||||
.volt_setup_time = 0xfff,
|
||||
.vp_erroroffset = OMAP3_VP_CONFIG_ERROROFFSET,
|
||||
.vp_vstepmin = OMAP3_VP_VSTEPMIN_VSTEPMIN,
|
||||
.vp_vstepmax = OMAP3_VP_VSTEPMAX_VSTEPMAX,
|
||||
.vp_vddmin = OMAP3430_VP2_VLIMITTO_VDDMIN,
|
||||
.vp_vddmax = OMAP3430_VP2_VLIMITTO_VDDMAX,
|
||||
.vddmin = 600000,
|
||||
.vddmax = 1450000,
|
||||
.vp_timeout_us = OMAP3_VP_VLIMITTO_TIMEOUT_US,
|
||||
.i2c_slave_addr = OMAP3_SRI2C_SLAVE_ADDR,
|
||||
.volt_reg_addr = OMAP3_VDD_CORE_SR_CONTROL_REG,
|
||||
|
@ -200,21 +173,17 @@ static struct omap_voltdm_pmic omap3_core_pmic = {
|
|||
static struct omap_voltdm_pmic omap4_mpu_pmic = {
|
||||
.slew_rate = 4000,
|
||||
.step_size = 12660,
|
||||
.on_volt = 1375000,
|
||||
.onlp_volt = 1375000,
|
||||
.ret_volt = 830000,
|
||||
.off_volt = 0,
|
||||
.volt_setup_time = 0,
|
||||
.vp_erroroffset = OMAP4_VP_CONFIG_ERROROFFSET,
|
||||
.vp_vstepmin = OMAP4_VP_VSTEPMIN_VSTEPMIN,
|
||||
.vp_vstepmax = OMAP4_VP_VSTEPMAX_VSTEPMAX,
|
||||
.vp_vddmin = OMAP4_VP_MPU_VLIMITTO_VDDMIN,
|
||||
.vp_vddmax = OMAP4_VP_MPU_VLIMITTO_VDDMAX,
|
||||
.vddmin = 0,
|
||||
.vddmax = 2100000,
|
||||
.vp_timeout_us = OMAP4_VP_VLIMITTO_TIMEOUT_US,
|
||||
.i2c_slave_addr = OMAP4_SRI2C_SLAVE_ADDR,
|
||||
.volt_reg_addr = OMAP4_VDD_MPU_SR_VOLT_REG,
|
||||
.cmd_reg_addr = OMAP4_VDD_MPU_SR_CMD_REG,
|
||||
.i2c_high_speed = true,
|
||||
.i2c_pad_load = 3,
|
||||
.vsel_to_uv = twl6030_vsel_to_uv,
|
||||
.uv_to_vsel = twl6030_uv_to_vsel,
|
||||
};
|
||||
|
@ -222,21 +191,17 @@ static struct omap_voltdm_pmic omap4_mpu_pmic = {
|
|||
static struct omap_voltdm_pmic omap4_iva_pmic = {
|
||||
.slew_rate = 4000,
|
||||
.step_size = 12660,
|
||||
.on_volt = 1188000,
|
||||
.onlp_volt = 1188000,
|
||||
.ret_volt = 830000,
|
||||
.off_volt = 0,
|
||||
.volt_setup_time = 0,
|
||||
.vp_erroroffset = OMAP4_VP_CONFIG_ERROROFFSET,
|
||||
.vp_vstepmin = OMAP4_VP_VSTEPMIN_VSTEPMIN,
|
||||
.vp_vstepmax = OMAP4_VP_VSTEPMAX_VSTEPMAX,
|
||||
.vp_vddmin = OMAP4_VP_IVA_VLIMITTO_VDDMIN,
|
||||
.vp_vddmax = OMAP4_VP_IVA_VLIMITTO_VDDMAX,
|
||||
.vddmin = 0,
|
||||
.vddmax = 2100000,
|
||||
.vp_timeout_us = OMAP4_VP_VLIMITTO_TIMEOUT_US,
|
||||
.i2c_slave_addr = OMAP4_SRI2C_SLAVE_ADDR,
|
||||
.volt_reg_addr = OMAP4_VDD_IVA_SR_VOLT_REG,
|
||||
.cmd_reg_addr = OMAP4_VDD_IVA_SR_CMD_REG,
|
||||
.i2c_high_speed = true,
|
||||
.i2c_pad_load = 3,
|
||||
.vsel_to_uv = twl6030_vsel_to_uv,
|
||||
.uv_to_vsel = twl6030_uv_to_vsel,
|
||||
};
|
||||
|
@ -244,20 +209,17 @@ static struct omap_voltdm_pmic omap4_iva_pmic = {
|
|||
static struct omap_voltdm_pmic omap4_core_pmic = {
|
||||
.slew_rate = 4000,
|
||||
.step_size = 12660,
|
||||
.on_volt = 1200000,
|
||||
.onlp_volt = 1200000,
|
||||
.ret_volt = 830000,
|
||||
.off_volt = 0,
|
||||
.volt_setup_time = 0,
|
||||
.vp_erroroffset = OMAP4_VP_CONFIG_ERROROFFSET,
|
||||
.vp_vstepmin = OMAP4_VP_VSTEPMIN_VSTEPMIN,
|
||||
.vp_vstepmax = OMAP4_VP_VSTEPMAX_VSTEPMAX,
|
||||
.vp_vddmin = OMAP4_VP_CORE_VLIMITTO_VDDMIN,
|
||||
.vp_vddmax = OMAP4_VP_CORE_VLIMITTO_VDDMAX,
|
||||
.vddmin = 0,
|
||||
.vddmax = 2100000,
|
||||
.vp_timeout_us = OMAP4_VP_VLIMITTO_TIMEOUT_US,
|
||||
.i2c_slave_addr = OMAP4_SRI2C_SLAVE_ADDR,
|
||||
.volt_reg_addr = OMAP4_VDD_CORE_SR_VOLT_REG,
|
||||
.cmd_reg_addr = OMAP4_VDD_CORE_SR_CMD_REG,
|
||||
.i2c_high_speed = true,
|
||||
.i2c_pad_load = 3,
|
||||
.vsel_to_uv = twl6030_vsel_to_uv,
|
||||
.uv_to_vsel = twl6030_uv_to_vsel,
|
||||
};
|
||||
|
@ -288,13 +250,6 @@ int __init omap3_twl_init(void)
|
|||
if (!cpu_is_omap34xx())
|
||||
return -ENODEV;
|
||||
|
||||
if (cpu_is_omap3630()) {
|
||||
omap3_mpu_pmic.vp_vddmin = OMAP3630_VP1_VLIMITTO_VDDMIN;
|
||||
omap3_mpu_pmic.vp_vddmax = OMAP3630_VP1_VLIMITTO_VDDMAX;
|
||||
omap3_core_pmic.vp_vddmin = OMAP3630_VP2_VLIMITTO_VDDMIN;
|
||||
omap3_core_pmic.vp_vddmax = OMAP3630_VP2_VLIMITTO_VDDMAX;
|
||||
}
|
||||
|
||||
/*
|
||||
* The smartreflex bit on twl4030 specifies if the setting of voltage
|
||||
* is done over the I2C_SR path. Since this setting is independent of
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/*
|
||||
* OMAP4 OPP table definitions.
|
||||
*
|
||||
* Copyright (C) 2010 Texas Instruments Incorporated - http://www.ti.com/
|
||||
* Copyright (C) 2010-2012 Texas Instruments Incorporated - http://www.ti.com/
|
||||
* Nishanth Menon
|
||||
* Kevin Hilman
|
||||
* Thara Gopinath
|
||||
|
@ -35,7 +35,7 @@
|
|||
#define OMAP4430_VDD_MPU_OPPTURBO_UV 1313000
|
||||
#define OMAP4430_VDD_MPU_OPPNITRO_UV 1375000
|
||||
|
||||
struct omap_volt_data omap44xx_vdd_mpu_volt_data[] = {
|
||||
struct omap_volt_data omap443x_vdd_mpu_volt_data[] = {
|
||||
VOLT_DATA_DEFINE(OMAP4430_VDD_MPU_OPP50_UV, OMAP44XX_CONTROL_FUSE_MPU_OPP50, 0xf4, 0x0c),
|
||||
VOLT_DATA_DEFINE(OMAP4430_VDD_MPU_OPP100_UV, OMAP44XX_CONTROL_FUSE_MPU_OPP100, 0xf9, 0x16),
|
||||
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[] = {
|
|||
#define OMAP4430_VDD_IVA_OPP100_UV 1188000
|
||||
#define OMAP4430_VDD_IVA_OPPTURBO_UV 1300000
|
||||
|
||||
struct omap_volt_data omap44xx_vdd_iva_volt_data[] = {
|
||||
struct omap_volt_data omap443x_vdd_iva_volt_data[] = {
|
||||
VOLT_DATA_DEFINE(OMAP4430_VDD_IVA_OPP50_UV, OMAP44XX_CONTROL_FUSE_IVA_OPP50, 0xf4, 0x0c),
|
||||
VOLT_DATA_DEFINE(OMAP4430_VDD_IVA_OPP100_UV, OMAP44XX_CONTROL_FUSE_IVA_OPP100, 0xf9, 0x16),
|
||||
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[] = {
|
|||
#define OMAP4430_VDD_CORE_OPP50_UV 1025000
|
||||
#define OMAP4430_VDD_CORE_OPP100_UV 1200000
|
||||
|
||||
struct omap_volt_data omap44xx_vdd_core_volt_data[] = {
|
||||
struct omap_volt_data omap443x_vdd_core_volt_data[] = {
|
||||
VOLT_DATA_DEFINE(OMAP4430_VDD_CORE_OPP50_UV, OMAP44XX_CONTROL_FUSE_CORE_OPP50, 0xf4, 0x0c),
|
||||
VOLT_DATA_DEFINE(OMAP4430_VDD_CORE_OPP100_UV, OMAP44XX_CONTROL_FUSE_CORE_OPP100, 0xf9, 0x16),
|
||||
VOLT_DATA_DEFINE(0, 0, 0, 0),
|
||||
};
|
||||
|
||||
|
||||
static struct omap_opp_def __initdata omap44xx_opp_def_list[] = {
|
||||
static struct omap_opp_def __initdata omap443x_opp_def_list[] = {
|
||||
/* MPU OPP1 - OPP50 */
|
||||
OPP_INITIALIZER("mpu", true, 300000000, OMAP4430_VDD_MPU_OPP50_UV),
|
||||
/* MPU OPP2 - OPP100 */
|
||||
|
@ -86,6 +86,82 @@ static struct omap_opp_def __initdata omap44xx_opp_def_list[] = {
|
|||
/* TODO: add DSP, aess, fdif, gpu */
|
||||
};
|
||||
|
||||
#define OMAP4460_VDD_MPU_OPP50_UV 1025000
|
||||
#define OMAP4460_VDD_MPU_OPP100_UV 1200000
|
||||
#define OMAP4460_VDD_MPU_OPPTURBO_UV 1313000
|
||||
#define OMAP4460_VDD_MPU_OPPNITRO_UV 1375000
|
||||
|
||||
struct omap_volt_data omap446x_vdd_mpu_volt_data[] = {
|
||||
VOLT_DATA_DEFINE(OMAP4460_VDD_MPU_OPP50_UV, OMAP44XX_CONTROL_FUSE_MPU_OPP50, 0xf4, 0x0c),
|
||||
VOLT_DATA_DEFINE(OMAP4460_VDD_MPU_OPP100_UV, OMAP44XX_CONTROL_FUSE_MPU_OPP100, 0xf9, 0x16),
|
||||
VOLT_DATA_DEFINE(OMAP4460_VDD_MPU_OPPTURBO_UV, OMAP44XX_CONTROL_FUSE_MPU_OPPTURBO, 0xfa, 0x23),
|
||||
VOLT_DATA_DEFINE(OMAP4460_VDD_MPU_OPPNITRO_UV, OMAP44XX_CONTROL_FUSE_MPU_OPPNITRO, 0xfa, 0x27),
|
||||
VOLT_DATA_DEFINE(0, 0, 0, 0),
|
||||
};
|
||||
|
||||
#define OMAP4460_VDD_IVA_OPP50_UV 1025000
|
||||
#define OMAP4460_VDD_IVA_OPP100_UV 1200000
|
||||
#define OMAP4460_VDD_IVA_OPPTURBO_UV 1313000
|
||||
#define OMAP4460_VDD_IVA_OPPNITRO_UV 1375000
|
||||
|
||||
struct omap_volt_data omap446x_vdd_iva_volt_data[] = {
|
||||
VOLT_DATA_DEFINE(OMAP4460_VDD_IVA_OPP50_UV, OMAP44XX_CONTROL_FUSE_IVA_OPP50, 0xf4, 0x0c),
|
||||
VOLT_DATA_DEFINE(OMAP4460_VDD_IVA_OPP100_UV, OMAP44XX_CONTROL_FUSE_IVA_OPP100, 0xf9, 0x16),
|
||||
VOLT_DATA_DEFINE(OMAP4460_VDD_IVA_OPPTURBO_UV, OMAP44XX_CONTROL_FUSE_IVA_OPPTURBO, 0xfa, 0x23),
|
||||
VOLT_DATA_DEFINE(OMAP4460_VDD_IVA_OPPNITRO_UV, OMAP44XX_CONTROL_FUSE_IVA_OPPNITRO, 0xfa, 0x23),
|
||||
VOLT_DATA_DEFINE(0, 0, 0, 0),
|
||||
};
|
||||
|
||||
#define OMAP4460_VDD_CORE_OPP50_UV 1025000
|
||||
#define OMAP4460_VDD_CORE_OPP100_UV 1200000
|
||||
#define OMAP4460_VDD_CORE_OPP100_OV_UV 1250000
|
||||
|
||||
struct omap_volt_data omap446x_vdd_core_volt_data[] = {
|
||||
VOLT_DATA_DEFINE(OMAP4460_VDD_CORE_OPP50_UV, OMAP44XX_CONTROL_FUSE_CORE_OPP50, 0xf4, 0x0c),
|
||||
VOLT_DATA_DEFINE(OMAP4460_VDD_CORE_OPP100_UV, OMAP44XX_CONTROL_FUSE_CORE_OPP100, 0xf9, 0x16),
|
||||
VOLT_DATA_DEFINE(OMAP4460_VDD_CORE_OPP100_OV_UV, OMAP44XX_CONTROL_FUSE_CORE_OPP100OV, 0xf9, 0x16),
|
||||
VOLT_DATA_DEFINE(0, 0, 0, 0),
|
||||
};
|
||||
|
||||
static struct omap_opp_def __initdata omap446x_opp_def_list[] = {
|
||||
/* MPU OPP1 - OPP50 */
|
||||
OPP_INITIALIZER("mpu", true, 350000000, OMAP4460_VDD_MPU_OPP50_UV),
|
||||
/* MPU OPP2 - OPP100 */
|
||||
OPP_INITIALIZER("mpu", true, 700000000, OMAP4460_VDD_MPU_OPP100_UV),
|
||||
/* MPU OPP3 - OPP-Turbo */
|
||||
OPP_INITIALIZER("mpu", true, 920000000, OMAP4460_VDD_MPU_OPPTURBO_UV),
|
||||
/*
|
||||
* MPU OPP4 - OPP-Nitro + Disabled as the reference schematics
|
||||
* recommends TPS623631 - confirm and enable the opp in board file
|
||||
* XXX: May be we should enable these based on mpu capability and
|
||||
* Exception board files disable it...
|
||||
*/
|
||||
OPP_INITIALIZER("mpu", false, 1200000000, OMAP4460_VDD_MPU_OPPNITRO_UV),
|
||||
/* MPU OPP4 - OPP-Nitro SpeedBin */
|
||||
OPP_INITIALIZER("mpu", false, 1500000000, OMAP4460_VDD_MPU_OPPNITRO_UV),
|
||||
/* L3 OPP1 - OPP50 */
|
||||
OPP_INITIALIZER("l3_main_1", true, 100000000, OMAP4460_VDD_CORE_OPP50_UV),
|
||||
/* L3 OPP2 - OPP100 */
|
||||
OPP_INITIALIZER("l3_main_1", true, 200000000, OMAP4460_VDD_CORE_OPP100_UV),
|
||||
/* IVA OPP1 - OPP50 */
|
||||
OPP_INITIALIZER("iva", true, 133000000, OMAP4460_VDD_IVA_OPP50_UV),
|
||||
/* IVA OPP2 - OPP100 */
|
||||
OPP_INITIALIZER("iva", true, 266100000, OMAP4460_VDD_IVA_OPP100_UV),
|
||||
/*
|
||||
* IVA OPP3 - OPP-Turbo + Disabled as the reference schematics
|
||||
* recommends Phoenix VCORE2 which can supply only 600mA - so the ones
|
||||
* above this OPP frequency, even though OMAP is capable, should be
|
||||
* enabled by board file which is sure of the chip power capability
|
||||
*/
|
||||
OPP_INITIALIZER("iva", false, 332000000, OMAP4460_VDD_IVA_OPPTURBO_UV),
|
||||
/* IVA OPP4 - OPP-Nitro */
|
||||
OPP_INITIALIZER("iva", false, 430000000, OMAP4460_VDD_IVA_OPPNITRO_UV),
|
||||
/* IVA OPP5 - OPP-Nitro SpeedBin*/
|
||||
OPP_INITIALIZER("iva", false, 500000000, OMAP4460_VDD_IVA_OPPNITRO_UV),
|
||||
|
||||
/* TODO: add DSP, aess, fdif, gpu */
|
||||
};
|
||||
|
||||
/**
|
||||
* omap4_opp_init() - initialize omap4 opp table
|
||||
*/
|
||||
|
@ -93,12 +169,12 @@ int __init omap4_opp_init(void)
|
|||
{
|
||||
int r = -ENODEV;
|
||||
|
||||
if (!cpu_is_omap443x())
|
||||
return r;
|
||||
|
||||
r = omap_init_opp_table(omap44xx_opp_def_list,
|
||||
ARRAY_SIZE(omap44xx_opp_def_list));
|
||||
|
||||
if (cpu_is_omap443x())
|
||||
r = omap_init_opp_table(omap443x_opp_def_list,
|
||||
ARRAY_SIZE(omap443x_opp_def_list));
|
||||
else if (cpu_is_omap446x())
|
||||
r = omap_init_opp_table(omap446x_opp_def_list,
|
||||
ARRAY_SIZE(omap446x_opp_def_list));
|
||||
return r;
|
||||
}
|
||||
device_initcall(omap4_opp_init);
|
||||
|
|
|
@ -39,6 +39,36 @@ static struct omap_device_pm_latency *pm_lats;
|
|||
*/
|
||||
int (*omap_pm_suspend)(void);
|
||||
|
||||
/**
|
||||
* struct omap2_oscillator - Describe the board main oscillator latencies
|
||||
* @startup_time: oscillator startup latency
|
||||
* @shutdown_time: oscillator shutdown latency
|
||||
*/
|
||||
struct omap2_oscillator {
|
||||
u32 startup_time;
|
||||
u32 shutdown_time;
|
||||
};
|
||||
|
||||
static struct omap2_oscillator oscillator = {
|
||||
.startup_time = ULONG_MAX,
|
||||
.shutdown_time = ULONG_MAX,
|
||||
};
|
||||
|
||||
void omap_pm_setup_oscillator(u32 tstart, u32 tshut)
|
||||
{
|
||||
oscillator.startup_time = tstart;
|
||||
oscillator.shutdown_time = tshut;
|
||||
}
|
||||
|
||||
void omap_pm_get_oscillator(u32 *tstart, u32 *tshut)
|
||||
{
|
||||
if (!tstart || !tshut)
|
||||
return;
|
||||
|
||||
*tstart = oscillator.startup_time;
|
||||
*tshut = oscillator.shutdown_time;
|
||||
}
|
||||
|
||||
static int __init _init_omap_device(char *name)
|
||||
{
|
||||
struct omap_hwmod *oh;
|
||||
|
|
|
@ -129,4 +129,14 @@ static inline int omap4_twl_init(void)
|
|||
}
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_PM
|
||||
extern void omap_pm_setup_oscillator(u32 tstart, u32 tshut);
|
||||
extern void omap_pm_get_oscillator(u32 *tstart, u32 *tshut);
|
||||
extern void omap_pm_setup_sr_i2c_pcb_length(u32 mm);
|
||||
#else
|
||||
static inline void omap_pm_setup_oscillator(u32 tstart, u32 tshut) { }
|
||||
static inline void omap_pm_get_oscillator(u32 *tstart, u32 *tshut) { }
|
||||
static inline void omap_pm_setup_sr_i2c_pcb_length(u32 mm) { }
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
|
|
@ -11,13 +11,20 @@
|
|||
#include <linux/delay.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/bug.h>
|
||||
#include <linux/io.h>
|
||||
|
||||
#include <asm/div64.h>
|
||||
|
||||
#include "iomap.h"
|
||||
#include "soc.h"
|
||||
#include "voltage.h"
|
||||
#include "vc.h"
|
||||
#include "prm-regbits-34xx.h"
|
||||
#include "prm-regbits-44xx.h"
|
||||
#include "prm44xx.h"
|
||||
#include "pm.h"
|
||||
#include "scrm44xx.h"
|
||||
#include "control.h"
|
||||
|
||||
/**
|
||||
* struct omap_vc_channel_cfg - describe the cfg_channel bitfield
|
||||
|
@ -63,6 +70,9 @@ static struct omap_vc_channel_cfg vc_mutant_channel_cfg = {
|
|||
};
|
||||
|
||||
static struct omap_vc_channel_cfg *vc_cfg_bits;
|
||||
|
||||
/* Default I2C trace length on pcb, 6.3cm. Used for capacitance calculations. */
|
||||
static u32 sr_i2c_pcb_length = 63;
|
||||
#define CFG_CHANNEL_MASK 0x1f
|
||||
|
||||
/**
|
||||
|
@ -135,6 +145,8 @@ int omap_vc_pre_scale(struct voltagedomain *voltdm,
|
|||
vc_cmdval |= (*target_vsel << vc->common->cmd_on_shift);
|
||||
voltdm->write(vc_cmdval, vc->cmdval_reg);
|
||||
|
||||
voltdm->vc_param->on = target_volt;
|
||||
|
||||
omap_vp_update_errorgain(voltdm, target_volt);
|
||||
|
||||
return 0;
|
||||
|
@ -202,46 +214,389 @@ int omap_vc_bypass_scale(struct voltagedomain *voltdm,
|
|||
return 0;
|
||||
}
|
||||
|
||||
static void __init omap3_vfsm_init(struct voltagedomain *voltdm)
|
||||
/* Convert microsecond value to number of 32kHz clock cycles */
|
||||
static inline u32 omap_usec_to_32k(u32 usec)
|
||||
{
|
||||
return DIV_ROUND_UP_ULL(32768ULL * (u64)usec, 1000000ULL);
|
||||
}
|
||||
|
||||
/* Set oscillator setup time for omap3 */
|
||||
static void omap3_set_clksetup(u32 usec, struct voltagedomain *voltdm)
|
||||
{
|
||||
voltdm->write(omap_usec_to_32k(usec), OMAP3_PRM_CLKSETUP_OFFSET);
|
||||
}
|
||||
|
||||
/**
|
||||
* omap3_set_i2c_timings - sets i2c sleep timings for a channel
|
||||
* @voltdm: channel to configure
|
||||
* @off_mode: select whether retention or off mode values used
|
||||
*
|
||||
* Calculates and sets up voltage controller to use I2C based
|
||||
* voltage scaling for sleep modes. This can be used for either off mode
|
||||
* or retention. Off mode has additionally an option to use sys_off_mode
|
||||
* pad, which uses a global signal to program the whole power IC to
|
||||
* off-mode.
|
||||
*/
|
||||
static void omap3_set_i2c_timings(struct voltagedomain *voltdm, bool off_mode)
|
||||
{
|
||||
unsigned long voltsetup1;
|
||||
u32 tgt_volt;
|
||||
|
||||
/*
|
||||
* Voltage Manager FSM parameters init
|
||||
* XXX This data should be passed in from the board file
|
||||
* Oscillator is shut down only if we are using sys_off_mode pad,
|
||||
* thus we set a minimal setup time here
|
||||
*/
|
||||
voltdm->write(OMAP3_CLKSETUP, OMAP3_PRM_CLKSETUP_OFFSET);
|
||||
voltdm->write(OMAP3_VOLTOFFSET, OMAP3_PRM_VOLTOFFSET_OFFSET);
|
||||
voltdm->write(OMAP3_VOLTSETUP2, OMAP3_PRM_VOLTSETUP2_OFFSET);
|
||||
omap3_set_clksetup(1, voltdm);
|
||||
|
||||
if (off_mode)
|
||||
tgt_volt = voltdm->vc_param->off;
|
||||
else
|
||||
tgt_volt = voltdm->vc_param->ret;
|
||||
|
||||
voltsetup1 = (voltdm->vc_param->on - tgt_volt) /
|
||||
voltdm->pmic->slew_rate;
|
||||
|
||||
voltsetup1 = voltsetup1 * voltdm->sys_clk.rate / 8 / 1000000 + 1;
|
||||
|
||||
voltdm->rmw(voltdm->vfsm->voltsetup_mask,
|
||||
voltsetup1 << __ffs(voltdm->vfsm->voltsetup_mask),
|
||||
voltdm->vfsm->voltsetup_reg);
|
||||
|
||||
/*
|
||||
* pmic is not controlling the voltage scaling during retention,
|
||||
* thus set voltsetup2 to 0
|
||||
*/
|
||||
voltdm->write(0, OMAP3_PRM_VOLTSETUP2_OFFSET);
|
||||
}
|
||||
|
||||
/**
|
||||
* omap3_set_off_timings - sets off-mode timings for a channel
|
||||
* @voltdm: channel to configure
|
||||
*
|
||||
* Calculates and sets up off-mode timings for a channel. Off-mode
|
||||
* can use either I2C based voltage scaling, or alternatively
|
||||
* sys_off_mode pad can be used to send a global command to power IC.
|
||||
* This function first checks which mode is being used, and calls
|
||||
* omap3_set_i2c_timings() if the system is using I2C control mode.
|
||||
* sys_off_mode has the additional benefit that voltages can be
|
||||
* scaled to zero volt level with TWL4030 / TWL5030, I2C can only
|
||||
* scale to 600mV.
|
||||
*/
|
||||
static void omap3_set_off_timings(struct voltagedomain *voltdm)
|
||||
{
|
||||
unsigned long clksetup;
|
||||
unsigned long voltsetup2;
|
||||
unsigned long voltsetup2_old;
|
||||
u32 val;
|
||||
u32 tstart, tshut;
|
||||
|
||||
/* check if sys_off_mode is used to control off-mode voltages */
|
||||
val = voltdm->read(OMAP3_PRM_VOLTCTRL_OFFSET);
|
||||
if (!(val & OMAP3430_SEL_OFF_MASK)) {
|
||||
/* No, omap is controlling them over I2C */
|
||||
omap3_set_i2c_timings(voltdm, true);
|
||||
return;
|
||||
}
|
||||
|
||||
omap_pm_get_oscillator(&tstart, &tshut);
|
||||
omap3_set_clksetup(tstart, voltdm);
|
||||
|
||||
clksetup = voltdm->read(OMAP3_PRM_CLKSETUP_OFFSET);
|
||||
|
||||
/* voltsetup 2 in us */
|
||||
voltsetup2 = voltdm->vc_param->on / voltdm->pmic->slew_rate;
|
||||
|
||||
/* convert to 32k clk cycles */
|
||||
voltsetup2 = DIV_ROUND_UP(voltsetup2 * 32768, 1000000);
|
||||
|
||||
voltsetup2_old = voltdm->read(OMAP3_PRM_VOLTSETUP2_OFFSET);
|
||||
|
||||
/*
|
||||
* Update voltsetup2 if higher than current value (needed because
|
||||
* we have multiple channels with different ramp times), also
|
||||
* update voltoffset always to value recommended by TRM
|
||||
*/
|
||||
if (voltsetup2 > voltsetup2_old) {
|
||||
voltdm->write(voltsetup2, OMAP3_PRM_VOLTSETUP2_OFFSET);
|
||||
voltdm->write(clksetup - voltsetup2,
|
||||
OMAP3_PRM_VOLTOFFSET_OFFSET);
|
||||
} else
|
||||
voltdm->write(clksetup - voltsetup2_old,
|
||||
OMAP3_PRM_VOLTOFFSET_OFFSET);
|
||||
|
||||
/*
|
||||
* omap is not controlling voltage scaling during off-mode,
|
||||
* thus set voltsetup1 to 0
|
||||
*/
|
||||
voltdm->rmw(voltdm->vfsm->voltsetup_mask, 0,
|
||||
voltdm->vfsm->voltsetup_reg);
|
||||
|
||||
/* voltoffset must be clksetup minus voltsetup2 according to TRM */
|
||||
voltdm->write(clksetup - voltsetup2, OMAP3_PRM_VOLTOFFSET_OFFSET);
|
||||
}
|
||||
|
||||
static void __init omap3_vc_init_channel(struct voltagedomain *voltdm)
|
||||
{
|
||||
static bool is_initialized;
|
||||
|
||||
if (is_initialized)
|
||||
return;
|
||||
|
||||
omap3_vfsm_init(voltdm);
|
||||
|
||||
is_initialized = true;
|
||||
omap3_set_off_timings(voltdm);
|
||||
}
|
||||
|
||||
/**
|
||||
* omap4_calc_volt_ramp - calculates voltage ramping delays on omap4
|
||||
* @voltdm: channel to calculate values for
|
||||
* @voltage_diff: voltage difference in microvolts
|
||||
*
|
||||
* Calculates voltage ramp prescaler + counter values for a voltage
|
||||
* difference on omap4. Returns a field value suitable for writing to
|
||||
* VOLTSETUP register for a channel in following format:
|
||||
* bits[8:9] prescaler ... bits[0:5] counter. See OMAP4 TRM for reference.
|
||||
*/
|
||||
static u32 omap4_calc_volt_ramp(struct voltagedomain *voltdm, u32 voltage_diff)
|
||||
{
|
||||
u32 prescaler;
|
||||
u32 cycles;
|
||||
u32 time;
|
||||
|
||||
time = voltage_diff / voltdm->pmic->slew_rate;
|
||||
|
||||
cycles = voltdm->sys_clk.rate / 1000 * time / 1000;
|
||||
|
||||
cycles /= 64;
|
||||
prescaler = 0;
|
||||
|
||||
/* shift to next prescaler until no overflow */
|
||||
|
||||
/* scale for div 256 = 64 * 4 */
|
||||
if (cycles > 63) {
|
||||
cycles /= 4;
|
||||
prescaler++;
|
||||
}
|
||||
|
||||
/* scale for div 512 = 256 * 2 */
|
||||
if (cycles > 63) {
|
||||
cycles /= 2;
|
||||
prescaler++;
|
||||
}
|
||||
|
||||
/* scale for div 2048 = 512 * 4 */
|
||||
if (cycles > 63) {
|
||||
cycles /= 4;
|
||||
prescaler++;
|
||||
}
|
||||
|
||||
/* check for overflow => invalid ramp time */
|
||||
if (cycles > 63) {
|
||||
pr_warn("%s: invalid setuptime for vdd_%s\n", __func__,
|
||||
voltdm->name);
|
||||
return 0;
|
||||
}
|
||||
|
||||
cycles++;
|
||||
|
||||
return (prescaler << OMAP4430_RAMP_UP_PRESCAL_SHIFT) |
|
||||
(cycles << OMAP4430_RAMP_UP_COUNT_SHIFT);
|
||||
}
|
||||
|
||||
/**
|
||||
* omap4_usec_to_val_scrm - convert microsecond value to SCRM module bitfield
|
||||
* @usec: microseconds
|
||||
* @shift: number of bits to shift left
|
||||
* @mask: bitfield mask
|
||||
*
|
||||
* Converts microsecond value to OMAP4 SCRM bitfield. Bitfield is
|
||||
* shifted to requested position, and checked agains the mask value.
|
||||
* If larger, forced to the max value of the field (i.e. the mask itself.)
|
||||
* Returns the SCRM bitfield value.
|
||||
*/
|
||||
static u32 omap4_usec_to_val_scrm(u32 usec, int shift, u32 mask)
|
||||
{
|
||||
u32 val;
|
||||
|
||||
val = omap_usec_to_32k(usec) << shift;
|
||||
|
||||
/* Check for overflow, if yes, force to max value */
|
||||
if (val > mask)
|
||||
val = mask;
|
||||
|
||||
return val;
|
||||
}
|
||||
|
||||
/**
|
||||
* omap4_set_timings - set voltage ramp timings for a channel
|
||||
* @voltdm: channel to configure
|
||||
* @off_mode: whether off-mode values are used
|
||||
*
|
||||
* Calculates and sets the voltage ramp up / down values for a channel.
|
||||
*/
|
||||
static void omap4_set_timings(struct voltagedomain *voltdm, bool off_mode)
|
||||
{
|
||||
u32 val;
|
||||
u32 ramp;
|
||||
int offset;
|
||||
u32 tstart, tshut;
|
||||
|
||||
if (off_mode) {
|
||||
ramp = omap4_calc_volt_ramp(voltdm,
|
||||
voltdm->vc_param->on - voltdm->vc_param->off);
|
||||
offset = voltdm->vfsm->voltsetup_off_reg;
|
||||
} else {
|
||||
ramp = omap4_calc_volt_ramp(voltdm,
|
||||
voltdm->vc_param->on - voltdm->vc_param->ret);
|
||||
offset = voltdm->vfsm->voltsetup_reg;
|
||||
}
|
||||
|
||||
if (!ramp)
|
||||
return;
|
||||
|
||||
val = voltdm->read(offset);
|
||||
|
||||
val |= ramp << OMAP4430_RAMP_DOWN_COUNT_SHIFT;
|
||||
|
||||
val |= ramp << OMAP4430_RAMP_UP_COUNT_SHIFT;
|
||||
|
||||
voltdm->write(val, offset);
|
||||
|
||||
omap_pm_get_oscillator(&tstart, &tshut);
|
||||
|
||||
val = omap4_usec_to_val_scrm(tstart, OMAP4_SETUPTIME_SHIFT,
|
||||
OMAP4_SETUPTIME_MASK);
|
||||
val |= omap4_usec_to_val_scrm(tshut, OMAP4_DOWNTIME_SHIFT,
|
||||
OMAP4_DOWNTIME_MASK);
|
||||
|
||||
__raw_writel(val, OMAP4_SCRM_CLKSETUPTIME);
|
||||
}
|
||||
|
||||
/* OMAP4 specific voltage init functions */
|
||||
static void __init omap4_vc_init_channel(struct voltagedomain *voltdm)
|
||||
{
|
||||
static bool is_initialized;
|
||||
u32 vc_val;
|
||||
|
||||
if (is_initialized)
|
||||
return;
|
||||
|
||||
/* XXX These are magic numbers and do not belong! */
|
||||
vc_val = (0x60 << OMAP4430_SCLL_SHIFT | 0x26 << OMAP4430_SCLH_SHIFT);
|
||||
voltdm->write(vc_val, OMAP4_PRM_VC_CFG_I2C_CLK_OFFSET);
|
||||
|
||||
is_initialized = true;
|
||||
omap4_set_timings(voltdm, true);
|
||||
omap4_set_timings(voltdm, false);
|
||||
}
|
||||
|
||||
struct i2c_init_data {
|
||||
u8 loadbits;
|
||||
u8 load;
|
||||
u8 hsscll_38_4;
|
||||
u8 hsscll_26;
|
||||
u8 hsscll_19_2;
|
||||
u8 hsscll_16_8;
|
||||
u8 hsscll_12;
|
||||
};
|
||||
|
||||
static const __initdata struct i2c_init_data omap4_i2c_timing_data[] = {
|
||||
{
|
||||
.load = 50,
|
||||
.loadbits = 0x3,
|
||||
.hsscll_38_4 = 13,
|
||||
.hsscll_26 = 11,
|
||||
.hsscll_19_2 = 9,
|
||||
.hsscll_16_8 = 9,
|
||||
.hsscll_12 = 8,
|
||||
},
|
||||
{
|
||||
.load = 25,
|
||||
.loadbits = 0x2,
|
||||
.hsscll_38_4 = 13,
|
||||
.hsscll_26 = 11,
|
||||
.hsscll_19_2 = 9,
|
||||
.hsscll_16_8 = 9,
|
||||
.hsscll_12 = 8,
|
||||
},
|
||||
{
|
||||
.load = 12,
|
||||
.loadbits = 0x1,
|
||||
.hsscll_38_4 = 11,
|
||||
.hsscll_26 = 10,
|
||||
.hsscll_19_2 = 9,
|
||||
.hsscll_16_8 = 9,
|
||||
.hsscll_12 = 8,
|
||||
},
|
||||
{
|
||||
.load = 0,
|
||||
.loadbits = 0x0,
|
||||
.hsscll_38_4 = 12,
|
||||
.hsscll_26 = 10,
|
||||
.hsscll_19_2 = 9,
|
||||
.hsscll_16_8 = 8,
|
||||
.hsscll_12 = 8,
|
||||
},
|
||||
};
|
||||
|
||||
/**
|
||||
* omap4_vc_i2c_timing_init - sets up board I2C timing parameters
|
||||
* @voltdm: voltagedomain pointer to get data from
|
||||
*
|
||||
* Use PMIC + board supplied settings for calculating the total I2C
|
||||
* channel capacitance and set the timing parameters based on this.
|
||||
* Pre-calculated values are provided in data tables, as it is not
|
||||
* too straightforward to calculate these runtime.
|
||||
*/
|
||||
static void __init omap4_vc_i2c_timing_init(struct voltagedomain *voltdm)
|
||||
{
|
||||
u32 capacitance;
|
||||
u32 val;
|
||||
u16 hsscll;
|
||||
const struct i2c_init_data *i2c_data;
|
||||
|
||||
if (!voltdm->pmic->i2c_high_speed) {
|
||||
pr_warn("%s: only high speed supported!\n", __func__);
|
||||
return;
|
||||
}
|
||||
|
||||
/* PCB trace capacitance, 0.125pF / mm => mm / 8 */
|
||||
capacitance = DIV_ROUND_UP(sr_i2c_pcb_length, 8);
|
||||
|
||||
/* OMAP pad capacitance */
|
||||
capacitance += 4;
|
||||
|
||||
/* PMIC pad capacitance */
|
||||
capacitance += voltdm->pmic->i2c_pad_load;
|
||||
|
||||
/* Search for capacitance match in the table */
|
||||
i2c_data = omap4_i2c_timing_data;
|
||||
|
||||
while (i2c_data->load > capacitance)
|
||||
i2c_data++;
|
||||
|
||||
/* Select proper values based on sysclk frequency */
|
||||
switch (voltdm->sys_clk.rate) {
|
||||
case 38400000:
|
||||
hsscll = i2c_data->hsscll_38_4;
|
||||
break;
|
||||
case 26000000:
|
||||
hsscll = i2c_data->hsscll_26;
|
||||
break;
|
||||
case 19200000:
|
||||
hsscll = i2c_data->hsscll_19_2;
|
||||
break;
|
||||
case 16800000:
|
||||
hsscll = i2c_data->hsscll_16_8;
|
||||
break;
|
||||
case 12000000:
|
||||
hsscll = i2c_data->hsscll_12;
|
||||
break;
|
||||
default:
|
||||
pr_warn("%s: unsupported sysclk rate: %d!\n", __func__,
|
||||
voltdm->sys_clk.rate);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Loadbits define pull setup for the I2C channels */
|
||||
val = i2c_data->loadbits << 25 | i2c_data->loadbits << 29;
|
||||
|
||||
/* Write to SYSCTRL_PADCONF_WKUP_CTRL_I2C_2 to setup I2C pull */
|
||||
__raw_writel(val, OMAP2_L4_IO_ADDRESS(OMAP4_CTRL_MODULE_PAD_WKUP +
|
||||
OMAP4_CTRL_MODULE_PAD_WKUP_CONTROL_I2C_2));
|
||||
|
||||
/* HSSCLH can always be zero */
|
||||
val = hsscll << OMAP4430_HSSCLL_SHIFT;
|
||||
val |= (0x28 << OMAP4430_SCLL_SHIFT | 0x2c << OMAP4430_SCLH_SHIFT);
|
||||
|
||||
/* Write setup times to I2C config register */
|
||||
voltdm->write(val, OMAP4_PRM_VC_CFG_I2C_CLK_OFFSET);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* omap_vc_i2c_init - initialize I2C interface to PMIC
|
||||
* @voltdm: voltage domain containing VC data
|
||||
|
@ -281,9 +636,49 @@ static void __init omap_vc_i2c_init(struct voltagedomain *voltdm)
|
|||
mcode << __ffs(vc->common->i2c_mcode_mask),
|
||||
vc->common->i2c_cfg_reg);
|
||||
|
||||
if (cpu_is_omap44xx())
|
||||
omap4_vc_i2c_timing_init(voltdm);
|
||||
|
||||
initialized = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* omap_vc_calc_vsel - calculate vsel value for a channel
|
||||
* @voltdm: channel to calculate value for
|
||||
* @uvolt: microvolt value to convert to vsel
|
||||
*
|
||||
* Converts a microvolt value to vsel value for the used PMIC.
|
||||
* This checks whether the microvolt value is out of bounds, and
|
||||
* adjusts the value accordingly. If unsupported value detected,
|
||||
* warning is thrown.
|
||||
*/
|
||||
static u8 omap_vc_calc_vsel(struct voltagedomain *voltdm, u32 uvolt)
|
||||
{
|
||||
if (voltdm->pmic->vddmin > uvolt)
|
||||
uvolt = voltdm->pmic->vddmin;
|
||||
if (voltdm->pmic->vddmax < uvolt) {
|
||||
WARN(1, "%s: voltage not supported by pmic: %u vs max %u\n",
|
||||
__func__, uvolt, voltdm->pmic->vddmax);
|
||||
/* Lets try maximum value anyway */
|
||||
uvolt = voltdm->pmic->vddmax;
|
||||
}
|
||||
|
||||
return voltdm->pmic->uv_to_vsel(uvolt);
|
||||
}
|
||||
|
||||
/**
|
||||
* omap_pm_setup_sr_i2c_pcb_length - set length of SR I2C traces on PCB
|
||||
* @mm: length of the PCB trace in millimetres
|
||||
*
|
||||
* Sets the PCB trace length for the I2C channel. By default uses 63mm.
|
||||
* This is needed for properly calculating the capacitance value for
|
||||
* the PCB trace, and for setting the SR I2C channel timing parameters.
|
||||
*/
|
||||
void __init omap_pm_setup_sr_i2c_pcb_length(u32 mm)
|
||||
{
|
||||
sr_i2c_pcb_length = mm;
|
||||
}
|
||||
|
||||
void __init omap_vc_init_channel(struct voltagedomain *voltdm)
|
||||
{
|
||||
struct omap_vc_channel *vc = voltdm->vc;
|
||||
|
@ -311,7 +706,6 @@ void __init omap_vc_init_channel(struct voltagedomain *voltdm)
|
|||
vc->i2c_slave_addr = voltdm->pmic->i2c_slave_addr;
|
||||
vc->volt_reg_addr = voltdm->pmic->volt_reg_addr;
|
||||
vc->cmd_reg_addr = voltdm->pmic->cmd_reg_addr;
|
||||
vc->setup_time = voltdm->pmic->volt_setup_time;
|
||||
|
||||
/* Configure the i2c slave address for this VC */
|
||||
voltdm->rmw(vc->smps_sa_mask,
|
||||
|
@ -331,14 +725,18 @@ void __init omap_vc_init_channel(struct voltagedomain *voltdm)
|
|||
voltdm->rmw(vc->smps_cmdra_mask,
|
||||
vc->cmd_reg_addr << __ffs(vc->smps_cmdra_mask),
|
||||
vc->smps_cmdra_reg);
|
||||
vc->cfg_channel |= vc_cfg_bits->rac | vc_cfg_bits->racen;
|
||||
vc->cfg_channel |= vc_cfg_bits->rac;
|
||||
}
|
||||
|
||||
if (vc->cmd_reg_addr == vc->volt_reg_addr)
|
||||
vc->cfg_channel |= vc_cfg_bits->racen;
|
||||
|
||||
/* Set up the on, inactive, retention and off voltage */
|
||||
on_vsel = voltdm->pmic->uv_to_vsel(voltdm->pmic->on_volt);
|
||||
onlp_vsel = voltdm->pmic->uv_to_vsel(voltdm->pmic->onlp_volt);
|
||||
ret_vsel = voltdm->pmic->uv_to_vsel(voltdm->pmic->ret_volt);
|
||||
off_vsel = voltdm->pmic->uv_to_vsel(voltdm->pmic->off_volt);
|
||||
on_vsel = omap_vc_calc_vsel(voltdm, voltdm->vc_param->on);
|
||||
onlp_vsel = omap_vc_calc_vsel(voltdm, voltdm->vc_param->onlp);
|
||||
ret_vsel = omap_vc_calc_vsel(voltdm, voltdm->vc_param->ret);
|
||||
off_vsel = omap_vc_calc_vsel(voltdm, voltdm->vc_param->off);
|
||||
|
||||
val = ((on_vsel << vc->common->cmd_on_shift) |
|
||||
(onlp_vsel << vc->common->cmd_onlp_shift) |
|
||||
(ret_vsel << vc->common->cmd_ret_shift) |
|
||||
|
@ -349,11 +747,6 @@ void __init omap_vc_init_channel(struct voltagedomain *voltdm)
|
|||
/* Channel configuration */
|
||||
omap_vc_config_channel(voltdm);
|
||||
|
||||
/* Configure the setup times */
|
||||
voltdm->rmw(voltdm->vfsm->voltsetup_mask,
|
||||
vc->setup_time << __ffs(voltdm->vfsm->voltsetup_mask),
|
||||
voltdm->vfsm->voltsetup_reg);
|
||||
|
||||
omap_vc_i2c_init(voltdm);
|
||||
|
||||
if (cpu_is_omap34xx())
|
||||
|
|
|
@ -86,7 +86,6 @@ struct omap_vc_channel {
|
|||
u16 i2c_slave_addr;
|
||||
u16 volt_reg_addr;
|
||||
u16 cmd_reg_addr;
|
||||
u16 setup_time;
|
||||
u8 cfg_channel;
|
||||
bool i2c_high_speed;
|
||||
|
||||
|
@ -111,6 +110,13 @@ extern struct omap_vc_channel omap4_vc_mpu;
|
|||
extern struct omap_vc_channel omap4_vc_iva;
|
||||
extern struct omap_vc_channel omap4_vc_core;
|
||||
|
||||
extern struct omap_vc_param omap3_mpu_vc_data;
|
||||
extern struct omap_vc_param omap3_core_vc_data;
|
||||
|
||||
extern struct omap_vc_param omap4_mpu_vc_data;
|
||||
extern struct omap_vc_param omap4_iva_vc_data;
|
||||
extern struct omap_vc_param omap4_core_vc_data;
|
||||
|
||||
void omap_vc_init_channel(struct voltagedomain *voltdm);
|
||||
int omap_vc_pre_scale(struct voltagedomain *voltdm,
|
||||
unsigned long target_volt,
|
||||
|
|
|
@ -71,3 +71,25 @@ struct omap_vc_channel omap3_vc_core = {
|
|||
.smps_cmdra_mask = OMAP3430_CMDRA1_MASK,
|
||||
.cfg_channel_sa_shift = OMAP3430_PRM_VC_SMPS_SA_SA1_SHIFT,
|
||||
};
|
||||
|
||||
/*
|
||||
* Voltage levels for different operating modes: on, sleep, retention and off
|
||||
*/
|
||||
#define OMAP3_ON_VOLTAGE_UV 1200000
|
||||
#define OMAP3_ONLP_VOLTAGE_UV 1000000
|
||||
#define OMAP3_RET_VOLTAGE_UV 975000
|
||||
#define OMAP3_OFF_VOLTAGE_UV 600000
|
||||
|
||||
struct omap_vc_param omap3_mpu_vc_data = {
|
||||
.on = OMAP3_ON_VOLTAGE_UV,
|
||||
.onlp = OMAP3_ONLP_VOLTAGE_UV,
|
||||
.ret = OMAP3_RET_VOLTAGE_UV,
|
||||
.off = OMAP3_OFF_VOLTAGE_UV,
|
||||
};
|
||||
|
||||
struct omap_vc_param omap3_core_vc_data = {
|
||||
.on = OMAP3_ON_VOLTAGE_UV,
|
||||
.onlp = OMAP3_ONLP_VOLTAGE_UV,
|
||||
.ret = OMAP3_RET_VOLTAGE_UV,
|
||||
.off = OMAP3_OFF_VOLTAGE_UV,
|
||||
};
|
||||
|
|
|
@ -87,3 +87,31 @@ struct omap_vc_channel omap4_vc_core = {
|
|||
.cfg_channel_sa_shift = OMAP4430_SA_VDD_CORE_L_SHIFT,
|
||||
};
|
||||
|
||||
/*
|
||||
* Voltage levels for different operating modes: on, sleep, retention and off
|
||||
*/
|
||||
#define OMAP4_ON_VOLTAGE_UV 1375000
|
||||
#define OMAP4_ONLP_VOLTAGE_UV 1375000
|
||||
#define OMAP4_RET_VOLTAGE_UV 837500
|
||||
#define OMAP4_OFF_VOLTAGE_UV 0
|
||||
|
||||
struct omap_vc_param omap4_mpu_vc_data = {
|
||||
.on = OMAP4_ON_VOLTAGE_UV,
|
||||
.onlp = OMAP4_ONLP_VOLTAGE_UV,
|
||||
.ret = OMAP4_RET_VOLTAGE_UV,
|
||||
.off = OMAP4_OFF_VOLTAGE_UV,
|
||||
};
|
||||
|
||||
struct omap_vc_param omap4_iva_vc_data = {
|
||||
.on = OMAP4_ON_VOLTAGE_UV,
|
||||
.onlp = OMAP4_ONLP_VOLTAGE_UV,
|
||||
.ret = OMAP4_RET_VOLTAGE_UV,
|
||||
.off = OMAP4_OFF_VOLTAGE_UV,
|
||||
};
|
||||
|
||||
struct omap_vc_param omap4_core_vc_data = {
|
||||
.on = OMAP4_ON_VOLTAGE_UV,
|
||||
.onlp = OMAP4_ONLP_VOLTAGE_UV,
|
||||
.ret = OMAP4_RET_VOLTAGE_UV,
|
||||
.off = OMAP4_OFF_VOLTAGE_UV,
|
||||
};
|
||||
|
|
|
@ -40,12 +40,14 @@ struct powerdomain;
|
|||
* data
|
||||
* @voltsetup_mask: SETUP_TIME* bitmask in the PRM_VOLTSETUP* register
|
||||
* @voltsetup_reg: register offset of PRM_VOLTSETUP from PRM base
|
||||
* @voltsetup_off_reg: register offset of PRM_VOLTSETUP_OFF from PRM base
|
||||
*
|
||||
* XXX What about VOLTOFFSET/VOLTCTRL?
|
||||
*/
|
||||
struct omap_vfsm_instance {
|
||||
u32 voltsetup_mask;
|
||||
u8 voltsetup_reg;
|
||||
u8 voltsetup_off_reg;
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -74,6 +76,8 @@ struct voltagedomain {
|
|||
const struct omap_vfsm_instance *vfsm;
|
||||
struct omap_vp_instance *vp;
|
||||
struct omap_voltdm_pmic *pmic;
|
||||
struct omap_vp_param *vp_param;
|
||||
struct omap_vc_param *vc_param;
|
||||
|
||||
/* VC/VP register access functions: SoC specific */
|
||||
u32 (*read) (u8 offset);
|
||||
|
@ -92,6 +96,24 @@ struct voltagedomain {
|
|||
struct omap_volt_data *volt_data;
|
||||
};
|
||||
|
||||
/* Min and max voltages from OMAP perspective */
|
||||
#define OMAP3430_VP1_VLIMITTO_VDDMIN 850000
|
||||
#define OMAP3430_VP1_VLIMITTO_VDDMAX 1425000
|
||||
#define OMAP3430_VP2_VLIMITTO_VDDMIN 900000
|
||||
#define OMAP3430_VP2_VLIMITTO_VDDMAX 1150000
|
||||
|
||||
#define OMAP3630_VP1_VLIMITTO_VDDMIN 900000
|
||||
#define OMAP3630_VP1_VLIMITTO_VDDMAX 1350000
|
||||
#define OMAP3630_VP2_VLIMITTO_VDDMIN 900000
|
||||
#define OMAP3630_VP2_VLIMITTO_VDDMAX 1200000
|
||||
|
||||
#define OMAP4_VP_MPU_VLIMITTO_VDDMIN 830000
|
||||
#define OMAP4_VP_MPU_VLIMITTO_VDDMAX 1410000
|
||||
#define OMAP4_VP_IVA_VLIMITTO_VDDMIN 830000
|
||||
#define OMAP4_VP_IVA_VLIMITTO_VDDMAX 1260000
|
||||
#define OMAP4_VP_CORE_VLIMITTO_VDDMIN 830000
|
||||
#define OMAP4_VP_CORE_VLIMITTO_VDDMAX 1200000
|
||||
|
||||
/**
|
||||
* struct omap_voltdm_pmic - PMIC specific data required by voltage driver.
|
||||
* @slew_rate: PMIC slew rate (in uv/us)
|
||||
|
@ -107,26 +129,34 @@ struct voltagedomain {
|
|||
struct omap_voltdm_pmic {
|
||||
int slew_rate;
|
||||
int step_size;
|
||||
u32 on_volt;
|
||||
u32 onlp_volt;
|
||||
u32 ret_volt;
|
||||
u32 off_volt;
|
||||
u16 volt_setup_time;
|
||||
u16 i2c_slave_addr;
|
||||
u16 volt_reg_addr;
|
||||
u16 cmd_reg_addr;
|
||||
u8 vp_erroroffset;
|
||||
u8 vp_vstepmin;
|
||||
u8 vp_vstepmax;
|
||||
u8 vp_vddmin;
|
||||
u8 vp_vddmax;
|
||||
u32 vddmin;
|
||||
u32 vddmax;
|
||||
u8 vp_timeout_us;
|
||||
bool i2c_high_speed;
|
||||
u32 i2c_pad_load;
|
||||
u8 i2c_mcode;
|
||||
unsigned long (*vsel_to_uv) (const u8 vsel);
|
||||
u8 (*uv_to_vsel) (unsigned long uV);
|
||||
};
|
||||
|
||||
struct omap_vp_param {
|
||||
u32 vddmax;
|
||||
u32 vddmin;
|
||||
};
|
||||
|
||||
struct omap_vc_param {
|
||||
u32 on;
|
||||
u32 onlp;
|
||||
u32 ret;
|
||||
u32 off;
|
||||
};
|
||||
|
||||
void omap_voltage_get_volttable(struct voltagedomain *voltdm,
|
||||
struct omap_volt_data **volt_data);
|
||||
struct omap_volt_data *omap_voltage_get_voltdata(struct voltagedomain *voltdm,
|
||||
|
|
|
@ -117,6 +117,11 @@ void __init omap3xxx_voltagedomains_init(void)
|
|||
}
|
||||
#endif
|
||||
|
||||
omap3_voltdm_mpu.vp_param = &omap3_mpu_vp_data;
|
||||
omap3_voltdm_core.vp_param = &omap3_core_vp_data;
|
||||
omap3_voltdm_mpu.vc_param = &omap3_mpu_vc_data;
|
||||
omap3_voltdm_core.vc_param = &omap3_core_vc_data;
|
||||
|
||||
if (soc_is_am35xx())
|
||||
voltdms = voltagedomains_am35xx;
|
||||
else
|
||||
|
|
|
@ -34,14 +34,17 @@
|
|||
|
||||
static const struct omap_vfsm_instance omap4_vdd_mpu_vfsm = {
|
||||
.voltsetup_reg = OMAP4_PRM_VOLTSETUP_MPU_RET_SLEEP_OFFSET,
|
||||
.voltsetup_off_reg = OMAP4_PRM_VOLTSETUP_MPU_OFF_OFFSET,
|
||||
};
|
||||
|
||||
static const struct omap_vfsm_instance omap4_vdd_iva_vfsm = {
|
||||
.voltsetup_reg = OMAP4_PRM_VOLTSETUP_IVA_RET_SLEEP_OFFSET,
|
||||
.voltsetup_off_reg = OMAP4_PRM_VOLTSETUP_IVA_OFF_OFFSET,
|
||||
};
|
||||
|
||||
static const struct omap_vfsm_instance omap4_vdd_core_vfsm = {
|
||||
.voltsetup_reg = OMAP4_PRM_VOLTSETUP_CORE_RET_SLEEP_OFFSET,
|
||||
.voltsetup_off_reg = OMAP4_PRM_VOLTSETUP_CORE_OFF_OFFSET,
|
||||
};
|
||||
|
||||
static struct voltagedomain omap4_voltdm_mpu = {
|
||||
|
@ -101,11 +104,25 @@ void __init omap44xx_voltagedomains_init(void)
|
|||
* for the currently-running IC
|
||||
*/
|
||||
#ifdef CONFIG_PM_OPP
|
||||
omap4_voltdm_mpu.volt_data = omap44xx_vdd_mpu_volt_data;
|
||||
omap4_voltdm_iva.volt_data = omap44xx_vdd_iva_volt_data;
|
||||
omap4_voltdm_core.volt_data = omap44xx_vdd_core_volt_data;
|
||||
if (cpu_is_omap443x()) {
|
||||
omap4_voltdm_mpu.volt_data = omap443x_vdd_mpu_volt_data;
|
||||
omap4_voltdm_iva.volt_data = omap443x_vdd_iva_volt_data;
|
||||
omap4_voltdm_core.volt_data = omap443x_vdd_core_volt_data;
|
||||
} else if (cpu_is_omap446x()) {
|
||||
omap4_voltdm_mpu.volt_data = omap446x_vdd_mpu_volt_data;
|
||||
omap4_voltdm_iva.volt_data = omap446x_vdd_iva_volt_data;
|
||||
omap4_voltdm_core.volt_data = omap446x_vdd_core_volt_data;
|
||||
}
|
||||
#endif
|
||||
|
||||
omap4_voltdm_mpu.vp_param = &omap4_mpu_vp_data;
|
||||
omap4_voltdm_iva.vp_param = &omap4_iva_vp_data;
|
||||
omap4_voltdm_core.vp_param = &omap4_core_vp_data;
|
||||
|
||||
omap4_voltdm_mpu.vc_param = &omap4_mpu_vc_data;
|
||||
omap4_voltdm_iva.vc_param = &omap4_iva_vc_data;
|
||||
omap4_voltdm_core.vc_param = &omap4_core_vc_data;
|
||||
|
||||
for (i = 0; voltdm = voltagedomains_omap4[i], voltdm; i++)
|
||||
voltdm->sys_clk.name = sys_clk_name;
|
||||
|
||||
|
|
|
@ -58,8 +58,10 @@ void __init omap_vp_init(struct voltagedomain *voltdm)
|
|||
sys_clk_rate = voltdm->sys_clk.rate / 1000;
|
||||
|
||||
timeout = (sys_clk_rate * voltdm->pmic->vp_timeout_us) / 1000;
|
||||
vddmin = voltdm->pmic->vp_vddmin;
|
||||
vddmax = voltdm->pmic->vp_vddmax;
|
||||
vddmin = max(voltdm->vp_param->vddmin, voltdm->pmic->vddmin);
|
||||
vddmax = min(voltdm->vp_param->vddmax, voltdm->pmic->vddmax);
|
||||
vddmin = voltdm->pmic->uv_to_vsel(vddmin);
|
||||
vddmax = voltdm->pmic->uv_to_vsel(vddmax);
|
||||
|
||||
waittime = DIV_ROUND_UP(voltdm->pmic->step_size * sys_clk_rate,
|
||||
1000 * voltdm->pmic->slew_rate);
|
||||
|
|
|
@ -117,6 +117,13 @@ extern struct omap_vp_instance omap4_vp_mpu;
|
|||
extern struct omap_vp_instance omap4_vp_iva;
|
||||
extern struct omap_vp_instance omap4_vp_core;
|
||||
|
||||
extern struct omap_vp_param omap3_mpu_vp_data;
|
||||
extern struct omap_vp_param omap3_core_vp_data;
|
||||
|
||||
extern struct omap_vp_param omap4_mpu_vp_data;
|
||||
extern struct omap_vp_param omap4_iva_vp_data;
|
||||
extern struct omap_vp_param omap4_core_vp_data;
|
||||
|
||||
void omap_vp_init(struct voltagedomain *voltdm);
|
||||
void omap_vp_enable(struct voltagedomain *voltdm);
|
||||
void omap_vp_disable(struct voltagedomain *voltdm);
|
||||
|
|
|
@ -77,3 +77,13 @@ struct omap_vp_instance omap3_vp_core = {
|
|||
.vstatus = OMAP3_PRM_VP2_STATUS_OFFSET,
|
||||
.voltage = OMAP3_PRM_VP2_VOLTAGE_OFFSET,
|
||||
};
|
||||
|
||||
struct omap_vp_param omap3_mpu_vp_data = {
|
||||
.vddmin = OMAP3430_VP1_VLIMITTO_VDDMIN,
|
||||
.vddmax = OMAP3430_VP1_VLIMITTO_VDDMAX,
|
||||
};
|
||||
|
||||
struct omap_vp_param omap3_core_vp_data = {
|
||||
.vddmin = OMAP3430_VP2_VLIMITTO_VDDMIN,
|
||||
.vddmax = OMAP3430_VP2_VLIMITTO_VDDMAX,
|
||||
};
|
||||
|
|
|
@ -87,3 +87,18 @@ struct omap_vp_instance omap4_vp_core = {
|
|||
.vstatus = OMAP4_PRM_VP_CORE_STATUS_OFFSET,
|
||||
.voltage = OMAP4_PRM_VP_CORE_VOLTAGE_OFFSET,
|
||||
};
|
||||
|
||||
struct omap_vp_param omap4_mpu_vp_data = {
|
||||
.vddmin = OMAP4_VP_MPU_VLIMITTO_VDDMIN,
|
||||
.vddmax = OMAP4_VP_MPU_VLIMITTO_VDDMAX,
|
||||
};
|
||||
|
||||
struct omap_vp_param omap4_iva_vp_data = {
|
||||
.vddmin = OMAP4_VP_IVA_VLIMITTO_VDDMIN,
|
||||
.vddmax = OMAP4_VP_IVA_VLIMITTO_VDDMAX,
|
||||
};
|
||||
|
||||
struct omap_vp_param omap4_core_vp_data = {
|
||||
.vddmin = OMAP4_VP_CORE_VLIMITTO_VDDMIN,
|
||||
.vddmax = OMAP4_VP_CORE_VLIMITTO_VDDMAX,
|
||||
};
|
||||
|
|
Loading…
Reference in New Issue