diff options
Diffstat (limited to 'arch/arm')
-rw-r--r-- | arch/arm/include/asm/omap_common.h | 23 | ||||
-rw-r--r-- | arch/arm/mach-omap2/clocks-common.c | 116 | ||||
-rw-r--r-- | arch/arm/mach-omap2/omap4/hw_data.c | 24 | ||||
-rw-r--r-- | arch/arm/mach-omap2/omap5/hw_data.c | 12 |
4 files changed, 111 insertions, 64 deletions
diff --git a/arch/arm/include/asm/omap_common.h b/arch/arm/include/asm/omap_common.h index 290a190..c3d5cda 100644 --- a/arch/arm/include/asm/omap_common.h +++ b/arch/arm/include/asm/omap_common.h @@ -539,18 +539,26 @@ struct pmic_data { int (*pmic_write)(u8 sa, u8 reg_addr, u8 reg_data); }; +enum { + OPP_LOW, + OPP_NOM, + OPP_OD, + OPP_HIGH, + NUM_OPPS, +}; + /** * struct volts_efuse_data - efuse definition for voltage * @reg: register address for efuse * @reg_bits: Number of bits in a register address, mandatory. */ struct volts_efuse_data { - u32 reg; + u32 reg[NUM_OPPS]; u8 reg_bits; }; struct volts { - u32 value; + u32 value[NUM_OPPS]; u32 addr; struct volts_efuse_data efuse; struct pmic_data *pmic; @@ -558,6 +566,16 @@ struct volts { u32 abb_tx_done_mask; }; +enum { + VOLT_MPU, + VOLT_CORE, + VOLT_MM, + VOLT_GPU, + VOLT_EVE, + VOLT_IVA, + NUM_VOLT_RAILS, +}; + struct vcores_data { struct volts mpu; struct volts core; @@ -612,6 +630,7 @@ void enable_usb_clocks(int index); void disable_usb_clocks(int index); void scale_vcores(struct vcores_data const *); +int get_voltrail_opp(int rail_offset); u32 get_offset_code(u32 volt_offset, struct pmic_data *pmic); void do_scale_vcore(u32 vcore_reg, u32 volt_mv, struct pmic_data *pmic); void abb_setup(u32 fuse, u32 ldovbb, u32 setup, u32 control, diff --git a/arch/arm/mach-omap2/clocks-common.c b/arch/arm/mach-omap2/clocks-common.c index 9b97583..84f93e7 100644 --- a/arch/arm/mach-omap2/clocks-common.c +++ b/arch/arm/mach-omap2/clocks-common.c @@ -477,35 +477,45 @@ void do_scale_vcore(u32 vcore_reg, u32 volt_mv, struct pmic_data *pmic) gpio_direction_output(pmic->gpio, 1); } -static u32 optimize_vcore_voltage(struct volts const *v) +int __weak get_voltrail_opp(int rail_offset) +{ + /* + * By default return OPP_NOM for all voltage rails. + */ + return OPP_NOM; +} + +static u32 optimize_vcore_voltage(struct volts const *v, int opp) { u32 val; - if (!v->value) + + if (!v->value[opp]) return 0; - if (!v->efuse.reg) - return v->value; + if (!v->efuse.reg[opp]) + return v->value[opp]; switch (v->efuse.reg_bits) { case 16: - val = readw(v->efuse.reg); + val = readw(v->efuse.reg[opp]); break; case 32: - val = readl(v->efuse.reg); + val = readl(v->efuse.reg[opp]); break; default: printf("Error: efuse 0x%08x bits=%d unknown\n", - v->efuse.reg, v->efuse.reg_bits); - return v->value; + v->efuse.reg[opp], v->efuse.reg_bits); + return v->value[opp]; } if (!val) { printf("Error: efuse 0x%08x bits=%d val=0, using %d\n", - v->efuse.reg, v->efuse.reg_bits, v->value); - return v->value; + v->efuse.reg[opp], v->efuse.reg_bits, v->value[opp]); + return v->value[opp]; } debug("%s:efuse 0x%08x bits=%d Vnom=%d, using efuse value %d\n", - __func__, v->efuse.reg, v->efuse.reg_bits, v->value, val); + __func__, v->efuse.reg[opp], v->efuse.reg_bits, v->value[opp], + val); return val; } @@ -529,16 +539,19 @@ void __weak recalibrate_iodelay(void) */ void scale_vcores(struct vcores_data const *vcores) { - int i; + int i, opp, j, ol; struct volts *pv = (struct volts *)vcores; struct volts *px; for (i=0; i<(sizeof(struct vcores_data)/sizeof(struct volts)); i++) { - debug("%d -> ", pv->value); - if (pv->value) { + opp = get_voltrail_opp(i); + debug("%d -> ", pv->value[opp]); + + if (pv->value[opp]) { /* Handle non-empty members only */ - pv->value = optimize_vcore_voltage(pv); + pv->value[opp] = optimize_vcore_voltage(pv, opp); px = (struct volts *)vcores; + j = 0; while (px < pv) { /* * Scan already handled non-empty members to see @@ -547,26 +560,29 @@ void scale_vcores(struct vcores_data const *vcores) * particular SMPS; the other group voltages are * zeroed. */ - if (px->value) { - if ((pv->pmic->i2c_slave_addr == - px->pmic->i2c_slave_addr) && - (pv->addr == px->addr)) { - /* Same PMIC, same SMPS */ - if (pv->value > px->value) - px->value = pv->value; - - pv->value = 0; - } - } + ol = get_voltrail_opp(j); + if (px->value[ol] && + (pv->pmic->i2c_slave_addr == + px->pmic->i2c_slave_addr) && + (pv->addr == px->addr)) { + /* Same PMIC, same SMPS */ + if (pv->value[opp] > px->value[ol]) + px->value[ol] = pv->value[opp]; + + pv->value[opp] = 0; + } px++; + j++; } } - debug("%d\n", pv->value); + debug("%d\n", pv->value[opp]); pv++; } - debug("cor: %d\n", vcores->core.value); - do_scale_vcore(vcores->core.addr, vcores->core.value, vcores->core.pmic); + opp = get_voltrail_opp(VOLT_CORE); + debug("cor: %d\n", vcores->core.value[opp]); + do_scale_vcore(vcores->core.addr, vcores->core.value[opp], + vcores->core.pmic); /* * IO delay recalibration should be done immediately after * adjusting AVS voltages for VDD_CORE_L. @@ -577,10 +593,12 @@ void scale_vcores(struct vcores_data const *vcores) recalibrate_iodelay(); #endif - debug("mpu: %d\n", vcores->mpu.value); - do_scale_vcore(vcores->mpu.addr, vcores->mpu.value, vcores->mpu.pmic); + opp = get_voltrail_opp(VOLT_MPU); + debug("mpu: %d\n", vcores->mpu.value[opp]); + do_scale_vcore(vcores->mpu.addr, vcores->mpu.value[opp], + vcores->mpu.pmic); /* Configure MPU ABB LDO after scale */ - abb_setup(vcores->mpu.efuse.reg, + abb_setup(vcores->mpu.efuse.reg[opp], (*ctrl)->control_wkup_ldovbb_mpu_voltage_ctrl, (*prcm)->prm_abbldo_mpu_setup, (*prcm)->prm_abbldo_mpu_ctrl, @@ -588,10 +606,12 @@ void scale_vcores(struct vcores_data const *vcores) vcores->mpu.abb_tx_done_mask, OMAP_ABB_FAST_OPP); - debug("mm: %d\n", vcores->mm.value); - do_scale_vcore(vcores->mm.addr, vcores->mm.value, vcores->mm.pmic); + opp = get_voltrail_opp(VOLT_MM); + debug("mm: %d\n", vcores->mm.value[opp]); + do_scale_vcore(vcores->mm.addr, vcores->mm.value[opp], + vcores->mm.pmic); /* Configure MM ABB LDO after scale */ - abb_setup(vcores->mm.efuse.reg, + abb_setup(vcores->mm.efuse.reg[opp], (*ctrl)->control_wkup_ldovbb_mm_voltage_ctrl, (*prcm)->prm_abbldo_mm_setup, (*prcm)->prm_abbldo_mm_ctrl, @@ -599,30 +619,38 @@ void scale_vcores(struct vcores_data const *vcores) vcores->mm.abb_tx_done_mask, OMAP_ABB_FAST_OPP); - debug("gpu: %d\n", vcores->gpu.value); - do_scale_vcore(vcores->gpu.addr, vcores->gpu.value, vcores->gpu.pmic); + opp = get_voltrail_opp(VOLT_GPU); + debug("gpu: %d\n", vcores->gpu.value[opp]); + do_scale_vcore(vcores->gpu.addr, vcores->gpu.value[opp], + vcores->gpu.pmic); /* Configure GPU ABB LDO after scale */ - abb_setup(vcores->gpu.efuse.reg, + abb_setup(vcores->gpu.efuse.reg[opp], (*ctrl)->control_wkup_ldovbb_gpu_voltage_ctrl, (*prcm)->prm_abbldo_gpu_setup, (*prcm)->prm_abbldo_gpu_ctrl, (*prcm)->prm_irqstatus_mpu, vcores->gpu.abb_tx_done_mask, OMAP_ABB_FAST_OPP); - debug("eve: %d\n", vcores->eve.value); - do_scale_vcore(vcores->eve.addr, vcores->eve.value, vcores->eve.pmic); + + opp = get_voltrail_opp(VOLT_EVE); + debug("eve: %d\n", vcores->eve.value[opp]); + do_scale_vcore(vcores->eve.addr, vcores->eve.value[opp], + vcores->eve.pmic); /* Configure EVE ABB LDO after scale */ - abb_setup(vcores->eve.efuse.reg, + abb_setup(vcores->eve.efuse.reg[opp], (*ctrl)->control_wkup_ldovbb_eve_voltage_ctrl, (*prcm)->prm_abbldo_eve_setup, (*prcm)->prm_abbldo_eve_ctrl, (*prcm)->prm_irqstatus_mpu, vcores->eve.abb_tx_done_mask, OMAP_ABB_FAST_OPP); - debug("iva: %d\n", vcores->iva.value); - do_scale_vcore(vcores->iva.addr, vcores->iva.value, vcores->iva.pmic); + + opp = get_voltrail_opp(VOLT_IVA); + debug("iva: %d\n", vcores->iva.value[opp]); + do_scale_vcore(vcores->iva.addr, vcores->iva.value[opp], + vcores->iva.pmic); /* Configure IVA ABB LDO after scale */ - abb_setup(vcores->iva.efuse.reg, + abb_setup(vcores->iva.efuse.reg[opp], (*ctrl)->control_wkup_ldovbb_iva_voltage_ctrl, (*prcm)->prm_abbldo_iva_setup, (*prcm)->prm_abbldo_iva_ctrl, diff --git a/arch/arm/mach-omap2/omap4/hw_data.c b/arch/arm/mach-omap2/omap4/hw_data.c index 02c06c1..6a4b8b9 100644 --- a/arch/arm/mach-omap2/omap4/hw_data.c +++ b/arch/arm/mach-omap2/omap4/hw_data.c @@ -261,43 +261,43 @@ struct pmic_data tps62361 = { }; struct vcores_data omap4430_volts_es1 = { - .mpu.value = 1325, + .mpu.value[OPP_NOM] = 1325, .mpu.addr = SMPS_REG_ADDR_VCORE1, .mpu.pmic = &twl6030_4430es1, - .core.value = 1200, + .core.value[OPP_NOM] = 1200, .core.addr = SMPS_REG_ADDR_VCORE3, .core.pmic = &twl6030_4430es1, - .mm.value = 1200, + .mm.value[OPP_NOM] = 1200, .mm.addr = SMPS_REG_ADDR_VCORE2, .mm.pmic = &twl6030_4430es1, }; struct vcores_data omap4430_volts = { - .mpu.value = 1325, + .mpu.value[OPP_NOM] = 1325, .mpu.addr = SMPS_REG_ADDR_VCORE1, .mpu.pmic = &twl6030, - .core.value = 1200, + .core.value[OPP_NOM] = 1200, .core.addr = SMPS_REG_ADDR_VCORE3, .core.pmic = &twl6030, - .mm.value = 1200, + .mm.value[OPP_NOM] = 1200, .mm.addr = SMPS_REG_ADDR_VCORE2, .mm.pmic = &twl6030, }; struct vcores_data omap4460_volts = { - .mpu.value = 1203, + .mpu.value[OPP_NOM] = 1203, .mpu.addr = TPS62361_REG_ADDR_SET1, .mpu.pmic = &tps62361, - .core.value = 1200, + .core.value[OPP_NOM] = 1200, .core.addr = SMPS_REG_ADDR_VCORE1, .core.pmic = &twl6030, - .mm.value = 1200, + .mm.value[OPP_NOM] = 1200, .mm.addr = SMPS_REG_ADDR_VCORE2, .mm.pmic = &twl6030, }; @@ -307,15 +307,15 @@ struct vcores_data omap4460_volts = { * voltage selection code. Aligned with OMAP4470 ES1.0 OCA V.0.7. */ struct vcores_data omap4470_volts = { - .mpu.value = 1202, + .mpu.value[OPP_NOM] = 1202, .mpu.addr = SMPS_REG_ADDR_SMPS1, .mpu.pmic = &twl6030, - .core.value = 1126, + .core.value[OPP_NOM] = 1126, .core.addr = SMPS_REG_ADDR_SMPS2, .core.pmic = &twl6030, - .mm.value = 1139, + .mm.value[OPP_NOM] = 1139, .mm.addr = SMPS_REG_ADDR_SMPS5, .mm.pmic = &twl6030, }; diff --git a/arch/arm/mach-omap2/omap5/hw_data.c b/arch/arm/mach-omap2/omap5/hw_data.c index 02f086b..c85c71a 100644 --- a/arch/arm/mach-omap2/omap5/hw_data.c +++ b/arch/arm/mach-omap2/omap5/hw_data.c @@ -337,30 +337,30 @@ struct pmic_data tps659038 = { }; struct vcores_data omap5430_volts = { - .mpu.value = VDD_MPU, + .mpu.value[OPP_NOM] = VDD_MPU, .mpu.addr = SMPS_REG_ADDR_12_MPU, .mpu.pmic = &palmas, - .core.value = VDD_CORE, + .core.value[OPP_NOM] = VDD_CORE, .core.addr = SMPS_REG_ADDR_8_CORE, .core.pmic = &palmas, - .mm.value = VDD_MM, + .mm.value[OPP_NOM] = VDD_MM, .mm.addr = SMPS_REG_ADDR_45_IVA, .mm.pmic = &palmas, }; struct vcores_data omap5430_volts_es2 = { - .mpu.value = VDD_MPU_ES2, + .mpu.value[OPP_NOM] = VDD_MPU_ES2, .mpu.addr = SMPS_REG_ADDR_12_MPU, .mpu.pmic = &palmas, .mpu.abb_tx_done_mask = OMAP_ABB_MPU_TXDONE_MASK, - .core.value = VDD_CORE_ES2, + .core.value[OPP_NOM] = VDD_CORE_ES2, .core.addr = SMPS_REG_ADDR_8_CORE, .core.pmic = &palmas, - .mm.value = VDD_MM_ES2, + .mm.value[OPP_NOM] = VDD_MM_ES2, .mm.addr = SMPS_REG_ADDR_45_IVA, .mm.pmic = &palmas, .mm.abb_tx_done_mask = OMAP_ABB_MM_TXDONE_MASK, |