[AMD Official Use Only - AMD Internal Distribution Only] Reviewed-by: Leo Liu <leo....@amd.com>
> -----Original Message----- > From: amd-gfx <amd-gfx-boun...@lists.freedesktop.org> On Behalf Of Sonny > Jiang > Sent: April 25, 2025 12:42 PM > To: amd-gfx@lists.freedesktop.org > Cc: Jiang, Sonny <sonny.ji...@amd.com> > Subject: [PATCH v2] drm/amdgpu: Add DPG pause for VCN v5.0.1 > > For vcn5.0.1 only, enable DPG PAUSE to avoid DPG resets. > > Signed-off-by: Sonny Jiang <sonny.ji...@amd.com> > --- > drivers/gpu/drm/amd/amdgpu/vcn_v5_0_1.c | 54 > +++++++++++++++++++++++++ > 1 file changed, 54 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..60ee6e02e6ac 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,52 @@ 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; > + uint32_t reg_data = 0; > + int vcn_inst; > + > + vcn_inst = GET_INST(VCN, vinst->inst); > + > + /* pause/unpause if state is changed */ > + if (vinst->pause_state.fw_based != new_state->fw_based) { > + DRM_DEV_DEBUG(adev->dev, "dpg pause state changed %d - > > %d %s\n", > + vinst->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); > + } > + vinst->pause_state.fw_based = new_state->fw_based; > + } > + > + return 0; > +} > + > + > /** > * vcn_v5_0_1_start_dpg_mode - VCN start with dpg mode > * > @@ -518,6 +564,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 +629,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 +825,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); > -- > 2.49.0