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 065bacfd8c77..0137001b8fc3 100644 --- a/drivers/gpu/msm/adreno.c +++ b/drivers/gpu/msm/adreno.c @@ -849,6 +849,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) { @@ -1018,6 +1070,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 b5249b366db9..e207a073c78a 100644 --- a/drivers/gpu/msm/kgsl_pwrscale.c +++ b/drivers/gpu/msm/kgsl_pwrscale.c @@ -985,24 +985,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 f74f7315bac6..9e28b6594b8d 100644 --- a/drivers/gpu/msm/kgsl_pwrscale.h +++ b/drivers/gpu/msm/kgsl_pwrscale.h @@ -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);