From: Sonny Jiang <[email protected]>

JPEG 5_0_2 has 2 instances per die. Each instance has 10 rings.
Each ring consuming a unique VM invalidation engine exhausts the
available engines per MMHUB.

All rings within a JPEG instance can safely share one engine since
MMHUB serializes concurrent invalidation requests via hardware
semaphore (see "drm/amdgpu: add invalidate semaphore support for
gmc v12.1").

Signed-off-by: Sonny Jiang <[email protected]>
Acked-by: Leo Liu <[email protected]>
---
 drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.c  |  9 +++++-
 drivers/gpu/drm/amd/amdgpu/amdgpu_jpeg.c | 38 ++++++++++++++++++++++++
 drivers/gpu/drm/amd/amdgpu/amdgpu_jpeg.h |  2 ++
 3 files changed, 48 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.c 
b/drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.c
index 3dc8faa091d7..2f6d20c00ce2 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.c
@@ -672,7 +672,8 @@ int amdgpu_gmc_allocate_vm_inv_eng(struct amdgpu_device 
*adev)
                        continue;
 
                /* Skip if the ring is a shared ring */
-               if (amdgpu_sdma_is_shared_inv_eng(adev, ring))
+               if (amdgpu_sdma_is_shared_inv_eng(adev, ring) ||
+                   amdgpu_jpeg_is_shared_inv_eng(adev, ring))
                        continue;
 
                inv_eng = ffs(vm_inv_engs[vmhub]);
@@ -702,6 +703,12 @@ int amdgpu_gmc_allocate_vm_inv_eng(struct amdgpu_device 
*adev)
                                        ring->name, ring->vm_inv_eng, 
shared_ring->name, ring->vm_hub);
                        continue;
                }
+
+               /* All decode rings within one JPEG instance share one VM
+                * invalidation engine (no-op unless ring is a JPEG instance's
+                * first ring).
+                */
+               amdgpu_jpeg_set_shared_inv_eng(adev, ring);
        }
 
        return 0;
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_jpeg.c 
b/drivers/gpu/drm/amd/amdgpu/amdgpu_jpeg.c
index 363b99168478..208566ffe898 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_jpeg.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_jpeg.c
@@ -607,3 +607,41 @@ int amdgpu_jpeg_dec_parse_cs(struct amdgpu_cs_parser 
*parser,
 
        return 0;
 }
+
+/**
+ * amdgpu_jpeg_is_shared_inv_eng - Check if a ring is a JPEG ring that shares 
a VM invalidation
+ * engine
+ * @adev: Pointer to the AMDGPU device structure
+ * @ring: Pointer to the ring structure to check
+ *
+ * All decode rings within one JPEG instance share a single VM invalidation
+ * engine (see amdgpu_jpeg_set_shared_inv_eng()). This returns true for every
+ * ring in the instance except the first (ring->pipe == 0), which owns the
+ * engine allocated by amdgpu_gmc_allocate_vm_inv_eng().
+ */
+bool amdgpu_jpeg_is_shared_inv_eng(struct amdgpu_device *adev, struct 
amdgpu_ring *ring)
+{
+       return ring->funcs->type == AMDGPU_RING_TYPE_VCN_JPEG && ring->pipe != 
0;
+}
+
+/**
+ * amdgpu_jpeg_set_shared_inv_eng - Propagate a VM invalidation engine to the 
rest of a JPEG
+ * instance
+ * @adev: Pointer to the AMDGPU device structure
+ * @ring: Pointer to the ring that just had a VM invalidation engine allocated
+ *
+ * No-op unless @ring is the owner (ring->pipe == 0) of a JPEG instance.
+ * When it is, mirrors its freshly allocated vm_inv_eng onto the rest of the
+ * rings in that instance, so the whole instance shares one engine instead of
+ * consuming one per ring.
+ */
+void amdgpu_jpeg_set_shared_inv_eng(struct amdgpu_device *adev, struct 
amdgpu_ring *ring)
+{
+       int j;
+
+       if (ring->funcs->type != AMDGPU_RING_TYPE_VCN_JPEG || ring->pipe != 0)
+               return;
+
+       for (j = 1; j < adev->jpeg.num_jpeg_rings; j++)
+               adev->jpeg.inst[ring->me].ring_dec[j].vm_inv_eng = 
ring->vm_inv_eng;
+}
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_jpeg.h 
b/drivers/gpu/drm/amd/amdgpu/amdgpu_jpeg.h
index fe95d9188713..05d58e6bbfab 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_jpeg.h
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_jpeg.h
@@ -183,5 +183,7 @@ void amdgpu_jpeg_print_ip_state(struct amdgpu_ip_block 
*ip_block, struct drm_pri
 int amdgpu_jpeg_dec_parse_cs(struct amdgpu_cs_parser *parser,
                             struct amdgpu_job *job,
                             struct amdgpu_ib *ib);
+bool amdgpu_jpeg_is_shared_inv_eng(struct amdgpu_device *adev, struct 
amdgpu_ring *ring);
+void amdgpu_jpeg_set_shared_inv_eng(struct amdgpu_device *adev, struct 
amdgpu_ring *ring);
 
 #endif /*__AMDGPU_JPEG_H__*/
-- 
2.43.0

Reply via email to