On Fri, Dec 19, 2014 at 05:34:31PM +0200, Lubomir Popov wrote: > 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-po...@ti.com>
Nishanth or Lokesh, any comments here? Thanks! > --- > Tested on the Vayu and J6Eco EVMs. > > arch/arm/cpu/armv7/omap-common/clocks-common.c | 83 > ++++++++++++++++++++++-- > arch/arm/cpu/armv7/omap5/hw_data.c | 43 ++++++------ > arch/arm/include/asm/arch-omap5/clock.h | 20 +++++- > 3 files changed, 118 insertions(+), 28 deletions(-) > > diff --git a/arch/arm/cpu/armv7/omap-common/clocks-common.c > b/arch/arm/cpu/armv7/omap-common/clocks-common.c > index 8e7411d..b036cbc 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 95f1686..b9734fe 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, > }; > > diff --git a/arch/arm/include/asm/arch-omap5/clock.h > b/arch/arm/include/asm/arch-omap5/clock.h > index 0dc584b..f8e5630 100644 > --- a/arch/arm/include/asm/arch-omap5/clock.h > +++ b/arch/arm/include/asm/arch-omap5/clock.h > @@ -236,13 +236,20 @@ > #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 > @@ -284,6 +291,13 @@ > #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 > -- > 1.7.9.5 > > _______________________________________________ > U-Boot mailing list > U-Boot@lists.denx.de > http://lists.denx.de/mailman/listinfo/u-boot -- Tom
signature.asc
Description: Digital signature
_______________________________________________ U-Boot mailing list U-Boot@lists.denx.de http://lists.denx.de/mailman/listinfo/u-boot