diff options
author | Amit Kamath <akamath@nvidia.com> | 2012-12-17 12:52:30 +0530 |
---|---|---|
committer | Mandar Padmawar <mpadmawar@nvidia.com> | 2012-12-31 03:51:07 -0800 |
commit | b15b288083e02f0caa7644a2e01f0703b501187f (patch) | |
tree | 445040fdc81070d70a86b98db0f8c31e4c7473f5 /arch/arm/mach-tegra/edp.c | |
parent | ecc4e2210acde46a655433b33aa5fa1bec9b8cf6 (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
Change-Id: Id2aa6ac61023b9c9de1810fe6a46e4a1bc70eed0
Signed-off-by: Amit Kamath <akamath@nvidia.com>
Reviewed-on: http://git-master/r/171819
Reviewed-by: Mandar Padmawar <mpadmawar@nvidia.com>
Tested-by: Mandar Padmawar <mpadmawar@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 ff6d134b6c3f..033bb81d2437 100644 --- a/arch/arm/mach-tegra/edp.c +++ b/arch/arm/mach-tegra/edp.c @@ -422,6 +422,8 @@ static struct tegra_edp_cpu_leakage_params leakage_params[] = { }, }; +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; @@ -505,13 +507,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 */ @@ -523,12 +527,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; @@ -578,12 +594,33 @@ 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(freq_voltage_lut); 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 (temp_idx = 0; temp_idx < ARRAY_SIZE(temperatures); temp_idx++) { edp_calculated_limits[temp_idx]. |