diff options
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.patch | 344 |
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 + |