diff options
author | Amit Kamath <akamath@nvidia.com> | 2012-12-17 12:52:30 +0530 |
---|---|---|
committer | Dan Willemsen <dwillemsen@nvidia.com> | 2013-09-14 13:00:02 -0700 |
commit | e0d6b4d9de4beb9fe707926763eeb36f3c07805e (patch) | |
tree | cea2cb658dca425304d395104d62f9bf63b99795 /arch/arm/mach-tegra/edp.c | |
parent | 14870896838bd1365d5b08b5920209a5763e517f (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.c | 47 |
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; |