cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

firmware_if.c (78343B)


      1// SPDX-License-Identifier: GPL-2.0
      2
      3/*
      4 * Copyright 2016-2022 HabanaLabs, Ltd.
      5 * All Rights Reserved.
      6 */
      7
      8#include "habanalabs.h"
      9#include "../include/common/hl_boot_if.h"
     10
     11#include <linux/firmware.h>
     12#include <linux/crc32.h>
     13#include <linux/slab.h>
     14#include <linux/ctype.h>
     15
     16#define FW_FILE_MAX_SIZE		0x1400000 /* maximum size of 20MB */
     17
     18static char *extract_fw_ver_from_str(const char *fw_str)
     19{
     20	char *str, *fw_ver, *whitespace;
     21	u32 ver_offset;
     22
     23	fw_ver = kmalloc(VERSION_MAX_LEN, GFP_KERNEL);
     24	if (!fw_ver)
     25		return NULL;
     26
     27	str = strnstr(fw_str, "fw-", VERSION_MAX_LEN);
     28	if (!str)
     29		goto free_fw_ver;
     30
     31	/* Skip the fw- part */
     32	str += 3;
     33	ver_offset = str - fw_str;
     34
     35	/* Copy until the next whitespace */
     36	whitespace =  strnstr(str, " ", VERSION_MAX_LEN - ver_offset);
     37	if (!whitespace)
     38		goto free_fw_ver;
     39
     40	strscpy(fw_ver, str, whitespace - str + 1);
     41
     42	return fw_ver;
     43
     44free_fw_ver:
     45	kfree(fw_ver);
     46	return NULL;
     47}
     48
     49static int hl_request_fw(struct hl_device *hdev,
     50				const struct firmware **firmware_p,
     51				const char *fw_name)
     52{
     53	size_t fw_size;
     54	int rc;
     55
     56	rc = request_firmware(firmware_p, fw_name, hdev->dev);
     57	if (rc) {
     58		dev_err(hdev->dev, "Firmware file %s is not found! (error %d)\n",
     59				fw_name, rc);
     60		goto out;
     61	}
     62
     63	fw_size = (*firmware_p)->size;
     64	if ((fw_size % 4) != 0) {
     65		dev_err(hdev->dev, "Illegal %s firmware size %zu\n",
     66				fw_name, fw_size);
     67		rc = -EINVAL;
     68		goto release_fw;
     69	}
     70
     71	dev_dbg(hdev->dev, "%s firmware size == %zu\n", fw_name, fw_size);
     72
     73	if (fw_size > FW_FILE_MAX_SIZE) {
     74		dev_err(hdev->dev,
     75			"FW file size %zu exceeds maximum of %u bytes\n",
     76			fw_size, FW_FILE_MAX_SIZE);
     77		rc = -EINVAL;
     78		goto release_fw;
     79	}
     80
     81	return 0;
     82
     83release_fw:
     84	release_firmware(*firmware_p);
     85out:
     86	return rc;
     87}
     88
     89/**
     90 * hl_release_firmware() - release FW
     91 *
     92 * @fw: fw descriptor
     93 *
     94 * note: this inline function added to serve as a comprehensive mirror for the
     95 *       hl_request_fw function.
     96 */
     97static inline void hl_release_firmware(const struct firmware *fw)
     98{
     99	release_firmware(fw);
    100}
    101
    102/**
    103 * hl_fw_copy_fw_to_device() - copy FW to device
    104 *
    105 * @hdev: pointer to hl_device structure.
    106 * @fw: fw descriptor
    107 * @dst: IO memory mapped address space to copy firmware to
    108 * @src_offset: offset in src FW to copy from
    109 * @size: amount of bytes to copy (0 to copy the whole binary)
    110 *
    111 * actual copy of FW binary data to device, shared by static and dynamic loaders
    112 */
    113static int hl_fw_copy_fw_to_device(struct hl_device *hdev,
    114				const struct firmware *fw, void __iomem *dst,
    115				u32 src_offset, u32 size)
    116{
    117	const void *fw_data;
    118
    119	/* size 0 indicates to copy the whole file */
    120	if (!size)
    121		size = fw->size;
    122
    123	if (src_offset + size > fw->size) {
    124		dev_err(hdev->dev,
    125			"size to copy(%u) and offset(%u) are invalid\n",
    126			size, src_offset);
    127		return -EINVAL;
    128	}
    129
    130	fw_data = (const void *) fw->data;
    131
    132	memcpy_toio(dst, fw_data + src_offset, size);
    133	return 0;
    134}
    135
    136/**
    137 * hl_fw_copy_msg_to_device() - copy message to device
    138 *
    139 * @hdev: pointer to hl_device structure.
    140 * @msg: message
    141 * @dst: IO memory mapped address space to copy firmware to
    142 * @src_offset: offset in src message to copy from
    143 * @size: amount of bytes to copy (0 to copy the whole binary)
    144 *
    145 * actual copy of message data to device.
    146 */
    147static int hl_fw_copy_msg_to_device(struct hl_device *hdev,
    148		struct lkd_msg_comms *msg, void __iomem *dst,
    149		u32 src_offset, u32 size)
    150{
    151	void *msg_data;
    152
    153	/* size 0 indicates to copy the whole file */
    154	if (!size)
    155		size = sizeof(struct lkd_msg_comms);
    156
    157	if (src_offset + size > sizeof(struct lkd_msg_comms)) {
    158		dev_err(hdev->dev,
    159			"size to copy(%u) and offset(%u) are invalid\n",
    160			size, src_offset);
    161		return -EINVAL;
    162	}
    163
    164	msg_data = (void *) msg;
    165
    166	memcpy_toio(dst, msg_data + src_offset, size);
    167
    168	return 0;
    169}
    170
    171/**
    172 * hl_fw_load_fw_to_device() - Load F/W code to device's memory.
    173 *
    174 * @hdev: pointer to hl_device structure.
    175 * @fw_name: the firmware image name
    176 * @dst: IO memory mapped address space to copy firmware to
    177 * @src_offset: offset in src FW to copy from
    178 * @size: amount of bytes to copy (0 to copy the whole binary)
    179 *
    180 * Copy fw code from firmware file to device memory.
    181 *
    182 * Return: 0 on success, non-zero for failure.
    183 */
    184int hl_fw_load_fw_to_device(struct hl_device *hdev, const char *fw_name,
    185				void __iomem *dst, u32 src_offset, u32 size)
    186{
    187	const struct firmware *fw;
    188	int rc;
    189
    190	rc = hl_request_fw(hdev, &fw, fw_name);
    191	if (rc)
    192		return rc;
    193
    194	rc = hl_fw_copy_fw_to_device(hdev, fw, dst, src_offset, size);
    195
    196	hl_release_firmware(fw);
    197	return rc;
    198}
    199
    200int hl_fw_send_pci_access_msg(struct hl_device *hdev, u32 opcode)
    201{
    202	struct cpucp_packet pkt = {};
    203
    204	pkt.ctl = cpu_to_le32(opcode << CPUCP_PKT_CTL_OPCODE_SHIFT);
    205
    206	return hdev->asic_funcs->send_cpu_message(hdev, (u32 *) &pkt,
    207						sizeof(pkt), 0, NULL);
    208}
    209
    210int hl_fw_send_cpu_message(struct hl_device *hdev, u32 hw_queue_id, u32 *msg,
    211				u16 len, u32 timeout, u64 *result)
    212{
    213	struct hl_hw_queue *queue = &hdev->kernel_queues[hw_queue_id];
    214	struct asic_fixed_properties *prop = &hdev->asic_prop;
    215	struct cpucp_packet *pkt;
    216	dma_addr_t pkt_dma_addr;
    217	struct hl_bd *sent_bd;
    218	u32 tmp, expected_ack_val, pi;
    219	int rc;
    220
    221	pkt = hdev->asic_funcs->cpu_accessible_dma_pool_alloc(hdev, len,
    222								&pkt_dma_addr);
    223	if (!pkt) {
    224		dev_err(hdev->dev,
    225			"Failed to allocate DMA memory for packet to CPU\n");
    226		return -ENOMEM;
    227	}
    228
    229	memcpy(pkt, msg, len);
    230
    231	mutex_lock(&hdev->send_cpu_message_lock);
    232
    233	/* CPU-CP messages can be sent during soft-reset */
    234	if (hdev->disabled && !hdev->reset_info.is_in_soft_reset) {
    235		rc = 0;
    236		goto out;
    237	}
    238
    239	if (hdev->device_cpu_disabled) {
    240		rc = -EIO;
    241		goto out;
    242	}
    243
    244	/* set fence to a non valid value */
    245	pkt->fence = cpu_to_le32(UINT_MAX);
    246	pi = queue->pi;
    247
    248	/*
    249	 * The CPU queue is a synchronous queue with an effective depth of
    250	 * a single entry (although it is allocated with room for multiple
    251	 * entries). We lock on it using 'send_cpu_message_lock' which
    252	 * serializes accesses to the CPU queue.
    253	 * Which means that we don't need to lock the access to the entire H/W
    254	 * queues module when submitting a JOB to the CPU queue.
    255	 */
    256	hl_hw_queue_submit_bd(hdev, queue, hl_queue_inc_ptr(queue->pi), len, pkt_dma_addr);
    257
    258	if (prop->fw_app_cpu_boot_dev_sts0 & CPU_BOOT_DEV_STS0_PKT_PI_ACK_EN)
    259		expected_ack_val = queue->pi;
    260	else
    261		expected_ack_val = CPUCP_PACKET_FENCE_VAL;
    262
    263	rc = hl_poll_timeout_memory(hdev, &pkt->fence, tmp,
    264				(tmp == expected_ack_val), 1000,
    265				timeout, true);
    266
    267	hl_hw_queue_inc_ci_kernel(hdev, hw_queue_id);
    268
    269	if (rc == -ETIMEDOUT) {
    270		dev_err(hdev->dev, "Device CPU packet timeout (0x%x)\n", tmp);
    271		hdev->device_cpu_disabled = true;
    272		goto out;
    273	}
    274
    275	tmp = le32_to_cpu(pkt->ctl);
    276
    277	rc = (tmp & CPUCP_PKT_CTL_RC_MASK) >> CPUCP_PKT_CTL_RC_SHIFT;
    278	if (rc) {
    279		dev_err(hdev->dev, "F/W ERROR %d for CPU packet %d\n",
    280			rc,
    281			(tmp & CPUCP_PKT_CTL_OPCODE_MASK)
    282						>> CPUCP_PKT_CTL_OPCODE_SHIFT);
    283		rc = -EIO;
    284	} else if (result) {
    285		*result = le64_to_cpu(pkt->result);
    286	}
    287
    288	/* Scrub previous buffer descriptor 'ctl' field which contains the
    289	 * previous PI value written during packet submission.
    290	 * We must do this or else F/W can read an old value upon queue wraparound.
    291	 */
    292	sent_bd = queue->kernel_address;
    293	sent_bd += hl_pi_2_offset(pi);
    294	sent_bd->ctl = cpu_to_le32(UINT_MAX);
    295
    296out:
    297	mutex_unlock(&hdev->send_cpu_message_lock);
    298
    299	hdev->asic_funcs->cpu_accessible_dma_pool_free(hdev, len, pkt);
    300
    301	return rc;
    302}
    303
    304int hl_fw_unmask_irq(struct hl_device *hdev, u16 event_type)
    305{
    306	struct cpucp_packet pkt;
    307	u64 result;
    308	int rc;
    309
    310	memset(&pkt, 0, sizeof(pkt));
    311
    312	pkt.ctl = cpu_to_le32(CPUCP_PACKET_UNMASK_RAZWI_IRQ <<
    313				CPUCP_PKT_CTL_OPCODE_SHIFT);
    314	pkt.value = cpu_to_le64(event_type);
    315
    316	rc = hdev->asic_funcs->send_cpu_message(hdev, (u32 *) &pkt, sizeof(pkt),
    317						0, &result);
    318
    319	if (rc)
    320		dev_err(hdev->dev, "failed to unmask RAZWI IRQ %d", event_type);
    321
    322	return rc;
    323}
    324
    325int hl_fw_unmask_irq_arr(struct hl_device *hdev, const u32 *irq_arr,
    326		size_t irq_arr_size)
    327{
    328	struct cpucp_unmask_irq_arr_packet *pkt;
    329	size_t total_pkt_size;
    330	u64 result;
    331	int rc;
    332
    333	total_pkt_size = sizeof(struct cpucp_unmask_irq_arr_packet) +
    334			irq_arr_size;
    335
    336	/* data should be aligned to 8 bytes in order to CPU-CP to copy it */
    337	total_pkt_size = (total_pkt_size + 0x7) & ~0x7;
    338
    339	/* total_pkt_size is casted to u16 later on */
    340	if (total_pkt_size > USHRT_MAX) {
    341		dev_err(hdev->dev, "too many elements in IRQ array\n");
    342		return -EINVAL;
    343	}
    344
    345	pkt = kzalloc(total_pkt_size, GFP_KERNEL);
    346	if (!pkt)
    347		return -ENOMEM;
    348
    349	pkt->length = cpu_to_le32(irq_arr_size / sizeof(irq_arr[0]));
    350	memcpy(&pkt->irqs, irq_arr, irq_arr_size);
    351
    352	pkt->cpucp_pkt.ctl = cpu_to_le32(CPUCP_PACKET_UNMASK_RAZWI_IRQ_ARRAY <<
    353						CPUCP_PKT_CTL_OPCODE_SHIFT);
    354
    355	rc = hdev->asic_funcs->send_cpu_message(hdev, (u32 *) pkt,
    356						total_pkt_size, 0, &result);
    357
    358	if (rc)
    359		dev_err(hdev->dev, "failed to unmask IRQ array\n");
    360
    361	kfree(pkt);
    362
    363	return rc;
    364}
    365
    366int hl_fw_test_cpu_queue(struct hl_device *hdev)
    367{
    368	struct cpucp_packet test_pkt = {};
    369	u64 result;
    370	int rc;
    371
    372	test_pkt.ctl = cpu_to_le32(CPUCP_PACKET_TEST <<
    373					CPUCP_PKT_CTL_OPCODE_SHIFT);
    374	test_pkt.value = cpu_to_le64(CPUCP_PACKET_FENCE_VAL);
    375
    376	rc = hdev->asic_funcs->send_cpu_message(hdev, (u32 *) &test_pkt,
    377						sizeof(test_pkt), 0, &result);
    378
    379	if (!rc) {
    380		if (result != CPUCP_PACKET_FENCE_VAL)
    381			dev_err(hdev->dev,
    382				"CPU queue test failed (%#08llx)\n", result);
    383	} else {
    384		dev_err(hdev->dev, "CPU queue test failed, error %d\n", rc);
    385	}
    386
    387	return rc;
    388}
    389
    390void *hl_fw_cpu_accessible_dma_pool_alloc(struct hl_device *hdev, size_t size,
    391						dma_addr_t *dma_handle)
    392{
    393	u64 kernel_addr;
    394
    395	kernel_addr = gen_pool_alloc(hdev->cpu_accessible_dma_pool, size);
    396
    397	*dma_handle = hdev->cpu_accessible_dma_address +
    398		(kernel_addr - (u64) (uintptr_t) hdev->cpu_accessible_dma_mem);
    399
    400	return (void *) (uintptr_t) kernel_addr;
    401}
    402
    403void hl_fw_cpu_accessible_dma_pool_free(struct hl_device *hdev, size_t size,
    404					void *vaddr)
    405{
    406	gen_pool_free(hdev->cpu_accessible_dma_pool, (u64) (uintptr_t) vaddr,
    407			size);
    408}
    409
    410int hl_fw_send_heartbeat(struct hl_device *hdev)
    411{
    412	struct cpucp_packet hb_pkt;
    413	u64 result;
    414	int rc;
    415
    416	memset(&hb_pkt, 0, sizeof(hb_pkt));
    417	hb_pkt.ctl = cpu_to_le32(CPUCP_PACKET_TEST <<
    418					CPUCP_PKT_CTL_OPCODE_SHIFT);
    419	hb_pkt.value = cpu_to_le64(CPUCP_PACKET_FENCE_VAL);
    420
    421	rc = hdev->asic_funcs->send_cpu_message(hdev, (u32 *) &hb_pkt,
    422						sizeof(hb_pkt), 0, &result);
    423
    424	if ((rc) || (result != CPUCP_PACKET_FENCE_VAL))
    425		return -EIO;
    426
    427	if (le32_to_cpu(hb_pkt.status_mask) &
    428					CPUCP_PKT_HB_STATUS_EQ_FAULT_MASK) {
    429		dev_warn(hdev->dev, "FW reported EQ fault during heartbeat\n");
    430		rc = -EIO;
    431	}
    432
    433	return rc;
    434}
    435
    436static bool fw_report_boot_dev0(struct hl_device *hdev, u32 err_val,
    437								u32 sts_val)
    438{
    439	bool err_exists = false;
    440
    441	if (!(err_val & CPU_BOOT_ERR0_ENABLED))
    442		return false;
    443
    444	if (err_val & CPU_BOOT_ERR0_DRAM_INIT_FAIL) {
    445		dev_err(hdev->dev,
    446			"Device boot error - DRAM initialization failed\n");
    447		err_exists = true;
    448	}
    449
    450	if (err_val & CPU_BOOT_ERR0_FIT_CORRUPTED) {
    451		dev_err(hdev->dev, "Device boot error - FIT image corrupted\n");
    452		err_exists = true;
    453	}
    454
    455	if (err_val & CPU_BOOT_ERR0_TS_INIT_FAIL) {
    456		dev_err(hdev->dev,
    457			"Device boot error - Thermal Sensor initialization failed\n");
    458		err_exists = true;
    459	}
    460
    461	if (err_val & CPU_BOOT_ERR0_BMC_WAIT_SKIPPED) {
    462		if (hdev->bmc_enable) {
    463			dev_err(hdev->dev,
    464				"Device boot error - Skipped waiting for BMC\n");
    465			err_exists = true;
    466		} else {
    467			dev_info(hdev->dev,
    468				"Device boot message - Skipped waiting for BMC\n");
    469			/* This is an info so we don't want it to disable the
    470			 * device
    471			 */
    472			err_val &= ~CPU_BOOT_ERR0_BMC_WAIT_SKIPPED;
    473		}
    474	}
    475
    476	if (err_val & CPU_BOOT_ERR0_NIC_DATA_NOT_RDY) {
    477		dev_err(hdev->dev,
    478			"Device boot error - Serdes data from BMC not available\n");
    479		err_exists = true;
    480	}
    481
    482	if (err_val & CPU_BOOT_ERR0_NIC_FW_FAIL) {
    483		dev_err(hdev->dev,
    484			"Device boot error - NIC F/W initialization failed\n");
    485		err_exists = true;
    486	}
    487
    488	if (err_val & CPU_BOOT_ERR0_SECURITY_NOT_RDY) {
    489		dev_err(hdev->dev,
    490			"Device boot warning - security not ready\n");
    491		err_exists = true;
    492	}
    493
    494	if (err_val & CPU_BOOT_ERR0_SECURITY_FAIL) {
    495		dev_err(hdev->dev, "Device boot error - security failure\n");
    496		err_exists = true;
    497	}
    498
    499	if (err_val & CPU_BOOT_ERR0_EFUSE_FAIL) {
    500		dev_err(hdev->dev, "Device boot error - eFuse failure\n");
    501		err_exists = true;
    502	}
    503
    504	if (err_val & CPU_BOOT_ERR0_SEC_IMG_VER_FAIL) {
    505		dev_err(hdev->dev, "Device boot error - Failed to load preboot secondary image\n");
    506		err_exists = true;
    507	}
    508
    509	if (err_val & CPU_BOOT_ERR0_PLL_FAIL) {
    510		dev_err(hdev->dev, "Device boot error - PLL failure\n");
    511		err_exists = true;
    512	}
    513
    514	if (err_val & CPU_BOOT_ERR0_DEVICE_UNUSABLE_FAIL) {
    515		/* Ignore this bit, don't prevent driver loading */
    516		dev_dbg(hdev->dev, "device unusable status is set\n");
    517		err_val &= ~CPU_BOOT_ERR0_DEVICE_UNUSABLE_FAIL;
    518	}
    519
    520	if (sts_val & CPU_BOOT_DEV_STS0_ENABLED)
    521		dev_dbg(hdev->dev, "Device status0 %#x\n", sts_val);
    522
    523	/* All warnings should go here in order not to reach the unknown error validation */
    524	if (err_val & CPU_BOOT_ERR0_DRAM_SKIPPED) {
    525		dev_warn(hdev->dev,
    526			"Device boot warning - Skipped DRAM initialization\n");
    527		/* This is a warning so we don't want it to disable the
    528		 * device
    529		 */
    530		err_val &= ~CPU_BOOT_ERR0_DRAM_SKIPPED;
    531	}
    532
    533	if (err_val & CPU_BOOT_ERR0_PRI_IMG_VER_FAIL) {
    534		dev_warn(hdev->dev,
    535			"Device boot warning - Failed to load preboot primary image\n");
    536		/* This is a warning so we don't want it to disable the
    537		 * device as we have a secondary preboot image
    538		 */
    539		err_val &= ~CPU_BOOT_ERR0_PRI_IMG_VER_FAIL;
    540	}
    541
    542	if (err_val & CPU_BOOT_ERR0_TPM_FAIL) {
    543		dev_warn(hdev->dev,
    544			"Device boot warning - TPM failure\n");
    545		/* This is a warning so we don't want it to disable the
    546		 * device
    547		 */
    548		err_val &= ~CPU_BOOT_ERR0_TPM_FAIL;
    549	}
    550
    551	if (!err_exists && (err_val & ~CPU_BOOT_ERR0_ENABLED)) {
    552		dev_err(hdev->dev,
    553			"Device boot error - unknown ERR0 error 0x%08x\n", err_val);
    554		err_exists = true;
    555	}
    556
    557	/* return error only if it's in the predefined mask */
    558	if (err_exists && ((err_val & ~CPU_BOOT_ERR0_ENABLED) &
    559				lower_32_bits(hdev->boot_error_status_mask)))
    560		return true;
    561
    562	return false;
    563}
    564
    565/* placeholder for ERR1 as no errors defined there yet */
    566static bool fw_report_boot_dev1(struct hl_device *hdev, u32 err_val,
    567								u32 sts_val)
    568{
    569	/*
    570	 * keep this variable to preserve the logic of the function.
    571	 * this way it would require less modifications when error will be
    572	 * added to DEV_ERR1
    573	 */
    574	bool err_exists = false;
    575
    576	if (!(err_val & CPU_BOOT_ERR1_ENABLED))
    577		return false;
    578
    579	if (sts_val & CPU_BOOT_DEV_STS1_ENABLED)
    580		dev_dbg(hdev->dev, "Device status1 %#x\n", sts_val);
    581
    582	if (!err_exists && (err_val & ~CPU_BOOT_ERR1_ENABLED)) {
    583		dev_err(hdev->dev,
    584			"Device boot error - unknown ERR1 error 0x%08x\n",
    585								err_val);
    586		err_exists = true;
    587	}
    588
    589	/* return error only if it's in the predefined mask */
    590	if (err_exists && ((err_val & ~CPU_BOOT_ERR1_ENABLED) &
    591				upper_32_bits(hdev->boot_error_status_mask)))
    592		return true;
    593
    594	return false;
    595}
    596
    597static int fw_read_errors(struct hl_device *hdev, u32 boot_err0_reg,
    598				u32 boot_err1_reg, u32 cpu_boot_dev_status0_reg,
    599				u32 cpu_boot_dev_status1_reg)
    600{
    601	u32 err_val, status_val;
    602	bool err_exists = false;
    603
    604	/* Some of the firmware status codes are deprecated in newer f/w
    605	 * versions. In those versions, the errors are reported
    606	 * in different registers. Therefore, we need to check those
    607	 * registers and print the exact errors. Moreover, there
    608	 * may be multiple errors, so we need to report on each error
    609	 * separately. Some of the error codes might indicate a state
    610	 * that is not an error per-se, but it is an error in production
    611	 * environment
    612	 */
    613	err_val = RREG32(boot_err0_reg);
    614	status_val = RREG32(cpu_boot_dev_status0_reg);
    615	err_exists = fw_report_boot_dev0(hdev, err_val, status_val);
    616
    617	err_val = RREG32(boot_err1_reg);
    618	status_val = RREG32(cpu_boot_dev_status1_reg);
    619	err_exists |= fw_report_boot_dev1(hdev, err_val, status_val);
    620
    621	if (err_exists)
    622		return -EIO;
    623
    624	return 0;
    625}
    626
    627int hl_fw_cpucp_info_get(struct hl_device *hdev,
    628				u32 sts_boot_dev_sts0_reg,
    629				u32 sts_boot_dev_sts1_reg, u32 boot_err0_reg,
    630				u32 boot_err1_reg)
    631{
    632	struct asic_fixed_properties *prop = &hdev->asic_prop;
    633	struct cpucp_packet pkt = {};
    634	dma_addr_t cpucp_info_dma_addr;
    635	void *cpucp_info_cpu_addr;
    636	char *kernel_ver;
    637	u64 result;
    638	int rc;
    639
    640	cpucp_info_cpu_addr =
    641			hdev->asic_funcs->cpu_accessible_dma_pool_alloc(hdev,
    642					sizeof(struct cpucp_info),
    643					&cpucp_info_dma_addr);
    644	if (!cpucp_info_cpu_addr) {
    645		dev_err(hdev->dev,
    646			"Failed to allocate DMA memory for CPU-CP info packet\n");
    647		return -ENOMEM;
    648	}
    649
    650	memset(cpucp_info_cpu_addr, 0, sizeof(struct cpucp_info));
    651
    652	pkt.ctl = cpu_to_le32(CPUCP_PACKET_INFO_GET <<
    653				CPUCP_PKT_CTL_OPCODE_SHIFT);
    654	pkt.addr = cpu_to_le64(cpucp_info_dma_addr);
    655	pkt.data_max_size = cpu_to_le32(sizeof(struct cpucp_info));
    656
    657	rc = hdev->asic_funcs->send_cpu_message(hdev, (u32 *) &pkt, sizeof(pkt),
    658					HL_CPUCP_INFO_TIMEOUT_USEC, &result);
    659	if (rc) {
    660		dev_err(hdev->dev,
    661			"Failed to handle CPU-CP info pkt, error %d\n", rc);
    662		goto out;
    663	}
    664
    665	rc = fw_read_errors(hdev, boot_err0_reg, boot_err1_reg,
    666				sts_boot_dev_sts0_reg, sts_boot_dev_sts1_reg);
    667	if (rc) {
    668		dev_err(hdev->dev, "Errors in device boot\n");
    669		goto out;
    670	}
    671
    672	memcpy(&prop->cpucp_info, cpucp_info_cpu_addr,
    673			sizeof(prop->cpucp_info));
    674
    675	rc = hl_build_hwmon_channel_info(hdev, prop->cpucp_info.sensors);
    676	if (rc) {
    677		dev_err(hdev->dev,
    678			"Failed to build hwmon channel info, error %d\n", rc);
    679		rc = -EFAULT;
    680		goto out;
    681	}
    682
    683	kernel_ver = extract_fw_ver_from_str(prop->cpucp_info.kernel_version);
    684	if (kernel_ver) {
    685		dev_info(hdev->dev, "Linux version %s", kernel_ver);
    686		kfree(kernel_ver);
    687	}
    688
    689	/* assume EQ code doesn't need to check eqe index */
    690	hdev->event_queue.check_eqe_index = false;
    691
    692	/* Read FW application security bits again */
    693	if (prop->fw_cpu_boot_dev_sts0_valid) {
    694		prop->fw_app_cpu_boot_dev_sts0 = RREG32(sts_boot_dev_sts0_reg);
    695		if (prop->fw_app_cpu_boot_dev_sts0 &
    696				CPU_BOOT_DEV_STS0_EQ_INDEX_EN)
    697			hdev->event_queue.check_eqe_index = true;
    698	}
    699
    700	if (prop->fw_cpu_boot_dev_sts1_valid)
    701		prop->fw_app_cpu_boot_dev_sts1 = RREG32(sts_boot_dev_sts1_reg);
    702
    703out:
    704	hdev->asic_funcs->cpu_accessible_dma_pool_free(hdev,
    705			sizeof(struct cpucp_info), cpucp_info_cpu_addr);
    706
    707	return rc;
    708}
    709
    710static int hl_fw_send_msi_info_msg(struct hl_device *hdev)
    711{
    712	struct cpucp_array_data_packet *pkt;
    713	size_t total_pkt_size, data_size;
    714	u64 result;
    715	int rc;
    716
    717	/* skip sending this info for unsupported ASICs */
    718	if (!hdev->asic_funcs->get_msi_info)
    719		return 0;
    720
    721	data_size = CPUCP_NUM_OF_MSI_TYPES * sizeof(u32);
    722	total_pkt_size = sizeof(struct cpucp_array_data_packet) + data_size;
    723
    724	/* data should be aligned to 8 bytes in order to CPU-CP to copy it */
    725	total_pkt_size = (total_pkt_size + 0x7) & ~0x7;
    726
    727	/* total_pkt_size is casted to u16 later on */
    728	if (total_pkt_size > USHRT_MAX) {
    729		dev_err(hdev->dev, "CPUCP array data is too big\n");
    730		return -EINVAL;
    731	}
    732
    733	pkt = kzalloc(total_pkt_size, GFP_KERNEL);
    734	if (!pkt)
    735		return -ENOMEM;
    736
    737	pkt->length = cpu_to_le32(CPUCP_NUM_OF_MSI_TYPES);
    738
    739	memset((void *) &pkt->data, 0xFF, data_size);
    740	hdev->asic_funcs->get_msi_info(pkt->data);
    741
    742	pkt->cpucp_pkt.ctl = cpu_to_le32(CPUCP_PACKET_MSI_INFO_SET <<
    743						CPUCP_PKT_CTL_OPCODE_SHIFT);
    744
    745	rc = hdev->asic_funcs->send_cpu_message(hdev, (u32 *)pkt,
    746						total_pkt_size, 0, &result);
    747
    748	/*
    749	 * in case packet result is invalid it means that FW does not support
    750	 * this feature and will use default/hard coded MSI values. no reason
    751	 * to stop the boot
    752	 */
    753	if (rc && result == cpucp_packet_invalid)
    754		rc = 0;
    755
    756	if (rc)
    757		dev_err(hdev->dev, "failed to send CPUCP array data\n");
    758
    759	kfree(pkt);
    760
    761	return rc;
    762}
    763
    764int hl_fw_cpucp_handshake(struct hl_device *hdev,
    765				u32 sts_boot_dev_sts0_reg,
    766				u32 sts_boot_dev_sts1_reg, u32 boot_err0_reg,
    767				u32 boot_err1_reg)
    768{
    769	int rc;
    770
    771	rc = hl_fw_cpucp_info_get(hdev, sts_boot_dev_sts0_reg,
    772					sts_boot_dev_sts1_reg, boot_err0_reg,
    773					boot_err1_reg);
    774	if (rc)
    775		return rc;
    776
    777	return hl_fw_send_msi_info_msg(hdev);
    778}
    779
    780int hl_fw_get_eeprom_data(struct hl_device *hdev, void *data, size_t max_size)
    781{
    782	struct cpucp_packet pkt = {};
    783	void *eeprom_info_cpu_addr;
    784	dma_addr_t eeprom_info_dma_addr;
    785	u64 result;
    786	int rc;
    787
    788	eeprom_info_cpu_addr =
    789			hdev->asic_funcs->cpu_accessible_dma_pool_alloc(hdev,
    790					max_size, &eeprom_info_dma_addr);
    791	if (!eeprom_info_cpu_addr) {
    792		dev_err(hdev->dev,
    793			"Failed to allocate DMA memory for CPU-CP EEPROM packet\n");
    794		return -ENOMEM;
    795	}
    796
    797	memset(eeprom_info_cpu_addr, 0, max_size);
    798
    799	pkt.ctl = cpu_to_le32(CPUCP_PACKET_EEPROM_DATA_GET <<
    800				CPUCP_PKT_CTL_OPCODE_SHIFT);
    801	pkt.addr = cpu_to_le64(eeprom_info_dma_addr);
    802	pkt.data_max_size = cpu_to_le32(max_size);
    803
    804	rc = hdev->asic_funcs->send_cpu_message(hdev, (u32 *) &pkt, sizeof(pkt),
    805			HL_CPUCP_EEPROM_TIMEOUT_USEC, &result);
    806
    807	if (rc) {
    808		dev_err(hdev->dev,
    809			"Failed to handle CPU-CP EEPROM packet, error %d\n",
    810			rc);
    811		goto out;
    812	}
    813
    814	/* result contains the actual size */
    815	memcpy(data, eeprom_info_cpu_addr, min((size_t)result, max_size));
    816
    817out:
    818	hdev->asic_funcs->cpu_accessible_dma_pool_free(hdev, max_size,
    819			eeprom_info_cpu_addr);
    820
    821	return rc;
    822}
    823
    824int hl_fw_get_monitor_dump(struct hl_device *hdev, void *data)
    825{
    826	struct cpucp_monitor_dump *mon_dump_cpu_addr;
    827	dma_addr_t mon_dump_dma_addr;
    828	struct cpucp_packet pkt = {};
    829	size_t data_size;
    830	__le32 *src_ptr;
    831	u32 *dst_ptr;
    832	u64 result;
    833	int i, rc;
    834
    835	data_size = sizeof(struct cpucp_monitor_dump);
    836	mon_dump_cpu_addr = hdev->asic_funcs->cpu_accessible_dma_pool_alloc(hdev, data_size,
    837										&mon_dump_dma_addr);
    838	if (!mon_dump_cpu_addr) {
    839		dev_err(hdev->dev,
    840			"Failed to allocate DMA memory for CPU-CP monitor-dump packet\n");
    841		return -ENOMEM;
    842	}
    843
    844	memset(mon_dump_cpu_addr, 0, data_size);
    845
    846	pkt.ctl = cpu_to_le32(CPUCP_PACKET_MONITOR_DUMP_GET << CPUCP_PKT_CTL_OPCODE_SHIFT);
    847	pkt.addr = cpu_to_le64(mon_dump_dma_addr);
    848	pkt.data_max_size = cpu_to_le32(data_size);
    849
    850	rc = hdev->asic_funcs->send_cpu_message(hdev, (u32 *) &pkt, sizeof(pkt),
    851							HL_CPUCP_MON_DUMP_TIMEOUT_USEC, &result);
    852	if (rc) {
    853		dev_err(hdev->dev, "Failed to handle CPU-CP monitor-dump packet, error %d\n", rc);
    854		goto out;
    855	}
    856
    857	/* result contains the actual size */
    858	src_ptr = (__le32 *) mon_dump_cpu_addr;
    859	dst_ptr = data;
    860	for (i = 0; i < (data_size / sizeof(u32)); i++) {
    861		*dst_ptr = le32_to_cpu(*src_ptr);
    862		src_ptr++;
    863		dst_ptr++;
    864	}
    865
    866out:
    867	hdev->asic_funcs->cpu_accessible_dma_pool_free(hdev, data_size, mon_dump_cpu_addr);
    868
    869	return rc;
    870}
    871
    872int hl_fw_cpucp_pci_counters_get(struct hl_device *hdev,
    873		struct hl_info_pci_counters *counters)
    874{
    875	struct cpucp_packet pkt = {};
    876	u64 result;
    877	int rc;
    878
    879	pkt.ctl = cpu_to_le32(CPUCP_PACKET_PCIE_THROUGHPUT_GET <<
    880			CPUCP_PKT_CTL_OPCODE_SHIFT);
    881
    882	/* Fetch PCI rx counter */
    883	pkt.index = cpu_to_le32(cpucp_pcie_throughput_rx);
    884	rc = hdev->asic_funcs->send_cpu_message(hdev, (u32 *) &pkt, sizeof(pkt),
    885					HL_CPUCP_INFO_TIMEOUT_USEC, &result);
    886	if (rc) {
    887		dev_err(hdev->dev,
    888			"Failed to handle CPU-CP PCI info pkt, error %d\n", rc);
    889		return rc;
    890	}
    891	counters->rx_throughput = result;
    892
    893	memset(&pkt, 0, sizeof(pkt));
    894	pkt.ctl = cpu_to_le32(CPUCP_PACKET_PCIE_THROUGHPUT_GET <<
    895			CPUCP_PKT_CTL_OPCODE_SHIFT);
    896
    897	/* Fetch PCI tx counter */
    898	pkt.index = cpu_to_le32(cpucp_pcie_throughput_tx);
    899	rc = hdev->asic_funcs->send_cpu_message(hdev, (u32 *) &pkt, sizeof(pkt),
    900					HL_CPUCP_INFO_TIMEOUT_USEC, &result);
    901	if (rc) {
    902		dev_err(hdev->dev,
    903			"Failed to handle CPU-CP PCI info pkt, error %d\n", rc);
    904		return rc;
    905	}
    906	counters->tx_throughput = result;
    907
    908	/* Fetch PCI replay counter */
    909	memset(&pkt, 0, sizeof(pkt));
    910	pkt.ctl = cpu_to_le32(CPUCP_PACKET_PCIE_REPLAY_CNT_GET <<
    911			CPUCP_PKT_CTL_OPCODE_SHIFT);
    912
    913	rc = hdev->asic_funcs->send_cpu_message(hdev, (u32 *) &pkt, sizeof(pkt),
    914			HL_CPUCP_INFO_TIMEOUT_USEC, &result);
    915	if (rc) {
    916		dev_err(hdev->dev,
    917			"Failed to handle CPU-CP PCI info pkt, error %d\n", rc);
    918		return rc;
    919	}
    920	counters->replay_cnt = (u32) result;
    921
    922	return rc;
    923}
    924
    925int hl_fw_cpucp_total_energy_get(struct hl_device *hdev, u64 *total_energy)
    926{
    927	struct cpucp_packet pkt = {};
    928	u64 result;
    929	int rc;
    930
    931	pkt.ctl = cpu_to_le32(CPUCP_PACKET_TOTAL_ENERGY_GET <<
    932				CPUCP_PKT_CTL_OPCODE_SHIFT);
    933
    934	rc = hdev->asic_funcs->send_cpu_message(hdev, (u32 *) &pkt, sizeof(pkt),
    935					HL_CPUCP_INFO_TIMEOUT_USEC, &result);
    936	if (rc) {
    937		dev_err(hdev->dev,
    938			"Failed to handle CpuCP total energy pkt, error %d\n",
    939				rc);
    940		return rc;
    941	}
    942
    943	*total_energy = result;
    944
    945	return rc;
    946}
    947
    948int get_used_pll_index(struct hl_device *hdev, u32 input_pll_index,
    949						enum pll_index *pll_index)
    950{
    951	struct asic_fixed_properties *prop = &hdev->asic_prop;
    952	u8 pll_byte, pll_bit_off;
    953	bool dynamic_pll;
    954	int fw_pll_idx;
    955
    956	dynamic_pll = !!(prop->fw_app_cpu_boot_dev_sts0 &
    957						CPU_BOOT_DEV_STS0_DYN_PLL_EN);
    958
    959	if (!dynamic_pll) {
    960		/*
    961		 * in case we are working with legacy FW (each asic has unique
    962		 * PLL numbering) use the driver based index as they are
    963		 * aligned with fw legacy numbering
    964		 */
    965		*pll_index = input_pll_index;
    966		return 0;
    967	}
    968
    969	/* retrieve a FW compatible PLL index based on
    970	 * ASIC specific user request
    971	 */
    972	fw_pll_idx = hdev->asic_funcs->map_pll_idx_to_fw_idx(input_pll_index);
    973	if (fw_pll_idx < 0) {
    974		dev_err(hdev->dev, "Invalid PLL index (%u) error %d\n",
    975			input_pll_index, fw_pll_idx);
    976		return -EINVAL;
    977	}
    978
    979	/* PLL map is a u8 array */
    980	pll_byte = prop->cpucp_info.pll_map[fw_pll_idx >> 3];
    981	pll_bit_off = fw_pll_idx & 0x7;
    982
    983	if (!(pll_byte & BIT(pll_bit_off))) {
    984		dev_err(hdev->dev, "PLL index %d is not supported\n",
    985			fw_pll_idx);
    986		return -EINVAL;
    987	}
    988
    989	*pll_index = fw_pll_idx;
    990
    991	return 0;
    992}
    993
    994int hl_fw_cpucp_pll_info_get(struct hl_device *hdev, u32 pll_index,
    995		u16 *pll_freq_arr)
    996{
    997	struct cpucp_packet pkt;
    998	enum pll_index used_pll_idx;
    999	u64 result;
   1000	int rc;
   1001
   1002	rc = get_used_pll_index(hdev, pll_index, &used_pll_idx);
   1003	if (rc)
   1004		return rc;
   1005
   1006	memset(&pkt, 0, sizeof(pkt));
   1007
   1008	pkt.ctl = cpu_to_le32(CPUCP_PACKET_PLL_INFO_GET <<
   1009				CPUCP_PKT_CTL_OPCODE_SHIFT);
   1010	pkt.pll_type = __cpu_to_le16((u16)used_pll_idx);
   1011
   1012	rc = hdev->asic_funcs->send_cpu_message(hdev, (u32 *) &pkt, sizeof(pkt),
   1013			HL_CPUCP_INFO_TIMEOUT_USEC, &result);
   1014	if (rc) {
   1015		dev_err(hdev->dev, "Failed to read PLL info, error %d\n", rc);
   1016		return rc;
   1017	}
   1018
   1019	pll_freq_arr[0] = FIELD_GET(CPUCP_PKT_RES_PLL_OUT0_MASK, result);
   1020	pll_freq_arr[1] = FIELD_GET(CPUCP_PKT_RES_PLL_OUT1_MASK, result);
   1021	pll_freq_arr[2] = FIELD_GET(CPUCP_PKT_RES_PLL_OUT2_MASK, result);
   1022	pll_freq_arr[3] = FIELD_GET(CPUCP_PKT_RES_PLL_OUT3_MASK, result);
   1023
   1024	return 0;
   1025}
   1026
   1027int hl_fw_cpucp_power_get(struct hl_device *hdev, u64 *power)
   1028{
   1029	struct cpucp_packet pkt;
   1030	u64 result;
   1031	int rc;
   1032
   1033	memset(&pkt, 0, sizeof(pkt));
   1034
   1035	pkt.ctl = cpu_to_le32(CPUCP_PACKET_POWER_GET <<
   1036				CPUCP_PKT_CTL_OPCODE_SHIFT);
   1037	pkt.type = cpu_to_le16(CPUCP_POWER_INPUT);
   1038
   1039	rc = hdev->asic_funcs->send_cpu_message(hdev, (u32 *) &pkt, sizeof(pkt),
   1040			HL_CPUCP_INFO_TIMEOUT_USEC, &result);
   1041	if (rc) {
   1042		dev_err(hdev->dev, "Failed to read power, error %d\n", rc);
   1043		return rc;
   1044	}
   1045
   1046	*power = result;
   1047
   1048	return rc;
   1049}
   1050
   1051int hl_fw_dram_replaced_row_get(struct hl_device *hdev,
   1052				struct cpucp_hbm_row_info *info)
   1053{
   1054	struct cpucp_hbm_row_info *cpucp_repl_rows_info_cpu_addr;
   1055	dma_addr_t cpucp_repl_rows_info_dma_addr;
   1056	struct cpucp_packet pkt = {};
   1057	u64 result;
   1058	int rc;
   1059
   1060	cpucp_repl_rows_info_cpu_addr =
   1061			hdev->asic_funcs->cpu_accessible_dma_pool_alloc(hdev,
   1062					sizeof(struct cpucp_hbm_row_info),
   1063					&cpucp_repl_rows_info_dma_addr);
   1064	if (!cpucp_repl_rows_info_cpu_addr) {
   1065		dev_err(hdev->dev,
   1066			"Failed to allocate DMA memory for CPU-CP replaced rows info packet\n");
   1067		return -ENOMEM;
   1068	}
   1069
   1070	memset(cpucp_repl_rows_info_cpu_addr, 0, sizeof(struct cpucp_hbm_row_info));
   1071
   1072	pkt.ctl = cpu_to_le32(CPUCP_PACKET_HBM_REPLACED_ROWS_INFO_GET <<
   1073					CPUCP_PKT_CTL_OPCODE_SHIFT);
   1074	pkt.addr = cpu_to_le64(cpucp_repl_rows_info_dma_addr);
   1075	pkt.data_max_size = cpu_to_le32(sizeof(struct cpucp_hbm_row_info));
   1076
   1077	rc = hdev->asic_funcs->send_cpu_message(hdev, (u32 *) &pkt, sizeof(pkt),
   1078					HL_CPUCP_INFO_TIMEOUT_USEC, &result);
   1079	if (rc) {
   1080		dev_err(hdev->dev,
   1081			"Failed to handle CPU-CP replaced rows info pkt, error %d\n", rc);
   1082		goto out;
   1083	}
   1084
   1085	memcpy(info, cpucp_repl_rows_info_cpu_addr, sizeof(*info));
   1086
   1087out:
   1088	hdev->asic_funcs->cpu_accessible_dma_pool_free(hdev,
   1089					sizeof(struct cpucp_hbm_row_info),
   1090					cpucp_repl_rows_info_cpu_addr);
   1091
   1092	return rc;
   1093}
   1094
   1095int hl_fw_dram_pending_row_get(struct hl_device *hdev, u32 *pend_rows_num)
   1096{
   1097	struct cpucp_packet pkt;
   1098	u64 result;
   1099	int rc;
   1100
   1101	memset(&pkt, 0, sizeof(pkt));
   1102
   1103	pkt.ctl = cpu_to_le32(CPUCP_PACKET_HBM_PENDING_ROWS_STATUS << CPUCP_PKT_CTL_OPCODE_SHIFT);
   1104
   1105	rc = hdev->asic_funcs->send_cpu_message(hdev, (u32 *) &pkt, sizeof(pkt), 0, &result);
   1106	if (rc) {
   1107		dev_err(hdev->dev,
   1108				"Failed to handle CPU-CP pending rows info pkt, error %d\n", rc);
   1109		goto out;
   1110	}
   1111
   1112	*pend_rows_num = (u32) result;
   1113out:
   1114	return rc;
   1115}
   1116
   1117int hl_fw_cpucp_engine_core_asid_set(struct hl_device *hdev, u32 asid)
   1118{
   1119	struct cpucp_packet pkt;
   1120	int rc;
   1121
   1122	memset(&pkt, 0, sizeof(pkt));
   1123
   1124	pkt.ctl = cpu_to_le32(CPUCP_PACKET_ENGINE_CORE_ASID_SET << CPUCP_PKT_CTL_OPCODE_SHIFT);
   1125	pkt.value = cpu_to_le64(asid);
   1126
   1127	rc = hdev->asic_funcs->send_cpu_message(hdev, (u32 *) &pkt, sizeof(pkt),
   1128						HL_CPUCP_INFO_TIMEOUT_USEC, NULL);
   1129	if (rc)
   1130		dev_err(hdev->dev,
   1131			"Failed on ASID configuration request for engine core, error %d\n",
   1132			rc);
   1133
   1134	return rc;
   1135}
   1136
   1137void hl_fw_ask_hard_reset_without_linux(struct hl_device *hdev)
   1138{
   1139	struct static_fw_load_mgr *static_loader =
   1140			&hdev->fw_loader.static_loader;
   1141	int rc;
   1142
   1143	if (hdev->asic_prop.dynamic_fw_load) {
   1144		rc = hl_fw_dynamic_send_protocol_cmd(hdev, &hdev->fw_loader,
   1145				COMMS_RST_DEV, 0, false,
   1146				hdev->fw_loader.cpu_timeout);
   1147		if (rc)
   1148			dev_warn(hdev->dev, "Failed sending COMMS_RST_DEV\n");
   1149	} else {
   1150		WREG32(static_loader->kmd_msg_to_cpu_reg, KMD_MSG_RST_DEV);
   1151	}
   1152}
   1153
   1154void hl_fw_ask_halt_machine_without_linux(struct hl_device *hdev)
   1155{
   1156	struct static_fw_load_mgr *static_loader =
   1157			&hdev->fw_loader.static_loader;
   1158	int rc;
   1159
   1160	if (hdev->device_cpu_is_halted)
   1161		return;
   1162
   1163	/* Stop device CPU to make sure nothing bad happens */
   1164	if (hdev->asic_prop.dynamic_fw_load) {
   1165		rc = hl_fw_dynamic_send_protocol_cmd(hdev, &hdev->fw_loader,
   1166				COMMS_GOTO_WFE, 0, true,
   1167				hdev->fw_loader.cpu_timeout);
   1168		if (rc)
   1169			dev_warn(hdev->dev, "Failed sending COMMS_GOTO_WFE\n");
   1170	} else {
   1171		WREG32(static_loader->kmd_msg_to_cpu_reg, KMD_MSG_GOTO_WFE);
   1172		msleep(static_loader->cpu_reset_wait_msec);
   1173
   1174		/* Must clear this register in order to prevent preboot
   1175		 * from reading WFE after reboot
   1176		 */
   1177		WREG32(static_loader->kmd_msg_to_cpu_reg, KMD_MSG_NA);
   1178	}
   1179
   1180	hdev->device_cpu_is_halted = true;
   1181}
   1182
   1183static void detect_cpu_boot_status(struct hl_device *hdev, u32 status)
   1184{
   1185	/* Some of the status codes below are deprecated in newer f/w
   1186	 * versions but we keep them here for backward compatibility
   1187	 */
   1188	switch (status) {
   1189	case CPU_BOOT_STATUS_NA:
   1190		dev_err(hdev->dev,
   1191			"Device boot progress - BTL/ROM did NOT run\n");
   1192		break;
   1193	case CPU_BOOT_STATUS_IN_WFE:
   1194		dev_err(hdev->dev,
   1195			"Device boot progress - Stuck inside WFE loop\n");
   1196		break;
   1197	case CPU_BOOT_STATUS_IN_BTL:
   1198		dev_err(hdev->dev,
   1199			"Device boot progress - Stuck in BTL\n");
   1200		break;
   1201	case CPU_BOOT_STATUS_IN_PREBOOT:
   1202		dev_err(hdev->dev,
   1203			"Device boot progress - Stuck in Preboot\n");
   1204		break;
   1205	case CPU_BOOT_STATUS_IN_SPL:
   1206		dev_err(hdev->dev,
   1207			"Device boot progress - Stuck in SPL\n");
   1208		break;
   1209	case CPU_BOOT_STATUS_IN_UBOOT:
   1210		dev_err(hdev->dev,
   1211			"Device boot progress - Stuck in u-boot\n");
   1212		break;
   1213	case CPU_BOOT_STATUS_DRAM_INIT_FAIL:
   1214		dev_err(hdev->dev,
   1215			"Device boot progress - DRAM initialization failed\n");
   1216		break;
   1217	case CPU_BOOT_STATUS_UBOOT_NOT_READY:
   1218		dev_err(hdev->dev,
   1219			"Device boot progress - Cannot boot\n");
   1220		break;
   1221	case CPU_BOOT_STATUS_TS_INIT_FAIL:
   1222		dev_err(hdev->dev,
   1223			"Device boot progress - Thermal Sensor initialization failed\n");
   1224		break;
   1225	case CPU_BOOT_STATUS_SECURITY_READY:
   1226		dev_err(hdev->dev,
   1227			"Device boot progress - Stuck in preboot after security initialization\n");
   1228		break;
   1229	default:
   1230		dev_err(hdev->dev,
   1231			"Device boot progress - Invalid status code %d\n",
   1232			status);
   1233		break;
   1234	}
   1235}
   1236
   1237static int hl_fw_read_preboot_caps(struct hl_device *hdev,
   1238					u32 cpu_boot_status_reg,
   1239					u32 sts_boot_dev_sts0_reg,
   1240					u32 sts_boot_dev_sts1_reg,
   1241					u32 boot_err0_reg, u32 boot_err1_reg,
   1242					u32 timeout)
   1243{
   1244	struct asic_fixed_properties *prop = &hdev->asic_prop;
   1245	u32 status, reg_val;
   1246	int rc;
   1247
   1248	/* Need to check two possible scenarios:
   1249	 *
   1250	 * CPU_BOOT_STATUS_WAITING_FOR_BOOT_FIT - for newer firmwares where
   1251	 * the preboot is waiting for the boot fit
   1252	 *
   1253	 * All other status values - for older firmwares where the uboot was
   1254	 * loaded from the FLASH
   1255	 */
   1256	rc = hl_poll_timeout(
   1257		hdev,
   1258		cpu_boot_status_reg,
   1259		status,
   1260		(status == CPU_BOOT_STATUS_NIC_FW_RDY) ||
   1261		(status == CPU_BOOT_STATUS_READY_TO_BOOT) ||
   1262		(status == CPU_BOOT_STATUS_WAITING_FOR_BOOT_FIT),
   1263		hdev->fw_poll_interval_usec,
   1264		timeout);
   1265
   1266	if (rc) {
   1267		dev_err(hdev->dev, "CPU boot ready status timeout\n");
   1268		detect_cpu_boot_status(hdev, status);
   1269
   1270		/* If we read all FF, then something is totally wrong, no point
   1271		 * of reading specific errors
   1272		 */
   1273		if (status != -1)
   1274			fw_read_errors(hdev, boot_err0_reg, boot_err1_reg,
   1275							sts_boot_dev_sts0_reg,
   1276							sts_boot_dev_sts1_reg);
   1277		return -EIO;
   1278	}
   1279
   1280	/*
   1281	 * the registers DEV_STS* contain FW capabilities/features.
   1282	 * We can rely on this registers only if bit CPU_BOOT_DEV_STS*_ENABLED
   1283	 * is set.
   1284	 * In the first read of this register we store the value of this
   1285	 * register ONLY if the register is enabled (which will be propagated
   1286	 * to next stages) and also mark the register as valid.
   1287	 * In case it is not enabled the stored value will be left 0- all
   1288	 * caps/features are off
   1289	 */
   1290	reg_val = RREG32(sts_boot_dev_sts0_reg);
   1291	if (reg_val & CPU_BOOT_DEV_STS0_ENABLED) {
   1292		prop->fw_cpu_boot_dev_sts0_valid = true;
   1293		prop->fw_preboot_cpu_boot_dev_sts0 = reg_val;
   1294	}
   1295
   1296	reg_val = RREG32(sts_boot_dev_sts1_reg);
   1297	if (reg_val & CPU_BOOT_DEV_STS1_ENABLED) {
   1298		prop->fw_cpu_boot_dev_sts1_valid = true;
   1299		prop->fw_preboot_cpu_boot_dev_sts1 = reg_val;
   1300	}
   1301
   1302	prop->dynamic_fw_load = !!(prop->fw_preboot_cpu_boot_dev_sts0 &
   1303						CPU_BOOT_DEV_STS0_FW_LD_COM_EN);
   1304
   1305	/* initialize FW loader once we know what load protocol is used */
   1306	hdev->asic_funcs->init_firmware_loader(hdev);
   1307
   1308	dev_dbg(hdev->dev, "Attempting %s FW load\n",
   1309			prop->dynamic_fw_load ? "dynamic" : "legacy");
   1310	return 0;
   1311}
   1312
   1313static int hl_fw_static_read_device_fw_version(struct hl_device *hdev,
   1314					enum hl_fw_component fwc)
   1315{
   1316	struct asic_fixed_properties *prop = &hdev->asic_prop;
   1317	struct fw_load_mgr *fw_loader = &hdev->fw_loader;
   1318	struct static_fw_load_mgr *static_loader;
   1319	char *dest, *boot_ver, *preboot_ver;
   1320	u32 ver_off, limit;
   1321	const char *name;
   1322	char btl_ver[32];
   1323
   1324	static_loader = &hdev->fw_loader.static_loader;
   1325
   1326	switch (fwc) {
   1327	case FW_COMP_BOOT_FIT:
   1328		ver_off = RREG32(static_loader->boot_fit_version_offset_reg);
   1329		dest = prop->uboot_ver;
   1330		name = "Boot-fit";
   1331		limit = static_loader->boot_fit_version_max_off;
   1332		break;
   1333	case FW_COMP_PREBOOT:
   1334		ver_off = RREG32(static_loader->preboot_version_offset_reg);
   1335		dest = prop->preboot_ver;
   1336		name = "Preboot";
   1337		limit = static_loader->preboot_version_max_off;
   1338		break;
   1339	default:
   1340		dev_warn(hdev->dev, "Undefined FW component: %d\n", fwc);
   1341		return -EIO;
   1342	}
   1343
   1344	ver_off &= static_loader->sram_offset_mask;
   1345
   1346	if (ver_off < limit) {
   1347		memcpy_fromio(dest,
   1348			hdev->pcie_bar[fw_loader->sram_bar_id] + ver_off,
   1349			VERSION_MAX_LEN);
   1350	} else {
   1351		dev_err(hdev->dev, "%s version offset (0x%x) is above SRAM\n",
   1352								name, ver_off);
   1353		strscpy(dest, "unavailable", VERSION_MAX_LEN);
   1354		return -EIO;
   1355	}
   1356
   1357	if (fwc == FW_COMP_BOOT_FIT) {
   1358		boot_ver = extract_fw_ver_from_str(prop->uboot_ver);
   1359		if (boot_ver) {
   1360			dev_info(hdev->dev, "boot-fit version %s\n", boot_ver);
   1361			kfree(boot_ver);
   1362		}
   1363	} else if (fwc == FW_COMP_PREBOOT) {
   1364		preboot_ver = strnstr(prop->preboot_ver, "Preboot",
   1365						VERSION_MAX_LEN);
   1366		if (preboot_ver && preboot_ver != prop->preboot_ver) {
   1367			strscpy(btl_ver, prop->preboot_ver,
   1368				min((int) (preboot_ver - prop->preboot_ver),
   1369									31));
   1370			dev_info(hdev->dev, "%s\n", btl_ver);
   1371		}
   1372
   1373		preboot_ver = extract_fw_ver_from_str(prop->preboot_ver);
   1374		if (preboot_ver) {
   1375			dev_info(hdev->dev, "preboot version %s\n",
   1376								preboot_ver);
   1377			kfree(preboot_ver);
   1378		}
   1379	}
   1380
   1381	return 0;
   1382}
   1383
   1384/**
   1385 * hl_fw_preboot_update_state - update internal data structures during
   1386 *                              handshake with preboot
   1387 *
   1388 *
   1389 * @hdev: pointer to the habanalabs device structure
   1390 *
   1391 * @return 0 on success, otherwise non-zero error code
   1392 */
   1393static void hl_fw_preboot_update_state(struct hl_device *hdev)
   1394{
   1395	struct asic_fixed_properties *prop = &hdev->asic_prop;
   1396	u32 cpu_boot_dev_sts0, cpu_boot_dev_sts1;
   1397
   1398	cpu_boot_dev_sts0 = prop->fw_preboot_cpu_boot_dev_sts0;
   1399	cpu_boot_dev_sts1 = prop->fw_preboot_cpu_boot_dev_sts1;
   1400
   1401	/* We read boot_dev_sts registers multiple times during boot:
   1402	 * 1. preboot - a. Check whether the security status bits are valid
   1403	 *              b. Check whether fw security is enabled
   1404	 *              c. Check whether hard reset is done by preboot
   1405	 * 2. boot cpu - a. Fetch boot cpu security status
   1406	 *               b. Check whether hard reset is done by boot cpu
   1407	 * 3. FW application - a. Fetch fw application security status
   1408	 *                     b. Check whether hard reset is done by fw app
   1409	 */
   1410	prop->hard_reset_done_by_fw = !!(cpu_boot_dev_sts0 & CPU_BOOT_DEV_STS0_FW_HARD_RST_EN);
   1411
   1412	dev_dbg(hdev->dev, "Firmware preboot boot device status0 %#x\n",
   1413							cpu_boot_dev_sts0);
   1414
   1415	dev_dbg(hdev->dev, "Firmware preboot boot device status1 %#x\n",
   1416							cpu_boot_dev_sts1);
   1417
   1418	dev_dbg(hdev->dev, "Firmware preboot hard-reset is %s\n",
   1419			prop->hard_reset_done_by_fw ? "enabled" : "disabled");
   1420
   1421	dev_dbg(hdev->dev, "firmware-level security is %s\n",
   1422			prop->fw_security_enabled ? "enabled" : "disabled");
   1423
   1424	dev_dbg(hdev->dev, "GIC controller is %s\n",
   1425			prop->gic_interrupts_enable ? "enabled" : "disabled");
   1426}
   1427
   1428static int hl_fw_static_read_preboot_status(struct hl_device *hdev)
   1429{
   1430	int rc;
   1431
   1432	rc = hl_fw_static_read_device_fw_version(hdev, FW_COMP_PREBOOT);
   1433	if (rc)
   1434		return rc;
   1435
   1436	return 0;
   1437}
   1438
   1439int hl_fw_read_preboot_status(struct hl_device *hdev, u32 cpu_boot_status_reg,
   1440				u32 sts_boot_dev_sts0_reg,
   1441				u32 sts_boot_dev_sts1_reg, u32 boot_err0_reg,
   1442				u32 boot_err1_reg, u32 timeout)
   1443{
   1444	int rc;
   1445
   1446	if (!(hdev->fw_components & FW_TYPE_PREBOOT_CPU))
   1447		return 0;
   1448
   1449	/*
   1450	 * In order to determine boot method (static VS dymanic) we need to
   1451	 * read the boot caps register
   1452	 */
   1453	rc = hl_fw_read_preboot_caps(hdev, cpu_boot_status_reg,
   1454					sts_boot_dev_sts0_reg,
   1455					sts_boot_dev_sts1_reg, boot_err0_reg,
   1456					boot_err1_reg, timeout);
   1457	if (rc)
   1458		return rc;
   1459
   1460	hl_fw_preboot_update_state(hdev);
   1461
   1462	/* no need to read preboot status in dynamic load */
   1463	if (hdev->asic_prop.dynamic_fw_load)
   1464		return 0;
   1465
   1466	return hl_fw_static_read_preboot_status(hdev);
   1467}
   1468
   1469/* associate string with COMM status */
   1470static char *hl_dynamic_fw_status_str[COMMS_STS_INVLD_LAST] = {
   1471	[COMMS_STS_NOOP] = "NOOP",
   1472	[COMMS_STS_ACK] = "ACK",
   1473	[COMMS_STS_OK] = "OK",
   1474	[COMMS_STS_ERR] = "ERR",
   1475	[COMMS_STS_VALID_ERR] = "VALID_ERR",
   1476	[COMMS_STS_TIMEOUT_ERR] = "TIMEOUT_ERR",
   1477};
   1478
   1479/**
   1480 * hl_fw_dynamic_report_error_status - report error status
   1481 *
   1482 * @hdev: pointer to the habanalabs device structure
   1483 * @status: value of FW status register
   1484 * @expected_status: the expected status
   1485 */
   1486static void hl_fw_dynamic_report_error_status(struct hl_device *hdev,
   1487						u32 status,
   1488						enum comms_sts expected_status)
   1489{
   1490	enum comms_sts comm_status =
   1491				FIELD_GET(COMMS_STATUS_STATUS_MASK, status);
   1492
   1493	if (comm_status < COMMS_STS_INVLD_LAST)
   1494		dev_err(hdev->dev, "Device status %s, expected status: %s\n",
   1495				hl_dynamic_fw_status_str[comm_status],
   1496				hl_dynamic_fw_status_str[expected_status]);
   1497	else
   1498		dev_err(hdev->dev, "Device status unknown %d, expected status: %s\n",
   1499				comm_status,
   1500				hl_dynamic_fw_status_str[expected_status]);
   1501}
   1502
   1503/**
   1504 * hl_fw_dynamic_send_cmd - send LKD to FW cmd
   1505 *
   1506 * @hdev: pointer to the habanalabs device structure
   1507 * @fw_loader: managing structure for loading device's FW
   1508 * @cmd: LKD to FW cmd code
   1509 * @size: size of next FW component to be loaded (0 if not necessary)
   1510 *
   1511 * LDK to FW exact command layout is defined at struct comms_command.
   1512 * note: the size argument is used only when the next FW component should be
   1513 *       loaded, otherwise it shall be 0. the size is used by the FW in later
   1514 *       protocol stages and when sending only indicating the amount of memory
   1515 *       to be allocated by the FW to receive the next boot component.
   1516 */
   1517static void hl_fw_dynamic_send_cmd(struct hl_device *hdev,
   1518				struct fw_load_mgr *fw_loader,
   1519				enum comms_cmd cmd, unsigned int size)
   1520{
   1521	struct cpu_dyn_regs *dyn_regs;
   1522	u32 val;
   1523
   1524	dyn_regs = &fw_loader->dynamic_loader.comm_desc.cpu_dyn_regs;
   1525
   1526	val = FIELD_PREP(COMMS_COMMAND_CMD_MASK, cmd);
   1527	val |= FIELD_PREP(COMMS_COMMAND_SIZE_MASK, size);
   1528
   1529	WREG32(le32_to_cpu(dyn_regs->kmd_msg_to_cpu), val);
   1530}
   1531
   1532/**
   1533 * hl_fw_dynamic_extract_fw_response - update the FW response
   1534 *
   1535 * @hdev: pointer to the habanalabs device structure
   1536 * @fw_loader: managing structure for loading device's FW
   1537 * @response: FW response
   1538 * @status: the status read from CPU status register
   1539 *
   1540 * @return 0 on success, otherwise non-zero error code
   1541 */
   1542static int hl_fw_dynamic_extract_fw_response(struct hl_device *hdev,
   1543						struct fw_load_mgr *fw_loader,
   1544						struct fw_response *response,
   1545						u32 status)
   1546{
   1547	response->status = FIELD_GET(COMMS_STATUS_STATUS_MASK, status);
   1548	response->ram_offset = FIELD_GET(COMMS_STATUS_OFFSET_MASK, status) <<
   1549						COMMS_STATUS_OFFSET_ALIGN_SHIFT;
   1550	response->ram_type = FIELD_GET(COMMS_STATUS_RAM_TYPE_MASK, status);
   1551
   1552	if ((response->ram_type != COMMS_SRAM) &&
   1553					(response->ram_type != COMMS_DRAM)) {
   1554		dev_err(hdev->dev, "FW status: invalid RAM type %u\n",
   1555							response->ram_type);
   1556		return -EIO;
   1557	}
   1558
   1559	return 0;
   1560}
   1561
   1562/**
   1563 * hl_fw_dynamic_wait_for_status - wait for status in dynamic FW load
   1564 *
   1565 * @hdev: pointer to the habanalabs device structure
   1566 * @fw_loader: managing structure for loading device's FW
   1567 * @expected_status: expected status to wait for
   1568 * @timeout: timeout for status wait
   1569 *
   1570 * @return 0 on success, otherwise non-zero error code
   1571 *
   1572 * waiting for status from FW include polling the FW status register until
   1573 * expected status is received or timeout occurs (whatever occurs first).
   1574 */
   1575static int hl_fw_dynamic_wait_for_status(struct hl_device *hdev,
   1576						struct fw_load_mgr *fw_loader,
   1577						enum comms_sts expected_status,
   1578						u32 timeout)
   1579{
   1580	struct cpu_dyn_regs *dyn_regs;
   1581	u32 status;
   1582	int rc;
   1583
   1584	dyn_regs = &fw_loader->dynamic_loader.comm_desc.cpu_dyn_regs;
   1585
   1586	/* Wait for expected status */
   1587	rc = hl_poll_timeout(
   1588		hdev,
   1589		le32_to_cpu(dyn_regs->cpu_cmd_status_to_host),
   1590		status,
   1591		FIELD_GET(COMMS_STATUS_STATUS_MASK, status) == expected_status,
   1592		hdev->fw_comms_poll_interval_usec,
   1593		timeout);
   1594
   1595	if (rc) {
   1596		hl_fw_dynamic_report_error_status(hdev, status,
   1597							expected_status);
   1598		return -EIO;
   1599	}
   1600
   1601	/*
   1602	 * skip storing FW response for NOOP to preserve the actual desired
   1603	 * FW status
   1604	 */
   1605	if (expected_status == COMMS_STS_NOOP)
   1606		return 0;
   1607
   1608	rc = hl_fw_dynamic_extract_fw_response(hdev, fw_loader,
   1609					&fw_loader->dynamic_loader.response,
   1610					status);
   1611	return rc;
   1612}
   1613
   1614/**
   1615 * hl_fw_dynamic_send_clear_cmd - send clear command to FW
   1616 *
   1617 * @hdev: pointer to the habanalabs device structure
   1618 * @fw_loader: managing structure for loading device's FW
   1619 *
   1620 * @return 0 on success, otherwise non-zero error code
   1621 *
   1622 * after command cycle between LKD to FW CPU (i.e. LKD got an expected status
   1623 * from FW) we need to clear the CPU status register in order to avoid garbage
   1624 * between command cycles.
   1625 * This is done by sending clear command and polling the CPU to LKD status
   1626 * register to hold the status NOOP
   1627 */
   1628static int hl_fw_dynamic_send_clear_cmd(struct hl_device *hdev,
   1629						struct fw_load_mgr *fw_loader)
   1630{
   1631	hl_fw_dynamic_send_cmd(hdev, fw_loader, COMMS_CLR_STS, 0);
   1632
   1633	return hl_fw_dynamic_wait_for_status(hdev, fw_loader, COMMS_STS_NOOP,
   1634							fw_loader->cpu_timeout);
   1635}
   1636
   1637/**
   1638 * hl_fw_dynamic_send_protocol_cmd - send LKD to FW cmd and wait for ACK
   1639 *
   1640 * @hdev: pointer to the habanalabs device structure
   1641 * @fw_loader: managing structure for loading device's FW
   1642 * @cmd: LKD to FW cmd code
   1643 * @size: size of next FW component to be loaded (0 if not necessary)
   1644 * @wait_ok: if true also wait for OK response from FW
   1645 * @timeout: timeout for status wait
   1646 *
   1647 * @return 0 on success, otherwise non-zero error code
   1648 *
   1649 * brief:
   1650 * when sending protocol command we have the following steps:
   1651 * - send clear (clear command and verify clear status register)
   1652 * - send the actual protocol command
   1653 * - wait for ACK on the protocol command
   1654 * - send clear
   1655 * - send NOOP
   1656 * if, in addition, the specific protocol command should wait for OK then:
   1657 * - wait for OK
   1658 * - send clear
   1659 * - send NOOP
   1660 *
   1661 * NOTES:
   1662 * send clear: this is necessary in order to clear the status register to avoid
   1663 *             leftovers between command
   1664 * NOOP command: necessary to avoid loop on the clear command by the FW
   1665 */
   1666int hl_fw_dynamic_send_protocol_cmd(struct hl_device *hdev,
   1667				struct fw_load_mgr *fw_loader,
   1668				enum comms_cmd cmd, unsigned int size,
   1669				bool wait_ok, u32 timeout)
   1670{
   1671	int rc;
   1672
   1673	/* first send clear command to clean former commands */
   1674	rc = hl_fw_dynamic_send_clear_cmd(hdev, fw_loader);
   1675
   1676	/* send the actual command */
   1677	hl_fw_dynamic_send_cmd(hdev, fw_loader, cmd, size);
   1678
   1679	/* wait for ACK for the command */
   1680	rc = hl_fw_dynamic_wait_for_status(hdev, fw_loader, COMMS_STS_ACK,
   1681								timeout);
   1682	if (rc)
   1683		return rc;
   1684
   1685	/* clear command to prepare for NOOP command */
   1686	rc = hl_fw_dynamic_send_clear_cmd(hdev, fw_loader);
   1687	if (rc)
   1688		return rc;
   1689
   1690	/* send the actual NOOP command */
   1691	hl_fw_dynamic_send_cmd(hdev, fw_loader, COMMS_NOOP, 0);
   1692
   1693	if (!wait_ok)
   1694		return 0;
   1695
   1696	rc = hl_fw_dynamic_wait_for_status(hdev, fw_loader, COMMS_STS_OK,
   1697								timeout);
   1698	if (rc)
   1699		return rc;
   1700
   1701	/* clear command to prepare for NOOP command */
   1702	rc = hl_fw_dynamic_send_clear_cmd(hdev, fw_loader);
   1703	if (rc)
   1704		return rc;
   1705
   1706	/* send the actual NOOP command */
   1707	hl_fw_dynamic_send_cmd(hdev, fw_loader, COMMS_NOOP, 0);
   1708
   1709	return 0;
   1710}
   1711
   1712/**
   1713 * hl_fw_compat_crc32 - CRC compatible with FW
   1714 *
   1715 * @data: pointer to the data
   1716 * @size: size of the data
   1717 *
   1718 * @return the CRC32 result
   1719 *
   1720 * NOTE: kernel's CRC32 differ's from standard CRC32 calculation.
   1721 *       in order to be aligned we need to flip the bits of both the input
   1722 *       initial CRC and kernel's CRC32 result.
   1723 *       in addition both sides use initial CRC of 0,
   1724 */
   1725static u32 hl_fw_compat_crc32(u8 *data, size_t size)
   1726{
   1727	return ~crc32_le(~((u32)0), data, size);
   1728}
   1729
   1730/**
   1731 * hl_fw_dynamic_validate_memory_bound - validate memory bounds for memory
   1732 *                                        transfer (image or descriptor) between
   1733 *                                        host and FW
   1734 *
   1735 * @hdev: pointer to the habanalabs device structure
   1736 * @addr: device address of memory transfer
   1737 * @size: memory transter size
   1738 * @region: PCI memory region
   1739 *
   1740 * @return 0 on success, otherwise non-zero error code
   1741 */
   1742static int hl_fw_dynamic_validate_memory_bound(struct hl_device *hdev,
   1743						u64 addr, size_t size,
   1744						struct pci_mem_region *region)
   1745{
   1746	u64 end_addr;
   1747
   1748	/* now make sure that the memory transfer is within region's bounds */
   1749	end_addr = addr + size;
   1750	if (end_addr >= region->region_base + region->region_size) {
   1751		dev_err(hdev->dev,
   1752			"dynamic FW load: memory transfer end address out of memory region bounds. addr: %llx\n",
   1753							end_addr);
   1754		return -EIO;
   1755	}
   1756
   1757	/*
   1758	 * now make sure memory transfer is within predefined BAR bounds.
   1759	 * this is to make sure we do not need to set the bar (e.g. for DRAM
   1760	 * memory transfers)
   1761	 */
   1762	if (end_addr >= region->region_base - region->offset_in_bar +
   1763							region->bar_size) {
   1764		dev_err(hdev->dev,
   1765			"FW image beyond PCI BAR bounds\n");
   1766		return -EIO;
   1767	}
   1768
   1769	return 0;
   1770}
   1771
   1772/**
   1773 * hl_fw_dynamic_validate_descriptor - validate FW descriptor
   1774 *
   1775 * @hdev: pointer to the habanalabs device structure
   1776 * @fw_loader: managing structure for loading device's FW
   1777 * @fw_desc: the descriptor form FW
   1778 *
   1779 * @return 0 on success, otherwise non-zero error code
   1780 */
   1781static int hl_fw_dynamic_validate_descriptor(struct hl_device *hdev,
   1782					struct fw_load_mgr *fw_loader,
   1783					struct lkd_fw_comms_desc *fw_desc)
   1784{
   1785	struct pci_mem_region *region;
   1786	enum pci_region region_id;
   1787	size_t data_size;
   1788	u32 data_crc32;
   1789	u8 *data_ptr;
   1790	u64 addr;
   1791	int rc;
   1792
   1793	if (le32_to_cpu(fw_desc->header.magic) != HL_COMMS_DESC_MAGIC) {
   1794		dev_err(hdev->dev, "Invalid magic for dynamic FW descriptor (%x)\n",
   1795				fw_desc->header.magic);
   1796		return -EIO;
   1797	}
   1798
   1799	if (fw_desc->header.version != HL_COMMS_DESC_VER) {
   1800		dev_err(hdev->dev, "Invalid version for dynamic FW descriptor (%x)\n",
   1801				fw_desc->header.version);
   1802		return -EIO;
   1803	}
   1804
   1805	/*
   1806	 * calc CRC32 of data without header.
   1807	 * note that no alignment/stride address issues here as all structures
   1808	 * are 64 bit padded
   1809	 */
   1810	data_size = sizeof(struct lkd_fw_comms_desc) -
   1811					sizeof(struct comms_desc_header);
   1812	data_ptr = (u8 *)fw_desc + sizeof(struct comms_desc_header);
   1813
   1814	if (le16_to_cpu(fw_desc->header.size) != data_size) {
   1815		dev_err(hdev->dev,
   1816			"Invalid descriptor size 0x%x, expected size 0x%zx\n",
   1817				le16_to_cpu(fw_desc->header.size), data_size);
   1818		return -EIO;
   1819	}
   1820
   1821	data_crc32 = hl_fw_compat_crc32(data_ptr, data_size);
   1822
   1823	if (data_crc32 != le32_to_cpu(fw_desc->header.crc32)) {
   1824		dev_err(hdev->dev,
   1825			"CRC32 mismatch for dynamic FW descriptor (%x:%x)\n",
   1826					data_crc32, fw_desc->header.crc32);
   1827		return -EIO;
   1828	}
   1829
   1830	/* find memory region to which to copy the image */
   1831	addr = le64_to_cpu(fw_desc->img_addr);
   1832	region_id = hl_get_pci_memory_region(hdev, addr);
   1833	if ((region_id != PCI_REGION_SRAM) &&
   1834			((region_id != PCI_REGION_DRAM))) {
   1835		dev_err(hdev->dev,
   1836			"Invalid region to copy FW image address=%llx\n", addr);
   1837		return -EIO;
   1838	}
   1839
   1840	region = &hdev->pci_mem_region[region_id];
   1841
   1842	/* store the region for the copy stage */
   1843	fw_loader->dynamic_loader.image_region = region;
   1844
   1845	/*
   1846	 * here we know that the start address is valid, now make sure that the
   1847	 * image is within region's bounds
   1848	 */
   1849	rc = hl_fw_dynamic_validate_memory_bound(hdev, addr,
   1850					fw_loader->dynamic_loader.fw_image_size,
   1851					region);
   1852	if (rc) {
   1853		dev_err(hdev->dev,
   1854			"invalid mem transfer request for FW image\n");
   1855		return rc;
   1856	}
   1857
   1858	/* here we can mark the descriptor as valid as the content has been validated */
   1859	fw_loader->dynamic_loader.fw_desc_valid = true;
   1860
   1861	return 0;
   1862}
   1863
   1864static int hl_fw_dynamic_validate_response(struct hl_device *hdev,
   1865						struct fw_response *response,
   1866						struct pci_mem_region *region)
   1867{
   1868	u64 device_addr;
   1869	int rc;
   1870
   1871	device_addr = region->region_base + response->ram_offset;
   1872
   1873	/*
   1874	 * validate that the descriptor is within region's bounds
   1875	 * Note that as the start address was supplied according to the RAM
   1876	 * type- testing only the end address is enough
   1877	 */
   1878	rc = hl_fw_dynamic_validate_memory_bound(hdev, device_addr,
   1879					sizeof(struct lkd_fw_comms_desc),
   1880					region);
   1881	return rc;
   1882}
   1883
   1884/**
   1885 * hl_fw_dynamic_read_and_validate_descriptor - read and validate FW descriptor
   1886 *
   1887 * @hdev: pointer to the habanalabs device structure
   1888 * @fw_loader: managing structure for loading device's FW
   1889 *
   1890 * @return 0 on success, otherwise non-zero error code
   1891 */
   1892static int hl_fw_dynamic_read_and_validate_descriptor(struct hl_device *hdev,
   1893						struct fw_load_mgr *fw_loader)
   1894{
   1895	struct lkd_fw_comms_desc *fw_desc;
   1896	struct pci_mem_region *region;
   1897	struct fw_response *response;
   1898	enum pci_region region_id;
   1899	void __iomem *src;
   1900	int rc;
   1901
   1902	fw_desc = &fw_loader->dynamic_loader.comm_desc;
   1903	response = &fw_loader->dynamic_loader.response;
   1904
   1905	region_id = (response->ram_type == COMMS_SRAM) ?
   1906					PCI_REGION_SRAM : PCI_REGION_DRAM;
   1907
   1908	region = &hdev->pci_mem_region[region_id];
   1909
   1910	rc = hl_fw_dynamic_validate_response(hdev, response, region);
   1911	if (rc) {
   1912		dev_err(hdev->dev,
   1913			"invalid mem transfer request for FW descriptor\n");
   1914		return rc;
   1915	}
   1916
   1917	/*
   1918	 * extract address to copy the descriptor from
   1919	 * in addition, as the descriptor value is going to be over-ridden by new data- we mark it
   1920	 * as invalid.
   1921	 * it will be marked again as valid once validated
   1922	 */
   1923	fw_loader->dynamic_loader.fw_desc_valid = false;
   1924	src = hdev->pcie_bar[region->bar_id] + region->offset_in_bar +
   1925							response->ram_offset;
   1926	memcpy_fromio(fw_desc, src, sizeof(struct lkd_fw_comms_desc));
   1927
   1928	return hl_fw_dynamic_validate_descriptor(hdev, fw_loader, fw_desc);
   1929}
   1930
   1931/**
   1932 * hl_fw_dynamic_request_descriptor - handshake with CPU to get FW descriptor
   1933 *
   1934 * @hdev: pointer to the habanalabs device structure
   1935 * @fw_loader: managing structure for loading device's FW
   1936 * @next_image_size: size to allocate for next FW component
   1937 *
   1938 * @return 0 on success, otherwise non-zero error code
   1939 */
   1940static int hl_fw_dynamic_request_descriptor(struct hl_device *hdev,
   1941						struct fw_load_mgr *fw_loader,
   1942						size_t next_image_size)
   1943{
   1944	int rc;
   1945
   1946	rc = hl_fw_dynamic_send_protocol_cmd(hdev, fw_loader, COMMS_PREP_DESC,
   1947						next_image_size, true,
   1948						fw_loader->cpu_timeout);
   1949	if (rc)
   1950		return rc;
   1951
   1952	return hl_fw_dynamic_read_and_validate_descriptor(hdev, fw_loader);
   1953}
   1954
   1955/**
   1956 * hl_fw_dynamic_read_device_fw_version - read FW version to exposed properties
   1957 *
   1958 * @hdev: pointer to the habanalabs device structure
   1959 * @fwc: the firmware component
   1960 * @fw_version: fw component's version string
   1961 */
   1962static int hl_fw_dynamic_read_device_fw_version(struct hl_device *hdev,
   1963					enum hl_fw_component fwc,
   1964					const char *fw_version)
   1965{
   1966	struct asic_fixed_properties *prop = &hdev->asic_prop;
   1967	char *preboot_ver, *boot_ver;
   1968	char btl_ver[32];
   1969
   1970	switch (fwc) {
   1971	case FW_COMP_BOOT_FIT:
   1972		strscpy(prop->uboot_ver, fw_version, VERSION_MAX_LEN);
   1973		boot_ver = extract_fw_ver_from_str(prop->uboot_ver);
   1974		if (boot_ver) {
   1975			dev_info(hdev->dev, "boot-fit version %s\n", boot_ver);
   1976			kfree(boot_ver);
   1977		}
   1978
   1979		break;
   1980	case FW_COMP_PREBOOT:
   1981		strscpy(prop->preboot_ver, fw_version, VERSION_MAX_LEN);
   1982		preboot_ver = strnstr(prop->preboot_ver, "Preboot",
   1983						VERSION_MAX_LEN);
   1984		if (preboot_ver && preboot_ver != prop->preboot_ver) {
   1985			strscpy(btl_ver, prop->preboot_ver,
   1986				min((int) (preboot_ver - prop->preboot_ver), 31));
   1987			dev_info(hdev->dev, "%s\n", btl_ver);
   1988		}
   1989
   1990		preboot_ver = extract_fw_ver_from_str(prop->preboot_ver);
   1991		if (preboot_ver) {
   1992			char major[8];
   1993			int rc;
   1994
   1995			dev_info(hdev->dev, "preboot version %s\n", preboot_ver);
   1996			sprintf(major, "%.2s", preboot_ver);
   1997			kfree(preboot_ver);
   1998
   1999			rc = kstrtou32(major, 10, &hdev->fw_major_version);
   2000			if (rc) {
   2001				dev_err(hdev->dev, "Error %d parsing preboot major version\n", rc);
   2002				return rc;
   2003			}
   2004		}
   2005
   2006		break;
   2007	default:
   2008		dev_warn(hdev->dev, "Undefined FW component: %d\n", fwc);
   2009		return -EINVAL;
   2010	}
   2011
   2012	return 0;
   2013}
   2014
   2015/**
   2016 * hl_fw_dynamic_copy_image - copy image to memory allocated by the FW
   2017 *
   2018 * @hdev: pointer to the habanalabs device structure
   2019 * @fw: fw descriptor
   2020 * @fw_loader: managing structure for loading device's FW
   2021 */
   2022static int hl_fw_dynamic_copy_image(struct hl_device *hdev,
   2023						const struct firmware *fw,
   2024						struct fw_load_mgr *fw_loader)
   2025{
   2026	struct lkd_fw_comms_desc *fw_desc;
   2027	struct pci_mem_region *region;
   2028	void __iomem *dest;
   2029	u64 addr;
   2030	int rc;
   2031
   2032	fw_desc = &fw_loader->dynamic_loader.comm_desc;
   2033	addr = le64_to_cpu(fw_desc->img_addr);
   2034
   2035	/* find memory region to which to copy the image */
   2036	region = fw_loader->dynamic_loader.image_region;
   2037
   2038	dest = hdev->pcie_bar[region->bar_id] + region->offset_in_bar +
   2039					(addr - region->region_base);
   2040
   2041	rc = hl_fw_copy_fw_to_device(hdev, fw, dest,
   2042					fw_loader->boot_fit_img.src_off,
   2043					fw_loader->boot_fit_img.copy_size);
   2044
   2045	return rc;
   2046}
   2047
   2048/**
   2049 * hl_fw_dynamic_copy_msg - copy msg to memory allocated by the FW
   2050 *
   2051 * @hdev: pointer to the habanalabs device structure
   2052 * @msg: message
   2053 * @fw_loader: managing structure for loading device's FW
   2054 */
   2055static int hl_fw_dynamic_copy_msg(struct hl_device *hdev,
   2056		struct lkd_msg_comms *msg, struct fw_load_mgr *fw_loader)
   2057{
   2058	struct lkd_fw_comms_desc *fw_desc;
   2059	struct pci_mem_region *region;
   2060	void __iomem *dest;
   2061	u64 addr;
   2062	int rc;
   2063
   2064	fw_desc = &fw_loader->dynamic_loader.comm_desc;
   2065	addr = le64_to_cpu(fw_desc->img_addr);
   2066
   2067	/* find memory region to which to copy the image */
   2068	region = fw_loader->dynamic_loader.image_region;
   2069
   2070	dest = hdev->pcie_bar[region->bar_id] + region->offset_in_bar +
   2071					(addr - region->region_base);
   2072
   2073	rc = hl_fw_copy_msg_to_device(hdev, msg, dest, 0, 0);
   2074
   2075	return rc;
   2076}
   2077
   2078/**
   2079 * hl_fw_boot_fit_update_state - update internal data structures after boot-fit
   2080 *                               is loaded
   2081 *
   2082 * @hdev: pointer to the habanalabs device structure
   2083 * @cpu_boot_dev_sts0_reg: register holding CPU boot dev status 0
   2084 * @cpu_boot_dev_sts1_reg: register holding CPU boot dev status 1
   2085 *
   2086 * @return 0 on success, otherwise non-zero error code
   2087 */
   2088static void hl_fw_boot_fit_update_state(struct hl_device *hdev,
   2089						u32 cpu_boot_dev_sts0_reg,
   2090						u32 cpu_boot_dev_sts1_reg)
   2091{
   2092	struct asic_fixed_properties *prop = &hdev->asic_prop;
   2093
   2094	hdev->fw_loader.fw_comp_loaded |= FW_TYPE_BOOT_CPU;
   2095
   2096	/* Read boot_cpu status bits */
   2097	if (prop->fw_preboot_cpu_boot_dev_sts0 & CPU_BOOT_DEV_STS0_ENABLED) {
   2098		prop->fw_bootfit_cpu_boot_dev_sts0 =
   2099				RREG32(cpu_boot_dev_sts0_reg);
   2100
   2101		prop->hard_reset_done_by_fw = !!(prop->fw_bootfit_cpu_boot_dev_sts0 &
   2102							CPU_BOOT_DEV_STS0_FW_HARD_RST_EN);
   2103
   2104		dev_dbg(hdev->dev, "Firmware boot CPU status0 %#x\n",
   2105					prop->fw_bootfit_cpu_boot_dev_sts0);
   2106	}
   2107
   2108	if (prop->fw_cpu_boot_dev_sts1_valid) {
   2109		prop->fw_bootfit_cpu_boot_dev_sts1 =
   2110				RREG32(cpu_boot_dev_sts1_reg);
   2111
   2112		dev_dbg(hdev->dev, "Firmware boot CPU status1 %#x\n",
   2113					prop->fw_bootfit_cpu_boot_dev_sts1);
   2114	}
   2115
   2116	dev_dbg(hdev->dev, "Firmware boot CPU hard-reset is %s\n",
   2117			prop->hard_reset_done_by_fw ? "enabled" : "disabled");
   2118}
   2119
   2120static void hl_fw_dynamic_update_linux_interrupt_if(struct hl_device *hdev)
   2121{
   2122	struct cpu_dyn_regs *dyn_regs =
   2123			&hdev->fw_loader.dynamic_loader.comm_desc.cpu_dyn_regs;
   2124
   2125	/* Check whether all 3 interrupt interfaces are set, if not use a
   2126	 * single interface
   2127	 */
   2128	if (!hdev->asic_prop.gic_interrupts_enable &&
   2129			!(hdev->asic_prop.fw_app_cpu_boot_dev_sts0 &
   2130				CPU_BOOT_DEV_STS0_MULTI_IRQ_POLL_EN)) {
   2131		dyn_regs->gic_host_halt_irq = dyn_regs->gic_host_pi_upd_irq;
   2132		dyn_regs->gic_host_ints_irq = dyn_regs->gic_host_pi_upd_irq;
   2133
   2134		dev_warn(hdev->dev,
   2135			"Using a single interrupt interface towards cpucp");
   2136	}
   2137}
   2138/**
   2139 * hl_fw_dynamic_load_image - load FW image using dynamic protocol
   2140 *
   2141 * @hdev: pointer to the habanalabs device structure
   2142 * @fw_loader: managing structure for loading device's FW
   2143 * @load_fwc: the FW component to be loaded
   2144 * @img_ld_timeout: image load timeout
   2145 *
   2146 * @return 0 on success, otherwise non-zero error code
   2147 */
   2148static int hl_fw_dynamic_load_image(struct hl_device *hdev,
   2149						struct fw_load_mgr *fw_loader,
   2150						enum hl_fw_component load_fwc,
   2151						u32 img_ld_timeout)
   2152{
   2153	enum hl_fw_component cur_fwc;
   2154	const struct firmware *fw;
   2155	char *fw_name;
   2156	int rc = 0;
   2157
   2158	/*
   2159	 * when loading image we have one of 2 scenarios:
   2160	 * 1. current FW component is preboot and we want to load boot-fit
   2161	 * 2. current FW component is boot-fit and we want to load linux
   2162	 */
   2163	if (load_fwc == FW_COMP_BOOT_FIT) {
   2164		cur_fwc = FW_COMP_PREBOOT;
   2165		fw_name = fw_loader->boot_fit_img.image_name;
   2166	} else {
   2167		cur_fwc = FW_COMP_BOOT_FIT;
   2168		fw_name = fw_loader->linux_img.image_name;
   2169	}
   2170
   2171	/* request FW in order to communicate to FW the size to be allocated */
   2172	rc = hl_request_fw(hdev, &fw, fw_name);
   2173	if (rc)
   2174		return rc;
   2175
   2176	/* store the image size for future validation */
   2177	fw_loader->dynamic_loader.fw_image_size = fw->size;
   2178
   2179	rc = hl_fw_dynamic_request_descriptor(hdev, fw_loader, fw->size);
   2180	if (rc)
   2181		goto release_fw;
   2182
   2183	/* read preboot version */
   2184	rc = hl_fw_dynamic_read_device_fw_version(hdev, cur_fwc,
   2185				fw_loader->dynamic_loader.comm_desc.cur_fw_ver);
   2186	if (rc)
   2187		goto release_fw;
   2188
   2189	/* update state according to boot stage */
   2190	if (cur_fwc == FW_COMP_BOOT_FIT) {
   2191		struct cpu_dyn_regs *dyn_regs;
   2192
   2193		dyn_regs = &fw_loader->dynamic_loader.comm_desc.cpu_dyn_regs;
   2194		hl_fw_boot_fit_update_state(hdev,
   2195				le32_to_cpu(dyn_regs->cpu_boot_dev_sts0),
   2196				le32_to_cpu(dyn_regs->cpu_boot_dev_sts1));
   2197	}
   2198
   2199	/* copy boot fit to space allocated by FW */
   2200	rc = hl_fw_dynamic_copy_image(hdev, fw, fw_loader);
   2201	if (rc)
   2202		goto release_fw;
   2203
   2204	rc = hl_fw_dynamic_send_protocol_cmd(hdev, fw_loader, COMMS_DATA_RDY,
   2205						0, true,
   2206						fw_loader->cpu_timeout);
   2207	if (rc)
   2208		goto release_fw;
   2209
   2210	rc = hl_fw_dynamic_send_protocol_cmd(hdev, fw_loader, COMMS_EXEC,
   2211						0, false,
   2212						img_ld_timeout);
   2213
   2214release_fw:
   2215	hl_release_firmware(fw);
   2216	return rc;
   2217}
   2218
   2219static int hl_fw_dynamic_wait_for_boot_fit_active(struct hl_device *hdev,
   2220					struct fw_load_mgr *fw_loader)
   2221{
   2222	struct dynamic_fw_load_mgr *dyn_loader;
   2223	u32 status;
   2224	int rc;
   2225
   2226	dyn_loader = &fw_loader->dynamic_loader;
   2227
   2228	/*
   2229	 * Make sure CPU boot-loader is running
   2230	 * Note that the CPU_BOOT_STATUS_SRAM_AVAIL is generally set by Linux
   2231	 * yet there is a debug scenario in which we loading uboot (without Linux)
   2232	 * which at later stage is relocated to DRAM. In this case we expect
   2233	 * uboot to set the CPU_BOOT_STATUS_SRAM_AVAIL and so we add it to the
   2234	 * poll flags
   2235	 */
   2236	rc = hl_poll_timeout(
   2237		hdev,
   2238		le32_to_cpu(dyn_loader->comm_desc.cpu_dyn_regs.cpu_boot_status),
   2239		status,
   2240		(status == CPU_BOOT_STATUS_READY_TO_BOOT) ||
   2241		(status == CPU_BOOT_STATUS_SRAM_AVAIL),
   2242		hdev->fw_poll_interval_usec,
   2243		dyn_loader->wait_for_bl_timeout);
   2244	if (rc) {
   2245		dev_err(hdev->dev, "failed to wait for boot\n");
   2246		return rc;
   2247	}
   2248
   2249	dev_dbg(hdev->dev, "uboot status = %d\n", status);
   2250	return 0;
   2251}
   2252
   2253static int hl_fw_dynamic_wait_for_linux_active(struct hl_device *hdev,
   2254						struct fw_load_mgr *fw_loader)
   2255{
   2256	struct dynamic_fw_load_mgr *dyn_loader;
   2257	u32 status;
   2258	int rc;
   2259
   2260	dyn_loader = &fw_loader->dynamic_loader;
   2261
   2262	/* Make sure CPU linux is running */
   2263
   2264	rc = hl_poll_timeout(
   2265		hdev,
   2266		le32_to_cpu(dyn_loader->comm_desc.cpu_dyn_regs.cpu_boot_status),
   2267		status,
   2268		(status == CPU_BOOT_STATUS_SRAM_AVAIL),
   2269		hdev->fw_poll_interval_usec,
   2270		fw_loader->cpu_timeout);
   2271	if (rc) {
   2272		dev_err(hdev->dev, "failed to wait for Linux\n");
   2273		return rc;
   2274	}
   2275
   2276	dev_dbg(hdev->dev, "Boot status = %d\n", status);
   2277	return 0;
   2278}
   2279
   2280/**
   2281 * hl_fw_linux_update_state -	update internal data structures after Linux
   2282 *				is loaded.
   2283 *				Note: Linux initialization is comprised mainly
   2284 *				of two stages - loading kernel (SRAM_AVAIL)
   2285 *				& loading ARMCP.
   2286 *				Therefore reading boot device status in any of
   2287 *				these stages might result in different values.
   2288 *
   2289 * @hdev: pointer to the habanalabs device structure
   2290 * @cpu_boot_dev_sts0_reg: register holding CPU boot dev status 0
   2291 * @cpu_boot_dev_sts1_reg: register holding CPU boot dev status 1
   2292 *
   2293 * @return 0 on success, otherwise non-zero error code
   2294 */
   2295static void hl_fw_linux_update_state(struct hl_device *hdev,
   2296						u32 cpu_boot_dev_sts0_reg,
   2297						u32 cpu_boot_dev_sts1_reg)
   2298{
   2299	struct asic_fixed_properties *prop = &hdev->asic_prop;
   2300
   2301	hdev->fw_loader.fw_comp_loaded |= FW_TYPE_LINUX;
   2302
   2303	/* Read FW application security bits */
   2304	if (prop->fw_cpu_boot_dev_sts0_valid) {
   2305		prop->fw_app_cpu_boot_dev_sts0 = RREG32(cpu_boot_dev_sts0_reg);
   2306
   2307		prop->hard_reset_done_by_fw = !!(prop->fw_app_cpu_boot_dev_sts0 &
   2308							CPU_BOOT_DEV_STS0_FW_HARD_RST_EN);
   2309
   2310		if (prop->fw_app_cpu_boot_dev_sts0 &
   2311				CPU_BOOT_DEV_STS0_GIC_PRIVILEGED_EN)
   2312			prop->gic_interrupts_enable = false;
   2313
   2314		dev_dbg(hdev->dev,
   2315			"Firmware application CPU status0 %#x\n",
   2316			prop->fw_app_cpu_boot_dev_sts0);
   2317
   2318		dev_dbg(hdev->dev, "GIC controller is %s\n",
   2319				prop->gic_interrupts_enable ?
   2320						"enabled" : "disabled");
   2321	}
   2322
   2323	if (prop->fw_cpu_boot_dev_sts1_valid) {
   2324		prop->fw_app_cpu_boot_dev_sts1 = RREG32(cpu_boot_dev_sts1_reg);
   2325
   2326		dev_dbg(hdev->dev,
   2327			"Firmware application CPU status1 %#x\n",
   2328			prop->fw_app_cpu_boot_dev_sts1);
   2329	}
   2330
   2331	dev_dbg(hdev->dev, "Firmware application CPU hard-reset is %s\n",
   2332			prop->hard_reset_done_by_fw ? "enabled" : "disabled");
   2333
   2334	dev_info(hdev->dev, "Successfully loaded firmware to device\n");
   2335}
   2336
   2337/**
   2338 * hl_fw_dynamic_send_msg - send a COMMS message with attached data
   2339 *
   2340 * @hdev: pointer to the habanalabs device structure
   2341 * @fw_loader: managing structure for loading device's FW
   2342 * @msg_type: message type
   2343 * @data: data to be sent
   2344 *
   2345 * @return 0 on success, otherwise non-zero error code
   2346 */
   2347static int hl_fw_dynamic_send_msg(struct hl_device *hdev,
   2348		struct fw_load_mgr *fw_loader, u8 msg_type, void *data)
   2349{
   2350	struct lkd_msg_comms msg;
   2351	int rc;
   2352
   2353	memset(&msg, 0, sizeof(msg));
   2354
   2355	/* create message to be sent */
   2356	msg.header.type = msg_type;
   2357	msg.header.size = cpu_to_le16(sizeof(struct comms_msg_header));
   2358	msg.header.magic = cpu_to_le32(HL_COMMS_MSG_MAGIC);
   2359
   2360	switch (msg_type) {
   2361	case HL_COMMS_RESET_CAUSE_TYPE:
   2362		msg.reset_cause = *(__u8 *) data;
   2363		break;
   2364	default:
   2365		dev_err(hdev->dev,
   2366			"Send COMMS message - invalid message type %u\n",
   2367			msg_type);
   2368		return -EINVAL;
   2369	}
   2370
   2371	rc = hl_fw_dynamic_request_descriptor(hdev, fw_loader,
   2372			sizeof(struct lkd_msg_comms));
   2373	if (rc)
   2374		return rc;
   2375
   2376	/* copy message to space allocated by FW */
   2377	rc = hl_fw_dynamic_copy_msg(hdev, &msg, fw_loader);
   2378	if (rc)
   2379		return rc;
   2380
   2381	rc = hl_fw_dynamic_send_protocol_cmd(hdev, fw_loader, COMMS_DATA_RDY,
   2382						0, true,
   2383						fw_loader->cpu_timeout);
   2384	if (rc)
   2385		return rc;
   2386
   2387	rc = hl_fw_dynamic_send_protocol_cmd(hdev, fw_loader, COMMS_EXEC,
   2388						0, true,
   2389						fw_loader->cpu_timeout);
   2390	if (rc)
   2391		return rc;
   2392
   2393	return 0;
   2394}
   2395
   2396/**
   2397 * hl_fw_dynamic_init_cpu - initialize the device CPU using dynamic protocol
   2398 *
   2399 * @hdev: pointer to the habanalabs device structure
   2400 * @fw_loader: managing structure for loading device's FW
   2401 *
   2402 * @return 0 on success, otherwise non-zero error code
   2403 *
   2404 * brief: the dynamic protocol is master (LKD) slave (FW CPU) protocol.
   2405 * the communication is done using registers:
   2406 * - LKD command register
   2407 * - FW status register
   2408 * the protocol is race free. this goal is achieved by splitting the requests
   2409 * and response to known synchronization points between the LKD and the FW.
   2410 * each response to LKD request is known and bound to a predefined timeout.
   2411 * in case of timeout expiration without the desired status from FW- the
   2412 * protocol (and hence the boot) will fail.
   2413 */
   2414static int hl_fw_dynamic_init_cpu(struct hl_device *hdev,
   2415					struct fw_load_mgr *fw_loader)
   2416{
   2417	struct cpu_dyn_regs *dyn_regs;
   2418	int rc;
   2419
   2420	dev_info(hdev->dev,
   2421		"Loading firmware to device, may take some time...\n");
   2422
   2423	/* initialize FW descriptor as invalid */
   2424	fw_loader->dynamic_loader.fw_desc_valid = false;
   2425
   2426	/*
   2427	 * In this stage, "cpu_dyn_regs" contains only LKD's hard coded values!
   2428	 * It will be updated from FW after hl_fw_dynamic_request_descriptor().
   2429	 */
   2430	dyn_regs = &fw_loader->dynamic_loader.comm_desc.cpu_dyn_regs;
   2431
   2432	rc = hl_fw_dynamic_send_protocol_cmd(hdev, fw_loader, COMMS_RST_STATE,
   2433						0, true,
   2434						fw_loader->cpu_timeout);
   2435	if (rc)
   2436		goto protocol_err;
   2437
   2438	if (hdev->reset_info.curr_reset_cause) {
   2439		rc = hl_fw_dynamic_send_msg(hdev, fw_loader,
   2440				HL_COMMS_RESET_CAUSE_TYPE, &hdev->reset_info.curr_reset_cause);
   2441		if (rc)
   2442			goto protocol_err;
   2443
   2444		/* Clear current reset cause */
   2445		hdev->reset_info.curr_reset_cause = HL_RESET_CAUSE_UNKNOWN;
   2446	}
   2447
   2448	if (!(hdev->fw_components & FW_TYPE_BOOT_CPU)) {
   2449		rc = hl_fw_dynamic_request_descriptor(hdev, fw_loader, 0);
   2450		if (rc)
   2451			goto protocol_err;
   2452
   2453		/* read preboot version */
   2454		return hl_fw_dynamic_read_device_fw_version(hdev, FW_COMP_PREBOOT,
   2455				fw_loader->dynamic_loader.comm_desc.cur_fw_ver);
   2456	}
   2457
   2458	/* load boot fit to FW */
   2459	rc = hl_fw_dynamic_load_image(hdev, fw_loader, FW_COMP_BOOT_FIT,
   2460						fw_loader->boot_fit_timeout);
   2461	if (rc) {
   2462		dev_err(hdev->dev, "failed to load boot fit\n");
   2463		goto protocol_err;
   2464	}
   2465
   2466	/*
   2467	 * when testing FW load (without Linux) on PLDM we don't want to
   2468	 * wait until boot fit is active as it may take several hours.
   2469	 * instead, we load the bootfit and let it do all initializations in
   2470	 * the background.
   2471	 */
   2472	if (hdev->pldm && !(hdev->fw_components & FW_TYPE_LINUX))
   2473		return 0;
   2474
   2475	rc = hl_fw_dynamic_wait_for_boot_fit_active(hdev, fw_loader);
   2476	if (rc)
   2477		goto protocol_err;
   2478
   2479	/* Enable DRAM scrambling before Linux boot and after successful
   2480	 *  UBoot
   2481	 */
   2482	hdev->asic_funcs->init_cpu_scrambler_dram(hdev);
   2483
   2484	if (!(hdev->fw_components & FW_TYPE_LINUX)) {
   2485		dev_info(hdev->dev, "Skip loading Linux F/W\n");
   2486		return 0;
   2487	}
   2488
   2489	if (fw_loader->skip_bmc) {
   2490		rc = hl_fw_dynamic_send_protocol_cmd(hdev, fw_loader,
   2491							COMMS_SKIP_BMC, 0,
   2492							true,
   2493							fw_loader->cpu_timeout);
   2494		if (rc) {
   2495			dev_err(hdev->dev, "failed to load boot fit\n");
   2496			goto protocol_err;
   2497		}
   2498	}
   2499
   2500	/* load Linux image to FW */
   2501	rc = hl_fw_dynamic_load_image(hdev, fw_loader, FW_COMP_LINUX,
   2502							fw_loader->cpu_timeout);
   2503	if (rc) {
   2504		dev_err(hdev->dev, "failed to load Linux\n");
   2505		goto protocol_err;
   2506	}
   2507
   2508	rc = hl_fw_dynamic_wait_for_linux_active(hdev, fw_loader);
   2509	if (rc)
   2510		goto protocol_err;
   2511
   2512	hl_fw_linux_update_state(hdev, le32_to_cpu(dyn_regs->cpu_boot_dev_sts0),
   2513				le32_to_cpu(dyn_regs->cpu_boot_dev_sts1));
   2514
   2515	hl_fw_dynamic_update_linux_interrupt_if(hdev);
   2516
   2517	return 0;
   2518
   2519protocol_err:
   2520	if (fw_loader->dynamic_loader.fw_desc_valid)
   2521		fw_read_errors(hdev, le32_to_cpu(dyn_regs->cpu_boot_err0),
   2522				le32_to_cpu(dyn_regs->cpu_boot_err1),
   2523				le32_to_cpu(dyn_regs->cpu_boot_dev_sts0),
   2524				le32_to_cpu(dyn_regs->cpu_boot_dev_sts1));
   2525	return rc;
   2526}
   2527
   2528/**
   2529 * hl_fw_static_init_cpu - initialize the device CPU using static protocol
   2530 *
   2531 * @hdev: pointer to the habanalabs device structure
   2532 * @fw_loader: managing structure for loading device's FW
   2533 *
   2534 * @return 0 on success, otherwise non-zero error code
   2535 */
   2536static int hl_fw_static_init_cpu(struct hl_device *hdev,
   2537					struct fw_load_mgr *fw_loader)
   2538{
   2539	u32 cpu_msg_status_reg, cpu_timeout, msg_to_cpu_reg, status;
   2540	u32 cpu_boot_dev_status0_reg, cpu_boot_dev_status1_reg;
   2541	struct static_fw_load_mgr *static_loader;
   2542	u32 cpu_boot_status_reg;
   2543	int rc;
   2544
   2545	if (!(hdev->fw_components & FW_TYPE_BOOT_CPU))
   2546		return 0;
   2547
   2548	/* init common loader parameters */
   2549	cpu_timeout = fw_loader->cpu_timeout;
   2550
   2551	/* init static loader parameters */
   2552	static_loader = &fw_loader->static_loader;
   2553	cpu_msg_status_reg = static_loader->cpu_cmd_status_to_host_reg;
   2554	msg_to_cpu_reg = static_loader->kmd_msg_to_cpu_reg;
   2555	cpu_boot_dev_status0_reg = static_loader->cpu_boot_dev_status0_reg;
   2556	cpu_boot_dev_status1_reg = static_loader->cpu_boot_dev_status1_reg;
   2557	cpu_boot_status_reg = static_loader->cpu_boot_status_reg;
   2558
   2559	dev_info(hdev->dev, "Going to wait for device boot (up to %lds)\n",
   2560		cpu_timeout / USEC_PER_SEC);
   2561
   2562	/* Wait for boot FIT request */
   2563	rc = hl_poll_timeout(
   2564		hdev,
   2565		cpu_boot_status_reg,
   2566		status,
   2567		status == CPU_BOOT_STATUS_WAITING_FOR_BOOT_FIT,
   2568		hdev->fw_poll_interval_usec,
   2569		fw_loader->boot_fit_timeout);
   2570
   2571	if (rc) {
   2572		dev_dbg(hdev->dev,
   2573			"No boot fit request received, resuming boot\n");
   2574	} else {
   2575		rc = hdev->asic_funcs->load_boot_fit_to_device(hdev);
   2576		if (rc)
   2577			goto out;
   2578
   2579		/* Clear device CPU message status */
   2580		WREG32(cpu_msg_status_reg, CPU_MSG_CLR);
   2581
   2582		/* Signal device CPU that boot loader is ready */
   2583		WREG32(msg_to_cpu_reg, KMD_MSG_FIT_RDY);
   2584
   2585		/* Poll for CPU device ack */
   2586		rc = hl_poll_timeout(
   2587			hdev,
   2588			cpu_msg_status_reg,
   2589			status,
   2590			status == CPU_MSG_OK,
   2591			hdev->fw_poll_interval_usec,
   2592			fw_loader->boot_fit_timeout);
   2593
   2594		if (rc) {
   2595			dev_err(hdev->dev,
   2596				"Timeout waiting for boot fit load ack\n");
   2597			goto out;
   2598		}
   2599
   2600		/* Clear message */
   2601		WREG32(msg_to_cpu_reg, KMD_MSG_NA);
   2602	}
   2603
   2604	/*
   2605	 * Make sure CPU boot-loader is running
   2606	 * Note that the CPU_BOOT_STATUS_SRAM_AVAIL is generally set by Linux
   2607	 * yet there is a debug scenario in which we loading uboot (without Linux)
   2608	 * which at later stage is relocated to DRAM. In this case we expect
   2609	 * uboot to set the CPU_BOOT_STATUS_SRAM_AVAIL and so we add it to the
   2610	 * poll flags
   2611	 */
   2612	rc = hl_poll_timeout(
   2613		hdev,
   2614		cpu_boot_status_reg,
   2615		status,
   2616		(status == CPU_BOOT_STATUS_DRAM_RDY) ||
   2617		(status == CPU_BOOT_STATUS_NIC_FW_RDY) ||
   2618		(status == CPU_BOOT_STATUS_READY_TO_BOOT) ||
   2619		(status == CPU_BOOT_STATUS_SRAM_AVAIL),
   2620		hdev->fw_poll_interval_usec,
   2621		cpu_timeout);
   2622
   2623	dev_dbg(hdev->dev, "uboot status = %d\n", status);
   2624
   2625	/* Read U-Boot version now in case we will later fail */
   2626	hl_fw_static_read_device_fw_version(hdev, FW_COMP_BOOT_FIT);
   2627
   2628	/* update state according to boot stage */
   2629	hl_fw_boot_fit_update_state(hdev, cpu_boot_dev_status0_reg,
   2630						cpu_boot_dev_status1_reg);
   2631
   2632	if (rc) {
   2633		detect_cpu_boot_status(hdev, status);
   2634		rc = -EIO;
   2635		goto out;
   2636	}
   2637
   2638	/* Enable DRAM scrambling before Linux boot and after successful
   2639	 *  UBoot
   2640	 */
   2641	hdev->asic_funcs->init_cpu_scrambler_dram(hdev);
   2642
   2643	if (!(hdev->fw_components & FW_TYPE_LINUX)) {
   2644		dev_info(hdev->dev, "Skip loading Linux F/W\n");
   2645		rc = 0;
   2646		goto out;
   2647	}
   2648
   2649	if (status == CPU_BOOT_STATUS_SRAM_AVAIL) {
   2650		rc = 0;
   2651		goto out;
   2652	}
   2653
   2654	dev_info(hdev->dev,
   2655		"Loading firmware to device, may take some time...\n");
   2656
   2657	rc = hdev->asic_funcs->load_firmware_to_device(hdev);
   2658	if (rc)
   2659		goto out;
   2660
   2661	if (fw_loader->skip_bmc) {
   2662		WREG32(msg_to_cpu_reg, KMD_MSG_SKIP_BMC);
   2663
   2664		rc = hl_poll_timeout(
   2665			hdev,
   2666			cpu_boot_status_reg,
   2667			status,
   2668			(status == CPU_BOOT_STATUS_BMC_WAITING_SKIPPED),
   2669			hdev->fw_poll_interval_usec,
   2670			cpu_timeout);
   2671
   2672		if (rc) {
   2673			dev_err(hdev->dev,
   2674				"Failed to get ACK on skipping BMC, %d\n",
   2675				status);
   2676			WREG32(msg_to_cpu_reg, KMD_MSG_NA);
   2677			rc = -EIO;
   2678			goto out;
   2679		}
   2680	}
   2681
   2682	WREG32(msg_to_cpu_reg, KMD_MSG_FIT_RDY);
   2683
   2684	rc = hl_poll_timeout(
   2685		hdev,
   2686		cpu_boot_status_reg,
   2687		status,
   2688		(status == CPU_BOOT_STATUS_SRAM_AVAIL),
   2689		hdev->fw_poll_interval_usec,
   2690		cpu_timeout);
   2691
   2692	/* Clear message */
   2693	WREG32(msg_to_cpu_reg, KMD_MSG_NA);
   2694
   2695	if (rc) {
   2696		if (status == CPU_BOOT_STATUS_FIT_CORRUPTED)
   2697			dev_err(hdev->dev,
   2698				"Device reports FIT image is corrupted\n");
   2699		else
   2700			dev_err(hdev->dev,
   2701				"Failed to load firmware to device, %d\n",
   2702				status);
   2703
   2704		rc = -EIO;
   2705		goto out;
   2706	}
   2707
   2708	rc = fw_read_errors(hdev, fw_loader->static_loader.boot_err0_reg,
   2709					fw_loader->static_loader.boot_err1_reg,
   2710					cpu_boot_dev_status0_reg,
   2711					cpu_boot_dev_status1_reg);
   2712	if (rc)
   2713		return rc;
   2714
   2715	hl_fw_linux_update_state(hdev, cpu_boot_dev_status0_reg,
   2716						cpu_boot_dev_status1_reg);
   2717
   2718	return 0;
   2719
   2720out:
   2721	fw_read_errors(hdev, fw_loader->static_loader.boot_err0_reg,
   2722					fw_loader->static_loader.boot_err1_reg,
   2723					cpu_boot_dev_status0_reg,
   2724					cpu_boot_dev_status1_reg);
   2725
   2726	return rc;
   2727}
   2728
   2729/**
   2730 * hl_fw_init_cpu - initialize the device CPU
   2731 *
   2732 * @hdev: pointer to the habanalabs device structure
   2733 *
   2734 * @return 0 on success, otherwise non-zero error code
   2735 *
   2736 * perform necessary initializations for device's CPU. takes into account if
   2737 * init protocol is static or dynamic.
   2738 */
   2739int hl_fw_init_cpu(struct hl_device *hdev)
   2740{
   2741	struct asic_fixed_properties *prop = &hdev->asic_prop;
   2742	struct fw_load_mgr *fw_loader = &hdev->fw_loader;
   2743
   2744	return  prop->dynamic_fw_load ?
   2745			hl_fw_dynamic_init_cpu(hdev, fw_loader) :
   2746			hl_fw_static_init_cpu(hdev, fw_loader);
   2747}
   2748
   2749void hl_fw_set_pll_profile(struct hl_device *hdev)
   2750{
   2751	hl_fw_set_frequency(hdev, hdev->asic_prop.clk_pll_index,
   2752				hdev->asic_prop.max_freq_value);
   2753}
   2754
   2755int hl_fw_get_clk_rate(struct hl_device *hdev, u32 *cur_clk, u32 *max_clk)
   2756{
   2757	long value;
   2758
   2759	if (!hl_device_operational(hdev, NULL))
   2760		return -ENODEV;
   2761
   2762	if (!hdev->pdev) {
   2763		*cur_clk = 0;
   2764		*max_clk = 0;
   2765		return 0;
   2766	}
   2767
   2768	value = hl_fw_get_frequency(hdev, hdev->asic_prop.clk_pll_index, false);
   2769
   2770	if (value < 0) {
   2771		dev_err(hdev->dev, "Failed to retrieve device max clock %ld\n", value);
   2772		return value;
   2773	}
   2774
   2775	*max_clk = (value / 1000 / 1000);
   2776
   2777	value = hl_fw_get_frequency(hdev, hdev->asic_prop.clk_pll_index, true);
   2778
   2779	if (value < 0) {
   2780		dev_err(hdev->dev, "Failed to retrieve device current clock %ld\n", value);
   2781		return value;
   2782	}
   2783
   2784	*cur_clk = (value / 1000 / 1000);
   2785
   2786	return 0;
   2787}
   2788
   2789long hl_fw_get_frequency(struct hl_device *hdev, u32 pll_index, bool curr)
   2790{
   2791	struct cpucp_packet pkt;
   2792	u32 used_pll_idx;
   2793	u64 result;
   2794	int rc;
   2795
   2796	rc = get_used_pll_index(hdev, pll_index, &used_pll_idx);
   2797	if (rc)
   2798		return rc;
   2799
   2800	memset(&pkt, 0, sizeof(pkt));
   2801
   2802	if (curr)
   2803		pkt.ctl = cpu_to_le32(CPUCP_PACKET_FREQUENCY_CURR_GET <<
   2804						CPUCP_PKT_CTL_OPCODE_SHIFT);
   2805	else
   2806		pkt.ctl = cpu_to_le32(CPUCP_PACKET_FREQUENCY_GET << CPUCP_PKT_CTL_OPCODE_SHIFT);
   2807
   2808	pkt.pll_index = cpu_to_le32((u32)used_pll_idx);
   2809
   2810	rc = hdev->asic_funcs->send_cpu_message(hdev, (u32 *) &pkt, sizeof(pkt), 0, &result);
   2811
   2812	if (rc) {
   2813		dev_err(hdev->dev, "Failed to get frequency of PLL %d, error %d\n",
   2814			used_pll_idx, rc);
   2815		return rc;
   2816	}
   2817
   2818	return (long) result;
   2819}
   2820
   2821void hl_fw_set_frequency(struct hl_device *hdev, u32 pll_index, u64 freq)
   2822{
   2823	struct cpucp_packet pkt;
   2824	u32 used_pll_idx;
   2825	int rc;
   2826
   2827	rc = get_used_pll_index(hdev, pll_index, &used_pll_idx);
   2828	if (rc)
   2829		return;
   2830
   2831	memset(&pkt, 0, sizeof(pkt));
   2832
   2833	pkt.ctl = cpu_to_le32(CPUCP_PACKET_FREQUENCY_SET << CPUCP_PKT_CTL_OPCODE_SHIFT);
   2834	pkt.pll_index = cpu_to_le32((u32)used_pll_idx);
   2835	pkt.value = cpu_to_le64(freq);
   2836
   2837	rc = hdev->asic_funcs->send_cpu_message(hdev, (u32 *) &pkt, sizeof(pkt), 0, NULL);
   2838
   2839	if (rc)
   2840		dev_err(hdev->dev, "Failed to set frequency to PLL %d, error %d\n",
   2841			used_pll_idx, rc);
   2842}
   2843
   2844long hl_fw_get_max_power(struct hl_device *hdev)
   2845{
   2846	struct cpucp_packet pkt;
   2847	u64 result;
   2848	int rc;
   2849
   2850	memset(&pkt, 0, sizeof(pkt));
   2851
   2852	pkt.ctl = cpu_to_le32(CPUCP_PACKET_MAX_POWER_GET << CPUCP_PKT_CTL_OPCODE_SHIFT);
   2853
   2854	rc = hdev->asic_funcs->send_cpu_message(hdev, (u32 *) &pkt, sizeof(pkt), 0, &result);
   2855
   2856	if (rc) {
   2857		dev_err(hdev->dev, "Failed to get max power, error %d\n", rc);
   2858		return rc;
   2859	}
   2860
   2861	return result;
   2862}
   2863
   2864void hl_fw_set_max_power(struct hl_device *hdev)
   2865{
   2866	struct cpucp_packet pkt;
   2867	int rc;
   2868
   2869	/* TODO: remove this after simulator supports this packet */
   2870	if (!hdev->pdev)
   2871		return;
   2872
   2873	memset(&pkt, 0, sizeof(pkt));
   2874
   2875	pkt.ctl = cpu_to_le32(CPUCP_PACKET_MAX_POWER_SET << CPUCP_PKT_CTL_OPCODE_SHIFT);
   2876	pkt.value = cpu_to_le64(hdev->max_power);
   2877
   2878	rc = hdev->asic_funcs->send_cpu_message(hdev, (u32 *) &pkt, sizeof(pkt), 0, NULL);
   2879
   2880	if (rc)
   2881		dev_err(hdev->dev, "Failed to set max power, error %d\n", rc);
   2882}