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

Commit a9c986c0 authored by Harshdeep Dhatt's avatar Harshdeep Dhatt Committed by Sunil Khatri
Browse files

msm: kgsl: Update ringbuffer timer when preemption completes



Ringbuffer timer should always be reset whenever we finish
preempting to that ringbuffer. Currently, there is a case when
wptr in the hardware and the kgsl are identical and thus
the timer isn't reset. Reset the timer regardless if they are
identical or not.
There is one special case when we shouldn't reset the timer.
This happens when we try to figure out next ringbuffer to preempt
but the next ringbuffer is the same one as current. In that case,
if nothing new got submitted to this ringbuffer, then don't reset
the timer.

Change-Id: I6b5aea46f1769021b39ba6e135bef780719a92e7
Signed-off-by: default avatarHarshdeep Dhatt <hdhatt@codeaurora.org>
parent ca644868
Loading
Loading
Loading
Loading
+11 −5
Original line number Diff line number Diff line
@@ -22,7 +22,7 @@
#define PREEMPT_SMMU_RECORD(_field) \
		offsetof(struct a5xx_cp_smmu_info, _field)

static void _update_wptr(struct adreno_device *adreno_dev)
static void _update_wptr(struct adreno_device *adreno_dev, bool reset_timer)
{
	struct adreno_ringbuffer *rb = adreno_dev->cur_rb;
	unsigned int wptr;
@@ -35,10 +35,16 @@ static void _update_wptr(struct adreno_device *adreno_dev)
	if (wptr != rb->wptr) {
		adreno_writereg(adreno_dev, ADRENO_REG_CP_RB_WPTR,
			rb->wptr);
		/*
		 * In case something got submitted while preemption was on
		 * going, reset the timer.
		 */
		reset_timer = 1;
	}

	if (reset_timer)
		rb->dispatch_q.expires = jiffies +
			msecs_to_jiffies(adreno_cmdbatch_timeout);
	}

	spin_unlock_irqrestore(&rb->preempt_lock, flags);
}
@@ -90,7 +96,7 @@ static void _a5xx_preemption_done(struct adreno_device *adreno_dev)
	adreno_dev->next_rb = NULL;

	/* Update the wptr for the new command queue */
	_update_wptr(adreno_dev);
	_update_wptr(adreno_dev, true);

	/* Update the dispatcher timer for the new command queue */
	mod_timer(&adreno_dev->dispatcher.timer,
@@ -213,7 +219,7 @@ void a5xx_preemption_trigger(struct adreno_device *adreno_dev)
		 */

		if (next != NULL) {
			_update_wptr(adreno_dev);
			_update_wptr(adreno_dev, false);

			mod_timer(&adreno_dev->dispatcher.timer,
				adreno_dev->cur_rb->dispatch_q.expires);
@@ -304,7 +310,7 @@ void a5xx_preempt_callback(struct adreno_device *adreno_dev, int bit)
	adreno_dev->next_rb = NULL;

	/* Update the wptr if it changed while preemption was ongoing */
	_update_wptr(adreno_dev);
	_update_wptr(adreno_dev, true);

	/* Update the dispatcher timer for the new command queue */
	mod_timer(&adreno_dev->dispatcher.timer,