summaryrefslogtreecommitdiff
path: root/arch
diff options
context:
space:
mode:
authorAlex Frid <afrid@nvidia.com>2012-05-26 20:12:01 -0700
committerSimone Willett <swillett@nvidia.com>2012-06-07 12:56:02 -0700
commitcc87e66730f603e339476619818d7b30906a172a (patch)
tree5211271034a156c5a4c53eee27f8f743ab59afc0 /arch
parent25c3334f0e1ea6bde84c0514bad0eb1859566dba (diff)
ARM: tegra: dvfs: Re-factor CPU alternative dvfs
Removed alternative frequencies table from dvfs structure, and replaced it with table pointer to facilitate future support for multiple alternative tables. Actually supported alternative dvfs table (Tegra3 CPU cold zone table) is not changed. Change-Id: Ia8c1d1f2dd450f0e48685e769ca925b8e6f5b57b Signed-off-by: Alex Frid <afrid@nvidia.com> Reviewed-on: http://git-master/r/104882 Reviewed-by: Simone Willett <swillett@nvidia.com> Tested-by: Simone Willett <swillett@nvidia.com>
Diffstat (limited to 'arch')
-rw-r--r--arch/arm/mach-tegra/dvfs.c25
-rw-r--r--arch/arm/mach-tegra/dvfs.h14
-rw-r--r--arch/arm/mach-tegra/tegra3_dvfs.c18
3 files changed, 21 insertions, 36 deletions
diff --git a/arch/arm/mach-tegra/dvfs.c b/arch/arm/mach-tegra/dvfs.c
index 8723e6fa60df..cb33e3db862f 100644
--- a/arch/arm/mach-tegra/dvfs.c
+++ b/arch/arm/mach-tegra/dvfs.c
@@ -322,8 +322,7 @@ static int dvfs_rail_connect_to_regulator(struct dvfs_rail *rail)
static inline unsigned long *dvfs_get_freqs(struct dvfs *d)
{
- return (d->alt_freqs_state == ALT_FREQS_ENABLED) ?
- &d->alt_freqs[0] : &d->freqs[0];
+ return d->alt_freqs ? : &d->freqs[0];
}
static int
@@ -367,26 +366,16 @@ __tegra_dvfs_set_rate(struct dvfs *d, unsigned long rate)
return ret;
}
-static inline int dvfs_alt_freqs_set(struct dvfs *d, bool enable)
+int tegra_dvfs_alt_freqs_set(struct dvfs *d, unsigned long *alt_freqs)
{
- if (d->alt_freqs_state == ALT_FREQS_NOT_SUPPORTED)
- return -ENOSYS;
-
- d->alt_freqs_state = enable ? ALT_FREQS_ENABLED : ALT_FREQS_DISABLED;
- return 0;
-}
-
-int tegra_dvfs_alt_freqs_set(struct dvfs *d, bool enable)
-{
- int ret;
- enum dvfs_alt_freqs old_state;
+ int ret = 0;
mutex_lock(&dvfs_lock);
- old_state = d->alt_freqs_state;
- ret = dvfs_alt_freqs_set(d, enable);
- if (!ret && (old_state != d->alt_freqs_state))
+ if (d->alt_freqs != alt_freqs) {
+ d->alt_freqs = alt_freqs;
ret = __tegra_dvfs_set_rate(d, d->cur_rate);
+ }
mutex_unlock(&dvfs_lock);
return ret;
@@ -407,7 +396,7 @@ int tegra_dvfs_predict_millivolts(struct clk *c, unsigned long rate)
* frequency limits. For now, just fail the call for clock that has
* alternative limits initialized.
*/
- if (c->dvfs->alt_freqs_state != ALT_FREQS_NOT_SUPPORTED)
+ if (c->dvfs->alt_freqs)
return -ENOSYS;
for (i = 0; i < c->dvfs->num_freqs; i++) {
diff --git a/arch/arm/mach-tegra/dvfs.h b/arch/arm/mach-tegra/dvfs.h
index a53a04ba95a2..f0de99146972 100644
--- a/arch/arm/mach-tegra/dvfs.h
+++ b/arch/arm/mach-tegra/dvfs.h
@@ -73,12 +73,6 @@ struct dvfs_rail {
struct rail_stats stats;
};
-enum dvfs_alt_freqs {
- ALT_FREQS_NOT_SUPPORTED = 0,
- ALT_FREQS_DISABLED,
- ALT_FREQS_ENABLED,
-};
-
struct dvfs {
/* Used only by tegra2_clock.c */
const char *clk_name;
@@ -88,11 +82,10 @@ struct dvfs {
/* Must be initialized before tegra_dvfs_init */
int freqs_mult;
unsigned long freqs[MAX_DVFS_FREQS];
- unsigned long alt_freqs[MAX_DVFS_FREQS];
+ unsigned long *alt_freqs;
const int *millivolts;
struct dvfs_rail *dvfs_rail;
bool auto_dvfs;
- enum dvfs_alt_freqs alt_freqs_state;
/* Filled in by tegra_dvfs_init */
int max_millivolts;
@@ -124,7 +117,7 @@ struct dvfs_rail *tegra_dvfs_get_rail_by_name(const char *reg_id);
int tegra_dvfs_predict_millivolts(struct clk *c, unsigned long rate);
void tegra_dvfs_core_cap_enable(bool enable);
void tegra_dvfs_core_cap_level_set(int level);
-int tegra_dvfs_alt_freqs_set(struct dvfs *d, bool enable);
+int tegra_dvfs_alt_freqs_set(struct dvfs *d, unsigned long *alt_freqs);
void tegra_cpu_dvfs_alter(int edp_thermal_index, bool before_clk_update);
#else
static inline void tegra_soc_init_dvfs(void)
@@ -160,7 +153,8 @@ static inline void tegra_dvfs_core_cap_enable(bool enable)
{}
static inline void tegra_dvfs_core_cap_level_set(int level)
{}
-static inline int tegra_dvfs_alt_freqs_set(struct dvfs *d, bool enable)
+static inline int tegra_dvfs_alt_freqs_set(struct dvfs *d,
+ unsigned long *alt_freqs)
{ return 0; }
static inline void tegra_cpu_dvfs_alter(int edp_thermal_index,
bool before_clk_update)
diff --git a/arch/arm/mach-tegra/tegra3_dvfs.c b/arch/arm/mach-tegra/tegra3_dvfs.c
index f36bfa774577..9b7b8a54b75a 100644
--- a/arch/arm/mach-tegra/tegra3_dvfs.c
+++ b/arch/arm/mach-tegra/tegra3_dvfs.c
@@ -352,6 +352,8 @@ static struct dvfs core_dvfs_table[] = {
CORE_DVFS("spdif_out", -1, 1, KHZ, 1, 26000, 26000, 26000, 26000, 26000, 26000, 26000, 26000),
};
+/* CPU alternative DVFS table for cold zone */
+static unsigned long cpu_cold_freqs[MAX_DVFS_FREQS];
int tegra_dvfs_disable_core_set(const char *arg, const struct kernel_param *kp)
{
@@ -473,19 +475,18 @@ static void __init init_dvfs_cold(struct dvfs *d, int nominal_mv_index)
for (i = 0; i < d->num_freqs; i++) {
offs = cpu_cold_offs_mhz[i] * MHZ;
if (i > nominal_mv_index)
- d->alt_freqs[i] = d->alt_freqs[i - 1];
+ cpu_cold_freqs[i] = cpu_cold_freqs[i - 1];
else if (d->freqs[i] > offs)
- d->alt_freqs[i] = d->freqs[i] - offs;
+ cpu_cold_freqs[i] = d->freqs[i] - offs;
else {
- d->alt_freqs[i] = d->freqs[i];
+ cpu_cold_freqs[i] = d->freqs[i];
pr_warn("tegra3_dvfs: cold offset %lu is too high for"
" regular dvfs limit %lu\n", offs, d->freqs[i]);
}
if (i)
- BUG_ON(d->alt_freqs[i] < d->alt_freqs[i - 1]);
+ BUG_ON(cpu_cold_freqs[i] < cpu_cold_freqs[i - 1]);
}
- d->alt_freqs_state = ALT_FREQS_DISABLED;
}
static bool __init match_dvfs_one(struct dvfs *d, int speedo_id, int process_id)
@@ -664,10 +665,11 @@ void __init tegra_soc_init_dvfs(void)
void tegra_cpu_dvfs_alter(int edp_thermal_index, bool before_clk_update)
{
- bool enable = !edp_thermal_index;
+ bool cpu_warm = !!edp_thermal_index;
+ unsigned long *alt_freqs = cpu_warm ? NULL : cpu_cold_freqs;
- if (enable != before_clk_update) {
- int ret = tegra_dvfs_alt_freqs_set(cpu_dvfs, enable);
+ if (cpu_warm == before_clk_update) {
+ int ret = tegra_dvfs_alt_freqs_set(cpu_dvfs, alt_freqs);
WARN_ONCE(ret, "tegra dvfs: failed to set CPU alternative"
" frequency limits for cold temeperature\n");
}