Re: [PATCH 4/4] OMAP: Voltage: Adaptive Body-Bias handlers

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Hi Mike,

On 2/21/2011 8:47 PM, Turquette, Mike wrote:
On Mon, Feb 21, 2011 at 4:31 AM, Gulati, Shweta<shweta.gulati@xxxxxx>  wrote:
Hi,

On Fri, Feb 18, 2011 at 2:50 PM, Mike Turquette<mturquette@xxxxxx>  wrote:
Introduce voltage transition notification handlers for Adaptive Body-Bias
LDOs.  There is an ABB LDO for VDD_MPU on OMAP3630 and an ABB_LDO on VDD_MPU
and VDD_IVA on OMAP4430.

All of these LDOs are handled similary.  Initial configuration is to enable
the possibility of going into Forward Body-Bias (which boosts voltage at
high OPPs).  This feature was designed for weak silicon, and eFuse values
exist to control whether or not this feature should be turned on.  However
recommendations from hardware folks always say to leave it on regardless of
eFuse values, so we don't bother checking them.  For all other OPPs the LDO
is in bypass and will follow the voltage of it's corresponding VDD_xxx.
Reverse Body-Bias exists but we never use this in practice (for saving power
on strongly characterised silicon).
Would RBB be never enabled in future for any of the OPPs or any platforms
that way SLOW_OPP should also be added in OPP types

Will do this in next version.  RBB is a possibility.

You should not waste you time with that, the RBB should be remove from the TRM soon.
That mode is not supported anymore.

Benoit


Upon a DVFS transition the notifiers handle the sequencing of voltage
scaling and ABB LDO transitions.  When moving to a higher OPP that needs
FBB, raise voltage first and then enable FBB.  When moving down to an OPP
that bypasses ABB, first bypass the LDO then lower voltage.

Signed-off-by: Mike Turquette<mturquette@xxxxxx>
---
  arch/arm/mach-omap2/voltage.c             |  379 ++++++++++++++++++++++++++++-
  arch/arm/plat-omap/include/plat/voltage.h |    6 +-
  2 files changed, 370 insertions(+), 15 deletions(-)

diff --git a/arch/arm/mach-omap2/voltage.c b/arch/arm/mach-omap2/voltage.c
index 6ede092..644a45f 100644
--- a/arch/arm/mach-omap2/voltage.c
+++ b/arch/arm/mach-omap2/voltage.c
@@ -43,6 +43,16 @@
  #define FAST_OPP               0x1
  #define NOMINAL_OPP            0x0

