Commit 029f7e24 authored by Dmitry Osipenko's avatar Dmitry Osipenko Committed by Thierry Reding

soc/tegra: regulators: Support core domain state syncing

The core voltage shall not drop until state of core domain is synced,
i.e. all device drivers that use core domain are loaded and ready.

Support core domain state syncing. The core domain driver invokes the
core-regulator voltage syncing once the state of domain is synced, at
this point the core voltage is allowed to go lower than the level left
after bootloader.

Tested-by: Peter Geis <pgwipeout@gmail.com> # Ouya T30
Tested-by: Paul Fertser <fercerpav@gmail.com> # PAZ00 T20
Tested-by: Nicolas Chauvet <kwizart@gmail.com> # PAZ00 T20 and TK1 T124
Tested-by: Matt Merhar <mattmerhar@protonmail.com> # Ouya T30
Reviewed-by: default avatarUlf Hansson <ulf.hansson@linaro.org>
Signed-off-by: default avatarDmitry Osipenko <digetx@gmail.com>
Signed-off-by: default avatarThierry Reding <treding@nvidia.com>
parent 41bafa69
...@@ -17,6 +17,8 @@ ...@@ -17,6 +17,8 @@
#include <linux/regulator/driver.h> #include <linux/regulator/driver.h>
#include <linux/regulator/machine.h> #include <linux/regulator/machine.h>
#include <soc/tegra/pmc.h>
struct tegra_regulator_coupler { struct tegra_regulator_coupler {
struct regulator_coupler coupler; struct regulator_coupler coupler;
struct regulator_dev *core_rdev; struct regulator_dev *core_rdev;
...@@ -42,6 +44,21 @@ static int tegra20_core_limit(struct tegra_regulator_coupler *tegra, ...@@ -42,6 +44,21 @@ static int tegra20_core_limit(struct tegra_regulator_coupler *tegra,
int core_cur_uV; int core_cur_uV;
int err; int err;
/*
* Tegra20 SoC has critical DVFS-capable devices that are
* permanently-active or active at a boot time, like EMC
* (DRAM controller) or Display controller for example.
*
* The voltage of a CORE SoC power domain shall not be dropped below
* a minimum level, which is determined by device's clock rate.
* This means that we can't fully allow CORE voltage scaling until
* the state of all DVFS-critical CORE devices is synced.
*/
if (tegra_pmc_core_domain_state_synced() && !tegra->sys_reboot_mode) {
pr_info_once("voltage state synced\n");
return 0;
}
if (tegra->core_min_uV > 0) if (tegra->core_min_uV > 0)
return tegra->core_min_uV; return tegra->core_min_uV;
...@@ -62,7 +79,7 @@ static int tegra20_core_limit(struct tegra_regulator_coupler *tegra, ...@@ -62,7 +79,7 @@ static int tegra20_core_limit(struct tegra_regulator_coupler *tegra,
*/ */
tegra->core_min_uV = core_max_uV; tegra->core_min_uV = core_max_uV;
pr_info("core minimum voltage limited to %duV\n", tegra->core_min_uV); pr_info("core voltage initialized to %duV\n", tegra->core_min_uV);
return tegra->core_min_uV; return tegra->core_min_uV;
} }
......
...@@ -18,6 +18,7 @@ ...@@ -18,6 +18,7 @@
#include <linux/regulator/machine.h> #include <linux/regulator/machine.h>
#include <soc/tegra/fuse.h> #include <soc/tegra/fuse.h>
#include <soc/tegra/pmc.h>
struct tegra_regulator_coupler { struct tegra_regulator_coupler {
struct regulator_coupler coupler; struct regulator_coupler coupler;
...@@ -43,6 +44,21 @@ static int tegra30_core_limit(struct tegra_regulator_coupler *tegra, ...@@ -43,6 +44,21 @@ static int tegra30_core_limit(struct tegra_regulator_coupler *tegra,
int core_cur_uV; int core_cur_uV;
int err; int err;
/*
* Tegra30 SoC has critical DVFS-capable devices that are
* permanently-active or active at a boot time, like EMC
* (DRAM controller) or Display controller for example.
*
* The voltage of a CORE SoC power domain shall not be dropped below
* a minimum level, which is determined by device's clock rate.
* This means that we can't fully allow CORE voltage scaling until
* the state of all DVFS-critical CORE devices is synced.
*/
if (tegra_pmc_core_domain_state_synced() && !tegra->sys_reboot_mode) {
pr_info_once("voltage state synced\n");
return 0;
}
if (tegra->core_min_uV > 0) if (tegra->core_min_uV > 0)
return tegra->core_min_uV; return tegra->core_min_uV;
...@@ -63,7 +79,7 @@ static int tegra30_core_limit(struct tegra_regulator_coupler *tegra, ...@@ -63,7 +79,7 @@ static int tegra30_core_limit(struct tegra_regulator_coupler *tegra,
*/ */
tegra->core_min_uV = core_max_uV; tegra->core_min_uV = core_max_uV;
pr_info("core minimum voltage limited to %duV\n", tegra->core_min_uV); pr_info("core voltage initialized to %duV\n", tegra->core_min_uV);
return tegra->core_min_uV; return tegra->core_min_uV;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment