aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAlex Deucher <alexander.deucher@amd.com>2013-10-02 15:18:14 -0400
committerAlex Deucher <alexander.deucher@amd.com>2014-01-08 18:42:24 -0500
commit0279ed19bd962434d334f5eeb16d14fdd9459a00 (patch)
treeaf41914174d3b22ca61de3a955f4c79f0ea8992f
parent4a5c8ea59f8360f354158fca039ee7fbef0fa4dd (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.c161
-rw-r--r--drivers/gpu/drm/radeon/cikd.h11
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
4883struct kv_reset_save_regs {
4884 u32 gmcon_reng_execute;
4885 u32 gmcon_misc;
4886 u32 gmcon_misc3;
4887};
4888
4889static 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
4901static 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
4974static 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