aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/amd/amdgpu
diff options
context:
space:
mode:
authorChunming Zhou <David1.Zhou@amd.com>2016-07-18 05:18:01 -0400
committerAlex Deucher <alexander.deucher@amd.com>2016-08-08 11:32:11 -0400
commitfc0b3b90b7e8c761372edc9d5661d0c4421ac116 (patch)
tree822c25625669630234cd1657f96d4548cf5b5530 /drivers/gpu/drm/amd/amdgpu
parent1015a1b1750e578868a96d812d388d3c65d7faaf (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.h1
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_device.c1
-rw-r--r--drivers/gpu/drm/amd/amdgpu/uvd_v6_0.c71
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
757static int uvd_v6_0_soft_reset(void *handle) 757#define AMDGPU_UVD_STATUS_BUSY_MASK 0xfd
758static 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}
778static 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
789static 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
820static 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};