diff options
| author | David Rosca <david.rosca@amd.com> | 2025-08-18 09:06:58 +0200 | 
|---|---|---|
| committer | Alex Deucher <alexander.deucher@amd.com> | 2025-09-09 16:18:22 -0400 | 
| commit | dc8f9f0f45166a6b37864e7a031c726981d6e5fc (patch) | |
| tree | b0b8cd6521ebcd22b22376c70edbb8d2edd597ca /drivers/gpu/drm/amd/amdgpu | |
| parent | d426a5b6da2bba04566acfad94b6921141a2bf85 (diff) | |
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>
Diffstat (limited to 'drivers/gpu/drm/amd/amdgpu')
| -rw-r--r-- | drivers/gpu/drm/amd/amdgpu/vcn_v4_0.c | 52 | 
1 files changed, 21 insertions, 31 deletions
| diff --git a/drivers/gpu/drm/amd/amdgpu/vcn_v4_0.c b/drivers/gpu/drm/amd/amdgpu/vcn_v4_0.c index d0d27790b73b..8d20ae5bdb86 100644 --- a/drivers/gpu/drm/amd/amdgpu/vcn_v4_0.c +++ b/drivers/gpu/drm/amd/amdgpu/vcn_v4_0.c @@ -1903,22 +1903,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;  	} @@ -1933,33 +1927,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;  } | 
