Loading drivers/gpu/msm/adreno.c +82 −7 Original line number Diff line number Diff line Loading @@ -57,6 +57,8 @@ MODULE_PARM_DESC(nopreempt, "Disable GPU preemption"); #define KGSL_LOG_LEVEL_DEFAULT 3 static void adreno_input_work(struct work_struct *work); static unsigned int counter_delta(struct adreno_device *adreno_dev, unsigned int reg, unsigned int *counter); static struct devfreq_msm_adreno_tz_data adreno_tz_data = { .bus = { Loading Loading @@ -1379,6 +1381,77 @@ static bool regulators_left_on(struct kgsl_device *device) return false; } static void _setup_throttling_counters(struct adreno_device *adreno_dev) { int i, ret; if (!adreno_is_a540(adreno_dev)) return; if (!ADRENO_FEATURE(adreno_dev, ADRENO_LM)) return; for (i = 0; i < ADRENO_GPMU_THROTTLE_COUNTERS; i++) { /* reset throttled cycles ivalue */ adreno_dev->busy_data.throttle_cycles[i] = 0; if (adreno_dev->gpmu_throttle_counters[i] != 0) continue; ret = adreno_perfcounter_get(adreno_dev, KGSL_PERFCOUNTER_GROUP_GPMU_PWR, ADRENO_GPMU_THROTTLE_COUNTERS_BASE_REG + i, &adreno_dev->gpmu_throttle_counters[i], NULL, PERFCOUNTER_FLAG_KERNEL); WARN_ONCE(ret, "Unable to get clock throttling counter %x\n", ADRENO_GPMU_THROTTLE_COUNTERS_BASE_REG + i); } } /* FW driven idle 10% throttle */ #define IDLE_10PCT 0 /* number of cycles when clock is throttled by 50% (CRC) */ #define CRC_50PCT 1 /* number of cycles when clock is throttled by more than 50% (CRC) */ #define CRC_MORE50PCT 2 /* number of cycles when clock is throttle by less than 50% (CRC) */ #define CRC_LESS50PCT 3 static uint64_t _read_throttling_counters(struct adreno_device *adreno_dev) { int i; uint32_t th[ADRENO_GPMU_THROTTLE_COUNTERS]; struct adreno_busy_data *busy = &adreno_dev->busy_data; if (!adreno_is_a540(adreno_dev)) return 0; if (!ADRENO_FEATURE(adreno_dev, ADRENO_LM)) return 0; for (i = 0; i < ADRENO_GPMU_THROTTLE_COUNTERS; i++) { if (!adreno_dev->gpmu_throttle_counters[i]) return 0; th[i] = counter_delta(adreno_dev, adreno_dev->gpmu_throttle_counters[i], &busy->throttle_cycles[i]); } return th[CRC_50PCT] + th[CRC_LESS50PCT] / 3 + (th[CRC_MORE50PCT] - th[IDLE_10PCT]) * 3; } static void _update_threshold_count(struct adreno_device *adreno_dev, uint64_t adj) { if (adreno_is_a530(adreno_dev)) kgsl_regread(&adreno_dev->dev, adreno_dev->lm_threshold_count, &adreno_dev->lm_threshold_cross); else if (adreno_is_a540(adreno_dev)) adreno_dev->lm_threshold_cross = adj; } /** * _adreno_start - Power up the GPU and prepare to accept commands * @adreno_dev: Pointer to an adreno_device structure Loading @@ -1390,7 +1463,7 @@ static int _adreno_start(struct adreno_device *adreno_dev) { struct kgsl_device *device = &adreno_dev->dev; struct adreno_gpudev *gpudev = ADRENO_GPU_DEVICE(adreno_dev); int status = -EINVAL; int status = -EINVAL, ret; unsigned int state = device->state; bool regulator_left_on; unsigned int pmqos_wakeup_vote = device->pwrctrl.pm_qos_wakeup_latency; Loading Loading @@ -1454,7 +1527,7 @@ static int _adreno_start(struct adreno_device *adreno_dev) gpudev->enable_64bit(adreno_dev); if (adreno_dev->perfctr_pwr_lo == 0) { int ret = adreno_perfcounter_get(adreno_dev, ret = adreno_perfcounter_get(adreno_dev, KGSL_PERFCOUNTER_GROUP_PWR, 1, &adreno_dev->perfctr_pwr_lo, NULL, PERFCOUNTER_FLAG_KERNEL); Loading @@ -1467,7 +1540,6 @@ static int _adreno_start(struct adreno_device *adreno_dev) } if (device->pwrctrl.bus_control) { int ret; /* VBIF waiting for RAM */ if (adreno_dev->starved_ram_lo == 0) { Loading Loading @@ -1504,9 +1576,8 @@ static int _adreno_start(struct adreno_device *adreno_dev) adreno_dev->busy_data.vbif_ram_cycles = 0; adreno_dev->busy_data.vbif_starved_ram = 0; if (ADRENO_FEATURE(adreno_dev, ADRENO_LM) if (adreno_is_a530(adreno_dev) && ADRENO_FEATURE(adreno_dev, ADRENO_LM) && adreno_dev->lm_threshold_count == 0) { int ret; ret = adreno_perfcounter_get(adreno_dev, KGSL_PERFCOUNTER_GROUP_GPMU_PWR, 27, Loading @@ -1517,6 +1588,8 @@ static int _adreno_start(struct adreno_device *adreno_dev) adreno_dev->lm_threshold_count = 0; } _setup_throttling_counters(adreno_dev); /* Restore performance counter registers with saved values */ adreno_perfcounter_restore(adreno_dev); Loading Loading @@ -2602,6 +2675,7 @@ static void adreno_power_stats(struct kgsl_device *device, struct adreno_device *adreno_dev = ADRENO_DEVICE(device); struct kgsl_pwrctrl *pwr = &device->pwrctrl; struct adreno_busy_data *busy = &adreno_dev->busy_data; uint64_t adj; memset(stats, 0, sizeof(*stats)); Loading @@ -2612,6 +2686,8 @@ static void adreno_power_stats(struct kgsl_device *device, gpu_busy = counter_delta(adreno_dev, adreno_dev->perfctr_pwr_lo, &busy->gpu_busy); adj = _read_throttling_counters(adreno_dev); gpu_busy += adj; stats->busy_time = adreno_ticks_to_us(gpu_busy, kgsl_pwrctrl_active_freq(pwr)); } Loading @@ -2633,8 +2709,7 @@ static void adreno_power_stats(struct kgsl_device *device, stats->ram_wait = starved_ram; } if (adreno_dev->lm_threshold_count) kgsl_regread(&adreno_dev->dev, adreno_dev->lm_threshold_count, &adreno_dev->lm_threshold_cross); _update_threshold_count(adreno_dev, adj); } static unsigned int adreno_gpuid(struct kgsl_device *device, Loading drivers/gpu/msm/adreno.h +8 −0 Original line number Diff line number Diff line Loading @@ -186,12 +186,18 @@ enum adreno_gpurev { #define ADRENO_PPD_CTRL 1 #define ADRENO_LM_CTRL 2 /* number of throttle counters for DCVS adjustment */ #define ADRENO_GPMU_THROTTLE_COUNTERS 4 /* base for throttle counters */ #define ADRENO_GPMU_THROTTLE_COUNTERS_BASE_REG 43 struct adreno_gpudev; struct adreno_busy_data { unsigned int gpu_busy; unsigned int vbif_ram_cycles; unsigned int vbif_starved_ram; unsigned int throttle_cycles[ADRENO_GPMU_THROTTLE_COUNTERS]; }; /** Loading Loading @@ -310,6 +316,7 @@ struct adreno_gpu_core { * @lm_threshold_cross: number of current peaks exceeding threshold * @speed_bin: Indicate which power level set to use * @csdev: Pointer to a coresight device (if applicable) * @gpmu_throttle_counters - counteers for number of throttled clocks */ struct adreno_device { struct kgsl_device dev; /* Must be first field in this struct */ Loading Loading @@ -369,6 +376,7 @@ struct adreno_device { unsigned int quirks; struct coresight_device *csdev; uint32_t gpmu_throttle_counters[ADRENO_GPMU_THROTTLE_COUNTERS]; }; /** Loading drivers/gpu/msm/adreno_perfcounter.c +8 −1 Original line number Diff line number Diff line Loading @@ -671,8 +671,15 @@ static void _power_counter_enable_gpmu(struct adreno_device *adreno_dev, struct kgsl_device *device = &adreno_dev->dev; struct adreno_perfcount_register *reg; if (adreno_is_a530(adreno_dev)) { if (countable > 43) return; } else if (adreno_is_a540(adreno_dev)) { if (countable > 47) return; } else /* return on platforms that have no GPMU */ return; reg = &counters->groups[group].regs[counter]; Loading Loading
drivers/gpu/msm/adreno.c +82 −7 Original line number Diff line number Diff line Loading @@ -57,6 +57,8 @@ MODULE_PARM_DESC(nopreempt, "Disable GPU preemption"); #define KGSL_LOG_LEVEL_DEFAULT 3 static void adreno_input_work(struct work_struct *work); static unsigned int counter_delta(struct adreno_device *adreno_dev, unsigned int reg, unsigned int *counter); static struct devfreq_msm_adreno_tz_data adreno_tz_data = { .bus = { Loading Loading @@ -1379,6 +1381,77 @@ static bool regulators_left_on(struct kgsl_device *device) return false; } static void _setup_throttling_counters(struct adreno_device *adreno_dev) { int i, ret; if (!adreno_is_a540(adreno_dev)) return; if (!ADRENO_FEATURE(adreno_dev, ADRENO_LM)) return; for (i = 0; i < ADRENO_GPMU_THROTTLE_COUNTERS; i++) { /* reset throttled cycles ivalue */ adreno_dev->busy_data.throttle_cycles[i] = 0; if (adreno_dev->gpmu_throttle_counters[i] != 0) continue; ret = adreno_perfcounter_get(adreno_dev, KGSL_PERFCOUNTER_GROUP_GPMU_PWR, ADRENO_GPMU_THROTTLE_COUNTERS_BASE_REG + i, &adreno_dev->gpmu_throttle_counters[i], NULL, PERFCOUNTER_FLAG_KERNEL); WARN_ONCE(ret, "Unable to get clock throttling counter %x\n", ADRENO_GPMU_THROTTLE_COUNTERS_BASE_REG + i); } } /* FW driven idle 10% throttle */ #define IDLE_10PCT 0 /* number of cycles when clock is throttled by 50% (CRC) */ #define CRC_50PCT 1 /* number of cycles when clock is throttled by more than 50% (CRC) */ #define CRC_MORE50PCT 2 /* number of cycles when clock is throttle by less than 50% (CRC) */ #define CRC_LESS50PCT 3 static uint64_t _read_throttling_counters(struct adreno_device *adreno_dev) { int i; uint32_t th[ADRENO_GPMU_THROTTLE_COUNTERS]; struct adreno_busy_data *busy = &adreno_dev->busy_data; if (!adreno_is_a540(adreno_dev)) return 0; if (!ADRENO_FEATURE(adreno_dev, ADRENO_LM)) return 0; for (i = 0; i < ADRENO_GPMU_THROTTLE_COUNTERS; i++) { if (!adreno_dev->gpmu_throttle_counters[i]) return 0; th[i] = counter_delta(adreno_dev, adreno_dev->gpmu_throttle_counters[i], &busy->throttle_cycles[i]); } return th[CRC_50PCT] + th[CRC_LESS50PCT] / 3 + (th[CRC_MORE50PCT] - th[IDLE_10PCT]) * 3; } static void _update_threshold_count(struct adreno_device *adreno_dev, uint64_t adj) { if (adreno_is_a530(adreno_dev)) kgsl_regread(&adreno_dev->dev, adreno_dev->lm_threshold_count, &adreno_dev->lm_threshold_cross); else if (adreno_is_a540(adreno_dev)) adreno_dev->lm_threshold_cross = adj; } /** * _adreno_start - Power up the GPU and prepare to accept commands * @adreno_dev: Pointer to an adreno_device structure Loading @@ -1390,7 +1463,7 @@ static int _adreno_start(struct adreno_device *adreno_dev) { struct kgsl_device *device = &adreno_dev->dev; struct adreno_gpudev *gpudev = ADRENO_GPU_DEVICE(adreno_dev); int status = -EINVAL; int status = -EINVAL, ret; unsigned int state = device->state; bool regulator_left_on; unsigned int pmqos_wakeup_vote = device->pwrctrl.pm_qos_wakeup_latency; Loading Loading @@ -1454,7 +1527,7 @@ static int _adreno_start(struct adreno_device *adreno_dev) gpudev->enable_64bit(adreno_dev); if (adreno_dev->perfctr_pwr_lo == 0) { int ret = adreno_perfcounter_get(adreno_dev, ret = adreno_perfcounter_get(adreno_dev, KGSL_PERFCOUNTER_GROUP_PWR, 1, &adreno_dev->perfctr_pwr_lo, NULL, PERFCOUNTER_FLAG_KERNEL); Loading @@ -1467,7 +1540,6 @@ static int _adreno_start(struct adreno_device *adreno_dev) } if (device->pwrctrl.bus_control) { int ret; /* VBIF waiting for RAM */ if (adreno_dev->starved_ram_lo == 0) { Loading Loading @@ -1504,9 +1576,8 @@ static int _adreno_start(struct adreno_device *adreno_dev) adreno_dev->busy_data.vbif_ram_cycles = 0; adreno_dev->busy_data.vbif_starved_ram = 0; if (ADRENO_FEATURE(adreno_dev, ADRENO_LM) if (adreno_is_a530(adreno_dev) && ADRENO_FEATURE(adreno_dev, ADRENO_LM) && adreno_dev->lm_threshold_count == 0) { int ret; ret = adreno_perfcounter_get(adreno_dev, KGSL_PERFCOUNTER_GROUP_GPMU_PWR, 27, Loading @@ -1517,6 +1588,8 @@ static int _adreno_start(struct adreno_device *adreno_dev) adreno_dev->lm_threshold_count = 0; } _setup_throttling_counters(adreno_dev); /* Restore performance counter registers with saved values */ adreno_perfcounter_restore(adreno_dev); Loading Loading @@ -2602,6 +2675,7 @@ static void adreno_power_stats(struct kgsl_device *device, struct adreno_device *adreno_dev = ADRENO_DEVICE(device); struct kgsl_pwrctrl *pwr = &device->pwrctrl; struct adreno_busy_data *busy = &adreno_dev->busy_data; uint64_t adj; memset(stats, 0, sizeof(*stats)); Loading @@ -2612,6 +2686,8 @@ static void adreno_power_stats(struct kgsl_device *device, gpu_busy = counter_delta(adreno_dev, adreno_dev->perfctr_pwr_lo, &busy->gpu_busy); adj = _read_throttling_counters(adreno_dev); gpu_busy += adj; stats->busy_time = adreno_ticks_to_us(gpu_busy, kgsl_pwrctrl_active_freq(pwr)); } Loading @@ -2633,8 +2709,7 @@ static void adreno_power_stats(struct kgsl_device *device, stats->ram_wait = starved_ram; } if (adreno_dev->lm_threshold_count) kgsl_regread(&adreno_dev->dev, adreno_dev->lm_threshold_count, &adreno_dev->lm_threshold_cross); _update_threshold_count(adreno_dev, adj); } static unsigned int adreno_gpuid(struct kgsl_device *device, Loading
drivers/gpu/msm/adreno.h +8 −0 Original line number Diff line number Diff line Loading @@ -186,12 +186,18 @@ enum adreno_gpurev { #define ADRENO_PPD_CTRL 1 #define ADRENO_LM_CTRL 2 /* number of throttle counters for DCVS adjustment */ #define ADRENO_GPMU_THROTTLE_COUNTERS 4 /* base for throttle counters */ #define ADRENO_GPMU_THROTTLE_COUNTERS_BASE_REG 43 struct adreno_gpudev; struct adreno_busy_data { unsigned int gpu_busy; unsigned int vbif_ram_cycles; unsigned int vbif_starved_ram; unsigned int throttle_cycles[ADRENO_GPMU_THROTTLE_COUNTERS]; }; /** Loading Loading @@ -310,6 +316,7 @@ struct adreno_gpu_core { * @lm_threshold_cross: number of current peaks exceeding threshold * @speed_bin: Indicate which power level set to use * @csdev: Pointer to a coresight device (if applicable) * @gpmu_throttle_counters - counteers for number of throttled clocks */ struct adreno_device { struct kgsl_device dev; /* Must be first field in this struct */ Loading Loading @@ -369,6 +376,7 @@ struct adreno_device { unsigned int quirks; struct coresight_device *csdev; uint32_t gpmu_throttle_counters[ADRENO_GPMU_THROTTLE_COUNTERS]; }; /** Loading
drivers/gpu/msm/adreno_perfcounter.c +8 −1 Original line number Diff line number Diff line Loading @@ -671,8 +671,15 @@ static void _power_counter_enable_gpmu(struct adreno_device *adreno_dev, struct kgsl_device *device = &adreno_dev->dev; struct adreno_perfcount_register *reg; if (adreno_is_a530(adreno_dev)) { if (countable > 43) return; } else if (adreno_is_a540(adreno_dev)) { if (countable > 47) return; } else /* return on platforms that have no GPMU */ return; reg = &counters->groups[group].regs[counter]; Loading