Commit 3617e579 authored by Bokun Zhang's avatar Bokun Zhang Committed by Alex Deucher
Browse files

drm/amd/amdgpu: Update VCN initizalization behvaior



- Issue:
  In the original vcn3.0 code, it assumes that the VCN's
  init_status is always 1, even after the MMSCH
  updates the header.

  This is incorrect since by default, it should be set to 0,
  and MMSCH will update it to 1 if VCN is ready.

- Fix:
  We need to read back the table header after send it to MMSCH.
  After that, if a VCN instance is not ready (host disabled it),
  we needs to disable the ring buffer as well.

Signed-off-by: default avatarBokun Zhang <Bokun.Zhang@amd.com>
Reviewed-by: default avatarMonk Liu <monk.liu@amd.com>
Signed-off-by: default avatarAlex Deucher <alexander.deucher@amd.com>
parent 6bfbfe8c
Loading
Loading
Loading
Loading
+37 −9
Original line number Diff line number Diff line
@@ -294,17 +294,19 @@ static int vcn_v3_0_hw_init(void *handle)
				continue;

			ring = &adev->vcn.inst[i].ring_dec;
			if (ring->sched.ready) {
				ring->wptr = 0;
				ring->wptr_old = 0;
				vcn_v3_0_dec_ring_set_wptr(ring);
			ring->sched.ready = true;
			}

			for (j = 0; j < adev->vcn.num_enc_rings; ++j) {
				ring = &adev->vcn.inst[i].ring_enc[j];
				if (ring->sched.ready) {
					ring->wptr = 0;
					ring->wptr_old = 0;
					vcn_v3_0_enc_ring_set_wptr(ring);
				ring->sched.ready = true;
				}
			}
		}
	} else {
@@ -1230,6 +1232,8 @@ static int vcn_v3_0_start_sriov(struct amdgpu_device *adev)
	uint32_t table_size;
	uint32_t size, size_dw;

	bool is_vcn_ready;

	struct mmsch_v3_0_cmd_direct_write
		direct_wt = { {0} };
	struct mmsch_v3_0_cmd_direct_read_modify_write
@@ -1367,7 +1371,7 @@ static int vcn_v3_0_start_sriov(struct amdgpu_device *adev)
		MMSCH_V3_0_INSERT_END();

		/* refine header */
		header.inst[i].init_status = 1;
		header.inst[i].init_status = 0;
		header.inst[i].table_offset = header.total_size;
		header.inst[i].table_size = table_size;
		header.total_size += table_size;
@@ -1425,6 +1429,30 @@ static int vcn_v3_0_start_sriov(struct amdgpu_device *adev)
		}
	}

	/* 6, check each VCN's init_status
	 * if it remains as 0, then this VCN is not assigned to current VF
	 * do not start ring for this VCN
	 */
	size = sizeof(struct mmsch_v3_0_init_header);
	table_loc = (uint32_t *)table->cpu_addr;
	memcpy(&header, (void *)table_loc, size);

	for (i = 0; i < adev->vcn.num_vcn_inst; i++) {
		if (adev->vcn.harvest_config & (1 << i))
			continue;

		is_vcn_ready = (header.inst[i].init_status == 1);
		if (!is_vcn_ready)
			DRM_INFO("VCN(%d) engine is disabled by hypervisor\n", i);

		ring = &adev->vcn.inst[i].ring_dec;
		ring->sched.ready = is_vcn_ready;
		for (j = 0; j < adev->vcn.num_enc_rings; ++j) {
			ring = &adev->vcn.inst[i].ring_enc[j];
			ring->sched.ready = is_vcn_ready;
		}
	}

	return 0;
}