<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=us-ascii">
<style type="text/css" style="display:none;"> P {margin-top:0;margin-bottom:0;} </style>
</head>
<body dir="ltr">
<p style="font-family:Calibri;font-size:10pt;color:#0000FF;margin:5pt;font-style:normal;font-weight:normal;text-decoration:none;" align="Left">
[AMD Official Use Only - AMD Internal Distribution Only]<br>
</p>
<br>
<div>
<div class="elementToProof" style="font-family: Aptos, Aptos_EmbeddedFont, Aptos_MSFontService, Calibri, Helvetica, sans-serif; font-size: 12pt; color: rgb(0, 0, 0);">
Ping.</div>
<div id="appendonsend"></div>
<hr style="display:inline-block;width:98%" tabindex="-1">
<div id="divRplyFwdMsg" dir="ltr"><font face="Calibri, sans-serif" style="font-size:11pt" color="#000000"><b>From:</b> Jiang, Sonny <Sonny.Jiang@amd.com><br>
<b>Sent:</b> Friday, April 25, 2025 12:41 PM<br>
<b>To:</b> amd-gfx@lists.freedesktop.org <amd-gfx@lists.freedesktop.org><br>
<b>Cc:</b> Jiang, Sonny <Sonny.Jiang@amd.com><br>
<b>Subject:</b> [PATCH v2] drm/amdgpu: Add DPG pause for VCN v5.0.1</font>
<div> </div>
</div>
<div class="BodyFragment"><font size="2"><span style="font-size:11pt;">
<div class="PlainText">For vcn5.0.1 only, enable DPG PAUSE to avoid DPG resets.<br>
<br>
Signed-off-by: Sonny Jiang <sonny.jiang@amd.com><br>
---<br>
 drivers/gpu/drm/amd/amdgpu/vcn_v5_0_1.c | 54 +++++++++++++++++++++++++<br>
 1 file changed, 54 insertions(+)<br>
<br>
diff --git a/drivers/gpu/drm/amd/amdgpu/vcn_v5_0_1.c b/drivers/gpu/drm/amd/amdgpu/vcn_v5_0_1.c<br>
index 4b2e6a033831..60ee6e02e6ac 100644<br>
--- a/drivers/gpu/drm/amd/amdgpu/vcn_v5_0_1.c<br>
+++ b/drivers/gpu/drm/amd/amdgpu/vcn_v5_0_1.c<br>
@@ -502,6 +502,52 @@ static void vcn_v5_0_1_enable_clock_gating(struct amdgpu_vcn_inst *vinst)<br>
 {<br>
 }<br>
 <br>
+/**<br>
+ * vcn_v5_0_1_pause_dpg_mode - VCN pause with dpg mode<br>
+ *<br>
+ * @vinst: VCN instance<br>
+ * @new_state: pause state<br>
+ *<br>
+ * Pause dpg mode for VCN block<br>
+ */<br>
+static int vcn_v5_0_1_pause_dpg_mode(struct amdgpu_vcn_inst *vinst,<br>
+                                    struct dpg_pause_state *new_state)<br>
+{<br>
+       struct amdgpu_device *adev = vinst->adev;<br>
+       uint32_t reg_data = 0;<br>
+       int vcn_inst;<br>
+<br>
+       vcn_inst = GET_INST(VCN, vinst->inst);<br>
+<br>
+       /* pause/unpause if state is changed */<br>
+       if (vinst->pause_state.fw_based != new_state->fw_based) {<br>
+               DRM_DEV_DEBUG(adev->dev, "dpg pause state changed %d -> %d %s\n",<br>
+                       vinst->pause_state.fw_based, new_state->fw_based,<br>
+                       new_state->fw_based ? "VCN_DPG_STATE__PAUSE" : "VCN_DPG_STATE__UNPAUSE");<br>
+               reg_data = RREG32_SOC15(VCN, vcn_inst, regUVD_DPG_PAUSE) &<br>
+                       (~UVD_DPG_PAUSE__NJ_PAUSE_DPG_ACK_MASK);<br>
+<br>
+               if (new_state->fw_based == VCN_DPG_STATE__PAUSE) {<br>
+                       /* pause DPG */<br>
+                       reg_data |= UVD_DPG_PAUSE__NJ_PAUSE_DPG_REQ_MASK;<br>
+                       WREG32_SOC15(VCN, vcn_inst, regUVD_DPG_PAUSE, reg_data);<br>
+<br>
+                       /* wait for ACK */<br>
+                       SOC15_WAIT_ON_RREG(VCN, vcn_inst, regUVD_DPG_PAUSE,<br>
+                                       UVD_DPG_PAUSE__NJ_PAUSE_DPG_ACK_MASK,<br>
+                                       UVD_DPG_PAUSE__NJ_PAUSE_DPG_ACK_MASK);<br>
+               } else {<br>
+                       /* unpause DPG, no need to wait */<br>
+                       reg_data &= ~UVD_DPG_PAUSE__NJ_PAUSE_DPG_REQ_MASK;<br>
+                       WREG32_SOC15(VCN, vcn_inst, regUVD_DPG_PAUSE, reg_data);<br>
+               }<br>
+               vinst->pause_state.fw_based = new_state->fw_based;<br>
+       }<br>
+<br>
+       return 0;<br>
+}<br>
+<br>
+<br>
 /**<br>
  * vcn_v5_0_1_start_dpg_mode - VCN start with dpg mode<br>
  *<br>
@@ -518,6 +564,7 @@ static int vcn_v5_0_1_start_dpg_mode(struct amdgpu_vcn_inst *vinst,<br>
         volatile struct amdgpu_vcn5_fw_shared *fw_shared =<br>
                 adev->vcn.inst[inst_idx].fw_shared.cpu_addr;<br>
         struct amdgpu_ring *ring;<br>
+       struct dpg_pause_state state = {.fw_based = VCN_DPG_STATE__PAUSE};<br>
         int vcn_inst;<br>
         uint32_t tmp;<br>
 <br>
@@ -582,6 +629,9 @@ static int vcn_v5_0_1_start_dpg_mode(struct amdgpu_vcn_inst *vinst,<br>
         if (indirect)<br>
                 amdgpu_vcn_psp_update_sram(adev, inst_idx, AMDGPU_UCODE_ID_VCN0_RAM);<br>
 <br>
+       /* Pause dpg */<br>
+       vcn_v5_0_1_pause_dpg_mode(vinst, &state);<br>
+<br>
         ring = &adev->vcn.inst[inst_idx].ring_enc[0];<br>
 <br>
         WREG32_SOC15(VCN, vcn_inst, regUVD_RB_BASE_LO, lower_32_bits(ring->gpu_addr));<br>
@@ -775,9 +825,13 @@ static void vcn_v5_0_1_stop_dpg_mode(struct amdgpu_vcn_inst *vinst)<br>
         int inst_idx = vinst->inst;<br>
         uint32_t tmp;<br>
         int vcn_inst;<br>
+       struct dpg_pause_state state = {.fw_based = VCN_DPG_STATE__UNPAUSE};<br>
 <br>
         vcn_inst = GET_INST(VCN, inst_idx);<br>
 <br>
+       /* Unpause dpg */<br>
+       vcn_v5_0_1_pause_dpg_mode(vinst, &state);<br>
+<br>
         /* Wait for power status to be 1 */<br>
         SOC15_WAIT_ON_RREG(VCN, vcn_inst, regUVD_POWER_STATUS, 1,<br>
                 UVD_POWER_STATUS__UVD_POWER_STATUS_MASK);<br>
-- <br>
2.49.0<br>
<br>
</div>
</span></font></div>
</div>
</body>
</html>