diff options
author | Alex Deucher <alexander.deucher@amd.com> | 2012-03-20 17:18:12 -0400 |
---|---|---|
committer | Dave Airlie <airlied@redhat.com> | 2012-03-21 02:55:52 -0400 |
commit | c476dde2eda8c3e1af676fe3702b9fce98904cfb (patch) | |
tree | ccfd842f9ffbbcd57284c0f7d20b70bc9437224f /drivers | |
parent | 0a96d72be9ce6c5080f5b08a07f8e34b81b575ba (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.c | 100 | ||||
-rw-r--r-- | drivers/gpu/drm/radeon/sid.h | 70 |
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 | ||
31 | extern void evergreen_fix_pci_max_read_req_size(struct radeon_device *rdev); | 31 | extern void evergreen_fix_pci_max_read_req_size(struct radeon_device *rdev); |
32 | extern void evergreen_mc_stop(struct radeon_device *rdev, struct evergreen_mc_save *save); | ||
33 | extern 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 */ |
34 | int si_get_temp(struct radeon_device *rdev) | 36 | int 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 | |||
1514 | bool 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 | |||
1544 | static 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 | |||
1606 | int 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) |