ARM: tegra: dvfs: Use fixed voltage as nominal.
Alex Frid [Tue, 9 Jul 2013 21:59:38 +0000 (14:59 -0700)]
On entry to suspend or when disabling rail scaling, used fixed voltage
instead of nominal for fixed regulator. It allows to avoid error on
setting nominal voltage above fixed level, and it is safe, since the
pll mode frequency is already capped to match fixed voltage level, and
in dfll mode voltage is always scaled to match the frequency.

Change-Id: I8e55f1c1bb551df76b2a3901fe1020857c4301e6
Signed-off-by: Alex Frid <afrid@nvidia.com>
Reviewed-on: http://git-master/r/246901
Reviewed-by: Automatic_Commit_Validation_User
Reviewed-by: Mitch Luban <mluban@nvidia.com>

arch/arm/mach-tegra/dvfs.c

index ffeb31f..9af494e 100644 (file)
@@ -390,6 +390,22 @@ static int dvfs_rail_update(struct dvfs_rail *rail)
        return ret;
 }
 
+/*
+ * This function is called on entry to suspend, or when rail scaling is disabled
+ * - can't do anything in either case if regulsator is fixed in pll mode. Since
+ * the pll mode frequency is already capped according to fixed voltage level, it
+ * is safe to substitute fixed level for nominal, just for stats update.
+ */
+static int dvfs_rail_set_nominal(struct dvfs_rail *rail)
+{
+       int mv;
+       if (!rail->dfll_mode && rail->fixed_millivolts)
+               mv = rail->fixed_millivolts;
+       else
+               mv = dvfs_rail_apply_limits(rail, rail->nominal_millivolts);
+       return dvfs_rail_set_voltage(rail, mv);
+}
+
 static struct regulator *get_fixed_regulator(struct dvfs_rail *rail)
 {
        struct regulator *reg;
@@ -804,9 +820,7 @@ static int tegra_dvfs_suspend_one(void)
        list_for_each_entry(rail, &dvfs_rail_list, node) {
                if (!rail->suspended && !rail->disabled &&
                    tegra_dvfs_from_rails_suspended_or_solved(rail)) {
-                       int mv = dvfs_rail_apply_limits(
-                               rail, rail->nominal_millivolts);
-                       ret = dvfs_rail_set_voltage(rail, mv);
+                       ret = dvfs_rail_set_nominal(rail);
                        if (ret)
                                return ret;
                        rail->suspended = true;
@@ -900,8 +914,7 @@ static void __tegra_dvfs_rail_disable(struct dvfs_rail *rail)
                return;
        }
 
-       ret = dvfs_rail_set_voltage(rail,
-               dvfs_rail_apply_limits(rail, rail->nominal_millivolts));
+       ret = dvfs_rail_set_nominal(rail);
        if (ret) {
                pr_info("dvfs: failed to set regulator %s to disable "
                        "voltage %d\n", rail->reg_id,