diff options
author | Harshdeep Dhatt <hdhatt@codeaurora.org> | 2016-11-22 16:14:44 -0700 |
---|---|---|
committer | Carter Cooper <ccooper@codeaurora.org> | 2016-11-29 09:33:09 -0700 |
commit | c0d96c8a762df9a931105206282912cf10fae1ac (patch) | |
tree | 8e872cf003694a7c7a76201bb0cf168f5b76307e /drivers/gpu | |
parent | 2be8fc81c3adef891480d3abd19639860d838443 (diff) |
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 where
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: Harshdeep Dhatt <hdhatt@codeaurora.org>
Diffstat (limited to 'drivers/gpu')
-rw-r--r-- | drivers/gpu/msm/adreno_a5xx_preempt.c | 16 |
1 files changed, 11 insertions, 5 deletions
diff --git a/drivers/gpu/msm/adreno_a5xx_preempt.c b/drivers/gpu/msm/adreno_a5xx_preempt.c index 09c550c9f58c..0e56731b16e2 100644 --- a/drivers/gpu/msm/adreno_a5xx_preempt.c +++ b/drivers/gpu/msm/adreno_a5xx_preempt.c @@ -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_drawobj_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, |