Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

drm/radeon/si: Add support for new ucode format (v3)

This adds SI support for the new ucode format.

v2: add size validation, integrate debug info
v3: update to latest version

Signed-off-by: Alex Deucher <alexander.deucher@amd.com>

+382 -155
+1
drivers/gpu/drm/radeon/radeon.h
··· 2306 2306 const struct firmware *smc_fw; /* SMC firmware */ 2307 2307 const struct firmware *uvd_fw; /* UVD firmware */ 2308 2308 const struct firmware *vce_fw; /* VCE firmware */ 2309 + bool new_fw; 2309 2310 struct r600_vram_scratch vram_scratch; 2310 2311 int msi_enabled; /* msi enabled */ 2311 2312 struct r600_ih ih; /* r6/700 interrupt ring */
+344 -130
drivers/gpu/drm/radeon/si.c
··· 42 42 MODULE_FIRMWARE("radeon/TAHITI_mc2.bin"); 43 43 MODULE_FIRMWARE("radeon/TAHITI_rlc.bin"); 44 44 MODULE_FIRMWARE("radeon/TAHITI_smc.bin"); 45 + 46 + MODULE_FIRMWARE("radeon/tahiti_pfp.bin"); 47 + MODULE_FIRMWARE("radeon/tahiti_me.bin"); 48 + MODULE_FIRMWARE("radeon/tahiti_ce.bin"); 49 + MODULE_FIRMWARE("radeon/tahiti_mc.bin"); 50 + MODULE_FIRMWARE("radeon/tahiti_rlc.bin"); 51 + MODULE_FIRMWARE("radeon/tahiti_smc.bin"); 52 + 45 53 MODULE_FIRMWARE("radeon/PITCAIRN_pfp.bin"); 46 54 MODULE_FIRMWARE("radeon/PITCAIRN_me.bin"); 47 55 MODULE_FIRMWARE("radeon/PITCAIRN_ce.bin"); ··· 57 49 MODULE_FIRMWARE("radeon/PITCAIRN_mc2.bin"); 58 50 MODULE_FIRMWARE("radeon/PITCAIRN_rlc.bin"); 59 51 MODULE_FIRMWARE("radeon/PITCAIRN_smc.bin"); 52 + 53 + MODULE_FIRMWARE("radeon/pitcairn_pfp.bin"); 54 + MODULE_FIRMWARE("radeon/pitcairn_me.bin"); 55 + MODULE_FIRMWARE("radeon/pitcairn_ce.bin"); 56 + MODULE_FIRMWARE("radeon/pitcairn_mc.bin"); 57 + MODULE_FIRMWARE("radeon/pitcairn_rlc.bin"); 58 + MODULE_FIRMWARE("radeon/pitcairn_smc.bin"); 59 + 60 60 MODULE_FIRMWARE("radeon/VERDE_pfp.bin"); 61 61 MODULE_FIRMWARE("radeon/VERDE_me.bin"); 62 62 MODULE_FIRMWARE("radeon/VERDE_ce.bin"); ··· 72 56 MODULE_FIRMWARE("radeon/VERDE_mc2.bin"); 73 57 MODULE_FIRMWARE("radeon/VERDE_rlc.bin"); 74 58 MODULE_FIRMWARE("radeon/VERDE_smc.bin"); 59 + 60 + MODULE_FIRMWARE("radeon/verde_pfp.bin"); 61 + MODULE_FIRMWARE("radeon/verde_me.bin"); 62 + MODULE_FIRMWARE("radeon/verde_ce.bin"); 63 + MODULE_FIRMWARE("radeon/verde_mc.bin"); 64 + MODULE_FIRMWARE("radeon/verde_rlc.bin"); 65 + MODULE_FIRMWARE("radeon/verde_smc.bin"); 66 + 75 67 MODULE_FIRMWARE("radeon/OLAND_pfp.bin"); 76 68 MODULE_FIRMWARE("radeon/OLAND_me.bin"); 77 69 MODULE_FIRMWARE("radeon/OLAND_ce.bin"); ··· 87 63 MODULE_FIRMWARE("radeon/OLAND_mc2.bin"); 88 64 MODULE_FIRMWARE("radeon/OLAND_rlc.bin"); 89 65 MODULE_FIRMWARE("radeon/OLAND_smc.bin"); 66 + 67 + MODULE_FIRMWARE("radeon/oland_pfp.bin"); 68 + MODULE_FIRMWARE("radeon/oland_me.bin"); 69 + MODULE_FIRMWARE("radeon/oland_ce.bin"); 70 + MODULE_FIRMWARE("radeon/oland_mc.bin"); 71 + MODULE_FIRMWARE("radeon/oland_rlc.bin"); 72 + MODULE_FIRMWARE("radeon/oland_smc.bin"); 73 + 90 74 MODULE_FIRMWARE("radeon/HAINAN_pfp.bin"); 91 75 MODULE_FIRMWARE("radeon/HAINAN_me.bin"); 92 76 MODULE_FIRMWARE("radeon/HAINAN_ce.bin"); ··· 102 70 MODULE_FIRMWARE("radeon/HAINAN_mc2.bin"); 103 71 MODULE_FIRMWARE("radeon/HAINAN_rlc.bin"); 104 72 MODULE_FIRMWARE("radeon/HAINAN_smc.bin"); 73 + 74 + MODULE_FIRMWARE("radeon/hainan_pfp.bin"); 75 + MODULE_FIRMWARE("radeon/hainan_me.bin"); 76 + MODULE_FIRMWARE("radeon/hainan_ce.bin"); 77 + MODULE_FIRMWARE("radeon/hainan_mc.bin"); 78 + MODULE_FIRMWARE("radeon/hainan_rlc.bin"); 79 + MODULE_FIRMWARE("radeon/hainan_smc.bin"); 105 80 106 81 static u32 si_get_cu_active_bitmap(struct radeon_device *rdev, u32 se, u32 sh); 107 82 static void si_pcie_gen3_enable(struct radeon_device *rdev); ··· 1509 1470 /* ucode loading */ 1510 1471 int si_mc_load_microcode(struct radeon_device *rdev) 1511 1472 { 1512 - const __be32 *fw_data; 1473 + const __be32 *fw_data = NULL; 1474 + const __le32 *new_fw_data = NULL; 1513 1475 u32 running, blackout = 0; 1514 - u32 *io_mc_regs; 1476 + u32 *io_mc_regs = NULL; 1477 + const __le32 *new_io_mc_regs = NULL; 1515 1478 int i, regs_size, ucode_size; 1516 1479 1517 1480 if (!rdev->mc_fw) 1518 1481 return -EINVAL; 1519 1482 1520 - ucode_size = rdev->mc_fw->size / 4; 1483 + if (rdev->new_fw) { 1484 + const struct mc_firmware_header_v1_0 *hdr = 1485 + (const struct mc_firmware_header_v1_0 *)rdev->mc_fw->data; 1521 1486 1522 - switch (rdev->family) { 1523 - case CHIP_TAHITI: 1524 - io_mc_regs = (u32 *)&tahiti_io_mc_regs; 1525 - regs_size = TAHITI_IO_MC_REGS_SIZE; 1526 - break; 1527 - case CHIP_PITCAIRN: 1528 - io_mc_regs = (u32 *)&pitcairn_io_mc_regs; 1529 - regs_size = TAHITI_IO_MC_REGS_SIZE; 1530 - break; 1531 - case CHIP_VERDE: 1532 - default: 1533 - io_mc_regs = (u32 *)&verde_io_mc_regs; 1534 - regs_size = TAHITI_IO_MC_REGS_SIZE; 1535 - break; 1536 - case CHIP_OLAND: 1537 - io_mc_regs = (u32 *)&oland_io_mc_regs; 1538 - regs_size = TAHITI_IO_MC_REGS_SIZE; 1539 - break; 1540 - case CHIP_HAINAN: 1541 - io_mc_regs = (u32 *)&hainan_io_mc_regs; 1542 - regs_size = TAHITI_IO_MC_REGS_SIZE; 1543 - break; 1487 + radeon_ucode_print_mc_hdr(&hdr->header); 1488 + regs_size = le32_to_cpu(hdr->io_debug_size_bytes) / (4 * 2); 1489 + new_io_mc_regs = (const __le32 *) 1490 + (rdev->mc_fw->data + le32_to_cpu(hdr->io_debug_array_offset_bytes)); 1491 + ucode_size = le32_to_cpu(hdr->header.ucode_size_bytes) / 4; 1492 + new_fw_data = (const __le32 *) 1493 + (rdev->mc_fw->data + le32_to_cpu(hdr->header.ucode_array_offset_bytes)); 1494 + } else { 1495 + ucode_size = rdev->mc_fw->size / 4; 1496 + 1497 + switch (rdev->family) { 1498 + case CHIP_TAHITI: 1499 + io_mc_regs = (u32 *)&tahiti_io_mc_regs; 1500 + regs_size = TAHITI_IO_MC_REGS_SIZE; 1501 + break; 1502 + case CHIP_PITCAIRN: 1503 + io_mc_regs = (u32 *)&pitcairn_io_mc_regs; 1504 + regs_size = TAHITI_IO_MC_REGS_SIZE; 1505 + break; 1506 + case CHIP_VERDE: 1507 + default: 1508 + io_mc_regs = (u32 *)&verde_io_mc_regs; 1509 + regs_size = TAHITI_IO_MC_REGS_SIZE; 1510 + break; 1511 + case CHIP_OLAND: 1512 + io_mc_regs = (u32 *)&oland_io_mc_regs; 1513 + regs_size = TAHITI_IO_MC_REGS_SIZE; 1514 + break; 1515 + case CHIP_HAINAN: 1516 + io_mc_regs = (u32 *)&hainan_io_mc_regs; 1517 + regs_size = TAHITI_IO_MC_REGS_SIZE; 1518 + break; 1519 + } 1520 + fw_data = (const __be32 *)rdev->mc_fw->data; 1544 1521 } 1545 1522 1546 1523 running = RREG32(MC_SEQ_SUP_CNTL) & RUN_MASK; ··· 1573 1518 1574 1519 /* load mc io regs */ 1575 1520 for (i = 0; i < regs_size; i++) { 1576 - WREG32(MC_SEQ_IO_DEBUG_INDEX, io_mc_regs[(i << 1)]); 1577 - WREG32(MC_SEQ_IO_DEBUG_DATA, io_mc_regs[(i << 1) + 1]); 1521 + if (rdev->new_fw) { 1522 + WREG32(MC_SEQ_IO_DEBUG_INDEX, le32_to_cpup(new_io_mc_regs++)); 1523 + WREG32(MC_SEQ_IO_DEBUG_DATA, le32_to_cpup(new_io_mc_regs++)); 1524 + } else { 1525 + WREG32(MC_SEQ_IO_DEBUG_INDEX, io_mc_regs[(i << 1)]); 1526 + WREG32(MC_SEQ_IO_DEBUG_DATA, io_mc_regs[(i << 1) + 1]); 1527 + } 1578 1528 } 1579 1529 /* load the MC ucode */ 1580 - fw_data = (const __be32 *)rdev->mc_fw->data; 1581 - for (i = 0; i < ucode_size; i++) 1582 - WREG32(MC_SEQ_SUP_PGM, be32_to_cpup(fw_data++)); 1530 + for (i = 0; i < ucode_size; i++) { 1531 + if (rdev->new_fw) 1532 + WREG32(MC_SEQ_SUP_PGM, le32_to_cpup(new_fw_data++)); 1533 + else 1534 + WREG32(MC_SEQ_SUP_PGM, be32_to_cpup(fw_data++)); 1535 + } 1583 1536 1584 1537 /* put the engine back into the active state */ 1585 1538 WREG32(MC_SEQ_SUP_CNTL, 0x00000008); ··· 1616 1553 static int si_init_microcode(struct radeon_device *rdev) 1617 1554 { 1618 1555 const char *chip_name; 1619 - const char *rlc_chip_name; 1556 + const char *new_chip_name; 1620 1557 size_t pfp_req_size, me_req_size, ce_req_size, rlc_req_size, mc_req_size; 1621 1558 size_t smc_req_size, mc2_req_size; 1622 1559 char fw_name[30]; 1623 1560 int err; 1561 + int new_fw = 0; 1624 1562 1625 1563 DRM_DEBUG("\n"); 1626 1564 1627 1565 switch (rdev->family) { 1628 1566 case CHIP_TAHITI: 1629 1567 chip_name = "TAHITI"; 1630 - rlc_chip_name = "TAHITI"; 1568 + new_chip_name = "tahiti"; 1631 1569 pfp_req_size = SI_PFP_UCODE_SIZE * 4; 1632 1570 me_req_size = SI_PM4_UCODE_SIZE * 4; 1633 1571 ce_req_size = SI_CE_UCODE_SIZE * 4; ··· 1639 1575 break; 1640 1576 case CHIP_PITCAIRN: 1641 1577 chip_name = "PITCAIRN"; 1642 - rlc_chip_name = "PITCAIRN"; 1578 + new_chip_name = "pitcairn"; 1643 1579 pfp_req_size = SI_PFP_UCODE_SIZE * 4; 1644 1580 me_req_size = SI_PM4_UCODE_SIZE * 4; 1645 1581 ce_req_size = SI_CE_UCODE_SIZE * 4; ··· 1650 1586 break; 1651 1587 case CHIP_VERDE: 1652 1588 chip_name = "VERDE"; 1653 - rlc_chip_name = "VERDE"; 1589 + new_chip_name = "verde"; 1654 1590 pfp_req_size = SI_PFP_UCODE_SIZE * 4; 1655 1591 me_req_size = SI_PM4_UCODE_SIZE * 4; 1656 1592 ce_req_size = SI_CE_UCODE_SIZE * 4; ··· 1661 1597 break; 1662 1598 case CHIP_OLAND: 1663 1599 chip_name = "OLAND"; 1664 - rlc_chip_name = "OLAND"; 1600 + new_chip_name = "oland"; 1665 1601 pfp_req_size = SI_PFP_UCODE_SIZE * 4; 1666 1602 me_req_size = SI_PM4_UCODE_SIZE * 4; 1667 1603 ce_req_size = SI_CE_UCODE_SIZE * 4; ··· 1671 1607 break; 1672 1608 case CHIP_HAINAN: 1673 1609 chip_name = "HAINAN"; 1674 - rlc_chip_name = "HAINAN"; 1610 + new_chip_name = "hainan"; 1675 1611 pfp_req_size = SI_PFP_UCODE_SIZE * 4; 1676 1612 me_req_size = SI_PM4_UCODE_SIZE * 4; 1677 1613 ce_req_size = SI_CE_UCODE_SIZE * 4; ··· 1682 1618 default: BUG(); 1683 1619 } 1684 1620 1685 - DRM_INFO("Loading %s Microcode\n", chip_name); 1621 + DRM_INFO("Loading %s Microcode\n", new_chip_name); 1686 1622 1687 - snprintf(fw_name, sizeof(fw_name), "radeon/%s_pfp.bin", chip_name); 1623 + snprintf(fw_name, sizeof(fw_name), "radeon/%s_pfp.bin", new_chip_name); 1688 1624 err = request_firmware(&rdev->pfp_fw, fw_name, rdev->dev); 1689 - if (err) 1690 - goto out; 1691 - if (rdev->pfp_fw->size != pfp_req_size) { 1692 - printk(KERN_ERR 1693 - "si_cp: Bogus length %zu in firmware \"%s\"\n", 1694 - rdev->pfp_fw->size, fw_name); 1695 - err = -EINVAL; 1696 - goto out; 1697 - } 1698 - 1699 - snprintf(fw_name, sizeof(fw_name), "radeon/%s_me.bin", chip_name); 1700 - err = request_firmware(&rdev->me_fw, fw_name, rdev->dev); 1701 - if (err) 1702 - goto out; 1703 - if (rdev->me_fw->size != me_req_size) { 1704 - printk(KERN_ERR 1705 - "si_cp: Bogus length %zu in firmware \"%s\"\n", 1706 - rdev->me_fw->size, fw_name); 1707 - err = -EINVAL; 1708 - } 1709 - 1710 - snprintf(fw_name, sizeof(fw_name), "radeon/%s_ce.bin", chip_name); 1711 - err = request_firmware(&rdev->ce_fw, fw_name, rdev->dev); 1712 - if (err) 1713 - goto out; 1714 - if (rdev->ce_fw->size != ce_req_size) { 1715 - printk(KERN_ERR 1716 - "si_cp: Bogus length %zu in firmware \"%s\"\n", 1717 - rdev->ce_fw->size, fw_name); 1718 - err = -EINVAL; 1719 - } 1720 - 1721 - snprintf(fw_name, sizeof(fw_name), "radeon/%s_rlc.bin", rlc_chip_name); 1722 - err = request_firmware(&rdev->rlc_fw, fw_name, rdev->dev); 1723 - if (err) 1724 - goto out; 1725 - if (rdev->rlc_fw->size != rlc_req_size) { 1726 - printk(KERN_ERR 1727 - "si_rlc: Bogus length %zu in firmware \"%s\"\n", 1728 - rdev->rlc_fw->size, fw_name); 1729 - err = -EINVAL; 1730 - } 1731 - 1732 - snprintf(fw_name, sizeof(fw_name), "radeon/%s_mc2.bin", chip_name); 1733 - err = request_firmware(&rdev->mc_fw, fw_name, rdev->dev); 1734 1625 if (err) { 1735 - snprintf(fw_name, sizeof(fw_name), "radeon/%s_mc.bin", chip_name); 1736 - err = request_firmware(&rdev->mc_fw, fw_name, rdev->dev); 1626 + snprintf(fw_name, sizeof(fw_name), "radeon/%s_pfp.bin", chip_name); 1627 + err = request_firmware(&rdev->pfp_fw, fw_name, rdev->dev); 1737 1628 if (err) 1738 1629 goto out; 1630 + if (rdev->pfp_fw->size != pfp_req_size) { 1631 + printk(KERN_ERR 1632 + "si_cp: Bogus length %zu in firmware \"%s\"\n", 1633 + rdev->pfp_fw->size, fw_name); 1634 + err = -EINVAL; 1635 + goto out; 1636 + } 1637 + } else { 1638 + err = radeon_ucode_validate(rdev->pfp_fw); 1639 + if (err) { 1640 + printk(KERN_ERR 1641 + "si_cp: validation failed for firmware \"%s\"\n", 1642 + fw_name); 1643 + goto out; 1644 + } else { 1645 + new_fw++; 1646 + } 1739 1647 } 1740 - if ((rdev->mc_fw->size != mc_req_size) && 1741 - (rdev->mc_fw->size != mc2_req_size)) { 1742 - printk(KERN_ERR 1743 - "si_mc: Bogus length %zu in firmware \"%s\"\n", 1744 - rdev->mc_fw->size, fw_name); 1745 - err = -EINVAL; 1746 - } 1747 - DRM_INFO("%s: %zu bytes\n", fw_name, rdev->mc_fw->size); 1748 1648 1749 - snprintf(fw_name, sizeof(fw_name), "radeon/%s_smc.bin", chip_name); 1649 + snprintf(fw_name, sizeof(fw_name), "radeon/%s_me.bin", new_chip_name); 1650 + err = request_firmware(&rdev->me_fw, fw_name, rdev->dev); 1651 + if (err) { 1652 + snprintf(fw_name, sizeof(fw_name), "radeon/%s_me.bin", chip_name); 1653 + err = request_firmware(&rdev->me_fw, fw_name, rdev->dev); 1654 + if (err) 1655 + goto out; 1656 + if (rdev->me_fw->size != me_req_size) { 1657 + printk(KERN_ERR 1658 + "si_cp: Bogus length %zu in firmware \"%s\"\n", 1659 + rdev->me_fw->size, fw_name); 1660 + err = -EINVAL; 1661 + } 1662 + } else { 1663 + err = radeon_ucode_validate(rdev->me_fw); 1664 + if (err) { 1665 + printk(KERN_ERR 1666 + "si_cp: validation failed for firmware \"%s\"\n", 1667 + fw_name); 1668 + goto out; 1669 + } else { 1670 + new_fw++; 1671 + } 1672 + } 1673 + 1674 + snprintf(fw_name, sizeof(fw_name), "radeon/%s_ce.bin", new_chip_name); 1675 + err = request_firmware(&rdev->ce_fw, fw_name, rdev->dev); 1676 + if (err) { 1677 + snprintf(fw_name, sizeof(fw_name), "radeon/%s_ce.bin", chip_name); 1678 + err = request_firmware(&rdev->ce_fw, fw_name, rdev->dev); 1679 + if (err) 1680 + goto out; 1681 + if (rdev->ce_fw->size != ce_req_size) { 1682 + printk(KERN_ERR 1683 + "si_cp: Bogus length %zu in firmware \"%s\"\n", 1684 + rdev->ce_fw->size, fw_name); 1685 + err = -EINVAL; 1686 + } 1687 + } else { 1688 + err = radeon_ucode_validate(rdev->ce_fw); 1689 + if (err) { 1690 + printk(KERN_ERR 1691 + "si_cp: validation failed for firmware \"%s\"\n", 1692 + fw_name); 1693 + goto out; 1694 + } else { 1695 + new_fw++; 1696 + } 1697 + } 1698 + 1699 + snprintf(fw_name, sizeof(fw_name), "radeon/%s_rlc.bin", new_chip_name); 1700 + err = request_firmware(&rdev->rlc_fw, fw_name, rdev->dev); 1701 + if (err) { 1702 + snprintf(fw_name, sizeof(fw_name), "radeon/%s_rlc.bin", chip_name); 1703 + err = request_firmware(&rdev->rlc_fw, fw_name, rdev->dev); 1704 + if (err) 1705 + goto out; 1706 + if (rdev->rlc_fw->size != rlc_req_size) { 1707 + printk(KERN_ERR 1708 + "si_rlc: Bogus length %zu in firmware \"%s\"\n", 1709 + rdev->rlc_fw->size, fw_name); 1710 + err = -EINVAL; 1711 + } 1712 + } else { 1713 + err = radeon_ucode_validate(rdev->rlc_fw); 1714 + if (err) { 1715 + printk(KERN_ERR 1716 + "si_cp: validation failed for firmware \"%s\"\n", 1717 + fw_name); 1718 + goto out; 1719 + } else { 1720 + new_fw++; 1721 + } 1722 + } 1723 + 1724 + snprintf(fw_name, sizeof(fw_name), "radeon/%s_mc.bin", new_chip_name); 1725 + err = request_firmware(&rdev->mc_fw, fw_name, rdev->dev); 1726 + if (err) { 1727 + snprintf(fw_name, sizeof(fw_name), "radeon/%s_mc2.bin", chip_name); 1728 + err = request_firmware(&rdev->mc_fw, fw_name, rdev->dev); 1729 + if (err) { 1730 + snprintf(fw_name, sizeof(fw_name), "radeon/%s_mc.bin", chip_name); 1731 + err = request_firmware(&rdev->mc_fw, fw_name, rdev->dev); 1732 + if (err) 1733 + goto out; 1734 + } 1735 + if ((rdev->mc_fw->size != mc_req_size) && 1736 + (rdev->mc_fw->size != mc2_req_size)) { 1737 + printk(KERN_ERR 1738 + "si_mc: Bogus length %zu in firmware \"%s\"\n", 1739 + rdev->mc_fw->size, fw_name); 1740 + err = -EINVAL; 1741 + } 1742 + DRM_INFO("%s: %zu bytes\n", fw_name, rdev->mc_fw->size); 1743 + } else { 1744 + err = radeon_ucode_validate(rdev->mc_fw); 1745 + if (err) { 1746 + printk(KERN_ERR 1747 + "si_cp: validation failed for firmware \"%s\"\n", 1748 + fw_name); 1749 + goto out; 1750 + } else { 1751 + new_fw++; 1752 + } 1753 + } 1754 + 1755 + snprintf(fw_name, sizeof(fw_name), "radeon/%s_smc.bin", new_chip_name); 1750 1756 err = request_firmware(&rdev->smc_fw, fw_name, rdev->dev); 1751 1757 if (err) { 1752 - printk(KERN_ERR 1753 - "smc: error loading firmware \"%s\"\n", 1754 - fw_name); 1755 - release_firmware(rdev->smc_fw); 1756 - rdev->smc_fw = NULL; 1757 - err = 0; 1758 - } else if (rdev->smc_fw->size != smc_req_size) { 1759 - printk(KERN_ERR 1760 - "si_smc: Bogus length %zu in firmware \"%s\"\n", 1761 - rdev->smc_fw->size, fw_name); 1762 - err = -EINVAL; 1758 + snprintf(fw_name, sizeof(fw_name), "radeon/%s_smc.bin", chip_name); 1759 + err = request_firmware(&rdev->smc_fw, fw_name, rdev->dev); 1760 + if (err) { 1761 + printk(KERN_ERR 1762 + "smc: error loading firmware \"%s\"\n", 1763 + fw_name); 1764 + release_firmware(rdev->smc_fw); 1765 + rdev->smc_fw = NULL; 1766 + err = 0; 1767 + } else if (rdev->smc_fw->size != smc_req_size) { 1768 + printk(KERN_ERR 1769 + "si_smc: Bogus length %zu in firmware \"%s\"\n", 1770 + rdev->smc_fw->size, fw_name); 1771 + err = -EINVAL; 1772 + } 1773 + } else { 1774 + err = radeon_ucode_validate(rdev->smc_fw); 1775 + if (err) { 1776 + printk(KERN_ERR 1777 + "si_cp: validation failed for firmware \"%s\"\n", 1778 + fw_name); 1779 + goto out; 1780 + } else { 1781 + new_fw++; 1782 + } 1763 1783 } 1764 1784 1785 + if (new_fw == 0) { 1786 + rdev->new_fw = false; 1787 + } else if (new_fw < 6) { 1788 + printk(KERN_ERR "si_fw: mixing new and old firmware!\n"); 1789 + err = -EINVAL; 1790 + } else { 1791 + rdev->new_fw = true; 1792 + } 1765 1793 out: 1766 1794 if (err) { 1767 1795 if (err != -EINVAL) ··· 3438 3282 3439 3283 static int si_cp_load_microcode(struct radeon_device *rdev) 3440 3284 { 3441 - const __be32 *fw_data; 3442 3285 int i; 3443 3286 3444 - if (!rdev->me_fw || !rdev->pfp_fw) 3287 + if (!rdev->me_fw || !rdev->pfp_fw || !rdev->ce_fw) 3445 3288 return -EINVAL; 3446 3289 3447 3290 si_cp_enable(rdev, false); 3448 3291 3449 - /* PFP */ 3450 - fw_data = (const __be32 *)rdev->pfp_fw->data; 3451 - WREG32(CP_PFP_UCODE_ADDR, 0); 3452 - for (i = 0; i < SI_PFP_UCODE_SIZE; i++) 3453 - WREG32(CP_PFP_UCODE_DATA, be32_to_cpup(fw_data++)); 3454 - WREG32(CP_PFP_UCODE_ADDR, 0); 3292 + if (rdev->new_fw) { 3293 + const struct gfx_firmware_header_v1_0 *pfp_hdr = 3294 + (const struct gfx_firmware_header_v1_0 *)rdev->pfp_fw->data; 3295 + const struct gfx_firmware_header_v1_0 *ce_hdr = 3296 + (const struct gfx_firmware_header_v1_0 *)rdev->ce_fw->data; 3297 + const struct gfx_firmware_header_v1_0 *me_hdr = 3298 + (const struct gfx_firmware_header_v1_0 *)rdev->me_fw->data; 3299 + const __le32 *fw_data; 3300 + u32 fw_size; 3455 3301 3456 - /* CE */ 3457 - fw_data = (const __be32 *)rdev->ce_fw->data; 3458 - WREG32(CP_CE_UCODE_ADDR, 0); 3459 - for (i = 0; i < SI_CE_UCODE_SIZE; i++) 3460 - WREG32(CP_CE_UCODE_DATA, be32_to_cpup(fw_data++)); 3461 - WREG32(CP_CE_UCODE_ADDR, 0); 3302 + radeon_ucode_print_gfx_hdr(&pfp_hdr->header); 3303 + radeon_ucode_print_gfx_hdr(&ce_hdr->header); 3304 + radeon_ucode_print_gfx_hdr(&me_hdr->header); 3462 3305 3463 - /* ME */ 3464 - fw_data = (const __be32 *)rdev->me_fw->data; 3465 - WREG32(CP_ME_RAM_WADDR, 0); 3466 - for (i = 0; i < SI_PM4_UCODE_SIZE; i++) 3467 - WREG32(CP_ME_RAM_DATA, be32_to_cpup(fw_data++)); 3468 - WREG32(CP_ME_RAM_WADDR, 0); 3306 + /* PFP */ 3307 + fw_data = (const __le32 *) 3308 + (rdev->pfp_fw->data + le32_to_cpu(pfp_hdr->header.ucode_array_offset_bytes)); 3309 + fw_size = le32_to_cpu(pfp_hdr->header.ucode_size_bytes) / 4; 3310 + WREG32(CP_PFP_UCODE_ADDR, 0); 3311 + for (i = 0; i < fw_size; i++) 3312 + WREG32(CP_PFP_UCODE_DATA, le32_to_cpup(fw_data++)); 3313 + WREG32(CP_PFP_UCODE_ADDR, 0); 3314 + 3315 + /* CE */ 3316 + fw_data = (const __le32 *) 3317 + (rdev->ce_fw->data + le32_to_cpu(ce_hdr->header.ucode_array_offset_bytes)); 3318 + fw_size = le32_to_cpu(ce_hdr->header.ucode_size_bytes) / 4; 3319 + WREG32(CP_CE_UCODE_ADDR, 0); 3320 + for (i = 0; i < fw_size; i++) 3321 + WREG32(CP_CE_UCODE_DATA, le32_to_cpup(fw_data++)); 3322 + WREG32(CP_CE_UCODE_ADDR, 0); 3323 + 3324 + /* ME */ 3325 + fw_data = (const __be32 *) 3326 + (rdev->me_fw->data + le32_to_cpu(me_hdr->header.ucode_array_offset_bytes)); 3327 + fw_size = le32_to_cpu(me_hdr->header.ucode_size_bytes) / 4; 3328 + WREG32(CP_ME_RAM_WADDR, 0); 3329 + for (i = 0; i < fw_size; i++) 3330 + WREG32(CP_ME_RAM_DATA, le32_to_cpup(fw_data++)); 3331 + WREG32(CP_ME_RAM_WADDR, 0); 3332 + } else { 3333 + const __be32 *fw_data; 3334 + 3335 + /* PFP */ 3336 + fw_data = (const __be32 *)rdev->pfp_fw->data; 3337 + WREG32(CP_PFP_UCODE_ADDR, 0); 3338 + for (i = 0; i < SI_PFP_UCODE_SIZE; i++) 3339 + WREG32(CP_PFP_UCODE_DATA, be32_to_cpup(fw_data++)); 3340 + WREG32(CP_PFP_UCODE_ADDR, 0); 3341 + 3342 + /* CE */ 3343 + fw_data = (const __be32 *)rdev->ce_fw->data; 3344 + WREG32(CP_CE_UCODE_ADDR, 0); 3345 + for (i = 0; i < SI_CE_UCODE_SIZE; i++) 3346 + WREG32(CP_CE_UCODE_DATA, be32_to_cpup(fw_data++)); 3347 + WREG32(CP_CE_UCODE_ADDR, 0); 3348 + 3349 + /* ME */ 3350 + fw_data = (const __be32 *)rdev->me_fw->data; 3351 + WREG32(CP_ME_RAM_WADDR, 0); 3352 + for (i = 0; i < SI_PM4_UCODE_SIZE; i++) 3353 + WREG32(CP_ME_RAM_DATA, be32_to_cpup(fw_data++)); 3354 + WREG32(CP_ME_RAM_WADDR, 0); 3355 + } 3469 3356 3470 3357 WREG32(CP_PFP_UCODE_ADDR, 0); 3471 3358 WREG32(CP_CE_UCODE_ADDR, 0); ··· 5791 5592 static int si_rlc_resume(struct radeon_device *rdev) 5792 5593 { 5793 5594 u32 i; 5794 - const __be32 *fw_data; 5795 5595 5796 5596 if (!rdev->rlc_fw) 5797 5597 return -EINVAL; ··· 5813 5615 WREG32(RLC_MC_CNTL, 0); 5814 5616 WREG32(RLC_UCODE_CNTL, 0); 5815 5617 5816 - fw_data = (const __be32 *)rdev->rlc_fw->data; 5817 - for (i = 0; i < SI_RLC_UCODE_SIZE; i++) { 5818 - WREG32(RLC_UCODE_ADDR, i); 5819 - WREG32(RLC_UCODE_DATA, be32_to_cpup(fw_data++)); 5618 + if (rdev->new_fw) { 5619 + const struct rlc_firmware_header_v1_0 *hdr = 5620 + (const struct rlc_firmware_header_v1_0 *)rdev->rlc_fw->data; 5621 + u32 fw_size = le32_to_cpu(hdr->header.ucode_size_bytes) / 4; 5622 + const __le32 *fw_data = (const __le32 *) 5623 + (rdev->rlc_fw->data + le32_to_cpu(hdr->header.ucode_array_offset_bytes)); 5624 + 5625 + radeon_ucode_print_rlc_hdr(&hdr->header); 5626 + 5627 + for (i = 0; i < fw_size; i++) { 5628 + WREG32(RLC_UCODE_ADDR, i); 5629 + WREG32(RLC_UCODE_DATA, le32_to_cpup(fw_data++)); 5630 + } 5631 + } else { 5632 + const __be32 *fw_data = 5633 + (const __be32 *)rdev->rlc_fw->data; 5634 + for (i = 0; i < SI_RLC_UCODE_SIZE; i++) { 5635 + WREG32(RLC_UCODE_ADDR, i); 5636 + WREG32(RLC_UCODE_DATA, be32_to_cpup(fw_data++)); 5637 + } 5820 5638 } 5821 5639 WREG32(RLC_UCODE_ADDR, 0); 5822 5640
+37 -25
drivers/gpu/drm/radeon/si_smc.c
··· 219 219 if (!rdev->smc_fw) 220 220 return -EINVAL; 221 221 222 - switch (rdev->family) { 223 - case CHIP_TAHITI: 224 - ucode_start_address = TAHITI_SMC_UCODE_START; 225 - ucode_size = TAHITI_SMC_UCODE_SIZE; 226 - break; 227 - case CHIP_PITCAIRN: 228 - ucode_start_address = PITCAIRN_SMC_UCODE_START; 229 - ucode_size = PITCAIRN_SMC_UCODE_SIZE; 230 - break; 231 - case CHIP_VERDE: 232 - ucode_start_address = VERDE_SMC_UCODE_START; 233 - ucode_size = VERDE_SMC_UCODE_SIZE; 234 - break; 235 - case CHIP_OLAND: 236 - ucode_start_address = OLAND_SMC_UCODE_START; 237 - ucode_size = OLAND_SMC_UCODE_SIZE; 238 - break; 239 - case CHIP_HAINAN: 240 - ucode_start_address = HAINAN_SMC_UCODE_START; 241 - ucode_size = HAINAN_SMC_UCODE_SIZE; 242 - break; 243 - default: 244 - DRM_ERROR("unknown asic in smc ucode loader\n"); 245 - BUG(); 222 + if (rdev->new_fw) { 223 + const struct smc_firmware_header_v1_0 *hdr = 224 + (const struct smc_firmware_header_v1_0 *)rdev->smc_fw->data; 225 + 226 + radeon_ucode_print_smc_hdr(&hdr->header); 227 + 228 + ucode_start_address = le32_to_cpu(hdr->ucode_start_addr); 229 + ucode_size = le32_to_cpu(hdr->header.ucode_size_bytes); 230 + src = (const u8 *) 231 + (rdev->smc_fw->data + le32_to_cpu(hdr->header.ucode_array_offset_bytes)); 232 + } else { 233 + switch (rdev->family) { 234 + case CHIP_TAHITI: 235 + ucode_start_address = TAHITI_SMC_UCODE_START; 236 + ucode_size = TAHITI_SMC_UCODE_SIZE; 237 + break; 238 + case CHIP_PITCAIRN: 239 + ucode_start_address = PITCAIRN_SMC_UCODE_START; 240 + ucode_size = PITCAIRN_SMC_UCODE_SIZE; 241 + break; 242 + case CHIP_VERDE: 243 + ucode_start_address = VERDE_SMC_UCODE_START; 244 + ucode_size = VERDE_SMC_UCODE_SIZE; 245 + break; 246 + case CHIP_OLAND: 247 + ucode_start_address = OLAND_SMC_UCODE_START; 248 + ucode_size = OLAND_SMC_UCODE_SIZE; 249 + break; 250 + case CHIP_HAINAN: 251 + ucode_start_address = HAINAN_SMC_UCODE_START; 252 + ucode_size = HAINAN_SMC_UCODE_SIZE; 253 + break; 254 + default: 255 + DRM_ERROR("unknown asic in smc ucode loader\n"); 256 + BUG(); 257 + } 258 + src = (const u8 *)rdev->smc_fw->data; 246 259 } 247 260 248 261 if (ucode_size & 3) 249 262 return -EINVAL; 250 263 251 - src = (const u8 *)rdev->smc_fw->data; 252 264 spin_lock_irqsave(&rdev->smc_idx_lock, flags); 253 265 WREG32(SMC_IND_INDEX_0, ucode_start_address); 254 266 WREG32_P(SMC_IND_ACCESS_CNTL, AUTO_INCREMENT_IND_0, ~AUTO_INCREMENT_IND_0);