diff options
author | Alex Deucher <alexander.deucher@amd.com> | 2013-10-02 15:18:14 -0400 |
---|---|---|
committer | Alex Deucher <alexander.deucher@amd.com> | 2014-01-08 18:42:24 -0500 |
commit | 0279ed19bd962434d334f5eeb16d14fdd9459a00 (patch) | |
tree | af41914174d3b22ca61de3a955f4c79f0ea8992f | |
parent | 4a5c8ea59f8360f354158fca039ee7fbef0fa4dd (diff) |
drm/radeon: implement pci config reset for CIK (v3)
pci config reset is a low level reset that resets
the entire chip from the bus interface. It can
be more reliable if soft reset fails.
v2: fix rebase
v3: hide behind module parameter
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
-rw-r--r-- | drivers/gpu/drm/radeon/cik.c | 161 | ||||
-rw-r--r-- | drivers/gpu/drm/radeon/cikd.h | 11 |
2 files changed, 172 insertions, 0 deletions
diff --git a/drivers/gpu/drm/radeon/cik.c b/drivers/gpu/drm/radeon/cik.c index e66eb4745347..9e50dd5d0e42 100644 --- a/drivers/gpu/drm/radeon/cik.c +++ b/drivers/gpu/drm/radeon/cik.c | |||
@@ -4880,6 +4880,160 @@ static void cik_gpu_soft_reset(struct radeon_device *rdev, u32 reset_mask) | |||
4880 | cik_print_gpu_status_regs(rdev); | 4880 | cik_print_gpu_status_regs(rdev); |
4881 | } | 4881 | } |
4882 | 4882 | ||
4883 | struct kv_reset_save_regs { | ||
4884 | u32 gmcon_reng_execute; | ||
4885 | u32 gmcon_misc; | ||
4886 | u32 gmcon_misc3; | ||
4887 | }; | ||
4888 | |||
4889 | static void kv_save_regs_for_reset(struct radeon_device *rdev, | ||
4890 | struct kv_reset_save_regs *save) | ||
4891 | { | ||
4892 | save->gmcon_reng_execute = RREG32(GMCON_RENG_EXECUTE); | ||
4893 | save->gmcon_misc = RREG32(GMCON_MISC); | ||
4894 | save->gmcon_misc3 = RREG32(GMCON_MISC3); | ||
4895 | |||
4896 | WREG32(GMCON_RENG_EXECUTE, save->gmcon_reng_execute & ~RENG_EXECUTE_ON_PWR_UP); | ||
4897 | WREG32(GMCON_MISC, save->gmcon_misc & ~(RENG_EXECUTE_ON_REG_UPDATE | | ||
4898 | STCTRL_STUTTER_EN)); | ||
4899 | } | ||
4900 | |||
4901 | static void kv_restore_regs_for_reset(struct radeon_device *rdev, | ||
4902 | struct kv_reset_save_regs *save) | ||
4903 | { | ||
4904 | int i; | ||
4905 | |||
4906 | WREG32(GMCON_PGFSM_WRITE, 0); | ||
4907 | WREG32(GMCON_PGFSM_CONFIG, 0x200010ff); | ||
4908 | |||
4909 | for (i = 0; i < 5; i++) | ||
4910 | WREG32(GMCON_PGFSM_WRITE, 0); | ||
4911 | |||
4912 | WREG32(GMCON_PGFSM_WRITE, 0); | ||
4913 | WREG32(GMCON_PGFSM_CONFIG, 0x300010ff); | ||
4914 | |||
4915 | for (i = 0; i < 5; i++) | ||
4916 | WREG32(GMCON_PGFSM_WRITE, 0); | ||
4917 | |||
4918 | WREG32(GMCON_PGFSM_WRITE, 0x210000); | ||
4919 | WREG32(GMCON_PGFSM_CONFIG, 0xa00010ff); | ||
4920 | |||
4921 | for (i = 0; i < 5; i++) | ||
4922 | WREG32(GMCON_PGFSM_WRITE, 0); | ||
4923 | |||
4924 | WREG32(GMCON_PGFSM_WRITE, 0x21003); | ||
4925 | WREG32(GMCON_PGFSM_CONFIG, 0xb00010ff); | ||
4926 | |||
4927 | for (i = 0; i < 5; i++) | ||
4928 | WREG32(GMCON_PGFSM_WRITE, 0); | ||
4929 | |||
4930 | WREG32(GMCON_PGFSM_WRITE, 0x2b00); | ||
4931 | WREG32(GMCON_PGFSM_CONFIG, 0xc00010ff); | ||
4932 | |||
4933 | for (i = 0; i < 5; i++) | ||
4934 | WREG32(GMCON_PGFSM_WRITE, 0); | ||
4935 | |||
4936 | WREG32(GMCON_PGFSM_WRITE, 0); | ||
4937 | WREG32(GMCON_PGFSM_CONFIG, 0xd00010ff); | ||
4938 | |||
4939 | for (i = 0; i < 5; i++) | ||
4940 | WREG32(GMCON_PGFSM_WRITE, 0); | ||
4941 | |||
4942 | WREG32(GMCON_PGFSM_WRITE, 0x420000); | ||
4943 | WREG32(GMCON_PGFSM_CONFIG, 0x100010ff); | ||
4944 | |||
4945 | for (i = 0; i < 5; i++) | ||
4946 | WREG32(GMCON_PGFSM_WRITE, 0); | ||
4947 | |||
4948 | WREG32(GMCON_PGFSM_WRITE, 0x120202); | ||
4949 | WREG32(GMCON_PGFSM_CONFIG, 0x500010ff); | ||
4950 | |||
4951 | for (i = 0; i < 5; i++) | ||
4952 | WREG32(GMCON_PGFSM_WRITE, 0); | ||
4953 | |||
4954 | WREG32(GMCON_PGFSM_WRITE, 0x3e3e36); | ||
4955 | WREG32(GMCON_PGFSM_CONFIG, 0x600010ff); | ||
4956 | |||
4957 | for (i = 0; i < 5; i++) | ||
4958 | WREG32(GMCON_PGFSM_WRITE, 0); | ||
4959 | |||
4960 | WREG32(GMCON_PGFSM_WRITE, 0x373f3e); | ||
4961 | WREG32(GMCON_PGFSM_CONFIG, 0x700010ff); | ||
4962 | |||
4963 | for (i = 0; i < 5; i++) | ||
4964 | WREG32(GMCON_PGFSM_WRITE, 0); | ||
4965 | |||
4966 | WREG32(GMCON_PGFSM_WRITE, 0x3e1332); | ||
4967 | WREG32(GMCON_PGFSM_CONFIG, 0xe00010ff); | ||
4968 | |||
4969 | WREG32(GMCON_MISC3, save->gmcon_misc3); | ||
4970 | WREG32(GMCON_MISC, save->gmcon_misc); | ||
4971 | WREG32(GMCON_RENG_EXECUTE, save->gmcon_reng_execute); | ||
4972 | } | ||
4973 | |||
4974 | static void cik_gpu_pci_config_reset(struct radeon_device *rdev) | ||
4975 | { | ||
4976 | struct evergreen_mc_save save; | ||
4977 | struct kv_reset_save_regs kv_save = { 0 }; | ||
4978 | u32 tmp, i; | ||
4979 | |||
4980 | dev_info(rdev->dev, "GPU pci config reset\n"); | ||
4981 | |||
4982 | /* disable dpm? */ | ||
4983 | |||
4984 | /* disable cg/pg */ | ||
4985 | cik_fini_pg(rdev); | ||
4986 | cik_fini_cg(rdev); | ||
4987 | |||
4988 | /* Disable GFX parsing/prefetching */ | ||
4989 | WREG32(CP_ME_CNTL, CP_ME_HALT | CP_PFP_HALT | CP_CE_HALT); | ||
4990 | |||
4991 | /* Disable MEC parsing/prefetching */ | ||
4992 | WREG32(CP_MEC_CNTL, MEC_ME1_HALT | MEC_ME2_HALT); | ||
4993 | |||
4994 | /* sdma0 */ | ||
4995 | tmp = RREG32(SDMA0_ME_CNTL + SDMA0_REGISTER_OFFSET); | ||
4996 | tmp |= SDMA_HALT; | ||
4997 | WREG32(SDMA0_ME_CNTL + SDMA0_REGISTER_OFFSET, tmp); | ||
4998 | /* sdma1 */ | ||
4999 | tmp = RREG32(SDMA0_ME_CNTL + SDMA1_REGISTER_OFFSET); | ||
5000 | tmp |= SDMA_HALT; | ||
5001 | WREG32(SDMA0_ME_CNTL + SDMA1_REGISTER_OFFSET, tmp); | ||
5002 | /* XXX other engines? */ | ||
5003 | |||
5004 | /* halt the rlc, disable cp internal ints */ | ||
5005 | cik_rlc_stop(rdev); | ||
5006 | |||
5007 | udelay(50); | ||
5008 | |||
5009 | /* disable mem access */ | ||
5010 | evergreen_mc_stop(rdev, &save); | ||
5011 | if (evergreen_mc_wait_for_idle(rdev)) { | ||
5012 | dev_warn(rdev->dev, "Wait for MC idle timed out !\n"); | ||
5013 | } | ||
5014 | |||
5015 | if (rdev->flags & RADEON_IS_IGP) | ||
5016 | kv_save_regs_for_reset(rdev, &kv_save); | ||
5017 | |||
5018 | /* disable BM */ | ||
5019 | pci_clear_master(rdev->pdev); | ||
5020 | /* reset */ | ||
5021 | radeon_pci_config_reset(rdev); | ||
5022 | |||
5023 | udelay(100); | ||
5024 | |||
5025 | /* wait for asic to come out of reset */ | ||
5026 | for (i = 0; i < rdev->usec_timeout; i++) { | ||
5027 | if (RREG32(CONFIG_MEMSIZE) != 0xffffffff) | ||
5028 | break; | ||
5029 | udelay(1); | ||
5030 | } | ||
5031 | |||
5032 | /* does asic init need to be run first??? */ | ||
5033 | if (rdev->flags & RADEON_IS_IGP) | ||
5034 | kv_restore_regs_for_reset(rdev, &kv_save); | ||
5035 | } | ||
5036 | |||
4883 | /** | 5037 | /** |
4884 | * cik_asic_reset - soft reset GPU | 5038 | * cik_asic_reset - soft reset GPU |
4885 | * | 5039 | * |
@@ -4898,10 +5052,17 @@ int cik_asic_reset(struct radeon_device *rdev) | |||
4898 | if (reset_mask) | 5052 | if (reset_mask) |
4899 | r600_set_bios_scratch_engine_hung(rdev, true); | 5053 | r600_set_bios_scratch_engine_hung(rdev, true); |
4900 | 5054 | ||
5055 | /* try soft reset */ | ||
4901 | cik_gpu_soft_reset(rdev, reset_mask); | 5056 | cik_gpu_soft_reset(rdev, reset_mask); |
4902 | 5057 | ||
4903 | reset_mask = cik_gpu_check_soft_reset(rdev); | 5058 | reset_mask = cik_gpu_check_soft_reset(rdev); |
4904 | 5059 | ||
5060 | /* try pci config reset */ | ||
5061 | if (reset_mask && radeon_hard_reset) | ||
5062 | cik_gpu_pci_config_reset(rdev); | ||
5063 | |||
5064 | reset_mask = cik_gpu_check_soft_reset(rdev); | ||
5065 | |||
4905 | if (!reset_mask) | 5066 | if (!reset_mask) |
4906 | r600_set_bios_scratch_engine_hung(rdev, false); | 5067 | r600_set_bios_scratch_engine_hung(rdev, false); |
4907 | 5068 | ||
diff --git a/drivers/gpu/drm/radeon/cikd.h b/drivers/gpu/drm/radeon/cikd.h index 5964af5e5b2d..98bae9d7b74d 100644 --- a/drivers/gpu/drm/radeon/cikd.h +++ b/drivers/gpu/drm/radeon/cikd.h | |||
@@ -724,6 +724,17 @@ | |||
724 | 724 | ||
725 | #define ATC_MISC_CG 0x3350 | 725 | #define ATC_MISC_CG 0x3350 |
726 | 726 | ||
727 | #define GMCON_RENG_EXECUTE 0x3508 | ||
728 | #define RENG_EXECUTE_ON_PWR_UP (1 << 0) | ||
729 | #define GMCON_MISC 0x350c | ||
730 | #define RENG_EXECUTE_ON_REG_UPDATE (1 << 11) | ||
731 | #define STCTRL_STUTTER_EN (1 << 16) | ||
732 | |||
733 | #define GMCON_PGFSM_CONFIG 0x3538 | ||
734 | #define GMCON_PGFSM_WRITE 0x353c | ||
735 | #define GMCON_PGFSM_READ 0x3540 | ||
736 | #define GMCON_MISC3 0x3544 | ||
737 | |||
727 | #define MC_SEQ_CNTL_3 0x3600 | 738 | #define MC_SEQ_CNTL_3 0x3600 |
728 | # define CAC_EN (1 << 31) | 739 | # define CAC_EN (1 << 31) |
729 | #define MC_SEQ_G5PDX_CTRL 0x3604 | 740 | #define MC_SEQ_G5PDX_CTRL 0x3604 |