diff options
author | Alex Deucher <alexander.deucher@amd.com> | 2018-07-25 15:11:34 -0500 |
---|---|---|
committer | Alex Deucher <alexander.deucher@amd.com> | 2018-07-27 09:07:44 -0500 |
commit | f1e582ebfd703ea01dc4caf4d339b7c84ec3ff29 (patch) | |
tree | 56bfd3cd4840cf6dee41cbbf77d468823065872b /drivers/gpu/drm/amd/amdgpu/uvd_v7_0.c | |
parent | d04cc604a66b07eff8fce824fb6c0fdc0875d2e3 (diff) | |
download | linux-f1e582ebfd703ea01dc4caf4d339b7c84ec3ff29.tar.bz2 |
drm/amdgpu: implement harvesting support for UVD 7.2 (v3)
Properly handle cases where one or more instance of the IP
block may be harvested.
v2: make sure ip_num_rings is initialized amdgpu_queue_mgr.c
v3: rebase on Christian's UVD changes, drop unused var
Reviewed-by: James Zhu <James.Zhu@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
Diffstat (limited to 'drivers/gpu/drm/amd/amdgpu/uvd_v7_0.c')
-rw-r--r-- | drivers/gpu/drm/amd/amdgpu/uvd_v7_0.c | 56 |
1 files changed, 53 insertions, 3 deletions
diff --git a/drivers/gpu/drm/amd/amdgpu/uvd_v7_0.c b/drivers/gpu/drm/amd/amdgpu/uvd_v7_0.c index d74c1b242667..5fab3560a71d 100644 --- a/drivers/gpu/drm/amd/amdgpu/uvd_v7_0.c +++ b/drivers/gpu/drm/amd/amdgpu/uvd_v7_0.c @@ -41,6 +41,12 @@ #include "mmhub/mmhub_1_0_sh_mask.h" #include "ivsrcid/uvd/irqsrcs_uvd_7_0.h" +#define mmUVD_PG0_CC_UVD_HARVESTING 0x00c7 +#define mmUVD_PG0_CC_UVD_HARVESTING_BASE_IDX 1 +//UVD_PG0_CC_UVD_HARVESTING +#define UVD_PG0_CC_UVD_HARVESTING__UVD_DISABLE__SHIFT 0x1 +#define UVD_PG0_CC_UVD_HARVESTING__UVD_DISABLE_MASK 0x00000002L + #define UVD7_MAX_HW_INSTANCES_VEGA20 2 static void uvd_v7_0_set_ring_funcs(struct amdgpu_device *adev); @@ -370,10 +376,25 @@ error: static int uvd_v7_0_early_init(void *handle) { struct amdgpu_device *adev = (struct amdgpu_device *)handle; - if (adev->asic_type == CHIP_VEGA20) + + if (adev->asic_type == CHIP_VEGA20) { + u32 harvest; + int i; + adev->uvd.num_uvd_inst = UVD7_MAX_HW_INSTANCES_VEGA20; - else + for (i = 0; i < adev->uvd.num_uvd_inst; i++) { + harvest = RREG32_SOC15(UVD, i, mmUVD_PG0_CC_UVD_HARVESTING); + if (harvest & UVD_PG0_CC_UVD_HARVESTING__UVD_DISABLE_MASK) { + adev->uvd.harvest_config |= 1 << i; + } + } + if (adev->uvd.harvest_config == (AMDGPU_UVD_HARVEST_UVD0 | + AMDGPU_UVD_HARVEST_UVD1)) + /* both instances are harvested, disable the block */ + return -ENOENT; + } else { adev->uvd.num_uvd_inst = 1; + } if (amdgpu_sriov_vf(adev)) adev->uvd.num_enc_rings = 1; @@ -393,6 +414,8 @@ static int uvd_v7_0_sw_init(void *handle) struct amdgpu_device *adev = (struct amdgpu_device *)handle; for (j = 0; j < adev->uvd.num_uvd_inst; j++) { + if (adev->uvd.harvest_config & (1 << j)) + continue; /* UVD TRAP */ r = amdgpu_irq_add_id(adev, amdgpu_ih_clientid_uvds[j], UVD_7_0__SRCID__UVD_SYSTEM_MESSAGE_INTERRUPT, &adev->uvd.inst[j].irq); if (r) @@ -425,6 +448,8 @@ static int uvd_v7_0_sw_init(void *handle) return r; for (j = 0; j < adev->uvd.num_uvd_inst; j++) { + if (adev->uvd.harvest_config & (1 << j)) + continue; if (!amdgpu_sriov_vf(adev)) { ring = &adev->uvd.inst[j].ring; sprintf(ring->name, "uvd<%d>", j); @@ -472,6 +497,8 @@ static int uvd_v7_0_sw_fini(void *handle) return r; for (j = 0; j < adev->uvd.num_uvd_inst; ++j) { + if (adev->uvd.harvest_config & (1 << j)) + continue; for (i = 0; i < adev->uvd.num_enc_rings; ++i) amdgpu_ring_fini(&adev->uvd.inst[j].ring_enc[i]); } @@ -500,6 +527,8 @@ static int uvd_v7_0_hw_init(void *handle) goto done; for (j = 0; j < adev->uvd.num_uvd_inst; ++j) { + if (adev->uvd.harvest_config & (1 << j)) + continue; ring = &adev->uvd.inst[j].ring; if (!amdgpu_sriov_vf(adev)) { @@ -579,8 +608,11 @@ static int uvd_v7_0_hw_fini(void *handle) DRM_DEBUG("For SRIOV client, shouldn't do anything.\n"); } - for (i = 0; i < adev->uvd.num_uvd_inst; ++i) + for (i = 0; i < adev->uvd.num_uvd_inst; ++i) { + if (adev->uvd.harvest_config & (1 << i)) + continue; adev->uvd.inst[i].ring.ready = false; + } return 0; } @@ -623,6 +655,8 @@ static void uvd_v7_0_mc_resume(struct amdgpu_device *adev) int i; for (i = 0; i < adev->uvd.num_uvd_inst; ++i) { + if (adev->uvd.harvest_config & (1 << i)) + continue; if (adev->firmware.load_type == AMDGPU_FW_LOAD_PSP) { WREG32_SOC15(UVD, i, mmUVD_LMI_VCPU_CACHE_64BIT_BAR_LOW, lower_32_bits(adev->firmware.ucode[AMDGPU_UCODE_ID_UVD].mc_addr)); @@ -695,6 +729,8 @@ static int uvd_v7_0_mmsch_start(struct amdgpu_device *adev, WREG32_SOC15(VCE, 0, mmVCE_MMSCH_VF_MAILBOX_RESP, 0); for (i = 0; i < adev->uvd.num_uvd_inst; ++i) { + if (adev->uvd.harvest_config & (1 << i)) + continue; WDOORBELL32(adev->uvd.inst[i].ring_enc[0].doorbell_index, 0); adev->wb.wb[adev->uvd.inst[i].ring_enc[0].wptr_offs] = 0; adev->uvd.inst[i].ring_enc[0].wptr = 0; @@ -751,6 +787,8 @@ static int uvd_v7_0_sriov_start(struct amdgpu_device *adev) init_table += header->uvd_table_offset; for (i = 0; i < adev->uvd.num_uvd_inst; ++i) { + if (adev->uvd.harvest_config & (1 << i)) + continue; ring = &adev->uvd.inst[i].ring; ring->wptr = 0; size = AMDGPU_GPU_PAGE_ALIGN(adev->uvd.fw->size + 4); @@ -890,6 +928,8 @@ static int uvd_v7_0_start(struct amdgpu_device *adev) int i, j, k, r; for (k = 0; k < adev->uvd.num_uvd_inst; ++k) { + if (adev->uvd.harvest_config & (1 << k)) + continue; /* disable DPG */ WREG32_P(SOC15_REG_OFFSET(UVD, k, mmUVD_POWER_STATUS), 0, ~UVD_POWER_STATUS__UVD_PG_MODE_MASK); @@ -902,6 +942,8 @@ static int uvd_v7_0_start(struct amdgpu_device *adev) uvd_v7_0_mc_resume(adev); for (k = 0; k < adev->uvd.num_uvd_inst; ++k) { + if (adev->uvd.harvest_config & (1 << k)) + continue; ring = &adev->uvd.inst[k].ring; /* disable clock gating */ WREG32_P(SOC15_REG_OFFSET(UVD, k, mmUVD_CGC_CTRL), 0, @@ -1069,6 +1111,8 @@ static void uvd_v7_0_stop(struct amdgpu_device *adev) uint8_t i = 0; for (i = 0; i < adev->uvd.num_uvd_inst; ++i) { + if (adev->uvd.harvest_config & (1 << i)) + continue; /* force RBC into idle state */ WREG32_SOC15(UVD, i, mmUVD_RBC_RB_CNTL, 0x11010101); @@ -1785,6 +1829,8 @@ static void uvd_v7_0_set_ring_funcs(struct amdgpu_device *adev) int i; for (i = 0; i < adev->uvd.num_uvd_inst; i++) { + if (adev->uvd.harvest_config & (1 << i)) + continue; adev->uvd.inst[i].ring.funcs = &uvd_v7_0_ring_vm_funcs; adev->uvd.inst[i].ring.me = i; DRM_INFO("UVD(%d) is enabled in VM mode\n", i); @@ -1796,6 +1842,8 @@ static void uvd_v7_0_set_enc_ring_funcs(struct amdgpu_device *adev) int i, j; for (j = 0; j < adev->uvd.num_uvd_inst; j++) { + if (adev->uvd.harvest_config & (1 << j)) + continue; for (i = 0; i < adev->uvd.num_enc_rings; ++i) { adev->uvd.inst[j].ring_enc[i].funcs = &uvd_v7_0_enc_ring_vm_funcs; adev->uvd.inst[j].ring_enc[i].me = j; @@ -1815,6 +1863,8 @@ static void uvd_v7_0_set_irq_funcs(struct amdgpu_device *adev) int i; for (i = 0; i < adev->uvd.num_uvd_inst; i++) { + if (adev->uvd.harvest_config & (1 << i)) + continue; adev->uvd.inst[i].irq.num_types = adev->uvd.num_enc_rings + 1; adev->uvd.inst[i].irq.funcs = &uvd_v7_0_irq_funcs; } |