Commit f823323b authored by David (Ming Qiang) Wu's avatar David (Ming Qiang) Wu Committed by Alex Deucher
Browse files

drm/amdgpu: limit AV1 to the first instance on VCN4 encode



AV1 is only supported on the first instance.
Added vcn_v4_0_enc_find_ib_param() to help search for an IB param.

Signed-off-by: default avatarDavid (Ming Qiang) Wu <David.Wu3@amd.com>
Reviewed-by: default avatarRuijing Dong <ruijing.dong@amd.com>
Signed-off-by: default avatarAlex Deucher <alexander.deucher@amd.com>
parent ae284577
Loading
Loading
Loading
Loading
+46 −16
Original line number Diff line number Diff line
@@ -1710,7 +1710,7 @@ static int vcn_v4_0_dec_msg(struct amdgpu_cs_parser *p, struct amdgpu_job *job,

		create = ptr + addr + offset - start;

		/* H246, HEVC and VP9 can run on any instance */
		/* H264, HEVC and VP9 can run on any instance */
		if (create[0] == 0x7 || create[0] == 0x10 || create[0] == 0x11)
			continue;

@@ -1724,8 +1724,30 @@ static int vcn_v4_0_dec_msg(struct amdgpu_cs_parser *p, struct amdgpu_job *job,
	return r;
}

#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)
{
	int i;

	for (i = 0; i < ib->length_dw && i < max_offset && ib->ptr[i] >= 8; i += ib->ptr[i]/4) {
		if (ib->ptr[i + 1] == id)
			return i;
	}
	return -1;
}

static int vcn_v4_0_ring_patch_cs_in_place(struct amdgpu_cs_parser *p,
					   struct amdgpu_job *job,
					   struct amdgpu_ib *ib)
@@ -1734,20 +1756,21 @@ 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;

	/* The first instance can decode anything */
	if (!ring->me)
		return 0;

	/* unified queue ib header has 8 double words. */
	if (ib->length_dw < 8)
		return 0;

	val = amdgpu_ib_get_value(ib, 6); //RADEON_VCN_ENGINE_TYPE
	if (val != RADEON_VCN_ENGINE_TYPE_DECODE)
	/* 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;

	decode_buffer = (struct amdgpu_vcn_decode_buffer *)&ib->ptr[10];
	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;
@@ -1755,6 +1778,13 @@ static int vcn_v4_0_ring_patch_cs_in_place(struct amdgpu_cs_parser *p,
		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);
	}
	return 0;
}

static const struct amdgpu_ring_funcs vcn_v4_0_unified_ring_vm_funcs = {