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: Lucas Stach <l.stach@pengutronix.de>
Reviewed-by: Christian Gmeiner <cgmeiner@igalia.com>
This commit is contained in:
Lucas Stach 2023-06-07 15:02:18 +02:00
parent 80f6b63e72
commit f098f9b804
3 changed files with 16 additions and 15 deletions

View File

@ -97,7 +97,6 @@ struct etnaviv_gem_submit {
struct list_head node; /* GPU active submit list */
struct etnaviv_cmdbuf cmdbuf;
struct pid *pid; /* submitting process */
bool runtime_resumed;
u32 exec_state;
u32 flags;
unsigned int nr_pmrs;

View File

@ -362,9 +362,6 @@ static void submit_cleanup(struct kref *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);

View File

@ -1147,7 +1147,8 @@ static int event_alloc(struct etnaviv_gpu *gpu, unsigned nr_events,
unsigned int *events)
{
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++) {
unsigned long ret;
@ -1156,6 +1157,7 @@ static int event_alloc(struct etnaviv_gpu *gpu, unsigned nr_events,
if (!ret) {
dev_err(gpu->dev, "wait_for_completion_timeout failed");
ret = -EBUSY;
goto out;
}
@ -1175,13 +1177,23 @@ static int event_alloc(struct etnaviv_gpu *gpu, unsigned nr_events,
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;
out_rpm:
for (i = 0; i < rpm_count; i++)
pm_runtime_put_autosuspend(gpu->dev);
out:
for (i = 0; i < acquired; i++)
complete(&gpu->event_free);
return -EBUSY;
return ret;
}
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);
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)
unsigned int i, nr_events = 1, event[3];
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
* - a sync point to re-configure gpu and process ETNA_PM_PROCESS_PRE