From: Greg Kroah-Hartman Date: Tue, 27 May 2025 15:14:07 +0000 (+0200) Subject: 6.14-stable patches X-Git-Tag: v6.12.31~18 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=bbb86ad66788672ef3d8f68fd31035c62065f300;p=thirdparty%2Fkernel%2Fstable-queue.git 6.14-stable patches added patches: drm-amdgpu-read-back-register-after-written-for-vcn-v4.0.5.patch drm-amdgpu-vcn4.0.5-split-code-along-instances.patch drm-i915-dp-fix-determining-sst-mst-mode-during-mtp-tu-state-computation.patch --- diff --git a/queue-6.14/drm-amdgpu-read-back-register-after-written-for-vcn-v4.0.5.patch b/queue-6.14/drm-amdgpu-read-back-register-after-written-for-vcn-v4.0.5.patch new file mode 100644 index 0000000000..20296b10be --- /dev/null +++ b/queue-6.14/drm-amdgpu-read-back-register-after-written-for-vcn-v4.0.5.patch @@ -0,0 +1,54 @@ +From ee7360fc27d6045510f8fe459b5649b2af27811a Mon Sep 17 00:00:00 2001 +From: "David (Ming Qiang) Wu" +Date: Mon, 12 May 2025 15:14:43 -0400 +Subject: drm/amdgpu: read back register after written for VCN v4.0.5 + +From: David (Ming Qiang) Wu + +commit ee7360fc27d6045510f8fe459b5649b2af27811a upstream. + +On VCN v4.0.5 there is a race condition where the WPTR is not +updated after starting from idle when doorbell is used. Adding +register read-back after written at function end is to ensure +all register writes are done before they can be used. + +Closes: https://gitlab.freedesktop.org/mesa/mesa/-/issues/12528 +Signed-off-by: David (Ming Qiang) Wu +Reviewed-by: Mario Limonciello +Tested-by: Mario Limonciello +Reviewed-by: Alex Deucher +Reviewed-by: Ruijing Dong +Signed-off-by: Alex Deucher +(cherry picked from commit 07c9db090b86e5211188e1b351303fbc673378cf) +Cc: stable@vger.kernel.org +Tested-by: Eric Naim +Signed-off-by: Eric Naim +Signed-off-by: Greg Kroah-Hartman +--- + drivers/gpu/drm/amd/amdgpu/vcn_v4_0_5.c | 8 ++++++++ + 1 file changed, 8 insertions(+) + +--- a/drivers/gpu/drm/amd/amdgpu/vcn_v4_0_5.c ++++ b/drivers/gpu/drm/amd/amdgpu/vcn_v4_0_5.c +@@ -983,6 +983,10 @@ static int vcn_v4_0_5_start_dpg_mode(str + ring->doorbell_index << VCN_RB1_DB_CTRL__OFFSET__SHIFT | + VCN_RB1_DB_CTRL__EN_MASK); + ++ /* Keeping one read-back to ensure all register writes are done, otherwise ++ * it may introduce race conditions */ ++ RREG32_SOC15(VCN, inst_idx, regVCN_RB1_DB_CTRL); ++ + return 0; + } + +@@ -1164,6 +1168,10 @@ static int vcn_v4_0_5_start(struct amdgp + WREG32_SOC15(VCN, i, regVCN_RB_ENABLE, tmp); + fw_shared->sq.queue_mode &= ~(FW_QUEUE_RING_RESET | FW_QUEUE_DPG_HOLD_OFF); + ++ /* Keeping one read-back to ensure all register writes are done, otherwise ++ * it may introduce race conditions */ ++ RREG32_SOC15(VCN, i, regVCN_RB_ENABLE); ++ + return 0; + } + diff --git a/queue-6.14/drm-amdgpu-vcn4.0.5-split-code-along-instances.patch b/queue-6.14/drm-amdgpu-vcn4.0.5-split-code-along-instances.patch new file mode 100644 index 0000000000..d5a917b5f7 --- /dev/null +++ b/queue-6.14/drm-amdgpu-vcn4.0.5-split-code-along-instances.patch @@ -0,0 +1,545 @@ +From ecc9ab4e924b7eb9e2c4a668162aaa1d9d60d08c Mon Sep 17 00:00:00 2001 +From: Alex Deucher +Date: Wed, 13 Nov 2024 12:21:18 -0500 +Subject: drm/amdgpu/vcn4.0.5: split code along instances + +From: Alex Deucher + +commit ecc9ab4e924b7eb9e2c4a668162aaa1d9d60d08c upstream. + +Split the code on a per instance basis. This will allow +us to use the per instance functions in the future to +handle more things per instance. + +v2: squash in fix for stop() from Boyuan + +Reviewed-by: Boyuan Zhang +Signed-off-by: Alex Deucher +Tested-by: Eric Naim +Signed-off-by: Eric Naim +Signed-off-by: Greg Kroah-Hartman +--- + drivers/gpu/drm/amd/amdgpu/vcn_v4_0_5.c | 462 +++++++++++++++----------------- + 1 file changed, 229 insertions(+), 233 deletions(-) + +--- a/drivers/gpu/drm/amd/amdgpu/vcn_v4_0_5.c ++++ b/drivers/gpu/drm/amd/amdgpu/vcn_v4_0_5.c +@@ -991,184 +991,179 @@ static int vcn_v4_0_5_start_dpg_mode(str + * vcn_v4_0_5_start - VCN start + * + * @adev: amdgpu_device pointer ++ * @i: instance to start + * + * Start VCN block + */ +-static int vcn_v4_0_5_start(struct amdgpu_device *adev) ++static int vcn_v4_0_5_start(struct amdgpu_device *adev, int i) + { + volatile struct amdgpu_vcn4_fw_shared *fw_shared; + struct amdgpu_ring *ring; + uint32_t tmp; +- int i, j, k, r; ++ int j, k, r; + +- for (i = 0; i < adev->vcn.num_vcn_inst; ++i) { +- if (adev->pm.dpm_enabled) +- amdgpu_dpm_enable_vcn(adev, true, i); +- } +- +- for (i = 0; i < adev->vcn.num_vcn_inst; ++i) { +- if (adev->vcn.harvest_config & (1 << i)) +- continue; ++ if (adev->vcn.harvest_config & (1 << i)) ++ return 0; + +- fw_shared = adev->vcn.inst[i].fw_shared.cpu_addr; ++ if (adev->pm.dpm_enabled) ++ amdgpu_dpm_enable_vcn(adev, true, i); + +- if (adev->pg_flags & AMD_PG_SUPPORT_VCN_DPG) { +- r = vcn_v4_0_5_start_dpg_mode(adev, i, adev->vcn.indirect_sram); +- continue; +- } ++ fw_shared = adev->vcn.inst[i].fw_shared.cpu_addr; + +- /* disable VCN power gating */ +- vcn_v4_0_5_disable_static_power_gating(adev, i); ++ if (adev->pg_flags & AMD_PG_SUPPORT_VCN_DPG) ++ return vcn_v4_0_5_start_dpg_mode(adev, i, adev->vcn.indirect_sram); + +- /* set VCN status busy */ +- tmp = RREG32_SOC15(VCN, i, regUVD_STATUS) | UVD_STATUS__UVD_BUSY; +- WREG32_SOC15(VCN, i, regUVD_STATUS, tmp); +- +- /*SW clock gating */ +- vcn_v4_0_5_disable_clock_gating(adev, i); +- +- /* enable VCPU clock */ +- WREG32_P(SOC15_REG_OFFSET(VCN, i, regUVD_VCPU_CNTL), +- UVD_VCPU_CNTL__CLK_EN_MASK, ~UVD_VCPU_CNTL__CLK_EN_MASK); +- +- /* disable master interrupt */ +- WREG32_P(SOC15_REG_OFFSET(VCN, i, regUVD_MASTINT_EN), 0, +- ~UVD_MASTINT_EN__VCPU_EN_MASK); +- +- /* enable LMI MC and UMC channels */ +- WREG32_P(SOC15_REG_OFFSET(VCN, i, regUVD_LMI_CTRL2), 0, +- ~UVD_LMI_CTRL2__STALL_ARB_UMC_MASK); +- +- tmp = RREG32_SOC15(VCN, i, regUVD_SOFT_RESET); +- tmp &= ~UVD_SOFT_RESET__LMI_SOFT_RESET_MASK; +- tmp &= ~UVD_SOFT_RESET__LMI_UMC_SOFT_RESET_MASK; +- WREG32_SOC15(VCN, i, regUVD_SOFT_RESET, tmp); +- +- /* setup regUVD_LMI_CTRL */ +- tmp = RREG32_SOC15(VCN, i, regUVD_LMI_CTRL); +- WREG32_SOC15(VCN, i, regUVD_LMI_CTRL, tmp | +- UVD_LMI_CTRL__WRITE_CLEAN_TIMER_EN_MASK | +- UVD_LMI_CTRL__MASK_MC_URGENT_MASK | +- UVD_LMI_CTRL__DATA_COHERENCY_EN_MASK | +- UVD_LMI_CTRL__VCPU_DATA_COHERENCY_EN_MASK); +- +- /* setup regUVD_MPC_CNTL */ +- tmp = RREG32_SOC15(VCN, i, regUVD_MPC_CNTL); +- tmp &= ~UVD_MPC_CNTL__REPLACEMENT_MODE_MASK; +- tmp |= 0x2 << UVD_MPC_CNTL__REPLACEMENT_MODE__SHIFT; +- WREG32_SOC15(VCN, i, regUVD_MPC_CNTL, tmp); +- +- /* setup UVD_MPC_SET_MUXA0 */ +- WREG32_SOC15(VCN, i, regUVD_MPC_SET_MUXA0, +- ((0x1 << UVD_MPC_SET_MUXA0__VARA_1__SHIFT) | +- (0x2 << UVD_MPC_SET_MUXA0__VARA_2__SHIFT) | +- (0x3 << UVD_MPC_SET_MUXA0__VARA_3__SHIFT) | +- (0x4 << UVD_MPC_SET_MUXA0__VARA_4__SHIFT))); +- +- /* setup UVD_MPC_SET_MUXB0 */ +- WREG32_SOC15(VCN, i, regUVD_MPC_SET_MUXB0, +- ((0x1 << UVD_MPC_SET_MUXB0__VARB_1__SHIFT) | +- (0x2 << UVD_MPC_SET_MUXB0__VARB_2__SHIFT) | +- (0x3 << UVD_MPC_SET_MUXB0__VARB_3__SHIFT) | +- (0x4 << UVD_MPC_SET_MUXB0__VARB_4__SHIFT))); +- +- /* setup UVD_MPC_SET_MUX */ +- WREG32_SOC15(VCN, i, regUVD_MPC_SET_MUX, +- ((0x0 << UVD_MPC_SET_MUX__SET_0__SHIFT) | +- (0x1 << UVD_MPC_SET_MUX__SET_1__SHIFT) | +- (0x2 << UVD_MPC_SET_MUX__SET_2__SHIFT))); +- +- vcn_v4_0_5_mc_resume(adev, i); +- +- /* VCN global tiling registers */ +- WREG32_SOC15(VCN, i, regUVD_GFX10_ADDR_CONFIG, +- adev->gfx.config.gb_addr_config); +- +- /* unblock VCPU register access */ +- WREG32_P(SOC15_REG_OFFSET(VCN, i, regUVD_RB_ARB_CTRL), 0, +- ~UVD_RB_ARB_CTRL__VCPU_DIS_MASK); +- +- /* release VCPU reset to boot */ +- WREG32_P(SOC15_REG_OFFSET(VCN, i, regUVD_VCPU_CNTL), 0, +- ~UVD_VCPU_CNTL__BLK_RST_MASK); +- +- for (j = 0; j < 10; ++j) { +- uint32_t status; +- +- for (k = 0; k < 100; ++k) { +- status = RREG32_SOC15(VCN, i, regUVD_STATUS); +- if (status & 2) +- break; +- mdelay(10); +- if (amdgpu_emu_mode == 1) +- msleep(1); +- } ++ /* disable VCN power gating */ ++ vcn_v4_0_5_disable_static_power_gating(adev, i); ++ ++ /* set VCN status busy */ ++ tmp = RREG32_SOC15(VCN, i, regUVD_STATUS) | UVD_STATUS__UVD_BUSY; ++ WREG32_SOC15(VCN, i, regUVD_STATUS, tmp); ++ ++ /* SW clock gating */ ++ vcn_v4_0_5_disable_clock_gating(adev, i); ++ ++ /* enable VCPU clock */ ++ WREG32_P(SOC15_REG_OFFSET(VCN, i, regUVD_VCPU_CNTL), ++ UVD_VCPU_CNTL__CLK_EN_MASK, ~UVD_VCPU_CNTL__CLK_EN_MASK); ++ ++ /* disable master interrupt */ ++ WREG32_P(SOC15_REG_OFFSET(VCN, i, regUVD_MASTINT_EN), 0, ++ ~UVD_MASTINT_EN__VCPU_EN_MASK); ++ ++ /* enable LMI MC and UMC channels */ ++ WREG32_P(SOC15_REG_OFFSET(VCN, i, regUVD_LMI_CTRL2), 0, ++ ~UVD_LMI_CTRL2__STALL_ARB_UMC_MASK); ++ ++ tmp = RREG32_SOC15(VCN, i, regUVD_SOFT_RESET); ++ tmp &= ~UVD_SOFT_RESET__LMI_SOFT_RESET_MASK; ++ tmp &= ~UVD_SOFT_RESET__LMI_UMC_SOFT_RESET_MASK; ++ WREG32_SOC15(VCN, i, regUVD_SOFT_RESET, tmp); ++ ++ /* setup regUVD_LMI_CTRL */ ++ tmp = RREG32_SOC15(VCN, i, regUVD_LMI_CTRL); ++ WREG32_SOC15(VCN, i, regUVD_LMI_CTRL, tmp | ++ UVD_LMI_CTRL__WRITE_CLEAN_TIMER_EN_MASK | ++ UVD_LMI_CTRL__MASK_MC_URGENT_MASK | ++ UVD_LMI_CTRL__DATA_COHERENCY_EN_MASK | ++ UVD_LMI_CTRL__VCPU_DATA_COHERENCY_EN_MASK); ++ ++ /* setup regUVD_MPC_CNTL */ ++ tmp = RREG32_SOC15(VCN, i, regUVD_MPC_CNTL); ++ tmp &= ~UVD_MPC_CNTL__REPLACEMENT_MODE_MASK; ++ tmp |= 0x2 << UVD_MPC_CNTL__REPLACEMENT_MODE__SHIFT; ++ WREG32_SOC15(VCN, i, regUVD_MPC_CNTL, tmp); ++ ++ /* setup UVD_MPC_SET_MUXA0 */ ++ WREG32_SOC15(VCN, i, regUVD_MPC_SET_MUXA0, ++ ((0x1 << UVD_MPC_SET_MUXA0__VARA_1__SHIFT) | ++ (0x2 << UVD_MPC_SET_MUXA0__VARA_2__SHIFT) | ++ (0x3 << UVD_MPC_SET_MUXA0__VARA_3__SHIFT) | ++ (0x4 << UVD_MPC_SET_MUXA0__VARA_4__SHIFT))); ++ ++ /* setup UVD_MPC_SET_MUXB0 */ ++ WREG32_SOC15(VCN, i, regUVD_MPC_SET_MUXB0, ++ ((0x1 << UVD_MPC_SET_MUXB0__VARB_1__SHIFT) | ++ (0x2 << UVD_MPC_SET_MUXB0__VARB_2__SHIFT) | ++ (0x3 << UVD_MPC_SET_MUXB0__VARB_3__SHIFT) | ++ (0x4 << UVD_MPC_SET_MUXB0__VARB_4__SHIFT))); ++ ++ /* setup UVD_MPC_SET_MUX */ ++ WREG32_SOC15(VCN, i, regUVD_MPC_SET_MUX, ++ ((0x0 << UVD_MPC_SET_MUX__SET_0__SHIFT) | ++ (0x1 << UVD_MPC_SET_MUX__SET_1__SHIFT) | ++ (0x2 << UVD_MPC_SET_MUX__SET_2__SHIFT))); ++ ++ vcn_v4_0_5_mc_resume(adev, i); ++ ++ /* VCN global tiling registers */ ++ WREG32_SOC15(VCN, i, regUVD_GFX10_ADDR_CONFIG, ++ adev->gfx.config.gb_addr_config); ++ ++ /* unblock VCPU register access */ ++ WREG32_P(SOC15_REG_OFFSET(VCN, i, regUVD_RB_ARB_CTRL), 0, ++ ~UVD_RB_ARB_CTRL__VCPU_DIS_MASK); ++ ++ /* release VCPU reset to boot */ ++ WREG32_P(SOC15_REG_OFFSET(VCN, i, regUVD_VCPU_CNTL), 0, ++ ~UVD_VCPU_CNTL__BLK_RST_MASK); ++ ++ for (j = 0; j < 10; ++j) { ++ uint32_t status; ++ ++ for (k = 0; k < 100; ++k) { ++ status = RREG32_SOC15(VCN, i, regUVD_STATUS); ++ if (status & 2) ++ break; ++ mdelay(10); ++ if (amdgpu_emu_mode == 1) ++ msleep(1); ++ } + +- if (amdgpu_emu_mode == 1) { +- r = -1; +- if (status & 2) { +- r = 0; +- break; +- } +- } else { ++ if (amdgpu_emu_mode == 1) { ++ r = -1; ++ if (status & 2) { + r = 0; +- if (status & 2) +- break; +- +- dev_err(adev->dev, +- "VCN[%d] is not responding, trying to reset VCPU!!!\n", i); +- WREG32_P(SOC15_REG_OFFSET(VCN, i, regUVD_VCPU_CNTL), +- UVD_VCPU_CNTL__BLK_RST_MASK, +- ~UVD_VCPU_CNTL__BLK_RST_MASK); +- mdelay(10); +- WREG32_P(SOC15_REG_OFFSET(VCN, i, regUVD_VCPU_CNTL), 0, +- ~UVD_VCPU_CNTL__BLK_RST_MASK); +- +- mdelay(10); +- r = -1; ++ break; + } +- } ++ } else { ++ r = 0; ++ if (status & 2) ++ break; ++ ++ dev_err(adev->dev, ++ "VCN[%d] is not responding, trying to reset VCPU!!!\n", i); ++ WREG32_P(SOC15_REG_OFFSET(VCN, i, regUVD_VCPU_CNTL), ++ UVD_VCPU_CNTL__BLK_RST_MASK, ++ ~UVD_VCPU_CNTL__BLK_RST_MASK); ++ mdelay(10); ++ WREG32_P(SOC15_REG_OFFSET(VCN, i, regUVD_VCPU_CNTL), 0, ++ ~UVD_VCPU_CNTL__BLK_RST_MASK); + +- if (r) { +- dev_err(adev->dev, "VCN[%d] is not responding, giving up!!!\n", i); +- return r; ++ mdelay(10); ++ r = -1; + } ++ } + +- /* enable master interrupt */ +- WREG32_P(SOC15_REG_OFFSET(VCN, i, regUVD_MASTINT_EN), +- UVD_MASTINT_EN__VCPU_EN_MASK, +- ~UVD_MASTINT_EN__VCPU_EN_MASK); +- +- /* clear the busy bit of VCN_STATUS */ +- WREG32_P(SOC15_REG_OFFSET(VCN, i, regUVD_STATUS), 0, +- ~(2 << UVD_STATUS__VCPU_REPORT__SHIFT)); +- +- ring = &adev->vcn.inst[i].ring_enc[0]; +- WREG32_SOC15(VCN, i, regVCN_RB1_DB_CTRL, +- ring->doorbell_index << VCN_RB1_DB_CTRL__OFFSET__SHIFT | +- VCN_RB1_DB_CTRL__EN_MASK); +- +- WREG32_SOC15(VCN, i, regUVD_RB_BASE_LO, ring->gpu_addr); +- WREG32_SOC15(VCN, i, regUVD_RB_BASE_HI, upper_32_bits(ring->gpu_addr)); +- WREG32_SOC15(VCN, i, regUVD_RB_SIZE, ring->ring_size / 4); +- +- tmp = RREG32_SOC15(VCN, i, regVCN_RB_ENABLE); +- tmp &= ~(VCN_RB_ENABLE__RB1_EN_MASK); +- WREG32_SOC15(VCN, i, regVCN_RB_ENABLE, tmp); +- fw_shared->sq.queue_mode |= FW_QUEUE_RING_RESET; +- WREG32_SOC15(VCN, i, regUVD_RB_RPTR, 0); +- WREG32_SOC15(VCN, i, regUVD_RB_WPTR, 0); +- +- tmp = RREG32_SOC15(VCN, i, regUVD_RB_RPTR); +- WREG32_SOC15(VCN, i, regUVD_RB_WPTR, tmp); +- ring->wptr = RREG32_SOC15(VCN, i, regUVD_RB_WPTR); +- +- tmp = RREG32_SOC15(VCN, i, regVCN_RB_ENABLE); +- tmp |= VCN_RB_ENABLE__RB1_EN_MASK; +- WREG32_SOC15(VCN, i, regVCN_RB_ENABLE, tmp); +- fw_shared->sq.queue_mode &= ~(FW_QUEUE_RING_RESET | FW_QUEUE_DPG_HOLD_OFF); ++ if (r) { ++ dev_err(adev->dev, "VCN[%d] is not responding, giving up!!!\n", i); ++ return r; + } + ++ /* enable master interrupt */ ++ WREG32_P(SOC15_REG_OFFSET(VCN, i, regUVD_MASTINT_EN), ++ UVD_MASTINT_EN__VCPU_EN_MASK, ++ ~UVD_MASTINT_EN__VCPU_EN_MASK); ++ ++ /* clear the busy bit of VCN_STATUS */ ++ WREG32_P(SOC15_REG_OFFSET(VCN, i, regUVD_STATUS), 0, ++ ~(2 << UVD_STATUS__VCPU_REPORT__SHIFT)); ++ ++ ring = &adev->vcn.inst[i].ring_enc[0]; ++ WREG32_SOC15(VCN, i, regVCN_RB1_DB_CTRL, ++ ring->doorbell_index << VCN_RB1_DB_CTRL__OFFSET__SHIFT | ++ VCN_RB1_DB_CTRL__EN_MASK); ++ ++ WREG32_SOC15(VCN, i, regUVD_RB_BASE_LO, ring->gpu_addr); ++ WREG32_SOC15(VCN, i, regUVD_RB_BASE_HI, upper_32_bits(ring->gpu_addr)); ++ WREG32_SOC15(VCN, i, regUVD_RB_SIZE, ring->ring_size / 4); ++ ++ tmp = RREG32_SOC15(VCN, i, regVCN_RB_ENABLE); ++ tmp &= ~(VCN_RB_ENABLE__RB1_EN_MASK); ++ WREG32_SOC15(VCN, i, regVCN_RB_ENABLE, tmp); ++ fw_shared->sq.queue_mode |= FW_QUEUE_RING_RESET; ++ WREG32_SOC15(VCN, i, regUVD_RB_RPTR, 0); ++ WREG32_SOC15(VCN, i, regUVD_RB_WPTR, 0); ++ ++ tmp = RREG32_SOC15(VCN, i, regUVD_RB_RPTR); ++ WREG32_SOC15(VCN, i, regUVD_RB_WPTR, tmp); ++ ring->wptr = RREG32_SOC15(VCN, i, regUVD_RB_WPTR); ++ ++ tmp = RREG32_SOC15(VCN, i, regVCN_RB_ENABLE); ++ tmp |= VCN_RB_ENABLE__RB1_EN_MASK; ++ WREG32_SOC15(VCN, i, regVCN_RB_ENABLE, tmp); ++ fw_shared->sq.queue_mode &= ~(FW_QUEUE_RING_RESET | FW_QUEUE_DPG_HOLD_OFF); ++ + return 0; + } + +@@ -1204,88 +1199,87 @@ static void vcn_v4_0_5_stop_dpg_mode(str + * vcn_v4_0_5_stop - VCN stop + * + * @adev: amdgpu_device pointer ++ * @i: instance to stop + * + * Stop VCN block + */ +-static int vcn_v4_0_5_stop(struct amdgpu_device *adev) ++static int vcn_v4_0_5_stop(struct amdgpu_device *adev, int i) + { + volatile struct amdgpu_vcn4_fw_shared *fw_shared; + uint32_t tmp; +- int i, r = 0; ++ int r = 0; + +- for (i = 0; i < adev->vcn.num_vcn_inst; ++i) { +- if (adev->vcn.harvest_config & (1 << i)) +- continue; +- +- fw_shared = adev->vcn.inst[i].fw_shared.cpu_addr; +- fw_shared->sq.queue_mode |= FW_QUEUE_DPG_HOLD_OFF; +- +- if (adev->pg_flags & AMD_PG_SUPPORT_VCN_DPG) { +- vcn_v4_0_5_stop_dpg_mode(adev, i); +- continue; +- } +- +- /* wait for vcn idle */ +- r = SOC15_WAIT_ON_RREG(VCN, i, regUVD_STATUS, UVD_STATUS__IDLE, 0x7); +- if (r) +- return r; +- +- tmp = UVD_LMI_STATUS__VCPU_LMI_WRITE_CLEAN_MASK | +- UVD_LMI_STATUS__READ_CLEAN_MASK | +- UVD_LMI_STATUS__WRITE_CLEAN_MASK | +- UVD_LMI_STATUS__WRITE_CLEAN_RAW_MASK; +- r = SOC15_WAIT_ON_RREG(VCN, i, regUVD_LMI_STATUS, tmp, tmp); +- if (r) +- return r; +- +- /* disable LMI UMC channel */ +- tmp = RREG32_SOC15(VCN, i, regUVD_LMI_CTRL2); +- tmp |= UVD_LMI_CTRL2__STALL_ARB_UMC_MASK; +- WREG32_SOC15(VCN, i, regUVD_LMI_CTRL2, tmp); +- tmp = UVD_LMI_STATUS__UMC_READ_CLEAN_RAW_MASK | +- UVD_LMI_STATUS__UMC_WRITE_CLEAN_RAW_MASK; +- r = SOC15_WAIT_ON_RREG(VCN, i, regUVD_LMI_STATUS, tmp, tmp); +- if (r) +- return r; +- +- /* block VCPU register access */ +- WREG32_P(SOC15_REG_OFFSET(VCN, i, regUVD_RB_ARB_CTRL), +- UVD_RB_ARB_CTRL__VCPU_DIS_MASK, +- ~UVD_RB_ARB_CTRL__VCPU_DIS_MASK); +- +- /* reset VCPU */ +- WREG32_P(SOC15_REG_OFFSET(VCN, i, regUVD_VCPU_CNTL), +- UVD_VCPU_CNTL__BLK_RST_MASK, +- ~UVD_VCPU_CNTL__BLK_RST_MASK); +- +- /* disable VCPU clock */ +- WREG32_P(SOC15_REG_OFFSET(VCN, i, regUVD_VCPU_CNTL), 0, +- ~(UVD_VCPU_CNTL__CLK_EN_MASK)); +- +- /* apply soft reset */ +- tmp = RREG32_SOC15(VCN, i, regUVD_SOFT_RESET); +- tmp |= UVD_SOFT_RESET__LMI_UMC_SOFT_RESET_MASK; +- WREG32_SOC15(VCN, i, regUVD_SOFT_RESET, tmp); +- tmp = RREG32_SOC15(VCN, i, regUVD_SOFT_RESET); +- tmp |= UVD_SOFT_RESET__LMI_SOFT_RESET_MASK; +- WREG32_SOC15(VCN, i, regUVD_SOFT_RESET, tmp); +- +- /* clear status */ +- WREG32_SOC15(VCN, i, regUVD_STATUS, 0); ++ if (adev->vcn.harvest_config & (1 << i)) ++ return 0; + +- /* apply HW clock gating */ +- vcn_v4_0_5_enable_clock_gating(adev, i); ++ fw_shared = adev->vcn.inst[i].fw_shared.cpu_addr; ++ fw_shared->sq.queue_mode |= FW_QUEUE_DPG_HOLD_OFF; + +- /* enable VCN power gating */ +- vcn_v4_0_5_enable_static_power_gating(adev, i); ++ if (adev->pg_flags & AMD_PG_SUPPORT_VCN_DPG) { ++ vcn_v4_0_5_stop_dpg_mode(adev, i); ++ r = 0; ++ goto done; + } + +- for (i = 0; i < adev->vcn.num_vcn_inst; ++i) { +- if (adev->pm.dpm_enabled) +- amdgpu_dpm_enable_vcn(adev, false, i); +- } ++ /* wait for vcn idle */ ++ r = SOC15_WAIT_ON_RREG(VCN, i, regUVD_STATUS, UVD_STATUS__IDLE, 0x7); ++ if (r) ++ goto done; ++ ++ tmp = UVD_LMI_STATUS__VCPU_LMI_WRITE_CLEAN_MASK | ++ UVD_LMI_STATUS__READ_CLEAN_MASK | ++ UVD_LMI_STATUS__WRITE_CLEAN_MASK | ++ UVD_LMI_STATUS__WRITE_CLEAN_RAW_MASK; ++ r = SOC15_WAIT_ON_RREG(VCN, i, regUVD_LMI_STATUS, tmp, tmp); ++ if (r) ++ goto done; ++ ++ /* disable LMI UMC channel */ ++ tmp = RREG32_SOC15(VCN, i, regUVD_LMI_CTRL2); ++ tmp |= UVD_LMI_CTRL2__STALL_ARB_UMC_MASK; ++ WREG32_SOC15(VCN, i, regUVD_LMI_CTRL2, tmp); ++ tmp = UVD_LMI_STATUS__UMC_READ_CLEAN_RAW_MASK | ++ UVD_LMI_STATUS__UMC_WRITE_CLEAN_RAW_MASK; ++ r = SOC15_WAIT_ON_RREG(VCN, i, regUVD_LMI_STATUS, tmp, tmp); ++ if (r) ++ goto done; ++ ++ /* block VCPU register access */ ++ WREG32_P(SOC15_REG_OFFSET(VCN, i, regUVD_RB_ARB_CTRL), ++ UVD_RB_ARB_CTRL__VCPU_DIS_MASK, ++ ~UVD_RB_ARB_CTRL__VCPU_DIS_MASK); ++ ++ /* reset VCPU */ ++ WREG32_P(SOC15_REG_OFFSET(VCN, i, regUVD_VCPU_CNTL), ++ UVD_VCPU_CNTL__BLK_RST_MASK, ++ ~UVD_VCPU_CNTL__BLK_RST_MASK); ++ ++ /* disable VCPU clock */ ++ WREG32_P(SOC15_REG_OFFSET(VCN, i, regUVD_VCPU_CNTL), 0, ++ ~(UVD_VCPU_CNTL__CLK_EN_MASK)); ++ ++ /* apply soft reset */ ++ tmp = RREG32_SOC15(VCN, i, regUVD_SOFT_RESET); ++ tmp |= UVD_SOFT_RESET__LMI_UMC_SOFT_RESET_MASK; ++ WREG32_SOC15(VCN, i, regUVD_SOFT_RESET, tmp); ++ tmp = RREG32_SOC15(VCN, i, regUVD_SOFT_RESET); ++ tmp |= UVD_SOFT_RESET__LMI_SOFT_RESET_MASK; ++ WREG32_SOC15(VCN, i, regUVD_SOFT_RESET, tmp); ++ ++ /* clear status */ ++ WREG32_SOC15(VCN, i, regUVD_STATUS, 0); ++ ++ /* apply HW clock gating */ ++ vcn_v4_0_5_enable_clock_gating(adev, i); ++ ++ /* enable VCN power gating */ ++ vcn_v4_0_5_enable_static_power_gating(adev, i); ++ ++done: ++ if (adev->pm.dpm_enabled) ++ amdgpu_dpm_enable_vcn(adev, false, i); + +- return 0; ++ return r; + } + + /** +@@ -1537,15 +1531,17 @@ static int vcn_v4_0_5_set_powergating_st + enum amd_powergating_state state) + { + struct amdgpu_device *adev = ip_block->adev; +- int ret; ++ int ret = 0, i; + + if (state == adev->vcn.cur_state) + return 0; + +- if (state == AMD_PG_STATE_GATE) +- ret = vcn_v4_0_5_stop(adev); +- else +- ret = vcn_v4_0_5_start(adev); ++ for (i = 0; i < adev->vcn.num_vcn_inst; ++i) { ++ if (state == AMD_PG_STATE_GATE) ++ ret |= vcn_v4_0_5_stop(adev, i); ++ else ++ ret |= vcn_v4_0_5_start(adev, i); ++ } + + if (!ret) + adev->vcn.cur_state = state; diff --git a/queue-6.14/drm-i915-dp-fix-determining-sst-mst-mode-during-mtp-tu-state-computation.patch b/queue-6.14/drm-i915-dp-fix-determining-sst-mst-mode-during-mtp-tu-state-computation.patch new file mode 100644 index 0000000000..3c085924eb --- /dev/null +++ b/queue-6.14/drm-i915-dp-fix-determining-sst-mst-mode-during-mtp-tu-state-computation.patch @@ -0,0 +1,54 @@ +From 732b87a409667a370b87955c518e5d004de740b5 Mon Sep 17 00:00:00 2001 +From: Imre Deak +Date: Wed, 7 May 2025 18:19:53 +0300 +Subject: drm/i915/dp: Fix determining SST/MST mode during MTP TU state computation + +From: Imre Deak + +commit 732b87a409667a370b87955c518e5d004de740b5 upstream. + +Determining the SST/MST mode during state computation must be done based +on the output type stored in the CRTC state, which in turn is set once +based on the modeset connector's SST vs. MST type and will not change as +long as the connector is using the CRTC. OTOH the MST mode indicated by +the given connector's intel_dp::is_mst flag can change independently of +the above output type, based on what sink is at any moment plugged to +the connector. + +Fix the state computation accordingly. + +Cc: Jani Nikula +Fixes: f6971d7427c2 ("drm/i915/mst: adapt intel_dp_mtp_tu_compute_config() for 128b/132b SST") +Closes: https://gitlab.freedesktop.org/drm/xe/kernel/-/issues/4607 +Reviewed-by: Jani Nikula +Signed-off-by: Imre Deak +Link: https://lore.kernel.org/r/20250507151953.251846-1-imre.deak@intel.com +(cherry picked from commit 0f45696ddb2b901fbf15cb8d2e89767be481d59f) +Signed-off-by: Jani Nikula +References: https://gitlab.freedesktop.org/drm/i915/kernel/-/issues/14218 +[Rebased on v6.14.8 and added References link. (Imre)] +Signed-off-by: Imre Deak +Signed-off-by: Greg Kroah-Hartman +--- + drivers/gpu/drm/i915/display/intel_dp_mst.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +--- a/drivers/gpu/drm/i915/display/intel_dp_mst.c ++++ b/drivers/gpu/drm/i915/display/intel_dp_mst.c +@@ -221,6 +221,7 @@ int intel_dp_mtp_tu_compute_config(struc + to_intel_connector(conn_state->connector); + const struct drm_display_mode *adjusted_mode = + &crtc_state->hw.adjusted_mode; ++ bool is_mst = intel_crtc_has_type(crtc_state, INTEL_OUTPUT_DP_MST); + fixed20_12 pbn_div; + int bpp, slots = -EINVAL; + int dsc_slice_count = 0; +@@ -271,7 +272,7 @@ int intel_dp_mtp_tu_compute_config(struc + link_bpp_x16, + &crtc_state->dp_m_n); + +- if (intel_dp->is_mst) { ++ if (is_mst) { + int remote_bw_overhead; + int remote_tu; + fixed20_12 pbn; diff --git a/queue-6.14/series b/queue-6.14/series index 7fa6f06634..ce36a9914a 100644 --- a/queue-6.14/series +++ b/queue-6.14/series @@ -776,3 +776,6 @@ spi-spi-fsl-dspi-halt-the-module-after-a-new-message.patch spi-spi-fsl-dspi-reset-sr-flags-before-sending-a-new.patch drm-xe-use-xe_mmio_read32-to-read-mtcfg-register.patch err.h-move-iomem_err_ptr-to-err.h.patch +drm-i915-dp-fix-determining-sst-mst-mode-during-mtp-tu-state-computation.patch +drm-amdgpu-vcn4.0.5-split-code-along-instances.patch +drm-amdgpu-read-back-register-after-written-for-vcn-v4.0.5.patch