summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorsreenivasulu velpula <svelpula@nvidia.com>2014-07-18 15:03:40 +0530
committerWinnie Hsu <whsu@nvidia.com>2014-10-27 12:52:43 -0700
commit4d44978f208f23fde7feef510b5490ee11335298 (patch)
treeb5ad2e34100c8e525d6b03bb0dbd7983d001cc8a
parent982f479a7a11fb0aeb997bbe001d48f983e9c3f3 (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.h12
-rw-r--r--arch/arm/mach-tegra/tegra12_clocks.c61
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;