Commit f098f9b8 authored by Lucas Stach's avatar Lucas Stach

drm/etnaviv: move runtime PM handling to events

Conceptually events are the right abstraction to handle the GPU
runtime PM state: as long as any event is pending the GPU can not
be idle. Events are also properly freed and reallocated when the
GPU has been reset after a hang.
Signed-off-by: default avatarLucas Stach <l.stach@pengutronix.de>
Reviewed-by: default avatarChristian Gmeiner <cgmeiner@igalia.com>
parent 80f6b63e
...@@ -97,7 +97,6 @@ struct etnaviv_gem_submit { ...@@ -97,7 +97,6 @@ struct etnaviv_gem_submit {
struct list_head node; /* GPU active submit list */ struct list_head node; /* GPU active submit list */
struct etnaviv_cmdbuf cmdbuf; struct etnaviv_cmdbuf cmdbuf;
struct pid *pid; /* submitting process */ struct pid *pid; /* submitting process */
bool runtime_resumed;
u32 exec_state; u32 exec_state;
u32 flags; u32 flags;
unsigned int nr_pmrs; unsigned int nr_pmrs;
......
...@@ -362,9 +362,6 @@ static void submit_cleanup(struct kref *kref) ...@@ -362,9 +362,6 @@ static void submit_cleanup(struct kref *kref)
container_of(kref, struct etnaviv_gem_submit, refcount); container_of(kref, struct etnaviv_gem_submit, refcount);
unsigned i; unsigned i;
if (submit->runtime_resumed)
pm_runtime_put_autosuspend(submit->gpu->dev);
if (submit->cmdbuf.suballoc) if (submit->cmdbuf.suballoc)
etnaviv_cmdbuf_free(&submit->cmdbuf); etnaviv_cmdbuf_free(&submit->cmdbuf);
......
...@@ -1147,7 +1147,8 @@ static int event_alloc(struct etnaviv_gpu *gpu, unsigned nr_events, ...@@ -1147,7 +1147,8 @@ static int event_alloc(struct etnaviv_gpu *gpu, unsigned nr_events,
unsigned int *events) unsigned int *events)
{ {
unsigned long timeout = msecs_to_jiffies(10 * 10000); unsigned long timeout = msecs_to_jiffies(10 * 10000);
unsigned i, acquired = 0; unsigned i, acquired = 0, rpm_count = 0;
int ret;
for (i = 0; i < nr_events; i++) { for (i = 0; i < nr_events; i++) {
unsigned long ret; unsigned long ret;
...@@ -1156,6 +1157,7 @@ static int event_alloc(struct etnaviv_gpu *gpu, unsigned nr_events, ...@@ -1156,6 +1157,7 @@ static int event_alloc(struct etnaviv_gpu *gpu, unsigned nr_events,
if (!ret) { if (!ret) {
dev_err(gpu->dev, "wait_for_completion_timeout failed"); dev_err(gpu->dev, "wait_for_completion_timeout failed");
ret = -EBUSY;
goto out; goto out;
} }
...@@ -1175,13 +1177,23 @@ static int event_alloc(struct etnaviv_gpu *gpu, unsigned nr_events, ...@@ -1175,13 +1177,23 @@ static int event_alloc(struct etnaviv_gpu *gpu, unsigned nr_events,
spin_unlock(&gpu->event_spinlock); spin_unlock(&gpu->event_spinlock);
for (i = 0; i < nr_events; i++) {
ret = pm_runtime_resume_and_get(gpu->dev);
if (ret)
goto out_rpm;
rpm_count++;
}
return 0; return 0;
out_rpm:
for (i = 0; i < rpm_count; i++)
pm_runtime_put_autosuspend(gpu->dev);
out: out:
for (i = 0; i < acquired; i++) for (i = 0; i < acquired; i++)
complete(&gpu->event_free); complete(&gpu->event_free);
return -EBUSY; return ret;
} }
static void event_free(struct etnaviv_gpu *gpu, unsigned int event) static void event_free(struct etnaviv_gpu *gpu, unsigned int event)
...@@ -1193,6 +1205,8 @@ static void event_free(struct etnaviv_gpu *gpu, unsigned int event) ...@@ -1193,6 +1205,8 @@ static void event_free(struct etnaviv_gpu *gpu, unsigned int event)
clear_bit(event, gpu->event_bitmap); clear_bit(event, gpu->event_bitmap);
complete(&gpu->event_free); complete(&gpu->event_free);
} }
pm_runtime_put_autosuspend(gpu->dev);
} }
/* /*
...@@ -1335,15 +1349,6 @@ struct dma_fence *etnaviv_gpu_submit(struct etnaviv_gem_submit *submit) ...@@ -1335,15 +1349,6 @@ struct dma_fence *etnaviv_gpu_submit(struct etnaviv_gem_submit *submit)
unsigned int i, nr_events = 1, event[3]; unsigned int i, nr_events = 1, event[3];
int ret; int ret;
if (!submit->runtime_resumed) {
ret = pm_runtime_get_sync(gpu->dev);
if (ret < 0) {
pm_runtime_put_noidle(gpu->dev);
return NULL;
}
submit->runtime_resumed = true;
}
/* /*
* if there are performance monitor requests we need to have * if there are performance monitor requests we need to have
* - a sync point to re-configure gpu and process ETNA_PM_PROCESS_PRE * - a sync point to re-configure gpu and process ETNA_PM_PROCESS_PRE
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment