summaryrefslogtreecommitdiffstats
path: root/arch/arm/cpu
diff options
context:
space:
mode:
authorLubomir Popov <lpopov@mm-sol.com>2014-12-19 17:34:31 +0200
committerTom Rini <trini@ti.com>2015-01-29 12:00:49 -0500
commitb558af81281975d032c063ad228a400d8e619ad5 (patch)
tree8cb863af9cd24cb23522341ac17172499b5f96f9 /arch/arm/cpu
parent2af13d6b6265a6700c4f65597410b769895024bf (diff)
downloadblackbird-obmc-uboot-b558af81281975d032c063ad228a400d8e619ad5.tar.gz
blackbird-obmc-uboot-b558af81281975d032c063ad228a400d8e619ad5.zip
ARM: OMAP5: DRA7xx: Add support for power rail grouping
On the DRA72x (J6Eco) EVM one PMIC SMPS is powering three SoC core rails. This concept of using one SMPS to supply multiple core domains (in various, although limited combinations, per primary device use case) has now become common and is used by many customer J6/J6Eco designs; it is supported by a number of corresponding PMIC OTP versions. This patch implements correct operation of the core voltages scaling routine by ensuring that each SMPS that is supplying more than one domain shall be written only once, and with the highest voltage of those fused in the SoC (or of those defined in the corresponding header if fuse read is disabled or fails) for the power rails belonging to the group. The patch also replaces some PMIC-related magic numbers with the appropriate definitions. The default OPP_NOM voltages for the DRA7xx SoCs are updated as well, per the latest DMs. Signed-off-by: Lubomir Popov <l-popov@ti.com>
Diffstat (limited to 'arch/arm/cpu')
-rw-r--r--arch/arm/cpu/armv7/omap-common/clocks-common.c83
-rw-r--r--arch/arm/cpu/armv7/omap5/hw_data.c43
2 files changed, 101 insertions, 25 deletions
diff --git a/arch/arm/cpu/armv7/omap-common/clocks-common.c b/arch/arm/cpu/armv7/omap-common/clocks-common.c
index 8e7411d437..03674e609f 100644
--- a/arch/arm/cpu/armv7/omap-common/clocks-common.c
+++ b/arch/arm/cpu/armv7/omap-common/clocks-common.c
@@ -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)
diff --git a/arch/arm/cpu/armv7/omap5/hw_data.c b/arch/arm/cpu/armv7/omap5/hw_data.c
index 95f16866e6..b9734fea8f 100644
--- a/arch/arm/cpu/armv7/omap5/hw_data.c
+++ b/arch/arm/cpu/armv7/omap5/hw_data.c
@@ -320,6 +320,7 @@ struct pmic_data palmas = {
.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 */
@@ -394,34 +395,38 @@ struct vcores_data dra752_volts = {
};
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,
};
OpenPOWER on IntegriCloud