diff options
Diffstat (limited to 'drivers/gpu/drm')
23 files changed, 802 insertions, 474 deletions
diff --git a/drivers/gpu/drm/radeon/evergreen.c b/drivers/gpu/drm/radeon/evergreen.c index e8f447e20507..bd1bb9fb2b2a 100644 --- a/drivers/gpu/drm/radeon/evergreen.c +++ b/drivers/gpu/drm/radeon/evergreen.c | |||
@@ -487,7 +487,13 @@ int evergreen_mc_init(struct radeon_device *rdev) | |||
487 | return 0; | 487 | return 0; |
488 | } | 488 | } |
489 | 489 | ||
490 | int evergreen_gpu_reset(struct radeon_device *rdev) | 490 | bool evergreen_gpu_is_lockup(struct radeon_device *rdev) |
491 | { | ||
492 | /* FIXME: implement for evergreen */ | ||
493 | return false; | ||
494 | } | ||
495 | |||
496 | int evergreen_asic_reset(struct radeon_device *rdev) | ||
491 | { | 497 | { |
492 | /* FIXME: implement for evergreen */ | 498 | /* FIXME: implement for evergreen */ |
493 | return 0; | 499 | return 0; |
diff --git a/drivers/gpu/drm/radeon/r100.c b/drivers/gpu/drm/radeon/r100.c index d7388fdb6d0b..9d3b47deecb3 100644 --- a/drivers/gpu/drm/radeon/r100.c +++ b/drivers/gpu/drm/radeon/r100.c | |||
@@ -663,26 +663,6 @@ int r100_cp_init(struct radeon_device *rdev, unsigned ring_size) | |||
663 | if (r100_debugfs_cp_init(rdev)) { | 663 | if (r100_debugfs_cp_init(rdev)) { |
664 | DRM_ERROR("Failed to register debugfs file for CP !\n"); | 664 | DRM_ERROR("Failed to register debugfs file for CP !\n"); |
665 | } | 665 | } |
666 | /* Reset CP */ | ||
667 | tmp = RREG32(RADEON_CP_CSQ_STAT); | ||
668 | if ((tmp & (1 << 31))) { | ||
669 | DRM_INFO("radeon: cp busy (0x%08X) resetting\n", tmp); | ||
670 | WREG32(RADEON_CP_CSQ_MODE, 0); | ||
671 | WREG32(RADEON_CP_CSQ_CNTL, 0); | ||
672 | WREG32(RADEON_RBBM_SOFT_RESET, RADEON_SOFT_RESET_CP); | ||
673 | tmp = RREG32(RADEON_RBBM_SOFT_RESET); | ||
674 | mdelay(2); | ||
675 | WREG32(RADEON_RBBM_SOFT_RESET, 0); | ||
676 | tmp = RREG32(RADEON_RBBM_SOFT_RESET); | ||
677 | mdelay(2); | ||
678 | tmp = RREG32(RADEON_CP_CSQ_STAT); | ||
679 | if ((tmp & (1 << 31))) { | ||
680 | DRM_INFO("radeon: cp reset failed (0x%08X)\n", tmp); | ||
681 | } | ||
682 | } else { | ||
683 | DRM_INFO("radeon: cp idle (0x%08X)\n", tmp); | ||
684 | } | ||
685 | |||
686 | if (!rdev->me_fw) { | 666 | if (!rdev->me_fw) { |
687 | r = r100_cp_init_microcode(rdev); | 667 | r = r100_cp_init_microcode(rdev); |
688 | if (r) { | 668 | if (r) { |
@@ -787,39 +767,6 @@ void r100_cp_disable(struct radeon_device *rdev) | |||
787 | } | 767 | } |
788 | } | 768 | } |
789 | 769 | ||
790 | int r100_cp_reset(struct radeon_device *rdev) | ||
791 | { | ||
792 | uint32_t tmp; | ||
793 | bool reinit_cp; | ||
794 | int i; | ||
795 | |||
796 | reinit_cp = rdev->cp.ready; | ||
797 | rdev->cp.ready = false; | ||
798 | WREG32(RADEON_CP_CSQ_MODE, 0); | ||
799 | WREG32(RADEON_CP_CSQ_CNTL, 0); | ||
800 | WREG32(RADEON_RBBM_SOFT_RESET, RADEON_SOFT_RESET_CP); | ||
801 | (void)RREG32(RADEON_RBBM_SOFT_RESET); | ||
802 | udelay(200); | ||
803 | WREG32(RADEON_RBBM_SOFT_RESET, 0); | ||
804 | /* Wait to prevent race in RBBM_STATUS */ | ||
805 | mdelay(1); | ||
806 | for (i = 0; i < rdev->usec_timeout; i++) { | ||
807 | tmp = RREG32(RADEON_RBBM_STATUS); | ||
808 | if (!(tmp & (1 << 16))) { | ||
809 | DRM_INFO("CP reset succeed (RBBM_STATUS=0x%08X)\n", | ||
810 | tmp); | ||
811 | if (reinit_cp) { | ||
812 | return r100_cp_init(rdev, rdev->cp.ring_size); | ||
813 | } | ||
814 | return 0; | ||
815 | } | ||
816 | DRM_UDELAY(1); | ||
817 | } | ||
818 | tmp = RREG32(RADEON_RBBM_STATUS); | ||
819 | DRM_ERROR("Failed to reset CP (RBBM_STATUS=0x%08X)!\n", tmp); | ||
820 | return -1; | ||
821 | } | ||
822 | |||
823 | void r100_cp_commit(struct radeon_device *rdev) | 770 | void r100_cp_commit(struct radeon_device *rdev) |
824 | { | 771 | { |
825 | WREG32(RADEON_CP_RB_WPTR, rdev->cp.wptr); | 772 | WREG32(RADEON_CP_RB_WPTR, rdev->cp.wptr); |
@@ -1733,76 +1680,163 @@ int r100_mc_wait_for_idle(struct radeon_device *rdev) | |||
1733 | return -1; | 1680 | return -1; |
1734 | } | 1681 | } |
1735 | 1682 | ||
1736 | void r100_gpu_init(struct radeon_device *rdev) | 1683 | void r100_gpu_lockup_update(struct r100_gpu_lockup *lockup, struct radeon_cp *cp) |
1737 | { | 1684 | { |
1738 | /* TODO: anythings to do here ? pipes ? */ | 1685 | lockup->last_cp_rptr = cp->rptr; |
1739 | r100_hdp_reset(rdev); | 1686 | lockup->last_jiffies = jiffies; |
1687 | } | ||
1688 | |||
1689 | /** | ||
1690 | * r100_gpu_cp_is_lockup() - check if CP is lockup by recording information | ||
1691 | * @rdev: radeon device structure | ||
1692 | * @lockup: r100_gpu_lockup structure holding CP lockup tracking informations | ||
1693 | * @cp: radeon_cp structure holding CP information | ||
1694 | * | ||
1695 | * We don't need to initialize the lockup tracking information as we will either | ||
1696 | * have CP rptr to a different value of jiffies wrap around which will force | ||
1697 | * initialization of the lockup tracking informations. | ||
1698 | * | ||
1699 | * A possible false positivie is if we get call after while and last_cp_rptr == | ||
1700 | * the current CP rptr, even if it's unlikely it might happen. To avoid this | ||
1701 | * if the elapsed time since last call is bigger than 2 second than we return | ||
1702 | * false and update the tracking information. Due to this the caller must call | ||
1703 | * r100_gpu_cp_is_lockup several time in less than 2sec for lockup to be reported | ||
1704 | * the fencing code should be cautious about that. | ||
1705 | * | ||
1706 | * Caller should write to the ring to force CP to do something so we don't get | ||
1707 | * false positive when CP is just gived nothing to do. | ||
1708 | * | ||
1709 | **/ | ||
1710 | bool r100_gpu_cp_is_lockup(struct radeon_device *rdev, struct r100_gpu_lockup *lockup, struct radeon_cp *cp) | ||
1711 | { | ||
1712 | unsigned long cjiffies, elapsed; | ||
1713 | |||
1714 | cjiffies = jiffies; | ||
1715 | if (!time_after(cjiffies, lockup->last_jiffies)) { | ||
1716 | /* likely a wrap around */ | ||
1717 | lockup->last_cp_rptr = cp->rptr; | ||
1718 | lockup->last_jiffies = jiffies; | ||
1719 | return false; | ||
1720 | } | ||
1721 | if (cp->rptr != lockup->last_cp_rptr) { | ||
1722 | /* CP is still working no lockup */ | ||
1723 | lockup->last_cp_rptr = cp->rptr; | ||
1724 | lockup->last_jiffies = jiffies; | ||
1725 | return false; | ||
1726 | } | ||
1727 | elapsed = jiffies_to_msecs(cjiffies - lockup->last_jiffies); | ||
1728 | if (elapsed >= 3000) { | ||
1729 | /* very likely the improbable case where current | ||
1730 | * rptr is equal to last recorded, a while ago, rptr | ||
1731 | * this is more likely a false positive update tracking | ||
1732 | * information which should force us to be recall at | ||
1733 | * latter point | ||
1734 | */ | ||
1735 | lockup->last_cp_rptr = cp->rptr; | ||
1736 | lockup->last_jiffies = jiffies; | ||
1737 | return false; | ||
1738 | } | ||
1739 | if (elapsed >= 1000) { | ||
1740 | dev_err(rdev->dev, "GPU lockup CP stall for more than %lumsec\n", elapsed); | ||
1741 | return true; | ||
1742 | } | ||
1743 | /* give a chance to the GPU ... */ | ||
1744 | return false; | ||
1740 | } | 1745 | } |
1741 | 1746 | ||
1742 | void r100_hdp_reset(struct radeon_device *rdev) | 1747 | bool r100_gpu_is_lockup(struct radeon_device *rdev) |
1743 | { | 1748 | { |
1744 | uint32_t tmp; | 1749 | u32 rbbm_status; |
1750 | int r; | ||
1745 | 1751 | ||
1746 | tmp = RREG32(RADEON_HOST_PATH_CNTL) & RADEON_HDP_APER_CNTL; | 1752 | rbbm_status = RREG32(R_000E40_RBBM_STATUS); |
1747 | tmp |= (7 << 28); | 1753 | if (!G_000E40_GUI_ACTIVE(rbbm_status)) { |
1748 | WREG32(RADEON_HOST_PATH_CNTL, tmp | RADEON_HDP_SOFT_RESET | RADEON_HDP_READ_BUFFER_INVALIDATE); | 1754 | r100_gpu_lockup_update(&rdev->config.r100.lockup, &rdev->cp); |
1749 | (void)RREG32(RADEON_HOST_PATH_CNTL); | 1755 | return false; |
1750 | udelay(200); | 1756 | } |
1751 | WREG32(RADEON_RBBM_SOFT_RESET, 0); | 1757 | /* force CP activities */ |
1752 | WREG32(RADEON_HOST_PATH_CNTL, tmp); | 1758 | r = radeon_ring_lock(rdev, 2); |
1753 | (void)RREG32(RADEON_HOST_PATH_CNTL); | 1759 | if (!r) { |
1760 | /* PACKET2 NOP */ | ||
1761 | radeon_ring_write(rdev, 0x80000000); | ||
1762 | radeon_ring_write(rdev, 0x80000000); | ||
1763 | radeon_ring_unlock_commit(rdev); | ||
1764 | } | ||
1765 | rdev->cp.rptr = RREG32(RADEON_CP_RB_RPTR); | ||
1766 | return r100_gpu_cp_is_lockup(rdev, &rdev->config.r100.lockup, &rdev->cp); | ||
1754 | } | 1767 | } |
1755 | 1768 | ||
1756 | int r100_rb2d_reset(struct radeon_device *rdev) | 1769 | void r100_bm_disable(struct radeon_device *rdev) |
1757 | { | 1770 | { |
1758 | uint32_t tmp; | 1771 | u32 tmp; |
1759 | int i; | ||
1760 | 1772 | ||
1761 | WREG32(RADEON_RBBM_SOFT_RESET, RADEON_SOFT_RESET_E2); | 1773 | /* disable bus mastering */ |
1762 | (void)RREG32(RADEON_RBBM_SOFT_RESET); | 1774 | tmp = RREG32(R_000030_BUS_CNTL); |
1763 | udelay(200); | 1775 | WREG32(R_000030_BUS_CNTL, (tmp & 0xFFFFFFFF) | 0x00000044); |
1764 | WREG32(RADEON_RBBM_SOFT_RESET, 0); | 1776 | mdelay(1); |
1765 | /* Wait to prevent race in RBBM_STATUS */ | 1777 | WREG32(R_000030_BUS_CNTL, (tmp & 0xFFFFFFFF) | 0x00000042); |
1778 | mdelay(1); | ||
1779 | WREG32(R_000030_BUS_CNTL, (tmp & 0xFFFFFFFF) | 0x00000040); | ||
1780 | tmp = RREG32(RADEON_BUS_CNTL); | ||
1781 | mdelay(1); | ||
1782 | pci_read_config_word(rdev->pdev, 0x4, (u16*)&tmp); | ||
1783 | pci_write_config_word(rdev->pdev, 0x4, tmp & 0xFFFB); | ||
1766 | mdelay(1); | 1784 | mdelay(1); |
1767 | for (i = 0; i < rdev->usec_timeout; i++) { | ||
1768 | tmp = RREG32(RADEON_RBBM_STATUS); | ||
1769 | if (!(tmp & (1 << 26))) { | ||
1770 | DRM_INFO("RB2D reset succeed (RBBM_STATUS=0x%08X)\n", | ||
1771 | tmp); | ||
1772 | return 0; | ||
1773 | } | ||
1774 | DRM_UDELAY(1); | ||
1775 | } | ||
1776 | tmp = RREG32(RADEON_RBBM_STATUS); | ||
1777 | DRM_ERROR("Failed to reset RB2D (RBBM_STATUS=0x%08X)!\n", tmp); | ||
1778 | return -1; | ||
1779 | } | 1785 | } |
1780 | 1786 | ||
1781 | int r100_gpu_reset(struct radeon_device *rdev) | 1787 | int r100_asic_reset(struct radeon_device *rdev) |
1782 | { | 1788 | { |
1783 | uint32_t status; | 1789 | struct r100_mc_save save; |
1790 | u32 status, tmp; | ||
1784 | 1791 | ||
1785 | /* reset order likely matter */ | 1792 | r100_mc_stop(rdev, &save); |
1786 | status = RREG32(RADEON_RBBM_STATUS); | 1793 | status = RREG32(R_000E40_RBBM_STATUS); |
1787 | /* reset HDP */ | 1794 | if (!G_000E40_GUI_ACTIVE(status)) { |
1788 | r100_hdp_reset(rdev); | 1795 | return 0; |
1789 | /* reset rb2d */ | ||
1790 | if (status & ((1 << 17) | (1 << 18) | (1 << 27))) { | ||
1791 | r100_rb2d_reset(rdev); | ||
1792 | } | 1796 | } |
1793 | /* TODO: reset 3D engine */ | 1797 | status = RREG32(R_000E40_RBBM_STATUS); |
1798 | dev_info(rdev->dev, "(%s:%d) RBBM_STATUS=0x%08X\n", __func__, __LINE__, status); | ||
1799 | /* stop CP */ | ||
1800 | WREG32(RADEON_CP_CSQ_CNTL, 0); | ||
1801 | tmp = RREG32(RADEON_CP_RB_CNTL); | ||
1802 | WREG32(RADEON_CP_RB_CNTL, tmp | RADEON_RB_RPTR_WR_ENA); | ||
1803 | WREG32(RADEON_CP_RB_RPTR_WR, 0); | ||
1804 | WREG32(RADEON_CP_RB_WPTR, 0); | ||
1805 | WREG32(RADEON_CP_RB_CNTL, tmp); | ||
1806 | /* save PCI state */ | ||
1807 | pci_save_state(rdev->pdev); | ||
1808 | /* disable bus mastering */ | ||
1809 | r100_bm_disable(rdev); | ||
1810 | WREG32(R_0000F0_RBBM_SOFT_RESET, S_0000F0_SOFT_RESET_SE(1) | | ||
1811 | S_0000F0_SOFT_RESET_RE(1) | | ||
1812 | S_0000F0_SOFT_RESET_PP(1) | | ||
1813 | S_0000F0_SOFT_RESET_RB(1)); | ||
1814 | RREG32(R_0000F0_RBBM_SOFT_RESET); | ||
1815 | mdelay(500); | ||
1816 | WREG32(R_0000F0_RBBM_SOFT_RESET, 0); | ||
1817 | mdelay(1); | ||
1818 | status = RREG32(R_000E40_RBBM_STATUS); | ||
1819 | dev_info(rdev->dev, "(%s:%d) RBBM_STATUS=0x%08X\n", __func__, __LINE__, status); | ||
1794 | /* reset CP */ | 1820 | /* reset CP */ |
1795 | status = RREG32(RADEON_RBBM_STATUS); | 1821 | WREG32(R_0000F0_RBBM_SOFT_RESET, S_0000F0_SOFT_RESET_CP(1)); |
1796 | if (status & (1 << 16)) { | 1822 | RREG32(R_0000F0_RBBM_SOFT_RESET); |
1797 | r100_cp_reset(rdev); | 1823 | mdelay(500); |
1798 | } | 1824 | WREG32(R_0000F0_RBBM_SOFT_RESET, 0); |
1825 | mdelay(1); | ||
1826 | status = RREG32(R_000E40_RBBM_STATUS); | ||
1827 | dev_info(rdev->dev, "(%s:%d) RBBM_STATUS=0x%08X\n", __func__, __LINE__, status); | ||
1828 | /* restore PCI & busmastering */ | ||
1829 | pci_restore_state(rdev->pdev); | ||
1830 | r100_enable_bm(rdev); | ||
1799 | /* Check if GPU is idle */ | 1831 | /* Check if GPU is idle */ |
1800 | status = RREG32(RADEON_RBBM_STATUS); | 1832 | if (G_000E40_SE_BUSY(status) || G_000E40_RE_BUSY(status) || |
1801 | if (status & RADEON_RBBM_ACTIVE) { | 1833 | G_000E40_TAM_BUSY(status) || G_000E40_PB_BUSY(status)) { |
1802 | DRM_ERROR("Failed to reset GPU (RBBM_STATUS=0x%08X)\n", status); | 1834 | dev_err(rdev->dev, "failed to reset GPU\n"); |
1835 | rdev->gpu_lockup = true; | ||
1803 | return -1; | 1836 | return -1; |
1804 | } | 1837 | } |
1805 | DRM_INFO("GPU reset succeed (RBBM_STATUS=0x%08X)\n", status); | 1838 | r100_mc_resume(rdev, &save); |
1839 | dev_info(rdev->dev, "GPU reset succeed\n"); | ||
1806 | return 0; | 1840 | return 0; |
1807 | } | 1841 | } |
1808 | 1842 | ||
@@ -3399,7 +3433,7 @@ static int r100_startup(struct radeon_device *rdev) | |||
3399 | /* Resume clock */ | 3433 | /* Resume clock */ |
3400 | r100_clock_startup(rdev); | 3434 | r100_clock_startup(rdev); |
3401 | /* Initialize GPU configuration (# pipes, ...) */ | 3435 | /* Initialize GPU configuration (# pipes, ...) */ |
3402 | r100_gpu_init(rdev); | 3436 | // r100_gpu_init(rdev); |
3403 | /* Initialize GART (initialize after TTM so we can allocate | 3437 | /* Initialize GART (initialize after TTM so we can allocate |
3404 | * memory through TTM but finalize after TTM) */ | 3438 | * memory through TTM but finalize after TTM) */ |
3405 | r100_enable_bm(rdev); | 3439 | r100_enable_bm(rdev); |
@@ -3436,7 +3470,7 @@ int r100_resume(struct radeon_device *rdev) | |||
3436 | /* Resume clock before doing reset */ | 3470 | /* Resume clock before doing reset */ |
3437 | r100_clock_startup(rdev); | 3471 | r100_clock_startup(rdev); |
3438 | /* Reset gpu before posting otherwise ATOM will enter infinite loop */ | 3472 | /* Reset gpu before posting otherwise ATOM will enter infinite loop */ |
3439 | if (radeon_gpu_reset(rdev)) { | 3473 | if (radeon_asic_reset(rdev)) { |
3440 | dev_warn(rdev->dev, "GPU reset failed ! (0xE40=0x%08X, 0x7C0=0x%08X)\n", | 3474 | dev_warn(rdev->dev, "GPU reset failed ! (0xE40=0x%08X, 0x7C0=0x%08X)\n", |
3441 | RREG32(R_000E40_RBBM_STATUS), | 3475 | RREG32(R_000E40_RBBM_STATUS), |
3442 | RREG32(R_0007C0_CP_STAT)); | 3476 | RREG32(R_0007C0_CP_STAT)); |
@@ -3505,7 +3539,7 @@ int r100_init(struct radeon_device *rdev) | |||
3505 | return r; | 3539 | return r; |
3506 | } | 3540 | } |
3507 | /* Reset gpu before posting otherwise ATOM will enter infinite loop */ | 3541 | /* Reset gpu before posting otherwise ATOM will enter infinite loop */ |
3508 | if (radeon_gpu_reset(rdev)) { | 3542 | if (radeon_asic_reset(rdev)) { |
3509 | dev_warn(rdev->dev, | 3543 | dev_warn(rdev->dev, |
3510 | "GPU reset failed ! (0xE40=0x%08X, 0x7C0=0x%08X)\n", | 3544 | "GPU reset failed ! (0xE40=0x%08X, 0x7C0=0x%08X)\n", |
3511 | RREG32(R_000E40_RBBM_STATUS), | 3545 | RREG32(R_000E40_RBBM_STATUS), |
diff --git a/drivers/gpu/drm/radeon/r100d.h b/drivers/gpu/drm/radeon/r100d.h index df29a630c466..de8abd104ab7 100644 --- a/drivers/gpu/drm/radeon/r100d.h +++ b/drivers/gpu/drm/radeon/r100d.h | |||
@@ -74,6 +74,134 @@ | |||
74 | #define CP_PACKET3_GET_OPCODE(h) (((h) >> 8) & 0xFF) | 74 | #define CP_PACKET3_GET_OPCODE(h) (((h) >> 8) & 0xFF) |
75 | 75 | ||
76 | /* Registers */ | 76 | /* Registers */ |
77 | #define R_0000F0_RBBM_SOFT_RESET 0x0000F0 | ||
78 | #define S_0000F0_SOFT_RESET_CP(x) (((x) & 0x1) << 0) | ||
79 | #define G_0000F0_SOFT_RESET_CP(x) (((x) >> 0) & 0x1) | ||
80 | #define C_0000F0_SOFT_RESET_CP 0xFFFFFFFE | ||
81 | #define S_0000F0_SOFT_RESET_HI(x) (((x) & 0x1) << 1) | ||
82 | #define G_0000F0_SOFT_RESET_HI(x) (((x) >> 1) & 0x1) | ||
83 | #define C_0000F0_SOFT_RESET_HI 0xFFFFFFFD | ||
84 | #define S_0000F0_SOFT_RESET_SE(x) (((x) & 0x1) << 2) | ||
85 | #define G_0000F0_SOFT_RESET_SE(x) (((x) >> 2) & 0x1) | ||
86 | #define C_0000F0_SOFT_RESET_SE 0xFFFFFFFB | ||
87 | #define S_0000F0_SOFT_RESET_RE(x) (((x) & 0x1) << 3) | ||
88 | #define G_0000F0_SOFT_RESET_RE(x) (((x) >> 3) & 0x1) | ||
89 | #define C_0000F0_SOFT_RESET_RE 0xFFFFFFF7 | ||
90 | #define S_0000F0_SOFT_RESET_PP(x) (((x) & 0x1) << 4) | ||
91 | #define G_0000F0_SOFT_RESET_PP(x) (((x) >> 4) & 0x1) | ||
92 | #define C_0000F0_SOFT_RESET_PP 0xFFFFFFEF | ||
93 | #define S_0000F0_SOFT_RESET_E2(x) (((x) & 0x1) << 5) | ||
94 | #define G_0000F0_SOFT_RESET_E2(x) (((x) >> 5) & 0x1) | ||
95 | #define C_0000F0_SOFT_RESET_E2 0xFFFFFFDF | ||
96 | #define S_0000F0_SOFT_RESET_RB(x) (((x) & 0x1) << 6) | ||
97 | #define G_0000F0_SOFT_RESET_RB(x) (((x) >> 6) & 0x1) | ||
98 | #define C_0000F0_SOFT_RESET_RB 0xFFFFFFBF | ||
99 | #define S_0000F0_SOFT_RESET_HDP(x) (((x) & 0x1) << 7) | ||
100 | #define G_0000F0_SOFT_RESET_HDP(x) (((x) >> 7) & 0x1) | ||
101 | #define C_0000F0_SOFT_RESET_HDP 0xFFFFFF7F | ||
102 | #define S_0000F0_SOFT_RESET_MC(x) (((x) & 0x1) << 8) | ||
103 | #define G_0000F0_SOFT_RESET_MC(x) (((x) >> 8) & 0x1) | ||
104 | #define C_0000F0_SOFT_RESET_MC 0xFFFFFEFF | ||
105 | #define S_0000F0_SOFT_RESET_AIC(x) (((x) & 0x1) << 9) | ||
106 | #define G_0000F0_SOFT_RESET_AIC(x) (((x) >> 9) & 0x1) | ||
107 | #define C_0000F0_SOFT_RESET_AIC 0xFFFFFDFF | ||
108 | #define S_0000F0_SOFT_RESET_VIP(x) (((x) & 0x1) << 10) | ||
109 | #define G_0000F0_SOFT_RESET_VIP(x) (((x) >> 10) & 0x1) | ||
110 | #define C_0000F0_SOFT_RESET_VIP 0xFFFFFBFF | ||
111 | #define S_0000F0_SOFT_RESET_DISP(x) (((x) & 0x1) << 11) | ||
112 | #define G_0000F0_SOFT_RESET_DISP(x) (((x) >> 11) & 0x1) | ||
113 | #define C_0000F0_SOFT_RESET_DISP 0xFFFFF7FF | ||
114 | #define S_0000F0_SOFT_RESET_CG(x) (((x) & 0x1) << 12) | ||
115 | #define G_0000F0_SOFT_RESET_CG(x) (((x) >> 12) & 0x1) | ||
116 | #define C_0000F0_SOFT_RESET_CG 0xFFFFEFFF | ||
117 | #define R_000030_BUS_CNTL 0x000030 | ||
118 | #define S_000030_BUS_DBL_RESYNC(x) (((x) & 0x1) << 0) | ||
119 | #define G_000030_BUS_DBL_RESYNC(x) (((x) >> 0) & 0x1) | ||
120 | #define C_000030_BUS_DBL_RESYNC 0xFFFFFFFE | ||
121 | #define S_000030_BUS_MSTR_RESET(x) (((x) & 0x1) << 1) | ||
122 | #define G_000030_BUS_MSTR_RESET(x) (((x) >> 1) & 0x1) | ||
123 | #define C_000030_BUS_MSTR_RESET 0xFFFFFFFD | ||
124 | #define S_000030_BUS_FLUSH_BUF(x) (((x) & 0x1) << 2) | ||
125 | #define G_000030_BUS_FLUSH_BUF(x) (((x) >> 2) & 0x1) | ||
126 | #define C_000030_BUS_FLUSH_BUF 0xFFFFFFFB | ||
127 | #define S_000030_BUS_STOP_REQ_DIS(x) (((x) & 0x1) << 3) | ||
128 | #define G_000030_BUS_STOP_REQ_DIS(x) (((x) >> 3) & 0x1) | ||
129 | #define C_000030_BUS_STOP_REQ_DIS 0xFFFFFFF7 | ||
130 | #define S_000030_BUS_PM4_READ_COMBINE_EN(x) (((x) & 0x1) << 4) | ||
131 | #define G_000030_BUS_PM4_READ_COMBINE_EN(x) (((x) >> 4) & 0x1) | ||
132 | #define C_000030_BUS_PM4_READ_COMBINE_EN 0xFFFFFFEF | ||
133 | #define S_000030_BUS_WRT_COMBINE_EN(x) (((x) & 0x1) << 5) | ||
134 | #define G_000030_BUS_WRT_COMBINE_EN(x) (((x) >> 5) & 0x1) | ||
135 | #define C_000030_BUS_WRT_COMBINE_EN 0xFFFFFFDF | ||
136 | #define S_000030_BUS_MASTER_DIS(x) (((x) & 0x1) << 6) | ||
137 | #define G_000030_BUS_MASTER_DIS(x) (((x) >> 6) & 0x1) | ||
138 | #define C_000030_BUS_MASTER_DIS 0xFFFFFFBF | ||
139 | #define S_000030_BIOS_ROM_WRT_EN(x) (((x) & 0x1) << 7) | ||
140 | #define G_000030_BIOS_ROM_WRT_EN(x) (((x) >> 7) & 0x1) | ||
141 | #define C_000030_BIOS_ROM_WRT_EN 0xFFFFFF7F | ||
142 | #define S_000030_BM_DAC_CRIPPLE(x) (((x) & 0x1) << 8) | ||
143 | #define G_000030_BM_DAC_CRIPPLE(x) (((x) >> 8) & 0x1) | ||
144 | #define C_000030_BM_DAC_CRIPPLE 0xFFFFFEFF | ||
145 | #define S_000030_BUS_NON_PM4_READ_COMBINE_EN(x) (((x) & 0x1) << 9) | ||
146 | #define G_000030_BUS_NON_PM4_READ_COMBINE_EN(x) (((x) >> 9) & 0x1) | ||
147 | #define C_000030_BUS_NON_PM4_READ_COMBINE_EN 0xFFFFFDFF | ||
148 | #define S_000030_BUS_XFERD_DISCARD_EN(x) (((x) & 0x1) << 10) | ||
149 | #define G_000030_BUS_XFERD_DISCARD_EN(x) (((x) >> 10) & 0x1) | ||
150 | #define C_000030_BUS_XFERD_DISCARD_EN 0xFFFFFBFF | ||
151 | #define S_000030_BUS_SGL_READ_DISABLE(x) (((x) & 0x1) << 11) | ||
152 | #define G_000030_BUS_SGL_READ_DISABLE(x) (((x) >> 11) & 0x1) | ||
153 | #define C_000030_BUS_SGL_READ_DISABLE 0xFFFFF7FF | ||
154 | #define S_000030_BIOS_DIS_ROM(x) (((x) & 0x1) << 12) | ||
155 | #define G_000030_BIOS_DIS_ROM(x) (((x) >> 12) & 0x1) | ||
156 | #define C_000030_BIOS_DIS_ROM 0xFFFFEFFF | ||
157 | #define S_000030_BUS_PCI_READ_RETRY_EN(x) (((x) & 0x1) << 13) | ||
158 | #define G_000030_BUS_PCI_READ_RETRY_EN(x) (((x) >> 13) & 0x1) | ||
159 | #define C_000030_BUS_PCI_READ_RETRY_EN 0xFFFFDFFF | ||
160 | #define S_000030_BUS_AGP_AD_STEPPING_EN(x) (((x) & 0x1) << 14) | ||
161 | #define G_000030_BUS_AGP_AD_STEPPING_EN(x) (((x) >> 14) & 0x1) | ||
162 | #define C_000030_BUS_AGP_AD_STEPPING_EN 0xFFFFBFFF | ||
163 | #define S_000030_BUS_PCI_WRT_RETRY_EN(x) (((x) & 0x1) << 15) | ||
164 | #define G_000030_BUS_PCI_WRT_RETRY_EN(x) (((x) >> 15) & 0x1) | ||
165 | #define C_000030_BUS_PCI_WRT_RETRY_EN 0xFFFF7FFF | ||
166 | #define S_000030_BUS_RETRY_WS(x) (((x) & 0xF) << 16) | ||
167 | #define G_000030_BUS_RETRY_WS(x) (((x) >> 16) & 0xF) | ||
168 | #define C_000030_BUS_RETRY_WS 0xFFF0FFFF | ||
169 | #define S_000030_BUS_MSTR_RD_MULT(x) (((x) & 0x1) << 20) | ||
170 | #define G_000030_BUS_MSTR_RD_MULT(x) (((x) >> 20) & 0x1) | ||
171 | #define C_000030_BUS_MSTR_RD_MULT 0xFFEFFFFF | ||
172 | #define S_000030_BUS_MSTR_RD_LINE(x) (((x) & 0x1) << 21) | ||
173 | #define G_000030_BUS_MSTR_RD_LINE(x) (((x) >> 21) & 0x1) | ||
174 | #define C_000030_BUS_MSTR_RD_LINE 0xFFDFFFFF | ||
175 | #define S_000030_BUS_SUSPEND(x) (((x) & 0x1) << 22) | ||
176 | #define G_000030_BUS_SUSPEND(x) (((x) >> 22) & 0x1) | ||
177 | #define C_000030_BUS_SUSPEND 0xFFBFFFFF | ||
178 | #define S_000030_LAT_16X(x) (((x) & 0x1) << 23) | ||
179 | #define G_000030_LAT_16X(x) (((x) >> 23) & 0x1) | ||
180 | #define C_000030_LAT_16X 0xFF7FFFFF | ||
181 | #define S_000030_BUS_RD_DISCARD_EN(x) (((x) & 0x1) << 24) | ||
182 | #define G_000030_BUS_RD_DISCARD_EN(x) (((x) >> 24) & 0x1) | ||
183 | #define C_000030_BUS_RD_DISCARD_EN 0xFEFFFFFF | ||
184 | #define S_000030_ENFRCWRDY(x) (((x) & 0x1) << 25) | ||
185 | #define G_000030_ENFRCWRDY(x) (((x) >> 25) & 0x1) | ||
186 | #define C_000030_ENFRCWRDY 0xFDFFFFFF | ||
187 | #define S_000030_BUS_MSTR_WS(x) (((x) & 0x1) << 26) | ||
188 | #define G_000030_BUS_MSTR_WS(x) (((x) >> 26) & 0x1) | ||
189 | #define C_000030_BUS_MSTR_WS 0xFBFFFFFF | ||
190 | #define S_000030_BUS_PARKING_DIS(x) (((x) & 0x1) << 27) | ||
191 | #define G_000030_BUS_PARKING_DIS(x) (((x) >> 27) & 0x1) | ||
192 | #define C_000030_BUS_PARKING_DIS 0xF7FFFFFF | ||
193 | #define S_000030_BUS_MSTR_DISCONNECT_EN(x) (((x) & 0x1) << 28) | ||
194 | #define G_000030_BUS_MSTR_DISCONNECT_EN(x) (((x) >> 28) & 0x1) | ||
195 | #define C_000030_BUS_MSTR_DISCONNECT_EN 0xEFFFFFFF | ||
196 | #define S_000030_SERR_EN(x) (((x) & 0x1) << 29) | ||
197 | #define G_000030_SERR_EN(x) (((x) >> 29) & 0x1) | ||
198 | #define C_000030_SERR_EN 0xDFFFFFFF | ||
199 | #define S_000030_BUS_READ_BURST(x) (((x) & 0x1) << 30) | ||
200 | #define G_000030_BUS_READ_BURST(x) (((x) >> 30) & 0x1) | ||
201 | #define C_000030_BUS_READ_BURST 0xBFFFFFFF | ||
202 | #define S_000030_BUS_RDY_READ_DLY(x) (((x) & 0x1) << 31) | ||
203 | #define G_000030_BUS_RDY_READ_DLY(x) (((x) >> 31) & 0x1) | ||
204 | #define C_000030_BUS_RDY_READ_DLY 0x7FFFFFFF | ||
77 | #define R_000040_GEN_INT_CNTL 0x000040 | 205 | #define R_000040_GEN_INT_CNTL 0x000040 |
78 | #define S_000040_CRTC_VBLANK(x) (((x) & 0x1) << 0) | 206 | #define S_000040_CRTC_VBLANK(x) (((x) & 0x1) << 0) |
79 | #define G_000040_CRTC_VBLANK(x) (((x) >> 0) & 0x1) | 207 | #define G_000040_CRTC_VBLANK(x) (((x) >> 0) & 0x1) |
diff --git a/drivers/gpu/drm/radeon/r300.c b/drivers/gpu/drm/radeon/r300.c index bd75f99bd65e..bb005bff4b08 100644 --- a/drivers/gpu/drm/radeon/r300.c +++ b/drivers/gpu/drm/radeon/r300.c | |||
@@ -27,8 +27,9 @@ | |||
27 | */ | 27 | */ |
28 | #include <linux/seq_file.h> | 28 | #include <linux/seq_file.h> |
29 | #include <linux/slab.h> | 29 | #include <linux/slab.h> |
30 | #include "drmP.h" | 30 | #include <drm/drmP.h> |
31 | #include "drm.h" | 31 | #include <drm/drm.h> |
32 | #include <drm/drm_crtc_helper.h> | ||
32 | #include "radeon_reg.h" | 33 | #include "radeon_reg.h" |
33 | #include "radeon.h" | 34 | #include "radeon.h" |
34 | #include "radeon_asic.h" | 35 | #include "radeon_asic.h" |
@@ -151,6 +152,10 @@ void rv370_pcie_gart_disable(struct radeon_device *rdev) | |||
151 | u32 tmp; | 152 | u32 tmp; |
152 | int r; | 153 | int r; |
153 | 154 | ||
155 | WREG32_PCIE(RADEON_PCIE_TX_GART_START_LO, 0); | ||
156 | WREG32_PCIE(RADEON_PCIE_TX_GART_END_LO, 0); | ||
157 | WREG32_PCIE(RADEON_PCIE_TX_GART_START_HI, 0); | ||
158 | WREG32_PCIE(RADEON_PCIE_TX_GART_END_HI, 0); | ||
154 | tmp = RREG32_PCIE(RADEON_PCIE_TX_GART_CNTL); | 159 | tmp = RREG32_PCIE(RADEON_PCIE_TX_GART_CNTL); |
155 | tmp |= RADEON_PCIE_TX_GART_UNMAPPED_ACCESS_DISCARD; | 160 | tmp |= RADEON_PCIE_TX_GART_UNMAPPED_ACCESS_DISCARD; |
156 | WREG32_PCIE(RADEON_PCIE_TX_GART_CNTL, tmp & ~RADEON_PCIE_TX_GART_EN); | 161 | WREG32_PCIE(RADEON_PCIE_TX_GART_CNTL, tmp & ~RADEON_PCIE_TX_GART_EN); |
@@ -323,7 +328,6 @@ void r300_gpu_init(struct radeon_device *rdev) | |||
323 | { | 328 | { |
324 | uint32_t gb_tile_config, tmp; | 329 | uint32_t gb_tile_config, tmp; |
325 | 330 | ||
326 | r100_hdp_reset(rdev); | ||
327 | /* FIXME: rv380 one pipes ? */ | 331 | /* FIXME: rv380 one pipes ? */ |
328 | if ((rdev->family == CHIP_R300 && rdev->pdev->device != 0x4144) || | 332 | if ((rdev->family == CHIP_R300 && rdev->pdev->device != 0x4144) || |
329 | (rdev->family == CHIP_R350)) { | 333 | (rdev->family == CHIP_R350)) { |
@@ -376,89 +380,93 @@ void r300_gpu_init(struct radeon_device *rdev) | |||
376 | rdev->num_gb_pipes, rdev->num_z_pipes); | 380 | rdev->num_gb_pipes, rdev->num_z_pipes); |
377 | } | 381 | } |
378 | 382 | ||
379 | int r300_ga_reset(struct radeon_device *rdev) | 383 | bool r300_gpu_is_lockup(struct radeon_device *rdev) |
380 | { | 384 | { |
381 | uint32_t tmp; | 385 | u32 rbbm_status; |
382 | bool reinit_cp; | 386 | int r; |
383 | int i; | ||
384 | 387 | ||
385 | reinit_cp = rdev->cp.ready; | 388 | rbbm_status = RREG32(R_000E40_RBBM_STATUS); |
386 | rdev->cp.ready = false; | 389 | if (!G_000E40_GUI_ACTIVE(rbbm_status)) { |
387 | for (i = 0; i < rdev->usec_timeout; i++) { | 390 | r100_gpu_lockup_update(&rdev->config.r300.lockup, &rdev->cp); |
388 | WREG32(RADEON_CP_CSQ_MODE, 0); | 391 | return false; |
389 | WREG32(RADEON_CP_CSQ_CNTL, 0); | ||
390 | WREG32(RADEON_RBBM_SOFT_RESET, 0x32005); | ||
391 | (void)RREG32(RADEON_RBBM_SOFT_RESET); | ||
392 | udelay(200); | ||
393 | WREG32(RADEON_RBBM_SOFT_RESET, 0); | ||
394 | /* Wait to prevent race in RBBM_STATUS */ | ||
395 | mdelay(1); | ||
396 | tmp = RREG32(RADEON_RBBM_STATUS); | ||
397 | if (tmp & ((1 << 20) | (1 << 26))) { | ||
398 | DRM_ERROR("VAP & CP still busy (RBBM_STATUS=0x%08X)", tmp); | ||
399 | /* GA still busy soft reset it */ | ||
400 | WREG32(0x429C, 0x200); | ||
401 | WREG32(R300_VAP_PVS_STATE_FLUSH_REG, 0); | ||
402 | WREG32(R300_RE_SCISSORS_TL, 0); | ||
403 | WREG32(R300_RE_SCISSORS_BR, 0); | ||
404 | WREG32(0x24AC, 0); | ||
405 | } | ||
406 | /* Wait to prevent race in RBBM_STATUS */ | ||
407 | mdelay(1); | ||
408 | tmp = RREG32(RADEON_RBBM_STATUS); | ||
409 | if (!(tmp & ((1 << 20) | (1 << 26)))) { | ||
410 | break; | ||
411 | } | ||
412 | } | 392 | } |
413 | for (i = 0; i < rdev->usec_timeout; i++) { | 393 | /* force CP activities */ |
414 | tmp = RREG32(RADEON_RBBM_STATUS); | 394 | r = radeon_ring_lock(rdev, 2); |
415 | if (!(tmp & ((1 << 20) | (1 << 26)))) { | 395 | if (!r) { |
416 | DRM_INFO("GA reset succeed (RBBM_STATUS=0x%08X)\n", | 396 | /* PACKET2 NOP */ |
417 | tmp); | 397 | radeon_ring_write(rdev, 0x80000000); |
418 | if (reinit_cp) { | 398 | radeon_ring_write(rdev, 0x80000000); |
419 | return r100_cp_init(rdev, rdev->cp.ring_size); | 399 | radeon_ring_unlock_commit(rdev); |
420 | } | ||
421 | return 0; | ||
422 | } | ||
423 | DRM_UDELAY(1); | ||
424 | } | 400 | } |
425 | tmp = RREG32(RADEON_RBBM_STATUS); | 401 | rdev->cp.rptr = RREG32(RADEON_CP_RB_RPTR); |
426 | DRM_ERROR("Failed to reset GA ! (RBBM_STATUS=0x%08X)\n", tmp); | 402 | return r100_gpu_cp_is_lockup(rdev, &rdev->config.r300.lockup, &rdev->cp); |
427 | return -1; | ||
428 | } | 403 | } |
429 | 404 | ||
430 | int r300_gpu_reset(struct radeon_device *rdev) | 405 | int r300_asic_reset(struct radeon_device *rdev) |
431 | { | 406 | { |
432 | uint32_t status; | 407 | struct r100_mc_save save; |
433 | 408 | u32 status, tmp; | |
434 | /* reset order likely matter */ | 409 | |
435 | status = RREG32(RADEON_RBBM_STATUS); | 410 | r100_mc_stop(rdev, &save); |
436 | /* reset HDP */ | 411 | status = RREG32(R_000E40_RBBM_STATUS); |
437 | r100_hdp_reset(rdev); | 412 | if (!G_000E40_GUI_ACTIVE(status)) { |
438 | /* reset rb2d */ | 413 | return 0; |
439 | if (status & ((1 << 17) | (1 << 18) | (1 << 27))) { | ||
440 | r100_rb2d_reset(rdev); | ||
441 | } | ||
442 | /* reset GA */ | ||
443 | if (status & ((1 << 20) | (1 << 26))) { | ||
444 | r300_ga_reset(rdev); | ||
445 | } | ||
446 | /* reset CP */ | ||
447 | status = RREG32(RADEON_RBBM_STATUS); | ||
448 | if (status & (1 << 16)) { | ||
449 | r100_cp_reset(rdev); | ||
450 | } | 414 | } |
415 | status = RREG32(R_000E40_RBBM_STATUS); | ||
416 | dev_info(rdev->dev, "(%s:%d) RBBM_STATUS=0x%08X\n", __func__, __LINE__, status); | ||
417 | /* stop CP */ | ||
418 | WREG32(RADEON_CP_CSQ_CNTL, 0); | ||
419 | tmp = RREG32(RADEON_CP_RB_CNTL); | ||
420 | WREG32(RADEON_CP_RB_CNTL, tmp | RADEON_RB_RPTR_WR_ENA); | ||
421 | WREG32(RADEON_CP_RB_RPTR_WR, 0); | ||
422 | WREG32(RADEON_CP_RB_WPTR, 0); | ||
423 | WREG32(RADEON_CP_RB_CNTL, tmp); | ||
424 | /* save PCI state */ | ||
425 | pci_save_state(rdev->pdev); | ||
426 | /* disable bus mastering */ | ||
427 | r100_bm_disable(rdev); | ||
428 | WREG32(R_0000F0_RBBM_SOFT_RESET, S_0000F0_SOFT_RESET_VAP(1) | | ||
429 | S_0000F0_SOFT_RESET_GA(1)); | ||
430 | RREG32(R_0000F0_RBBM_SOFT_RESET); | ||
431 | mdelay(500); | ||
432 | WREG32(R_0000F0_RBBM_SOFT_RESET, 0); | ||
433 | mdelay(1); | ||
434 | status = RREG32(R_000E40_RBBM_STATUS); | ||
435 | dev_info(rdev->dev, "(%s:%d) RBBM_STATUS=0x%08X\n", __func__, __LINE__, status); | ||
436 | /* resetting the CP seems to be problematic sometimes it end up | ||
437 | * hard locking the computer, but it's necessary for successfull | ||
438 | * reset more test & playing is needed on R3XX/R4XX to find a | ||
439 | * reliable (if any solution) | ||
440 | */ | ||
441 | WREG32(R_0000F0_RBBM_SOFT_RESET, S_0000F0_SOFT_RESET_CP(1)); | ||
442 | RREG32(R_0000F0_RBBM_SOFT_RESET); | ||
443 | mdelay(500); | ||
444 | WREG32(R_0000F0_RBBM_SOFT_RESET, 0); | ||
445 | mdelay(1); | ||
446 | status = RREG32(R_000E40_RBBM_STATUS); | ||
447 | dev_info(rdev->dev, "(%s:%d) RBBM_STATUS=0x%08X\n", __func__, __LINE__, status); | ||
448 | /* reset MC */ | ||
449 | WREG32(R_0000F0_RBBM_SOFT_RESET, S_0000F0_SOFT_RESET_MC(1)); | ||
450 | RREG32(R_0000F0_RBBM_SOFT_RESET); | ||
451 | mdelay(500); | ||
452 | WREG32(R_0000F0_RBBM_SOFT_RESET, 0); | ||
453 | mdelay(1); | ||
454 | status = RREG32(R_000E40_RBBM_STATUS); | ||
455 | dev_info(rdev->dev, "(%s:%d) RBBM_STATUS=0x%08X\n", __func__, __LINE__, status); | ||
456 | /* restore PCI & busmastering */ | ||
457 | pci_restore_state(rdev->pdev); | ||
458 | r100_enable_bm(rdev); | ||
451 | /* Check if GPU is idle */ | 459 | /* Check if GPU is idle */ |
452 | status = RREG32(RADEON_RBBM_STATUS); | 460 | if (G_000E40_GA_BUSY(status) || G_000E40_VAP_BUSY(status)) { |
453 | if (status & RADEON_RBBM_ACTIVE) { | 461 | dev_err(rdev->dev, "failed to reset GPU\n"); |
454 | DRM_ERROR("Failed to reset GPU (RBBM_STATUS=0x%08X)\n", status); | 462 | rdev->gpu_lockup = true; |
455 | return -1; | 463 | return -1; |
456 | } | 464 | } |
457 | DRM_INFO("GPU reset succeed (RBBM_STATUS=0x%08X)\n", status); | 465 | r100_mc_resume(rdev, &save); |
466 | dev_info(rdev->dev, "GPU reset succeed\n"); | ||
458 | return 0; | 467 | return 0; |
459 | } | 468 | } |
460 | 469 | ||
461 | |||
462 | /* | 470 | /* |
463 | * r300,r350,rv350,rv380 VRAM info | 471 | * r300,r350,rv350,rv380 VRAM info |
464 | */ | 472 | */ |
@@ -1317,7 +1325,7 @@ int r300_resume(struct radeon_device *rdev) | |||
1317 | /* Resume clock before doing reset */ | 1325 | /* Resume clock before doing reset */ |
1318 | r300_clock_startup(rdev); | 1326 | r300_clock_startup(rdev); |
1319 | /* Reset gpu before posting otherwise ATOM will enter infinite loop */ | 1327 | /* Reset gpu before posting otherwise ATOM will enter infinite loop */ |
1320 | if (radeon_gpu_reset(rdev)) { | 1328 | if (radeon_asic_reset(rdev)) { |
1321 | dev_warn(rdev->dev, "GPU reset failed ! (0xE40=0x%08X, 0x7C0=0x%08X)\n", | 1329 | dev_warn(rdev->dev, "GPU reset failed ! (0xE40=0x%08X, 0x7C0=0x%08X)\n", |
1322 | RREG32(R_000E40_RBBM_STATUS), | 1330 | RREG32(R_000E40_RBBM_STATUS), |
1323 | RREG32(R_0007C0_CP_STAT)); | 1331 | RREG32(R_0007C0_CP_STAT)); |
@@ -1388,7 +1396,7 @@ int r300_init(struct radeon_device *rdev) | |||
1388 | return r; | 1396 | return r; |
1389 | } | 1397 | } |
1390 | /* Reset gpu before posting otherwise ATOM will enter infinite loop */ | 1398 | /* Reset gpu before posting otherwise ATOM will enter infinite loop */ |
1391 | if (radeon_gpu_reset(rdev)) { | 1399 | if (radeon_asic_reset(rdev)) { |
1392 | dev_warn(rdev->dev, | 1400 | dev_warn(rdev->dev, |
1393 | "GPU reset failed ! (0xE40=0x%08X, 0x7C0=0x%08X)\n", | 1401 | "GPU reset failed ! (0xE40=0x%08X, 0x7C0=0x%08X)\n", |
1394 | RREG32(R_000E40_RBBM_STATUS), | 1402 | RREG32(R_000E40_RBBM_STATUS), |
diff --git a/drivers/gpu/drm/radeon/r300d.h b/drivers/gpu/drm/radeon/r300d.h index 4c73114f0de9..968a33317fbf 100644 --- a/drivers/gpu/drm/radeon/r300d.h +++ b/drivers/gpu/drm/radeon/r300d.h | |||
@@ -209,7 +209,52 @@ | |||
209 | #define S_000E40_GUI_ACTIVE(x) (((x) & 0x1) << 31) | 209 | #define S_000E40_GUI_ACTIVE(x) (((x) & 0x1) << 31) |
210 | #define G_000E40_GUI_ACTIVE(x) (((x) >> 31) & 0x1) | 210 | #define G_000E40_GUI_ACTIVE(x) (((x) >> 31) & 0x1) |
211 | #define C_000E40_GUI_ACTIVE 0x7FFFFFFF | 211 | #define C_000E40_GUI_ACTIVE 0x7FFFFFFF |
212 | 212 | #define R_0000F0_RBBM_SOFT_RESET 0x0000F0 | |
213 | #define S_0000F0_SOFT_RESET_CP(x) (((x) & 0x1) << 0) | ||
214 | #define G_0000F0_SOFT_RESET_CP(x) (((x) >> 0) & 0x1) | ||
215 | #define C_0000F0_SOFT_RESET_CP 0xFFFFFFFE | ||
216 | #define S_0000F0_SOFT_RESET_HI(x) (((x) & 0x1) << 1) | ||
217 | #define G_0000F0_SOFT_RESET_HI(x) (((x) >> 1) & 0x1) | ||
218 | #define C_0000F0_SOFT_RESET_HI 0xFFFFFFFD | ||
219 | #define S_0000F0_SOFT_RESET_VAP(x) (((x) & 0x1) << 2) | ||
220 | #define G_0000F0_SOFT_RESET_VAP(x) (((x) >> 2) & 0x1) | ||
221 | #define C_0000F0_SOFT_RESET_VAP 0xFFFFFFFB | ||
222 | #define S_0000F0_SOFT_RESET_RE(x) (((x) & 0x1) << 3) | ||
223 | #define G_0000F0_SOFT_RESET_RE(x) (((x) >> 3) & 0x1) | ||
224 | #define C_0000F0_SOFT_RESET_RE 0xFFFFFFF7 | ||
225 | #define S_0000F0_SOFT_RESET_PP(x) (((x) & 0x1) << 4) | ||
226 | #define G_0000F0_SOFT_RESET_PP(x) (((x) >> 4) & 0x1) | ||
227 | #define C_0000F0_SOFT_RESET_PP 0xFFFFFFEF | ||
228 | #define S_0000F0_SOFT_RESET_E2(x) (((x) & 0x1) << 5) | ||
229 | #define G_0000F0_SOFT_RESET_E2(x) (((x) >> 5) & 0x1) | ||
230 | #define C_0000F0_SOFT_RESET_E2 0xFFFFFFDF | ||
231 | #define S_0000F0_SOFT_RESET_RB(x) (((x) & 0x1) << 6) | ||
232 | #define G_0000F0_SOFT_RESET_RB(x) (((x) >> 6) & 0x1) | ||
233 | #define C_0000F0_SOFT_RESET_RB 0xFFFFFFBF | ||
234 | #define S_0000F0_SOFT_RESET_HDP(x) (((x) & 0x1) << 7) | ||
235 | #define G_0000F0_SOFT_RESET_HDP(x) (((x) >> 7) & 0x1) | ||
236 | #define C_0000F0_SOFT_RESET_HDP 0xFFFFFF7F | ||
237 | #define S_0000F0_SOFT_RESET_MC(x) (((x) & 0x1) << 8) | ||
238 | #define G_0000F0_SOFT_RESET_MC(x) (((x) >> 8) & 0x1) | ||
239 | #define C_0000F0_SOFT_RESET_MC 0xFFFFFEFF | ||
240 | #define S_0000F0_SOFT_RESET_AIC(x) (((x) & 0x1) << 9) | ||
241 | #define G_0000F0_SOFT_RESET_AIC(x) (((x) >> 9) & 0x1) | ||
242 | #define C_0000F0_SOFT_RESET_AIC 0xFFFFFDFF | ||
243 | #define S_0000F0_SOFT_RESET_VIP(x) (((x) & 0x1) << 10) | ||
244 | #define G_0000F0_SOFT_RESET_VIP(x) (((x) >> 10) & 0x1) | ||
245 | #define C_0000F0_SOFT_RESET_VIP 0xFFFFFBFF | ||
246 | #define S_0000F0_SOFT_RESET_DISP(x) (((x) & 0x1) << 11) | ||
247 | #define G_0000F0_SOFT_RESET_DISP(x) (((x) >> 11) & 0x1) | ||
248 | #define C_0000F0_SOFT_RESET_DISP 0xFFFFF7FF | ||
249 | #define S_0000F0_SOFT_RESET_CG(x) (((x) & 0x1) << 12) | ||
250 | #define G_0000F0_SOFT_RESET_CG(x) (((x) >> 12) & 0x1) | ||
251 | #define C_0000F0_SOFT_RESET_CG 0xFFFFEFFF | ||
252 | #define S_0000F0_SOFT_RESET_GA(x) (((x) & 0x1) << 13) | ||
253 | #define G_0000F0_SOFT_RESET_GA(x) (((x) >> 13) & 0x1) | ||
254 | #define C_0000F0_SOFT_RESET_GA 0xFFFFDFFF | ||
255 | #define S_0000F0_SOFT_RESET_IDCT(x) (((x) & 0x1) << 14) | ||
256 | #define G_0000F0_SOFT_RESET_IDCT(x) (((x) >> 14) & 0x1) | ||
257 | #define C_0000F0_SOFT_RESET_IDCT 0xFFFFBFFF | ||
213 | 258 | ||
214 | #define R_00000D_SCLK_CNTL 0x00000D | 259 | #define R_00000D_SCLK_CNTL 0x00000D |
215 | #define S_00000D_SCLK_SRC_SEL(x) (((x) & 0x7) << 0) | 260 | #define S_00000D_SCLK_SRC_SEL(x) (((x) & 0x7) << 0) |
diff --git a/drivers/gpu/drm/radeon/r420.c b/drivers/gpu/drm/radeon/r420.c index 3dc968c9f5a4..3759d8384294 100644 --- a/drivers/gpu/drm/radeon/r420.c +++ b/drivers/gpu/drm/radeon/r420.c | |||
@@ -235,7 +235,7 @@ int r420_resume(struct radeon_device *rdev) | |||
235 | /* Resume clock before doing reset */ | 235 | /* Resume clock before doing reset */ |
236 | r420_clock_resume(rdev); | 236 | r420_clock_resume(rdev); |
237 | /* Reset gpu before posting otherwise ATOM will enter infinite loop */ | 237 | /* Reset gpu before posting otherwise ATOM will enter infinite loop */ |
238 | if (radeon_gpu_reset(rdev)) { | 238 | if (radeon_asic_reset(rdev)) { |
239 | dev_warn(rdev->dev, "GPU reset failed ! (0xE40=0x%08X, 0x7C0=0x%08X)\n", | 239 | dev_warn(rdev->dev, "GPU reset failed ! (0xE40=0x%08X, 0x7C0=0x%08X)\n", |
240 | RREG32(R_000E40_RBBM_STATUS), | 240 | RREG32(R_000E40_RBBM_STATUS), |
241 | RREG32(R_0007C0_CP_STAT)); | 241 | RREG32(R_0007C0_CP_STAT)); |
@@ -316,7 +316,7 @@ int r420_init(struct radeon_device *rdev) | |||
316 | } | 316 | } |
317 | } | 317 | } |
318 | /* Reset gpu before posting otherwise ATOM will enter infinite loop */ | 318 | /* Reset gpu before posting otherwise ATOM will enter infinite loop */ |
319 | if (radeon_gpu_reset(rdev)) { | 319 | if (radeon_asic_reset(rdev)) { |
320 | dev_warn(rdev->dev, | 320 | dev_warn(rdev->dev, |
321 | "GPU reset failed ! (0xE40=0x%08X, 0x7C0=0x%08X)\n", | 321 | "GPU reset failed ! (0xE40=0x%08X, 0x7C0=0x%08X)\n", |
322 | RREG32(R_000E40_RBBM_STATUS), | 322 | RREG32(R_000E40_RBBM_STATUS), |
diff --git a/drivers/gpu/drm/radeon/r520.c b/drivers/gpu/drm/radeon/r520.c index 3c44b8d39318..870111e26bd1 100644 --- a/drivers/gpu/drm/radeon/r520.c +++ b/drivers/gpu/drm/radeon/r520.c | |||
@@ -53,7 +53,6 @@ static void r520_gpu_init(struct radeon_device *rdev) | |||
53 | { | 53 | { |
54 | unsigned pipe_select_current, gb_pipe_select, tmp; | 54 | unsigned pipe_select_current, gb_pipe_select, tmp; |
55 | 55 | ||
56 | r100_hdp_reset(rdev); | ||
57 | rv515_vga_render_disable(rdev); | 56 | rv515_vga_render_disable(rdev); |
58 | /* | 57 | /* |
59 | * DST_PIPE_CONFIG 0x170C | 58 | * DST_PIPE_CONFIG 0x170C |
@@ -209,7 +208,7 @@ int r520_resume(struct radeon_device *rdev) | |||
209 | /* Resume clock before doing reset */ | 208 | /* Resume clock before doing reset */ |
210 | rv515_clock_startup(rdev); | 209 | rv515_clock_startup(rdev); |
211 | /* Reset gpu before posting otherwise ATOM will enter infinite loop */ | 210 | /* Reset gpu before posting otherwise ATOM will enter infinite loop */ |
212 | if (radeon_gpu_reset(rdev)) { | 211 | if (radeon_asic_reset(rdev)) { |
213 | dev_warn(rdev->dev, "GPU reset failed ! (0xE40=0x%08X, 0x7C0=0x%08X)\n", | 212 | dev_warn(rdev->dev, "GPU reset failed ! (0xE40=0x%08X, 0x7C0=0x%08X)\n", |
214 | RREG32(R_000E40_RBBM_STATUS), | 213 | RREG32(R_000E40_RBBM_STATUS), |
215 | RREG32(R_0007C0_CP_STAT)); | 214 | RREG32(R_0007C0_CP_STAT)); |
@@ -246,7 +245,7 @@ int r520_init(struct radeon_device *rdev) | |||
246 | return -EINVAL; | 245 | return -EINVAL; |
247 | } | 246 | } |
248 | /* Reset gpu before posting otherwise ATOM will enter infinite loop */ | 247 | /* Reset gpu before posting otherwise ATOM will enter infinite loop */ |
249 | if (radeon_gpu_reset(rdev)) { | 248 | if (radeon_asic_reset(rdev)) { |
250 | dev_warn(rdev->dev, | 249 | dev_warn(rdev->dev, |
251 | "GPU reset failed ! (0xE40=0x%08X, 0x7C0=0x%08X)\n", | 250 | "GPU reset failed ! (0xE40=0x%08X, 0x7C0=0x%08X)\n", |
252 | RREG32(R_000E40_RBBM_STATUS), | 251 | RREG32(R_000E40_RBBM_STATUS), |
diff --git a/drivers/gpu/drm/radeon/r600.c b/drivers/gpu/drm/radeon/r600.c index 8f3454e2056a..6ea947d669e9 100644 --- a/drivers/gpu/drm/radeon/r600.c +++ b/drivers/gpu/drm/radeon/r600.c | |||
@@ -750,7 +750,6 @@ int r600_gpu_soft_reset(struct radeon_device *rdev) | |||
750 | S_008014_DB2_BUSY(1) | S_008014_DB3_BUSY(1) | | 750 | S_008014_DB2_BUSY(1) | S_008014_DB3_BUSY(1) | |
751 | S_008014_CB0_BUSY(1) | S_008014_CB1_BUSY(1) | | 751 | S_008014_CB0_BUSY(1) | S_008014_CB1_BUSY(1) | |
752 | S_008014_CB2_BUSY(1) | S_008014_CB3_BUSY(1); | 752 | S_008014_CB2_BUSY(1) | S_008014_CB3_BUSY(1); |
753 | u32 srbm_reset = 0; | ||
754 | u32 tmp; | 753 | u32 tmp; |
755 | 754 | ||
756 | dev_info(rdev->dev, "GPU softreset \n"); | 755 | dev_info(rdev->dev, "GPU softreset \n"); |
@@ -765,7 +764,7 @@ int r600_gpu_soft_reset(struct radeon_device *rdev) | |||
765 | dev_warn(rdev->dev, "Wait for MC idle timedout !\n"); | 764 | dev_warn(rdev->dev, "Wait for MC idle timedout !\n"); |
766 | } | 765 | } |
767 | /* Disable CP parsing/prefetching */ | 766 | /* Disable CP parsing/prefetching */ |
768 | WREG32(R_0086D8_CP_ME_CNTL, S_0086D8_CP_ME_HALT(0xff)); | 767 | WREG32(R_0086D8_CP_ME_CNTL, S_0086D8_CP_ME_HALT(1)); |
769 | /* Check if any of the rendering block is busy and reset it */ | 768 | /* Check if any of the rendering block is busy and reset it */ |
770 | if ((RREG32(R_008010_GRBM_STATUS) & grbm_busy_mask) || | 769 | if ((RREG32(R_008010_GRBM_STATUS) & grbm_busy_mask) || |
771 | (RREG32(R_008014_GRBM_STATUS2) & grbm2_busy_mask)) { | 770 | (RREG32(R_008014_GRBM_STATUS2) & grbm2_busy_mask)) { |
@@ -784,72 +783,56 @@ int r600_gpu_soft_reset(struct radeon_device *rdev) | |||
784 | S_008020_SOFT_RESET_VGT(1); | 783 | S_008020_SOFT_RESET_VGT(1); |
785 | dev_info(rdev->dev, " R_008020_GRBM_SOFT_RESET=0x%08X\n", tmp); | 784 | dev_info(rdev->dev, " R_008020_GRBM_SOFT_RESET=0x%08X\n", tmp); |
786 | WREG32(R_008020_GRBM_SOFT_RESET, tmp); | 785 | WREG32(R_008020_GRBM_SOFT_RESET, tmp); |
787 | (void)RREG32(R_008020_GRBM_SOFT_RESET); | 786 | RREG32(R_008020_GRBM_SOFT_RESET); |
788 | udelay(50); | 787 | mdelay(15); |
789 | WREG32(R_008020_GRBM_SOFT_RESET, 0); | 788 | WREG32(R_008020_GRBM_SOFT_RESET, 0); |
790 | (void)RREG32(R_008020_GRBM_SOFT_RESET); | ||
791 | } | 789 | } |
792 | /* Reset CP (we always reset CP) */ | 790 | /* Reset CP (we always reset CP) */ |
793 | tmp = S_008020_SOFT_RESET_CP(1); | 791 | tmp = S_008020_SOFT_RESET_CP(1); |
794 | dev_info(rdev->dev, "R_008020_GRBM_SOFT_RESET=0x%08X\n", tmp); | 792 | dev_info(rdev->dev, "R_008020_GRBM_SOFT_RESET=0x%08X\n", tmp); |
795 | WREG32(R_008020_GRBM_SOFT_RESET, tmp); | 793 | WREG32(R_008020_GRBM_SOFT_RESET, tmp); |
796 | (void)RREG32(R_008020_GRBM_SOFT_RESET); | 794 | RREG32(R_008020_GRBM_SOFT_RESET); |
797 | udelay(50); | 795 | mdelay(15); |
798 | WREG32(R_008020_GRBM_SOFT_RESET, 0); | 796 | WREG32(R_008020_GRBM_SOFT_RESET, 0); |
799 | (void)RREG32(R_008020_GRBM_SOFT_RESET); | ||
800 | /* Reset others GPU block if necessary */ | ||
801 | if (G_000E50_RLC_BUSY(RREG32(R_000E50_SRBM_STATUS))) | ||
802 | srbm_reset |= S_000E60_SOFT_RESET_RLC(1); | ||
803 | if (G_000E50_GRBM_RQ_PENDING(RREG32(R_000E50_SRBM_STATUS))) | ||
804 | srbm_reset |= S_000E60_SOFT_RESET_GRBM(1); | ||
805 | if (G_000E50_HI_RQ_PENDING(RREG32(R_000E50_SRBM_STATUS))) | ||
806 | srbm_reset |= S_000E60_SOFT_RESET_IH(1); | ||
807 | if (G_000E50_VMC_BUSY(RREG32(R_000E50_SRBM_STATUS))) | ||
808 | srbm_reset |= S_000E60_SOFT_RESET_VMC(1); | ||
809 | if (G_000E50_MCB_BUSY(RREG32(R_000E50_SRBM_STATUS))) | ||
810 | srbm_reset |= S_000E60_SOFT_RESET_MC(1); | ||
811 | if (G_000E50_MCDZ_BUSY(RREG32(R_000E50_SRBM_STATUS))) | ||
812 | srbm_reset |= S_000E60_SOFT_RESET_MC(1); | ||
813 | if (G_000E50_MCDY_BUSY(RREG32(R_000E50_SRBM_STATUS))) | ||
814 | srbm_reset |= S_000E60_SOFT_RESET_MC(1); | ||
815 | if (G_000E50_MCDX_BUSY(RREG32(R_000E50_SRBM_STATUS))) | ||
816 | srbm_reset |= S_000E60_SOFT_RESET_MC(1); | ||
817 | if (G_000E50_MCDW_BUSY(RREG32(R_000E50_SRBM_STATUS))) | ||
818 | srbm_reset |= S_000E60_SOFT_RESET_MC(1); | ||
819 | if (G_000E50_RLC_BUSY(RREG32(R_000E50_SRBM_STATUS))) | ||
820 | srbm_reset |= S_000E60_SOFT_RESET_RLC(1); | ||
821 | if (G_000E50_SEM_BUSY(RREG32(R_000E50_SRBM_STATUS))) | ||
822 | srbm_reset |= S_000E60_SOFT_RESET_SEM(1); | ||
823 | if (G_000E50_BIF_BUSY(RREG32(R_000E50_SRBM_STATUS))) | ||
824 | srbm_reset |= S_000E60_SOFT_RESET_BIF(1); | ||
825 | dev_info(rdev->dev, " R_000E60_SRBM_SOFT_RESET=0x%08X\n", srbm_reset); | ||
826 | WREG32(R_000E60_SRBM_SOFT_RESET, srbm_reset); | ||
827 | (void)RREG32(R_000E60_SRBM_SOFT_RESET); | ||
828 | udelay(50); | ||
829 | WREG32(R_000E60_SRBM_SOFT_RESET, 0); | ||
830 | (void)RREG32(R_000E60_SRBM_SOFT_RESET); | ||
831 | WREG32(R_000E60_SRBM_SOFT_RESET, srbm_reset); | ||
832 | (void)RREG32(R_000E60_SRBM_SOFT_RESET); | ||
833 | udelay(50); | ||
834 | WREG32(R_000E60_SRBM_SOFT_RESET, 0); | ||
835 | (void)RREG32(R_000E60_SRBM_SOFT_RESET); | ||
836 | /* Wait a little for things to settle down */ | 797 | /* Wait a little for things to settle down */ |
837 | udelay(50); | 798 | mdelay(1); |
838 | dev_info(rdev->dev, " R_008010_GRBM_STATUS=0x%08X\n", | 799 | dev_info(rdev->dev, " R_008010_GRBM_STATUS=0x%08X\n", |
839 | RREG32(R_008010_GRBM_STATUS)); | 800 | RREG32(R_008010_GRBM_STATUS)); |
840 | dev_info(rdev->dev, " R_008014_GRBM_STATUS2=0x%08X\n", | 801 | dev_info(rdev->dev, " R_008014_GRBM_STATUS2=0x%08X\n", |
841 | RREG32(R_008014_GRBM_STATUS2)); | 802 | RREG32(R_008014_GRBM_STATUS2)); |
842 | dev_info(rdev->dev, " R_000E50_SRBM_STATUS=0x%08X\n", | 803 | dev_info(rdev->dev, " R_000E50_SRBM_STATUS=0x%08X\n", |
843 | RREG32(R_000E50_SRBM_STATUS)); | 804 | RREG32(R_000E50_SRBM_STATUS)); |
844 | /* After reset we need to reinit the asic as GPU often endup in an | ||
845 | * incoherent state. | ||
846 | */ | ||
847 | atom_asic_init(rdev->mode_info.atom_context); | ||
848 | rv515_mc_resume(rdev, &save); | 805 | rv515_mc_resume(rdev, &save); |
849 | return 0; | 806 | return 0; |
850 | } | 807 | } |
851 | 808 | ||
852 | int r600_gpu_reset(struct radeon_device *rdev) | 809 | bool r600_gpu_is_lockup(struct radeon_device *rdev) |
810 | { | ||
811 | u32 srbm_status; | ||
812 | u32 grbm_status; | ||
813 | u32 grbm_status2; | ||
814 | int r; | ||
815 | |||
816 | srbm_status = RREG32(R_000E50_SRBM_STATUS); | ||
817 | grbm_status = RREG32(R_008010_GRBM_STATUS); | ||
818 | grbm_status2 = RREG32(R_008014_GRBM_STATUS2); | ||
819 | if (!G_008010_GUI_ACTIVE(grbm_status)) { | ||
820 | r100_gpu_lockup_update(&rdev->config.r300.lockup, &rdev->cp); | ||
821 | return false; | ||
822 | } | ||
823 | /* force CP activities */ | ||
824 | r = radeon_ring_lock(rdev, 2); | ||
825 | if (!r) { | ||
826 | /* PACKET2 NOP */ | ||
827 | radeon_ring_write(rdev, 0x80000000); | ||
828 | radeon_ring_write(rdev, 0x80000000); | ||
829 | radeon_ring_unlock_commit(rdev); | ||
830 | } | ||
831 | rdev->cp.rptr = RREG32(R600_CP_RB_RPTR); | ||
832 | return r100_gpu_cp_is_lockup(rdev, &rdev->config.r300.lockup, &rdev->cp); | ||
833 | } | ||
834 | |||
835 | int r600_asic_reset(struct radeon_device *rdev) | ||
853 | { | 836 | { |
854 | return r600_gpu_soft_reset(rdev); | 837 | return r600_gpu_soft_reset(rdev); |
855 | } | 838 | } |
diff --git a/drivers/gpu/drm/radeon/r600_blit_kms.c b/drivers/gpu/drm/radeon/r600_blit_kms.c index f6c6c77db7e0..d13622ae74e9 100644 --- a/drivers/gpu/drm/radeon/r600_blit_kms.c +++ b/drivers/gpu/drm/radeon/r600_blit_kms.c | |||
@@ -447,6 +447,9 @@ int r600_blit_init(struct radeon_device *rdev) | |||
447 | u32 packet2s[16]; | 447 | u32 packet2s[16]; |
448 | int num_packet2s = 0; | 448 | int num_packet2s = 0; |
449 | 449 | ||
450 | /* don't reinitialize blit */ | ||
451 | if (rdev->r600_blit.shader_obj) | ||
452 | return 0; | ||
450 | mutex_init(&rdev->r600_blit.mutex); | 453 | mutex_init(&rdev->r600_blit.mutex); |
451 | rdev->r600_blit.state_offset = 0; | 454 | rdev->r600_blit.state_offset = 0; |
452 | 455 | ||
diff --git a/drivers/gpu/drm/radeon/radeon.h b/drivers/gpu/drm/radeon/radeon.h index 034218c3dbbb..4ac97ab28947 100644 --- a/drivers/gpu/drm/radeon/radeon.h +++ b/drivers/gpu/drm/radeon/radeon.h | |||
@@ -99,6 +99,7 @@ extern int radeon_hw_i2c; | |||
99 | * symbol; | 99 | * symbol; |
100 | */ | 100 | */ |
101 | #define RADEON_MAX_USEC_TIMEOUT 100000 /* 100 ms */ | 101 | #define RADEON_MAX_USEC_TIMEOUT 100000 /* 100 ms */ |
102 | #define RADEON_FENCE_JIFFIES_TIMEOUT (HZ / 2) | ||
102 | /* RADEON_IB_POOL_SIZE must be a power of 2 */ | 103 | /* RADEON_IB_POOL_SIZE must be a power of 2 */ |
103 | #define RADEON_IB_POOL_SIZE 16 | 104 | #define RADEON_IB_POOL_SIZE 16 |
104 | #define RADEON_DEBUGFS_MAX_NUM_FILES 32 | 105 | #define RADEON_DEBUGFS_MAX_NUM_FILES 32 |
@@ -182,7 +183,8 @@ struct radeon_fence_driver { | |||
182 | uint32_t scratch_reg; | 183 | uint32_t scratch_reg; |
183 | atomic_t seq; | 184 | atomic_t seq; |
184 | uint32_t last_seq; | 185 | uint32_t last_seq; |
185 | unsigned long count_timeout; | 186 | unsigned long last_jiffies; |
187 | unsigned long last_timeout; | ||
186 | wait_queue_head_t queue; | 188 | wait_queue_head_t queue; |
187 | rwlock_t lock; | 189 | rwlock_t lock; |
188 | struct list_head created; | 190 | struct list_head created; |
@@ -197,7 +199,6 @@ struct radeon_fence { | |||
197 | struct list_head list; | 199 | struct list_head list; |
198 | /* protected by radeon_fence.lock */ | 200 | /* protected by radeon_fence.lock */ |
199 | uint32_t seq; | 201 | uint32_t seq; |
200 | unsigned long timeout; | ||
201 | bool emited; | 202 | bool emited; |
202 | bool signaled; | 203 | bool signaled; |
203 | }; | 204 | }; |
@@ -746,7 +747,8 @@ struct radeon_asic { | |||
746 | int (*resume)(struct radeon_device *rdev); | 747 | int (*resume)(struct radeon_device *rdev); |
747 | int (*suspend)(struct radeon_device *rdev); | 748 | int (*suspend)(struct radeon_device *rdev); |
748 | void (*vga_set_state)(struct radeon_device *rdev, bool state); | 749 | void (*vga_set_state)(struct radeon_device *rdev, bool state); |
749 | int (*gpu_reset)(struct radeon_device *rdev); | 750 | bool (*gpu_is_lockup)(struct radeon_device *rdev); |
751 | int (*asic_reset)(struct radeon_device *rdev); | ||
750 | void (*gart_tlb_flush)(struct radeon_device *rdev); | 752 | void (*gart_tlb_flush)(struct radeon_device *rdev); |
751 | int (*gart_set_page)(struct radeon_device *rdev, int i, uint64_t addr); | 753 | int (*gart_set_page)(struct radeon_device *rdev, int i, uint64_t addr); |
752 | int (*cp_init)(struct radeon_device *rdev, unsigned ring_size); | 754 | int (*cp_init)(struct radeon_device *rdev, unsigned ring_size); |
@@ -804,59 +806,68 @@ struct radeon_asic { | |||
804 | /* | 806 | /* |
805 | * Asic structures | 807 | * Asic structures |
806 | */ | 808 | */ |
809 | struct r100_gpu_lockup { | ||
810 | unsigned long last_jiffies; | ||
811 | u32 last_cp_rptr; | ||
812 | }; | ||
813 | |||
807 | struct r100_asic { | 814 | struct r100_asic { |
808 | const unsigned *reg_safe_bm; | 815 | const unsigned *reg_safe_bm; |
809 | unsigned reg_safe_bm_size; | 816 | unsigned reg_safe_bm_size; |
810 | u32 hdp_cntl; | 817 | u32 hdp_cntl; |
818 | struct r100_gpu_lockup lockup; | ||
811 | }; | 819 | }; |
812 | 820 | ||
813 | struct r300_asic { | 821 | struct r300_asic { |
814 | const unsigned *reg_safe_bm; | 822 | const unsigned *reg_safe_bm; |
815 | unsigned reg_safe_bm_size; | 823 | unsigned reg_safe_bm_size; |
816 | u32 resync_scratch; | 824 | u32 resync_scratch; |
817 | u32 hdp_cntl; | 825 | u32 hdp_cntl; |
826 | struct r100_gpu_lockup lockup; | ||
818 | }; | 827 | }; |
819 | 828 | ||
820 | struct r600_asic { | 829 | struct r600_asic { |
821 | unsigned max_pipes; | 830 | unsigned max_pipes; |
822 | unsigned max_tile_pipes; | 831 | unsigned max_tile_pipes; |
823 | unsigned max_simds; | 832 | unsigned max_simds; |
824 | unsigned max_backends; | 833 | unsigned max_backends; |
825 | unsigned max_gprs; | 834 | unsigned max_gprs; |
826 | unsigned max_threads; | 835 | unsigned max_threads; |
827 | unsigned max_stack_entries; | 836 | unsigned max_stack_entries; |
828 | unsigned max_hw_contexts; | 837 | unsigned max_hw_contexts; |
829 | unsigned max_gs_threads; | 838 | unsigned max_gs_threads; |
830 | unsigned sx_max_export_size; | 839 | unsigned sx_max_export_size; |
831 | unsigned sx_max_export_pos_size; | 840 | unsigned sx_max_export_pos_size; |
832 | unsigned sx_max_export_smx_size; | 841 | unsigned sx_max_export_smx_size; |
833 | unsigned sq_num_cf_insts; | 842 | unsigned sq_num_cf_insts; |
834 | unsigned tiling_nbanks; | 843 | unsigned tiling_nbanks; |
835 | unsigned tiling_npipes; | 844 | unsigned tiling_npipes; |
836 | unsigned tiling_group_size; | 845 | unsigned tiling_group_size; |
846 | struct r100_gpu_lockup lockup; | ||
837 | }; | 847 | }; |
838 | 848 | ||
839 | struct rv770_asic { | 849 | struct rv770_asic { |
840 | unsigned max_pipes; | 850 | unsigned max_pipes; |
841 | unsigned max_tile_pipes; | 851 | unsigned max_tile_pipes; |
842 | unsigned max_simds; | 852 | unsigned max_simds; |
843 | unsigned max_backends; | 853 | unsigned max_backends; |
844 | unsigned max_gprs; | 854 | unsigned max_gprs; |
845 | unsigned max_threads; | 855 | unsigned max_threads; |
846 | unsigned max_stack_entries; | 856 | unsigned max_stack_entries; |
847 | unsigned max_hw_contexts; | 857 | unsigned max_hw_contexts; |
848 | unsigned max_gs_threads; | 858 | unsigned max_gs_threads; |
849 | unsigned sx_max_export_size; | 859 | unsigned sx_max_export_size; |
850 | unsigned sx_max_export_pos_size; | 860 | unsigned sx_max_export_pos_size; |
851 | unsigned sx_max_export_smx_size; | 861 | unsigned sx_max_export_smx_size; |
852 | unsigned sq_num_cf_insts; | 862 | unsigned sq_num_cf_insts; |
853 | unsigned sx_num_of_sets; | 863 | unsigned sx_num_of_sets; |
854 | unsigned sc_prim_fifo_size; | 864 | unsigned sc_prim_fifo_size; |
855 | unsigned sc_hiz_tile_fifo_size; | 865 | unsigned sc_hiz_tile_fifo_size; |
856 | unsigned sc_earlyz_tile_fifo_fize; | 866 | unsigned sc_earlyz_tile_fifo_fize; |
857 | unsigned tiling_nbanks; | 867 | unsigned tiling_nbanks; |
858 | unsigned tiling_npipes; | 868 | unsigned tiling_npipes; |
859 | unsigned tiling_group_size; | 869 | unsigned tiling_group_size; |
870 | struct r100_gpu_lockup lockup; | ||
860 | }; | 871 | }; |
861 | 872 | ||
862 | union radeon_asic_config { | 873 | union radeon_asic_config { |
@@ -1145,7 +1156,8 @@ static inline void radeon_ring_write(struct radeon_device *rdev, uint32_t v) | |||
1145 | #define radeon_suspend(rdev) (rdev)->asic->suspend((rdev)) | 1156 | #define radeon_suspend(rdev) (rdev)->asic->suspend((rdev)) |
1146 | #define radeon_cs_parse(p) rdev->asic->cs_parse((p)) | 1157 | #define radeon_cs_parse(p) rdev->asic->cs_parse((p)) |
1147 | #define radeon_vga_set_state(rdev, state) (rdev)->asic->vga_set_state((rdev), (state)) | 1158 | #define radeon_vga_set_state(rdev, state) (rdev)->asic->vga_set_state((rdev), (state)) |
1148 | #define radeon_gpu_reset(rdev) (rdev)->asic->gpu_reset((rdev)) | 1159 | #define radeon_gpu_is_lockup(rdev) (rdev)->asic->gpu_is_lockup((rdev)) |
1160 | #define radeon_asic_reset(rdev) (rdev)->asic->asic_reset((rdev)) | ||
1149 | #define radeon_gart_tlb_flush(rdev) (rdev)->asic->gart_tlb_flush((rdev)) | 1161 | #define radeon_gart_tlb_flush(rdev) (rdev)->asic->gart_tlb_flush((rdev)) |
1150 | #define radeon_gart_set_page(rdev, i, p) (rdev)->asic->gart_set_page((rdev), (i), (p)) | 1162 | #define radeon_gart_set_page(rdev, i, p) (rdev)->asic->gart_set_page((rdev), (i), (p)) |
1151 | #define radeon_cp_commit(rdev) (rdev)->asic->cp_commit((rdev)) | 1163 | #define radeon_cp_commit(rdev) (rdev)->asic->cp_commit((rdev)) |
@@ -1176,6 +1188,7 @@ static inline void radeon_ring_write(struct radeon_device *rdev, uint32_t v) | |||
1176 | 1188 | ||
1177 | /* Common functions */ | 1189 | /* Common functions */ |
1178 | /* AGP */ | 1190 | /* AGP */ |
1191 | extern int radeon_gpu_reset(struct radeon_device *rdev); | ||
1179 | extern void radeon_agp_disable(struct radeon_device *rdev); | 1192 | extern void radeon_agp_disable(struct radeon_device *rdev); |
1180 | extern int radeon_gart_table_vram_pin(struct radeon_device *rdev); | 1193 | extern int radeon_gart_table_vram_pin(struct radeon_device *rdev); |
1181 | extern void radeon_gart_restore(struct radeon_device *rdev); | 1194 | extern void radeon_gart_restore(struct radeon_device *rdev); |
@@ -1200,6 +1213,8 @@ extern int radeon_resume_kms(struct drm_device *dev); | |||
1200 | extern int radeon_suspend_kms(struct drm_device *dev, pm_message_t state); | 1213 | extern int radeon_suspend_kms(struct drm_device *dev, pm_message_t state); |
1201 | 1214 | ||
1202 | /* r100,rv100,rs100,rv200,rs200,r200,rv250,rs300,rv280 */ | 1215 | /* r100,rv100,rs100,rv200,rs200,r200,rv250,rs300,rv280 */ |
1216 | extern void r100_gpu_lockup_update(struct r100_gpu_lockup *lockup, struct radeon_cp *cp); | ||
1217 | extern bool r100_gpu_cp_is_lockup(struct radeon_device *rdev, struct r100_gpu_lockup *lockup, struct radeon_cp *cp); | ||
1203 | 1218 | ||
1204 | /* rv200,rv250,rv280 */ | 1219 | /* rv200,rv250,rv280 */ |
1205 | extern void r200_set_safe_registers(struct radeon_device *rdev); | 1220 | extern void r200_set_safe_registers(struct radeon_device *rdev); |
@@ -1276,7 +1291,7 @@ extern void r600_scratch_init(struct radeon_device *rdev); | |||
1276 | extern int r600_blit_init(struct radeon_device *rdev); | 1291 | extern int r600_blit_init(struct radeon_device *rdev); |
1277 | extern void r600_blit_fini(struct radeon_device *rdev); | 1292 | extern void r600_blit_fini(struct radeon_device *rdev); |
1278 | extern int r600_init_microcode(struct radeon_device *rdev); | 1293 | extern int r600_init_microcode(struct radeon_device *rdev); |
1279 | extern int r600_gpu_reset(struct radeon_device *rdev); | 1294 | extern int r600_asic_reset(struct radeon_device *rdev); |
1280 | /* r600 irq */ | 1295 | /* r600 irq */ |
1281 | extern int r600_irq_init(struct radeon_device *rdev); | 1296 | extern int r600_irq_init(struct radeon_device *rdev); |
1282 | extern void r600_irq_fini(struct radeon_device *rdev); | 1297 | extern void r600_irq_fini(struct radeon_device *rdev); |
diff --git a/drivers/gpu/drm/radeon/radeon_asic.c b/drivers/gpu/drm/radeon/radeon_asic.c index a4b4bc9fa322..0d7664b8e489 100644 --- a/drivers/gpu/drm/radeon/radeon_asic.c +++ b/drivers/gpu/drm/radeon/radeon_asic.c | |||
@@ -134,7 +134,8 @@ static struct radeon_asic r100_asic = { | |||
134 | .suspend = &r100_suspend, | 134 | .suspend = &r100_suspend, |
135 | .resume = &r100_resume, | 135 | .resume = &r100_resume, |
136 | .vga_set_state = &r100_vga_set_state, | 136 | .vga_set_state = &r100_vga_set_state, |
137 | .gpu_reset = &r100_gpu_reset, | 137 | .gpu_is_lockup = &r100_gpu_is_lockup, |
138 | .asic_reset = &r100_asic_reset, | ||
138 | .gart_tlb_flush = &r100_pci_gart_tlb_flush, | 139 | .gart_tlb_flush = &r100_pci_gart_tlb_flush, |
139 | .gart_set_page = &r100_pci_gart_set_page, | 140 | .gart_set_page = &r100_pci_gart_set_page, |
140 | .cp_commit = &r100_cp_commit, | 141 | .cp_commit = &r100_cp_commit, |
@@ -172,7 +173,8 @@ static struct radeon_asic r200_asic = { | |||
172 | .suspend = &r100_suspend, | 173 | .suspend = &r100_suspend, |
173 | .resume = &r100_resume, | 174 | .resume = &r100_resume, |
174 | .vga_set_state = &r100_vga_set_state, | 175 | .vga_set_state = &r100_vga_set_state, |
175 | .gpu_reset = &r100_gpu_reset, | 176 | .gpu_is_lockup = &r100_gpu_is_lockup, |
177 | .asic_reset = &r100_asic_reset, | ||
176 | .gart_tlb_flush = &r100_pci_gart_tlb_flush, | 178 | .gart_tlb_flush = &r100_pci_gart_tlb_flush, |
177 | .gart_set_page = &r100_pci_gart_set_page, | 179 | .gart_set_page = &r100_pci_gart_set_page, |
178 | .cp_commit = &r100_cp_commit, | 180 | .cp_commit = &r100_cp_commit, |
@@ -209,7 +211,8 @@ static struct radeon_asic r300_asic = { | |||
209 | .suspend = &r300_suspend, | 211 | .suspend = &r300_suspend, |
210 | .resume = &r300_resume, | 212 | .resume = &r300_resume, |
211 | .vga_set_state = &r100_vga_set_state, | 213 | .vga_set_state = &r100_vga_set_state, |
212 | .gpu_reset = &r300_gpu_reset, | 214 | .gpu_is_lockup = &r300_gpu_is_lockup, |
215 | .asic_reset = &r300_asic_reset, | ||
213 | .gart_tlb_flush = &r100_pci_gart_tlb_flush, | 216 | .gart_tlb_flush = &r100_pci_gart_tlb_flush, |
214 | .gart_set_page = &r100_pci_gart_set_page, | 217 | .gart_set_page = &r100_pci_gart_set_page, |
215 | .cp_commit = &r100_cp_commit, | 218 | .cp_commit = &r100_cp_commit, |
@@ -247,7 +250,8 @@ static struct radeon_asic r300_asic_pcie = { | |||
247 | .suspend = &r300_suspend, | 250 | .suspend = &r300_suspend, |
248 | .resume = &r300_resume, | 251 | .resume = &r300_resume, |
249 | .vga_set_state = &r100_vga_set_state, | 252 | .vga_set_state = &r100_vga_set_state, |
250 | .gpu_reset = &r300_gpu_reset, | 253 | .gpu_is_lockup = &r300_gpu_is_lockup, |
254 | .asic_reset = &r300_asic_reset, | ||
251 | .gart_tlb_flush = &rv370_pcie_gart_tlb_flush, | 255 | .gart_tlb_flush = &rv370_pcie_gart_tlb_flush, |
252 | .gart_set_page = &rv370_pcie_gart_set_page, | 256 | .gart_set_page = &rv370_pcie_gart_set_page, |
253 | .cp_commit = &r100_cp_commit, | 257 | .cp_commit = &r100_cp_commit, |
@@ -284,7 +288,8 @@ static struct radeon_asic r420_asic = { | |||
284 | .suspend = &r420_suspend, | 288 | .suspend = &r420_suspend, |
285 | .resume = &r420_resume, | 289 | .resume = &r420_resume, |
286 | .vga_set_state = &r100_vga_set_state, | 290 | .vga_set_state = &r100_vga_set_state, |
287 | .gpu_reset = &r300_gpu_reset, | 291 | .gpu_is_lockup = &r300_gpu_is_lockup, |
292 | .asic_reset = &r300_asic_reset, | ||
288 | .gart_tlb_flush = &rv370_pcie_gart_tlb_flush, | 293 | .gart_tlb_flush = &rv370_pcie_gart_tlb_flush, |
289 | .gart_set_page = &rv370_pcie_gart_set_page, | 294 | .gart_set_page = &rv370_pcie_gart_set_page, |
290 | .cp_commit = &r100_cp_commit, | 295 | .cp_commit = &r100_cp_commit, |
@@ -322,7 +327,8 @@ static struct radeon_asic rs400_asic = { | |||
322 | .suspend = &rs400_suspend, | 327 | .suspend = &rs400_suspend, |
323 | .resume = &rs400_resume, | 328 | .resume = &rs400_resume, |
324 | .vga_set_state = &r100_vga_set_state, | 329 | .vga_set_state = &r100_vga_set_state, |
325 | .gpu_reset = &r300_gpu_reset, | 330 | .gpu_is_lockup = &r300_gpu_is_lockup, |
331 | .asic_reset = &r300_asic_reset, | ||
326 | .gart_tlb_flush = &rs400_gart_tlb_flush, | 332 | .gart_tlb_flush = &rs400_gart_tlb_flush, |
327 | .gart_set_page = &rs400_gart_set_page, | 333 | .gart_set_page = &rs400_gart_set_page, |
328 | .cp_commit = &r100_cp_commit, | 334 | .cp_commit = &r100_cp_commit, |
@@ -360,7 +366,8 @@ static struct radeon_asic rs600_asic = { | |||
360 | .suspend = &rs600_suspend, | 366 | .suspend = &rs600_suspend, |
361 | .resume = &rs600_resume, | 367 | .resume = &rs600_resume, |
362 | .vga_set_state = &r100_vga_set_state, | 368 | .vga_set_state = &r100_vga_set_state, |
363 | .gpu_reset = &r300_gpu_reset, | 369 | .gpu_is_lockup = &r300_gpu_is_lockup, |
370 | .asic_reset = &rs600_asic_reset, | ||
364 | .gart_tlb_flush = &rs600_gart_tlb_flush, | 371 | .gart_tlb_flush = &rs600_gart_tlb_flush, |
365 | .gart_set_page = &rs600_gart_set_page, | 372 | .gart_set_page = &rs600_gart_set_page, |
366 | .cp_commit = &r100_cp_commit, | 373 | .cp_commit = &r100_cp_commit, |
@@ -398,7 +405,8 @@ static struct radeon_asic rs690_asic = { | |||
398 | .suspend = &rs690_suspend, | 405 | .suspend = &rs690_suspend, |
399 | .resume = &rs690_resume, | 406 | .resume = &rs690_resume, |
400 | .vga_set_state = &r100_vga_set_state, | 407 | .vga_set_state = &r100_vga_set_state, |
401 | .gpu_reset = &r300_gpu_reset, | 408 | .gpu_is_lockup = &r300_gpu_is_lockup, |
409 | .asic_reset = &rs600_asic_reset, | ||
402 | .gart_tlb_flush = &rs400_gart_tlb_flush, | 410 | .gart_tlb_flush = &rs400_gart_tlb_flush, |
403 | .gart_set_page = &rs400_gart_set_page, | 411 | .gart_set_page = &rs400_gart_set_page, |
404 | .cp_commit = &r100_cp_commit, | 412 | .cp_commit = &r100_cp_commit, |
@@ -436,7 +444,8 @@ static struct radeon_asic rv515_asic = { | |||
436 | .suspend = &rv515_suspend, | 444 | .suspend = &rv515_suspend, |
437 | .resume = &rv515_resume, | 445 | .resume = &rv515_resume, |
438 | .vga_set_state = &r100_vga_set_state, | 446 | .vga_set_state = &r100_vga_set_state, |
439 | .gpu_reset = &rv515_gpu_reset, | 447 | .gpu_is_lockup = &r300_gpu_is_lockup, |
448 | .asic_reset = &rs600_asic_reset, | ||
440 | .gart_tlb_flush = &rv370_pcie_gart_tlb_flush, | 449 | .gart_tlb_flush = &rv370_pcie_gart_tlb_flush, |
441 | .gart_set_page = &rv370_pcie_gart_set_page, | 450 | .gart_set_page = &rv370_pcie_gart_set_page, |
442 | .cp_commit = &r100_cp_commit, | 451 | .cp_commit = &r100_cp_commit, |
@@ -474,7 +483,8 @@ static struct radeon_asic r520_asic = { | |||
474 | .suspend = &rv515_suspend, | 483 | .suspend = &rv515_suspend, |
475 | .resume = &r520_resume, | 484 | .resume = &r520_resume, |
476 | .vga_set_state = &r100_vga_set_state, | 485 | .vga_set_state = &r100_vga_set_state, |
477 | .gpu_reset = &rv515_gpu_reset, | 486 | .gpu_is_lockup = &r300_gpu_is_lockup, |
487 | .asic_reset = &rs600_asic_reset, | ||
478 | .gart_tlb_flush = &rv370_pcie_gart_tlb_flush, | 488 | .gart_tlb_flush = &rv370_pcie_gart_tlb_flush, |
479 | .gart_set_page = &rv370_pcie_gart_set_page, | 489 | .gart_set_page = &rv370_pcie_gart_set_page, |
480 | .cp_commit = &r100_cp_commit, | 490 | .cp_commit = &r100_cp_commit, |
@@ -513,7 +523,8 @@ static struct radeon_asic r600_asic = { | |||
513 | .resume = &r600_resume, | 523 | .resume = &r600_resume, |
514 | .cp_commit = &r600_cp_commit, | 524 | .cp_commit = &r600_cp_commit, |
515 | .vga_set_state = &r600_vga_set_state, | 525 | .vga_set_state = &r600_vga_set_state, |
516 | .gpu_reset = &r600_gpu_reset, | 526 | .gpu_is_lockup = &r600_gpu_is_lockup, |
527 | .asic_reset = &r600_asic_reset, | ||
517 | .gart_tlb_flush = &r600_pcie_gart_tlb_flush, | 528 | .gart_tlb_flush = &r600_pcie_gart_tlb_flush, |
518 | .gart_set_page = &rs600_gart_set_page, | 529 | .gart_set_page = &rs600_gart_set_page, |
519 | .ring_test = &r600_ring_test, | 530 | .ring_test = &r600_ring_test, |
@@ -549,8 +560,9 @@ static struct radeon_asic rs780_asic = { | |||
549 | .suspend = &r600_suspend, | 560 | .suspend = &r600_suspend, |
550 | .resume = &r600_resume, | 561 | .resume = &r600_resume, |
551 | .cp_commit = &r600_cp_commit, | 562 | .cp_commit = &r600_cp_commit, |
563 | .gpu_is_lockup = &r600_gpu_is_lockup, | ||
552 | .vga_set_state = &r600_vga_set_state, | 564 | .vga_set_state = &r600_vga_set_state, |
553 | .gpu_reset = &r600_gpu_reset, | 565 | .asic_reset = &r600_asic_reset, |
554 | .gart_tlb_flush = &r600_pcie_gart_tlb_flush, | 566 | .gart_tlb_flush = &r600_pcie_gart_tlb_flush, |
555 | .gart_set_page = &rs600_gart_set_page, | 567 | .gart_set_page = &rs600_gart_set_page, |
556 | .ring_test = &r600_ring_test, | 568 | .ring_test = &r600_ring_test, |
@@ -586,7 +598,8 @@ static struct radeon_asic rv770_asic = { | |||
586 | .suspend = &rv770_suspend, | 598 | .suspend = &rv770_suspend, |
587 | .resume = &rv770_resume, | 599 | .resume = &rv770_resume, |
588 | .cp_commit = &r600_cp_commit, | 600 | .cp_commit = &r600_cp_commit, |
589 | .gpu_reset = &rv770_gpu_reset, | 601 | .asic_reset = &r600_asic_reset, |
602 | .gpu_is_lockup = &r600_gpu_is_lockup, | ||
590 | .vga_set_state = &r600_vga_set_state, | 603 | .vga_set_state = &r600_vga_set_state, |
591 | .gart_tlb_flush = &r600_pcie_gart_tlb_flush, | 604 | .gart_tlb_flush = &r600_pcie_gart_tlb_flush, |
592 | .gart_set_page = &rs600_gart_set_page, | 605 | .gart_set_page = &rs600_gart_set_page, |
@@ -623,7 +636,8 @@ static struct radeon_asic evergreen_asic = { | |||
623 | .suspend = &evergreen_suspend, | 636 | .suspend = &evergreen_suspend, |
624 | .resume = &evergreen_resume, | 637 | .resume = &evergreen_resume, |
625 | .cp_commit = NULL, | 638 | .cp_commit = NULL, |
626 | .gpu_reset = &evergreen_gpu_reset, | 639 | .gpu_is_lockup = &evergreen_gpu_is_lockup, |
640 | .asic_reset = &evergreen_asic_reset, | ||
627 | .vga_set_state = &r600_vga_set_state, | 641 | .vga_set_state = &r600_vga_set_state, |
628 | .gart_tlb_flush = &r600_pcie_gart_tlb_flush, | 642 | .gart_tlb_flush = &r600_pcie_gart_tlb_flush, |
629 | .gart_set_page = &rs600_gart_set_page, | 643 | .gart_set_page = &rs600_gart_set_page, |
diff --git a/drivers/gpu/drm/radeon/radeon_asic.h b/drivers/gpu/drm/radeon/radeon_asic.h index a0b8280663d1..77d48ba4a29a 100644 --- a/drivers/gpu/drm/radeon/radeon_asic.h +++ b/drivers/gpu/drm/radeon/radeon_asic.h | |||
@@ -60,7 +60,8 @@ int r100_resume(struct radeon_device *rdev); | |||
60 | uint32_t r100_mm_rreg(struct radeon_device *rdev, uint32_t reg); | 60 | uint32_t r100_mm_rreg(struct radeon_device *rdev, uint32_t reg); |
61 | void r100_mm_wreg(struct radeon_device *rdev, uint32_t reg, uint32_t v); | 61 | void r100_mm_wreg(struct radeon_device *rdev, uint32_t reg, uint32_t v); |
62 | void r100_vga_set_state(struct radeon_device *rdev, bool state); | 62 | void r100_vga_set_state(struct radeon_device *rdev, bool state); |
63 | int r100_gpu_reset(struct radeon_device *rdev); | 63 | bool r100_gpu_is_lockup(struct radeon_device *rdev); |
64 | int r100_asic_reset(struct radeon_device *rdev); | ||
64 | u32 r100_get_vblank_counter(struct radeon_device *rdev, int crtc); | 65 | u32 r100_get_vblank_counter(struct radeon_device *rdev, int crtc); |
65 | void r100_pci_gart_tlb_flush(struct radeon_device *rdev); | 66 | void r100_pci_gart_tlb_flush(struct radeon_device *rdev); |
66 | int r100_pci_gart_set_page(struct radeon_device *rdev, int i, uint64_t addr); | 67 | int r100_pci_gart_set_page(struct radeon_device *rdev, int i, uint64_t addr); |
@@ -110,8 +111,6 @@ void r100_vram_init_sizes(struct radeon_device *rdev); | |||
110 | void r100_wb_disable(struct radeon_device *rdev); | 111 | void r100_wb_disable(struct radeon_device *rdev); |
111 | void r100_wb_fini(struct radeon_device *rdev); | 112 | void r100_wb_fini(struct radeon_device *rdev); |
112 | int r100_wb_init(struct radeon_device *rdev); | 113 | int r100_wb_init(struct radeon_device *rdev); |
113 | void r100_hdp_reset(struct radeon_device *rdev); | ||
114 | int r100_rb2d_reset(struct radeon_device *rdev); | ||
115 | int r100_cp_reset(struct radeon_device *rdev); | 114 | int r100_cp_reset(struct radeon_device *rdev); |
116 | void r100_vga_render_disable(struct radeon_device *rdev); | 115 | void r100_vga_render_disable(struct radeon_device *rdev); |
117 | int r100_cs_track_check_pkt3_indx_buffer(struct radeon_cs_parser *p, | 116 | int r100_cs_track_check_pkt3_indx_buffer(struct radeon_cs_parser *p, |
@@ -126,7 +125,7 @@ int r100_cs_packet_parse(struct radeon_cs_parser *p, | |||
126 | unsigned idx); | 125 | unsigned idx); |
127 | void r100_enable_bm(struct radeon_device *rdev); | 126 | void r100_enable_bm(struct radeon_device *rdev); |
128 | void r100_set_common_regs(struct radeon_device *rdev); | 127 | void r100_set_common_regs(struct radeon_device *rdev); |
129 | 128 | void r100_bm_disable(struct radeon_device *rdev); | |
130 | /* | 129 | /* |
131 | * r200,rv250,rs300,rv280 | 130 | * r200,rv250,rs300,rv280 |
132 | */ | 131 | */ |
@@ -134,7 +133,7 @@ extern int r200_copy_dma(struct radeon_device *rdev, | |||
134 | uint64_t src_offset, | 133 | uint64_t src_offset, |
135 | uint64_t dst_offset, | 134 | uint64_t dst_offset, |
136 | unsigned num_pages, | 135 | unsigned num_pages, |
137 | struct radeon_fence *fence); | 136 | struct radeon_fence *fence); |
138 | 137 | ||
139 | /* | 138 | /* |
140 | * r300,r350,rv350,rv380 | 139 | * r300,r350,rv350,rv380 |
@@ -143,7 +142,8 @@ extern int r300_init(struct radeon_device *rdev); | |||
143 | extern void r300_fini(struct radeon_device *rdev); | 142 | extern void r300_fini(struct radeon_device *rdev); |
144 | extern int r300_suspend(struct radeon_device *rdev); | 143 | extern int r300_suspend(struct radeon_device *rdev); |
145 | extern int r300_resume(struct radeon_device *rdev); | 144 | extern int r300_resume(struct radeon_device *rdev); |
146 | extern int r300_gpu_reset(struct radeon_device *rdev); | 145 | extern bool r300_gpu_is_lockup(struct radeon_device *rdev); |
146 | extern int r300_asic_reset(struct radeon_device *rdev); | ||
147 | extern void r300_ring_start(struct radeon_device *rdev); | 147 | extern void r300_ring_start(struct radeon_device *rdev); |
148 | extern void r300_fence_ring_emit(struct radeon_device *rdev, | 148 | extern void r300_fence_ring_emit(struct radeon_device *rdev, |
149 | struct radeon_fence *fence); | 149 | struct radeon_fence *fence); |
@@ -178,6 +178,7 @@ void rs400_mc_wreg(struct radeon_device *rdev, uint32_t reg, uint32_t v); | |||
178 | /* | 178 | /* |
179 | * rs600. | 179 | * rs600. |
180 | */ | 180 | */ |
181 | extern int rs600_asic_reset(struct radeon_device *rdev); | ||
181 | extern int rs600_init(struct radeon_device *rdev); | 182 | extern int rs600_init(struct radeon_device *rdev); |
182 | extern void rs600_fini(struct radeon_device *rdev); | 183 | extern void rs600_fini(struct radeon_device *rdev); |
183 | extern int rs600_suspend(struct radeon_device *rdev); | 184 | extern int rs600_suspend(struct radeon_device *rdev); |
@@ -212,7 +213,6 @@ void rs690_bandwidth_update(struct radeon_device *rdev); | |||
212 | */ | 213 | */ |
213 | int rv515_init(struct radeon_device *rdev); | 214 | int rv515_init(struct radeon_device *rdev); |
214 | void rv515_fini(struct radeon_device *rdev); | 215 | void rv515_fini(struct radeon_device *rdev); |
215 | int rv515_gpu_reset(struct radeon_device *rdev); | ||
216 | uint32_t rv515_mc_rreg(struct radeon_device *rdev, uint32_t reg); | 216 | uint32_t rv515_mc_rreg(struct radeon_device *rdev, uint32_t reg); |
217 | void rv515_mc_wreg(struct radeon_device *rdev, uint32_t reg, uint32_t v); | 217 | void rv515_mc_wreg(struct radeon_device *rdev, uint32_t reg, uint32_t v); |
218 | void rv515_ring_start(struct radeon_device *rdev); | 218 | void rv515_ring_start(struct radeon_device *rdev); |
@@ -252,7 +252,8 @@ int r600_copy_dma(struct radeon_device *rdev, | |||
252 | struct radeon_fence *fence); | 252 | struct radeon_fence *fence); |
253 | int r600_irq_process(struct radeon_device *rdev); | 253 | int r600_irq_process(struct radeon_device *rdev); |
254 | int r600_irq_set(struct radeon_device *rdev); | 254 | int r600_irq_set(struct radeon_device *rdev); |
255 | int r600_gpu_reset(struct radeon_device *rdev); | 255 | bool r600_gpu_is_lockup(struct radeon_device *rdev); |
256 | int r600_asic_reset(struct radeon_device *rdev); | ||
256 | int r600_set_surface_reg(struct radeon_device *rdev, int reg, | 257 | int r600_set_surface_reg(struct radeon_device *rdev, int reg, |
257 | uint32_t tiling_flags, uint32_t pitch, | 258 | uint32_t tiling_flags, uint32_t pitch, |
258 | uint32_t offset, uint32_t obj_size); | 259 | uint32_t offset, uint32_t obj_size); |
@@ -276,7 +277,6 @@ int rv770_init(struct radeon_device *rdev); | |||
276 | void rv770_fini(struct radeon_device *rdev); | 277 | void rv770_fini(struct radeon_device *rdev); |
277 | int rv770_suspend(struct radeon_device *rdev); | 278 | int rv770_suspend(struct radeon_device *rdev); |
278 | int rv770_resume(struct radeon_device *rdev); | 279 | int rv770_resume(struct radeon_device *rdev); |
279 | int rv770_gpu_reset(struct radeon_device *rdev); | ||
280 | 280 | ||
281 | /* | 281 | /* |
282 | * evergreen | 282 | * evergreen |
@@ -285,7 +285,8 @@ int evergreen_init(struct radeon_device *rdev); | |||
285 | void evergreen_fini(struct radeon_device *rdev); | 285 | void evergreen_fini(struct radeon_device *rdev); |
286 | int evergreen_suspend(struct radeon_device *rdev); | 286 | int evergreen_suspend(struct radeon_device *rdev); |
287 | int evergreen_resume(struct radeon_device *rdev); | 287 | int evergreen_resume(struct radeon_device *rdev); |
288 | int evergreen_gpu_reset(struct radeon_device *rdev); | 288 | bool evergreen_gpu_is_lockup(struct radeon_device *rdev); |
289 | int evergreen_asic_reset(struct radeon_device *rdev); | ||
289 | void evergreen_bandwidth_update(struct radeon_device *rdev); | 290 | void evergreen_bandwidth_update(struct radeon_device *rdev); |
290 | void evergreen_hpd_init(struct radeon_device *rdev); | 291 | void evergreen_hpd_init(struct radeon_device *rdev); |
291 | void evergreen_hpd_fini(struct radeon_device *rdev); | 292 | void evergreen_hpd_fini(struct radeon_device *rdev); |
diff --git a/drivers/gpu/drm/radeon/radeon_cs.c b/drivers/gpu/drm/radeon/radeon_cs.c index f9b0fe002c0a..ae0fb7356e62 100644 --- a/drivers/gpu/drm/radeon/radeon_cs.c +++ b/drivers/gpu/drm/radeon/radeon_cs.c | |||
@@ -220,10 +220,6 @@ int radeon_cs_ioctl(struct drm_device *dev, void *data, struct drm_file *filp) | |||
220 | int r; | 220 | int r; |
221 | 221 | ||
222 | mutex_lock(&rdev->cs_mutex); | 222 | mutex_lock(&rdev->cs_mutex); |
223 | if (rdev->gpu_lockup) { | ||
224 | mutex_unlock(&rdev->cs_mutex); | ||
225 | return -EINVAL; | ||
226 | } | ||
227 | /* initialize parser */ | 223 | /* initialize parser */ |
228 | memset(&parser, 0, sizeof(struct radeon_cs_parser)); | 224 | memset(&parser, 0, sizeof(struct radeon_cs_parser)); |
229 | parser.filp = filp; | 225 | parser.filp = filp; |
diff --git a/drivers/gpu/drm/radeon/radeon_device.c b/drivers/gpu/drm/radeon/radeon_device.c index 7b629e305560..001779d678b5 100644 --- a/drivers/gpu/drm/radeon/radeon_device.c +++ b/drivers/gpu/drm/radeon/radeon_device.c | |||
@@ -671,7 +671,7 @@ int radeon_device_init(struct radeon_device *rdev, | |||
671 | /* Acceleration not working on AGP card try again | 671 | /* Acceleration not working on AGP card try again |
672 | * with fallback to PCI or PCIE GART | 672 | * with fallback to PCI or PCIE GART |
673 | */ | 673 | */ |
674 | radeon_gpu_reset(rdev); | 674 | radeon_asic_reset(rdev); |
675 | radeon_fini(rdev); | 675 | radeon_fini(rdev); |
676 | radeon_agp_disable(rdev); | 676 | radeon_agp_disable(rdev); |
677 | r = radeon_init(rdev); | 677 | r = radeon_init(rdev); |
@@ -691,6 +691,8 @@ void radeon_device_fini(struct radeon_device *rdev) | |||
691 | { | 691 | { |
692 | DRM_INFO("radeon: finishing device.\n"); | 692 | DRM_INFO("radeon: finishing device.\n"); |
693 | rdev->shutdown = true; | 693 | rdev->shutdown = true; |
694 | /* evict vram memory */ | ||
695 | radeon_bo_evict_vram(rdev); | ||
694 | radeon_fini(rdev); | 696 | radeon_fini(rdev); |
695 | destroy_workqueue(rdev->wq); | 697 | destroy_workqueue(rdev->wq); |
696 | vga_switcheroo_unregister_client(rdev->pdev); | 698 | vga_switcheroo_unregister_client(rdev->pdev); |
@@ -789,6 +791,26 @@ int radeon_resume_kms(struct drm_device *dev) | |||
789 | return 0; | 791 | return 0; |
790 | } | 792 | } |
791 | 793 | ||
794 | int radeon_gpu_reset(struct radeon_device *rdev) | ||
795 | { | ||
796 | int r; | ||
797 | |||
798 | radeon_save_bios_scratch_regs(rdev); | ||
799 | radeon_suspend(rdev); | ||
800 | |||
801 | r = radeon_asic_reset(rdev); | ||
802 | if (!r) { | ||
803 | dev_info(rdev->dev, "GPU reset succeed\n"); | ||
804 | radeon_resume(rdev); | ||
805 | radeon_restore_bios_scratch_regs(rdev); | ||
806 | drm_helper_resume_force_mode(rdev->ddev); | ||
807 | return 0; | ||
808 | } | ||
809 | /* bad news, how to tell it to userspace ? */ | ||
810 | dev_info(rdev->dev, "GPU reset failed\n"); | ||
811 | return r; | ||
812 | } | ||
813 | |||
792 | 814 | ||
793 | /* | 815 | /* |
794 | * Debugfs | 816 | * Debugfs |
diff --git a/drivers/gpu/drm/radeon/radeon_fence.c b/drivers/gpu/drm/radeon/radeon_fence.c index d90f95b405c5..1b8b9cc271f2 100644 --- a/drivers/gpu/drm/radeon/radeon_fence.c +++ b/drivers/gpu/drm/radeon/radeon_fence.c | |||
@@ -58,7 +58,6 @@ int radeon_fence_emit(struct radeon_device *rdev, struct radeon_fence *fence) | |||
58 | radeon_fence_ring_emit(rdev, fence); | 58 | radeon_fence_ring_emit(rdev, fence); |
59 | 59 | ||
60 | fence->emited = true; | 60 | fence->emited = true; |
61 | fence->timeout = jiffies + ((2000 * HZ) / 1000); | ||
62 | list_del(&fence->list); | 61 | list_del(&fence->list); |
63 | list_add_tail(&fence->list, &rdev->fence_drv.emited); | 62 | list_add_tail(&fence->list, &rdev->fence_drv.emited); |
64 | write_unlock_irqrestore(&rdev->fence_drv.lock, irq_flags); | 63 | write_unlock_irqrestore(&rdev->fence_drv.lock, irq_flags); |
@@ -71,15 +70,34 @@ static bool radeon_fence_poll_locked(struct radeon_device *rdev) | |||
71 | struct list_head *i, *n; | 70 | struct list_head *i, *n; |
72 | uint32_t seq; | 71 | uint32_t seq; |
73 | bool wake = false; | 72 | bool wake = false; |
73 | unsigned long cjiffies; | ||
74 | 74 | ||
75 | if (rdev == NULL) { | ||
76 | return true; | ||
77 | } | ||
78 | if (rdev->shutdown) { | ||
79 | return true; | ||
80 | } | ||
81 | seq = RREG32(rdev->fence_drv.scratch_reg); | 75 | seq = RREG32(rdev->fence_drv.scratch_reg); |
82 | rdev->fence_drv.last_seq = seq; | 76 | if (seq != rdev->fence_drv.last_seq) { |
77 | rdev->fence_drv.last_seq = seq; | ||
78 | rdev->fence_drv.last_jiffies = jiffies; | ||
79 | rdev->fence_drv.last_timeout = RADEON_FENCE_JIFFIES_TIMEOUT; | ||
80 | } else { | ||
81 | cjiffies = jiffies; | ||
82 | if (time_after(cjiffies, rdev->fence_drv.last_jiffies)) { | ||
83 | cjiffies -= rdev->fence_drv.last_jiffies; | ||
84 | if (time_after(rdev->fence_drv.last_timeout, cjiffies)) { | ||
85 | /* update the timeout */ | ||
86 | rdev->fence_drv.last_timeout -= cjiffies; | ||
87 | } else { | ||
88 | /* the 500ms timeout is elapsed we should test | ||
89 | * for GPU lockup | ||
90 | */ | ||
91 | rdev->fence_drv.last_timeout = 1; | ||
92 | } | ||
93 | } else { | ||
94 | /* wrap around update last jiffies, we will just wait | ||
95 | * a little longer | ||
96 | */ | ||
97 | rdev->fence_drv.last_jiffies = cjiffies; | ||
98 | } | ||
99 | return false; | ||
100 | } | ||
83 | n = NULL; | 101 | n = NULL; |
84 | list_for_each(i, &rdev->fence_drv.emited) { | 102 | list_for_each(i, &rdev->fence_drv.emited) { |
85 | fence = list_entry(i, struct radeon_fence, list); | 103 | fence = list_entry(i, struct radeon_fence, list); |
@@ -171,9 +189,8 @@ bool radeon_fence_signaled(struct radeon_fence *fence) | |||
171 | int radeon_fence_wait(struct radeon_fence *fence, bool intr) | 189 | int radeon_fence_wait(struct radeon_fence *fence, bool intr) |
172 | { | 190 | { |
173 | struct radeon_device *rdev; | 191 | struct radeon_device *rdev; |
174 | unsigned long cur_jiffies; | 192 | unsigned long irq_flags, timeout; |
175 | unsigned long timeout; | 193 | u32 seq; |
176 | bool expired = false; | ||
177 | int r; | 194 | int r; |
178 | 195 | ||
179 | if (fence == NULL) { | 196 | if (fence == NULL) { |
@@ -184,21 +201,18 @@ int radeon_fence_wait(struct radeon_fence *fence, bool intr) | |||
184 | if (radeon_fence_signaled(fence)) { | 201 | if (radeon_fence_signaled(fence)) { |
185 | return 0; | 202 | return 0; |
186 | } | 203 | } |
187 | 204 | timeout = rdev->fence_drv.last_timeout; | |
188 | retry: | 205 | retry: |
189 | cur_jiffies = jiffies; | 206 | /* save current sequence used to check for GPU lockup */ |
190 | timeout = HZ / 100; | 207 | seq = rdev->fence_drv.last_seq; |
191 | if (time_after(fence->timeout, cur_jiffies)) { | ||
192 | timeout = fence->timeout - cur_jiffies; | ||
193 | } | ||
194 | |||
195 | if (intr) { | 208 | if (intr) { |
196 | radeon_irq_kms_sw_irq_get(rdev); | 209 | radeon_irq_kms_sw_irq_get(rdev); |
197 | r = wait_event_interruptible_timeout(rdev->fence_drv.queue, | 210 | r = wait_event_interruptible_timeout(rdev->fence_drv.queue, |
198 | radeon_fence_signaled(fence), timeout); | 211 | radeon_fence_signaled(fence), timeout); |
199 | radeon_irq_kms_sw_irq_put(rdev); | 212 | radeon_irq_kms_sw_irq_put(rdev); |
200 | if (unlikely(r < 0)) | 213 | if (unlikely(r < 0)) { |
201 | return r; | 214 | return r; |
215 | } | ||
202 | } else { | 216 | } else { |
203 | radeon_irq_kms_sw_irq_get(rdev); | 217 | radeon_irq_kms_sw_irq_get(rdev); |
204 | r = wait_event_timeout(rdev->fence_drv.queue, | 218 | r = wait_event_timeout(rdev->fence_drv.queue, |
@@ -206,38 +220,36 @@ retry: | |||
206 | radeon_irq_kms_sw_irq_put(rdev); | 220 | radeon_irq_kms_sw_irq_put(rdev); |
207 | } | 221 | } |
208 | if (unlikely(!radeon_fence_signaled(fence))) { | 222 | if (unlikely(!radeon_fence_signaled(fence))) { |
209 | if (unlikely(r == 0)) { | 223 | /* we were interrupted for some reason and fence isn't |
210 | expired = true; | 224 | * isn't signaled yet, resume wait |
225 | */ | ||
226 | if (r) { | ||
227 | timeout = r; | ||
228 | goto retry; | ||
211 | } | 229 | } |
212 | if (unlikely(expired)) { | 230 | /* don't protect read access to rdev->fence_drv.last_seq |
213 | timeout = 1; | 231 | * if we experiencing a lockup the value doesn't change |
214 | if (time_after(cur_jiffies, fence->timeout)) { | 232 | */ |
215 | timeout = cur_jiffies - fence->timeout; | 233 | if (seq == rdev->fence_drv.last_seq && radeon_gpu_is_lockup(rdev)) { |
216 | } | 234 | /* good news we believe it's a lockup */ |
217 | timeout = jiffies_to_msecs(timeout); | 235 | WARN(1, "GPU lockup (waiting for 0x%08X last fence id 0x%08X)\n", fence->seq, seq); |
218 | if (timeout > 500) { | 236 | /* FIXME: what should we do ? marking everyone |
219 | DRM_ERROR("fence(%p:0x%08X) %lums timeout " | 237 | * as signaled for now |
220 | "going to reset GPU\n", | 238 | */ |
221 | fence, fence->seq, timeout); | 239 | rdev->gpu_lockup = true; |
222 | radeon_gpu_reset(rdev); | 240 | WREG32(rdev->fence_drv.scratch_reg, fence->seq); |
223 | WREG32(rdev->fence_drv.scratch_reg, fence->seq); | 241 | r = radeon_gpu_reset(rdev); |
224 | } | 242 | if (r) |
243 | return r; | ||
244 | rdev->gpu_lockup = false; | ||
225 | } | 245 | } |
246 | timeout = RADEON_FENCE_JIFFIES_TIMEOUT; | ||
247 | write_lock_irqsave(&rdev->fence_drv.lock, irq_flags); | ||
248 | rdev->fence_drv.last_timeout = RADEON_FENCE_JIFFIES_TIMEOUT; | ||
249 | rdev->fence_drv.last_jiffies = jiffies; | ||
250 | write_unlock_irqrestore(&rdev->fence_drv.lock, irq_flags); | ||
226 | goto retry; | 251 | goto retry; |
227 | } | 252 | } |
228 | if (unlikely(expired)) { | ||
229 | rdev->fence_drv.count_timeout++; | ||
230 | cur_jiffies = jiffies; | ||
231 | timeout = 1; | ||
232 | if (time_after(cur_jiffies, fence->timeout)) { | ||
233 | timeout = cur_jiffies - fence->timeout; | ||
234 | } | ||
235 | timeout = jiffies_to_msecs(timeout); | ||
236 | DRM_ERROR("fence(%p:0x%08X) %lums timeout\n", | ||
237 | fence, fence->seq, timeout); | ||
238 | DRM_ERROR("last signaled fence(0x%08X)\n", | ||
239 | rdev->fence_drv.last_seq); | ||
240 | } | ||
241 | return 0; | 253 | return 0; |
242 | } | 254 | } |
243 | 255 | ||
@@ -333,7 +345,6 @@ int radeon_fence_driver_init(struct radeon_device *rdev) | |||
333 | INIT_LIST_HEAD(&rdev->fence_drv.created); | 345 | INIT_LIST_HEAD(&rdev->fence_drv.created); |
334 | INIT_LIST_HEAD(&rdev->fence_drv.emited); | 346 | INIT_LIST_HEAD(&rdev->fence_drv.emited); |
335 | INIT_LIST_HEAD(&rdev->fence_drv.signaled); | 347 | INIT_LIST_HEAD(&rdev->fence_drv.signaled); |
336 | rdev->fence_drv.count_timeout = 0; | ||
337 | init_waitqueue_head(&rdev->fence_drv.queue); | 348 | init_waitqueue_head(&rdev->fence_drv.queue); |
338 | rdev->fence_drv.initialized = true; | 349 | rdev->fence_drv.initialized = true; |
339 | write_unlock_irqrestore(&rdev->fence_drv.lock, irq_flags); | 350 | write_unlock_irqrestore(&rdev->fence_drv.lock, irq_flags); |
diff --git a/drivers/gpu/drm/radeon/radeon_gart.c b/drivers/gpu/drm/radeon/radeon_gart.c index 1770d3c07fd0..e65b90317fab 100644 --- a/drivers/gpu/drm/radeon/radeon_gart.c +++ b/drivers/gpu/drm/radeon/radeon_gart.c | |||
@@ -173,7 +173,7 @@ int radeon_gart_bind(struct radeon_device *rdev, unsigned offset, | |||
173 | int i, j; | 173 | int i, j; |
174 | 174 | ||
175 | if (!rdev->gart.ready) { | 175 | if (!rdev->gart.ready) { |
176 | DRM_ERROR("trying to bind memory to unitialized GART !\n"); | 176 | WARN(1, "trying to bind memory to unitialized GART !\n"); |
177 | return -EINVAL; | 177 | return -EINVAL; |
178 | } | 178 | } |
179 | t = offset / RADEON_GPU_PAGE_SIZE; | 179 | t = offset / RADEON_GPU_PAGE_SIZE; |
diff --git a/drivers/gpu/drm/radeon/rs400.c b/drivers/gpu/drm/radeon/rs400.c index 1a41cb268b72..dc76fe76eb25 100644 --- a/drivers/gpu/drm/radeon/rs400.c +++ b/drivers/gpu/drm/radeon/rs400.c | |||
@@ -243,8 +243,6 @@ int rs400_mc_wait_for_idle(struct radeon_device *rdev) | |||
243 | 243 | ||
244 | void rs400_gpu_init(struct radeon_device *rdev) | 244 | void rs400_gpu_init(struct radeon_device *rdev) |
245 | { | 245 | { |
246 | /* FIXME: HDP same place on rs400 ? */ | ||
247 | r100_hdp_reset(rdev); | ||
248 | /* FIXME: is this correct ? */ | 246 | /* FIXME: is this correct ? */ |
249 | r420_pipes_init(rdev); | 247 | r420_pipes_init(rdev); |
250 | if (rs400_mc_wait_for_idle(rdev)) { | 248 | if (rs400_mc_wait_for_idle(rdev)) { |
@@ -433,7 +431,7 @@ int rs400_resume(struct radeon_device *rdev) | |||
433 | /* setup MC before calling post tables */ | 431 | /* setup MC before calling post tables */ |
434 | rs400_mc_program(rdev); | 432 | rs400_mc_program(rdev); |
435 | /* Reset gpu before posting otherwise ATOM will enter infinite loop */ | 433 | /* Reset gpu before posting otherwise ATOM will enter infinite loop */ |
436 | if (radeon_gpu_reset(rdev)) { | 434 | if (radeon_asic_reset(rdev)) { |
437 | dev_warn(rdev->dev, "GPU reset failed ! (0xE40=0x%08X, 0x7C0=0x%08X)\n", | 435 | dev_warn(rdev->dev, "GPU reset failed ! (0xE40=0x%08X, 0x7C0=0x%08X)\n", |
438 | RREG32(R_000E40_RBBM_STATUS), | 436 | RREG32(R_000E40_RBBM_STATUS), |
439 | RREG32(R_0007C0_CP_STAT)); | 437 | RREG32(R_0007C0_CP_STAT)); |
@@ -497,7 +495,7 @@ int rs400_init(struct radeon_device *rdev) | |||
497 | return r; | 495 | return r; |
498 | } | 496 | } |
499 | /* Reset gpu before posting otherwise ATOM will enter infinite loop */ | 497 | /* Reset gpu before posting otherwise ATOM will enter infinite loop */ |
500 | if (radeon_gpu_reset(rdev)) { | 498 | if (radeon_asic_reset(rdev)) { |
501 | dev_warn(rdev->dev, | 499 | dev_warn(rdev->dev, |
502 | "GPU reset failed ! (0xE40=0x%08X, 0x7C0=0x%08X)\n", | 500 | "GPU reset failed ! (0xE40=0x%08X, 0x7C0=0x%08X)\n", |
503 | RREG32(R_000E40_RBBM_STATUS), | 501 | RREG32(R_000E40_RBBM_STATUS), |
diff --git a/drivers/gpu/drm/radeon/rs600.c b/drivers/gpu/drm/radeon/rs600.c index a81bc7a21e14..5e3f21861f45 100644 --- a/drivers/gpu/drm/radeon/rs600.c +++ b/drivers/gpu/drm/radeon/rs600.c | |||
@@ -147,6 +147,78 @@ void rs600_hpd_fini(struct radeon_device *rdev) | |||
147 | } | 147 | } |
148 | } | 148 | } |
149 | 149 | ||
150 | void rs600_bm_disable(struct radeon_device *rdev) | ||
151 | { | ||
152 | u32 tmp; | ||
153 | |||
154 | /* disable bus mastering */ | ||
155 | pci_read_config_word(rdev->pdev, 0x4, (u16*)&tmp); | ||
156 | pci_write_config_word(rdev->pdev, 0x4, tmp & 0xFFFB); | ||
157 | mdelay(1); | ||
158 | } | ||
159 | |||
160 | int rs600_asic_reset(struct radeon_device *rdev) | ||
161 | { | ||
162 | u32 status, tmp; | ||
163 | |||
164 | struct rv515_mc_save save; | ||
165 | |||
166 | /* Stops all mc clients */ | ||
167 | rv515_mc_stop(rdev, &save); | ||
168 | status = RREG32(R_000E40_RBBM_STATUS); | ||
169 | if (!G_000E40_GUI_ACTIVE(status)) { | ||
170 | return 0; | ||
171 | } | ||
172 | status = RREG32(R_000E40_RBBM_STATUS); | ||
173 | dev_info(rdev->dev, "(%s:%d) RBBM_STATUS=0x%08X\n", __func__, __LINE__, status); | ||
174 | /* stop CP */ | ||
175 | WREG32(RADEON_CP_CSQ_CNTL, 0); | ||
176 | tmp = RREG32(RADEON_CP_RB_CNTL); | ||
177 | WREG32(RADEON_CP_RB_CNTL, tmp | RADEON_RB_RPTR_WR_ENA); | ||
178 | WREG32(RADEON_CP_RB_RPTR_WR, 0); | ||
179 | WREG32(RADEON_CP_RB_WPTR, 0); | ||
180 | WREG32(RADEON_CP_RB_CNTL, tmp); | ||
181 | pci_save_state(rdev->pdev); | ||
182 | /* disable bus mastering */ | ||
183 | rs600_bm_disable(rdev); | ||
184 | /* reset GA+VAP */ | ||
185 | WREG32(R_0000F0_RBBM_SOFT_RESET, S_0000F0_SOFT_RESET_VAP(1) | | ||
186 | S_0000F0_SOFT_RESET_GA(1)); | ||
187 | RREG32(R_0000F0_RBBM_SOFT_RESET); | ||
188 | mdelay(500); | ||
189 | WREG32(R_0000F0_RBBM_SOFT_RESET, 0); | ||
190 | mdelay(1); | ||
191 | status = RREG32(R_000E40_RBBM_STATUS); | ||
192 | dev_info(rdev->dev, "(%s:%d) RBBM_STATUS=0x%08X\n", __func__, __LINE__, status); | ||
193 | /* reset CP */ | ||
194 | WREG32(R_0000F0_RBBM_SOFT_RESET, S_0000F0_SOFT_RESET_CP(1)); | ||
195 | RREG32(R_0000F0_RBBM_SOFT_RESET); | ||
196 | mdelay(500); | ||
197 | WREG32(R_0000F0_RBBM_SOFT_RESET, 0); | ||
198 | mdelay(1); | ||
199 | status = RREG32(R_000E40_RBBM_STATUS); | ||
200 | dev_info(rdev->dev, "(%s:%d) RBBM_STATUS=0x%08X\n", __func__, __LINE__, status); | ||
201 | /* reset MC */ | ||
202 | WREG32(R_0000F0_RBBM_SOFT_RESET, S_0000F0_SOFT_RESET_MC(1)); | ||
203 | RREG32(R_0000F0_RBBM_SOFT_RESET); | ||
204 | mdelay(500); | ||
205 | WREG32(R_0000F0_RBBM_SOFT_RESET, 0); | ||
206 | mdelay(1); | ||
207 | status = RREG32(R_000E40_RBBM_STATUS); | ||
208 | dev_info(rdev->dev, "(%s:%d) RBBM_STATUS=0x%08X\n", __func__, __LINE__, status); | ||
209 | /* restore PCI & busmastering */ | ||
210 | pci_restore_state(rdev->pdev); | ||
211 | /* Check if GPU is idle */ | ||
212 | if (G_000E40_GA_BUSY(status) || G_000E40_VAP_BUSY(status)) { | ||
213 | dev_err(rdev->dev, "failed to reset GPU\n"); | ||
214 | rdev->gpu_lockup = true; | ||
215 | return -1; | ||
216 | } | ||
217 | rv515_mc_resume(rdev, &save); | ||
218 | dev_info(rdev->dev, "GPU reset succeed\n"); | ||
219 | return 0; | ||
220 | } | ||
221 | |||
150 | /* | 222 | /* |
151 | * GART. | 223 | * GART. |
152 | */ | 224 | */ |
@@ -454,7 +526,6 @@ int rs600_mc_wait_for_idle(struct radeon_device *rdev) | |||
454 | 526 | ||
455 | void rs600_gpu_init(struct radeon_device *rdev) | 527 | void rs600_gpu_init(struct radeon_device *rdev) |
456 | { | 528 | { |
457 | r100_hdp_reset(rdev); | ||
458 | r420_pipes_init(rdev); | 529 | r420_pipes_init(rdev); |
459 | /* Wait for mc idle */ | 530 | /* Wait for mc idle */ |
460 | if (rs600_mc_wait_for_idle(rdev)) | 531 | if (rs600_mc_wait_for_idle(rdev)) |
@@ -601,7 +672,7 @@ int rs600_resume(struct radeon_device *rdev) | |||
601 | /* Resume clock before doing reset */ | 672 | /* Resume clock before doing reset */ |
602 | rv515_clock_startup(rdev); | 673 | rv515_clock_startup(rdev); |
603 | /* Reset gpu before posting otherwise ATOM will enter infinite loop */ | 674 | /* Reset gpu before posting otherwise ATOM will enter infinite loop */ |
604 | if (radeon_gpu_reset(rdev)) { | 675 | if (radeon_asic_reset(rdev)) { |
605 | dev_warn(rdev->dev, "GPU reset failed ! (0xE40=0x%08X, 0x7C0=0x%08X)\n", | 676 | dev_warn(rdev->dev, "GPU reset failed ! (0xE40=0x%08X, 0x7C0=0x%08X)\n", |
606 | RREG32(R_000E40_RBBM_STATUS), | 677 | RREG32(R_000E40_RBBM_STATUS), |
607 | RREG32(R_0007C0_CP_STAT)); | 678 | RREG32(R_0007C0_CP_STAT)); |
@@ -664,7 +735,7 @@ int rs600_init(struct radeon_device *rdev) | |||
664 | return -EINVAL; | 735 | return -EINVAL; |
665 | } | 736 | } |
666 | /* Reset gpu before posting otherwise ATOM will enter infinite loop */ | 737 | /* Reset gpu before posting otherwise ATOM will enter infinite loop */ |
667 | if (radeon_gpu_reset(rdev)) { | 738 | if (radeon_asic_reset(rdev)) { |
668 | dev_warn(rdev->dev, | 739 | dev_warn(rdev->dev, |
669 | "GPU reset failed ! (0xE40=0x%08X, 0x7C0=0x%08X)\n", | 740 | "GPU reset failed ! (0xE40=0x%08X, 0x7C0=0x%08X)\n", |
670 | RREG32(R_000E40_RBBM_STATUS), | 741 | RREG32(R_000E40_RBBM_STATUS), |
diff --git a/drivers/gpu/drm/radeon/rs600d.h b/drivers/gpu/drm/radeon/rs600d.h index e52d2695510b..08c4bebd3011 100644 --- a/drivers/gpu/drm/radeon/rs600d.h +++ b/drivers/gpu/drm/radeon/rs600d.h | |||
@@ -178,6 +178,52 @@ | |||
178 | #define S_000074_MC_IND_DATA(x) (((x) & 0xFFFFFFFF) << 0) | 178 | #define S_000074_MC_IND_DATA(x) (((x) & 0xFFFFFFFF) << 0) |
179 | #define G_000074_MC_IND_DATA(x) (((x) >> 0) & 0xFFFFFFFF) | 179 | #define G_000074_MC_IND_DATA(x) (((x) >> 0) & 0xFFFFFFFF) |
180 | #define C_000074_MC_IND_DATA 0x00000000 | 180 | #define C_000074_MC_IND_DATA 0x00000000 |
181 | #define R_0000F0_RBBM_SOFT_RESET 0x0000F0 | ||
182 | #define S_0000F0_SOFT_RESET_CP(x) (((x) & 0x1) << 0) | ||
183 | #define G_0000F0_SOFT_RESET_CP(x) (((x) >> 0) & 0x1) | ||
184 | #define C_0000F0_SOFT_RESET_CP 0xFFFFFFFE | ||
185 | #define S_0000F0_SOFT_RESET_HI(x) (((x) & 0x1) << 1) | ||
186 | #define G_0000F0_SOFT_RESET_HI(x) (((x) >> 1) & 0x1) | ||
187 | #define C_0000F0_SOFT_RESET_HI 0xFFFFFFFD | ||
188 | #define S_0000F0_SOFT_RESET_VAP(x) (((x) & 0x1) << 2) | ||
189 | #define G_0000F0_SOFT_RESET_VAP(x) (((x) >> 2) & 0x1) | ||
190 | #define C_0000F0_SOFT_RESET_VAP 0xFFFFFFFB | ||
191 | #define S_0000F0_SOFT_RESET_RE(x) (((x) & 0x1) << 3) | ||
192 | #define G_0000F0_SOFT_RESET_RE(x) (((x) >> 3) & 0x1) | ||
193 | #define C_0000F0_SOFT_RESET_RE 0xFFFFFFF7 | ||
194 | #define S_0000F0_SOFT_RESET_PP(x) (((x) & 0x1) << 4) | ||
195 | #define G_0000F0_SOFT_RESET_PP(x) (((x) >> 4) & 0x1) | ||
196 | #define C_0000F0_SOFT_RESET_PP 0xFFFFFFEF | ||
197 | #define S_0000F0_SOFT_RESET_E2(x) (((x) & 0x1) << 5) | ||
198 | #define G_0000F0_SOFT_RESET_E2(x) (((x) >> 5) & 0x1) | ||
199 | #define C_0000F0_SOFT_RESET_E2 0xFFFFFFDF | ||
200 | #define S_0000F0_SOFT_RESET_RB(x) (((x) & 0x1) << 6) | ||
201 | #define G_0000F0_SOFT_RESET_RB(x) (((x) >> 6) & 0x1) | ||
202 | #define C_0000F0_SOFT_RESET_RB 0xFFFFFFBF | ||
203 | #define S_0000F0_SOFT_RESET_HDP(x) (((x) & 0x1) << 7) | ||
204 | #define G_0000F0_SOFT_RESET_HDP(x) (((x) >> 7) & 0x1) | ||
205 | #define C_0000F0_SOFT_RESET_HDP 0xFFFFFF7F | ||
206 | #define S_0000F0_SOFT_RESET_MC(x) (((x) & 0x1) << 8) | ||
207 | #define G_0000F0_SOFT_RESET_MC(x) (((x) >> 8) & 0x1) | ||
208 | #define C_0000F0_SOFT_RESET_MC 0xFFFFFEFF | ||
209 | #define S_0000F0_SOFT_RESET_AIC(x) (((x) & 0x1) << 9) | ||
210 | #define G_0000F0_SOFT_RESET_AIC(x) (((x) >> 9) & 0x1) | ||
211 | #define C_0000F0_SOFT_RESET_AIC 0xFFFFFDFF | ||
212 | #define S_0000F0_SOFT_RESET_VIP(x) (((x) & 0x1) << 10) | ||
213 | #define G_0000F0_SOFT_RESET_VIP(x) (((x) >> 10) & 0x1) | ||
214 | #define C_0000F0_SOFT_RESET_VIP 0xFFFFFBFF | ||
215 | #define S_0000F0_SOFT_RESET_DISP(x) (((x) & 0x1) << 11) | ||
216 | #define G_0000F0_SOFT_RESET_DISP(x) (((x) >> 11) & 0x1) | ||
217 | #define C_0000F0_SOFT_RESET_DISP 0xFFFFF7FF | ||
218 | #define S_0000F0_SOFT_RESET_CG(x) (((x) & 0x1) << 12) | ||
219 | #define G_0000F0_SOFT_RESET_CG(x) (((x) >> 12) & 0x1) | ||
220 | #define C_0000F0_SOFT_RESET_CG 0xFFFFEFFF | ||
221 | #define S_0000F0_SOFT_RESET_GA(x) (((x) & 0x1) << 13) | ||
222 | #define G_0000F0_SOFT_RESET_GA(x) (((x) >> 13) & 0x1) | ||
223 | #define C_0000F0_SOFT_RESET_GA 0xFFFFDFFF | ||
224 | #define S_0000F0_SOFT_RESET_IDCT(x) (((x) & 0x1) << 14) | ||
225 | #define G_0000F0_SOFT_RESET_IDCT(x) (((x) >> 14) & 0x1) | ||
226 | #define C_0000F0_SOFT_RESET_IDCT 0xFFFFBFFF | ||
181 | #define R_000134_HDP_FB_LOCATION 0x000134 | 227 | #define R_000134_HDP_FB_LOCATION 0x000134 |
182 | #define S_000134_HDP_FB_START(x) (((x) & 0xFFFF) << 0) | 228 | #define S_000134_HDP_FB_START(x) (((x) & 0xFFFF) << 0) |
183 | #define G_000134_HDP_FB_START(x) (((x) >> 0) & 0xFFFF) | 229 | #define G_000134_HDP_FB_START(x) (((x) >> 0) & 0xFFFF) |
diff --git a/drivers/gpu/drm/radeon/rs690.c b/drivers/gpu/drm/radeon/rs690.c index bbf3da790fd5..56a0aec84af2 100644 --- a/drivers/gpu/drm/radeon/rs690.c +++ b/drivers/gpu/drm/radeon/rs690.c | |||
@@ -48,8 +48,6 @@ static int rs690_mc_wait_for_idle(struct radeon_device *rdev) | |||
48 | 48 | ||
49 | static void rs690_gpu_init(struct radeon_device *rdev) | 49 | static void rs690_gpu_init(struct radeon_device *rdev) |
50 | { | 50 | { |
51 | /* FIXME: HDP same place on rs690 ? */ | ||
52 | r100_hdp_reset(rdev); | ||
53 | /* FIXME: is this correct ? */ | 51 | /* FIXME: is this correct ? */ |
54 | r420_pipes_init(rdev); | 52 | r420_pipes_init(rdev); |
55 | if (rs690_mc_wait_for_idle(rdev)) { | 53 | if (rs690_mc_wait_for_idle(rdev)) { |
@@ -653,7 +651,7 @@ int rs690_resume(struct radeon_device *rdev) | |||
653 | /* Resume clock before doing reset */ | 651 | /* Resume clock before doing reset */ |
654 | rv515_clock_startup(rdev); | 652 | rv515_clock_startup(rdev); |
655 | /* Reset gpu before posting otherwise ATOM will enter infinite loop */ | 653 | /* Reset gpu before posting otherwise ATOM will enter infinite loop */ |
656 | if (radeon_gpu_reset(rdev)) { | 654 | if (radeon_asic_reset(rdev)) { |
657 | dev_warn(rdev->dev, "GPU reset failed ! (0xE40=0x%08X, 0x7C0=0x%08X)\n", | 655 | dev_warn(rdev->dev, "GPU reset failed ! (0xE40=0x%08X, 0x7C0=0x%08X)\n", |
658 | RREG32(R_000E40_RBBM_STATUS), | 656 | RREG32(R_000E40_RBBM_STATUS), |
659 | RREG32(R_0007C0_CP_STAT)); | 657 | RREG32(R_0007C0_CP_STAT)); |
@@ -717,7 +715,7 @@ int rs690_init(struct radeon_device *rdev) | |||
717 | return -EINVAL; | 715 | return -EINVAL; |
718 | } | 716 | } |
719 | /* Reset gpu before posting otherwise ATOM will enter infinite loop */ | 717 | /* Reset gpu before posting otherwise ATOM will enter infinite loop */ |
720 | if (radeon_gpu_reset(rdev)) { | 718 | if (radeon_asic_reset(rdev)) { |
721 | dev_warn(rdev->dev, | 719 | dev_warn(rdev->dev, |
722 | "GPU reset failed ! (0xE40=0x%08X, 0x7C0=0x%08X)\n", | 720 | "GPU reset failed ! (0xE40=0x%08X, 0x7C0=0x%08X)\n", |
723 | RREG32(R_000E40_RBBM_STATUS), | 721 | RREG32(R_000E40_RBBM_STATUS), |
diff --git a/drivers/gpu/drm/radeon/rv515.c b/drivers/gpu/drm/radeon/rv515.c index 9035121f4b58..c513473d72ae 100644 --- a/drivers/gpu/drm/radeon/rv515.c +++ b/drivers/gpu/drm/radeon/rv515.c | |||
@@ -147,16 +147,11 @@ void rv515_gpu_init(struct radeon_device *rdev) | |||
147 | { | 147 | { |
148 | unsigned pipe_select_current, gb_pipe_select, tmp; | 148 | unsigned pipe_select_current, gb_pipe_select, tmp; |
149 | 149 | ||
150 | r100_hdp_reset(rdev); | ||
151 | r100_rb2d_reset(rdev); | ||
152 | |||
153 | if (r100_gui_wait_for_idle(rdev)) { | 150 | if (r100_gui_wait_for_idle(rdev)) { |
154 | printk(KERN_WARNING "Failed to wait GUI idle while " | 151 | printk(KERN_WARNING "Failed to wait GUI idle while " |
155 | "reseting GPU. Bad things might happen.\n"); | 152 | "reseting GPU. Bad things might happen.\n"); |
156 | } | 153 | } |
157 | |||
158 | rv515_vga_render_disable(rdev); | 154 | rv515_vga_render_disable(rdev); |
159 | |||
160 | r420_pipes_init(rdev); | 155 | r420_pipes_init(rdev); |
161 | gb_pipe_select = RREG32(0x402C); | 156 | gb_pipe_select = RREG32(0x402C); |
162 | tmp = RREG32(0x170C); | 157 | tmp = RREG32(0x170C); |
@@ -174,91 +169,6 @@ void rv515_gpu_init(struct radeon_device *rdev) | |||
174 | } | 169 | } |
175 | } | 170 | } |
176 | 171 | ||
177 | int rv515_ga_reset(struct radeon_device *rdev) | ||
178 | { | ||
179 | uint32_t tmp; | ||
180 | bool reinit_cp; | ||
181 | int i; | ||
182 | |||
183 | reinit_cp = rdev->cp.ready; | ||
184 | rdev->cp.ready = false; | ||
185 | for (i = 0; i < rdev->usec_timeout; i++) { | ||
186 | WREG32(CP_CSQ_MODE, 0); | ||
187 | WREG32(CP_CSQ_CNTL, 0); | ||
188 | WREG32(RBBM_SOFT_RESET, 0x32005); | ||
189 | (void)RREG32(RBBM_SOFT_RESET); | ||
190 | udelay(200); | ||
191 | WREG32(RBBM_SOFT_RESET, 0); | ||
192 | /* Wait to prevent race in RBBM_STATUS */ | ||
193 | mdelay(1); | ||
194 | tmp = RREG32(RBBM_STATUS); | ||
195 | if (tmp & ((1 << 20) | (1 << 26))) { | ||
196 | DRM_ERROR("VAP & CP still busy (RBBM_STATUS=0x%08X)\n", tmp); | ||
197 | /* GA still busy soft reset it */ | ||
198 | WREG32(0x429C, 0x200); | ||
199 | WREG32(VAP_PVS_STATE_FLUSH_REG, 0); | ||
200 | WREG32(0x43E0, 0); | ||
201 | WREG32(0x43E4, 0); | ||
202 | WREG32(0x24AC, 0); | ||
203 | } | ||
204 | /* Wait to prevent race in RBBM_STATUS */ | ||
205 | mdelay(1); | ||
206 | tmp = RREG32(RBBM_STATUS); | ||
207 | if (!(tmp & ((1 << 20) | (1 << 26)))) { | ||
208 | break; | ||
209 | } | ||
210 | } | ||
211 | for (i = 0; i < rdev->usec_timeout; i++) { | ||
212 | tmp = RREG32(RBBM_STATUS); | ||
213 | if (!(tmp & ((1 << 20) | (1 << 26)))) { | ||
214 | DRM_INFO("GA reset succeed (RBBM_STATUS=0x%08X)\n", | ||
215 | tmp); | ||
216 | DRM_INFO("GA_IDLE=0x%08X\n", RREG32(0x425C)); | ||
217 | DRM_INFO("RB3D_RESET_STATUS=0x%08X\n", RREG32(0x46f0)); | ||
218 | DRM_INFO("ISYNC_CNTL=0x%08X\n", RREG32(0x1724)); | ||
219 | if (reinit_cp) { | ||
220 | return r100_cp_init(rdev, rdev->cp.ring_size); | ||
221 | } | ||
222 | return 0; | ||
223 | } | ||
224 | DRM_UDELAY(1); | ||
225 | } | ||
226 | tmp = RREG32(RBBM_STATUS); | ||
227 | DRM_ERROR("Failed to reset GA ! (RBBM_STATUS=0x%08X)\n", tmp); | ||
228 | return -1; | ||
229 | } | ||
230 | |||
231 | int rv515_gpu_reset(struct radeon_device *rdev) | ||
232 | { | ||
233 | uint32_t status; | ||
234 | |||
235 | /* reset order likely matter */ | ||
236 | status = RREG32(RBBM_STATUS); | ||
237 | /* reset HDP */ | ||
238 | r100_hdp_reset(rdev); | ||
239 | /* reset rb2d */ | ||
240 | if (status & ((1 << 17) | (1 << 18) | (1 << 27))) { | ||
241 | r100_rb2d_reset(rdev); | ||
242 | } | ||
243 | /* reset GA */ | ||
244 | if (status & ((1 << 20) | (1 << 26))) { | ||
245 | rv515_ga_reset(rdev); | ||
246 | } | ||
247 | /* reset CP */ | ||
248 | status = RREG32(RBBM_STATUS); | ||
249 | if (status & (1 << 16)) { | ||
250 | r100_cp_reset(rdev); | ||
251 | } | ||
252 | /* Check if GPU is idle */ | ||
253 | status = RREG32(RBBM_STATUS); | ||
254 | if (status & (1 << 31)) { | ||
255 | DRM_ERROR("Failed to reset GPU (RBBM_STATUS=0x%08X)\n", status); | ||
256 | return -1; | ||
257 | } | ||
258 | DRM_INFO("GPU reset succeed (RBBM_STATUS=0x%08X)\n", status); | ||
259 | return 0; | ||
260 | } | ||
261 | |||
262 | static void rv515_vram_get_type(struct radeon_device *rdev) | 172 | static void rv515_vram_get_type(struct radeon_device *rdev) |
263 | { | 173 | { |
264 | uint32_t tmp; | 174 | uint32_t tmp; |
@@ -335,7 +245,7 @@ static int rv515_debugfs_ga_info(struct seq_file *m, void *data) | |||
335 | 245 | ||
336 | tmp = RREG32(0x2140); | 246 | tmp = RREG32(0x2140); |
337 | seq_printf(m, "VAP_CNTL_STATUS 0x%08x\n", tmp); | 247 | seq_printf(m, "VAP_CNTL_STATUS 0x%08x\n", tmp); |
338 | radeon_gpu_reset(rdev); | 248 | radeon_asic_reset(rdev); |
339 | tmp = RREG32(0x425C); | 249 | tmp = RREG32(0x425C); |
340 | seq_printf(m, "GA_IDLE 0x%08x\n", tmp); | 250 | seq_printf(m, "GA_IDLE 0x%08x\n", tmp); |
341 | return 0; | 251 | return 0; |
@@ -503,7 +413,7 @@ int rv515_resume(struct radeon_device *rdev) | |||
503 | /* Resume clock before doing reset */ | 413 | /* Resume clock before doing reset */ |
504 | rv515_clock_startup(rdev); | 414 | rv515_clock_startup(rdev); |
505 | /* Reset gpu before posting otherwise ATOM will enter infinite loop */ | 415 | /* Reset gpu before posting otherwise ATOM will enter infinite loop */ |
506 | if (radeon_gpu_reset(rdev)) { | 416 | if (radeon_asic_reset(rdev)) { |
507 | dev_warn(rdev->dev, "GPU reset failed ! (0xE40=0x%08X, 0x7C0=0x%08X)\n", | 417 | dev_warn(rdev->dev, "GPU reset failed ! (0xE40=0x%08X, 0x7C0=0x%08X)\n", |
508 | RREG32(R_000E40_RBBM_STATUS), | 418 | RREG32(R_000E40_RBBM_STATUS), |
509 | RREG32(R_0007C0_CP_STAT)); | 419 | RREG32(R_0007C0_CP_STAT)); |
@@ -573,7 +483,7 @@ int rv515_init(struct radeon_device *rdev) | |||
573 | return -EINVAL; | 483 | return -EINVAL; |
574 | } | 484 | } |
575 | /* Reset gpu before posting otherwise ATOM will enter infinite loop */ | 485 | /* Reset gpu before posting otherwise ATOM will enter infinite loop */ |
576 | if (radeon_gpu_reset(rdev)) { | 486 | if (radeon_asic_reset(rdev)) { |
577 | dev_warn(rdev->dev, | 487 | dev_warn(rdev->dev, |
578 | "GPU reset failed ! (0xE40=0x%08X, 0x7C0=0x%08X)\n", | 488 | "GPU reset failed ! (0xE40=0x%08X, 0x7C0=0x%08X)\n", |
579 | RREG32(R_000E40_RBBM_STATUS), | 489 | RREG32(R_000E40_RBBM_STATUS), |
diff --git a/drivers/gpu/drm/radeon/rv515d.h b/drivers/gpu/drm/radeon/rv515d.h index fc216e49384d..590309a710b1 100644 --- a/drivers/gpu/drm/radeon/rv515d.h +++ b/drivers/gpu/drm/radeon/rv515d.h | |||
@@ -217,6 +217,52 @@ | |||
217 | #define CP_PACKET3_GET_OPCODE(h) (((h) >> 8) & 0xFF) | 217 | #define CP_PACKET3_GET_OPCODE(h) (((h) >> 8) & 0xFF) |
218 | 218 | ||
219 | /* Registers */ | 219 | /* Registers */ |
220 | #define R_0000F0_RBBM_SOFT_RESET 0x0000F0 | ||
221 | #define S_0000F0_SOFT_RESET_CP(x) (((x) & 0x1) << 0) | ||
222 | #define G_0000F0_SOFT_RESET_CP(x) (((x) >> 0) & 0x1) | ||
223 | #define C_0000F0_SOFT_RESET_CP 0xFFFFFFFE | ||
224 | #define S_0000F0_SOFT_RESET_HI(x) (((x) & 0x1) << 1) | ||
225 | #define G_0000F0_SOFT_RESET_HI(x) (((x) >> 1) & 0x1) | ||
226 | #define C_0000F0_SOFT_RESET_HI 0xFFFFFFFD | ||
227 | #define S_0000F0_SOFT_RESET_VAP(x) (((x) & 0x1) << 2) | ||
228 | #define G_0000F0_SOFT_RESET_VAP(x) (((x) >> 2) & 0x1) | ||
229 | #define C_0000F0_SOFT_RESET_VAP 0xFFFFFFFB | ||
230 | #define S_0000F0_SOFT_RESET_RE(x) (((x) & 0x1) << 3) | ||
231 | #define G_0000F0_SOFT_RESET_RE(x) (((x) >> 3) & 0x1) | ||
232 | #define C_0000F0_SOFT_RESET_RE 0xFFFFFFF7 | ||
233 | #define S_0000F0_SOFT_RESET_PP(x) (((x) & 0x1) << 4) | ||
234 | #define G_0000F0_SOFT_RESET_PP(x) (((x) >> 4) & 0x1) | ||
235 | #define C_0000F0_SOFT_RESET_PP 0xFFFFFFEF | ||
236 | #define S_0000F0_SOFT_RESET_E2(x) (((x) & 0x1) << 5) | ||
237 | #define G_0000F0_SOFT_RESET_E2(x) (((x) >> 5) & 0x1) | ||
238 | #define C_0000F0_SOFT_RESET_E2 0xFFFFFFDF | ||
239 | #define S_0000F0_SOFT_RESET_RB(x) (((x) & 0x1) << 6) | ||
240 | #define G_0000F0_SOFT_RESET_RB(x) (((x) >> 6) & 0x1) | ||
241 | #define C_0000F0_SOFT_RESET_RB 0xFFFFFFBF | ||
242 | #define S_0000F0_SOFT_RESET_HDP(x) (((x) & 0x1) << 7) | ||
243 | #define G_0000F0_SOFT_RESET_HDP(x) (((x) >> 7) & 0x1) | ||
244 | #define C_0000F0_SOFT_RESET_HDP 0xFFFFFF7F | ||
245 | #define S_0000F0_SOFT_RESET_MC(x) (((x) & 0x1) << 8) | ||
246 | #define G_0000F0_SOFT_RESET_MC(x) (((x) >> 8) & 0x1) | ||
247 | #define C_0000F0_SOFT_RESET_MC 0xFFFFFEFF | ||
248 | #define S_0000F0_SOFT_RESET_AIC(x) (((x) & 0x1) << 9) | ||
249 | #define G_0000F0_SOFT_RESET_AIC(x) (((x) >> 9) & 0x1) | ||
250 | #define C_0000F0_SOFT_RESET_AIC 0xFFFFFDFF | ||
251 | #define S_0000F0_SOFT_RESET_VIP(x) (((x) & 0x1) << 10) | ||
252 | #define G_0000F0_SOFT_RESET_VIP(x) (((x) >> 10) & 0x1) | ||
253 | #define C_0000F0_SOFT_RESET_VIP 0xFFFFFBFF | ||
254 | #define S_0000F0_SOFT_RESET_DISP(x) (((x) & 0x1) << 11) | ||
255 | #define G_0000F0_SOFT_RESET_DISP(x) (((x) >> 11) & 0x1) | ||
256 | #define C_0000F0_SOFT_RESET_DISP 0xFFFFF7FF | ||
257 | #define S_0000F0_SOFT_RESET_CG(x) (((x) & 0x1) << 12) | ||
258 | #define G_0000F0_SOFT_RESET_CG(x) (((x) >> 12) & 0x1) | ||
259 | #define C_0000F0_SOFT_RESET_CG 0xFFFFEFFF | ||
260 | #define S_0000F0_SOFT_RESET_GA(x) (((x) & 0x1) << 13) | ||
261 | #define G_0000F0_SOFT_RESET_GA(x) (((x) >> 13) & 0x1) | ||
262 | #define C_0000F0_SOFT_RESET_GA 0xFFFFDFFF | ||
263 | #define S_0000F0_SOFT_RESET_IDCT(x) (((x) & 0x1) << 14) | ||
264 | #define G_0000F0_SOFT_RESET_IDCT(x) (((x) >> 14) & 0x1) | ||
265 | #define C_0000F0_SOFT_RESET_IDCT 0xFFFFBFFF | ||
220 | #define R_0000F8_CONFIG_MEMSIZE 0x0000F8 | 266 | #define R_0000F8_CONFIG_MEMSIZE 0x0000F8 |
221 | #define S_0000F8_CONFIG_MEMSIZE(x) (((x) & 0xFFFFFFFF) << 0) | 267 | #define S_0000F8_CONFIG_MEMSIZE(x) (((x) & 0xFFFFFFFF) << 0) |
222 | #define G_0000F8_CONFIG_MEMSIZE(x) (((x) >> 0) & 0xFFFFFFFF) | 268 | #define G_0000F8_CONFIG_MEMSIZE(x) (((x) >> 0) & 0xFFFFFFFF) |
diff --git a/drivers/gpu/drm/radeon/rv770.c b/drivers/gpu/drm/radeon/rv770.c index 97958a64df1a..72bc57a92388 100644 --- a/drivers/gpu/drm/radeon/rv770.c +++ b/drivers/gpu/drm/radeon/rv770.c | |||
@@ -917,12 +917,6 @@ int rv770_mc_init(struct radeon_device *rdev) | |||
917 | return 0; | 917 | return 0; |
918 | } | 918 | } |
919 | 919 | ||
920 | int rv770_gpu_reset(struct radeon_device *rdev) | ||
921 | { | ||
922 | /* FIXME: implement any rv770 specific bits */ | ||
923 | return r600_gpu_reset(rdev); | ||
924 | } | ||
925 | |||
926 | static int rv770_startup(struct radeon_device *rdev) | 920 | static int rv770_startup(struct radeon_device *rdev) |
927 | { | 921 | { |
928 | int r; | 922 | int r; |