diff options
Diffstat (limited to 'drivers/gpu/drm/amd/amdgpu/amdgpu_virt.c')
-rw-r--r-- | drivers/gpu/drm/amd/amdgpu/amdgpu_virt.c | 75 |
1 files changed, 75 insertions, 0 deletions
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 | |||
279 | int 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 | |||
299 | void 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 | |||