summaryrefslogtreecommitdiff
path: root/drivers/gpu
diff options
context:
space:
mode:
authorHarshdeep Dhatt <hdhatt@codeaurora.org>2016-11-22 16:14:44 -0700
committerCarter Cooper <ccooper@codeaurora.org>2016-11-29 09:33:09 -0700
commitc0d96c8a762df9a931105206282912cf10fae1ac (patch)
tree8e872cf003694a7c7a76201bb0cf168f5b76307e /drivers/gpu
parent2be8fc81c3adef891480d3abd19639860d838443 (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.c16
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,