aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_device.c3
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_virt.c75
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_virt.h178
-rw-r--r--drivers/gpu/drm/amd/amdgpu/mxgpu_ai.c6
4 files changed, 262 insertions, 0 deletions
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
index 1f793eb301ef..9cdaba4af216 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
@@ -2300,6 +2300,9 @@ int amdgpu_device_init(struct amdgpu_device *adev,
2300 if (r) 2300 if (r)
2301 DRM_ERROR("ib ring test failed (%d).\n", r); 2301 DRM_ERROR("ib ring test failed (%d).\n", r);
2302 2302
2303 if (amdgpu_sriov_vf(adev))
2304 amdgpu_virt_init_data_exchange(adev);
2305
2303 amdgpu_fbdev_init(adev); 2306 amdgpu_fbdev_init(adev);
2304 2307
2305 r = amdgpu_pm_sysfs_init(adev); 2308 r = amdgpu_pm_sysfs_init(adev);
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_virt.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_virt.c
index ab05121b9272..ed7be2eb24b0 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_virt.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_virt.c
@@ -274,3 +274,78 @@ void amdgpu_virt_free_mm_table(struct amdgpu_device *adev)
274 (void *)&adev->virt.mm_table.cpu_addr); 274 (void *)&adev->virt.mm_table.cpu_addr);
275 adev->virt.mm_table.gpu_addr = 0; 275 adev->virt.mm_table.gpu_addr = 0;
276} 276}
277
278
279int amdgpu_virt_fw_reserve_get_checksum(void *obj,
280 unsigned long obj_size,
281 unsigned int key,
282 unsigned int chksum)
283{
284 unsigned int ret = key;
285 unsigned long i = 0;
286 unsigned char *pos;
287
288 pos = (char *)obj;
289 /* calculate checksum */
290 for (i = 0; i < obj_size; ++i)
291 ret += *(pos + i);
292 /* minus the chksum itself */
293 pos = (char *)&chksum;
294 for (i = 0; i < sizeof(chksum); ++i)
295 ret -= *(pos + i);
296 return ret;
297}
298
299void amdgpu_virt_init_data_exchange(struct amdgpu_device *adev)
300{
301 uint32_t pf2vf_ver = 0;
302 uint32_t pf2vf_size = 0;
303 uint32_t checksum = 0;
304 uint32_t checkval;
305 char *str;
306
307 adev->virt.fw_reserve.p_pf2vf = NULL;
308 adev->virt.fw_reserve.p_vf2pf = NULL;
309
310 if (adev->fw_vram_usage.va != NULL) {
311 adev->virt.fw_reserve.p_pf2vf =
312 (struct amdgim_pf2vf_info_header *)(
313 adev->fw_vram_usage.va + AMDGIM_DATAEXCHANGE_OFFSET);
314 pf2vf_ver = adev->virt.fw_reserve.p_pf2vf->version;
315 AMDGPU_FW_VRAM_PF2VF_READ(adev, header.size, &pf2vf_size);
316 AMDGPU_FW_VRAM_PF2VF_READ(adev, checksum, &checksum);
317
318 /* pf2vf message must be in 4K */
319 if (pf2vf_size > 0 && pf2vf_size < 4096) {
320 checkval = amdgpu_virt_fw_reserve_get_checksum(
321 adev->virt.fw_reserve.p_pf2vf, pf2vf_size,
322 adev->virt.fw_reserve.checksum_key, checksum);
323 if (checkval == checksum) {
324 adev->virt.fw_reserve.p_vf2pf =
325 ((void *)adev->virt.fw_reserve.p_pf2vf +
326 pf2vf_size);
327 memset((void *)adev->virt.fw_reserve.p_vf2pf, 0,
328 sizeof(amdgim_vf2pf_info));
329 AMDGPU_FW_VRAM_VF2PF_WRITE(adev, header.version,
330 AMDGPU_FW_VRAM_VF2PF_VER);
331 AMDGPU_FW_VRAM_VF2PF_WRITE(adev, header.size,
332 sizeof(amdgim_vf2pf_info));
333 AMDGPU_FW_VRAM_VF2PF_READ(adev, driver_version,
334 &str);
335 if (THIS_MODULE->version != NULL)
336 strcpy(str, THIS_MODULE->version);
337 else
338 strcpy(str, "N/A");
339 AMDGPU_FW_VRAM_VF2PF_WRITE(adev, driver_cert,
340 0);
341 AMDGPU_FW_VRAM_VF2PF_WRITE(adev, checksum,
342 amdgpu_virt_fw_reserve_get_checksum(
343 adev->virt.fw_reserve.p_vf2pf,
344 pf2vf_size,
345 adev->virt.fw_reserve.checksum_key, 0));
346 }
347 }
348 }
349}
350
351
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_virt.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_virt.h
index e5fd0ff6b29d..b89d37fc406f 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_virt.h
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_virt.h
@@ -58,6 +58,179 @@ struct amdgpu_virt_ops {
58 void (*trans_msg)(struct amdgpu_device *adev, u32 req, u32 data1, u32 data2, u32 data3); 58 void (*trans_msg)(struct amdgpu_device *adev, u32 req, u32 data1, u32 data2, u32 data3);
59}; 59};
60 60
61/*
62 * Firmware Reserve Frame buffer
63 */
64struct amdgpu_virt_fw_reserve {
65 struct amdgim_pf2vf_info_header *p_pf2vf;
66 struct amdgim_vf2pf_info_header *p_vf2pf;
67 unsigned int checksum_key;
68};
69/*
70 * Defination between PF and VF
71 * Structures forcibly aligned to 4 to keep the same style as PF.
72 */
73#define AMDGIM_DATAEXCHANGE_OFFSET (64 * 1024)
74
75#define AMDGIM_GET_STRUCTURE_RESERVED_SIZE(total, u8, u16, u32, u64) \
76 (total - (((u8)+3) / 4 + ((u16)+1) / 2 + (u32) + (u64)*2))
77
78enum AMDGIM_FEATURE_FLAG {
79 /* GIM supports feature of Error log collecting */
80 AMDGIM_FEATURE_ERROR_LOG_COLLECT = 0x1,
81 /* GIM supports feature of loading uCodes */
82 AMDGIM_FEATURE_GIM_LOAD_UCODES = 0x2,
83};
84
85struct amdgim_pf2vf_info_header {
86 /* the total structure size in byte. */
87 uint32_t size;
88 /* version of this structure, written by the GIM */
89 uint32_t version;
90} __aligned(4);
91struct amdgim_pf2vf_info_v1 {
92 /* header contains size and version */
93 struct amdgim_pf2vf_info_header header;
94 /* max_width * max_height */
95 unsigned int uvd_enc_max_pixels_count;
96 /* 16x16 pixels/sec, codec independent */
97 unsigned int uvd_enc_max_bandwidth;
98 /* max_width * max_height */
99 unsigned int vce_enc_max_pixels_count;
100 /* 16x16 pixels/sec, codec independent */
101 unsigned int vce_enc_max_bandwidth;
102 /* MEC FW position in kb from the start of visible frame buffer */
103 unsigned int mecfw_kboffset;
104 /* The features flags of the GIM driver supports. */
105 unsigned int feature_flags;
106 /* use private key from mailbox 2 to create chueksum */
107 unsigned int checksum;
108} __aligned(4);
109
110struct amdgim_pf2vf_info_v2 {
111 /* header contains size and version */
112 struct amdgim_pf2vf_info_header header;
113 /* use private key from mailbox 2 to create chueksum */
114 uint32_t checksum;
115 /* The features flags of the GIM driver supports. */
116 uint32_t feature_flags;
117 /* max_width * max_height */
118 uint32_t uvd_enc_max_pixels_count;
119 /* 16x16 pixels/sec, codec independent */
120 uint32_t uvd_enc_max_bandwidth;
121 /* max_width * max_height */
122 uint32_t vce_enc_max_pixels_count;
123 /* 16x16 pixels/sec, codec independent */
124 uint32_t vce_enc_max_bandwidth;
125 /* MEC FW position in kb from the start of VF visible frame buffer */
126 uint64_t mecfw_kboffset;
127 /* MEC FW size in KB */
128 uint32_t mecfw_ksize;
129 /* UVD FW position in kb from the start of VF visible frame buffer */
130 uint64_t uvdfw_kboffset;
131 /* UVD FW size in KB */
132 uint32_t uvdfw_ksize;
133 /* VCE FW position in kb from the start of VF visible frame buffer */
134 uint64_t vcefw_kboffset;
135 /* VCE FW size in KB */
136 uint32_t vcefw_ksize;
137 uint32_t reserved[AMDGIM_GET_STRUCTURE_RESERVED_SIZE(256, 0, 0, (9 + sizeof(struct amdgim_pf2vf_info_header)/sizeof(uint32_t)), 3)];
138} __aligned(4);
139
140
141struct amdgim_vf2pf_info_header {
142 /* the total structure size in byte. */
143 uint32_t size;
144 /*version of this structure, written by the guest */
145 uint32_t version;
146} __aligned(4);
147
148struct amdgim_vf2pf_info_v1 {
149 /* header contains size and version */
150 struct amdgim_vf2pf_info_header header;
151 /* driver version */
152 char driver_version[64];
153 /* driver certification, 1=WHQL, 0=None */
154 unsigned int driver_cert;
155 /* guest OS type and version: need a define */
156 unsigned int os_info;
157 /* in the unit of 1M */
158 unsigned int fb_usage;
159 /* guest gfx engine usage percentage */
160 unsigned int gfx_usage;
161 /* guest gfx engine health percentage */
162 unsigned int gfx_health;
163 /* guest compute engine usage percentage */
164 unsigned int compute_usage;
165 /* guest compute engine health percentage */
166 unsigned int compute_health;
167 /* guest vce engine usage percentage. 0xffff means N/A. */
168 unsigned int vce_enc_usage;
169 /* guest vce engine health percentage. 0xffff means N/A. */
170 unsigned int vce_enc_health;
171 /* guest uvd engine usage percentage. 0xffff means N/A. */
172 unsigned int uvd_enc_usage;
173 /* guest uvd engine usage percentage. 0xffff means N/A. */
174 unsigned int uvd_enc_health;
175 unsigned int checksum;
176} __aligned(4);
177
178struct amdgim_vf2pf_info_v2 {
179 /* header contains size and version */
180 struct amdgim_vf2pf_info_header header;
181 uint32_t checksum;
182 /* driver version */
183 uint8_t driver_version[64];
184 /* driver certification, 1=WHQL, 0=None */
185 uint32_t driver_cert;
186 /* guest OS type and version: need a define */
187 uint32_t os_info;
188 /* in the unit of 1M */
189 uint32_t fb_usage;
190 /* guest gfx engine usage percentage */
191 uint32_t gfx_usage;
192 /* guest gfx engine health percentage */
193 uint32_t gfx_health;
194 /* guest compute engine usage percentage */
195 uint32_t compute_usage;
196 /* guest compute engine health percentage */
197 uint32_t compute_health;
198 /* guest vce engine usage percentage. 0xffff means N/A. */
199 uint32_t vce_enc_usage;
200 /* guest vce engine health percentage. 0xffff means N/A. */
201 uint32_t vce_enc_health;
202 /* guest uvd engine usage percentage. 0xffff means N/A. */
203 uint32_t uvd_enc_usage;
204 /* guest uvd engine usage percentage. 0xffff means N/A. */
205 uint32_t uvd_enc_health;
206 uint32_t reserved[AMDGIM_GET_STRUCTURE_RESERVED_SIZE(256, 64, 0, (12 + sizeof(struct amdgim_vf2pf_info_header)/sizeof(uint32_t)), 0)];
207} __aligned(4);
208
209#define AMDGPU_FW_VRAM_VF2PF_VER 2
210typedef struct amdgim_vf2pf_info_v2 amdgim_vf2pf_info ;
211
212#define AMDGPU_FW_VRAM_VF2PF_WRITE(adev, field, val) \
213 do { \
214 ((amdgim_vf2pf_info *)adev->virt.fw_reserve.p_vf2pf)->field = (val); \
215 } while (0)
216
217#define AMDGPU_FW_VRAM_VF2PF_READ(adev, field, val) \
218 do { \
219 (*val) = ((amdgim_vf2pf_info *)adev->virt.fw_reserve.p_vf2pf)->field; \
220 } while (0)
221
222#define AMDGPU_FW_VRAM_PF2VF_READ(adev, field, val) \
223 do { \
224 if (!adev->virt.fw_reserve.p_pf2vf) \
225 *(val) = 0; \
226 else { \
227 if (adev->virt.fw_reserve.p_pf2vf->version == 1) \
228 *(val) = ((struct amdgim_pf2vf_info_v1 *)adev->virt.fw_reserve.p_pf2vf)->field; \
229 if (adev->virt.fw_reserve.p_pf2vf->version == 2) \
230 *(val) = ((struct amdgim_pf2vf_info_v2 *)adev->virt.fw_reserve.p_pf2vf)->field; \
231 } \
232 } while (0)
233
61/* GPU virtualization */ 234/* GPU virtualization */
62struct amdgpu_virt { 235struct amdgpu_virt {
63 uint32_t caps; 236 uint32_t caps;
@@ -72,6 +245,7 @@ struct amdgpu_virt {
72 struct amdgpu_mm_table mm_table; 245 struct amdgpu_mm_table mm_table;
73 const struct amdgpu_virt_ops *ops; 246 const struct amdgpu_virt_ops *ops;
74 struct amdgpu_vf_error_buffer vf_errors; 247 struct amdgpu_vf_error_buffer vf_errors;
248 struct amdgpu_virt_fw_reserve fw_reserve;
75}; 249};
76 250
77#define AMDGPU_CSA_SIZE (8 * 1024) 251#define AMDGPU_CSA_SIZE (8 * 1024)
@@ -114,5 +288,9 @@ int amdgpu_virt_reset_gpu(struct amdgpu_device *adev);
114int amdgpu_sriov_gpu_reset(struct amdgpu_device *adev, struct amdgpu_job *job); 288int amdgpu_sriov_gpu_reset(struct amdgpu_device *adev, struct amdgpu_job *job);
115int amdgpu_virt_alloc_mm_table(struct amdgpu_device *adev); 289int amdgpu_virt_alloc_mm_table(struct amdgpu_device *adev);
116void amdgpu_virt_free_mm_table(struct amdgpu_device *adev); 290void amdgpu_virt_free_mm_table(struct amdgpu_device *adev);
291int amdgpu_virt_fw_reserve_get_checksum(void *obj, unsigned long obj_size,
292 unsigned int key,
293 unsigned int chksum);
294void amdgpu_virt_init_data_exchange(struct amdgpu_device *adev);
117 295
118#endif 296#endif
diff --git a/drivers/gpu/drm/amd/amdgpu/mxgpu_ai.c b/drivers/gpu/drm/amd/amdgpu/mxgpu_ai.c
index 2812d88a8bdd..b4906d2f30d3 100644
--- a/drivers/gpu/drm/amd/amdgpu/mxgpu_ai.c
+++ b/drivers/gpu/drm/amd/amdgpu/mxgpu_ai.c
@@ -183,6 +183,12 @@ static int xgpu_ai_send_access_requests(struct amdgpu_device *adev,
183 pr_err("Doesn't get READY_TO_ACCESS_GPU from pf, give up\n"); 183 pr_err("Doesn't get READY_TO_ACCESS_GPU from pf, give up\n");
184 return r; 184 return r;
185 } 185 }
186 /* Retrieve checksum from mailbox2 */
187 if (req == IDH_REQ_GPU_INIT_ACCESS) {
188 adev->virt.fw_reserve.checksum_key =
189 RREG32_NO_KIQ(SOC15_REG_OFFSET(NBIO, 0,
190 mmBIF_BX_PF0_MAILBOX_MSGBUF_RCV_DW2));
191 }
186 } 192 }
187 193
188 return 0; 194 return 0;