Skip to content

Commit 645d694

Browse files
kwachowssgruszka
authored andcommitted
accel/ivpu: Use cached buffers for FW loading
Create buffers with cache coherency on the CPU side (write-back) while disabling snooping on the VPU side. These buffers require an explicit cache flush after each CPU-side modification. Configuring pages as write-combined may introduce significant delays, potentially taking hundreds of milliseconds for 64 MB buffers. Added internal DRM_IVPU_BO_NOSNOOP mask which disables snooping on the VPU side. Allocate FW runtime memory buffer (64 MB) as cached with snooping-disabled. This fixes random long FW loading times and boot params memory corruption on warmboot (due to missed wmb). Fixes: 02d5b0a ("accel/ivpu: Implement firmware parsing and booting") Signed-off-by: Karol Wachowski <[email protected]> Reviewed-by: Stanislaw Gruszka <[email protected]> Reviewed-by: Jeffrey Hugo <[email protected]> Signed-off-by: Stanislaw Gruszka <[email protected]> Link: https://patchwork.freedesktop.org/patch/msgid/[email protected]
1 parent 09bb81c commit 645d694

File tree

2 files changed

+10
-3
lines changed

2 files changed

+10
-3
lines changed

drivers/accel/ivpu/ivpu_fw.c

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -220,7 +220,8 @@ static int ivpu_fw_mem_init(struct ivpu_device *vdev)
220220
if (ret)
221221
return ret;
222222

223-
fw->mem = ivpu_bo_alloc_internal(vdev, fw->runtime_addr, fw->runtime_size, DRM_IVPU_BO_WC);
223+
fw->mem = ivpu_bo_alloc_internal(vdev, fw->runtime_addr, fw->runtime_size,
224+
DRM_IVPU_BO_CACHED | DRM_IVPU_BO_NOSNOOP);
224225
if (!fw->mem) {
225226
ivpu_err(vdev, "Failed to allocate firmware runtime memory\n");
226227
return -ENOMEM;
@@ -330,7 +331,7 @@ int ivpu_fw_load(struct ivpu_device *vdev)
330331
memset(start, 0, size);
331332
}
332333

333-
wmb(); /* Flush WC buffers after writing fw->mem */
334+
clflush_cache_range(fw->mem->kvaddr, fw->mem->base.size);
334335

335336
return 0;
336337
}
@@ -432,6 +433,7 @@ void ivpu_fw_boot_params_setup(struct ivpu_device *vdev, struct vpu_boot_params
432433
if (!ivpu_fw_is_cold_boot(vdev)) {
433434
boot_params->save_restore_ret_address = 0;
434435
vdev->pm->is_warmboot = true;
436+
clflush_cache_range(vdev->fw->mem->kvaddr, SZ_4K);
435437
return;
436438
}
437439

@@ -493,7 +495,7 @@ void ivpu_fw_boot_params_setup(struct ivpu_device *vdev, struct vpu_boot_params
493495
boot_params->punit_telemetry_sram_size = ivpu_hw_reg_telemetry_size_get(vdev);
494496
boot_params->vpu_telemetry_enable = ivpu_hw_reg_telemetry_enable_get(vdev);
495497

496-
wmb(); /* Flush WC buffers after writing bootparams */
498+
clflush_cache_range(vdev->fw->mem->kvaddr, SZ_4K);
497499

498500
ivpu_fw_boot_params_print(vdev, boot_params);
499501
}

drivers/accel/ivpu/ivpu_gem.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@
88
#include <drm/drm_gem.h>
99
#include <drm/drm_mm.h>
1010

11+
#define DRM_IVPU_BO_NOSNOOP 0x10000000
12+
1113
struct dma_buf;
1214
struct ivpu_bo_ops;
1315
struct ivpu_file_priv;
@@ -83,6 +85,9 @@ static inline u32 ivpu_bo_cache_mode(struct ivpu_bo *bo)
8385

8486
static inline bool ivpu_bo_is_snooped(struct ivpu_bo *bo)
8587
{
88+
if (bo->flags & DRM_IVPU_BO_NOSNOOP)
89+
return false;
90+
8691
return ivpu_bo_cache_mode(bo) == DRM_IVPU_BO_CACHED;
8792
}
8893

0 commit comments

Comments
 (0)