aboutsummaryrefslogtreecommitdiffstats
path: root/meta-amd-bsp/recipes-kernel/linux/linux-yocto-4.19.8/1952-drm-amdgpu-make-VCN-DPG-pause-mode-detached-from-gen.patch
diff options
context:
space:
mode:
Diffstat (limited to 'meta-amd-bsp/recipes-kernel/linux/linux-yocto-4.19.8/1952-drm-amdgpu-make-VCN-DPG-pause-mode-detached-from-gen.patch')
-rw-r--r--meta-amd-bsp/recipes-kernel/linux/linux-yocto-4.19.8/1952-drm-amdgpu-make-VCN-DPG-pause-mode-detached-from-gen.patch344
1 files changed, 344 insertions, 0 deletions
diff --git a/meta-amd-bsp/recipes-kernel/linux/linux-yocto-4.19.8/1952-drm-amdgpu-make-VCN-DPG-pause-mode-detached-from-gen.patch b/meta-amd-bsp/recipes-kernel/linux/linux-yocto-4.19.8/1952-drm-amdgpu-make-VCN-DPG-pause-mode-detached-from-gen.patch
new file mode 100644
index 00000000..843bb6a3
--- /dev/null
+++ b/meta-amd-bsp/recipes-kernel/linux/linux-yocto-4.19.8/1952-drm-amdgpu-make-VCN-DPG-pause-mode-detached-from-gen.patch
@@ -0,0 +1,344 @@
+From 4dc5660f3e0203430d91bd85200e8ebb47e9a76a Mon Sep 17 00:00:00 2001
+From: Leo Liu <leo.liu@amd.com>
+Date: Mon, 13 May 2019 12:41:54 -0400
+Subject: [PATCH 1952/2940] drm/amdgpu: make VCN DPG pause mode detached from
+ general VCN
+
+It should be attached to VCN 1.0
+
+Signed-off-by: Leo Liu <leo.liu@amd.com>
+Reviewed-by: Alex Deucher <alexander.deucher@amd.com>
+---
+ drivers/gpu/drm/amd/amdgpu/amdgpu_vcn.c | 130 +----------------------
+ drivers/gpu/drm/amd/amdgpu/amdgpu_vcn.h | 2 +
+ drivers/gpu/drm/amd/amdgpu/vcn_v1_0.c | 132 +++++++++++++++++++++++-
+ 3 files changed, 135 insertions(+), 129 deletions(-)
+
+diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vcn.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_vcn.c
+index ecf6f96df2ad..118451f5e3aa 100644
+--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vcn.c
++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vcn.c
+@@ -212,132 +212,6 @@ int amdgpu_vcn_resume(struct amdgpu_device *adev)
+ return 0;
+ }
+
+-static int amdgpu_vcn_pause_dpg_mode(struct amdgpu_device *adev,
+- struct dpg_pause_state *new_state)
+-{
+- int ret_code;
+- uint32_t reg_data = 0;
+- uint32_t reg_data2 = 0;
+- struct amdgpu_ring *ring;
+-
+- /* 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 -> %d:%d",
+- adev->vcn.pause_state.fw_based, adev->vcn.pause_state.jpeg,
+- new_state->fw_based, new_state->jpeg);
+-
+- 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;
+-
+- if (!(reg_data & UVD_DPG_PAUSE__JPEG_PAUSE_DPG_ACK_MASK))
+- SOC15_WAIT_ON_RREG(UVD, 0, mmUVD_POWER_STATUS,
+- UVD_POWER_STATUS__UVD_POWER_STATUS_TILES_OFF,
+- UVD_POWER_STATUS__UVD_POWER_STATUS_MASK, ret_code);
+-
+- if (!ret_code) {
+- /* pause DPG non-jpeg */
+- reg_data |= UVD_DPG_PAUSE__NJ_PAUSE_DPG_REQ_MASK;
+- WREG32_SOC15(UVD, 0, mmUVD_DPG_PAUSE, reg_data);
+- 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));
+-
+- ring = &adev->vcn.ring_dec;
+- 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 non-jpeg, 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;
+- }
+-
+- /* pause/unpause if state is changed */
+- if (adev->vcn.pause_state.jpeg != new_state->jpeg) {
+- DRM_DEBUG("dpg pause state changed %d:%d -> %d:%d",
+- adev->vcn.pause_state.fw_based, adev->vcn.pause_state.jpeg,
+- new_state->fw_based, new_state->jpeg);
+-
+- reg_data = RREG32_SOC15(UVD, 0, mmUVD_DPG_PAUSE) &
+- (~UVD_DPG_PAUSE__JPEG_PAUSE_DPG_ACK_MASK);
+-
+- if (new_state->jpeg == VCN_DPG_STATE__PAUSE) {
+- ret_code = 0;
+-
+- if (!(reg_data & UVD_DPG_PAUSE__NJ_PAUSE_DPG_ACK_MASK))
+- SOC15_WAIT_ON_RREG(UVD, 0, mmUVD_POWER_STATUS,
+- UVD_POWER_STATUS__UVD_POWER_STATUS_TILES_OFF,
+- UVD_POWER_STATUS__UVD_POWER_STATUS_MASK, ret_code);
+-
+- if (!ret_code) {
+- /* Make sure JPRG Snoop is disabled before sending the pause */
+- reg_data2 = RREG32_SOC15(UVD, 0, mmUVD_POWER_STATUS);
+- reg_data2 |= UVD_POWER_STATUS__JRBC_SNOOP_DIS_MASK;
+- WREG32_SOC15(UVD, 0, mmUVD_POWER_STATUS, reg_data2);
+-
+- /* pause DPG jpeg */
+- reg_data |= UVD_DPG_PAUSE__JPEG_PAUSE_DPG_REQ_MASK;
+- WREG32_SOC15(UVD, 0, mmUVD_DPG_PAUSE, reg_data);
+- SOC15_WAIT_ON_RREG(UVD, 0, mmUVD_DPG_PAUSE,
+- UVD_DPG_PAUSE__JPEG_PAUSE_DPG_ACK_MASK,
+- UVD_DPG_PAUSE__JPEG_PAUSE_DPG_ACK_MASK, ret_code);
+-
+- /* Restore */
+- ring = &adev->vcn.ring_jpeg;
+- WREG32_SOC15(UVD, 0, mmUVD_LMI_JRBC_RB_VMID, 0);
+- WREG32_SOC15(UVD, 0, mmUVD_JRBC_RB_CNTL,
+- UVD_JRBC_RB_CNTL__RB_NO_FETCH_MASK |
+- UVD_JRBC_RB_CNTL__RB_RPTR_WR_EN_MASK);
+- WREG32_SOC15(UVD, 0, mmUVD_LMI_JRBC_RB_64BIT_BAR_LOW,
+- lower_32_bits(ring->gpu_addr));
+- WREG32_SOC15(UVD, 0, mmUVD_LMI_JRBC_RB_64BIT_BAR_HIGH,
+- upper_32_bits(ring->gpu_addr));
+- WREG32_SOC15(UVD, 0, mmUVD_JRBC_RB_RPTR, ring->wptr);
+- WREG32_SOC15(UVD, 0, mmUVD_JRBC_RB_WPTR, ring->wptr);
+- WREG32_SOC15(UVD, 0, mmUVD_JRBC_RB_CNTL,
+- UVD_JRBC_RB_CNTL__RB_RPTR_WR_EN_MASK);
+-
+- ring = &adev->vcn.ring_dec;
+- 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 jpeg, no need to wait */
+- reg_data &= ~UVD_DPG_PAUSE__JPEG_PAUSE_DPG_REQ_MASK;
+- WREG32_SOC15(UVD, 0, mmUVD_DPG_PAUSE, reg_data);
+- }
+- adev->vcn.pause_state.jpeg = new_state->jpeg;
+- }
+-
+- return 0;
+-}
+-
+ static void amdgpu_vcn_idle_work_handler(struct work_struct *work)
+ {
+ struct amdgpu_device *adev =
+@@ -362,7 +236,7 @@ static void amdgpu_vcn_idle_work_handler(struct work_struct *work)
+ else
+ new_state.jpeg = VCN_DPG_STATE__UNPAUSE;
+
+- amdgpu_vcn_pause_dpg_mode(adev, &new_state);
++ adev->vcn.pause_dpg_mode(adev, &new_state);
+ }
+
+ fences += amdgpu_fence_count_emitted(&adev->vcn.ring_jpeg);
+@@ -417,7 +291,7 @@ void amdgpu_vcn_ring_begin_use(struct amdgpu_ring *ring)
+ else if (ring->funcs->type == AMDGPU_RING_TYPE_VCN_JPEG)
+ new_state.jpeg = VCN_DPG_STATE__PAUSE;
+
+- amdgpu_vcn_pause_dpg_mode(adev, &new_state);
++ adev->vcn.pause_dpg_mode(adev, &new_state);
+ }
+ }
+
+diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vcn.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_vcn.h
+index 98bd0982d325..a1ee19251aae 100644
+--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vcn.h
++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vcn.h
+@@ -102,6 +102,8 @@ struct amdgpu_vcn {
+ unsigned num_enc_rings;
+ enum amd_powergating_state cur_state;
+ struct dpg_pause_state pause_state;
++ int (*pause_dpg_mode)(struct amdgpu_device *adev,
++ struct dpg_pause_state *new_state);
+ };
+
+ int amdgpu_vcn_sw_init(struct amdgpu_device *adev);
+diff --git a/drivers/gpu/drm/amd/amdgpu/vcn_v1_0.c b/drivers/gpu/drm/amd/amdgpu/vcn_v1_0.c
+index ac2e5a1eb576..bb47f5b24be5 100644
+--- a/drivers/gpu/drm/amd/amdgpu/vcn_v1_0.c
++++ b/drivers/gpu/drm/amd/amdgpu/vcn_v1_0.c
+@@ -49,6 +49,8 @@ static void vcn_v1_0_set_jpeg_ring_funcs(struct amdgpu_device *adev);
+ static void vcn_v1_0_set_irq_funcs(struct amdgpu_device *adev);
+ static void vcn_v1_0_jpeg_ring_set_patch_ring(struct amdgpu_ring *ring, uint32_t ptr);
+ static int vcn_v1_0_set_powergating_state(void *handle, enum amd_powergating_state state);
++static int vcn_v1_0_pause_dpg_mode(struct amdgpu_device *adev,
++ struct dpg_pause_state *new_state);
+
+ /**
+ * vcn_v1_0_early_init - set function pointers
+@@ -140,7 +142,9 @@ static int vcn_v1_0_sw_init(void *handle)
+ if (r)
+ return r;
+
+- return r;
++ adev->vcn.pause_dpg_mode = vcn_v1_0_pause_dpg_mode;
++
++ return 0;
+ }
+
+ /**
+@@ -1204,6 +1208,132 @@ static int vcn_v1_0_stop(struct amdgpu_device *adev)
+ return r;
+ }
+
++static int vcn_v1_0_pause_dpg_mode(struct amdgpu_device *adev,
++ struct dpg_pause_state *new_state)
++{
++ int ret_code;
++ uint32_t reg_data = 0;
++ uint32_t reg_data2 = 0;
++ struct amdgpu_ring *ring;
++
++ /* 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 -> %d:%d",
++ adev->vcn.pause_state.fw_based, adev->vcn.pause_state.jpeg,
++ new_state->fw_based, new_state->jpeg);
++
++ 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;
++
++ if (!(reg_data & UVD_DPG_PAUSE__JPEG_PAUSE_DPG_ACK_MASK))
++ SOC15_WAIT_ON_RREG(UVD, 0, mmUVD_POWER_STATUS,
++ UVD_POWER_STATUS__UVD_POWER_STATUS_TILES_OFF,
++ UVD_POWER_STATUS__UVD_POWER_STATUS_MASK, ret_code);
++
++ if (!ret_code) {
++ /* pause DPG non-jpeg */
++ reg_data |= UVD_DPG_PAUSE__NJ_PAUSE_DPG_REQ_MASK;
++ WREG32_SOC15(UVD, 0, mmUVD_DPG_PAUSE, reg_data);
++ 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));
++
++ ring = &adev->vcn.ring_dec;
++ 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 non-jpeg, 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;
++ }
++
++ /* pause/unpause if state is changed */
++ if (adev->vcn.pause_state.jpeg != new_state->jpeg) {
++ DRM_DEBUG("dpg pause state changed %d:%d -> %d:%d",
++ adev->vcn.pause_state.fw_based, adev->vcn.pause_state.jpeg,
++ new_state->fw_based, new_state->jpeg);
++
++ reg_data = RREG32_SOC15(UVD, 0, mmUVD_DPG_PAUSE) &
++ (~UVD_DPG_PAUSE__JPEG_PAUSE_DPG_ACK_MASK);
++
++ if (new_state->jpeg == VCN_DPG_STATE__PAUSE) {
++ ret_code = 0;
++
++ if (!(reg_data & UVD_DPG_PAUSE__NJ_PAUSE_DPG_ACK_MASK))
++ SOC15_WAIT_ON_RREG(UVD, 0, mmUVD_POWER_STATUS,
++ UVD_POWER_STATUS__UVD_POWER_STATUS_TILES_OFF,
++ UVD_POWER_STATUS__UVD_POWER_STATUS_MASK, ret_code);
++
++ if (!ret_code) {
++ /* Make sure JPRG Snoop is disabled before sending the pause */
++ reg_data2 = RREG32_SOC15(UVD, 0, mmUVD_POWER_STATUS);
++ reg_data2 |= UVD_POWER_STATUS__JRBC_SNOOP_DIS_MASK;
++ WREG32_SOC15(UVD, 0, mmUVD_POWER_STATUS, reg_data2);
++
++ /* pause DPG jpeg */
++ reg_data |= UVD_DPG_PAUSE__JPEG_PAUSE_DPG_REQ_MASK;
++ WREG32_SOC15(UVD, 0, mmUVD_DPG_PAUSE, reg_data);
++ SOC15_WAIT_ON_RREG(UVD, 0, mmUVD_DPG_PAUSE,
++ UVD_DPG_PAUSE__JPEG_PAUSE_DPG_ACK_MASK,
++ UVD_DPG_PAUSE__JPEG_PAUSE_DPG_ACK_MASK, ret_code);
++
++ /* Restore */
++ ring = &adev->vcn.ring_jpeg;
++ WREG32_SOC15(UVD, 0, mmUVD_LMI_JRBC_RB_VMID, 0);
++ WREG32_SOC15(UVD, 0, mmUVD_JRBC_RB_CNTL,
++ UVD_JRBC_RB_CNTL__RB_NO_FETCH_MASK |
++ UVD_JRBC_RB_CNTL__RB_RPTR_WR_EN_MASK);
++ WREG32_SOC15(UVD, 0, mmUVD_LMI_JRBC_RB_64BIT_BAR_LOW,
++ lower_32_bits(ring->gpu_addr));
++ WREG32_SOC15(UVD, 0, mmUVD_LMI_JRBC_RB_64BIT_BAR_HIGH,
++ upper_32_bits(ring->gpu_addr));
++ WREG32_SOC15(UVD, 0, mmUVD_JRBC_RB_RPTR, ring->wptr);
++ WREG32_SOC15(UVD, 0, mmUVD_JRBC_RB_WPTR, ring->wptr);
++ WREG32_SOC15(UVD, 0, mmUVD_JRBC_RB_CNTL,
++ UVD_JRBC_RB_CNTL__RB_RPTR_WR_EN_MASK);
++
++ ring = &adev->vcn.ring_dec;
++ 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 jpeg, no need to wait */
++ reg_data &= ~UVD_DPG_PAUSE__JPEG_PAUSE_DPG_REQ_MASK;
++ WREG32_SOC15(UVD, 0, mmUVD_DPG_PAUSE, reg_data);
++ }
++ adev->vcn.pause_state.jpeg = new_state->jpeg;
++ }
++
++ return 0;
++}
++
+ static bool vcn_v1_0_is_idle(void *handle)
+ {
+ struct amdgpu_device *adev = (struct amdgpu_device *)handle;
+--
+2.17.1
+