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/gpu/drm/radeon/si.c | |
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/gpu/drm/radeon/si.c')
-rw-r--r-- | drivers/gpu/drm/radeon/si.c | 100 |
1 files changed, 100 insertions, 0 deletions
diff --git a/drivers/gpu/drm/radeon/si.c b/drivers/gpu/drm/radeon/si.c index dd9e7d3d23b..58ad9008cf0 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 | |||