+/* prototypes used by ABB function pointers */
+static int omap_abb_notify_voltage(struct notifier_block *nb,
+               unsigned long val, void *data);
+
+static int omap3_abb_configure(struct omap_abb_info *abb);
+static int omap3_abb_set_opp(struct omap_abb_info *abb, int opp_type);
+
+static int omap4_abb_configure(struct omap_abb_info *abb);
+static int omap4_abb_set_opp(struct omap_abb_info *abb, int opp_type);
+
  static struct omap_vdd_info *vdd_info;
  /*
  * Number of scalable voltage domains.
@@ -70,9 +80,11 @@ static struct omap_vdd_info omap3_vdd_info[] = {
                                        = OMAP3_PRM_IRQSTATUS_MPU_OFFSET,
                        .done_st_shift  = OMAP3630_ABB_LDO_TRANXDONE_ST_SHIFT,
                        .done_st_mask   = OMAP3630_ABB_LDO_TRANXDONE_ST_MASK,
-                       .configure      = NULL,
-                       .nb_handler     = NULL,
-                       .set_opp        = NULL,
+                       .nb     = {
+                               .notifier_call = omap_abb_notify_voltage,
+                       },
+                       .configure      = omap3_abb_configure,
+                       .set_opp        = omap3_abb_set_opp,
                },
        },
        {
@@ -113,9 +125,11 @@ static struct omap_vdd_info omap4_vdd_info[] = {
                                        = OMAP4_PRM_IRQSTATUS_MPU_2_OFFSET,
                        .done_st_shift  = OMAP4430_ABB_MPU_DONE_ST_SHIFT,
                        .done_st_mask   = OMAP4430_ABB_MPU_DONE_ST_MASK,
-                       .configure      = NULL,
-                       .nb_handler     = NULL,
-                       .set_opp        = NULL,
+                       .nb             = {
+                               .notifier_call = omap_abb_notify_voltage,
+                       },
+                       .configure      = omap4_abb_configure,
+                       .set_opp        = omap4_abb_set_opp,
                },
        },
        {
@@ -137,9 +151,11 @@ static struct omap_vdd_info omap4_vdd_info[] = {
                                        = OMAP4_PRM_IRQSTATUS_MPU_OFFSET,
                        .done_st_shift  = OMAP4430_ABB_IVA_DONE_ST_SHIFT,
                        .done_st_mask   = OMAP4430_ABB_IVA_DONE_ST_MASK,
-                       .configure      = NULL,
-                       .nb_handler     = NULL,
-                       .set_opp        = NULL,
+                       .nb             = {
+                               .notifier_call = omap_abb_notify_voltage,
+                       },
+                       .configure      = omap4_abb_configure,
+                       .set_opp        = omap4_abb_set_opp,
                },
        },
        {
@@ -194,7 +210,7 @@ static struct omap_volt_data omap36xx_vddmpu_volt_data[] = {
                        NOMINAL_OPP),
        VOLT_DATA_DEFINE(OMAP3630_VDD_MPU_OPP100_UV,
                        OMAP3630_CONTROL_FUSE_OPP100_VDD1, 0xf9, 0x16,
-                       NOMINAL_OPP),
+                       FAST_OPP),
        VOLT_DATA_DEFINE(OMAP3630_VDD_MPU_OPP120_UV,
                        OMAP3630_CONTROL_FUSE_OPP120_VDD1, 0xfa, 0x23,
                        NOMINAL_OPP),
@@ -493,6 +509,74 @@ static void __init vdd_debugfs_init(struct omap_vdd_info *vdd)
                                &nom_volt_debug_fops);
  }

+/* voltage transition notification handlers */
+
+/**
+ * omap_abb_notify_voltage - voltage change notifier handler for ABB
+ * @nb         : notifier block
+ * @val                : VOLTSCALE_PRECHANGE or VOLTSCALE_POSTCHANGE
+ * @data       : struct omap_volt_change_info for a given voltage domain
+ *
+ * Sets ABB LDO to either bypass or Forward Body-Bias whenever a voltage
+ * change notification is generated.  Voltages marked as FAST will result in
+ * FBB operation of ABB LDO and voltages marked as NOMINAL will bypass the
+ * LDO.  Does not handle Reverse Body-Bias since there is not benefit for it
+ * on any existing silicon.  Returns 0 upon success, negative error code
+ * otherwise.
+ */
+static int omap_abb_notify_voltage(struct notifier_block *nb,
+               unsigned long val, void *data)
+{
+       struct omap_volt_change_info *v_info;
+       struct omap_vdd_info *vdd;
+       struct omap_volt_data *curr_volt_data, *target_volt_data;
+       int ret = 0;
+
+       if (!nb || IS_ERR(nb) || !data || IS_ERR(data)) {
+               pr_warning("%s: invalid data specified\n", __func__);
+               ret = -EINVAL;
+               goto out;
+       }
+
+       v_info = (struct omap_volt_change_info *)data;
+       vdd = v_info->vdd;
+
+       /* get the voltdata structures for the current&  target voltage */
+       target_volt_data = omap_voltage_get_voltdata(&vdd->voltdm,
+                       v_info->target_volt);
+       curr_volt_data = omap_voltage_get_voltdata(&vdd->voltdm,
+                       v_info->curr_volt);
+
+       /* nothing to do here */
+       if (target_volt_data->abb_opp == curr_volt_data->abb_opp)
+               goto out;
+
+       /*
+        * When the VDD drops from a voltage requiring the ABB LDO to be in
+        * FBB mode to a voltage requiring bypass mode, we must bypass the LDO
+        * before the voltage transition.
+        */
+       if (val == VOLTSCALE_PRECHANGE&&
+                       target_volt_data->abb_opp == NOMINAL_OPP) {
+               ret = vdd->abb.set_opp(&vdd->abb, NOMINAL_OPP);
+
+       /*
+        * When moving from a voltage requiring the ABB LDO to be bypassed to
+        * a voltage requiring FBB mode, we must change the LDO operation
+        * after the voltage transition.
+        */
+       } else if (val == VOLTSCALE_POSTCHANGE&&
+                       target_volt_data->abb_opp == FAST_OPP) {
+               ret = vdd->abb.set_opp(&vdd->abb, FAST_OPP);
+
+       /* invalid combination, bail out */
+       } else
+               ret = -EINVAL;
+
+out:
+       return ret;
+}
+
  /* Voltage scale and accessory APIs */
  static int _pre_volt_scale(struct omap_vdd_info *vdd,
                unsigned long target_volt, u8 *target_vsel, u8 *current_vsel)
