Commit 95a428c1 authored by Christian Gmeiner's avatar Christian Gmeiner Committed by Lucas Stach

drm/etnaviv: make it possible to allocate multiple events

This makes it possible to allocate multiple events under the event
spinlock. This change is needed to support 'sync'-points.

Changes v2 -> v3:
- wait for the completion of all events
- use 10sec timeout regardless of the number of events
- removed validation if there are enough free events
- fixed return value evaluation of event_alloc(..) in etnaviv_gpu_submit(..)
Signed-off-by: default avatarChristian Gmeiner <christian.gmeiner@gmail.com>
Signed-off-by: default avatarLucas Stach <l.stach@pengutronix.de>
parent 355502e0
...@@ -1142,28 +1142,44 @@ int etnaviv_gpu_fence_sync_obj(struct etnaviv_gem_object *etnaviv_obj, ...@@ -1142,28 +1142,44 @@ int etnaviv_gpu_fence_sync_obj(struct etnaviv_gem_object *etnaviv_obj,
* event management: * event management:
*/ */
static unsigned int event_alloc(struct etnaviv_gpu *gpu) static int event_alloc(struct etnaviv_gpu *gpu, unsigned nr_events,
unsigned int *events)
{ {
unsigned long ret, flags; unsigned long flags, timeout = msecs_to_jiffies(10 * 10000);
unsigned int event; unsigned i, acquired = 0;
ret = wait_for_completion_timeout(&gpu->event_free, for (i = 0; i < nr_events; i++) {
msecs_to_jiffies(10 * 10000)); unsigned long ret;
if (!ret)
dev_err(gpu->dev, "wait_for_completion_timeout failed"); ret = wait_for_completion_timeout(&gpu->event_free, timeout);
if (!ret) {
dev_err(gpu->dev, "wait_for_completion_timeout failed");
goto out;
}
acquired++;
timeout = ret;
}
spin_lock_irqsave(&gpu->event_spinlock, flags); spin_lock_irqsave(&gpu->event_spinlock, flags);
/* find first free event */ for (i = 0; i < nr_events; i++) {
event = find_first_zero_bit(gpu->event_bitmap, ETNA_NR_EVENTS); int event = find_first_zero_bit(gpu->event_bitmap, ETNA_NR_EVENTS);
if (event < ETNA_NR_EVENTS)
events[i] = event;
set_bit(event, gpu->event_bitmap); set_bit(event, gpu->event_bitmap);
else }
event = ~0U;
spin_unlock_irqrestore(&gpu->event_spinlock, flags); spin_unlock_irqrestore(&gpu->event_spinlock, flags);
return event; return 0;
out:
for (i = 0; i < acquired; i++)
complete(&gpu->event_free);
return -EBUSY;
} }
static void event_free(struct etnaviv_gpu *gpu, unsigned int event) static void event_free(struct etnaviv_gpu *gpu, unsigned int event)
...@@ -1332,10 +1348,9 @@ int etnaviv_gpu_submit(struct etnaviv_gpu *gpu, ...@@ -1332,10 +1348,9 @@ int etnaviv_gpu_submit(struct etnaviv_gpu *gpu,
* *
*/ */
event = event_alloc(gpu); ret = event_alloc(gpu, 1, &event);
if (unlikely(event == ~0U)) { if (ret) {
DRM_ERROR("no free event\n"); DRM_ERROR("no free event\n");
ret = -EBUSY;
goto out_pm_put; goto out_pm_put;
} }
......
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