]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
drm/msm/a6xx: Add yield & flush helper
authorRob Clark <robin.clark@oss.qualcomm.com>
Tue, 26 May 2026 14:50:42 +0000 (07:50 -0700)
committerRob Clark <robin.clark@oss.qualcomm.com>
Fri, 29 May 2026 14:07:28 +0000 (07:07 -0700)
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 <robin.clark@oss.qualcomm.com>
Reviewed-by: Dmitry Baryshkov <dmitry.baryshkov@oss.qualcomm.com>
Reviewed-by: Anna Maniscalco <anna.maniscalco2000@gmail.com>
Reviewed-by: Akhil P Oommen <akhilpo@oss.qualcomm.com>
Patchwork: https://patchwork.freedesktop.org/patch/728208/
Message-ID: <20260526145137.160554-9-robin.clark@oss.qualcomm.com>

drivers/gpu/drm/msm/adreno/a6xx_gpu.c
drivers/gpu/drm/msm/adreno/a6xx_gpu.h
drivers/gpu/drm/msm/adreno/a8xx_gpu.c

index d24601cb162d1b746c4885ae9a928b7cc1ed06e3..e1ada0ebbe1a00c249e2bc9ad8f413b85cdfe2ad 100644 (file)
@@ -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;
 }
index eb431e5e00b1af21bb50fbdc70959d4d97acad4b..99c3e55f5ca8fcc73cbef065f391d5bb73c9c8ee 100644 (file)
@@ -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);
index 9cf307cf9fdadde9a1d70de7b52c39c9f2f07d02..f29cd6e1fde06c5d9fb784bbc1671d4ff13c6b59 100644 (file)
@@ -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;
 }