]> git.ipfire.org Git - thirdparty/kernel/stable.git/commitdiff
drm/amdgpu/vcn4: Fix IB parsing with multiple engine info packages
authorDavid Rosca <david.rosca@amd.com>
Mon, 18 Aug 2025 07:06:58 +0000 (09:06 +0200)
committerAlex Deucher <alexander.deucher@amd.com>
Tue, 9 Sep 2025 20:41:49 +0000 (16:41 -0400)
There can be multiple engine info packages in one IB and the first one
may be common engine, not decode/encode.
We need to parse the entire IB instead of stopping after finding first
engine info.

Signed-off-by: David Rosca <david.rosca@amd.com>
Reviewed-by: Leo Liu <leo.liu@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
(cherry picked from commit dc8f9f0f45166a6b37864e7a031c726981d6e5fc)
Cc: stable@vger.kernel.org
drivers/gpu/drm/amd/amdgpu/vcn_v4_0.c

index 1924e075b66f4173be08fdad3f5974b757e8bc67..311fb595bd693066833f1a6499a53675f3587bb9 100644 (file)
@@ -1907,22 +1907,16 @@ out:
 
 #define RADEON_VCN_ENGINE_TYPE_ENCODE                  (0x00000002)
 #define RADEON_VCN_ENGINE_TYPE_DECODE                  (0x00000003)
-
 #define RADEON_VCN_ENGINE_INFO                         (0x30000001)
-#define RADEON_VCN_ENGINE_INFO_MAX_OFFSET              16
-
 #define RENCODE_ENCODE_STANDARD_AV1                    2
 #define RENCODE_IB_PARAM_SESSION_INIT                  0x00000003
-#define RENCODE_IB_PARAM_SESSION_INIT_MAX_OFFSET       64
 
-/* return the offset in ib if id is found, -1 otherwise
- * to speed up the searching we only search upto max_offset
- */
-static int vcn_v4_0_enc_find_ib_param(struct amdgpu_ib *ib, uint32_t id, int max_offset)
+/* return the offset in ib if id is found, -1 otherwise */
+static int vcn_v4_0_enc_find_ib_param(struct amdgpu_ib *ib, uint32_t id, int start)
 {
        int i;
 
-       for (i = 0; i < ib->length_dw && i < max_offset && ib->ptr[i] >= 8; i += ib->ptr[i]/4) {
+       for (i = start; i < ib->length_dw && ib->ptr[i] >= 8; i += ib->ptr[i] / 4) {
                if (ib->ptr[i + 1] == id)
                        return i;
        }
@@ -1937,33 +1931,29 @@ static int vcn_v4_0_ring_patch_cs_in_place(struct amdgpu_cs_parser *p,
        struct amdgpu_vcn_decode_buffer *decode_buffer;
        uint64_t addr;
        uint32_t val;
-       int idx;
+       int idx = 0, sidx;
 
        /* The first instance can decode anything */
        if (!ring->me)
                return 0;
 
-       /* RADEON_VCN_ENGINE_INFO is at the top of ib block */
-       idx = vcn_v4_0_enc_find_ib_param(ib, RADEON_VCN_ENGINE_INFO,
-                       RADEON_VCN_ENGINE_INFO_MAX_OFFSET);
-       if (idx < 0) /* engine info is missing */
-               return 0;
-
-       val = amdgpu_ib_get_value(ib, idx + 2); /* RADEON_VCN_ENGINE_TYPE */
-       if (val == RADEON_VCN_ENGINE_TYPE_DECODE) {
-               decode_buffer = (struct amdgpu_vcn_decode_buffer *)&ib->ptr[idx + 6];
-
-               if (!(decode_buffer->valid_buf_flag  & 0x1))
-                       return 0;
-
-               addr = ((u64)decode_buffer->msg_buffer_address_hi) << 32 |
-                       decode_buffer->msg_buffer_address_lo;
-               return vcn_v4_0_dec_msg(p, job, addr);
-       } else if (val == RADEON_VCN_ENGINE_TYPE_ENCODE) {
-               idx = vcn_v4_0_enc_find_ib_param(ib, RENCODE_IB_PARAM_SESSION_INIT,
-                       RENCODE_IB_PARAM_SESSION_INIT_MAX_OFFSET);
-               if (idx >= 0 && ib->ptr[idx + 2] == RENCODE_ENCODE_STANDARD_AV1)
-                       return vcn_v4_0_limit_sched(p, job);
+       while ((idx = vcn_v4_0_enc_find_ib_param(ib, RADEON_VCN_ENGINE_INFO, idx)) >= 0) {
+               val = amdgpu_ib_get_value(ib, idx + 2); /* RADEON_VCN_ENGINE_TYPE */
+               if (val == RADEON_VCN_ENGINE_TYPE_DECODE) {
+                       decode_buffer = (struct amdgpu_vcn_decode_buffer *)&ib->ptr[idx + 6];
+
+                       if (!(decode_buffer->valid_buf_flag & 0x1))
+                               return 0;
+
+                       addr = ((u64)decode_buffer->msg_buffer_address_hi) << 32 |
+                               decode_buffer->msg_buffer_address_lo;
+                       return vcn_v4_0_dec_msg(p, job, addr);
+               } else if (val == RADEON_VCN_ENGINE_TYPE_ENCODE) {
+                       sidx = vcn_v4_0_enc_find_ib_param(ib, RENCODE_IB_PARAM_SESSION_INIT, idx);
+                       if (sidx >= 0 && ib->ptr[sidx + 2] == RENCODE_ENCODE_STANDARD_AV1)
+                               return vcn_v4_0_limit_sched(p, job);
+               }
+               idx += ib->ptr[idx] / 4;
        }
        return 0;
 }