aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/radeon/r600.c
diff options
context:
space:
mode:
authorAlex Deucher <alexander.deucher@amd.com>2013-11-01 19:01:36 -0400
committerAlex Deucher <alexander.deucher@amd.com>2014-01-08 18:42:22 -0500
commitde9ae7447aaa2fed8ae4aa9e6b7260915e5b4f7b (patch)
tree3866f2fcf1aa0868dc4d9ec53b1bfd5dad50cf74 /drivers/gpu/drm/radeon/r600.c
parent1a0041b8f99656a4600b587a491a1caa0e979e18 (diff)
drm/radeon: implement pci config reset for r6xx/7xx (v3)
pci config reset is a low level reset that resets the entire chip from the bus interface. It can be more reliable if soft reset fails. There's not much information still available on r6xx, so r6xx is based on guess-work. v2: put behind module parameter v3: add IGP check Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
Diffstat (limited to 'drivers/gpu/drm/radeon/r600.c')
-rw-r--r--drivers/gpu/drm/radeon/r600.c69
1 files changed, 69 insertions, 0 deletions
diff --git a/drivers/gpu/drm/radeon/r600.c b/drivers/gpu/drm/radeon/r600.c
index bf0792cf0729..ad99bae2e85c 100644
--- a/drivers/gpu/drm/radeon/r600.c
+++ b/drivers/gpu/drm/radeon/r600.c
@@ -105,6 +105,7 @@ void r600_fini(struct radeon_device *rdev);
105void r600_irq_disable(struct radeon_device *rdev); 105void r600_irq_disable(struct radeon_device *rdev);
106static void r600_pcie_gen2_enable(struct radeon_device *rdev); 106static void r600_pcie_gen2_enable(struct radeon_device *rdev);
107extern int evergreen_rlc_resume(struct radeon_device *rdev); 107extern int evergreen_rlc_resume(struct radeon_device *rdev);
108extern void rv770_set_clk_bypass_mode(struct radeon_device *rdev);
108 109
109/** 110/**
110 * r600_get_xclk - get the xclk 111 * r600_get_xclk - get the xclk
@@ -1644,6 +1645,67 @@ static void r600_gpu_soft_reset(struct radeon_device *rdev, u32 reset_mask)
1644 r600_print_gpu_status_regs(rdev); 1645 r600_print_gpu_status_regs(rdev);
1645} 1646}
1646 1647
1648static void r600_gpu_pci_config_reset(struct radeon_device *rdev)
1649{
1650 struct rv515_mc_save save;
1651 u32 tmp, i;
1652
1653 dev_info(rdev->dev, "GPU pci config reset\n");
1654
1655 /* disable dpm? */
1656
1657 /* Disable CP parsing/prefetching */
1658 if (rdev->family >= CHIP_RV770)
1659 WREG32(R_0086D8_CP_ME_CNTL, S_0086D8_CP_ME_HALT(1) | S_0086D8_CP_PFP_HALT(1));
1660 else
1661 WREG32(R_0086D8_CP_ME_CNTL, S_0086D8_CP_ME_HALT(1));
1662
1663 /* disable the RLC */
1664 WREG32(RLC_CNTL, 0);
1665
1666 /* Disable DMA */
1667 tmp = RREG32(DMA_RB_CNTL);
1668 tmp &= ~DMA_RB_ENABLE;
1669 WREG32(DMA_RB_CNTL, tmp);
1670
1671 mdelay(50);
1672
1673 /* set mclk/sclk to bypass */
1674 if (rdev->family >= CHIP_RV770)
1675 rv770_set_clk_bypass_mode(rdev);
1676 /* disable BM */
1677 pci_clear_master(rdev->pdev);
1678 /* disable mem access */
1679 rv515_mc_stop(rdev, &save);
1680 if (r600_mc_wait_for_idle(rdev)) {
1681 dev_warn(rdev->dev, "Wait for MC idle timedout !\n");
1682 }
1683
1684 /* BIF reset workaround. Not sure if this is needed on 6xx */
1685 tmp = RREG32(BUS_CNTL);
1686 tmp |= VGA_COHE_SPEC_TIMER_DIS;
1687 WREG32(BUS_CNTL, tmp);
1688
1689 tmp = RREG32(BIF_SCRATCH0);
1690
1691 /* reset */
1692 radeon_pci_config_reset(rdev);
1693 mdelay(1);
1694
1695 /* BIF reset workaround. Not sure if this is needed on 6xx */
1696 tmp = SOFT_RESET_BIF;
1697 WREG32(SRBM_SOFT_RESET, tmp);
1698 mdelay(1);
1699 WREG32(SRBM_SOFT_RESET, 0);
1700
1701 /* wait for asic to come out of reset */
1702 for (i = 0; i < rdev->usec_timeout; i++) {
1703 if (RREG32(CONFIG_MEMSIZE) != 0xffffffff)
1704 break;
1705 udelay(1);
1706 }
1707}
1708
1647int r600_asic_reset(struct radeon_device *rdev) 1709int r600_asic_reset(struct radeon_device *rdev)
1648{ 1710{
1649 u32 reset_mask; 1711 u32 reset_mask;
@@ -1653,10 +1715,17 @@ int r600_asic_reset(struct radeon_device *rdev)
1653 if (reset_mask) 1715 if (reset_mask)
1654 r600_set_bios_scratch_engine_hung(rdev, true); 1716 r600_set_bios_scratch_engine_hung(rdev, true);
1655 1717
1718 /* try soft reset */
1656 r600_gpu_soft_reset(rdev, reset_mask); 1719 r600_gpu_soft_reset(rdev, reset_mask);
1657 1720
1658 reset_mask = r600_gpu_check_soft_reset(rdev); 1721 reset_mask = r600_gpu_check_soft_reset(rdev);
1659 1722
1723 /* try pci config reset */
1724 if (reset_mask && radeon_hard_reset)
1725 r600_gpu_pci_config_reset(rdev);
1726
1727 reset_mask = r600_gpu_check_soft_reset(rdev);
1728
1660 if (!reset_mask) 1729 if (!reset_mask)
1661 r600_set_bios_scratch_engine_hung(rdev, false); 1730 r600_set_bios_scratch_engine_hung(rdev, false);
1662 1731