diff options
Diffstat (limited to 'drivers/gpu/drm/radeon/ni.c')
-rw-r--r-- | drivers/gpu/drm/radeon/ni.c | 142 |
1 files changed, 105 insertions, 37 deletions
diff --git a/drivers/gpu/drm/radeon/ni.c b/drivers/gpu/drm/radeon/ni.c index f59a9e9fccf8..bf6300cfd62d 100644 --- a/drivers/gpu/drm/radeon/ni.c +++ b/drivers/gpu/drm/radeon/ni.c | |||
@@ -174,6 +174,7 @@ extern void evergreen_pcie_gen2_enable(struct radeon_device *rdev); | |||
174 | extern void evergreen_program_aspm(struct radeon_device *rdev); | 174 | extern void evergreen_program_aspm(struct radeon_device *rdev); |
175 | extern void sumo_rlc_fini(struct radeon_device *rdev); | 175 | extern void sumo_rlc_fini(struct radeon_device *rdev); |
176 | extern int sumo_rlc_init(struct radeon_device *rdev); | 176 | extern int sumo_rlc_init(struct radeon_device *rdev); |
177 | extern void evergreen_gpu_pci_config_reset(struct radeon_device *rdev); | ||
177 | 178 | ||
178 | /* Firmware Names */ | 179 | /* Firmware Names */ |
179 | MODULE_FIRMWARE("radeon/BARTS_pfp.bin"); | 180 | MODULE_FIRMWARE("radeon/BARTS_pfp.bin"); |
@@ -1330,13 +1331,12 @@ void cayman_fence_ring_emit(struct radeon_device *rdev, | |||
1330 | { | 1331 | { |
1331 | struct radeon_ring *ring = &rdev->ring[fence->ring]; | 1332 | struct radeon_ring *ring = &rdev->ring[fence->ring]; |
1332 | u64 addr = rdev->fence_drv[fence->ring].gpu_addr; | 1333 | u64 addr = rdev->fence_drv[fence->ring].gpu_addr; |
1334 | u32 cp_coher_cntl = PACKET3_FULL_CACHE_ENA | PACKET3_TC_ACTION_ENA | | ||
1335 | PACKET3_SH_ACTION_ENA; | ||
1333 | 1336 | ||
1334 | /* flush read cache over gart for this vmid */ | 1337 | /* flush read cache over gart for this vmid */ |
1335 | radeon_ring_write(ring, PACKET3(PACKET3_SET_CONFIG_REG, 1)); | ||
1336 | radeon_ring_write(ring, (CP_COHER_CNTL2 - PACKET3_SET_CONFIG_REG_START) >> 2); | ||
1337 | radeon_ring_write(ring, 0); | ||
1338 | radeon_ring_write(ring, PACKET3(PACKET3_SURFACE_SYNC, 3)); | 1338 | radeon_ring_write(ring, PACKET3(PACKET3_SURFACE_SYNC, 3)); |
1339 | radeon_ring_write(ring, PACKET3_TC_ACTION_ENA | PACKET3_SH_ACTION_ENA); | 1339 | radeon_ring_write(ring, PACKET3_ENGINE_ME | cp_coher_cntl); |
1340 | radeon_ring_write(ring, 0xFFFFFFFF); | 1340 | radeon_ring_write(ring, 0xFFFFFFFF); |
1341 | radeon_ring_write(ring, 0); | 1341 | radeon_ring_write(ring, 0); |
1342 | radeon_ring_write(ring, 10); /* poll interval */ | 1342 | radeon_ring_write(ring, 10); /* poll interval */ |
@@ -1352,6 +1352,8 @@ void cayman_fence_ring_emit(struct radeon_device *rdev, | |||
1352 | void cayman_ring_ib_execute(struct radeon_device *rdev, struct radeon_ib *ib) | 1352 | void cayman_ring_ib_execute(struct radeon_device *rdev, struct radeon_ib *ib) |
1353 | { | 1353 | { |
1354 | struct radeon_ring *ring = &rdev->ring[ib->ring]; | 1354 | struct radeon_ring *ring = &rdev->ring[ib->ring]; |
1355 | u32 cp_coher_cntl = PACKET3_FULL_CACHE_ENA | PACKET3_TC_ACTION_ENA | | ||
1356 | PACKET3_SH_ACTION_ENA; | ||
1355 | 1357 | ||
1356 | /* set to DX10/11 mode */ | 1358 | /* set to DX10/11 mode */ |
1357 | radeon_ring_write(ring, PACKET3(PACKET3_MODE_CONTROL, 0)); | 1359 | radeon_ring_write(ring, PACKET3(PACKET3_MODE_CONTROL, 0)); |
@@ -1376,14 +1378,11 @@ void cayman_ring_ib_execute(struct radeon_device *rdev, struct radeon_ib *ib) | |||
1376 | (ib->vm ? (ib->vm->id << 24) : 0)); | 1378 | (ib->vm ? (ib->vm->id << 24) : 0)); |
1377 | 1379 | ||
1378 | /* flush read cache over gart for this vmid */ | 1380 | /* flush read cache over gart for this vmid */ |
1379 | radeon_ring_write(ring, PACKET3(PACKET3_SET_CONFIG_REG, 1)); | ||
1380 | radeon_ring_write(ring, (CP_COHER_CNTL2 - PACKET3_SET_CONFIG_REG_START) >> 2); | ||
1381 | radeon_ring_write(ring, ib->vm ? ib->vm->id : 0); | ||
1382 | radeon_ring_write(ring, PACKET3(PACKET3_SURFACE_SYNC, 3)); | 1381 | radeon_ring_write(ring, PACKET3(PACKET3_SURFACE_SYNC, 3)); |
1383 | radeon_ring_write(ring, PACKET3_TC_ACTION_ENA | PACKET3_SH_ACTION_ENA); | 1382 | radeon_ring_write(ring, PACKET3_ENGINE_ME | cp_coher_cntl); |
1384 | radeon_ring_write(ring, 0xFFFFFFFF); | 1383 | radeon_ring_write(ring, 0xFFFFFFFF); |
1385 | radeon_ring_write(ring, 0); | 1384 | radeon_ring_write(ring, 0); |
1386 | radeon_ring_write(ring, 10); /* poll interval */ | 1385 | radeon_ring_write(ring, ((ib->vm ? ib->vm->id : 0) << 24) | 10); /* poll interval */ |
1387 | } | 1386 | } |
1388 | 1387 | ||
1389 | static void cayman_cp_enable(struct radeon_device *rdev, bool enable) | 1388 | static void cayman_cp_enable(struct radeon_device *rdev, bool enable) |
@@ -1391,13 +1390,63 @@ static void cayman_cp_enable(struct radeon_device *rdev, bool enable) | |||
1391 | if (enable) | 1390 | if (enable) |
1392 | WREG32(CP_ME_CNTL, 0); | 1391 | WREG32(CP_ME_CNTL, 0); |
1393 | else { | 1392 | else { |
1394 | radeon_ttm_set_active_vram_size(rdev, rdev->mc.visible_vram_size); | 1393 | if (rdev->asic->copy.copy_ring_index == RADEON_RING_TYPE_GFX_INDEX) |
1394 | radeon_ttm_set_active_vram_size(rdev, rdev->mc.visible_vram_size); | ||
1395 | WREG32(CP_ME_CNTL, (CP_ME_HALT | CP_PFP_HALT)); | 1395 | WREG32(CP_ME_CNTL, (CP_ME_HALT | CP_PFP_HALT)); |
1396 | WREG32(SCRATCH_UMSK, 0); | 1396 | WREG32(SCRATCH_UMSK, 0); |
1397 | rdev->ring[RADEON_RING_TYPE_GFX_INDEX].ready = false; | 1397 | rdev->ring[RADEON_RING_TYPE_GFX_INDEX].ready = false; |
1398 | } | 1398 | } |
1399 | } | 1399 | } |
1400 | 1400 | ||
1401 | u32 cayman_gfx_get_rptr(struct radeon_device *rdev, | ||
1402 | struct radeon_ring *ring) | ||
1403 | { | ||
1404 | u32 rptr; | ||
1405 | |||
1406 | if (rdev->wb.enabled) | ||
1407 | rptr = rdev->wb.wb[ring->rptr_offs/4]; | ||
1408 | else { | ||
1409 | if (ring->idx == RADEON_RING_TYPE_GFX_INDEX) | ||
1410 | rptr = RREG32(CP_RB0_RPTR); | ||
1411 | else if (ring->idx == CAYMAN_RING_TYPE_CP1_INDEX) | ||
1412 | rptr = RREG32(CP_RB1_RPTR); | ||
1413 | else | ||
1414 | rptr = RREG32(CP_RB2_RPTR); | ||
1415 | } | ||
1416 | |||
1417 | return rptr; | ||
1418 | } | ||
1419 | |||
1420 | u32 cayman_gfx_get_wptr(struct radeon_device *rdev, | ||
1421 | struct radeon_ring *ring) | ||
1422 | { | ||
1423 | u32 wptr; | ||
1424 | |||
1425 | if (ring->idx == RADEON_RING_TYPE_GFX_INDEX) | ||
1426 | wptr = RREG32(CP_RB0_WPTR); | ||
1427 | else if (ring->idx == CAYMAN_RING_TYPE_CP1_INDEX) | ||
1428 | wptr = RREG32(CP_RB1_WPTR); | ||
1429 | else | ||
1430 | wptr = RREG32(CP_RB2_WPTR); | ||
1431 | |||
1432 | return wptr; | ||
1433 | } | ||
1434 | |||
1435 | void cayman_gfx_set_wptr(struct radeon_device *rdev, | ||
1436 | struct radeon_ring *ring) | ||
1437 | { | ||
1438 | if (ring->idx == RADEON_RING_TYPE_GFX_INDEX) { | ||
1439 | WREG32(CP_RB0_WPTR, ring->wptr); | ||
1440 | (void)RREG32(CP_RB0_WPTR); | ||
1441 | } else if (ring->idx == CAYMAN_RING_TYPE_CP1_INDEX) { | ||
1442 | WREG32(CP_RB1_WPTR, ring->wptr); | ||
1443 | (void)RREG32(CP_RB1_WPTR); | ||
1444 | } else { | ||
1445 | WREG32(CP_RB2_WPTR, ring->wptr); | ||
1446 | (void)RREG32(CP_RB2_WPTR); | ||
1447 | } | ||
1448 | } | ||
1449 | |||
1401 | static int cayman_cp_load_microcode(struct radeon_device *rdev) | 1450 | static int cayman_cp_load_microcode(struct radeon_device *rdev) |
1402 | { | 1451 | { |
1403 | const __be32 *fw_data; | 1452 | const __be32 *fw_data; |
@@ -1526,6 +1575,16 @@ static int cayman_cp_resume(struct radeon_device *rdev) | |||
1526 | CP_RB1_BASE, | 1575 | CP_RB1_BASE, |
1527 | CP_RB2_BASE | 1576 | CP_RB2_BASE |
1528 | }; | 1577 | }; |
1578 | static const unsigned cp_rb_rptr[] = { | ||
1579 | CP_RB0_RPTR, | ||
1580 | CP_RB1_RPTR, | ||
1581 | CP_RB2_RPTR | ||
1582 | }; | ||
1583 | static const unsigned cp_rb_wptr[] = { | ||
1584 | CP_RB0_WPTR, | ||
1585 | CP_RB1_WPTR, | ||
1586 | CP_RB2_WPTR | ||
1587 | }; | ||
1529 | struct radeon_ring *ring; | 1588 | struct radeon_ring *ring; |
1530 | int i, r; | 1589 | int i, r; |
1531 | 1590 | ||
@@ -1584,8 +1643,8 @@ static int cayman_cp_resume(struct radeon_device *rdev) | |||
1584 | WREG32_P(cp_rb_cntl[i], RB_RPTR_WR_ENA, ~RB_RPTR_WR_ENA); | 1643 | WREG32_P(cp_rb_cntl[i], RB_RPTR_WR_ENA, ~RB_RPTR_WR_ENA); |
1585 | 1644 | ||
1586 | ring->rptr = ring->wptr = 0; | 1645 | ring->rptr = ring->wptr = 0; |
1587 | WREG32(ring->rptr_reg, ring->rptr); | 1646 | WREG32(cp_rb_rptr[i], ring->rptr); |
1588 | WREG32(ring->wptr_reg, ring->wptr); | 1647 | WREG32(cp_rb_wptr[i], ring->wptr); |
1589 | 1648 | ||
1590 | mdelay(1); | 1649 | mdelay(1); |
1591 | WREG32_P(cp_rb_cntl[i], 0, ~RB_RPTR_WR_ENA); | 1650 | WREG32_P(cp_rb_cntl[i], 0, ~RB_RPTR_WR_ENA); |
@@ -1605,6 +1664,9 @@ static int cayman_cp_resume(struct radeon_device *rdev) | |||
1605 | return r; | 1664 | return r; |
1606 | } | 1665 | } |
1607 | 1666 | ||
1667 | if (rdev->asic->copy.copy_ring_index == RADEON_RING_TYPE_GFX_INDEX) | ||
1668 | radeon_ttm_set_active_vram_size(rdev, rdev->mc.real_vram_size); | ||
1669 | |||
1608 | return 0; | 1670 | return 0; |
1609 | } | 1671 | } |
1610 | 1672 | ||
@@ -1831,8 +1893,10 @@ int cayman_asic_reset(struct radeon_device *rdev) | |||
1831 | 1893 | ||
1832 | reset_mask = cayman_gpu_check_soft_reset(rdev); | 1894 | reset_mask = cayman_gpu_check_soft_reset(rdev); |
1833 | 1895 | ||
1834 | if (!reset_mask) | 1896 | if (reset_mask) |
1835 | r600_set_bios_scratch_engine_hung(rdev, false); | 1897 | evergreen_gpu_pci_config_reset(rdev); |
1898 | |||
1899 | r600_set_bios_scratch_engine_hung(rdev, false); | ||
1836 | 1900 | ||
1837 | return 0; | 1901 | return 0; |
1838 | } | 1902 | } |
@@ -1878,23 +1942,7 @@ static int cayman_startup(struct radeon_device *rdev) | |||
1878 | 1942 | ||
1879 | evergreen_mc_program(rdev); | 1943 | evergreen_mc_program(rdev); |
1880 | 1944 | ||
1881 | if (rdev->flags & RADEON_IS_IGP) { | 1945 | if (!(rdev->flags & RADEON_IS_IGP) && !rdev->pm.dpm_enabled) { |
1882 | if (!rdev->me_fw || !rdev->pfp_fw || !rdev->rlc_fw) { | ||
1883 | r = ni_init_microcode(rdev); | ||
1884 | if (r) { | ||
1885 | DRM_ERROR("Failed to load firmware!\n"); | ||
1886 | return r; | ||
1887 | } | ||
1888 | } | ||
1889 | } else { | ||
1890 | if (!rdev->me_fw || !rdev->pfp_fw || !rdev->rlc_fw || !rdev->mc_fw) { | ||
1891 | r = ni_init_microcode(rdev); | ||
1892 | if (r) { | ||
1893 | DRM_ERROR("Failed to load firmware!\n"); | ||
1894 | return r; | ||
1895 | } | ||
1896 | } | ||
1897 | |||
1898 | r = ni_mc_load_microcode(rdev); | 1946 | r = ni_mc_load_microcode(rdev); |
1899 | if (r) { | 1947 | if (r) { |
1900 | DRM_ERROR("Failed to load MC firmware!\n"); | 1948 | DRM_ERROR("Failed to load MC firmware!\n"); |
@@ -1981,23 +2029,18 @@ static int cayman_startup(struct radeon_device *rdev) | |||
1981 | evergreen_irq_set(rdev); | 2029 | evergreen_irq_set(rdev); |
1982 | 2030 | ||
1983 | r = radeon_ring_init(rdev, ring, ring->ring_size, RADEON_WB_CP_RPTR_OFFSET, | 2031 | r = radeon_ring_init(rdev, ring, ring->ring_size, RADEON_WB_CP_RPTR_OFFSET, |
1984 | CP_RB0_RPTR, CP_RB0_WPTR, | ||
1985 | RADEON_CP_PACKET2); | 2032 | RADEON_CP_PACKET2); |
1986 | if (r) | 2033 | if (r) |
1987 | return r; | 2034 | return r; |
1988 | 2035 | ||
1989 | ring = &rdev->ring[R600_RING_TYPE_DMA_INDEX]; | 2036 | ring = &rdev->ring[R600_RING_TYPE_DMA_INDEX]; |
1990 | r = radeon_ring_init(rdev, ring, ring->ring_size, R600_WB_DMA_RPTR_OFFSET, | 2037 | r = radeon_ring_init(rdev, ring, ring->ring_size, R600_WB_DMA_RPTR_OFFSET, |
1991 | DMA_RB_RPTR + DMA0_REGISTER_OFFSET, | ||
1992 | DMA_RB_WPTR + DMA0_REGISTER_OFFSET, | ||
1993 | DMA_PACKET(DMA_PACKET_NOP, 0, 0, 0)); | 2038 | DMA_PACKET(DMA_PACKET_NOP, 0, 0, 0)); |
1994 | if (r) | 2039 | if (r) |
1995 | return r; | 2040 | return r; |
1996 | 2041 | ||
1997 | ring = &rdev->ring[CAYMAN_RING_TYPE_DMA1_INDEX]; | 2042 | ring = &rdev->ring[CAYMAN_RING_TYPE_DMA1_INDEX]; |
1998 | r = radeon_ring_init(rdev, ring, ring->ring_size, CAYMAN_WB_DMA1_RPTR_OFFSET, | 2043 | r = radeon_ring_init(rdev, ring, ring->ring_size, CAYMAN_WB_DMA1_RPTR_OFFSET, |
1999 | DMA_RB_RPTR + DMA1_REGISTER_OFFSET, | ||
2000 | DMA_RB_WPTR + DMA1_REGISTER_OFFSET, | ||
2001 | DMA_PACKET(DMA_PACKET_NOP, 0, 0, 0)); | 2044 | DMA_PACKET(DMA_PACKET_NOP, 0, 0, 0)); |
2002 | if (r) | 2045 | if (r) |
2003 | return r; | 2046 | return r; |
@@ -2016,7 +2059,6 @@ static int cayman_startup(struct radeon_device *rdev) | |||
2016 | ring = &rdev->ring[R600_RING_TYPE_UVD_INDEX]; | 2059 | ring = &rdev->ring[R600_RING_TYPE_UVD_INDEX]; |
2017 | if (ring->ring_size) { | 2060 | if (ring->ring_size) { |
2018 | r = radeon_ring_init(rdev, ring, ring->ring_size, 0, | 2061 | r = radeon_ring_init(rdev, ring, ring->ring_size, 0, |
2019 | UVD_RBC_RB_RPTR, UVD_RBC_RB_WPTR, | ||
2020 | RADEON_CP_PACKET2); | 2062 | RADEON_CP_PACKET2); |
2021 | if (!r) | 2063 | if (!r) |
2022 | r = uvd_v1_0_init(rdev); | 2064 | r = uvd_v1_0_init(rdev); |
@@ -2063,6 +2105,9 @@ int cayman_resume(struct radeon_device *rdev) | |||
2063 | /* init golden registers */ | 2105 | /* init golden registers */ |
2064 | ni_init_golden_registers(rdev); | 2106 | ni_init_golden_registers(rdev); |
2065 | 2107 | ||
2108 | if (rdev->pm.pm_method == PM_METHOD_DPM) | ||
2109 | radeon_pm_resume(rdev); | ||
2110 | |||
2066 | rdev->accel_working = true; | 2111 | rdev->accel_working = true; |
2067 | r = cayman_startup(rdev); | 2112 | r = cayman_startup(rdev); |
2068 | if (r) { | 2113 | if (r) { |
@@ -2075,6 +2120,7 @@ int cayman_resume(struct radeon_device *rdev) | |||
2075 | 2120 | ||
2076 | int cayman_suspend(struct radeon_device *rdev) | 2121 | int cayman_suspend(struct radeon_device *rdev) |
2077 | { | 2122 | { |
2123 | radeon_pm_suspend(rdev); | ||
2078 | if (ASIC_IS_DCE6(rdev)) | 2124 | if (ASIC_IS_DCE6(rdev)) |
2079 | dce6_audio_fini(rdev); | 2125 | dce6_audio_fini(rdev); |
2080 | else | 2126 | else |
@@ -2145,6 +2191,27 @@ int cayman_init(struct radeon_device *rdev) | |||
2145 | if (r) | 2191 | if (r) |
2146 | return r; | 2192 | return r; |
2147 | 2193 | ||
2194 | if (rdev->flags & RADEON_IS_IGP) { | ||
2195 | if (!rdev->me_fw || !rdev->pfp_fw || !rdev->rlc_fw) { | ||
2196 | r = ni_init_microcode(rdev); | ||
2197 | if (r) { | ||
2198 | DRM_ERROR("Failed to load firmware!\n"); | ||
2199 | return r; | ||
2200 | } | ||
2201 | } | ||
2202 | } else { | ||
2203 | if (!rdev->me_fw || !rdev->pfp_fw || !rdev->rlc_fw || !rdev->mc_fw) { | ||
2204 | r = ni_init_microcode(rdev); | ||
2205 | if (r) { | ||
2206 | DRM_ERROR("Failed to load firmware!\n"); | ||
2207 | return r; | ||
2208 | } | ||
2209 | } | ||
2210 | } | ||
2211 | |||
2212 | /* Initialize power management */ | ||
2213 | radeon_pm_init(rdev); | ||
2214 | |||
2148 | ring->ring_obj = NULL; | 2215 | ring->ring_obj = NULL; |
2149 | r600_ring_init(rdev, ring, 1024 * 1024); | 2216 | r600_ring_init(rdev, ring, 1024 * 1024); |
2150 | 2217 | ||
@@ -2204,6 +2271,7 @@ int cayman_init(struct radeon_device *rdev) | |||
2204 | 2271 | ||
2205 | void cayman_fini(struct radeon_device *rdev) | 2272 | void cayman_fini(struct radeon_device *rdev) |
2206 | { | 2273 | { |
2274 | radeon_pm_fini(rdev); | ||
2207 | cayman_cp_fini(rdev); | 2275 | cayman_cp_fini(rdev); |
2208 | cayman_dma_fini(rdev); | 2276 | cayman_dma_fini(rdev); |
2209 | r600_irq_fini(rdev); | 2277 | r600_irq_fini(rdev); |