|
|
|
@ -437,12 +437,15 @@ void do_scale_vcore(u32 vcore_reg, u32 volt_mv, struct pmic_data *pmic) |
|
|
|
|
{ |
|
|
|
|
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"); |
|
|
|
@ -456,7 +459,7 @@ void do_scale_vcore(u32 vcore_reg, u32 volt_mv, struct pmic_data *pmic) |
|
|
|
|
/* 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; |
|
|
|
|
|
|
|
|
@ -467,9 +470,10 @@ void do_scale_vcore(u32 vcore_reg, u32 volt_mv, struct pmic_data *pmic) |
|
|
|
|
|
|
|
|
|
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) |
|
|
|
@ -505,13 +509,79 @@ 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); |
|
|
|
@ -540,6 +610,7 @@ void scale_vcores(struct vcores_data const *vcores) |
|
|
|
|
|
|
|
|
|
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) |
|
|
|
|