diff options
author | Chunming Zhou <David1.Zhou@amd.com> | 2016-07-18 05:18:01 -0400 |
---|---|---|
committer | Alex Deucher <alexander.deucher@amd.com> | 2016-08-08 11:32:11 -0400 |
commit | fc0b3b90b7e8c761372edc9d5661d0c4421ac116 (patch) | |
tree | 822c25625669630234cd1657f96d4548cf5b5530 /drivers/gpu/drm/amd/amdgpu | |
parent | 1015a1b1750e578868a96d812d388d3c65d7faaf (diff) |
drm/amdgpu: implement UVD6 check/pre/post_soft_reset
Signed-off-by: Chunming Zhou <David1.Zhou@amd.com>
Reviewed-by: Christian König <christian.koenig@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
Diffstat (limited to 'drivers/gpu/drm/amd/amdgpu')
-rw-r--r-- | drivers/gpu/drm/amd/amdgpu/amdgpu.h | 1 | ||||
-rw-r--r-- | drivers/gpu/drm/amd/amdgpu/amdgpu_device.c | 1 | ||||
-rw-r--r-- | drivers/gpu/drm/amd/amdgpu/uvd_v6_0.c | 71 |
3 files changed, 69 insertions, 4 deletions
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu.h b/drivers/gpu/drm/amd/amdgpu/amdgpu.h index e4a731bc9fc1..108e04fc0987 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu.h | |||
@@ -1689,6 +1689,7 @@ struct amdgpu_uvd { | |||
1689 | bool address_64_bit; | 1689 | bool address_64_bit; |
1690 | bool use_ctx_buf; | 1690 | bool use_ctx_buf; |
1691 | struct amd_sched_entity entity; | 1691 | struct amd_sched_entity entity; |
1692 | uint32_t srbm_soft_reset; | ||
1692 | }; | 1693 | }; |
1693 | 1694 | ||
1694 | /* | 1695 | /* |
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c index 3640b124851e..309e58cd1263 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c | |||
@@ -1977,7 +1977,6 @@ static bool amdgpu_need_full_reset(struct amdgpu_device *adev) | |||
1977 | { | 1977 | { |
1978 | if (adev->ip_block_status[AMD_IP_BLOCK_TYPE_GMC].hang || | 1978 | if (adev->ip_block_status[AMD_IP_BLOCK_TYPE_GMC].hang || |
1979 | adev->ip_block_status[AMD_IP_BLOCK_TYPE_SMC].hang || | 1979 | adev->ip_block_status[AMD_IP_BLOCK_TYPE_SMC].hang || |
1980 | adev->ip_block_status[AMD_IP_BLOCK_TYPE_UVD].hang || | ||
1981 | adev->ip_block_status[AMD_IP_BLOCK_TYPE_VCE].hang || | 1980 | adev->ip_block_status[AMD_IP_BLOCK_TYPE_VCE].hang || |
1982 | adev->ip_block_status[AMD_IP_BLOCK_TYPE_ACP].hang || | 1981 | adev->ip_block_status[AMD_IP_BLOCK_TYPE_ACP].hang || |
1983 | adev->ip_block_status[AMD_IP_BLOCK_TYPE_DCE].hang) { | 1982 | adev->ip_block_status[AMD_IP_BLOCK_TYPE_DCE].hang) { |
diff --git a/drivers/gpu/drm/amd/amdgpu/uvd_v6_0.c b/drivers/gpu/drm/amd/amdgpu/uvd_v6_0.c index 7f21102bfb99..4fa50918e886 100644 --- a/drivers/gpu/drm/amd/amdgpu/uvd_v6_0.c +++ b/drivers/gpu/drm/amd/amdgpu/uvd_v6_0.c | |||
@@ -754,14 +754,76 @@ static int uvd_v6_0_wait_for_idle(void *handle) | |||
754 | return -ETIMEDOUT; | 754 | return -ETIMEDOUT; |
755 | } | 755 | } |
756 | 756 | ||
757 | static int uvd_v6_0_soft_reset(void *handle) | 757 | #define AMDGPU_UVD_STATUS_BUSY_MASK 0xfd |
758 | static int uvd_v6_0_check_soft_reset(void *handle) | ||
759 | { | ||
760 | struct amdgpu_device *adev = (struct amdgpu_device *)handle; | ||
761 | u32 srbm_soft_reset = 0; | ||
762 | u32 tmp = RREG32(mmSRBM_STATUS); | ||
763 | |||
764 | if (REG_GET_FIELD(tmp, SRBM_STATUS, UVD_RQ_PENDING) || | ||
765 | REG_GET_FIELD(tmp, SRBM_STATUS, UVD_BUSY) || | ||
766 | (RREG32(mmUVD_STATUS) & AMDGPU_UVD_STATUS_BUSY_MASK)) | ||
767 | srbm_soft_reset = REG_SET_FIELD(srbm_soft_reset, SRBM_SOFT_RESET, SOFT_RESET_UVD, 1); | ||
768 | |||
769 | if (srbm_soft_reset) { | ||
770 | adev->ip_block_status[AMD_IP_BLOCK_TYPE_UVD].hang = true; | ||
771 | adev->uvd.srbm_soft_reset = srbm_soft_reset; | ||
772 | } else { | ||
773 | adev->ip_block_status[AMD_IP_BLOCK_TYPE_UVD].hang = false; | ||
774 | adev->uvd.srbm_soft_reset = 0; | ||
775 | } | ||
776 | return 0; | ||
777 | } | ||
778 | static int uvd_v6_0_pre_soft_reset(void *handle) | ||
758 | { | 779 | { |
759 | struct amdgpu_device *adev = (struct amdgpu_device *)handle; | 780 | struct amdgpu_device *adev = (struct amdgpu_device *)handle; |
760 | 781 | ||
782 | if (!adev->ip_block_status[AMD_IP_BLOCK_TYPE_UVD].hang) | ||
783 | return 0; | ||
784 | |||
761 | uvd_v6_0_stop(adev); | 785 | uvd_v6_0_stop(adev); |
786 | return 0; | ||
787 | } | ||
788 | |||
789 | static int uvd_v6_0_soft_reset(void *handle) | ||
790 | { | ||
791 | struct amdgpu_device *adev = (struct amdgpu_device *)handle; | ||
792 | u32 srbm_soft_reset; | ||
793 | |||
794 | if (!adev->ip_block_status[AMD_IP_BLOCK_TYPE_UVD].hang) | ||
795 | return 0; | ||
796 | srbm_soft_reset = adev->uvd.srbm_soft_reset; | ||
797 | |||
798 | if (srbm_soft_reset) { | ||
799 | u32 tmp; | ||
800 | |||
801 | tmp = RREG32(mmSRBM_SOFT_RESET); | ||
802 | tmp |= srbm_soft_reset; | ||
803 | dev_info(adev->dev, "SRBM_SOFT_RESET=0x%08X\n", tmp); | ||
804 | WREG32(mmSRBM_SOFT_RESET, tmp); | ||
805 | tmp = RREG32(mmSRBM_SOFT_RESET); | ||
806 | |||
807 | udelay(50); | ||
808 | |||
809 | tmp &= ~srbm_soft_reset; | ||
810 | WREG32(mmSRBM_SOFT_RESET, tmp); | ||
811 | tmp = RREG32(mmSRBM_SOFT_RESET); | ||
812 | |||
813 | /* Wait a little for things to settle down */ | ||
814 | udelay(50); | ||
815 | } | ||
816 | |||
817 | return 0; | ||
818 | } | ||
819 | |||
820 | static int uvd_v6_0_post_soft_reset(void *handle) | ||
821 | { | ||
822 | struct amdgpu_device *adev = (struct amdgpu_device *)handle; | ||
823 | |||
824 | if (!adev->ip_block_status[AMD_IP_BLOCK_TYPE_UVD].hang) | ||
825 | return 0; | ||
762 | 826 | ||
763 | WREG32_P(mmSRBM_SOFT_RESET, SRBM_SOFT_RESET__SOFT_RESET_UVD_MASK, | ||
764 | ~SRBM_SOFT_RESET__SOFT_RESET_UVD_MASK); | ||
765 | mdelay(5); | 827 | mdelay(5); |
766 | 828 | ||
767 | return uvd_v6_0_start(adev); | 829 | return uvd_v6_0_start(adev); |
@@ -966,7 +1028,10 @@ const struct amd_ip_funcs uvd_v6_0_ip_funcs = { | |||
966 | .resume = uvd_v6_0_resume, | 1028 | .resume = uvd_v6_0_resume, |
967 | .is_idle = uvd_v6_0_is_idle, | 1029 | .is_idle = uvd_v6_0_is_idle, |
968 | .wait_for_idle = uvd_v6_0_wait_for_idle, | 1030 | .wait_for_idle = uvd_v6_0_wait_for_idle, |
1031 | .check_soft_reset = uvd_v6_0_check_soft_reset, | ||
1032 | .pre_soft_reset = uvd_v6_0_pre_soft_reset, | ||
969 | .soft_reset = uvd_v6_0_soft_reset, | 1033 | .soft_reset = uvd_v6_0_soft_reset, |
1034 | .post_soft_reset = uvd_v6_0_post_soft_reset, | ||
970 | .set_clockgating_state = uvd_v6_0_set_clockgating_state, | 1035 | .set_clockgating_state = uvd_v6_0_set_clockgating_state, |
971 | .set_powergating_state = uvd_v6_0_set_powergating_state, | 1036 | .set_powergating_state = uvd_v6_0_set_powergating_state, |
972 | }; | 1037 | }; |