mirror of
https://github.com/hardkernel/linux.git
synced 2026-06-10 21:07:02 +09:00
ARM: tegra: dvfs: Allow boot or run time disabling of dvfs rails
Change-Id: Ie56cbf4ade1bbdb5835851f3c09668c1e0941a2c Signed-off-by: Colin Cross <ccross@android.com>
This commit is contained in:
@@ -32,6 +32,7 @@ void __init tegra_reserve(unsigned long carveout_size, unsigned long fb_size,
|
||||
void __init tegra_protected_aperture_init(unsigned long aperture);
|
||||
void tegra_move_framebuffer(unsigned long to, unsigned long from,
|
||||
unsigned long size);
|
||||
int tegra_dvfs_rail_disable_by_name(const char *reg_id);
|
||||
|
||||
extern unsigned long tegra_bootloader_fb_start;
|
||||
extern unsigned long tegra_bootloader_fb_size;
|
||||
|
||||
@@ -395,6 +395,64 @@ static struct notifier_block tegra_dvfs_nb = {
|
||||
.notifier_call = tegra_dvfs_pm_notify,
|
||||
};
|
||||
|
||||
/* must be called with dvfs lock held */
|
||||
static void __tegra_dvfs_rail_disable(struct dvfs_rail *rail)
|
||||
{
|
||||
int ret;
|
||||
|
||||
if (!rail->disabled) {
|
||||
ret = dvfs_rail_set_voltage(rail, rail->nominal_millivolts);
|
||||
if (ret)
|
||||
pr_info("dvfs: failed to set regulator %s to disable "
|
||||
"voltage %d\n", rail->reg_id,
|
||||
rail->nominal_millivolts);
|
||||
rail->disabled = true;
|
||||
}
|
||||
}
|
||||
|
||||
/* must be called with dvfs lock held */
|
||||
static void __tegra_dvfs_rail_enable(struct dvfs_rail *rail)
|
||||
{
|
||||
if (rail->disabled) {
|
||||
rail->disabled = false;
|
||||
dvfs_rail_update(rail);
|
||||
}
|
||||
}
|
||||
|
||||
void tegra_dvfs_rail_enable(struct dvfs_rail *rail)
|
||||
{
|
||||
mutex_lock(&dvfs_lock);
|
||||
__tegra_dvfs_rail_enable(rail);
|
||||
mutex_unlock(&dvfs_lock);
|
||||
}
|
||||
|
||||
void tegra_dvfs_rail_disable(struct dvfs_rail *rail)
|
||||
{
|
||||
mutex_lock(&dvfs_lock);
|
||||
__tegra_dvfs_rail_disable(rail);
|
||||
mutex_unlock(&dvfs_lock);
|
||||
}
|
||||
|
||||
int tegra_dvfs_rail_disable_by_name(const char *reg_id)
|
||||
{
|
||||
struct dvfs_rail *rail;
|
||||
int ret = 0;
|
||||
|
||||
mutex_lock(&dvfs_lock);
|
||||
list_for_each_entry(rail, &dvfs_rail_list, node) {
|
||||
if (!strcmp(reg_id, rail->reg_id)) {
|
||||
__tegra_dvfs_rail_disable(rail);
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
|
||||
ret = -EINVAL;
|
||||
|
||||
out:
|
||||
mutex_unlock(&dvfs_lock);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
* Iterate through all the dvfs regulators, finding the regulator exported
|
||||
* by the regulator api for each one. Must be called in late init, after
|
||||
|
||||
@@ -87,5 +87,7 @@ int dvfs_debugfs_init(struct dentry *clk_debugfs_root);
|
||||
int tegra_dvfs_late_init(void);
|
||||
int tegra_dvfs_init_rails(struct dvfs_rail *dvfs_rails[], int n);
|
||||
void tegra_dvfs_add_relationships(struct dvfs_relationship *rels, int n);
|
||||
void tegra_dvfs_rail_enable(struct dvfs_rail *rail);
|
||||
void tegra_dvfs_rail_disable(struct dvfs_rail *rail);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -20,11 +20,23 @@
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/string.h>
|
||||
#include <linux/module.h>
|
||||
|
||||
#include "clock.h"
|
||||
#include "dvfs.h"
|
||||
#include "fuse.h"
|
||||
|
||||
#ifdef CONFIG_TEGRA_CORE_DVFS
|
||||
static bool tegra_dvfs_core_disabled;
|
||||
#else
|
||||
static bool tegra_dvfs_core_disabled = true;
|
||||
#endif
|
||||
#ifdef CONFIG_TEGRA_CPU_DVFS
|
||||
static bool tegra_dvfs_cpu_disabled;
|
||||
#else
|
||||
static bool tegra_dvfs_cpu_disabled = true;
|
||||
#endif
|
||||
|
||||
static const int core_millivolts[MAX_DVFS_FREQS] =
|
||||
{950, 1000, 1100, 1200, 1275};
|
||||
static const int cpu_millivolts[MAX_DVFS_FREQS] =
|
||||
@@ -38,9 +50,6 @@ static struct dvfs_rail tegra2_dvfs_rail_vdd_cpu = {
|
||||
.max_millivolts = 1100,
|
||||
.min_millivolts = 750,
|
||||
.nominal_millivolts = 1100,
|
||||
#ifndef CONFIG_TEGRA_CPU_DVFS
|
||||
.disabled = true,
|
||||
#endif
|
||||
};
|
||||
|
||||
static struct dvfs_rail tegra2_dvfs_rail_vdd_core = {
|
||||
@@ -49,9 +58,6 @@ static struct dvfs_rail tegra2_dvfs_rail_vdd_core = {
|
||||
.min_millivolts = 950,
|
||||
.nominal_millivolts = 1200,
|
||||
.step = 150, /* step vdd_core by 150 mV to allow vdd_aon to follow */
|
||||
#ifndef CONFIG_TEGRA_CORE_DVFS
|
||||
.disabled = true,
|
||||
#endif
|
||||
};
|
||||
|
||||
static struct dvfs_rail tegra2_dvfs_rail_vdd_aon = {
|
||||
@@ -195,6 +201,58 @@ static struct dvfs dvfs_init[] = {
|
||||
CORE_DVFS("NVRM_DEVID_CLK_SRC", 1, MHZ, 480, 600, 800, 1067, 1067),
|
||||
};
|
||||
|
||||
int tegra_dvfs_disable_core_set(const char *arg, const struct kernel_param *kp)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = param_set_bool(arg, kp);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
if (tegra_dvfs_core_disabled)
|
||||
tegra_dvfs_rail_disable(&tegra2_dvfs_rail_vdd_core);
|
||||
else
|
||||
tegra_dvfs_rail_enable(&tegra2_dvfs_rail_vdd_core);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int tegra_dvfs_disable_cpu_set(const char *arg, const struct kernel_param *kp)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = param_set_bool(arg, kp);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
if (tegra_dvfs_cpu_disabled)
|
||||
tegra_dvfs_rail_disable(&tegra2_dvfs_rail_vdd_cpu);
|
||||
else
|
||||
tegra_dvfs_rail_enable(&tegra2_dvfs_rail_vdd_cpu);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int tegra_dvfs_disable_get(char *buffer, const struct kernel_param *kp)
|
||||
{
|
||||
return param_get_bool(buffer, kp);
|
||||
}
|
||||
|
||||
static struct kernel_param_ops tegra_dvfs_disable_core_ops = {
|
||||
.set = tegra_dvfs_disable_core_set,
|
||||
.get = tegra_dvfs_disable_get,
|
||||
};
|
||||
|
||||
static struct kernel_param_ops tegra_dvfs_disable_cpu_ops = {
|
||||
.set = tegra_dvfs_disable_cpu_set,
|
||||
.get = tegra_dvfs_disable_get,
|
||||
};
|
||||
|
||||
module_param_cb(disable_core, &tegra_dvfs_disable_core_ops,
|
||||
&tegra_dvfs_core_disabled, 0644);
|
||||
module_param_cb(disable_cpu, &tegra_dvfs_disable_cpu_ops,
|
||||
&tegra_dvfs_cpu_disabled, 0644);
|
||||
|
||||
void __init tegra2_init_dvfs(void)
|
||||
{
|
||||
int i;
|
||||
@@ -230,4 +288,10 @@ void __init tegra2_init_dvfs(void)
|
||||
pr_err("tegra_dvfs: failed to enable dvfs on %s\n",
|
||||
c->name);
|
||||
}
|
||||
|
||||
if (tegra_dvfs_core_disabled)
|
||||
tegra_dvfs_rail_disable(&tegra2_dvfs_rail_vdd_core);
|
||||
|
||||
if (tegra_dvfs_cpu_disabled)
|
||||
tegra_dvfs_rail_disable(&tegra2_dvfs_rail_vdd_cpu);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user