xref: /openbmc/linux/drivers/accel/ivpu/ivpu_fw.c (revision fac59652993f075d57860769c99045b3ca18780d)
102d5b0aaSJacek Lawrynowicz // SPDX-License-Identifier: GPL-2.0-only
202d5b0aaSJacek Lawrynowicz /*
302d5b0aaSJacek Lawrynowicz  * Copyright (C) 2020-2023 Intel Corporation
402d5b0aaSJacek Lawrynowicz  */
502d5b0aaSJacek Lawrynowicz 
602d5b0aaSJacek Lawrynowicz #include <linux/firmware.h>
702d5b0aaSJacek Lawrynowicz #include <linux/highmem.h>
802d5b0aaSJacek Lawrynowicz #include <linux/moduleparam.h>
902d5b0aaSJacek Lawrynowicz #include <linux/pci.h>
1002d5b0aaSJacek Lawrynowicz 
1102d5b0aaSJacek Lawrynowicz #include "vpu_boot_api.h"
1202d5b0aaSJacek Lawrynowicz #include "ivpu_drv.h"
1302d5b0aaSJacek Lawrynowicz #include "ivpu_fw.h"
14d4e4257aSStanislaw Gruszka #include "ivpu_fw_log.h"
1502d5b0aaSJacek Lawrynowicz #include "ivpu_gem.h"
1602d5b0aaSJacek Lawrynowicz #include "ivpu_hw.h"
1702d5b0aaSJacek Lawrynowicz #include "ivpu_ipc.h"
18852be13fSJacek Lawrynowicz #include "ivpu_pm.h"
1902d5b0aaSJacek Lawrynowicz 
2002d5b0aaSJacek Lawrynowicz #define FW_GLOBAL_MEM_START	(2ull * SZ_1G)
2102d5b0aaSJacek Lawrynowicz #define FW_GLOBAL_MEM_END	(3ull * SZ_1G)
2202d5b0aaSJacek Lawrynowicz #define FW_SHARED_MEM_SIZE	SZ_256M /* Must be aligned to FW_SHARED_MEM_ALIGNMENT */
2302d5b0aaSJacek Lawrynowicz #define FW_SHARED_MEM_ALIGNMENT	SZ_128K /* VPU MTRR limitation */
2402d5b0aaSJacek Lawrynowicz #define FW_RUNTIME_MAX_SIZE	SZ_512M
2502d5b0aaSJacek Lawrynowicz #define FW_SHAVE_NN_MAX_SIZE	SZ_2M
2602d5b0aaSJacek Lawrynowicz #define FW_RUNTIME_MIN_ADDR	(FW_GLOBAL_MEM_START)
2702d5b0aaSJacek Lawrynowicz #define FW_RUNTIME_MAX_ADDR	(FW_GLOBAL_MEM_END - FW_SHARED_MEM_SIZE)
2802d5b0aaSJacek Lawrynowicz #define FW_VERSION_HEADER_SIZE	SZ_4K
2902d5b0aaSJacek Lawrynowicz #define FW_FILE_IMAGE_OFFSET	(VPU_FW_HEADER_SIZE + FW_VERSION_HEADER_SIZE)
3002d5b0aaSJacek Lawrynowicz 
3102d5b0aaSJacek Lawrynowicz #define WATCHDOG_MSS_REDIRECT	32
3202d5b0aaSJacek Lawrynowicz #define WATCHDOG_NCE_REDIRECT	33
3302d5b0aaSJacek Lawrynowicz 
3402d5b0aaSJacek Lawrynowicz #define ADDR_TO_L2_CACHE_CFG(addr) ((addr) >> 31)
3502d5b0aaSJacek Lawrynowicz 
364ea1e504SAndrzej Kacprowski #define IVPU_FW_CHECK_API(vdev, fw_hdr, name, min_major) \
374ea1e504SAndrzej Kacprowski 	ivpu_fw_check_api(vdev, fw_hdr, #name, \
3802d5b0aaSJacek Lawrynowicz 			  VPU_##name##_API_VER_INDEX, \
3902d5b0aaSJacek Lawrynowicz 			  VPU_##name##_API_VER_MAJOR, \
404ea1e504SAndrzej Kacprowski 			  VPU_##name##_API_VER_MINOR, min_major)
4102d5b0aaSJacek Lawrynowicz 
4202d5b0aaSJacek Lawrynowicz static char *ivpu_firmware;
4302d5b0aaSJacek Lawrynowicz module_param_named_unsafe(firmware, ivpu_firmware, charp, 0644);
4402d5b0aaSJacek Lawrynowicz MODULE_PARM_DESC(firmware, "VPU firmware binary in /lib/firmware/..");
4502d5b0aaSJacek Lawrynowicz 
469ab43e95SJacek Lawrynowicz /* TODO: Remove mtl_vpu.bin from names after transition to generation based FW names */
479ab43e95SJacek Lawrynowicz static struct {
489ab43e95SJacek Lawrynowicz 	int gen;
499ab43e95SJacek Lawrynowicz 	const char *name;
509ab43e95SJacek Lawrynowicz } fw_names[] = {
519ab43e95SJacek Lawrynowicz 	{ IVPU_HW_37XX, "vpu_37xx.bin" },
529ab43e95SJacek Lawrynowicz 	{ IVPU_HW_37XX, "mtl_vpu.bin" },
539ab43e95SJacek Lawrynowicz 	{ IVPU_HW_37XX, "intel/vpu/vpu_37xx_v0.0.bin" },
5479cdc56cSStanislaw Gruszka 	{ IVPU_HW_40XX, "vpu_40xx.bin" },
5579cdc56cSStanislaw Gruszka 	{ IVPU_HW_40XX, "intel/vpu/vpu_40xx_v0.0.bin" },
569ab43e95SJacek Lawrynowicz };
579ab43e95SJacek Lawrynowicz 
58*106f10feSAlexander F. Lent /* Production fw_names from the table above */
59*106f10feSAlexander F. Lent MODULE_FIRMWARE("intel/vpu/vpu_37xx_v0.0.bin");
60*106f10feSAlexander F. Lent MODULE_FIRMWARE("intel/vpu/vpu_40xx_v0.0.bin");
61*106f10feSAlexander F. Lent 
ivpu_fw_request(struct ivpu_device * vdev)6202d5b0aaSJacek Lawrynowicz static int ivpu_fw_request(struct ivpu_device *vdev)
6302d5b0aaSJacek Lawrynowicz {
6402d5b0aaSJacek Lawrynowicz 	int ret = -ENOENT;
6502d5b0aaSJacek Lawrynowicz 	int i;
6602d5b0aaSJacek Lawrynowicz 
67f9d918cfSAndrzej Kacprowski 	if (ivpu_firmware) {
68f9d918cfSAndrzej Kacprowski 		ret = request_firmware(&vdev->fw->file, ivpu_firmware, vdev->drm.dev);
69f9d918cfSAndrzej Kacprowski 		if (!ret)
70f9d918cfSAndrzej Kacprowski 			vdev->fw->name = ivpu_firmware;
71f9d918cfSAndrzej Kacprowski 		return ret;
72f9d918cfSAndrzej Kacprowski 	}
7302d5b0aaSJacek Lawrynowicz 
7402d5b0aaSJacek Lawrynowicz 	for (i = 0; i < ARRAY_SIZE(fw_names); i++) {
759ab43e95SJacek Lawrynowicz 		if (fw_names[i].gen != ivpu_hw_gen(vdev))
769ab43e95SJacek Lawrynowicz 			continue;
779ab43e95SJacek Lawrynowicz 
789ab43e95SJacek Lawrynowicz 		ret = firmware_request_nowarn(&vdev->fw->file, fw_names[i].name, vdev->drm.dev);
79f9d918cfSAndrzej Kacprowski 		if (!ret) {
809ab43e95SJacek Lawrynowicz 			vdev->fw->name = fw_names[i].name;
8102d5b0aaSJacek Lawrynowicz 			return 0;
8202d5b0aaSJacek Lawrynowicz 		}
83f9d918cfSAndrzej Kacprowski 	}
8402d5b0aaSJacek Lawrynowicz 
8502d5b0aaSJacek Lawrynowicz 	ivpu_err(vdev, "Failed to request firmware: %d\n", ret);
8602d5b0aaSJacek Lawrynowicz 	return ret;
8702d5b0aaSJacek Lawrynowicz }
8802d5b0aaSJacek Lawrynowicz 
894ea1e504SAndrzej Kacprowski static int
ivpu_fw_check_api(struct ivpu_device * vdev,const struct vpu_firmware_header * fw_hdr,const char * str,int index,u16 expected_major,u16 expected_minor,u16 min_major)9002d5b0aaSJacek Lawrynowicz ivpu_fw_check_api(struct ivpu_device *vdev, const struct vpu_firmware_header *fw_hdr,
914ea1e504SAndrzej Kacprowski 		  const char *str, int index, u16 expected_major, u16 expected_minor,
924ea1e504SAndrzej Kacprowski 		  u16 min_major)
9302d5b0aaSJacek Lawrynowicz {
9402d5b0aaSJacek Lawrynowicz 	u16 major = (u16)(fw_hdr->api_version[index] >> 16);
9502d5b0aaSJacek Lawrynowicz 	u16 minor = (u16)(fw_hdr->api_version[index]);
9602d5b0aaSJacek Lawrynowicz 
974ea1e504SAndrzej Kacprowski 	if (major < min_major) {
984ea1e504SAndrzej Kacprowski 		ivpu_err(vdev, "Incompatible FW %s API version: %d.%d, required %d.0 or later\n",
994ea1e504SAndrzej Kacprowski 			 str, major, minor, min_major);
1004ea1e504SAndrzej Kacprowski 		return -EINVAL;
1014ea1e504SAndrzej Kacprowski 	}
10202d5b0aaSJacek Lawrynowicz 	if (major != expected_major) {
1034ea1e504SAndrzej Kacprowski 		ivpu_warn(vdev, "Major FW %s API version different: %d.%d (expected %d.%d)\n",
10402d5b0aaSJacek Lawrynowicz 			  str, major, minor, expected_major, expected_minor);
10502d5b0aaSJacek Lawrynowicz 	}
10602d5b0aaSJacek Lawrynowicz 	ivpu_dbg(vdev, FW_BOOT, "FW %s API version: %d.%d (expected %d.%d)\n",
10702d5b0aaSJacek Lawrynowicz 		 str, major, minor, expected_major, expected_minor);
1084ea1e504SAndrzej Kacprowski 
1094ea1e504SAndrzej Kacprowski 	return 0;
11002d5b0aaSJacek Lawrynowicz }
11102d5b0aaSJacek Lawrynowicz 
ivpu_fw_parse(struct ivpu_device * vdev)11202d5b0aaSJacek Lawrynowicz static int ivpu_fw_parse(struct ivpu_device *vdev)
11302d5b0aaSJacek Lawrynowicz {
11402d5b0aaSJacek Lawrynowicz 	struct ivpu_fw_info *fw = vdev->fw;
11502d5b0aaSJacek Lawrynowicz 	const struct vpu_firmware_header *fw_hdr = (const void *)fw->file->data;
11602d5b0aaSJacek Lawrynowicz 	u64 runtime_addr, image_load_addr, runtime_size, image_size;
11702d5b0aaSJacek Lawrynowicz 
11802d5b0aaSJacek Lawrynowicz 	if (fw->file->size <= FW_FILE_IMAGE_OFFSET) {
11902d5b0aaSJacek Lawrynowicz 		ivpu_err(vdev, "Firmware file is too small: %zu\n", fw->file->size);
12002d5b0aaSJacek Lawrynowicz 		return -EINVAL;
12102d5b0aaSJacek Lawrynowicz 	}
12202d5b0aaSJacek Lawrynowicz 
12302d5b0aaSJacek Lawrynowicz 	if (fw_hdr->header_version != VPU_FW_HEADER_VERSION) {
12402d5b0aaSJacek Lawrynowicz 		ivpu_err(vdev, "Invalid firmware header version: %u\n", fw_hdr->header_version);
12502d5b0aaSJacek Lawrynowicz 		return -EINVAL;
12602d5b0aaSJacek Lawrynowicz 	}
12702d5b0aaSJacek Lawrynowicz 
12802d5b0aaSJacek Lawrynowicz 	runtime_addr = fw_hdr->boot_params_load_address;
12902d5b0aaSJacek Lawrynowicz 	runtime_size = fw_hdr->runtime_size;
13002d5b0aaSJacek Lawrynowicz 	image_load_addr = fw_hdr->image_load_address;
13102d5b0aaSJacek Lawrynowicz 	image_size = fw_hdr->image_size;
13202d5b0aaSJacek Lawrynowicz 
13302d5b0aaSJacek Lawrynowicz 	if (runtime_addr < FW_RUNTIME_MIN_ADDR || runtime_addr > FW_RUNTIME_MAX_ADDR) {
13402d5b0aaSJacek Lawrynowicz 		ivpu_err(vdev, "Invalid firmware runtime address: 0x%llx\n", runtime_addr);
13502d5b0aaSJacek Lawrynowicz 		return -EINVAL;
13602d5b0aaSJacek Lawrynowicz 	}
13702d5b0aaSJacek Lawrynowicz 
13802d5b0aaSJacek Lawrynowicz 	if (runtime_size < fw->file->size || runtime_size > FW_RUNTIME_MAX_SIZE) {
13902d5b0aaSJacek Lawrynowicz 		ivpu_err(vdev, "Invalid firmware runtime size: %llu\n", runtime_size);
14002d5b0aaSJacek Lawrynowicz 		return -EINVAL;
14102d5b0aaSJacek Lawrynowicz 	}
14202d5b0aaSJacek Lawrynowicz 
14302d5b0aaSJacek Lawrynowicz 	if (FW_FILE_IMAGE_OFFSET + image_size > fw->file->size) {
14402d5b0aaSJacek Lawrynowicz 		ivpu_err(vdev, "Invalid image size: %llu\n", image_size);
14502d5b0aaSJacek Lawrynowicz 		return -EINVAL;
14602d5b0aaSJacek Lawrynowicz 	}
14702d5b0aaSJacek Lawrynowicz 
14802d5b0aaSJacek Lawrynowicz 	if (image_load_addr < runtime_addr ||
14902d5b0aaSJacek Lawrynowicz 	    image_load_addr + image_size > runtime_addr + runtime_size) {
15002d5b0aaSJacek Lawrynowicz 		ivpu_err(vdev, "Invalid firmware load address size: 0x%llx and size %llu\n",
15102d5b0aaSJacek Lawrynowicz 			 image_load_addr, image_size);
15202d5b0aaSJacek Lawrynowicz 		return -EINVAL;
15302d5b0aaSJacek Lawrynowicz 	}
15402d5b0aaSJacek Lawrynowicz 
15502d5b0aaSJacek Lawrynowicz 	if (fw_hdr->shave_nn_fw_size > FW_SHAVE_NN_MAX_SIZE) {
15602d5b0aaSJacek Lawrynowicz 		ivpu_err(vdev, "SHAVE NN firmware is too big: %u\n", fw_hdr->shave_nn_fw_size);
15702d5b0aaSJacek Lawrynowicz 		return -EINVAL;
15802d5b0aaSJacek Lawrynowicz 	}
15902d5b0aaSJacek Lawrynowicz 
16002d5b0aaSJacek Lawrynowicz 	if (fw_hdr->entry_point < image_load_addr ||
16102d5b0aaSJacek Lawrynowicz 	    fw_hdr->entry_point >= image_load_addr + image_size) {
16202d5b0aaSJacek Lawrynowicz 		ivpu_err(vdev, "Invalid entry point: 0x%llx\n", fw_hdr->entry_point);
16302d5b0aaSJacek Lawrynowicz 		return -EINVAL;
16402d5b0aaSJacek Lawrynowicz 	}
1654ea1e504SAndrzej Kacprowski 	ivpu_dbg(vdev, FW_BOOT, "Header version: 0x%x, format 0x%x\n",
1664ea1e504SAndrzej Kacprowski 		 fw_hdr->header_version, fw_hdr->image_format);
167f9d918cfSAndrzej Kacprowski 
168f9d918cfSAndrzej Kacprowski 	ivpu_info(vdev, "Firmware: %s, version: %s", fw->name,
169f9d918cfSAndrzej Kacprowski 		  (const char *)fw_hdr + VPU_FW_HEADER_SIZE);
1704ea1e504SAndrzej Kacprowski 
1714ea1e504SAndrzej Kacprowski 	if (IVPU_FW_CHECK_API(vdev, fw_hdr, BOOT, 3))
1724ea1e504SAndrzej Kacprowski 		return -EINVAL;
1734ea1e504SAndrzej Kacprowski 	if (IVPU_FW_CHECK_API(vdev, fw_hdr, JSM, 3))
1744ea1e504SAndrzej Kacprowski 		return -EINVAL;
17502d5b0aaSJacek Lawrynowicz 
17602d5b0aaSJacek Lawrynowicz 	fw->runtime_addr = runtime_addr;
17702d5b0aaSJacek Lawrynowicz 	fw->runtime_size = runtime_size;
17802d5b0aaSJacek Lawrynowicz 	fw->image_load_offset = image_load_addr - runtime_addr;
17902d5b0aaSJacek Lawrynowicz 	fw->image_size = image_size;
18002d5b0aaSJacek Lawrynowicz 	fw->shave_nn_size = PAGE_ALIGN(fw_hdr->shave_nn_fw_size);
18102d5b0aaSJacek Lawrynowicz 
18202d5b0aaSJacek Lawrynowicz 	fw->cold_boot_entry_point = fw_hdr->entry_point;
18302d5b0aaSJacek Lawrynowicz 	fw->entry_point = fw->cold_boot_entry_point;
18402d5b0aaSJacek Lawrynowicz 
185d4e4257aSStanislaw Gruszka 	fw->trace_level = min_t(u32, ivpu_log_level, IVPU_FW_LOG_FATAL);
186d4e4257aSStanislaw Gruszka 	fw->trace_destination_mask = VPU_TRACE_DESTINATION_VERBOSE_TRACING;
187d4e4257aSStanislaw Gruszka 	fw->trace_hw_component_mask = -1;
188d4e4257aSStanislaw Gruszka 
18902d5b0aaSJacek Lawrynowicz 	ivpu_dbg(vdev, FW_BOOT, "Size: file %lu image %u runtime %u shavenn %u\n",
19002d5b0aaSJacek Lawrynowicz 		 fw->file->size, fw->image_size, fw->runtime_size, fw->shave_nn_size);
19102d5b0aaSJacek Lawrynowicz 	ivpu_dbg(vdev, FW_BOOT, "Address: runtime 0x%llx, load 0x%llx, entry point 0x%llx\n",
19202d5b0aaSJacek Lawrynowicz 		 fw->runtime_addr, image_load_addr, fw->entry_point);
19302d5b0aaSJacek Lawrynowicz 
19402d5b0aaSJacek Lawrynowicz 	return 0;
19502d5b0aaSJacek Lawrynowicz }
19602d5b0aaSJacek Lawrynowicz 
ivpu_fw_release(struct ivpu_device * vdev)19702d5b0aaSJacek Lawrynowicz static void ivpu_fw_release(struct ivpu_device *vdev)
19802d5b0aaSJacek Lawrynowicz {
19902d5b0aaSJacek Lawrynowicz 	release_firmware(vdev->fw->file);
20002d5b0aaSJacek Lawrynowicz }
20102d5b0aaSJacek Lawrynowicz 
ivpu_fw_update_global_range(struct ivpu_device * vdev)20202d5b0aaSJacek Lawrynowicz static int ivpu_fw_update_global_range(struct ivpu_device *vdev)
20302d5b0aaSJacek Lawrynowicz {
20402d5b0aaSJacek Lawrynowicz 	struct ivpu_fw_info *fw = vdev->fw;
20502d5b0aaSJacek Lawrynowicz 	u64 start = ALIGN(fw->runtime_addr + fw->runtime_size, FW_SHARED_MEM_ALIGNMENT);
20602d5b0aaSJacek Lawrynowicz 	u64 size = FW_SHARED_MEM_SIZE;
20702d5b0aaSJacek Lawrynowicz 
20802d5b0aaSJacek Lawrynowicz 	if (start + size > FW_GLOBAL_MEM_END) {
20902d5b0aaSJacek Lawrynowicz 		ivpu_err(vdev, "No space for shared region, start %lld, size %lld\n", start, size);
21002d5b0aaSJacek Lawrynowicz 		return -EINVAL;
21102d5b0aaSJacek Lawrynowicz 	}
21202d5b0aaSJacek Lawrynowicz 
213162f17b2SKarol Wachowski 	ivpu_hw_init_range(&vdev->hw->ranges.global, start, size);
21402d5b0aaSJacek Lawrynowicz 	return 0;
21502d5b0aaSJacek Lawrynowicz }
21602d5b0aaSJacek Lawrynowicz 
ivpu_fw_mem_init(struct ivpu_device * vdev)21702d5b0aaSJacek Lawrynowicz static int ivpu_fw_mem_init(struct ivpu_device *vdev)
21802d5b0aaSJacek Lawrynowicz {
21902d5b0aaSJacek Lawrynowicz 	struct ivpu_fw_info *fw = vdev->fw;
220d4e4257aSStanislaw Gruszka 	int log_verb_size;
22102d5b0aaSJacek Lawrynowicz 	int ret;
22202d5b0aaSJacek Lawrynowicz 
22302d5b0aaSJacek Lawrynowicz 	ret = ivpu_fw_update_global_range(vdev);
22402d5b0aaSJacek Lawrynowicz 	if (ret)
22502d5b0aaSJacek Lawrynowicz 		return ret;
22602d5b0aaSJacek Lawrynowicz 
227610b5d21SStanislaw Gruszka 	fw->mem = ivpu_bo_alloc_internal(vdev, fw->runtime_addr, fw->runtime_size, DRM_IVPU_BO_WC);
22802d5b0aaSJacek Lawrynowicz 	if (!fw->mem) {
22902d5b0aaSJacek Lawrynowicz 		ivpu_err(vdev, "Failed to allocate firmware runtime memory\n");
23002d5b0aaSJacek Lawrynowicz 		return -ENOMEM;
23102d5b0aaSJacek Lawrynowicz 	}
23202d5b0aaSJacek Lawrynowicz 
233d4e4257aSStanislaw Gruszka 	fw->mem_log_crit = ivpu_bo_alloc_internal(vdev, 0, IVPU_FW_CRITICAL_BUFFER_SIZE,
234d4e4257aSStanislaw Gruszka 						  DRM_IVPU_BO_CACHED);
235d4e4257aSStanislaw Gruszka 	if (!fw->mem_log_crit) {
236d4e4257aSStanislaw Gruszka 		ivpu_err(vdev, "Failed to allocate critical log buffer\n");
237d4e4257aSStanislaw Gruszka 		ret = -ENOMEM;
238d4e4257aSStanislaw Gruszka 		goto err_free_fw_mem;
239d4e4257aSStanislaw Gruszka 	}
240d4e4257aSStanislaw Gruszka 
241d4e4257aSStanislaw Gruszka 	if (ivpu_log_level <= IVPU_FW_LOG_INFO)
242d4e4257aSStanislaw Gruszka 		log_verb_size = IVPU_FW_VERBOSE_BUFFER_LARGE_SIZE;
243d4e4257aSStanislaw Gruszka 	else
244d4e4257aSStanislaw Gruszka 		log_verb_size = IVPU_FW_VERBOSE_BUFFER_SMALL_SIZE;
245d4e4257aSStanislaw Gruszka 
246d4e4257aSStanislaw Gruszka 	fw->mem_log_verb = ivpu_bo_alloc_internal(vdev, 0, log_verb_size, DRM_IVPU_BO_CACHED);
247d4e4257aSStanislaw Gruszka 	if (!fw->mem_log_verb) {
248d4e4257aSStanislaw Gruszka 		ivpu_err(vdev, "Failed to allocate verbose log buffer\n");
249d4e4257aSStanislaw Gruszka 		ret = -ENOMEM;
250d4e4257aSStanislaw Gruszka 		goto err_free_log_crit;
251d4e4257aSStanislaw Gruszka 	}
252d4e4257aSStanislaw Gruszka 
25302d5b0aaSJacek Lawrynowicz 	if (fw->shave_nn_size) {
254162f17b2SKarol Wachowski 		fw->mem_shave_nn = ivpu_bo_alloc_internal(vdev, vdev->hw->ranges.shave.start,
25502d5b0aaSJacek Lawrynowicz 							  fw->shave_nn_size, DRM_IVPU_BO_UNCACHED);
25602d5b0aaSJacek Lawrynowicz 		if (!fw->mem_shave_nn) {
25702d5b0aaSJacek Lawrynowicz 			ivpu_err(vdev, "Failed to allocate shavenn buffer\n");
258d4e4257aSStanislaw Gruszka 			ret = -ENOMEM;
259d4e4257aSStanislaw Gruszka 			goto err_free_log_verb;
26002d5b0aaSJacek Lawrynowicz 		}
26102d5b0aaSJacek Lawrynowicz 	}
26202d5b0aaSJacek Lawrynowicz 
26302d5b0aaSJacek Lawrynowicz 	return 0;
264d4e4257aSStanislaw Gruszka 
265d4e4257aSStanislaw Gruszka err_free_log_verb:
266d4e4257aSStanislaw Gruszka 	ivpu_bo_free_internal(fw->mem_log_verb);
267d4e4257aSStanislaw Gruszka err_free_log_crit:
268d4e4257aSStanislaw Gruszka 	ivpu_bo_free_internal(fw->mem_log_crit);
269d4e4257aSStanislaw Gruszka err_free_fw_mem:
270d4e4257aSStanislaw Gruszka 	ivpu_bo_free_internal(fw->mem);
271d4e4257aSStanislaw Gruszka 	return ret;
27202d5b0aaSJacek Lawrynowicz }
27302d5b0aaSJacek Lawrynowicz 
ivpu_fw_mem_fini(struct ivpu_device * vdev)27402d5b0aaSJacek Lawrynowicz static void ivpu_fw_mem_fini(struct ivpu_device *vdev)
27502d5b0aaSJacek Lawrynowicz {
27602d5b0aaSJacek Lawrynowicz 	struct ivpu_fw_info *fw = vdev->fw;
27702d5b0aaSJacek Lawrynowicz 
27802d5b0aaSJacek Lawrynowicz 	if (fw->mem_shave_nn) {
27902d5b0aaSJacek Lawrynowicz 		ivpu_bo_free_internal(fw->mem_shave_nn);
28002d5b0aaSJacek Lawrynowicz 		fw->mem_shave_nn = NULL;
28102d5b0aaSJacek Lawrynowicz 	}
28202d5b0aaSJacek Lawrynowicz 
283d4e4257aSStanislaw Gruszka 	ivpu_bo_free_internal(fw->mem_log_verb);
284d4e4257aSStanislaw Gruszka 	ivpu_bo_free_internal(fw->mem_log_crit);
28502d5b0aaSJacek Lawrynowicz 	ivpu_bo_free_internal(fw->mem);
286d4e4257aSStanislaw Gruszka 
287d4e4257aSStanislaw Gruszka 	fw->mem_log_verb = NULL;
288d4e4257aSStanislaw Gruszka 	fw->mem_log_crit = NULL;
28902d5b0aaSJacek Lawrynowicz 	fw->mem = NULL;
29002d5b0aaSJacek Lawrynowicz }
29102d5b0aaSJacek Lawrynowicz 
ivpu_fw_init(struct ivpu_device * vdev)29202d5b0aaSJacek Lawrynowicz int ivpu_fw_init(struct ivpu_device *vdev)
29302d5b0aaSJacek Lawrynowicz {
29402d5b0aaSJacek Lawrynowicz 	int ret;
29502d5b0aaSJacek Lawrynowicz 
29602d5b0aaSJacek Lawrynowicz 	ret = ivpu_fw_request(vdev);
29702d5b0aaSJacek Lawrynowicz 	if (ret)
29802d5b0aaSJacek Lawrynowicz 		return ret;
29902d5b0aaSJacek Lawrynowicz 
30002d5b0aaSJacek Lawrynowicz 	ret = ivpu_fw_parse(vdev);
30102d5b0aaSJacek Lawrynowicz 	if (ret)
30202d5b0aaSJacek Lawrynowicz 		goto err_fw_release;
30302d5b0aaSJacek Lawrynowicz 
30402d5b0aaSJacek Lawrynowicz 	ret = ivpu_fw_mem_init(vdev);
30502d5b0aaSJacek Lawrynowicz 	if (ret)
30602d5b0aaSJacek Lawrynowicz 		goto err_fw_release;
30702d5b0aaSJacek Lawrynowicz 
30802d5b0aaSJacek Lawrynowicz 	return 0;
30902d5b0aaSJacek Lawrynowicz 
31002d5b0aaSJacek Lawrynowicz err_fw_release:
31102d5b0aaSJacek Lawrynowicz 	ivpu_fw_release(vdev);
31202d5b0aaSJacek Lawrynowicz 	return ret;
31302d5b0aaSJacek Lawrynowicz }
31402d5b0aaSJacek Lawrynowicz 
ivpu_fw_fini(struct ivpu_device * vdev)31502d5b0aaSJacek Lawrynowicz void ivpu_fw_fini(struct ivpu_device *vdev)
31602d5b0aaSJacek Lawrynowicz {
31702d5b0aaSJacek Lawrynowicz 	ivpu_fw_mem_fini(vdev);
31802d5b0aaSJacek Lawrynowicz 	ivpu_fw_release(vdev);
31902d5b0aaSJacek Lawrynowicz }
32002d5b0aaSJacek Lawrynowicz 
ivpu_fw_load(struct ivpu_device * vdev)32102d5b0aaSJacek Lawrynowicz int ivpu_fw_load(struct ivpu_device *vdev)
32202d5b0aaSJacek Lawrynowicz {
32302d5b0aaSJacek Lawrynowicz 	struct ivpu_fw_info *fw = vdev->fw;
32402d5b0aaSJacek Lawrynowicz 	u64 image_end_offset = fw->image_load_offset + fw->image_size;
32502d5b0aaSJacek Lawrynowicz 
32602d5b0aaSJacek Lawrynowicz 	memset(fw->mem->kvaddr, 0, fw->image_load_offset);
32702d5b0aaSJacek Lawrynowicz 	memcpy(fw->mem->kvaddr + fw->image_load_offset,
32802d5b0aaSJacek Lawrynowicz 	       fw->file->data + FW_FILE_IMAGE_OFFSET, fw->image_size);
32902d5b0aaSJacek Lawrynowicz 
33002d5b0aaSJacek Lawrynowicz 	if (IVPU_WA(clear_runtime_mem)) {
33102d5b0aaSJacek Lawrynowicz 		u8 *start = fw->mem->kvaddr + image_end_offset;
33202d5b0aaSJacek Lawrynowicz 		u64 size = fw->mem->base.size - image_end_offset;
33302d5b0aaSJacek Lawrynowicz 
33402d5b0aaSJacek Lawrynowicz 		memset(start, 0, size);
33502d5b0aaSJacek Lawrynowicz 	}
33602d5b0aaSJacek Lawrynowicz 
337610b5d21SStanislaw Gruszka 	wmb(); /* Flush WC buffers after writing fw->mem */
33802d5b0aaSJacek Lawrynowicz 
33902d5b0aaSJacek Lawrynowicz 	return 0;
34002d5b0aaSJacek Lawrynowicz }
34102d5b0aaSJacek Lawrynowicz 
ivpu_fw_boot_params_print(struct ivpu_device * vdev,struct vpu_boot_params * boot_params)34202d5b0aaSJacek Lawrynowicz static void ivpu_fw_boot_params_print(struct ivpu_device *vdev, struct vpu_boot_params *boot_params)
34302d5b0aaSJacek Lawrynowicz {
34402d5b0aaSJacek Lawrynowicz 	ivpu_dbg(vdev, FW_BOOT, "boot_params.magic = 0x%x\n",
34502d5b0aaSJacek Lawrynowicz 		 boot_params->magic);
34602d5b0aaSJacek Lawrynowicz 	ivpu_dbg(vdev, FW_BOOT, "boot_params.vpu_id = 0x%x\n",
34702d5b0aaSJacek Lawrynowicz 		 boot_params->vpu_id);
34802d5b0aaSJacek Lawrynowicz 	ivpu_dbg(vdev, FW_BOOT, "boot_params.vpu_count = 0x%x\n",
34902d5b0aaSJacek Lawrynowicz 		 boot_params->vpu_count);
35002d5b0aaSJacek Lawrynowicz 	ivpu_dbg(vdev, FW_BOOT, "boot_params.frequency = %u\n",
35102d5b0aaSJacek Lawrynowicz 		 boot_params->frequency);
35202d5b0aaSJacek Lawrynowicz 	ivpu_dbg(vdev, FW_BOOT, "boot_params.perf_clk_frequency = %u\n",
35302d5b0aaSJacek Lawrynowicz 		 boot_params->perf_clk_frequency);
35402d5b0aaSJacek Lawrynowicz 
35502d5b0aaSJacek Lawrynowicz 	ivpu_dbg(vdev, FW_BOOT, "boot_params.ipc_header_area_start = 0x%llx\n",
35602d5b0aaSJacek Lawrynowicz 		 boot_params->ipc_header_area_start);
35702d5b0aaSJacek Lawrynowicz 	ivpu_dbg(vdev, FW_BOOT, "boot_params.ipc_header_area_size = 0x%x\n",
35802d5b0aaSJacek Lawrynowicz 		 boot_params->ipc_header_area_size);
35902d5b0aaSJacek Lawrynowicz 	ivpu_dbg(vdev, FW_BOOT, "boot_params.shared_region_base = 0x%llx\n",
36002d5b0aaSJacek Lawrynowicz 		 boot_params->shared_region_base);
36102d5b0aaSJacek Lawrynowicz 	ivpu_dbg(vdev, FW_BOOT, "boot_params.shared_region_size = 0x%x\n",
36202d5b0aaSJacek Lawrynowicz 		 boot_params->shared_region_size);
36302d5b0aaSJacek Lawrynowicz 	ivpu_dbg(vdev, FW_BOOT, "boot_params.ipc_payload_area_start = 0x%llx\n",
36402d5b0aaSJacek Lawrynowicz 		 boot_params->ipc_payload_area_start);
36502d5b0aaSJacek Lawrynowicz 	ivpu_dbg(vdev, FW_BOOT, "boot_params.ipc_payload_area_size = 0x%x\n",
36602d5b0aaSJacek Lawrynowicz 		 boot_params->ipc_payload_area_size);
36702d5b0aaSJacek Lawrynowicz 	ivpu_dbg(vdev, FW_BOOT, "boot_params.global_aliased_pio_base = 0x%llx\n",
36802d5b0aaSJacek Lawrynowicz 		 boot_params->global_aliased_pio_base);
36902d5b0aaSJacek Lawrynowicz 	ivpu_dbg(vdev, FW_BOOT, "boot_params.global_aliased_pio_size = 0x%x\n",
37002d5b0aaSJacek Lawrynowicz 		 boot_params->global_aliased_pio_size);
37102d5b0aaSJacek Lawrynowicz 
37202d5b0aaSJacek Lawrynowicz 	ivpu_dbg(vdev, FW_BOOT, "boot_params.autoconfig = 0x%x\n",
37302d5b0aaSJacek Lawrynowicz 		 boot_params->autoconfig);
37402d5b0aaSJacek Lawrynowicz 
37502d5b0aaSJacek Lawrynowicz 	ivpu_dbg(vdev, FW_BOOT, "boot_params.cache_defaults[VPU_BOOT_L2_CACHE_CFG_NN].use = 0x%x\n",
37602d5b0aaSJacek Lawrynowicz 		 boot_params->cache_defaults[VPU_BOOT_L2_CACHE_CFG_NN].use);
37702d5b0aaSJacek Lawrynowicz 	ivpu_dbg(vdev, FW_BOOT, "boot_params.cache_defaults[VPU_BOOT_L2_CACHE_CFG_NN].cfg = 0x%x\n",
37802d5b0aaSJacek Lawrynowicz 		 boot_params->cache_defaults[VPU_BOOT_L2_CACHE_CFG_NN].cfg);
37902d5b0aaSJacek Lawrynowicz 
38002d5b0aaSJacek Lawrynowicz 	ivpu_dbg(vdev, FW_BOOT, "boot_params.global_memory_allocator_base = 0x%llx\n",
38102d5b0aaSJacek Lawrynowicz 		 boot_params->global_memory_allocator_base);
38202d5b0aaSJacek Lawrynowicz 	ivpu_dbg(vdev, FW_BOOT, "boot_params.global_memory_allocator_size = 0x%x\n",
38302d5b0aaSJacek Lawrynowicz 		 boot_params->global_memory_allocator_size);
38402d5b0aaSJacek Lawrynowicz 
38502d5b0aaSJacek Lawrynowicz 	ivpu_dbg(vdev, FW_BOOT, "boot_params.shave_nn_fw_base = 0x%llx\n",
38602d5b0aaSJacek Lawrynowicz 		 boot_params->shave_nn_fw_base);
38702d5b0aaSJacek Lawrynowicz 
38802d5b0aaSJacek Lawrynowicz 	ivpu_dbg(vdev, FW_BOOT, "boot_params.watchdog_irq_mss = 0x%x\n",
38902d5b0aaSJacek Lawrynowicz 		 boot_params->watchdog_irq_mss);
39002d5b0aaSJacek Lawrynowicz 	ivpu_dbg(vdev, FW_BOOT, "boot_params.watchdog_irq_nce = 0x%x\n",
39102d5b0aaSJacek Lawrynowicz 		 boot_params->watchdog_irq_nce);
39202d5b0aaSJacek Lawrynowicz 	ivpu_dbg(vdev, FW_BOOT, "boot_params.host_to_vpu_irq = 0x%x\n",
39302d5b0aaSJacek Lawrynowicz 		 boot_params->host_to_vpu_irq);
39402d5b0aaSJacek Lawrynowicz 	ivpu_dbg(vdev, FW_BOOT, "boot_params.job_done_irq = 0x%x\n",
39502d5b0aaSJacek Lawrynowicz 		 boot_params->job_done_irq);
39602d5b0aaSJacek Lawrynowicz 
39702d5b0aaSJacek Lawrynowicz 	ivpu_dbg(vdev, FW_BOOT, "boot_params.host_version_id = 0x%x\n",
39802d5b0aaSJacek Lawrynowicz 		 boot_params->host_version_id);
39902d5b0aaSJacek Lawrynowicz 	ivpu_dbg(vdev, FW_BOOT, "boot_params.si_stepping = 0x%x\n",
40002d5b0aaSJacek Lawrynowicz 		 boot_params->si_stepping);
40102d5b0aaSJacek Lawrynowicz 	ivpu_dbg(vdev, FW_BOOT, "boot_params.device_id = 0x%llx\n",
40202d5b0aaSJacek Lawrynowicz 		 boot_params->device_id);
40302d5b0aaSJacek Lawrynowicz 	ivpu_dbg(vdev, FW_BOOT, "boot_params.feature_exclusion = 0x%llx\n",
40402d5b0aaSJacek Lawrynowicz 		 boot_params->feature_exclusion);
40502d5b0aaSJacek Lawrynowicz 	ivpu_dbg(vdev, FW_BOOT, "boot_params.sku = 0x%llx\n",
40602d5b0aaSJacek Lawrynowicz 		 boot_params->sku);
40702d5b0aaSJacek Lawrynowicz 	ivpu_dbg(vdev, FW_BOOT, "boot_params.min_freq_pll_ratio = 0x%x\n",
40802d5b0aaSJacek Lawrynowicz 		 boot_params->min_freq_pll_ratio);
40902d5b0aaSJacek Lawrynowicz 	ivpu_dbg(vdev, FW_BOOT, "boot_params.pn_freq_pll_ratio = 0x%x\n",
41002d5b0aaSJacek Lawrynowicz 		 boot_params->pn_freq_pll_ratio);
41102d5b0aaSJacek Lawrynowicz 	ivpu_dbg(vdev, FW_BOOT, "boot_params.max_freq_pll_ratio = 0x%x\n",
41202d5b0aaSJacek Lawrynowicz 		 boot_params->max_freq_pll_ratio);
41302d5b0aaSJacek Lawrynowicz 	ivpu_dbg(vdev, FW_BOOT, "boot_params.default_trace_level = 0x%x\n",
41402d5b0aaSJacek Lawrynowicz 		 boot_params->default_trace_level);
41502d5b0aaSJacek Lawrynowicz 	ivpu_dbg(vdev, FW_BOOT, "boot_params.tracing_buff_message_format_mask = 0x%llx\n",
41602d5b0aaSJacek Lawrynowicz 		 boot_params->tracing_buff_message_format_mask);
41702d5b0aaSJacek Lawrynowicz 	ivpu_dbg(vdev, FW_BOOT, "boot_params.trace_destination_mask = 0x%x\n",
41802d5b0aaSJacek Lawrynowicz 		 boot_params->trace_destination_mask);
41902d5b0aaSJacek Lawrynowicz 	ivpu_dbg(vdev, FW_BOOT, "boot_params.trace_hw_component_mask = 0x%llx\n",
42002d5b0aaSJacek Lawrynowicz 		 boot_params->trace_hw_component_mask);
42102d5b0aaSJacek Lawrynowicz 	ivpu_dbg(vdev, FW_BOOT, "boot_params.boot_type = 0x%x\n",
42202d5b0aaSJacek Lawrynowicz 		 boot_params->boot_type);
42302d5b0aaSJacek Lawrynowicz 	ivpu_dbg(vdev, FW_BOOT, "boot_params.punit_telemetry_sram_base = 0x%llx\n",
42402d5b0aaSJacek Lawrynowicz 		 boot_params->punit_telemetry_sram_base);
42502d5b0aaSJacek Lawrynowicz 	ivpu_dbg(vdev, FW_BOOT, "boot_params.punit_telemetry_sram_size = 0x%llx\n",
42602d5b0aaSJacek Lawrynowicz 		 boot_params->punit_telemetry_sram_size);
42702d5b0aaSJacek Lawrynowicz 	ivpu_dbg(vdev, FW_BOOT, "boot_params.vpu_telemetry_enable = 0x%x\n",
42802d5b0aaSJacek Lawrynowicz 		 boot_params->vpu_telemetry_enable);
42902d5b0aaSJacek Lawrynowicz }
43002d5b0aaSJacek Lawrynowicz 
ivpu_fw_boot_params_setup(struct ivpu_device * vdev,struct vpu_boot_params * boot_params)43102d5b0aaSJacek Lawrynowicz void ivpu_fw_boot_params_setup(struct ivpu_device *vdev, struct vpu_boot_params *boot_params)
43202d5b0aaSJacek Lawrynowicz {
43302d5b0aaSJacek Lawrynowicz 	struct ivpu_bo *ipc_mem_rx = vdev->ipc->mem_rx;
43402d5b0aaSJacek Lawrynowicz 
43502d5b0aaSJacek Lawrynowicz 	/* In case of warm boot we only have to reset the entrypoint addr */
43602d5b0aaSJacek Lawrynowicz 	if (!ivpu_fw_is_cold_boot(vdev)) {
43702d5b0aaSJacek Lawrynowicz 		boot_params->save_restore_ret_address = 0;
438852be13fSJacek Lawrynowicz 		vdev->pm->is_warmboot = true;
439610b5d21SStanislaw Gruszka 		wmb(); /* Flush WC buffers after writing save_restore_ret_address */
44002d5b0aaSJacek Lawrynowicz 		return;
44102d5b0aaSJacek Lawrynowicz 	}
44202d5b0aaSJacek Lawrynowicz 
443852be13fSJacek Lawrynowicz 	vdev->pm->is_warmboot = false;
444852be13fSJacek Lawrynowicz 
44502d5b0aaSJacek Lawrynowicz 	boot_params->magic = VPU_BOOT_PARAMS_MAGIC;
44602d5b0aaSJacek Lawrynowicz 	boot_params->vpu_id = to_pci_dev(vdev->drm.dev)->bus->number;
44702d5b0aaSJacek Lawrynowicz 	boot_params->frequency = ivpu_hw_reg_pll_freq_get(vdev);
44802d5b0aaSJacek Lawrynowicz 
44902d5b0aaSJacek Lawrynowicz 	/*
45002d5b0aaSJacek Lawrynowicz 	 * Uncached region of VPU address space, covers IPC buffers, job queues
45102d5b0aaSJacek Lawrynowicz 	 * and log buffers, programmable to L2$ Uncached by VPU MTRR
45202d5b0aaSJacek Lawrynowicz 	 */
453162f17b2SKarol Wachowski 	boot_params->shared_region_base = vdev->hw->ranges.global.start;
454162f17b2SKarol Wachowski 	boot_params->shared_region_size = vdev->hw->ranges.global.end -
455162f17b2SKarol Wachowski 					  vdev->hw->ranges.global.start;
45602d5b0aaSJacek Lawrynowicz 
45702d5b0aaSJacek Lawrynowicz 	boot_params->ipc_header_area_start = ipc_mem_rx->vpu_addr;
45802d5b0aaSJacek Lawrynowicz 	boot_params->ipc_header_area_size = ipc_mem_rx->base.size / 2;
45902d5b0aaSJacek Lawrynowicz 
46002d5b0aaSJacek Lawrynowicz 	boot_params->ipc_payload_area_start = ipc_mem_rx->vpu_addr + ipc_mem_rx->base.size / 2;
46102d5b0aaSJacek Lawrynowicz 	boot_params->ipc_payload_area_size = ipc_mem_rx->base.size / 2;
46202d5b0aaSJacek Lawrynowicz 
463162f17b2SKarol Wachowski 	boot_params->global_aliased_pio_base = vdev->hw->ranges.user.start;
464162f17b2SKarol Wachowski 	boot_params->global_aliased_pio_size = ivpu_hw_range_size(&vdev->hw->ranges.user);
46502d5b0aaSJacek Lawrynowicz 
46602d5b0aaSJacek Lawrynowicz 	/* Allow configuration for L2C_PAGE_TABLE with boot param value */
46702d5b0aaSJacek Lawrynowicz 	boot_params->autoconfig = 1;
46802d5b0aaSJacek Lawrynowicz 
46902d5b0aaSJacek Lawrynowicz 	/* Enable L2 cache for first 2GB of high memory */
47002d5b0aaSJacek Lawrynowicz 	boot_params->cache_defaults[VPU_BOOT_L2_CACHE_CFG_NN].use = 1;
47102d5b0aaSJacek Lawrynowicz 	boot_params->cache_defaults[VPU_BOOT_L2_CACHE_CFG_NN].cfg =
472162f17b2SKarol Wachowski 		ADDR_TO_L2_CACHE_CFG(vdev->hw->ranges.shave.start);
47302d5b0aaSJacek Lawrynowicz 
47402d5b0aaSJacek Lawrynowicz 	if (vdev->fw->mem_shave_nn)
47502d5b0aaSJacek Lawrynowicz 		boot_params->shave_nn_fw_base = vdev->fw->mem_shave_nn->vpu_addr;
47602d5b0aaSJacek Lawrynowicz 
47702d5b0aaSJacek Lawrynowicz 	boot_params->watchdog_irq_mss = WATCHDOG_MSS_REDIRECT;
47802d5b0aaSJacek Lawrynowicz 	boot_params->watchdog_irq_nce = WATCHDOG_NCE_REDIRECT;
47902d5b0aaSJacek Lawrynowicz 	boot_params->si_stepping = ivpu_revision(vdev);
48002d5b0aaSJacek Lawrynowicz 	boot_params->device_id = ivpu_device_id(vdev);
48102d5b0aaSJacek Lawrynowicz 	boot_params->feature_exclusion = vdev->hw->tile_fuse;
48202d5b0aaSJacek Lawrynowicz 	boot_params->sku = vdev->hw->sku;
48302d5b0aaSJacek Lawrynowicz 
48402d5b0aaSJacek Lawrynowicz 	boot_params->min_freq_pll_ratio = vdev->hw->pll.min_ratio;
48502d5b0aaSJacek Lawrynowicz 	boot_params->pn_freq_pll_ratio = vdev->hw->pll.pn_ratio;
48602d5b0aaSJacek Lawrynowicz 	boot_params->max_freq_pll_ratio = vdev->hw->pll.max_ratio;
48702d5b0aaSJacek Lawrynowicz 
488d4e4257aSStanislaw Gruszka 	boot_params->default_trace_level = vdev->fw->trace_level;
489d4e4257aSStanislaw Gruszka 	boot_params->tracing_buff_message_format_mask = BIT(VPU_TRACING_FORMAT_STRING);
490d4e4257aSStanislaw Gruszka 	boot_params->trace_destination_mask = vdev->fw->trace_destination_mask;
491d4e4257aSStanislaw Gruszka 	boot_params->trace_hw_component_mask = vdev->fw->trace_hw_component_mask;
492d4e4257aSStanislaw Gruszka 	boot_params->crit_tracing_buff_addr = vdev->fw->mem_log_crit->vpu_addr;
493d4e4257aSStanislaw Gruszka 	boot_params->crit_tracing_buff_size = vdev->fw->mem_log_crit->base.size;
494d4e4257aSStanislaw Gruszka 	boot_params->verbose_tracing_buff_addr = vdev->fw->mem_log_verb->vpu_addr;
495d4e4257aSStanislaw Gruszka 	boot_params->verbose_tracing_buff_size = vdev->fw->mem_log_verb->base.size;
496d4e4257aSStanislaw Gruszka 
49702d5b0aaSJacek Lawrynowicz 	boot_params->punit_telemetry_sram_base = ivpu_hw_reg_telemetry_offset_get(vdev);
49802d5b0aaSJacek Lawrynowicz 	boot_params->punit_telemetry_sram_size = ivpu_hw_reg_telemetry_size_get(vdev);
49902d5b0aaSJacek Lawrynowicz 	boot_params->vpu_telemetry_enable = ivpu_hw_reg_telemetry_enable_get(vdev);
50002d5b0aaSJacek Lawrynowicz 
501610b5d21SStanislaw Gruszka 	wmb(); /* Flush WC buffers after writing bootparams */
50202d5b0aaSJacek Lawrynowicz 
50302d5b0aaSJacek Lawrynowicz 	ivpu_fw_boot_params_print(vdev, boot_params);
50402d5b0aaSJacek Lawrynowicz }
505