aboutsummaryrefslogtreecommitdiffstats
path: root/common/recipes-kernel/linux/linux-yocto-4.14.71/5017-drm-amdgpu-implement-harvesting-support-for-UVD-7.2-.patch
diff options
context:
space:
mode:
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-.patch353
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
+