drm/amdgpu/vcn4.0.3: split code along instances

Split the code on a per instance basis.  This will allow
us to use the per instance functions in the future to
handle more things per instance.

v2: squash in fix for stop() from Boyuan

Reviewed-by: Boyuan Zhang <Boyuan.Zhang@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
This commit is contained in:
Alex Deucher 2024-11-13 12:13:15 -05:00
parent f4cd7a85db
commit 5826d5a5d5

View File

@ -1117,172 +1117,169 @@ static int vcn_v4_0_3_start_sriov(struct amdgpu_device *adev)
* vcn_v4_0_3_start - VCN start
*
* @adev: amdgpu_device pointer
* @i: instance to start
*
* Start VCN block
*/
static int vcn_v4_0_3_start(struct amdgpu_device *adev)
static int vcn_v4_0_3_start(struct amdgpu_device *adev, int i)
{
volatile struct amdgpu_vcn4_fw_shared *fw_shared;
struct amdgpu_ring *ring;
int i, j, k, r, vcn_inst;
int j, k, r, vcn_inst;
uint32_t tmp;
for (i = 0; i < adev->vcn.num_vcn_inst; ++i) {
if (adev->pg_flags & AMD_PG_SUPPORT_VCN_DPG) {
r = vcn_v4_0_3_start_dpg_mode(adev, i, adev->vcn.indirect_sram);
continue;
}
if (adev->pg_flags & AMD_PG_SUPPORT_VCN_DPG)
return vcn_v4_0_3_start_dpg_mode(adev, i, adev->vcn.indirect_sram);
vcn_inst = GET_INST(VCN, i);
/* set VCN status busy */
tmp = RREG32_SOC15(VCN, vcn_inst, regUVD_STATUS) |
UVD_STATUS__UVD_BUSY;
WREG32_SOC15(VCN, vcn_inst, regUVD_STATUS, tmp);
vcn_inst = GET_INST(VCN, i);
/* set VCN status busy */
tmp = RREG32_SOC15(VCN, vcn_inst, regUVD_STATUS) |
UVD_STATUS__UVD_BUSY;
WREG32_SOC15(VCN, vcn_inst, regUVD_STATUS, tmp);
/*SW clock gating */
vcn_v4_0_3_disable_clock_gating(adev, i);
/* SW clock gating */
vcn_v4_0_3_disable_clock_gating(adev, i);
/* enable VCPU clock */
WREG32_P(SOC15_REG_OFFSET(VCN, vcn_inst, regUVD_VCPU_CNTL),
UVD_VCPU_CNTL__CLK_EN_MASK,
~UVD_VCPU_CNTL__CLK_EN_MASK);
/* enable VCPU clock */
WREG32_P(SOC15_REG_OFFSET(VCN, vcn_inst, regUVD_VCPU_CNTL),
UVD_VCPU_CNTL__CLK_EN_MASK,
~UVD_VCPU_CNTL__CLK_EN_MASK);
/* disable master interrupt */
WREG32_P(SOC15_REG_OFFSET(VCN, vcn_inst, regUVD_MASTINT_EN), 0,
~UVD_MASTINT_EN__VCPU_EN_MASK);
/* disable master interrupt */
WREG32_P(SOC15_REG_OFFSET(VCN, vcn_inst, regUVD_MASTINT_EN), 0,
~UVD_MASTINT_EN__VCPU_EN_MASK);
/* enable LMI MC and UMC channels */
WREG32_P(SOC15_REG_OFFSET(VCN, vcn_inst, regUVD_LMI_CTRL2), 0,
~UVD_LMI_CTRL2__STALL_ARB_UMC_MASK);
/* enable LMI MC and UMC channels */
WREG32_P(SOC15_REG_OFFSET(VCN, vcn_inst, regUVD_LMI_CTRL2), 0,
~UVD_LMI_CTRL2__STALL_ARB_UMC_MASK);
tmp = RREG32_SOC15(VCN, vcn_inst, regUVD_SOFT_RESET);
tmp &= ~UVD_SOFT_RESET__LMI_SOFT_RESET_MASK;
tmp &= ~UVD_SOFT_RESET__LMI_UMC_SOFT_RESET_MASK;
WREG32_SOC15(VCN, vcn_inst, regUVD_SOFT_RESET, tmp);
tmp = RREG32_SOC15(VCN, vcn_inst, regUVD_SOFT_RESET);
tmp &= ~UVD_SOFT_RESET__LMI_SOFT_RESET_MASK;
tmp &= ~UVD_SOFT_RESET__LMI_UMC_SOFT_RESET_MASK;
WREG32_SOC15(VCN, vcn_inst, regUVD_SOFT_RESET, tmp);
/* setup regUVD_LMI_CTRL */
tmp = RREG32_SOC15(VCN, vcn_inst, regUVD_LMI_CTRL);
WREG32_SOC15(VCN, vcn_inst, regUVD_LMI_CTRL,
tmp | UVD_LMI_CTRL__WRITE_CLEAN_TIMER_EN_MASK |
UVD_LMI_CTRL__MASK_MC_URGENT_MASK |
UVD_LMI_CTRL__DATA_COHERENCY_EN_MASK |
UVD_LMI_CTRL__VCPU_DATA_COHERENCY_EN_MASK);
/* setup regUVD_LMI_CTRL */
tmp = RREG32_SOC15(VCN, vcn_inst, regUVD_LMI_CTRL);
WREG32_SOC15(VCN, vcn_inst, regUVD_LMI_CTRL,
tmp | UVD_LMI_CTRL__WRITE_CLEAN_TIMER_EN_MASK |
UVD_LMI_CTRL__MASK_MC_URGENT_MASK |
UVD_LMI_CTRL__DATA_COHERENCY_EN_MASK |
UVD_LMI_CTRL__VCPU_DATA_COHERENCY_EN_MASK);
/* setup regUVD_MPC_CNTL */
tmp = RREG32_SOC15(VCN, vcn_inst, regUVD_MPC_CNTL);
tmp &= ~UVD_MPC_CNTL__REPLACEMENT_MODE_MASK;
tmp |= 0x2 << UVD_MPC_CNTL__REPLACEMENT_MODE__SHIFT;
WREG32_SOC15(VCN, vcn_inst, regUVD_MPC_CNTL, tmp);
/* setup regUVD_MPC_CNTL */
tmp = RREG32_SOC15(VCN, vcn_inst, regUVD_MPC_CNTL);
tmp &= ~UVD_MPC_CNTL__REPLACEMENT_MODE_MASK;
tmp |= 0x2 << UVD_MPC_CNTL__REPLACEMENT_MODE__SHIFT;
WREG32_SOC15(VCN, vcn_inst, regUVD_MPC_CNTL, tmp);
/* setup UVD_MPC_SET_MUXA0 */
WREG32_SOC15(VCN, vcn_inst, regUVD_MPC_SET_MUXA0,
((0x1 << UVD_MPC_SET_MUXA0__VARA_1__SHIFT) |
(0x2 << UVD_MPC_SET_MUXA0__VARA_2__SHIFT) |
(0x3 << UVD_MPC_SET_MUXA0__VARA_3__SHIFT) |
(0x4 << UVD_MPC_SET_MUXA0__VARA_4__SHIFT)));
/* setup UVD_MPC_SET_MUXA0 */
WREG32_SOC15(VCN, vcn_inst, regUVD_MPC_SET_MUXA0,
((0x1 << UVD_MPC_SET_MUXA0__VARA_1__SHIFT) |
(0x2 << UVD_MPC_SET_MUXA0__VARA_2__SHIFT) |
(0x3 << UVD_MPC_SET_MUXA0__VARA_3__SHIFT) |
(0x4 << UVD_MPC_SET_MUXA0__VARA_4__SHIFT)));
/* setup UVD_MPC_SET_MUXB0 */
WREG32_SOC15(VCN, vcn_inst, regUVD_MPC_SET_MUXB0,
((0x1 << UVD_MPC_SET_MUXB0__VARB_1__SHIFT) |
(0x2 << UVD_MPC_SET_MUXB0__VARB_2__SHIFT) |
(0x3 << UVD_MPC_SET_MUXB0__VARB_3__SHIFT) |
(0x4 << UVD_MPC_SET_MUXB0__VARB_4__SHIFT)));
/* setup UVD_MPC_SET_MUXB0 */
WREG32_SOC15(VCN, vcn_inst, regUVD_MPC_SET_MUXB0,
((0x1 << UVD_MPC_SET_MUXB0__VARB_1__SHIFT) |
(0x2 << UVD_MPC_SET_MUXB0__VARB_2__SHIFT) |
(0x3 << UVD_MPC_SET_MUXB0__VARB_3__SHIFT) |
(0x4 << UVD_MPC_SET_MUXB0__VARB_4__SHIFT)));
/* setup UVD_MPC_SET_MUX */
WREG32_SOC15(VCN, vcn_inst, regUVD_MPC_SET_MUX,
((0x0 << UVD_MPC_SET_MUX__SET_0__SHIFT) |
(0x1 << UVD_MPC_SET_MUX__SET_1__SHIFT) |
(0x2 << UVD_MPC_SET_MUX__SET_2__SHIFT)));
/* setup UVD_MPC_SET_MUX */
WREG32_SOC15(VCN, vcn_inst, regUVD_MPC_SET_MUX,
((0x0 << UVD_MPC_SET_MUX__SET_0__SHIFT) |
(0x1 << UVD_MPC_SET_MUX__SET_1__SHIFT) |
(0x2 << UVD_MPC_SET_MUX__SET_2__SHIFT)));
vcn_v4_0_3_mc_resume(adev, i);
vcn_v4_0_3_mc_resume(adev, i);
/* VCN global tiling registers */
WREG32_SOC15(VCN, vcn_inst, regUVD_GFX8_ADDR_CONFIG,
adev->gfx.config.gb_addr_config);
WREG32_SOC15(VCN, vcn_inst, regUVD_GFX10_ADDR_CONFIG,
adev->gfx.config.gb_addr_config);
/* VCN global tiling registers */
WREG32_SOC15(VCN, vcn_inst, regUVD_GFX8_ADDR_CONFIG,
adev->gfx.config.gb_addr_config);
WREG32_SOC15(VCN, vcn_inst, regUVD_GFX10_ADDR_CONFIG,
adev->gfx.config.gb_addr_config);
/* unblock VCPU register access */
WREG32_P(SOC15_REG_OFFSET(VCN, vcn_inst, regUVD_RB_ARB_CTRL), 0,
~UVD_RB_ARB_CTRL__VCPU_DIS_MASK);
/* unblock VCPU register access */
WREG32_P(SOC15_REG_OFFSET(VCN, vcn_inst, regUVD_RB_ARB_CTRL), 0,
~UVD_RB_ARB_CTRL__VCPU_DIS_MASK);
/* release VCPU reset to boot */
WREG32_P(SOC15_REG_OFFSET(VCN, vcn_inst, regUVD_VCPU_CNTL), 0,
~UVD_VCPU_CNTL__BLK_RST_MASK);
/* release VCPU reset to boot */
WREG32_P(SOC15_REG_OFFSET(VCN, vcn_inst, regUVD_VCPU_CNTL), 0,
~UVD_VCPU_CNTL__BLK_RST_MASK);
for (j = 0; j < 10; ++j) {
uint32_t status;
for (j = 0; j < 10; ++j) {
uint32_t status;
for (k = 0; k < 100; ++k) {
status = RREG32_SOC15(VCN, vcn_inst,
regUVD_STATUS);
if (status & 2)
break;
mdelay(10);
}
r = 0;
for (k = 0; k < 100; ++k) {
status = RREG32_SOC15(VCN, vcn_inst,
regUVD_STATUS);
if (status & 2)
break;
DRM_DEV_ERROR(adev->dev,
"VCN decode not responding, trying to reset the VCPU!!!\n");
WREG32_P(SOC15_REG_OFFSET(VCN, vcn_inst,
regUVD_VCPU_CNTL),
UVD_VCPU_CNTL__BLK_RST_MASK,
~UVD_VCPU_CNTL__BLK_RST_MASK);
mdelay(10);
WREG32_P(SOC15_REG_OFFSET(VCN, vcn_inst,
regUVD_VCPU_CNTL),
0, ~UVD_VCPU_CNTL__BLK_RST_MASK);
mdelay(10);
r = -1;
}
r = 0;
if (status & 2)
break;
if (r) {
DRM_DEV_ERROR(adev->dev, "VCN decode not responding, giving up!!!\n");
return r;
}
/* enable master interrupt */
WREG32_P(SOC15_REG_OFFSET(VCN, vcn_inst, regUVD_MASTINT_EN),
UVD_MASTINT_EN__VCPU_EN_MASK,
~UVD_MASTINT_EN__VCPU_EN_MASK);
/* clear the busy bit of VCN_STATUS */
WREG32_P(SOC15_REG_OFFSET(VCN, vcn_inst, regUVD_STATUS), 0,
~(2 << UVD_STATUS__VCPU_REPORT__SHIFT));
ring = &adev->vcn.inst[i].ring_enc[0];
fw_shared = adev->vcn.inst[i].fw_shared.cpu_addr;
/* program the RB_BASE for ring buffer */
WREG32_SOC15(VCN, vcn_inst, regUVD_RB_BASE_LO,
lower_32_bits(ring->gpu_addr));
WREG32_SOC15(VCN, vcn_inst, regUVD_RB_BASE_HI,
upper_32_bits(ring->gpu_addr));
WREG32_SOC15(VCN, vcn_inst, regUVD_RB_SIZE,
ring->ring_size / sizeof(uint32_t));
/* resetting ring, fw should not check RB ring */
tmp = RREG32_SOC15(VCN, vcn_inst, regVCN_RB_ENABLE);
tmp &= ~(VCN_RB_ENABLE__RB_EN_MASK);
WREG32_SOC15(VCN, vcn_inst, regVCN_RB_ENABLE, tmp);
/* Initialize the ring buffer's read and write pointers */
WREG32_SOC15(VCN, vcn_inst, regUVD_RB_RPTR, 0);
WREG32_SOC15(VCN, vcn_inst, regUVD_RB_WPTR, 0);
tmp = RREG32_SOC15(VCN, vcn_inst, regVCN_RB_ENABLE);
tmp |= VCN_RB_ENABLE__RB_EN_MASK;
WREG32_SOC15(VCN, vcn_inst, regVCN_RB_ENABLE, tmp);
ring->wptr = RREG32_SOC15(VCN, vcn_inst, regUVD_RB_WPTR);
fw_shared->sq.queue_mode &=
cpu_to_le32(~(FW_QUEUE_RING_RESET | FW_QUEUE_DPG_HOLD_OFF));
DRM_DEV_ERROR(adev->dev,
"VCN decode not responding, trying to reset the VCPU!!!\n");
WREG32_P(SOC15_REG_OFFSET(VCN, vcn_inst,
regUVD_VCPU_CNTL),
UVD_VCPU_CNTL__BLK_RST_MASK,
~UVD_VCPU_CNTL__BLK_RST_MASK);
mdelay(10);
WREG32_P(SOC15_REG_OFFSET(VCN, vcn_inst,
regUVD_VCPU_CNTL),
0, ~UVD_VCPU_CNTL__BLK_RST_MASK);
mdelay(10);
r = -1;
}
if (r) {
DRM_DEV_ERROR(adev->dev, "VCN decode not responding, giving up!!!\n");
return r;
}
/* enable master interrupt */
WREG32_P(SOC15_REG_OFFSET(VCN, vcn_inst, regUVD_MASTINT_EN),
UVD_MASTINT_EN__VCPU_EN_MASK,
~UVD_MASTINT_EN__VCPU_EN_MASK);
/* clear the busy bit of VCN_STATUS */
WREG32_P(SOC15_REG_OFFSET(VCN, vcn_inst, regUVD_STATUS), 0,
~(2 << UVD_STATUS__VCPU_REPORT__SHIFT));
ring = &adev->vcn.inst[i].ring_enc[0];
fw_shared = adev->vcn.inst[i].fw_shared.cpu_addr;
/* program the RB_BASE for ring buffer */
WREG32_SOC15(VCN, vcn_inst, regUVD_RB_BASE_LO,
lower_32_bits(ring->gpu_addr));
WREG32_SOC15(VCN, vcn_inst, regUVD_RB_BASE_HI,
upper_32_bits(ring->gpu_addr));
WREG32_SOC15(VCN, vcn_inst, regUVD_RB_SIZE,
ring->ring_size / sizeof(uint32_t));
/* resetting ring, fw should not check RB ring */
tmp = RREG32_SOC15(VCN, vcn_inst, regVCN_RB_ENABLE);
tmp &= ~(VCN_RB_ENABLE__RB_EN_MASK);
WREG32_SOC15(VCN, vcn_inst, regVCN_RB_ENABLE, tmp);
/* Initialize the ring buffer's read and write pointers */
WREG32_SOC15(VCN, vcn_inst, regUVD_RB_RPTR, 0);
WREG32_SOC15(VCN, vcn_inst, regUVD_RB_WPTR, 0);
tmp = RREG32_SOC15(VCN, vcn_inst, regVCN_RB_ENABLE);
tmp |= VCN_RB_ENABLE__RB_EN_MASK;
WREG32_SOC15(VCN, vcn_inst, regVCN_RB_ENABLE, tmp);
ring->wptr = RREG32_SOC15(VCN, vcn_inst, regUVD_RB_WPTR);
fw_shared->sq.queue_mode &=
cpu_to_le32(~(FW_QUEUE_RING_RESET | FW_QUEUE_DPG_HOLD_OFF));
return 0;
}
@ -1322,81 +1319,81 @@ static int vcn_v4_0_3_stop_dpg_mode(struct amdgpu_device *adev, int inst_idx)
* vcn_v4_0_3_stop - VCN stop
*
* @adev: amdgpu_device pointer
* @i: instance to stop
*
* Stop VCN block
*/
static int vcn_v4_0_3_stop(struct amdgpu_device *adev)
static int vcn_v4_0_3_stop(struct amdgpu_device *adev, int i)
{
volatile struct amdgpu_vcn4_fw_shared *fw_shared;
int i, r = 0, vcn_inst;
int r = 0, vcn_inst;
uint32_t tmp;
for (i = 0; i < adev->vcn.num_vcn_inst; ++i) {
vcn_inst = GET_INST(VCN, i);
vcn_inst = GET_INST(VCN, i);
fw_shared = adev->vcn.inst[i].fw_shared.cpu_addr;
fw_shared->sq.queue_mode |= FW_QUEUE_DPG_HOLD_OFF;
fw_shared = adev->vcn.inst[i].fw_shared.cpu_addr;
fw_shared->sq.queue_mode |= FW_QUEUE_DPG_HOLD_OFF;
if (adev->pg_flags & AMD_PG_SUPPORT_VCN_DPG) {
vcn_v4_0_3_stop_dpg_mode(adev, i);
continue;
}
/* wait for vcn idle */
r = SOC15_WAIT_ON_RREG(VCN, vcn_inst, regUVD_STATUS,
UVD_STATUS__IDLE, 0x7);
if (r)
goto Done;
tmp = UVD_LMI_STATUS__VCPU_LMI_WRITE_CLEAN_MASK |
UVD_LMI_STATUS__READ_CLEAN_MASK |
UVD_LMI_STATUS__WRITE_CLEAN_MASK |
UVD_LMI_STATUS__WRITE_CLEAN_RAW_MASK;
r = SOC15_WAIT_ON_RREG(VCN, vcn_inst, regUVD_LMI_STATUS, tmp,
tmp);
if (r)
goto Done;
/* stall UMC channel */
tmp = RREG32_SOC15(VCN, vcn_inst, regUVD_LMI_CTRL2);
tmp |= UVD_LMI_CTRL2__STALL_ARB_UMC_MASK;
WREG32_SOC15(VCN, vcn_inst, regUVD_LMI_CTRL2, tmp);
tmp = UVD_LMI_STATUS__UMC_READ_CLEAN_RAW_MASK |
UVD_LMI_STATUS__UMC_WRITE_CLEAN_RAW_MASK;
r = SOC15_WAIT_ON_RREG(VCN, vcn_inst, regUVD_LMI_STATUS, tmp,
tmp);
if (r)
goto Done;
/* Unblock VCPU Register access */
WREG32_P(SOC15_REG_OFFSET(VCN, vcn_inst, regUVD_RB_ARB_CTRL),
UVD_RB_ARB_CTRL__VCPU_DIS_MASK,
~UVD_RB_ARB_CTRL__VCPU_DIS_MASK);
/* release VCPU reset to boot */
WREG32_P(SOC15_REG_OFFSET(VCN, vcn_inst, regUVD_VCPU_CNTL),
UVD_VCPU_CNTL__BLK_RST_MASK,
~UVD_VCPU_CNTL__BLK_RST_MASK);
/* disable VCPU clock */
WREG32_P(SOC15_REG_OFFSET(VCN, vcn_inst, regUVD_VCPU_CNTL), 0,
~(UVD_VCPU_CNTL__CLK_EN_MASK));
/* reset LMI UMC/LMI/VCPU */
tmp = RREG32_SOC15(VCN, vcn_inst, regUVD_SOFT_RESET);
tmp |= UVD_SOFT_RESET__LMI_UMC_SOFT_RESET_MASK;
WREG32_SOC15(VCN, vcn_inst, regUVD_SOFT_RESET, tmp);
tmp = RREG32_SOC15(VCN, vcn_inst, regUVD_SOFT_RESET);
tmp |= UVD_SOFT_RESET__LMI_SOFT_RESET_MASK;
WREG32_SOC15(VCN, vcn_inst, regUVD_SOFT_RESET, tmp);
/* clear VCN status */
WREG32_SOC15(VCN, vcn_inst, regUVD_STATUS, 0);
/* apply HW clock gating */
vcn_v4_0_3_enable_clock_gating(adev, i);
if (adev->pg_flags & AMD_PG_SUPPORT_VCN_DPG) {
vcn_v4_0_3_stop_dpg_mode(adev, i);
goto Done;
}
/* wait for vcn idle */
r = SOC15_WAIT_ON_RREG(VCN, vcn_inst, regUVD_STATUS,
UVD_STATUS__IDLE, 0x7);
if (r)
goto Done;
tmp = UVD_LMI_STATUS__VCPU_LMI_WRITE_CLEAN_MASK |
UVD_LMI_STATUS__READ_CLEAN_MASK |
UVD_LMI_STATUS__WRITE_CLEAN_MASK |
UVD_LMI_STATUS__WRITE_CLEAN_RAW_MASK;
r = SOC15_WAIT_ON_RREG(VCN, vcn_inst, regUVD_LMI_STATUS, tmp,
tmp);
if (r)
goto Done;
/* stall UMC channel */
tmp = RREG32_SOC15(VCN, vcn_inst, regUVD_LMI_CTRL2);
tmp |= UVD_LMI_CTRL2__STALL_ARB_UMC_MASK;
WREG32_SOC15(VCN, vcn_inst, regUVD_LMI_CTRL2, tmp);
tmp = UVD_LMI_STATUS__UMC_READ_CLEAN_RAW_MASK |
UVD_LMI_STATUS__UMC_WRITE_CLEAN_RAW_MASK;
r = SOC15_WAIT_ON_RREG(VCN, vcn_inst, regUVD_LMI_STATUS, tmp,
tmp);
if (r)
goto Done;
/* Unblock VCPU Register access */
WREG32_P(SOC15_REG_OFFSET(VCN, vcn_inst, regUVD_RB_ARB_CTRL),
UVD_RB_ARB_CTRL__VCPU_DIS_MASK,
~UVD_RB_ARB_CTRL__VCPU_DIS_MASK);
/* release VCPU reset to boot */
WREG32_P(SOC15_REG_OFFSET(VCN, vcn_inst, regUVD_VCPU_CNTL),
UVD_VCPU_CNTL__BLK_RST_MASK,
~UVD_VCPU_CNTL__BLK_RST_MASK);
/* disable VCPU clock */
WREG32_P(SOC15_REG_OFFSET(VCN, vcn_inst, regUVD_VCPU_CNTL), 0,
~(UVD_VCPU_CNTL__CLK_EN_MASK));
/* reset LMI UMC/LMI/VCPU */
tmp = RREG32_SOC15(VCN, vcn_inst, regUVD_SOFT_RESET);
tmp |= UVD_SOFT_RESET__LMI_UMC_SOFT_RESET_MASK;
WREG32_SOC15(VCN, vcn_inst, regUVD_SOFT_RESET, tmp);
tmp = RREG32_SOC15(VCN, vcn_inst, regUVD_SOFT_RESET);
tmp |= UVD_SOFT_RESET__LMI_SOFT_RESET_MASK;
WREG32_SOC15(VCN, vcn_inst, regUVD_SOFT_RESET, tmp);
/* clear VCN status */
WREG32_SOC15(VCN, vcn_inst, regUVD_STATUS, 0);
/* apply HW clock gating */
vcn_v4_0_3_enable_clock_gating(adev, i);
Done:
return 0;
}
@ -1653,7 +1650,7 @@ static int vcn_v4_0_3_set_powergating_state(struct amdgpu_ip_block *ip_block,
enum amd_powergating_state state)
{
struct amdgpu_device *adev = ip_block->adev;
int ret;
int ret = 0, i;
/* for SRIOV, guest should not control VCN Power-gating
* MMSCH FW should control Power-gating and clock-gating
@ -1667,10 +1664,12 @@ static int vcn_v4_0_3_set_powergating_state(struct amdgpu_ip_block *ip_block,
if (state == adev->vcn.cur_state)
return 0;
if (state == AMD_PG_STATE_GATE)
ret = vcn_v4_0_3_stop(adev);
else
ret = vcn_v4_0_3_start(adev);
for (i = 0; i < adev->vcn.num_vcn_inst; ++i) {
if (state == AMD_PG_STATE_GATE)
ret |= vcn_v4_0_3_stop(adev, i);
else
ret |= vcn_v4_0_3_start(adev, i);
}
if (!ret)
adev->vcn.cur_state = state;