aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJerome Glisse <jglisse@redhat.com>2010-03-09 09:45:12 -0500
committerDave Airlie <airlied@redhat.com>2010-04-05 21:21:11 -0400
commit90aca4d2740255bd130ea71a91530b9920c70abe (patch)
treeacf9b8a4353e6727cd6cba5b71caaf9f067e465d
parenta2d07b7438f015a0349bc9af3c96a8164549bbc5 (diff)
drm/radeon/kms: simplify & improve GPU reset V2
This simplify and improve GPU reset for R1XX-R6XX hw, it's not 100% reliable here are result: - R1XX/R2XX works bunch of time in a row, sometimes it seems it can work indifinitly - R3XX/R3XX the most unreliable one, sometimes you will be able to reset few times, sometimes not even once - R5XX more reliable than previous hw, seems to work most of the times but once in a while it fails for no obvious reasons (same status than previous reset just no same happy ending) - R6XX/R7XX are lot more reliable with this patch, still it seems that it can fail after a bunch (reset every 2sec for 3hour bring down the GPU & computer) This have been tested on various hw, for some odd reasons i wasn't able to lockup RS480/RS690 (while they use to love locking up). Note that on R1XX-R5XX the cursor will disapear after lockup haven't checked why, switch to console and back to X will restore cursor. Next step is to record the bogus command that leaded to the lockup. V2 Fix r6xx resume path to avoid reinitializing blit module, use the gpu_lockup boolean to avoid entering inifinite waiting loop on fence while reiniting the GPU Signed-off-by: Jerome Glisse <jglisse@redhat.com> Signed-off-by: Dave Airlie <airlied@redhat.com>
-rw-r--r--drivers/gpu/drm/radeon/r100.c180
-rw-r--r--drivers/gpu/drm/radeon/r100d.h128
-rw-r--r--drivers/gpu/drm/radeon/r300.c134
-rw-r--r--drivers/gpu/drm/radeon/r300d.h47
-rw-r--r--drivers/gpu/drm/radeon/r520.c1
-rw-r--r--drivers/gpu/drm/radeon/r600.c53
-rw-r--r--drivers/gpu/drm/radeon/r600_blit_kms.c3
-rw-r--r--drivers/gpu/drm/radeon/radeon.h1
-rw-r--r--drivers/gpu/drm/radeon/radeon_asic.c9
-rw-r--r--drivers/gpu/drm/radeon/radeon_asic.h6
-rw-r--r--drivers/gpu/drm/radeon/radeon_cs.c4
-rw-r--r--drivers/gpu/drm/radeon/radeon_device.c22
-rw-r--r--drivers/gpu/drm/radeon/radeon_fence.c13
-rw-r--r--drivers/gpu/drm/radeon/radeon_gart.c2
-rw-r--r--drivers/gpu/drm/radeon/rs400.c2
-rw-r--r--drivers/gpu/drm/radeon/rs600.c73
-rw-r--r--drivers/gpu/drm/radeon/rs600d.h46
-rw-r--r--drivers/gpu/drm/radeon/rs690.c2
-rw-r--r--drivers/gpu/drm/radeon/rv515.c90
-rw-r--r--drivers/gpu/drm/radeon/rv515d.h46
20 files changed, 508 insertions, 354 deletions
diff --git a/drivers/gpu/drm/radeon/r100.c b/drivers/gpu/drm/radeon/r100.c
index 8bb91092bffc..7a4a4fc276b3 100644
--- a/drivers/gpu/drm/radeon/r100.c
+++ b/drivers/gpu/drm/radeon/r100.c
@@ -662,26 +662,6 @@ int r100_cp_init(struct radeon_device *rdev, unsigned ring_size)
662 if (r100_debugfs_cp_init(rdev)) { 662 if (r100_debugfs_cp_init(rdev)) {
663 DRM_ERROR("Failed to register debugfs file for CP !\n"); 663 DRM_ERROR("Failed to register debugfs file for CP !\n");
664 } 664 }
665 /* Reset CP */
666 tmp = RREG32(RADEON_CP_CSQ_STAT);
667 if ((tmp & (1 << 31))) {
668 DRM_INFO("radeon: cp busy (0x%08X) resetting\n", tmp);
669 WREG32(RADEON_CP_CSQ_MODE, 0);
670 WREG32(RADEON_CP_CSQ_CNTL, 0);
671 WREG32(RADEON_RBBM_SOFT_RESET, RADEON_SOFT_RESET_CP);
672 tmp = RREG32(RADEON_RBBM_SOFT_RESET);
673 mdelay(2);
674 WREG32(RADEON_RBBM_SOFT_RESET, 0);
675 tmp = RREG32(RADEON_RBBM_SOFT_RESET);
676 mdelay(2);
677 tmp = RREG32(RADEON_CP_CSQ_STAT);
678 if ((tmp & (1 << 31))) {
679 DRM_INFO("radeon: cp reset failed (0x%08X)\n", tmp);
680 }
681 } else {
682 DRM_INFO("radeon: cp idle (0x%08X)\n", tmp);
683 }
684
685 if (!rdev->me_fw) { 665 if (!rdev->me_fw) {
686 r = r100_cp_init_microcode(rdev); 666 r = r100_cp_init_microcode(rdev);
687 if (r) { 667 if (r) {
@@ -786,39 +766,6 @@ void r100_cp_disable(struct radeon_device *rdev)
786 } 766 }
787} 767}
788 768
789int r100_cp_reset(struct radeon_device *rdev)
790{
791 uint32_t tmp;
792 bool reinit_cp;
793 int i;
794
795 reinit_cp = rdev->cp.ready;
796 rdev->cp.ready = false;
797 WREG32(RADEON_CP_CSQ_MODE, 0);
798 WREG32(RADEON_CP_CSQ_CNTL, 0);
799 WREG32(RADEON_RBBM_SOFT_RESET, RADEON_SOFT_RESET_CP);
800 (void)RREG32(RADEON_RBBM_SOFT_RESET);
801 udelay(200);
802 WREG32(RADEON_RBBM_SOFT_RESET, 0);
803 /* Wait to prevent race in RBBM_STATUS */
804 mdelay(1);
805 for (i = 0; i < rdev->usec_timeout; i++) {
806 tmp = RREG32(RADEON_RBBM_STATUS);
807 if (!(tmp & (1 << 16))) {
808 DRM_INFO("CP reset succeed (RBBM_STATUS=0x%08X)\n",
809 tmp);
810 if (reinit_cp) {
811 return r100_cp_init(rdev, rdev->cp.ring_size);
812 }
813 return 0;
814 }
815 DRM_UDELAY(1);
816 }
817 tmp = RREG32(RADEON_RBBM_STATUS);
818 DRM_ERROR("Failed to reset CP (RBBM_STATUS=0x%08X)!\n", tmp);
819 return -1;
820}
821
822void r100_cp_commit(struct radeon_device *rdev) 769void r100_cp_commit(struct radeon_device *rdev)
823{ 770{
824 WREG32(RADEON_CP_RB_WPTR, rdev->cp.wptr); 771 WREG32(RADEON_CP_RB_WPTR, rdev->cp.wptr);
@@ -1732,51 +1679,6 @@ int r100_mc_wait_for_idle(struct radeon_device *rdev)
1732 return -1; 1679 return -1;
1733} 1680}
1734 1681
1735void r100_gpu_init(struct radeon_device *rdev)
1736{
1737 /* TODO: anythings to do here ? pipes ? */
1738 r100_hdp_reset(rdev);
1739}
1740
1741void r100_hdp_reset(struct radeon_device *rdev)
1742{
1743 uint32_t tmp;
1744
1745 tmp = RREG32(RADEON_HOST_PATH_CNTL) & RADEON_HDP_APER_CNTL;
1746 tmp |= (7 << 28);
1747 WREG32(RADEON_HOST_PATH_CNTL, tmp | RADEON_HDP_SOFT_RESET | RADEON_HDP_READ_BUFFER_INVALIDATE);
1748 (void)RREG32(RADEON_HOST_PATH_CNTL);
1749 udelay(200);
1750 WREG32(RADEON_RBBM_SOFT_RESET, 0);
1751 WREG32(RADEON_HOST_PATH_CNTL, tmp);
1752 (void)RREG32(RADEON_HOST_PATH_CNTL);
1753}
1754
1755int r100_rb2d_reset(struct radeon_device *rdev)
1756{
1757 uint32_t tmp;
1758 int i;
1759
1760 WREG32(RADEON_RBBM_SOFT_RESET, RADEON_SOFT_RESET_E2);
1761 (void)RREG32(RADEON_RBBM_SOFT_RESET);
1762 udelay(200);
1763 WREG32(RADEON_RBBM_SOFT_RESET, 0);
1764 /* Wait to prevent race in RBBM_STATUS */
1765 mdelay(1);
1766 for (i = 0; i < rdev->usec_timeout; i++) {
1767 tmp = RREG32(RADEON_RBBM_STATUS);
1768 if (!(tmp & (1 << 26))) {
1769 DRM_INFO("RB2D reset succeed (RBBM_STATUS=0x%08X)\n",
1770 tmp);
1771 return 0;
1772 }
1773 DRM_UDELAY(1);
1774 }
1775 tmp = RREG32(RADEON_RBBM_STATUS);
1776 DRM_ERROR("Failed to reset RB2D (RBBM_STATUS=0x%08X)!\n", tmp);
1777 return -1;
1778}
1779
1780void r100_gpu_lockup_update(struct r100_gpu_lockup *lockup, struct radeon_cp *cp) 1682void r100_gpu_lockup_update(struct r100_gpu_lockup *lockup, struct radeon_cp *cp)
1781{ 1683{
1782 lockup->last_cp_rptr = cp->rptr; 1684 lockup->last_cp_rptr = cp->rptr;
@@ -1863,31 +1765,77 @@ bool r100_gpu_is_lockup(struct radeon_device *rdev)
1863 return r100_gpu_cp_is_lockup(rdev, &rdev->config.r100.lockup, &rdev->cp); 1765 return r100_gpu_cp_is_lockup(rdev, &rdev->config.r100.lockup, &rdev->cp);
1864} 1766}
1865 1767
1768void r100_bm_disable(struct radeon_device *rdev)
1769{
1770 u32 tmp;
1771
1772 /* disable bus mastering */
1773 tmp = RREG32(R_000030_BUS_CNTL);
1774 WREG32(R_000030_BUS_CNTL, (tmp & 0xFFFFFFFF) | 0x00000044);
1775 mdelay(1);
1776 WREG32(R_000030_BUS_CNTL, (tmp & 0xFFFFFFFF) | 0x00000042);
1777 mdelay(1);
1778 WREG32(R_000030_BUS_CNTL, (tmp & 0xFFFFFFFF) | 0x00000040);
1779 tmp = RREG32(RADEON_BUS_CNTL);
1780 mdelay(1);
1781 pci_read_config_word(rdev->pdev, 0x4, (u16*)&tmp);
1782 pci_write_config_word(rdev->pdev, 0x4, tmp & 0xFFFB);
1783 mdelay(1);
1784}
1785
1866int r100_asic_reset(struct radeon_device *rdev) 1786int r100_asic_reset(struct radeon_device *rdev)
1867{ 1787{
1868 uint32_t status; 1788 struct r100_mc_save save;
1789 u32 status, tmp;
1869 1790
1870 /* reset order likely matter */ 1791 r100_mc_stop(rdev, &save);
1871 status = RREG32(RADEON_RBBM_STATUS); 1792 status = RREG32(R_000E40_RBBM_STATUS);
1872 /* reset HDP */ 1793 if (!G_000E40_GUI_ACTIVE(status)) {
1873 r100_hdp_reset(rdev); 1794 return 0;
1874 /* reset rb2d */
1875 if (status & ((1 << 17) | (1 << 18) | (1 << 27))) {
1876 r100_rb2d_reset(rdev);
1877 } 1795 }
1878 /* TODO: reset 3D engine */ 1796 status = RREG32(R_000E40_RBBM_STATUS);
1797 dev_info(rdev->dev, "(%s:%d) RBBM_STATUS=0x%08X\n", __func__, __LINE__, status);
1798 /* stop CP */
1799 WREG32(RADEON_CP_CSQ_CNTL, 0);
1800 tmp = RREG32(RADEON_CP_RB_CNTL);
1801 WREG32(RADEON_CP_RB_CNTL, tmp | RADEON_RB_RPTR_WR_ENA);
1802 WREG32(RADEON_CP_RB_RPTR_WR, 0);
1803 WREG32(RADEON_CP_RB_WPTR, 0);
1804 WREG32(RADEON_CP_RB_CNTL, tmp);
1805 /* save PCI state */
1806 pci_save_state(rdev->pdev);
1807 /* disable bus mastering */
1808 r100_bm_disable(rdev);
1809 WREG32(R_0000F0_RBBM_SOFT_RESET, S_0000F0_SOFT_RESET_SE(1) |
1810 S_0000F0_SOFT_RESET_RE(1) |
1811 S_0000F0_SOFT_RESET_PP(1) |
1812 S_0000F0_SOFT_RESET_RB(1));
1813 RREG32(R_0000F0_RBBM_SOFT_RESET);
1814 mdelay(500);
1815 WREG32(R_0000F0_RBBM_SOFT_RESET, 0);
1816 mdelay(1);
1817 status = RREG32(R_000E40_RBBM_STATUS);
1818 dev_info(rdev->dev, "(%s:%d) RBBM_STATUS=0x%08X\n", __func__, __LINE__, status);
1879 /* reset CP */ 1819 /* reset CP */
1880 status = RREG32(RADEON_RBBM_STATUS); 1820 WREG32(R_0000F0_RBBM_SOFT_RESET, S_0000F0_SOFT_RESET_CP(1));
1881 if (status & (1 << 16)) { 1821 RREG32(R_0000F0_RBBM_SOFT_RESET);
1882 r100_cp_reset(rdev); 1822 mdelay(500);
1883 } 1823 WREG32(R_0000F0_RBBM_SOFT_RESET, 0);
1824 mdelay(1);
1825 status = RREG32(R_000E40_RBBM_STATUS);
1826 dev_info(rdev->dev, "(%s:%d) RBBM_STATUS=0x%08X\n", __func__, __LINE__, status);
1827 /* restore PCI & busmastering */
1828 pci_restore_state(rdev->pdev);
1829 r100_enable_bm(rdev);
1884 /* Check if GPU is idle */ 1830 /* Check if GPU is idle */
1885 status = RREG32(RADEON_RBBM_STATUS); 1831 if (G_000E40_SE_BUSY(status) || G_000E40_RE_BUSY(status) ||
1886 if (status & RADEON_RBBM_ACTIVE) { 1832 G_000E40_TAM_BUSY(status) || G_000E40_PB_BUSY(status)) {
1887 DRM_ERROR("Failed to reset GPU (RBBM_STATUS=0x%08X)\n", status); 1833 dev_err(rdev->dev, "failed to reset GPU\n");
1834 rdev->gpu_lockup = true;
1888 return -1; 1835 return -1;
1889 } 1836 }
1890 DRM_INFO("GPU reset succeed (RBBM_STATUS=0x%08X)\n", status); 1837 r100_mc_resume(rdev, &save);
1838 dev_info(rdev->dev, "GPU reset succeed\n");
1891 return 0; 1839 return 0;
1892} 1840}
1893 1841
@@ -3475,7 +3423,7 @@ static int r100_startup(struct radeon_device *rdev)
3475 /* Resume clock */ 3423 /* Resume clock */
3476 r100_clock_startup(rdev); 3424 r100_clock_startup(rdev);
3477 /* Initialize GPU configuration (# pipes, ...) */ 3425 /* Initialize GPU configuration (# pipes, ...) */
3478 r100_gpu_init(rdev); 3426// r100_gpu_init(rdev);
3479 /* Initialize GART (initialize after TTM so we can allocate 3427 /* Initialize GART (initialize after TTM so we can allocate
3480 * memory through TTM but finalize after TTM) */ 3428 * memory through TTM but finalize after TTM) */
3481 r100_enable_bm(rdev); 3429 r100_enable_bm(rdev);
diff --git a/drivers/gpu/drm/radeon/r100d.h b/drivers/gpu/drm/radeon/r100d.h
index df29a630c466..de8abd104ab7 100644
--- a/drivers/gpu/drm/radeon/r100d.h
+++ b/drivers/gpu/drm/radeon/r100d.h
@@ -74,6 +74,134 @@
74#define CP_PACKET3_GET_OPCODE(h) (((h) >> 8) & 0xFF) 74#define CP_PACKET3_GET_OPCODE(h) (((h) >> 8) & 0xFF)
75 75
76/* Registers */ 76/* Registers */
77#define R_0000F0_RBBM_SOFT_RESET 0x0000F0
78#define S_0000F0_SOFT_RESET_CP(x) (((x) & 0x1) << 0)
79#define G_0000F0_SOFT_RESET_CP(x) (((x) >> 0) & 0x1)
80#define C_0000F0_SOFT_RESET_CP 0xFFFFFFFE
81#define S_0000F0_SOFT_RESET_HI(x) (((x) & 0x1) << 1)
82#define G_0000F0_SOFT_RESET_HI(x) (((x) >> 1) & 0x1)
83#define C_0000F0_SOFT_RESET_HI 0xFFFFFFFD
84#define S_0000F0_SOFT_RESET_SE(x) (((x) & 0x1) << 2)
85#define G_0000F0_SOFT_RESET_SE(x) (((x) >> 2) & 0x1)
86#define C_0000F0_SOFT_RESET_SE 0xFFFFFFFB
87#define S_0000F0_SOFT_RESET_RE(x) (((x) & 0x1) << 3)
88#define G_0000F0_SOFT_RESET_RE(x) (((x) >> 3) & 0x1)
89#define C_0000F0_SOFT_RESET_RE 0xFFFFFFF7
90#define S_0000F0_SOFT_RESET_PP(x) (((x) & 0x1) << 4)
91#define G_0000F0_SOFT_RESET_PP(x) (((x) >> 4) & 0x1)
92#define C_0000F0_SOFT_RESET_PP 0xFFFFFFEF
93#define S_0000F0_SOFT_RESET_E2(x) (((x) & 0x1) << 5)
94#define G_0000F0_SOFT_RESET_E2(x) (((x) >> 5) & 0x1)
95#define C_0000F0_SOFT_RESET_E2 0xFFFFFFDF
96#define S_0000F0_SOFT_RESET_RB(x) (((x) & 0x1) << 6)
97#define G_0000F0_SOFT_RESET_RB(x) (((x) >> 6) & 0x1)
98#define C_0000F0_SOFT_RESET_RB 0xFFFFFFBF
99#define S_0000F0_SOFT_RESET_HDP(x) (((x) & 0x1) << 7)
100#define G_0000F0_SOFT_RESET_HDP(x) (((x) >> 7) & 0x1)
101#define C_0000F0_SOFT_RESET_HDP 0xFFFFFF7F
102#define S_0000F0_SOFT_RESET_MC(x) (((x) & 0x1) << 8)
103#define G_0000F0_SOFT_RESET_MC(x) (((x) >> 8) & 0x1)
104#define C_0000F0_SOFT_RESET_MC 0xFFFFFEFF
105#define S_0000F0_SOFT_RESET_AIC(x) (((x) & 0x1) << 9)
106#define G_0000F0_SOFT_RESET_AIC(x) (((x) >> 9) & 0x1)
107#define C_0000F0_SOFT_RESET_AIC 0xFFFFFDFF
108#define S_0000F0_SOFT_RESET_VIP(x) (((x) & 0x1) << 10)
109#define G_0000F0_SOFT_RESET_VIP(x) (((x) >> 10) & 0x1)
110#define C_0000F0_SOFT_RESET_VIP 0xFFFFFBFF
111#define S_0000F0_SOFT_RESET_DISP(x) (((x) & 0x1) << 11)
112#define G_0000F0_SOFT_RESET_DISP(x) (((x) >> 11) & 0x1)
113#define C_0000F0_SOFT_RESET_DISP 0xFFFFF7FF
114#define S_0000F0_SOFT_RESET_CG(x) (((x) & 0x1) << 12)
115#define G_0000F0_SOFT_RESET_CG(x) (((x) >> 12) & 0x1)
116#define C_0000F0_SOFT_RESET_CG 0xFFFFEFFF
117#define R_000030_BUS_CNTL 0x000030
118#define S_000030_BUS_DBL_RESYNC(x) (((x) & 0x1) << 0)
119#define G_000030_BUS_DBL_RESYNC(x) (((x) >> 0) & 0x1)
120#define C_000030_BUS_DBL_RESYNC 0xFFFFFFFE
121#define S_000030_BUS_MSTR_RESET(x) (((x) & 0x1) << 1)
122#define G_000030_BUS_MSTR_RESET(x) (((x) >> 1) & 0x1)
123#define C_000030_BUS_MSTR_RESET 0xFFFFFFFD
124#define S_000030_BUS_FLUSH_BUF(x) (((x) & 0x1) << 2)
125#define G_000030_BUS_FLUSH_BUF(x) (((x) >> 2) & 0x1)
126#define C_000030_BUS_FLUSH_BUF 0xFFFFFFFB
127#define S_000030_BUS_STOP_REQ_DIS(x) (((x) & 0x1) << 3)
128#define G_000030_BUS_STOP_REQ_DIS(x) (((x) >> 3) & 0x1)
129#define C_000030_BUS_STOP_REQ_DIS 0xFFFFFFF7
130#define S_000030_BUS_PM4_READ_COMBINE_EN(x) (((x) & 0x1) << 4)
131#define G_000030_BUS_PM4_READ_COMBINE_EN(x) (((x) >> 4) & 0x1)
132#define C_000030_BUS_PM4_READ_COMBINE_EN 0xFFFFFFEF
133#define S_000030_BUS_WRT_COMBINE_EN(x) (((x) & 0x1) << 5)
134#define G_000030_BUS_WRT_COMBINE_EN(x) (((x) >> 5) & 0x1)
135#define C_000030_BUS_WRT_COMBINE_EN 0xFFFFFFDF
136#define S_000030_BUS_MASTER_DIS(x) (((x) & 0x1) << 6)
137#define G_000030_BUS_MASTER_DIS(x) (((x) >> 6) & 0x1)
138#define C_000030_BUS_MASTER_DIS 0xFFFFFFBF
139#define S_000030_BIOS_ROM_WRT_EN(x) (((x) & 0x1) << 7)
140#define G_000030_BIOS_ROM_WRT_EN(x) (((x) >> 7) & 0x1)
141#define C_000030_BIOS_ROM_WRT_EN 0xFFFFFF7F
142#define S_000030_BM_DAC_CRIPPLE(x) (((x) & 0x1) << 8)
143#define G_000030_BM_DAC_CRIPPLE(x) (((x) >> 8) & 0x1)
144#define C_000030_BM_DAC_CRIPPLE 0xFFFFFEFF
145#define S_000030_BUS_NON_PM4_READ_COMBINE_EN(x) (((x) & 0x1) << 9)
146#define G_000030_BUS_NON_PM4_READ_COMBINE_EN(x) (((x) >> 9) & 0x1)
147#define C_000030_BUS_NON_PM4_READ_COMBINE_EN 0xFFFFFDFF
148#define S_000030_BUS_XFERD_DISCARD_EN(x) (((x) & 0x1) << 10)
149#define G_000030_BUS_XFERD_DISCARD_EN(x) (((x) >> 10) & 0x1)
150#define C_000030_BUS_XFERD_DISCARD_EN 0xFFFFFBFF
151#define S_000030_BUS_SGL_READ_DISABLE(x) (((x) & 0x1) << 11)
152#define G_000030_BUS_SGL_READ_DISABLE(x) (((x) >> 11) & 0x1)
153#define C_000030_BUS_SGL_READ_DISABLE 0xFFFFF7FF
154#define S_000030_BIOS_DIS_ROM(x) (((x) & 0x1) << 12)
155#define G_000030_BIOS_DIS_ROM(x) (((x) >> 12) & 0x1)
156#define C_000030_BIOS_DIS_ROM 0xFFFFEFFF
157#define S_000030_BUS_PCI_READ_RETRY_EN(x) (((x) & 0x1) << 13)
158#define G_000030_BUS_PCI_READ_RETRY_EN(x) (((x) >> 13) & 0x1)
159#define C_000030_BUS_PCI_READ_RETRY_EN 0xFFFFDFFF
160#define S_000030_BUS_AGP_AD_STEPPING_EN(x) (((x) & 0x1) << 14)
161#define G_000030_BUS_AGP_AD_STEPPING_EN(x) (((x) >> 14) & 0x1)
162#define C_000030_BUS_AGP_AD_STEPPING_EN 0xFFFFBFFF
163#define S_000030_BUS_PCI_WRT_RETRY_EN(x) (((x) & 0x1) << 15)
164#define G_000030_BUS_PCI_WRT_RETRY_EN(x) (((x) >> 15) & 0x1)
165#define C_000030_BUS_PCI_WRT_RETRY_EN 0xFFFF7FFF
166#define S_000030_BUS_RETRY_WS(x) (((x) & 0xF) << 16)
167#define G_000030_BUS_RETRY_WS(x) (((x) >> 16) & 0xF)
168#define C_000030_BUS_RETRY_WS 0xFFF0FFFF
169#define S_000030_BUS_MSTR_RD_MULT(x) (((x) & 0x1) << 20)
170#define G_000030_BUS_MSTR_RD_MULT(x) (((x) >> 20) & 0x1)
171#define C_000030_BUS_MSTR_RD_MULT 0xFFEFFFFF
172#define S_000030_BUS_MSTR_RD_LINE(x) (((x) & 0x1) << 21)
173#define G_000030_BUS_MSTR_RD_LINE(x) (((x) >> 21) & 0x1)
174#define C_000030_BUS_MSTR_RD_LINE 0xFFDFFFFF
175#define S_000030_BUS_SUSPEND(x) (((x) & 0x1) << 22)
176#define G_000030_BUS_SUSPEND(x) (((x) >> 22) & 0x1)
177#define C_000030_BUS_SUSPEND 0xFFBFFFFF
178#define S_000030_LAT_16X(x) (((x) & 0x1) << 23)
179#define G_000030_LAT_16X(x) (((x) >> 23) & 0x1)
180#define C_000030_LAT_16X 0xFF7FFFFF
181#define S_000030_BUS_RD_DISCARD_EN(x) (((x) & 0x1) << 24)
182#define G_000030_BUS_RD_DISCARD_EN(x) (((x) >> 24) & 0x1)
183#define C_000030_BUS_RD_DISCARD_EN 0xFEFFFFFF
184#define S_000030_ENFRCWRDY(x) (((x) & 0x1) << 25)
185#define G_000030_ENFRCWRDY(x) (((x) >> 25) & 0x1)
186#define C_000030_ENFRCWRDY 0xFDFFFFFF
187#define S_000030_BUS_MSTR_WS(x) (((x) & 0x1) << 26)
188#define G_000030_BUS_MSTR_WS(x) (((x) >> 26) & 0x1)
189#define C_000030_BUS_MSTR_WS 0xFBFFFFFF
190#define S_000030_BUS_PARKING_DIS(x) (((x) & 0x1) << 27)
191#define G_000030_BUS_PARKING_DIS(x) (((x) >> 27) & 0x1)
192#define C_000030_BUS_PARKING_DIS 0xF7FFFFFF
193#define S_000030_BUS_MSTR_DISCONNECT_EN(x) (((x) & 0x1) << 28)
194#define G_000030_BUS_MSTR_DISCONNECT_EN(x) (((x) >> 28) & 0x1)
195#define C_000030_BUS_MSTR_DISCONNECT_EN 0xEFFFFFFF
196#define S_000030_SERR_EN(x) (((x) & 0x1) << 29)
197#define G_000030_SERR_EN(x) (((x) >> 29) & 0x1)
198#define C_000030_SERR_EN 0xDFFFFFFF
199#define S_000030_BUS_READ_BURST(x) (((x) & 0x1) << 30)
200#define G_000030_BUS_READ_BURST(x) (((x) >> 30) & 0x1)
201#define C_000030_BUS_READ_BURST 0xBFFFFFFF
202#define S_000030_BUS_RDY_READ_DLY(x) (((x) & 0x1) << 31)
203#define G_000030_BUS_RDY_READ_DLY(x) (((x) >> 31) & 0x1)
204#define C_000030_BUS_RDY_READ_DLY 0x7FFFFFFF
77#define R_000040_GEN_INT_CNTL 0x000040 205#define R_000040_GEN_INT_CNTL 0x000040
78#define S_000040_CRTC_VBLANK(x) (((x) & 0x1) << 0) 206#define S_000040_CRTC_VBLANK(x) (((x) & 0x1) << 0)
79#define G_000040_CRTC_VBLANK(x) (((x) >> 0) & 0x1) 207#define G_000040_CRTC_VBLANK(x) (((x) >> 0) & 0x1)
diff --git a/drivers/gpu/drm/radeon/r300.c b/drivers/gpu/drm/radeon/r300.c
index 7d5de5dbde23..199110ef8df2 100644
--- a/drivers/gpu/drm/radeon/r300.c
+++ b/drivers/gpu/drm/radeon/r300.c
@@ -151,6 +151,10 @@ void rv370_pcie_gart_disable(struct radeon_device *rdev)
151 u32 tmp; 151 u32 tmp;
152 int r; 152 int r;
153 153
154 WREG32_PCIE(RADEON_PCIE_TX_GART_START_LO, 0);
155 WREG32_PCIE(RADEON_PCIE_TX_GART_END_LO, 0);
156 WREG32_PCIE(RADEON_PCIE_TX_GART_START_HI, 0);
157 WREG32_PCIE(RADEON_PCIE_TX_GART_END_HI, 0);
154 tmp = RREG32_PCIE(RADEON_PCIE_TX_GART_CNTL); 158 tmp = RREG32_PCIE(RADEON_PCIE_TX_GART_CNTL);
155 tmp |= RADEON_PCIE_TX_GART_UNMAPPED_ACCESS_DISCARD; 159 tmp |= RADEON_PCIE_TX_GART_UNMAPPED_ACCESS_DISCARD;
156 WREG32_PCIE(RADEON_PCIE_TX_GART_CNTL, tmp & ~RADEON_PCIE_TX_GART_EN); 160 WREG32_PCIE(RADEON_PCIE_TX_GART_CNTL, tmp & ~RADEON_PCIE_TX_GART_EN);
@@ -323,7 +327,6 @@ void r300_gpu_init(struct radeon_device *rdev)
323{ 327{
324 uint32_t gb_tile_config, tmp; 328 uint32_t gb_tile_config, tmp;
325 329
326 r100_hdp_reset(rdev);
327 /* FIXME: rv380 one pipes ? */ 330 /* FIXME: rv380 one pipes ? */
328 if ((rdev->family == CHIP_R300 && rdev->pdev->device != 0x4144) || 331 if ((rdev->family == CHIP_R300 && rdev->pdev->device != 0x4144) ||
329 (rdev->family == CHIP_R350)) { 332 (rdev->family == CHIP_R350)) {
@@ -376,57 +379,6 @@ void r300_gpu_init(struct radeon_device *rdev)
376 rdev->num_gb_pipes, rdev->num_z_pipes); 379 rdev->num_gb_pipes, rdev->num_z_pipes);
377} 380}
378 381
379int r300_ga_reset(struct radeon_device *rdev)
380{
381 uint32_t tmp;
382 bool reinit_cp;
383 int i;
384
385 reinit_cp = rdev->cp.ready;
386 rdev->cp.ready = false;
387 for (i = 0; i < rdev->usec_timeout; i++) {
388 WREG32(RADEON_CP_CSQ_MODE, 0);
389 WREG32(RADEON_CP_CSQ_CNTL, 0);
390 WREG32(RADEON_RBBM_SOFT_RESET, 0x32005);
391 (void)RREG32(RADEON_RBBM_SOFT_RESET);
392 udelay(200);
393 WREG32(RADEON_RBBM_SOFT_RESET, 0);
394 /* Wait to prevent race in RBBM_STATUS */
395 mdelay(1);
396 tmp = RREG32(RADEON_RBBM_STATUS);
397 if (tmp & ((1 << 20) | (1 << 26))) {
398 DRM_ERROR("VAP & CP still busy (RBBM_STATUS=0x%08X)", tmp);
399 /* GA still busy soft reset it */
400 WREG32(0x429C, 0x200);
401 WREG32(R300_VAP_PVS_STATE_FLUSH_REG, 0);
402 WREG32(R300_RE_SCISSORS_TL, 0);
403 WREG32(R300_RE_SCISSORS_BR, 0);
404 WREG32(0x24AC, 0);
405 }
406 /* Wait to prevent race in RBBM_STATUS */
407 mdelay(1);
408 tmp = RREG32(RADEON_RBBM_STATUS);
409 if (!(tmp & ((1 << 20) | (1 << 26)))) {
410 break;
411 }
412 }
413 for (i = 0; i < rdev->usec_timeout; i++) {
414 tmp = RREG32(RADEON_RBBM_STATUS);
415 if (!(tmp & ((1 << 20) | (1 << 26)))) {
416 DRM_INFO("GA reset succeed (RBBM_STATUS=0x%08X)\n",
417 tmp);
418 if (reinit_cp) {
419 return r100_cp_init(rdev, rdev->cp.ring_size);
420 }
421 return 0;
422 }
423 DRM_UDELAY(1);
424 }
425 tmp = RREG32(RADEON_RBBM_STATUS);
426 DRM_ERROR("Failed to reset GA ! (RBBM_STATUS=0x%08X)\n", tmp);
427 return -1;
428}
429
430bool r300_gpu_is_lockup(struct radeon_device *rdev) 382bool r300_gpu_is_lockup(struct radeon_device *rdev)
431{ 383{
432 u32 rbbm_status; 384 u32 rbbm_status;
@@ -451,37 +403,69 @@ bool r300_gpu_is_lockup(struct radeon_device *rdev)
451 403
452int r300_asic_reset(struct radeon_device *rdev) 404int r300_asic_reset(struct radeon_device *rdev)
453{ 405{
454 uint32_t status; 406 struct r100_mc_save save;
407 u32 status, tmp;
455 408
456 /* reset order likely matter */ 409 r100_mc_stop(rdev, &save);
457 status = RREG32(RADEON_RBBM_STATUS); 410 status = RREG32(R_000E40_RBBM_STATUS);
458 dev_info(rdev->dev, "(%s:%d) RBBM_STATUS=0x%08X\n", __func__, __LINE__, status); 411 if (!G_000E40_GUI_ACTIVE(status)) {
459 /* reset HDP */ 412 return 0;
460 r100_hdp_reset(rdev);
461 /* reset rb2d */
462 if (status & ((1 << 17) | (1 << 18) | (1 << 27))) {
463 r100_rb2d_reset(rdev);
464 }
465 /* reset GA */
466 if (status & ((1 << 20) | (1 << 26))) {
467 r300_ga_reset(rdev);
468 }
469 /* reset CP */
470 status = RREG32(RADEON_RBBM_STATUS);
471 if (status & (1 << 16)) {
472 r100_cp_reset(rdev);
473 } 413 }
414 status = RREG32(R_000E40_RBBM_STATUS);
415 dev_info(rdev->dev, "(%s:%d) RBBM_STATUS=0x%08X\n", __func__, __LINE__, status);
416 /* stop CP */
417 WREG32(RADEON_CP_CSQ_CNTL, 0);
418 tmp = RREG32(RADEON_CP_RB_CNTL);
419 WREG32(RADEON_CP_RB_CNTL, tmp | RADEON_RB_RPTR_WR_ENA);
420 WREG32(RADEON_CP_RB_RPTR_WR, 0);
421 WREG32(RADEON_CP_RB_WPTR, 0);
422 WREG32(RADEON_CP_RB_CNTL, tmp);
423 /* save PCI state */
424 pci_save_state(rdev->pdev);
425 /* disable bus mastering */
426 r100_bm_disable(rdev);
427 WREG32(R_0000F0_RBBM_SOFT_RESET, S_0000F0_SOFT_RESET_VAP(1) |
428 S_0000F0_SOFT_RESET_GA(1));
429 RREG32(R_0000F0_RBBM_SOFT_RESET);
430 mdelay(500);
431 WREG32(R_0000F0_RBBM_SOFT_RESET, 0);
432 mdelay(1);
433 status = RREG32(R_000E40_RBBM_STATUS);
434 dev_info(rdev->dev, "(%s:%d) RBBM_STATUS=0x%08X\n", __func__, __LINE__, status);
435 /* resetting the CP seems to be problematic sometimes it end up
436 * hard locking the computer, but it's necessary for successfull
437 * reset more test & playing is needed on R3XX/R4XX to find a
438 * reliable (if any solution)
439 */
440 WREG32(R_0000F0_RBBM_SOFT_RESET, S_0000F0_SOFT_RESET_CP(1));
441 RREG32(R_0000F0_RBBM_SOFT_RESET);
442 mdelay(500);
443 WREG32(R_0000F0_RBBM_SOFT_RESET, 0);
444 mdelay(1);
445 status = RREG32(R_000E40_RBBM_STATUS);
446 dev_info(rdev->dev, "(%s:%d) RBBM_STATUS=0x%08X\n", __func__, __LINE__, status);
447 /* reset MC */
448 WREG32(R_0000F0_RBBM_SOFT_RESET, S_0000F0_SOFT_RESET_MC(1));
449 RREG32(R_0000F0_RBBM_SOFT_RESET);
450 mdelay(500);
451 WREG32(R_0000F0_RBBM_SOFT_RESET, 0);
452 mdelay(1);
453 status = RREG32(R_000E40_RBBM_STATUS);
454 dev_info(rdev->dev, "(%s:%d) RBBM_STATUS=0x%08X\n", __func__, __LINE__, status);
455 /* restore PCI & busmastering */
456 pci_restore_state(rdev->pdev);
457 r100_enable_bm(rdev);
474 /* Check if GPU is idle */ 458 /* Check if GPU is idle */
475 status = RREG32(RADEON_RBBM_STATUS); 459 if (G_000E40_GA_BUSY(status) || G_000E40_VAP_BUSY(status)) {
476 if (status & RADEON_RBBM_ACTIVE) { 460 dev_err(rdev->dev, "failed to reset GPU\n");
477 DRM_ERROR("Failed to reset GPU (RBBM_STATUS=0x%08X)\n", status); 461 rdev->gpu_lockup = true;
478 return -1; 462 return -1;
479 } 463 }
480 DRM_INFO("GPU reset succeed (RBBM_STATUS=0x%08X)\n", status); 464 r100_mc_resume(rdev, &save);
465 dev_info(rdev->dev, "GPU reset succeed\n");
481 return 0; 466 return 0;
482} 467}
483 468
484
485/* 469/*
486 * r300,r350,rv350,rv380 VRAM info 470 * r300,r350,rv350,rv380 VRAM info
487 */ 471 */
diff --git a/drivers/gpu/drm/radeon/r300d.h b/drivers/gpu/drm/radeon/r300d.h
index 4c73114f0de9..968a33317fbf 100644
--- a/drivers/gpu/drm/radeon/r300d.h
+++ b/drivers/gpu/drm/radeon/r300d.h
@@ -209,7 +209,52 @@
209#define S_000E40_GUI_ACTIVE(x) (((x) & 0x1) << 31) 209#define S_000E40_GUI_ACTIVE(x) (((x) & 0x1) << 31)
210#define G_000E40_GUI_ACTIVE(x) (((x) >> 31) & 0x1) 210#define G_000E40_GUI_ACTIVE(x) (((x) >> 31) & 0x1)
211#define C_000E40_GUI_ACTIVE 0x7FFFFFFF 211#define C_000E40_GUI_ACTIVE 0x7FFFFFFF
212 212#define R_0000F0_RBBM_SOFT_RESET 0x0000F0
213#define S_0000F0_SOFT_RESET_CP(x) (((x) & 0x1) << 0)
214#define G_0000F0_SOFT_RESET_CP(x) (((x) >> 0) & 0x1)
215#define C_0000F0_SOFT_RESET_CP 0xFFFFFFFE
216#define S_0000F0_SOFT_RESET_HI(x) (((x) & 0x1) << 1)
217#define G_0000F0_SOFT_RESET_HI(x) (((x) >> 1) & 0x1)
218#define C_0000F0_SOFT_RESET_HI 0xFFFFFFFD
219#define S_0000F0_SOFT_RESET_VAP(x) (((x) & 0x1) << 2)
220#define G_0000F0_SOFT_RESET_VAP(x) (((x) >> 2) & 0x1)
221#define C_0000F0_SOFT_RESET_VAP 0xFFFFFFFB
222#define S_0000F0_SOFT_RESET_RE(x) (((x) & 0x1) << 3)
223#define G_0000F0_SOFT_RESET_RE(x) (((x) >> 3) & 0x1)
224#define C_0000F0_SOFT_RESET_RE 0xFFFFFFF7
225#define S_0000F0_SOFT_RESET_PP(x) (((x) & 0x1) << 4)
226#define G_0000F0_SOFT_RESET_PP(x) (((x) >> 4) & 0x1)
227#define C_0000F0_SOFT_RESET_PP 0xFFFFFFEF
228#define S_0000F0_SOFT_RESET_E2(x) (((x) & 0x1) << 5)
229#define G_0000F0_SOFT_RESET_E2(x) (((x) >> 5) & 0x1)
230#define C_0000F0_SOFT_RESET_E2 0xFFFFFFDF
231#define S_0000F0_SOFT_RESET_RB(x) (((x) & 0x1) << 6)
232#define G_0000F0_SOFT_RESET_RB(x) (((x) >> 6) & 0x1)
233#define C_0000F0_SOFT_RESET_RB 0xFFFFFFBF
234#define S_0000F0_SOFT_RESET_HDP(x) (((x) & 0x1) << 7)
235#define G_0000F0_SOFT_RESET_HDP(x) (((x) >> 7) & 0x1)
236#define C_0000F0_SOFT_RESET_HDP 0xFFFFFF7F
237#define S_0000F0_SOFT_RESET_MC(x) (((x) & 0x1) << 8)
238#define G_0000F0_SOFT_RESET_MC(x) (((x) >> 8) & 0x1)
239#define C_0000F0_SOFT_RESET_MC 0xFFFFFEFF
240#define S_0000F0_SOFT_RESET_AIC(x) (((x) & 0x1) << 9)
241#define G_0000F0_SOFT_RESET_AIC(x) (((x) >> 9) & 0x1)
242#define C_0000F0_SOFT_RESET_AIC 0xFFFFFDFF
243#define S_0000F0_SOFT_RESET_VIP(x) (((x) & 0x1) << 10)
244#define G_0000F0_SOFT_RESET_VIP(x) (((x) >> 10) & 0x1)
245#define C_0000F0_SOFT_RESET_VIP 0xFFFFFBFF
246#define S_0000F0_SOFT_RESET_DISP(x) (((x) & 0x1) << 11)
247#define G_0000F0_SOFT_RESET_DISP(x) (((x) >> 11) & 0x1)
248#define C_0000F0_SOFT_RESET_DISP 0xFFFFF7FF
249#define S_0000F0_SOFT_RESET_CG(x) (((x) & 0x1) << 12)
250#define G_0000F0_SOFT_RESET_CG(x) (((x) >> 12) & 0x1)
251#define C_0000F0_SOFT_RESET_CG 0xFFFFEFFF
252#define S_0000F0_SOFT_RESET_GA(x) (((x) & 0x1) << 13)
253#define G_0000F0_SOFT_RESET_GA(x) (((x) >> 13) & 0x1)
254#define C_0000F0_SOFT_RESET_GA 0xFFFFDFFF
255#define S_0000F0_SOFT_RESET_IDCT(x) (((x) & 0x1) << 14)
256#define G_0000F0_SOFT_RESET_IDCT(x) (((x) >> 14) & 0x1)
257#define C_0000F0_SOFT_RESET_IDCT 0xFFFFBFFF
213 258
214#define R_00000D_SCLK_CNTL 0x00000D 259#define R_00000D_SCLK_CNTL 0x00000D
215#define S_00000D_SCLK_SRC_SEL(x) (((x) & 0x7) << 0) 260#define S_00000D_SCLK_SRC_SEL(x) (((x) & 0x7) << 0)
diff --git a/drivers/gpu/drm/radeon/r520.c b/drivers/gpu/drm/radeon/r520.c
index 3ade473e69ba..870111e26bd1 100644
--- a/drivers/gpu/drm/radeon/r520.c
+++ b/drivers/gpu/drm/radeon/r520.c
@@ -53,7 +53,6 @@ static void r520_gpu_init(struct radeon_device *rdev)
53{ 53{
54 unsigned pipe_select_current, gb_pipe_select, tmp; 54 unsigned pipe_select_current, gb_pipe_select, tmp;
55 55
56 r100_hdp_reset(rdev);
57 rv515_vga_render_disable(rdev); 56 rv515_vga_render_disable(rdev);
58 /* 57 /*
59 * DST_PIPE_CONFIG 0x170C 58 * DST_PIPE_CONFIG 0x170C
diff --git a/drivers/gpu/drm/radeon/r600.c b/drivers/gpu/drm/radeon/r600.c
index 24fd5459fb42..13c9cc34231d 100644
--- a/drivers/gpu/drm/radeon/r600.c
+++ b/drivers/gpu/drm/radeon/r600.c
@@ -749,7 +749,6 @@ int r600_gpu_soft_reset(struct radeon_device *rdev)
749 S_008014_DB2_BUSY(1) | S_008014_DB3_BUSY(1) | 749 S_008014_DB2_BUSY(1) | S_008014_DB3_BUSY(1) |
750 S_008014_CB0_BUSY(1) | S_008014_CB1_BUSY(1) | 750 S_008014_CB0_BUSY(1) | S_008014_CB1_BUSY(1) |
751 S_008014_CB2_BUSY(1) | S_008014_CB3_BUSY(1); 751 S_008014_CB2_BUSY(1) | S_008014_CB3_BUSY(1);
752 u32 srbm_reset = 0;
753 u32 tmp; 752 u32 tmp;
754 753
755 dev_info(rdev->dev, "GPU softreset \n"); 754 dev_info(rdev->dev, "GPU softreset \n");
@@ -764,7 +763,7 @@ int r600_gpu_soft_reset(struct radeon_device *rdev)
764 dev_warn(rdev->dev, "Wait for MC idle timedout !\n"); 763 dev_warn(rdev->dev, "Wait for MC idle timedout !\n");
765 } 764 }
766 /* Disable CP parsing/prefetching */ 765 /* Disable CP parsing/prefetching */
767 WREG32(R_0086D8_CP_ME_CNTL, S_0086D8_CP_ME_HALT(0xff)); 766 WREG32(R_0086D8_CP_ME_CNTL, S_0086D8_CP_ME_HALT(1));
768 /* Check if any of the rendering block is busy and reset it */ 767 /* Check if any of the rendering block is busy and reset it */
769 if ((RREG32(R_008010_GRBM_STATUS) & grbm_busy_mask) || 768 if ((RREG32(R_008010_GRBM_STATUS) & grbm_busy_mask) ||
770 (RREG32(R_008014_GRBM_STATUS2) & grbm2_busy_mask)) { 769 (RREG32(R_008014_GRBM_STATUS2) & grbm2_busy_mask)) {
@@ -783,55 +782,17 @@ int r600_gpu_soft_reset(struct radeon_device *rdev)
783 S_008020_SOFT_RESET_VGT(1); 782 S_008020_SOFT_RESET_VGT(1);
784 dev_info(rdev->dev, " R_008020_GRBM_SOFT_RESET=0x%08X\n", tmp); 783 dev_info(rdev->dev, " R_008020_GRBM_SOFT_RESET=0x%08X\n", tmp);
785 WREG32(R_008020_GRBM_SOFT_RESET, tmp); 784 WREG32(R_008020_GRBM_SOFT_RESET, tmp);
786 (void)RREG32(R_008020_GRBM_SOFT_RESET); 785 RREG32(R_008020_GRBM_SOFT_RESET);
787 mdelay(1); 786 mdelay(15);
788 WREG32(R_008020_GRBM_SOFT_RESET, 0); 787 WREG32(R_008020_GRBM_SOFT_RESET, 0);
789 (void)RREG32(R_008020_GRBM_SOFT_RESET);
790 } 788 }
791 /* Reset CP (we always reset CP) */ 789 /* Reset CP (we always reset CP) */
792 tmp = S_008020_SOFT_RESET_CP(1); 790 tmp = S_008020_SOFT_RESET_CP(1);
793 dev_info(rdev->dev, "R_008020_GRBM_SOFT_RESET=0x%08X\n", tmp); 791 dev_info(rdev->dev, "R_008020_GRBM_SOFT_RESET=0x%08X\n", tmp);
794 WREG32(R_008020_GRBM_SOFT_RESET, tmp); 792 WREG32(R_008020_GRBM_SOFT_RESET, tmp);
795 (void)RREG32(R_008020_GRBM_SOFT_RESET); 793 RREG32(R_008020_GRBM_SOFT_RESET);
796 udelay(50); 794 mdelay(15);
797 WREG32(R_008020_GRBM_SOFT_RESET, 0); 795 WREG32(R_008020_GRBM_SOFT_RESET, 0);
798 (void)RREG32(R_008020_GRBM_SOFT_RESET);
799 /* Reset others GPU block if necessary */
800 if (G_000E50_RLC_BUSY(RREG32(R_000E50_SRBM_STATUS)))
801 srbm_reset |= S_000E60_SOFT_RESET_RLC(1);
802 if (G_000E50_GRBM_RQ_PENDING(RREG32(R_000E50_SRBM_STATUS)))
803 srbm_reset |= S_000E60_SOFT_RESET_GRBM(1);
804 if (G_000E50_HI_RQ_PENDING(RREG32(R_000E50_SRBM_STATUS)))
805 srbm_reset |= S_000E60_SOFT_RESET_IH(1);
806 if (G_000E50_VMC_BUSY(RREG32(R_000E50_SRBM_STATUS)))
807 srbm_reset |= S_000E60_SOFT_RESET_VMC(1);
808 if (G_000E50_MCB_BUSY(RREG32(R_000E50_SRBM_STATUS)))
809 srbm_reset |= S_000E60_SOFT_RESET_MC(1);
810 if (G_000E50_MCDZ_BUSY(RREG32(R_000E50_SRBM_STATUS)))
811 srbm_reset |= S_000E60_SOFT_RESET_MC(1);
812 if (G_000E50_MCDY_BUSY(RREG32(R_000E50_SRBM_STATUS)))
813 srbm_reset |= S_000E60_SOFT_RESET_MC(1);
814 if (G_000E50_MCDX_BUSY(RREG32(R_000E50_SRBM_STATUS)))
815 srbm_reset |= S_000E60_SOFT_RESET_MC(1);
816 if (G_000E50_MCDW_BUSY(RREG32(R_000E50_SRBM_STATUS)))
817 srbm_reset |= S_000E60_SOFT_RESET_MC(1);
818 if (G_000E50_RLC_BUSY(RREG32(R_000E50_SRBM_STATUS)))
819 srbm_reset |= S_000E60_SOFT_RESET_RLC(1);
820 if (G_000E50_SEM_BUSY(RREG32(R_000E50_SRBM_STATUS)))
821 srbm_reset |= S_000E60_SOFT_RESET_SEM(1);
822 if (G_000E50_BIF_BUSY(RREG32(R_000E50_SRBM_STATUS)))
823 srbm_reset |= S_000E60_SOFT_RESET_BIF(1);
824 dev_info(rdev->dev, " R_000E60_SRBM_SOFT_RESET=0x%08X\n", srbm_reset);
825 WREG32(R_000E60_SRBM_SOFT_RESET, srbm_reset);
826 (void)RREG32(R_000E60_SRBM_SOFT_RESET);
827 mdelay(1);
828 WREG32(R_000E60_SRBM_SOFT_RESET, 0);
829 (void)RREG32(R_000E60_SRBM_SOFT_RESET);
830 WREG32(R_000E60_SRBM_SOFT_RESET, srbm_reset);
831 (void)RREG32(R_000E60_SRBM_SOFT_RESET);
832 mdelay(1);
833 WREG32(R_000E60_SRBM_SOFT_RESET, 0);
834 (void)RREG32(R_000E60_SRBM_SOFT_RESET);
835 /* Wait a little for things to settle down */ 796 /* Wait a little for things to settle down */
836 mdelay(1); 797 mdelay(1);
837 dev_info(rdev->dev, " R_008010_GRBM_STATUS=0x%08X\n", 798 dev_info(rdev->dev, " R_008010_GRBM_STATUS=0x%08X\n",
@@ -840,10 +801,6 @@ int r600_gpu_soft_reset(struct radeon_device *rdev)
840 RREG32(R_008014_GRBM_STATUS2)); 801 RREG32(R_008014_GRBM_STATUS2));
841 dev_info(rdev->dev, " R_000E50_SRBM_STATUS=0x%08X\n", 802 dev_info(rdev->dev, " R_000E50_SRBM_STATUS=0x%08X\n",
842 RREG32(R_000E50_SRBM_STATUS)); 803 RREG32(R_000E50_SRBM_STATUS));
843 /* After reset we need to reinit the asic as GPU often endup in an
844 * incoherent state.
845 */
846 atom_asic_init(rdev->mode_info.atom_context);
847 rv515_mc_resume(rdev, &save); 804 rv515_mc_resume(rdev, &save);
848 return 0; 805 return 0;
849} 806}
diff --git a/drivers/gpu/drm/radeon/r600_blit_kms.c b/drivers/gpu/drm/radeon/r600_blit_kms.c
index f6c6c77db7e0..d13622ae74e9 100644
--- a/drivers/gpu/drm/radeon/r600_blit_kms.c
+++ b/drivers/gpu/drm/radeon/r600_blit_kms.c
@@ -447,6 +447,9 @@ int r600_blit_init(struct radeon_device *rdev)
447 u32 packet2s[16]; 447 u32 packet2s[16];
448 int num_packet2s = 0; 448 int num_packet2s = 0;
449 449
450 /* don't reinitialize blit */
451 if (rdev->r600_blit.shader_obj)
452 return 0;
450 mutex_init(&rdev->r600_blit.mutex); 453 mutex_init(&rdev->r600_blit.mutex);
451 rdev->r600_blit.state_offset = 0; 454 rdev->r600_blit.state_offset = 0;
452 455
diff --git a/drivers/gpu/drm/radeon/radeon.h b/drivers/gpu/drm/radeon/radeon.h
index 3cc5820b0e1b..4ac97ab28947 100644
--- a/drivers/gpu/drm/radeon/radeon.h
+++ b/drivers/gpu/drm/radeon/radeon.h
@@ -1188,6 +1188,7 @@ static inline void radeon_ring_write(struct radeon_device *rdev, uint32_t v)
1188 1188
1189/* Common functions */ 1189/* Common functions */
1190/* AGP */ 1190/* AGP */
1191extern int radeon_gpu_reset(struct radeon_device *rdev);
1191extern void radeon_agp_disable(struct radeon_device *rdev); 1192extern void radeon_agp_disable(struct radeon_device *rdev);
1192extern int radeon_gart_table_vram_pin(struct radeon_device *rdev); 1193extern int radeon_gart_table_vram_pin(struct radeon_device *rdev);
1193extern void radeon_gart_restore(struct radeon_device *rdev); 1194extern void radeon_gart_restore(struct radeon_device *rdev);
diff --git a/drivers/gpu/drm/radeon/radeon_asic.c b/drivers/gpu/drm/radeon/radeon_asic.c
index 011ac6d86581..0d7664b8e489 100644
--- a/drivers/gpu/drm/radeon/radeon_asic.c
+++ b/drivers/gpu/drm/radeon/radeon_asic.c
@@ -367,7 +367,7 @@ static struct radeon_asic rs600_asic = {
367 .resume = &rs600_resume, 367 .resume = &rs600_resume,
368 .vga_set_state = &r100_vga_set_state, 368 .vga_set_state = &r100_vga_set_state,
369 .gpu_is_lockup = &r300_gpu_is_lockup, 369 .gpu_is_lockup = &r300_gpu_is_lockup,
370 .asic_reset = &r300_asic_reset, 370 .asic_reset = &rs600_asic_reset,
371 .gart_tlb_flush = &rs600_gart_tlb_flush, 371 .gart_tlb_flush = &rs600_gart_tlb_flush,
372 .gart_set_page = &rs600_gart_set_page, 372 .gart_set_page = &rs600_gart_set_page,
373 .cp_commit = &r100_cp_commit, 373 .cp_commit = &r100_cp_commit,
@@ -406,7 +406,7 @@ static struct radeon_asic rs690_asic = {
406 .resume = &rs690_resume, 406 .resume = &rs690_resume,
407 .vga_set_state = &r100_vga_set_state, 407 .vga_set_state = &r100_vga_set_state,
408 .gpu_is_lockup = &r300_gpu_is_lockup, 408 .gpu_is_lockup = &r300_gpu_is_lockup,
409 .asic_reset = &r300_asic_reset, 409 .asic_reset = &rs600_asic_reset,
410 .gart_tlb_flush = &rs400_gart_tlb_flush, 410 .gart_tlb_flush = &rs400_gart_tlb_flush,
411 .gart_set_page = &rs400_gart_set_page, 411 .gart_set_page = &rs400_gart_set_page,
412 .cp_commit = &r100_cp_commit, 412 .cp_commit = &r100_cp_commit,
@@ -445,7 +445,7 @@ static struct radeon_asic rv515_asic = {
445 .resume = &rv515_resume, 445 .resume = &rv515_resume,
446 .vga_set_state = &r100_vga_set_state, 446 .vga_set_state = &r100_vga_set_state,
447 .gpu_is_lockup = &r300_gpu_is_lockup, 447 .gpu_is_lockup = &r300_gpu_is_lockup,
448 .asic_reset = &rv515_asic_reset, 448 .asic_reset = &rs600_asic_reset,
449 .gart_tlb_flush = &rv370_pcie_gart_tlb_flush, 449 .gart_tlb_flush = &rv370_pcie_gart_tlb_flush,
450 .gart_set_page = &rv370_pcie_gart_set_page, 450 .gart_set_page = &rv370_pcie_gart_set_page,
451 .cp_commit = &r100_cp_commit, 451 .cp_commit = &r100_cp_commit,
@@ -484,7 +484,7 @@ static struct radeon_asic r520_asic = {
484 .resume = &r520_resume, 484 .resume = &r520_resume,
485 .vga_set_state = &r100_vga_set_state, 485 .vga_set_state = &r100_vga_set_state,
486 .gpu_is_lockup = &r300_gpu_is_lockup, 486 .gpu_is_lockup = &r300_gpu_is_lockup,
487 .asic_reset = &rv515_asic_reset, 487 .asic_reset = &rs600_asic_reset,
488 .gart_tlb_flush = &rv370_pcie_gart_tlb_flush, 488 .gart_tlb_flush = &rv370_pcie_gart_tlb_flush,
489 .gart_set_page = &rv370_pcie_gart_set_page, 489 .gart_set_page = &rv370_pcie_gart_set_page,
490 .cp_commit = &r100_cp_commit, 490 .cp_commit = &r100_cp_commit,
@@ -560,6 +560,7 @@ static struct radeon_asic rs780_asic = {
560 .suspend = &r600_suspend, 560 .suspend = &r600_suspend,
561 .resume = &r600_resume, 561 .resume = &r600_resume,
562 .cp_commit = &r600_cp_commit, 562 .cp_commit = &r600_cp_commit,
563 .gpu_is_lockup = &r600_gpu_is_lockup,
563 .vga_set_state = &r600_vga_set_state, 564 .vga_set_state = &r600_vga_set_state,
564 .asic_reset = &r600_asic_reset, 565 .asic_reset = &r600_asic_reset,
565 .gart_tlb_flush = &r600_pcie_gart_tlb_flush, 566 .gart_tlb_flush = &r600_pcie_gart_tlb_flush,
diff --git a/drivers/gpu/drm/radeon/radeon_asic.h b/drivers/gpu/drm/radeon/radeon_asic.h
index 53ebcacbd0e0..77d48ba4a29a 100644
--- a/drivers/gpu/drm/radeon/radeon_asic.h
+++ b/drivers/gpu/drm/radeon/radeon_asic.h
@@ -111,8 +111,6 @@ void r100_vram_init_sizes(struct radeon_device *rdev);
111void r100_wb_disable(struct radeon_device *rdev); 111void r100_wb_disable(struct radeon_device *rdev);
112void r100_wb_fini(struct radeon_device *rdev); 112void r100_wb_fini(struct radeon_device *rdev);
113int r100_wb_init(struct radeon_device *rdev); 113int r100_wb_init(struct radeon_device *rdev);
114void r100_hdp_reset(struct radeon_device *rdev);
115int r100_rb2d_reset(struct radeon_device *rdev);
116int r100_cp_reset(struct radeon_device *rdev); 114int r100_cp_reset(struct radeon_device *rdev);
117void r100_vga_render_disable(struct radeon_device *rdev); 115void r100_vga_render_disable(struct radeon_device *rdev);
118int r100_cs_track_check_pkt3_indx_buffer(struct radeon_cs_parser *p, 116int r100_cs_track_check_pkt3_indx_buffer(struct radeon_cs_parser *p,
@@ -127,7 +125,7 @@ int r100_cs_packet_parse(struct radeon_cs_parser *p,
127 unsigned idx); 125 unsigned idx);
128void r100_enable_bm(struct radeon_device *rdev); 126void r100_enable_bm(struct radeon_device *rdev);
129void r100_set_common_regs(struct radeon_device *rdev); 127void r100_set_common_regs(struct radeon_device *rdev);
130 128void r100_bm_disable(struct radeon_device *rdev);
131/* 129/*
132 * r200,rv250,rs300,rv280 130 * r200,rv250,rs300,rv280
133 */ 131 */
@@ -180,6 +178,7 @@ void rs400_mc_wreg(struct radeon_device *rdev, uint32_t reg, uint32_t v);
180/* 178/*
181 * rs600. 179 * rs600.
182 */ 180 */
181extern int rs600_asic_reset(struct radeon_device *rdev);
183extern int rs600_init(struct radeon_device *rdev); 182extern int rs600_init(struct radeon_device *rdev);
184extern void rs600_fini(struct radeon_device *rdev); 183extern void rs600_fini(struct radeon_device *rdev);
185extern int rs600_suspend(struct radeon_device *rdev); 184extern int rs600_suspend(struct radeon_device *rdev);
@@ -214,7 +213,6 @@ void rs690_bandwidth_update(struct radeon_device *rdev);
214 */ 213 */
215int rv515_init(struct radeon_device *rdev); 214int rv515_init(struct radeon_device *rdev);
216void rv515_fini(struct radeon_device *rdev); 215void rv515_fini(struct radeon_device *rdev);
217int rv515_asic_reset(struct radeon_device *rdev);
218uint32_t rv515_mc_rreg(struct radeon_device *rdev, uint32_t reg); 216uint32_t rv515_mc_rreg(struct radeon_device *rdev, uint32_t reg);
219void rv515_mc_wreg(struct radeon_device *rdev, uint32_t reg, uint32_t v); 217void rv515_mc_wreg(struct radeon_device *rdev, uint32_t reg, uint32_t v);
220void rv515_ring_start(struct radeon_device *rdev); 218void rv515_ring_start(struct radeon_device *rdev);
diff --git a/drivers/gpu/drm/radeon/radeon_cs.c b/drivers/gpu/drm/radeon/radeon_cs.c
index f9b0fe002c0a..ae0fb7356e62 100644
--- a/drivers/gpu/drm/radeon/radeon_cs.c
+++ b/drivers/gpu/drm/radeon/radeon_cs.c
@@ -220,10 +220,6 @@ int radeon_cs_ioctl(struct drm_device *dev, void *data, struct drm_file *filp)
220 int r; 220 int r;
221 221
222 mutex_lock(&rdev->cs_mutex); 222 mutex_lock(&rdev->cs_mutex);
223 if (rdev->gpu_lockup) {
224 mutex_unlock(&rdev->cs_mutex);
225 return -EINVAL;
226 }
227 /* initialize parser */ 223 /* initialize parser */
228 memset(&parser, 0, sizeof(struct radeon_cs_parser)); 224 memset(&parser, 0, sizeof(struct radeon_cs_parser));
229 parser.filp = filp; 225 parser.filp = filp;
diff --git a/drivers/gpu/drm/radeon/radeon_device.c b/drivers/gpu/drm/radeon/radeon_device.c
index 232a30768499..d4ff5a6d3496 100644
--- a/drivers/gpu/drm/radeon/radeon_device.c
+++ b/drivers/gpu/drm/radeon/radeon_device.c
@@ -639,6 +639,8 @@ void radeon_device_fini(struct radeon_device *rdev)
639{ 639{
640 DRM_INFO("radeon: finishing device.\n"); 640 DRM_INFO("radeon: finishing device.\n");
641 rdev->shutdown = true; 641 rdev->shutdown = true;
642 /* evict vram memory */
643 radeon_bo_evict_vram(rdev);
642 radeon_fini(rdev); 644 radeon_fini(rdev);
643 destroy_workqueue(rdev->wq); 645 destroy_workqueue(rdev->wq);
644 vga_switcheroo_unregister_client(rdev->pdev); 646 vga_switcheroo_unregister_client(rdev->pdev);
@@ -737,6 +739,26 @@ int radeon_resume_kms(struct drm_device *dev)
737 return 0; 739 return 0;
738} 740}
739 741
742int radeon_gpu_reset(struct radeon_device *rdev)
743{
744 int r;
745
746 radeon_save_bios_scratch_regs(rdev);
747 radeon_suspend(rdev);
748
749 r = radeon_asic_reset(rdev);
750 if (!r) {
751 dev_info(rdev->dev, "GPU reset succeed\n");
752 radeon_resume(rdev);
753 radeon_restore_bios_scratch_regs(rdev);
754 drm_helper_resume_force_mode(rdev->ddev);
755 return 0;
756 }
757 /* bad news, how to tell it to userspace ? */
758 dev_info(rdev->dev, "GPU reset failed\n");
759 return r;
760}
761
740 762
741/* 763/*
742 * Debugfs 764 * Debugfs
diff --git a/drivers/gpu/drm/radeon/radeon_fence.c b/drivers/gpu/drm/radeon/radeon_fence.c
index 2560740ff922..fcd7802d8a71 100644
--- a/drivers/gpu/drm/radeon/radeon_fence.c
+++ b/drivers/gpu/drm/radeon/radeon_fence.c
@@ -209,8 +209,9 @@ retry:
209 r = wait_event_interruptible_timeout(rdev->fence_drv.queue, 209 r = wait_event_interruptible_timeout(rdev->fence_drv.queue,
210 radeon_fence_signaled(fence), timeout); 210 radeon_fence_signaled(fence), timeout);
211 radeon_irq_kms_sw_irq_put(rdev); 211 radeon_irq_kms_sw_irq_put(rdev);
212 if (unlikely(r < 0)) 212 if (unlikely(r < 0)) {
213 return r; 213 return r;
214 }
214 } else { 215 } else {
215 radeon_irq_kms_sw_irq_get(rdev); 216 radeon_irq_kms_sw_irq_get(rdev);
216 r = wait_event_timeout(rdev->fence_drv.queue, 217 r = wait_event_timeout(rdev->fence_drv.queue,
@@ -230,14 +231,16 @@ retry:
230 */ 231 */
231 if (seq == rdev->fence_drv.last_seq && radeon_gpu_is_lockup(rdev)) { 232 if (seq == rdev->fence_drv.last_seq && radeon_gpu_is_lockup(rdev)) {
232 /* good news we believe it's a lockup */ 233 /* good news we believe it's a lockup */
233 dev_warn(rdev->dev, "GPU lockup (last fence id 0x%08X)\n", seq); 234 WARN(1, "GPU lockup (waiting for 0x%08X last fence id 0x%08X)\n", fence->seq, seq);
234 r = radeon_asic_reset(rdev);
235 if (r)
236 return r;
237 /* FIXME: what should we do ? marking everyone 235 /* FIXME: what should we do ? marking everyone
238 * as signaled for now 236 * as signaled for now
239 */ 237 */
238 rdev->gpu_lockup = true;
240 WREG32(rdev->fence_drv.scratch_reg, fence->seq); 239 WREG32(rdev->fence_drv.scratch_reg, fence->seq);
240 r = radeon_gpu_reset(rdev);
241 if (r)
242 return r;
243 rdev->gpu_lockup = false;
241 } 244 }
242 timeout = RADEON_FENCE_JIFFIES_TIMEOUT; 245 timeout = RADEON_FENCE_JIFFIES_TIMEOUT;
243 write_lock_irqsave(&rdev->fence_drv.lock, irq_flags); 246 write_lock_irqsave(&rdev->fence_drv.lock, irq_flags);
diff --git a/drivers/gpu/drm/radeon/radeon_gart.c b/drivers/gpu/drm/radeon/radeon_gart.c
index 1770d3c07fd0..e65b90317fab 100644
--- a/drivers/gpu/drm/radeon/radeon_gart.c
+++ b/drivers/gpu/drm/radeon/radeon_gart.c
@@ -173,7 +173,7 @@ int radeon_gart_bind(struct radeon_device *rdev, unsigned offset,
173 int i, j; 173 int i, j;
174 174
175 if (!rdev->gart.ready) { 175 if (!rdev->gart.ready) {
176 DRM_ERROR("trying to bind memory to unitialized GART !\n"); 176 WARN(1, "trying to bind memory to unitialized GART !\n");
177 return -EINVAL; 177 return -EINVAL;
178 } 178 }
179 t = offset / RADEON_GPU_PAGE_SIZE; 179 t = offset / RADEON_GPU_PAGE_SIZE;
diff --git a/drivers/gpu/drm/radeon/rs400.c b/drivers/gpu/drm/radeon/rs400.c
index 3deec2185083..9420c20dc142 100644
--- a/drivers/gpu/drm/radeon/rs400.c
+++ b/drivers/gpu/drm/radeon/rs400.c
@@ -242,8 +242,6 @@ int rs400_mc_wait_for_idle(struct radeon_device *rdev)
242 242
243void rs400_gpu_init(struct radeon_device *rdev) 243void rs400_gpu_init(struct radeon_device *rdev)
244{ 244{
245 /* FIXME: HDP same place on rs400 ? */
246 r100_hdp_reset(rdev);
247 /* FIXME: is this correct ? */ 245 /* FIXME: is this correct ? */
248 r420_pipes_init(rdev); 246 r420_pipes_init(rdev);
249 if (rs400_mc_wait_for_idle(rdev)) { 247 if (rs400_mc_wait_for_idle(rdev)) {
diff --git a/drivers/gpu/drm/radeon/rs600.c b/drivers/gpu/drm/radeon/rs600.c
index c1be20afd429..a16d9d79f36f 100644
--- a/drivers/gpu/drm/radeon/rs600.c
+++ b/drivers/gpu/drm/radeon/rs600.c
@@ -147,6 +147,78 @@ void rs600_hpd_fini(struct radeon_device *rdev)
147 } 147 }
148} 148}
149 149
150void rs600_bm_disable(struct radeon_device *rdev)
151{
152 u32 tmp;
153
154 /* disable bus mastering */
155 pci_read_config_word(rdev->pdev, 0x4, (u16*)&tmp);
156 pci_write_config_word(rdev->pdev, 0x4, tmp & 0xFFFB);
157 mdelay(1);
158}
159
160int rs600_asic_reset(struct radeon_device *rdev)
161{
162 u32 status, tmp;
163
164 struct rv515_mc_save save;
165
166 /* Stops all mc clients */
167 rv515_mc_stop(rdev, &save);
168 status = RREG32(R_000E40_RBBM_STATUS);
169 if (!G_000E40_GUI_ACTIVE(status)) {
170 return 0;
171 }
172 status = RREG32(R_000E40_RBBM_STATUS);
173 dev_info(rdev->dev, "(%s:%d) RBBM_STATUS=0x%08X\n", __func__, __LINE__, status);
174 /* stop CP */
175 WREG32(RADEON_CP_CSQ_CNTL, 0);
176 tmp = RREG32(RADEON_CP_RB_CNTL);
177 WREG32(RADEON_CP_RB_CNTL, tmp | RADEON_RB_RPTR_WR_ENA);
178 WREG32(RADEON_CP_RB_RPTR_WR, 0);
179 WREG32(RADEON_CP_RB_WPTR, 0);
180 WREG32(RADEON_CP_RB_CNTL, tmp);
181 pci_save_state(rdev->pdev);
182 /* disable bus mastering */
183 rs600_bm_disable(rdev);
184 /* reset GA+VAP */
185 WREG32(R_0000F0_RBBM_SOFT_RESET, S_0000F0_SOFT_RESET_VAP(1) |
186 S_0000F0_SOFT_RESET_GA(1));
187 RREG32(R_0000F0_RBBM_SOFT_RESET);
188 mdelay(500);
189 WREG32(R_0000F0_RBBM_SOFT_RESET, 0);
190 mdelay(1);
191 status = RREG32(R_000E40_RBBM_STATUS);
192 dev_info(rdev->dev, "(%s:%d) RBBM_STATUS=0x%08X\n", __func__, __LINE__, status);
193 /* reset CP */
194 WREG32(R_0000F0_RBBM_SOFT_RESET, S_0000F0_SOFT_RESET_CP(1));
195 RREG32(R_0000F0_RBBM_SOFT_RESET);
196 mdelay(500);
197 WREG32(R_0000F0_RBBM_SOFT_RESET, 0);
198 mdelay(1);
199 status = RREG32(R_000E40_RBBM_STATUS);
200 dev_info(rdev->dev, "(%s:%d) RBBM_STATUS=0x%08X\n", __func__, __LINE__, status);
201 /* reset MC */
202 WREG32(R_0000F0_RBBM_SOFT_RESET, S_0000F0_SOFT_RESET_MC(1));
203 RREG32(R_0000F0_RBBM_SOFT_RESET);
204 mdelay(500);
205 WREG32(R_0000F0_RBBM_SOFT_RESET, 0);
206 mdelay(1);
207 status = RREG32(R_000E40_RBBM_STATUS);
208 dev_info(rdev->dev, "(%s:%d) RBBM_STATUS=0x%08X\n", __func__, __LINE__, status);
209 /* restore PCI & busmastering */
210 pci_restore_state(rdev->pdev);
211 /* Check if GPU is idle */
212 if (G_000E40_GA_BUSY(status) || G_000E40_VAP_BUSY(status)) {
213 dev_err(rdev->dev, "failed to reset GPU\n");
214 rdev->gpu_lockup = true;
215 return -1;
216 }
217 rv515_mc_resume(rdev, &save);
218 dev_info(rdev->dev, "GPU reset succeed\n");
219 return 0;
220}
221
150/* 222/*
151 * GART. 223 * GART.
152 */ 224 */
@@ -454,7 +526,6 @@ int rs600_mc_wait_for_idle(struct radeon_device *rdev)
454 526
455void rs600_gpu_init(struct radeon_device *rdev) 527void rs600_gpu_init(struct radeon_device *rdev)
456{ 528{
457 r100_hdp_reset(rdev);
458 r420_pipes_init(rdev); 529 r420_pipes_init(rdev);
459 /* Wait for mc idle */ 530 /* Wait for mc idle */
460 if (rs600_mc_wait_for_idle(rdev)) 531 if (rs600_mc_wait_for_idle(rdev))
diff --git a/drivers/gpu/drm/radeon/rs600d.h b/drivers/gpu/drm/radeon/rs600d.h
index e52d2695510b..08c4bebd3011 100644
--- a/drivers/gpu/drm/radeon/rs600d.h
+++ b/drivers/gpu/drm/radeon/rs600d.h
@@ -178,6 +178,52 @@
178#define S_000074_MC_IND_DATA(x) (((x) & 0xFFFFFFFF) << 0) 178#define S_000074_MC_IND_DATA(x) (((x) & 0xFFFFFFFF) << 0)
179#define G_000074_MC_IND_DATA(x) (((x) >> 0) & 0xFFFFFFFF) 179#define G_000074_MC_IND_DATA(x) (((x) >> 0) & 0xFFFFFFFF)
180#define C_000074_MC_IND_DATA 0x00000000 180#define C_000074_MC_IND_DATA 0x00000000
181#define R_0000F0_RBBM_SOFT_RESET 0x0000F0
182#define S_0000F0_SOFT_RESET_CP(x) (((x) & 0x1) << 0)
183#define G_0000F0_SOFT_RESET_CP(x) (((x) >> 0) & 0x1)
184#define C_0000F0_SOFT_RESET_CP 0xFFFFFFFE
185#define S_0000F0_SOFT_RESET_HI(x) (((x) & 0x1) << 1)
186#define G_0000F0_SOFT_RESET_HI(x) (((x) >> 1) & 0x1)
187#define C_0000F0_SOFT_RESET_HI 0xFFFFFFFD
188#define S_0000F0_SOFT_RESET_VAP(x) (((x) & 0x1) << 2)
189#define G_0000F0_SOFT_RESET_VAP(x) (((x) >> 2) & 0x1)
190#define C_0000F0_SOFT_RESET_VAP 0xFFFFFFFB
191#define S_0000F0_SOFT_RESET_RE(x) (((x) & 0x1) << 3)
192#define G_0000F0_SOFT_RESET_RE(x) (((x) >> 3) & 0x1)
193#define C_0000F0_SOFT_RESET_RE 0xFFFFFFF7
194#define S_0000F0_SOFT_RESET_PP(x) (((x) & 0x1) << 4)
195#define G_0000F0_SOFT_RESET_PP(x) (((x) >> 4) & 0x1)
196#define C_0000F0_SOFT_RESET_PP 0xFFFFFFEF
197#define S_0000F0_SOFT_RESET_E2(x) (((x) & 0x1) << 5)
198#define G_0000F0_SOFT_RESET_E2(x) (((x) >> 5) & 0x1)
199#define C_0000F0_SOFT_RESET_E2 0xFFFFFFDF
200#define S_0000F0_SOFT_RESET_RB(x) (((x) & 0x1) << 6)
201#define G_0000F0_SOFT_RESET_RB(x) (((x) >> 6) & 0x1)
202#define C_0000F0_SOFT_RESET_RB 0xFFFFFFBF
203#define S_0000F0_SOFT_RESET_HDP(x) (((x) & 0x1) << 7)
204#define G_0000F0_SOFT_RESET_HDP(x) (((x) >> 7) & 0x1)
205#define C_0000F0_SOFT_RESET_HDP 0xFFFFFF7F
206#define S_0000F0_SOFT_RESET_MC(x) (((x) & 0x1) << 8)
207#define G_0000F0_SOFT_RESET_MC(x) (((x) >> 8) & 0x1)
208#define C_0000F0_SOFT_RESET_MC 0xFFFFFEFF
209#define S_0000F0_SOFT_RESET_AIC(x) (((x) & 0x1) << 9)
210#define G_0000F0_SOFT_RESET_AIC(x) (((x) >> 9) & 0x1)
211#define C_0000F0_SOFT_RESET_AIC 0xFFFFFDFF
212#define S_0000F0_SOFT_RESET_VIP(x) (((x) & 0x1) << 10)
213#define G_0000F0_SOFT_RESET_VIP(x) (((x) >> 10) & 0x1)
214#define C_0000F0_SOFT_RESET_VIP 0xFFFFFBFF
215#define S_0000F0_SOFT_RESET_DISP(x) (((x) & 0x1) << 11)
216#define G_0000F0_SOFT_RESET_DISP(x) (((x) >> 11) & 0x1)
217#define C_0000F0_SOFT_RESET_DISP 0xFFFFF7FF
218#define S_0000F0_SOFT_RESET_CG(x) (((x) & 0x1) << 12)
219#define G_0000F0_SOFT_RESET_CG(x) (((x) >> 12) & 0x1)
220#define C_0000F0_SOFT_RESET_CG 0xFFFFEFFF
221#define S_0000F0_SOFT_RESET_GA(x) (((x) & 0x1) << 13)
222#define G_0000F0_SOFT_RESET_GA(x) (((x) >> 13) & 0x1)
223#define C_0000F0_SOFT_RESET_GA 0xFFFFDFFF
224#define S_0000F0_SOFT_RESET_IDCT(x) (((x) & 0x1) << 14)
225#define G_0000F0_SOFT_RESET_IDCT(x) (((x) >> 14) & 0x1)
226#define C_0000F0_SOFT_RESET_IDCT 0xFFFFBFFF
181#define R_000134_HDP_FB_LOCATION 0x000134 227#define R_000134_HDP_FB_LOCATION 0x000134
182#define S_000134_HDP_FB_START(x) (((x) & 0xFFFF) << 0) 228#define S_000134_HDP_FB_START(x) (((x) & 0xFFFF) << 0)
183#define G_000134_HDP_FB_START(x) (((x) >> 0) & 0xFFFF) 229#define G_000134_HDP_FB_START(x) (((x) >> 0) & 0xFFFF)
diff --git a/drivers/gpu/drm/radeon/rs690.c b/drivers/gpu/drm/radeon/rs690.c
index ef35e0468f13..56a0aec84af2 100644
--- a/drivers/gpu/drm/radeon/rs690.c
+++ b/drivers/gpu/drm/radeon/rs690.c
@@ -48,8 +48,6 @@ static int rs690_mc_wait_for_idle(struct radeon_device *rdev)
48 48
49static void rs690_gpu_init(struct radeon_device *rdev) 49static void rs690_gpu_init(struct radeon_device *rdev)
50{ 50{
51 /* FIXME: HDP same place on rs690 ? */
52 r100_hdp_reset(rdev);
53 /* FIXME: is this correct ? */ 51 /* FIXME: is this correct ? */
54 r420_pipes_init(rdev); 52 r420_pipes_init(rdev);
55 if (rs690_mc_wait_for_idle(rdev)) { 53 if (rs690_mc_wait_for_idle(rdev)) {
diff --git a/drivers/gpu/drm/radeon/rv515.c b/drivers/gpu/drm/radeon/rv515.c
index 2a4c01f5cf12..b42f8d90a0f6 100644
--- a/drivers/gpu/drm/radeon/rv515.c
+++ b/drivers/gpu/drm/radeon/rv515.c
@@ -146,16 +146,11 @@ void rv515_gpu_init(struct radeon_device *rdev)
146{ 146{
147 unsigned pipe_select_current, gb_pipe_select, tmp; 147 unsigned pipe_select_current, gb_pipe_select, tmp;
148 148
149 r100_hdp_reset(rdev);
150 r100_rb2d_reset(rdev);
151
152 if (r100_gui_wait_for_idle(rdev)) { 149 if (r100_gui_wait_for_idle(rdev)) {
153 printk(KERN_WARNING "Failed to wait GUI idle while " 150 printk(KERN_WARNING "Failed to wait GUI idle while "
154 "reseting GPU. Bad things might happen.\n"); 151 "reseting GPU. Bad things might happen.\n");
155 } 152 }
156
157 rv515_vga_render_disable(rdev); 153 rv515_vga_render_disable(rdev);
158
159 r420_pipes_init(rdev); 154 r420_pipes_init(rdev);
160 gb_pipe_select = RREG32(0x402C); 155 gb_pipe_select = RREG32(0x402C);
161 tmp = RREG32(0x170C); 156 tmp = RREG32(0x170C);
@@ -173,91 +168,6 @@ void rv515_gpu_init(struct radeon_device *rdev)
173 } 168 }
174} 169}
175 170
176int rv515_ga_reset(struct radeon_device *rdev)
177{
178 uint32_t tmp;
179 bool reinit_cp;
180 int i;
181
182 reinit_cp = rdev->cp.ready;
183 rdev->cp.ready = false;
184 for (i = 0; i < rdev->usec_timeout; i++) {
185 WREG32(CP_CSQ_MODE, 0);
186 WREG32(CP_CSQ_CNTL, 0);
187 WREG32(RBBM_SOFT_RESET, 0x32005);
188 (void)RREG32(RBBM_SOFT_RESET);
189 udelay(200);
190 WREG32(RBBM_SOFT_RESET, 0);
191 /* Wait to prevent race in RBBM_STATUS */
192 mdelay(1);
193 tmp = RREG32(RBBM_STATUS);
194 if (tmp & ((1 << 20) | (1 << 26))) {
195 DRM_ERROR("VAP & CP still busy (RBBM_STATUS=0x%08X)\n", tmp);
196 /* GA still busy soft reset it */
197 WREG32(0x429C, 0x200);
198 WREG32(VAP_PVS_STATE_FLUSH_REG, 0);
199 WREG32(0x43E0, 0);
200 WREG32(0x43E4, 0);
201 WREG32(0x24AC, 0);
202 }
203 /* Wait to prevent race in RBBM_STATUS */
204 mdelay(1);
205 tmp = RREG32(RBBM_STATUS);
206 if (!(tmp & ((1 << 20) | (1 << 26)))) {
207 break;
208 }
209 }
210 for (i = 0; i < rdev->usec_timeout; i++) {
211 tmp = RREG32(RBBM_STATUS);
212 if (!(tmp & ((1 << 20) | (1 << 26)))) {
213 DRM_INFO("GA reset succeed (RBBM_STATUS=0x%08X)\n",
214 tmp);
215 DRM_INFO("GA_IDLE=0x%08X\n", RREG32(0x425C));
216 DRM_INFO("RB3D_RESET_STATUS=0x%08X\n", RREG32(0x46f0));
217 DRM_INFO("ISYNC_CNTL=0x%08X\n", RREG32(0x1724));
218 if (reinit_cp) {
219 return r100_cp_init(rdev, rdev->cp.ring_size);
220 }
221 return 0;
222 }
223 DRM_UDELAY(1);
224 }
225 tmp = RREG32(RBBM_STATUS);
226 DRM_ERROR("Failed to reset GA ! (RBBM_STATUS=0x%08X)\n", tmp);
227 return -1;
228}
229
230int rv515_asic_reset(struct radeon_device *rdev)
231{
232 uint32_t status;
233
234 /* reset order likely matter */
235 status = RREG32(RBBM_STATUS);
236 /* reset HDP */
237 r100_hdp_reset(rdev);
238 /* reset rb2d */
239 if (status & ((1 << 17) | (1 << 18) | (1 << 27))) {
240 r100_rb2d_reset(rdev);
241 }
242 /* reset GA */
243 if (status & ((1 << 20) | (1 << 26))) {
244 rv515_ga_reset(rdev);
245 }
246 /* reset CP */
247 status = RREG32(RBBM_STATUS);
248 if (status & (1 << 16)) {
249 r100_cp_reset(rdev);
250 }
251 /* Check if GPU is idle */
252 status = RREG32(RBBM_STATUS);
253 if (status & (1 << 31)) {
254 DRM_ERROR("Failed to reset GPU (RBBM_STATUS=0x%08X)\n", status);
255 return -1;
256 }
257 DRM_INFO("GPU reset succeed (RBBM_STATUS=0x%08X)\n", status);
258 return 0;
259}
260
261static void rv515_vram_get_type(struct radeon_device *rdev) 171static void rv515_vram_get_type(struct radeon_device *rdev)
262{ 172{
263 uint32_t tmp; 173 uint32_t tmp;
diff --git a/drivers/gpu/drm/radeon/rv515d.h b/drivers/gpu/drm/radeon/rv515d.h
index fc216e49384d..590309a710b1 100644
--- a/drivers/gpu/drm/radeon/rv515d.h
+++ b/drivers/gpu/drm/radeon/rv515d.h
@@ -217,6 +217,52 @@
217#define CP_PACKET3_GET_OPCODE(h) (((h) >> 8) & 0xFF) 217#define CP_PACKET3_GET_OPCODE(h) (((h) >> 8) & 0xFF)
218 218
219/* Registers */ 219/* Registers */
220#define R_0000F0_RBBM_SOFT_RESET 0x0000F0
221#define S_0000F0_SOFT_RESET_CP(x) (((x) & 0x1) << 0)
222#define G_0000F0_SOFT_RESET_CP(x) (((x) >> 0) & 0x1)
223#define C_0000F0_SOFT_RESET_CP 0xFFFFFFFE
224#define S_0000F0_SOFT_RESET_HI(x) (((x) & 0x1) << 1)
225#define G_0000F0_SOFT_RESET_HI(x) (((x) >> 1) & 0x1)
226#define C_0000F0_SOFT_RESET_HI 0xFFFFFFFD
227#define S_0000F0_SOFT_RESET_VAP(x) (((x) & 0x1) << 2)
228#define G_0000F0_SOFT_RESET_VAP(x) (((x) >> 2) & 0x1)
229#define C_0000F0_SOFT_RESET_VAP 0xFFFFFFFB
230#define S_0000F0_SOFT_RESET_RE(x) (((x) & 0x1) << 3)
231#define G_0000F0_SOFT_RESET_RE(x) (((x) >> 3) & 0x1)
232#define C_0000F0_SOFT_RESET_RE 0xFFFFFFF7
233#define S_0000F0_SOFT_RESET_PP(x) (((x) & 0x1) << 4)
234#define G_0000F0_SOFT_RESET_PP(x) (((x) >> 4) & 0x1)
235#define C_0000F0_SOFT_RESET_PP 0xFFFFFFEF
236#define S_0000F0_SOFT_RESET_E2(x) (((x) & 0x1) << 5)
237#define G_0000F0_SOFT_RESET_E2(x) (((x) >> 5) & 0x1)
238#define C_0000F0_SOFT_RESET_E2 0xFFFFFFDF
239#define S_0000F0_SOFT_RESET_RB(x) (((x) & 0x1) << 6)
240#define G_0000F0_SOFT_RESET_RB(x) (((x) >> 6) & 0x1)
241#define C_0000F0_SOFT_RESET_RB 0xFFFFFFBF
242#define S_0000F0_SOFT_RESET_HDP(x) (((x) & 0x1) << 7)
243#define G_0000F0_SOFT_RESET_HDP(x) (((x) >> 7) & 0x1)
244#define C_0000F0_SOFT_RESET_HDP 0xFFFFFF7F
245#define S_0000F0_SOFT_RESET_MC(x) (((x) & 0x1) << 8)
246#define G_0000F0_SOFT_RESET_MC(x) (((x) >> 8) & 0x1)
247#define C_0000F0_SOFT_RESET_MC 0xFFFFFEFF
248#define S_0000F0_SOFT_RESET_AIC(x) (((x) & 0x1) << 9)
249#define G_0000F0_SOFT_RESET_AIC(x) (((x) >> 9) & 0x1)
250#define C_0000F0_SOFT_RESET_AIC 0xFFFFFDFF
251#define S_0000F0_SOFT_RESET_VIP(x) (((x) & 0x1) << 10)
252#define G_0000F0_SOFT_RESET_VIP(x) (((x) >> 10) & 0x1)
253#define C_0000F0_SOFT_RESET_VIP 0xFFFFFBFF
254#define S_0000F0_SOFT_RESET_DISP(x) (((x) & 0x1) << 11)
255#define G_0000F0_SOFT_RESET_DISP(x) (((x) >> 11) & 0x1)
256#define C_0000F0_SOFT_RESET_DISP 0xFFFFF7FF
257#define S_0000F0_SOFT_RESET_CG(x) (((x) & 0x1) << 12)
258#define G_0000F0_SOFT_RESET_CG(x) (((x) >> 12) & 0x1)
259#define C_0000F0_SOFT_RESET_CG 0xFFFFEFFF
260#define S_0000F0_SOFT_RESET_GA(x) (((x) & 0x1) << 13)
261#define G_0000F0_SOFT_RESET_GA(x) (((x) >> 13) & 0x1)
262#define C_0000F0_SOFT_RESET_GA 0xFFFFDFFF
263#define S_0000F0_SOFT_RESET_IDCT(x) (((x) & 0x1) << 14)
264#define G_0000F0_SOFT_RESET_IDCT(x) (((x) >> 14) & 0x1)
265#define C_0000F0_SOFT_RESET_IDCT 0xFFFFBFFF
220#define R_0000F8_CONFIG_MEMSIZE 0x0000F8 266#define R_0000F8_CONFIG_MEMSIZE 0x0000F8
221#define S_0000F8_CONFIG_MEMSIZE(x) (((x) & 0xFFFFFFFF) << 0) 267#define S_0000F8_CONFIG_MEMSIZE(x) (((x) & 0xFFFFFFFF) << 0)
222#define G_0000F8_CONFIG_MEMSIZE(x) (((x) >> 0) & 0xFFFFFFFF) 268#define G_0000F8_CONFIG_MEMSIZE(x) (((x) >> 0) & 0xFFFFFFFF)