summaryrefslogtreecommitdiff
path: root/arch/arm/mach-tegra/edp.c
diff options
context:
space:
mode:
authorAmit Kamath <akamath@nvidia.com>2012-12-17 12:52:30 +0530
committerDan Willemsen <dwillemsen@nvidia.com>2013-09-14 13:00:02 -0700
commite0d6b4d9de4beb9fe707926763eeb36f3c07805e (patch)
treecea2cb658dca425304d395104d62f9bf63b99795 /arch/arm/mach-tegra/edp.c
parent14870896838bd1365d5b08b5920209a5763e517f (diff)
ARM: tegra: power: Add voltage to freq convertion interface.
Use EDP generated tables to calculate the frequency supported at a specified voltage bug 1042409 Reviewed-on: http://git-master/r/171819 (cherry picked from commit b15b288083e02f0caa7644a2e01f0703b501187f) Change-Id: Id2aa6ac61023b9c9de1810fe6a46e4a1bc70eed0 Signed-off-by: Amit Kamath <akamath@nvidia.com> Signed-off-by: Richard Zhao <rizhao@nvidia.com> Reviewed-on: http://git-master/r/199964 Reviewed-by: Simone Willett <swillett@nvidia.com> Tested-by: Simone Willett <swillett@nvidia.com>
Diffstat (limited to 'arch/arm/mach-tegra/edp.c')
-rw-r--r--arch/arm/mach-tegra/edp.c47
1 files changed, 42 insertions, 5 deletions
diff --git a/arch/arm/mach-tegra/edp.c b/arch/arm/mach-tegra/edp.c
index 53140190082e..b80891f0a787 100644
--- a/arch/arm/mach-tegra/edp.c
+++ b/arch/arm/mach-tegra/edp.c
@@ -477,6 +477,8 @@ static struct tegra_edp_cpu_leakage_params leakage_params[] = {
};
#endif
+static struct tegra_edp_freq_voltage_table *freq_voltage_lut_saved;
+static unsigned int freq_voltage_lut_size_saved;
static struct tegra_edp_freq_voltage_table *freq_voltage_lut;
static unsigned int freq_voltage_lut_size;
@@ -569,13 +571,15 @@ unsigned int edp_calculate_maxf(struct tegra_edp_cpu_leakage_params *params,
}
static int edp_relate_freq_voltage(struct clk *clk_cpu_g,
- unsigned int cpu_speedo_idx)
+ unsigned int cpu_speedo_idx,
+ unsigned int freq_volt_lut_size,
+ struct tegra_edp_freq_voltage_table *freq_volt_lut)
{
unsigned int i, j, freq;
int voltage_mV;
for (i = 0, j = 0, freq = 0;
- i < freq_voltage_lut_size;
+ i < freq_volt_lut_size;
i++, freq += FREQ_STEP) {
/* Predict voltages */
@@ -587,12 +591,24 @@ static int edp_relate_freq_voltage(struct clk *clk_cpu_g,
}
/* Cache frequency / voltage / voltage constant relationship */
- freq_voltage_lut[i].freq = freq;
- freq_voltage_lut[i].voltage_mV = voltage_mV;
+ freq_volt_lut[i].freq = freq;
+ freq_volt_lut[i].voltage_mV = voltage_mV;
}
return 0;
}
+unsigned int tegra_edp_find_maxf(int volt)
+{
+ unsigned int i;
+
+ for (i = 0; i < freq_voltage_lut_size_saved; i++) {
+ if (freq_voltage_lut_saved[i].voltage_mV > volt)
+ break;
+ }
+ return freq_voltage_lut[i - 1].freq;
+}
+
+
int edp_find_speedo_idx(int cpu_speedo_id, unsigned int *cpu_speedo_idx)
{
int i;
@@ -650,7 +666,8 @@ static int init_cpu_edp_limits_calculated(void)
return -ENOMEM;
}
- ret = edp_relate_freq_voltage(clk_cpu_g, cpu_speedo_idx);
+ ret = edp_relate_freq_voltage(clk_cpu_g, cpu_speedo_idx,
+ freq_voltage_lut_size, freq_voltage_lut);
if (ret) {
kfree(power_edp_calc_limits);
kfree(edp_calculated_limits);
@@ -658,6 +675,26 @@ static int init_cpu_edp_limits_calculated(void)
return ret;
}
+ if (freq_voltage_lut_size != freq_voltage_lut_size_saved) {
+ /* release previous table if present */
+ kfree(freq_voltage_lut_saved);
+ /* create table to save */
+ freq_voltage_lut_saved =
+ kmalloc(sizeof(struct tegra_edp_freq_voltage_table) *
+ freq_voltage_lut_size, GFP_KERNEL);
+ if (!freq_voltage_lut_saved) {
+ pr_err("%s: failed alloc mem for freq/voltage LUT\n",
+ __func__);
+ kfree(freq_voltage_lut);
+ return -ENOMEM;
+ }
+ freq_voltage_lut_size_saved = freq_voltage_lut_size;
+ }
+ memcpy(freq_voltage_lut_saved,
+ freq_voltage_lut,
+ sizeof(struct tegra_edp_freq_voltage_table) *
+ freq_voltage_lut_size);
+
/* Calculate EDP table */
for (n_cores_idx = 0; n_cores_idx < NR_CPUS; n_cores_idx++) {
for (temp_idx = 0;