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

Commit b4dbd6e5 authored by Kasin Li's avatar Kasin Li Committed by Gerrit - the friendly Code Review server
Browse files

drm/msm: Make ringbuffer could wrap



Currently, if read pointer is in front of write pointer,
when there is not enough space toward the end of the ringbuffer
for new commands, the driver should wait for the read pointer
reach to the end of ringbuffer.
This is not efficient, so remove the wait to end and write pointer
could back to the beginning of ring buffer without breaking the
commands list and catching up with read pointer.

Change-Id: I144249e2e517843b6bb468621ab41cbc9475867d
Signed-off-by: default avatarKasin Li <donglil@codeaurora.org>
parent b3818159
Loading
Loading
Loading
Loading
+31 −21
Original line number Diff line number Diff line
@@ -85,6 +85,14 @@ static uint32_t get_wptr(struct msm_ringbuffer *ring)
	return ring->cur - ring->start;
}

static uint32_t get_rptr(struct msm_ringbuffer *ring)
{
	struct msm_gpu *gpu = ring->gpu;
	struct adreno_gpu *adreno_gpu = to_adreno_gpu(gpu);

	return adreno_gpu_read(adreno_gpu, REG_ADRENO_CP_RB_RPTR);
}

uint32_t adreno_last_fence(struct msm_gpu *gpu)
{
	struct adreno_gpu *adreno_gpu = to_adreno_gpu(gpu);
@@ -255,36 +263,38 @@ void adreno_dump(struct msm_gpu *gpu)
	}
}

static uint32_t ring_freewords(struct msm_gpu *gpu)
#define GSL_RB_NOP_SIZEDWORDS      2
static bool ring_freewords(struct msm_gpu *gpu, uint32_t ndwords)
{
	uint32_t size = gpu->rb->size / 4;
	uint32_t wptr = get_wptr(gpu->rb);
	uint32_t rptr = get_rptr(gpu->rb);

	return size - wptr - 1;
}

	if (rptr <= wptr) {
		if ((wptr + ndwords) <=
				(size - GSL_RB_NOP_SIZEDWORDS))
			return true;
		/*
 * TODO next stage, remove wait on the tail of ring buffer.
		 * There isn't enough space toward the end of ringbuffer. So
		 * look for space from the beginning of ringbuffer upto the
		 * read pointer.
		 */
static int rb_check_and_split(struct msm_gpu *gpu, uint32_t ndwords)
{
	uint32_t size = gpu->rb->size / 4;
	uint32_t wptr = get_wptr(gpu->rb);

	if ((wptr + ndwords) < size-1)
		return 0;

		if (ndwords < rptr) {
			OUT_RING(gpu->rb, cp_pkt7(CP_NOP, (size - wptr - 1)));
			gpu->rb->cur = gpu->rb->start;
	gpu->funcs->flush(gpu);
	gpu->funcs->idle(gpu);
	return 1;
			return true;
		}
	}

	if ((wptr + ndwords) < rptr)
		return true;

	return false;
}

void adreno_wait_ring(struct msm_gpu *gpu, uint32_t ndwords)
{
	rb_check_and_split(gpu, ndwords);
	if (spin_until(ring_freewords(gpu) >= ndwords))
	if (spin_until(ring_freewords(gpu, ndwords)))
		DRM_ERROR("%s: timeout waiting for ringbuffer space\n",
			  gpu->name);
}