Blob Blame History Raw
From: Lucas Stach <l.stach@pengutronix.de>
Date: Fri, 24 Nov 2017 17:56:29 +0100
Subject: drm/etnaviv: couple runtime PM management to submit object lifetime
Git-commit: 8bda1516fb4acf4bd6eaeb746258a9f536aeeb5d
Patch-mainline: v4.16-rc1
References: FATE#326289 FATE#326079 FATE#326049 FATE#322398 FATE#326166

As long as there is an active submit, we want the GPU to stay awake. This
is slightly complicated by the fact that we really want to wake the GPU
at the last possible moment to achieve maximum power savings.

Signed-off-by: Lucas Stach <l.stach@pengutronix.de>
Acked-by: Petr Tesarik <ptesarik@suse.com>
---
 drivers/gpu/drm/etnaviv/etnaviv_gem.h        |    1 
 drivers/gpu/drm/etnaviv/etnaviv_gem_submit.c |    3 ++
 drivers/gpu/drm/etnaviv/etnaviv_gpu.c        |   30 ++-------------------------
 3 files changed, 7 insertions(+), 27 deletions(-)

--- a/drivers/gpu/drm/etnaviv/etnaviv_gem.h
+++ b/drivers/gpu/drm/etnaviv/etnaviv_gem.h
@@ -106,6 +106,7 @@ struct etnaviv_gem_submit {
 	struct dma_fence *out_fence, *in_fence;
 	struct list_head node; /* GPU active submit list */
 	struct etnaviv_cmdbuf cmdbuf;
+	bool runtime_resumed;
 	u32 exec_state;
 	u32 flags;
 	unsigned int nr_pmrs;
--- a/drivers/gpu/drm/etnaviv/etnaviv_gem_submit.c
+++ b/drivers/gpu/drm/etnaviv/etnaviv_gem_submit.c
@@ -355,6 +355,9 @@ static void submit_cleanup(struct kref *
 			container_of(kref, struct etnaviv_gem_submit, refcount);
 	unsigned i;
 
+	if (submit->runtime_resumed)
+		pm_runtime_put_autosuspend(submit->gpu->dev);
+
 	if (submit->cmdbuf.suballoc)
 		etnaviv_cmdbuf_free(&submit->cmdbuf);
 
--- a/drivers/gpu/drm/etnaviv/etnaviv_gpu.c
+++ b/drivers/gpu/drm/etnaviv/etnaviv_gpu.c
@@ -1210,14 +1210,6 @@ static void retire_worker(struct work_st
 		list_del(&submit->node);
 
 		etnaviv_submit_put(submit);
-		/*
-		 * We need to balance the runtime PM count caused by
-		 * each submission.  Upon submission, we increment
-		 * the runtime PM counter, and allocate one event.
-		 * So here, we put the runtime PM count for each
-		 * completed event.
-		 */
-		pm_runtime_put_autosuspend(gpu->dev);
 	}
 
 	gpu->retired_fence = fence;
@@ -1289,17 +1281,6 @@ int etnaviv_gpu_wait_obj_inactive(struct
 		return -ETIMEDOUT;
 }
 
-int etnaviv_gpu_pm_get_sync(struct etnaviv_gpu *gpu)
-{
-	return pm_runtime_get_sync(gpu->dev);
-}
-
-void etnaviv_gpu_pm_put(struct etnaviv_gpu *gpu)
-{
-	pm_runtime_mark_last_busy(gpu->dev);
-	pm_runtime_put_autosuspend(gpu->dev);
-}
-
 static void sync_point_perfmon_sample(struct etnaviv_gpu *gpu,
 	struct etnaviv_event *event, unsigned int flags)
 {
@@ -1366,9 +1347,10 @@ int etnaviv_gpu_submit(struct etnaviv_gp
 	unsigned int i, nr_events = 1, event[3];
 	int ret;
 
-	ret = etnaviv_gpu_pm_get_sync(gpu);
+	ret = pm_runtime_get_sync(gpu->dev);
 	if (ret < 0)
 		return ret;
+	submit->runtime_resumed = true;
 
 	/*
 	 * if there are performance monitor requests we need to have
@@ -1383,7 +1365,7 @@ int etnaviv_gpu_submit(struct etnaviv_gp
 	ret = event_alloc(gpu, nr_events, event);
 	if (ret) {
 		DRM_ERROR("no free events\n");
-		goto out_pm_put;
+		return ret;
 	}
 
 	mutex_lock(&gpu->lock);
@@ -1420,18 +1402,12 @@ int etnaviv_gpu_submit(struct etnaviv_gp
 
 	list_add_tail(&submit->node, &gpu->active_submit_list);
 
-	/* We're committed to adding this command buffer, hold a PM reference */
-	pm_runtime_get_noresume(gpu->dev);
-
 	hangcheck_timer_reset(gpu);
 	ret = 0;
 
 out_unlock:
 	mutex_unlock(&gpu->lock);
 
-out_pm_put:
-	etnaviv_gpu_pm_put(gpu);
-
 	return ret;
 }