diff options
Diffstat (limited to 'drivers/gpu/drm/radeon/ni.c')
-rw-r--r-- | drivers/gpu/drm/radeon/ni.c | 147 |
1 files changed, 121 insertions, 26 deletions
diff --git a/drivers/gpu/drm/radeon/ni.c b/drivers/gpu/drm/radeon/ni.c index 2509c505acb8..a48ca53fcd6a 100644 --- a/drivers/gpu/drm/radeon/ni.c +++ b/drivers/gpu/drm/radeon/ni.c | |||
@@ -42,6 +42,8 @@ extern void evergreen_irq_suspend(struct radeon_device *rdev); | |||
42 | extern int evergreen_mc_init(struct radeon_device *rdev); | 42 | extern int evergreen_mc_init(struct radeon_device *rdev); |
43 | extern void evergreen_fix_pci_max_read_req_size(struct radeon_device *rdev); | 43 | extern void evergreen_fix_pci_max_read_req_size(struct radeon_device *rdev); |
44 | extern void evergreen_pcie_gen2_enable(struct radeon_device *rdev); | 44 | extern void evergreen_pcie_gen2_enable(struct radeon_device *rdev); |
45 | extern void si_rlc_fini(struct radeon_device *rdev); | ||
46 | extern int si_rlc_init(struct radeon_device *rdev); | ||
45 | 47 | ||
46 | #define EVERGREEN_PFP_UCODE_SIZE 1120 | 48 | #define EVERGREEN_PFP_UCODE_SIZE 1120 |
47 | #define EVERGREEN_PM4_UCODE_SIZE 1376 | 49 | #define EVERGREEN_PM4_UCODE_SIZE 1376 |
@@ -53,6 +55,8 @@ extern void evergreen_pcie_gen2_enable(struct radeon_device *rdev); | |||
53 | #define CAYMAN_RLC_UCODE_SIZE 1024 | 55 | #define CAYMAN_RLC_UCODE_SIZE 1024 |
54 | #define CAYMAN_MC_UCODE_SIZE 6037 | 56 | #define CAYMAN_MC_UCODE_SIZE 6037 |
55 | 57 | ||
58 | #define ARUBA_RLC_UCODE_SIZE 1536 | ||
59 | |||
56 | /* Firmware Names */ | 60 | /* Firmware Names */ |
57 | MODULE_FIRMWARE("radeon/BARTS_pfp.bin"); | 61 | MODULE_FIRMWARE("radeon/BARTS_pfp.bin"); |
58 | MODULE_FIRMWARE("radeon/BARTS_me.bin"); | 62 | MODULE_FIRMWARE("radeon/BARTS_me.bin"); |
@@ -68,6 +72,9 @@ MODULE_FIRMWARE("radeon/CAYMAN_pfp.bin"); | |||
68 | MODULE_FIRMWARE("radeon/CAYMAN_me.bin"); | 72 | MODULE_FIRMWARE("radeon/CAYMAN_me.bin"); |
69 | MODULE_FIRMWARE("radeon/CAYMAN_mc.bin"); | 73 | MODULE_FIRMWARE("radeon/CAYMAN_mc.bin"); |
70 | MODULE_FIRMWARE("radeon/CAYMAN_rlc.bin"); | 74 | MODULE_FIRMWARE("radeon/CAYMAN_rlc.bin"); |
75 | MODULE_FIRMWARE("radeon/ARUBA_pfp.bin"); | ||
76 | MODULE_FIRMWARE("radeon/ARUBA_me.bin"); | ||
77 | MODULE_FIRMWARE("radeon/ARUBA_rlc.bin"); | ||
71 | 78 | ||
72 | #define BTC_IO_MC_REGS_SIZE 29 | 79 | #define BTC_IO_MC_REGS_SIZE 29 |
73 | 80 | ||
@@ -326,6 +333,15 @@ int ni_init_microcode(struct radeon_device *rdev) | |||
326 | rlc_req_size = CAYMAN_RLC_UCODE_SIZE * 4; | 333 | rlc_req_size = CAYMAN_RLC_UCODE_SIZE * 4; |
327 | mc_req_size = CAYMAN_MC_UCODE_SIZE * 4; | 334 | mc_req_size = CAYMAN_MC_UCODE_SIZE * 4; |
328 | break; | 335 | break; |
336 | case CHIP_ARUBA: | ||
337 | chip_name = "ARUBA"; | ||
338 | rlc_chip_name = "ARUBA"; | ||
339 | /* pfp/me same size as CAYMAN */ | ||
340 | pfp_req_size = CAYMAN_PFP_UCODE_SIZE * 4; | ||
341 | me_req_size = CAYMAN_PM4_UCODE_SIZE * 4; | ||
342 | rlc_req_size = ARUBA_RLC_UCODE_SIZE * 4; | ||
343 | mc_req_size = 0; | ||
344 | break; | ||
329 | default: BUG(); | 345 | default: BUG(); |
330 | } | 346 | } |
331 | 347 | ||
@@ -365,15 +381,18 @@ int ni_init_microcode(struct radeon_device *rdev) | |||
365 | err = -EINVAL; | 381 | err = -EINVAL; |
366 | } | 382 | } |
367 | 383 | ||
368 | snprintf(fw_name, sizeof(fw_name), "radeon/%s_mc.bin", chip_name); | 384 | /* no MC ucode on TN */ |
369 | err = request_firmware(&rdev->mc_fw, fw_name, &pdev->dev); | 385 | if (!(rdev->flags & RADEON_IS_IGP)) { |
370 | if (err) | 386 | snprintf(fw_name, sizeof(fw_name), "radeon/%s_mc.bin", chip_name); |
371 | goto out; | 387 | err = request_firmware(&rdev->mc_fw, fw_name, &pdev->dev); |
372 | if (rdev->mc_fw->size != mc_req_size) { | 388 | if (err) |
373 | printk(KERN_ERR | 389 | goto out; |
374 | "ni_mc: Bogus length %zu in firmware \"%s\"\n", | 390 | if (rdev->mc_fw->size != mc_req_size) { |
375 | rdev->mc_fw->size, fw_name); | 391 | printk(KERN_ERR |
376 | err = -EINVAL; | 392 | "ni_mc: Bogus length %zu in firmware \"%s\"\n", |
393 | rdev->mc_fw->size, fw_name); | ||
394 | err = -EINVAL; | ||
395 | } | ||
377 | } | 396 | } |
378 | out: | 397 | out: |
379 | platform_device_unregister(pdev); | 398 | platform_device_unregister(pdev); |
@@ -478,6 +497,7 @@ static u32 cayman_get_tile_pipe_to_backend_map(struct radeon_device *rdev, | |||
478 | memset((uint8_t *)&swizzle_pipe[0], 0, sizeof(u32) * CAYMAN_MAX_PIPES); | 497 | memset((uint8_t *)&swizzle_pipe[0], 0, sizeof(u32) * CAYMAN_MAX_PIPES); |
479 | switch (rdev->family) { | 498 | switch (rdev->family) { |
480 | case CHIP_CAYMAN: | 499 | case CHIP_CAYMAN: |
500 | case CHIP_ARUBA: | ||
481 | force_no_swizzle = true; | 501 | force_no_swizzle = true; |
482 | break; | 502 | break; |
483 | default: | 503 | default: |
@@ -610,7 +630,6 @@ static void cayman_gpu_init(struct radeon_device *rdev) | |||
610 | 630 | ||
611 | switch (rdev->family) { | 631 | switch (rdev->family) { |
612 | case CHIP_CAYMAN: | 632 | case CHIP_CAYMAN: |
613 | default: | ||
614 | rdev->config.cayman.max_shader_engines = 2; | 633 | rdev->config.cayman.max_shader_engines = 2; |
615 | rdev->config.cayman.max_pipes_per_simd = 4; | 634 | rdev->config.cayman.max_pipes_per_simd = 4; |
616 | rdev->config.cayman.max_tile_pipes = 8; | 635 | rdev->config.cayman.max_tile_pipes = 8; |
@@ -632,6 +651,43 @@ static void cayman_gpu_init(struct radeon_device *rdev) | |||
632 | rdev->config.cayman.sc_hiz_tile_fifo_size = 0x30; | 651 | rdev->config.cayman.sc_hiz_tile_fifo_size = 0x30; |
633 | rdev->config.cayman.sc_earlyz_tile_fifo_size = 0x130; | 652 | rdev->config.cayman.sc_earlyz_tile_fifo_size = 0x130; |
634 | break; | 653 | break; |
654 | case CHIP_ARUBA: | ||
655 | default: | ||
656 | rdev->config.cayman.max_shader_engines = 1; | ||
657 | rdev->config.cayman.max_pipes_per_simd = 4; | ||
658 | rdev->config.cayman.max_tile_pipes = 2; | ||
659 | if ((rdev->pdev->device == 0x9900) || | ||
660 | (rdev->pdev->device == 0x9901)) { | ||
661 | rdev->config.cayman.max_simds_per_se = 6; | ||
662 | rdev->config.cayman.max_backends_per_se = 2; | ||
663 | } else if ((rdev->pdev->device == 0x9903) || | ||
664 | (rdev->pdev->device == 0x9904)) { | ||
665 | rdev->config.cayman.max_simds_per_se = 4; | ||
666 | rdev->config.cayman.max_backends_per_se = 2; | ||
667 | } else if ((rdev->pdev->device == 0x9990) || | ||
668 | (rdev->pdev->device == 0x9991)) { | ||
669 | rdev->config.cayman.max_simds_per_se = 3; | ||
670 | rdev->config.cayman.max_backends_per_se = 1; | ||
671 | } else { | ||
672 | rdev->config.cayman.max_simds_per_se = 2; | ||
673 | rdev->config.cayman.max_backends_per_se = 1; | ||
674 | } | ||
675 | rdev->config.cayman.max_texture_channel_caches = 2; | ||
676 | rdev->config.cayman.max_gprs = 256; | ||
677 | rdev->config.cayman.max_threads = 256; | ||
678 | rdev->config.cayman.max_gs_threads = 32; | ||
679 | rdev->config.cayman.max_stack_entries = 512; | ||
680 | rdev->config.cayman.sx_num_of_sets = 8; | ||
681 | rdev->config.cayman.sx_max_export_size = 256; | ||
682 | rdev->config.cayman.sx_max_export_pos_size = 64; | ||
683 | rdev->config.cayman.sx_max_export_smx_size = 192; | ||
684 | rdev->config.cayman.max_hw_contexts = 8; | ||
685 | rdev->config.cayman.sq_num_cf_insts = 2; | ||
686 | |||
687 | rdev->config.cayman.sc_prim_fifo_size = 0x40; | ||
688 | rdev->config.cayman.sc_hiz_tile_fifo_size = 0x30; | ||
689 | rdev->config.cayman.sc_earlyz_tile_fifo_size = 0x130; | ||
690 | break; | ||
635 | } | 691 | } |
636 | 692 | ||
637 | /* Initialize HDP */ | 693 | /* Initialize HDP */ |
@@ -652,7 +708,9 @@ static void cayman_gpu_init(struct radeon_device *rdev) | |||
652 | 708 | ||
653 | cc_rb_backend_disable = RREG32(CC_RB_BACKEND_DISABLE); | 709 | cc_rb_backend_disable = RREG32(CC_RB_BACKEND_DISABLE); |
654 | cc_gc_shader_pipe_config = RREG32(CC_GC_SHADER_PIPE_CONFIG); | 710 | cc_gc_shader_pipe_config = RREG32(CC_GC_SHADER_PIPE_CONFIG); |
655 | cgts_tcc_disable = 0xff000000; | 711 | cgts_tcc_disable = 0xffff0000; |
712 | for (i = 0; i < rdev->config.cayman.max_texture_channel_caches; i++) | ||
713 | cgts_tcc_disable &= ~(1 << (16 + i)); | ||
656 | gc_user_rb_backend_disable = RREG32(GC_USER_RB_BACKEND_DISABLE); | 714 | gc_user_rb_backend_disable = RREG32(GC_USER_RB_BACKEND_DISABLE); |
657 | gc_user_shader_pipe_config = RREG32(GC_USER_SHADER_PIPE_CONFIG); | 715 | gc_user_shader_pipe_config = RREG32(GC_USER_SHADER_PIPE_CONFIG); |
658 | cgts_user_tcc_disable = RREG32(CGTS_USER_TCC_DISABLE); | 716 | cgts_user_tcc_disable = RREG32(CGTS_USER_TCC_DISABLE); |
@@ -804,8 +862,13 @@ static void cayman_gpu_init(struct radeon_device *rdev) | |||
804 | rdev->config.cayman.tile_config |= (3 << 0); | 862 | rdev->config.cayman.tile_config |= (3 << 0); |
805 | break; | 863 | break; |
806 | } | 864 | } |
807 | rdev->config.cayman.tile_config |= | 865 | |
808 | ((mc_arb_ramcfg & NOOFBANK_MASK) >> NOOFBANK_SHIFT) << 4; | 866 | /* num banks is 8 on all fusion asics. 0 = 4, 1 = 8, 2 = 16 */ |
867 | if (rdev->flags & RADEON_IS_IGP) | ||
868 | rdev->config.evergreen.tile_config |= 1 << 4; | ||
869 | else | ||
870 | rdev->config.cayman.tile_config |= | ||
871 | ((mc_arb_ramcfg & NOOFBANK_MASK) >> NOOFBANK_SHIFT) << 4; | ||
809 | rdev->config.cayman.tile_config |= | 872 | rdev->config.cayman.tile_config |= |
810 | ((gb_addr_config & PIPE_INTERLEAVE_SIZE_MASK) >> PIPE_INTERLEAVE_SIZE_SHIFT) << 8; | 873 | ((gb_addr_config & PIPE_INTERLEAVE_SIZE_MASK) >> PIPE_INTERLEAVE_SIZE_SHIFT) << 8; |
811 | rdev->config.cayman.tile_config |= | 874 | rdev->config.cayman.tile_config |= |
@@ -1318,7 +1381,7 @@ int cayman_cp_resume(struct radeon_device *rdev) | |||
1318 | rdev->ring[CAYMAN_RING_TYPE_CP1_INDEX].ready = false; | 1381 | rdev->ring[CAYMAN_RING_TYPE_CP1_INDEX].ready = false; |
1319 | rdev->ring[CAYMAN_RING_TYPE_CP2_INDEX].ready = false; | 1382 | rdev->ring[CAYMAN_RING_TYPE_CP2_INDEX].ready = false; |
1320 | /* this only test cp0 */ | 1383 | /* this only test cp0 */ |
1321 | r = radeon_ring_test(rdev, &rdev->ring[RADEON_RING_TYPE_GFX_INDEX]); | 1384 | r = radeon_ring_test(rdev, RADEON_RING_TYPE_GFX_INDEX, &rdev->ring[RADEON_RING_TYPE_GFX_INDEX]); |
1322 | if (r) { | 1385 | if (r) { |
1323 | rdev->ring[RADEON_RING_TYPE_GFX_INDEX].ready = false; | 1386 | rdev->ring[RADEON_RING_TYPE_GFX_INDEX].ready = false; |
1324 | rdev->ring[CAYMAN_RING_TYPE_CP1_INDEX].ready = false; | 1387 | rdev->ring[CAYMAN_RING_TYPE_CP1_INDEX].ready = false; |
@@ -1440,18 +1503,29 @@ static int cayman_startup(struct radeon_device *rdev) | |||
1440 | /* enable pcie gen2 link */ | 1503 | /* enable pcie gen2 link */ |
1441 | evergreen_pcie_gen2_enable(rdev); | 1504 | evergreen_pcie_gen2_enable(rdev); |
1442 | 1505 | ||
1443 | if (!rdev->me_fw || !rdev->pfp_fw || !rdev->rlc_fw || !rdev->mc_fw) { | 1506 | if (rdev->flags & RADEON_IS_IGP) { |
1444 | r = ni_init_microcode(rdev); | 1507 | if (!rdev->me_fw || !rdev->pfp_fw || !rdev->rlc_fw) { |
1508 | r = ni_init_microcode(rdev); | ||
1509 | if (r) { | ||
1510 | DRM_ERROR("Failed to load firmware!\n"); | ||
1511 | return r; | ||
1512 | } | ||
1513 | } | ||
1514 | } else { | ||
1515 | if (!rdev->me_fw || !rdev->pfp_fw || !rdev->rlc_fw || !rdev->mc_fw) { | ||
1516 | r = ni_init_microcode(rdev); | ||
1517 | if (r) { | ||
1518 | DRM_ERROR("Failed to load firmware!\n"); | ||
1519 | return r; | ||
1520 | } | ||
1521 | } | ||
1522 | |||
1523 | r = ni_mc_load_microcode(rdev); | ||
1445 | if (r) { | 1524 | if (r) { |
1446 | DRM_ERROR("Failed to load firmware!\n"); | 1525 | DRM_ERROR("Failed to load MC firmware!\n"); |
1447 | return r; | 1526 | return r; |
1448 | } | 1527 | } |
1449 | } | 1528 | } |
1450 | r = ni_mc_load_microcode(rdev); | ||
1451 | if (r) { | ||
1452 | DRM_ERROR("Failed to load MC firmware!\n"); | ||
1453 | return r; | ||
1454 | } | ||
1455 | 1529 | ||
1456 | r = r600_vram_scratch_init(rdev); | 1530 | r = r600_vram_scratch_init(rdev); |
1457 | if (r) | 1531 | if (r) |
@@ -1466,10 +1540,19 @@ static int cayman_startup(struct radeon_device *rdev) | |||
1466 | r = evergreen_blit_init(rdev); | 1540 | r = evergreen_blit_init(rdev); |
1467 | if (r) { | 1541 | if (r) { |
1468 | r600_blit_fini(rdev); | 1542 | r600_blit_fini(rdev); |
1469 | rdev->asic->copy = NULL; | 1543 | rdev->asic->copy.copy = NULL; |
1470 | dev_warn(rdev->dev, "failed blitter (%d) falling back to memcpy\n", r); | 1544 | dev_warn(rdev->dev, "failed blitter (%d) falling back to memcpy\n", r); |
1471 | } | 1545 | } |
1472 | 1546 | ||
1547 | /* allocate rlc buffers */ | ||
1548 | if (rdev->flags & RADEON_IS_IGP) { | ||
1549 | r = si_rlc_init(rdev); | ||
1550 | if (r) { | ||
1551 | DRM_ERROR("Failed to init rlc BOs!\n"); | ||
1552 | return r; | ||
1553 | } | ||
1554 | } | ||
1555 | |||
1473 | /* allocate wb buffer */ | 1556 | /* allocate wb buffer */ |
1474 | r = radeon_wb_init(rdev); | 1557 | r = radeon_wb_init(rdev); |
1475 | if (r) | 1558 | if (r) |
@@ -1518,7 +1601,7 @@ static int cayman_startup(struct radeon_device *rdev) | |||
1518 | if (r) | 1601 | if (r) |
1519 | return r; | 1602 | return r; |
1520 | 1603 | ||
1521 | r = r600_ib_test(rdev, RADEON_RING_TYPE_GFX_INDEX); | 1604 | r = radeon_ib_test(rdev, RADEON_RING_TYPE_GFX_INDEX, &rdev->ring[RADEON_RING_TYPE_GFX_INDEX]); |
1522 | if (r) { | 1605 | if (r) { |
1523 | DRM_ERROR("radeon: failed testing IB (%d).\n", r); | 1606 | DRM_ERROR("radeon: failed testing IB (%d).\n", r); |
1524 | rdev->accel_working = false; | 1607 | rdev->accel_working = false; |
@@ -1654,6 +1737,8 @@ int cayman_init(struct radeon_device *rdev) | |||
1654 | dev_err(rdev->dev, "disabling GPU acceleration\n"); | 1737 | dev_err(rdev->dev, "disabling GPU acceleration\n"); |
1655 | cayman_cp_fini(rdev); | 1738 | cayman_cp_fini(rdev); |
1656 | r600_irq_fini(rdev); | 1739 | r600_irq_fini(rdev); |
1740 | if (rdev->flags & RADEON_IS_IGP) | ||
1741 | si_rlc_fini(rdev); | ||
1657 | radeon_wb_fini(rdev); | 1742 | radeon_wb_fini(rdev); |
1658 | r100_ib_fini(rdev); | 1743 | r100_ib_fini(rdev); |
1659 | radeon_vm_manager_fini(rdev); | 1744 | radeon_vm_manager_fini(rdev); |
@@ -1665,8 +1750,11 @@ int cayman_init(struct radeon_device *rdev) | |||
1665 | /* Don't start up if the MC ucode is missing. | 1750 | /* Don't start up if the MC ucode is missing. |
1666 | * The default clocks and voltages before the MC ucode | 1751 | * The default clocks and voltages before the MC ucode |
1667 | * is loaded are not suffient for advanced operations. | 1752 | * is loaded are not suffient for advanced operations. |
1753 | * | ||
1754 | * We can skip this check for TN, because there is no MC | ||
1755 | * ucode. | ||
1668 | */ | 1756 | */ |
1669 | if (!rdev->mc_fw) { | 1757 | if (!rdev->mc_fw && !(rdev->flags & RADEON_IS_IGP)) { |
1670 | DRM_ERROR("radeon: MC ucode required for NI+.\n"); | 1758 | DRM_ERROR("radeon: MC ucode required for NI+.\n"); |
1671 | return -EINVAL; | 1759 | return -EINVAL; |
1672 | } | 1760 | } |
@@ -1679,6 +1767,8 @@ void cayman_fini(struct radeon_device *rdev) | |||
1679 | r600_blit_fini(rdev); | 1767 | r600_blit_fini(rdev); |
1680 | cayman_cp_fini(rdev); | 1768 | cayman_cp_fini(rdev); |
1681 | r600_irq_fini(rdev); | 1769 | r600_irq_fini(rdev); |
1770 | if (rdev->flags & RADEON_IS_IGP) | ||
1771 | si_rlc_fini(rdev); | ||
1682 | radeon_wb_fini(rdev); | 1772 | radeon_wb_fini(rdev); |
1683 | radeon_vm_manager_fini(rdev); | 1773 | radeon_vm_manager_fini(rdev); |
1684 | r100_ib_fini(rdev); | 1774 | r100_ib_fini(rdev); |
@@ -1702,7 +1792,12 @@ int cayman_vm_init(struct radeon_device *rdev) | |||
1702 | /* number of VMs */ | 1792 | /* number of VMs */ |
1703 | rdev->vm_manager.nvm = 8; | 1793 | rdev->vm_manager.nvm = 8; |
1704 | /* base offset of vram pages */ | 1794 | /* base offset of vram pages */ |
1705 | rdev->vm_manager.vram_base_offset = 0; | 1795 | if (rdev->flags & RADEON_IS_IGP) { |
1796 | u64 tmp = RREG32(FUS_MC_VM_FB_OFFSET); | ||
1797 | tmp <<= 22; | ||
1798 | rdev->vm_manager.vram_base_offset = tmp; | ||
1799 | } else | ||
1800 | rdev->vm_manager.vram_base_offset = 0; | ||
1706 | return 0; | 1801 | return 0; |
1707 | } | 1802 | } |
1708 | 1803 | ||