[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