ARM: tegra: dvfs: Force CPU rail update
Alex Frid [Wed, 17 Oct 2012 03:08:56 +0000 (20:08 -0700)]
To force CPU rail update on exit from DFLL mode:

- altered by 1mV recorded rail level in DFLL mode, so that it won't
match any target level after switch from DFLL to PLL (actual level
in DFLL mode is approximately close to the recorded, anyway)

- altered by 1mV maximum limit requested from regulator, so that
core regulator call is not resolved as NOP (tegra dvfs would not
call core API to set the same voltage, with the exception of special
cases like switch from DFLL - and in these cases we do not need core
second guess).

Signed-off-by: Alex Frid <afrid@nvidia.com>
Reviewed-on: http://git-master/r/145168
(cherry picked from commit e18df75763f0d9f6980a2d77ed8e532afda4e96d)

Change-Id: I45271085bc1cdd9176a9a136b389292c6336ed35
Signed-off-by: Bharat Nihalani <bnihalani@nvidia.com>
Reviewed-on: http://git-master/r/146288
Reviewed-by: Automatic_Commit_Validation_User

arch/arm/mach-tegra/dvfs.c
arch/arm/mach-tegra/dvfs.h

index 2d25fe5..0456cb3 100644 (file)
@@ -189,10 +189,15 @@ static int dvfs_rail_set_voltage(struct dvfs_rail *rail, int millivolts)
                        return -EINVAL;
        }
 
-       /* DFLL adjusts rail voltage automatically - only update stats */
+       /*
+        * DFLL adjusts rail voltage automatically, but not exactly to the
+        * expected level - update stats, anyway, and made sure that recorded
+        * level will not match any target that can be requested when/if we
+        * switch back from DFLL to s/w control
+        */
        if (rail->dfll_mode) {
-               rail->millivolts = rail->new_millivolts;
-               dvfs_rail_stats_update(rail, rail->millivolts, ktime_get());
+               rail->millivolts = rail->new_millivolts = millivolts - 1;
+               dvfs_rail_stats_update(rail, millivolts, ktime_get());
                return 0;
        }
 
@@ -226,9 +231,12 @@ static int dvfs_rail_set_voltage(struct dvfs_rail *rail, int millivolts)
 
                if (!rail->disabled) {
                        rail->updating = true;
+                       rail->reg_max_millivolts = rail->reg_max_millivolts ==
+                               rail->max_millivolts ?
+                               rail->max_millivolts + 1 : rail->max_millivolts;
                        ret = regulator_set_voltage(rail->reg,
                                rail->new_millivolts * 1000,
-                               rail->max_millivolts * 1000);
+                               rail->reg_max_millivolts * 1000);
                        rail->updating = false;
                }
                if (ret) {
index 574ab5d..1b3df84 100644 (file)
@@ -58,6 +58,7 @@ struct dvfs_rail {
        const char *reg_id;
        int min_millivolts;
        int max_millivolts;
+       int reg_max_millivolts;
        int nominal_millivolts;
        int step;
        bool jmp_to_zero;