From 6996ed3d124a487933edfb831a231f191b72918d Mon Sep 17 00:00:00 2001 From: Deepak Kumar Date: Wed, 7 Mar 2018 20:06:58 +0530 Subject: [PATCH] msm: kgsl: Specify context aware target power level for each speed bin Some platforms support multiple GPU clock plans based on the speed bin in the efuse. Specify context aware DCVS target power level for each speed bin to make sure context aware jump happens at correct level for each GPU clock plan. Change-Id: I4837423815c94d5d0966d4f7ea7a4427d65d0d50 Signed-off-by: Deepak Kumar --- .../bindings/gpu/adreno-pwrlevels.txt | 4 ++ .../devicetree/bindings/gpu/adreno.txt | 19 +++++++ drivers/gpu/msm/adreno.c | 55 +++++++++++++++++++ drivers/gpu/msm/kgsl_pwrscale.c | 24 ++------ drivers/gpu/msm/kgsl_pwrscale.h | 10 +++- 5 files changed, 93 insertions(+), 19 deletions(-) diff --git a/Documentation/devicetree/bindings/gpu/adreno-pwrlevels.txt b/Documentation/devicetree/bindings/gpu/adreno-pwrlevels.txt index aece6ac44b78..747e0b601da2 100644 --- a/Documentation/devicetree/bindings/gpu/adreno-pwrlevels.txt +++ b/Documentation/devicetree/bindings/gpu/adreno-pwrlevels.txt @@ -17,6 +17,10 @@ Properties: - qcom,gpu-pwrlevel: A single powerlevel +- qcom,ca-target-pwrlevel: + This value indicates which qcom,gpu-pwrlevel + to jump on in case of context aware power level + jump. Properties: - reg: Index of the powerlevel (0 = highest perf) - qcom,gpu-freq GPU frequency for the powerlevel (in Hz) diff --git a/Documentation/devicetree/bindings/gpu/adreno.txt b/Documentation/devicetree/bindings/gpu/adreno.txt index 375e929ab367..7976a8728b15 100644 --- a/Documentation/devicetree/bindings/gpu/adreno.txt +++ b/Documentation/devicetree/bindings/gpu/adreno.txt @@ -167,6 +167,15 @@ Optional Properties: Specify the size of snapshot in bytes. This will override snapshot size defined in the driver code. +- qcom,enable-ca-jump: + Boolean. Enables use of context aware DCVS +- qcom,ca-busy-penalty: + This property represents the time in microseconds required to + initiate context aware power level jump. +- qcom,ca-target-pwrlevel: + This value indicates which qcom,gpu-pwrlevel to jump on in case + of context aware power level jump. + - qcom,gpu-qdss-stm: baseAddr - base address of the gpu channels in the qdss stm memory region @@ -323,6 +332,15 @@ Example of A330 GPU in MSM8916: coresight-child-list = <&funnel_in0>; coresight-child-ports = <5>; + /* Enable context aware freq. scaling */ + qcom,enable-ca-jump; + + /* Context aware jump busy penalty in us */ + qcom,ca-busy-penalty = <12000>; + + /* Context aware jump target power level */ + qcom,ca-target-pwrlevel = <1>; + qcom,soc-hw-revisions { #address-cells = <1>; #size-cells = <0>; @@ -389,6 +407,7 @@ Example of A330 GPU in MSM8916: #size-cells = <0>; qcom,speed-bin = <0>; + qcom,ca-target-pwrlevel = <1>; qcom,gpu-pwrlevel@0 { reg = <0>; diff --git a/drivers/gpu/msm/adreno.c b/drivers/gpu/msm/adreno.c index ab9f20363c84..9a0d2e6dfcf6 100644 --- a/drivers/gpu/msm/adreno.c +++ b/drivers/gpu/msm/adreno.c @@ -848,6 +848,58 @@ static const struct of_device_id adreno_match_table[] = { {} }; +static void adreno_of_get_ca_target_pwrlevel(struct adreno_device *adreno_dev, + struct device_node *node) +{ + struct kgsl_device *device = KGSL_DEVICE(adreno_dev); + unsigned int ca_target_pwrlevel = 1; + + of_property_read_u32(node, "qcom,ca-target-pwrlevel", + &ca_target_pwrlevel); + + if (ca_target_pwrlevel > device->pwrctrl.num_pwrlevels - 2) + ca_target_pwrlevel = 1; + + device->pwrscale.ctxt_aware_target_pwrlevel = ca_target_pwrlevel; +} + +static void adreno_of_get_ca_aware_properties(struct adreno_device *adreno_dev, + struct device_node *parent) +{ + struct kgsl_device *device = KGSL_DEVICE(adreno_dev); + struct kgsl_pwrscale *pwrscale = &device->pwrscale; + struct device_node *node, *child; + unsigned int bin = 0; + + pwrscale->ctxt_aware_enable = + of_property_read_bool(parent, "qcom,enable-ca-jump"); + + if (pwrscale->ctxt_aware_enable) { + if (of_property_read_u32(parent, "qcom,ca-busy-penalty", + &pwrscale->ctxt_aware_busy_penalty)) + pwrscale->ctxt_aware_busy_penalty = 12000; + + node = of_find_node_by_name(parent, "qcom,gpu-pwrlevel-bins"); + if (node == NULL) { + adreno_of_get_ca_target_pwrlevel(adreno_dev, parent); + return; + } + + for_each_child_of_node(node, child) { + if (of_property_read_u32(child, "qcom,speed-bin", &bin)) + continue; + + if (bin == adreno_dev->speed_bin) { + adreno_of_get_ca_target_pwrlevel(adreno_dev, + child); + return; + } + } + + pwrscale->ctxt_aware_target_pwrlevel = 1; + } +} + static int adreno_of_parse_pwrlevels(struct adreno_device *adreno_dev, struct device_node *node) { @@ -1005,6 +1057,9 @@ static int adreno_of_get_power(struct adreno_device *adreno_dev, if (adreno_of_get_pwrlevels(adreno_dev, node)) return -EINVAL; + /* Get context aware DCVS properties */ + adreno_of_get_ca_aware_properties(adreno_dev, node); + /* get pm-qos-active-latency, set it to default if not found */ if (of_property_read_u32(node, "qcom,pm-qos-active-latency", &device->pwrctrl.pm_qos_active_latency)) diff --git a/drivers/gpu/msm/kgsl_pwrscale.c b/drivers/gpu/msm/kgsl_pwrscale.c index 3f7ea18de21e..13c3981e7467 100644 --- a/drivers/gpu/msm/kgsl_pwrscale.c +++ b/drivers/gpu/msm/kgsl_pwrscale.c @@ -1039,24 +1039,12 @@ int kgsl_pwrscale_init(struct device *dev, const char *governor) data->disable_busy_time_burst = of_property_read_bool( device->pdev->dev.of_node, "qcom,disable-busy-time-burst"); - data->ctxt_aware_enable = - of_property_read_bool(device->pdev->dev.of_node, - "qcom,enable-ca-jump"); - - if (data->ctxt_aware_enable) { - if (of_property_read_u32(device->pdev->dev.of_node, - "qcom,ca-target-pwrlevel", - &data->bin.ctxt_aware_target_pwrlevel)) - data->bin.ctxt_aware_target_pwrlevel = 1; - - if ((data->bin.ctxt_aware_target_pwrlevel > - pwr->num_pwrlevels)) - data->bin.ctxt_aware_target_pwrlevel = 1; - - if (of_property_read_u32(device->pdev->dev.of_node, - "qcom,ca-busy-penalty", - &data->bin.ctxt_aware_busy_penalty)) - data->bin.ctxt_aware_busy_penalty = 12000; + if (pwrscale->ctxt_aware_enable) { + data->ctxt_aware_enable = pwrscale->ctxt_aware_enable; + data->bin.ctxt_aware_target_pwrlevel = + pwrscale->ctxt_aware_target_pwrlevel; + data->bin.ctxt_aware_busy_penalty = + pwrscale->ctxt_aware_busy_penalty; } if (of_property_read_bool(device->pdev->dev.of_node, diff --git a/drivers/gpu/msm/kgsl_pwrscale.h b/drivers/gpu/msm/kgsl_pwrscale.h index 7e906a04d174..9e28b6594b8d 100644 --- a/drivers/gpu/msm/kgsl_pwrscale.h +++ b/drivers/gpu/msm/kgsl_pwrscale.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2010-2017, The Linux Foundation. All rights reserved. +/* Copyright (c) 2010-2018, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -91,6 +91,11 @@ struct kgsl_pwr_history { * @popp_level - Current level of POPP mitigation * @popp_state - Control state for POPP, on/off, recently pushed, etc * @cooling_dev - Thermal cooling device handle + * @ctxt_aware_enable - Whether or not ctxt aware DCVS feature is enabled + * @ctxt_aware_busy_penalty - The time in microseconds required to trigger + * ctxt aware power level jump + * @ctxt_aware_target_pwrlevel - pwrlevel to jump on in case of ctxt aware + * power level jump */ struct kgsl_pwrscale { struct devfreq *devfreqptr; @@ -113,6 +118,9 @@ struct kgsl_pwrscale { int popp_level; unsigned long popp_state; struct thermal_cooling_device *cooling_dev; + bool ctxt_aware_enable; + unsigned int ctxt_aware_target_pwrlevel; + unsigned int ctxt_aware_busy_penalty; }; int kgsl_pwrscale_init(struct device *dev, const char *governor);