aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorAlex Deucher <alexander.deucher@amd.com>2012-03-20 17:18:12 -0400
committerDave Airlie <airlied@redhat.com>2012-03-21 02:55:52 -0400
commitc476dde2eda8c3e1af676fe3702b9fce98904cfb (patch)
treeccfd842f9ffbbcd57284c0f7d20b70bc9437224f /drivers
parent0a96d72be9ce6c5080f5b08a07f8e34b81b575ba (diff)
drm/radeon/kms: Add support for SI GPU reset
Signed-off-by: Alex Deucher <alexander.deucher@amd.com> Signed-off-by: Dave Airlie <airlied@redhat.com>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/gpu/drm/radeon/si.c100
-rw-r--r--drivers/gpu/drm/radeon/sid.h70
2 files changed, 170 insertions, 0 deletions
diff --git a/drivers/gpu/drm/radeon/si.c b/drivers/gpu/drm/radeon/si.c
index dd9e7d3d23be..58ad9008cf05 100644
--- a/drivers/gpu/drm/radeon/si.c
+++ b/drivers/gpu/drm/radeon/si.c
@@ -29,6 +29,8 @@
29#include "atom.h" 29#include "atom.h"
30 30
31extern void evergreen_fix_pci_max_read_req_size(struct radeon_device *rdev); 31extern void evergreen_fix_pci_max_read_req_size(struct radeon_device *rdev);
32extern void evergreen_mc_stop(struct radeon_device *rdev, struct evergreen_mc_save *save);
33extern void evergreen_mc_resume(struct radeon_device *rdev, struct evergreen_mc_save *save);
32 34
33/* get temperature in millidegrees */ 35/* get temperature in millidegrees */
34int si_get_temp(struct radeon_device *rdev) 36int si_get_temp(struct radeon_device *rdev)
@@ -1508,3 +1510,101 @@ static void si_gpu_init(struct radeon_device *rdev)
1508 1510
1509 udelay(50); 1511 udelay(50);
1510} 1512}
1513
1514bool si_gpu_is_lockup(struct radeon_device *rdev, struct radeon_ring *ring)
1515{
1516 u32 srbm_status;
1517 u32 grbm_status, grbm_status2;
1518 u32 grbm_status_se0, grbm_status_se1;
1519 struct r100_gpu_lockup *lockup = &rdev->config.si.lockup;
1520 int r;
1521
1522 srbm_status = RREG32(SRBM_STATUS);
1523 grbm_status = RREG32(GRBM_STATUS);
1524 grbm_status2 = RREG32(GRBM_STATUS2);
1525 grbm_status_se0 = RREG32(GRBM_STATUS_SE0);
1526 grbm_status_se1 = RREG32(GRBM_STATUS_SE1);
1527 if (!(grbm_status & GUI_ACTIVE)) {
1528 r100_gpu_lockup_update(lockup, ring);
1529 return false;
1530 }
1531 /* force CP activities */
1532 r = radeon_ring_lock(rdev, ring, 2);
1533 if (!r) {
1534 /* PACKET2 NOP */
1535 radeon_ring_write(ring, 0x80000000);
1536 radeon_ring_write(ring, 0x80000000);
1537 radeon_ring_unlock_commit(rdev, ring);
1538 }
1539 /* XXX deal with CP0,1,2 */
1540 ring->rptr = RREG32(ring->rptr_reg);
1541 return r100_gpu_cp_is_lockup(rdev, lockup, ring);
1542}
1543
1544static int si_gpu_soft_reset(struct radeon_device *rdev)
1545{
1546 struct evergreen_mc_save save;
1547 u32 grbm_reset = 0;
1548
1549 if (!(RREG32(GRBM_STATUS) & GUI_ACTIVE))
1550 return 0;
1551
1552 dev_info(rdev->dev, "GPU softreset \n");
1553 dev_info(rdev->dev, " GRBM_STATUS=0x%08X\n",
1554 RREG32(GRBM_STATUS));
1555 dev_info(rdev->dev, " GRBM_STATUS2=0x%08X\n",
1556 RREG32(GRBM_STATUS2));
1557 dev_info(rdev->dev, " GRBM_STATUS_SE0=0x%08X\n",
1558 RREG32(GRBM_STATUS_SE0));
1559 dev_info(rdev->dev, " GRBM_STATUS_SE1=0x%08X\n",
1560 RREG32(GRBM_STATUS_SE1));
1561 dev_info(rdev->dev, " SRBM_STATUS=0x%08X\n",
1562 RREG32(SRBM_STATUS));
1563 evergreen_mc_stop(rdev, &save);
1564 if (radeon_mc_wait_for_idle(rdev)) {
1565 dev_warn(rdev->dev, "Wait for MC idle timedout !\n");
1566 }
1567 /* Disable CP parsing/prefetching */
1568 WREG32(CP_ME_CNTL, CP_ME_HALT | CP_PFP_HALT | CP_CE_HALT);
1569
1570 /* reset all the gfx blocks */
1571 grbm_reset = (SOFT_RESET_CP |
1572 SOFT_RESET_CB |
1573 SOFT_RESET_DB |
1574 SOFT_RESET_GDS |
1575 SOFT_RESET_PA |
1576 SOFT_RESET_SC |
1577 SOFT_RESET_SPI |
1578 SOFT_RESET_SX |
1579 SOFT_RESET_TC |
1580 SOFT_RESET_TA |
1581 SOFT_RESET_VGT |
1582 SOFT_RESET_IA);
1583
1584 dev_info(rdev->dev, " GRBM_SOFT_RESET=0x%08X\n", grbm_reset);
1585 WREG32(GRBM_SOFT_RESET, grbm_reset);
1586 (void)RREG32(GRBM_SOFT_RESET);
1587 udelay(50);
1588 WREG32(GRBM_SOFT_RESET, 0);
1589 (void)RREG32(GRBM_SOFT_RESET);
1590 /* Wait a little for things to settle down */
1591 udelay(50);
1592 dev_info(rdev->dev, " GRBM_STATUS=0x%08X\n",
1593 RREG32(GRBM_STATUS));
1594 dev_info(rdev->dev, " GRBM_STATUS2=0x%08X\n",
1595 RREG32(GRBM_STATUS2));
1596 dev_info(rdev->dev, " GRBM_STATUS_SE0=0x%08X\n",
1597 RREG32(GRBM_STATUS_SE0));
1598 dev_info(rdev->dev, " GRBM_STATUS_SE1=0x%08X\n",
1599 RREG32(GRBM_STATUS_SE1));
1600 dev_info(rdev->dev, " SRBM_STATUS=0x%08X\n",
1601 RREG32(SRBM_STATUS));
1602 evergreen_mc_resume(rdev, &save);
1603 return 0;
1604}
1605
1606int si_asic_reset(struct radeon_device *rdev)
1607{
1608 return si_gpu_soft_reset(rdev);
1609}
1610
diff --git a/drivers/gpu/drm/radeon/sid.h b/drivers/gpu/drm/radeon/sid.h
index cf06dcc9ba96..4c6ff1c8b5ed 100644
--- a/drivers/gpu/drm/radeon/sid.h
+++ b/drivers/gpu/drm/radeon/sid.h
@@ -52,6 +52,8 @@
52 52
53#define DMIF_ADDR_CONFIG 0xBD4 53#define DMIF_ADDR_CONFIG 0xBD4
54 54
55#define SRBM_STATUS 0xE50
56
55#define CC_SYS_RB_BACKEND_DISABLE 0xe80 57#define CC_SYS_RB_BACKEND_DISABLE 0xe80
56#define GC_USER_SYS_RB_BACKEND_DISABLE 0xe84 58#define GC_USER_SYS_RB_BACKEND_DISABLE 0xe84
57 59
@@ -102,6 +104,74 @@
102#define GRBM_CNTL 0x8000 104#define GRBM_CNTL 0x8000
103#define GRBM_READ_TIMEOUT(x) ((x) << 0) 105#define GRBM_READ_TIMEOUT(x) ((x) << 0)
104 106
107#define GRBM_STATUS2 0x8008
108#define RLC_RQ_PENDING (1 << 0)
109#define RLC_BUSY (1 << 8)
110#define TC_BUSY (1 << 9)
111
112#define GRBM_STATUS 0x8010
113#define CMDFIFO_AVAIL_MASK 0x0000000F
114#define RING2_RQ_PENDING (1 << 4)
115#define SRBM_RQ_PENDING (1 << 5)
116#define RING1_RQ_PENDING (1 << 6)
117#define CF_RQ_PENDING (1 << 7)
118#define PF_RQ_PENDING (1 << 8)
119#define GDS_DMA_RQ_PENDING (1 << 9)
120#define GRBM_EE_BUSY (1 << 10)
121#define DB_CLEAN (1 << 12)
122#define CB_CLEAN (1 << 13)
123#define TA_BUSY (1 << 14)
124#define GDS_BUSY (1 << 15)
125#define VGT_BUSY (1 << 17)
126#define IA_BUSY_NO_DMA (1 << 18)
127#define IA_BUSY (1 << 19)
128#define SX_BUSY (1 << 20)
129#define SPI_BUSY (1 << 22)
130#define BCI_BUSY (1 << 23)
131#define SC_BUSY (1 << 24)
132#define PA_BUSY (1 << 25)
133#define DB_BUSY (1 << 26)
134#define CP_COHERENCY_BUSY (1 << 28)
135#define CP_BUSY (1 << 29)
136#define CB_BUSY (1 << 30)
137#define GUI_ACTIVE (1 << 31)
138#define GRBM_STATUS_SE0 0x8014
139#define GRBM_STATUS_SE1 0x8018
140#define SE_DB_CLEAN (1 << 1)
141#define SE_CB_CLEAN (1 << 2)
142#define SE_BCI_BUSY (1 << 22)
143#define SE_VGT_BUSY (1 << 23)
144#define SE_PA_BUSY (1 << 24)
145#define SE_TA_BUSY (1 << 25)
146#define SE_SX_BUSY (1 << 26)
147#define SE_SPI_BUSY (1 << 27)
148#define SE_SC_BUSY (1 << 29)
149#define SE_DB_BUSY (1 << 30)
150#define SE_CB_BUSY (1 << 31)
151
152#define GRBM_SOFT_RESET 0x8020
153#define SOFT_RESET_CP (1 << 0)
154#define SOFT_RESET_CB (1 << 1)
155#define SOFT_RESET_RLC (1 << 2)
156#define SOFT_RESET_DB (1 << 3)
157#define SOFT_RESET_GDS (1 << 4)
158#define SOFT_RESET_PA (1 << 5)
159#define SOFT_RESET_SC (1 << 6)
160#define SOFT_RESET_BCI (1 << 7)
161#define SOFT_RESET_SPI (1 << 8)
162#define SOFT_RESET_SX (1 << 10)
163#define SOFT_RESET_TC (1 << 11)
164#define SOFT_RESET_TA (1 << 12)
165#define SOFT_RESET_VGT (1 << 14)
166#define SOFT_RESET_IA (1 << 15)
167
168#define CP_ME_CNTL 0x86D8
169#define CP_CE_HALT (1 << 24)
170#define CP_PFP_HALT (1 << 26)
171#define CP_ME_HALT (1 << 28)
172
173#define CP_RB0_RPTR 0x8700
174
105#define CP_QUEUE_THRESHOLDS 0x8760 175#define CP_QUEUE_THRESHOLDS 0x8760
106#define ROQ_IB1_START(x) ((x) << 0) 176#define ROQ_IB1_START(x) ((x) << 0)
107#define ROQ_IB2_START(x) ((x) << 8) 177#define ROQ_IB2_START(x) ((x) << 8)