Loading Documentation/devicetree/bindings/gpu/adreno.txt +2 −0 Original line number Diff line number Diff line Loading @@ -85,6 +85,8 @@ DCVS Core info Optional Properties: - qcom,initial-powerlevel: This value indicates which qcom,gpu-pwrlevel should be used at start time and when coming back out of resume - qcom,throttle-pwrlevel: This value indicates which qcom,gpu-pwrlevel LM throttling may start to occur - qcom,bus-control: Boolean. Enables an independent bus vote from the gpu frequency - qcom,bus-width: Bus width in number of bytes. This enables dynamic AB bus voting based on bus width and actual bus transactions. Loading drivers/gpu/msm/adreno.c +9 −0 Original line number Diff line number Diff line Loading @@ -1092,6 +1092,7 @@ static int adreno_of_get_power(struct adreno_device *adreno_dev, struct device_node *node = pdev->dev.of_node; struct resource *res; unsigned int timeout; unsigned int throt = 4; if (of_property_read_string(node, "label", &pdev->name)) { KGSL_CORE_ERR("Unable to read 'label'\n"); Loading Loading @@ -1120,6 +1121,14 @@ static int adreno_of_get_power(struct adreno_device *adreno_dev, if (adreno_of_get_pwrlevels(adreno_dev, node)) return -EINVAL; /* Get throttle power level */ of_property_read_u32(node, "qcom,throttle-pwrlevel", &throt); if (throt < device->pwrctrl.num_pwrlevels) device->pwrctrl.throttle_mask = GENMASK(device->pwrctrl.num_pwrlevels - 1, device->pwrctrl.num_pwrlevels - 1 - throt); /* Get context aware DCVS properties */ adreno_of_get_ca_aware_properties(adreno_dev, node); Loading drivers/gpu/msm/adreno_a6xx.c +3 −3 Original line number Diff line number Diff line Loading @@ -1424,7 +1424,7 @@ static int a6xx_soft_reset(struct adreno_device *adreno_dev) static int64_t a6xx_read_throttling_counters(struct adreno_device *adreno_dev) { int i; int64_t adj = 0; int64_t adj = -1; uint32_t counts[ADRENO_GPMU_THROTTLE_COUNTERS]; struct adreno_busy_data *busy = &adreno_dev->busy_data; Loading @@ -1440,12 +1440,12 @@ static int64_t a6xx_read_throttling_counters(struct adreno_device *adreno_dev) /* * The adjustment is the number of cycles lost to throttling, which * is calculated as a weighted average of the cycles throttled * at 10%, 50%, and 90%. The adjustment is negative because in A6XX, * at 15%, 50%, and 90%. The adjustment is negative because in A6XX, * the busy count includes the throttled cycles. Therefore, we want * to remove them to prevent appearing to be busier than * we actually are. */ adj = -((counts[0] * 1) + (counts[1] * 5) + (counts[2] * 9)) / 10; adj *= ((counts[0] * 15) + (counts[1] * 50) + (counts[2] * 90)) / 100; trace_kgsl_clock_throttling(0, counts[1], counts[2], counts[0], adj); Loading drivers/gpu/msm/kgsl_hfi.c +3 −8 Original line number Diff line number Diff line Loading @@ -16,6 +16,7 @@ #include "kgsl_gmu.h" #include "adreno.h" #include "kgsl_trace.h" #include "kgsl_pwrctrl.h" #define HFI_QUEUE_OFFSET(i) \ (ALIGN(sizeof(struct hfi_queue_table), SZ_16) + \ Loading Loading @@ -649,9 +650,6 @@ static int hfi_verify_fw_version(struct kgsl_device *device, return 0; } /* Levels greater than or equal to LM_DCVS_LEVEL are subject to throttling */ #define LM_DCVS_LEVEL 4 int hfi_start(struct kgsl_device *device, struct gmu_device *gmu, uint32_t boot_state) { Loading Loading @@ -714,11 +712,8 @@ int hfi_start(struct kgsl_device *device, return result; if (test_bit(ADRENO_LM_CTRL, &adreno_dev->pwrctrl_flag)) { /* We want all bits starting at LM_DCVS_LEVEL to be 1 */ int lm_data = -1 << (LM_DCVS_LEVEL - 1); result = hfi_send_feature_ctrl(gmu, HFI_FEATURE_LM, 1, lm_data); result = hfi_send_feature_ctrl(gmu, HFI_FEATURE_LM, 1, device->pwrctrl.throttle_mask); if (result) return result; } Loading drivers/gpu/msm/kgsl_pwrctrl.h +2 −0 Original line number Diff line number Diff line Loading @@ -137,6 +137,7 @@ struct kgsl_regulator { * @max_pwrlevel - maximum allowable powerlevel per the user * @min_pwrlevel - minimum allowable powerlevel per the user * @num_pwrlevels - number of available power levels * @throttle_mask - LM throttle mask * @interval_timeout - timeout in jiffies to be idle before a power event * @clock_times - Each GPU frequency's accumulated active time in us * @regulators - array of pointers to kgsl_regulator structs Loading Loading @@ -196,6 +197,7 @@ struct kgsl_pwrctrl { unsigned int max_pwrlevel; unsigned int min_pwrlevel; unsigned int num_pwrlevels; unsigned int throttle_mask; unsigned long interval_timeout; u64 clock_times[KGSL_MAX_PWRLEVELS]; struct kgsl_regulator regulators[KGSL_MAX_REGULATORS]; Loading Loading
Documentation/devicetree/bindings/gpu/adreno.txt +2 −0 Original line number Diff line number Diff line Loading @@ -85,6 +85,8 @@ DCVS Core info Optional Properties: - qcom,initial-powerlevel: This value indicates which qcom,gpu-pwrlevel should be used at start time and when coming back out of resume - qcom,throttle-pwrlevel: This value indicates which qcom,gpu-pwrlevel LM throttling may start to occur - qcom,bus-control: Boolean. Enables an independent bus vote from the gpu frequency - qcom,bus-width: Bus width in number of bytes. This enables dynamic AB bus voting based on bus width and actual bus transactions. Loading
drivers/gpu/msm/adreno.c +9 −0 Original line number Diff line number Diff line Loading @@ -1092,6 +1092,7 @@ static int adreno_of_get_power(struct adreno_device *adreno_dev, struct device_node *node = pdev->dev.of_node; struct resource *res; unsigned int timeout; unsigned int throt = 4; if (of_property_read_string(node, "label", &pdev->name)) { KGSL_CORE_ERR("Unable to read 'label'\n"); Loading Loading @@ -1120,6 +1121,14 @@ static int adreno_of_get_power(struct adreno_device *adreno_dev, if (adreno_of_get_pwrlevels(adreno_dev, node)) return -EINVAL; /* Get throttle power level */ of_property_read_u32(node, "qcom,throttle-pwrlevel", &throt); if (throt < device->pwrctrl.num_pwrlevels) device->pwrctrl.throttle_mask = GENMASK(device->pwrctrl.num_pwrlevels - 1, device->pwrctrl.num_pwrlevels - 1 - throt); /* Get context aware DCVS properties */ adreno_of_get_ca_aware_properties(adreno_dev, node); Loading
drivers/gpu/msm/adreno_a6xx.c +3 −3 Original line number Diff line number Diff line Loading @@ -1424,7 +1424,7 @@ static int a6xx_soft_reset(struct adreno_device *adreno_dev) static int64_t a6xx_read_throttling_counters(struct adreno_device *adreno_dev) { int i; int64_t adj = 0; int64_t adj = -1; uint32_t counts[ADRENO_GPMU_THROTTLE_COUNTERS]; struct adreno_busy_data *busy = &adreno_dev->busy_data; Loading @@ -1440,12 +1440,12 @@ static int64_t a6xx_read_throttling_counters(struct adreno_device *adreno_dev) /* * The adjustment is the number of cycles lost to throttling, which * is calculated as a weighted average of the cycles throttled * at 10%, 50%, and 90%. The adjustment is negative because in A6XX, * at 15%, 50%, and 90%. The adjustment is negative because in A6XX, * the busy count includes the throttled cycles. Therefore, we want * to remove them to prevent appearing to be busier than * we actually are. */ adj = -((counts[0] * 1) + (counts[1] * 5) + (counts[2] * 9)) / 10; adj *= ((counts[0] * 15) + (counts[1] * 50) + (counts[2] * 90)) / 100; trace_kgsl_clock_throttling(0, counts[1], counts[2], counts[0], adj); Loading
drivers/gpu/msm/kgsl_hfi.c +3 −8 Original line number Diff line number Diff line Loading @@ -16,6 +16,7 @@ #include "kgsl_gmu.h" #include "adreno.h" #include "kgsl_trace.h" #include "kgsl_pwrctrl.h" #define HFI_QUEUE_OFFSET(i) \ (ALIGN(sizeof(struct hfi_queue_table), SZ_16) + \ Loading Loading @@ -649,9 +650,6 @@ static int hfi_verify_fw_version(struct kgsl_device *device, return 0; } /* Levels greater than or equal to LM_DCVS_LEVEL are subject to throttling */ #define LM_DCVS_LEVEL 4 int hfi_start(struct kgsl_device *device, struct gmu_device *gmu, uint32_t boot_state) { Loading Loading @@ -714,11 +712,8 @@ int hfi_start(struct kgsl_device *device, return result; if (test_bit(ADRENO_LM_CTRL, &adreno_dev->pwrctrl_flag)) { /* We want all bits starting at LM_DCVS_LEVEL to be 1 */ int lm_data = -1 << (LM_DCVS_LEVEL - 1); result = hfi_send_feature_ctrl(gmu, HFI_FEATURE_LM, 1, lm_data); result = hfi_send_feature_ctrl(gmu, HFI_FEATURE_LM, 1, device->pwrctrl.throttle_mask); if (result) return result; } Loading
drivers/gpu/msm/kgsl_pwrctrl.h +2 −0 Original line number Diff line number Diff line Loading @@ -137,6 +137,7 @@ struct kgsl_regulator { * @max_pwrlevel - maximum allowable powerlevel per the user * @min_pwrlevel - minimum allowable powerlevel per the user * @num_pwrlevels - number of available power levels * @throttle_mask - LM throttle mask * @interval_timeout - timeout in jiffies to be idle before a power event * @clock_times - Each GPU frequency's accumulated active time in us * @regulators - array of pointers to kgsl_regulator structs Loading Loading @@ -196,6 +197,7 @@ struct kgsl_pwrctrl { unsigned int max_pwrlevel; unsigned int min_pwrlevel; unsigned int num_pwrlevels; unsigned int throttle_mask; unsigned long interval_timeout; u64 clock_times[KGSL_MAX_PWRLEVELS]; struct kgsl_regulator regulators[KGSL_MAX_REGULATORS]; Loading