Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 355502e0 authored by Christian Gmeiner's avatar Christian Gmeiner Committed by Lucas Stach
Browse files

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: default avatarChristian Gmeiner <christian.gmeiner@gmail.com>
Signed-off-by: default avatarLucas Stach <l.stach@pengutronix.de>
parent 6eb3ecc3
Loading
Loading
Loading
Loading
+13 −18
Original line number Diff line number Diff line
@@ -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);
+4 −2
Original line number Diff line number Diff line
@@ -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;