提交 355502e0 编写于 作者: C Christian Gmeiner 提交者: Lucas Stach

drm/etnaviv: use bitmap to keep track of events

This is prep work to be able to allocate multiple events in one go.
Signed-off-by: NChristian Gmeiner <christian.gmeiner@gmail.com>
Signed-off-by: NLucas Stach <l.stach@pengutronix.de>
上级 6eb3ecc3
...@@ -744,10 +744,9 @@ int etnaviv_gpu_init(struct etnaviv_gpu *gpu) ...@@ -744,10 +744,9 @@ int etnaviv_gpu_init(struct etnaviv_gpu *gpu)
/* Setup event management */ /* Setup event management */
spin_lock_init(&gpu->event_spinlock); spin_lock_init(&gpu->event_spinlock);
init_completion(&gpu->event_free); init_completion(&gpu->event_free);
for (i = 0; i < ARRAY_SIZE(gpu->event); i++) { bitmap_zero(gpu->event_bitmap, ETNA_NR_EVENTS);
gpu->event[i].used = false; for (i = 0; i < ARRAY_SIZE(gpu->event); i++)
complete(&gpu->event_free); complete(&gpu->event_free);
}
/* Now program the hardware */ /* Now program the hardware */
mutex_lock(&gpu->lock); mutex_lock(&gpu->lock);
...@@ -931,7 +930,7 @@ static void recover_worker(struct work_struct *work) ...@@ -931,7 +930,7 @@ static void recover_worker(struct work_struct *work)
struct etnaviv_gpu *gpu = container_of(work, struct etnaviv_gpu, struct etnaviv_gpu *gpu = container_of(work, struct etnaviv_gpu,
recover_work); recover_work);
unsigned long flags; unsigned long flags;
unsigned int i; unsigned int i = 0;
dev_err(gpu->dev, "hangcheck recover!\n"); dev_err(gpu->dev, "hangcheck recover!\n");
...@@ -950,14 +949,12 @@ static void recover_worker(struct work_struct *work) ...@@ -950,14 +949,12 @@ static void recover_worker(struct work_struct *work)
/* complete all events, the GPU won't do it after the reset */ /* complete all events, the GPU won't do it after the reset */
spin_lock_irqsave(&gpu->event_spinlock, flags); spin_lock_irqsave(&gpu->event_spinlock, flags);
for (i = 0; i < ARRAY_SIZE(gpu->event); i++) { for_each_set_bit_from(i, gpu->event_bitmap, ETNA_NR_EVENTS) {
if (!gpu->event[i].used)
continue;
dma_fence_signal(gpu->event[i].fence); dma_fence_signal(gpu->event[i].fence);
gpu->event[i].fence = NULL; gpu->event[i].fence = NULL;
gpu->event[i].used = false;
complete(&gpu->event_free); complete(&gpu->event_free);
} }
bitmap_zero(gpu->event_bitmap, ETNA_NR_EVENTS);
spin_unlock_irqrestore(&gpu->event_spinlock, flags); spin_unlock_irqrestore(&gpu->event_spinlock, flags);
gpu->completed_fence = gpu->active_fence; gpu->completed_fence = gpu->active_fence;
...@@ -1148,7 +1145,7 @@ int etnaviv_gpu_fence_sync_obj(struct etnaviv_gem_object *etnaviv_obj, ...@@ -1148,7 +1145,7 @@ int etnaviv_gpu_fence_sync_obj(struct etnaviv_gem_object *etnaviv_obj,
static unsigned int event_alloc(struct etnaviv_gpu *gpu) static unsigned int event_alloc(struct etnaviv_gpu *gpu)
{ {
unsigned long ret, flags; unsigned long ret, flags;
unsigned int i, event = ~0U; unsigned int event;
ret = wait_for_completion_timeout(&gpu->event_free, ret = wait_for_completion_timeout(&gpu->event_free,
msecs_to_jiffies(10 * 10000)); msecs_to_jiffies(10 * 10000));
...@@ -1158,13 +1155,11 @@ static unsigned int event_alloc(struct etnaviv_gpu *gpu) ...@@ -1158,13 +1155,11 @@ static unsigned int event_alloc(struct etnaviv_gpu *gpu)
spin_lock_irqsave(&gpu->event_spinlock, flags); spin_lock_irqsave(&gpu->event_spinlock, flags);
/* find first free event */ /* find first free event */
for (i = 0; i < ARRAY_SIZE(gpu->event); i++) { event = find_first_zero_bit(gpu->event_bitmap, ETNA_NR_EVENTS);
if (gpu->event[i].used == false) { if (event < ETNA_NR_EVENTS)
gpu->event[i].used = true; set_bit(event, gpu->event_bitmap);
event = i; else
break; event = ~0U;
}
}
spin_unlock_irqrestore(&gpu->event_spinlock, flags); spin_unlock_irqrestore(&gpu->event_spinlock, flags);
...@@ -1177,12 +1172,12 @@ static void event_free(struct etnaviv_gpu *gpu, unsigned int event) ...@@ -1177,12 +1172,12 @@ static void event_free(struct etnaviv_gpu *gpu, unsigned int event)
spin_lock_irqsave(&gpu->event_spinlock, flags); spin_lock_irqsave(&gpu->event_spinlock, flags);
if (gpu->event[event].used == false) { if (!test_bit(event, gpu->event_bitmap)) {
dev_warn(gpu->dev, "event %u is already marked as free", dev_warn(gpu->dev, "event %u is already marked as free",
event); event);
spin_unlock_irqrestore(&gpu->event_spinlock, flags); spin_unlock_irqrestore(&gpu->event_spinlock, flags);
} else { } else {
gpu->event[event].used = false; clear_bit(event, gpu->event_bitmap);
spin_unlock_irqrestore(&gpu->event_spinlock, flags); spin_unlock_irqrestore(&gpu->event_spinlock, flags);
complete(&gpu->event_free); complete(&gpu->event_free);
......
...@@ -88,13 +88,14 @@ struct etnaviv_chip_identity { ...@@ -88,13 +88,14 @@ struct etnaviv_chip_identity {
}; };
struct etnaviv_event { struct etnaviv_event {
bool used;
struct dma_fence *fence; struct dma_fence *fence;
}; };
struct etnaviv_cmdbuf_suballoc; struct etnaviv_cmdbuf_suballoc;
struct etnaviv_cmdbuf; struct etnaviv_cmdbuf;
#define ETNA_NR_EVENTS 30
struct etnaviv_gpu { struct etnaviv_gpu {
struct drm_device *drm; struct drm_device *drm;
struct thermal_cooling_device *cooling; struct thermal_cooling_device *cooling;
...@@ -112,7 +113,8 @@ struct etnaviv_gpu { ...@@ -112,7 +113,8 @@ struct etnaviv_gpu {
u32 memory_base; u32 memory_base;
/* event management: */ /* event management: */
struct etnaviv_event event[30]; DECLARE_BITMAP(event_bitmap, ETNA_NR_EVENTS);
struct etnaviv_event event[ETNA_NR_EVENTS];
struct completion event_free; struct completion event_free;
spinlock_t event_spinlock; spinlock_t event_spinlock;
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册