Thara Gopinath <[email protected]> writes:

> This patch adds voltage driver support for OMAP4.

Need a better changelog here... different registers definitions, more
VDDs, etc. etc.

> Signed-off-by: Thara Gopinath <[email protected]>
> ---
>  arch/arm/mach-omap2/Makefile              |    2 +-
>  arch/arm/mach-omap2/voltage.c             |  246 
> ++++++++++++++++++++++++++++-
>  arch/arm/plat-omap/include/plat/voltage.h |   20 +++-
>  3 files changed, 264 insertions(+), 4 deletions(-)
>
> diff --git a/arch/arm/mach-omap2/Makefile b/arch/arm/mach-omap2/Makefile
> index 03e494e..d46fbec 100644
> --- a/arch/arm/mach-omap2/Makefile
> +++ b/arch/arm/mach-omap2/Makefile
> @@ -51,7 +51,7 @@ obj-$(CONFIG_ARCH_OMAP2)            += pm24xx.o
>  obj-$(CONFIG_ARCH_OMAP2)             += sleep24xx.o
>  obj-$(CONFIG_ARCH_OMAP3)             += pm34xx.o sleep34xx.o voltage.o \
>                                          cpuidle34xx.o
> -obj-$(CONFIG_ARCH_OMAP4)             += pm44xx.o
> +obj-$(CONFIG_ARCH_OMAP4)             += pm44xx.o voltage.o
>  obj-$(CONFIG_PM_DEBUG)                       += pm-debug.o
>  obj-$(CONFIG_OMAP_SMARTREFLEX)          += sr_device.o smartreflex.o
>  obj-$(CONFIG_OMAP_SMARTREFLEX_CLASS3)        += smartreflex-class3.o
> diff --git a/arch/arm/mach-omap2/voltage.c b/arch/arm/mach-omap2/voltage.c
> index d15c5cb..6a07fe9 100644
> --- a/arch/arm/mach-omap2/voltage.c
> +++ b/arch/arm/mach-omap2/voltage.c
> @@ -34,6 +34,8 @@
>  #include <plat/voltage.h>
>  
>  #include "prm-regbits-34xx.h"
> +#include "prm44xx.h"
> +#include "prm-regbits-44xx.h"
>  
>  #define VP_IDLE_TIMEOUT              200
>  #define VP_TRANXDONE_TIMEOUT 300
> @@ -158,7 +160,49 @@ static struct omap_vdd_info omap3_vdd_info[] = {
>  
>  #define OMAP3_NO_SCALABLE_VDD ARRAY_SIZE(omap3_vdd_info)
>  
> -/* TODO: OMAP4 register offsets */
> +/* OMAP4 VDD sturctures */
> +static struct omap_vdd_info omap4_vdd_info[] = {
> +     {
> +             .vp_offs = {
> +                     .vpconfig = OMAP4_PRM_VP_MPU_CONFIG_OFFSET,
> +                     .vstepmin = OMAP4_PRM_VP_MPU_VSTEPMIN_OFFSET,
> +                     .vstepmax = OMAP4_PRM_VP_MPU_VSTEPMAX_OFFSET,
> +                     .vlimitto = OMAP4_PRM_VP_MPU_VLIMITTO_OFFSET,
> +                     .vstatus = OMAP4_PRM_VP_MPU_STATUS_OFFSET,
> +                     .voltage = OMAP4_PRM_VP_MPU_VOLTAGE_OFFSET,
> +             },
> +             .voltdm = {
> +                     .name = "mpu",
> +             },
> +     },
> +     {
> +             .vp_offs = {
> +                     .vpconfig = OMAP4_PRM_VP_IVA_CONFIG_OFFSET,
> +                     .vstepmin = OMAP4_PRM_VP_IVA_VSTEPMIN_OFFSET,
> +                     .vstepmax = OMAP4_PRM_VP_IVA_VSTEPMAX_OFFSET,
> +                     .vlimitto = OMAP4_PRM_VP_IVA_VLIMITTO_OFFSET,
> +                     .vstatus = OMAP4_PRM_VP_IVA_STATUS_OFFSET,
> +                     .voltage = OMAP4_PRM_VP_IVA_VOLTAGE_OFFSET,
> +             },
> +             .voltdm = {
> +                     .name = "iva",
> +             },
> +     },
> +     {
> +             .vp_offs = {
> +                     .vpconfig = OMAP4_PRM_VP_CORE_CONFIG_OFFSET,
> +                     .vstepmin = OMAP4_PRM_VP_CORE_VSTEPMIN_OFFSET,
> +                     .vstepmax = OMAP4_PRM_VP_CORE_VSTEPMAX_OFFSET,
> +                     .vlimitto = OMAP4_PRM_VP_CORE_VLIMITTO_OFFSET,
> +                     .vstatus = OMAP4_PRM_VP_CORE_STATUS_OFFSET,
> +                     .voltage = OMAP4_PRM_VP_CORE_VOLTAGE_OFFSET,
> +             },
> +             .voltdm = {
> +                     .name = "core",
> +             },
> +     },
> +};
> +#define OMAP4_NO_SCALABLE_VDD ARRAY_SIZE(omap4_vdd_info)

same comment as with OMAP3 version: drop the 'NO' part in favor of _NUM,
or _NR.

>  /*
>   * Default voltage controller settings.
> @@ -222,6 +266,29 @@ static struct omap_volt_data omap36xx_vdd2_volt_data[] = 
> {
>       {.volt_nominal = 1137500, .sr_errminlimit = 0xF9, .vp_errgain = 0x16},
>  };
>  
> +/*
> + * Structures containing OMAP4430 voltage supported and various
> + * data associated with it per voltage domain basis. Smartreflex Ntarget
> + * values are left as 0 as they have to be populated by smartreflex
> + * driver after reading the efuse.
> + */
> +static struct omap_volt_data omap44xx_vdd_mpu_volt_data[] = {
> +     {.volt_nominal = 930000, .sr_errminlimit = 0xF4, .vp_errgain = 0x0C},
> +     {.volt_nominal = 1100000, .sr_errminlimit = 0xF9, .vp_errgain = 0x16},
> +     {.volt_nominal = 1260000, .sr_errminlimit = 0xFA, .vp_errgain = 0x23},
> +     {.volt_nominal = 1350000, .sr_errminlimit = 0xFA, .vp_errgain = 0x27},
> +};
> +
> +static struct omap_volt_data omap44xx_vdd_iva_volt_data[] = {
> +     {.volt_nominal = 930000, .sr_errminlimit = 0xF4, .vp_errgain = 0x0C},
> +     {.volt_nominal = 1100000, .sr_errminlimit = 0xF9, .vp_errgain = 0x16},
> +     {.volt_nominal = 1260000, .sr_errminlimit = 0xFA, .vp_errgain = 0x23},
> +};
> +
> +static struct omap_volt_data omap44xx_vdd_core_volt_data[] = {
> +     {.volt_nominal = 930000, .sr_errminlimit = 0xF4, .vp_errgain = 0x0C},
> +     {.volt_nominal = 1100000, .sr_errminlimit = 0xF9, .vp_errgain = 0x16},
> +};
>  
>  /* By default VPFORCEUPDATE is the chosen method of voltage scaling */
>  static bool voltscale_vpforceupdate = true;
> @@ -510,6 +577,165 @@ static void __init omap3_vdd_data_configure(struct 
> omap_vdd_info *vdd)
>       vdd->vp_reg.vlimitto_timeout_shift = OMAP3430_TIMEOUT_SHIFT;
>  }
>  
> +/* OMAP4 specific voltage init functions */
> +static void __init omap4_init_voltagecontroller(void)
> +{
> +     voltage_write_reg(OMAP4_PRM_VC_SMPS_SA_OFFSET,
> +                     (OMAP4_SRI2C_SLAVE_ADDR <<
> +                      OMAP4430_SA_VDD_CORE_L_0_6_SHIFT) |
> +                     (OMAP4_SRI2C_SLAVE_ADDR <<
> +                      OMAP4430_SA_VDD_IVA_L_PRM_VC_SMPS_SA_SHIFT) |
> +                     (OMAP4_SRI2C_SLAVE_ADDR <<
> +                      OMAP4430_SA_VDD_MPU_L_PRM_VC_SMPS_SA_SHIFT));
> +     voltage_write_reg(OMAP4_PRM_VC_VAL_SMPS_RA_VOL_OFFSET,
> +                     (OMAP4_VDD_MPU_SR_VOLT_REG <<
> +                      OMAP4430_VOLRA_VDD_MPU_L_SHIFT) |
> +                     (OMAP4_VDD_IVA_SR_VOLT_REG <<
> +                      OMAP4430_VOLRA_VDD_IVA_L_SHIFT) |
> +                     (OMAP4_VDD_CORE_SR_VOLT_REG <<
> +                      OMAP4430_VOLRA_VDD_CORE_L_SHIFT));
> +     voltage_write_reg(OMAP4_PRM_VC_CFG_CHANNEL_OFFSET,
> +                     OMAP4430_RAV_VDD_MPU_L_MASK |
> +                     OMAP4430_CMD_VDD_MPU_L_MASK |
> +                     OMAP4430_RAV_VDD_IVA_L_MASK |
> +                     OMAP4430_CMD_VDD_IVA_L_MASK |
> +                     OMAP4430_RAV_VDD_CORE_L_MASK |
> +                     OMAP4430_CMD_VDD_CORE_L_MASK);

insert blank line 

> +     /*
> +      * Configure SR I2C in HS Mode. Is there really a need to configure
> +      * i2c in the normal mode??
> +      */
> +/*   voltage_write_reg(OMAP4_PRM_VC_CFG_I2C_MODE_OFFSET,
> +                     0x0 << OMAP4430_HSMCODE_SHIFT);
> +     voltage_write_reg(OMAP4_PRM_VC_CFG_I2C_CLK_OFFSET,
> +                     (0x0A << OMAP4430_HSSCLL_SHIFT |
> +                     0x05 << OMAP4430_HSSCLH_SHIFT));*/

this is commented out.  Either remove it, or make it conditional on
something meaningful.

> +     voltage_write_reg(OMAP4_PRM_VC_CFG_I2C_CLK_OFFSET,
> +                     (0x60 << OMAP4430_SCLL_SHIFT |
> +                     0x26 << OMAP4430_SCLH_SHIFT));
> +     /* TODO: Configure setup times and CMD_VAL values*/
> +}
> +
> +/* Sets up all the VDD related info for OMAP4 */
> +static void __init omap4_vdd_data_configure(struct omap_vdd_info *vdd)
> +{
> +     unsigned long curr_volt;
> +     struct omap_volt_data *volt_data;
> +     struct clk *sys_ck;
> +     u32 sys_clk_speed, timeout_val, waittime;
> +
> +     if (!strcmp(vdd->voltdm.name, "mpu")) {
> +             vdd->vp_reg.vlimitto_vddmin = OMAP4_VP_MPU_VLIMITTO_VDDMIN;
> +             vdd->vp_reg.vlimitto_vddmax = OMAP4_VP_MPU_VLIMITTO_VDDMAX;
> +             vdd->volt_data = omap44xx_vdd_mpu_volt_data;
> +             vdd->volt_data_count = ARRAY_SIZE(omap44xx_vdd_mpu_volt_data);
> +             vdd->volt_clk = clk_get(NULL, "dpll_mpu_ck");
> +             WARN(IS_ERR(vdd->volt_clk), "unable to get clock for vdd_%s\n",
> +                             vdd->voltdm.name);
> +             vdd->opp_dev = omap2_get_mpuss_device();
> +             vdd->vp_reg.tranxdone_status =
> +                             OMAP4430_VP_MPU_TRANXDONE_ST_MASK;
> +             vdd->cmdval_reg = OMAP4_PRM_VC_VAL_CMD_VDD_MPU_L_OFFSET;
> +             vdd->vdd_sr_reg = OMAP4_VDD_MPU_SR_VOLT_REG;
> +     } else if (!strcmp(vdd->voltdm.name, "core")) {
> +             vdd->vp_reg.vlimitto_vddmin = OMAP4_VP_CORE_VLIMITTO_VDDMIN;
> +             vdd->vp_reg.vlimitto_vddmax = OMAP4_VP_CORE_VLIMITTO_VDDMAX;
> +             vdd->volt_data = omap44xx_vdd_core_volt_data;
> +             vdd->volt_data_count = ARRAY_SIZE(omap44xx_vdd_core_volt_data);
> +             vdd->volt_clk = clk_get(NULL, "l3_div_ck");
> +             WARN(IS_ERR(vdd->volt_clk), "unable to get clock for vdd_%s\n",
> +                             vdd->voltdm.name);
> +             vdd->opp_dev = omap2_get_l3_device();
> +             vdd->vp_reg.tranxdone_status =
> +                             OMAP4430_VP_CORE_TRANXDONE_ST_MASK;
> +             vdd->cmdval_reg = OMAP4_PRM_VC_VAL_CMD_VDD_CORE_L_OFFSET;
> +             vdd->vdd_sr_reg = OMAP4_VDD_CORE_SR_VOLT_REG;
> +     } else if (!strcmp(vdd->voltdm.name, "iva")) {
> +             vdd->vp_reg.vlimitto_vddmin = OMAP4_VP_IVA_VLIMITTO_VDDMIN;
> +             vdd->vp_reg.vlimitto_vddmax = OMAP4_VP_IVA_VLIMITTO_VDDMAX;
> +             vdd->volt_data = omap44xx_vdd_iva_volt_data;
> +             vdd->volt_data_count = ARRAY_SIZE(omap44xx_vdd_iva_volt_data);
> +             vdd->volt_clk = clk_get(NULL, "dpll_iva_m5x2_ck");
> +             WARN(IS_ERR(vdd->volt_clk), "unable to get clock for vdd_%s\n",
> +                             vdd->voltdm.name);
> +             vdd->opp_dev = omap2_get_iva_device();
> +             vdd->vp_reg.tranxdone_status =
> +                     OMAP4430_VP_IVA_TRANXDONE_ST_MASK;
> +             vdd->cmdval_reg = OMAP4_PRM_VC_VAL_CMD_VDD_IVA_L_OFFSET;
> +             vdd->vdd_sr_reg = OMAP4_VDD_IVA_SR_VOLT_REG;
> +     } else {
> +             pr_warning("%s: vdd_%s does not exisit in OMAP4\n",
> +                     __func__, vdd->voltdm.name);
> +             return;
> +     }
> +
> +     curr_volt = omap_voltage_get_nom_volt(&vdd->voltdm);
> +     if (!curr_volt) {
> +             pr_warning("%s: unable to find current voltage for vdd_%s\n",
> +                     __func__, vdd->voltdm.name);
> +             return;
> +     }
> +
> +     volt_data = omap_voltage_get_voltdata(&vdd->voltdm, curr_volt);
> +     if (IS_ERR(volt_data)) {
> +             pr_warning("%s: Unable to get volt table for vdd_%s at init",
> +                     __func__, vdd->voltdm.name);
> +             return;
> +     }
> +     /*
> +      * Sys clk rate is require to calculate vp timeout value and
> +      * smpswaittimemin and smpswaittimemax.
> +      */
> +     sys_ck = clk_get(NULL, "sys_clkin_ck");
> +     if (IS_ERR(sys_ck)) {
> +             pr_warning("%s: Could not get the sys clk to calculate"
> +                     "various vdd_%s params\n", __func__, vdd->voltdm.name);
> +             return;
> +     }
> +     sys_clk_speed = clk_get_rate(sys_ck);
> +     clk_put(sys_ck);

insert blank line

[...]

Kevin
--
To unsubscribe from this list: send the line "unsubscribe linux-omap" in
the body of a message to [email protected]
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to