@@ -717,6 +801,142 @@ static int vp_forceupdate_scale_voltage(struct omap_vdd_info *vdd,
        return 0;
  }

+/**
+ * omap3_abb_set_opp - program ABB LDO upon a voltage transition
+ *
+ * @abb                : ABB instance being programmed
+ * @opp_type   : flag for NOMINAL or FAST OPP
+ */
+static int omap3_abb_set_opp(struct omap_abb_info *abb, int opp_type)
+{
+       int ret = 0;
+       int timeout;
+
+       /* program for NOMINAL OPP or FAST OPP */
+       omap2_prm_rmw_mod_reg_bits(OMAP3630_OPP_SEL_MASK,
+                       (opp_type<<  OMAP3630_OPP_SEL_SHIFT),
+                       OMAP3430_GR_MOD, abb->setup_offs);
Rather than passing a parameter 'opp_type' u can set OPP_SEL bit in
SETUP Register in API

I'm not sure I follow.  The opp_type corresponds to the voltage we're
transitioning to, so that data must be passed in to this generic
set_opp function.

omap_abb_notify_voltage where if-else are used to check whether ABB
needs to transition or not.

The notifier handles this... it will not execute call set_opp function
if there is no need to change ABB registers.

+
+       /* clear ABB ldo interrupt status */
+       omap2_prm_clear_mod_reg_bits(abb->done_st_mask, OCP_MOD,
+                       abb->irqstatus_mpu_offs);
+
+       /* enable ABB LDO OPP change */
+       omap2_prm_set_mod_reg_bits(OMAP3630_OPP_CHANGE_MASK, OMAP3430_GR_MOD,
+                       abb->setup_offs);
+
+       timeout = 0;
+
+       /* wait until OPP change completes */
+       while ((timeout<  ABB_TRANXDONE_TIMEOUT)&&
+                       (!(omap2_prm_read_mod_reg(OCP_MOD,
+                                                 abb->irqstatus_mpu_offs)&
+                          abb->done_st_mask))) {
+               udelay(1);
+               timeout++;
+       }
+
+       if (timeout == ABB_TRANXDONE_TIMEOUT)
+               pr_warning("%s: TRANXDONE timed out waiting for OPP change\n",
+                               __func__);
+
+       timeout = 0;
+
+       /* Clear all pending TRANXDONE interrupts/status */
+       while (timeout<  ABB_TRANXDONE_TIMEOUT) {
+               omap2_prm_write_mod_reg((1<<  abb->done_st_shift), OCP_MOD,
+                               abb->irqstatus_mpu_offs);
+
+               if (!(omap2_prm_read_mod_reg(OCP_MOD, abb->irqstatus_mpu_offs)
+&  abb->done_st_mask))
+                       break;
+
+               udelay(1);
+               timeout++;
+       }
+
+       if (timeout == ABB_TRANXDONE_TIMEOUT) {
+               pr_warning("%s: TRANXDONE timed out trying to clear status\n",
+                               __func__);
+               ret = -EBUSY;
+       }
+
+       return ret;
+}
+
+/**
+ * omap4_abb_set_opp - program ABB LDO upon a voltage transition
+ *
+ * @abb                : ABB instance being programmed
+ * @opp_type   : flag for NOMINAL or FAST OPP
+ */
+static int omap4_abb_set_opp(struct omap_abb_info *abb, int opp_type)
+{
+       int ret = 0;
+       int timeout;
+
+       /* program for NOMINAL OPP or FAST OPP */
+       omap4_prminst_rmw_inst_reg_bits(OMAP4430_OPP_SEL_MASK,
+                       (opp_type<<  OMAP4430_OPP_SEL_SHIFT),
+                       OMAP4430_PRM_PARTITION, OMAP4430_PRM_DEVICE_INST,
+                       abb->ctrl_offs);
+
+       /* clear ABB ldo interrupt status */
+       omap4_prminst_rmw_inst_reg_bits(abb->done_st_mask,
+                       (0x0<<  abb->done_st_shift), OMAP4430_PRM_PARTITION,
+                       OMAP4430_PRM_DEVICE_INST, abb->ctrl_offs);
+
+       /* enable ABB LDO OPP change */
+       omap4_prminst_rmw_inst_reg_bits(OMAP4430_OPP_CHANGE_MASK,
+                       (0x1<<  OMAP4430_OPP_CHANGE_SHIFT),
+                       OMAP4430_PRM_PARTITION, OMAP4430_PRM_DEVICE_INST,
+                       abb->ctrl_offs);
+
A generic struct can be created which has Masks and shifts of all
register offsets  like OMAP4430_OPP_CHANGE_MASK
and OMAP3630_ACTIVE_FBB_SEL_MASK whose objects for OMAP3 and OMAP4 can be used.

True.  I chose to have the struct differentiate between VDDs, not OMAP
chips.  Do others have an opinion on this?  I guess it comes down to
whether we should have OMAP-specific ABB set_opp functions, and that
struct data should be per-VDD (like it is in my patch)... OR if we
should have a generic ABB set_opp function only that works across all
OMAPs and all data is in the struct whether it is VDD- or
OMAP-specific.  My problem with the latter solution is that it assumes
the programming model will not change from OMAP to OMAP...

+       timeout = 0;
+
+       /* wait until OPP change completes */
+       while ((timeout<  ABB_TRANXDONE_TIMEOUT)&&
+                       (!(omap4_prminst_read_inst_reg(OMAP4430_PRM_PARTITION,
+                                                      OMAP4430_PRM_DEVICE_INST,
+                                                      abb->irqstatus_mpu_offs)
+&  abb->done_st_mask))) {
+               udelay(1);
+               timeout++;
+       }
+
+       if (timeout == ABB_TRANXDONE_TIMEOUT)
+               pr_warning("%s: TRANXDONE timed out waiting for OPP change\n",
+                               __func__);
+
+       timeout = 0;
+
+       /* Clear all pending TRANXDONE interrupts/status */
+       while (timeout<  ABB_TRANXDONE_TIMEOUT) {
+               omap4_prminst_write_inst_reg((1<<  abb->done_st_shift),
+                               OMAP4430_PRM_PARTITION,
+                               OMAP4430_PRM_DEVICE_INST,
+                               abb->irqstatus_mpu_offs);
+
+               if (!(omap4_prminst_read_inst_reg(OMAP4430_PRM_PARTITION,
+                                               OMAP4430_PRM_DEVICE_INST,
+                                               abb->irqstatus_mpu_offs)
+&  abb->done_st_mask)) {
+                       break;
+
+                       udelay(1);
+                       timeout++;
+               }
+       }
+
+       if (timeout == ABB_TRANXDONE_TIMEOUT) {
+               pr_warning("%s: TRANXDONE timed out trying to clear status\n",
+                               __func__);
+               ret = -EBUSY;
+       }
+
+       return ret;
+}
+
  /* OMAP3 specific voltage init functions */

  /*
@@ -789,6 +1009,64 @@ static void __init omap3_vc_init(struct omap_vdd_info *vdd)
        is_initialized = true;
  }

+/**
+ * omap3_abb_configure - per-VDD configuration of ABB
+ *
+ * @abb                : abb instance being initialized
+ */
+static int omap3_abb_configure(struct omap_abb_info *abb)
+{
+       int ret = 0;
+       u32 sr2_wt_cnt_val;
+       struct clk *sys_ck;
+       struct omap_vdd_info *vdd;
+
+       if (!abb || IS_ERR(abb)) {
+                       pr_warning("%s: invalid abb\n", __func__);
+                       ret = -EINVAL;
+                       goto out;
+       }
+
+       sys_ck = clk_get(NULL, "sys_ck");
+       if (IS_ERR(sys_ck)) {
+               pr_warning("%s: unable to fetch SYS_CK\n", __func__);
+               ret = -ENODEV;
+               goto out;
+       }
+
+       vdd = container_of(abb, struct omap_vdd_info, abb);
+
+       /* LDO settling time */
+       sr2_wt_cnt_val = clk_get_rate(sys_ck);
+       sr2_wt_cnt_val = sr2_wt_cnt_val / 1000000 / 16;
+
+       omap2_prm_rmw_mod_reg_bits(OMAP3630_SR2_WTCNT_VALUE_MASK,
+                       (sr2_wt_cnt_val<<  OMAP3630_SR2_WTCNT_VALUE_SHIFT),
+                       OMAP3430_GR_MOD, abb->setup_offs);
+
+       /* allow FBB operation */
+       omap2_prm_set_mod_reg_bits(OMAP3630_ACTIVE_FBB_SEL_MASK,
+                       OMAP3430_GR_MOD, abb->setup_offs);
+
+       /* do not allow ACTIVE RBB operation */
+       omap2_prm_set_mod_reg_bits(OMAP3630_ACTIVE_RBB_SEL_MASK,
+                       OMAP3430_GR_MOD, abb->setup_offs);
+
+       /* do not allow SLEEP RBB operation */
+       omap2_prm_set_mod_reg_bits(OMAP3630_SLEEP_RBB_SEL_MASK,
+                       OMAP3430_GR_MOD, abb->setup_offs);
+
+       /* enable ABB LDO */
+       omap2_prm_set_mod_reg_bits(OMAP3630_SR2EN_MASK,
+                       OMAP3430_GR_MOD, abb->ctrl_offs);
ABB should n't be enabled in this API rather it should be enabled only
when it goes to FBB/RBB mode

I disagree.  I've verified with hw team that this is perfectly safe as
it leaves ABB ldo in bypass and will follow VDD_xxx voltage.  No
reason to complicate notifier code with some "if
(!abb_already_enabled)" check.

+
+       /* register the notifier handler */
+       omap_voltage_register_notifier(vdd,&abb->nb);
+
+out:
+       return ret;
+}
+
  /* Sets up all the VDD related info for OMAP3 */
  static int __init omap3_vdd_data_configure(struct omap_vdd_info *vdd)
  {
@@ -824,6 +1102,9 @@ static int __init omap3_vdd_data_configure(struct omap_vdd_info *vdd)
                vdd->vc_reg.smps_volra_mask = OMAP3430_VOLRA0_MASK;
                vdd->vc_reg.voltsetup_shift = OMAP3430_SETUP_TIME1_SHIFT;
                vdd->vc_reg.voltsetup_mask = OMAP3430_SETUP_TIME1_MASK;
+
+               /* configure ABB */
+               vdd->abb.configure(&vdd->abb);
        } else if (!strcmp(vdd->voltdm.name, "core")) {
                if (cpu_is_omap3630())
                        vdd->volt_data = omap36xx_vddcore_volt_data;
@@ -975,6 +1256,73 @@ static void __init omap4_vc_init(struct omap_vdd_info *vdd)
        is_initialized = true;
  }

