diff options
author | Taniya Das <tdas@codeaurora.org> | 2014-07-10 16:32:12 +0530 |
---|---|---|
committer | Taniya Das <tdas@codeaurora.org> | 2014-07-25 15:07:09 +0530 |
commit | 9d284232ab66e08682bbcb6f2838d93f4d865e64 (patch) | |
tree | 1bfac22d132479c4a263b7066c74104631de9ffe | |
parent | ab1c56b8800190115b54782af93d0130021995a7 (diff) |
devfreq_cpubw: Support vote for CPU to DDR absolute bandwidth
In the cases where the cpu does not vote for ddr absolute bandwidth and
the instantaneous bandwidths does not fully help at system level use
cases.
Add support to take the absolute bandwidth table and the values could
be taken from system-wide analysis done based on instantaneous
bandwidth.
Change-Id: Ic33ad990ae8e0fd12e7accc35635eff4a97d0bca
Signed-off-by: Taniya Das <tdas@codeaurora.org>
-rw-r--r-- | Documentation/devicetree/bindings/arm/msm/cpubw.txt | 7 | ||||
-rw-r--r-- | arch/arm/mach-msm/devfreq_cpubw.c | 45 |
2 files changed, 51 insertions, 1 deletions
diff --git a/Documentation/devicetree/bindings/arm/msm/cpubw.txt b/Documentation/devicetree/bindings/arm/msm/cpubw.txt index 1dc38357ec6f..64c7a4854b97 100644 --- a/Documentation/devicetree/bindings/arm/msm/cpubw.txt +++ b/Documentation/devicetree/bindings/arm/msm/cpubw.txt @@ -13,6 +13,13 @@ Required properties: subsystem to DDR. The list of values depend on the supported DDR frequencies and the bus widths. +Optional properties: +- qcom,ab-tbl: A list of pre-calculated absolute bandwidth values + (in MB/s) that can be requested from the CPU subsystem + to DDR for particular instantaneous bandwidth. The list + of values could depend on a certain percentage of + instantaneous bandwidth. + Example: qcom,cpubw { diff --git a/arch/arm/mach-msm/devfreq_cpubw.c b/arch/arm/mach-msm/devfreq_cpubw.c index 50d8a45247d9..5498bab63673 100644 --- a/arch/arm/mach-msm/devfreq_cpubw.c +++ b/arch/arm/mach-msm/devfreq_cpubw.c @@ -48,6 +48,7 @@ static struct msm_bus_scale_pdata bw_data = { static int num_paths; static u32 bus_client; +static unsigned int *freq_ab_table; static int set_bw(int new_ib, int new_ab) { static int cur_idx, cur_ab, cur_ib; @@ -77,6 +78,22 @@ static int set_bw(int new_ib, int new_ab) return ret; } +static unsigned int find_ab(struct devfreq_dev_profile *p, unsigned long *freq) +{ + int i; + unsigned long f; + + if (freq_ab_table == NULL) + return 0; + + for (i = 0; i < p->max_state; i++) { + f = p->freq_table[i]; + if (f == *freq) + break; + } + return freq_ab_table[i]; +} + static void find_freq(struct devfreq_dev_profile *p, unsigned long *freq, u32 flags) { @@ -105,7 +122,11 @@ static long gov_ab; int cpubw_target(struct device *dev, unsigned long *freq, u32 flags) { find_freq(&cpubw_profile, freq, flags); - return set_bw(*freq, gov_ab); + + if (!gov_ab) + return set_bw(*freq, find_ab(&cpubw_profile, freq)); + else + return set_bw(*freq, gov_ab); } static struct devfreq_governor_data gov_data[] = { @@ -125,6 +146,7 @@ struct devfreq_dev_profile cpubw_profile = { #define PROP_PORTS "qcom,cpu-mem-ports" #define PROP_TBL "qcom,bw-tbl" +#define PROP_AB_TBL "qcom,ab-tbl" static int __init cpubw_probe(struct platform_device *pdev) { @@ -182,6 +204,27 @@ static int __init cpubw_probe(struct platform_device *pdev) p->max_state = len; } + if (of_find_property(dev->of_node, PROP_AB_TBL, &len)) { + len /= sizeof(*data); + data = devm_kzalloc(dev, len * sizeof(*data), GFP_KERNEL); + if (!data) + return -ENOMEM; + + freq_ab_table = devm_kzalloc(dev, + len * sizeof(*freq_ab_table), + GFP_KERNEL); + if (!freq_ab_table) + return -ENOMEM; + + ret = of_property_read_u32_array(dev->of_node, PROP_AB_TBL, + data, len); + if (ret) + return ret; + + for (i = 0; i < len; i++) + freq_ab_table[i] = data[i]; + } + bus_client = msm_bus_scale_register_client(&bw_data); if (!bus_client) { dev_err(dev, "Unable to register bus client\n"); |