summaryrefslogtreecommitdiff
path: root/drivers/gpu/drm/etnaviv
diff options
context:
space:
mode:
authorChristian Gmeiner <christian.gmeiner@gmail.com>2017-09-24 15:15:19 +0200
committerLucas Stach <l.stach@pengutronix.de>2017-10-10 11:45:39 +0200
commit355502e03ad26e3c872a0f5c408a4accca57ba7e (patch)
treec1327e81702aa186a5ea6be0a9279f0667315cc4 /drivers/gpu/drm/etnaviv
parent6eb3ecc33a6aaedda5ceb0824cafe34c47af2f55 (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.c31
-rw-r--r--drivers/gpu/drm/etnaviv/etnaviv_gpu.h6
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;