To remove code repetition rather than having 2 APIs for abb_configure,
I believe 1 API which has generic register offsets struct objects for
all platforms
(OMAP3 and OMAP4 for now) can be used.
This would be scalable for OMAP5+ also.

This is the same as what I've stated above for the ABB set_opp
function.  We can't be sure what the programming model will be for
future OMAPs, so should we really do it as your suggest?  It is
possible that we retain the same set_opp function pointer, and only
implemenet it once since it can be used by both OMAP3 and OMAP4 using
more verbose struct data.  OMAP5 might have a different programming
model altogether, so we will need to retain the set_opp function
pointer just to be safe.  Thoughts on this?


+/**
+ * omap4_abb_configure - per-VDD configuration of ABB
+ *
+ * @abb                : abb instance being initialized
+ */
+static int omap4_abb_configure(struct omap_abb_info *abb)
+{
+       int ret = 0;
+       u32 sr2_wt_cnt_val;
+       struct clk *sys_ck;
+       struct omap_vdd_info *vdd;
+
+       if (!abb || IS_ERR(abb)) {
+                       pr_warning("%s: invalid abb\n", __func__);
+                       ret = -EINVAL;
+                       goto out;
+       }
+
+       sys_ck = clk_get(NULL, "sys_clkin_ck");
+       if (IS_ERR(sys_ck)) {
+               pr_warning("%s: unable to fetch SYS_CK", __func__);
+               ret = -ENODEV;
+               goto out;
+       }
+
+       vdd = container_of(abb, struct omap_vdd_info, abb);
+
+       /* LDO settling time */
+       sr2_wt_cnt_val = clk_get_rate(sys_ck);
+       sr2_wt_cnt_val = sr2_wt_cnt_val / 1000000 / 16;
+
+       omap4_prminst_rmw_inst_reg_bits(OMAP4430_SR2_WTCNT_VALUE_MASK,
+                       (sr2_wt_cnt_val<<  OMAP4430_SR2_WTCNT_VALUE_SHIFT),
+                       OMAP4430_PRM_PARTITION, OMAP4430_PRM_DEVICE_INST,
+                       abb->setup_offs);
+
+       /* allow FBB operation */
+       omap4_prminst_rmw_inst_reg_bits(OMAP4430_ACTIVE_FBB_SEL_MASK,
+                       (1<<  OMAP4430_ACTIVE_FBB_SEL_SHIFT),
+                       OMAP4430_PRM_PARTITION, OMAP4430_PRM_DEVICE_INST,
+                       abb->setup_offs);
+
+       /* do not allow ACTIVE RBB operation */
+       omap4_prminst_rmw_inst_reg_bits(OMAP4430_ACTIVE_RBB_SEL_MASK,
+                       (0<<  OMAP4430_ACTIVE_RBB_SEL_SHIFT),
+                       OMAP4430_PRM_PARTITION, OMAP4430_PRM_DEVICE_INST,
+                       abb->setup_offs);
+
+       /* do not allow SLEEP RBB operation */
+       omap4_prminst_rmw_inst_reg_bits(OMAP4430_SLEEP_RBB_SEL_MASK,
+                       (0<<  OMAP4430_SLEEP_RBB_SEL_SHIFT),
+                       OMAP4430_PRM_PARTITION, OMAP4430_PRM_DEVICE_INST,
+                       abb->setup_offs);
+
+       /* enable ABB LDO */
+       omap4_prminst_rmw_inst_reg_bits(OMAP4430_SR2EN_MASK,
+                       (1<<  OMAP4430_SR2EN_SHIFT),
+                       OMAP4430_PRM_PARTITION, OMAP4430_PRM_DEVICE_INST,
+                       abb->setup_offs);
Same as above.

Same as my above comment ;-)  This is safe and there is no reason to change it.

