diff options
Diffstat (limited to 'drivers/gpu/drm/radeon/ni.c')
-rw-r--r-- | drivers/gpu/drm/radeon/ni.c | 373 |
1 files changed, 39 insertions, 334 deletions
diff --git a/drivers/gpu/drm/radeon/ni.c b/drivers/gpu/drm/radeon/ni.c index ccb4f8b54852..93c1f9ef5da9 100644 --- a/drivers/gpu/drm/radeon/ni.c +++ b/drivers/gpu/drm/radeon/ni.c | |||
@@ -35,7 +35,7 @@ | |||
35 | #include "radeon_ucode.h" | 35 | #include "radeon_ucode.h" |
36 | #include "clearstate_cayman.h" | 36 | #include "clearstate_cayman.h" |
37 | 37 | ||
38 | static u32 tn_rlc_save_restore_register_list[] = | 38 | static const u32 tn_rlc_save_restore_register_list[] = |
39 | { | 39 | { |
40 | 0x98fc, | 40 | 0x98fc, |
41 | 0x98f0, | 41 | 0x98f0, |
@@ -160,7 +160,6 @@ static u32 tn_rlc_save_restore_register_list[] = | |||
160 | 0x9830, | 160 | 0x9830, |
161 | 0x802c, | 161 | 0x802c, |
162 | }; | 162 | }; |
163 | static u32 tn_rlc_save_restore_register_list_size = ARRAY_SIZE(tn_rlc_save_restore_register_list); | ||
164 | 163 | ||
165 | extern bool evergreen_is_display_hung(struct radeon_device *rdev); | 164 | extern bool evergreen_is_display_hung(struct radeon_device *rdev); |
166 | extern void evergreen_print_gpu_status_regs(struct radeon_device *rdev); | 165 | extern void evergreen_print_gpu_status_regs(struct radeon_device *rdev); |
@@ -175,6 +174,11 @@ extern void evergreen_pcie_gen2_enable(struct radeon_device *rdev); | |||
175 | extern void evergreen_program_aspm(struct radeon_device *rdev); | 174 | extern void evergreen_program_aspm(struct radeon_device *rdev); |
176 | extern void sumo_rlc_fini(struct radeon_device *rdev); | 175 | extern void sumo_rlc_fini(struct radeon_device *rdev); |
177 | extern int sumo_rlc_init(struct radeon_device *rdev); | 176 | extern int sumo_rlc_init(struct radeon_device *rdev); |
177 | extern void cayman_dma_vm_set_page(struct radeon_device *rdev, | ||
178 | struct radeon_ib *ib, | ||
179 | uint64_t pe, | ||
180 | uint64_t addr, unsigned count, | ||
181 | uint32_t incr, uint32_t flags); | ||
178 | 182 | ||
179 | /* Firmware Names */ | 183 | /* Firmware Names */ |
180 | MODULE_FIRMWARE("radeon/BARTS_pfp.bin"); | 184 | MODULE_FIRMWARE("radeon/BARTS_pfp.bin"); |
@@ -1374,23 +1378,6 @@ void cayman_ring_ib_execute(struct radeon_device *rdev, struct radeon_ib *ib) | |||
1374 | radeon_ring_write(ring, 10); /* poll interval */ | 1378 | radeon_ring_write(ring, 10); /* poll interval */ |
1375 | } | 1379 | } |
1376 | 1380 | ||
1377 | void cayman_uvd_semaphore_emit(struct radeon_device *rdev, | ||
1378 | struct radeon_ring *ring, | ||
1379 | struct radeon_semaphore *semaphore, | ||
1380 | bool emit_wait) | ||
1381 | { | ||
1382 | uint64_t addr = semaphore->gpu_addr; | ||
1383 | |||
1384 | radeon_ring_write(ring, PACKET0(UVD_SEMA_ADDR_LOW, 0)); | ||
1385 | radeon_ring_write(ring, (addr >> 3) & 0x000FFFFF); | ||
1386 | |||
1387 | radeon_ring_write(ring, PACKET0(UVD_SEMA_ADDR_HIGH, 0)); | ||
1388 | radeon_ring_write(ring, (addr >> 23) & 0x000FFFFF); | ||
1389 | |||
1390 | radeon_ring_write(ring, PACKET0(UVD_SEMA_CMD, 0)); | ||
1391 | radeon_ring_write(ring, 0x80 | (emit_wait ? 1 : 0)); | ||
1392 | } | ||
1393 | |||
1394 | static void cayman_cp_enable(struct radeon_device *rdev, bool enable) | 1381 | static void cayman_cp_enable(struct radeon_device *rdev, bool enable) |
1395 | { | 1382 | { |
1396 | if (enable) | 1383 | if (enable) |
@@ -1564,8 +1551,8 @@ static int cayman_cp_resume(struct radeon_device *rdev) | |||
1564 | 1551 | ||
1565 | /* Set ring buffer size */ | 1552 | /* Set ring buffer size */ |
1566 | ring = &rdev->ring[ridx[i]]; | 1553 | ring = &rdev->ring[ridx[i]]; |
1567 | rb_cntl = drm_order(ring->ring_size / 8); | 1554 | rb_cntl = order_base_2(ring->ring_size / 8); |
1568 | rb_cntl |= drm_order(RADEON_GPU_PAGE_SIZE/8) << 8; | 1555 | rb_cntl |= order_base_2(RADEON_GPU_PAGE_SIZE/8) << 8; |
1569 | #ifdef __BIG_ENDIAN | 1556 | #ifdef __BIG_ENDIAN |
1570 | rb_cntl |= BUF_SWAP_32BIT; | 1557 | rb_cntl |= BUF_SWAP_32BIT; |
1571 | #endif | 1558 | #endif |
@@ -1613,186 +1600,7 @@ static int cayman_cp_resume(struct radeon_device *rdev) | |||
1613 | return 0; | 1600 | return 0; |
1614 | } | 1601 | } |
1615 | 1602 | ||
1616 | /* | 1603 | u32 cayman_gpu_check_soft_reset(struct radeon_device *rdev) |
1617 | * DMA | ||
1618 | * Starting with R600, the GPU has an asynchronous | ||
1619 | * DMA engine. The programming model is very similar | ||
1620 | * to the 3D engine (ring buffer, IBs, etc.), but the | ||
1621 | * DMA controller has it's own packet format that is | ||
1622 | * different form the PM4 format used by the 3D engine. | ||
1623 | * It supports copying data, writing embedded data, | ||
1624 | * solid fills, and a number of other things. It also | ||
1625 | * has support for tiling/detiling of buffers. | ||
1626 | * Cayman and newer support two asynchronous DMA engines. | ||
1627 | */ | ||
1628 | /** | ||
1629 | * cayman_dma_ring_ib_execute - Schedule an IB on the DMA engine | ||
1630 | * | ||
1631 | * @rdev: radeon_device pointer | ||
1632 | * @ib: IB object to schedule | ||
1633 | * | ||
1634 | * Schedule an IB in the DMA ring (cayman-SI). | ||
1635 | */ | ||
1636 | void cayman_dma_ring_ib_execute(struct radeon_device *rdev, | ||
1637 | struct radeon_ib *ib) | ||
1638 | { | ||
1639 | struct radeon_ring *ring = &rdev->ring[ib->ring]; | ||
1640 | |||
1641 | if (rdev->wb.enabled) { | ||
1642 | u32 next_rptr = ring->wptr + 4; | ||
1643 | while ((next_rptr & 7) != 5) | ||
1644 | next_rptr++; | ||
1645 | next_rptr += 3; | ||
1646 | radeon_ring_write(ring, DMA_PACKET(DMA_PACKET_WRITE, 0, 0, 1)); | ||
1647 | radeon_ring_write(ring, ring->next_rptr_gpu_addr & 0xfffffffc); | ||
1648 | radeon_ring_write(ring, upper_32_bits(ring->next_rptr_gpu_addr) & 0xff); | ||
1649 | radeon_ring_write(ring, next_rptr); | ||
1650 | } | ||
1651 | |||
1652 | /* The indirect buffer packet must end on an 8 DW boundary in the DMA ring. | ||
1653 | * Pad as necessary with NOPs. | ||
1654 | */ | ||
1655 | while ((ring->wptr & 7) != 5) | ||
1656 | radeon_ring_write(ring, DMA_PACKET(DMA_PACKET_NOP, 0, 0, 0)); | ||
1657 | radeon_ring_write(ring, DMA_IB_PACKET(DMA_PACKET_INDIRECT_BUFFER, ib->vm ? ib->vm->id : 0, 0)); | ||
1658 | radeon_ring_write(ring, (ib->gpu_addr & 0xFFFFFFE0)); | ||
1659 | radeon_ring_write(ring, (ib->length_dw << 12) | (upper_32_bits(ib->gpu_addr) & 0xFF)); | ||
1660 | |||
1661 | } | ||
1662 | |||
1663 | /** | ||
1664 | * cayman_dma_stop - stop the async dma engines | ||
1665 | * | ||
1666 | * @rdev: radeon_device pointer | ||
1667 | * | ||
1668 | * Stop the async dma engines (cayman-SI). | ||
1669 | */ | ||
1670 | void cayman_dma_stop(struct radeon_device *rdev) | ||
1671 | { | ||
1672 | u32 rb_cntl; | ||
1673 | |||
1674 | radeon_ttm_set_active_vram_size(rdev, rdev->mc.visible_vram_size); | ||
1675 | |||
1676 | /* dma0 */ | ||
1677 | rb_cntl = RREG32(DMA_RB_CNTL + DMA0_REGISTER_OFFSET); | ||
1678 | rb_cntl &= ~DMA_RB_ENABLE; | ||
1679 | WREG32(DMA_RB_CNTL + DMA0_REGISTER_OFFSET, rb_cntl); | ||
1680 | |||
1681 | /* dma1 */ | ||
1682 | rb_cntl = RREG32(DMA_RB_CNTL + DMA1_REGISTER_OFFSET); | ||
1683 | rb_cntl &= ~DMA_RB_ENABLE; | ||
1684 | WREG32(DMA_RB_CNTL + DMA1_REGISTER_OFFSET, rb_cntl); | ||
1685 | |||
1686 | rdev->ring[R600_RING_TYPE_DMA_INDEX].ready = false; | ||
1687 | rdev->ring[CAYMAN_RING_TYPE_DMA1_INDEX].ready = false; | ||
1688 | } | ||
1689 | |||
1690 | /** | ||
1691 | * cayman_dma_resume - setup and start the async dma engines | ||
1692 | * | ||
1693 | * @rdev: radeon_device pointer | ||
1694 | * | ||
1695 | * Set up the DMA ring buffers and enable them. (cayman-SI). | ||
1696 | * Returns 0 for success, error for failure. | ||
1697 | */ | ||
1698 | int cayman_dma_resume(struct radeon_device *rdev) | ||
1699 | { | ||
1700 | struct radeon_ring *ring; | ||
1701 | u32 rb_cntl, dma_cntl, ib_cntl; | ||
1702 | u32 rb_bufsz; | ||
1703 | u32 reg_offset, wb_offset; | ||
1704 | int i, r; | ||
1705 | |||
1706 | /* Reset dma */ | ||
1707 | WREG32(SRBM_SOFT_RESET, SOFT_RESET_DMA | SOFT_RESET_DMA1); | ||
1708 | RREG32(SRBM_SOFT_RESET); | ||
1709 | udelay(50); | ||
1710 | WREG32(SRBM_SOFT_RESET, 0); | ||
1711 | |||
1712 | for (i = 0; i < 2; i++) { | ||
1713 | if (i == 0) { | ||
1714 | ring = &rdev->ring[R600_RING_TYPE_DMA_INDEX]; | ||
1715 | reg_offset = DMA0_REGISTER_OFFSET; | ||
1716 | wb_offset = R600_WB_DMA_RPTR_OFFSET; | ||
1717 | } else { | ||
1718 | ring = &rdev->ring[CAYMAN_RING_TYPE_DMA1_INDEX]; | ||
1719 | reg_offset = DMA1_REGISTER_OFFSET; | ||
1720 | wb_offset = CAYMAN_WB_DMA1_RPTR_OFFSET; | ||
1721 | } | ||
1722 | |||
1723 | WREG32(DMA_SEM_INCOMPLETE_TIMER_CNTL + reg_offset, 0); | ||
1724 | WREG32(DMA_SEM_WAIT_FAIL_TIMER_CNTL + reg_offset, 0); | ||
1725 | |||
1726 | /* Set ring buffer size in dwords */ | ||
1727 | rb_bufsz = drm_order(ring->ring_size / 4); | ||
1728 | rb_cntl = rb_bufsz << 1; | ||
1729 | #ifdef __BIG_ENDIAN | ||
1730 | rb_cntl |= DMA_RB_SWAP_ENABLE | DMA_RPTR_WRITEBACK_SWAP_ENABLE; | ||
1731 | #endif | ||
1732 | WREG32(DMA_RB_CNTL + reg_offset, rb_cntl); | ||
1733 | |||
1734 | /* Initialize the ring buffer's read and write pointers */ | ||
1735 | WREG32(DMA_RB_RPTR + reg_offset, 0); | ||
1736 | WREG32(DMA_RB_WPTR + reg_offset, 0); | ||
1737 | |||
1738 | /* set the wb address whether it's enabled or not */ | ||
1739 | WREG32(DMA_RB_RPTR_ADDR_HI + reg_offset, | ||
1740 | upper_32_bits(rdev->wb.gpu_addr + wb_offset) & 0xFF); | ||
1741 | WREG32(DMA_RB_RPTR_ADDR_LO + reg_offset, | ||
1742 | ((rdev->wb.gpu_addr + wb_offset) & 0xFFFFFFFC)); | ||
1743 | |||
1744 | if (rdev->wb.enabled) | ||
1745 | rb_cntl |= DMA_RPTR_WRITEBACK_ENABLE; | ||
1746 | |||
1747 | WREG32(DMA_RB_BASE + reg_offset, ring->gpu_addr >> 8); | ||
1748 | |||
1749 | /* enable DMA IBs */ | ||
1750 | ib_cntl = DMA_IB_ENABLE | CMD_VMID_FORCE; | ||
1751 | #ifdef __BIG_ENDIAN | ||
1752 | ib_cntl |= DMA_IB_SWAP_ENABLE; | ||
1753 | #endif | ||
1754 | WREG32(DMA_IB_CNTL + reg_offset, ib_cntl); | ||
1755 | |||
1756 | dma_cntl = RREG32(DMA_CNTL + reg_offset); | ||
1757 | dma_cntl &= ~CTXEMPTY_INT_ENABLE; | ||
1758 | WREG32(DMA_CNTL + reg_offset, dma_cntl); | ||
1759 | |||
1760 | ring->wptr = 0; | ||
1761 | WREG32(DMA_RB_WPTR + reg_offset, ring->wptr << 2); | ||
1762 | |||
1763 | ring->rptr = RREG32(DMA_RB_RPTR + reg_offset) >> 2; | ||
1764 | |||
1765 | WREG32(DMA_RB_CNTL + reg_offset, rb_cntl | DMA_RB_ENABLE); | ||
1766 | |||
1767 | ring->ready = true; | ||
1768 | |||
1769 | r = radeon_ring_test(rdev, ring->idx, ring); | ||
1770 | if (r) { | ||
1771 | ring->ready = false; | ||
1772 | return r; | ||
1773 | } | ||
1774 | } | ||
1775 | |||
1776 | radeon_ttm_set_active_vram_size(rdev, rdev->mc.real_vram_size); | ||
1777 | |||
1778 | return 0; | ||
1779 | } | ||
1780 | |||
1781 | /** | ||
1782 | * cayman_dma_fini - tear down the async dma engines | ||
1783 | * | ||
1784 | * @rdev: radeon_device pointer | ||
1785 | * | ||
1786 | * Stop the async dma engines and free the rings (cayman-SI). | ||
1787 | */ | ||
1788 | void cayman_dma_fini(struct radeon_device *rdev) | ||
1789 | { | ||
1790 | cayman_dma_stop(rdev); | ||
1791 | radeon_ring_fini(rdev, &rdev->ring[R600_RING_TYPE_DMA_INDEX]); | ||
1792 | radeon_ring_fini(rdev, &rdev->ring[CAYMAN_RING_TYPE_DMA1_INDEX]); | ||
1793 | } | ||
1794 | |||
1795 | static u32 cayman_gpu_check_soft_reset(struct radeon_device *rdev) | ||
1796 | { | 1604 | { |
1797 | u32 reset_mask = 0; | 1605 | u32 reset_mask = 0; |
1798 | u32 tmp; | 1606 | u32 tmp; |
@@ -2045,34 +1853,6 @@ bool cayman_gfx_is_lockup(struct radeon_device *rdev, struct radeon_ring *ring) | |||
2045 | return radeon_ring_test_lockup(rdev, ring); | 1853 | return radeon_ring_test_lockup(rdev, ring); |
2046 | } | 1854 | } |
2047 | 1855 | ||
2048 | /** | ||
2049 | * cayman_dma_is_lockup - Check if the DMA engine is locked up | ||
2050 | * | ||
2051 | * @rdev: radeon_device pointer | ||
2052 | * @ring: radeon_ring structure holding ring information | ||
2053 | * | ||
2054 | * Check if the async DMA engine is locked up. | ||
2055 | * Returns true if the engine appears to be locked up, false if not. | ||
2056 | */ | ||
2057 | bool cayman_dma_is_lockup(struct radeon_device *rdev, struct radeon_ring *ring) | ||
2058 | { | ||
2059 | u32 reset_mask = cayman_gpu_check_soft_reset(rdev); | ||
2060 | u32 mask; | ||
2061 | |||
2062 | if (ring->idx == R600_RING_TYPE_DMA_INDEX) | ||
2063 | mask = RADEON_RESET_DMA; | ||
2064 | else | ||
2065 | mask = RADEON_RESET_DMA1; | ||
2066 | |||
2067 | if (!(reset_mask & mask)) { | ||
2068 | radeon_ring_lockup_update(ring); | ||
2069 | return false; | ||
2070 | } | ||
2071 | /* force ring activities */ | ||
2072 | radeon_ring_force_activity(rdev, ring); | ||
2073 | return radeon_ring_test_lockup(rdev, ring); | ||
2074 | } | ||
2075 | |||
2076 | static int cayman_startup(struct radeon_device *rdev) | 1856 | static int cayman_startup(struct radeon_device *rdev) |
2077 | { | 1857 | { |
2078 | struct radeon_ring *ring = &rdev->ring[RADEON_RING_TYPE_GFX_INDEX]; | 1858 | struct radeon_ring *ring = &rdev->ring[RADEON_RING_TYPE_GFX_INDEX]; |
@@ -2083,6 +1863,11 @@ static int cayman_startup(struct radeon_device *rdev) | |||
2083 | /* enable aspm */ | 1863 | /* enable aspm */ |
2084 | evergreen_program_aspm(rdev); | 1864 | evergreen_program_aspm(rdev); |
2085 | 1865 | ||
1866 | /* scratch needs to be initialized before MC */ | ||
1867 | r = r600_vram_scratch_init(rdev); | ||
1868 | if (r) | ||
1869 | return r; | ||
1870 | |||
2086 | evergreen_mc_program(rdev); | 1871 | evergreen_mc_program(rdev); |
2087 | 1872 | ||
2088 | if (rdev->flags & RADEON_IS_IGP) { | 1873 | if (rdev->flags & RADEON_IS_IGP) { |
@@ -2109,26 +1894,16 @@ static int cayman_startup(struct radeon_device *rdev) | |||
2109 | } | 1894 | } |
2110 | } | 1895 | } |
2111 | 1896 | ||
2112 | r = r600_vram_scratch_init(rdev); | ||
2113 | if (r) | ||
2114 | return r; | ||
2115 | |||
2116 | r = cayman_pcie_gart_enable(rdev); | 1897 | r = cayman_pcie_gart_enable(rdev); |
2117 | if (r) | 1898 | if (r) |
2118 | return r; | 1899 | return r; |
2119 | cayman_gpu_init(rdev); | 1900 | cayman_gpu_init(rdev); |
2120 | 1901 | ||
2121 | r = evergreen_blit_init(rdev); | ||
2122 | if (r) { | ||
2123 | r600_blit_fini(rdev); | ||
2124 | rdev->asic->copy.copy = NULL; | ||
2125 | dev_warn(rdev->dev, "failed blitter (%d) falling back to memcpy\n", r); | ||
2126 | } | ||
2127 | |||
2128 | /* allocate rlc buffers */ | 1902 | /* allocate rlc buffers */ |
2129 | if (rdev->flags & RADEON_IS_IGP) { | 1903 | if (rdev->flags & RADEON_IS_IGP) { |
2130 | rdev->rlc.reg_list = tn_rlc_save_restore_register_list; | 1904 | rdev->rlc.reg_list = tn_rlc_save_restore_register_list; |
2131 | rdev->rlc.reg_list_size = tn_rlc_save_restore_register_list_size; | 1905 | rdev->rlc.reg_list_size = |
1906 | (u32)ARRAY_SIZE(tn_rlc_save_restore_register_list); | ||
2132 | rdev->rlc.cs_data = cayman_cs_data; | 1907 | rdev->rlc.cs_data = cayman_cs_data; |
2133 | r = sumo_rlc_init(rdev); | 1908 | r = sumo_rlc_init(rdev); |
2134 | if (r) { | 1909 | if (r) { |
@@ -2148,7 +1923,7 @@ static int cayman_startup(struct radeon_device *rdev) | |||
2148 | return r; | 1923 | return r; |
2149 | } | 1924 | } |
2150 | 1925 | ||
2151 | r = rv770_uvd_resume(rdev); | 1926 | r = uvd_v2_2_resume(rdev); |
2152 | if (!r) { | 1927 | if (!r) { |
2153 | r = radeon_fence_driver_start_ring(rdev, | 1928 | r = radeon_fence_driver_start_ring(rdev, |
2154 | R600_RING_TYPE_UVD_INDEX); | 1929 | R600_RING_TYPE_UVD_INDEX); |
@@ -2199,7 +1974,7 @@ static int cayman_startup(struct radeon_device *rdev) | |||
2199 | 1974 | ||
2200 | r = radeon_ring_init(rdev, ring, ring->ring_size, RADEON_WB_CP_RPTR_OFFSET, | 1975 | r = radeon_ring_init(rdev, ring, ring->ring_size, RADEON_WB_CP_RPTR_OFFSET, |
2201 | CP_RB0_RPTR, CP_RB0_WPTR, | 1976 | CP_RB0_RPTR, CP_RB0_WPTR, |
2202 | 0, 0xfffff, RADEON_CP_PACKET2); | 1977 | RADEON_CP_PACKET2); |
2203 | if (r) | 1978 | if (r) |
2204 | return r; | 1979 | return r; |
2205 | 1980 | ||
@@ -2207,7 +1982,7 @@ static int cayman_startup(struct radeon_device *rdev) | |||
2207 | r = radeon_ring_init(rdev, ring, ring->ring_size, R600_WB_DMA_RPTR_OFFSET, | 1982 | r = radeon_ring_init(rdev, ring, ring->ring_size, R600_WB_DMA_RPTR_OFFSET, |
2208 | DMA_RB_RPTR + DMA0_REGISTER_OFFSET, | 1983 | DMA_RB_RPTR + DMA0_REGISTER_OFFSET, |
2209 | DMA_RB_WPTR + DMA0_REGISTER_OFFSET, | 1984 | DMA_RB_WPTR + DMA0_REGISTER_OFFSET, |
2210 | 2, 0x3fffc, DMA_PACKET(DMA_PACKET_NOP, 0, 0, 0)); | 1985 | DMA_PACKET(DMA_PACKET_NOP, 0, 0, 0)); |
2211 | if (r) | 1986 | if (r) |
2212 | return r; | 1987 | return r; |
2213 | 1988 | ||
@@ -2215,7 +1990,7 @@ static int cayman_startup(struct radeon_device *rdev) | |||
2215 | r = radeon_ring_init(rdev, ring, ring->ring_size, CAYMAN_WB_DMA1_RPTR_OFFSET, | 1990 | r = radeon_ring_init(rdev, ring, ring->ring_size, CAYMAN_WB_DMA1_RPTR_OFFSET, |
2216 | DMA_RB_RPTR + DMA1_REGISTER_OFFSET, | 1991 | DMA_RB_RPTR + DMA1_REGISTER_OFFSET, |
2217 | DMA_RB_WPTR + DMA1_REGISTER_OFFSET, | 1992 | DMA_RB_WPTR + DMA1_REGISTER_OFFSET, |
2218 | 2, 0x3fffc, DMA_PACKET(DMA_PACKET_NOP, 0, 0, 0)); | 1993 | DMA_PACKET(DMA_PACKET_NOP, 0, 0, 0)); |
2219 | if (r) | 1994 | if (r) |
2220 | return r; | 1995 | return r; |
2221 | 1996 | ||
@@ -2232,12 +2007,11 @@ static int cayman_startup(struct radeon_device *rdev) | |||
2232 | 2007 | ||
2233 | ring = &rdev->ring[R600_RING_TYPE_UVD_INDEX]; | 2008 | ring = &rdev->ring[R600_RING_TYPE_UVD_INDEX]; |
2234 | if (ring->ring_size) { | 2009 | if (ring->ring_size) { |
2235 | r = radeon_ring_init(rdev, ring, ring->ring_size, | 2010 | r = radeon_ring_init(rdev, ring, ring->ring_size, 0, |
2236 | R600_WB_UVD_RPTR_OFFSET, | ||
2237 | UVD_RBC_RB_RPTR, UVD_RBC_RB_WPTR, | 2011 | UVD_RBC_RB_RPTR, UVD_RBC_RB_WPTR, |
2238 | 0, 0xfffff, RADEON_CP_PACKET2); | 2012 | RADEON_CP_PACKET2); |
2239 | if (!r) | 2013 | if (!r) |
2240 | r = r600_uvd_init(rdev); | 2014 | r = uvd_v1_0_init(rdev); |
2241 | if (r) | 2015 | if (r) |
2242 | DRM_ERROR("radeon: failed initializing UVD (%d).\n", r); | 2016 | DRM_ERROR("radeon: failed initializing UVD (%d).\n", r); |
2243 | } | 2017 | } |
@@ -2254,9 +2028,15 @@ static int cayman_startup(struct radeon_device *rdev) | |||
2254 | return r; | 2028 | return r; |
2255 | } | 2029 | } |
2256 | 2030 | ||
2257 | r = r600_audio_init(rdev); | 2031 | if (ASIC_IS_DCE6(rdev)) { |
2258 | if (r) | 2032 | r = dce6_audio_init(rdev); |
2259 | return r; | 2033 | if (r) |
2034 | return r; | ||
2035 | } else { | ||
2036 | r = r600_audio_init(rdev); | ||
2037 | if (r) | ||
2038 | return r; | ||
2039 | } | ||
2260 | 2040 | ||
2261 | return 0; | 2041 | return 0; |
2262 | } | 2042 | } |
@@ -2287,11 +2067,14 @@ int cayman_resume(struct radeon_device *rdev) | |||
2287 | 2067 | ||
2288 | int cayman_suspend(struct radeon_device *rdev) | 2068 | int cayman_suspend(struct radeon_device *rdev) |
2289 | { | 2069 | { |
2290 | r600_audio_fini(rdev); | 2070 | if (ASIC_IS_DCE6(rdev)) |
2071 | dce6_audio_fini(rdev); | ||
2072 | else | ||
2073 | r600_audio_fini(rdev); | ||
2291 | radeon_vm_manager_fini(rdev); | 2074 | radeon_vm_manager_fini(rdev); |
2292 | cayman_cp_enable(rdev, false); | 2075 | cayman_cp_enable(rdev, false); |
2293 | cayman_dma_stop(rdev); | 2076 | cayman_dma_stop(rdev); |
2294 | r600_uvd_stop(rdev); | 2077 | uvd_v1_0_fini(rdev); |
2295 | radeon_uvd_suspend(rdev); | 2078 | radeon_uvd_suspend(rdev); |
2296 | evergreen_irq_suspend(rdev); | 2079 | evergreen_irq_suspend(rdev); |
2297 | radeon_wb_disable(rdev); | 2080 | radeon_wb_disable(rdev); |
@@ -2413,7 +2196,6 @@ int cayman_init(struct radeon_device *rdev) | |||
2413 | 2196 | ||
2414 | void cayman_fini(struct radeon_device *rdev) | 2197 | void cayman_fini(struct radeon_device *rdev) |
2415 | { | 2198 | { |
2416 | r600_blit_fini(rdev); | ||
2417 | cayman_cp_fini(rdev); | 2199 | cayman_cp_fini(rdev); |
2418 | cayman_dma_fini(rdev); | 2200 | cayman_dma_fini(rdev); |
2419 | r600_irq_fini(rdev); | 2201 | r600_irq_fini(rdev); |
@@ -2423,7 +2205,7 @@ void cayman_fini(struct radeon_device *rdev) | |||
2423 | radeon_vm_manager_fini(rdev); | 2205 | radeon_vm_manager_fini(rdev); |
2424 | radeon_ib_pool_fini(rdev); | 2206 | radeon_ib_pool_fini(rdev); |
2425 | radeon_irq_kms_fini(rdev); | 2207 | radeon_irq_kms_fini(rdev); |
2426 | r600_uvd_stop(rdev); | 2208 | uvd_v1_0_fini(rdev); |
2427 | radeon_uvd_fini(rdev); | 2209 | radeon_uvd_fini(rdev); |
2428 | cayman_pcie_gart_fini(rdev); | 2210 | cayman_pcie_gart_fini(rdev); |
2429 | r600_vram_scratch_fini(rdev); | 2211 | r600_vram_scratch_fini(rdev); |
@@ -2684,61 +2466,7 @@ void cayman_vm_set_page(struct radeon_device *rdev, | |||
2684 | } | 2466 | } |
2685 | } | 2467 | } |
2686 | } else { | 2468 | } else { |
2687 | if ((flags & RADEON_VM_PAGE_SYSTEM) || | 2469 | cayman_dma_vm_set_page(rdev, ib, pe, addr, count, incr, flags); |
2688 | (count == 1)) { | ||
2689 | while (count) { | ||
2690 | ndw = count * 2; | ||
2691 | if (ndw > 0xFFFFE) | ||
2692 | ndw = 0xFFFFE; | ||
2693 | |||
2694 | /* for non-physically contiguous pages (system) */ | ||
2695 | ib->ptr[ib->length_dw++] = DMA_PACKET(DMA_PACKET_WRITE, 0, 0, ndw); | ||
2696 | ib->ptr[ib->length_dw++] = pe; | ||
2697 | ib->ptr[ib->length_dw++] = upper_32_bits(pe) & 0xff; | ||
2698 | for (; ndw > 0; ndw -= 2, --count, pe += 8) { | ||
2699 | if (flags & RADEON_VM_PAGE_SYSTEM) { | ||
2700 | value = radeon_vm_map_gart(rdev, addr); | ||
2701 | value &= 0xFFFFFFFFFFFFF000ULL; | ||
2702 | } else if (flags & RADEON_VM_PAGE_VALID) { | ||
2703 | value = addr; | ||
2704 | } else { | ||
2705 | value = 0; | ||
2706 | } | ||
2707 | addr += incr; | ||
2708 | value |= r600_flags; | ||
2709 | ib->ptr[ib->length_dw++] = value; | ||
2710 | ib->ptr[ib->length_dw++] = upper_32_bits(value); | ||
2711 | } | ||
2712 | } | ||
2713 | while (ib->length_dw & 0x7) | ||
2714 | ib->ptr[ib->length_dw++] = DMA_PACKET(DMA_PACKET_NOP, 0, 0, 0); | ||
2715 | } else { | ||
2716 | while (count) { | ||
2717 | ndw = count * 2; | ||
2718 | if (ndw > 0xFFFFE) | ||
2719 | ndw = 0xFFFFE; | ||
2720 | |||
2721 | if (flags & RADEON_VM_PAGE_VALID) | ||
2722 | value = addr; | ||
2723 | else | ||
2724 | value = 0; | ||
2725 | /* for physically contiguous pages (vram) */ | ||
2726 | ib->ptr[ib->length_dw++] = DMA_PTE_PDE_PACKET(ndw); | ||
2727 | ib->ptr[ib->length_dw++] = pe; /* dst addr */ | ||
2728 | ib->ptr[ib->length_dw++] = upper_32_bits(pe) & 0xff; | ||
2729 | ib->ptr[ib->length_dw++] = r600_flags; /* mask */ | ||
2730 | ib->ptr[ib->length_dw++] = 0; | ||
2731 | ib->ptr[ib->length_dw++] = value; /* value */ | ||
2732 | ib->ptr[ib->length_dw++] = upper_32_bits(value); | ||
2733 | ib->ptr[ib->length_dw++] = incr; /* increment size */ | ||
2734 | ib->ptr[ib->length_dw++] = 0; | ||
2735 | pe += ndw * 4; | ||
2736 | addr += (ndw / 2) * incr; | ||
2737 | count -= ndw / 2; | ||
2738 | } | ||
2739 | } | ||
2740 | while (ib->length_dw & 0x7) | ||
2741 | ib->ptr[ib->length_dw++] = DMA_PACKET(DMA_PACKET_NOP, 0, 0, 0); | ||
2742 | } | 2470 | } |
2743 | } | 2471 | } |
2744 | 2472 | ||
@@ -2772,26 +2500,3 @@ void cayman_vm_flush(struct radeon_device *rdev, int ridx, struct radeon_vm *vm) | |||
2772 | radeon_ring_write(ring, PACKET3(PACKET3_PFP_SYNC_ME, 0)); | 2500 | radeon_ring_write(ring, PACKET3(PACKET3_PFP_SYNC_ME, 0)); |
2773 | radeon_ring_write(ring, 0x0); | 2501 | radeon_ring_write(ring, 0x0); |
2774 | } | 2502 | } |
2775 | |||
2776 | void cayman_dma_vm_flush(struct radeon_device *rdev, int ridx, struct radeon_vm *vm) | ||
2777 | { | ||
2778 | struct radeon_ring *ring = &rdev->ring[ridx]; | ||
2779 | |||
2780 | if (vm == NULL) | ||
2781 | return; | ||
2782 | |||
2783 | radeon_ring_write(ring, DMA_PACKET(DMA_PACKET_SRBM_WRITE, 0, 0, 0)); | ||
2784 | radeon_ring_write(ring, (0xf << 16) | ((VM_CONTEXT0_PAGE_TABLE_BASE_ADDR + (vm->id << 2)) >> 2)); | ||
2785 | radeon_ring_write(ring, vm->pd_gpu_addr >> 12); | ||
2786 | |||
2787 | /* flush hdp cache */ | ||
2788 | radeon_ring_write(ring, DMA_PACKET(DMA_PACKET_SRBM_WRITE, 0, 0, 0)); | ||
2789 | radeon_ring_write(ring, (0xf << 16) | (HDP_MEM_COHERENCY_FLUSH_CNTL >> 2)); | ||
2790 | radeon_ring_write(ring, 1); | ||
2791 | |||
2792 | /* bits 0-7 are the VM contexts0-7 */ | ||
2793 | radeon_ring_write(ring, DMA_PACKET(DMA_PACKET_SRBM_WRITE, 0, 0, 0)); | ||
2794 | radeon_ring_write(ring, (0xf << 16) | (VM_INVALIDATE_REQUEST >> 2)); | ||
2795 | radeon_ring_write(ring, 1 << vm->id); | ||
2796 | } | ||
2797 | |||