[PATCH] drm/amdgpu: Fix the null pointer dereference for amdgpu_ras_reset_error_status
Check return value and conduct null pointer handling to avoid null pointer dereference. Signed-off-by: Bob Zhou --- drivers/gpu/drm/amd/amdgpu/amdgpu_ras.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ras.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_ras.c index 68e9935028db..0ea836b376a6 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ras.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ras.c @@ -1442,6 +1442,9 @@ int amdgpu_ras_reset_error_status(struct amdgpu_device *adev, if (amdgpu_ras_reset_error_count(adev, block) == -EOPNOTSUPP) return 0; + if (!block_obj || !block_obj->hw_ops) + return -EINVAL; + if ((block == AMDGPU_RAS_BLOCK__GFX) || (block == AMDGPU_RAS_BLOCK__MMHUB)) { if (block_obj->hw_ops->reset_ras_error_status) -- 2.34.1
Re: [PATCH v2 8/8] drm/amdgpu: Call drm_atomic_helper_shutdown() at shutdown time
Hi, On Wed, Jun 19, 2024 at 09:53:12AM GMT, Alex Deucher wrote: > On Wed, Jun 19, 2024 at 9:50 AM Alex Deucher wrote: > > > > On Tue, Jun 18, 2024 at 7:53 PM Doug Anderson wrote: > > > > > > Hi, > > > > > > On Tue, Jun 18, 2024 at 3:00 PM Alex Deucher > > > wrote: > > > > > > > > On Tue, Jun 18, 2024 at 5:40 PM Doug Anderson > > > > wrote: > > > > > > > > > > Hi, > > > > > > > > > > > > > > > On Mon, Jun 17, 2024 at 8:01 AM Alex Deucher > > > > > wrote: > > > > > > > > > > > > On Wed, Jun 12, 2024 at 6:37 PM Douglas Anderson > > > > > > wrote: > > > > > > > > > > > > > > Based on grepping through the source code this driver appears to > > > > > > > be > > > > > > > missing a call to drm_atomic_helper_shutdown() at system shutdown > > > > > > > time. Among other things, this means that if a panel is in use > > > > > > > that it > > > > > > > won't be cleanly powered off at system shutdown time. > > > > > > > > > > > > > > The fact that we should call drm_atomic_helper_shutdown() in the > > > > > > > case > > > > > > > of OS shutdown/restart comes straight out of the kernel doc > > > > > > > "driver > > > > > > > instance overview" in drm_drv.c. > > > > > > > > > > > > > > Suggested-by: Maxime Ripard > > > > > > > Cc: Alex Deucher > > > > > > > Cc: Christian König > > > > > > > Cc: Xinhui Pan > > > > > > > Signed-off-by: Douglas Anderson > > > > > > > --- > > > > > > > This commit is only compile-time tested. > > > > > > > > > > > > > > ...and further, I'd say that this patch is more of a plea for help > > > > > > > than a patch I think is actually right. I'm _fairly_ certain that > > > > > > > drm/amdgpu needs this call at shutdown time but the logic is a bit > > > > > > > hard for me to follow. I'd appreciate if anyone who actually knows > > > > > > > what this should look like could illuminate me, or perhaps even > > > > > > > just > > > > > > > post a patch themselves! > > > > > > > > > > > > I'm not sure this patch makes sense or not. The driver doesn't > > > > > > really > > > > > > do a formal tear down in its shutdown routine, it just quiesces the > > > > > > hardware. What are the actual requirements of the shutdown > > > > > > function? > > > > > > In the past when we did a full driver tear down in shutdown, it > > > > > > delayed the shutdown sequence and users complained. > > > > > > > > > > The "inspiration" for this patch is to handle panels properly. > > > > > Specifically, panels often have several power/enable signals going to > > > > > them and often have requirements that these signals are powered off in > > > > > the proper order with the proper delays between them. While we can't > > > > > always do so when the system crashes / reboots in an uncontrolled way, > > > > > panel manufacturers / HW Engineers get upset if we don't power things > > > > > off properly during an orderly shutdown/reboot. When panels are > > > > > powered off badly it can cause garbage on the screen and, so I've been > > > > > told, can even cause long term damage to the panels over time. > > > > > > > > > > In Linux, some panel drivers have tried to ensure a proper poweroff of > > > > > the panel by handling the shutdown() call themselves. However, this is > > > > > ugly and panel maintainers want panel drivers to stop doing it. We > > > > > have removed the code doing this from most panels now [1]. Instead the > > > > > assumption is that the DRM modeset drivers should be calling > > > > > drm_atomic_helper_shutdown() which will make sure panels get an > > > > > orderly shutdown. > > > > > > > > > > For a lot more details, see the cover letter [2] which then contains > > > > > links to even more discussions about the topic. > > > > > > > > > > [1] > > > > > https://lore.kernel.org/r/20240605002401.2848541-1-diand...@chromium.org > > > > > [2] > > > > > https://lore.kernel.org/r/2024061435.3188234-1-diand...@chromium.org > > > > > > > > I don't think it's an issue. We quiesce the hardware as if we were > > > > about to suspend the system (e.g., S3). For the display hardware we > > > > call drm_atomic_helper_suspend() as part of that sequence. > > > > > > OK. It's no skin off my teeth and we can drop this patch if you're > > > convinced it's not needed. From the point of view of someone who has > > > no experience with this driver it seems weird to me that it would use > > > drm_atomic_helper_suspend() at shutdown time instead of the documented > > > drm_atomic_helper_shutdown(), but if it works for everyone then I'm > > > not gonna complain. > > > > I think the problem is that it is not clear exactly what the > > expectations are around the PCI shutdown callback. The documentation > > says: > > > > "Hook into reboot_notifier_list (kernel/sys.c). Intended to stop any > > idling DMA operations. Useful for enabling wake-on-lan (NIC) or > > changing the power state of a device before reboot. e.g. > > drivers/net/e100.c." > > Arguably, there is no requirement to even touch the display
[PATCH] drm/amdgpu: add missing error handling in function amdgpu_gmc_flush_gpu_tlb_pasid
Fix the unchecked return value warning by warning reported by Coverity, so add error handling. Signed-off-by: Bob Zhou --- drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.c | 6 +- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.c index 322b8ff67cde..3a7622611916 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.c @@ -718,7 +718,11 @@ int amdgpu_gmc_flush_gpu_tlb_pasid(struct amdgpu_device *adev, uint16_t pasid, ndw += kiq->pmf->invalidate_tlbs_size; spin_lock(&adev->gfx.kiq[inst].ring_lock); - amdgpu_ring_alloc(ring, ndw); + r = amdgpu_ring_alloc(ring, ndw); + if (r) { + spin_unlock(&adev->gfx.kiq[inst].ring_lock); + goto error_unlock_reset; + } if (adev->gmc.flush_tlb_needs_extra_type_2) kiq->pmf->kiq_invalidate_tlbs(ring, pasid, 2, all_hub); -- 2.34.1
RE: [PATCH] drm/amdgpu: part I - normalize registers as local xcc to read/write under sriov in TLB
[AMD Official Use Only - AMD Internal Distribution Only] Ping for this. Thanks, Jane -Original Message- From: Jane Jian Sent: Thursday, June 20, 2024 12:32 AM To: Lazar, Lijo Cc: amd-gfx@lists.freedesktop.org; Jian, Jane Subject: [PATCH] drm/amdgpu: part I - normalize registers as local xcc to read/write under sriov in TLB [WHY] sriov has the higher bit violation when flushing tlb [HOW] normalize the registers to keep lower 16-bit(dword aligned) to aviod higher bit violation RLCG will mask xcd out and always assume it's accessing its own xcd [TODO] later will add the normalization in sriovw/rreg after fixing bugs v2 rename the normalized macro, add ip block type for further use Signed-off-by: Jane Jian --- drivers/gpu/drm/amd/amdgpu/amdgpu.h| 2 ++ drivers/gpu/drm/amd/amdgpu/aqua_vanjaram.c | 16 drivers/gpu/drm/amd/amdgpu/gmc_v9_0.c | 10 -- drivers/gpu/drm/amd/amdgpu/soc15.c | 1 + drivers/gpu/drm/amd/amdgpu/soc15.h | 1 + drivers/gpu/drm/amd/amdgpu/soc15_common.h | 5 - 6 files changed, 32 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu.h b/drivers/gpu/drm/amd/amdgpu/amdgpu.h index 083f353cff6e..eb2e7312bf1b 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu.h @@ -636,6 +636,8 @@ struct amdgpu_asic_funcs { ssize_t (*get_reg_state)(struct amdgpu_device *adev, enum amdgpu_reg_state reg_state, void *buf, size_t max_size); + /* normalize offset to keep in lower 16-bit */ + u32 (*normalize_reg_offset)(u32 hwip, u32 offset); }; /* diff --git a/drivers/gpu/drm/amd/amdgpu/aqua_vanjaram.c b/drivers/gpu/drm/amd/amdgpu/aqua_vanjaram.c index 2c9a0aa41e2d..9b4bea2ca7df 100644 --- a/drivers/gpu/drm/amd/amdgpu/aqua_vanjaram.c +++ b/drivers/gpu/drm/amd/amdgpu/aqua_vanjaram.c @@ -1085,3 +1085,19 @@ ssize_t aqua_vanjaram_get_reg_state(struct amdgpu_device *adev, return size; } + +u32 aqua_vanjaram_normalize_reg_offset(u32 hwip, u32 offset) { + u32 normalized_offset; + + switch (hwip) { + case GC_HWIP: + normalized_offset = offset & 0x; + break; + default: + normalized_offset = offset; + break; + } + + return normalized_offset; +} diff --git a/drivers/gpu/drm/amd/amdgpu/gmc_v9_0.c b/drivers/gpu/drm/amd/amdgpu/gmc_v9_0.c index 88b4644f8e96..1d24e19f304d 100644 --- a/drivers/gpu/drm/amd/amdgpu/gmc_v9_0.c +++ b/drivers/gpu/drm/amd/amdgpu/gmc_v9_0.c @@ -853,8 +853,14 @@ static void gmc_v9_0_flush_gpu_tlb(struct amdgpu_device *adev, uint32_t vmid, */ if (adev->gfx.kiq[inst].ring.sched.ready && (amdgpu_sriov_runtime(adev) || !amdgpu_sriov_vf(adev))) { - uint32_t req = hub->vm_inv_eng0_req + hub->eng_distance * eng; - uint32_t ack = hub->vm_inv_eng0_ack + hub->eng_distance * eng; + + /* Select lower 16 bits to write in local xcc +* for MMHUB it uses xcc0, NO cross AID reg offset +*/ + if (AMDGPU_IS_GFXHUB(vmhub)) { + req = NORMALIZE_XCC_REG_OFFSET(GC, req); + ack = NORMALIZE_XCC_REG_OFFSET(GC, ack); + } amdgpu_gmc_fw_reg_write_reg_wait(adev, req, ack, inv_req, 1 << vmid, inst); diff --git a/drivers/gpu/drm/amd/amdgpu/soc15.c b/drivers/gpu/drm/amd/amdgpu/soc15.c index 8d16dacdc172..e6e61fc77080 100644 --- a/drivers/gpu/drm/amd/amdgpu/soc15.c +++ b/drivers/gpu/drm/amd/amdgpu/soc15.c @@ -927,6 +927,7 @@ static const struct amdgpu_asic_funcs aqua_vanjaram_asic_funcs = .query_video_codecs = &soc15_query_video_codecs, .encode_ext_smn_addressing = &aqua_vanjaram_encode_ext_smn_addressing, .get_reg_state = &aqua_vanjaram_get_reg_state, + .normalize_reg_offset = &aqua_vanjaram_normalize_reg_offset, }; static int soc15_common_early_init(void *handle) diff --git a/drivers/gpu/drm/amd/amdgpu/soc15.h b/drivers/gpu/drm/amd/amdgpu/soc15.h index 282584a48be0..f1e974604e3e 100644 --- a/drivers/gpu/drm/amd/amdgpu/soc15.h +++ b/drivers/gpu/drm/amd/amdgpu/soc15.h @@ -124,4 +124,5 @@ ssize_t aqua_vanjaram_get_reg_state(struct amdgpu_device *adev, void vega10_doorbell_index_init(struct amdgpu_device *adev); void vega20_doorbell_index_init(struct amdgpu_device *adev); void aqua_vanjaram_doorbell_index_init(struct amdgpu_device *adev); +u32 aqua_vanjaram_normalize_reg_offset(u32 hwip, u32 offset); #endif diff --git a/drivers/gpu/drm/amd/amdgpu/soc15_common.h b/drivers/gpu/drm/amd/amdgpu/soc15_common.h index 242b24f73c17..ddf0aad51821 100644 --- a/drivers/gpu/drm/amd/amdgpu/soc15_common.h +++ b/drivers/gpu/drm/amd/amdgpu/soc15_common.h @@ -210,4 +210,7 @@ #define WREG64_MCA(ext, mca_base, idx, val) \ WREG64_PCIE_EXT(ad
Re: [PATCH] drm/amdgpu: track bo memory stats at runtime
Am 20.06.24 um 02:30 schrieb Yunxiang Li: Before, every time fdinfo is queried we try to lock all the BOs in the VM and calculate memory usage from scratch. This works okay if the fdinfo is rarely read and the VMs don't have a ton of BOs. If either of these conditions is not true, we get a massive performance hit. In this new revision, we track the BOs as they change state. This way when the fdinfo is queried we only need to take the status lock and copy out the usage stats with minimal impact to the runtime performance. To simplify the initial implementation, this revision drops tracking how much memory is visible, since on modern systems all of vram can be visible anyways. Also we do not track "unsharing" a BO, the shared stat is only decreased when the BO is destroyed. Signed-off-by: Yunxiang Li --- drivers/gpu/drm/amd/amdgpu/amdgpu_dma_buf.c | 26 ++- drivers/gpu/drm/amd/amdgpu/amdgpu_fdinfo.c | 6 --- drivers/gpu/drm/amd/amdgpu/amdgpu_object.c | 52 ++--- drivers/gpu/drm/amd/amdgpu/amdgpu_object.h | 31 ++-- drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c | 15 -- drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c | 47 +++ drivers/gpu/drm/amd/amdgpu/amdgpu_vm.h | 25 +- drivers/gpu/drm/amd/amdgpu/amdgpu_vm_pt.c | 1 + include/uapi/drm/amdgpu_drm.h | 5 ++ 9 files changed, 111 insertions(+), 97 deletions(-) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_dma_buf.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_dma_buf.c index 8e81a83d37d8..cc78704a5f4e 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_dma_buf.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_dma_buf.c @@ -35,6 +35,8 @@ #include "amdgpu_display.h" #include "amdgpu_gem.h" #include "amdgpu_dma_buf.h" +#include "amdgpu_object.h" +#include "amdgpu_vm.h" #include "amdgpu_xgmi.h" #include #include @@ -259,14 +261,36 @@ struct dma_buf *amdgpu_gem_prime_export(struct drm_gem_object *gobj, { struct amdgpu_bo *bo = gem_to_amdgpu_bo(gobj); struct dma_buf *buf; + struct amdgpu_vm_bo_base *base; + struct amdgpu_mem_stats stats = { 0 }; + bool update_stats; if (amdgpu_ttm_tt_get_usermm(bo->tbo.ttm) || bo->flags & AMDGPU_GEM_CREATE_VM_ALWAYS_VALID) return ERR_PTR(-EPERM); + dma_resv_lock(bo->tbo.base.resv, NULL); Why do you grab the BO lock to update the stats? That doesn't seem to make any sense. + update_stats = !(bo->flags & AMDGPU_GEM_WAS_EXPORTED); + if (update_stats) + amdgpu_bo_add_memory(bo, &stats); + else + dma_resv_unlock(bo->tbo.base.resv); + buf = drm_gem_prime_export(gobj, flags); - if (!IS_ERR(buf)) + if (!IS_ERR(buf)) { buf->ops = &amdgpu_dmabuf_ops; + if (update_stats) { + for (base = bo->vm_bo; base; base = base->next) { + spin_lock(&base->vm->status_lock); + base->vm->stats.vram_shared += stats.vram; + base->vm->stats.gtt_shared += stats.gtt; + base->vm->stats.cpu_shared += stats.cpu; + spin_unlock(&base->vm->status_lock); + } + bo->flags |= AMDGPU_GEM_WAS_EXPORTED; + dma_resv_unlock(bo->tbo.base.resv); + } + } return buf; } diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_fdinfo.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_fdinfo.c index c7df7fa3459f..9a40ff5c6dd3 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_fdinfo.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_fdinfo.c @@ -85,16 +85,10 @@ void amdgpu_show_fdinfo(struct drm_printer *p, struct drm_file *file) drm_printf(p, "drm-memory-vram:\t%llu KiB\n", stats.vram/1024UL); drm_printf(p, "drm-memory-gtt: \t%llu KiB\n", stats.gtt/1024UL); drm_printf(p, "drm-memory-cpu: \t%llu KiB\n", stats.cpu/1024UL); - drm_printf(p, "amd-memory-visible-vram:\t%llu KiB\n", - stats.visible_vram/1024UL); drm_printf(p, "amd-evicted-vram:\t%llu KiB\n", stats.evicted_vram/1024UL); - drm_printf(p, "amd-evicted-visible-vram:\t%llu KiB\n", - stats.evicted_visible_vram/1024UL); drm_printf(p, "amd-requested-vram:\t%llu KiB\n", stats.requested_vram/1024UL); - drm_printf(p, "amd-requested-visible-vram:\t%llu KiB\n", - stats.requested_visible_vram/1024UL); drm_printf(p, "amd-requested-gtt:\t%llu KiB\n", stats.requested_gtt/1024UL); drm_printf(p, "drm-shared-vram:\t%llu KiB\n", stats.vram_shared/1024UL); diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c index 1eadcad1856d..4d6fda142f65 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c +++ b/drivers/gpu/drm/amd/amdgpu
Re: [PATCH] drm/amdgpu: part I - normalize registers as local xcc to read/write under sriov in TLB
On 6/19/2024 10:01 PM, Jane Jian wrote: > [WHY] > sriov has the higher bit violation when flushing tlb > > [HOW] > normalize the registers to keep lower 16-bit(dword aligned) to aviod higher > bit violation > RLCG will mask xcd out and always assume it's accessing its own xcd > > [TODO] > later will add the normalization in sriovw/rreg after fixing bugs > > v2 > rename the normalized macro, add ip block type for further use > In subject, part I etc. doesn't look good. Only put the intent - like normalize xcc register offsets for TLB flush. Rest of the story may be put in description. > Signed-off-by: Jane Jian > --- > drivers/gpu/drm/amd/amdgpu/amdgpu.h| 2 ++ > drivers/gpu/drm/amd/amdgpu/aqua_vanjaram.c | 16 > drivers/gpu/drm/amd/amdgpu/gmc_v9_0.c | 10 -- > drivers/gpu/drm/amd/amdgpu/soc15.c | 1 + > drivers/gpu/drm/amd/amdgpu/soc15.h | 1 + > drivers/gpu/drm/amd/amdgpu/soc15_common.h | 5 - > 6 files changed, 32 insertions(+), 3 deletions(-) > > diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu.h > b/drivers/gpu/drm/amd/amdgpu/amdgpu.h > index 083f353cff6e..eb2e7312bf1b 100644 > --- a/drivers/gpu/drm/amd/amdgpu/amdgpu.h > +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu.h > @@ -636,6 +636,8 @@ struct amdgpu_asic_funcs { > ssize_t (*get_reg_state)(struct amdgpu_device *adev, >enum amdgpu_reg_state reg_state, void *buf, >size_t max_size); > + /* normalize offset to keep in lower 16-bit */ > + u32 (*normalize_reg_offset)(u32 hwip, u32 offset); Please change the hwip argument type to enum amd_hw_ip_block_type. > }; > > /* > diff --git a/drivers/gpu/drm/amd/amdgpu/aqua_vanjaram.c > b/drivers/gpu/drm/amd/amdgpu/aqua_vanjaram.c > index 2c9a0aa41e2d..9b4bea2ca7df 100644 > --- a/drivers/gpu/drm/amd/amdgpu/aqua_vanjaram.c > +++ b/drivers/gpu/drm/amd/amdgpu/aqua_vanjaram.c > @@ -1085,3 +1085,19 @@ ssize_t aqua_vanjaram_get_reg_state(struct > amdgpu_device *adev, > > return size; > } > + > +u32 aqua_vanjaram_normalize_reg_offset(u32 hwip, u32 offset) > +{ > + u32 normalized_offset; > + > + switch (hwip) { > + case GC_HWIP: > + normalized_offset = offset & 0x; > + break; > + default: > + normalized_offset = offset; > + break; > + } > + > + return normalized_offset; > +} > diff --git a/drivers/gpu/drm/amd/amdgpu/gmc_v9_0.c > b/drivers/gpu/drm/amd/amdgpu/gmc_v9_0.c > index 88b4644f8e96..1d24e19f304d 100644 > --- a/drivers/gpu/drm/amd/amdgpu/gmc_v9_0.c > +++ b/drivers/gpu/drm/amd/amdgpu/gmc_v9_0.c > @@ -853,8 +853,14 @@ static void gmc_v9_0_flush_gpu_tlb(struct amdgpu_device > *adev, uint32_t vmid, >*/ > if (adev->gfx.kiq[inst].ring.sched.ready && > (amdgpu_sriov_runtime(adev) || !amdgpu_sriov_vf(adev))) { > - uint32_t req = hub->vm_inv_eng0_req + hub->eng_distance * eng; > - uint32_t ack = hub->vm_inv_eng0_ack + hub->eng_distance * eng; > + > + /* Select lower 16 bits to write in local xcc > + * for MMHUB it uses xcc0, NO cross AID reg offset > + */ The comment about MMHUB is confusing. MMHUB offset in the current form will be SOC wide, though it is passed to xcc0. Better remove it. > + if (AMDGPU_IS_GFXHUB(vmhub)) { > + req = NORMALIZE_XCC_REG_OFFSET(GC, req); Since IP is parameter, naming the macro as XCC_REG_OFFSET doesn't suit. Thanks, Lijo > + ack = NORMALIZE_XCC_REG_OFFSET(GC, ack); > + } > > amdgpu_gmc_fw_reg_write_reg_wait(adev, req, ack, inv_req, >1 << vmid, inst); > diff --git a/drivers/gpu/drm/amd/amdgpu/soc15.c > b/drivers/gpu/drm/amd/amdgpu/soc15.c > index 8d16dacdc172..e6e61fc77080 100644 > --- a/drivers/gpu/drm/amd/amdgpu/soc15.c > +++ b/drivers/gpu/drm/amd/amdgpu/soc15.c > @@ -927,6 +927,7 @@ static const struct amdgpu_asic_funcs > aqua_vanjaram_asic_funcs = > .query_video_codecs = &soc15_query_video_codecs, > .encode_ext_smn_addressing = &aqua_vanjaram_encode_ext_smn_addressing, > .get_reg_state = &aqua_vanjaram_get_reg_state, > + .normalize_reg_offset = &aqua_vanjaram_normalize_reg_offset, > }; > > static int soc15_common_early_init(void *handle) > diff --git a/drivers/gpu/drm/amd/amdgpu/soc15.h > b/drivers/gpu/drm/amd/amdgpu/soc15.h > index 282584a48be0..f1e974604e3e 100644 > --- a/drivers/gpu/drm/amd/amdgpu/soc15.h > +++ b/drivers/gpu/drm/amd/amdgpu/soc15.h > @@ -124,4 +124,5 @@ ssize_t aqua_vanjaram_get_reg_state(struct amdgpu_device > *adev, > void vega10_doorbell_index_init(struct amdgpu_device *adev); > void vega20_doorbell_index_init(struct amdgpu_device *adev); > void aqua_vanjaram_doorbell_index_init(struct amdgpu_device *adev); > +u32 aqua_vanjaram_normalize_reg_offset(u32 hwip, u32 offset); > #endif > diff
Re: [PATCH 2/2] Revert "drm/amd/amdgpu: add module parameter for jpeg"
On Wed, Jun 19, 2024 at 9:32 PM Kenneth Feng wrote: > > This reverts commit 63400bcf5cb23b6a9b674eb3f2d733d826860065. > Revert this due to a final solution in amdgu vcn: > commit eef47ed5f703377781ce89eae4b9140325049873 > Author: Sonny Jiang > Date: Tue Jun 18 11:11:11 2024 -0400 > > drm/amdgpu/jpeg5: reprogram doorbell setting after power up for each playback > > Doorbell needs to be configured after power up during each playback > > Signed-off-by: Kenneth Feng Series is: Acked-by: Alex Deucher > --- > drivers/gpu/drm/amd/amdgpu/amdgpu.h | 2 -- > drivers/gpu/drm/amd/amdgpu/amdgpu_discovery.c | 2 -- > drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c | 4 > 3 files changed, 8 deletions(-) > > diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu.h > b/drivers/gpu/drm/amd/amdgpu/amdgpu.h > index 6129f9f7a577..137a88b8de45 100644 > --- a/drivers/gpu/drm/amd/amdgpu/amdgpu.h > +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu.h > @@ -224,7 +224,6 @@ extern int amdgpu_mes; > extern int amdgpu_mes_log_enable; > extern int amdgpu_mes_kiq; > extern int amdgpu_uni_mes; > -extern int amdgpu_jpeg_test; > extern int amdgpu_noretry; > extern int amdgpu_force_asic_type; > extern int amdgpu_smartshift_bias; > @@ -1022,7 +1021,6 @@ struct amdgpu_device { > > /* jpeg */ > struct amdgpu_jpeg jpeg; > - bool enable_jpeg_test; > > /* vpe */ > struct amdgpu_vpe vpe; > diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_discovery.c > b/drivers/gpu/drm/amd/amdgpu/amdgpu_discovery.c > index 4edcbd272fa4..df753ebfd109 100644 > --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_discovery.c > +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_discovery.c > @@ -2302,8 +2302,6 @@ static int amdgpu_discovery_set_mm_ip_blocks(struct > amdgpu_device *adev) > case IP_VERSION(5, 0, 0): > amdgpu_device_ip_block_add(adev, > &vcn_v5_0_0_ip_block); > amdgpu_device_ip_block_add(adev, > &jpeg_v5_0_0_ip_block); > - if (amdgpu_jpeg_test) > - adev->enable_jpeg_test = true; > break; > default: > dev_err(adev->dev, > diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c > b/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c > index 60d5758939ae..802debd8d9f0 100644 > --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c > +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c > @@ -205,7 +205,6 @@ int amdgpu_force_asic_type = -1; > int amdgpu_tmz = -1; /* auto */ > uint amdgpu_freesync_vid_mode; > int amdgpu_reset_method = -1; /* auto */ > -int amdgpu_jpeg_test; > int amdgpu_num_kcq = -1; > int amdgpu_smartshift_bias; > int amdgpu_use_xgmi_p2p = 1; > @@ -941,9 +940,6 @@ module_param_named(freesync_video, > amdgpu_freesync_vid_mode, uint, 0444); > MODULE_PARM_DESC(reset_method, "GPU reset method (-1 = auto (default), 0 = > legacy, 1 = mode0, 2 = mode1, 3 = mode2, 4 = baco/bamaco)"); > module_param_named(reset_method, amdgpu_reset_method, int, 0644); > > -MODULE_PARM_DESC(jpeg_test, "jpeg test(0 = disable (default), 1 = enable)"); > -module_param_named(jpeg_test, amdgpu_jpeg_test, int, 0444); > - > /** > * DOC: bad_page_threshold (int) Bad page threshold is specifies the > * threshold value of faulty pages detected by RAS ECC, which may > -- > 2.34.1 >
Re: [PATCH v2 8/8] drm/amdgpu: Call drm_atomic_helper_shutdown() at shutdown time
On Thu, Jun 20, 2024 at 3:10 AM Maxime Ripard wrote: > > Hi, > > On Wed, Jun 19, 2024 at 09:53:12AM GMT, Alex Deucher wrote: > > On Wed, Jun 19, 2024 at 9:50 AM Alex Deucher wrote: > > > > > > On Tue, Jun 18, 2024 at 7:53 PM Doug Anderson > > > wrote: > > > > > > > > Hi, > > > > > > > > On Tue, Jun 18, 2024 at 3:00 PM Alex Deucher > > > > wrote: > > > > > > > > > > On Tue, Jun 18, 2024 at 5:40 PM Doug Anderson > > > > > wrote: > > > > > > > > > > > > Hi, > > > > > > > > > > > > > > > > > > On Mon, Jun 17, 2024 at 8:01 AM Alex Deucher > > > > > > wrote: > > > > > > > > > > > > > > On Wed, Jun 12, 2024 at 6:37 PM Douglas Anderson > > > > > > > wrote: > > > > > > > > > > > > > > > > Based on grepping through the source code this driver appears > > > > > > > > to be > > > > > > > > missing a call to drm_atomic_helper_shutdown() at system > > > > > > > > shutdown > > > > > > > > time. Among other things, this means that if a panel is in use > > > > > > > > that it > > > > > > > > won't be cleanly powered off at system shutdown time. > > > > > > > > > > > > > > > > The fact that we should call drm_atomic_helper_shutdown() in > > > > > > > > the case > > > > > > > > of OS shutdown/restart comes straight out of the kernel doc > > > > > > > > "driver > > > > > > > > instance overview" in drm_drv.c. > > > > > > > > > > > > > > > > Suggested-by: Maxime Ripard > > > > > > > > Cc: Alex Deucher > > > > > > > > Cc: Christian König > > > > > > > > Cc: Xinhui Pan > > > > > > > > Signed-off-by: Douglas Anderson > > > > > > > > --- > > > > > > > > This commit is only compile-time tested. > > > > > > > > > > > > > > > > ...and further, I'd say that this patch is more of a plea for > > > > > > > > help > > > > > > > > than a patch I think is actually right. I'm _fairly_ certain > > > > > > > > that > > > > > > > > drm/amdgpu needs this call at shutdown time but the logic is a > > > > > > > > bit > > > > > > > > hard for me to follow. I'd appreciate if anyone who actually > > > > > > > > knows > > > > > > > > what this should look like could illuminate me, or perhaps even > > > > > > > > just > > > > > > > > post a patch themselves! > > > > > > > > > > > > > > I'm not sure this patch makes sense or not. The driver doesn't > > > > > > > really > > > > > > > do a formal tear down in its shutdown routine, it just quiesces > > > > > > > the > > > > > > > hardware. What are the actual requirements of the shutdown > > > > > > > function? > > > > > > > In the past when we did a full driver tear down in shutdown, it > > > > > > > delayed the shutdown sequence and users complained. > > > > > > > > > > > > The "inspiration" for this patch is to handle panels properly. > > > > > > Specifically, panels often have several power/enable signals going > > > > > > to > > > > > > them and often have requirements that these signals are powered off > > > > > > in > > > > > > the proper order with the proper delays between them. While we can't > > > > > > always do so when the system crashes / reboots in an uncontrolled > > > > > > way, > > > > > > panel manufacturers / HW Engineers get upset if we don't power > > > > > > things > > > > > > off properly during an orderly shutdown/reboot. When panels are > > > > > > powered off badly it can cause garbage on the screen and, so I've > > > > > > been > > > > > > told, can even cause long term damage to the panels over time. > > > > > > > > > > > > In Linux, some panel drivers have tried to ensure a proper poweroff > > > > > > of > > > > > > the panel by handling the shutdown() call themselves. However, this > > > > > > is > > > > > > ugly and panel maintainers want panel drivers to stop doing it. We > > > > > > have removed the code doing this from most panels now [1]. Instead > > > > > > the > > > > > > assumption is that the DRM modeset drivers should be calling > > > > > > drm_atomic_helper_shutdown() which will make sure panels get an > > > > > > orderly shutdown. > > > > > > > > > > > > For a lot more details, see the cover letter [2] which then contains > > > > > > links to even more discussions about the topic. > > > > > > > > > > > > [1] > > > > > > https://lore.kernel.org/r/20240605002401.2848541-1-diand...@chromium.org > > > > > > [2] > > > > > > https://lore.kernel.org/r/2024061435.3188234-1-diand...@chromium.org > > > > > > > > > > I don't think it's an issue. We quiesce the hardware as if we were > > > > > about to suspend the system (e.g., S3). For the display hardware we > > > > > call drm_atomic_helper_suspend() as part of that sequence. > > > > > > > > OK. It's no skin off my teeth and we can drop this patch if you're > > > > convinced it's not needed. From the point of view of someone who has > > > > no experience with this driver it seems weird to me that it would use > > > > drm_atomic_helper_suspend() at shutdown time instead of the documented > > > > drm_atomic_helper_shutdown(), but if it works for everyone then I'm > > > > not gonn
Re: [PATCH 1/6] drm/amdgpu: allow ioctls to opt-out of runtime pm
Le 19/06/2024 à 11:26, Christian König a écrit : Am 18.06.24 um 17:23 schrieb Pierre-Eric Pelloux-Prayer: Waking up a device can take multiple seconds, so if it's not going to be used we might as well not resume it. The safest default behavior for all ioctls is to resume the GPU, so this change allows specific ioctls to opt-out of generic runtime pm. I'm really wondering if we shouldn't put that into the IOCTL description. See amdgpu_ioctls_kms and DRM_IOCTL_DEF_DRV() for what I mean. Are you suggesting to add a new entry in enum drm_ioctl_flags to indicate ioctls which need the device to be awake? Something like: "DRM_NO_DEVICE = BIT(6)" and then use it for both core and amdgpu ioctls? Pierre-Eric Regards, Christian. Signed-off-by: Pierre-Eric Pelloux-Prayer --- drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c | 25 - 1 file changed, 20 insertions(+), 5 deletions(-) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c index 60d5758939ae..a9831b243bfc 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c @@ -2855,18 +2855,33 @@ long amdgpu_drm_ioctl(struct file *filp, { struct drm_file *file_priv = filp->private_data; struct drm_device *dev; + bool needs_device; long ret; dev = file_priv->minor->dev; - ret = pm_runtime_get_sync(dev->dev); - if (ret < 0) - goto out; + + /* Some ioctl can opt-out of powermanagement handling + * if they don't require the device to be resumed. + */ + switch (cmd) { + default: + needs_device = true; + } + + if (needs_device) { + ret = pm_runtime_get_sync(dev->dev); + if (ret < 0) + goto out; + } ret = drm_ioctl(filp, cmd, arg); - pm_runtime_mark_last_busy(dev->dev); out: - pm_runtime_put_autosuspend(dev->dev); + if (needs_device) { + pm_runtime_mark_last_busy(dev->dev); + pm_runtime_put_autosuspend(dev->dev); + } + return ret; }
Re: [PATCH 4/6] drm/amdgpu: add AMDGPU_INFO_GB_ADDR_CONFIG query
Both versions are fine by me, so I'll update the code to match whatever you agree on. Pierre-Eric Le 19/06/2024 à 20:44, Marek Olšák a écrit : The INFO ioctl was designed to allow increasing the sizes of all info structures. GB_ADDR_CONFIG isn't that special to justify a separate query. Marek On Wed, Jun 19, 2024 at 5:31 AM Christian König wrote: I would try to avoid that. Putting everything into amdgpu_info_device was a mistake only done because people assumed that IOCTLs on Linux are to expensive to query all information separately. We should rather have distinct IOCTLs for each value because that is way more flexible and we won't find later that we have to deprecate fields and work around issues because of legacy hw. Regards, Christian. Am 19.06.24 um 02:34 schrieb Marek Olšák: I would put this into drm_amdgpu_info_device. That structure can grow in size. Marek On Tue, Jun 18, 2024 at 11:30 AM Pierre-Eric Pelloux-Prayer wrote: libdrm_amdgpu uses AMDGPU_INFO_READ_MMR_REG to fill the dev->info.gb_addr_cfg value. Since this value is already known by the kernel, this commit implements a new query to return it. The libdrm MR to use this query is: https://gitlab.freedesktop.org/mesa/drm/-/merge_requests/368 Signed-off-by: Pierre-Eric Pelloux-Prayer --- drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c | 3 ++- drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c | 5 + include/uapi/drm/amdgpu_drm.h | 2 ++ 3 files changed, 9 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c index f51f121d804e..403add7f05af 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c @@ -117,9 +117,10 @@ * - 3.56.0 - Update IB start address and size alignment for decode and encode * - 3.57.0 - Compute tunneling on GFX10+ * - 3.58.0 - Add AMDGPU_IDS_FLAGS_MODE_PF, AMDGPU_IDS_FLAGS_MODE_VF & AMDGPU_IDS_FLAGS_MODE_PT + * - 3.59.0 - Add AMDGPU_INFO_GB_ADDR_CONFIG support */ #define KMS_DRIVER_MAJOR 3 -#define KMS_DRIVER_MINOR 58 +#define KMS_DRIVER_MINOR 59 #define KMS_DRIVER_PATCHLEVEL 0 /* diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c index b32ff6e1baaf..dbb05d51682b 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c @@ -1256,6 +1256,10 @@ static int amdgpu_info(struct drm_device *dev, void *data, struct drm_file *filp return copy_to_user(out, &gpuvm_fault, min((size_t)size, sizeof(gpuvm_fault))) ? -EFAULT : 0; } + case AMDGPU_INFO_GB_ADDR_CONFIG: { + ui32 = adev->gfx.config.gb_addr_config; + return copy_to_user(out, &ui32, min(size, 4u)) ? -EFAULT : 0; + } default: DRM_DEBUG_KMS("Invalid request %d\n", info->query); return -EINVAL; @@ -1310,6 +1314,7 @@ int amdgpu_info_ioctl(struct drm_device *dev, void *data, struct drm_file *filp) case AMDGPU_INFO_VIDEO_CAPS: case AMDGPU_INFO_MAX_IBS: case AMDGPU_INFO_GPUVM_FAULT: + case AMDGPU_INFO_GB_ADDR_CONFIG: need_runtime_pm = false; break; diff --git a/include/uapi/drm/amdgpu_drm.h b/include/uapi/drm/amdgpu_drm.h index 3e488b0119eb..680492cd73d8 100644 --- a/include/uapi/drm/amdgpu_drm.h +++ b/include/uapi/drm/amdgpu_drm.h @@ -933,6 +933,8 @@ struct drm_amdgpu_cs_chunk_cp_gfx_shadow { #define AMDGPU_INFO_MAX_IBS0x22 /* query last page fault info */ #define AMDGPU_INFO_GPUVM_FAULT0x23 +/* Query GB_ADDR_CONFIG */ +#define AMDGPU_INFO_GB_ADDR_CONFIG 0x24 #define AMDGPU_INFO_MMR_SE_INDEX_SHIFT 0 #define AMDGPU_INFO_MMR_SE_INDEX_MASK 0xff -- 2.40.1
Re: [PATCH] drm/amdgpu: access ltr through pci cfg space
On Thu, Jun 20, 2024 at 3:02 AM Min, Frank wrote: > > [AMD Official Use Only - AMD Internal Distribution Only] > > From: Frank Min > > Access ltr through pci cfg space instead of mmio while programing aspm on > gfx12 > > Signed-off-by: Frank Min Acked-by: Alex Deucher > --- > drivers/gpu/drm/amd/amdgpu/nbif_v6_3_1.c | 14 ++ > 1 file changed, 10 insertions(+), 4 deletions(-) > > diff --git a/drivers/gpu/drm/amd/amdgpu/nbif_v6_3_1.c > b/drivers/gpu/drm/amd/amdgpu/nbif_v6_3_1.c > index 5a20bb229788..39919e0892c1 100644 > --- a/drivers/gpu/drm/amd/amdgpu/nbif_v6_3_1.c > +++ b/drivers/gpu/drm/amd/amdgpu/nbif_v6_3_1.c > @@ -345,6 +345,7 @@ static void nbif_v6_3_1_program_aspm(struct amdgpu_device > *adev) { #ifdef CONFIG_PCIEASPM > uint32_t def, data; > + u16 devctl2, ltr; > > def = data = RREG32_SOC15(PCIE, 0, regPCIE_LC_CNTL); > data &= ~PCIE_LC_CNTL__LC_L1_INACTIVITY_MASK; > @@ -374,12 +375,17 @@ static void nbif_v6_3_1_program_aspm(struct > amdgpu_device *adev) > if (def != data) > WREG32_SOC15(NBIO, 0, regRCC_STRAP0_RCC_BIF_STRAP5, data); > > - def = data = RREG32_SOC15(NBIO, 0, regBIF_CFG_DEV0_EPF0_DEVICE_CNTL2); > - data &= ~BIF_CFG_DEV0_EPF0_DEVICE_CNTL2__LTR_EN_MASK; > + pcie_capability_read_word(adev->pdev, PCI_EXP_DEVCTL2, &devctl2); > + data = def = devctl2; > + data &= ~PCI_EXP_DEVCTL2_LTR_EN; > if (def != data) > - WREG32_SOC15(NBIO, 0, regBIF_CFG_DEV0_EPF0_DEVICE_CNTL2, > data); > + pcie_capability_set_word(adev->pdev, PCI_EXP_DEVCTL2, > (u16)data); > + > + ltr = pci_find_ext_capability(adev->pdev, PCI_EXT_CAP_ID_LTR); > > - WREG32_SOC15(NBIO, 0, regBIF_CFG_DEV0_EPF0_PCIE_LTR_CAP, 0x10011001); > + if (ltr) { > + pci_write_config_dword(adev->pdev, ltr + > PCI_LTR_MAX_SNOOP_LAT, 0x10011001); > + } > > #if 0 > /* regPSWUSP0_PCIE_LC_CNTL2 should be replace by PCIE_LC_CNTL2 or > someone else ? */ > -- > 2.34.1 >
Re: [PATCH 1/6] drm/amdgpu: allow ioctls to opt-out of runtime pm
Am 20.06.24 um 15:06 schrieb Pierre-Eric Pelloux-Prayer: Le 19/06/2024 à 11:26, Christian König a écrit : Am 18.06.24 um 17:23 schrieb Pierre-Eric Pelloux-Prayer: Waking up a device can take multiple seconds, so if it's not going to be used we might as well not resume it. The safest default behavior for all ioctls is to resume the GPU, so this change allows specific ioctls to opt-out of generic runtime pm. I'm really wondering if we shouldn't put that into the IOCTL description. See amdgpu_ioctls_kms and DRM_IOCTL_DEF_DRV() for what I mean. Are you suggesting to add a new entry in enum drm_ioctl_flags to indicate ioctls which need the device to be awake? Something like: "DRM_NO_DEVICE = BIT(6)" and then use it for both core and amdgpu ioctls? Yeah something like that. Maybe name that DRM_SW_ONLY or something like that. Christian. Pierre-Eric Regards, Christian. Signed-off-by: Pierre-Eric Pelloux-Prayer --- drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c | 25 - 1 file changed, 20 insertions(+), 5 deletions(-) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c index 60d5758939ae..a9831b243bfc 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c @@ -2855,18 +2855,33 @@ long amdgpu_drm_ioctl(struct file *filp, { struct drm_file *file_priv = filp->private_data; struct drm_device *dev; + bool needs_device; long ret; dev = file_priv->minor->dev; - ret = pm_runtime_get_sync(dev->dev); - if (ret < 0) - goto out; + + /* Some ioctl can opt-out of powermanagement handling + * if they don't require the device to be resumed. + */ + switch (cmd) { + default: + needs_device = true; + } + + if (needs_device) { + ret = pm_runtime_get_sync(dev->dev); + if (ret < 0) + goto out; + } ret = drm_ioctl(filp, cmd, arg); - pm_runtime_mark_last_busy(dev->dev); out: - pm_runtime_put_autosuspend(dev->dev); + if (needs_device) { + pm_runtime_mark_last_busy(dev->dev); + pm_runtime_put_autosuspend(dev->dev); + } + return ret; }
[PATCH] drm/amdgpu: normalize registers as local xcc to read/write under sriov in TLB flush
[WHY] sriov has the higher bit violation when flushing tlb [HOW] normalize the registers to keep lower 16-bit(dword aligned) to aviod higher bit violation RLCG will mask xcd out and always assume it's accessing its own xcd [TODO] later will add the normalization in sriovw/rreg after fixing bugs v2 rename the normalized macro, add ip block type for further use move asics func declaration after ip block type since new func refers ip block type Signed-off-by: Jane Jian --- amdgpu.h| 112 +++-- aqua_vanjaram.c | 16 +++ gmc_v9_0.c | 8 +- soc15.c | 1 + soc15.h | 1 + soc15_common.h | 5 +- 6 files changed, 85 insertions(+), 58 deletions(-) diff --git a/amdgpu.h b/amdgpu.h index 083f353cff6e..070fd9e601fe 100644 --- a/amdgpu.h +++ b/amdgpu.h @@ -583,61 +583,6 @@ struct amdgpu_video_codecs { const struct amdgpu_video_codec_info *codec_array; }; -/* - * ASIC specific functions. - */ -struct amdgpu_asic_funcs { - bool (*read_disabled_bios)(struct amdgpu_device *adev); - bool (*read_bios_from_rom)(struct amdgpu_device *adev, - u8 *bios, u32 length_bytes); - int (*read_register)(struct amdgpu_device *adev, u32 se_num, -u32 sh_num, u32 reg_offset, u32 *value); - void (*set_vga_state)(struct amdgpu_device *adev, bool state); - int (*reset)(struct amdgpu_device *adev); - enum amd_reset_method (*reset_method)(struct amdgpu_device *adev); - /* get the reference clock */ - u32 (*get_xclk)(struct amdgpu_device *adev); - /* MM block clocks */ - int (*set_uvd_clocks)(struct amdgpu_device *adev, u32 vclk, u32 dclk); - int (*set_vce_clocks)(struct amdgpu_device *adev, u32 evclk, u32 ecclk); - /* static power management */ - int (*get_pcie_lanes)(struct amdgpu_device *adev); - void (*set_pcie_lanes)(struct amdgpu_device *adev, int lanes); - /* get config memsize register */ - u32 (*get_config_memsize)(struct amdgpu_device *adev); - /* flush hdp write queue */ - void (*flush_hdp)(struct amdgpu_device *adev, struct amdgpu_ring *ring); - /* invalidate hdp read cache */ - void (*invalidate_hdp)(struct amdgpu_device *adev, - struct amdgpu_ring *ring); - /* check if the asic needs a full reset of if soft reset will work */ - bool (*need_full_reset)(struct amdgpu_device *adev); - /* initialize doorbell layout for specific asic*/ - void (*init_doorbell_index)(struct amdgpu_device *adev); - /* PCIe bandwidth usage */ - void (*get_pcie_usage)(struct amdgpu_device *adev, uint64_t *count0, - uint64_t *count1); - /* do we need to reset the asic at init time (e.g., kexec) */ - bool (*need_reset_on_init)(struct amdgpu_device *adev); - /* PCIe replay counter */ - uint64_t (*get_pcie_replay_count)(struct amdgpu_device *adev); - /* device supports BACO */ - int (*supports_baco)(struct amdgpu_device *adev); - /* pre asic_init quirks */ - void (*pre_asic_init)(struct amdgpu_device *adev); - /* enter/exit umd stable pstate */ - int (*update_umd_stable_pstate)(struct amdgpu_device *adev, bool enter); - /* query video codecs */ - int (*query_video_codecs)(struct amdgpu_device *adev, bool encode, - const struct amdgpu_video_codecs **codecs); - /* encode "> 32bits" smn addressing */ - u64 (*encode_ext_smn_addressing)(int ext_id); - - ssize_t (*get_reg_state)(struct amdgpu_device *adev, -enum amdgpu_reg_state reg_state, void *buf, -size_t max_size); -}; - /* * IOCTL. */ @@ -728,6 +673,63 @@ enum amd_hw_ip_block_type { MAX_HWIP }; +/* + * ASIC specific functions. + */ +struct amdgpu_asic_funcs { + bool (*read_disabled_bios)(struct amdgpu_device *adev); + bool (*read_bios_from_rom)(struct amdgpu_device *adev, + u8 *bios, u32 length_bytes); + int (*read_register)(struct amdgpu_device *adev, u32 se_num, +u32 sh_num, u32 reg_offset, u32 *value); + void (*set_vga_state)(struct amdgpu_device *adev, bool state); + int (*reset)(struct amdgpu_device *adev); + enum amd_reset_method (*reset_method)(struct amdgpu_device *adev); + /* get the reference clock */ + u32 (*get_xclk)(struct amdgpu_device *adev); + /* MM block clocks */ + int (*set_uvd_clocks)(struct amdgpu_device *adev, u32 vclk, u32 dclk); + int (*set_vce_clocks)(struct amdgpu_device *adev, u32 evclk, u32 ecclk); + /* static power management */ + int (*get_pcie_lanes)(struct amdgpu_device *adev); + void (*set_pcie_lanes)(struct amdgpu_device *adev, int lanes); + /* get config memsize register */ + u32 (*get_co
[PATCH] drm/amdgpu: clear IH_RB_W/RPTR during enabling interrupts in sriov case
Clearing the IH_RB_W/RPTR during interrupts disable is not clearing the RB_OVERFLOW bit. Adding workaround to clear the wptr when enabling interrupts in case RB_OVERFLOW bit is set. Signed-off-by: Danijel Slivka --- drivers/gpu/drm/amd/amdgpu/ih_v6_0.c | 6 ++ 1 file changed, 6 insertions(+) diff --git a/drivers/gpu/drm/amd/amdgpu/ih_v6_0.c b/drivers/gpu/drm/amd/amdgpu/ih_v6_0.c index 3cb64c8f7175..d6212a98ca99 100644 --- a/drivers/gpu/drm/amd/amdgpu/ih_v6_0.c +++ b/drivers/gpu/drm/amd/amdgpu/ih_v6_0.c @@ -147,6 +147,12 @@ static int ih_v6_0_toggle_ring_interrupts(struct amdgpu_device *adev, } if (enable) { + if (amdgpu_sriov_vf(adev) && + REG_GET_FIELD(RREG32(ih_regs->ih_rb_wptr), IH_RB_WPTR, RB_OVERFLOW)) { + /* clear rptr, wptr*/ + WREG32(ih_regs->ih_rb_rptr, 0); + WREG32(ih_regs->ih_rb_wptr, 0); + } ih->enabled = true; } else { /* set rptr, wptr to 0 */ -- 2.34.1
[PATCH] drm/amdgpu: update gfxhub client id for gfx12
[AMD Official Use Only - AMD Internal Distribution Only] From: Frank Min update gfxhub client id for gfx12 Signed-off-by: Frank Min --- drivers/gpu/drm/amd/amdgpu/gfxhub_v12_0.c | 22 +- 1 file changed, 21 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/amd/amdgpu/gfxhub_v12_0.c b/drivers/gpu/drm/amd/amdgpu/gfxhub_v12_0.c index 7ea64f1e1e48..7609b9cecae8 100644 --- a/drivers/gpu/drm/amd/amdgpu/gfxhub_v12_0.c +++ b/drivers/gpu/drm/amd/amdgpu/gfxhub_v12_0.c @@ -35,7 +35,27 @@ #define regGRBM_GFX_INDEX_DEFAULT 0xe000 static const char *gfxhub_client_ids[] = { - /* TODO */ + "CB", + "DB", + "GE1", + "GE2", + "CPF", + "CPC", + "CPG", + "RLC", + "TCP", + "SQC (inst)", + "SQC (data)", + "SQG/PC/SC", + "Reserved", + "SDMA0", + "SDMA1", + "GCR", + "Reserved", + "Reserved", + "WGS", + "DSM", + "PA" }; static uint32_t gfxhub_v12_0_get_invalidate_req(unsigned int vmid, -- 2.34.1
Re: [PATCH 2/2] Revert "drm/amd/amdgpu: add module parameter for jpeg"
[AMD Official Use Only - AMD Internal Distribution Only] Series is: Reviewed-by: Sonny Jiang From: Alex Deucher Sent: Thursday, June 20, 2024 8:48 AM To: Feng, Kenneth Cc: amd-gfx@lists.freedesktop.org ; Jiang, Sonny Subject: Re: [PATCH 2/2] Revert "drm/amd/amdgpu: add module parameter for jpeg" On Wed, Jun 19, 2024 at 9:32 PM Kenneth Feng wrote: > > This reverts commit 63400bcf5cb23b6a9b674eb3f2d733d826860065. > Revert this due to a final solution in amdgu vcn: > commit eef47ed5f703377781ce89eae4b9140325049873 > Author: Sonny Jiang > Date: Tue Jun 18 11:11:11 2024 -0400 > > drm/amdgpu/jpeg5: reprogram doorbell setting after power up for each playback > > Doorbell needs to be configured after power up during each playback > > Signed-off-by: Kenneth Feng Series is: Acked-by: Alex Deucher > --- > drivers/gpu/drm/amd/amdgpu/amdgpu.h | 2 -- > drivers/gpu/drm/amd/amdgpu/amdgpu_discovery.c | 2 -- > drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c | 4 > 3 files changed, 8 deletions(-) > > diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu.h > b/drivers/gpu/drm/amd/amdgpu/amdgpu.h > index 6129f9f7a577..137a88b8de45 100644 > --- a/drivers/gpu/drm/amd/amdgpu/amdgpu.h > +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu.h > @@ -224,7 +224,6 @@ extern int amdgpu_mes; > extern int amdgpu_mes_log_enable; > extern int amdgpu_mes_kiq; > extern int amdgpu_uni_mes; > -extern int amdgpu_jpeg_test; > extern int amdgpu_noretry; > extern int amdgpu_force_asic_type; > extern int amdgpu_smartshift_bias; > @@ -1022,7 +1021,6 @@ struct amdgpu_device { > > /* jpeg */ > struct amdgpu_jpeg jpeg; > - bool enable_jpeg_test; > > /* vpe */ > struct amdgpu_vpe vpe; > diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_discovery.c > b/drivers/gpu/drm/amd/amdgpu/amdgpu_discovery.c > index 4edcbd272fa4..df753ebfd109 100644 > --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_discovery.c > +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_discovery.c > @@ -2302,8 +2302,6 @@ static int amdgpu_discovery_set_mm_ip_blocks(struct > amdgpu_device *adev) > case IP_VERSION(5, 0, 0): > amdgpu_device_ip_block_add(adev, > &vcn_v5_0_0_ip_block); > amdgpu_device_ip_block_add(adev, > &jpeg_v5_0_0_ip_block); > - if (amdgpu_jpeg_test) > - adev->enable_jpeg_test = true; > break; > default: > dev_err(adev->dev, > diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c > b/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c > index 60d5758939ae..802debd8d9f0 100644 > --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c > +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c > @@ -205,7 +205,6 @@ int amdgpu_force_asic_type = -1; > int amdgpu_tmz = -1; /* auto */ > uint amdgpu_freesync_vid_mode; > int amdgpu_reset_method = -1; /* auto */ > -int amdgpu_jpeg_test; > int amdgpu_num_kcq = -1; > int amdgpu_smartshift_bias; > int amdgpu_use_xgmi_p2p = 1; > @@ -941,9 +940,6 @@ module_param_named(freesync_video, > amdgpu_freesync_vid_mode, uint, 0444); > MODULE_PARM_DESC(reset_method, "GPU reset method (-1 = auto (default), 0 = > legacy, 1 = mode0, 2 = mode1, 3 = mode2, 4 = baco/bamaco)"); > module_param_named(reset_method, amdgpu_reset_method, int, 0644); > > -MODULE_PARM_DESC(jpeg_test, "jpeg test(0 = disable (default), 1 = enable)"); > -module_param_named(jpeg_test, amdgpu_jpeg_test, int, 0444); > - > /** > * DOC: bad_page_threshold (int) Bad page threshold is specifies the > * threshold value of faulty pages detected by RAS ECC, which may > -- > 2.34.1 >
RE: [PATCH] drm/amdgpu: track bo memory stats at runtime
[Public] > > + dma_resv_lock(bo->tbo.base.resv, NULL); > > Why do you grab the BO lock to update the stats? That doesn't seem to make > any sense. > > > + update_stats = !(bo->flags & AMDGPU_GEM_WAS_EXPORTED); > > + if (update_stats) > > + amdgpu_bo_add_memory(bo, &stats); > > + else > > + dma_resv_unlock(bo->tbo.base.resv); > > + > > buf = drm_gem_prime_export(gobj, flags); > > - if (!IS_ERR(buf)) > > + if (!IS_ERR(buf)) { > > buf->ops = &amdgpu_dmabuf_ops; > > + if (update_stats) { > > + for (base = bo->vm_bo; base; base = base->next) { > > + spin_lock(&base->vm->status_lock); > > + base->vm->stats.vram_shared += stats.vram; > > + base->vm->stats.gtt_shared += stats.gtt; > > + base->vm->stats.cpu_shared += stats.cpu; > > + spin_unlock(&base->vm->status_lock); > > + } > > + bo->flags |= AMDGPU_GEM_WAS_EXPORTED; > > + dma_resv_unlock(bo->tbo.base.resv); The thought here is that I don't want two exports of the same buffer to race here and increase the stats twice. But if BO can only be exported once then yes this is not needed. > Don't touch any VM internals from the BO code. > Don't touch any VM internals in TTM code. What would be the preferred approach? I can put a small helper in amdgpu_vm or amdgpu_bo I suppose. > > #define AMDGPU_GEM_CREATE_GFX12_DCC (1 << 16) > > > > +/* Flag that BO was exported at one point and counts torwards the > "shared" > > + * memory stats. Once set it does not get cleared until the BO is > > destroyed. > > + */ > > +#define AMDGPU_GEM_WAS_EXPORTED(1 << 17) > > + > > Absolutely clear NAK to that approach. This is not even remotely an allocation > flag but some status. > > Additional to that completely unnecessary since BOs are usually only exported > once. If BOs can only be exported once then we don't need this kind of marker, but I think user space is free to export as many times as they wish right? I first tried to handle the unshare case as well, but I don't see any where in that path we can easily hook into. I can give it another try. Regards, Teddy
Re: [PATCH] drm/amdgpu: update gfxhub client id for gfx12
On Thu, Jun 20, 2024 at 10:32 AM Min, Frank wrote: > > [AMD Official Use Only - AMD Internal Distribution Only] > > From: Frank Min Acked-by: Alex Deucher > > update gfxhub client id for gfx12 > > Signed-off-by: Frank Min > --- > drivers/gpu/drm/amd/amdgpu/gfxhub_v12_0.c | 22 +- > 1 file changed, 21 insertions(+), 1 deletion(-) > > diff --git a/drivers/gpu/drm/amd/amdgpu/gfxhub_v12_0.c > b/drivers/gpu/drm/amd/amdgpu/gfxhub_v12_0.c > index 7ea64f1e1e48..7609b9cecae8 100644 > --- a/drivers/gpu/drm/amd/amdgpu/gfxhub_v12_0.c > +++ b/drivers/gpu/drm/amd/amdgpu/gfxhub_v12_0.c > @@ -35,7 +35,27 @@ > #define regGRBM_GFX_INDEX_DEFAULT 0xe000 > > static const char *gfxhub_client_ids[] = { > - /* TODO */ > + "CB", > + "DB", > + "GE1", > + "GE2", > + "CPF", > + "CPC", > + "CPG", > + "RLC", > + "TCP", > + "SQC (inst)", > + "SQC (data)", > + "SQG/PC/SC", > + "Reserved", > + "SDMA0", > + "SDMA1", > + "GCR", > + "Reserved", > + "Reserved", > + "WGS", > + "DSM", > + "PA" > }; > > static uint32_t gfxhub_v12_0_get_invalidate_req(unsigned int vmid, > -- > 2.34.1 >
Re: [PATCH] drm/amdgpu: track bo memory stats at runtime
Am 20.06.24 um 16:30 schrieb Li, Yunxiang (Teddy): [Public] + dma_resv_lock(bo->tbo.base.resv, NULL); Why do you grab the BO lock to update the stats? That doesn't seem to make any sense. + update_stats = !(bo->flags & AMDGPU_GEM_WAS_EXPORTED); + if (update_stats) + amdgpu_bo_add_memory(bo, &stats); + else + dma_resv_unlock(bo->tbo.base.resv); + buf = drm_gem_prime_export(gobj, flags); - if (!IS_ERR(buf)) + if (!IS_ERR(buf)) { buf->ops = &amdgpu_dmabuf_ops; + if (update_stats) { + for (base = bo->vm_bo; base; base = base->next) { + spin_lock(&base->vm->status_lock); + base->vm->stats.vram_shared += stats.vram; + base->vm->stats.gtt_shared += stats.gtt; + base->vm->stats.cpu_shared += stats.cpu; + spin_unlock(&base->vm->status_lock); + } + bo->flags |= AMDGPU_GEM_WAS_EXPORTED; + dma_resv_unlock(bo->tbo.base.resv); The thought here is that I don't want two exports of the same buffer to race here and increase the stats twice. But if BO can only be exported once then yes this is not needed. Don't touch any VM internals from the BO code. Don't touch any VM internals in TTM code. What would be the preferred approach? I can put a small helper in amdgpu_vm or amdgpu_bo I suppose. In general the VM should already have most of the necessary functionality. amdgpu_vm_bo_add() is called when a BO is initially added to the VM. amdgpu_vm_bo_del() is called when a BO is removed from the VM. amdgpu_vm_bo_invalidate() is called when a BO moves. This needs to be improved to take old_mem/new_mem as well. Then you only need another function which signals that the BO is exported and you should be done. Regards, Christian. #define AMDGPU_GEM_CREATE_GFX12_DCC (1 << 16) +/* Flag that BO was exported at one point and counts torwards the "shared" + * memory stats. Once set it does not get cleared until the BO is destroyed. + */ +#define AMDGPU_GEM_WAS_EXPORTED(1 << 17) + Absolutely clear NAK to that approach. This is not even remotely an allocation flag but some status. Additional to that completely unnecessary since BOs are usually only exported once. If BOs can only be exported once then we don't need this kind of marker, but I think user space is free to export as many times as they wish right? I first tried to handle the unshare case as well, but I don't see any where in that path we can easily hook into. I can give it another try. Regards, Teddy
[RFC PATCH 0/2] drm/amdgpu: Convert to ttm_bo_vmap()
Convert amdgpu to use ttm_bo_vmap() instead of ttm_bo_kmap(). The latter is deprecated. Passing ttm_bo_vmap()'s locking validation requires to remove the implicit unmap from the BO release path. Smoke-tested with an Radeon RX 460. There's similar patchset for xe at [1], which requires additional changes. [1] https://lore.kernel.org/dri-devel/20240614133556.11378-1-tzimmerm...@suse.de/ Thomas Zimmermann (2): drm/amdgpu: Unmap BO memory before calling amdgpu_bo_unref() drm/amdgpu: Convert to ttm_bo_vmap() et al drivers/gpu/drm/amd/amdgpu/amdgpu_object.c | 25 ++ drivers/gpu/drm/amd/amdgpu/amdgpu_object.h | 4 +++- 2 files changed, 19 insertions(+), 10 deletions(-) -- 2.45.2
[PATCH 2/2] drm/amdgpu: Convert to ttm_bo_vmap() et al
Replace each call to ttm_bo_kmap() with a call to ttm_bo_vmap(). Same for ttm_bo_kunmap() and ttm_bo_vunmap(). There's now one less driver depending on the deprecated ttm_bo_kmap(). Also allows for dropping struct ttm_bo_kmap_obj in favor of struct iosys_map, which is the preferred representation of BO memory mappings. Manual type conversion in amdgpu_bo_kptr() is required to make the returned pointer usable within amdgpu. In a follow-up patch, amdgpu should be convert to use struct iosys_map directly. Signed-off-by: Thomas Zimmermann --- drivers/gpu/drm/amd/amdgpu/amdgpu_object.c | 16 ++-- drivers/gpu/drm/amd/amdgpu/amdgpu_object.h | 4 +++- 2 files changed, 13 insertions(+), 7 deletions(-) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c index d58b11ea0ead5..baa60e25c13e1 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c @@ -62,7 +62,7 @@ static void amdgpu_bo_destroy(struct ttm_buffer_object *tbo) * BO memory pages should be unmapped at this point. Call * amdgpu_bo_kunmap() before releasing the BO. */ - if (drm_WARN_ON_ONCE(bo->tbo.base.dev, bo->kmap.bo)) + if (drm_WARN_ON_ONCE(bo->tbo.base.dev, !iosys_map_is_null(&bo->map))) amdgpu_bo_kunmap(bo); if (bo->tbo.base.import_attach) @@ -802,7 +802,7 @@ int amdgpu_bo_kmap(struct amdgpu_bo *bo, void **ptr) return 0; } - r = ttm_bo_kmap(&bo->tbo, 0, PFN_UP(bo->tbo.base.size), &bo->kmap); + r = ttm_bo_vmap(&bo->tbo, &bo->map); if (r) return r; @@ -823,9 +823,12 @@ int amdgpu_bo_kmap(struct amdgpu_bo *bo, void **ptr) */ void *amdgpu_bo_kptr(struct amdgpu_bo *bo) { - bool is_iomem; + if (iosys_map_is_null(&bo->map)) + return NULL; + if (bo->map.is_iomem) + return (void __force *)bo->map.vaddr_iomem; - return ttm_kmap_obj_virtual(&bo->kmap, &is_iomem); + return bo->map.vaddr; } /** @@ -836,8 +839,9 @@ void *amdgpu_bo_kptr(struct amdgpu_bo *bo) */ void amdgpu_bo_kunmap(struct amdgpu_bo *bo) { - if (bo->kmap.bo) - ttm_bo_kunmap(&bo->kmap); + if (iosys_map_is_null(&bo->map)) + return; + ttm_bo_vunmap(&bo->tbo, &bo->map); } /** diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_object.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_object.h index bc42ccbde659a..553a92303339f 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_object.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_object.h @@ -28,6 +28,8 @@ #ifndef __AMDGPU_OBJECT_H__ #define __AMDGPU_OBJECT_H__ +#include + #include #include "amdgpu.h" #include "amdgpu_res_cursor.h" @@ -99,7 +101,7 @@ struct amdgpu_bo { struct ttm_placeplacements[AMDGPU_BO_MAX_PLACEMENTS]; struct ttm_placementplacement; struct ttm_buffer_objecttbo; - struct ttm_bo_kmap_obj kmap; + struct iosys_mapmap; u64 flags; /* per VM structure for page tables and with virtual addresses */ struct amdgpu_vm_bo_base*vm_bo; -- 2.45.2
[PATCH 1/2] drm/amdgpu: Unmap BO memory before calling amdgpu_bo_unref()
Prepares for using ttm_bo_vmap() and ttm_bo_vunmap() in amdgpu. Both require the caller to hold the GEM reservation lock, which is not the case while releasing a buffer object. Hence, push a possible call to unmap out from the buffer-object release code. Warn if a buffer object with mapped pages is supposed to be released. Signed-off-by: Thomas Zimmermann --- drivers/gpu/drm/amd/amdgpu/amdgpu_object.c | 11 +++ 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c index a1b7438c43dc8..d58b11ea0ead5 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c @@ -58,7 +58,12 @@ static void amdgpu_bo_destroy(struct ttm_buffer_object *tbo) { struct amdgpu_bo *bo = ttm_to_amdgpu_bo(tbo); - amdgpu_bo_kunmap(bo); + /* +* BO memory pages should be unmapped at this point. Call +* amdgpu_bo_kunmap() before releasing the BO. +*/ + if (drm_WARN_ON_ONCE(bo->tbo.base.dev, bo->kmap.bo)) + amdgpu_bo_kunmap(bo); if (bo->tbo.base.import_attach) drm_prime_gem_destroy(&bo->tbo.base, bo->tbo.sg); @@ -450,9 +455,7 @@ void amdgpu_bo_free_kernel(struct amdgpu_bo **bo, u64 *gpu_addr, WARN_ON(amdgpu_ttm_adev((*bo)->tbo.bdev)->in_suspend); if (likely(amdgpu_bo_reserve(*bo, true) == 0)) { - if (cpu_addr) - amdgpu_bo_kunmap(*bo); - + amdgpu_bo_kunmap(*bo); amdgpu_bo_unpin(*bo); amdgpu_bo_unreserve(*bo); } -- 2.45.2
Re: [PATCH] drm/amdgpu: add missing error handling in function amdgpu_gmc_flush_gpu_tlb_pasid
On Thu, Jun 20, 2024 at 3:47 AM Bob Zhou wrote: > > Fix the unchecked return value warning by warning reported by > Coverity, so add error handling. > > Signed-off-by: Bob Zhou Looks like there are a few other places in the driver where amdgpu_ring_alloc() is not checked. Can you fix those up too? Reviewed-by: Alex Deucher > --- > drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.c | 6 +- > 1 file changed, 5 insertions(+), 1 deletion(-) > > diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.c > b/drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.c > index 322b8ff67cde..3a7622611916 100644 > --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.c > +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.c > @@ -718,7 +718,11 @@ int amdgpu_gmc_flush_gpu_tlb_pasid(struct amdgpu_device > *adev, uint16_t pasid, > ndw += kiq->pmf->invalidate_tlbs_size; > > spin_lock(&adev->gfx.kiq[inst].ring_lock); > - amdgpu_ring_alloc(ring, ndw); > + r = amdgpu_ring_alloc(ring, ndw); > + if (r) { > + spin_unlock(&adev->gfx.kiq[inst].ring_lock); > + goto error_unlock_reset; > + } > if (adev->gmc.flush_tlb_needs_extra_type_2) > kiq->pmf->kiq_invalidate_tlbs(ring, pasid, 2, > all_hub); > > -- > 2.34.1 >
Re: [PATCH] drm/amd/display: Clean up indenting in dm_dp_mst_is_port_support_mode()
Applied. Thanks! Alex On Thu, Jun 20, 2024 at 4:49 AM Dan Carpenter wrote: > > This code works, but it's not aligned correctly. Add a couple missing > tabs. > > Signed-off-by: Dan Carpenter > --- > drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c | 4 ++-- > 1 file changed, 2 insertions(+), 2 deletions(-) > > diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c > b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c > index 48118447c8d9..5d4f831b1e55 100644 > --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c > +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c > @@ -1691,7 +1691,7 @@ enum dc_status dm_dp_mst_is_port_support_mode( > if (aconnector->mst_output_port->passthrough_aux) { > if (bw_range.min_kbps > end_to_end_bw_in_kbps) { > DRM_DEBUG_DRIVER("DSC passthrough. Max dsc > compression can't fit into end-to-end bw\n"); > - return DC_FAIL_BANDWIDTH_VALIDATE; > + return DC_FAIL_BANDWIDTH_VALIDATE; > } > } else { > /*dsc bitstream decoded at the dp last link*/ > @@ -1756,7 +1756,7 @@ enum dc_status dm_dp_mst_is_port_support_mode( > if (branch_max_throughput_mps != 0 && > ((stream->timing.pix_clk_100hz / 10) > > branch_max_throughput_mps * 1000)) { > DRM_DEBUG_DRIVER("DSC is required but max throughput > mps fails"); > - return DC_FAIL_BANDWIDTH_VALIDATE; > + return DC_FAIL_BANDWIDTH_VALIDATE; > } > } else { > DRM_DEBUG_DRIVER("DSC is required but can't find common dsc > config."); > -- > 2.43.0 >
Re: [PATCH] drm/amd/display: Remove redundant code and semicolons
Applied. Thanks! Alex On Thu, Jun 20, 2024 at 5:07 AM Jiapeng Chong wrote: > > No functional modification involved. > > ./drivers/gpu/drm/amd/display/dc/dml2/dml21/src/dml2_core/dml2_core_shared.c:3171:2-3: > Unneeded semicolon. > ./drivers/gpu/drm/amd/display/dc/dml2/dml21/src/dml2_core/dml2_core_shared.c:3185:2-3: > Unneeded semicolon. > ./drivers/gpu/drm/amd/display/dc/dml2/dml21/src/dml2_core/dml2_core_shared.c:3200:2-3: > Unneeded semicolon. > > Reported-by: Abaci Robot > Closes: https://bugzilla.openanolis.cn/show_bug.cgi?id=9365 > Signed-off-by: Jiapeng Chong > --- > .../dml21/src/dml2_core/dml2_core_shared.c| 46 +-- > 1 file changed, 23 insertions(+), 23 deletions(-) > > diff --git > a/drivers/gpu/drm/amd/display/dc/dml2/dml21/src/dml2_core/dml2_core_shared.c > b/drivers/gpu/drm/amd/display/dc/dml2/dml21/src/dml2_core/dml2_core_shared.c > index cfa4c4475821..1a9895b1833f 100644 > --- > a/drivers/gpu/drm/amd/display/dc/dml2/dml21/src/dml2_core/dml2_core_shared.c > +++ > b/drivers/gpu/drm/amd/display/dc/dml2/dml21/src/dml2_core/dml2_core_shared.c > @@ -3142,62 +3142,62 @@ static unsigned int > dml_get_tile_block_size_bytes(enum dml2_swizzle_mode sw_mode > { > switch (sw_mode) { > case (dml2_sw_linear): > - return 256; break; > + return 256; > case (dml2_sw_256b_2d): > - return 256; break; > + return 256; > case (dml2_sw_4kb_2d): > - return 4096; break; > + return 4096; > case (dml2_sw_64kb_2d): > - return 65536; break; > + return 65536; > case (dml2_sw_256kb_2d): > - return 262144; break; > + return 262144; > case (dml2_gfx11_sw_linear): > - return 256; break; > + return 256; > case (dml2_gfx11_sw_64kb_d): > - return 65536; break; > + return 65536; > case (dml2_gfx11_sw_64kb_d_t): > - return 65536; break; > + return 65536; > case (dml2_gfx11_sw_64kb_d_x): > - return 65536; break; > + return 65536; > case (dml2_gfx11_sw_64kb_r_x): > - return 65536; break; > + return 65536; > case (dml2_gfx11_sw_256kb_d_x): > - return 262144; break; > + return 262144; > case (dml2_gfx11_sw_256kb_r_x): > - return 262144; break; > + return 262144; > default: > DML2_ASSERT(0); > return 256; > - }; > + } > } > > const char *dml2_core_internal_bw_type_str(enum dml2_core_internal_bw_type > bw_type) > { > switch (bw_type) { > case (dml2_core_internal_bw_sdp): > - return("dml2_core_internal_bw_sdp"); break; > + return("dml2_core_internal_bw_sdp"); > case (dml2_core_internal_bw_dram): > - return("dml2_core_internal_bw_dram"); break; > + return("dml2_core_internal_bw_dram"); > case (dml2_core_internal_bw_max): > - return("dml2_core_internal_bw_max"); break; > + return("dml2_core_internal_bw_max"); > default: > - return("dml2_core_internal_bw_unknown"); break; > - }; > + return("dml2_core_internal_bw_unknown"); > + } > } > > const char *dml2_core_internal_soc_state_type_str(enum > dml2_core_internal_soc_state_type dml2_core_internal_soc_state_type) > { > switch (dml2_core_internal_soc_state_type) { > case (dml2_core_internal_soc_state_sys_idle): > - return("dml2_core_internal_soc_state_sys_idle"); break; > + return("dml2_core_internal_soc_state_sys_idle"); > case (dml2_core_internal_soc_state_sys_active): > - return("dml2_core_internal_soc_state_sys_active"); break; > + return("dml2_core_internal_soc_state_sys_active"); > case (dml2_core_internal_soc_state_svp_prefetch): > - return("dml2_core_internal_soc_state_svp_prefetch"); break; > + return("dml2_core_internal_soc_state_svp_prefetch"); > case dml2_core_internal_soc_state_max: > default: > - return("dml2_core_internal_soc_state_unknown"); break; > - }; > + return("dml2_core_internal_soc_state_unknown"); > + } > } > > static bool dml_is_vertical_rotation(enum dml2_rotation_angle Scan) > -- > 2.20.1.7.g153144c >
Re: [PATCH] drm/amdgpu/kfd: Add unlock() on error path to add_queue_mes()
Applied. Thanks! Alex On Thu, Jun 20, 2024 at 5:07 AM Dan Carpenter wrote: > > We recently added locking to add_queue_mes() but this error path was > overlooked. Add an unlock to the error path. > > Fixes: 1802b042a343 ("drm/amdgpu/kfd: remove is_hws_hang and is_resetting") > Signed-off-by: Dan Carpenter > --- > drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.c | 1 + > 1 file changed, 1 insertion(+) > > diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.c > b/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.c > index d2fceb6f9802..4f48507418d2 100644 > --- a/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.c > +++ b/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.c > @@ -230,6 +230,7 @@ static int add_queue_mes(struct device_queue_manager > *dqm, struct queue *q, > if (queue_type < 0) { > dev_err(adev->dev, "Queue type not supported with MES, > queue:%d\n", > q->properties.type); > + up_read(&adev->reset_domain->sem); > return -EINVAL; > } > queue_input.queue_type = (uint32_t)queue_type; > -- > 2.43.0 >
Re: [PATCH] drm/amd/display: Remove redundant code and semicolons
I think the "break;" there is to silence the compilation warning - it is ugly but needed. David On 2024-06-20 11:38, Alex Deucher wrote: Applied. Thanks! Alex On Thu, Jun 20, 2024 at 5:07 AM Jiapeng Chong wrote: No functional modification involved. ./drivers/gpu/drm/amd/display/dc/dml2/dml21/src/dml2_core/dml2_core_shared.c:3171:2-3: Unneeded semicolon. ./drivers/gpu/drm/amd/display/dc/dml2/dml21/src/dml2_core/dml2_core_shared.c:3185:2-3: Unneeded semicolon. ./drivers/gpu/drm/amd/display/dc/dml2/dml21/src/dml2_core/dml2_core_shared.c:3200:2-3: Unneeded semicolon. Reported-by: Abaci Robot Closes: https://bugzilla.openanolis.cn/show_bug.cgi?id=9365 Signed-off-by: Jiapeng Chong --- .../dml21/src/dml2_core/dml2_core_shared.c| 46 +-- 1 file changed, 23 insertions(+), 23 deletions(-) diff --git a/drivers/gpu/drm/amd/display/dc/dml2/dml21/src/dml2_core/dml2_core_shared.c b/drivers/gpu/drm/amd/display/dc/dml2/dml21/src/dml2_core/dml2_core_shared.c index cfa4c4475821..1a9895b1833f 100644 --- a/drivers/gpu/drm/amd/display/dc/dml2/dml21/src/dml2_core/dml2_core_shared.c +++ b/drivers/gpu/drm/amd/display/dc/dml2/dml21/src/dml2_core/dml2_core_shared.c @@ -3142,62 +3142,62 @@ static unsigned int dml_get_tile_block_size_bytes(enum dml2_swizzle_mode sw_mode { switch (sw_mode) { case (dml2_sw_linear): - return 256; break; + return 256; case (dml2_sw_256b_2d): - return 256; break; + return 256; case (dml2_sw_4kb_2d): - return 4096; break; + return 4096; case (dml2_sw_64kb_2d): - return 65536; break; + return 65536; case (dml2_sw_256kb_2d): - return 262144; break; + return 262144; case (dml2_gfx11_sw_linear): - return 256; break; + return 256; case (dml2_gfx11_sw_64kb_d): - return 65536; break; + return 65536; case (dml2_gfx11_sw_64kb_d_t): - return 65536; break; + return 65536; case (dml2_gfx11_sw_64kb_d_x): - return 65536; break; + return 65536; case (dml2_gfx11_sw_64kb_r_x): - return 65536; break; + return 65536; case (dml2_gfx11_sw_256kb_d_x): - return 262144; break; + return 262144; case (dml2_gfx11_sw_256kb_r_x): - return 262144; break; + return 262144; default: DML2_ASSERT(0); return 256; - }; + } } const char *dml2_core_internal_bw_type_str(enum dml2_core_internal_bw_type bw_type) { switch (bw_type) { case (dml2_core_internal_bw_sdp): - return("dml2_core_internal_bw_sdp"); break; + return("dml2_core_internal_bw_sdp"); case (dml2_core_internal_bw_dram): - return("dml2_core_internal_bw_dram"); break; + return("dml2_core_internal_bw_dram"); case (dml2_core_internal_bw_max): - return("dml2_core_internal_bw_max"); break; + return("dml2_core_internal_bw_max"); default: - return("dml2_core_internal_bw_unknown"); break; - }; + return("dml2_core_internal_bw_unknown"); + } } const char *dml2_core_internal_soc_state_type_str(enum dml2_core_internal_soc_state_type dml2_core_internal_soc_state_type) { switch (dml2_core_internal_soc_state_type) { case (dml2_core_internal_soc_state_sys_idle): - return("dml2_core_internal_soc_state_sys_idle"); break; + return("dml2_core_internal_soc_state_sys_idle"); case (dml2_core_internal_soc_state_sys_active): - return("dml2_core_internal_soc_state_sys_active"); break; + return("dml2_core_internal_soc_state_sys_active"); case (dml2_core_internal_soc_state_svp_prefetch): - return("dml2_core_internal_soc_state_svp_prefetch"); break; + return("dml2_core_internal_soc_state_svp_prefetch"); case dml2_core_internal_soc_state_max: default: - return("dml2_core_internal_soc_state_unknown"); break; - }; + return("dml2_core_internal_soc_state_unknown"); + } } static bool dml_is_vertical_rotation(enum dml2_rotation_angle Scan) -- 2.20.1.7.g153144c
Re: [PATCH 1/2] drm/amdgpu: Unmap BO memory before calling amdgpu_bo_unref()
Am 20.06.24 um 16:44 schrieb Thomas Zimmermann: Prepares for using ttm_bo_vmap() and ttm_bo_vunmap() in amdgpu. Both require the caller to hold the GEM reservation lock, which is not the case while releasing a buffer object. Hence, push a possible call to unmap out from the buffer-object release code. Warn if a buffer object with mapped pages is supposed to be released. Yeah, I've looked into this a while ago as well and that unfortunately won't work like this. Amdgpu also uses ttm_bo_kmap() on user allocations, so the amdgpu_bo_kunmap() in amdgpu_bo_destroy() is a must have. On the other hand I'm pretty sure that calling ttm_bo_vunmap() without holding the reservation lock is ok in this situation. After all it's guaranteed that nobody else is having a reference to the BO any more. Regards, Christian. Signed-off-by: Thomas Zimmermann --- drivers/gpu/drm/amd/amdgpu/amdgpu_object.c | 11 +++ 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c index a1b7438c43dc8..d58b11ea0ead5 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c @@ -58,7 +58,12 @@ static void amdgpu_bo_destroy(struct ttm_buffer_object *tbo) { struct amdgpu_bo *bo = ttm_to_amdgpu_bo(tbo); - amdgpu_bo_kunmap(bo); + /* +* BO memory pages should be unmapped at this point. Call +* amdgpu_bo_kunmap() before releasing the BO. +*/ + if (drm_WARN_ON_ONCE(bo->tbo.base.dev, bo->kmap.bo)) + amdgpu_bo_kunmap(bo); if (bo->tbo.base.import_attach) drm_prime_gem_destroy(&bo->tbo.base, bo->tbo.sg); @@ -450,9 +455,7 @@ void amdgpu_bo_free_kernel(struct amdgpu_bo **bo, u64 *gpu_addr, WARN_ON(amdgpu_ttm_adev((*bo)->tbo.bdev)->in_suspend); if (likely(amdgpu_bo_reserve(*bo, true) == 0)) { - if (cpu_addr) - amdgpu_bo_kunmap(*bo); - + amdgpu_bo_kunmap(*bo); amdgpu_bo_unpin(*bo); amdgpu_bo_unreserve(*bo); }
Re: [PATCH] drm/amdgpu: clear IH_RB_W/RPTR during enabling interrupts in sriov case
Am 20.06.24 um 15:55 schrieb Danijel Slivka: Clearing the IH_RB_W/RPTR during interrupts disable is not clearing the RB_OVERFLOW bit. Adding workaround to clear the wptr when enabling interrupts in case RB_OVERFLOW bit is set. Signed-off-by: Danijel Slivka --- drivers/gpu/drm/amd/amdgpu/ih_v6_0.c | 6 ++ 1 file changed, 6 insertions(+) diff --git a/drivers/gpu/drm/amd/amdgpu/ih_v6_0.c b/drivers/gpu/drm/amd/amdgpu/ih_v6_0.c index 3cb64c8f7175..d6212a98ca99 100644 --- a/drivers/gpu/drm/amd/amdgpu/ih_v6_0.c +++ b/drivers/gpu/drm/amd/amdgpu/ih_v6_0.c @@ -147,6 +147,12 @@ static int ih_v6_0_toggle_ring_interrupts(struct amdgpu_device *adev, } if (enable) { + if (amdgpu_sriov_vf(adev) && + REG_GET_FIELD(RREG32(ih_regs->ih_rb_wptr), IH_RB_WPTR, RB_OVERFLOW)) { + /* clear rptr, wptr*/ + WREG32(ih_regs->ih_rb_rptr, 0); + WREG32(ih_regs->ih_rb_wptr, 0); + } Well that change doesn't really make much sense. We disable the IH ring before we do any initialisation, see ih_v6_0_irq_init(). That in turn sets RPTR and WPTR to 0: /* set rptr, wptr to 0 */ WREG32(ih_regs->ih_rb_rptr, 0); WREG32(ih_regs->ih_rb_wptr, 0); ih->enabled = false; So why should this be needed here? Regards, Christian. ih->enabled = true; } else { /* set rptr, wptr to 0 */
[PATCH 00/39] DC Patches June 20, 2024
This DC patchset brings improvements in multiple areas. In summary, we highlight: * Enable DCC on DCN401 * Fix cursor issues * Misc Coverity fixes Cc: Daniel Wheeler Alex Hung (12): drm/amd/display: Remove redundant checks for pipe_ctx->stream drm/amd/display: Run DC_LOG_DC after checking link->link_enc drm/amd/display: Fix uninitialized variables in dcn401 drm/amd/display: Remove useless function call drm/amd/display: Check and log for function error codes drm/amd/display: Check and log for function error codes drm/amd/display: Check HDCP returned status drm/amd/display: Add null checks before accessing struct elements drm/amd/display: Ensure curve to hw translation succeed drm/amd/display: Validate function returns drm/amd/display: Remove always true condition drm/amd/display: Remove duplicate null check Alvin Lee (2): drm/amd/display: Program CURSOR_DST_X_OFFSET in viewport space drm/amd/display: Wait for double buffer update on ODM changes Aric Cyr (1): drm/amd/display: 3.2.290 Aurabindo Pillai (3): drm/amd/display: Use sw cursor for DCN401 with rotation drm/amd: Add reg definitions for DCN401 DCC drm/amd/display: Enable DCC on DCN401 Daniel Sa (1): drm/amd/display: Fix reduced resolution and refresh rate Dillon Varone (1): drm/amd/display: Make DML2.1 P-State method force per stream Duncan Ma (1): drm/amd/display: Reset DSC memory status George Shen (1): drm/amd/display: Call dpmm when checking mode support Ivan Lipski (2): drm/amd/display: Remove redundant var from display_rq_dig_calc in dml drm/amd/display: Remove unnecessary variable Joan Lee (1): drm/amd/display: Add Replay general cmd Leo (Hanghong) Ma (1): drm/amd/display: Always enable HPO for DCN4 dGPU Michael Strauss (1): drm/amd/display: Send DP_TOTAL_LTTPR_CNT during detection if LTTPR is present Nevenko Stupar (3): drm/amd/display: Fix cursor issues with ODMs and HW rotations drm/amd/display: Fix cursor size issues drm/amd/display: Fix cursor issues with ODMs and magnification Nicholas Susanto (1): drm/amd/display: Temporarily disable HPO PG on DCN35 Relja Vojvodic (2): drm/amd/display: Refactor dccg401_get_other_enable_symclk_fe drm/amd/display: Fix 1DLUT setting for NL SDR blending Roman Li (1): drm/amd/display: Use periodic detection for ipx/headless Ryan Seto (2): drm/amd/display: Add HW cursor visual confirm drm/amd/display: Adjust reg field for DSC wait for disconnect Sung-huai Wang (1): drm/amd/display: Add workaround to restrict max frac urgent for DPM0 TungYu Lu (1): drm/amd/display: resync OTG after DIO FIFO resync Wenjing Liu (1): drm/amd/display: Remove a redundant check in authenticated_dp .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 39 ++- .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h | 3 + .../amd/display/amdgpu_dm/amdgpu_dm_crtc.c| 48 ++- .../amd/display/amdgpu_dm/amdgpu_dm_debugfs.c | 5 +- .../amd/display/amdgpu_dm/amdgpu_dm_helpers.c | 5 +- .../drm/amd/display/dc/bios/command_table2.c | 3 +- .../dc/clk_mgr/dcn201/dcn201_clk_mgr.c| 2 - .../display/dc/clk_mgr/dcn32/dcn32_clk_mgr.c | 10 +- .../dc/clk_mgr/dcn401/dcn401_clk_mgr.c| 10 +- drivers/gpu/drm/amd/display/dc/core/dc.c | 12 + .../drm/amd/display/dc/core/dc_hw_sequencer.c | 11 + .../gpu/drm/amd/display/dc/core/dc_stream.c | 29 ++ drivers/gpu/drm/amd/display/dc/dc.h | 9 +- drivers/gpu/drm/amd/display/dc/dc_dmub_srv.c | 7 +- drivers/gpu/drm/amd/display/dc/dc_types.h | 1 + .../amd/display/dc/dccg/dcn401/dcn401_dccg.c | 57 ++-- .../drm/amd/display/dc/dce/dce_link_encoder.c | 5 +- .../gpu/drm/amd/display/dc/dce/dmub_replay.c | 18 +- .../amd/display/dc/dcn10/dcn10_link_encoder.c | 8 +- .../drm/amd/display/dc/dml/dcn20/dcn20_fpu.c | 2 +- .../dc/dml/dcn20/display_rq_dlg_calc_20.c | 14 +- .../dc/dml/dcn20/display_rq_dlg_calc_20v2.c | 14 +- .../dc/dml/dcn21/display_rq_dlg_calc_21.c | 14 +- .../dc/dml/dcn30/display_rq_dlg_calc_30.c | 14 +- .../dc/dml/dcn31/display_rq_dlg_calc_31.c | 14 +- .../dc/dml/dcn314/display_rq_dlg_calc_314.c | 14 +- .../dc/dml2/dml21/dml21_translation_helper.c | 2 +- .../amd/display/dc/dml2/dml21/dml21_wrapper.c | 4 +- .../src/dml2_core/dml2_core_dcn4_calcs.c | 4 +- .../dc/dml2/dml21/src/dml2_top/dml_top.c | 17 ++ .../src/inc/dml2_internal_shared_types.h | 1 + .../drm/amd/display/dc/dml2/dml2_wrapper.c| 29 +- .../drm/amd/display/dc/dml2/dml2_wrapper.h| 6 +- .../amd/display/dc/dpp/dcn401/dcn401_dpp_cm.c | 50 .../drm/amd/display/dc/dsc/dcn20/dcn20_dsc.c | 24 +- .../drm/amd/display/dc/dsc/dcn20/dcn20_dsc.h | 13 +- .../drm/amd/display/dc/dsc/dcn35/dcn35_dsc.c | 58 +++- .../amd/display/dc/dsc/dcn401/dcn401_dsc.c| 2 +- .../amd/display/dc/dsc/dcn401/dcn401_dsc.h| 3 +- .../display/dc/hubbub/dcn20/dcn20_hubbub.c| 3 +- .../display/dc/hubbub/dcn30/dcn30
[PATCH 01/39] drm/amd/display: Temporarily disable HPO PG on DCN35
From: Nicholas Susanto [WHY] On hotpluggin a 4k144 HDMI FRL setup, display fails FRL link training and falls back to TMDS which is caused by driver not ungating HPO before doing FRL link training. [HOW] Enable debug flag to disable HPO power gate in DCN35 Reviewed-by: Nicholas Kazlauskas Reviewed-by: Charlene Liu Acked-by: Alex Hung Signed-off-by: Nicholas Susanto --- drivers/gpu/drm/amd/display/dc/resource/dcn35/dcn35_resource.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/amd/display/dc/resource/dcn35/dcn35_resource.c b/drivers/gpu/drm/amd/display/dc/resource/dcn35/dcn35_resource.c index 0094ef223c5d..67ab8c1962ff 100644 --- a/drivers/gpu/drm/amd/display/dc/resource/dcn35/dcn35_resource.c +++ b/drivers/gpu/drm/amd/display/dc/resource/dcn35/dcn35_resource.c @@ -721,7 +721,7 @@ static const struct dc_debug_options debug_defaults_drv = { .disable_dpp_power_gate = true, .disable_hubp_power_gate = true, .disable_optc_power_gate = true, /*should the same as above two*/ - .disable_hpo_power_gate = false, /*dmubfw force domain25 on*/ + .disable_hpo_power_gate = true, /*dmubfw force domain25 on*/ .disable_clock_gate = false, .disable_dsc_power_gate = true, .vsr_support = true, -- 2.34.1
[PATCH 02/39] drm/amd/display: Refactor dccg401_get_other_enable_symclk_fe
From: Relja Vojvodic [WHY] Function was used to check the number of FEs connected to the current BE. This was then used to determine if the symclk could be disabled, if all FEs were disconnected. However, the function would skip over the primary FE and return 0 when the primary FE was still connected. This caused black screens on driver disable with an MST daisy chain hooked up. [HOW] Refactored the function to correctly return the number of FEs connected to the input BE. Also renamed it for clarity. Reviewed-by: Wenjing Liu Acked-by: Alex Hung Signed-off-by: Relja Vojvodic --- .../amd/display/dc/dccg/dcn401/dcn401_dccg.c | 57 +++ 1 file changed, 22 insertions(+), 35 deletions(-) diff --git a/drivers/gpu/drm/amd/display/dc/dccg/dcn401/dcn401_dccg.c b/drivers/gpu/drm/amd/display/dc/dccg/dcn401/dcn401_dccg.c index 6a467c49b4a4..07f1f396ba52 100644 --- a/drivers/gpu/drm/amd/display/dc/dccg/dcn401/dcn401_dccg.c +++ b/drivers/gpu/drm/amd/display/dc/dccg/dcn401/dcn401_dccg.c @@ -853,43 +853,30 @@ static void dccg401_enable_symclk_se(struct dccg *dccg, uint32_t stream_enc_inst } /*get other front end connected to this backend*/ -static uint8_t dccg401_get_other_enabled_symclk_fe(struct dccg *dccg, uint32_t stream_enc_inst, uint32_t link_enc_inst) +static uint8_t dccg401_get_number_enabled_symclk_fe_connected_to_be(struct dccg *dccg, uint32_t link_enc_inst) { uint8_t num_enabled_symclk_fe = 0; - uint32_t be_clk_en = 0, fe_clk_en[4] = {0}, be_clk_sel[4] = {0}; + uint32_t fe_clk_en[4] = {0}, be_clk_sel[4] = {0}; struct dcn_dccg *dccg_dcn = TO_DCN_DCCG(dccg); + uint8_t i; - switch (link_enc_inst) { - case 0: - REG_GET_3(SYMCLKA_CLOCK_ENABLE, SYMCLKA_CLOCK_ENABLE, &be_clk_en, - SYMCLKA_FE_EN, &fe_clk_en[0], - SYMCLKA_FE_SRC_SEL, &be_clk_sel[0]); - break; - case 1: - REG_GET_3(SYMCLKB_CLOCK_ENABLE, SYMCLKB_CLOCK_ENABLE, &be_clk_en, - SYMCLKB_FE_EN, &fe_clk_en[1], - SYMCLKB_FE_SRC_SEL, &be_clk_sel[1]); - break; - case 2: - REG_GET_3(SYMCLKC_CLOCK_ENABLE, SYMCLKC_CLOCK_ENABLE, &be_clk_en, - SYMCLKC_FE_EN, &fe_clk_en[2], - SYMCLKC_FE_SRC_SEL, &be_clk_sel[2]); - break; - case 3: - REG_GET_3(SYMCLKD_CLOCK_ENABLE, SYMCLKD_CLOCK_ENABLE, &be_clk_en, - SYMCLKD_FE_EN, &fe_clk_en[3], - SYMCLKD_FE_SRC_SEL, &be_clk_sel[3]); - break; - } - if (be_clk_en) { - /* for DPMST, this backend could be used by multiple front end. - only disable the backend if this stream_enc_ins is the last active stream enc connected to this back_end*/ - uint8_t i; - for (i = 0; i != link_enc_inst && i < ARRAY_SIZE(fe_clk_en); i++) { - if (fe_clk_en[i] && be_clk_sel[i] == link_enc_inst) - num_enabled_symclk_fe++; - } + REG_GET_2(SYMCLKA_CLOCK_ENABLE, SYMCLKA_FE_EN, &fe_clk_en[0], + SYMCLKA_FE_SRC_SEL, &be_clk_sel[0]); + + REG_GET_2(SYMCLKB_CLOCK_ENABLE, SYMCLKB_FE_EN, &fe_clk_en[1], + SYMCLKB_FE_SRC_SEL, &be_clk_sel[1]); + + REG_GET_2(SYMCLKC_CLOCK_ENABLE, SYMCLKC_FE_EN, &fe_clk_en[2], + SYMCLKC_FE_SRC_SEL, &be_clk_sel[2]); + + REG_GET_2(SYMCLKD_CLOCK_ENABLE, SYMCLKD_FE_EN, &fe_clk_en[3], + SYMCLKD_FE_SRC_SEL, &be_clk_sel[3]); + + for (i = 0; i < ARRAY_SIZE(fe_clk_en); i++) { + if (fe_clk_en[i] && be_clk_sel[i] == link_enc_inst) + num_enabled_symclk_fe++; } + return num_enabled_symclk_fe; } @@ -921,9 +908,9 @@ static void dccg401_disable_symclk_se(struct dccg *dccg, uint32_t stream_enc_ins break; } - /*check other enabled symclk fe */ - num_enabled_symclk_fe = dccg401_get_other_enabled_symclk_fe(dccg, stream_enc_inst, link_enc_inst); - /*only turn off backend clk if other front end attachecd to this backend are all off, + /*check other enabled symclk fe connected to this be */ + num_enabled_symclk_fe = dccg401_get_number_enabled_symclk_fe_connected_to_be(dccg, link_enc_inst); + /*only turn off backend clk if other front ends attached to this backend are all off, for mst, only turn off the backend if this is the last front end*/ if (num_enabled_symclk_fe == 0) { switch (link_enc_inst) { -- 2.34.1
[PATCH 03/39] drm/amd/display: Remove redundant var from display_rq_dig_calc in dml
From: Ivan Lipski [WHY] Coverity analysis flagged these files as containing DEADCODE, i. e. redundant or unreachabale. In these files, variable 'mode_422' is always the same file (0 or false), so any code logic with it is redundant. [HOW] Removed 'mode_422' variable and all code with it from 'display_rq_dlg_calc_' functions in dml. Reviewed-by: Alex Hung Acked-by: Alex Hung Signed-off-by: Ivan Lipski --- .../display/dc/dml/dcn20/display_rq_dlg_calc_20.c | 14 +++--- .../dc/dml/dcn20/display_rq_dlg_calc_20v2.c| 14 +++--- .../display/dc/dml/dcn21/display_rq_dlg_calc_21.c | 14 +++--- .../display/dc/dml/dcn30/display_rq_dlg_calc_30.c | 14 +++--- .../display/dc/dml/dcn31/display_rq_dlg_calc_31.c | 14 +++--- .../dc/dml/dcn314/display_rq_dlg_calc_314.c| 14 +++--- 6 files changed, 18 insertions(+), 66 deletions(-) diff --git a/drivers/gpu/drm/amd/display/dc/dml/dcn20/display_rq_dlg_calc_20.c b/drivers/gpu/drm/amd/display/dc/dml/dcn20/display_rq_dlg_calc_20.c index 07146569e335..7c56ad0f8812 100644 --- a/drivers/gpu/drm/amd/display/dc/dml/dcn20/display_rq_dlg_calc_20.c +++ b/drivers/gpu/drm/amd/display/dc/dml/dcn20/display_rq_dlg_calc_20.c @@ -688,12 +688,11 @@ static void get_surf_rq_param(struct display_mode_lib *mode_lib, const display_pipe_source_params_st *pipe_src_param, bool is_chroma) { - bool mode_422 = false; unsigned int vp_width = 0; unsigned int vp_height = 0; unsigned int data_pitch = 0; unsigned int meta_pitch = 0; - unsigned int ppe = mode_422 ? 2 : 1; + unsigned int ppe = 1; // TODO check if ppe apply for both luma and chroma in 422 case if (is_chroma) { @@ -825,7 +824,6 @@ static void dml20_rq_dlg_get_dlg_params(struct display_mode_lib *mode_lib, double min_dst_y_ttu_vblank; unsigned int dlg_vblank_start; bool dual_plane; - bool mode_422; unsigned int access_dir; unsigned int vp_height_l; unsigned int vp_width_l; @@ -971,7 +969,6 @@ static void dml20_rq_dlg_get_dlg_params(struct display_mode_lib *mode_lib, // Source // dcc_en = src.dcc; dual_plane = is_dual_plane((enum source_format_class)(src->source_format)); - mode_422 = false; // TODO access_dir = (src->source_scan == dm_vert); // vp access direction: horizontal or vertical accessed // bytes_per_element_l = get_bytes_per_element(source_format_class(src.source_format), 0); // bytes_per_element_c = get_bytes_per_element(source_format_class(src.source_format), 1); @@ -1148,13 +1145,8 @@ static void dml20_rq_dlg_get_dlg_params(struct display_mode_lib *mode_lib, dpte_row_height_l = rq_dlg_param->rq_l.dpte_row_height; dpte_row_height_c = rq_dlg_param->rq_c.dpte_row_height; - if (mode_422) { - swath_width_pixels_ub_l = swath_width_ub_l * 2; // *2 for 2 pixel per element - swath_width_pixels_ub_c = swath_width_ub_c * 2; - } else { - swath_width_pixels_ub_l = swath_width_ub_l * 1; - swath_width_pixels_ub_c = swath_width_ub_c * 1; - } + swath_width_pixels_ub_l = swath_width_ub_l; + swath_width_pixels_ub_c = swath_width_ub_c; if (htaps_l <= 1) min_hratio_fact_l = 2.0; diff --git a/drivers/gpu/drm/amd/display/dc/dml/dcn20/display_rq_dlg_calc_20v2.c b/drivers/gpu/drm/amd/display/dc/dml/dcn20/display_rq_dlg_calc_20v2.c index f4bba1f2aeb6..3d95bfa5aca2 100644 --- a/drivers/gpu/drm/amd/display/dc/dml/dcn20/display_rq_dlg_calc_20v2.c +++ b/drivers/gpu/drm/amd/display/dc/dml/dcn20/display_rq_dlg_calc_20v2.c @@ -688,12 +688,11 @@ static void get_surf_rq_param(struct display_mode_lib *mode_lib, const display_pipe_source_params_st *pipe_src_param, bool is_chroma) { - bool mode_422 = false; unsigned int vp_width = 0; unsigned int vp_height = 0; unsigned int data_pitch = 0; unsigned int meta_pitch = 0; - unsigned int ppe = mode_422 ? 2 : 1; + unsigned int ppe = 1; // TODO check if ppe apply for both luma and chroma in 422 case if (is_chroma) { @@ -825,7 +824,6 @@ static void dml20v2_rq_dlg_get_dlg_params(struct display_mode_lib *mode_lib, double min_dst_y_ttu_vblank; unsigned int dlg_vblank_start; bool dual_plane; - bool mode_422; unsigned int access_dir; unsigned int vp_height_l; unsigned int vp_width_l; @@ -972,7 +970,6 @@ static void dml20v2_rq_dlg_get_dlg_params(struct display_mode_lib *mode_lib, // Source // dcc_en = src.dcc; dual_plane = is_dual_plane((enum source_format_class)(src->source_format)); - mode_422 = false; // TODO access_dir = (src->source_scan == dm_vert); // vp access direction: horizontal or v
[PATCH 04/39] drm/amd/display: Remove unnecessary variable
From: Ivan Lipski [WHY] Coverity analysis flagged this code as DEADCODE because the condition '(!need_recovery)' is never true. The variable 'need_recovery' is initialized as 'true', is not assigned to 'false' anywhere before the conditional statement. Since the variable is only used for the conditional check, but the check can never be true, the variable itself is redundant. [HOW] Removed the variable 'need_recovery'. Reviewed-by: Alex Hung Acked-by: Alex Hung Signed-off-by: Ivan Lipski --- .../drm/amd/display/dc/hwss/dcn10/dcn10_hwseq.c | 17 - 1 file changed, 17 deletions(-) diff --git a/drivers/gpu/drm/amd/display/dc/hwss/dcn10/dcn10_hwseq.c b/drivers/gpu/drm/amd/display/dc/hwss/dcn10/dcn10_hwseq.c index 35151dd056cb..4ef329a4d764 100644 --- a/drivers/gpu/drm/amd/display/dc/hwss/dcn10/dcn10_hwseq.c +++ b/drivers/gpu/drm/amd/display/dc/hwss/dcn10/dcn10_hwseq.c @@ -1134,26 +1134,9 @@ static bool dcn10_hw_wa_force_recovery(struct dc *dc) { struct hubp *hubp ; unsigned int i; - bool need_recover = true; if (!dc->debug.recovery_enabled) return false; - - for (i = 0; i < dc->res_pool->pipe_count; i++) { - struct pipe_ctx *pipe_ctx = - &dc->current_state->res_ctx.pipe_ctx[i]; - if (pipe_ctx != NULL) { - hubp = pipe_ctx->plane_res.hubp; - if (hubp != NULL && hubp->funcs->hubp_get_underflow_status) { - if (hubp->funcs->hubp_get_underflow_status(hubp) != 0) { - /* one pipe underflow, we will reset all the pipes*/ - need_recover = true; - } - } - } - } - if (!need_recover) - return false; /* DCHUBP_CNTL:HUBP_BLANK_EN=1 DCHUBBUB_SOFT_RESET:DCHUBBUB_GLOBAL_SOFT_RESET=1 -- 2.34.1
[PATCH 05/39] drm/amd/display: Fix cursor issues with ODMs and HW rotations
From: Nevenko Stupar [WHY & HOW] Current code for cursor positions does not work properly with different ODM options and HW rotations like ODM 2to1, 3to1 and 4to1, and has different issues depending on angle of HW rotations. [HOW] Fixed these issues so to work properly when ODM is used with HW rotations. Reviewed-by: Sridevi Arvindekar Acked-by: Alex Hung Signed-off-by: Nevenko Stupar --- .../amd/display/dc/dpp/dcn401/dcn401_dpp_cm.c | 50 --- .../amd/display/dc/hubp/dcn401/dcn401_hubp.c | 38 - .../amd/display/dc/hwss/dcn401/dcn401_hwseq.c | 135 +++--- 3 files changed, 19 insertions(+), 204 deletions(-) diff --git a/drivers/gpu/drm/amd/display/dc/dpp/dcn401/dcn401_dpp_cm.c b/drivers/gpu/drm/amd/display/dc/dpp/dcn401/dcn401_dpp_cm.c index aef73bd1221a..d0f8c9ff5232 100644 --- a/drivers/gpu/drm/amd/display/dc/dpp/dcn401/dcn401_dpp_cm.c +++ b/drivers/gpu/drm/amd/display/dc/dpp/dcn401/dcn401_dpp_cm.c @@ -153,58 +153,8 @@ void dpp401_set_cursor_position( uint32_t height) { struct dcn401_dpp *dpp = TO_DCN401_DPP(dpp_base); - int x_pos = pos->x - param->recout.x; - int y_pos = pos->y - param->recout.y; - int x_hotspot = pos->x_hotspot; - int y_hotspot = pos->y_hotspot; - int rec_x_offset = x_pos - pos->x_hotspot; - int rec_y_offset = y_pos - pos->y_hotspot; - int cursor_height = (int)height; - int cursor_width = (int)width; uint32_t cur_en = pos->enable ? 1 : 0; - // Transform cursor width / height and hotspots for offset calculations - if (param->rotation == ROTATION_ANGLE_90 || param->rotation == ROTATION_ANGLE_270) { - swap(cursor_height, cursor_width); - swap(x_hotspot, y_hotspot); - - if (param->rotation == ROTATION_ANGLE_90) { - // hotspot = (-y, x) - rec_x_offset = x_pos - (cursor_width - x_hotspot); - rec_y_offset = y_pos - y_hotspot; - } else if (param->rotation == ROTATION_ANGLE_270) { - // hotspot = (y, -x) - rec_x_offset = x_pos - x_hotspot; - rec_y_offset = y_pos - (cursor_height - y_hotspot); - } - } else if (param->rotation == ROTATION_ANGLE_180) { - // hotspot = (-x, -y) - if (!param->mirror) - rec_x_offset = x_pos - (cursor_width - x_hotspot); - - rec_y_offset = y_pos - (cursor_height - y_hotspot); - } - - if (param->rotation == ROTATION_ANGLE_0 && !param->mirror) { - if (rec_x_offset >= (int)param->recout.width) - cur_en = 0; /* not visible beyond right edge*/ - - if (rec_y_offset >= (int)param->recout.height) - cur_en = 0; /* not visible beyond bottom edge*/ - } else { - if (rec_x_offset > (int)param->recout.width) - cur_en = 0; /* not visible beyond right edge*/ - - if (rec_y_offset > (int)param->recout.height) - cur_en = 0; /* not visible beyond bottom edge*/ - } - - if (rec_x_offset + cursor_width <= 0) - cur_en = 0; /* not visible beyond left edge*/ - - if (rec_y_offset + cursor_height <= 0) - cur_en = 0; /* not visible beyond top edge*/ - REG_UPDATE(CURSOR0_CONTROL, CUR0_ENABLE, cur_en); dpp_base->pos.cur0_ctl.bits.cur0_enable = cur_en; diff --git a/drivers/gpu/drm/amd/display/dc/hubp/dcn401/dcn401_hubp.c b/drivers/gpu/drm/amd/display/dc/hubp/dcn401/dcn401_hubp.c index 6692d57d5cce..a893160ae775 100644 --- a/drivers/gpu/drm/amd/display/dc/hubp/dcn401/dcn401_hubp.c +++ b/drivers/gpu/drm/amd/display/dc/hubp/dcn401/dcn401_hubp.c @@ -654,12 +654,8 @@ void hubp401_cursor_set_position( struct dcn20_hubp *hubp2 = TO_DCN20_HUBP(hubp); int x_pos = pos->x - param->recout.x; int y_pos = pos->y - param->recout.y; - int x_hotspot = pos->x_hotspot; - int y_hotspot = pos->y_hotspot; int rec_x_offset = x_pos - pos->x_hotspot; int rec_y_offset = y_pos - pos->y_hotspot; - int cursor_height = (int)hubp->curs_attr.height; - int cursor_width = (int)hubp->curs_attr.width; uint32_t dst_x_offset; uint32_t cur_en = pos->enable ? 1 : 0; @@ -672,28 +668,6 @@ void hubp401_cursor_set_position( if (hubp->curs_attr.address.quad_part == 0) return; - // Transform cursor width / height and hotspots for offset calculations - if (param->rotation == ROTATION_ANGLE_90 || param->rotation == ROTATION_ANGLE_270) { - swap(cursor_height, cursor_width); - swap(x_hotspot, y_hotspot); - - if (param->rotation == ROTATION_ANGLE_90) { - // hotspot = (-y, x) - rec_x_offset = x_pos - (cursor_width - x_hotspot); -
[PATCH 06/39] drm/amd/display: Send DP_TOTAL_LTTPR_CNT during detection if LTTPR is present
From: Michael Strauss [WHY] New register field added in DP2.1 SCR, needed for auxless ALPM [HOW] Echo value read from 0xF0007 back to sink Reviewed-by: Wenjing Liu Cc: Mario Limonciello Cc: Alex Deucher Cc: sta...@vger.kernel.org Acked-by: Alex Hung Signed-off-by: Michael Strauss --- .../amd/display/dc/link/protocols/link_dp_capability.c | 10 +- drivers/gpu/drm/amd/display/include/dpcd_defs.h| 5 + 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_capability.c b/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_capability.c index 00974c50e11f..f1cac74dd7f7 100644 --- a/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_capability.c +++ b/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_capability.c @@ -1605,9 +1605,17 @@ static bool retrieve_link_cap(struct dc_link *link) return false; } - if (dp_is_lttpr_present(link)) + if (dp_is_lttpr_present(link)) { configure_lttpr_mode_transparent(link); + // Echo TOTAL_LTTPR_CNT back downstream + core_link_write_dpcd( + link, + DP_TOTAL_LTTPR_CNT, + &link->dpcd_caps.lttpr_caps.phy_repeater_cnt, + sizeof(link->dpcd_caps.lttpr_caps.phy_repeater_cnt)); + } + /* Read DP tunneling information. */ status = dpcd_get_tunneling_device_data(link); diff --git a/drivers/gpu/drm/amd/display/include/dpcd_defs.h b/drivers/gpu/drm/amd/display/include/dpcd_defs.h index 914f28e9f224..aee5170f5fb2 100644 --- a/drivers/gpu/drm/amd/display/include/dpcd_defs.h +++ b/drivers/gpu/drm/amd/display/include/dpcd_defs.h @@ -177,4 +177,9 @@ enum dpcd_psr_sink_states { #define DP_SINK_PR_PIXEL_DEVIATION_PER_LINE 0x379 #define DP_SINK_PR_MAX_NUMBER_OF_DEVIATION_LINE 0x37A +/* Remove once drm_dp_helper.h is updated upstream */ +#ifndef DP_TOTAL_LTTPR_CNT +#define DP_TOTAL_LTTPR_CNT 0xF000A /* 2.1 */ +#endif + #endif /* __DAL_DPCD_DEFS_H__ */ -- 2.34.1
[PATCH 07/39] drm/amd/display: Remove redundant checks for pipe_ctx->stream
[WHAT & HOW] The null checks for pipe_ctx->stream and pipe_ctx->stream_res.tg are redundant as they were already dereferenced previously, as reported by Coverity; therefore the null checks are removed. This fixes 6 REVERSE_INULL issues reported by Coverity. Reviewed-by: Rodrigo Siqueira Acked-by: Alex Hung Signed-off-by: Alex Hung --- drivers/gpu/drm/amd/display/dc/hwss/dcn20/dcn20_hwseq.c| 7 +++ drivers/gpu/drm/amd/display/dc/hwss/dcn401/dcn401_hwseq.c | 4 ++-- .../gpu/drm/amd/display/dc/link/accessories/link_dp_cts.c | 2 +- 3 files changed, 6 insertions(+), 7 deletions(-) diff --git a/drivers/gpu/drm/amd/display/dc/hwss/dcn20/dcn20_hwseq.c b/drivers/gpu/drm/amd/display/dc/hwss/dcn20/dcn20_hwseq.c index 82d1ded09561..4d359bb9b1ec 100644 --- a/drivers/gpu/drm/amd/display/dc/hwss/dcn20/dcn20_hwseq.c +++ b/drivers/gpu/drm/amd/display/dc/hwss/dcn20/dcn20_hwseq.c @@ -974,8 +974,8 @@ enum dc_status dcn20_enable_stream_timing( /* TODO enable stream if timing changed */ /* TODO unblank stream if DP */ - if (pipe_ctx->stream && dc_state_get_pipe_subvp_type(context, pipe_ctx) == SUBVP_PHANTOM) { - if (pipe_ctx->stream_res.tg && pipe_ctx->stream_res.tg->funcs->phantom_crtc_post_enable) + if (dc_state_get_pipe_subvp_type(context, pipe_ctx) == SUBVP_PHANTOM) { + if (pipe_ctx->stream_res.tg->funcs->phantom_crtc_post_enable) pipe_ctx->stream_res.tg->funcs->phantom_crtc_post_enable(pipe_ctx->stream_res.tg); } @@ -1827,8 +1827,7 @@ static void dcn20_update_dchubp_dpp( if (pipe_ctx->update_flags.bits.enable) hubp->funcs->set_blank(hubp, false); /* If the stream paired with this plane is phantom, the plane is also phantom */ - if (pipe_ctx->stream && pipe_mall_type == SUBVP_PHANTOM - && hubp->funcs->phantom_hubp_post_enable) + if (pipe_mall_type == SUBVP_PHANTOM && hubp->funcs->phantom_hubp_post_enable) hubp->funcs->phantom_hubp_post_enable(hubp); } diff --git a/drivers/gpu/drm/amd/display/dc/hwss/dcn401/dcn401_hwseq.c b/drivers/gpu/drm/amd/display/dc/hwss/dcn401/dcn401_hwseq.c index 8d0da56e4cc5..0cf55f557c3c 100644 --- a/drivers/gpu/drm/amd/display/dc/hwss/dcn401/dcn401_hwseq.c +++ b/drivers/gpu/drm/amd/display/dc/hwss/dcn401/dcn401_hwseq.c @@ -916,8 +916,8 @@ enum dc_status dcn401_enable_stream_timing( /* TODO enable stream if timing changed */ /* TODO unblank stream if DP */ - if (pipe_ctx->stream && dc_state_get_pipe_subvp_type(context, pipe_ctx) == SUBVP_PHANTOM) { - if (pipe_ctx->stream_res.tg && pipe_ctx->stream_res.tg->funcs->phantom_crtc_post_enable) + if (dc_state_get_pipe_subvp_type(context, pipe_ctx) == SUBVP_PHANTOM) { + if (pipe_ctx->stream_res.tg->funcs->phantom_crtc_post_enable) pipe_ctx->stream_res.tg->funcs->phantom_crtc_post_enable(pipe_ctx->stream_res.tg); } diff --git a/drivers/gpu/drm/amd/display/dc/link/accessories/link_dp_cts.c b/drivers/gpu/drm/amd/display/dc/link/accessories/link_dp_cts.c index 8d1a1cc94a8b..555c1c484cfd 100644 --- a/drivers/gpu/drm/amd/display/dc/link/accessories/link_dp_cts.c +++ b/drivers/gpu/drm/amd/display/dc/link/accessories/link_dp_cts.c @@ -853,7 +853,7 @@ bool dp_set_test_pattern( CRTC_STATE_VACTIVE); if (pipe_ctx->stream_res.tg->funcs->lock_doublebuffer_disable) { - if (pipe_ctx->stream && should_use_dmub_lock(pipe_ctx->stream->link)) { + if (should_use_dmub_lock(pipe_ctx->stream->link)) { union dmub_hw_lock_flags hw_locks = { 0 }; struct dmub_hw_lock_inst_flags inst_flags = { 0 }; -- 2.34.1
[PATCH 08/39] drm/amd/display: Run DC_LOG_DC after checking link->link_enc
[WHAT] The DC_LOG_DC should be run after link->link_enc is checked, not before. This fixes 1 REVERSE_INULL issue reported by Coverity. Reviewed-by: Rodrigo Siqueira Acked-by: Alex Hung Signed-off-by: Alex Hung --- drivers/gpu/drm/amd/display/dc/link/link_factory.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/amd/display/dc/link/link_factory.c b/drivers/gpu/drm/amd/display/dc/link/link_factory.c index 8073fdae9cb1..8246006857b3 100644 --- a/drivers/gpu/drm/amd/display/dc/link/link_factory.c +++ b/drivers/gpu/drm/amd/display/dc/link/link_factory.c @@ -610,14 +610,14 @@ static bool construct_phy(struct dc_link *link, link->link_enc = link->dc->res_pool->funcs->link_enc_create(dc_ctx, &enc_init_data); - DC_LOG_DC("BIOS object table - DP_IS_USB_C: %d", link->link_enc->features.flags.bits.DP_IS_USB_C); - DC_LOG_DC("BIOS object table - IS_DP2_CAPABLE: %d", link->link_enc->features.flags.bits.IS_DP2_CAPABLE); - if (!link->link_enc) { DC_ERROR("Failed to create link encoder!\n"); goto link_enc_create_fail; } + DC_LOG_DC("BIOS object table - DP_IS_USB_C: %d", link->link_enc->features.flags.bits.DP_IS_USB_C); + DC_LOG_DC("BIOS object table - IS_DP2_CAPABLE: %d", link->link_enc->features.flags.bits.IS_DP2_CAPABLE); + /* Update link encoder tracking variables. These are used for the dynamic * assignment of link encoders to streams. */ -- 2.34.1
[PATCH 09/39] drm/amd/display: Fix cursor size issues
From: Nevenko Stupar [WHY & HOW] Fix the cursor size between ODM slices. Reviewed-by: Sridevi Arvindekar Cc: Mario Limonciello Cc: Alex Deucher Cc: sta...@vger.kernel.org Acked-by: Alex Hung Signed-off-by: Nevenko Stupar --- .../drm/amd/display/dc/hwss/dcn401/dcn401_hwseq.c | 14 ++ 1 file changed, 14 insertions(+) diff --git a/drivers/gpu/drm/amd/display/dc/hwss/dcn401/dcn401_hwseq.c b/drivers/gpu/drm/amd/display/dc/hwss/dcn401/dcn401_hwseq.c index 0cf55f557c3c..42753f56d31d 100644 --- a/drivers/gpu/drm/amd/display/dc/hwss/dcn401/dcn401_hwseq.c +++ b/drivers/gpu/drm/amd/display/dc/hwss/dcn401/dcn401_hwseq.c @@ -1169,6 +1169,20 @@ void dcn401_set_cursor_position(struct pipe_ctx *pipe_ctx) x_pos -= (prev_odm_width + prev_odm_offset); } + /* If the position is negative then we need to add to the hotspot +* to fix cursor size between ODM slices +*/ + + if (x_pos < 0) { + pos_cpy.x_hotspot -= x_pos; + x_pos = 0; + } + + if (y_pos < 0) { + pos_cpy.y_hotspot -= y_pos; + y_pos = 0; + } + pos_cpy.x = (uint32_t)x_pos; pos_cpy.y = (uint32_t)y_pos; -- 2.34.1
[PATCH 10/39] drm/amd/display: Fix uninitialized variables in dcn401
[WHAT & HOW] surf_linear_128_l/c are used in CalculateBytePerPixelAndBlockSizes before they are assigned, so initializing them before passing them into the function. This fixes 2 UNINIT issues reported by Coverity. Reviewed-by: Rodrigo Siqueira Acked-by: Alex Hung Signed-off-by: Alex Hung --- .../dc/dml2/dml21/src/dml2_core/dml2_core_dcn4_calcs.c| 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/amd/display/dc/dml2/dml21/src/dml2_core/dml2_core_dcn4_calcs.c b/drivers/gpu/drm/amd/display/dc/dml2/dml21/src/dml2_core/dml2_core_dcn4_calcs.c index be73784e21eb..6f4026e396e0 100644 --- a/drivers/gpu/drm/amd/display/dc/dml2/dml21/src/dml2_core/dml2_core_dcn4_calcs.c +++ b/drivers/gpu/drm/amd/display/dc/dml2/dml21/src/dml2_core/dml2_core_dcn4_calcs.c @@ -11521,8 +11521,8 @@ void dml2_core_calcs_get_dpte_row_height( unsigned int MacroTileWidthC; unsigned int MacroTileHeightY; unsigned int MacroTileHeightC; - bool surf_linear_128_l; - bool surf_linear_128_c; + bool surf_linear_128_l = false; + bool surf_linear_128_c = false; CalculateBytePerPixelAndBlockSizes( SourcePixelFormat, -- 2.34.1
[PATCH 11/39] drm/amd/display: Remove useless function call
[WHAT & HOW] clk_mgr_helper_get_active_display_cnt returns display count and itself alone has no use. This fixes 1 CHECKED_RETURN issue reported by Coverity. Reviewed-by: Rodrigo Siqueira Acked-by: Alex Hung Signed-off-by: Alex Hung --- drivers/gpu/drm/amd/display/dc/clk_mgr/dcn201/dcn201_clk_mgr.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn201/dcn201_clk_mgr.c b/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn201/dcn201_clk_mgr.c index f77840dd051e..7920f6f1aa62 100644 --- a/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn201/dcn201_clk_mgr.c +++ b/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn201/dcn201_clk_mgr.c @@ -113,8 +113,6 @@ static void dcn201_update_clocks(struct clk_mgr *clk_mgr_base, dcn2_read_clocks_from_hw_dentist(clk_mgr_base); } - clk_mgr_helper_get_active_display_cnt(dc, context); - if (should_set_clock(safe_to_lower, new_clocks->phyclk_khz, clk_mgr_base->clks.phyclk_khz)) clk_mgr_base->clks.phyclk_khz = new_clocks->phyclk_khz; -- 2.34.1
[PATCH 12/39] drm/amd/display: Check and log for function error codes
[WHAT & HOW] BIOS_CMD_TABLE_REVISION and link_transmitter_control can return error codes and errors should be reported. This fixes 3 CHECKED_RETURN issues reported by Coverity. Reviewed-by: Rodrigo Siqueira Acked-by: Alex Hung Signed-off-by: Alex Hung --- drivers/gpu/drm/amd/display/dc/bios/command_table2.c | 3 ++- drivers/gpu/drm/amd/display/dc/dce/dce_link_encoder.c | 5 - drivers/gpu/drm/amd/display/dc/dcn10/dcn10_link_encoder.c | 8 +++- 3 files changed, 13 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/amd/display/dc/bios/command_table2.c b/drivers/gpu/drm/amd/display/dc/bios/command_table2.c index cc000833d300..4254bdfefe38 100644 --- a/drivers/gpu/drm/amd/display/dc/bios/command_table2.c +++ b/drivers/gpu/drm/amd/display/dc/bios/command_table2.c @@ -227,7 +227,8 @@ static void init_transmitter_control(struct bios_parser *bp) uint8_t frev; uint8_t crev = 0; - BIOS_CMD_TABLE_REVISION(dig1transmittercontrol, frev, crev); + if (!BIOS_CMD_TABLE_REVISION(dig1transmittercontrol, frev, crev)) + BREAK_TO_DEBUGGER(); switch (crev) { case 6: diff --git a/drivers/gpu/drm/amd/display/dc/dce/dce_link_encoder.c b/drivers/gpu/drm/amd/display/dc/dce/dce_link_encoder.c index 136bd93c3b65..4a9d07c31bc5 100644 --- a/drivers/gpu/drm/amd/display/dc/dce/dce_link_encoder.c +++ b/drivers/gpu/drm/amd/display/dc/dce/dce_link_encoder.c @@ -1361,7 +1361,10 @@ void dce110_link_encoder_dp_set_lane_settings( cntl.lane_settings = training_lane_set.raw; /* call VBIOS table to set voltage swing and pre-emphasis */ - link_transmitter_control(enc110, &cntl); + if (link_transmitter_control(enc110, &cntl) != BP_RESULT_OK) { + DC_LOG_ERROR("%s: Failed to execute VBIOS command table!\n", __func__); + BREAK_TO_DEBUGGER(); + } } } diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_link_encoder.c b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_link_encoder.c index 4d0eed7598b2..e0558a78b11c 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_link_encoder.c +++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_link_encoder.c @@ -1104,6 +1104,7 @@ void dcn10_link_encoder_dp_set_lane_settings( union dpcd_training_lane_set training_lane_set = { { 0 } }; int32_t lane = 0; struct bp_transmitter_control cntl = { 0 }; + enum bp_result result; if (!link_settings) { BREAK_TO_DEBUGGER(); @@ -1138,7 +1139,12 @@ void dcn10_link_encoder_dp_set_lane_settings( cntl.lane_settings = training_lane_set.raw; /* call VBIOS table to set voltage swing and pre-emphasis */ - link_transmitter_control(enc10, &cntl); + result = link_transmitter_control(enc10, &cntl); + + if (result != BP_RESULT_OK) { + DC_LOG_ERROR("%s: Failed to execute VBIOS command table!\n", __func__); + BREAK_TO_DEBUGGER(); + } } } -- 2.34.1
[PATCH 13/39] drm/amd/display: Check and log for function error codes
[WHAT & HOW] dm_dmub_hw_init and drm_dp_mst_topology_mgr_set_mst can return error codes and errors should be reported. This fixes 2 CHECKED_RETURN issues reported by Coverity. Reviewed-by: Rodrigo Siqueira Acked-by: Alex Hung Signed-off-by: Alex Hung --- drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 5 - drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_debugfs.c | 5 - 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c index 60404385d4d0..590e899ae3d0 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c @@ -1302,6 +1302,7 @@ static void dm_dmub_hw_resume(struct amdgpu_device *adev) struct dmub_srv *dmub_srv = adev->dm.dmub_srv; enum dmub_status status; bool init; + int r; if (!dmub_srv) { /* DMUB isn't supported on the ASIC. */ @@ -1319,7 +1320,9 @@ static void dm_dmub_hw_resume(struct amdgpu_device *adev) DRM_WARN("Wait for DMUB auto-load failed: %d\n", status); } else { /* Perform the full hardware initialization. */ - dm_dmub_hw_init(adev); + r = dm_dmub_hw_init(adev); + if (r) + DRM_ERROR("DMUB interface failed to initialize: status=%d\n", r); } } diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_debugfs.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_debugfs.c index 717d97191dda..62cb59f00929 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_debugfs.c +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_debugfs.c @@ -3795,6 +3795,7 @@ static int trigger_hpd_mst_set(void *data, u64 val) struct amdgpu_dm_connector *aconnector; struct drm_connector *connector; struct dc_link *link = NULL; + int ret; if (val == 1) { drm_connector_list_iter_begin(dev, &iter); @@ -3806,7 +3807,9 @@ static int trigger_hpd_mst_set(void *data, u64 val) dc_link_detect(aconnector->dc_link, DETECT_REASON_HPD); mutex_unlock(&adev->dm.dc_lock); - drm_dp_mst_topology_mgr_set_mst(&aconnector->mst_mgr, true); + ret = drm_dp_mst_topology_mgr_set_mst(&aconnector->mst_mgr, true); + if (ret < 0) + DRM_ERROR("DM_MST: Failed to set the device into MST mode!"); } } } else if (val == 0) { -- 2.34.1
[PATCH 14/39] drm/amd/display: Check HDCP returned status
[WHAT & HOW] Check mod_hdcp_execute_and_set() return values in authenticated_dp. This fixes 3 CHECKED_RETURN issues reported by Coverity. Reviewed-by: Rodrigo Siqueira Acked-by: Alex Hung Signed-off-by: Alex Hung --- .../amd/display/modules/hdcp/hdcp1_execution.c| 15 +-- 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/drivers/gpu/drm/amd/display/modules/hdcp/hdcp1_execution.c b/drivers/gpu/drm/amd/display/modules/hdcp/hdcp1_execution.c index 182e7532dda8..d77836cef563 100644 --- a/drivers/gpu/drm/amd/display/modules/hdcp/hdcp1_execution.c +++ b/drivers/gpu/drm/amd/display/modules/hdcp/hdcp1_execution.c @@ -433,17 +433,20 @@ static enum mod_hdcp_status authenticated_dp(struct mod_hdcp *hdcp, } if (status == MOD_HDCP_STATUS_SUCCESS) - mod_hdcp_execute_and_set(mod_hdcp_read_bstatus, + if (!mod_hdcp_execute_and_set(mod_hdcp_read_bstatus, &input->bstatus_read, &status, - hdcp, "bstatus_read"); + hdcp, "bstatus_read")) + goto out; if (status == MOD_HDCP_STATUS_SUCCESS) - mod_hdcp_execute_and_set(check_link_integrity_dp, + if (!mod_hdcp_execute_and_set(check_link_integrity_dp, &input->link_integrity_check, &status, - hdcp, "link_integrity_check"); + hdcp, "link_integrity_check")) + goto out; if (status == MOD_HDCP_STATUS_SUCCESS) - mod_hdcp_execute_and_set(check_no_reauthentication_request_dp, + if (!mod_hdcp_execute_and_set(check_no_reauthentication_request_dp, &input->reauth_request_check, &status, - hdcp, "reauth_request_check"); + hdcp, "reauth_request_check")) + goto out; out: return status; } -- 2.34.1
[PATCH 15/39] drm/amd/display: Add Replay general cmd
From: Joan Lee [WHY & HOW] Driver side adding replay general cmd interface. Replay general command will config at most two uint_32 parameters, with a replay general command subtype to set relative configurations. Reviewed-by: Nicholas Kazlauskas Acked-by: Alex Hung Signed-off-by: Joan Lee --- drivers/gpu/drm/amd/display/dc/dc_types.h | 1 + .../gpu/drm/amd/display/dc/dce/dmub_replay.c | 18 +- 2 files changed, 18 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/amd/display/dc/dc_types.h b/drivers/gpu/drm/amd/display/dc/dc_types.h index 21f4af9ab096..c550e8997033 100644 --- a/drivers/gpu/drm/amd/display/dc/dc_types.h +++ b/drivers/gpu/drm/amd/display/dc/dc_types.h @@ -1036,6 +1036,7 @@ enum replay_FW_Message_type { Replay_Set_Residency_Frameupdate_Timer, Replay_Set_Pseudo_VTotal, Replay_Disabled_Adaptive_Sync_SDP, + Replay_Set_General_Cmd, }; union replay_error_status { diff --git a/drivers/gpu/drm/amd/display/dc/dce/dmub_replay.c b/drivers/gpu/drm/amd/display/dc/dce/dmub_replay.c index 5437ebd8bc21..2a21bcf5224f 100644 --- a/drivers/gpu/drm/amd/display/dc/dce/dmub_replay.c +++ b/drivers/gpu/drm/amd/display/dc/dce/dmub_replay.c @@ -346,13 +346,29 @@ static void dmub_replay_send_cmd(struct dmub_replay *dmub, cmd.replay_disabled_adaptive_sync_sdp.header.sub_type = DMUB_CMD__REPLAY_DISABLED_ADAPTIVE_SYNC_SDP; cmd.replay_disabled_adaptive_sync_sdp.header.payload_bytes = - sizeof(struct dmub_rb_cmd_replay_set_pseudo_vtotal); + sizeof(struct dmub_rb_cmd_replay_disabled_adaptive_sync_sdp); //Cmd Body cmd.replay_disabled_adaptive_sync_sdp.data.panel_inst = cmd_element->disabled_adaptive_sync_sdp_data.panel_inst; cmd.replay_disabled_adaptive_sync_sdp.data.force_disabled = cmd_element->disabled_adaptive_sync_sdp_data.force_disabled; break; + case Replay_Set_General_Cmd: + //Header + cmd.replay_set_general_cmd.header.sub_type = + DMUB_CMD__REPLAY_SET_GENERAL_CMD; + cmd.replay_set_general_cmd.header.payload_bytes = + sizeof(struct dmub_rb_cmd_replay_set_general_cmd); + //Cmd Body + cmd.replay_set_general_cmd.data.panel_inst = + cmd_element->set_general_cmd_data.panel_inst; + cmd.replay_set_general_cmd.data.subtype = + cmd_element->set_general_cmd_data.subtype; + cmd.replay_set_general_cmd.data.param1 = + cmd_element->set_general_cmd_data.param1; + cmd.replay_set_general_cmd.data.param2 = + cmd_element->set_general_cmd_data.param2; + break; case Replay_Msg_Not_Support: default: return; -- 2.34.1
[PATCH 16/39] drm/amd/display: Use sw cursor for DCN401 with rotation
From: Aurabindo Pillai [WHAT & HOW] On DCN401, the cursor composition to the plane happens after scaler. So the cursor isn't stretched with the rest of the surface. Temporarily disable hardware cursor in case when hardware rotation is enabled such that userspace falls back to software cursor. Reviewed-by: Sun peng Li Reviewed-by: Rodrigo Siqueira Cc: Mario Limonciello Cc: Alex Deucher Cc: sta...@vger.kernel.org Acked-by: Alex Hung Signed-off-by: Aurabindo Pillai --- .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 34 --- 1 file changed, 29 insertions(+), 5 deletions(-) diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c index 590e899ae3d0..89e371f870b8 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c @@ -11093,8 +11093,12 @@ static int dm_crtc_get_cursor_mode(struct amdgpu_device *adev, int cursor_scale_w, cursor_scale_h; int i; - /* Overlay cursor not supported on HW before DCN */ - if (amdgpu_ip_version(adev, DCE_HWIP, 0) == 0) { + /* Overlay cursor not supported on HW before DCN +* DCN401 does not have the cursor-on-scaled-plane or cursor-on-yuv-plane restrictions +* as previous DCN generations, so enable native mode on DCN401 in addition to DCE +*/ + if (amdgpu_ip_version(adev, DCE_HWIP, 0) == 0 || + amdgpu_ip_version(adev, DCE_HWIP, 0) == IP_VERSION(4, 0, 1)) { *cursor_mode = DM_CURSOR_NATIVE_MODE; return 0; } @@ -11237,7 +11241,7 @@ static int amdgpu_dm_atomic_check(struct drm_device *dev, struct drm_crtc *crtc; struct drm_crtc_state *old_crtc_state, *new_crtc_state; struct drm_plane *plane; - struct drm_plane_state *old_plane_state, *new_plane_state; + struct drm_plane_state *old_plane_state, *new_plane_state, *new_cursor_state; enum dc_status status; int ret, i; bool lock_and_validation_needed = false; @@ -11465,19 +11469,39 @@ static int amdgpu_dm_atomic_check(struct drm_device *dev, drm_dbg_atomic(dev, "MPO enablement requested on crtc:[%p]\n", crtc); } - /* Check cursor planes restrictions */ + /* Check cursor restrictions */ for_each_new_crtc_in_state(state, crtc, new_crtc_state, i) { enum amdgpu_dm_cursor_mode required_cursor_mode; + int is_rotated, is_scaled; /* Overlay cusor not subject to native cursor restrictions */ dm_new_crtc_state = to_dm_crtc_state(new_crtc_state); if (dm_new_crtc_state->cursor_mode == DM_CURSOR_OVERLAY_MODE) continue; + /* Check if rotation or scaling is enabled on DCN401 */ + if ((drm_plane_mask(crtc->cursor) & new_crtc_state->plane_mask) && + amdgpu_ip_version(adev, DCE_HWIP, 0) == IP_VERSION(4, 0, 1)) { + new_cursor_state = drm_atomic_get_new_plane_state(state, crtc->cursor); + + is_rotated = new_cursor_state && + ((new_cursor_state->rotation & DRM_MODE_ROTATE_MASK) != DRM_MODE_ROTATE_0); + is_scaled = new_cursor_state && ((new_cursor_state->src_w >> 16 != new_cursor_state->crtc_w) || + (new_cursor_state->src_h >> 16 != new_cursor_state->crtc_h)); + + if (is_rotated || is_scaled) { + drm_dbg_driver( + crtc->dev, + "[CRTC:%d:%s] cannot enable hardware cursor due to rotation/scaling\n", + crtc->base.id, crtc->name); + ret = -EINVAL; + goto fail; + } + } + /* If HW can only do native cursor, check restrictions again */ ret = dm_crtc_get_cursor_mode(adev, state, dm_new_crtc_state, &required_cursor_mode); - if (ret) { drm_dbg_driver(crtc->dev, "[CRTC:%d:%s] Checking cursor mode failed\n", -- 2.34.1
[PATCH 17/39] drm/amd/display: Always enable HPO for DCN4 dGPU
From: "Leo (Hanghong) Ma" [WHY && HOW] Some DP EDID CTS tests fail due to HPO disable, and we should keep it enable on DCN4 dGPU. Reviewed-by: Wenjing Liu Cc: Mario Limonciello Cc: Alex Deucher Cc: sta...@vger.kernel.org Acked-by: Alex Hung Signed-off-by: Leo (Hanghong) Ma --- drivers/gpu/drm/amd/display/dc/hwss/dcn401/dcn401_hwseq.c | 2 ++ drivers/gpu/drm/amd/display/dc/hwss/dcn401/dcn401_init.c | 1 - 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/amd/display/dc/hwss/dcn401/dcn401_hwseq.c b/drivers/gpu/drm/amd/display/dc/hwss/dcn401/dcn401_hwseq.c index 42753f56d31d..79a911e1a09a 100644 --- a/drivers/gpu/drm/amd/display/dc/hwss/dcn401/dcn401_hwseq.c +++ b/drivers/gpu/drm/amd/display/dc/hwss/dcn401/dcn401_hwseq.c @@ -408,6 +408,8 @@ void dcn401_init_hw(struct dc *dc) REG_UPDATE(DCFCLK_CNTL, DCFCLK_GATE_DIS, 0); } + dcn401_setup_hpo_hw_control(hws, true); + if (!dcb->funcs->is_accelerated_mode(dcb) && dc->res_pool->hubbub->funcs->init_watermarks) dc->res_pool->hubbub->funcs->init_watermarks(dc->res_pool->hubbub); diff --git a/drivers/gpu/drm/amd/display/dc/hwss/dcn401/dcn401_init.c b/drivers/gpu/drm/amd/display/dc/hwss/dcn401/dcn401_init.c index 1cf0608e1980..8159fd838dc3 100644 --- a/drivers/gpu/drm/amd/display/dc/hwss/dcn401/dcn401_init.c +++ b/drivers/gpu/drm/amd/display/dc/hwss/dcn401/dcn401_init.c @@ -137,7 +137,6 @@ static const struct hwseq_private_funcs dcn401_private_funcs = { .program_mall_pipe_config = dcn32_program_mall_pipe_config, .update_force_pstate = dcn32_update_force_pstate, .update_mall_sel = dcn32_update_mall_sel, - .setup_hpo_hw_control = dcn401_setup_hpo_hw_control, .calculate_dccg_k1_k2_values = NULL, .apply_single_controller_ctx_to_hw = dce110_apply_single_controller_ctx_to_hw, .reset_back_end_for_pipe = dcn20_reset_back_end_for_pipe, -- 2.34.1
[PATCH 18/39] drm/amd/display: resync OTG after DIO FIFO resync
From: TungYu Lu [WHY] Tiled displays showed not aligned on 8K60hz when system resumed from S3/S4. [HOW] Do dc_trigger_sync to re-sync pipes to ensure OTG become synced. Reviewed-by: Alvin Lee Cc: Mario Limonciello Cc: Alex Deucher Cc: sta...@vger.kernel.org Acked-by: Alex Hung Signed-off-by: TungYu Lu --- drivers/gpu/drm/amd/display/dc/hwss/dcn32/dcn32_hwseq.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/gpu/drm/amd/display/dc/hwss/dcn32/dcn32_hwseq.c b/drivers/gpu/drm/amd/display/dc/hwss/dcn32/dcn32_hwseq.c index bdbb4a71651f..fe62478fbcde 100644 --- a/drivers/gpu/drm/amd/display/dc/hwss/dcn32/dcn32_hwseq.c +++ b/drivers/gpu/drm/amd/display/dc/hwss/dcn32/dcn32_hwseq.c @@ -1254,6 +1254,8 @@ void dcn32_resync_fifo_dccg_dio(struct dce_hwseq *hws, struct dc *dc, struct dc_ pipe->stream_res.tg->funcs->enable_crtc(pipe->stream_res.tg); } } + + dc_trigger_sync(dc, dc->current_state); } void dcn32_unblank_stream(struct pipe_ctx *pipe_ctx, -- 2.34.1
[PATCH 19/39] drm/amd/display: Call dpmm when checking mode support
From: George Shen [WHY] In check_mode_supported, we should validate that the required clocks can be successfully mapped to DPM levels. This ensures we only apply dynamic ODM optimizations to modes that are supported without dynamic ODM optimizations to begin with. [HOW] Call dpmm to check that the display config can successfully be mapped to a DPM level. Reviewed-by: Chaitanya Dhere Cc: Mario Limonciello Cc: Alex Deucher Cc: sta...@vger.kernel.org Acked-by: Alex Hung Signed-off-by: George Shen --- .../amd/display/dc/dml2/dml21/dml21_wrapper.c | 1 + .../dc/dml2/dml21/src/dml2_top/dml_top.c| 17 + .../dml21/src/inc/dml2_internal_shared_types.h | 1 + 3 files changed, 19 insertions(+) diff --git a/drivers/gpu/drm/amd/display/dc/dml2/dml21/dml21_wrapper.c b/drivers/gpu/drm/amd/display/dc/dml2/dml21/dml21_wrapper.c index b442e1f9f204..9c28304568d2 100644 --- a/drivers/gpu/drm/amd/display/dc/dml2/dml21/dml21_wrapper.c +++ b/drivers/gpu/drm/amd/display/dc/dml2/dml21/dml21_wrapper.c @@ -257,6 +257,7 @@ static bool dml21_check_mode_support(const struct dc *in_dc, struct dc_state *co mode_support->dml2_instance = dml_init->dml2_instance; dml21_map_dc_state_into_dml_display_cfg(in_dc, context, dml_ctx); + dml_ctx->v21.mode_programming.dml2_instance->scratch.build_mode_programming_locals.mode_programming_params.programming = dml_ctx->v21.mode_programming.programming; is_supported = dml2_check_mode_supported(mode_support); if (!is_supported) return false; diff --git a/drivers/gpu/drm/amd/display/dc/dml2/dml21/src/dml2_top/dml_top.c b/drivers/gpu/drm/amd/display/dc/dml2/dml21/src/dml2_top/dml_top.c index 6f334fdc6eb8..2fb3e2f45e07 100644 --- a/drivers/gpu/drm/amd/display/dc/dml2/dml21/src/dml2_top/dml_top.c +++ b/drivers/gpu/drm/amd/display/dc/dml2/dml21/src/dml2_top/dml_top.c @@ -96,10 +96,15 @@ bool dml2_check_mode_supported(struct dml2_check_mode_supported_in_out *in_out) { struct dml2_instance *dml = (struct dml2_instance *)in_out->dml2_instance; struct dml2_check_mode_supported_locals *l = &dml->scratch.check_mode_supported_locals; + /* Borrow the build_mode_programming_locals programming struct for DPMM call. */ + struct dml2_display_cfg_programming *dpmm_programming = dml->scratch.build_mode_programming_locals.mode_programming_params.programming; bool result = false; bool mcache_success = false; + if (dpmm_programming) + memset(dpmm_programming, 0, sizeof(struct dml2_display_cfg_programming)); + setup_unoptimized_display_config_with_meta(dml, &l->base_display_config_with_meta, in_out->display_config); l->mode_support_params.instance = &dml->core_instance; @@ -122,6 +127,18 @@ bool dml2_check_mode_supported(struct dml2_check_mode_supported_in_out *in_out) mcache_success = dml2_top_optimization_perform_optimization_phase(&l->optimization_phase_locals, &mcache_phase); } + /* +* Call DPMM to map all requirements to minimum clock state +*/ + if (result && dpmm_programming) { + l->dppm_map_mode_params.min_clk_table = &dml->min_clk_table; + l->dppm_map_mode_params.display_cfg = &l->base_display_config_with_meta; + l->dppm_map_mode_params.programming = dpmm_programming; + l->dppm_map_mode_params.soc_bb = &dml->soc_bbox; + l->dppm_map_mode_params.ip = &dml->core_instance.clean_me_up.mode_lib.ip; + result = dml->dpmm_instance.map_mode_to_soc_dpm(&l->dppm_map_mode_params); + } + in_out->is_supported = mcache_success; result = result && in_out->is_supported; diff --git a/drivers/gpu/drm/amd/display/dc/dml2/dml21/src/inc/dml2_internal_shared_types.h b/drivers/gpu/drm/amd/display/dc/dml2/dml21/src/inc/dml2_internal_shared_types.h index dd90c5df5a5a..5632cdacb7f4 100644 --- a/drivers/gpu/drm/amd/display/dc/dml2/dml21/src/inc/dml2_internal_shared_types.h +++ b/drivers/gpu/drm/amd/display/dc/dml2/dml21/src/inc/dml2_internal_shared_types.h @@ -870,6 +870,7 @@ struct dml2_check_mode_supported_locals { struct dml2_optimization_phase_locals optimization_phase_locals; struct display_configuation_with_meta base_display_config_with_meta; struct display_configuation_with_meta optimized_display_config_with_meta; + struct dml2_dpmm_map_mode_to_soc_dpm_params_in_out dppm_map_mode_params; }; struct optimization_init_function_params { -- 2.34.1
[PATCH 20/39] drm/amd/display: Add workaround to restrict max frac urgent for DPM0
From: Sung-huai Wang [WHY] Underflow occurs on some platforms when urgent BW is close to the maximum in DPM0. [HOW] It does not occur at DPM1, so as a workaround restrict the maximum amount and increase the lowest state index for clock states until we're out of DPM0. Adds DML2 config options to specify this pe platform as required. Reviewed-by: Nicholas Kazlauskas Acked-by: Alex Hung Signed-off-by: Sung-huai Wang --- .../gpu/drm/amd/display/dc/dml2/dml2_wrapper.c| 15 +++ .../gpu/drm/amd/display/dc/dml2/dml2_wrapper.h| 2 ++ .../display/dc/resource/dcn35/dcn35_resource.c| 3 ++- 3 files changed, 19 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/amd/display/dc/dml2/dml2_wrapper.c b/drivers/gpu/drm/amd/display/dc/dml2/dml2_wrapper.c index f6310408dbba..f4038ac2e476 100644 --- a/drivers/gpu/drm/amd/display/dc/dml2/dml2_wrapper.c +++ b/drivers/gpu/drm/amd/display/dc/dml2/dml2_wrapper.c @@ -628,6 +628,21 @@ static bool dml2_validate_and_build_resource(const struct dc *in_dc, struct dc_s if (result) { unsigned int lowest_state_idx = s->mode_support_params.out_lowest_state_idx; + double min_fclk_mhz_for_urgent_workaround = (double)dml2->config.min_fclk_for_urgent_workaround_khz / 1000.0; + double max_frac_urgent = (double)dml2->config.max_frac_urgent_for_min_fclk_x1000 / 1000.0; + + if (min_fclk_mhz_for_urgent_workaround > 0.0 && max_frac_urgent > 0.0 && + (dml2->v20.dml_core_ctx.mp.FractionOfUrgentBandwidth > max_frac_urgent || + dml2->v20.dml_core_ctx.mp.FractionOfUrgentBandwidthImmediateFlip > max_frac_urgent)) { + unsigned int forced_lowest_state_idx = lowest_state_idx; + + while (forced_lowest_state_idx < dml2->v20.dml_core_ctx.states.num_states && + dml2->v20.dml_core_ctx.states.state_array[forced_lowest_state_idx].fabricclk_mhz <= min_fclk_mhz_for_urgent_workaround) { + forced_lowest_state_idx += 1; + } + lowest_state_idx = forced_lowest_state_idx; + } + out_clks.dispclk_khz = (unsigned int)dml2->v20.dml_core_ctx.mp.Dispclk_calculated * 1000; out_clks.p_state_supported = s->mode_support_info.DRAMClockChangeSupport[0] != dml_dram_clock_change_unsupported; if (in_dc->config.use_default_clock_table && diff --git a/drivers/gpu/drm/amd/display/dc/dml2/dml2_wrapper.h b/drivers/gpu/drm/amd/display/dc/dml2/dml2_wrapper.h index 20b3970c0857..79bf2d757804 100644 --- a/drivers/gpu/drm/amd/display/dc/dml2/dml2_wrapper.h +++ b/drivers/gpu/drm/amd/display/dc/dml2/dml2_wrapper.h @@ -237,6 +237,8 @@ struct dml2_configuration_options { bool use_clock_dc_limits; bool gpuvm_enable; struct dml2_soc_bb *bb_from_dmub; + int max_frac_urgent_for_min_fclk_x1000; + int min_fclk_for_urgent_workaround_khz; }; /* diff --git a/drivers/gpu/drm/amd/display/dc/resource/dcn35/dcn35_resource.c b/drivers/gpu/drm/amd/display/dc/resource/dcn35/dcn35_resource.c index 67ab8c1962ff..1ce0f9ecff9c 100644 --- a/drivers/gpu/drm/amd/display/dc/resource/dcn35/dcn35_resource.c +++ b/drivers/gpu/drm/amd/display/dc/resource/dcn35/dcn35_resource.c @@ -2152,8 +2152,9 @@ static bool dcn35_resource_construct( dc->dml2_options.callbacks.can_support_mclk_switch_using_fw_based_vblank_stretch = &dcn30_can_support_mclk_switch_using_fw_based_vblank_stretch; dc->dml2_options.max_segments_per_hubp = 24; - dc->dml2_options.det_segment_size = DCN3_2_DET_SEG_SIZE;/*todo*/ + dc->dml2_options.max_frac_urgent_for_min_fclk_x1000 = 900; + dc->dml2_options.min_fclk_for_urgent_workaround_khz = 400 * 1000; if (dc->config.sdpif_request_limit_words_per_umc == 0) dc->config.sdpif_request_limit_words_per_umc = 16;/*todo*/ -- 2.34.1
[PATCH 21/39] drm/amd/display: Make DML2.1 P-State method force per stream
From: Dillon Varone [WHY & HOW] Currently the force only works for a single display, make it so it can be forced per stream. Reviewed-by: Alvin Lee Cc: Mario Limonciello Cc: Alex Deucher Cc: sta...@vger.kernel.org Acked-by: Alex Hung Signed-off-by: Dillon Varone --- drivers/gpu/drm/amd/display/dc/dc.h| 2 +- .../drm/amd/display/dc/dml2/dml21/dml21_translation_helper.c | 2 +- drivers/gpu/drm/amd/display/dc/dml2/dml21/dml21_wrapper.c | 3 ++- drivers/gpu/drm/amd/display/dc/dml2/dml2_wrapper.h | 2 +- 4 files changed, 5 insertions(+), 4 deletions(-) diff --git a/drivers/gpu/drm/amd/display/dc/dc.h b/drivers/gpu/drm/amd/display/dc/dc.h index d0d1af451b64..e0334b573f2d 100644 --- a/drivers/gpu/drm/amd/display/dc/dc.h +++ b/drivers/gpu/drm/amd/display/dc/dc.h @@ -1038,7 +1038,7 @@ struct dc_debug_options { bool force_chroma_subsampling_1tap; bool disable_422_left_edge_pixel; bool dml21_force_pstate_method; - uint32_t dml21_force_pstate_method_value; + uint32_t dml21_force_pstate_method_values[MAX_PIPES]; uint32_t dml21_disable_pstate_method_mask; union dmub_fams2_global_feature_config fams2_config; bool enable_legacy_clock_update; diff --git a/drivers/gpu/drm/amd/display/dc/dml2/dml21/dml21_translation_helper.c b/drivers/gpu/drm/amd/display/dc/dml2/dml21/dml21_translation_helper.c index d5ead0205053..06387b8b0aee 100644 --- a/drivers/gpu/drm/amd/display/dc/dml2/dml21/dml21_translation_helper.c +++ b/drivers/gpu/drm/amd/display/dc/dml2/dml21/dml21_translation_helper.c @@ -1000,7 +1000,7 @@ bool dml21_map_dc_state_into_dml_display_cfg(const struct dc *in_dc, struct dc_s /* apply forced pstate policy */ if (dml_ctx->config.pmo.force_pstate_method_enable) { dml_dispcfg->plane_descriptors[disp_cfg_plane_location].overrides.uclk_pstate_change_strategy = - dml21_force_pstate_method_to_uclk_state_change_strategy(dml_ctx->config.pmo.force_pstate_method_value); + dml21_force_pstate_method_to_uclk_state_change_strategy(dml_ctx->config.pmo.force_pstate_method_values[stream_index]); } } } diff --git a/drivers/gpu/drm/amd/display/dc/dml2/dml21/dml21_wrapper.c b/drivers/gpu/drm/amd/display/dc/dml2/dml21/dml21_wrapper.c index 9c28304568d2..c310354cd5fc 100644 --- a/drivers/gpu/drm/amd/display/dc/dml2/dml21/dml21_wrapper.c +++ b/drivers/gpu/drm/amd/display/dc/dml2/dml21/dml21_wrapper.c @@ -47,7 +47,8 @@ static void dml21_apply_debug_options(const struct dc *in_dc, struct dml2_contex /* UCLK P-State options */ if (in_dc->debug.dml21_force_pstate_method) { dml_ctx->config.pmo.force_pstate_method_enable = true; - dml_ctx->config.pmo.force_pstate_method_value = in_dc->debug.dml21_force_pstate_method_value; + for (int i = 0; i < MAX_PIPES; i++) + dml_ctx->config.pmo.force_pstate_method_values[i] = in_dc->debug.dml21_force_pstate_method_values[i]; } else { dml_ctx->config.pmo.force_pstate_method_enable = false; } diff --git a/drivers/gpu/drm/amd/display/dc/dml2/dml2_wrapper.h b/drivers/gpu/drm/amd/display/dc/dml2/dml2_wrapper.h index 79bf2d757804..1e891a3297c2 100644 --- a/drivers/gpu/drm/amd/display/dc/dml2/dml2_wrapper.h +++ b/drivers/gpu/drm/amd/display/dc/dml2/dml2_wrapper.h @@ -230,7 +230,7 @@ struct dml2_configuration_options { struct socbb_ip_params_external *external_socbb_ip_params; struct { bool force_pstate_method_enable; - enum dml2_force_pstate_methods force_pstate_method_value; + enum dml2_force_pstate_methods force_pstate_method_values[MAX_PIPES]; } pmo; bool map_dc_pipes_with_callbacks; -- 2.34.1
[PATCH 22/39] drm/amd/display: Fix reduced resolution and refresh rate
From: Daniel Sa [WHY] Some monitors are forced to a lower resolution and refresh rate after system restarts. [HOW] Some monitors may give invalid LTTPR information when queried such as indicating they have one DP lane instead of 4. If given an invalid DPCD version, skip over getting lttpr link rate and lane counts. Reviewed-by: Wenjing Liu Cc: Mario Limonciello Cc: Alex Deucher Cc: sta...@vger.kernel.org Acked-by: Alex Hung Signed-off-by: Daniel Sa --- .../dc/link/protocols/link_dp_capability.c| 21 ++- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_capability.c b/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_capability.c index f1cac74dd7f7..46bb7a855bc2 100644 --- a/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_capability.c +++ b/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_capability.c @@ -409,9 +409,6 @@ static enum dc_link_rate get_lttpr_max_link_rate(struct dc_link *link) case LINK_RATE_HIGH3: lttpr_max_link_rate = link->dpcd_caps.lttpr_caps.max_link_rate; break; - default: - // Assume all LTTPRs support up to HBR3 to improve misbehaving sink interop - lttpr_max_link_rate = LINK_RATE_HIGH3; } if (link->dpcd_caps.lttpr_caps.supported_128b_132b_rates.bits.UHBR20) @@ -2137,15 +2134,19 @@ struct dc_link_settings dp_get_max_link_cap(struct dc_link *link) * notes: repeaters do not snoop in the DPRX Capabilities addresses (3.6.3). */ if (dp_is_lttpr_present(link)) { - if (link->dpcd_caps.lttpr_caps.max_lane_count < max_link_cap.lane_count) - max_link_cap.lane_count = link->dpcd_caps.lttpr_caps.max_lane_count; - lttpr_max_link_rate = get_lttpr_max_link_rate(link); - if (lttpr_max_link_rate < max_link_cap.link_rate) - max_link_cap.link_rate = lttpr_max_link_rate; + /* Some LTTPR devices do not report valid DPCD revisions, if so, do not take it's link cap into consideration. */ + if (link->dpcd_caps.lttpr_caps.revision.raw >= DPCD_REV_14) { + if (link->dpcd_caps.lttpr_caps.max_lane_count < max_link_cap.lane_count) + max_link_cap.lane_count = link->dpcd_caps.lttpr_caps.max_lane_count; + lttpr_max_link_rate = get_lttpr_max_link_rate(link); - if (!link->dpcd_caps.lttpr_caps.supported_128b_132b_rates.bits.UHBR13_5) - is_uhbr13_5_supported = false; + if (lttpr_max_link_rate < max_link_cap.link_rate) + max_link_cap.link_rate = lttpr_max_link_rate; + + if (!link->dpcd_caps.lttpr_caps.supported_128b_132b_rates.bits.UHBR13_5) + is_uhbr13_5_supported = false; + } DC_LOG_HW_LINK_TRAINING("%s\n Training with LTTPR, max_lane count %d max_link rate %d \n", __func__, -- 2.34.1
[PATCH 23/39] drm/amd/display: Add null checks before accessing struct elements
[WHAT] 1. is_pwrseq0 needs to check link before accessing link->link_index. 2. context is checked before accessing its bw_ctx.dml2 3. clk_mgr_base->bw_params is checked before clk_table.num_entries_per_cl This fixes 4 REVERSE_INULL issues reported by Coverity. Reviewed-by: Rodrigo Siqueira Acked-by: Alex Hung Signed-off-by: Alex Hung --- .../drm/amd/display/dc/clk_mgr/dcn32/dcn32_clk_mgr.c | 10 ++ .../drm/amd/display/dc/clk_mgr/dcn401/dcn401_clk_mgr.c | 10 ++ drivers/gpu/drm/amd/display/dc/dml/dcn20/dcn20_fpu.c | 2 +- drivers/gpu/drm/amd/display/dc/dml2/dml2_wrapper.c | 4 +++- 4 files changed, 16 insertions(+), 10 deletions(-) diff --git a/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn32/dcn32_clk_mgr.c b/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn32/dcn32_clk_mgr.c index 06f0c41ad6f1..3b10b24f5e23 100644 --- a/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn32/dcn32_clk_mgr.c +++ b/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn32/dcn32_clk_mgr.c @@ -163,9 +163,14 @@ void dcn32_init_clocks(struct clk_mgr *clk_mgr_base) { struct clk_mgr_internal *clk_mgr = TO_CLK_MGR_INTERNAL(clk_mgr_base); unsigned int num_levels; - struct clk_limit_num_entries *num_entries_per_clk = &clk_mgr_base->bw_params->clk_table.num_entries_per_clk; + struct clk_limit_num_entries *num_entries_per_clk; unsigned int i; + if (!clk_mgr_base->bw_params) + return; + + num_entries_per_clk = &clk_mgr_base->bw_params->clk_table.num_entries_per_clk; + memset(&(clk_mgr_base->clks), 0, sizeof(struct dc_clocks)); clk_mgr_base->clks.p_state_change_support = true; clk_mgr_base->clks.prev_p_state_change_support = true; @@ -173,9 +178,6 @@ void dcn32_init_clocks(struct clk_mgr *clk_mgr_base) clk_mgr->smu_present = false; clk_mgr->dpm_present = false; - if (!clk_mgr_base->bw_params) - return; - if (!clk_mgr_base->force_smu_not_present && dcn30_smu_get_smu_version(clk_mgr, &clk_mgr->smu_ver)) clk_mgr->smu_present = true; diff --git a/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn401/dcn401_clk_mgr.c b/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn401/dcn401_clk_mgr.c index 70f06a7c882e..606b2411eee9 100644 --- a/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn401/dcn401_clk_mgr.c +++ b/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn401/dcn401_clk_mgr.c @@ -207,9 +207,14 @@ static void dcn401_build_wm_range_table(struct clk_mgr *clk_mgr) void dcn401_init_clocks(struct clk_mgr *clk_mgr_base) { struct clk_mgr_internal *clk_mgr = TO_CLK_MGR_INTERNAL(clk_mgr_base); - struct clk_limit_num_entries *num_entries_per_clk = &clk_mgr_base->bw_params->clk_table.num_entries_per_clk; + struct clk_limit_num_entries *num_entries_per_clk; unsigned int i; + if (!clk_mgr_base->bw_params) + return; + + num_entries_per_clk = &clk_mgr_base->bw_params->clk_table.num_entries_per_clk; + memset(&(clk_mgr_base->clks), 0, sizeof(struct dc_clocks)); clk_mgr_base->clks.p_state_change_support = true; clk_mgr_base->clks.prev_p_state_change_support = true; @@ -217,9 +222,6 @@ void dcn401_init_clocks(struct clk_mgr *clk_mgr_base) clk_mgr->smu_present = false; clk_mgr->dpm_present = false; - if (!clk_mgr_base->bw_params) - return; - if (!clk_mgr_base->force_smu_not_present && dcn30_smu_get_smu_version(clk_mgr, &clk_mgr->smu_ver)) clk_mgr->smu_present = true; diff --git a/drivers/gpu/drm/amd/display/dc/dml/dcn20/dcn20_fpu.c b/drivers/gpu/drm/amd/display/dc/dml/dcn20/dcn20_fpu.c index 54dd7e164635..8a8efe408a9d 100644 --- a/drivers/gpu/drm/amd/display/dc/dml/dcn20/dcn20_fpu.c +++ b/drivers/gpu/drm/amd/display/dc/dml/dcn20/dcn20_fpu.c @@ -1084,7 +1084,7 @@ static enum dcn_zstate_support_state decide_zstate_support(struct dc *dc, struc struct dc_stream_status *stream_status = &context->stream_status[0]; int minmum_z8_residency = dc->debug.minimum_z8_residency_time > 0 ? dc->debug.minimum_z8_residency_time : 1000; bool allow_z8 = context->bw_ctx.dml.vba.StutterPeriod > (double)minmum_z8_residency; - bool is_pwrseq0 = link->link_index == 0; + bool is_pwrseq0 = (link && link->link_index == 0); bool is_psr = (link && (link->psr_settings.psr_version == DC_PSR_VERSION_1 || link->psr_settings.psr_version == DC_PSR_VERSION_SU_1) && !link->panel_config.psr.disable_psr); bool is_replay = link && link->replay_settings.replay_feature_enabled; diff --git a/drivers/gpu/drm/amd/display/dc/dml2/dml2_wrapper.c b/drivers/gpu/drm/amd/display/dc/dml2/dml2_wrapper.c index f4038ac2e476..90bb6e718301 100644 --- a/drivers/gpu/drm/amd/display/dc/dml2/dml2_wrapper.c +++ b/drivers/gpu/drm/amd/display/dc/dml2/dml2_wrapper.c @@ -687,12 +687,14 @@ stat
[PATCH 24/39] drm/amd/display: Program CURSOR_DST_X_OFFSET in viewport space
From: Alvin Lee [WHAT & HOW] According to register specifications, the CURSOR_DST_X_OFFSET is relative to the start of the data viewport, not RECOUT space. In this case we must transform the cursor coordinates passed to hubp401_cursor_set_position into viewport space to program this register. This fixes an underflow issue that occurs in scaled mode with low refresh rate. Reviewed-by: Nevenko Stupar Cc: Mario Limonciello Cc: Alex Deucher Cc: sta...@vger.kernel.org Acked-by: Alex Hung Signed-off-by: Alvin Lee --- .../gpu/drm/amd/display/dc/hubp/dcn401/dcn401_hubp.c | 12 ++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/amd/display/dc/hubp/dcn401/dcn401_hubp.c b/drivers/gpu/drm/amd/display/dc/hubp/dcn401/dcn401_hubp.c index a893160ae775..3f9ca9b40949 100644 --- a/drivers/gpu/drm/amd/display/dc/hubp/dcn401/dcn401_hubp.c +++ b/drivers/gpu/drm/amd/display/dc/hubp/dcn401/dcn401_hubp.c @@ -656,7 +656,9 @@ void hubp401_cursor_set_position( int y_pos = pos->y - param->recout.y; int rec_x_offset = x_pos - pos->x_hotspot; int rec_y_offset = y_pos - pos->y_hotspot; - uint32_t dst_x_offset; + int dst_x_offset; + int x_pos_viewport = x_pos * param->viewport.width / param->recout.width; + int x_hot_viewport = pos->x_hotspot * param->viewport.width / param->recout.width; uint32_t cur_en = pos->enable ? 1 : 0; hubp->curs_pos = *pos; @@ -668,7 +670,13 @@ void hubp401_cursor_set_position( if (hubp->curs_attr.address.quad_part == 0) return; - dst_x_offset = (rec_x_offset >= 0) ? rec_x_offset : 0; + /* Translate the x position of the cursor from rect +* space into viewport space. CURSOR_DST_X_OFFSET +* is the offset relative to viewport start position. +*/ + dst_x_offset = x_pos_viewport - x_hot_viewport * + (1 + hubp->curs_attr.attribute_flags.bits.ENABLE_MAGNIFICATION); + dst_x_offset = (dst_x_offset >= 0) ? dst_x_offset : 0; dst_x_offset *= param->ref_clk_khz; dst_x_offset /= param->pixel_clk_khz; -- 2.34.1
[PATCH 25/39] drm/amd/display: Reset DSC memory status
From: Duncan Ma [WHY] When system exits idle state followed by enabling the display, DSC memory may still be forced in a deep sleep or shutdown state. Intermittent DSC corruption is seen when display is visible. [HOW] When DSC is enabled, reset dsc memory to force and disable status. Reviewed-by: Nicholas Kazlauskas Cc: Mario Limonciello Cc: Alex Deucher Cc: sta...@vger.kernel.org Acked-by: Alex Hung Signed-off-by: Duncan Ma --- .../drm/amd/display/dc/dsc/dcn20/dcn20_dsc.c | 24 +++- .../drm/amd/display/dc/dsc/dcn20/dcn20_dsc.h | 9 +++ .../drm/amd/display/dc/dsc/dcn35/dcn35_dsc.c | 58 ++- 3 files changed, 71 insertions(+), 20 deletions(-) diff --git a/drivers/gpu/drm/amd/display/dc/dsc/dcn20/dcn20_dsc.c b/drivers/gpu/drm/amd/display/dc/dsc/dcn20/dcn20_dsc.c index d6b2334d5364..75128fd34306 100644 --- a/drivers/gpu/drm/amd/display/dc/dsc/dcn20/dcn20_dsc.c +++ b/drivers/gpu/drm/amd/display/dc/dsc/dcn20/dcn20_dsc.c @@ -32,16 +32,6 @@ static void dsc_write_to_registers(struct display_stream_compressor *dsc, const struct dsc_reg_values *reg_vals); -/* Object I/F functions */ -static void dsc2_read_state(struct display_stream_compressor *dsc, struct dcn_dsc_state *s); -static bool dsc2_validate_stream(struct display_stream_compressor *dsc, const struct dsc_config *dsc_cfg); -static void dsc2_set_config(struct display_stream_compressor *dsc, const struct dsc_config *dsc_cfg, - struct dsc_optc_config *dsc_optc_cfg); -static void dsc2_enable(struct display_stream_compressor *dsc, int opp_pipe); -static void dsc2_disable(struct display_stream_compressor *dsc); -static void dsc2_disconnect(struct display_stream_compressor *dsc); -static void dsc2_wait_disconnect_pending_clear(struct display_stream_compressor *dsc); - static const struct dsc_funcs dcn20_dsc_funcs = { .dsc_get_enc_caps = dsc2_get_enc_caps, .dsc_read_state = dsc2_read_state, @@ -156,7 +146,7 @@ void dsc2_get_enc_caps(struct dsc_enc_caps *dsc_enc_caps, int pixel_clock_100Hz) /* this function read dsc related register fields to be logged later in dcn10_log_hw_state * into a dcn_dsc_state struct. */ -static void dsc2_read_state(struct display_stream_compressor *dsc, struct dcn_dsc_state *s) +void dsc2_read_state(struct display_stream_compressor *dsc, struct dcn_dsc_state *s) { struct dcn20_dsc *dsc20 = TO_DCN20_DSC(dsc); @@ -173,7 +163,7 @@ static void dsc2_read_state(struct display_stream_compressor *dsc, struct dcn_ds } -static bool dsc2_validate_stream(struct display_stream_compressor *dsc, const struct dsc_config *dsc_cfg) +bool dsc2_validate_stream(struct display_stream_compressor *dsc, const struct dsc_config *dsc_cfg) { struct dsc_optc_config dsc_optc_cfg; struct dcn20_dsc *dsc20 = TO_DCN20_DSC(dsc); @@ -196,7 +186,7 @@ void dsc_config_log(struct display_stream_compressor *dsc, const struct dsc_conf DC_LOG_DSC("\tcolor_depth %d", config->color_depth); } -static void dsc2_set_config(struct display_stream_compressor *dsc, const struct dsc_config *dsc_cfg, +void dsc2_set_config(struct display_stream_compressor *dsc, const struct dsc_config *dsc_cfg, struct dsc_optc_config *dsc_optc_cfg) { bool is_config_ok; @@ -233,7 +223,7 @@ bool dsc2_get_packed_pps(struct display_stream_compressor *dsc, const struct dsc } -static void dsc2_enable(struct display_stream_compressor *dsc, int opp_pipe) +void dsc2_enable(struct display_stream_compressor *dsc, int opp_pipe) { struct dcn20_dsc *dsc20 = TO_DCN20_DSC(dsc); int dsc_clock_en; @@ -258,7 +248,7 @@ static void dsc2_enable(struct display_stream_compressor *dsc, int opp_pipe) } -static void dsc2_disable(struct display_stream_compressor *dsc) +void dsc2_disable(struct display_stream_compressor *dsc) { struct dcn20_dsc *dsc20 = TO_DCN20_DSC(dsc); int dsc_clock_en; @@ -277,14 +267,14 @@ static void dsc2_disable(struct display_stream_compressor *dsc) DSC_CLOCK_EN, 0); } -static void dsc2_wait_disconnect_pending_clear(struct display_stream_compressor *dsc) +void dsc2_wait_disconnect_pending_clear(struct display_stream_compressor *dsc) { struct dcn20_dsc *dsc20 = TO_DCN20_DSC(dsc); REG_WAIT(DSCRM_DSC_FORWARD_CONFIG, DSCRM_DSC_DOUBLE_BUFFER_REG_UPDATE_PENDING, 0, 2, 5); } -static void dsc2_disconnect(struct display_stream_compressor *dsc) +void dsc2_disconnect(struct display_stream_compressor *dsc) { struct dcn20_dsc *dsc20 = TO_DCN20_DSC(dsc); diff --git a/drivers/gpu/drm/amd/display/dc/dsc/dcn20/dcn20_dsc.h b/drivers/gpu/drm/amd/display/dc/dsc/dcn20/dcn20_dsc.h index a136b26c914c..a23308a785bc 100644 --- a/drivers/gpu/drm/amd/display/dc/dsc/dcn20/dcn20_dsc.h +++ b/drivers/gpu/drm/amd/display/dc/dsc/dcn20/dcn20_dsc.h @@ -597,5 +597,14 @@ bool dsc2_get_packed_pps(struct display_stream_compressor *dsc, const struct dsc_config *dsc_cfg,
[PATCH 26/39] drm/amd/display: Wait for double buffer update on ODM changes
From: Alvin Lee [WHAT & HOW] We must wait for ODM double buffer updates to complete before exiting the pipe update sequence or we may reduce DISPCLK and hit some transient underflow (pixel rate is reduced before the pipes have ODM enabled). Reviewed-by: Samson Tam Cc: Mario Limonciello Cc: Alex Deucher Cc: sta...@vger.kernel.org Acked-by: Alex Hung Signed-off-by: Alvin Lee --- .../amd/display/dc/hwss/dcn20/dcn20_hwseq.c | 23 +++ .../amd/display/dc/inc/hw/timing_generator.h | 1 + .../amd/display/dc/optc/dcn10/dcn10_optc.h| 3 ++- .../amd/display/dc/optc/dcn32/dcn32_optc.c| 13 +++ .../amd/display/dc/optc/dcn32/dcn32_optc.h| 2 ++ .../amd/display/dc/optc/dcn401/dcn401_optc.c | 1 + .../amd/display/dc/optc/dcn401/dcn401_optc.h | 1 + 7 files changed, 43 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/amd/display/dc/hwss/dcn20/dcn20_hwseq.c b/drivers/gpu/drm/amd/display/dc/hwss/dcn20/dcn20_hwseq.c index 4d359bb9b1ec..36797ed7ad8c 100644 --- a/drivers/gpu/drm/amd/display/dc/hwss/dcn20/dcn20_hwseq.c +++ b/drivers/gpu/drm/amd/display/dc/hwss/dcn20/dcn20_hwseq.c @@ -2227,6 +2227,29 @@ void dcn20_post_unlock_program_front_end( } } + for (i = 0; i < dc->res_pool->pipe_count; i++) { + struct pipe_ctx *pipe = &context->res_ctx.pipe_ctx[i]; + struct pipe_ctx *old_pipe = &dc->current_state->res_ctx.pipe_ctx[i]; + + /* When going from a smaller ODM slice count to larger, we must ensure double +* buffer update completes before we return to ensure we don't reduce DISPCLK +* before we've transitioned to 2:1 or 4:1 +*/ + if (resource_is_pipe_type(old_pipe, OTG_MASTER) && resource_is_pipe_type(pipe, OTG_MASTER) && + resource_get_odm_slice_count(old_pipe) < resource_get_odm_slice_count(pipe) && + dc_state_get_pipe_subvp_type(context, pipe) != SUBVP_PHANTOM) { + int j = 0; + struct timing_generator *tg = pipe->stream_res.tg; + + + if (tg->funcs->get_double_buffer_pending) { + for (j = 0; j < TIMEOUT_FOR_PIPE_ENABLE_US / polling_interval_us + && tg->funcs->get_double_buffer_pending(tg); j++) + udelay(polling_interval_us); + } + } + } + if (dc->res_pool->hubbub->funcs->force_pstate_change_control) dc->res_pool->hubbub->funcs->force_pstate_change_control( dc->res_pool->hubbub, false, false); diff --git a/drivers/gpu/drm/amd/display/dc/inc/hw/timing_generator.h b/drivers/gpu/drm/amd/display/dc/inc/hw/timing_generator.h index cd4826f329c1..0f453452234c 100644 --- a/drivers/gpu/drm/amd/display/dc/inc/hw/timing_generator.h +++ b/drivers/gpu/drm/amd/display/dc/inc/hw/timing_generator.h @@ -340,6 +340,7 @@ struct timing_generator_funcs { void (*wait_drr_doublebuffer_pending_clear)(struct timing_generator *tg); void (*set_long_vtotal)(struct timing_generator *optc, const struct long_vtotal_params *params); void (*wait_odm_doublebuffer_pending_clear)(struct timing_generator *tg); + bool (*get_double_buffer_pending)(struct timing_generator *tg); }; #endif diff --git a/drivers/gpu/drm/amd/display/dc/optc/dcn10/dcn10_optc.h b/drivers/gpu/drm/amd/display/dc/optc/dcn10/dcn10_optc.h index e3e70c1db040..369a13244e5e 100644 --- a/drivers/gpu/drm/amd/display/dc/optc/dcn10/dcn10_optc.h +++ b/drivers/gpu/drm/amd/display/dc/optc/dcn10/dcn10_optc.h @@ -562,7 +562,8 @@ struct dcn_optc_registers { type OTG_CRC_DATA_FORMAT;\ type OTG_V_TOTAL_LAST_USED_BY_DRR;\ type OTG_DRR_TIMING_DBUF_UPDATE_PENDING;\ - type OTG_H_TIMING_DIV_MODE_DB_UPDATE_PENDING; + type OTG_H_TIMING_DIV_MODE_DB_UPDATE_PENDING;\ + type OPTC_DOUBLE_BUFFER_PENDING;\ #define TG_REG_FIELD_LIST_DCN3_2(type) \ type OTG_H_TIMING_DIV_MODE_MANUAL; diff --git a/drivers/gpu/drm/amd/display/dc/optc/dcn32/dcn32_optc.c b/drivers/gpu/drm/amd/display/dc/optc/dcn32/dcn32_optc.c index 6c837409df42..00094f0e8470 100644 --- a/drivers/gpu/drm/amd/display/dc/optc/dcn32/dcn32_optc.c +++ b/drivers/gpu/drm/amd/display/dc/optc/dcn32/dcn32_optc.c @@ -297,6 +297,18 @@ static void optc32_set_drr( optc32_setup_manual_trigger(optc); } +bool optc32_get_double_buffer_pending(struct timing_generator *optc) +{ + struct optc *optc1 = DCN10TG_FROM_TG(optc); + uint32_t update_pending = 0; + + REG_GET(OPTC_INPUT_GLOBAL_CONTROL, + OPTC_DOUBLE_BUFFER_PENDING, + &update_pending); + + return (update_pending == 1); +} + static struct timing_generator_funcs dcn32_tg_funcs = { .validate_timing = optc1_validate_timing,
[PATCH 27/39] drm/amd/display: Fix cursor issues with ODMs and magnification
From: Nevenko Stupar [WHY & HOW] Adjust hot spot positions between ODM slices when cursor magnification is used. Reviewed-by: Sridevi Arvindekar Cc: Mario Limonciello Cc: Alex Deucher Cc: sta...@vger.kernel.org Acked-by: Alex Hung Signed-off-by: Nevenko Stupar --- .../gpu/drm/amd/display/dc/hwss/dcn401/dcn401_hwseq.c| 9 + 1 file changed, 9 insertions(+) diff --git a/drivers/gpu/drm/amd/display/dc/hwss/dcn401/dcn401_hwseq.c b/drivers/gpu/drm/amd/display/dc/hwss/dcn401/dcn401_hwseq.c index 79a911e1a09a..5306c8c170c5 100644 --- a/drivers/gpu/drm/amd/display/dc/hwss/dcn401/dcn401_hwseq.c +++ b/drivers/gpu/drm/amd/display/dc/hwss/dcn401/dcn401_hwseq.c @@ -1177,6 +1177,15 @@ void dcn401_set_cursor_position(struct pipe_ctx *pipe_ctx) if (x_pos < 0) { pos_cpy.x_hotspot -= x_pos; + if ((odm_combine_on) && (hubp->curs_attr.attribute_flags.bits.ENABLE_MAGNIFICATION)) { + if (hubp->curs_attr.width <= 128) { + pos_cpy.x_hotspot /= 2; + pos_cpy.x_hotspot += 1; + } else { + pos_cpy.x_hotspot /= 2; + pos_cpy.x_hotspot += 2; + } + } x_pos = 0; } -- 2.34.1
[PATCH 28/39] drm/amd/display: Add HW cursor visual confirm
From: Ryan Seto [WHY] Added HW cursor visual confirm [HOW] Added visual confirm logic when programming cursor positions. HW is programmed on cursor updates since cursor can change without flips. Reviewed-by: Alvin Lee Cc: Mario Limonciello Cc: Alex Deucher Cc: sta...@vger.kernel.org Acked-by: Alex Hung Signed-off-by: Ryan Seto --- .../gpu/drm/amd/display/dc/core/dc_stream.c | 29 +++ drivers/gpu/drm/amd/display/dc/dc.h | 1 + 2 files changed, 30 insertions(+) diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_stream.c b/drivers/gpu/drm/amd/display/dc/core/dc_stream.c index 9b24f448ce50..de0633f98158 100644 --- a/drivers/gpu/drm/amd/display/dc/core/dc_stream.c +++ b/drivers/gpu/drm/amd/display/dc/core/dc_stream.c @@ -416,6 +416,35 @@ bool dc_stream_program_cursor_position( if (reset_idle_optimizations && !dc->debug.disable_dmub_reallow_idle) dc_allow_idle_optimizations(dc, true); + /* apply/update visual confirm */ + if (dc->debug.visual_confirm == VISUAL_CONFIRM_HW_CURSOR) { + /* update software state */ + uint32_t color_value = MAX_TG_COLOR_VALUE; + int i; + + for (i = 0; i < dc->res_pool->pipe_count; i++) { + struct pipe_ctx *pipe_ctx = &dc->current_state->res_ctx.pipe_ctx[i]; + + /* adjust visual confirm color for all pipes with current stream */ + if (stream == pipe_ctx->stream) { + if (stream->cursor_position.enable) { + pipe_ctx->visual_confirm_color.color_r_cr = color_value; + pipe_ctx->visual_confirm_color.color_g_y = 0; + pipe_ctx->visual_confirm_color.color_b_cb = 0; + } else { + pipe_ctx->visual_confirm_color.color_r_cr = 0; + pipe_ctx->visual_confirm_color.color_g_y = 0; + pipe_ctx->visual_confirm_color.color_b_cb = color_value; + } + + /* programming hardware */ + if (pipe_ctx->plane_state) + dc->hwss.update_visual_confirm_color(dc, pipe_ctx, + pipe_ctx->plane_res.hubp->mpcc_id); + } + } + } + return true; } diff --git a/drivers/gpu/drm/amd/display/dc/dc.h b/drivers/gpu/drm/amd/display/dc/dc.h index e0334b573f2d..64241de70f15 100644 --- a/drivers/gpu/drm/amd/display/dc/dc.h +++ b/drivers/gpu/drm/amd/display/dc/dc.h @@ -476,6 +476,7 @@ enum visual_confirm { VISUAL_CONFIRM_SUBVP = 14, VISUAL_CONFIRM_MCLK_SWITCH = 16, VISUAL_CONFIRM_FAMS2 = 19, + VISUAL_CONFIRM_HW_CURSOR = 20, }; enum dc_psr_power_opts { -- 2.34.1
[PATCH 29/39] drm/amd/display: Remove a redundant check in authenticated_dp
From: Wenjing Liu [WHY] mod_hdcp_execute_and_set returns (*status == MOD_HDCP_STATUS_SUCCESS). When it return 0, it is guaranteed that status == MOD_HDCP_STATUS_SUCCESS will be evaluated as false. Since now we are using goto out already, all 3 if (status == MOD_HDCP_STATUS_SUCCESS) clauses are guaranteed to enter. Therefore we are removing the if statements due to redundancy. Reviewed-by: Rodrigo Siqueira Acked-by: Alex Hung Signed-off-by: Wenjing Liu --- .../display/modules/hdcp/hdcp1_execution.c| 27 +-- 1 file changed, 12 insertions(+), 15 deletions(-) diff --git a/drivers/gpu/drm/amd/display/modules/hdcp/hdcp1_execution.c b/drivers/gpu/drm/amd/display/modules/hdcp/hdcp1_execution.c index d77836cef563..1e495e884484 100644 --- a/drivers/gpu/drm/amd/display/modules/hdcp/hdcp1_execution.c +++ b/drivers/gpu/drm/amd/display/modules/hdcp/hdcp1_execution.c @@ -432,21 +432,18 @@ static enum mod_hdcp_status authenticated_dp(struct mod_hdcp *hdcp, goto out; } - if (status == MOD_HDCP_STATUS_SUCCESS) - if (!mod_hdcp_execute_and_set(mod_hdcp_read_bstatus, - &input->bstatus_read, &status, - hdcp, "bstatus_read")) - goto out; - if (status == MOD_HDCP_STATUS_SUCCESS) - if (!mod_hdcp_execute_and_set(check_link_integrity_dp, - &input->link_integrity_check, &status, - hdcp, "link_integrity_check")) - goto out; - if (status == MOD_HDCP_STATUS_SUCCESS) - if (!mod_hdcp_execute_and_set(check_no_reauthentication_request_dp, - &input->reauth_request_check, &status, - hdcp, "reauth_request_check")) - goto out; + if (!mod_hdcp_execute_and_set(mod_hdcp_read_bstatus, + &input->bstatus_read, &status, + hdcp, "bstatus_read")) + goto out; + if (!mod_hdcp_execute_and_set(check_link_integrity_dp, + &input->link_integrity_check, &status, + hdcp, "link_integrity_check")) + goto out; + if (!mod_hdcp_execute_and_set(check_no_reauthentication_request_dp, + &input->reauth_request_check, &status, + hdcp, "reauth_request_check")) + goto out; out: return status; } -- 2.34.1
[PATCH 30/39] drm/amd/display: Adjust reg field for DSC wait for disconnect
From: Ryan Seto [WHY] DSC was waiting for the wrong field to disconnect cleanly. [HOW] Changed field the DSC disconnect was waiting on. Reviewed-by: Wenjing Liu Cc: Mario Limonciello Cc: Alex Deucher Cc: sta...@vger.kernel.org Acked-by: Alex Hung Signed-off-by: Ryan Seto --- drivers/gpu/drm/amd/display/dc/dsc/dcn20/dcn20_dsc.h | 4 +++- drivers/gpu/drm/amd/display/dc/dsc/dcn401/dcn401_dsc.c | 2 +- drivers/gpu/drm/amd/display/dc/dsc/dcn401/dcn401_dsc.h | 3 ++- 3 files changed, 6 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/amd/display/dc/dsc/dcn20/dcn20_dsc.h b/drivers/gpu/drm/amd/display/dc/dsc/dcn20/dcn20_dsc.h index a23308a785bc..1fb90b52b814 100644 --- a/drivers/gpu/drm/amd/display/dc/dsc/dcn20/dcn20_dsc.h +++ b/drivers/gpu/drm/amd/display/dc/dsc/dcn20/dcn20_dsc.h @@ -454,7 +454,9 @@ type DSCCIF_UPDATE_TAKEN_ACK; \ type DSCRM_DSC_FORWARD_EN; \ type DSCRM_DSC_OPP_PIPE_SOURCE; \ - type DSCRM_DSC_DOUBLE_BUFFER_REG_UPDATE_PENDING + type DSCRM_DSC_DOUBLE_BUFFER_REG_UPDATE_PENDING; \ + type DSCRM_DSC_FORWARD_EN_STATUS + struct dcn20_dsc_registers { uint32_t DSC_TOP_CONTROL; diff --git a/drivers/gpu/drm/amd/display/dc/dsc/dcn401/dcn401_dsc.c b/drivers/gpu/drm/amd/display/dc/dsc/dcn401/dcn401_dsc.c index 52f23bb554af..6acb6699f146 100644 --- a/drivers/gpu/drm/amd/display/dc/dsc/dcn401/dcn401_dsc.c +++ b/drivers/gpu/drm/amd/display/dc/dsc/dcn401/dcn401_dsc.c @@ -208,7 +208,7 @@ static void dsc401_wait_disconnect_pending_clear(struct display_stream_compresso { struct dcn401_dsc *dsc401 = TO_DCN401_DSC(dsc); - REG_WAIT(DSCRM_DSC_FORWARD_CONFIG, DSCRM_DSC_DOUBLE_BUFFER_REG_UPDATE_PENDING, 0, 2, 5); + REG_WAIT(DSCRM_DSC_FORWARD_CONFIG, DSCRM_DSC_FORWARD_EN_STATUS, 0, 2, 5); } static void dsc401_disconnect(struct display_stream_compressor *dsc) diff --git a/drivers/gpu/drm/amd/display/dc/dsc/dcn401/dcn401_dsc.h b/drivers/gpu/drm/amd/display/dc/dsc/dcn401/dcn401_dsc.h index 2143e81ca22a..3c9fa8988974 100644 --- a/drivers/gpu/drm/amd/display/dc/dsc/dcn401/dcn401_dsc.h +++ b/drivers/gpu/drm/amd/display/dc/dsc/dcn401/dcn401_dsc.h @@ -196,7 +196,8 @@ DSC2_SF(DSCCIF0, DSCCIF_CONFIG0__BITS_PER_COMPONENT, mask_sh), \ DSC_SF(DSCCIF0_DSCCIF_CONFIG0, DOUBLE_BUFFER_REG_UPDATE_PENDING, mask_sh), \ DSC_SF(DSCRM0_DSCRM_DSC_FORWARD_CONFIG, DSCRM_DSC_FORWARD_EN, mask_sh), \ - DSC_SF(DSCRM0_DSCRM_DSC_FORWARD_CONFIG, DSCRM_DSC_OPP_PIPE_SOURCE, mask_sh) + DSC_SF(DSCRM0_DSCRM_DSC_FORWARD_CONFIG, DSCRM_DSC_OPP_PIPE_SOURCE, mask_sh), \ + DSC_SF(DSCRM0_DSCRM_DSC_FORWARD_CONFIG, DSCRM_DSC_FORWARD_EN_STATUS, mask_sh) struct dcn401_dsc_registers { uint32_t DSC_TOP_CONTROL; -- 2.34.1
[PATCH 31/39] drm/amd/display: Fix 1DLUT setting for NL SDR blending
From: Relja Vojvodic [WHY] Enabling NL SDR blending caused the 1D LUTs to be set/populated in two different functions. This caused flickering as the LUT was set differently by the two functions, one of which should only have been modifying the 1D LUT if 3D LUT was enabled. [HOW] Added check to only modify the 1D LUT in populate_mcm if 3D LUT was enabled. Added blend_tf function update for non-main planes if the 3D LUT path was taken. Reviewed-by: Ilya Bakoulin Cc: Mario Limonciello Cc: Alex Deucher Cc: sta...@vger.kernel.org Acked-by: Alex Hung Signed-off-by: Relja Vojvodic --- drivers/gpu/drm/amd/display/dc/hwss/dcn401/dcn401_hwseq.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/amd/display/dc/hwss/dcn401/dcn401_hwseq.c b/drivers/gpu/drm/amd/display/dc/hwss/dcn401/dcn401_hwseq.c index 5306c8c170c5..b5a02a8fc9d8 100644 --- a/drivers/gpu/drm/amd/display/dc/hwss/dcn401/dcn401_hwseq.c +++ b/drivers/gpu/drm/amd/display/dc/hwss/dcn401/dcn401_hwseq.c @@ -502,7 +502,7 @@ void dcn401_populate_mcm_luts(struct dc *dc, dcn401_get_mcm_lut_xable_from_pipe_ctx(dc, pipe_ctx, &shaper_xable, &lut3d_xable, &lut1d_xable); /* 1D LUT */ - if (mcm_luts.lut1d_func) { + if (mcm_luts.lut1d_func && lut3d_xable != MCM_LUT_DISABLE) { memset(&m_lut_params, 0, sizeof(m_lut_params)); if (mcm_luts.lut1d_func->type == TF_TYPE_HWPWL) m_lut_params.pwl = &mcm_luts.lut1d_func->pwl; @@ -674,7 +674,7 @@ bool dcn401_set_mcm_luts(struct pipe_ctx *pipe_ctx, mpc->funcs->set_movable_cm_location(mpc, MPCC_MOVABLE_CM_LOCATION_BEFORE, mpcc_id); pipe_ctx->plane_state->mcm_location = MPCC_MOVABLE_CM_LOCATION_BEFORE; // 1D LUT - if (!plane_state->mcm_lut1d_enable) { + if (plane_state->mcm_shaper_3dlut_setting == DC_CM2_SHAPER_3DLUT_SETTING_BYPASS_ALL) { if (plane_state->blend_tf.type == TF_TYPE_HWPWL) lut_params = &plane_state->blend_tf.pwl; else if (plane_state->blend_tf.type == TF_TYPE_DISTRIBUTED_POINTS) { -- 2.34.1
[PATCH 32/39] drm/amd/display: Use periodic detection for ipx/headless
From: Roman Li [WHY] Hotplug is not detected in headless (no eDP) mode on dcn35x. With no display dcn35x goes to IPS2 powersaving state where HPD interrupt is not handled. [HOW] Use idle worker thread for periodic detection of HPD in headless mode. Reviewed-by: Aurabindo Pillai Cc: Mario Limonciello Cc: Alex Deucher Cc: sta...@vger.kernel.org Acked-by: Alex Hung Signed-off-by: Roman Li --- .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h | 3 ++ .../amd/display/amdgpu_dm/amdgpu_dm_crtc.c| 48 +++ .../amd/display/amdgpu_dm/amdgpu_dm_helpers.c | 5 +- 3 files changed, 46 insertions(+), 10 deletions(-) diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h index dfcbc1970fe6..5fd1b6b44577 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h @@ -989,4 +989,7 @@ void *dm_allocate_gpu_mem(struct amdgpu_device *adev, enum dc_gpu_mem_alloc_type type, size_t size, long long *addr); + +bool amdgpu_dm_is_headless(struct amdgpu_device *adev); + #endif /* __AMDGPU_DM_H__ */ diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_crtc.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_crtc.c index e16eecb146fd..99014339aaa3 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_crtc.c +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_crtc.c @@ -162,33 +162,63 @@ static void amdgpu_dm_crtc_set_panel_sr_feature( } } +bool amdgpu_dm_is_headless(struct amdgpu_device *adev) +{ + struct drm_connector *connector; + struct drm_connector_list_iter iter; + struct drm_device *dev; + bool is_headless = true; + + if (adev == NULL) + return true; + + dev = adev->dm.ddev; + + drm_connector_list_iter_begin(dev, &iter); + drm_for_each_connector_iter(connector, &iter) { + + if (connector->connector_type == DRM_MODE_CONNECTOR_WRITEBACK) + continue; + + if (connector->status == connector_status_connected) { + is_headless = false; + break; + } + } + drm_connector_list_iter_end(&iter); + return is_headless; +} + static void amdgpu_dm_idle_worker(struct work_struct *work) { struct idle_workqueue *idle_work; idle_work = container_of(work, struct idle_workqueue, work); idle_work->dm->idle_workqueue->running = true; - fsleep(HPD_DETECTION_PERIOD_uS); - mutex_lock(&idle_work->dm->dc_lock); + while (idle_work->enable) { - if (!idle_work->dm->dc->idle_optimizations_allowed) + fsleep(HPD_DETECTION_PERIOD_uS); + mutex_lock(&idle_work->dm->dc_lock); + if (!idle_work->dm->dc->idle_optimizations_allowed) { + mutex_unlock(&idle_work->dm->dc_lock); break; - + } dc_allow_idle_optimizations(idle_work->dm->dc, false); mutex_unlock(&idle_work->dm->dc_lock); fsleep(HPD_DETECTION_TIME_uS); mutex_lock(&idle_work->dm->dc_lock); - if (!amdgpu_dm_psr_is_active_allowed(idle_work->dm)) + if (!amdgpu_dm_is_headless(idle_work->dm->adev) && + !amdgpu_dm_psr_is_active_allowed(idle_work->dm)) { + mutex_unlock(&idle_work->dm->dc_lock); break; + } - dc_allow_idle_optimizations(idle_work->dm->dc, true); + if (idle_work->enable) + dc_allow_idle_optimizations(idle_work->dm->dc, true); mutex_unlock(&idle_work->dm->dc_lock); - fsleep(HPD_DETECTION_PERIOD_uS); - mutex_lock(&idle_work->dm->dc_lock); } - mutex_unlock(&idle_work->dm->dc_lock); idle_work->dm->idle_workqueue->running = false; } diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_helpers.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_helpers.c index 659dd67be1ba..f5e1f2d1c5f2 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_helpers.c +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_helpers.c @@ -1239,8 +1239,11 @@ void dm_helpers_enable_periodic_detection(struct dc_context *ctx, bool enable) { struct amdgpu_device *adev = ctx->driver_context; - if (adev->dm.idle_workqueue) + if (adev->dm.idle_workqueue) { adev->dm.idle_workqueue->enable = enable; + if (enable && !adev->dm.idle_workqueue->running && amdgpu_dm_is_headless(adev)) + schedule_work(&adev->dm.idle_workqueue->work); + } } void dm_helpers_dp_mst_update_branch_bandwidth( -- 2.34.
[PATCH 33/39] drm/amd/display: Ensure curve to hw translation succeed
[WHAT & HOW] Check cm3_helper_translate_curve_to_hw_format runs successfully so the regamma_params is valid and can be used. Also revmoed two result assignments. This fixes 2 CHECKED_RETURN UNUSED_VALUE issues reported by Coverity. Reviewed-by: Harry Wentland Acked-by: Alex Hung Signed-off-by: Alex Hung --- drivers/gpu/drm/amd/display/dc/hwss/dcn30/dcn30_hwseq.c | 5 - drivers/gpu/drm/amd/display/dc/hwss/dcn32/dcn32_hwseq.c | 9 ++--- 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/drivers/gpu/drm/amd/display/dc/hwss/dcn30/dcn30_hwseq.c b/drivers/gpu/drm/amd/display/dc/hwss/dcn30/dcn30_hwseq.c index bcacfd893cf7..eaeeade31ed7 100644 --- a/drivers/gpu/drm/amd/display/dc/hwss/dcn30/dcn30_hwseq.c +++ b/drivers/gpu/drm/amd/display/dc/hwss/dcn30/dcn30_hwseq.c @@ -228,8 +228,11 @@ bool dcn30_set_blend_lut( if (plane_state->blend_tf.type == TF_TYPE_HWPWL) blend_lut = &plane_state->blend_tf.pwl; else if (plane_state->blend_tf.type == TF_TYPE_DISTRIBUTED_POINTS) { - cm3_helper_translate_curve_to_hw_format( + result = cm3_helper_translate_curve_to_hw_format( &plane_state->blend_tf, &dpp_base->regamma_params, false); + if (!result) + return result; + blend_lut = &dpp_base->regamma_params; } result = dpp_base->funcs->dpp_program_blnd_lut(dpp_base, blend_lut); diff --git a/drivers/gpu/drm/amd/display/dc/hwss/dcn32/dcn32_hwseq.c b/drivers/gpu/drm/amd/display/dc/hwss/dcn32/dcn32_hwseq.c index fe62478fbcde..05d8f81daa06 100644 --- a/drivers/gpu/drm/amd/display/dc/hwss/dcn32/dcn32_hwseq.c +++ b/drivers/gpu/drm/amd/display/dc/hwss/dcn32/dcn32_hwseq.c @@ -483,11 +483,14 @@ bool dcn32_set_mcm_luts( if (plane_state->blend_tf.type == TF_TYPE_HWPWL) lut_params = &plane_state->blend_tf.pwl; else if (plane_state->blend_tf.type == TF_TYPE_DISTRIBUTED_POINTS) { - cm3_helper_translate_curve_to_hw_format(&plane_state->blend_tf, + result = cm3_helper_translate_curve_to_hw_format(&plane_state->blend_tf, &dpp_base->regamma_params, false); + if (!result) + return result; + lut_params = &dpp_base->regamma_params; } - result = mpc->funcs->program_1dlut(mpc, lut_params, mpcc_id); + mpc->funcs->program_1dlut(mpc, lut_params, mpcc_id); lut_params = NULL; // Shaper @@ -501,7 +504,7 @@ bool dcn32_set_mcm_luts( lut_params = &dpp_base->shaper_params; } - result = mpc->funcs->program_shaper(mpc, lut_params, mpcc_id); + mpc->funcs->program_shaper(mpc, lut_params, mpcc_id); // 3D if (plane_state->lut3d_func.state.bits.initialized == 1) -- 2.34.1
[PATCH 34/39] drm/amd/display: Validate function returns
[WHAT & HOW] Function return values must be checked before data can be used in subsequent functions. This fixes 4 CHECKED_RETURN issues reported by Coverity. Reviewed-by: Harry Wentland Acked-by: Alex Hung Signed-off-by: Alex Hung --- drivers/gpu/drm/amd/display/dc/dc_dmub_srv.c | 7 +-- drivers/gpu/drm/amd/display/dc/hubbub/dcn20/dcn20_hubbub.c | 3 ++- .../drm/amd/display/dc/link/protocols/link_dp_training.c | 3 +-- 3 files changed, 8 insertions(+), 5 deletions(-) diff --git a/drivers/gpu/drm/amd/display/dc/dc_dmub_srv.c b/drivers/gpu/drm/amd/display/dc/dc_dmub_srv.c index b2051c4dd7b6..ded13026c8ff 100644 --- a/drivers/gpu/drm/amd/display/dc/dc_dmub_srv.c +++ b/drivers/gpu/drm/amd/display/dc/dc_dmub_srv.c @@ -245,7 +245,9 @@ bool dc_dmub_srv_cmd_run_list(struct dc_dmub_srv *dc_dmub_srv, unsigned int coun if (status == DMUB_STATUS_POWER_STATE_D3) return false; - dmub_srv_wait_for_idle(dmub, 10); + status = dmub_srv_wait_for_idle(dmub, 10); + if (status != DMUB_STATUS_OK) + return false; /* Requeue the command. */ status = dmub_srv_cmd_queue(dmub, &cmd_list[i]); @@ -517,7 +519,8 @@ void dc_dmub_srv_get_visual_confirm_color_cmd(struct dc *dc, struct pipe_ctx *pi union dmub_rb_cmd cmd = { 0 }; unsigned int panel_inst = 0; - dc_get_edp_link_panel_inst(dc, pipe_ctx->stream->link, &panel_inst); + if (!dc_get_edp_link_panel_inst(dc, pipe_ctx->stream->link, &panel_inst)) + return; memset(&cmd, 0, sizeof(cmd)); diff --git a/drivers/gpu/drm/amd/display/dc/hubbub/dcn20/dcn20_hubbub.c b/drivers/gpu/drm/amd/display/dc/hubbub/dcn20/dcn20_hubbub.c index 8901bd80f7d1..5c6f7ddafd6b 100644 --- a/drivers/gpu/drm/amd/display/dc/hubbub/dcn20/dcn20_hubbub.c +++ b/drivers/gpu/drm/amd/display/dc/hubbub/dcn20/dcn20_hubbub.c @@ -616,7 +616,8 @@ static bool hubbub2_program_watermarks( hubbub1->base.ctx->dc->clk_mgr->clks.p_state_change_support == false) safe_to_lower = true; - hubbub1_program_pstate_watermarks(hubbub, watermarks, refclk_mhz, safe_to_lower); + if (hubbub1_program_pstate_watermarks(hubbub, watermarks, refclk_mhz, safe_to_lower)) + wm_pending = true; REG_SET(DCHUBBUB_ARB_SAT_LEVEL, 0, DCHUBBUB_ARB_SAT_LEVEL, 60 * refclk_mhz); diff --git a/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_training.c b/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_training.c index 5a0f574056d4..988999c44475 100644 --- a/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_training.c +++ b/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_training.c @@ -1663,8 +1663,7 @@ bool perform_link_training_with_retries( if (status == LINK_TRAINING_ABORT) { enum dc_connection_type type = dc_connection_none; - link_detect_connection_type(link, &type); - if (type == dc_connection_none) { + if (link_detect_connection_type(link, &type) && type == dc_connection_none) { DC_LOG_HW_LINK_TRAINING("%s: Aborting training because sink unplugged\n", __func__); break; } -- 2.34.1
[PATCH 35/39] drm/amd/display: Remove always true condition
[WHAT & HOW] advanced_pstate_switching was initialized to false and never assigned to another value; as a result !advanced_pstate_switching is always true and should be removed. This fixes 2 DEADCODE issues reported by Coverity. Reviewed-by: Rodrigo Siqueira Acked-by: Alex Hung Signed-off-by: Alex Hung --- drivers/gpu/drm/amd/display/dc/dml2/dml2_wrapper.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/drivers/gpu/drm/amd/display/dc/dml2/dml2_wrapper.c b/drivers/gpu/drm/amd/display/dc/dml2/dml2_wrapper.c index 90bb6e718301..60e2bf4ae6de 100644 --- a/drivers/gpu/drm/amd/display/dc/dml2/dml2_wrapper.c +++ b/drivers/gpu/drm/amd/display/dc/dml2/dml2_wrapper.c @@ -442,7 +442,6 @@ static bool optimize_pstate_with_svp_and_drr(struct dml2_context *dml2, struct d bool result = false; int drr_display_index = 0, non_svp_streams = 0; bool force_svp = dml2->config.svp_pstate.force_enable_subvp; - bool advanced_pstate_switching = false; display_state->bw_ctx.bw.dcn.clk.fw_based_mclk_switching = false; display_state->bw_ctx.bw.dcn.legacy_svp_drr_stream_index_valid = false; @@ -451,8 +450,7 @@ static bool optimize_pstate_with_svp_and_drr(struct dml2_context *dml2, struct d if (!result) { pstate_optimization_done = true; - } else if (!advanced_pstate_switching || - (s->mode_support_info.DRAMClockChangeSupport[0] != dml_dram_clock_change_unsupported && !force_svp)) { + } else if (s->mode_support_info.DRAMClockChangeSupport[0] != dml_dram_clock_change_unsupported && !force_svp) { pstate_optimization_success = true; pstate_optimization_done = true; } -- 2.34.1
[PATCH 36/39] drm/amd/display: Remove duplicate null check
[WHAT & HOW] The same display null check was a few lines above. This fixes 1 DEADCODE issue reported by Coverity. Reviewed-by: Rodrigo Siqueira Acked-by: Alex Hung Signed-off-by: Alex Hung --- drivers/gpu/drm/amd/display/modules/hdcp/hdcp_psp.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/drivers/gpu/drm/amd/display/modules/hdcp/hdcp_psp.c b/drivers/gpu/drm/amd/display/modules/hdcp/hdcp_psp.c index 7c9805705fd3..8c137d7c032e 100644 --- a/drivers/gpu/drm/amd/display/modules/hdcp/hdcp_psp.c +++ b/drivers/gpu/drm/amd/display/modules/hdcp/hdcp_psp.c @@ -513,9 +513,6 @@ enum mod_hdcp_status mod_hdcp_hdcp2_create_session(struct mod_hdcp *hdcp) hdcp_cmd = (struct ta_hdcp_shared_memory *)psp->hdcp_context.context.mem_context.shared_buf; memset(hdcp_cmd, 0, sizeof(struct ta_hdcp_shared_memory)); - if (!display) - return MOD_HDCP_STATUS_DISPLAY_NOT_FOUND; - hdcp_cmd->in_msg.hdcp2_create_session_v2.display_handle = display->index; if (hdcp->connection.link.adjust.hdcp2.force_type == MOD_HDCP_FORCE_TYPE_0) -- 2.34.1
[PATCH 37/39] drm/amd: Add reg definitions for DCN401 DCC
From: Aurabindo Pillai [WHAT] Add the necessary register definitions to enable DCC on DCN4x Reviewed-by: Rodrigo Siqueira Acked-by: Alex Hung Signed-off-by: Aurabindo Pillai --- .../include/asic_reg/dcn/dcn_4_1_0_sh_mask.h | 110 ++ 1 file changed, 110 insertions(+) diff --git a/drivers/gpu/drm/amd/include/asic_reg/dcn/dcn_4_1_0_sh_mask.h b/drivers/gpu/drm/amd/include/asic_reg/dcn/dcn_4_1_0_sh_mask.h index 0c68f5d818bb..f42a276499cd 100644 --- a/drivers/gpu/drm/amd/include/asic_reg/dcn/dcn_4_1_0_sh_mask.h +++ b/drivers/gpu/drm/amd/include/asic_reg/dcn/dcn_4_1_0_sh_mask.h @@ -6430,6 +6430,28 @@ //DCHUBBUB_SDPIF_MEM_PWR_STATUS #define DCHUBBUB_SDPIF_MEM_PWR_STATUS__DCHUBBUB_SDPIF_MEM_PWR_STATE__SHIFT 0x0 #define DCHUBBUB_SDPIF_MEM_PWR_STATUS__DCHUBBUB_SDPIF_MEM_PWR_STATE_MASK 0x0003L +//DCHUBBUB_SDPIF_MCACHE_INVALIDATION_CTL +#define DCHUBBUB_SDPIF_MCACHE_INVALIDATION_CTL__DCHUBBUB_SDPIF_FLIP_AWAY_MISSING_PIPE0__SHIFT 0x0 +#define DCHUBBUB_SDPIF_MCACHE_INVALIDATION_CTL__DCHUBBUB_SDPIF_FLIP_AWAY_MISSING_PIPE1__SHIFT 0x1 +#define DCHUBBUB_SDPIF_MCACHE_INVALIDATION_CTL__DCHUBBUB_SDPIF_FLIP_AWAY_MISSING_PIPE2__SHIFT 0x2 +#define DCHUBBUB_SDPIF_MCACHE_INVALIDATION_CTL__DCHUBBUB_SDPIF_FLIP_AWAY_MISSING_PIPE3__SHIFT 0x3 +#define DCHUBBUB_SDPIF_MCACHE_INVALIDATION_CTL__DCHUBBUB_SDPIF_MCACHEID_INV_ERR_CLEAR_PIPE0__SHIFT 0xc +#define DCHUBBUB_SDPIF_MCACHE_INVALIDATION_CTL__DCHUBBUB_SDPIF_MCACHEID_INV_ERR_CLEAR_PIPE1__SHIFT 0xd +#define DCHUBBUB_SDPIF_MCACHE_INVALIDATION_CTL__DCHUBBUB_SDPIF_MCACHEID_INV_ERR_CLEAR_PIPE2__SHIFT 0xe +#define DCHUBBUB_SDPIF_MCACHE_INVALIDATION_CTL__DCHUBBUB_SDPIF_MCACHEID_INV_ERR_CLEAR_PIPE3__SHIFT 0xf +#define DCHUBBUB_SDPIF_MCACHE_INVALIDATION_CTL__DCHUBBUB_SDPIF_MCACHEID_INV_ERR_ENABLE__SHIFT 0x1c +#define DCHUBBUB_SDPIF_MCACHE_INVALIDATION_CTL__DCHUBBUB_SDPIF_MCACHEID_INV_VREADY_MODE__SHIFT 0x1f +#define DCHUBBUB_SDPIF_MCACHE_INVALIDATION_CTL__DCHUBBUB_SDPIF_FLIP_AWAY_MISSING_PIPE0_MASK 0x0001L +#define DCHUBBUB_SDPIF_MCACHE_INVALIDATION_CTL__DCHUBBUB_SDPIF_FLIP_AWAY_MISSING_PIPE1_MASK 0x0002L +#define DCHUBBUB_SDPIF_MCACHE_INVALIDATION_CTL__DCHUBBUB_SDPIF_FLIP_AWAY_MISSING_PIPE2_MASK 0x0004L +#define DCHUBBUB_SDPIF_MCACHE_INVALIDATION_CTL__DCHUBBUB_SDPIF_FLIP_AWAY_MISSING_PIPE3_MASK 0x0008L +#define DCHUBBUB_SDPIF_MCACHE_INVALIDATION_CTL__DCHUBBUB_SDPIF_MCACHEID_INV_ERR_CLEAR_PIPE0_MASK 0x1000L +#define DCHUBBUB_SDPIF_MCACHE_INVALIDATION_CTL__DCHUBBUB_SDPIF_MCACHEID_INV_ERR_CLEAR_PIPE1_MASK 0x2000L +#define DCHUBBUB_SDPIF_MCACHE_INVALIDATION_CTL__DCHUBBUB_SDPIF_MCACHEID_INV_ERR_CLEAR_PIPE2_MASK 0x4000L +#define DCHUBBUB_SDPIF_MCACHE_INVALIDATION_CTL__DCHUBBUB_SDPIF_MCACHEID_INV_ERR_CLEAR_PIPE3_MASK 0x8000L +#define DCHUBBUB_SDPIF_MCACHE_INVALIDATION_CTL__DCHUBBUB_SDPIF_MCACHEID_INV_ERR_ENABLE_MASK 0x1000L +#define DCHUBBUB_SDPIF_MCACHE_INVALIDATION_CTL__DCHUBBUB_SDPIF_MCACHEID_INV_VREADY_MODE_MASK 0x8000L + // addressBlock: dcn_dcec_dchubbubl_hubbub_ret_path_dispdec @@ -7084,6 +7106,11 @@ #define HUBP0_DCSURF_PRI_VIEWPORT_START__PRI_VIEWPORT_Y_START__SHIFT 0x10 #define HUBP0_DCSURF_PRI_VIEWPORT_START__PRI_VIEWPORT_X_START_MASK 0xL #define HUBP0_DCSURF_PRI_VIEWPORT_START__PRI_VIEWPORT_Y_START_MASK 0xL +//HUBP0_DCSURF_VIEWPORT_MCACHE_SPLIT_COORDINATE +#define HUBP0_DCSURF_VIEWPORT_MCACHE_SPLIT_COORDINATE__VIEWPORT_MCACHE_SPLIT_COORDINATE__SHIFT 0x0 +#define HUBP0_DCSURF_VIEWPORT_MCACHE_SPLIT_COORDINATE__VIEWPORT_MCACHE_SPLIT_COORDINATE_C__SHIFT 0x10 +#define HUBP0_DCSURF_VIEWPORT_MCACHE_SPLIT_COORDINATE__VIEWPORT_MCACHE_SPLIT_COORDINATE_MASK 0xL +#define HUBP0_DCSURF_VIEWPORT_MCACHE_SPLIT_COORDINATE__VIEWPORT_MCACHE_SPLIT_COORDINATE_C_MASK 0xL //HUBP0_DCSURF_PRI_VIEWPORT_DIMENSION #define HUBP0_DCSURF_PRI_VIEWPORT_DIMENSION__PRI_VIEWPORT_WIDTH__SHIFT 0x0 #define HUBP0_DCSURF_PRI_VIEWPORT_DIMENSION__PRI_VIEWPORT_HEIGHT__SHIFT 0x10 @@ -7244,6 +7271,23 @@ #define HUBP0_DCHUBP_MALL_SUB_VP2__SUB_VP_HEIGHT_NEXT_S1__SHIFT 0xc #define HUBP0_DCHUBP_MALL_SUB_VP2__SUB_VP_HEIGHT_CURR_S1_MASK 0x0FFFL #define HUBP0_DCHUBP_MALL_SUB_VP2__SUB_VP_HEIGHT_NEXT_S1_MASK
[PATCH 38/39] drm/amd/display: Enable DCC on DCN401
From: Aurabindo Pillai [WHAT] Add registers and entry points to enable DCC on DCN4x Reviewed-by: Rodrigo Siqueira Acked-by: Alex Hung Signed-off-by: Aurabindo Pillai --- drivers/gpu/drm/amd/display/dc/core/dc.c | 12 + .../drm/amd/display/dc/core/dc_hw_sequencer.c | 11 + drivers/gpu/drm/amd/display/dc/dc.h | 4 + .../drm/amd/display/dc/dml2/dml2_wrapper.c| 6 + .../drm/amd/display/dc/dml2/dml2_wrapper.h| 2 +- .../display/dc/hubbub/dcn30/dcn30_hubbub.c| 3 + .../display/dc/hubbub/dcn31/dcn31_hubbub.c| 3 + .../display/dc/hubbub/dcn401/dcn401_hubbub.c | 280 ++ .../display/dc/hubbub/dcn401/dcn401_hubbub.h | 5 + .../amd/display/dc/hubp/dcn20/dcn20_hubp.h| 14 + .../amd/display/dc/hubp/dcn401/dcn401_hubp.c | 21 ++ .../amd/display/dc/hubp/dcn401/dcn401_hubp.h | 14 +- .../amd/display/dc/hwss/dcn20/dcn20_hwseq.c | 4 + .../amd/display/dc/hwss/dcn401/dcn401_hwseq.c | 25 ++ .../amd/display/dc/hwss/dcn401/dcn401_hwseq.h | 2 + .../amd/display/dc/hwss/dcn401/dcn401_init.c | 1 + .../drm/amd/display/dc/hwss/hw_sequencer.h| 9 + .../gpu/drm/amd/display/dc/inc/core_types.h | 3 + .../gpu/drm/amd/display/dc/inc/hw/dchubbub.h | 4 + drivers/gpu/drm/amd/display/dc/inc/hw/hubp.h | 1 + .../dc/resource/dcn401/dcn401_resource.c | 9 + .../dc/resource/dcn401/dcn401_resource.h | 2 + 22 files changed, 433 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/amd/display/dc/core/dc.c b/drivers/gpu/drm/amd/display/dc/core/dc.c index a4ba6f99cd34..85a2ef82afa5 100644 --- a/drivers/gpu/drm/amd/display/dc/core/dc.c +++ b/drivers/gpu/drm/amd/display/dc/core/dc.c @@ -1264,6 +1264,9 @@ static void disable_dangling_plane(struct dc *dc, struct dc_state *context) apply_ctx_interdependent_lock(dc, dc->current_state, old_stream, false); dc->hwss.post_unlock_program_front_end(dc, dangling_context); } + + if (dc->res_pool->funcs->prepare_mcache_programming) + dc->res_pool->funcs->prepare_mcache_programming(dc, dangling_context); if (dc->hwss.program_front_end_for_ctx) { dc->hwss.interdependent_update_lock(dc, dc->current_state, true); dc->hwss.program_front_end_for_ctx(dc, dangling_context); @@ -2037,6 +2040,8 @@ static enum dc_status dc_commit_state_no_check(struct dc *dc, struct dc_state *c } /* Program all planes within new context*/ + if (dc->res_pool->funcs->prepare_mcache_programming) + dc->res_pool->funcs->prepare_mcache_programming(dc, context); if (dc->hwss.program_front_end_for_ctx) { dc->hwss.interdependent_update_lock(dc, context, true); dc->hwss.program_front_end_for_ctx(dc, context); @@ -3884,6 +3889,9 @@ static void commit_planes_for_stream(struct dc *dc, odm_pipe->ttu_regs.min_ttu_vblank = MAX_TTU; } + if (update_type != UPDATE_TYPE_FAST && dc->res_pool->funcs->prepare_mcache_programming) + dc->res_pool->funcs->prepare_mcache_programming(dc, context); + if ((update_type != UPDATE_TYPE_FAST) && stream->update_flags.bits.dsc_changed) if (top_pipe_to_program && top_pipe_to_program->stream_res.tg->funcs->lock_doublebuffer_enable) { @@ -3903,6 +3911,10 @@ static void commit_planes_for_stream(struct dc *dc, top_pipe_to_program->stream_res.tg); } + if (dc->hwss.wait_for_dcc_meta_propagation) { + dc->hwss.wait_for_dcc_meta_propagation(dc, top_pipe_to_program); + } + if (should_lock_all_pipes && dc->hwss.interdependent_update_lock) { if (dc->hwss.subvp_pipe_control_lock) dc->hwss.subvp_pipe_control_lock(dc, context, true, should_lock_all_pipes, NULL, subvp_prev_use); diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_hw_sequencer.c b/drivers/gpu/drm/amd/display/dc/core/dc_hw_sequencer.c index 5037474bf95c..87e36d51c56d 100644 --- a/drivers/gpu/drm/amd/display/dc/core/dc_hw_sequencer.c +++ b/drivers/gpu/drm/amd/display/dc/core/dc_hw_sequencer.c @@ -595,6 +595,12 @@ void hwss_build_fast_sequence(struct dc *dc, if (!plane || !stream) return; + if (dc->hwss.wait_for_dcc_meta_propagation) { + block_sequence[*num_steps].params.wait_for_dcc_meta_propagation_params.dc = dc; + block_sequence[*num_steps].params.wait_for_dcc_meta_propagation_params.top_pipe_to_program = pipe_ctx; + block_sequence[*num_steps].func = HUBP_WAIT_FOR_DCC_META_PROP; + (*num_steps)++; + } if (dc->hwss.subvp_pipe_control_lock_fast) { block_sequence[*num_steps].pa
[PATCH 39/39] drm/amd/display: 3.2.290
From: Aric Cyr This version brings along the following: - Enable DCC on DCN401 - Add reg definitions for DCN401 DCC - Remove duplicate null check - Remove always true condition - Validate function returns - Ensure curve to hw translation succeed - Use periodic detection for ipx/headless - Fix 1DLUT setting for NL SDR blending - Adjust reg field for DSC wait for disconnect - Remove a redundant check in authenticated_dp - Add HW cursor visual confirm - Fix cursor issues with ODMs and magnification - Wait for double buffer update on ODM changes - Reset DSC memory status - Program CURSOR_DST_X_OFFSET in viewport space - Add null checks before accessing struct elements - Fix reduced resolution and refresh rate - Make DML2.1 P-State method force per stream - Add workaround to restrict max frac urgent for DPM0 - Call dpmm when checking mode support - resync OTG after DIO FIFO resync - Always enable HPO for DCN4 dGPU - Use sw cursor for DCN401 with rotation - Add Replay general cmd - Check HDCP returned status - Check and log for function error codes - Check and log for function error codes - Remove useless function call - Fix uninitialized variables in dcn401 - Fix cursor size issues - Run DC_LOG_DC after checking link->link_enc - Remove redundant checks for pipe_ctx->stream - Send DP_TOTAL_LTTPR_CNT during detection if LTTPR is present - Fix cursor issues with ODMs and HW rotations - Remove unnecessary variable - Remove redundant var from display_rq_dig_calc in dml - Refactor dccg401_get_other_enable_symclk_fe Acked-by: Alex Hung Signed-off-by: Aric Cyr --- drivers/gpu/drm/amd/display/dc/dc.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/amd/display/dc/dc.h b/drivers/gpu/drm/amd/display/dc/dc.h index 40f183816e31..900892855436 100644 --- a/drivers/gpu/drm/amd/display/dc/dc.h +++ b/drivers/gpu/drm/amd/display/dc/dc.h @@ -55,7 +55,7 @@ struct aux_payload; struct set_config_cmd_payload; struct dmub_notification; -#define DC_VER "3.2.289" +#define DC_VER "3.2.290" #define MAX_SURFACES 3 #define MAX_PLANES 6 -- 2.34.1
Re: [PATCH] drm/amdgpu: clear IH_RB_W/RPTR during enabling interrupts in sriov case
On Thu, Jun 20, 2024 at 10:12 AM Danijel Slivka wrote: > > Clearing the IH_RB_W/RPTR during interrupts disable is not clearing > the RB_OVERFLOW bit. > Adding workaround to clear the wptr when enabling interrupts in case > RB_OVERFLOW bit is set. > > Signed-off-by: Danijel Slivka > --- > drivers/gpu/drm/amd/amdgpu/ih_v6_0.c | 6 ++ > 1 file changed, 6 insertions(+) > > diff --git a/drivers/gpu/drm/amd/amdgpu/ih_v6_0.c > b/drivers/gpu/drm/amd/amdgpu/ih_v6_0.c > index 3cb64c8f7175..d6212a98ca99 100644 > --- a/drivers/gpu/drm/amd/amdgpu/ih_v6_0.c > +++ b/drivers/gpu/drm/amd/amdgpu/ih_v6_0.c > @@ -147,6 +147,12 @@ static int ih_v6_0_toggle_ring_interrupts(struct > amdgpu_device *adev, > } > > if (enable) { > + if (amdgpu_sriov_vf(adev) && > + REG_GET_FIELD(RREG32(ih_regs->ih_rb_wptr), IH_RB_WPTR, > RB_OVERFLOW)) { > + /* clear rptr, wptr*/ > + WREG32(ih_regs->ih_rb_rptr, 0); > + WREG32(ih_regs->ih_rb_wptr, 0); > + } > ih->enabled = true; > } else { > /* set rptr, wptr to 0 */ These already get cleared in the else case and this function gets called at the start of ih_v6_0_irq_init() so these should already be cleared by the time we get here. Alex
Re: [PATCH] drm/amd/display: Remove redundant code and semicolons
On Thu, Jun 20, 2024 at 12:07 PM David Wu wrote: > > I think the "break;" there is to silence the compilation warning - it is > ugly but needed. Which break? It looks fine to me. Alex > > David > > On 2024-06-20 11:38, Alex Deucher wrote: > > Applied. Thanks! > > > > Alex > > > > On Thu, Jun 20, 2024 at 5:07 AM Jiapeng Chong > > wrote: > >> No functional modification involved. > >> > >> ./drivers/gpu/drm/amd/display/dc/dml2/dml21/src/dml2_core/dml2_core_shared.c:3171:2-3: > >> Unneeded semicolon. > >> ./drivers/gpu/drm/amd/display/dc/dml2/dml21/src/dml2_core/dml2_core_shared.c:3185:2-3: > >> Unneeded semicolon. > >> ./drivers/gpu/drm/amd/display/dc/dml2/dml21/src/dml2_core/dml2_core_shared.c:3200:2-3: > >> Unneeded semicolon. > >> > >> Reported-by: Abaci Robot > >> Closes: https://bugzilla.openanolis.cn/show_bug.cgi?id=9365 > >> Signed-off-by: Jiapeng Chong > >> --- > >> .../dml21/src/dml2_core/dml2_core_shared.c| 46 +-- > >> 1 file changed, 23 insertions(+), 23 deletions(-) > >> > >> diff --git > >> a/drivers/gpu/drm/amd/display/dc/dml2/dml21/src/dml2_core/dml2_core_shared.c > >> > >> b/drivers/gpu/drm/amd/display/dc/dml2/dml21/src/dml2_core/dml2_core_shared.c > >> index cfa4c4475821..1a9895b1833f 100644 > >> --- > >> a/drivers/gpu/drm/amd/display/dc/dml2/dml21/src/dml2_core/dml2_core_shared.c > >> +++ > >> b/drivers/gpu/drm/amd/display/dc/dml2/dml21/src/dml2_core/dml2_core_shared.c > >> @@ -3142,62 +3142,62 @@ static unsigned int > >> dml_get_tile_block_size_bytes(enum dml2_swizzle_mode sw_mode > >> { > >> switch (sw_mode) { > >> case (dml2_sw_linear): > >> - return 256; break; > >> + return 256; > >> case (dml2_sw_256b_2d): > >> - return 256; break; > >> + return 256; > >> case (dml2_sw_4kb_2d): > >> - return 4096; break; > >> + return 4096; > >> case (dml2_sw_64kb_2d): > >> - return 65536; break; > >> + return 65536; > >> case (dml2_sw_256kb_2d): > >> - return 262144; break; > >> + return 262144; > >> case (dml2_gfx11_sw_linear): > >> - return 256; break; > >> + return 256; > >> case (dml2_gfx11_sw_64kb_d): > >> - return 65536; break; > >> + return 65536; > >> case (dml2_gfx11_sw_64kb_d_t): > >> - return 65536; break; > >> + return 65536; > >> case (dml2_gfx11_sw_64kb_d_x): > >> - return 65536; break; > >> + return 65536; > >> case (dml2_gfx11_sw_64kb_r_x): > >> - return 65536; break; > >> + return 65536; > >> case (dml2_gfx11_sw_256kb_d_x): > >> - return 262144; break; > >> + return 262144; > >> case (dml2_gfx11_sw_256kb_r_x): > >> - return 262144; break; > >> + return 262144; > >> default: > >> DML2_ASSERT(0); > >> return 256; > >> - }; > >> + } > >> } > >> > >> const char *dml2_core_internal_bw_type_str(enum > >> dml2_core_internal_bw_type bw_type) > >> { > >> switch (bw_type) { > >> case (dml2_core_internal_bw_sdp): > >> - return("dml2_core_internal_bw_sdp"); break; > >> + return("dml2_core_internal_bw_sdp"); > >> case (dml2_core_internal_bw_dram): > >> - return("dml2_core_internal_bw_dram"); break; > >> + return("dml2_core_internal_bw_dram"); > >> case (dml2_core_internal_bw_max): > >> - return("dml2_core_internal_bw_max"); break; > >> + return("dml2_core_internal_bw_max"); > >> default: > >> - return("dml2_core_internal_bw_unknown"); break; > >> - }; > >> + return("dml2_core_internal_bw_unknown"); > >> + } > >> } > >> > >> const char *dml2_core_internal_soc_state_type_str(enum > >> dml2_core_internal_soc_state_type dml2_core_internal_soc_state_type) > >> { > >> switch (dml2_core_internal_soc_state_type) { > >> case (dml2_core_internal_soc_state_sys_idle): > >> - return("dml2_core_internal_soc_state_sys_idle"); break; > >> + return("dml2_core_internal_soc_state_sys_idle"); > >> case (dml2_core_internal_soc_state_sys_active): > >> - return("dml2_core_internal_soc_state_sys_active"); break; > >> + return("dml2_core_internal_soc_state_sys_active"); > >> case (dml2_core_internal_soc_state_svp_prefetch): > >> - return("dml2_core_internal_soc_state_svp_prefetch"); break; > >> + return("dml2_core_internal_soc_state_svp_prefetch"); > >> case dml2_core_internal_soc_state_max: > >> default: > >> - return("dml2_core_internal_soc_state_unk
Re: [PATCH] drm/amd/display: Remove redundant code and semicolons
see inline, please David On 2024-06-20 12:50, Alex Deucher wrote: On Thu, Jun 20, 2024 at 12:07 PM David Wu wrote: I think the "break;" there is to silence the compilation warning - it is ugly but needed. Which break? It looks fine to me. example here - code is fine but the compiler will complain about missing "break" for case statement. - return 256; break; + return 256; Alex David On 2024-06-20 11:38, Alex Deucher wrote: Applied. Thanks! Alex On Thu, Jun 20, 2024 at 5:07 AM Jiapeng Chong wrote: No functional modification involved. ./drivers/gpu/drm/amd/display/dc/dml2/dml21/src/dml2_core/dml2_core_shared.c:3171:2-3: Unneeded semicolon. ./drivers/gpu/drm/amd/display/dc/dml2/dml21/src/dml2_core/dml2_core_shared.c:3185:2-3: Unneeded semicolon. ./drivers/gpu/drm/amd/display/dc/dml2/dml21/src/dml2_core/dml2_core_shared.c:3200:2-3: Unneeded semicolon. Reported-by: Abaci Robot Closes: https://bugzilla.openanolis.cn/show_bug.cgi?id=9365 Signed-off-by: Jiapeng Chong --- .../dml21/src/dml2_core/dml2_core_shared.c| 46 +-- 1 file changed, 23 insertions(+), 23 deletions(-) diff --git a/drivers/gpu/drm/amd/display/dc/dml2/dml21/src/dml2_core/dml2_core_shared.c b/drivers/gpu/drm/amd/display/dc/dml2/dml21/src/dml2_core/dml2_core_shared.c index cfa4c4475821..1a9895b1833f 100644 --- a/drivers/gpu/drm/amd/display/dc/dml2/dml21/src/dml2_core/dml2_core_shared.c +++ b/drivers/gpu/drm/amd/display/dc/dml2/dml21/src/dml2_core/dml2_core_shared.c @@ -3142,62 +3142,62 @@ static unsigned int dml_get_tile_block_size_bytes(enum dml2_swizzle_mode sw_mode { switch (sw_mode) { case (dml2_sw_linear): - return 256; break; + return 256; case (dml2_sw_256b_2d): - return 256; break; + return 256; case (dml2_sw_4kb_2d): - return 4096; break; + return 4096; case (dml2_sw_64kb_2d): - return 65536; break; + return 65536; case (dml2_sw_256kb_2d): - return 262144; break; + return 262144; case (dml2_gfx11_sw_linear): - return 256; break; + return 256; case (dml2_gfx11_sw_64kb_d): - return 65536; break; + return 65536; case (dml2_gfx11_sw_64kb_d_t): - return 65536; break; + return 65536; case (dml2_gfx11_sw_64kb_d_x): - return 65536; break; + return 65536; case (dml2_gfx11_sw_64kb_r_x): - return 65536; break; + return 65536; case (dml2_gfx11_sw_256kb_d_x): - return 262144; break; + return 262144; case (dml2_gfx11_sw_256kb_r_x): - return 262144; break; + return 262144; default: DML2_ASSERT(0); return 256; - }; + } } const char *dml2_core_internal_bw_type_str(enum dml2_core_internal_bw_type bw_type) { switch (bw_type) { case (dml2_core_internal_bw_sdp): - return("dml2_core_internal_bw_sdp"); break; + return("dml2_core_internal_bw_sdp"); case (dml2_core_internal_bw_dram): - return("dml2_core_internal_bw_dram"); break; + return("dml2_core_internal_bw_dram"); case (dml2_core_internal_bw_max): - return("dml2_core_internal_bw_max"); break; + return("dml2_core_internal_bw_max"); default: - return("dml2_core_internal_bw_unknown"); break; - }; + return("dml2_core_internal_bw_unknown"); + } } const char *dml2_core_internal_soc_state_type_str(enum dml2_core_internal_soc_state_type dml2_core_internal_soc_state_type) { switch (dml2_core_internal_soc_state_type) { case (dml2_core_internal_soc_state_sys_idle): - return("dml2_core_internal_soc_state_sys_idle"); break; + return("dml2_core_internal_soc_state_sys_idle"); case (dml2_core_internal_soc_state_sys_active): - return("dml2_core_internal_soc_state_sys_active"); break; + return("dml2_core_internal_soc_state_sys_active"); case (dml2_core_internal_soc_state_svp_prefetch): - return("dml2_core_internal_soc_state_svp_prefetch"); break; + return("dml2_core_internal_soc_state_svp_prefetch"); case dml2_core_internal_soc_state_max: default: - return("dml2_core_internal_soc_state_unknown"); break; - }; + return("dml2_core_internal_soc_state_unknown"); + } } static bool dml_is_vertical_rotation(enum dml2_rotation_angle Scan) -- 2.20.1.7.g153144c
Re: [PATCH] drm/amd/display: Remove redundant code and semicolons
On Thu, Jun 20, 2024 at 1:18 PM David Wu wrote: > > see inline, please > David > > On 2024-06-20 12:50, Alex Deucher wrote: > > On Thu, Jun 20, 2024 at 12:07 PM David Wu wrote: > >> I think the "break;" there is to silence the compilation warning - it is > >> ugly but needed. > > Which break? It looks fine to me. > example here - code is fine but the compiler will complain about missing > "break" for case statement. > > - return 256; break; > + return 256; It shouldn't. Actually a number of checkers will complain about having a break after a return. Alex > > > > > Alex > > > >> David > >> > >> On 2024-06-20 11:38, Alex Deucher wrote: > >>> Applied. Thanks! > >>> > >>> Alex > >>> > >>> On Thu, Jun 20, 2024 at 5:07 AM Jiapeng Chong > >>> wrote: > No functional modification involved. > > ./drivers/gpu/drm/amd/display/dc/dml2/dml21/src/dml2_core/dml2_core_shared.c:3171:2-3: > Unneeded semicolon. > ./drivers/gpu/drm/amd/display/dc/dml2/dml21/src/dml2_core/dml2_core_shared.c:3185:2-3: > Unneeded semicolon. > ./drivers/gpu/drm/amd/display/dc/dml2/dml21/src/dml2_core/dml2_core_shared.c:3200:2-3: > Unneeded semicolon. > > Reported-by: Abaci Robot > Closes: https://bugzilla.openanolis.cn/show_bug.cgi?id=9365 > Signed-off-by: Jiapeng Chong > --- > .../dml21/src/dml2_core/dml2_core_shared.c| 46 +-- > 1 file changed, 23 insertions(+), 23 deletions(-) > > diff --git > a/drivers/gpu/drm/amd/display/dc/dml2/dml21/src/dml2_core/dml2_core_shared.c > > b/drivers/gpu/drm/amd/display/dc/dml2/dml21/src/dml2_core/dml2_core_shared.c > index cfa4c4475821..1a9895b1833f 100644 > --- > a/drivers/gpu/drm/amd/display/dc/dml2/dml21/src/dml2_core/dml2_core_shared.c > +++ > b/drivers/gpu/drm/amd/display/dc/dml2/dml21/src/dml2_core/dml2_core_shared.c > @@ -3142,62 +3142,62 @@ static unsigned int > dml_get_tile_block_size_bytes(enum dml2_swizzle_mode sw_mode > { > switch (sw_mode) { > case (dml2_sw_linear): > - return 256; break; > + return 256; > case (dml2_sw_256b_2d): > - return 256; break; > + return 256; > case (dml2_sw_4kb_2d): > - return 4096; break; > + return 4096; > case (dml2_sw_64kb_2d): > - return 65536; break; > + return 65536; > case (dml2_sw_256kb_2d): > - return 262144; break; > + return 262144; > case (dml2_gfx11_sw_linear): > - return 256; break; > + return 256; > case (dml2_gfx11_sw_64kb_d): > - return 65536; break; > + return 65536; > case (dml2_gfx11_sw_64kb_d_t): > - return 65536; break; > + return 65536; > case (dml2_gfx11_sw_64kb_d_x): > - return 65536; break; > + return 65536; > case (dml2_gfx11_sw_64kb_r_x): > - return 65536; break; > + return 65536; > case (dml2_gfx11_sw_256kb_d_x): > - return 262144; break; > + return 262144; > case (dml2_gfx11_sw_256kb_r_x): > - return 262144; break; > + return 262144; > default: > DML2_ASSERT(0); > return 256; > - }; > + } > } > > const char *dml2_core_internal_bw_type_str(enum > dml2_core_internal_bw_type bw_type) > { > switch (bw_type) { > case (dml2_core_internal_bw_sdp): > - return("dml2_core_internal_bw_sdp"); break; > + return("dml2_core_internal_bw_sdp"); > case (dml2_core_internal_bw_dram): > - return("dml2_core_internal_bw_dram"); break; > + return("dml2_core_internal_bw_dram"); > case (dml2_core_internal_bw_max): > - return("dml2_core_internal_bw_max"); break; > + return("dml2_core_internal_bw_max"); > default: > - return("dml2_core_internal_bw_unknown"); break; > - }; > + return("dml2_core_internal_bw_unknown"); > + } > } > > const char *dml2_core_internal_soc_state_type_str(enum > dml2_core_internal_soc_state_type dml2_core_internal_soc_state_type) > { > switch (dml2_core_internal_soc_state_type) { > case (dml2_core_internal_soc_state_sys_idle): > - return("dml2_core_inte
[PATCH] drm/amdgpu/gfx10: handle SDMA in KIQ map/unmap
Add support for SMDA to the KIQ map/unmap functions. Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/amdgpu/gfx_v10_0.c | 85 +- drivers/gpu/drm/amd/amdgpu/nvd.h | 2 + 2 files changed, 73 insertions(+), 14 deletions(-) diff --git a/drivers/gpu/drm/amd/amdgpu/gfx_v10_0.c b/drivers/gpu/drm/amd/amdgpu/gfx_v10_0.c index 18488c02d1cf..abbf906496fd 100644 --- a/drivers/gpu/drm/amd/amdgpu/gfx_v10_0.c +++ b/drivers/gpu/drm/amd/amdgpu/gfx_v10_0.c @@ -3693,25 +3693,58 @@ static void gfx10_kiq_map_queues(struct amdgpu_ring *kiq_ring, { uint64_t mqd_addr = amdgpu_bo_gpu_offset(ring->mqd_obj); uint64_t wptr_addr = ring->wptr_gpu_addr; - uint32_t eng_sel = 0; + uint32_t eng_sel, ext_eng_sel; - switch (ring->funcs->type) { - case AMDGPU_RING_TYPE_COMPUTE: - eng_sel = 0; - break; - case AMDGPU_RING_TYPE_GFX: - eng_sel = 4; - break; - case AMDGPU_RING_TYPE_MES: - eng_sel = 5; - break; - default: - WARN_ON(1); + if (amdgpu_ip_version(kiq_ring->adev, GC_HWIP, 0) < IP_VERSION(10, 3, 0)) { + ext_eng_sel = 0; + switch (ring->funcs->type) { + case AMDGPU_RING_TYPE_COMPUTE: + eng_sel = 0; + break; + case AMDGPU_RING_TYPE_GFX: + eng_sel = 4; + break; + case AMDGPU_RING_TYPE_MES: + eng_sel = 5; + break; + case AMDGPU_RING_TYPE_SDMA: + eng_sel = 2 + ring->me; + break; + default: + eng_sel = 0; + WARN_ON(1); + break; + } + } else { + switch (ring->funcs->type) { + case AMDGPU_RING_TYPE_COMPUTE: + ext_eng_sel = 0; + eng_sel = 0; + break; + case AMDGPU_RING_TYPE_GFX: + ext_eng_sel = 0; + eng_sel = 4; + break; + case AMDGPU_RING_TYPE_MES: + ext_eng_sel = 0; + eng_sel = 5; + break; + case AMDGPU_RING_TYPE_SDMA: + ext_eng_sel = 1; + eng_sel = ring->me; + break; + default: + eng_sel = 0; + ext_eng_sel = 0; + WARN_ON(1); + break; + } } amdgpu_ring_write(kiq_ring, PACKET3(PACKET3_MAP_QUEUES, 5)); /* Q_sel:0, vmid:0, vidmem: 1, engine:0, num_Q:1*/ amdgpu_ring_write(kiq_ring, /* Q_sel: 0, vmid: 0, engine: 0, num_Q: 1 */ + PACKET3_MAP_QUEUES_EXTENDED_ENGINE_SEL(ext_eng_sel) | PACKET3_MAP_QUEUES_QUEUE_SEL(0) | /* Queue_Sel */ PACKET3_MAP_QUEUES_VMID(0) | /* VMID */ PACKET3_MAP_QUEUES_QUEUE(ring->queue) | @@ -3733,11 +3766,35 @@ static void gfx10_kiq_unmap_queues(struct amdgpu_ring *kiq_ring, enum amdgpu_unmap_queues_action action, u64 gpu_addr, u64 seq) { - uint32_t eng_sel = ring->funcs->type == AMDGPU_RING_TYPE_GFX ? 4 : 0; + uint32_t eng_sel, ext_eng_sel; + + if (amdgpu_ip_version(kiq_ring->adev, GC_HWIP, 0) < IP_VERSION(10, 3, 0)) { + ext_eng_sel = 0; + if (ring->funcs->type == AMDGPU_RING_TYPE_GFX) + eng_sel = 4; + else if (ring->funcs->type == AMDGPU_RING_TYPE_COMPUTE) + eng_sel = 0; + else + /* SDMA */ + eng_sel = 2 + ring->me; + } else { + if (ring->funcs->type == AMDGPU_RING_TYPE_GFX) { + ext_eng_sel = 0; + eng_sel = 4; + } else if (ring->funcs->type == AMDGPU_RING_TYPE_COMPUTE) { + ext_eng_sel = 0; + eng_sel = 0; + } else { + /* SDMA */ + ext_eng_sel = 1; + eng_sel = ring->me; + } + } amdgpu_ring_write(kiq_ring, PACKET3(PACKET3_UNMAP_QUEUES, 4)); amdgpu_ring_write(kiq_ring, /* Q_sel: 0, vmid: 0, engine: 0, num_Q: 1 */ PACKET3_UNMAP_QUEUES_ACTION(action) | + PACKET3_UNMAP_QUEUES_EXTENDED_ENGINE_SEL(ext_eng_sel) | PACKET3_UNMAP_QUEUES_QUEUE_SEL(0) | PACKET3_UNMAP_QUEUES_ENGINE_SEL(eng_sel) | PACKET3_UNMAP_QUEUES_N
Re: [PATCH] drm/amd/display: Remove redundant code and semicolons
On 2024-06-20 13:21, Alex Deucher wrote: On Thu, Jun 20, 2024 at 1:18 PM David Wu wrote: see inline, please David On 2024-06-20 12:50, Alex Deucher wrote: On Thu, Jun 20, 2024 at 12:07 PM David Wu wrote: I think the "break;" there is to silence the compilation warning - it is ugly but needed. Which break? It looks fine to me. example here - code is fine but the compiler will complain about missing "break" for case statement. - return 256; break; + return 256; It shouldn't. Actually a number of checkers will complain about having a break after a return. maybe in my experience I am using a quite outdated compiler with -Wall. (I have to add "break" after "return" which drives me nuts!) Alex Alex David On 2024-06-20 11:38, Alex Deucher wrote: Applied. Thanks! Alex On Thu, Jun 20, 2024 at 5:07 AM Jiapeng Chong wrote: No functional modification involved. ./drivers/gpu/drm/amd/display/dc/dml2/dml21/src/dml2_core/dml2_core_shared.c:3171:2-3: Unneeded semicolon. ./drivers/gpu/drm/amd/display/dc/dml2/dml21/src/dml2_core/dml2_core_shared.c:3185:2-3: Unneeded semicolon. ./drivers/gpu/drm/amd/display/dc/dml2/dml21/src/dml2_core/dml2_core_shared.c:3200:2-3: Unneeded semicolon. Reported-by: Abaci Robot Closes: https://bugzilla.openanolis.cn/show_bug.cgi?id=9365 Signed-off-by: Jiapeng Chong --- .../dml21/src/dml2_core/dml2_core_shared.c| 46 +-- 1 file changed, 23 insertions(+), 23 deletions(-) diff --git a/drivers/gpu/drm/amd/display/dc/dml2/dml21/src/dml2_core/dml2_core_shared.c b/drivers/gpu/drm/amd/display/dc/dml2/dml21/src/dml2_core/dml2_core_shared.c index cfa4c4475821..1a9895b1833f 100644 --- a/drivers/gpu/drm/amd/display/dc/dml2/dml21/src/dml2_core/dml2_core_shared.c +++ b/drivers/gpu/drm/amd/display/dc/dml2/dml21/src/dml2_core/dml2_core_shared.c @@ -3142,62 +3142,62 @@ static unsigned int dml_get_tile_block_size_bytes(enum dml2_swizzle_mode sw_mode { switch (sw_mode) { case (dml2_sw_linear): - return 256; break; + return 256; case (dml2_sw_256b_2d): - return 256; break; + return 256; case (dml2_sw_4kb_2d): - return 4096; break; + return 4096; case (dml2_sw_64kb_2d): - return 65536; break; + return 65536; case (dml2_sw_256kb_2d): - return 262144; break; + return 262144; case (dml2_gfx11_sw_linear): - return 256; break; + return 256; case (dml2_gfx11_sw_64kb_d): - return 65536; break; + return 65536; case (dml2_gfx11_sw_64kb_d_t): - return 65536; break; + return 65536; case (dml2_gfx11_sw_64kb_d_x): - return 65536; break; + return 65536; case (dml2_gfx11_sw_64kb_r_x): - return 65536; break; + return 65536; case (dml2_gfx11_sw_256kb_d_x): - return 262144; break; + return 262144; case (dml2_gfx11_sw_256kb_r_x): - return 262144; break; + return 262144; default: DML2_ASSERT(0); return 256; - }; + } } const char *dml2_core_internal_bw_type_str(enum dml2_core_internal_bw_type bw_type) { switch (bw_type) { case (dml2_core_internal_bw_sdp): - return("dml2_core_internal_bw_sdp"); break; + return("dml2_core_internal_bw_sdp"); case (dml2_core_internal_bw_dram): - return("dml2_core_internal_bw_dram"); break; + return("dml2_core_internal_bw_dram"); case (dml2_core_internal_bw_max): - return("dml2_core_internal_bw_max"); break; + return("dml2_core_internal_bw_max"); default: - return("dml2_core_internal_bw_unknown"); break; - }; + return("dml2_core_internal_bw_unknown"); + } } const char *dml2_core_internal_soc_state_type_str(enum dml2_core_internal_soc_state_type dml2_core_internal_soc_state_type) { switch (dml2_core_internal_soc_state_type) { case (dml2_core_internal_soc_state_sys_idle): - return("dml2_core_internal_soc_state_sys_idle"); break; + return("dml2_core_internal_soc_state_sys_idle"); case (dml2_core_internal_soc_state_sys_active): - return("dml2_core_internal_soc_state_sys_active"); break; + return("dml2_core_internal_soc_state_sys_active"); case (dml2_core_internal_soc_state_svp_prefetch): - return("dml2_core_internal_soc_state_svp_prefetch"); break; + return("dml2_core_internal_soc_state_svp_prefetch"); case dml2_core_internal_soc_state_max:
RE: [PATCH] drm/amdgpu: add missing error handling in function amdgpu_gmc_flush_gpu_tlb_pasid
[AMD Official Use Only - AMD Internal Distribution Only] Hi Alex, Thanks for your review, I will push other patch to fix those issues. Regards, Bob -Original Message- From: Alex Deucher Sent: 2024年6月20日 22:59 To: Zhou, Bob Cc: amd-gfx@lists.freedesktop.org; Huang, Tim ; Zhang, Jesse(Jie) ; Deucher, Alexander ; Koenig, Christian Subject: Re: [PATCH] drm/amdgpu: add missing error handling in function amdgpu_gmc_flush_gpu_tlb_pasid On Thu, Jun 20, 2024 at 3:47 AM Bob Zhou wrote: > > Fix the unchecked return value warning by warning reported by > Coverity, so add error handling. > > Signed-off-by: Bob Zhou Looks like there are a few other places in the driver where amdgpu_ring_alloc() is not checked. Can you fix those up too? Reviewed-by: Alex Deucher > --- > drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.c | 6 +- > 1 file changed, 5 insertions(+), 1 deletion(-) > > diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.c > b/drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.c > index 322b8ff67cde..3a7622611916 100644 > --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.c > +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.c > @@ -718,7 +718,11 @@ int amdgpu_gmc_flush_gpu_tlb_pasid(struct amdgpu_device > *adev, uint16_t pasid, > ndw += kiq->pmf->invalidate_tlbs_size; > > spin_lock(&adev->gfx.kiq[inst].ring_lock); > - amdgpu_ring_alloc(ring, ndw); > + r = amdgpu_ring_alloc(ring, ndw); > + if (r) { > + spin_unlock(&adev->gfx.kiq[inst].ring_lock); > + goto error_unlock_reset; > + } > if (adev->gmc.flush_tlb_needs_extra_type_2) > kiq->pmf->kiq_invalidate_tlbs(ring, pasid, 2, > all_hub); > > -- > 2.34.1 >
[PATCH] drm/amdgpu: Fix register access violation
fault_status is read only register. fault_cntl is not accessible from guest environment. Signed-off-by: Hawking Zhang --- drivers/gpu/drm/amd/amdgpu/gfxhub_v1_2.c | 8 +--- drivers/gpu/drm/amd/amdgpu/gmc_v9_0.c| 3 ++- drivers/gpu/drm/amd/amdgpu/mmhub_v1_8.c | 8 +--- 3 files changed, 12 insertions(+), 7 deletions(-) diff --git a/drivers/gpu/drm/amd/amdgpu/gfxhub_v1_2.c b/drivers/gpu/drm/amd/amdgpu/gfxhub_v1_2.c index e14acab5cceb..72109abe7c86 100644 --- a/drivers/gpu/drm/amd/amdgpu/gfxhub_v1_2.c +++ b/drivers/gpu/drm/amd/amdgpu/gfxhub_v1_2.c @@ -629,9 +629,11 @@ static bool gfxhub_v1_2_query_utcl2_poison_status(struct amdgpu_device *adev, status = RREG32_SOC15(GC, GET_INST(GC, xcc_id), regVM_L2_PROTECTION_FAULT_STATUS); fed = REG_GET_FIELD(status, VM_L2_PROTECTION_FAULT_STATUS, FED); - /* reset page fault status */ - WREG32_P(SOC15_REG_OFFSET(GC, GET_INST(GC, xcc_id), - regVM_L2_PROTECTION_FAULT_STATUS), 1, ~1); + if (!amdgpu_sriov_vf(adev)) { + /* clear page fault status and address */ + WREG32_P(SOC15_REG_OFFSET(GC, GET_INST(GC, xcc_id), +regVM_L2_PROTECTION_FAULT_CNTL), 1, ~1); + } return fed; } diff --git a/drivers/gpu/drm/amd/amdgpu/gmc_v9_0.c b/drivers/gpu/drm/amd/amdgpu/gmc_v9_0.c index 88b4644f8e96..b73136d390cc 100644 --- a/drivers/gpu/drm/amd/amdgpu/gmc_v9_0.c +++ b/drivers/gpu/drm/amd/amdgpu/gmc_v9_0.c @@ -672,7 +672,8 @@ static int gmc_v9_0_process_interrupt(struct amdgpu_device *adev, (amdgpu_ip_version(adev, GC_HWIP, 0) >= IP_VERSION(9, 4, 2))) return 0; - WREG32_P(hub->vm_l2_pro_fault_cntl, 1, ~1); + if (!amdgpu_sriov_vf(adev)) + WREG32_P(hub->vm_l2_pro_fault_cntl, 1, ~1); amdgpu_vm_update_fault_cache(adev, entry->pasid, addr, status, vmhub); diff --git a/drivers/gpu/drm/amd/amdgpu/mmhub_v1_8.c b/drivers/gpu/drm/amd/amdgpu/mmhub_v1_8.c index 7a1ff298417a..8d7267a013d2 100644 --- a/drivers/gpu/drm/amd/amdgpu/mmhub_v1_8.c +++ b/drivers/gpu/drm/amd/amdgpu/mmhub_v1_8.c @@ -566,9 +566,11 @@ static bool mmhub_v1_8_query_utcl2_poison_status(struct amdgpu_device *adev, status = RREG32_SOC15(MMHUB, hub_inst, regVM_L2_PROTECTION_FAULT_STATUS); fed = REG_GET_FIELD(status, VM_L2_PROTECTION_FAULT_STATUS, FED); - /* reset page fault status */ - WREG32_P(SOC15_REG_OFFSET(MMHUB, hub_inst, - regVM_L2_PROTECTION_FAULT_STATUS), 1, ~1); + if (!amdgpu_sriov_vf(adev)) { + /* clear page fault status and address */ + WREG32_P(SOC15_REG_OFFSET(MMHUB, hub_inst, +regVM_L2_PROTECTION_FAULT_STATUS), 1, ~1); + } return fed; } -- 2.17.1
RE: [PATCH] drm/amdgpu: Fix register access violation
[AMD Official Use Only - AMD Internal Distribution Only] Reviewed-by: Tao Zhou > -Original Message- > From: amd-gfx On Behalf Of Hawking > Zhang > Sent: Friday, June 21, 2024 11:30 AM > To: amd-gfx@lists.freedesktop.org; Zhou1, Tao > Cc: Zhang, Hawking > Subject: [PATCH] drm/amdgpu: Fix register access violation > > fault_status is read only register. fault_cntl is not accessible from guest > environment. > > Signed-off-by: Hawking Zhang > --- > drivers/gpu/drm/amd/amdgpu/gfxhub_v1_2.c | 8 +--- > drivers/gpu/drm/amd/amdgpu/gmc_v9_0.c| 3 ++- > drivers/gpu/drm/amd/amdgpu/mmhub_v1_8.c | 8 +--- > 3 files changed, 12 insertions(+), 7 deletions(-) > > diff --git a/drivers/gpu/drm/amd/amdgpu/gfxhub_v1_2.c > b/drivers/gpu/drm/amd/amdgpu/gfxhub_v1_2.c > index e14acab5cceb..72109abe7c86 100644 > --- a/drivers/gpu/drm/amd/amdgpu/gfxhub_v1_2.c > +++ b/drivers/gpu/drm/amd/amdgpu/gfxhub_v1_2.c > @@ -629,9 +629,11 @@ static bool > gfxhub_v1_2_query_utcl2_poison_status(struct amdgpu_device *adev, > > status = RREG32_SOC15(GC, GET_INST(GC, xcc_id), > regVM_L2_PROTECTION_FAULT_STATUS); > fed = REG_GET_FIELD(status, VM_L2_PROTECTION_FAULT_STATUS, > FED); > - /* reset page fault status */ > - WREG32_P(SOC15_REG_OFFSET(GC, GET_INST(GC, xcc_id), > - regVM_L2_PROTECTION_FAULT_STATUS), 1, ~1); > + if (!amdgpu_sriov_vf(adev)) { > + /* clear page fault status and address */ > + WREG32_P(SOC15_REG_OFFSET(GC, GET_INST(GC, xcc_id), > + regVM_L2_PROTECTION_FAULT_CNTL), 1, ~1); > + } > > return fed; > } > diff --git a/drivers/gpu/drm/amd/amdgpu/gmc_v9_0.c > b/drivers/gpu/drm/amd/amdgpu/gmc_v9_0.c > index 88b4644f8e96..b73136d390cc 100644 > --- a/drivers/gpu/drm/amd/amdgpu/gmc_v9_0.c > +++ b/drivers/gpu/drm/amd/amdgpu/gmc_v9_0.c > @@ -672,7 +672,8 @@ static int gmc_v9_0_process_interrupt(struct > amdgpu_device *adev, > (amdgpu_ip_version(adev, GC_HWIP, 0) >= IP_VERSION(9, 4, 2))) > return 0; > > - WREG32_P(hub->vm_l2_pro_fault_cntl, 1, ~1); > + if (!amdgpu_sriov_vf(adev)) > + WREG32_P(hub->vm_l2_pro_fault_cntl, 1, ~1); > > amdgpu_vm_update_fault_cache(adev, entry->pasid, addr, status, > vmhub); > > diff --git a/drivers/gpu/drm/amd/amdgpu/mmhub_v1_8.c > b/drivers/gpu/drm/amd/amdgpu/mmhub_v1_8.c > index 7a1ff298417a..8d7267a013d2 100644 > --- a/drivers/gpu/drm/amd/amdgpu/mmhub_v1_8.c > +++ b/drivers/gpu/drm/amd/amdgpu/mmhub_v1_8.c > @@ -566,9 +566,11 @@ static bool > mmhub_v1_8_query_utcl2_poison_status(struct amdgpu_device *adev, > > status = RREG32_SOC15(MMHUB, hub_inst, > regVM_L2_PROTECTION_FAULT_STATUS); > fed = REG_GET_FIELD(status, VM_L2_PROTECTION_FAULT_STATUS, > FED); > - /* reset page fault status */ > - WREG32_P(SOC15_REG_OFFSET(MMHUB, hub_inst, > - regVM_L2_PROTECTION_FAULT_STATUS), 1, ~1); > + if (!amdgpu_sriov_vf(adev)) { > + /* clear page fault status and address */ > + WREG32_P(SOC15_REG_OFFSET(MMHUB, hub_inst, > + regVM_L2_PROTECTION_FAULT_STATUS), 1, ~1); > + } > > return fed; > } > -- > 2.17.1
[PATCH] drm/amdgpu: normalize registers as local xcc to read/write under sriov in TLB flush
[WHY] sriov has the higher bit violation when flushing tlb [HOW] normalize the registers to keep lower 16-bit(dword aligned) to aviod higher bit violation RLCG will mask xcd out and always assume it's accessing its own xcd [TODO] later will add the normalization in sriovw/rreg after fixing bugs v2 rename the normalized macro, add ip block type for further use move asics func declaration after ip block type since new func refers ip block type Signed-off-by: Jane Jian --- drivers/gpu/drm/amd/amdgpu/amdgpu.h| 112 +++-- drivers/gpu/drm/amd/amdgpu/aqua_vanjaram.c | 16 +++ drivers/gpu/drm/amd/amdgpu/gmc_v9_0.c | 8 +- drivers/gpu/drm/amd/amdgpu/soc15.c | 1 + drivers/gpu/drm/amd/amdgpu/soc15.h | 1 + drivers/gpu/drm/amd/amdgpu/soc15_common.h | 5 +- 6 files changed, 85 insertions(+), 58 deletions(-) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu.h b/drivers/gpu/drm/amd/amdgpu/amdgpu.h index 083f353cff6e..070fd9e601fe 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu.h @@ -583,61 +583,6 @@ struct amdgpu_video_codecs { const struct amdgpu_video_codec_info *codec_array; }; -/* - * ASIC specific functions. - */ -struct amdgpu_asic_funcs { - bool (*read_disabled_bios)(struct amdgpu_device *adev); - bool (*read_bios_from_rom)(struct amdgpu_device *adev, - u8 *bios, u32 length_bytes); - int (*read_register)(struct amdgpu_device *adev, u32 se_num, -u32 sh_num, u32 reg_offset, u32 *value); - void (*set_vga_state)(struct amdgpu_device *adev, bool state); - int (*reset)(struct amdgpu_device *adev); - enum amd_reset_method (*reset_method)(struct amdgpu_device *adev); - /* get the reference clock */ - u32 (*get_xclk)(struct amdgpu_device *adev); - /* MM block clocks */ - int (*set_uvd_clocks)(struct amdgpu_device *adev, u32 vclk, u32 dclk); - int (*set_vce_clocks)(struct amdgpu_device *adev, u32 evclk, u32 ecclk); - /* static power management */ - int (*get_pcie_lanes)(struct amdgpu_device *adev); - void (*set_pcie_lanes)(struct amdgpu_device *adev, int lanes); - /* get config memsize register */ - u32 (*get_config_memsize)(struct amdgpu_device *adev); - /* flush hdp write queue */ - void (*flush_hdp)(struct amdgpu_device *adev, struct amdgpu_ring *ring); - /* invalidate hdp read cache */ - void (*invalidate_hdp)(struct amdgpu_device *adev, - struct amdgpu_ring *ring); - /* check if the asic needs a full reset of if soft reset will work */ - bool (*need_full_reset)(struct amdgpu_device *adev); - /* initialize doorbell layout for specific asic*/ - void (*init_doorbell_index)(struct amdgpu_device *adev); - /* PCIe bandwidth usage */ - void (*get_pcie_usage)(struct amdgpu_device *adev, uint64_t *count0, - uint64_t *count1); - /* do we need to reset the asic at init time (e.g., kexec) */ - bool (*need_reset_on_init)(struct amdgpu_device *adev); - /* PCIe replay counter */ - uint64_t (*get_pcie_replay_count)(struct amdgpu_device *adev); - /* device supports BACO */ - int (*supports_baco)(struct amdgpu_device *adev); - /* pre asic_init quirks */ - void (*pre_asic_init)(struct amdgpu_device *adev); - /* enter/exit umd stable pstate */ - int (*update_umd_stable_pstate)(struct amdgpu_device *adev, bool enter); - /* query video codecs */ - int (*query_video_codecs)(struct amdgpu_device *adev, bool encode, - const struct amdgpu_video_codecs **codecs); - /* encode "> 32bits" smn addressing */ - u64 (*encode_ext_smn_addressing)(int ext_id); - - ssize_t (*get_reg_state)(struct amdgpu_device *adev, -enum amdgpu_reg_state reg_state, void *buf, -size_t max_size); -}; - /* * IOCTL. */ @@ -728,6 +673,63 @@ enum amd_hw_ip_block_type { MAX_HWIP }; +/* + * ASIC specific functions. + */ +struct amdgpu_asic_funcs { + bool (*read_disabled_bios)(struct amdgpu_device *adev); + bool (*read_bios_from_rom)(struct amdgpu_device *adev, + u8 *bios, u32 length_bytes); + int (*read_register)(struct amdgpu_device *adev, u32 se_num, +u32 sh_num, u32 reg_offset, u32 *value); + void (*set_vga_state)(struct amdgpu_device *adev, bool state); + int (*reset)(struct amdgpu_device *adev); + enum amd_reset_method (*reset_method)(struct amdgpu_device *adev); + /* get the reference clock */ + u32 (*get_xclk)(struct amdgpu_device *adev); + /* MM block clocks */ + int (*set_uvd_clocks)(struct amdgpu_device *adev, u32 vclk, u32 dclk); + int (*set_vce_clocks)(struct amd
[PATCH] drm/buddy: Add start address support to trim function
- Add a new start parameter in trim function to specify exact address from where to start the trimming. This would help us in situations like if drivers would like to do address alignment for specific requirements. - Add a new flag DRM_BUDDY_TRIM_DISABLE. Drivers can use this flag to disable the allocator trimming part. This patch enables the drivers control trimming and they can do it themselves based on the application requirements. Signed-off-by: Arunpravin Paneer Selvam --- drivers/gpu/drm/drm_buddy.c | 22 -- drivers/gpu/drm/xe/xe_ttm_vram_mgr.c | 2 +- include/drm/drm_buddy.h | 2 ++ 3 files changed, 23 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/drm_buddy.c b/drivers/gpu/drm/drm_buddy.c index 6a8e45e9d0ec..287b6acb1637 100644 --- a/drivers/gpu/drm/drm_buddy.c +++ b/drivers/gpu/drm/drm_buddy.c @@ -851,6 +851,7 @@ static int __alloc_contig_try_harder(struct drm_buddy *mm, * drm_buddy_block_trim - free unused pages * * @mm: DRM buddy manager + * @start: start address to begin the trimming. * @new_size: original size requested * @blocks: Input and output list of allocated blocks. * MUST contain single block as input to be trimmed. @@ -866,11 +867,13 @@ static int __alloc_contig_try_harder(struct drm_buddy *mm, * 0 on success, error code on failure. */ int drm_buddy_block_trim(struct drm_buddy *mm, +u64 *start, u64 new_size, struct list_head *blocks) { struct drm_buddy_block *parent; struct drm_buddy_block *block; + u64 block_start, block_end; LIST_HEAD(dfs); u64 new_start; int err; @@ -882,6 +885,9 @@ int drm_buddy_block_trim(struct drm_buddy *mm, struct drm_buddy_block, link); + block_start = drm_buddy_block_offset(block); + block_end = block_start + drm_buddy_block_size(mm, block) - 1; + if (WARN_ON(!drm_buddy_block_is_allocated(block))) return -EINVAL; @@ -894,6 +900,17 @@ int drm_buddy_block_trim(struct drm_buddy *mm, if (new_size == drm_buddy_block_size(mm, block)) return 0; + new_start = block_start; + if (start) { + new_start = *start; + + if (new_start < block_start) + return -EINVAL; + + if ((new_start + new_size) > block_end) + return -EINVAL; + } + list_del(&block->link); mark_free(mm, block); mm->avail += drm_buddy_block_size(mm, block); @@ -904,7 +921,6 @@ int drm_buddy_block_trim(struct drm_buddy *mm, parent = block->parent; block->parent = NULL; - new_start = drm_buddy_block_offset(block); list_add(&block->tmp_link, &dfs); err = __alloc_range(mm, &dfs, new_start, new_size, blocks, NULL); if (err) { @@ -1066,7 +1082,8 @@ int drm_buddy_alloc_blocks(struct drm_buddy *mm, } while (1); /* Trim the allocated block to the required size */ - if (original_size != size) { + if (!(flags & DRM_BUDDY_TRIM_DISABLE) && + original_size != size) { struct list_head *trim_list; LIST_HEAD(temp); u64 trim_size; @@ -1083,6 +1100,7 @@ int drm_buddy_alloc_blocks(struct drm_buddy *mm, } drm_buddy_block_trim(mm, +NULL, trim_size, trim_list); diff --git a/drivers/gpu/drm/xe/xe_ttm_vram_mgr.c b/drivers/gpu/drm/xe/xe_ttm_vram_mgr.c index fe3779fdba2c..423b261ea743 100644 --- a/drivers/gpu/drm/xe/xe_ttm_vram_mgr.c +++ b/drivers/gpu/drm/xe/xe_ttm_vram_mgr.c @@ -150,7 +150,7 @@ static int xe_ttm_vram_mgr_new(struct ttm_resource_manager *man, } while (remaining_size); if (place->flags & TTM_PL_FLAG_CONTIGUOUS) { - if (!drm_buddy_block_trim(mm, vres->base.size, &vres->blocks)) + if (!drm_buddy_block_trim(mm, NULL, vres->base.size, &vres->blocks)) size = vres->base.size; } diff --git a/include/drm/drm_buddy.h b/include/drm/drm_buddy.h index 2a74fa9d0ce5..9689a7c5dd36 100644 --- a/include/drm/drm_buddy.h +++ b/include/drm/drm_buddy.h @@ -27,6 +27,7 @@ #define DRM_BUDDY_CONTIGUOUS_ALLOCATIONBIT(2) #define DRM_BUDDY_CLEAR_ALLOCATION BIT(3) #define DRM_BUDDY_CLEARED BIT(4) +#define DRM_BUDDY_TRIM_DISABLE BIT(5) struct drm_buddy_block { #define DRM_BUDDY_HEADER_OFFSET GENMASK_ULL(63, 12) @@ -155,6 +156,7 @@ int drm_buddy_alloc_blocks(struct drm_buddy *mm, unsigned long flags); int drm_buddy_block_trim(struct drm_buddy *mm, +u64 *start, u64 new_size,
RE: [PATCH] drm/amdgpu: access ltr through pci cfg space
[AMD Official Use Only - AMD Internal Distribution Only] Reviewed-by: Hawking Zhang Regards, Hawking -Original Message- From: Min, Frank Sent: Thursday, June 20, 2024 14:52 To: amd-gfx@lists.freedesktop.org Cc: Deucher, Alexander ; Zhang, Hawking ; Koenig, Christian ; Gao, Likun Subject: [PATCH] drm/amdgpu: access ltr through pci cfg space [AMD Official Use Only - AMD Internal Distribution Only] From: Frank Min Access ltr through pci cfg space instead of mmio while programing aspm on gfx12 Signed-off-by: Frank Min --- drivers/gpu/drm/amd/amdgpu/nbif_v6_3_1.c | 14 ++ 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/drivers/gpu/drm/amd/amdgpu/nbif_v6_3_1.c b/drivers/gpu/drm/amd/amdgpu/nbif_v6_3_1.c index 5a20bb229788..39919e0892c1 100644 --- a/drivers/gpu/drm/amd/amdgpu/nbif_v6_3_1.c +++ b/drivers/gpu/drm/amd/amdgpu/nbif_v6_3_1.c @@ -345,6 +345,7 @@ static void nbif_v6_3_1_program_aspm(struct amdgpu_device *adev) { #ifdef CONFIG_PCIEASPM uint32_t def, data; + u16 devctl2, ltr; def = data = RREG32_SOC15(PCIE, 0, regPCIE_LC_CNTL); data &= ~PCIE_LC_CNTL__LC_L1_INACTIVITY_MASK; @@ -374,12 +375,17 @@ static void nbif_v6_3_1_program_aspm(struct amdgpu_device *adev) if (def != data) WREG32_SOC15(NBIO, 0, regRCC_STRAP0_RCC_BIF_STRAP5, data); - def = data = RREG32_SOC15(NBIO, 0, regBIF_CFG_DEV0_EPF0_DEVICE_CNTL2); - data &= ~BIF_CFG_DEV0_EPF0_DEVICE_CNTL2__LTR_EN_MASK; + pcie_capability_read_word(adev->pdev, PCI_EXP_DEVCTL2, &devctl2); + data = def = devctl2; + data &= ~PCI_EXP_DEVCTL2_LTR_EN; if (def != data) - WREG32_SOC15(NBIO, 0, regBIF_CFG_DEV0_EPF0_DEVICE_CNTL2, data); + pcie_capability_set_word(adev->pdev, PCI_EXP_DEVCTL2, (u16)data); + + ltr = pci_find_ext_capability(adev->pdev, PCI_EXT_CAP_ID_LTR); - WREG32_SOC15(NBIO, 0, regBIF_CFG_DEV0_EPF0_PCIE_LTR_CAP, 0x10011001); + if (ltr) { + pci_write_config_dword(adev->pdev, ltr + PCI_LTR_MAX_SNOOP_LAT, 0x10011001); + } #if 0 /* regPSWUSP0_PCIE_LC_CNTL2 should be replace by PCIE_LC_CNTL2 or someone else ? */ -- 2.34.1
RE: [PATCH] drm/amdgpu: update MTYPE mapping for gfx12
[AMD Official Use Only - AMD Internal Distribution Only] Reviewed-by: Hawking Zhang Regards, Hawking -Original Message- From: Min, Frank Sent: Tuesday, June 18, 2024 21:07 To: amd-gfx@lists.freedesktop.org Cc: Zhang, Hawking ; Gao, Likun ; Deucher, Alexander ; Koenig, Christian Subject: [PATCH] drm/amdgpu: update MTYPE mapping for gfx12 [AMD Official Use Only - AMD Internal Distribution Only] From: Frank Min gfx12 only support MTYPE UC and NC, so update it accordingly. Signed-off-by: Frank Min --- drivers/gpu/drm/amd/amdgpu/gmc_v12_0.c | 4 1 file changed, 4 deletions(-) diff --git a/drivers/gpu/drm/amd/amdgpu/gmc_v12_0.c b/drivers/gpu/drm/amd/amdgpu/gmc_v12_0.c index 26122c8cfcc3..61db331adcc2 100644 --- a/drivers/gpu/drm/amd/amdgpu/gmc_v12_0.c +++ b/drivers/gpu/drm/amd/amdgpu/gmc_v12_0.c @@ -464,10 +464,6 @@ static uint64_t gmc_v12_0_map_mtype(struct amdgpu_device *adev, uint32_t flags) return AMDGPU_PTE_MTYPE_GFX12(0ULL, MTYPE_NC); case AMDGPU_VM_MTYPE_NC: return AMDGPU_PTE_MTYPE_GFX12(0ULL, MTYPE_NC); - case AMDGPU_VM_MTYPE_WC: - return AMDGPU_PTE_MTYPE_GFX12(0ULL, MTYPE_WC); - case AMDGPU_VM_MTYPE_CC: - return AMDGPU_PTE_MTYPE_GFX12(0ULL, MTYPE_CC); case AMDGPU_VM_MTYPE_UC: return AMDGPU_PTE_MTYPE_GFX12(0ULL, MTYPE_UC); default: -- 2.34.1
RE: [PATCH V2 1/4] drm/amdgpu: add variable to record the deferred error number read by driver
[AMD Official Use Only - AMD Internal Distribution Only] Shall we make pre_de_queried_count to be local variable? Others look good to me Regards, Hawking -Original Message- From: Chai, Thomas Sent: Thursday, June 20, 2024 13:40 To: amd-gfx@lists.freedesktop.org Cc: Zhang, Hawking ; Zhou1, Tao ; Li, Candice ; Wang, Yang(Kevin) ; Yang, Stanley ; Chai, Thomas Subject: [PATCH V2 1/4] drm/amdgpu: add variable to record the deferred error number read by driver Add variable to record the deferred error number read by driver. Signed-off-by: YiPeng Chai --- drivers/gpu/drm/amd/amdgpu/amdgpu_ras.c | 62 ++--- drivers/gpu/drm/amd/amdgpu/amdgpu_ras.h | 3 +- drivers/gpu/drm/amd/amdgpu/umc_v12_0.c | 4 +- 3 files changed, 48 insertions(+), 21 deletions(-) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ras.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_ras.c index 86cb97d2155b..f674e34037b6 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ras.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ras.c @@ -120,7 +120,7 @@ const char *get_ras_block_str(struct ras_common_if *ras_block) /* typical ECC bad page rate is 1 bad page per 100MB VRAM */ #define RAS_BAD_PAGE_COVER (100 * 1024 * 1024ULL) -#define MAX_UMC_POISON_POLLING_TIME_ASYNC 100 //ms +#define MAX_UMC_POISON_POLLING_TIME_ASYNC 300 //ms #define AMDGPU_RAS_RETIRE_PAGE_INTERVAL 100 //ms @@ -2804,7 +2804,8 @@ static void amdgpu_ras_ecc_log_init(struct ras_ecc_log_info *ecc_log) memset(&ecc_log->ecc_key, 0xad, sizeof(ecc_log->ecc_key)); INIT_RADIX_TREE(&ecc_log->de_page_tree, GFP_KERNEL); - ecc_log->de_updated = false; + ecc_log->de_queried_count = 0; + ecc_log->prev_de_queried_count = 0; } static void amdgpu_ras_ecc_log_fini(struct ras_ecc_log_info *ecc_log) @@ -2823,7 +2824,8 @@ static void amdgpu_ras_ecc_log_fini(struct ras_ecc_log_info *ecc_log) mutex_unlock(&ecc_log->lock); mutex_destroy(&ecc_log->lock); - ecc_log->de_updated = false; + ecc_log->de_queried_count = 0; + ecc_log->prev_de_queried_count = 0; } #endif @@ -2856,40 +2858,64 @@ static void amdgpu_ras_do_page_retirement(struct work_struct *work) mutex_unlock(&con->umc_ecc_log.lock); } -static void amdgpu_ras_poison_creation_handler(struct amdgpu_device *adev, - uint32_t timeout_ms) +static int amdgpu_ras_poison_creation_handler(struct amdgpu_device *adev, + uint32_t poison_creation_count) { int ret = 0; struct ras_ecc_log_info *ecc_log; struct ras_query_if info; - uint32_t timeout = timeout_ms; + uint32_t timeout = 0; struct amdgpu_ras *ras = amdgpu_ras_get_context(adev); + uint64_t de_queried_count; + uint32_t new_detect_count, total_detect_count; + uint32_t need_query_count = poison_creation_count; + bool query_data_timeout = false; memset(&info, 0, sizeof(info)); info.head.block = AMDGPU_RAS_BLOCK__UMC; ecc_log = &ras->umc_ecc_log; - ecc_log->de_updated = false; + total_detect_count = 0; do { ret = amdgpu_ras_query_error_status(adev, &info); - if (ret) { - dev_err(adev->dev, "Failed to query ras error! ret:%d\n", ret); - return; + if (ret) + return ret; + + de_queried_count = ecc_log->de_queried_count; + if (de_queried_count > ecc_log->prev_de_queried_count) { + new_detect_count = de_queried_count - ecc_log->prev_de_queried_count; + ecc_log->prev_de_queried_count = de_queried_count; + timeout = 0; + } else { + new_detect_count = 0; } - if (timeout && !ecc_log->de_updated) { - msleep(1); - timeout--; + if (new_detect_count) { + total_detect_count += new_detect_count; + } else { + if (!timeout && need_query_count) + timeout = MAX_UMC_POISON_POLLING_TIME_ASYNC; + + if (timeout) { + if (!--timeout) { + query_data_timeout = true; + break; + } + msleep(1); + } } - } while (timeout && !ecc_log->de_updated); + } while (total_detect_count < need_query_count); - if (timeout_ms && !timeout) { - dev_warn(adev->dev, "Can't find deferred error\n"); - return; + if (query_data_timeout) { + dev_warn(adev->dev, "Can't find deferred error! count: %u\n", + (need_query_count - total_detect_coun
RE: [PATCH V2 4/4] drm/amdgpu: add gpu reset check and exception handling
[AMD Official Use Only - AMD Internal Distribution Only] Reviewed-by: Hawking Zhang Regards, Hawking -Original Message- From: Chai, Thomas Sent: Thursday, June 20, 2024 13:40 To: amd-gfx@lists.freedesktop.org Cc: Zhang, Hawking ; Zhou1, Tao ; Li, Candice ; Wang, Yang(Kevin) ; Yang, Stanley ; Chai, Thomas Subject: [PATCH V2 4/4] drm/amdgpu: add gpu reset check and exception handling Add gpu reset check and exception handling for page retirement. v2: Clear poison consumption messages cached in fifo after non mode-1 reset. Signed-off-by: YiPeng Chai --- drivers/gpu/drm/amd/amdgpu/amdgpu_ras.c | 52 + 1 file changed, 52 insertions(+) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ras.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_ras.c index a4030dc12a1c..ce7c7723e626 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ras.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ras.c @@ -1384,10 +1384,15 @@ int amdgpu_ras_query_error_status(struct amdgpu_device *adev, struct ras_query_i memset(&qctx, 0, sizeof(qctx)); qctx.event_id = amdgpu_ras_acquire_event_id(adev, amdgpu_ras_intr_triggered() ? RAS_EVENT_TYPE_ISR : RAS_EVENT_TYPE_INVALID); + + if (!down_read_trylock(&adev->reset_domain->sem)) + return -EIO; + ret = amdgpu_ras_query_error_status_helper(adev, info, &err_data, &qctx, error_query_mode); + up_read(&adev->reset_domain->sem); if (ret) goto out_fini_err_data; @@ -2916,6 +2921,14 @@ static int amdgpu_ras_poison_creation_handler(struct amdgpu_device *adev, return 0; } +static void amdgpu_ras_clear_poison_fifo(struct amdgpu_device *adev) { + struct amdgpu_ras *con = amdgpu_ras_get_context(adev); + struct ras_poison_msg msg; + + while (kfifo_get(&con->poison_fifo, &msg)); } + static int amdgpu_ras_poison_consumption_handler(struct amdgpu_device *adev, uint32_t msg_count, uint32_t *gpu_reset) { @@ -2946,12 +2959,20 @@ static int amdgpu_ras_poison_consumption_handler(struct amdgpu_device *adev, else reset = reset_flags; + /* If gpu reset is ongoing, not need to reset gpu again */ + if (!down_read_trylock(&adev->reset_domain->sem)) + return -EIO; + up_read(&adev->reset_domain->sem); + flush_delayed_work(&con->page_retirement_dwork); con->gpu_reset_flags |= reset; amdgpu_ras_reset_gpu(adev); *gpu_reset = reset; + + /* Wait for gpu recovery to complete */ + flush_work(&con->recovery_work); } return 0; @@ -3000,6 +3021,37 @@ static int amdgpu_ras_page_retirement_thread(void *param) } } + if ((ret == -EIO) || (gpu_reset == AMDGPU_RAS_GPU_RESET_MODE1_RESET)) { + /* gpu mode-1 reset is ongoing or just completed ras mode-1 reset */ + /* Clear poison creation request */ + atomic_set(&con->poison_creation_count, 0); + + /* Clear poison fifo */ + amdgpu_ras_clear_poison_fifo(adev); + + /* Clear all poison requests*/ + atomic_set(&con->page_retirement_req_cnt, 0); + + if (ret == -EIO) { + /* Wait for mode-1 reset to complete */ + down_read(&adev->reset_domain->sem); + up_read(&adev->reset_domain->sem); + } + + /* Wake up work to save bad pages to eeprom */ + schedule_delayed_work(&con->page_retirement_dwork, 0); + } else if (gpu_reset) { + /* gpu just completed mode-2 reset or other reset */ + /* Clear poison consumption messages cached in fifo */ + msg_count = kfifo_len(&con->poison_fifo); + if (msg_count) { + amdgpu_ras_clear_poison_fifo(adev); + atomic_sub(msg_count, &con->page_retirement_req_cnt); + } + + /* Wake up work to save bad pages to eeprom */ + schedule_delayed_work(&con->page_retirement_dwork, 0); + } #else dev_info(adev->dev, "Start processing page retirement. request:%d\n", atomic_read(&con->page_retirement_req_cnt)); -- 2.34.1
RE: [PATCH V2 2/4] drm/amdgpu: refine poison creation interrupt handler
[AMD Official Use Only - AMD Internal Distribution Only] Reviewed-by: Hawking Zhang Regards, Hawking -Original Message- From: Chai, Thomas Sent: Thursday, June 20, 2024 13:40 To: amd-gfx@lists.freedesktop.org Cc: Zhang, Hawking ; Zhou1, Tao ; Li, Candice ; Wang, Yang(Kevin) ; Yang, Stanley ; Chai, Thomas Subject: [PATCH V2 2/4] drm/amdgpu: refine poison creation interrupt handler In order to apply to the case where a large number of ras poison interrupts: 1. Change to use variable to record poison creation requests to avoid fifo full. 2. Prioritize handling poison creation requests instead of following the order of requests received by the driver. Signed-off-by: YiPeng Chai --- drivers/gpu/drm/amd/amdgpu/amdgpu_ras.c | 37 - drivers/gpu/drm/amd/amdgpu/amdgpu_ras.h | 1 + 2 files changed, 18 insertions(+), 20 deletions(-) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ras.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_ras.c index f674e34037b6..308348b4644f 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ras.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ras.c @@ -2106,10 +2106,8 @@ static void amdgpu_ras_interrupt_poison_creation_handler(struct ras_manager *obj if (amdgpu_ip_version(obj->adev, UMC_HWIP, 0) >= IP_VERSION(12, 0, 0)) { struct amdgpu_ras *con = amdgpu_ras_get_context(obj->adev); - amdgpu_ras_put_poison_req(obj->adev, - AMDGPU_RAS_BLOCK__UMC, 0, NULL, NULL, false); - atomic_inc(&con->page_retirement_req_cnt); + atomic_inc(&con->poison_creation_count); wake_up(&con->page_retirement_wq); } @@ -2945,6 +2943,8 @@ static int amdgpu_ras_page_retirement_thread(void *param) { struct amdgpu_device *adev = (struct amdgpu_device *)param; struct amdgpu_ras *con = amdgpu_ras_get_context(adev); + uint32_t poison_creation_count; + int ret; struct ras_poison_msg poison_msg; enum amdgpu_ras_block ras_block; bool poison_creation_is_handled = false; @@ -2958,7 +2958,18 @@ static int amdgpu_ras_page_retirement_thread(void *param) if (kthread_should_stop()) break; - atomic_dec(&con->page_retirement_req_cnt); + + do { + poison_creation_count = atomic_read(&con->poison_creation_count); + ret = amdgpu_ras_poison_creation_handler(adev, poison_creation_count); + if (ret == -EIO) + break; + + if (poison_creation_count) { + atomic_sub(poison_creation_count, &con->poison_creation_count); + atomic_sub(poison_creation_count, &con->page_retirement_req_cnt); + } + } while (atomic_read(&con->poison_creation_count)); #ifdef HAVE_KFIFO_PUT_NON_POINTER if (!amdgpu_ras_get_poison_req(adev, &poison_msg)) @@ -2969,24 +2980,8 @@ static int amdgpu_ras_page_retirement_thread(void *param) dev_dbg(adev->dev, "Start processing ras block %s(%d)\n", ras_block_str(ras_block), ras_block); - if (ras_block == AMDGPU_RAS_BLOCK__UMC) { - amdgpu_ras_poison_creation_handler(adev, - MAX_UMC_POISON_POLLING_TIME_ASYNC); - poison_creation_is_handled = true; - } else { - /* poison_creation_is_handled: -* false: no poison creation interrupt, but it has poison -* consumption interrupt. -* true: It has poison creation interrupt at the beginning, -* but it has no poison creation interrupt later. -*/ - amdgpu_ras_poison_creation_handler(adev, - poison_creation_is_handled ? - 0 : MAX_UMC_POISON_POLLING_TIME_ASYNC); amdgpu_ras_poison_consumption_handler(adev, &poison_msg); - poison_creation_is_handled = false; - } #else dev_info(adev->dev, "Start processing page retirement. request:%d\n", atomic_read(&con->page_retirement_req_cnt)); @@ -3066,6 +3061,7 @@ int amdgpu_ras_recovery_init(struct amdgpu_device *adev) mutex_init(&con->page_retirement_lock); init_waitqueue_head(&con->page_retirement_wq); atomic_set(&con->page_retirement_req_cnt, 0); + atomic_set(&con->poison_creation_count, 0); con->page_retirement_thread = kthread_run(amdgpu_ras_page_retirement_thread, adev, "umc_page_retirement"); if (IS_ERR(con->page_retirement_thread)) { @@ -3117,6 +3113,7 @@ static int amdgpu_ras_recovery_fini(st
RE: [PATCH V2 3/4] drm/amdgpu: refine poison consumption interrupt handler
[AMD Official Use Only - AMD Internal Distribution Only] Reviewed-by: Hawking Zhang Regards, Hawking -Original Message- From: Chai, Thomas Sent: Thursday, June 20, 2024 13:40 To: amd-gfx@lists.freedesktop.org Cc: Zhang, Hawking ; Zhou1, Tao ; Li, Candice ; Wang, Yang(Kevin) ; Yang, Stanley ; Chai, Thomas Subject: [PATCH V2 3/4] drm/amdgpu: refine poison consumption interrupt handler 1. The poison fifo is only used for poison consumption requests. 2. Merge reset requests when poison fifo caches multiple poison consumption messages Signed-off-by: YiPeng Chai --- drivers/gpu/drm/amd/amdgpu/amdgpu_ras.c | 56 - drivers/gpu/drm/amd/amdgpu/amdgpu_umc.c | 12 +++--- 2 files changed, 44 insertions(+), 24 deletions(-) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ras.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_ras.c index 308348b4644f..a4030dc12a1c 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ras.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ras.c @@ -2917,23 +2917,41 @@ static int amdgpu_ras_poison_creation_handler(struct amdgpu_device *adev, } static int amdgpu_ras_poison_consumption_handler(struct amdgpu_device *adev, - struct ras_poison_msg *poison_msg) + uint32_t msg_count, uint32_t *gpu_reset) { struct amdgpu_ras *con = amdgpu_ras_get_context(adev); - uint32_t reset = poison_msg->reset; - uint16_t pasid = poison_msg->pasid; + uint32_t reset_flags = 0, reset = 0; + struct ras_poison_msg msg; + int ret, i; kgd2kfd_set_sram_ecc_flag(adev->kfd.dev); - if (poison_msg->pasid_fn) - poison_msg->pasid_fn(adev, pasid, poison_msg->data); + for (i = 0; i < msg_count; i++) { + ret = amdgpu_ras_get_poison_req(adev, &msg); + if (!ret) + continue; + + if (msg.pasid_fn) + msg.pasid_fn(adev, msg.pasid, msg.data); + + reset_flags |= msg.reset; + } /* for RMA, amdgpu_ras_poison_creation_handler will trigger gpu reset */ - if (reset && !con->is_rma) { + if (reset_flags && !con->is_rma) { + if (reset_flags & AMDGPU_RAS_GPU_RESET_MODE1_RESET) + reset = AMDGPU_RAS_GPU_RESET_MODE1_RESET; + else if (reset_flags & AMDGPU_RAS_GPU_RESET_MODE2_RESET) + reset = AMDGPU_RAS_GPU_RESET_MODE2_RESET; + else + reset = reset_flags; + flush_delayed_work(&con->page_retirement_dwork); con->gpu_reset_flags |= reset; amdgpu_ras_reset_gpu(adev); + + *gpu_reset = reset; } return 0; @@ -2943,11 +2961,9 @@ static int amdgpu_ras_page_retirement_thread(void *param) { struct amdgpu_device *adev = (struct amdgpu_device *)param; struct amdgpu_ras *con = amdgpu_ras_get_context(adev); - uint32_t poison_creation_count; + uint32_t poison_creation_count, msg_count; + uint32_t gpu_reset; int ret; - struct ras_poison_msg poison_msg; - enum amdgpu_ras_block ras_block; - bool poison_creation_is_handled = false; while (!kthread_should_stop()) { @@ -2958,6 +2974,7 @@ static int amdgpu_ras_page_retirement_thread(void *param) if (kthread_should_stop()) break; + gpu_reset = 0; do { poison_creation_count = atomic_read(&con->poison_creation_count); @@ -2972,16 +2989,17 @@ static int amdgpu_ras_page_retirement_thread(void *param) } while (atomic_read(&con->poison_creation_count)); #ifdef HAVE_KFIFO_PUT_NON_POINTER - if (!amdgpu_ras_get_poison_req(adev, &poison_msg)) - continue; - - ras_block = poison_msg.block; - - dev_dbg(adev->dev, "Start processing ras block %s(%d)\n", - ras_block_str(ras_block), ras_block); - + if (ret != -EIO) { + msg_count = kfifo_len(&con->poison_fifo); + if (msg_count) { + ret = amdgpu_ras_poison_consumption_handler(adev, + msg_count, &gpu_reset); + if ((ret != -EIO) && + (gpu_reset != AMDGPU_RAS_GPU_RESET_MODE1_RESET)) + atomic_sub(msg_count, &con->page_retirement_req_cnt); + } + } - amdgpu_ras_poison_consumption_handler(adev, &poison_msg); #else dev_info(adev->dev, "Start processing page retirement. request:%d\n", atomic_read(&con->page_retirement_req_cnt)); diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_umc.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_umc.c index 4a72ff8d8d80..38e77