summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTaniya Das <tdas@codeaurora.org>2014-07-10 16:32:12 +0530
committerTaniya Das <tdas@codeaurora.org>2014-07-25 15:07:09 +0530
commit9d284232ab66e08682bbcb6f2838d93f4d865e64 (patch)
tree1bfac22d132479c4a263b7066c74104631de9ffe
parentab1c56b8800190115b54782af93d0130021995a7 (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.txt7
-rw-r--r--arch/arm/mach-msm/devfreq_cpubw.c45
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");