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

Commit 8f78d5fb authored by Harshdeep Dhatt's avatar Harshdeep Dhatt Committed by Tarun Karra
Browse files

msm: kgsl: Make the fenced register write function generic



This function will also be used for A6XX preemption register
writes to go through if the FENCE is in drop mode.

Change-Id: Ifc0d31f672e5b9c7b4e085ad4cbc47e70a4c21bc
Signed-off-by: default avatarHarshdeep Dhatt <hdhatt@codeaurora.org>
Signed-off-by: default avatarTarun Karra <tkarra@codeaurora.org>
parent 1a02b381
Loading
Loading
Loading
Loading
+3 −0
Original line number Diff line number Diff line
@@ -1898,4 +1898,7 @@ static inline int adreno_vbif_clear_pending_transactions(
	return ret;
}

void adreno_gmu_fenced_write(struct adreno_device *adreno_dev,
	enum adreno_regs offset, unsigned int val,
	unsigned int fence_mask);
#endif /*__ADRENO_H */
+4 −43
Original line number Diff line number Diff line
@@ -80,44 +80,6 @@ static void adreno_get_submit_time(struct adreno_device *adreno_dev,
	local_irq_restore(flags);
}

/*
 * Wait time before trying to write the register again.
 * Hopefully the GMU has finished waking up during this delay.
 * This delay must be less than the IFPC main hysteresis or
 * the GMU will start shutting down before we try again.
 */
#define GMU_WAKEUP_DELAY 10
/* Max amount of tries to wake up the GMU. */
#define GMU_WAKEUP_RETRY_MAX 60

/*
 * Check the WRITEDROPPED0 bit in the
 * FENCE_STATUS regsiter to check if the write went
 * through. If it didn't then we retry the write.
 */
static inline void _gmu_wptr_update_if_dropped(struct adreno_device *adreno_dev,
		struct adreno_ringbuffer *rb)
{
	unsigned int val, i;

	for (i = 0; i < GMU_WAKEUP_RETRY_MAX; i++) {
		adreno_read_gmureg(adreno_dev, ADRENO_REG_GMU_AHB_FENCE_STATUS,
				&val);

		/* If !writedropped, then wptr update was successful */
		if (!(val & 0x1))
			return;

		/* Wait a small amount of time before trying again */
		udelay(GMU_WAKEUP_DELAY);

		/* Try to write WPTR again */
		adreno_writereg(adreno_dev, ADRENO_REG_CP_RB_WPTR, rb->_wptr);
	}

	dev_err(adreno_dev->dev.dev, "GMU WPTR update timed out\n");
}

static void adreno_ringbuffer_wptr(struct adreno_device *adreno_dev,
		struct adreno_ringbuffer *rb)
{
@@ -132,15 +94,14 @@ static void adreno_ringbuffer_wptr(struct adreno_device *adreno_dev,
			 * been submitted.
			 */
			kgsl_pwrscale_busy(KGSL_DEVICE(adreno_dev));
			adreno_writereg(adreno_dev, ADRENO_REG_CP_RB_WPTR,
				rb->_wptr);

			/*
			 * If GMU, ensure the write posted after a possible
			 * Ensure the write posted after a possible
			 * GMU wakeup (write could have dropped during wakeup)
			 */
			if (kgsl_gmu_isenabled(KGSL_DEVICE(adreno_dev)))
				_gmu_wptr_update_if_dropped(adreno_dev, rb);
			adreno_gmu_fenced_write(adreno_dev,
				ADRENO_REG_CP_RB_WPTR, rb->_wptr,
				FENCE_STATUS_WRITEDROPPED0_MASK);

		}
	}
+43 −0
Original line number Diff line number Diff line
@@ -1620,3 +1620,46 @@ void gmu_remove(struct kgsl_device *device)

	device->gmu.pdev = NULL;
}

/*
 * adreno_gmu_fenced_write() - Check if there is a GMU and it is enabled
 * @adreno_dev: Pointer to the Adreno device device that owns the GMU
 * @offset: 32bit register enum that is to be written
 * @val: The value to be written to the register
 * @fence_mask: The value to poll the fence status register
 *
 * Check the WRITEDROPPED0/1 bit in the FENCE_STATUS regsiter to check if
 * the write to the fenced register went through. If it didn't then we retry
 * the write until it goes through or we time out.
 */
void adreno_gmu_fenced_write(struct adreno_device *adreno_dev,
		enum adreno_regs offset, unsigned int val,
		unsigned int fence_mask)
{
	unsigned int status, i;

	adreno_writereg(adreno_dev, offset, val);

	if (!kgsl_gmu_isenabled(KGSL_DEVICE(adreno_dev)))
		return;

	for (i = 0; i < GMU_WAKEUP_RETRY_MAX; i++) {
		adreno_read_gmureg(adreno_dev, ADRENO_REG_GMU_AHB_FENCE_STATUS,
			&status);

		/*
		 * If !writedropped0/1, then the write to fenced register
		 * was successful
		 */
		if (!(status & fence_mask))
			return;
		/* Wait a small amount of time before trying again */
		udelay(GMU_WAKEUP_DELAY_US);

		/* Try to write the fenced register again */
		adreno_writereg(adreno_dev, offset, val);
	}

	dev_err(adreno_dev->dev.dev,
		"GMU fenced register write timed out: reg %x\n", offset);
}
+13 −0
Original line number Diff line number Diff line
@@ -33,6 +33,9 @@
#define MAX_GMUFW_SIZE	0x2000	/* in bytes */
#define FENCE_RANGE_MASK	((0x1 << 31) | ((0xA << 2) << 18) | (0x8A0))

#define FENCE_STATUS_WRITEDROPPED0_MASK 0x1
#define FENCE_STATUS_WRITEDROPPED1_MASK 0x2

/* Bitmask for GPU low power mode enabling and hysterisis*/
#define SPTP_ENABLE_MASK (BIT(2) | BIT(0))
#define IFPC_ENABLE_MASK (BIT(1) | BIT(0))
@@ -79,6 +82,16 @@
#define OOB_PERFCNTR_CHECK_MASK		BIT(25)
#define OOB_PERFCNTR_CLEAR_MASK		BIT(25)

/*
 * Wait time before trying to write the register again.
 * Hopefully the GMU has finished waking up during this delay.
 * This delay must be less than the IFPC main hysteresis or
 * the GMU will start shutting down before we try again.
 */
#define GMU_WAKEUP_DELAY_US 10
/* Max amount of tries to wake up the GMU. */
#define GMU_WAKEUP_RETRY_MAX 60

/* Bits for the flags field in the gmu structure */
enum gmu_flags {
	GMU_BOOT_INIT_DONE = 0,