mirror of
https://github.com/torvalds/linux.git
synced 2026-05-24 07:03:03 +02:00
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: Bokun Zhang <Bokun.Zhang@amd.com> Reviewed-by: Monk Liu <monk.liu@amd.com> Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
This commit is contained in:
parent
6bfbfe8c45
commit
3617e579eb
|
|
@ -294,17 +294,19 @@ static int vcn_v3_0_hw_init(void *handle)
|
|||
continue;
|
||||
|
||||
ring = &adev->vcn.inst[i].ring_dec;
|
||||
ring->wptr = 0;
|
||||
ring->wptr_old = 0;
|
||||
vcn_v3_0_dec_ring_set_wptr(ring);
|
||||
ring->sched.ready = true;
|
||||
if (ring->sched.ready) {
|
||||
ring->wptr = 0;
|
||||
ring->wptr_old = 0;
|
||||
vcn_v3_0_dec_ring_set_wptr(ring);
|
||||
}
|
||||
|
||||
for (j = 0; j < adev->vcn.num_enc_rings; ++j) {
|
||||
ring = &adev->vcn.inst[i].ring_enc[j];
|
||||
ring->wptr = 0;
|
||||
ring->wptr_old = 0;
|
||||
vcn_v3_0_enc_ring_set_wptr(ring);
|
||||
ring->sched.ready = true;
|
||||
if (ring->sched.ready) {
|
||||
ring->wptr = 0;
|
||||
ring->wptr_old = 0;
|
||||
vcn_v3_0_enc_ring_set_wptr(ring);
|
||||
}
|
||||
}
|
||||
}
|
||||
} 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;
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user