diff options
Diffstat (limited to 'common/recipes-kernel/linux/linux-yocto-4.14.71/5017-drm-amdgpu-implement-harvesting-support-for-UVD-7.2-.patch')
-rw-r--r-- | common/recipes-kernel/linux/linux-yocto-4.14.71/5017-drm-amdgpu-implement-harvesting-support-for-UVD-7.2-.patch | 353 |
1 files changed, 353 insertions, 0 deletions
diff --git a/common/recipes-kernel/linux/linux-yocto-4.14.71/5017-drm-amdgpu-implement-harvesting-support-for-UVD-7.2-.patch b/common/recipes-kernel/linux/linux-yocto-4.14.71/5017-drm-amdgpu-implement-harvesting-support-for-UVD-7.2-.patch new file mode 100644 index 00000000..69291789 --- /dev/null +++ b/common/recipes-kernel/linux/linux-yocto-4.14.71/5017-drm-amdgpu-implement-harvesting-support-for-UVD-7.2-.patch @@ -0,0 +1,353 @@ +From f916806866884732b15d0516d3146dd48e5e271c Mon Sep 17 00:00:00 2001 +From: Chaudhary Amit Kumar <chaudharyamit.kumar@amd.com> +Date: Wed, 9 Jan 2019 20:47:48 +0530 +Subject: [PATCH 5017/5725] 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> +Signed-off-by: Raveendra Talabattula <raveendra.talabattula@amd.com> +Signed-off-by: Chaudhary Amit Kumar <chaudharyamit.kumar@amd.com> +--- + drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c | 17 +++++--- + drivers/gpu/drm/amd/amdgpu/amdgpu_queue_mgr.c | 13 +++++-- + drivers/gpu/drm/amd/amdgpu/amdgpu_uvd.c | 11 +++++- + drivers/gpu/drm/amd/amdgpu/amdgpu_uvd.h | 4 ++ + drivers/gpu/drm/amd/amdgpu/uvd_v7_0.c | 56 +++++++++++++++++++++++++-- + 5 files changed, 89 insertions(+), 12 deletions(-) + +diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c +index 5aab580..be1770d 100644 +--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c ++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c +@@ -283,7 +283,7 @@ static int amdgpu_info_ioctl(struct drm_device *dev, void *data, struct drm_file + struct drm_crtc *crtc; + uint32_t ui32 = 0; + uint64_t ui64 = 0; +- int i, found; ++ int i, j, found; + int ui32_size = sizeof(ui32); + + if (!info->return_size || !info->return_pointer) +@@ -362,7 +362,11 @@ static int amdgpu_info_ioctl(struct drm_device *dev, void *data, struct drm_file + break; + case AMDGPU_HW_IP_UVD: + type = AMD_IP_BLOCK_TYPE_UVD; +- ring_mask |= adev->uvd.inst[0].ring.ready; ++ for (i = 0; i < adev->uvd.num_uvd_inst; i++) { ++ if (adev->uvd.harvest_config & (1 << i)) ++ continue; ++ ring_mask |= adev->uvd.inst[i].ring.ready; ++ } + ib_start_alignment = 64; + ib_size_alignment = 64; + break; +@@ -375,9 +379,12 @@ static int amdgpu_info_ioctl(struct drm_device *dev, void *data, struct drm_file + break; + case AMDGPU_HW_IP_UVD_ENC: + type = AMD_IP_BLOCK_TYPE_UVD; +- for (i = 0; i < adev->uvd.num_enc_rings; i++) +- ring_mask |= +- adev->uvd.inst[0].ring_enc[i].ready << i; ++ for (i = 0; i < adev->uvd.num_uvd_inst; i++) { ++ if (adev->uvd.harvest_config & (1 << i)) ++ continue; ++ for (j = 0; j < adev->uvd.num_enc_rings; j++) ++ ring_mask |= adev->uvd.inst[i].ring_enc[j].ready << j; ++ } + ib_start_alignment = 64; + ib_size_alignment = 64; + break; +diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_queue_mgr.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_queue_mgr.c +index d835729..a172bba 100644 +--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_queue_mgr.c ++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_queue_mgr.c +@@ -214,7 +214,7 @@ int amdgpu_queue_mgr_map(struct amdgpu_device *adev, + u32 hw_ip, u32 instance, u32 ring, + struct amdgpu_ring **out_ring) + { +- int r, ip_num_rings; ++ int i, r, ip_num_rings = 0; + struct amdgpu_queue_mapper *mapper = &mgr->mapper[hw_ip]; + + if (!adev || !mgr || !out_ring) +@@ -243,14 +243,21 @@ int amdgpu_queue_mgr_map(struct amdgpu_device *adev, + ip_num_rings = adev->sdma.num_instances; + break; + case AMDGPU_HW_IP_UVD: +- ip_num_rings = adev->uvd.num_uvd_inst; ++ for (i = 0; i < adev->uvd.num_uvd_inst; i++) { ++ if (!(adev->uvd.harvest_config & (1 << i))) ++ ip_num_rings++; ++ } + break; + case AMDGPU_HW_IP_VCE: + ip_num_rings = adev->vce.num_rings; + break; + case AMDGPU_HW_IP_UVD_ENC: ++ for (i = 0; i < adev->uvd.num_uvd_inst; i++) { ++ if (!(adev->uvd.harvest_config & (1 << i))) ++ ip_num_rings++; ++ } + ip_num_rings = +- adev->uvd.num_enc_rings * adev->uvd.num_uvd_inst; ++ adev->uvd.num_enc_rings * ip_num_rings; + break; + case AMDGPU_HW_IP_VCN_DEC: + ip_num_rings = 1; +diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_uvd.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_uvd.c +index 420a533..b933d1f 100644 +--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_uvd.c ++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_uvd.c +@@ -255,7 +255,8 @@ int amdgpu_uvd_sw_init(struct amdgpu_device *adev) + bo_size += AMDGPU_GPU_PAGE_ALIGN(le32_to_cpu(hdr->ucode_size_bytes) + 8); + + for (j = 0; j < adev->uvd.num_uvd_inst; j++) { +- ++ if (adev->uvd.harvest_config & (1 << j)) ++ continue; + r = amdgpu_bo_create_kernel(adev, bo_size, PAGE_SIZE, + AMDGPU_GEM_DOMAIN_VRAM, &adev->uvd.inst[j].vcpu_bo, + &adev->uvd.inst[j].gpu_addr, &adev->uvd.inst[j].cpu_addr); +@@ -311,6 +312,8 @@ int amdgpu_uvd_sw_fini(struct amdgpu_device *adev) + &adev->uvd.entity); + + for (j = 0; j < adev->uvd.num_uvd_inst; ++j) { ++ if (adev->uvd.harvest_config & (1 << j)) ++ continue; + kfree(adev->uvd.inst[j].saved_bo); + + amdgpu_bo_free_kernel(&adev->uvd.inst[j].vcpu_bo, +@@ -347,6 +350,8 @@ int amdgpu_uvd_suspend(struct amdgpu_device *adev) + + + for (j = 0; j < adev->uvd.num_uvd_inst; ++j) { ++ if (adev->uvd.harvest_config & (1 << j)) ++ continue; + if (adev->uvd.inst[j].vcpu_bo == NULL) + continue; + +@@ -371,6 +376,8 @@ int amdgpu_uvd_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->uvd.inst[i].vcpu_bo == NULL) + return -EINVAL; + +@@ -1168,6 +1175,8 @@ static void amdgpu_uvd_idle_work_handler(struct work_struct *work) + unsigned fences = 0, i, j; + + for (i = 0; i < adev->uvd.num_uvd_inst; ++i) { ++ if (adev->uvd.harvest_config & (1 << i)) ++ continue; + fences += amdgpu_fence_count_emitted(&adev->uvd.inst[i].ring); + for (j = 0; j < adev->uvd.num_enc_rings; ++j) { + fences += amdgpu_fence_count_emitted(&adev->uvd.inst[i].ring_enc[j]); +diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_uvd.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_uvd.h +index 6687228..33c5f80 100644 +--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_uvd.h ++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_uvd.h +@@ -48,6 +48,9 @@ struct amdgpu_uvd_inst { + uint32_t srbm_soft_reset; + }; + ++#define AMDGPU_UVD_HARVEST_UVD0 (1 << 0) ++#define AMDGPU_UVD_HARVEST_UVD1 (1 << 1) ++ + struct amdgpu_uvd { + const struct firmware *fw; /* UVD firmware */ + unsigned fw_version; +@@ -61,6 +64,7 @@ struct amdgpu_uvd { + atomic_t handles[AMDGPU_MAX_UVD_HANDLES]; + struct drm_sched_entity entity; + struct delayed_work idle_work; ++ unsigned harvest_config; + }; + + int amdgpu_uvd_sw_init(struct amdgpu_device *adev); +diff --git a/drivers/gpu/drm/amd/amdgpu/uvd_v7_0.c b/drivers/gpu/drm/amd/amdgpu/uvd_v7_0.c +index 87d6a59..2a583d8 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 @@ static int uvd_v7_0_enc_ring_test_ib(struct amdgpu_ring *ring, long timeout) + 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); + +@@ -1807,6 +1851,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); +@@ -1818,6 +1864,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; +@@ -1837,6 +1885,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; + } +-- +2.7.4 + |