diff --git a/drivers/gpu/msm/adreno.c b/drivers/gpu/msm/adreno.c index 8e4933975c38..e783c6e09bae 100644 --- a/drivers/gpu/msm/adreno.c +++ b/drivers/gpu/msm/adreno.c @@ -769,58 +769,6 @@ 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) - 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; - } -} - /* Dynamically build the OPP table for the GPU device */ static void adreno_build_opp_table(struct device *dev, struct kgsl_pwrctrl *pwr) { @@ -1030,7 +978,7 @@ static int adreno_of_get_pwrlevels(struct adreno_device *adreno_dev, if (of_property_read_u32(child, "qcom,speed-bin", &bin)) continue; - if (bin == adreno_dev->speed_bin) { + if (bin == device->speed_bin) { int ret; ret = adreno_of_parse_pwrlevels(adreno_dev, child); @@ -1052,7 +1000,7 @@ static int adreno_of_get_pwrlevels(struct adreno_device *adreno_dev, dev_err(&device->pdev->dev, "GPU speed_bin:%d mismatch for efused bin:%d\n", - adreno_dev->speed_bin, bin); + device->speed_bin, bin); return -ENODEV; } @@ -1119,9 +1067,6 @@ 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); - l3_pwrlevel_probe(device, node); /* Default timeout is 80 ms across all targets */ @@ -1418,7 +1363,7 @@ static int adreno_bind(struct device *dev) if (status < 0) return status; - adreno_dev->speed_bin = status; + device->speed_bin = status; /* Get the chip ID from the DT and set up target specific parameters */ if (adreno_identify_gpu(adreno_dev)) @@ -2507,7 +2452,7 @@ static int adreno_prop_u32(struct kgsl_device *device, else if (param->type == KGSL_PROP_DEVICE_BITNESS) val = adreno_support_64bit(adreno_dev) ? 48 : 32; else if (param->type == KGSL_PROP_SPEED_BIN) - val = adreno_dev->speed_bin; + val = device->speed_bin; return copy_prop(param, &val, sizeof(val)); } diff --git a/drivers/gpu/msm/adreno.h b/drivers/gpu/msm/adreno.h index aeef52bd585a..155590d55511 100644 --- a/drivers/gpu/msm/adreno.h +++ b/drivers/gpu/msm/adreno.h @@ -416,7 +416,6 @@ struct adreno_gpu_core { * @lm_threshold_count: register value for counter for lm threshold breakin * @lm_threshold_cross: number of current peaks exceeding threshold * @ifpc_count: Number of times the GPU went into IFPC - * @speed_bin: Indicate which power level set to use * @highest_bank_bit: Value of the highest bank bit * @csdev: Pointer to a coresight device (if applicable) * @gpmu_throttle_counters - counteers for number of throttled clocks @@ -499,7 +498,6 @@ struct adreno_device { uint32_t lm_threshold_cross; uint32_t ifpc_count; - unsigned int speed_bin; unsigned int highest_bank_bit; unsigned int quirks; diff --git a/drivers/gpu/msm/kgsl_device.h b/drivers/gpu/msm/kgsl_device.h index 9e45d8455f58..2d82dc7384ce 100644 --- a/drivers/gpu/msm/kgsl_device.h +++ b/drivers/gpu/msm/kgsl_device.h @@ -314,6 +314,8 @@ struct kgsl_device { struct list_head event_groups; /** @event_groups_lock: A R/W lock for the events group list */ rwlock_t event_groups_lock; + /** @speed_bin: Speed bin for the GPU device if applicable */ + u32 speed_bin; }; #define KGSL_MMU_DEVICE(_mmu) \ diff --git a/drivers/gpu/msm/kgsl_pwrscale.c b/drivers/gpu/msm/kgsl_pwrscale.c index 9c2c6c7ca1c1..c07cc7583084 100644 --- a/drivers/gpu/msm/kgsl_pwrscale.c +++ b/drivers/gpu/msm/kgsl_pwrscale.c @@ -709,6 +709,61 @@ static void pwrscale_busmon_create(struct kgsl_device *device, pwrscale->gpu_profile.bus_devfreq = bus_devfreq; } +static void pwrscale_of_get_ca_target_pwrlevel(struct kgsl_device *device, + struct device_node *node) +{ + u32 pwrlevel = 1; + + of_property_read_u32(node, "qcom,ca-target-pwrlevel", &pwrlevel); + + if (pwrlevel >= device->pwrctrl.num_pwrlevels) + pwrlevel = 1; + + device->pwrscale.ctxt_aware_target_pwrlevel = pwrlevel; +} + +/* Get context aware properties */ +static void pwrscale_of_ca_aware(struct kgsl_device *device) +{ + struct kgsl_pwrscale *pwrscale = &device->pwrscale; + struct device_node *parent = device->pdev->dev.of_node; + struct device_node *node, *child; + + pwrscale->ctxt_aware_enable = + of_property_read_bool(parent, "qcom,enable-ca-jump"); + + if (!pwrscale->ctxt_aware_enable) + return; + + pwrscale->ctxt_aware_busy_penalty = 12000; + of_property_read_u32(parent, "qcom,ca-busy-penalty", + &pwrscale->ctxt_aware_busy_penalty); + + + pwrscale->ctxt_aware_target_pwrlevel = 1; + + node = of_find_node_by_name(parent, "qcom,gpu-pwrlevel-bins"); + if (node == NULL) { + pwrscale_of_get_ca_target_pwrlevel(device, parent); + return; + } + + for_each_child_of_node(node, child) { + u32 bin; + + if (of_property_read_u32(child, "qcom,speed-bin", &bin)) + continue; + + if (bin == device->speed_bin) { + pwrscale_of_get_ca_target_pwrlevel(device, child); + of_node_put(child); + break; + } + } + + of_node_put(node); +} + int kgsl_pwrscale_init(struct kgsl_device *device, struct platform_device *pdev, const char *governor) { @@ -734,6 +789,8 @@ int kgsl_pwrscale_init(struct kgsl_device *device, struct platform_device *pdev, pwr->nb.notifier_call = opp_notify; + pwrscale_of_ca_aware(device); + dev_pm_opp_register_notifier(&pdev->dev, &pwr->nb); srcu_init_notifier_head(&pwrscale->nh);