aboutsummaryrefslogtreecommitdiffstats
path: root/meta-amd-bsp/recipes-kernel/linux/linux-yocto-4.19.8/2404-drm-amdgpu-VCN2.0-add-DPG-pause-mode.patch
diff options
context:
space:
mode:
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.patch119
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
+