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

Commit e8046965 authored by Harshdeep Dhatt's avatar Harshdeep Dhatt Committed by Gerrit - the friendly Code Review server
Browse files

msm: kgsl: Make sure RBBM_INT_0_STATUS is not transitory



In the interrupt handler, read the STATUS register for up to
3 times to see if the STATUS bits are not changing. This
is done in order to avoid handling the transitory bits.
Empirical data has shown that the transitory bits vanish
in the small window between two or three consecutive reads
of the register.

Change-Id: Ic7ef241d62ff2dc60f9427531d02381c396795b0
Signed-off-by: default avatarHarshdeep Dhatt <hdhatt@codeaurora.org>
parent 669aeab5
Loading
Loading
Loading
Loading
+27 −0
Original line number Diff line number Diff line
@@ -613,6 +613,7 @@ static irqreturn_t adreno_irq_handler(struct kgsl_device *device)
	struct adreno_irq *irq_params = gpudev->irq;
	irqreturn_t ret = IRQ_NONE;
	unsigned int status = 0, fence = 0, fence_retries = 0, tmp, int_bit;
	unsigned int status_retries = 0;
	int i;

	atomic_inc(&adreno_dev->pending_irq_refcnt);
@@ -651,6 +652,32 @@ static irqreturn_t adreno_irq_handler(struct kgsl_device *device)

	adreno_readreg(adreno_dev, ADRENO_REG_RBBM_INT_0_STATUS, &status);

	/*
	 * Read status again to make sure the bits aren't transitory.
	 * Transitory bits mean that they are spurious interrupts and are
	 * seen while preemption is on going. Empirical experiments have
	 * shown that the transitory bits are a timing thing and they
	 * go away in the small time window between two or three consecutive
	 * reads. If they don't go away, log the message and return.
	 */
	while (status_retries < STATUS_RETRY_MAX) {
		unsigned int new_status;

		adreno_readreg(adreno_dev, ADRENO_REG_RBBM_INT_0_STATUS,
			&new_status);

		if (status == new_status)
			break;

		status = new_status;
		status_retries++;
	}

	if (status_retries == STATUS_RETRY_MAX) {
		KGSL_DRV_CRIT_RATELIMIT(device, "STATUS bits are not stable\n");
			return ret;
	}

	/*
	 * Clear all the interrupt bits but ADRENO_INT_RBBM_AHB_ERROR. Because
	 * even if we clear it here, it will stay high until it is cleared
+3 −0
Original line number Diff line number Diff line
@@ -167,6 +167,9 @@
/* Number of times to poll the AHB fence in ISR */
#define FENCE_RETRY_MAX 100

/* Number of times to see if INT_0_STATUS changed or not */
#define STATUS_RETRY_MAX 3

/* One cannot wait forever for the core to idle, so set an upper limit to the
 * amount of time to wait for the core to go idle
 */