[PATCH] drm/amdgpu: Add DPG pause for VCN v5.0.1
Lazar, Lijo
lijo.lazar at amd.com
Fri Apr 25 06:07:20 UTC 2025
On 4/24/2025 10:43 PM, Sonny Jiang wrote:
> For vcn5.0.1 only, enable DPG PAUSE to avoid DPG resets.
>
> Signed-off-by: Sonny Jiang <sonny.jiang at amd.com>
> ---
> drivers/gpu/drm/amd/amdgpu/vcn_v5_0_1.c | 55 +++++++++++++++++++++++++
> 1 file changed, 55 insertions(+)
>
> diff --git a/drivers/gpu/drm/amd/amdgpu/vcn_v5_0_1.c b/drivers/gpu/drm/amd/amdgpu/vcn_v5_0_1.c
> index 4b2e6a033831..a115dd2c1d82 100644
> --- a/drivers/gpu/drm/amd/amdgpu/vcn_v5_0_1.c
> +++ b/drivers/gpu/drm/amd/amdgpu/vcn_v5_0_1.c
> @@ -502,6 +502,53 @@ static void vcn_v5_0_1_enable_clock_gating(struct amdgpu_vcn_inst *vinst)
> {
> }
>
> +/**
> + * vcn_v5_0_1_pause_dpg_mode - VCN pause with dpg mode
> + *
> + * @vinst: VCN instance
> + * @new_state: pause state
> + *
> + * Pause dpg mode for VCN block
> + */
> +static int vcn_v5_0_1_pause_dpg_mode(struct amdgpu_vcn_inst *vinst,
> + struct dpg_pause_state *new_state)
> +{
> + struct amdgpu_device *adev = vinst->adev;
> + int inst_idx = vinst->inst;
> + uint32_t reg_data = 0;
> + int vcn_inst;
> +
> + vcn_inst = GET_INST(VCN, inst_idx);
> +
> + /* pause/unpause if state is changed */
> + if (adev->vcn.inst[inst_idx].pause_state.fw_based != new_state->fw_based) {
adev->vcn.inst[inst_idx] => Please replace all with vinst.
Thanks,
Lijo
> + DRM_DEV_DEBUG(adev->dev, "dpg pause state changed %d -> %d %s\n",
> + adev->vcn.inst[inst_idx].pause_state.fw_based, new_state->fw_based,
> + new_state->fw_based ? "VCN_DPG_STATE__PAUSE" : "VCN_DPG_STATE__UNPAUSE");
> + reg_data = RREG32_SOC15(VCN, vcn_inst, regUVD_DPG_PAUSE) &
> + (~UVD_DPG_PAUSE__NJ_PAUSE_DPG_ACK_MASK);
> +
> + if (new_state->fw_based == VCN_DPG_STATE__PAUSE) {
> + /* pause DPG */
> + reg_data |= UVD_DPG_PAUSE__NJ_PAUSE_DPG_REQ_MASK;
> + WREG32_SOC15(VCN, vcn_inst, regUVD_DPG_PAUSE, reg_data);
> +
> + /* wait for ACK */
> + SOC15_WAIT_ON_RREG(VCN, vcn_inst, regUVD_DPG_PAUSE,
> + UVD_DPG_PAUSE__NJ_PAUSE_DPG_ACK_MASK,
> + UVD_DPG_PAUSE__NJ_PAUSE_DPG_ACK_MASK);
> + } else {
> + /* unpause DPG, no need to wait */
> + reg_data &= ~UVD_DPG_PAUSE__NJ_PAUSE_DPG_REQ_MASK;
> + WREG32_SOC15(VCN, vcn_inst, regUVD_DPG_PAUSE, reg_data);
> + }
> + adev->vcn.inst[inst_idx].pause_state.fw_based = new_state->fw_based;
> + }
> +
> + return 0;
> +}
> +
> +
> /**
> * vcn_v5_0_1_start_dpg_mode - VCN start with dpg mode
> *
> @@ -518,6 +565,7 @@ static int vcn_v5_0_1_start_dpg_mode(struct amdgpu_vcn_inst *vinst,
> volatile struct amdgpu_vcn5_fw_shared *fw_shared =
> adev->vcn.inst[inst_idx].fw_shared.cpu_addr;
> struct amdgpu_ring *ring;
> + struct dpg_pause_state state = {.fw_based = VCN_DPG_STATE__PAUSE};
> int vcn_inst;
> uint32_t tmp;
>
> @@ -582,6 +630,9 @@ static int vcn_v5_0_1_start_dpg_mode(struct amdgpu_vcn_inst *vinst,
> if (indirect)
> amdgpu_vcn_psp_update_sram(adev, inst_idx, AMDGPU_UCODE_ID_VCN0_RAM);
>
> + /* Pause dpg */
> + vcn_v5_0_1_pause_dpg_mode(vinst, &state);
> +
> ring = &adev->vcn.inst[inst_idx].ring_enc[0];
>
> WREG32_SOC15(VCN, vcn_inst, regUVD_RB_BASE_LO, lower_32_bits(ring->gpu_addr));
> @@ -775,9 +826,13 @@ static void vcn_v5_0_1_stop_dpg_mode(struct amdgpu_vcn_inst *vinst)
> int inst_idx = vinst->inst;
> uint32_t tmp;
> int vcn_inst;
> + struct dpg_pause_state state = {.fw_based = VCN_DPG_STATE__UNPAUSE};
>
> vcn_inst = GET_INST(VCN, inst_idx);
>
> + /* Unpause dpg */
> + vcn_v5_0_1_pause_dpg_mode(vinst, &state);
> +
> /* Wait for power status to be 1 */
> SOC15_WAIT_ON_RREG(VCN, vcn_inst, regUVD_POWER_STATUS, 1,
> UVD_POWER_STATUS__UVD_POWER_STATUS_MASK);
More information about the amd-gfx
mailing list