diff --git a/arch/arm/include/asm/omap_common.h b/arch/arm/include/asm/omap_common.h
index 290a190c7b59f1be0654e40d7443228c6e088b98..c3d5cda6a1eeee10bce8f3772c14d65dc5a1d545 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 9b975831046ddedf0166ded2599489608c8cc5de..84f93e73f6d09c99c3e9f42374a7c658747bab1c 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 02c06c157760853a35684aa6099500e7077a74df..6a4b8b93c0db72a01e0dabbb5e2cec92f42c3175 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 02f086b2fbae3ed5100a000b9f160afaae92eae5..c85c71a87c3d01088fae5ffe7e1fcbfe4cb68ffb 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,
diff --git a/board/ti/am57xx/board.c b/board/ti/am57xx/board.c
index 9dcc302d13bf96b176c5d85ece1c580e603a4b49..02cedbaa9c62df19ab7897a9e009ae6dbde2e720 100644
--- a/board/ti/am57xx/board.c
+++ b/board/ti/am57xx/board.c
@@ -217,35 +217,47 @@ void emif_get_ext_phy_ctrl_const_regs(u32 emif_nr, const u32 **regs, u32 *size)
 }
 
 struct vcores_data beagle_x15_volts = {
-	.mpu.value		= VDD_MPU_DRA7,
-	.mpu.efuse.reg		= STD_FUSE_OPP_VMIN_MPU,
+	.mpu.value[OPP_NOM]	= VDD_MPU_DRA7_NOM,
+	.mpu.efuse.reg[OPP_NOM]	= STD_FUSE_OPP_VMIN_MPU_NOM,
 	.mpu.efuse.reg_bits     = DRA752_EFUSE_REGBITS,
 	.mpu.addr		= TPS659038_REG_ADDR_SMPS12,
 	.mpu.pmic		= &tps659038,
 	.mpu.abb_tx_done_mask	= OMAP_ABB_MPU_TXDONE_MASK,
 
-	.eve.value		= VDD_EVE_DRA7,
-	.eve.efuse.reg		= STD_FUSE_OPP_VMIN_DSPEVE,
+	.eve.value[OPP_NOM]	= VDD_EVE_DRA7_NOM,
+	.eve.value[OPP_OD]	= VDD_EVE_DRA7_OD,
+	.eve.value[OPP_HIGH]	= VDD_EVE_DRA7_HIGH,
+	.eve.efuse.reg[OPP_NOM]	= STD_FUSE_OPP_VMIN_DSPEVE_NOM,
+	.eve.efuse.reg[OPP_OD]	= STD_FUSE_OPP_VMIN_DSPEVE_OD,
+	.eve.efuse.reg[OPP_HIGH]	= STD_FUSE_OPP_VMIN_DSPEVE_HIGH,
 	.eve.efuse.reg_bits	= DRA752_EFUSE_REGBITS,
 	.eve.addr		= TPS659038_REG_ADDR_SMPS45,
 	.eve.pmic		= &tps659038,
 	.eve.abb_tx_done_mask	= OMAP_ABB_EVE_TXDONE_MASK,
 
-	.gpu.value		= VDD_GPU_DRA7,
-	.gpu.efuse.reg		= STD_FUSE_OPP_VMIN_GPU,
+	.gpu.value[OPP_NOM]	= VDD_GPU_DRA7_NOM,
+	.gpu.value[OPP_OD]	= VDD_GPU_DRA7_OD,
+	.gpu.value[OPP_HIGH]	= VDD_GPU_DRA7_HIGH,
+	.gpu.efuse.reg[OPP_NOM]	= STD_FUSE_OPP_VMIN_GPU_NOM,
+	.gpu.efuse.reg[OPP_OD]	= STD_FUSE_OPP_VMIN_GPU_OD,
+	.gpu.efuse.reg[OPP_HIGH]	= STD_FUSE_OPP_VMIN_GPU_HIGH,
 	.gpu.efuse.reg_bits	= DRA752_EFUSE_REGBITS,
 	.gpu.addr		= TPS659038_REG_ADDR_SMPS45,
 	.gpu.pmic		= &tps659038,
 	.gpu.abb_tx_done_mask	= OMAP_ABB_GPU_TXDONE_MASK,
 
-	.core.value		= VDD_CORE_DRA7,
-	.core.efuse.reg		= STD_FUSE_OPP_VMIN_CORE,
+	.core.value[OPP_NOM]	= VDD_CORE_DRA7_NOM,
+	.core.efuse.reg[OPP_NOM]	= STD_FUSE_OPP_VMIN_CORE_NOM,
 	.core.efuse.reg_bits	= DRA752_EFUSE_REGBITS,
 	.core.addr		= TPS659038_REG_ADDR_SMPS6,
 	.core.pmic		= &tps659038,
 
-	.iva.value		= VDD_IVA_DRA7,
-	.iva.efuse.reg		= STD_FUSE_OPP_VMIN_IVA,
+	.iva.value[OPP_NOM]	= VDD_IVA_DRA7_NOM,
+	.iva.value[OPP_OD]	= VDD_IVA_DRA7_OD,
+	.iva.value[OPP_HIGH]	= VDD_IVA_DRA7_HIGH,
+	.iva.efuse.reg[OPP_NOM]	= STD_FUSE_OPP_VMIN_IVA_NOM,
+	.iva.efuse.reg[OPP_OD]	= STD_FUSE_OPP_VMIN_IVA_OD,
+	.iva.efuse.reg[OPP_HIGH]	= STD_FUSE_OPP_VMIN_IVA_HIGH,
 	.iva.efuse.reg_bits	= DRA752_EFUSE_REGBITS,
 	.iva.addr		= TPS659038_REG_ADDR_SMPS45,
 	.iva.pmic		= &tps659038,
@@ -253,41 +265,81 @@ struct vcores_data beagle_x15_volts = {
 };
 
 struct vcores_data am572x_idk_volts = {
-	.mpu.value		= VDD_MPU_DRA7,
-	.mpu.efuse.reg		= STD_FUSE_OPP_VMIN_MPU,
+	.mpu.value[OPP_NOM]	= VDD_MPU_DRA7_NOM,
+	.mpu.efuse.reg[OPP_NOM]	= STD_FUSE_OPP_VMIN_MPU_NOM,
 	.mpu.efuse.reg_bits     = DRA752_EFUSE_REGBITS,
 	.mpu.addr		= TPS659038_REG_ADDR_SMPS12,
 	.mpu.pmic		= &tps659038,
 	.mpu.abb_tx_done_mask	= OMAP_ABB_MPU_TXDONE_MASK,
 
-	.eve.value		= VDD_EVE_DRA7,
-	.eve.efuse.reg		= STD_FUSE_OPP_VMIN_DSPEVE,
+	.eve.value[OPP_NOM]	= VDD_EVE_DRA7_NOM,
+	.eve.value[OPP_OD]	= VDD_EVE_DRA7_OD,
+	.eve.value[OPP_HIGH]	= VDD_EVE_DRA7_HIGH,
+	.eve.efuse.reg[OPP_NOM]	= STD_FUSE_OPP_VMIN_DSPEVE_NOM,
+	.eve.efuse.reg[OPP_OD]	= STD_FUSE_OPP_VMIN_DSPEVE_OD,
+	.eve.efuse.reg[OPP_HIGH]	= STD_FUSE_OPP_VMIN_DSPEVE_HIGH,
 	.eve.efuse.reg_bits	= DRA752_EFUSE_REGBITS,
 	.eve.addr		= TPS659038_REG_ADDR_SMPS45,
 	.eve.pmic		= &tps659038,
 	.eve.abb_tx_done_mask	= OMAP_ABB_EVE_TXDONE_MASK,
 
-	.gpu.value		= VDD_GPU_DRA7,
-	.gpu.efuse.reg		= STD_FUSE_OPP_VMIN_GPU,
+	.gpu.value[OPP_NOM]	= VDD_GPU_DRA7_NOM,
+	.gpu.value[OPP_OD]	= VDD_GPU_DRA7_OD,
+	.gpu.value[OPP_HIGH]	= VDD_GPU_DRA7_HIGH,
+	.gpu.efuse.reg[OPP_NOM]	= STD_FUSE_OPP_VMIN_GPU_NOM,
+	.gpu.efuse.reg[OPP_OD]	= STD_FUSE_OPP_VMIN_GPU_OD,
+	.gpu.efuse.reg[OPP_HIGH]	= STD_FUSE_OPP_VMIN_GPU_HIGH,
 	.gpu.efuse.reg_bits	= DRA752_EFUSE_REGBITS,
 	.gpu.addr		= TPS659038_REG_ADDR_SMPS6,
 	.gpu.pmic		= &tps659038,
 	.gpu.abb_tx_done_mask	= OMAP_ABB_GPU_TXDONE_MASK,
 
-	.core.value		= VDD_CORE_DRA7,
-	.core.efuse.reg		= STD_FUSE_OPP_VMIN_CORE,
+	.core.value[OPP_NOM]	= VDD_CORE_DRA7_NOM,
+	.core.efuse.reg[OPP_NOM]	= STD_FUSE_OPP_VMIN_CORE_NOM,
 	.core.efuse.reg_bits	= DRA752_EFUSE_REGBITS,
 	.core.addr		= TPS659038_REG_ADDR_SMPS7,
 	.core.pmic		= &tps659038,
 
-	.iva.value		= VDD_IVA_DRA7,
-	.iva.efuse.reg		= STD_FUSE_OPP_VMIN_IVA,
+	.iva.value[OPP_NOM]	= VDD_IVA_DRA7_NOM,
+	.iva.value[OPP_OD]	= VDD_IVA_DRA7_OD,
+	.iva.value[OPP_HIGH]	= VDD_IVA_DRA7_HIGH,
+	.iva.efuse.reg[OPP_NOM]	= STD_FUSE_OPP_VMIN_IVA_NOM,
+	.iva.efuse.reg[OPP_OD]	= STD_FUSE_OPP_VMIN_IVA_OD,
+	.iva.efuse.reg[OPP_HIGH]	= STD_FUSE_OPP_VMIN_IVA_HIGH,
 	.iva.efuse.reg_bits	= DRA752_EFUSE_REGBITS,
 	.iva.addr		= TPS659038_REG_ADDR_SMPS8,
 	.iva.pmic		= &tps659038,
 	.iva.abb_tx_done_mask	= OMAP_ABB_IVA_TXDONE_MASK,
 };
 
+int get_voltrail_opp(int rail_offset)
+{
+	int opp;
+
+	switch (rail_offset) {
+	case VOLT_MPU:
+		opp = DRA7_MPU_OPP;
+		break;
+	case VOLT_CORE:
+		opp = DRA7_CORE_OPP;
+		break;
+	case VOLT_GPU:
+		opp = DRA7_GPU_OPP;
+		break;
+	case VOLT_EVE:
+		opp = DRA7_DSPEVE_OPP;
+		break;
+	case VOLT_IVA:
+		opp = DRA7_IVA_OPP;
+		break;
+	default:
+		opp = OPP_NOM;
+	}
+
+	return opp;
+}
+
+
 #ifdef CONFIG_SPL_BUILD
 /* No env to setup for SPL */
 static inline void setup_board_eeprom_env(void) { }
diff --git a/board/ti/dra7xx/evm.c b/board/ti/dra7xx/evm.c
index 31c52a6afb809f11d36b850b00f5a42d297dcf68..432ebd12e05040bf8d3dfca06549f2ad570809b8 100644
--- a/board/ti/dra7xx/evm.c
+++ b/board/ti/dra7xx/evm.c
@@ -308,35 +308,47 @@ void emif_get_dmm_regs(const struct dmm_lisa_map_regs **dmm_lisa_regs)
 }
 
 struct vcores_data dra752_volts = {
-	.mpu.value	= VDD_MPU_DRA7,
-	.mpu.efuse.reg	= STD_FUSE_OPP_VMIN_MPU,
+	.mpu.value[OPP_NOM]	= VDD_MPU_DRA7_NOM,
+	.mpu.efuse.reg[OPP_NOM]	= STD_FUSE_OPP_VMIN_MPU_NOM,
 	.mpu.efuse.reg_bits	= DRA752_EFUSE_REGBITS,
 	.mpu.addr	= TPS659038_REG_ADDR_SMPS12,
 	.mpu.pmic	= &tps659038,
 	.mpu.abb_tx_done_mask = OMAP_ABB_MPU_TXDONE_MASK,
 
-	.eve.value	= VDD_EVE_DRA7,
-	.eve.efuse.reg	= STD_FUSE_OPP_VMIN_DSPEVE,
+	.eve.value[OPP_NOM]	= VDD_EVE_DRA7_NOM,
+	.eve.value[OPP_OD]	= VDD_EVE_DRA7_OD,
+	.eve.value[OPP_HIGH]	= VDD_EVE_DRA7_HIGH,
+	.eve.efuse.reg[OPP_NOM]	= STD_FUSE_OPP_VMIN_DSPEVE_NOM,
+	.eve.efuse.reg[OPP_OD]	= STD_FUSE_OPP_VMIN_DSPEVE_OD,
+	.eve.efuse.reg[OPP_HIGH]	= STD_FUSE_OPP_VMIN_DSPEVE_HIGH,
 	.eve.efuse.reg_bits	= DRA752_EFUSE_REGBITS,
 	.eve.addr	= TPS659038_REG_ADDR_SMPS45,
 	.eve.pmic	= &tps659038,
 	.eve.abb_tx_done_mask = OMAP_ABB_EVE_TXDONE_MASK,
 
-	.gpu.value	= VDD_GPU_DRA7,
-	.gpu.efuse.reg	= STD_FUSE_OPP_VMIN_GPU,
+	.gpu.value[OPP_NOM]	= VDD_GPU_DRA7_NOM,
+	.gpu.value[OPP_OD]	= VDD_GPU_DRA7_OD,
+	.gpu.value[OPP_HIGH]	= VDD_GPU_DRA7_HIGH,
+	.gpu.efuse.reg[OPP_NOM]	= STD_FUSE_OPP_VMIN_GPU_NOM,
+	.gpu.efuse.reg[OPP_OD]	= STD_FUSE_OPP_VMIN_GPU_OD,
+	.gpu.efuse.reg[OPP_HIGH]	= STD_FUSE_OPP_VMIN_GPU_HIGH,
 	.gpu.efuse.reg_bits	= DRA752_EFUSE_REGBITS,
 	.gpu.addr	= TPS659038_REG_ADDR_SMPS6,
 	.gpu.pmic	= &tps659038,
 	.gpu.abb_tx_done_mask = OMAP_ABB_GPU_TXDONE_MASK,
 
-	.core.value	= VDD_CORE_DRA7,
-	.core.efuse.reg	= STD_FUSE_OPP_VMIN_CORE,
+	.core.value[OPP_NOM]	= VDD_CORE_DRA7_NOM,
+	.core.efuse.reg[OPP_NOM]	= STD_FUSE_OPP_VMIN_CORE_NOM,
 	.core.efuse.reg_bits = DRA752_EFUSE_REGBITS,
 	.core.addr	= TPS659038_REG_ADDR_SMPS7,
 	.core.pmic	= &tps659038,
 
-	.iva.value	= VDD_IVA_DRA7,
-	.iva.efuse.reg	= STD_FUSE_OPP_VMIN_IVA,
+	.iva.value[OPP_NOM]	= VDD_IVA_DRA7_NOM,
+	.iva.value[OPP_OD]	= VDD_IVA_DRA7_OD,
+	.iva.value[OPP_HIGH]	= VDD_IVA_DRA7_HIGH,
+	.iva.efuse.reg[OPP_NOM]	= STD_FUSE_OPP_VMIN_IVA_NOM,
+	.iva.efuse.reg[OPP_OD]	= STD_FUSE_OPP_VMIN_IVA_OD,
+	.iva.efuse.reg[OPP_HIGH]	= STD_FUSE_OPP_VMIN_IVA_HIGH,
 	.iva.efuse.reg_bits	= DRA752_EFUSE_REGBITS,
 	.iva.addr	= TPS659038_REG_ADDR_SMPS8,
 	.iva.pmic	= &tps659038,
@@ -344,15 +356,15 @@ struct vcores_data dra752_volts = {
 };
 
 struct vcores_data dra722_volts = {
-	.mpu.value	= VDD_MPU_DRA7,
-	.mpu.efuse.reg	= STD_FUSE_OPP_VMIN_MPU,
+	.mpu.value[OPP_NOM]	= VDD_MPU_DRA7_NOM,
+	.mpu.efuse.reg[OPP_NOM]	= STD_FUSE_OPP_VMIN_MPU_NOM,
 	.mpu.efuse.reg_bits = DRA752_EFUSE_REGBITS,
 	.mpu.addr	= TPS65917_REG_ADDR_SMPS1,
 	.mpu.pmic	= &tps659038,
 	.mpu.abb_tx_done_mask = OMAP_ABB_MPU_TXDONE_MASK,
 
-	.core.value	= VDD_CORE_DRA7,
-	.core.efuse.reg	= STD_FUSE_OPP_VMIN_CORE,
+	.core.value[OPP_NOM]	= VDD_CORE_DRA7_NOM,
+	.core.efuse.reg[OPP_NOM]	= STD_FUSE_OPP_VMIN_CORE_NOM,
 	.core.efuse.reg_bits = DRA752_EFUSE_REGBITS,
 	.core.addr	= TPS65917_REG_ADDR_SMPS2,
 	.core.pmic	= &tps659038,
@@ -361,28 +373,67 @@ struct vcores_data dra722_volts = {
 	 * The DSPEVE, GPU and IVA rails are usually grouped on DRA72x
 	 * designs and powered by TPS65917 SMPS3, as on the J6Eco EVM.
 	 */
-	.gpu.value	= VDD_GPU_DRA7,
-	.gpu.efuse.reg	= STD_FUSE_OPP_VMIN_GPU,
+	.gpu.value[OPP_NOM]	= VDD_GPU_DRA7_NOM,
+	.gpu.value[OPP_OD]	= VDD_GPU_DRA7_OD,
+	.gpu.value[OPP_HIGH]	= VDD_GPU_DRA7_HIGH,
+	.gpu.efuse.reg[OPP_NOM]	= STD_FUSE_OPP_VMIN_GPU_NOM,
+	.gpu.efuse.reg[OPP_OD]	= STD_FUSE_OPP_VMIN_GPU_OD,
+	.gpu.efuse.reg[OPP_HIGH]	= STD_FUSE_OPP_VMIN_GPU_HIGH,
 	.gpu.efuse.reg_bits = DRA752_EFUSE_REGBITS,
 	.gpu.addr	= TPS65917_REG_ADDR_SMPS3,
 	.gpu.pmic	= &tps659038,
 	.gpu.abb_tx_done_mask = OMAP_ABB_GPU_TXDONE_MASK,
 
-	.eve.value	= VDD_EVE_DRA7,
-	.eve.efuse.reg	= STD_FUSE_OPP_VMIN_DSPEVE,
+	.eve.value[OPP_NOM]	= VDD_EVE_DRA7_NOM,
+	.eve.value[OPP_OD]	= VDD_EVE_DRA7_OD,
+	.eve.value[OPP_HIGH]	= VDD_EVE_DRA7_HIGH,
+	.eve.efuse.reg[OPP_NOM]	= STD_FUSE_OPP_VMIN_DSPEVE_NOM,
+	.eve.efuse.reg[OPP_OD]	= STD_FUSE_OPP_VMIN_DSPEVE_OD,
+	.eve.efuse.reg[OPP_HIGH]	= STD_FUSE_OPP_VMIN_DSPEVE_HIGH,
 	.eve.efuse.reg_bits = DRA752_EFUSE_REGBITS,
 	.eve.addr	= TPS65917_REG_ADDR_SMPS3,
 	.eve.pmic	= &tps659038,
 	.eve.abb_tx_done_mask = OMAP_ABB_EVE_TXDONE_MASK,
 
-	.iva.value	= VDD_IVA_DRA7,
-	.iva.efuse.reg	= STD_FUSE_OPP_VMIN_IVA,
+	.iva.value[OPP_NOM]	= VDD_IVA_DRA7_NOM,
+	.iva.value[OPP_OD]	= VDD_IVA_DRA7_OD,
+	.iva.value[OPP_HIGH]	= VDD_IVA_DRA7_HIGH,
+	.iva.efuse.reg[OPP_NOM]	= STD_FUSE_OPP_VMIN_IVA_NOM,
+	.iva.efuse.reg[OPP_OD]	= STD_FUSE_OPP_VMIN_IVA_OD,
+	.iva.efuse.reg[OPP_HIGH]	= STD_FUSE_OPP_VMIN_IVA_HIGH,
 	.iva.efuse.reg_bits = DRA752_EFUSE_REGBITS,
 	.iva.addr	= TPS65917_REG_ADDR_SMPS3,
 	.iva.pmic	= &tps659038,
 	.iva.abb_tx_done_mask = OMAP_ABB_IVA_TXDONE_MASK,
 };
 
+int get_voltrail_opp(int rail_offset)
+{
+	int opp;
+
+	switch (rail_offset) {
+	case VOLT_MPU:
+		opp = DRA7_MPU_OPP;
+		break;
+	case VOLT_CORE:
+		opp = DRA7_CORE_OPP;
+		break;
+	case VOLT_GPU:
+		opp = DRA7_GPU_OPP;
+		break;
+	case VOLT_EVE:
+		opp = DRA7_DSPEVE_OPP;
+		break;
+	case VOLT_IVA:
+		opp = DRA7_IVA_OPP;
+		break;
+	default:
+		opp = OPP_NOM;
+	}
+
+	return opp;
+}
+
 /**
  * @brief board_init
  *