<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=us-ascii">
<style type="text/css" style="display:none;"> P {margin-top:0;margin-bottom:0;} </style>
</head>
<body dir="ltr">
<p style="font-family:Arial;font-size:10pt;color:#008000;margin:15pt;" align="Left">
[Public]<br>
</p>
<br>
<div>
<div style="font-family: Calibri, Arial, Helvetica, sans-serif; font-size: 12pt; color: rgb(0, 0, 0);">
May want to update the sysfs interface as well.<br>
</div>
<div style="font-family: Calibri, Arial, Helvetica, sans-serif; font-size: 12pt; color: rgb(0, 0, 0);">
<br>
</div>
<div style="font-family: Calibri, Arial, Helvetica, sans-serif; font-size: 12pt; color: rgb(0, 0, 0);">
Reviewed-by: Alex Deucher <alexander.deucher@amd.com></div>
<div style="font-family: Calibri, Arial, Helvetica, sans-serif; font-size: 12pt; color: rgb(0, 0, 0);">
<br>
</div>
<div id="appendonsend"></div>
<hr style="display:inline-block;width:98%" tabindex="-1">
<div id="divRplyFwdMsg" dir="ltr"><font face="Calibri, sans-serif" style="font-size:11pt" color="#000000"><b>From:</b> Chen, Guchun <Guchun.Chen@amd.com><br>
<b>Sent:</b> Thursday, February 17, 2022 11:56 PM<br>
<b>To:</b> amd-gfx@lists.freedesktop.org <amd-gfx@lists.freedesktop.org>; Deucher, Alexander <Alexander.Deucher@amd.com>; Zhang, Hawking <Hawking.Zhang@amd.com>; Koenig, Christian <Christian.Koenig@amd.com>; Pan, Xinhui <Xinhui.Pan@amd.com><br>
<b>Cc:</b> Chen, Guchun <Guchun.Chen@amd.com><br>
<b>Subject:</b> [PATCH] drm/amdgpu: read harvest bit per IP data on legacy GPUs</font>
<div> </div>
</div>
<div class="BodyFragment"><font size="2"><span style="font-size:11pt;">
<div class="PlainText">Based on firmware team's input, harvest table in VBIOS does<br>
not apply well to legacy products like Navi1x, so seperate<br>
harvest mask configuration retrieve from different places.<br>
On legacy GPUs, scan harvest bit per IP data stuctures,<br>
while for newer ones, still read IP harvest info from harvest<br>
table.<br>
<br>
Signed-off-by: Guchun Chen <guchun.chen@amd.com><br>
---<br>
drivers/gpu/drm/amd/amdgpu/amdgpu_discovery.c | 119 ++++++++++++++----<br>
1 file changed, 93 insertions(+), 26 deletions(-)<br>
<br>
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_discovery.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_discovery.c<br>
index 2506bcf36c87..2ccac1f1582f 100644<br>
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_discovery.c<br>
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_discovery.c<br>
@@ -385,6 +385,87 @@ static int amdgpu_discovery_validate_ip(const struct ip *ip)<br>
return 0;<br>
}<br>
<br>
+static void amdgpu_discovery_read_harvest_bit_per_ip(struct amdgpu_device *adev,<br>
+ uint32_t *vcn_harvest_count)<br>
+{<br>
+ struct binary_header *bhdr;<br>
+ struct ip_discovery_header *ihdr;<br>
+ struct die_header *dhdr;<br>
+ struct ip *ip;<br>
+ uint16_t die_offset, ip_offset, num_dies, num_ips;<br>
+ int i, j;<br>
+<br>
+ bhdr = (struct binary_header *)adev->mman.discovery_bin;<br>
+ ihdr = (struct ip_discovery_header *)(adev->mman.discovery_bin +<br>
+ le16_to_cpu(bhdr->table_list[IP_DISCOVERY].offset));<br>
+ num_dies = le16_to_cpu(ihdr->num_dies);<br>
+<br>
+ /* scan harvest bit of all IP data structures */<br>
+ for (i = 0; i < num_dies; i++) {<br>
+ die_offset = le16_to_cpu(ihdr->die_info[i].die_offset);<br>
+ dhdr = (struct die_header *)(adev->mman.discovery_bin + die_offset);<br>
+ num_ips = le16_to_cpu(dhdr->num_ips);<br>
+ ip_offset = die_offset + sizeof(*dhdr);<br>
+<br>
+ for (j = 0; j < num_ips; j++) {<br>
+ ip = (struct ip *)(adev->mman.discovery_bin + ip_offset);<br>
+<br>
+ if (amdgpu_discovery_validate_ip(ip))<br>
+ goto next_ip;<br>
+<br>
+ if (le16_to_cpu(ip->harvest) == 1) {<br>
+ switch (le16_to_cpu(ip->hw_id)) {<br>
+ case VCN_HWID:<br>
+ (*vcn_harvest_count)++;<br>
+ if (ip->number_instance == 0)<br>
+ adev->vcn.harvest_config |= AMDGPU_VCN_HARVEST_VCN0;<br>
+ else<br>
+ adev->vcn.harvest_config |= AMDGPU_VCN_HARVEST_VCN1;<br>
+ break;<br>
+ case DMU_HWID:<br>
+ adev->harvest_ip_mask |= AMD_HARVEST_IP_DMU_MASK;<br>
+ break;<br>
+ default:<br>
+ break;<br>
+ }<br>
+ }<br>
+next_ip:<br>
+ ip_offset += sizeof(*ip) + 4 * (ip->num_base_address - 1);<br>
+ }<br>
+ }<br>
+}<br>
+<br>
+static void amdgpu_disocvery_read_from_harvest_table(struct amdgpu_device *adev,<br>
+ uint32_t *vcn_harvest_count)<br>
+{<br>
+ struct binary_header *bhdr;<br>
+ struct harvest_table *harvest_info;<br>
+ int i;<br>
+<br>
+ bhdr = (struct binary_header *)adev->mman.discovery_bin;<br>
+ harvest_info = (struct harvest_table *)(adev->mman.discovery_bin +<br>
+ le16_to_cpu(bhdr->table_list[HARVEST_INFO].offset));<br>
+ for (i = 0; i < 32; i++) {<br>
+ if (le16_to_cpu(harvest_info->list[i].hw_id) == 0)<br>
+ break;<br>
+<br>
+ switch (le16_to_cpu(harvest_info->list[i].hw_id)) {<br>
+ case VCN_HWID:<br>
+ (*vcn_harvest_count)++;<br>
+ if (harvest_info->list[i].number_instance == 0)<br>
+ adev->vcn.harvest_config |= AMDGPU_VCN_HARVEST_VCN0;<br>
+ else<br>
+ adev->vcn.harvest_config |= AMDGPU_VCN_HARVEST_VCN1;<br>
+ break;<br>
+ case DMU_HWID:<br>
+ adev->harvest_ip_mask |= AMD_HARVEST_IP_DMU_MASK;<br>
+ break;<br>
+ default:<br>
+ break;<br>
+ }<br>
+ }<br>
+}<br>
+<br>
/* ================================================== */<br>
<br>
struct ip_hw_instance {<br>
@@ -1046,33 +1127,19 @@ int amdgpu_discovery_get_ip_version(struct amdgpu_device *adev, int hw_id, int n<br>
<br>
void amdgpu_discovery_harvest_ip(struct amdgpu_device *adev)<br>
{<br>
- struct binary_header *bhdr;<br>
- struct harvest_table *harvest_info;<br>
- int i, vcn_harvest_count = 0;<br>
-<br>
- bhdr = (struct binary_header *)adev->mman.discovery_bin;<br>
- harvest_info = (struct harvest_table *)(adev->mman.discovery_bin +<br>
- le16_to_cpu(bhdr->table_list[HARVEST_INFO].offset));<br>
-<br>
- for (i = 0; i < 32; i++) {<br>
- if (le16_to_cpu(harvest_info->list[i].hw_id) == 0)<br>
- break;<br>
+ int vcn_harvest_count = 0;<br>
<br>
- switch (le16_to_cpu(harvest_info->list[i].hw_id)) {<br>
- case VCN_HWID:<br>
- vcn_harvest_count++;<br>
- if (harvest_info->list[i].number_instance == 0)<br>
- adev->vcn.harvest_config |= AMDGPU_VCN_HARVEST_VCN0;<br>
- else<br>
- adev->vcn.harvest_config |= AMDGPU_VCN_HARVEST_VCN1;<br>
- break;<br>
- case DMU_HWID:<br>
- adev->harvest_ip_mask |= AMD_HARVEST_IP_DMU_MASK;<br>
- break;<br>
- default:<br>
- break;<br>
- }<br>
- }<br>
+ /*<br>
+ * Harvest table does not fit Navi1x and legacy GPUs,<br>
+ * so read harvest bit per IP data structure to set<br>
+ * harvest configuration.<br>
+ */<br>
+ if (adev->ip_versions[GC_HWIP][0] < IP_VERSION(10, 2, 0))<br>
+ amdgpu_discovery_read_harvest_bit_per_ip(adev,<br>
+ &vcn_harvest_count);<br>
+ else<br>
+ amdgpu_disocvery_read_from_harvest_table(adev,<br>
+ &vcn_harvest_count);<br>
<br>
amdgpu_discovery_harvest_config_quirk(adev);<br>
<br>
-- <br>
2.17.1<br>
<br>
</div>
</span></font></div>
</div>
</body>
</html>