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

drm/amdgpu: Add option to refresh NPS data

In certain use cases, NPS data needs to be refreshed again from
discovery table. Add API parameter to refresh NPS data from discovery
table.

Signed-off-by: Lijo Lazar <lijo.lazar@amd.com>
Reviewed-by: Rajneesh Bhardwaj <rajneesh.bhardwaj@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>

authored by

Lijo Lazar and committed by
Alex Deucher
fcd91a95 5682cd86

+58 -20
+56 -18
drivers/gpu/drm/amd/amdgpu/amdgpu_discovery.c
··· 1723 1723 struct nps_info_v1_0 v1; 1724 1724 }; 1725 1725 1726 + static int amdgpu_discovery_refresh_nps_info(struct amdgpu_device *adev, 1727 + union nps_info *nps_data) 1728 + { 1729 + uint64_t vram_size, pos, offset; 1730 + struct nps_info_header *nhdr; 1731 + struct binary_header bhdr; 1732 + uint16_t checksum; 1733 + 1734 + vram_size = (uint64_t)RREG32(mmRCC_CONFIG_MEMSIZE) << 20; 1735 + pos = vram_size - DISCOVERY_TMR_OFFSET; 1736 + amdgpu_device_vram_access(adev, pos, &bhdr, sizeof(bhdr), false); 1737 + 1738 + offset = le16_to_cpu(bhdr.table_list[NPS_INFO].offset); 1739 + checksum = le16_to_cpu(bhdr.table_list[NPS_INFO].checksum); 1740 + 1741 + amdgpu_device_vram_access(adev, (pos + offset), nps_data, 1742 + sizeof(*nps_data), false); 1743 + 1744 + nhdr = (struct nps_info_header *)(nps_data); 1745 + if (!amdgpu_discovery_verify_checksum((uint8_t *)nps_data, 1746 + le32_to_cpu(nhdr->size_bytes), 1747 + checksum)) { 1748 + dev_err(adev->dev, "nps data refresh, checksum mismatch\n"); 1749 + return -EINVAL; 1750 + } 1751 + 1752 + return 0; 1753 + } 1754 + 1726 1755 int amdgpu_discovery_get_nps_info(struct amdgpu_device *adev, 1727 1756 uint32_t *nps_type, 1728 1757 struct amdgpu_gmc_memrange **ranges, 1729 - int *range_cnt) 1758 + int *range_cnt, bool refresh) 1730 1759 { 1731 1760 struct amdgpu_gmc_memrange *mem_ranges; 1732 1761 struct binary_header *bhdr; 1733 1762 union nps_info *nps_info; 1763 + union nps_info nps_data; 1734 1764 u16 offset; 1735 - int i; 1765 + int i, r; 1736 1766 1737 1767 if (!nps_type || !range_cnt || !ranges) 1738 1768 return -EINVAL; 1739 1769 1740 - if (!adev->mman.discovery_bin) { 1741 - dev_err(adev->dev, 1742 - "fetch mem range failed, ip discovery uninitialized\n"); 1743 - return -EINVAL; 1770 + if (refresh) { 1771 + r = amdgpu_discovery_refresh_nps_info(adev, &nps_data); 1772 + if (r) 1773 + return r; 1774 + nps_info = &nps_data; 1775 + } else { 1776 + if (!adev->mman.discovery_bin) { 1777 + dev_err(adev->dev, 1778 + "fetch mem range failed, ip discovery uninitialized\n"); 1779 + return -EINVAL; 1780 + } 1781 + 1782 + bhdr = (struct binary_header *)adev->mman.discovery_bin; 1783 + offset = le16_to_cpu(bhdr->table_list[NPS_INFO].offset); 1784 + 1785 + if (!offset) 1786 + return -ENOENT; 1787 + 1788 + /* If verification fails, return as if NPS table doesn't exist */ 1789 + if (amdgpu_discovery_verify_npsinfo(adev, bhdr)) 1790 + return -ENOENT; 1791 + 1792 + nps_info = 1793 + (union nps_info *)(adev->mman.discovery_bin + offset); 1744 1794 } 1745 - 1746 - bhdr = (struct binary_header *)adev->mman.discovery_bin; 1747 - offset = le16_to_cpu(bhdr->table_list[NPS_INFO].offset); 1748 - 1749 - if (!offset) 1750 - return -ENOENT; 1751 - 1752 - /* If verification fails, return as if NPS table doesn't exist */ 1753 - if (amdgpu_discovery_verify_npsinfo(adev, bhdr)) 1754 - return -ENOENT; 1755 - 1756 - nps_info = (union nps_info *)(adev->mman.discovery_bin + offset); 1757 1795 1758 1796 switch (le16_to_cpu(nps_info->v1.header.version_major)) { 1759 1797 case 1:
+1 -1
drivers/gpu/drm/amd/amdgpu/amdgpu_discovery.h
··· 33 33 int amdgpu_discovery_get_nps_info(struct amdgpu_device *adev, 34 34 uint32_t *nps_type, 35 35 struct amdgpu_gmc_memrange **ranges, 36 - int *range_cnt); 36 + int *range_cnt, bool refresh); 37 37 38 38 #endif /* __AMDGPU_DISCOVERY__ */
+1 -1
drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.c
··· 1172 1172 return -EINVAL; 1173 1173 1174 1174 ret = amdgpu_discovery_get_nps_info(adev, &nps_type, &ranges, 1175 - &range_cnt); 1175 + &range_cnt, false); 1176 1176 1177 1177 if (ret) 1178 1178 return ret;