From: Rob Clark Date: Tue, 26 May 2026 14:50:42 +0000 (-0700) Subject: drm/msm/a6xx: Add yield & flush helper X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=90f2b0461b0cf41b1553d9ec51fba0d6bb1695b2;p=thirdparty%2Flinux.git drm/msm/a6xx: Add yield & flush helper It's a common pattern, needing to insert a yield packet before flushing the rb. And we'll need this once again for configuring perfcntr SEL regs. So add a helper. Signed-off-by: Rob Clark Reviewed-by: Dmitry Baryshkov Reviewed-by: Anna Maniscalco Reviewed-by: Akhil P Oommen Patchwork: https://patchwork.freedesktop.org/patch/728208/ Message-ID: <20260526145137.160554-9-robin.clark@oss.qualcomm.com> --- diff --git a/drivers/gpu/drm/msm/adreno/a6xx_gpu.c b/drivers/gpu/drm/msm/adreno/a6xx_gpu.c index d24601cb162d1..e1ada0ebbe1a0 100644 --- a/drivers/gpu/drm/msm/adreno/a6xx_gpu.c +++ b/drivers/gpu/drm/msm/adreno/a6xx_gpu.c @@ -189,6 +189,30 @@ void a6xx_flush(struct msm_gpu *gpu, struct msm_ringbuffer *ring) spin_unlock_irqrestore(&ring->preempt_lock, flags); } +void +a6xx_flush_yield(struct msm_gpu *gpu, struct msm_ringbuffer *ring) +{ + /* If preemption is enabled */ + if (gpu->nr_rings > 1) { + /* Yield the floor on command completion */ + OUT_PKT7(ring, CP_CONTEXT_SWITCH_YIELD, 4); + + /* + * If dword[2:1] are non zero, they specify an address for + * the CP to write the value of dword[3] to on preemption + * complete. Write 0 to skip the write + */ + OUT_RING(ring, 0x00); + OUT_RING(ring, 0x00); + /* Data value - not used if the address above is 0 */ + OUT_RING(ring, 0x01); + /* generate interrupt on preemption completion */ + OUT_RING(ring, 0x00); + } + + a6xx_flush(gpu, ring); +} + static void get_stats_counter(struct msm_ringbuffer *ring, u32 counter, u64 iova) { @@ -597,28 +621,9 @@ static void a7xx_submit(struct msm_gpu *gpu, struct msm_gem_submit *submit) OUT_PKT7(ring, CP_SET_MARKER, 1); OUT_RING(ring, 0x100); /* IFPC enable */ - /* If preemption is enabled */ - if (gpu->nr_rings > 1) { - /* Yield the floor on command completion */ - OUT_PKT7(ring, CP_CONTEXT_SWITCH_YIELD, 4); - - /* - * If dword[2:1] are non zero, they specify an address for - * the CP to write the value of dword[3] to on preemption - * complete. Write 0 to skip the write - */ - OUT_RING(ring, 0x00); - OUT_RING(ring, 0x00); - /* Data value - not used if the address above is 0 */ - OUT_RING(ring, 0x01); - /* generate interrupt on preemption completion */ - OUT_RING(ring, 0x00); - } - - trace_msm_gpu_submit_flush(submit, adreno_gpu->funcs->get_timestamp(gpu)); - a6xx_flush(gpu, ring); + a6xx_flush_yield(gpu, ring); /* Check to see if we need to start preemption */ if (adreno_is_a8xx(adreno_gpu)) @@ -881,15 +886,7 @@ static int a7xx_preempt_start(struct msm_gpu *gpu) a6xx_emit_set_pseudo_reg(ring, a6xx_gpu, NULL); - /* Yield the floor on command completion */ - OUT_PKT7(ring, CP_CONTEXT_SWITCH_YIELD, 4); - OUT_RING(ring, 0x00); - OUT_RING(ring, 0x00); - OUT_RING(ring, 0x00); - /* Generate interrupt on preemption completion */ - OUT_RING(ring, 0x00); - - a6xx_flush(gpu, ring); + a6xx_flush_yield(gpu, ring); return a6xx_idle(gpu, ring) ? 0 : -EINVAL; } diff --git a/drivers/gpu/drm/msm/adreno/a6xx_gpu.h b/drivers/gpu/drm/msm/adreno/a6xx_gpu.h index eb431e5e00b1a..99c3e55f5ca8f 100644 --- a/drivers/gpu/drm/msm/adreno/a6xx_gpu.h +++ b/drivers/gpu/drm/msm/adreno/a6xx_gpu.h @@ -317,6 +317,7 @@ void a6xx_bus_clear_pending_transactions(struct adreno_gpu *adreno_gpu, bool gx_ void a6xx_gpu_sw_reset(struct msm_gpu *gpu, bool assert); int a6xx_fenced_write(struct a6xx_gpu *gpu, u32 offset, u64 value, u32 mask, bool is_64b); void a6xx_flush(struct msm_gpu *gpu, struct msm_ringbuffer *ring); +void a6xx_flush_yield(struct msm_gpu *gpu, struct msm_ringbuffer *ring); int a6xx_zap_shader_init(struct msm_gpu *gpu); void a8xx_bus_clear_pending_transactions(struct adreno_gpu *adreno_gpu, bool gx_off); diff --git a/drivers/gpu/drm/msm/adreno/a8xx_gpu.c b/drivers/gpu/drm/msm/adreno/a8xx_gpu.c index 9cf307cf9fdad..f29cd6e1fde06 100644 --- a/drivers/gpu/drm/msm/adreno/a8xx_gpu.c +++ b/drivers/gpu/drm/msm/adreno/a8xx_gpu.c @@ -484,15 +484,7 @@ static int a8xx_preempt_start(struct msm_gpu *gpu) a6xx_emit_set_pseudo_reg(ring, a6xx_gpu, NULL); - /* Yield the floor on command completion */ - OUT_PKT7(ring, CP_CONTEXT_SWITCH_YIELD, 4); - OUT_RING(ring, 0x00); - OUT_RING(ring, 0x00); - OUT_RING(ring, 0x00); - /* Generate interrupt on preemption completion */ - OUT_RING(ring, 0x00); - - a6xx_flush(gpu, ring); + a6xx_flush_yield(gpu, ring); return a8xx_idle(gpu, ring) ? 0 : -EINVAL; }