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

Commit 119d5bf3 authored by Jordan Crouse's avatar Jordan Crouse
Browse files

msm: kgsl: Split out adreno_idle into a lighter weight function



In most cases idling the GPU is a heavy weight operation: stop the
dispatcher, wait for the hardware, deal with faults, etc. The idle
following ME_INIT is not one of those cases. The init sequence
is a controlled operation with a stopped dispatcher so we can forgo
the heavier bits of adreno_idle(). Break out the idle loop
and turn it into adreno_spin_idle() for use by both adreno_idle()
and ringbuffer init.

Change-Id: Ic0dedbad870ea65cc78d2a45d90ed895b87a7f5e
Signed-off-by: default avatarJordan Crouse <jcrouse@codeaurora.org>
parent 8834ae89
Loading
Loading
Loading
Loading
+34 −21
Original line number Diff line number Diff line
@@ -2787,6 +2787,39 @@ bool adreno_isidle(struct kgsl_device *device)
	return false;
}

/**
 * adreno_spin_idle() - Spin wait for the GPU to idle
 * @device: Pointer to the KGSL device
 *
 * Spin the CPU waiting for the RBBM status to return idle
 */
int adreno_spin_idle(struct kgsl_device *device)
{
	struct adreno_device *adreno_dev = ADRENO_DEVICE(device);
	unsigned long wait = jiffies + msecs_to_jiffies(ADRENO_IDLE_TIMEOUT);

	kgsl_cffdump_regpoll(device,
		adreno_getreg(adreno_dev, ADRENO_REG_RBBM_STATUS) << 2,
		0x00000000, 0x80000000);

	while (time_before(jiffies, wait)) {
		/*
		 * If we fault, stop waiting and return an error. The dispatcher
		 * will clean up the fault from the work queue, but we need to
		 * make sure we don't block it by waiting for an idle that
		 * will never come.
		 */

		if (adreno_gpu_fault(adreno_dev) != 0)
			return -EDEADLK;

		if (adreno_isidle(device))
			return 0;
	}

	return -ETIMEDOUT;
}

/**
 * adreno_idle() - wait for the GPU hardware to go idle
 * @device: Pointer to the KGSL device structure for the GPU
@@ -2797,7 +2830,6 @@ bool adreno_isidle(struct kgsl_device *device)
int adreno_idle(struct kgsl_device *device)
{
	struct adreno_device *adreno_dev = ADRENO_DEVICE(device);
	unsigned long wait = jiffies + msecs_to_jiffies(ADRENO_IDLE_TIMEOUT);
	int ret;

	/*
@@ -2807,10 +2839,6 @@ int adreno_idle(struct kgsl_device *device)

	BUG_ON(!mutex_is_locked(&device->mutex));

	kgsl_cffdump_regpoll(device,
		adreno_getreg(adreno_dev, ADRENO_REG_RBBM_STATUS) << 2,
		0x00000000, 0x80000000);

	/* Check if we are already idle before idling dispatcher */
	if (adreno_isidle(device))
		return 0;
@@ -2822,22 +2850,7 @@ int adreno_idle(struct kgsl_device *device)
	if (ret)
		return ret;

	while (time_before(jiffies, wait)) {
		/*
		 * If we fault, stop waiting and return an error. The dispatcher
		 * will clean up the fault from the work queue, but we need to
		 * make sure we don't block it by waiting for an idle that
		 * will never come.
		 */

		if (adreno_gpu_fault(adreno_dev) != 0)
			return -EDEADLK;

		if (adreno_isidle(device))
			return 0;
	}

	return -ETIMEDOUT;
	return adreno_spin_idle(device);
}

/**
+1 −0
Original line number Diff line number Diff line
@@ -608,6 +608,7 @@ extern const unsigned int a4xx_sp_tp_registers_count;

extern unsigned int ft_detect_regs[];

int adreno_spin_idle(struct kgsl_device *device);
int adreno_idle(struct kgsl_device *device);
bool adreno_isidle(struct kgsl_device *device);

+1 −1
Original line number Diff line number Diff line
@@ -475,7 +475,7 @@ static int _ringbuffer_start_common(struct adreno_ringbuffer *rb)
		return status;

	/* idle device to validate ME INIT */
	status = adreno_idle(device);
	status = adreno_spin_idle(device);

	if (status == 0)
		rb->flags |= KGSL_FLAGS_STARTED;