On GFX6, the compute rings use the same CP path as
the graphics ring. The only difference is that they
don't support draw commands. (As opposed to GFX7 and
newer which have a separate command parser that is
called MEC for compute queues.)

This means that we have to take into consideration
that the PFP also exists on compute queues on GFX6:

Use PFP for register writes on both graphics and
compute queues.

In the pipeline sync, use the PFP to wait for the
previous fence (and not the ME) to prevent the PFP
from starting to execute the next submission while
the ME is still in the previous submission.

In the VM flush, writing the TLB flush registers
is now done by the PFP. Synchronize PFP to ME before
doing the TLB flush to make sure the ME isn't using the
VMID being flushed. Then the register is read by the
PFP now so there is no need to sync with ME afterwards.

Fixes: 2cd46ad22383 ("drm/amdgpu: add graphic pipeline implementation for si 
v8")
Signed-off-by: Timur Kristóf <[email protected]>
---
 drivers/gpu/drm/amd/amdgpu/gfx_v6_0.c | 22 ++++++++--------------
 1 file changed, 8 insertions(+), 14 deletions(-)

diff --git a/drivers/gpu/drm/amd/amdgpu/gfx_v6_0.c 
b/drivers/gpu/drm/amd/amdgpu/gfx_v6_0.c
index 1a9866e40912..8e8e5fe487f5 100644
--- a/drivers/gpu/drm/amd/amdgpu/gfx_v6_0.c
+++ b/drivers/gpu/drm/amd/amdgpu/gfx_v6_0.c
@@ -2347,14 +2347,13 @@ static int gfx_v6_0_cp_resume(struct amdgpu_device 
*adev)
 
 static void gfx_v6_0_ring_emit_pipeline_sync(struct amdgpu_ring *ring)
 {
-       int usepfp = (ring->funcs->type == AMDGPU_RING_TYPE_GFX);
        uint32_t seq = ring->fence_drv.sync_seq;
        uint64_t addr = ring->fence_drv.gpu_addr;
 
        amdgpu_ring_write(ring, PACKET3(PACKET3_WAIT_REG_MEM, 5));
        amdgpu_ring_write(ring, (WAIT_REG_MEM_MEM_SPACE(1) | /* memory */
                                 WAIT_REG_MEM_FUNCTION(3) | /* equal */
-                                WAIT_REG_MEM_ENGINE(usepfp)));   /* pfp or me 
*/
+                                WAIT_REG_MEM_ENGINE(1))); /* pfp */
        amdgpu_ring_write(ring, addr & 0xfffffffc);
        amdgpu_ring_write(ring, upper_32_bits(addr) & 0xffffffff);
        amdgpu_ring_write(ring, seq);
@@ -2365,34 +2364,29 @@ static void gfx_v6_0_ring_emit_pipeline_sync(struct 
amdgpu_ring *ring)
 static void gfx_v6_0_ring_emit_vm_flush(struct amdgpu_ring *ring,
                                        unsigned vmid, uint64_t pd_addr)
 {
-       int usepfp = (ring->funcs->type == AMDGPU_RING_TYPE_GFX);
+       /* sync PFP to ME, otherwise ME might still use the VMID when we flush 
it */
+       amdgpu_ring_write(ring, PACKET3(PACKET3_PFP_SYNC_ME, 0));
+       amdgpu_ring_write(ring, 0x0);
 
+       /* Write VM_CONTEXT0_PAGE_TABLE_BASE_ADDR and VM_INVALIDATE_REQUEST 
using PFP */
        amdgpu_gmc_emit_flush_gpu_tlb(ring, vmid, pd_addr);
 
        /* wait for the invalidate to complete */
        amdgpu_ring_write(ring, PACKET3(PACKET3_WAIT_REG_MEM, 5));
        amdgpu_ring_write(ring, (WAIT_REG_MEM_FUNCTION(0) |  /* always */
-                                WAIT_REG_MEM_ENGINE(0))); /* me */
+                                WAIT_REG_MEM_ENGINE(1))); /* pfp */
        amdgpu_ring_write(ring, mmVM_INVALIDATE_REQUEST);
        amdgpu_ring_write(ring, 0);
        amdgpu_ring_write(ring, 0); /* ref */
        amdgpu_ring_write(ring, 0); /* mask */
        amdgpu_ring_write(ring, 0x20); /* poll interval */
-
-       if (usepfp) {
-               /* sync PFP to ME, otherwise we might get invalid PFP reads */
-               amdgpu_ring_write(ring, PACKET3(PACKET3_PFP_SYNC_ME, 0));
-               amdgpu_ring_write(ring, 0x0);
-       }
 }
 
 static void gfx_v6_0_ring_emit_wreg(struct amdgpu_ring *ring,
                                    uint32_t reg, uint32_t val)
 {
-       int usepfp = (ring->funcs->type == AMDGPU_RING_TYPE_GFX);
-
        amdgpu_ring_write(ring, PACKET3(PACKET3_WRITE_DATA, 3));
-       amdgpu_ring_write(ring, (WRITE_DATA_ENGINE_SEL(usepfp) |
+       amdgpu_ring_write(ring, (WRITE_DATA_ENGINE_SEL(1) | /* pfp */
                                 WRITE_DATA_DST_SEL(0)));
        amdgpu_ring_write(ring, reg);
        amdgpu_ring_write(ring, 0);
@@ -3556,7 +3550,7 @@ static const struct amdgpu_ring_funcs 
gfx_v6_0_ring_funcs_compute = {
        .emit_frame_size =
                5 + 5 + /* hdp flush / invalidate */
                7 + /* gfx_v6_0_ring_emit_pipeline_sync */
-               SI_FLUSH_GPU_TLB_NUM_WREG * 5 + 7 + /* 
gfx_v6_0_ring_emit_vm_flush */
+               SI_FLUSH_GPU_TLB_NUM_WREG * 5 + 7 + 2 + /* 
gfx_v6_0_ring_emit_vm_flush */
                14 + 14 + 14 + /* gfx_v6_0_ring_emit_fence x3 for user fence, 
vm fence */
                3 * 2 + /* gfx_v6_0_ring_emit_sb x3 (from amdgpu_vm_flush, 
amdgpu_ib_schedule) */
                5, /* SURFACE_SYNC */
-- 
2.55.0

Reply via email to