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);
        drm_sched_entity_destroy(&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,
        }
 
        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;
 
        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;
 
        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]);
 
 #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);
 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;
        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)
                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);
                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]);
        }
                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)) {
                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;
 }
        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));
        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;
                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);
        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);
        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,
        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);
 
        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);
        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;
        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;
        }