@@ -502,6 +502,52 @@ static void vcn_v5_0_1_enable_clock_gating(struct amdgpu_vcn_inst *vinst)
502502{
503503}
504504
505+ /**
506+ * vcn_v5_0_1_pause_dpg_mode - VCN pause with dpg mode
507+ *
508+ * @vinst: VCN instance
509+ * @new_state: pause state
510+ *
511+ * Pause dpg mode for VCN block
512+ */
513+ static int vcn_v5_0_1_pause_dpg_mode (struct amdgpu_vcn_inst * vinst ,
514+ struct dpg_pause_state * new_state )
515+ {
516+ struct amdgpu_device * adev = vinst -> adev ;
517+ uint32_t reg_data = 0 ;
518+ int vcn_inst ;
519+
520+ vcn_inst = GET_INST (VCN , vinst -> inst );
521+
522+ /* pause/unpause if state is changed */
523+ if (vinst -> pause_state .fw_based != new_state -> fw_based ) {
524+ DRM_DEV_DEBUG (adev -> dev , "dpg pause state changed %d -> %d %s\n" ,
525+ vinst -> pause_state .fw_based , new_state -> fw_based ,
526+ new_state -> fw_based ? "VCN_DPG_STATE__PAUSE" : "VCN_DPG_STATE__UNPAUSE" );
527+ reg_data = RREG32_SOC15 (VCN , vcn_inst , regUVD_DPG_PAUSE ) &
528+ (~UVD_DPG_PAUSE__NJ_PAUSE_DPG_ACK_MASK );
529+
530+ if (new_state -> fw_based == VCN_DPG_STATE__PAUSE ) {
531+ /* pause DPG */
532+ reg_data |= UVD_DPG_PAUSE__NJ_PAUSE_DPG_REQ_MASK ;
533+ WREG32_SOC15 (VCN , vcn_inst , regUVD_DPG_PAUSE , reg_data );
534+
535+ /* wait for ACK */
536+ SOC15_WAIT_ON_RREG (VCN , vcn_inst , regUVD_DPG_PAUSE ,
537+ UVD_DPG_PAUSE__NJ_PAUSE_DPG_ACK_MASK ,
538+ UVD_DPG_PAUSE__NJ_PAUSE_DPG_ACK_MASK );
539+ } else {
540+ /* unpause DPG, no need to wait */
541+ reg_data &= ~UVD_DPG_PAUSE__NJ_PAUSE_DPG_REQ_MASK ;
542+ WREG32_SOC15 (VCN , vcn_inst , regUVD_DPG_PAUSE , reg_data );
543+ }
544+ vinst -> pause_state .fw_based = new_state -> fw_based ;
545+ }
546+
547+ return 0 ;
548+ }
549+
550+
505551/**
506552 * vcn_v5_0_1_start_dpg_mode - VCN start with dpg mode
507553 *
@@ -518,6 +564,7 @@ static int vcn_v5_0_1_start_dpg_mode(struct amdgpu_vcn_inst *vinst,
518564 volatile struct amdgpu_vcn5_fw_shared * fw_shared =
519565 adev -> vcn .inst [inst_idx ].fw_shared .cpu_addr ;
520566 struct amdgpu_ring * ring ;
567+ struct dpg_pause_state state = {.fw_based = VCN_DPG_STATE__PAUSE };
521568 int vcn_inst ;
522569 uint32_t tmp ;
523570
@@ -582,6 +629,9 @@ static int vcn_v5_0_1_start_dpg_mode(struct amdgpu_vcn_inst *vinst,
582629 if (indirect )
583630 amdgpu_vcn_psp_update_sram (adev , inst_idx , AMDGPU_UCODE_ID_VCN0_RAM );
584631
632+ /* Pause dpg */
633+ vcn_v5_0_1_pause_dpg_mode (vinst , & state );
634+
585635 ring = & adev -> vcn .inst [inst_idx ].ring_enc [0 ];
586636
587637 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)
775825 int inst_idx = vinst -> inst ;
776826 uint32_t tmp ;
777827 int vcn_inst ;
828+ struct dpg_pause_state state = {.fw_based = VCN_DPG_STATE__UNPAUSE };
778829
779830 vcn_inst = GET_INST (VCN , inst_idx );
780831
832+ /* Unpause dpg */
833+ vcn_v5_0_1_pause_dpg_mode (vinst , & state );
834+
781835 /* Wait for power status to be 1 */
782836 SOC15_WAIT_ON_RREG (VCN , vcn_inst , regUVD_POWER_STATUS , 1 ,
783837 UVD_POWER_STATUS__UVD_POWER_STATUS_MASK );
0 commit comments