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

Commit 7afc6882 authored by Deepak Kumar's avatar Deepak Kumar Committed by Gerrit - the friendly Code Review server
Browse files

msm: kgsl: Trigger preemption only if GMU is in ACTIVE state



Wait for GMU to move to ACTIVE state before triggering preemption.
This is required to make sure CP doesn't interrupt GMU during
wake-up from IFPC.

Change-Id: I9c8ee07a4887deb30483b5523585d547b5d38806
Signed-off-by: default avatarDeepak Kumar <dkumar@codeaurora.org>
parent 315bb5ae
Loading
Loading
Loading
Loading
+49 −0
Original line number Diff line number Diff line
@@ -232,6 +232,38 @@ static struct adreno_ringbuffer *a6xx_next_ringbuffer(
	return NULL;
}

#define GMU_ACTIVE_STATE_RETRY_MAX 100

static int adreno_gmu_wait_for_active(struct adreno_device *adreno_dev)
{
	unsigned int reg, num_retries = 0;
	struct kgsl_device *device = KGSL_DEVICE(adreno_dev);

	if (!kgsl_gmu_isenabled(device))
		return 0;

	kgsl_gmu_regread(device,
		A6XX_GPU_GMU_CX_GMU_RPMH_POWER_STATE, &reg);

	while (reg != GPU_HW_ACTIVE) {
		/* Wait for small time before trying again */
		udelay(5);
		kgsl_gmu_regread(device,
			A6XX_GPU_GMU_CX_GMU_RPMH_POWER_STATE, &reg);

		if (num_retries == GMU_ACTIVE_STATE_RETRY_MAX &&
			reg != GPU_HW_ACTIVE) {
			dev_err(adreno_dev->dev.dev,
				"GMU failed to move to ACTIVE state: 0x%x\n",
				reg);
			return -ETIMEDOUT;
		}
		num_retries++;
	}

	return 0;
}

void a6xx_preemption_trigger(struct adreno_device *adreno_dev)
{
	struct kgsl_device *device = KGSL_DEVICE(adreno_dev);
@@ -361,6 +393,23 @@ void a6xx_preemption_trigger(struct adreno_device *adreno_dev)
		upper_32_bits(gpuaddr),
		FENCE_STATUS_WRITEDROPPED1_MASK);

	/*
	 * Above fence writes will make sure GMU comes out of
	 * IFPC state if its was in IFPC state but it doesn't
	 * guarantee that GMU FW actually moved to ACTIVE state
	 * i.e. wake-up from IFPC is complete.
	 * Wait for GMU to move to ACTIVE state before triggering
	 * preemption. This is require to make sure CP doesn't
	 * interrupt GMU during wake-up from IFPC.
	 */
	if (adreno_gmu_wait_for_active(adreno_dev)) {
		adreno_set_preempt_state(adreno_dev, ADRENO_PREEMPT_NONE);

		adreno_set_gpu_fault(adreno_dev, ADRENO_GMU_FAULT);
		adreno_dispatcher_schedule(device);
		return;
	}

	adreno_dev->next_rb = next;

	/* Start the timer to detect a stuck preemption */