aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/radeon/si.c
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/gpu/drm/radeon/si.c
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/gpu/drm/radeon/si.c')
-rw-r--r--drivers/gpu/drm/radeon/si.c100
1 files changed, 100 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