diff options
author | Christian Gmeiner <christian.gmeiner@gmail.com> | 2017-09-24 15:15:19 +0200 |
---|---|---|
committer | Lucas Stach <l.stach@pengutronix.de> | 2017-10-10 11:45:39 +0200 |
commit | 355502e03ad26e3c872a0f5c408a4accca57ba7e (patch) | |
tree | c1327e81702aa186a5ea6be0a9279f0667315cc4 /drivers/gpu/drm/etnaviv | |
parent | 6eb3ecc33a6aaedda5ceb0824cafe34c47af2f55 (diff) |
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: Christian Gmeiner <christian.gmeiner@gmail.com>
Signed-off-by: Lucas Stach <l.stach@pengutronix.de>
Diffstat (limited to 'drivers/gpu/drm/etnaviv')
-rw-r--r-- | drivers/gpu/drm/etnaviv/etnaviv_gpu.c | 31 | ||||
-rw-r--r-- | drivers/gpu/drm/etnaviv/etnaviv_gpu.h | 6 |
2 files changed, 17 insertions, 20 deletions
diff --git a/drivers/gpu/drm/etnaviv/etnaviv_gpu.c b/drivers/gpu/drm/etnaviv/etnaviv_gpu.c index de34e221c2fe..3b02814b9c52 100644 --- a/drivers/gpu/drm/etnaviv/etnaviv_gpu.c +++ b/drivers/gpu/drm/etnaviv/etnaviv_gpu.c @@ -744,10 +744,9 @@ int etnaviv_gpu_init(struct etnaviv_gpu *gpu) /* Setup event management */ spin_lock_init(&gpu->event_spinlock); init_completion(&gpu->event_free); - for (i = 0; i < ARRAY_SIZE(gpu->event); i++) { - gpu->event[i].used = false; + bitmap_zero(gpu->event_bitmap, ETNA_NR_EVENTS); + for (i = 0; i < ARRAY_SIZE(gpu->event); i++) complete(&gpu->event_free); - } /* Now program the hardware */ mutex_lock(&gpu->lock); @@ -931,7 +930,7 @@ static void recover_worker(struct work_struct *work) struct etnaviv_gpu *gpu = container_of(work, struct etnaviv_gpu, recover_work); unsigned long flags; - unsigned int i; + unsigned int i = 0; dev_err(gpu->dev, "hangcheck recover!\n"); @@ -950,14 +949,12 @@ static void recover_worker(struct work_struct *work) /* complete all events, the GPU won't do it after the reset */ spin_lock_irqsave(&gpu->event_spinlock, flags); - for (i = 0; i < ARRAY_SIZE(gpu->event); i++) { - if (!gpu->event[i].used) - continue; + for_each_set_bit_from(i, gpu->event_bitmap, ETNA_NR_EVENTS) { dma_fence_signal(gpu->event[i].fence); gpu->event[i].fence = NULL; - gpu->event[i].used = false; complete(&gpu->event_free); } + bitmap_zero(gpu->event_bitmap, ETNA_NR_EVENTS); spin_unlock_irqrestore(&gpu->event_spinlock, flags); gpu->completed_fence = gpu->active_fence; @@ -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) { unsigned long ret, flags; - unsigned int i, event = ~0U; + unsigned int event; ret = wait_for_completion_timeout(&gpu->event_free, msecs_to_jiffies(10 * 10000)); @@ -1158,13 +1155,11 @@ static unsigned int event_alloc(struct etnaviv_gpu *gpu) spin_lock_irqsave(&gpu->event_spinlock, flags); /* find first free event */ - for (i = 0; i < ARRAY_SIZE(gpu->event); i++) { - if (gpu->event[i].used == false) { - gpu->event[i].used = true; - event = i; - break; - } - } + event = find_first_zero_bit(gpu->event_bitmap, ETNA_NR_EVENTS); + if (event < ETNA_NR_EVENTS) + set_bit(event, gpu->event_bitmap); + else + event = ~0U; spin_unlock_irqrestore(&gpu->event_spinlock, flags); @@ -1177,12 +1172,12 @@ static void event_free(struct etnaviv_gpu *gpu, unsigned int event) 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", event); spin_unlock_irqrestore(&gpu->event_spinlock, flags); } else { - gpu->event[event].used = false; + clear_bit(event, gpu->event_bitmap); spin_unlock_irqrestore(&gpu->event_spinlock, flags); complete(&gpu->event_free); diff --git a/drivers/gpu/drm/etnaviv/etnaviv_gpu.h b/drivers/gpu/drm/etnaviv/etnaviv_gpu.h index 689cb8f3680c..70e6590aacdf 100644 --- a/drivers/gpu/drm/etnaviv/etnaviv_gpu.h +++ b/drivers/gpu/drm/etnaviv/etnaviv_gpu.h @@ -88,13 +88,14 @@ struct etnaviv_chip_identity { }; struct etnaviv_event { - bool used; struct dma_fence *fence; }; struct etnaviv_cmdbuf_suballoc; struct etnaviv_cmdbuf; +#define ETNA_NR_EVENTS 30 + struct etnaviv_gpu { struct drm_device *drm; struct thermal_cooling_device *cooling; @@ -112,7 +113,8 @@ struct etnaviv_gpu { u32 memory_base; /* 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; spinlock_t event_spinlock; |