diff options
Diffstat (limited to 'meta-amd-bsp/recipes-kernel/linux/linux-yocto-4.19.8/2404-drm-amdgpu-VCN2.0-add-DPG-pause-mode.patch')
-rw-r--r-- | meta-amd-bsp/recipes-kernel/linux/linux-yocto-4.19.8/2404-drm-amdgpu-VCN2.0-add-DPG-pause-mode.patch | 119 |
1 files changed, 119 insertions, 0 deletions
diff --git a/meta-amd-bsp/recipes-kernel/linux/linux-yocto-4.19.8/2404-drm-amdgpu-VCN2.0-add-DPG-pause-mode.patch b/meta-amd-bsp/recipes-kernel/linux/linux-yocto-4.19.8/2404-drm-amdgpu-VCN2.0-add-DPG-pause-mode.patch new file mode 100644 index 00000000..c7151552 --- /dev/null +++ b/meta-amd-bsp/recipes-kernel/linux/linux-yocto-4.19.8/2404-drm-amdgpu-VCN2.0-add-DPG-pause-mode.patch @@ -0,0 +1,119 @@ +From 7ca208685d7e9d5cca1294234f72151d34d25cae Mon Sep 17 00:00:00 2001 +From: Leo Liu <leo.liu@amd.com> +Date: Fri, 24 May 2019 12:51:48 -0400 +Subject: [PATCH 2404/2940] drm/amdgpu/VCN2.0: add DPG pause mode + +Pause the DPG when not doing decode + +Signed-off-by: Leo Liu <leo.liu@amd.com> +Reviewed-by: Alex Deucher <alexander.deucher@amd.com> +Signed-off-by: Alex Deucher <alexander.deucher@amd.com> +--- + drivers/gpu/drm/amd/amdgpu/vcn_v2_0.c | 70 +++++++++++++++++++++++++++ + 1 file changed, 70 insertions(+) + +diff --git a/drivers/gpu/drm/amd/amdgpu/vcn_v2_0.c b/drivers/gpu/drm/amd/amdgpu/vcn_v2_0.c +index 3068b0870c8f..bef20704e2b9 100644 +--- a/drivers/gpu/drm/amd/amdgpu/vcn_v2_0.c ++++ b/drivers/gpu/drm/amd/amdgpu/vcn_v2_0.c +@@ -77,6 +77,8 @@ static void vcn_v2_0_set_jpeg_ring_funcs(struct amdgpu_device *adev); + static void vcn_v2_0_set_irq_funcs(struct amdgpu_device *adev); + static int vcn_v2_0_set_powergating_state(void *handle, + enum amd_powergating_state state); ++static int vcn_v2_0_pause_dpg_mode(struct amdgpu_device *adev, ++ struct dpg_pause_state *new_state); + + /** + * vcn_v2_0_early_init - set function pointers +@@ -192,6 +194,8 @@ static int vcn_v2_0_sw_init(void *handle) + if (r) + return r; + ++ adev->vcn.pause_dpg_mode = vcn_v2_0_pause_dpg_mode; ++ + adev->vcn.internal.jpeg_pitch = mmUVD_JPEG_PITCH_INTERNAL_OFFSET; + adev->vcn.external.jpeg_pitch = SOC15_REG_OFFSET(UVD, 0, mmUVD_JPEG_PITCH); + +@@ -1289,6 +1293,68 @@ static int vcn_v2_0_stop(struct amdgpu_device *adev) + return 0; + } + ++static int vcn_v2_0_pause_dpg_mode(struct amdgpu_device *adev, ++ struct dpg_pause_state *new_state) ++{ ++ struct amdgpu_ring *ring; ++ uint32_t reg_data = 0; ++ int ret_code; ++ ++ /* pause/unpause if state is changed */ ++ if (adev->vcn.pause_state.fw_based != new_state->fw_based) { ++ DRM_DEBUG("dpg pause state changed %d -> %d", ++ adev->vcn.pause_state.fw_based, new_state->fw_based); ++ reg_data = RREG32_SOC15(UVD, 0, mmUVD_DPG_PAUSE) & ++ (~UVD_DPG_PAUSE__NJ_PAUSE_DPG_ACK_MASK); ++ ++ if (new_state->fw_based == VCN_DPG_STATE__PAUSE) { ++ ret_code = 0; ++ SOC15_WAIT_ON_RREG(UVD, 0, mmUVD_POWER_STATUS, 0x1, ++ UVD_POWER_STATUS__UVD_POWER_STATUS_MASK, ret_code); ++ ++ if (!ret_code) { ++ /* pause DPG */ ++ reg_data |= UVD_DPG_PAUSE__NJ_PAUSE_DPG_REQ_MASK; ++ WREG32_SOC15(UVD, 0, mmUVD_DPG_PAUSE, reg_data); ++ ++ /* wait for ACK */ ++ SOC15_WAIT_ON_RREG(UVD, 0, mmUVD_DPG_PAUSE, ++ UVD_DPG_PAUSE__NJ_PAUSE_DPG_ACK_MASK, ++ UVD_DPG_PAUSE__NJ_PAUSE_DPG_ACK_MASK, ret_code); ++ ++ /* Restore */ ++ ring = &adev->vcn.ring_enc[0]; ++ WREG32_SOC15(UVD, 0, mmUVD_RB_BASE_LO, ring->gpu_addr); ++ WREG32_SOC15(UVD, 0, mmUVD_RB_BASE_HI, upper_32_bits(ring->gpu_addr)); ++ WREG32_SOC15(UVD, 0, mmUVD_RB_SIZE, ring->ring_size / 4); ++ WREG32_SOC15(UVD, 0, mmUVD_RB_RPTR, lower_32_bits(ring->wptr)); ++ WREG32_SOC15(UVD, 0, mmUVD_RB_WPTR, lower_32_bits(ring->wptr)); ++ ++ ring = &adev->vcn.ring_enc[1]; ++ WREG32_SOC15(UVD, 0, mmUVD_RB_BASE_LO2, ring->gpu_addr); ++ WREG32_SOC15(UVD, 0, mmUVD_RB_BASE_HI2, upper_32_bits(ring->gpu_addr)); ++ WREG32_SOC15(UVD, 0, mmUVD_RB_SIZE2, ring->ring_size / 4); ++ WREG32_SOC15(UVD, 0, mmUVD_RB_RPTR2, lower_32_bits(ring->wptr)); ++ WREG32_SOC15(UVD, 0, mmUVD_RB_WPTR2, lower_32_bits(ring->wptr)); ++ ++ WREG32_SOC15(UVD, 0, mmUVD_RBC_RB_WPTR, ++ RREG32_SOC15(UVD, 0, mmUVD_SCRATCH2) & 0x7FFFFFFF); ++ ++ SOC15_WAIT_ON_RREG(UVD, 0, mmUVD_POWER_STATUS, ++ UVD_PGFSM_CONFIG__UVDM_UVDU_PWR_ON, ++ UVD_POWER_STATUS__UVD_POWER_STATUS_MASK, ret_code); ++ } ++ } else { ++ /* unpause dpg, no need to wait */ ++ reg_data &= ~UVD_DPG_PAUSE__NJ_PAUSE_DPG_REQ_MASK; ++ WREG32_SOC15(UVD, 0, mmUVD_DPG_PAUSE, reg_data); ++ } ++ adev->vcn.pause_state.fw_based = new_state->fw_based; ++ } ++ ++ return 0; ++} ++ + static bool vcn_v2_0_is_idle(void *handle) + { + struct amdgpu_device *adev = (struct amdgpu_device *)handle; +@@ -1367,6 +1433,10 @@ static void vcn_v2_0_dec_ring_set_wptr(struct amdgpu_ring *ring) + { + struct amdgpu_device *adev = ring->adev; + ++ if (adev->pg_flags & AMD_PG_SUPPORT_VCN_DPG) ++ WREG32_SOC15(UVD, 0, mmUVD_SCRATCH2, ++ lower_32_bits(ring->wptr) | 0x80000000); ++ + if (ring->use_doorbell) { + adev->wb.wb[ring->wptr_offs] = lower_32_bits(ring->wptr); + WDOORBELL32(ring->doorbell_index, lower_32_bits(ring->wptr)); +-- +2.17.1 + |