aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/radeon/ni.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gpu/drm/radeon/ni.c')
-rw-r--r--drivers/gpu/drm/radeon/ni.c241
1 files changed, 240 insertions, 1 deletions
diff --git a/drivers/gpu/drm/radeon/ni.c b/drivers/gpu/drm/radeon/ni.c
index 3a3fdf5b5dd2..227173bf0127 100644
--- a/drivers/gpu/drm/radeon/ni.c
+++ b/drivers/gpu/drm/radeon/ni.c
@@ -36,6 +36,9 @@
36extern void evergreen_mc_stop(struct radeon_device *rdev, struct evergreen_mc_save *save); 36extern void evergreen_mc_stop(struct radeon_device *rdev, struct evergreen_mc_save *save);
37extern void evergreen_mc_resume(struct radeon_device *rdev, struct evergreen_mc_save *save); 37extern void evergreen_mc_resume(struct radeon_device *rdev, struct evergreen_mc_save *save);
38extern int evergreen_mc_wait_for_idle(struct radeon_device *rdev); 38extern int evergreen_mc_wait_for_idle(struct radeon_device *rdev);
39extern void evergreen_mc_program(struct radeon_device *rdev);
40extern void evergreen_irq_suspend(struct radeon_device *rdev);
41extern int evergreen_mc_init(struct radeon_device *rdev);
39 42
40#define EVERGREEN_PFP_UCODE_SIZE 1120 43#define EVERGREEN_PFP_UCODE_SIZE 1120
41#define EVERGREEN_PM4_UCODE_SIZE 1376 44#define EVERGREEN_PM4_UCODE_SIZE 1376
@@ -193,7 +196,7 @@ static const u32 cayman_io_mc_regs[BTC_IO_MC_REGS_SIZE][2] = {
193 {0x0000009f, 0x00976b00} 196 {0x0000009f, 0x00976b00}
194}; 197};
195 198
196int btc_mc_load_microcode(struct radeon_device *rdev) 199int ni_mc_load_microcode(struct radeon_device *rdev)
197{ 200{
198 const __be32 *fw_data; 201 const __be32 *fw_data;
199 u32 mem_type, running, blackout = 0; 202 u32 mem_type, running, blackout = 0;
@@ -1129,6 +1132,12 @@ static int cayman_cp_start(struct radeon_device *rdev)
1129 return 0; 1132 return 0;
1130} 1133}
1131 1134
1135static void cayman_cp_fini(struct radeon_device *rdev)
1136{
1137 cayman_cp_enable(rdev, false);
1138 radeon_ring_fini(rdev);
1139}
1140
1132int cayman_cp_resume(struct radeon_device *rdev) 1141int cayman_cp_resume(struct radeon_device *rdev)
1133{ 1142{
1134 u32 tmp; 1143 u32 tmp;
@@ -1346,3 +1355,233 @@ int cayman_asic_reset(struct radeon_device *rdev)
1346 return cayman_gpu_soft_reset(rdev); 1355 return cayman_gpu_soft_reset(rdev);
1347} 1356}
1348 1357
1358static int cayman_startup(struct radeon_device *rdev)
1359{
1360 int r;
1361
1362 if (!rdev->me_fw || !rdev->pfp_fw || !rdev->rlc_fw || !rdev->mc_fw) {
1363 r = ni_init_microcode(rdev);
1364 if (r) {
1365 DRM_ERROR("Failed to load firmware!\n");
1366 return r;
1367 }
1368 }
1369 r = ni_mc_load_microcode(rdev);
1370 if (r) {
1371 DRM_ERROR("Failed to load MC firmware!\n");
1372 return r;
1373 }
1374
1375 evergreen_mc_program(rdev);
1376 r = cayman_pcie_gart_enable(rdev);
1377 if (r)
1378 return r;
1379 cayman_gpu_init(rdev);
1380
1381#if 0
1382 r = cayman_blit_init(rdev);
1383 if (r) {
1384 cayman_blit_fini(rdev);
1385 rdev->asic->copy = NULL;
1386 dev_warn(rdev->dev, "failed blitter (%d) falling back to memcpy\n", r);
1387 }
1388#endif
1389
1390 /* allocate wb buffer */
1391 r = radeon_wb_init(rdev);
1392 if (r)
1393 return r;
1394
1395 /* Enable IRQ */
1396 r = r600_irq_init(rdev);
1397 if (r) {
1398 DRM_ERROR("radeon: IH init failed (%d).\n", r);
1399 radeon_irq_kms_fini(rdev);
1400 return r;
1401 }
1402 evergreen_irq_set(rdev);
1403
1404 r = radeon_ring_init(rdev, rdev->cp.ring_size);
1405 if (r)
1406 return r;
1407 r = cayman_cp_load_microcode(rdev);
1408 if (r)
1409 return r;
1410 r = cayman_cp_resume(rdev);
1411 if (r)
1412 return r;
1413
1414 return 0;
1415}
1416
1417int cayman_resume(struct radeon_device *rdev)
1418{
1419 int r;
1420
1421 /* Do not reset GPU before posting, on rv770 hw unlike on r500 hw,
1422 * posting will perform necessary task to bring back GPU into good
1423 * shape.
1424 */
1425 /* post card */
1426 atom_asic_init(rdev->mode_info.atom_context);
1427
1428 r = cayman_startup(rdev);
1429 if (r) {
1430 DRM_ERROR("cayman startup failed on resume\n");
1431 return r;
1432 }
1433
1434 r = r600_ib_test(rdev);
1435 if (r) {
1436 DRM_ERROR("radeon: failled testing IB (%d).\n", r);
1437 return r;
1438 }
1439
1440 return r;
1441
1442}
1443
1444int cayman_suspend(struct radeon_device *rdev)
1445{
1446 /* int r; */
1447
1448 /* FIXME: we should wait for ring to be empty */
1449 cayman_cp_enable(rdev, false);
1450 rdev->cp.ready = false;
1451 evergreen_irq_suspend(rdev);
1452 radeon_wb_disable(rdev);
1453 cayman_pcie_gart_disable(rdev);
1454
1455#if 0
1456 /* unpin shaders bo */
1457 r = radeon_bo_reserve(rdev->r600_blit.shader_obj, false);
1458 if (likely(r == 0)) {
1459 radeon_bo_unpin(rdev->r600_blit.shader_obj);
1460 radeon_bo_unreserve(rdev->r600_blit.shader_obj);
1461 }
1462#endif
1463 return 0;
1464}
1465
1466/* Plan is to move initialization in that function and use
1467 * helper function so that radeon_device_init pretty much
1468 * do nothing more than calling asic specific function. This
1469 * should also allow to remove a bunch of callback function
1470 * like vram_info.
1471 */
1472int cayman_init(struct radeon_device *rdev)
1473{
1474 int r;
1475
1476 /* This don't do much */
1477 r = radeon_gem_init(rdev);
1478 if (r)
1479 return r;
1480 /* Read BIOS */
1481 if (!radeon_get_bios(rdev)) {
1482 if (ASIC_IS_AVIVO(rdev))
1483 return -EINVAL;
1484 }
1485 /* Must be an ATOMBIOS */
1486 if (!rdev->is_atom_bios) {
1487 dev_err(rdev->dev, "Expecting atombios for cayman GPU\n");
1488 return -EINVAL;
1489 }
1490 r = radeon_atombios_init(rdev);
1491 if (r)
1492 return r;
1493
1494 /* Post card if necessary */
1495 if (!radeon_card_posted(rdev)) {
1496 if (!rdev->bios) {
1497 dev_err(rdev->dev, "Card not posted and no BIOS - ignoring\n");
1498 return -EINVAL;
1499 }
1500 DRM_INFO("GPU not posted. posting now...\n");
1501 atom_asic_init(rdev->mode_info.atom_context);
1502 }
1503 /* Initialize scratch registers */
1504 r600_scratch_init(rdev);
1505 /* Initialize surface registers */
1506 radeon_surface_init(rdev);
1507 /* Initialize clocks */
1508 radeon_get_clock_info(rdev->ddev);
1509 /* Fence driver */
1510 r = radeon_fence_driver_init(rdev);
1511 if (r)
1512 return r;
1513 /* initialize memory controller */
1514 r = evergreen_mc_init(rdev);
1515 if (r)
1516 return r;
1517 /* Memory manager */
1518 r = radeon_bo_init(rdev);
1519 if (r)
1520 return r;
1521
1522 r = radeon_irq_kms_init(rdev);
1523 if (r)
1524 return r;
1525
1526 rdev->cp.ring_obj = NULL;
1527 r600_ring_init(rdev, 1024 * 1024);
1528
1529 rdev->ih.ring_obj = NULL;
1530 r600_ih_ring_init(rdev, 64 * 1024);
1531
1532 r = r600_pcie_gart_init(rdev);
1533 if (r)
1534 return r;
1535
1536 rdev->accel_working = true;
1537 r = cayman_startup(rdev);
1538 if (r) {
1539 dev_err(rdev->dev, "disabling GPU acceleration\n");
1540 cayman_cp_fini(rdev);
1541 r600_irq_fini(rdev);
1542 radeon_wb_fini(rdev);
1543 radeon_irq_kms_fini(rdev);
1544 cayman_pcie_gart_fini(rdev);
1545 rdev->accel_working = false;
1546 }
1547 if (rdev->accel_working) {
1548 r = radeon_ib_pool_init(rdev);
1549 if (r) {
1550 DRM_ERROR("radeon: failed initializing IB pool (%d).\n", r);
1551 rdev->accel_working = false;
1552 }
1553 r = r600_ib_test(rdev);
1554 if (r) {
1555 DRM_ERROR("radeon: failed testing IB (%d).\n", r);
1556 rdev->accel_working = false;
1557 }
1558 }
1559
1560 /* Don't start up if the MC ucode is missing.
1561 * The default clocks and voltages before the MC ucode
1562 * is loaded are not suffient for advanced operations.
1563 */
1564 if (!rdev->mc_fw) {
1565 DRM_ERROR("radeon: MC ucode required for NI+.\n");
1566 return -EINVAL;
1567 }
1568
1569 return 0;
1570}
1571
1572void cayman_fini(struct radeon_device *rdev)
1573{
1574 /* cayman_blit_fini(rdev); */
1575 cayman_cp_fini(rdev);
1576 r600_irq_fini(rdev);
1577 radeon_wb_fini(rdev);
1578 radeon_irq_kms_fini(rdev);
1579 cayman_pcie_gart_fini(rdev);
1580 radeon_gem_fini(rdev);
1581 radeon_fence_driver_fini(rdev);
1582 radeon_bo_fini(rdev);
1583 radeon_atombios_fini(rdev);
1584 kfree(rdev->bios);
1585 rdev->bios = NULL;
1586}
1587