Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

drm/amdgpu/vcn4: Fix IB parsing with multiple engine info packages

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>

authored by

David Rosca and committed by
Alex Deucher
dc8f9f0f d426a5b6

+19 -29
+19 -29
drivers/gpu/drm/amd/amdgpu/vcn_v4_0.c
··· 1903 1903 1904 1904 #define RADEON_VCN_ENGINE_TYPE_ENCODE (0x00000002) 1905 1905 #define RADEON_VCN_ENGINE_TYPE_DECODE (0x00000003) 1906 - 1907 1906 #define RADEON_VCN_ENGINE_INFO (0x30000001) 1908 - #define RADEON_VCN_ENGINE_INFO_MAX_OFFSET 16 1909 - 1910 1907 #define RENCODE_ENCODE_STANDARD_AV1 2 1911 1908 #define RENCODE_IB_PARAM_SESSION_INIT 0x00000003 1912 - #define RENCODE_IB_PARAM_SESSION_INIT_MAX_OFFSET 64 1913 1909 1914 - /* return the offset in ib if id is found, -1 otherwise 1915 - * to speed up the searching we only search upto max_offset 1916 - */ 1917 - static int vcn_v4_0_enc_find_ib_param(struct amdgpu_ib *ib, uint32_t id, int max_offset) 1910 + /* return the offset in ib if id is found, -1 otherwise */ 1911 + static int vcn_v4_0_enc_find_ib_param(struct amdgpu_ib *ib, uint32_t id, int start) 1918 1912 { 1919 1913 int i; 1920 1914 1921 - for (i = 0; i < ib->length_dw && i < max_offset && ib->ptr[i] >= 8; i += ib->ptr[i]/4) { 1915 + for (i = start; i < ib->length_dw && ib->ptr[i] >= 8; i += ib->ptr[i] / 4) { 1922 1916 if (ib->ptr[i + 1] == id) 1923 1917 return i; 1924 1918 } ··· 1927 1933 struct amdgpu_vcn_decode_buffer *decode_buffer; 1928 1934 uint64_t addr; 1929 1935 uint32_t val; 1930 - int idx; 1936 + int idx = 0, sidx; 1931 1937 1932 1938 /* The first instance can decode anything */ 1933 1939 if (!ring->me) 1934 1940 return 0; 1935 1941 1936 - /* RADEON_VCN_ENGINE_INFO is at the top of ib block */ 1937 - idx = vcn_v4_0_enc_find_ib_param(ib, RADEON_VCN_ENGINE_INFO, 1938 - RADEON_VCN_ENGINE_INFO_MAX_OFFSET); 1939 - if (idx < 0) /* engine info is missing */ 1940 - return 0; 1942 + while ((idx = vcn_v4_0_enc_find_ib_param(ib, RADEON_VCN_ENGINE_INFO, idx)) >= 0) { 1943 + val = amdgpu_ib_get_value(ib, idx + 2); /* RADEON_VCN_ENGINE_TYPE */ 1944 + if (val == RADEON_VCN_ENGINE_TYPE_DECODE) { 1945 + decode_buffer = (struct amdgpu_vcn_decode_buffer *)&ib->ptr[idx + 6]; 1941 1946 1942 - val = amdgpu_ib_get_value(ib, idx + 2); /* RADEON_VCN_ENGINE_TYPE */ 1943 - if (val == RADEON_VCN_ENGINE_TYPE_DECODE) { 1944 - decode_buffer = (struct amdgpu_vcn_decode_buffer *)&ib->ptr[idx + 6]; 1947 + if (!(decode_buffer->valid_buf_flag & 0x1)) 1948 + return 0; 1945 1949 1946 - if (!(decode_buffer->valid_buf_flag & 0x1)) 1947 - return 0; 1948 - 1949 - addr = ((u64)decode_buffer->msg_buffer_address_hi) << 32 | 1950 - decode_buffer->msg_buffer_address_lo; 1951 - return vcn_v4_0_dec_msg(p, job, addr); 1952 - } else if (val == RADEON_VCN_ENGINE_TYPE_ENCODE) { 1953 - idx = vcn_v4_0_enc_find_ib_param(ib, RENCODE_IB_PARAM_SESSION_INIT, 1954 - RENCODE_IB_PARAM_SESSION_INIT_MAX_OFFSET); 1955 - if (idx >= 0 && ib->ptr[idx + 2] == RENCODE_ENCODE_STANDARD_AV1) 1956 - return vcn_v4_0_limit_sched(p, job); 1950 + addr = ((u64)decode_buffer->msg_buffer_address_hi) << 32 | 1951 + decode_buffer->msg_buffer_address_lo; 1952 + return vcn_v4_0_dec_msg(p, job, addr); 1953 + } else if (val == RADEON_VCN_ENGINE_TYPE_ENCODE) { 1954 + sidx = vcn_v4_0_enc_find_ib_param(ib, RENCODE_IB_PARAM_SESSION_INIT, idx); 1955 + if (sidx >= 0 && ib->ptr[sidx + 2] == RENCODE_ENCODE_STANDARD_AV1) 1956 + return vcn_v4_0_limit_sched(p, job); 1957 + } 1958 + idx += ib->ptr[idx] / 4; 1957 1959 } 1958 1960 return 0; 1959 1961 }