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

Attachment: signature.asc
Description: Digital signature

_______________________________________________
U-Boot mailing list
U-Boot@lists.denx.de
http://lists.denx.de/mailman/listinfo/u-boot

Reply via email to