diff options
author | Alex Frid <afrid@nvidia.com> | 2011-08-13 00:38:41 -0700 |
---|---|---|
committer | Varun Colbert <vcolbert@nvidia.com> | 2011-08-18 16:27:56 -0700 |
commit | c52a7398c2a1960865ddfc75d94403757b1af256 (patch) | |
tree | ca185a982918b718c2e4a74af0e362784aa493af /arch | |
parent | ce3578e6eec793bdc6b008af7f1fe242804565b4 (diff) |
ARM: tegra: dvfs: Retry rail update
Since rail voltage change may be limited by from-relationship with
another rail, retry rail update to account for circular dependencies.
Bug 864112
Change-Id: Ie45f656a74eac925ab2383fbe620fad47742d02f
Reviewed-on: http://git-master/r/47233
Reviewed-by: Narendra Damahe <ndamahe@nvidia.com>
Tested-by: Aleksandr Frid <afrid@nvidia.com>
Reviewed-by: Karan Jhavar <kjhavar@nvidia.com>
Tested-by: Karan Jhavar <kjhavar@nvidia.com>
Reviewed-by: Chih-Lung Huang <lhuang@nvidia.com>
Reviewed-by: Yu-Huan Hsu <yhsu@nvidia.com>
Reviewed-by: Scott Williams <scwilliams@nvidia.com>
Diffstat (limited to 'arch')
-rw-r--r-- | arch/arm/mach-tegra/dvfs.c | 18 |
1 files changed, 13 insertions, 5 deletions
diff --git a/arch/arm/mach-tegra/dvfs.c b/arch/arm/mach-tegra/dvfs.c index 7d396ca98c21..dd97e6944fe3 100644 --- a/arch/arm/mach-tegra/dvfs.c +++ b/arch/arm/mach-tegra/dvfs.c @@ -232,6 +232,7 @@ static int dvfs_rail_update(struct dvfs_rail *rail) struct dvfs *d; struct dvfs_relationship *rel; int ret = 0; + int steps; /* if dvfs is suspended, return and handle it during resume */ if (rail->suspended) @@ -250,14 +251,21 @@ static int dvfs_rail_update(struct dvfs_rail *rail) list_for_each_entry(d, &rail->dvfs, reg_node) millivolts = max(d->cur_millivolts, millivolts); - rail->new_millivolts = millivolts; + /* retry update if limited by from-relationship to account for + circular dependencies */ + steps = DIV_ROUND_UP(abs(millivolts - rail->millivolts), rail->step); + for (; steps >= 0; steps--) { + rail->new_millivolts = millivolts; - /* Check any rails that this rail depends on */ - list_for_each_entry(rel, &rail->relationships_from, from_node) - rail->new_millivolts = dvfs_solve_relationship(rel); + /* Check any rails that this rail depends on */ + list_for_each_entry(rel, &rail->relationships_from, from_node) + rail->new_millivolts = dvfs_solve_relationship(rel); + + if (rail->new_millivolts == rail->millivolts) + break; - if (rail->new_millivolts != rail->millivolts) ret = dvfs_rail_set_voltage(rail, rail->new_millivolts); + } return ret; } |