diff options
author | sreenivasulu velpula <svelpula@nvidia.com> | 2014-07-18 15:03:40 +0530 |
---|---|---|
committer | Winnie Hsu <whsu@nvidia.com> | 2014-10-27 12:52:43 -0700 |
commit | 4d44978f208f23fde7feef510b5490ee11335298 (patch) | |
tree | b5ad2e34100c8e525d6b03bb0dbd7983d001cc8a | |
parent | 982f479a7a11fb0aeb997bbe001d48f983e9c3f3 (diff) |
arm: t12: clock: Change use_dfll behaviour
- If CONFIG_TEGRA_USE_DFLL_RANGE is set to '3'
then do not allow use_dfll sysfs to control
dfll range.
AND
during kernel init also, by default dfll
range becomes 0.
Bug 1563635
Change-Id: I886a6ca365a1ee0fd7619312eca1ccd17d73222b
Signed-off-by: sreenivasulu velpula <svelpula@nvidia.com>
Reviewed-on: http://git-master/r/439769
(cherry picked from commit ce3cd984f88d19f5d929c0acbe509486fddcb8bc)
Reviewed-on: http://git-master/r/559391
Reviewed-by: Automatic_Commit_Validation_User
Reviewed-by: Bibek Basu <bbasu@nvidia.com>
Tested-by: Bibek Basu <bbasu@nvidia.com>
Reviewed-by: Aleksandr Frid <afrid@nvidia.com>
GVS: Gerrit_Virtual_Submit
Reviewed-by: Venkat Moganty <vmoganty@nvidia.com>
-rw-r--r-- | arch/arm/mach-tegra/dvfs.h | 12 | ||||
-rw-r--r-- | arch/arm/mach-tegra/tegra12_clocks.c | 61 |
2 files changed, 25 insertions, 48 deletions
diff --git a/arch/arm/mach-tegra/dvfs.h b/arch/arm/mach-tegra/dvfs.h index 16d705fb9ad6..c891786c642c 100644 --- a/arch/arm/mach-tegra/dvfs.h +++ b/arch/arm/mach-tegra/dvfs.h @@ -124,12 +124,23 @@ struct dvfs_rail { const char *version; }; +/* + * dfll_range - + * DFLL_RANGE_NONE : DFLL is not used + * DFLL_RANGE_ALL_RATES : DFLL is is used for all CPU rates + * DFLL_RANGE_HIGH_RATES : DFLL is used only for high rates + * above crossover with PLL dvfs curve + */ enum dfll_range { DFLL_RANGE_NONE = 0, DFLL_RANGE_ALL_RATES, DFLL_RANGE_HIGH_RATES, }; +/* DFLL usage is under thermal cooling device control */ +#define TEGRA_USE_DFLL_CDEV_CNTRL 3 + +/* DVFS settings specific for DFLL clock source */ struct dvfs_dfll_data { u32 tune0; u32 tune0_high_mv; @@ -279,6 +290,7 @@ int tegra_dvfs_replace_voltage_table(struct dvfs *d, const int *new_millivolts); int tegra_dvfs_dfll_mode_set(struct dvfs *d, unsigned long rate); int tegra_dvfs_dfll_mode_clear(struct dvfs *d, unsigned long rate); +int tegra_clk_dfll_range_control(enum dfll_range use_dfll); struct tegra_cooling_device *tegra_dvfs_get_cpu_vmax_cdev(void); struct tegra_cooling_device *tegra_dvfs_get_cpu_vmin_cdev(void); diff --git a/arch/arm/mach-tegra/tegra12_clocks.c b/arch/arm/mach-tegra/tegra12_clocks.c index 7a8d2be1da60..647b07f1ba0a 100644 --- a/arch/arm/mach-tegra/tegra12_clocks.c +++ b/arch/arm/mach-tegra/tegra12_clocks.c @@ -4358,56 +4358,19 @@ static struct clk_ops tegra_dfll_ops = { static int tegra12_use_dfll_cb(const char *arg, const struct kernel_param *kp) { int ret = 0; - unsigned long c_flags, p_flags; unsigned int old_use_dfll; - struct clk *c = tegra_get_clock_by_name("cpu"); - struct clk *dfll = tegra_get_clock_by_name("dfll_cpu"); - - if (!c->parent || !c->parent->dvfs || !dfll) - return -ENOSYS; - - ret = tegra_cpu_reg_mode_force_normal(true); - if (ret) { - pr_err("%s: Failed to force regulator normal mode\n", __func__); - return ret; - } - - clk_lock_save(c, &c_flags); - if (dfll->state == UNINITIALIZED) { - pr_err("%s: DFLL is not initialized\n", __func__); - clk_unlock_restore(c, &c_flags); - tegra_cpu_reg_mode_force_normal(false); - return -ENOSYS; - } - if (c->parent->u.cpu.mode == MODE_LP) { - pr_err("%s: DFLL is not used on LP CPU\n", __func__); - clk_unlock_restore(c, &c_flags); - tegra_cpu_reg_mode_force_normal(false); - return -ENOSYS; - } - - clk_lock_save(c->parent, &p_flags); - old_use_dfll = use_dfll; - param_set_int(arg, kp); - - if (use_dfll != old_use_dfll) { - ret = tegra_dvfs_set_dfll_range(c->parent->dvfs, use_dfll); - if (ret) { + if (CONFIG_TEGRA_USE_DFLL_RANGE != TEGRA_USE_DFLL_CDEV_CNTRL) { + old_use_dfll = use_dfll; + param_set_int(arg, kp); + ret = tegra_clk_dfll_range_control(use_dfll); + if (ret) use_dfll = old_use_dfll; - } else { - ret = clk_set_rate_locked(c->parent, - clk_get_rate_locked(c->parent)); - if (ret) { - use_dfll = old_use_dfll; - tegra_dvfs_set_dfll_range( - c->parent->dvfs, use_dfll); - } - } + return ret; + } else { + pr_warn("\n%s: Failed to set use_dfll\n", __func__); + pr_warn("DFLL usage is under thermal cooling device control\n"); + return -EACCES; } - clk_unlock_restore(c->parent, &p_flags); - clk_unlock_restore(c, &c_flags); - tegra_update_cpu_edp_limits(); - return ret; } static struct kernel_param_ops tegra12_use_dfll_ops = { @@ -8926,7 +8889,9 @@ static void __init tegra12_dfll_cpu_late_init(struct clk *c) if (!ret) { c->state = OFF; if (tegra_platform_is_silicon()) { - use_dfll = CONFIG_TEGRA_USE_DFLL_RANGE; + if (CONFIG_TEGRA_USE_DFLL_RANGE != + TEGRA_USE_DFLL_CDEV_CNTRL) + use_dfll = CONFIG_TEGRA_USE_DFLL_RANGE; #ifdef CONFIG_ARCH_TEGRA_13x_SOC if (tegra_cpu_speedo_id() == 0) use_dfll = 0; |