{
        u32 offset_code;
        u32 offset = volt_mv;
+#ifndef        CONFIG_DRA7XX
        int ret = 0;
+#endif
 
        if (!volt_mv)
                return;
 
        pmic->pmic_bus_init();
+#ifndef        CONFIG_DRA7XX
        /* See if we can first get the GPIO if needed */
        if (pmic->gpio_en)
                ret = gpio_request(pmic->gpio, "PMIC_GPIO");
        /* Pull the GPIO low to select SET0 register, while we program SET1 */
        if (pmic->gpio_en)
                gpio_direction_output(pmic->gpio, 0);
-
+#endif
        /* convert to uV for better accuracy in the calculations */
        offset *= 1000;
 
 
        if (pmic->pmic_write(pmic->i2c_slave_addr, vcore_reg, offset_code))
                printf("Scaling voltage failed for 0x%x\n", vcore_reg);
-
+#ifndef        CONFIG_DRA7XX
        if (pmic->gpio_en)
                gpio_direction_output(pmic->gpio, 1);
+#endif
 }
 
 static u32 optimize_vcore_voltage(struct volts const *v)
 }
 
 /*
- * Setup the voltages for vdd_mpu, vdd_core, and vdd_iva
- * We set the maximum voltages allowed here because Smart-Reflex is not
- * enabled in bootloader. Voltage initialization in the kernel will set
- * these to the nominal values after enabling Smart-Reflex
+ * Setup the voltages for the main SoC core power domains.
+ * We start with the maximum voltages allowed here, as set in the corresponding
+ * vcores_data struct, and then scale (usually down) to the fused values that
+ * are retrieved from the SoC. The scaling happens only if the efuse.reg fields
+ * are initialised.
+ * Rail grouping is supported for the DRA7xx SoCs only, therefore the code is
+ * compiled conditionally. Note that the new code writes the scaled (or zeroed)
+ * values back to the vcores_data struct for eventual reuse. Zero values mean
+ * that the corresponding rails are not controlled separately, and are not sent
+ * to the PMIC.
  */
 void scale_vcores(struct vcores_data const *vcores)
 {
+#if defined(CONFIG_DRA7XX)
+       int i;
+       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) {
+                       /* Handle non-empty members only */
+                       pv->value = optimize_vcore_voltage(pv);
+                       px = (struct volts *)vcores;
+                       while (px < pv) {
+                               /*
+                                * Scan already handled non-empty members to see
+                                * if we have a group and find the max voltage,
+                                * which is set to the first occurance of the
+                                * 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;
+                                       }
+                               }
+                               px++;
+                       }
+               }
+               debug("%d\n", pv->value);
+               pv++;
+       }
+
+       debug("cor: %d\n", vcores->core.value);
+       do_scale_vcore(vcores->core.addr, vcores->core.value, vcores->core.pmic);
+       debug("mpu: %d\n", vcores->mpu.value);
+       do_scale_vcore(vcores->mpu.addr, vcores->mpu.value, vcores->mpu.pmic);
+       /* Configure MPU ABB LDO after scale */
+       abb_setup((*ctrl)->control_std_fuse_opp_vdd_mpu_2,
+                 (*ctrl)->control_wkup_ldovbb_mpu_voltage_ctrl,
+                 (*prcm)->prm_abbldo_mpu_setup,
+                 (*prcm)->prm_abbldo_mpu_ctrl,
+                 (*prcm)->prm_irqstatus_mpu_2,
+                 OMAP_ABB_MPU_TXDONE_MASK,
+                 OMAP_ABB_FAST_OPP);
+
+       /* The .mm member is not used for the DRA7xx */
+
+       debug("gpu: %d\n", vcores->gpu.value);
+       do_scale_vcore(vcores->gpu.addr, vcores->gpu.value, vcores->gpu.pmic);
+       debug("eve: %d\n", vcores->eve.value);
+       do_scale_vcore(vcores->eve.addr, vcores->eve.value, vcores->eve.pmic);
+       debug("iva: %d\n", vcores->iva.value);
+       do_scale_vcore(vcores->iva.addr, vcores->iva.value, vcores->iva.pmic);
+       /* Might need udelay(1000) here if debug is enabled to see all prints */
+#else
        u32 val;
 
        val = optimize_vcore_voltage(&vcores->core);
 
        val = optimize_vcore_voltage(&vcores->iva);
        do_scale_vcore(vcores->iva.addr, val, vcores->iva.pmic);
+#endif
 }
 
 static inline void enable_clock_domain(u32 const clkctrl_reg, u32 enable_mode)
 
        .pmic_write     = omap_vc_bypass_send_value,
 };
 
