summaryrefslogtreecommitdiff
path: root/drivers/gpu/drm/msm/msm_gpu.c
diff options
context:
space:
mode:
authorRob Clark <robdclark@chromium.org>2021-07-26 17:46:50 +0300
committerRob Clark <robdclark@chromium.org>2021-07-28 03:54:36 +0300
commit9bc95570175a7fbca29d86d22c54bbf399f4ad5a (patch)
tree4bcffcdc786e9334c787be5b7abe8e81507328d6 /drivers/gpu/drm/msm/msm_gpu.c
parent552fce98b06f702b041432ad650db3e50c380ce3 (diff)
downloadlinux-9bc95570175a7fbca29d86d22c54bbf399f4ad5a.tar.xz
drm/msm: Devfreq tuning
This adds a few things to try and make frequency scaling better match the workload: 1) Longer polling interval to avoid whip-lashing between too-high and too-low frequencies in certain workloads, like mobile games which throttle themselves to 30fps. Previously our polling interval was short enough to let things ramp down to minimum freq in the "off" frame, but long enough to not react quickly enough when rendering started on the next frame, leading to uneven frame times. (Ie. rather than a consistent 33ms it would alternate between 16/33/48ms.) 2) Awareness of when the GPU is active vs idle. Since we know when the GPU is active vs idle, we can clamp the frequency down to the minimum while it is idle. (If it is idle for long enough, then the autosuspend delay will eventually kick in and power down the GPU.) Since devfreq has no knowledge of powered-but-idle, this takes a small bit of trickery to maintain a "fake" frequency while idle. This, combined with the longer polling period allows devfreq to arrive at a reasonable "active" frequency, while still clamping to minimum freq when idle to reduce power draw. 3) Boost. Because simple_ondemand needs to see a certain threshold of busyness to ramp up, we could end up needing multiple polling cycles before it reacts appropriately on interactive workloads (ex. scrolling a web page after reading for some time), on top of the already lengthened polling interval, when we see a idle to active transition after a period of idle time we boost the frequency that we return to. Signed-off-by: Rob Clark <robdclark@chromium.org> Link: https://lore.kernel.org/r/20210726144653.2180096-4-robdclark@gmail.com Signed-off-by: Rob Clark <robdclark@chromium.org>
Diffstat (limited to 'drivers/gpu/drm/msm/msm_gpu.c')
-rw-r--r--drivers/gpu/drm/msm/msm_gpu.c16
1 files changed, 16 insertions, 0 deletions
diff --git a/drivers/gpu/drm/msm/msm_gpu.c b/drivers/gpu/drm/msm/msm_gpu.c
index fedbd785e42f..c4ed8694f721 100644
--- a/drivers/gpu/drm/msm/msm_gpu.c
+++ b/drivers/gpu/drm/msm/msm_gpu.c
@@ -680,6 +680,14 @@ static void retire_submit(struct msm_gpu *gpu, struct msm_ringbuffer *ring,
list_del(&submit->node);
spin_unlock_irqrestore(&ring->submit_lock, flags);
+ /* Update devfreq on transition from active->idle: */
+ mutex_lock(&gpu->active_lock);
+ gpu->active_submits--;
+ WARN_ON(gpu->active_submits < 0);
+ if (!gpu->active_submits)
+ msm_devfreq_idle(gpu);
+ mutex_unlock(&gpu->active_lock);
+
msm_gem_submit_put(submit);
}
@@ -781,6 +789,13 @@ void msm_gpu_submit(struct msm_gpu *gpu, struct msm_gem_submit *submit)
list_add_tail(&submit->node, &ring->submits);
spin_unlock_irqrestore(&ring->submit_lock, flags);
+ /* Update devfreq on transition from idle->active: */
+ mutex_lock(&gpu->active_lock);
+ if (!gpu->active_submits)
+ msm_devfreq_active(gpu);
+ gpu->active_submits++;
+ mutex_unlock(&gpu->active_lock);
+
gpu->funcs->submit(gpu, submit);
priv->lastctx = submit->queue->ctx;
@@ -866,6 +881,7 @@ int msm_gpu_init(struct drm_device *drm, struct platform_device *pdev,
sched_set_fifo_low(gpu->worker->task);
INIT_LIST_HEAD(&gpu->active_list);
+ mutex_init(&gpu->active_lock);
kthread_init_work(&gpu->retire_work, retire_worker);
kthread_init_work(&gpu->recover_work, recover_worker);
kthread_init_work(&gpu->fault_work, fault_worker);