From b35803e7901f2afafa81ff5dde396856ea5c7426 Mon Sep 17 00:00:00 2001 From: George Shen Date: Tue, 3 May 2016 18:23:22 -0700 Subject: [PATCH] msm: kgsl: track GPU active time per frequency Tracks GPU active time per frequency for GPU workload profiling. The data will be output in /sys/class/kgsl/kgsl-3d0/gpu_clock_stats with one u64 value in microseconds per clock level. For example: cat /sys/class/kgsl/kgsl-3d0/gpu_clock_stats 39392 29292 929292 929292 4040404 CRs-Fixed: 1011462 Change-Id: I5f2caa8b38d99ffd23f03c1dfed1efda273fc2fb Signed-off-by: George Shen --- drivers/gpu/msm/adreno.c | 2 ++ drivers/gpu/msm/kgsl_pwrctrl.c | 31 +++++++++++++++++++++++++++++++ drivers/gpu/msm/kgsl_pwrctrl.h | 2 ++ drivers/gpu/msm/kgsl_pwrscale.c | 3 +++ 4 files changed, 38 insertions(+) diff --git a/drivers/gpu/msm/adreno.c b/drivers/gpu/msm/adreno.c index a802671acba0..fad5356e2c9e 100644 --- a/drivers/gpu/msm/adreno.c +++ b/drivers/gpu/msm/adreno.c @@ -1595,6 +1595,8 @@ static int adreno_stop(struct kgsl_device *device) adreno_ringbuffer_stop(adreno_dev); + kgsl_pwrscale_update_stats(device); + adreno_irqctrl(adreno_dev, 0); adreno_ocmem_free(adreno_dev); diff --git a/drivers/gpu/msm/kgsl_pwrctrl.c b/drivers/gpu/msm/kgsl_pwrctrl.c index 2b9eef8b6351..11b323e9d40c 100644 --- a/drivers/gpu/msm/kgsl_pwrctrl.c +++ b/drivers/gpu/msm/kgsl_pwrctrl.c @@ -363,6 +363,8 @@ void kgsl_pwrctrl_pwrlevel_change(struct kgsl_device *device, if (new_level == old_level) return; + kgsl_pwrscale_update_stats(device); + /* * Set the active and previous powerlevel first in case the clocks are * off - if we don't do this then the pwrlevel change won't take effect @@ -934,6 +936,31 @@ static ssize_t kgsl_pwrctrl_gpu_available_frequencies_show( return num_chars; } +static ssize_t kgsl_pwrctrl_gpu_clock_stats_show( + struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct kgsl_device *device = kgsl_device_from_dev(dev); + struct kgsl_pwrctrl *pwr; + int index, num_chars = 0; + + if (device == NULL) + return 0; + pwr = &device->pwrctrl; + mutex_lock(&device->mutex); + kgsl_pwrscale_update_stats(device); + mutex_unlock(&device->mutex); + for (index = 0; index < pwr->num_pwrlevels - 1; index++) + num_chars += snprintf(buf + num_chars, PAGE_SIZE - num_chars, + "%llu ", pwr->clock_times[index]); + + if (num_chars < PAGE_SIZE) + buf[num_chars++] = '\n'; + + return num_chars; +} + static ssize_t kgsl_pwrctrl_reset_count_show(struct device *dev, struct device_attribute *attr, char *buf) @@ -1201,6 +1228,9 @@ static DEVICE_ATTR(gpubusy, 0444, kgsl_pwrctrl_gpubusy_show, static DEVICE_ATTR(gpu_available_frequencies, 0444, kgsl_pwrctrl_gpu_available_frequencies_show, NULL); +static DEVICE_ATTR(gpu_clock_stats, 0444, + kgsl_pwrctrl_gpu_clock_stats_show, + NULL); static DEVICE_ATTR(max_pwrlevel, 0644, kgsl_pwrctrl_max_pwrlevel_show, kgsl_pwrctrl_max_pwrlevel_store); @@ -1249,6 +1279,7 @@ static const struct device_attribute *pwrctrl_attr_list[] = { &dev_attr_deep_nap_timer, &dev_attr_gpubusy, &dev_attr_gpu_available_frequencies, + &dev_attr_gpu_clock_stats, &dev_attr_max_pwrlevel, &dev_attr_min_pwrlevel, &dev_attr_thermal_pwrlevel, diff --git a/drivers/gpu/msm/kgsl_pwrctrl.h b/drivers/gpu/msm/kgsl_pwrctrl.h index 0029c389484f..8fd06531aa81 100644 --- a/drivers/gpu/msm/kgsl_pwrctrl.h +++ b/drivers/gpu/msm/kgsl_pwrctrl.h @@ -122,6 +122,7 @@ struct kgsl_regulator { * @min_pwrlevel - minimum allowable powerlevel per the user * @num_pwrlevels - number of available power levels * @interval_timeout - timeout in jiffies to be idle before a power event + * @clock_times - Each GPU frequency's accumulated active time in us * @strtstp_sleepwake - true if the device supports low latency GPU start/stop * @regulators - array of pointers to kgsl_regulator structs * @pcl - bus scale identifier @@ -178,6 +179,7 @@ struct kgsl_pwrctrl { unsigned int min_pwrlevel; unsigned int num_pwrlevels; unsigned long interval_timeout; + u64 clock_times[KGSL_MAX_PWRLEVELS]; bool strtstp_sleepwake; struct kgsl_regulator regulators[KGSL_MAX_REGULATORS]; uint32_t pcl; diff --git a/drivers/gpu/msm/kgsl_pwrscale.c b/drivers/gpu/msm/kgsl_pwrscale.c index 4f6677d9a1de..d90aec42f30a 100644 --- a/drivers/gpu/msm/kgsl_pwrscale.c +++ b/drivers/gpu/msm/kgsl_pwrscale.c @@ -127,6 +127,7 @@ EXPORT_SYMBOL(kgsl_pwrscale_busy); */ void kgsl_pwrscale_update_stats(struct kgsl_device *device) { + struct kgsl_pwrctrl *pwrctrl = &device->pwrctrl; struct kgsl_pwrscale *psc = &device->pwrscale; BUG_ON(!mutex_is_locked(&device->mutex)); @@ -150,6 +151,8 @@ void kgsl_pwrscale_update_stats(struct kgsl_device *device) device->pwrscale.accum_stats.busy_time += stats.busy_time; device->pwrscale.accum_stats.ram_time += stats.ram_time; device->pwrscale.accum_stats.ram_wait += stats.ram_wait; + pwrctrl->clock_times[pwrctrl->active_pwrlevel] += + stats.busy_time; } } EXPORT_SYMBOL(kgsl_pwrscale_update_stats); -- 2.11.0