+/* The TPS659038 and TPS65917 are software-compatible, use common struct */
 struct pmic_data tps659038 = {
        .base_offset = PALMAS_SMPS_BASE_VOLT_UV,
        .step = 10000, /* 10 mV represented in uV */
 };
 
 struct vcores_data dra722_volts = {
-       .mpu.value      = 1000,
+       .mpu.value      = VDD_MPU_DRA72x,
        .mpu.efuse.reg  = STD_FUSE_OPP_VMIN_MPU_NOM,
-       .mpu.efuse.reg_bits     = DRA752_EFUSE_REGBITS,
-       .mpu.addr       = 0x23,
+       .mpu.efuse.reg_bits = DRA752_EFUSE_REGBITS,
+       .mpu.addr       = TPS65917_REG_ADDR_SMPS1,
        .mpu.pmic       = &tps659038,
 
-       .eve.value      = 1000,
-       .eve.efuse.reg  = STD_FUSE_OPP_VMIN_DSPEVE_NOM,
-       .eve.efuse.reg_bits     = DRA752_EFUSE_REGBITS,
-       .eve.addr       = 0x2f,
-       .eve.pmic       = &tps659038,
+       .core.value     = VDD_CORE_DRA72x,
+       .core.efuse.reg = STD_FUSE_OPP_VMIN_CORE_NOM,
+       .core.efuse.reg_bits = DRA752_EFUSE_REGBITS,
+       .core.addr      = TPS65917_REG_ADDR_SMPS2,
+       .core.pmic      = &tps659038,
 
-       .gpu.value      = 1000,
+       /*
+        * 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_DRA72x,
        .gpu.efuse.reg  = STD_FUSE_OPP_VMIN_GPU_NOM,
-       .gpu.efuse.reg_bits     = DRA752_EFUSE_REGBITS,
-       .gpu.addr       = 0x2f,
+       .gpu.efuse.reg_bits = DRA752_EFUSE_REGBITS,
+       .gpu.addr       = TPS65917_REG_ADDR_SMPS3,
        .gpu.pmic       = &tps659038,
 
-       .core.value     = 1000,
-       .core.efuse.reg = STD_FUSE_OPP_VMIN_CORE_NOM,
-       .core.efuse.reg_bits = DRA752_EFUSE_REGBITS,
-       .core.addr      = 0x27,
-       .core.pmic      = &tps659038,
+       .eve.value      = VDD_EVE_DRA72x,
+       .eve.efuse.reg  = STD_FUSE_OPP_VMIN_DSPEVE_NOM,
+       .eve.efuse.reg_bits = DRA752_EFUSE_REGBITS,
+       .eve.addr       = TPS65917_REG_ADDR_SMPS3,
+       .eve.pmic       = &tps659038,
 
-       .iva.value      = 1000,
+       .iva.value      = VDD_IVA_DRA72x,
        .iva.efuse.reg  = STD_FUSE_OPP_VMIN_IVA_NOM,
-       .iva.efuse.reg_bits     = DRA752_EFUSE_REGBITS,
-       .iva.addr       = 0x2f,
+       .iva.efuse.reg_bits = DRA752_EFUSE_REGBITS,
+       .iva.addr       = TPS65917_REG_ADDR_SMPS3,
        .iva.pmic       = &tps659038,
 };
 
 
 #define VDD_MPU_ES2_LOW 880
 #define VDD_MM_ES2_LOW 880
 
-/* TPS659038 Voltage settings in mv for OPP_NOMINAL */
-#define VDD_MPU_DRA752         1090
+/* DRA74x/75x voltage settings in mv for OPP_NOM per DM */
+#define VDD_MPU_DRA752         1100
 #define VDD_EVE_DRA752         1060
 #define VDD_GPU_DRA752         1060
-#define VDD_CORE_DRA752                1030
+#define VDD_CORE_DRA752                1060
 #define VDD_IVA_DRA752         1060
 
+/* DRA72x voltage settings in mv for OPP_NOM per DM */
+#define VDD_MPU_DRA72x         1100
+#define VDD_EVE_DRA72x         1060
+#define VDD_GPU_DRA72x         1060
+#define VDD_CORE_DRA72x                1060
+#define VDD_IVA_DRA72x         1060
+
 /* Efuse register offsets for DRA7xx platform */
 #define DRA752_EFUSE_BASE      0x4A002000
 #define DRA752_EFUSE_REGBITS   16
 #define TPS659038_REG_ADDR_SMPS7               0x33
 #define TPS659038_REG_ADDR_SMPS8               0x37
 
+/* TPS65917 */
+#define TPS65917_I2C_SLAVE_ADDR                0x58
+#define TPS65917_REG_ADDR_SMPS1                0x23
+#define TPS65917_REG_ADDR_SMPS2                0x27
+#define TPS65917_REG_ADDR_SMPS3                0x2F
+
+
 /* TPS */
 #define TPS62361_I2C_SLAVE_ADDR                0x60
 #define TPS62361_REG_ADDR_SET0         0x0