Regards,
Mike

+       /* register the notifier handler */
+       omap_voltage_register_notifier(vdd,&abb->nb);
+
+out:
+       return ret;
+}
+
  /* Sets up all the VDD related info for OMAP4 */
  static int __init omap4_vdd_data_configure(struct omap_vdd_info *vdd)
  {
@@ -983,8 +1331,8 @@ static int __init omap4_vdd_data_configure(struct omap_vdd_info *vdd)

        if (!vdd->pmic_info) {
                pr_err("%s: PMIC info requried to configure vdd_%s not"
-                       "populated.Hence cannot initialize vdd_%s\n",
-                       __func__, vdd->voltdm.name, vdd->voltdm.name);
+                               "populated.Hence cannot initialize vdd_%s\n",
+                               __func__, vdd->voltdm.name, vdd->voltdm.name);
                return -EINVAL;
        }

@@ -1005,6 +1353,9 @@ static int __init omap4_vdd_data_configure(struct omap_vdd_info *vdd)
                vdd->vc_reg.voltsetup_reg =
                                OMAP4_PRM_VOLTSETUP_MPU_RET_SLEEP_OFFSET;
                vdd->prm_irqst_reg = OMAP4_PRM_IRQSTATUS_MPU_2_OFFSET;
+
+               /* configure ABB */
+               vdd->abb.configure(&vdd->abb);
        } else if (!strcmp(vdd->voltdm.name, "core")) {
                vdd->volt_data = omap44xx_vdd_core_volt_data;
                vdd->vp_reg.tranxdone_status =
@@ -1032,6 +1383,9 @@ static int __init omap4_vdd_data_configure(struct omap_vdd_info *vdd)
                vdd->vc_reg.voltsetup_reg =
                                OMAP4_PRM_VOLTSETUP_IVA_RET_SLEEP_OFFSET;
                vdd->prm_irqst_reg = OMAP4_PRM_IRQSTATUS_MPU_OFFSET;
+
+               /* configure ABB */
+               vdd->abb.configure(&vdd->abb);
        } else {
                pr_warning("%s: vdd_%s does not exisit in OMAP4\n",
                        __func__, vdd->voltdm.name);
@@ -1299,6 +1653,7 @@ int omap_voltage_scale_vdd(struct voltagedomain *voltdm,

        /* load notifier chain data */
        v_info.target_volt = target_volt;
+       v_info.curr_volt = vdd->curr_volt;
        v_info.vdd = vdd;

        srcu_notifier_call_chain(&vdd->volt_change_notify_chain,
diff --git a/arch/arm/plat-omap/include/plat/voltage.h b/arch/arm/plat-omap/include/plat/voltage.h
index af790bf..07997f7 100644
--- a/arch/arm/plat-omap/include/plat/voltage.h
+++ b/arch/arm/plat-omap/include/plat/voltage.h
@@ -235,8 +235,8 @@ struct omap_vdd_dep_info {
  * @irqstatus_mpu_offs : PRM_IRQSTATUS_MPU* register offset
  * @done_st_shift      : ABB_vdd_DONE_ST shift
  * @done_st_mask       : ABB_vdd_DONE_ST bit mask
+ * @nb                 : voltage transition notifier block
  * @configure          : boot-time configuration
- * @nb_handler         : voltage transition notification handler
  * @set_opp            : transition function called from nb_handler
  */
  struct omap_abb_info {
@@ -245,9 +245,8 @@ struct omap_abb_info {
        u8 irqstatus_mpu_offs;
        u8 done_st_shift;
        u32 done_st_mask;
+       struct notifier_block nb;
        int (*configure) (struct omap_abb_info *abb);
-       int (*nb_handler) (struct notifier_block *nb, unsigned long val,
-                       void *data);
        int (*set_opp) (struct omap_abb_info *abb, int opp_type);
  };

@@ -302,6 +301,7 @@ struct omap_vdd_info {
  */
  struct omap_volt_change_info {
        unsigned long target_volt;
+       unsigned long curr_volt;
        struct omap_vdd_info *vdd;
  };

--
1.7.1

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




--
Thanks,
Regards,
Shweta

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

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


[Index of Archives]     [Linux Arm (vger)]     [ARM Kernel]     [ARM MSM]     [Linux Tegra]     [Linux WPAN Networking]     [Linux Wireless Networking]     [Maemo Users]     [Linux USB Devel]     [Video for Linux]     [Linux Audio Users]     [Yosemite Trails]     [Linux Kernel]     [Linux SCSI]

  Powered by Linux