1 // SPDX-License-Identifier: GPL-2.0-only
3 * Copyright (C) 2020-2024 Intel Corporation
6 #include <linux/firmware.h>
7 #include <linux/highmem.h>
8 #include <linux/moduleparam.h>
11 #include "vpu_boot_api.h"
14 #include "ivpu_fw_log.h"
20 #define FW_GLOBAL_MEM_START (2ull * SZ_1G)
21 #define FW_GLOBAL_MEM_END (3ull * SZ_1G)
22 #define FW_SHARED_MEM_SIZE SZ_256M /* Must be aligned to FW_SHARED_MEM_ALIGNMENT */
23 #define FW_SHARED_MEM_ALIGNMENT SZ_128K /* VPU MTRR limitation */
24 #define FW_RUNTIME_MAX_SIZE SZ_512M
25 #define FW_SHAVE_NN_MAX_SIZE SZ_2M
26 #define FW_RUNTIME_MIN_ADDR (FW_GLOBAL_MEM_START)
27 #define FW_RUNTIME_MAX_ADDR (FW_GLOBAL_MEM_END - FW_SHARED_MEM_SIZE)
28 #define FW_FILE_IMAGE_OFFSET (VPU_FW_HEADER_SIZE + FW_VERSION_HEADER_SIZE)
30 #define WATCHDOG_MSS_REDIRECT 32
31 #define WATCHDOG_NCE_REDIRECT 33
33 #define ADDR_TO_L2_CACHE_CFG(addr) ((addr) >> 31)
35 /* Check if FW API is compatible with the driver */
36 #define IVPU_FW_CHECK_API_COMPAT(vdev, fw_hdr, name, min_major) \
37 ivpu_fw_check_api(vdev, fw_hdr, #name, \
38 VPU_##name##_API_VER_INDEX, \
39 VPU_##name##_API_VER_MAJOR, \
40 VPU_##name##_API_VER_MINOR, min_major)
42 /* Check if API version is lower that the given version */
43 #define IVPU_FW_CHECK_API_VER_LT(vdev, fw_hdr, name, major, minor) \
44 ivpu_fw_check_api_ver_lt(vdev, fw_hdr, #name, VPU_##name##_API_VER_INDEX, major, minor)
46 #define IVPU_FOCUS_PRESENT_TIMER_MS 1000
48 static char *ivpu_firmware
;
49 #if IS_ENABLED(CONFIG_DRM_ACCEL_IVPU_DEBUG)
50 module_param_named_unsafe(firmware
, ivpu_firmware
, charp
, 0644);
51 MODULE_PARM_DESC(firmware
, "NPU firmware binary in /lib/firmware/..");
58 { IVPU_HW_IP_37XX
, "vpu_37xx.bin" },
59 { IVPU_HW_IP_37XX
, "intel/vpu/vpu_37xx_v0.0.bin" },
60 { IVPU_HW_IP_40XX
, "vpu_40xx.bin" },
61 { IVPU_HW_IP_40XX
, "intel/vpu/vpu_40xx_v0.0.bin" },
62 { IVPU_HW_IP_50XX
, "vpu_50xx.bin" },
63 { IVPU_HW_IP_50XX
, "intel/vpu/vpu_50xx_v0.0.bin" },
66 /* Production fw_names from the table above */
67 MODULE_FIRMWARE("intel/vpu/vpu_37xx_v0.0.bin");
68 MODULE_FIRMWARE("intel/vpu/vpu_40xx_v0.0.bin");
69 MODULE_FIRMWARE("intel/vpu/vpu_50xx_v0.0.bin");
71 static int ivpu_fw_request(struct ivpu_device
*vdev
)
77 ret
= request_firmware(&vdev
->fw
->file
, ivpu_firmware
, vdev
->drm
.dev
);
79 vdev
->fw
->name
= ivpu_firmware
;
83 for (i
= 0; i
< ARRAY_SIZE(fw_names
); i
++) {
84 if (fw_names
[i
].gen
!= ivpu_hw_ip_gen(vdev
))
87 ret
= firmware_request_nowarn(&vdev
->fw
->file
, fw_names
[i
].name
, vdev
->drm
.dev
);
89 vdev
->fw
->name
= fw_names
[i
].name
;
94 ivpu_err(vdev
, "Failed to request firmware: %d\n", ret
);
99 ivpu_fw_check_api(struct ivpu_device
*vdev
, const struct vpu_firmware_header
*fw_hdr
,
100 const char *str
, int index
, u16 expected_major
, u16 expected_minor
,
103 u16 major
= (u16
)(fw_hdr
->api_version
[index
] >> 16);
104 u16 minor
= (u16
)(fw_hdr
->api_version
[index
]);
106 if (major
< min_major
) {
107 ivpu_err(vdev
, "Incompatible FW %s API version: %d.%d, required %d.0 or later\n",
108 str
, major
, minor
, min_major
);
111 if (major
!= expected_major
) {
112 ivpu_warn(vdev
, "Major FW %s API version different: %d.%d (expected %d.%d)\n",
113 str
, major
, minor
, expected_major
, expected_minor
);
115 ivpu_dbg(vdev
, FW_BOOT
, "FW %s API version: %d.%d (expected %d.%d)\n",
116 str
, major
, minor
, expected_major
, expected_minor
);
122 ivpu_fw_check_api_ver_lt(struct ivpu_device
*vdev
, const struct vpu_firmware_header
*fw_hdr
,
123 const char *str
, int index
, u16 major
, u16 minor
)
125 u16 fw_major
= (u16
)(fw_hdr
->api_version
[index
] >> 16);
126 u16 fw_minor
= (u16
)(fw_hdr
->api_version
[index
]);
128 if (fw_major
< major
|| (fw_major
== major
&& fw_minor
< minor
))
134 static bool is_within_range(u64 addr
, size_t size
, u64 range_start
, size_t range_size
)
136 if (addr
< range_start
|| addr
+ size
> range_start
+ range_size
)
143 ivpu_fw_sched_mode_select(struct ivpu_device
*vdev
, const struct vpu_firmware_header
*fw_hdr
)
145 if (ivpu_sched_mode
!= IVPU_SCHED_MODE_AUTO
)
146 return ivpu_sched_mode
;
148 return VPU_SCHEDULING_MODE_OS
;
151 static int ivpu_fw_parse(struct ivpu_device
*vdev
)
153 struct ivpu_fw_info
*fw
= vdev
->fw
;
154 const struct vpu_firmware_header
*fw_hdr
= (const void *)fw
->file
->data
;
155 u64 runtime_addr
, image_load_addr
, runtime_size
, image_size
;
157 if (fw
->file
->size
<= FW_FILE_IMAGE_OFFSET
) {
158 ivpu_err(vdev
, "Firmware file is too small: %zu\n", fw
->file
->size
);
162 if (fw_hdr
->header_version
!= VPU_FW_HEADER_VERSION
) {
163 ivpu_err(vdev
, "Invalid firmware header version: %u\n", fw_hdr
->header_version
);
167 runtime_addr
= fw_hdr
->boot_params_load_address
;
168 runtime_size
= fw_hdr
->runtime_size
;
169 image_load_addr
= fw_hdr
->image_load_address
;
170 image_size
= fw_hdr
->image_size
;
172 if (runtime_addr
< FW_RUNTIME_MIN_ADDR
|| runtime_addr
> FW_RUNTIME_MAX_ADDR
) {
173 ivpu_err(vdev
, "Invalid firmware runtime address: 0x%llx\n", runtime_addr
);
177 if (runtime_size
< fw
->file
->size
|| runtime_size
> FW_RUNTIME_MAX_SIZE
) {
178 ivpu_err(vdev
, "Invalid firmware runtime size: %llu\n", runtime_size
);
182 if (FW_FILE_IMAGE_OFFSET
+ image_size
> fw
->file
->size
) {
183 ivpu_err(vdev
, "Invalid image size: %llu\n", image_size
);
187 if (image_load_addr
< runtime_addr
||
188 image_load_addr
+ image_size
> runtime_addr
+ runtime_size
) {
189 ivpu_err(vdev
, "Invalid firmware load address size: 0x%llx and size %llu\n",
190 image_load_addr
, image_size
);
194 if (fw_hdr
->shave_nn_fw_size
> FW_SHAVE_NN_MAX_SIZE
) {
195 ivpu_err(vdev
, "SHAVE NN firmware is too big: %u\n", fw_hdr
->shave_nn_fw_size
);
199 if (fw_hdr
->entry_point
< image_load_addr
||
200 fw_hdr
->entry_point
>= image_load_addr
+ image_size
) {
201 ivpu_err(vdev
, "Invalid entry point: 0x%llx\n", fw_hdr
->entry_point
);
204 ivpu_dbg(vdev
, FW_BOOT
, "Header version: 0x%x, format 0x%x\n",
205 fw_hdr
->header_version
, fw_hdr
->image_format
);
207 if (!scnprintf(fw
->version
, sizeof(fw
->version
), "%s", fw
->file
->data
+ VPU_FW_HEADER_SIZE
))
208 ivpu_warn(vdev
, "Missing firmware version\n");
210 ivpu_info(vdev
, "Firmware: %s, version: %s\n", fw
->name
, fw
->version
);
212 if (IVPU_FW_CHECK_API_COMPAT(vdev
, fw_hdr
, BOOT
, 3))
214 if (IVPU_FW_CHECK_API_COMPAT(vdev
, fw_hdr
, JSM
, 3))
217 fw
->runtime_addr
= runtime_addr
;
218 fw
->runtime_size
= runtime_size
;
219 fw
->image_load_offset
= image_load_addr
- runtime_addr
;
220 fw
->image_size
= image_size
;
221 fw
->shave_nn_size
= PAGE_ALIGN(fw_hdr
->shave_nn_fw_size
);
223 fw
->cold_boot_entry_point
= fw_hdr
->entry_point
;
224 fw
->entry_point
= fw
->cold_boot_entry_point
;
226 fw
->trace_level
= min_t(u32
, ivpu_fw_log_level
, IVPU_FW_LOG_FATAL
);
227 fw
->trace_destination_mask
= VPU_TRACE_DESTINATION_VERBOSE_TRACING
;
228 fw
->trace_hw_component_mask
= -1;
232 fw
->sched_mode
= ivpu_fw_sched_mode_select(vdev
, fw_hdr
);
233 fw
->primary_preempt_buf_size
= fw_hdr
->preemption_buffer_1_size
;
234 fw
->secondary_preempt_buf_size
= fw_hdr
->preemption_buffer_2_size
;
235 ivpu_info(vdev
, "Scheduler mode: %s\n", fw
->sched_mode
? "HW" : "OS");
237 if (fw_hdr
->ro_section_start_address
&& !is_within_range(fw_hdr
->ro_section_start_address
,
238 fw_hdr
->ro_section_size
,
239 fw_hdr
->image_load_address
,
240 fw_hdr
->image_size
)) {
241 ivpu_err(vdev
, "Invalid read-only section: start address 0x%llx, size %u\n",
242 fw_hdr
->ro_section_start_address
, fw_hdr
->ro_section_size
);
246 fw
->read_only_addr
= fw_hdr
->ro_section_start_address
;
247 fw
->read_only_size
= fw_hdr
->ro_section_size
;
249 ivpu_dbg(vdev
, FW_BOOT
, "Size: file %lu image %u runtime %u shavenn %u\n",
250 fw
->file
->size
, fw
->image_size
, fw
->runtime_size
, fw
->shave_nn_size
);
251 ivpu_dbg(vdev
, FW_BOOT
, "Address: runtime 0x%llx, load 0x%llx, entry point 0x%llx\n",
252 fw
->runtime_addr
, image_load_addr
, fw
->entry_point
);
253 ivpu_dbg(vdev
, FW_BOOT
, "Read-only section: address 0x%llx, size %u\n",
254 fw
->read_only_addr
, fw
->read_only_size
);
259 static void ivpu_fw_release(struct ivpu_device
*vdev
)
261 release_firmware(vdev
->fw
->file
);
264 /* Initialize workarounds that depend on FW version */
266 ivpu_fw_init_wa(struct ivpu_device
*vdev
)
268 const struct vpu_firmware_header
*fw_hdr
= (const void *)vdev
->fw
->file
->data
;
270 if (IVPU_FW_CHECK_API_VER_LT(vdev
, fw_hdr
, BOOT
, 3, 17) ||
271 (ivpu_test_mode
& IVPU_TEST_MODE_D0I3_MSG_DISABLE
))
272 vdev
->wa
.disable_d0i3_msg
= true;
274 /* Force enable the feature for testing purposes */
275 if (ivpu_test_mode
& IVPU_TEST_MODE_D0I3_MSG_ENABLE
)
276 vdev
->wa
.disable_d0i3_msg
= false;
278 IVPU_PRINT_WA(disable_d0i3_msg
);
281 static int ivpu_fw_update_global_range(struct ivpu_device
*vdev
)
283 struct ivpu_fw_info
*fw
= vdev
->fw
;
284 u64 start
= ALIGN(fw
->runtime_addr
+ fw
->runtime_size
, FW_SHARED_MEM_ALIGNMENT
);
285 u64 size
= FW_SHARED_MEM_SIZE
;
287 if (start
+ size
> FW_GLOBAL_MEM_END
) {
288 ivpu_err(vdev
, "No space for shared region, start %lld, size %lld\n", start
, size
);
292 ivpu_hw_range_init(&vdev
->hw
->ranges
.global
, start
, size
);
296 static int ivpu_fw_mem_init(struct ivpu_device
*vdev
)
298 struct ivpu_fw_info
*fw
= vdev
->fw
;
299 struct ivpu_addr_range fw_range
;
303 ret
= ivpu_fw_update_global_range(vdev
);
307 fw_range
.start
= fw
->runtime_addr
;
308 fw_range
.end
= fw
->runtime_addr
+ fw
->runtime_size
;
309 fw
->mem
= ivpu_bo_create(vdev
, &vdev
->gctx
, &fw_range
, fw
->runtime_size
,
310 DRM_IVPU_BO_WC
| DRM_IVPU_BO_MAPPABLE
);
312 ivpu_err(vdev
, "Failed to create firmware runtime memory buffer\n");
316 ret
= ivpu_mmu_context_set_pages_ro(vdev
, &vdev
->gctx
, fw
->read_only_addr
,
319 ivpu_err(vdev
, "Failed to set firmware image read-only\n");
320 goto err_free_fw_mem
;
323 fw
->mem_log_crit
= ivpu_bo_create_global(vdev
, IVPU_FW_CRITICAL_BUFFER_SIZE
,
324 DRM_IVPU_BO_CACHED
| DRM_IVPU_BO_MAPPABLE
);
325 if (!fw
->mem_log_crit
) {
326 ivpu_err(vdev
, "Failed to create critical log buffer\n");
328 goto err_free_fw_mem
;
331 if (ivpu_fw_log_level
<= IVPU_FW_LOG_INFO
)
332 log_verb_size
= IVPU_FW_VERBOSE_BUFFER_LARGE_SIZE
;
334 log_verb_size
= IVPU_FW_VERBOSE_BUFFER_SMALL_SIZE
;
336 fw
->mem_log_verb
= ivpu_bo_create_global(vdev
, log_verb_size
,
337 DRM_IVPU_BO_CACHED
| DRM_IVPU_BO_MAPPABLE
);
338 if (!fw
->mem_log_verb
) {
339 ivpu_err(vdev
, "Failed to create verbose log buffer\n");
341 goto err_free_log_crit
;
344 if (fw
->shave_nn_size
) {
345 fw
->mem_shave_nn
= ivpu_bo_create(vdev
, &vdev
->gctx
, &vdev
->hw
->ranges
.shave
,
346 fw
->shave_nn_size
, DRM_IVPU_BO_WC
);
347 if (!fw
->mem_shave_nn
) {
348 ivpu_err(vdev
, "Failed to create shavenn buffer\n");
350 goto err_free_log_verb
;
357 ivpu_bo_free(fw
->mem_log_verb
);
359 ivpu_bo_free(fw
->mem_log_crit
);
361 ivpu_bo_free(fw
->mem
);
365 static void ivpu_fw_mem_fini(struct ivpu_device
*vdev
)
367 struct ivpu_fw_info
*fw
= vdev
->fw
;
369 if (fw
->mem_shave_nn
) {
370 ivpu_bo_free(fw
->mem_shave_nn
);
371 fw
->mem_shave_nn
= NULL
;
374 ivpu_bo_free(fw
->mem_log_verb
);
375 ivpu_bo_free(fw
->mem_log_crit
);
376 ivpu_bo_free(fw
->mem
);
378 fw
->mem_log_verb
= NULL
;
379 fw
->mem_log_crit
= NULL
;
383 int ivpu_fw_init(struct ivpu_device
*vdev
)
387 ret
= ivpu_fw_request(vdev
);
391 ret
= ivpu_fw_parse(vdev
);
395 ivpu_fw_init_wa(vdev
);
397 ret
= ivpu_fw_mem_init(vdev
);
406 ivpu_fw_release(vdev
);
410 void ivpu_fw_fini(struct ivpu_device
*vdev
)
412 ivpu_fw_mem_fini(vdev
);
413 ivpu_fw_release(vdev
);
416 void ivpu_fw_load(struct ivpu_device
*vdev
)
418 struct ivpu_fw_info
*fw
= vdev
->fw
;
419 u64 image_end_offset
= fw
->image_load_offset
+ fw
->image_size
;
421 memset(ivpu_bo_vaddr(fw
->mem
), 0, fw
->image_load_offset
);
422 memcpy(ivpu_bo_vaddr(fw
->mem
) + fw
->image_load_offset
,
423 fw
->file
->data
+ FW_FILE_IMAGE_OFFSET
, fw
->image_size
);
425 if (IVPU_WA(clear_runtime_mem
)) {
426 u8
*start
= ivpu_bo_vaddr(fw
->mem
) + image_end_offset
;
427 u64 size
= ivpu_bo_size(fw
->mem
) - image_end_offset
;
429 memset(start
, 0, size
);
432 wmb(); /* Flush WC buffers after writing fw->mem */
435 static void ivpu_fw_boot_params_print(struct ivpu_device
*vdev
, struct vpu_boot_params
*boot_params
)
437 ivpu_dbg(vdev
, FW_BOOT
, "boot_params.magic = 0x%x\n",
439 ivpu_dbg(vdev
, FW_BOOT
, "boot_params.vpu_id = 0x%x\n",
440 boot_params
->vpu_id
);
441 ivpu_dbg(vdev
, FW_BOOT
, "boot_params.vpu_count = 0x%x\n",
442 boot_params
->vpu_count
);
443 ivpu_dbg(vdev
, FW_BOOT
, "boot_params.frequency = %u\n",
444 boot_params
->frequency
);
445 ivpu_dbg(vdev
, FW_BOOT
, "boot_params.perf_clk_frequency = %u\n",
446 boot_params
->perf_clk_frequency
);
448 ivpu_dbg(vdev
, FW_BOOT
, "boot_params.ipc_header_area_start = 0x%llx\n",
449 boot_params
->ipc_header_area_start
);
450 ivpu_dbg(vdev
, FW_BOOT
, "boot_params.ipc_header_area_size = 0x%x\n",
451 boot_params
->ipc_header_area_size
);
452 ivpu_dbg(vdev
, FW_BOOT
, "boot_params.shared_region_base = 0x%llx\n",
453 boot_params
->shared_region_base
);
454 ivpu_dbg(vdev
, FW_BOOT
, "boot_params.shared_region_size = 0x%x\n",
455 boot_params
->shared_region_size
);
456 ivpu_dbg(vdev
, FW_BOOT
, "boot_params.ipc_payload_area_start = 0x%llx\n",
457 boot_params
->ipc_payload_area_start
);
458 ivpu_dbg(vdev
, FW_BOOT
, "boot_params.ipc_payload_area_size = 0x%x\n",
459 boot_params
->ipc_payload_area_size
);
460 ivpu_dbg(vdev
, FW_BOOT
, "boot_params.global_aliased_pio_base = 0x%llx\n",
461 boot_params
->global_aliased_pio_base
);
462 ivpu_dbg(vdev
, FW_BOOT
, "boot_params.global_aliased_pio_size = 0x%x\n",
463 boot_params
->global_aliased_pio_size
);
465 ivpu_dbg(vdev
, FW_BOOT
, "boot_params.autoconfig = 0x%x\n",
466 boot_params
->autoconfig
);
468 ivpu_dbg(vdev
, FW_BOOT
, "boot_params.cache_defaults[VPU_BOOT_L2_CACHE_CFG_NN].use = 0x%x\n",
469 boot_params
->cache_defaults
[VPU_BOOT_L2_CACHE_CFG_NN
].use
);
470 ivpu_dbg(vdev
, FW_BOOT
, "boot_params.cache_defaults[VPU_BOOT_L2_CACHE_CFG_NN].cfg = 0x%x\n",
471 boot_params
->cache_defaults
[VPU_BOOT_L2_CACHE_CFG_NN
].cfg
);
473 ivpu_dbg(vdev
, FW_BOOT
, "boot_params.global_memory_allocator_base = 0x%llx\n",
474 boot_params
->global_memory_allocator_base
);
475 ivpu_dbg(vdev
, FW_BOOT
, "boot_params.global_memory_allocator_size = 0x%x\n",
476 boot_params
->global_memory_allocator_size
);
478 ivpu_dbg(vdev
, FW_BOOT
, "boot_params.shave_nn_fw_base = 0x%llx\n",
479 boot_params
->shave_nn_fw_base
);
481 ivpu_dbg(vdev
, FW_BOOT
, "boot_params.watchdog_irq_mss = 0x%x\n",
482 boot_params
->watchdog_irq_mss
);
483 ivpu_dbg(vdev
, FW_BOOT
, "boot_params.watchdog_irq_nce = 0x%x\n",
484 boot_params
->watchdog_irq_nce
);
485 ivpu_dbg(vdev
, FW_BOOT
, "boot_params.host_to_vpu_irq = 0x%x\n",
486 boot_params
->host_to_vpu_irq
);
487 ivpu_dbg(vdev
, FW_BOOT
, "boot_params.job_done_irq = 0x%x\n",
488 boot_params
->job_done_irq
);
490 ivpu_dbg(vdev
, FW_BOOT
, "boot_params.host_version_id = 0x%x\n",
491 boot_params
->host_version_id
);
492 ivpu_dbg(vdev
, FW_BOOT
, "boot_params.si_stepping = 0x%x\n",
493 boot_params
->si_stepping
);
494 ivpu_dbg(vdev
, FW_BOOT
, "boot_params.device_id = 0x%llx\n",
495 boot_params
->device_id
);
496 ivpu_dbg(vdev
, FW_BOOT
, "boot_params.feature_exclusion = 0x%llx\n",
497 boot_params
->feature_exclusion
);
498 ivpu_dbg(vdev
, FW_BOOT
, "boot_params.sku = 0x%llx\n",
500 ivpu_dbg(vdev
, FW_BOOT
, "boot_params.min_freq_pll_ratio = 0x%x\n",
501 boot_params
->min_freq_pll_ratio
);
502 ivpu_dbg(vdev
, FW_BOOT
, "boot_params.pn_freq_pll_ratio = 0x%x\n",
503 boot_params
->pn_freq_pll_ratio
);
504 ivpu_dbg(vdev
, FW_BOOT
, "boot_params.max_freq_pll_ratio = 0x%x\n",
505 boot_params
->max_freq_pll_ratio
);
506 ivpu_dbg(vdev
, FW_BOOT
, "boot_params.default_trace_level = 0x%x\n",
507 boot_params
->default_trace_level
);
508 ivpu_dbg(vdev
, FW_BOOT
, "boot_params.tracing_buff_message_format_mask = 0x%llx\n",
509 boot_params
->tracing_buff_message_format_mask
);
510 ivpu_dbg(vdev
, FW_BOOT
, "boot_params.trace_destination_mask = 0x%x\n",
511 boot_params
->trace_destination_mask
);
512 ivpu_dbg(vdev
, FW_BOOT
, "boot_params.trace_hw_component_mask = 0x%llx\n",
513 boot_params
->trace_hw_component_mask
);
514 ivpu_dbg(vdev
, FW_BOOT
, "boot_params.boot_type = 0x%x\n",
515 boot_params
->boot_type
);
516 ivpu_dbg(vdev
, FW_BOOT
, "boot_params.punit_telemetry_sram_base = 0x%llx\n",
517 boot_params
->punit_telemetry_sram_base
);
518 ivpu_dbg(vdev
, FW_BOOT
, "boot_params.punit_telemetry_sram_size = 0x%llx\n",
519 boot_params
->punit_telemetry_sram_size
);
520 ivpu_dbg(vdev
, FW_BOOT
, "boot_params.vpu_telemetry_enable = 0x%x\n",
521 boot_params
->vpu_telemetry_enable
);
522 ivpu_dbg(vdev
, FW_BOOT
, "boot_params.vpu_scheduling_mode = 0x%x\n",
523 boot_params
->vpu_scheduling_mode
);
524 ivpu_dbg(vdev
, FW_BOOT
, "boot_params.dvfs_mode = %u\n",
525 boot_params
->dvfs_mode
);
526 ivpu_dbg(vdev
, FW_BOOT
, "boot_params.d0i3_delayed_entry = %d\n",
527 boot_params
->d0i3_delayed_entry
);
528 ivpu_dbg(vdev
, FW_BOOT
, "boot_params.d0i3_residency_time_us = %lld\n",
529 boot_params
->d0i3_residency_time_us
);
530 ivpu_dbg(vdev
, FW_BOOT
, "boot_params.d0i3_entry_vpu_ts = %llu\n",
531 boot_params
->d0i3_entry_vpu_ts
);
532 ivpu_dbg(vdev
, FW_BOOT
, "boot_params.system_time_us = %llu\n",
533 boot_params
->system_time_us
);
536 void ivpu_fw_boot_params_setup(struct ivpu_device
*vdev
, struct vpu_boot_params
*boot_params
)
538 struct ivpu_bo
*ipc_mem_rx
= vdev
->ipc
->mem_rx
;
540 /* In case of warm boot only update variable params */
541 if (!ivpu_fw_is_cold_boot(vdev
)) {
542 boot_params
->d0i3_residency_time_us
=
543 ktime_us_delta(ktime_get_boottime(), vdev
->hw
->d0i3_entry_host_ts
);
544 boot_params
->d0i3_entry_vpu_ts
= vdev
->hw
->d0i3_entry_vpu_ts
;
545 boot_params
->system_time_us
= ktime_to_us(ktime_get_real());
547 ivpu_dbg(vdev
, FW_BOOT
, "boot_params.d0i3_residency_time_us = %lld\n",
548 boot_params
->d0i3_residency_time_us
);
549 ivpu_dbg(vdev
, FW_BOOT
, "boot_params.d0i3_entry_vpu_ts = %llu\n",
550 boot_params
->d0i3_entry_vpu_ts
);
551 ivpu_dbg(vdev
, FW_BOOT
, "boot_params.system_time_us = %llu\n",
552 boot_params
->system_time_us
);
554 boot_params
->save_restore_ret_address
= 0;
555 vdev
->pm
->is_warmboot
= true;
556 wmb(); /* Flush WC buffers after writing save_restore_ret_address */
560 vdev
->pm
->is_warmboot
= false;
562 boot_params
->magic
= VPU_BOOT_PARAMS_MAGIC
;
563 boot_params
->vpu_id
= to_pci_dev(vdev
->drm
.dev
)->bus
->number
;
564 boot_params
->frequency
= ivpu_hw_pll_freq_get(vdev
);
567 * This param is a debug firmware feature. It switches default clock
568 * to higher resolution one for fine-grained and more accurate firmware
571 boot_params
->perf_clk_frequency
= ivpu_hw_profiling_freq_get(vdev
);
574 * Uncached region of VPU address space, covers IPC buffers, job queues
575 * and log buffers, programmable to L2$ Uncached by VPU MTRR
577 boot_params
->shared_region_base
= vdev
->hw
->ranges
.global
.start
;
578 boot_params
->shared_region_size
= vdev
->hw
->ranges
.global
.end
-
579 vdev
->hw
->ranges
.global
.start
;
581 boot_params
->ipc_header_area_start
= ipc_mem_rx
->vpu_addr
;
582 boot_params
->ipc_header_area_size
= ivpu_bo_size(ipc_mem_rx
) / 2;
584 boot_params
->ipc_payload_area_start
= ipc_mem_rx
->vpu_addr
+ ivpu_bo_size(ipc_mem_rx
) / 2;
585 boot_params
->ipc_payload_area_size
= ivpu_bo_size(ipc_mem_rx
) / 2;
587 if (ivpu_hw_ip_gen(vdev
) == IVPU_HW_IP_37XX
) {
588 boot_params
->global_aliased_pio_base
= vdev
->hw
->ranges
.user
.start
;
589 boot_params
->global_aliased_pio_size
= ivpu_hw_range_size(&vdev
->hw
->ranges
.user
);
592 /* Allow configuration for L2C_PAGE_TABLE with boot param value */
593 boot_params
->autoconfig
= 1;
595 /* Enable L2 cache for first 2GB of high memory */
596 boot_params
->cache_defaults
[VPU_BOOT_L2_CACHE_CFG_NN
].use
= 1;
597 boot_params
->cache_defaults
[VPU_BOOT_L2_CACHE_CFG_NN
].cfg
=
598 ADDR_TO_L2_CACHE_CFG(vdev
->hw
->ranges
.shave
.start
);
600 if (vdev
->fw
->mem_shave_nn
)
601 boot_params
->shave_nn_fw_base
= vdev
->fw
->mem_shave_nn
->vpu_addr
;
603 boot_params
->watchdog_irq_mss
= WATCHDOG_MSS_REDIRECT
;
604 boot_params
->watchdog_irq_nce
= WATCHDOG_NCE_REDIRECT
;
605 boot_params
->si_stepping
= ivpu_revision(vdev
);
606 boot_params
->device_id
= ivpu_device_id(vdev
);
607 boot_params
->feature_exclusion
= vdev
->hw
->tile_fuse
;
608 boot_params
->sku
= vdev
->hw
->sku
;
610 boot_params
->min_freq_pll_ratio
= vdev
->hw
->pll
.min_ratio
;
611 boot_params
->pn_freq_pll_ratio
= vdev
->hw
->pll
.pn_ratio
;
612 boot_params
->max_freq_pll_ratio
= vdev
->hw
->pll
.max_ratio
;
614 boot_params
->default_trace_level
= vdev
->fw
->trace_level
;
615 boot_params
->tracing_buff_message_format_mask
= BIT(VPU_TRACING_FORMAT_STRING
);
616 boot_params
->trace_destination_mask
= vdev
->fw
->trace_destination_mask
;
617 boot_params
->trace_hw_component_mask
= vdev
->fw
->trace_hw_component_mask
;
618 boot_params
->crit_tracing_buff_addr
= vdev
->fw
->mem_log_crit
->vpu_addr
;
619 boot_params
->crit_tracing_buff_size
= ivpu_bo_size(vdev
->fw
->mem_log_crit
);
620 boot_params
->verbose_tracing_buff_addr
= vdev
->fw
->mem_log_verb
->vpu_addr
;
621 boot_params
->verbose_tracing_buff_size
= ivpu_bo_size(vdev
->fw
->mem_log_verb
);
623 boot_params
->punit_telemetry_sram_base
= ivpu_hw_telemetry_offset_get(vdev
);
624 boot_params
->punit_telemetry_sram_size
= ivpu_hw_telemetry_size_get(vdev
);
625 boot_params
->vpu_telemetry_enable
= ivpu_hw_telemetry_enable_get(vdev
);
626 boot_params
->vpu_scheduling_mode
= vdev
->fw
->sched_mode
;
627 if (vdev
->fw
->sched_mode
== VPU_SCHEDULING_MODE_HW
)
628 boot_params
->vpu_focus_present_timer_ms
= IVPU_FOCUS_PRESENT_TIMER_MS
;
629 boot_params
->dvfs_mode
= vdev
->fw
->dvfs_mode
;
630 if (!IVPU_WA(disable_d0i3_msg
))
631 boot_params
->d0i3_delayed_entry
= 1;
632 boot_params
->d0i3_residency_time_us
= 0;
633 boot_params
->d0i3_entry_vpu_ts
= 0;
635 boot_params
->system_time_us
= ktime_to_us(ktime_get_real());
636 wmb(); /* Flush WC buffers after writing bootparams */
638 ivpu_fw_boot_params_print(vdev
, boot_params
);