summaryrefslogtreecommitdiff
path: root/drivers/gpu/drm/amd/amdgpu/vcn_v4_0.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gpu/drm/amd/amdgpu/vcn_v4_0.c')
-rw-r--r--drivers/gpu/drm/amd/amdgpu/vcn_v4_0.c80
1 files changed, 59 insertions, 21 deletions
diff --git a/drivers/gpu/drm/amd/amdgpu/vcn_v4_0.c b/drivers/gpu/drm/amd/amdgpu/vcn_v4_0.c
index 29164289c5f3..48bfcd0d558b 100644
--- a/drivers/gpu/drm/amd/amdgpu/vcn_v4_0.c
+++ b/drivers/gpu/drm/amd/amdgpu/vcn_v4_0.c
@@ -169,15 +169,13 @@ static int vcn_v4_0_sw_init(void *handle)
fw_shared->smu_dpm_interface.smu_interface_type = (adev->flags & AMD_IS_APU) ?
AMDGPU_VCN_SMU_DPM_INTERFACE_APU : AMDGPU_VCN_SMU_DPM_INTERFACE_DGPU;
- if (adev->ip_versions[VCN_HWIP][0] == IP_VERSION(4, 0, 2)) {
+ if (amdgpu_ip_version(adev, VCN_HWIP, 0) ==
+ IP_VERSION(4, 0, 2)) {
fw_shared->present_flag_0 |= AMDGPU_FW_SHARED_FLAG_0_DRM_KEY_INJECT;
fw_shared->drm_key_wa.method =
AMDGPU_DRM_KEY_INJECT_WORKAROUND_VCNFW_ASD_HANDSHAKING;
}
- if (amdgpu_sriov_vf(adev))
- fw_shared->present_flag_0 |= cpu_to_le32(AMDGPU_VCN_VF_RB_SETUP_FLAG);
-
if (amdgpu_vcnfw_log)
amdgpu_vcn_fwlog_init(&adev->vcn.inst[i]);
}
@@ -876,8 +874,6 @@ static void vcn_v4_0_enable_clock_gating(struct amdgpu_device *adev, int inst)
| UVD_SUVD_CGC_CTRL__IME_MODE_MASK
| UVD_SUVD_CGC_CTRL__SITE_MODE_MASK);
WREG32_SOC15(VCN, inst, regUVD_SUVD_CGC_CTRL, data);
-
- return;
}
static void vcn_v4_0_enable_ras(struct amdgpu_device *adev, int inst_idx,
@@ -1210,6 +1206,24 @@ static int vcn_v4_0_start(struct amdgpu_device *adev)
return 0;
}
+static int vcn_v4_0_init_ring_metadata(struct amdgpu_device *adev, uint32_t vcn_inst, struct amdgpu_ring *ring_enc)
+{
+ struct amdgpu_vcn_rb_metadata *rb_metadata = NULL;
+ uint8_t *rb_ptr = (uint8_t *)ring_enc->ring;
+
+ rb_ptr += ring_enc->ring_size;
+ rb_metadata = (struct amdgpu_vcn_rb_metadata *)rb_ptr;
+
+ memset(rb_metadata, 0, sizeof(struct amdgpu_vcn_rb_metadata));
+ rb_metadata->size = sizeof(struct amdgpu_vcn_rb_metadata);
+ rb_metadata->present_flag_0 |= cpu_to_le32(AMDGPU_VCN_VF_RB_SETUP_FLAG);
+ rb_metadata->present_flag_0 |= cpu_to_le32(AMDGPU_VCN_VF_RB_DECOUPLE_FLAG);
+ rb_metadata->version = 1;
+ rb_metadata->ring_id = vcn_inst & 0xFF;
+
+ return 0;
+}
+
static int vcn_v4_0_start_sriov(struct amdgpu_device *adev)
{
int i;
@@ -1332,11 +1346,30 @@ static int vcn_v4_0_start_sriov(struct amdgpu_device *adev)
rb_enc_addr = ring_enc->gpu_addr;
rb_setup->is_rb_enabled_flags |= RB_ENABLED;
- rb_setup->rb_addr_lo = lower_32_bits(rb_enc_addr);
- rb_setup->rb_addr_hi = upper_32_bits(rb_enc_addr);
- rb_setup->rb_size = ring_enc->ring_size / 4;
fw_shared->present_flag_0 |= cpu_to_le32(AMDGPU_VCN_VF_RB_SETUP_FLAG);
+ if (amdgpu_sriov_is_vcn_rb_decouple(adev)) {
+ vcn_v4_0_init_ring_metadata(adev, i, ring_enc);
+
+ memset((void *)&rb_setup->rb_info, 0, sizeof(struct amdgpu_vcn_rb_setup_info) * MAX_NUM_VCN_RB_SETUP);
+ if (!(adev->vcn.harvest_config & (1 << 0))) {
+ rb_setup->rb_info[0].rb_addr_lo = lower_32_bits(adev->vcn.inst[0].ring_enc[0].gpu_addr);
+ rb_setup->rb_info[0].rb_addr_hi = upper_32_bits(adev->vcn.inst[0].ring_enc[0].gpu_addr);
+ rb_setup->rb_info[0].rb_size = adev->vcn.inst[0].ring_enc[0].ring_size / 4;
+ }
+ if (!(adev->vcn.harvest_config & (1 << 1))) {
+ rb_setup->rb_info[2].rb_addr_lo = lower_32_bits(adev->vcn.inst[1].ring_enc[0].gpu_addr);
+ rb_setup->rb_info[2].rb_addr_hi = upper_32_bits(adev->vcn.inst[1].ring_enc[0].gpu_addr);
+ rb_setup->rb_info[2].rb_size = adev->vcn.inst[1].ring_enc[0].ring_size / 4;
+ }
+ fw_shared->decouple.is_enabled = 1;
+ fw_shared->present_flag_0 |= cpu_to_le32(AMDGPU_VCN_VF_RB_DECOUPLE_FLAG);
+ } else {
+ rb_setup->rb_addr_lo = lower_32_bits(rb_enc_addr);
+ rb_setup->rb_addr_hi = upper_32_bits(rb_enc_addr);
+ rb_setup->rb_size = ring_enc->ring_size / 4;
+ }
+
MMSCH_V4_0_INSERT_DIRECT_WT(SOC15_REG_OFFSET(VCN, i,
regUVD_LMI_VCPU_NC0_64BIT_BAR_LOW),
lower_32_bits(adev->vcn.inst[i].fw_shared.gpu_addr));
@@ -1808,6 +1841,7 @@ static struct amdgpu_ring_funcs vcn_v4_0_unified_ring_vm_funcs = {
.type = AMDGPU_RING_TYPE_VCN_ENC,
.align_mask = 0x3f,
.nop = VCN_ENC_CMD_NO_OP,
+ .extra_dw = sizeof(struct amdgpu_vcn_rb_metadata),
.get_rptr = vcn_v4_0_unified_ring_get_rptr,
.get_wptr = vcn_v4_0_unified_ring_get_wptr,
.set_wptr = vcn_v4_0_unified_ring_set_wptr,
@@ -1849,7 +1883,7 @@ static void vcn_v4_0_set_unified_ring_funcs(struct amdgpu_device *adev)
if (adev->vcn.harvest_config & (1 << i))
continue;
- if (adev->ip_versions[VCN_HWIP][0] == IP_VERSION(4, 0, 2))
+ if (amdgpu_ip_version(adev, VCN_HWIP, 0) == IP_VERSION(4, 0, 2))
vcn_v4_0_unified_ring_vm_funcs.secure_submission_supported = true;
adev->vcn.inst[i].ring_enc[0].funcs =
@@ -2021,16 +2055,20 @@ static int vcn_v4_0_process_interrupt(struct amdgpu_device *adev, struct amdgpu_
{
uint32_t ip_instance;
- switch (entry->client_id) {
- case SOC15_IH_CLIENTID_VCN:
- ip_instance = 0;
- break;
- case SOC15_IH_CLIENTID_VCN1:
- ip_instance = 1;
- break;
- default:
- DRM_ERROR("Unhandled client id: %d\n", entry->client_id);
- return 0;
+ if (amdgpu_sriov_is_vcn_rb_decouple(adev)) {
+ ip_instance = entry->ring_id;
+ } else {
+ switch (entry->client_id) {
+ case SOC15_IH_CLIENTID_VCN:
+ ip_instance = 0;
+ break;
+ case SOC15_IH_CLIENTID_VCN1:
+ ip_instance = 1;
+ break;
+ default:
+ DRM_ERROR("Unhandled client id: %d\n", entry->client_id);
+ return 0;
+ }
}
DRM_DEBUG("IH: VCN TRAP\n");
@@ -2156,7 +2194,7 @@ static struct amdgpu_vcn_ras vcn_v4_0_ras = {
static void vcn_v4_0_set_ras_funcs(struct amdgpu_device *adev)
{
- switch (adev->ip_versions[VCN_HWIP][0]) {
+ switch (amdgpu_ip_version(adev, VCN_HWIP, 0)) {
case IP_VERSION(4, 0, 0):
adev->vcn.ras = &vcn_v4_0_ras;
break;