Loading drivers/gpu/msm/adreno_a6xx_preempt.c +20 −0 Original line number Diff line number Diff line Loading @@ -27,6 +27,7 @@ static void _update_wptr(struct adreno_device *adreno_dev, bool reset_timer) struct adreno_ringbuffer *rb = adreno_dev->cur_rb; unsigned long flags; int ret = 0; struct kgsl_device *device = KGSL_DEVICE(adreno_dev); spin_lock_irqsave(&rb->preempt_lock, flags); Loading @@ -36,11 +37,30 @@ static void _update_wptr(struct adreno_device *adreno_dev, bool reset_timer) * dispatcher context. Do it now. */ if (rb->skip_inline_wptr) { /* * There could be a situation where GPU comes out of * ifpc after a fenced write transaction but before * reading AHB_FENCE_STATUS from KMD, it goes back to * ifpc due to inactivity (kernel scheduler plays a * role here). Thus, the GPU could technically be * re-collapsed between subsequent register writes * leading to a prolonged preemption sequence. The * keepalive bit prevents any further power collapse * while it is set. */ if (gmu_core_isenabled(device)) gmu_core_regrmw(device, A6XX_GMU_AO_SPARE_CNTL, 0x0, 0x2); ret = adreno_gmu_fenced_write(adreno_dev, ADRENO_REG_CP_RB_WPTR, rb->wptr, FENCE_STATUS_WRITEDROPPED0_MASK); /* Clear the keep alive */ if (gmu_core_isenabled(device)) gmu_core_regrmw(device, A6XX_GMU_AO_SPARE_CNTL, 0x2, 0x0); reset_timer = true; rb->skip_inline_wptr = false; } Loading drivers/gpu/msm/adreno_ringbuffer.c +15 −0 Original line number Diff line number Diff line Loading @@ -75,6 +75,7 @@ static void adreno_ringbuffer_wptr(struct adreno_device *adreno_dev, struct adreno_ringbuffer *rb) { struct kgsl_device *device = KGSL_DEVICE(adreno_dev); struct adreno_gpudev *gpudev = ADRENO_GPU_DEVICE(adreno_dev); unsigned long flags; int ret = 0; Loading @@ -88,6 +89,17 @@ static void adreno_ringbuffer_wptr(struct adreno_device *adreno_dev, */ kgsl_pwrscale_busy(device); /* * There could be a situation where GPU comes out of * ifpc after a fenced write transaction but before * reading AHB_FENCE_STATUS from KMD, it goes back to * ifpc due to inactivity (kernel scheduler plays a * role here). Put a keep alive vote to avoid such * unlikely scenario. */ if (gpudev->gpu_keepalive) gpudev->gpu_keepalive(adreno_dev, true); /* * Ensure the write posted after a possible * GMU wakeup (write could have dropped during wakeup) Loading @@ -96,6 +108,9 @@ static void adreno_ringbuffer_wptr(struct adreno_device *adreno_dev, ADRENO_REG_CP_RB_WPTR, rb->_wptr, FENCE_STATUS_WRITEDROPPED0_MASK); rb->skip_inline_wptr = false; if (gpudev->gpu_keepalive) gpudev->gpu_keepalive(adreno_dev, false); } } else { /* Loading Loading
drivers/gpu/msm/adreno_a6xx_preempt.c +20 −0 Original line number Diff line number Diff line Loading @@ -27,6 +27,7 @@ static void _update_wptr(struct adreno_device *adreno_dev, bool reset_timer) struct adreno_ringbuffer *rb = adreno_dev->cur_rb; unsigned long flags; int ret = 0; struct kgsl_device *device = KGSL_DEVICE(adreno_dev); spin_lock_irqsave(&rb->preempt_lock, flags); Loading @@ -36,11 +37,30 @@ static void _update_wptr(struct adreno_device *adreno_dev, bool reset_timer) * dispatcher context. Do it now. */ if (rb->skip_inline_wptr) { /* * There could be a situation where GPU comes out of * ifpc after a fenced write transaction but before * reading AHB_FENCE_STATUS from KMD, it goes back to * ifpc due to inactivity (kernel scheduler plays a * role here). Thus, the GPU could technically be * re-collapsed between subsequent register writes * leading to a prolonged preemption sequence. The * keepalive bit prevents any further power collapse * while it is set. */ if (gmu_core_isenabled(device)) gmu_core_regrmw(device, A6XX_GMU_AO_SPARE_CNTL, 0x0, 0x2); ret = adreno_gmu_fenced_write(adreno_dev, ADRENO_REG_CP_RB_WPTR, rb->wptr, FENCE_STATUS_WRITEDROPPED0_MASK); /* Clear the keep alive */ if (gmu_core_isenabled(device)) gmu_core_regrmw(device, A6XX_GMU_AO_SPARE_CNTL, 0x2, 0x0); reset_timer = true; rb->skip_inline_wptr = false; } Loading
drivers/gpu/msm/adreno_ringbuffer.c +15 −0 Original line number Diff line number Diff line Loading @@ -75,6 +75,7 @@ static void adreno_ringbuffer_wptr(struct adreno_device *adreno_dev, struct adreno_ringbuffer *rb) { struct kgsl_device *device = KGSL_DEVICE(adreno_dev); struct adreno_gpudev *gpudev = ADRENO_GPU_DEVICE(adreno_dev); unsigned long flags; int ret = 0; Loading @@ -88,6 +89,17 @@ static void adreno_ringbuffer_wptr(struct adreno_device *adreno_dev, */ kgsl_pwrscale_busy(device); /* * There could be a situation where GPU comes out of * ifpc after a fenced write transaction but before * reading AHB_FENCE_STATUS from KMD, it goes back to * ifpc due to inactivity (kernel scheduler plays a * role here). Put a keep alive vote to avoid such * unlikely scenario. */ if (gpudev->gpu_keepalive) gpudev->gpu_keepalive(adreno_dev, true); /* * Ensure the write posted after a possible * GMU wakeup (write could have dropped during wakeup) Loading @@ -96,6 +108,9 @@ static void adreno_ringbuffer_wptr(struct adreno_device *adreno_dev, ADRENO_REG_CP_RB_WPTR, rb->_wptr, FENCE_STATUS_WRITEDROPPED0_MASK); rb->skip_inline_wptr = false; if (gpudev->gpu_keepalive) gpudev->gpu_keepalive(adreno_dev, false); } } else { /* Loading