Missing out the RB, Reviewed-by: James Zhu <James.Zhu at amd.com> On 2018-07-25 05:29 PM, Alex Deucher wrote: > On Wed, Jul 25, 2018 at 5:26 PM, James Zhu <jamesz at amd.com> wrote: >> This patch is James Zhu <James.Zhu at amd.com> > Is that an RB or an AB or? > > Alex > >> >> On 2018-07-25 05:02 PM, Alex Deucher wrote: >>> 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 >>> >>> Signed-off-by: Alex Deucher <alexander.deucher at 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 c7dce14fd47d..dd2132fa2b89 100644 >>> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c >>> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c >>> @@ -286,7 +286,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) >>> @@ -348,7 +348,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; >>> @@ -361,9 +365,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 d8357290ad09..a172bba32b45 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 fca86d71fafc..632fa5980ff4 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); >>> @@ -308,6 +309,8 @@ int amdgpu_uvd_sw_fini(struct amdgpu_device *adev) >>> 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, >>> @@ -343,6 +346,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; >>> @@ -365,6 +370,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; >>> @@ -1159,6 +1166,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 66872286ab12..33c5f806f925 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 db5f3d78ab12..8179317be750 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); >>> @@ -1756,6 +1800,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); >>> @@ -1767,6 +1813,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; >>> @@ -1786,6 +1834,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; >>> } >> >> _______________________________________________ >> amd-gfx mailing list >> amd-gfx at lists.freedesktop.org >> https://lists.freedesktop.org/mailman/listinfo/amd-gfx > _______________________________________________ > amd-gfx mailing list > amd-gfx at lists.freedesktop.org > https://lists.freedesktop.org/mailman/listinfo/amd-gfx