Loading drivers/gpu/msm/adreno_a6xx_preempt.c +20 −0 Original line number Diff line number Diff line Loading @@ -36,6 +36,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 @@ -45,11 +46,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 +16 −1 Original line number Diff line number Diff line /* Copyright (c) 2002,2007-2019, The Linux Foundation. All rights reserved. /* Copyright (c) 2002,2007-2020, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and Loading Loading @@ -89,6 +89,7 @@ static void adreno_get_submit_time(struct adreno_device *adreno_dev, static void adreno_ringbuffer_wptr(struct adreno_device *adreno_dev, struct adreno_ringbuffer *rb) { struct adreno_gpudev *gpudev = ADRENO_GPU_DEVICE(adreno_dev); unsigned long flags; int ret = 0; Loading @@ -102,6 +103,17 @@ static void adreno_ringbuffer_wptr(struct adreno_device *adreno_dev, */ kgsl_pwrscale_busy(KGSL_DEVICE(adreno_dev)); /* * 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 @@ -110,6 +122,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 @@ -36,6 +36,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 @@ -45,11 +46,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 +16 −1 Original line number Diff line number Diff line /* Copyright (c) 2002,2007-2019, The Linux Foundation. All rights reserved. /* Copyright (c) 2002,2007-2020, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and Loading Loading @@ -89,6 +89,7 @@ static void adreno_get_submit_time(struct adreno_device *adreno_dev, static void adreno_ringbuffer_wptr(struct adreno_device *adreno_dev, struct adreno_ringbuffer *rb) { struct adreno_gpudev *gpudev = ADRENO_GPU_DEVICE(adreno_dev); unsigned long flags; int ret = 0; Loading @@ -102,6 +103,17 @@ static void adreno_ringbuffer_wptr(struct adreno_device *adreno_dev, */ kgsl_pwrscale_busy(KGSL_DEVICE(adreno_dev)); /* * 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 @@ -110,6 +122,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