aboutsummaryrefslogtreecommitdiffstats
path: root/common/recipes-kernel/linux/linux-yocto-4.19.8/2234-drm-amdgpu-discovery-refactor-ip-list-traversal.patch
blob: 217d69da2f6feff6de2fcf2d33b1106178932a3d (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
From 2265fd4bd7049a3a7836a0385f9003a8d7672ee0 Mon Sep 17 00:00:00 2001
From: Xiaojie Yuan <xiaojie.yuan@amd.com>
Date: Wed, 27 Mar 2019 17:58:25 +0800
Subject: [PATCH 2234/2940] drm/amdgpu/discovery: refactor ip list traversal

for each ip, check whether it is needed by amdgpu driver,
if yes, record its base addresses

v2: change some DRM_INFO to DRM_DEBUG
v3: remove unused variable (Alex)

Signed-off-by: Xiaojie Yuan <xiaojie.yuan@amd.com>
Reviewed-by: Hawking Zhang <Hawking.Zhang@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
---
 drivers/gpu/drm/amd/amdgpu/amdgpu_discovery.c | 71 +++++++++++--------
 1 file changed, 42 insertions(+), 29 deletions(-)

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_discovery.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_discovery.c
index 697800c4741f..e049ae6a76fb 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_discovery.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_discovery.c
@@ -266,7 +266,6 @@ int amdgpu_discovery_reg_base_init(struct amdgpu_device *adev)
 	uint16_t num_ips;
 	uint8_t num_base_address;
 	int hw_ip;
-	int hw_id;
 	int i, j, k;
 
 	if (!adev->discovery) {
@@ -279,40 +278,54 @@ int amdgpu_discovery_reg_base_init(struct amdgpu_device *adev)
 			le16_to_cpu(bhdr->table_list[IP_DISCOVERY].offset));
 	num_dies = le16_to_cpu(ihdr->num_dies);
 
-	for (hw_ip = 0; hw_ip < MAX_HWIP; hw_ip++) {
-		hw_id = hw_id_map[hw_ip];
-
-		for (i = 0; i < num_dies; i++) {
-			die_offset = le16_to_cpu(ihdr->die_info[i].die_offset);
-			dhdr = (struct die_header *)(adev->discovery + die_offset);
-			num_ips = le16_to_cpu(dhdr->num_ips);
-			ip_offset = die_offset + sizeof(*dhdr);
-
-			for (j = 0; j < num_ips; j++) {
-				ip = (struct ip *)(adev->discovery + ip_offset);
-				num_base_address = ip->num_base_address;
-
-				if (le16_to_cpu(ip->hw_id) == hw_id) {
-					DRM_DEBUG("%s(%d) v%d.%d.%d:\n",
-						  hw_id_names[hw_id], hw_id,
-						  ip->major, ip->minor,
-						  ip->revision);
-
-					for (k = 0; k < num_base_address; k++) {
-						/*
-						 * convert the endianness of base addresses in place,
-						 * so that we don't need to convert them when accessing adev->reg_offset.
-						 */
-						ip->base_address[k] = le32_to_cpu(ip->base_address[k]);
-						DRM_DEBUG("\t0x%08x\n", ip->base_address[k]);
-					}
+	DRM_DEBUG("number of dies: %d\n", num_dies);
 
+	for (i = 0; i < num_dies; i++) {
+		die_offset = le16_to_cpu(ihdr->die_info[i].die_offset);
+		dhdr = (struct die_header *)(adev->discovery + die_offset);
+		num_ips = le16_to_cpu(dhdr->num_ips);
+		ip_offset = die_offset + sizeof(*dhdr);
+
+		if (le16_to_cpu(dhdr->die_id) != i) {
+			DRM_ERROR("invalid die id %d, expected %d\n",
+					le16_to_cpu(dhdr->die_id), i);
+			return -EINVAL;
+		}
+
+		DRM_DEBUG("number of hardware IPs on die%d: %d\n",
+				le16_to_cpu(dhdr->die_id), num_ips);
+
+		for (j = 0; j < num_ips; j++) {
+			ip = (struct ip *)(adev->discovery + ip_offset);
+			num_base_address = ip->num_base_address;
+
+			DRM_DEBUG("%s(%d) #%d v%d.%d.%d:\n",
+				  hw_id_names[le16_to_cpu(ip->hw_id)],
+				  le16_to_cpu(ip->hw_id),
+				  ip->number_instance,
+				  ip->major, ip->minor,
+				  ip->revision);
+
+			for (k = 0; k < num_base_address; k++) {
+				/*
+				 * convert the endianness of base addresses in place,
+				 * so that we don't need to convert them when accessing adev->reg_offset.
+				 */
+				ip->base_address[k] = le32_to_cpu(ip->base_address[k]);
+				DRM_DEBUG("\t0x%08x\n", ip->base_address[k]);
+			}
+
+			for (hw_ip = 0; hw_ip < MAX_HWIP; hw_ip++) {
+				if (hw_id_map[hw_ip] == le16_to_cpu(ip->hw_id)) {
+					DRM_INFO("set register base offset for %s\n",
+							hw_id_names[le16_to_cpu(ip->hw_id)]);
 					adev->reg_offset[hw_ip][ip->number_instance] =
 						ip->base_address;
 				}
 
-				ip_offset += sizeof(*ip) + 4 * (ip->num_base_address - 1);
 			}
+
+			ip_offset += sizeof(*ip) + 4 * (ip->num_base_address - 1);
 		}
 	}
 
-- 
2.17.1