18c2ecf20Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0
28c2ecf20Sopenharmony_ci
38c2ecf20Sopenharmony_ci/*
48c2ecf20Sopenharmony_ci * Copyright 2016-2020 HabanaLabs, Ltd.
58c2ecf20Sopenharmony_ci * All Rights Reserved.
68c2ecf20Sopenharmony_ci */
78c2ecf20Sopenharmony_ci
88c2ecf20Sopenharmony_ci#include "gaudiP.h"
98c2ecf20Sopenharmony_ci#include "../include/hw_ip/mmu/mmu_general.h"
108c2ecf20Sopenharmony_ci#include "../include/hw_ip/mmu/mmu_v1_1.h"
118c2ecf20Sopenharmony_ci#include "../include/gaudi/gaudi_masks.h"
128c2ecf20Sopenharmony_ci#include "../include/gaudi/gaudi_fw_if.h"
138c2ecf20Sopenharmony_ci#include "../include/gaudi/gaudi_reg_map.h"
148c2ecf20Sopenharmony_ci#include "../include/gaudi/gaudi_async_ids_map_extended.h"
158c2ecf20Sopenharmony_ci
168c2ecf20Sopenharmony_ci#include <linux/module.h>
178c2ecf20Sopenharmony_ci#include <linux/pci.h>
188c2ecf20Sopenharmony_ci#include <linux/firmware.h>
198c2ecf20Sopenharmony_ci#include <linux/hwmon.h>
208c2ecf20Sopenharmony_ci#include <linux/genalloc.h>
218c2ecf20Sopenharmony_ci#include <linux/io-64-nonatomic-lo-hi.h>
228c2ecf20Sopenharmony_ci#include <linux/iommu.h>
238c2ecf20Sopenharmony_ci#include <linux/seq_file.h>
248c2ecf20Sopenharmony_ci
258c2ecf20Sopenharmony_ci/*
268c2ecf20Sopenharmony_ci * Gaudi security scheme:
278c2ecf20Sopenharmony_ci *
288c2ecf20Sopenharmony_ci * 1. Host is protected by:
298c2ecf20Sopenharmony_ci *        - Range registers
308c2ecf20Sopenharmony_ci *        - MMU
318c2ecf20Sopenharmony_ci *
328c2ecf20Sopenharmony_ci * 2. DDR is protected by:
338c2ecf20Sopenharmony_ci *        - Range registers (protect the first 512MB)
348c2ecf20Sopenharmony_ci *
358c2ecf20Sopenharmony_ci * 3. Configuration is protected by:
368c2ecf20Sopenharmony_ci *        - Range registers
378c2ecf20Sopenharmony_ci *        - Protection bits
388c2ecf20Sopenharmony_ci *
398c2ecf20Sopenharmony_ci * MMU is always enabled.
408c2ecf20Sopenharmony_ci *
418c2ecf20Sopenharmony_ci * QMAN DMA channels 0,1,5 (PCI DMAN):
428c2ecf20Sopenharmony_ci *     - DMA is not secured.
438c2ecf20Sopenharmony_ci *     - PQ and CQ are secured.
448c2ecf20Sopenharmony_ci *     - CP is secured: The driver needs to parse CB but WREG should be allowed
458c2ecf20Sopenharmony_ci *                      because of TDMA (tensor DMA). Hence, WREG is always not
468c2ecf20Sopenharmony_ci *                      secured.
478c2ecf20Sopenharmony_ci *
488c2ecf20Sopenharmony_ci * When the driver needs to use DMA it will check that Gaudi is idle, set DMA
498c2ecf20Sopenharmony_ci * channel 0 to be secured, execute the DMA and change it back to not secured.
508c2ecf20Sopenharmony_ci * Currently, the driver doesn't use the DMA while there are compute jobs
518c2ecf20Sopenharmony_ci * running.
528c2ecf20Sopenharmony_ci *
538c2ecf20Sopenharmony_ci * The current use cases for the driver to use the DMA are:
548c2ecf20Sopenharmony_ci *     - Clear SRAM on context switch (happens on context switch when device is
558c2ecf20Sopenharmony_ci *       idle)
568c2ecf20Sopenharmony_ci *     - MMU page tables area clear (happens on init)
578c2ecf20Sopenharmony_ci *
588c2ecf20Sopenharmony_ci * QMAN DMA 2-4,6,7, TPC, MME, NIC:
598c2ecf20Sopenharmony_ci * PQ is secured and is located on the Host (HBM CON TPC3 bug)
608c2ecf20Sopenharmony_ci * CQ, CP and the engine are not secured
618c2ecf20Sopenharmony_ci *
628c2ecf20Sopenharmony_ci */
638c2ecf20Sopenharmony_ci
648c2ecf20Sopenharmony_ci#define GAUDI_BOOT_FIT_FILE	"habanalabs/gaudi/gaudi-boot-fit.itb"
658c2ecf20Sopenharmony_ci#define GAUDI_LINUX_FW_FILE	"habanalabs/gaudi/gaudi-fit.itb"
668c2ecf20Sopenharmony_ci#define GAUDI_TPC_FW_FILE	"habanalabs/gaudi/gaudi_tpc.bin"
678c2ecf20Sopenharmony_ci
688c2ecf20Sopenharmony_ci#define GAUDI_DMA_POOL_BLK_SIZE		0x100 /* 256 bytes */
698c2ecf20Sopenharmony_ci
708c2ecf20Sopenharmony_ci#define GAUDI_RESET_TIMEOUT_MSEC	1000		/* 1000ms */
718c2ecf20Sopenharmony_ci#define GAUDI_RESET_WAIT_MSEC		1		/* 1ms */
728c2ecf20Sopenharmony_ci#define GAUDI_CPU_RESET_WAIT_MSEC	200		/* 200ms */
738c2ecf20Sopenharmony_ci#define GAUDI_TEST_QUEUE_WAIT_USEC	100000		/* 100ms */
748c2ecf20Sopenharmony_ci
758c2ecf20Sopenharmony_ci#define GAUDI_PLDM_RESET_WAIT_MSEC	1000		/* 1s */
768c2ecf20Sopenharmony_ci#define GAUDI_PLDM_HRESET_TIMEOUT_MSEC	20000		/* 20s */
778c2ecf20Sopenharmony_ci#define GAUDI_PLDM_TEST_QUEUE_WAIT_USEC	1000000		/* 1s */
788c2ecf20Sopenharmony_ci#define GAUDI_PLDM_MMU_TIMEOUT_USEC	(MMU_CONFIG_TIMEOUT_USEC * 100)
798c2ecf20Sopenharmony_ci#define GAUDI_PLDM_QMAN0_TIMEOUT_USEC	(HL_DEVICE_TIMEOUT_USEC * 30)
808c2ecf20Sopenharmony_ci#define GAUDI_PLDM_TPC_KERNEL_WAIT_USEC	(HL_DEVICE_TIMEOUT_USEC * 30)
818c2ecf20Sopenharmony_ci#define GAUDI_BOOT_FIT_REQ_TIMEOUT_USEC	1000000		/* 1s */
828c2ecf20Sopenharmony_ci#define GAUDI_MSG_TO_CPU_TIMEOUT_USEC	4000000		/* 4s */
838c2ecf20Sopenharmony_ci
848c2ecf20Sopenharmony_ci#define GAUDI_QMAN0_FENCE_VAL		0x72E91AB9
858c2ecf20Sopenharmony_ci
868c2ecf20Sopenharmony_ci#define GAUDI_MAX_STRING_LEN		20
878c2ecf20Sopenharmony_ci
888c2ecf20Sopenharmony_ci#define GAUDI_CB_POOL_CB_CNT		512
898c2ecf20Sopenharmony_ci#define GAUDI_CB_POOL_CB_SIZE		0x20000 /* 128KB */
908c2ecf20Sopenharmony_ci
918c2ecf20Sopenharmony_ci#define GAUDI_ALLOC_CPU_MEM_RETRY_CNT	3
928c2ecf20Sopenharmony_ci
938c2ecf20Sopenharmony_ci#define GAUDI_NUM_OF_TPC_INTR_CAUSE	20
948c2ecf20Sopenharmony_ci
958c2ecf20Sopenharmony_ci#define GAUDI_NUM_OF_QM_ERR_CAUSE	16
968c2ecf20Sopenharmony_ci
978c2ecf20Sopenharmony_ci#define GAUDI_NUM_OF_QM_ARB_ERR_CAUSE	3
988c2ecf20Sopenharmony_ci
998c2ecf20Sopenharmony_ci#define GAUDI_ARB_WDT_TIMEOUT		0x1000000
1008c2ecf20Sopenharmony_ci
1018c2ecf20Sopenharmony_ci#define GAUDI_CLK_GATE_DEBUGFS_MASK	(\
1028c2ecf20Sopenharmony_ci		BIT(GAUDI_ENGINE_ID_MME_0) |\
1038c2ecf20Sopenharmony_ci		BIT(GAUDI_ENGINE_ID_MME_2) |\
1048c2ecf20Sopenharmony_ci		GENMASK_ULL(GAUDI_ENGINE_ID_TPC_7, GAUDI_ENGINE_ID_TPC_0))
1058c2ecf20Sopenharmony_ci
1068c2ecf20Sopenharmony_cistatic const char gaudi_irq_name[GAUDI_MSI_ENTRIES][GAUDI_MAX_STRING_LEN] = {
1078c2ecf20Sopenharmony_ci		"gaudi cq 0_0", "gaudi cq 0_1", "gaudi cq 0_2", "gaudi cq 0_3",
1088c2ecf20Sopenharmony_ci		"gaudi cq 1_0", "gaudi cq 1_1", "gaudi cq 1_2", "gaudi cq 1_3",
1098c2ecf20Sopenharmony_ci		"gaudi cq 5_0", "gaudi cq 5_1", "gaudi cq 5_2", "gaudi cq 5_3",
1108c2ecf20Sopenharmony_ci		"gaudi cpu eq"
1118c2ecf20Sopenharmony_ci};
1128c2ecf20Sopenharmony_ci
1138c2ecf20Sopenharmony_cistatic const u8 gaudi_dma_assignment[GAUDI_DMA_MAX] = {
1148c2ecf20Sopenharmony_ci	[GAUDI_PCI_DMA_1] = GAUDI_ENGINE_ID_DMA_0,
1158c2ecf20Sopenharmony_ci	[GAUDI_PCI_DMA_2] = GAUDI_ENGINE_ID_DMA_1,
1168c2ecf20Sopenharmony_ci	[GAUDI_PCI_DMA_3] = GAUDI_ENGINE_ID_DMA_5,
1178c2ecf20Sopenharmony_ci	[GAUDI_HBM_DMA_1] = GAUDI_ENGINE_ID_DMA_2,
1188c2ecf20Sopenharmony_ci	[GAUDI_HBM_DMA_2] = GAUDI_ENGINE_ID_DMA_3,
1198c2ecf20Sopenharmony_ci	[GAUDI_HBM_DMA_3] = GAUDI_ENGINE_ID_DMA_4,
1208c2ecf20Sopenharmony_ci	[GAUDI_HBM_DMA_4] = GAUDI_ENGINE_ID_DMA_6,
1218c2ecf20Sopenharmony_ci	[GAUDI_HBM_DMA_5] = GAUDI_ENGINE_ID_DMA_7
1228c2ecf20Sopenharmony_ci};
1238c2ecf20Sopenharmony_ci
1248c2ecf20Sopenharmony_cistatic const u8 gaudi_cq_assignment[NUMBER_OF_CMPLT_QUEUES] = {
1258c2ecf20Sopenharmony_ci	[0] = GAUDI_QUEUE_ID_DMA_0_0,
1268c2ecf20Sopenharmony_ci	[1] = GAUDI_QUEUE_ID_DMA_0_1,
1278c2ecf20Sopenharmony_ci	[2] = GAUDI_QUEUE_ID_DMA_0_2,
1288c2ecf20Sopenharmony_ci	[3] = GAUDI_QUEUE_ID_DMA_0_3,
1298c2ecf20Sopenharmony_ci	[4] = GAUDI_QUEUE_ID_DMA_1_0,
1308c2ecf20Sopenharmony_ci	[5] = GAUDI_QUEUE_ID_DMA_1_1,
1318c2ecf20Sopenharmony_ci	[6] = GAUDI_QUEUE_ID_DMA_1_2,
1328c2ecf20Sopenharmony_ci	[7] = GAUDI_QUEUE_ID_DMA_1_3,
1338c2ecf20Sopenharmony_ci	[8] = GAUDI_QUEUE_ID_DMA_5_0,
1348c2ecf20Sopenharmony_ci	[9] = GAUDI_QUEUE_ID_DMA_5_1,
1358c2ecf20Sopenharmony_ci	[10] = GAUDI_QUEUE_ID_DMA_5_2,
1368c2ecf20Sopenharmony_ci	[11] = GAUDI_QUEUE_ID_DMA_5_3
1378c2ecf20Sopenharmony_ci};
1388c2ecf20Sopenharmony_ci
1398c2ecf20Sopenharmony_cistatic const u16 gaudi_packet_sizes[MAX_PACKET_ID] = {
1408c2ecf20Sopenharmony_ci	[PACKET_WREG_32]	= sizeof(struct packet_wreg32),
1418c2ecf20Sopenharmony_ci	[PACKET_WREG_BULK]	= sizeof(struct packet_wreg_bulk),
1428c2ecf20Sopenharmony_ci	[PACKET_MSG_LONG]	= sizeof(struct packet_msg_long),
1438c2ecf20Sopenharmony_ci	[PACKET_MSG_SHORT]	= sizeof(struct packet_msg_short),
1448c2ecf20Sopenharmony_ci	[PACKET_CP_DMA]		= sizeof(struct packet_cp_dma),
1458c2ecf20Sopenharmony_ci	[PACKET_REPEAT]		= sizeof(struct packet_repeat),
1468c2ecf20Sopenharmony_ci	[PACKET_MSG_PROT]	= sizeof(struct packet_msg_prot),
1478c2ecf20Sopenharmony_ci	[PACKET_FENCE]		= sizeof(struct packet_fence),
1488c2ecf20Sopenharmony_ci	[PACKET_LIN_DMA]	= sizeof(struct packet_lin_dma),
1498c2ecf20Sopenharmony_ci	[PACKET_NOP]		= sizeof(struct packet_nop),
1508c2ecf20Sopenharmony_ci	[PACKET_STOP]		= sizeof(struct packet_stop),
1518c2ecf20Sopenharmony_ci	[PACKET_ARB_POINT]	= sizeof(struct packet_arb_point),
1528c2ecf20Sopenharmony_ci	[PACKET_WAIT]		= sizeof(struct packet_wait),
1538c2ecf20Sopenharmony_ci	[PACKET_LOAD_AND_EXE]	= sizeof(struct packet_load_and_exe)
1548c2ecf20Sopenharmony_ci};
1558c2ecf20Sopenharmony_ci
1568c2ecf20Sopenharmony_cistatic inline bool validate_packet_id(enum packet_id id)
1578c2ecf20Sopenharmony_ci{
1588c2ecf20Sopenharmony_ci	switch (id) {
1598c2ecf20Sopenharmony_ci	case PACKET_WREG_32:
1608c2ecf20Sopenharmony_ci	case PACKET_WREG_BULK:
1618c2ecf20Sopenharmony_ci	case PACKET_MSG_LONG:
1628c2ecf20Sopenharmony_ci	case PACKET_MSG_SHORT:
1638c2ecf20Sopenharmony_ci	case PACKET_CP_DMA:
1648c2ecf20Sopenharmony_ci	case PACKET_REPEAT:
1658c2ecf20Sopenharmony_ci	case PACKET_MSG_PROT:
1668c2ecf20Sopenharmony_ci	case PACKET_FENCE:
1678c2ecf20Sopenharmony_ci	case PACKET_LIN_DMA:
1688c2ecf20Sopenharmony_ci	case PACKET_NOP:
1698c2ecf20Sopenharmony_ci	case PACKET_STOP:
1708c2ecf20Sopenharmony_ci	case PACKET_ARB_POINT:
1718c2ecf20Sopenharmony_ci	case PACKET_WAIT:
1728c2ecf20Sopenharmony_ci	case PACKET_LOAD_AND_EXE:
1738c2ecf20Sopenharmony_ci		return true;
1748c2ecf20Sopenharmony_ci	default:
1758c2ecf20Sopenharmony_ci		return false;
1768c2ecf20Sopenharmony_ci	}
1778c2ecf20Sopenharmony_ci}
1788c2ecf20Sopenharmony_ci
1798c2ecf20Sopenharmony_cistatic const char * const
1808c2ecf20Sopenharmony_cigaudi_tpc_interrupts_cause[GAUDI_NUM_OF_TPC_INTR_CAUSE] = {
1818c2ecf20Sopenharmony_ci	"tpc_address_exceed_slm",
1828c2ecf20Sopenharmony_ci	"tpc_div_by_0",
1838c2ecf20Sopenharmony_ci	"tpc_spu_mac_overflow",
1848c2ecf20Sopenharmony_ci	"tpc_spu_addsub_overflow",
1858c2ecf20Sopenharmony_ci	"tpc_spu_abs_overflow",
1868c2ecf20Sopenharmony_ci	"tpc_spu_fp_dst_nan_inf",
1878c2ecf20Sopenharmony_ci	"tpc_spu_fp_dst_denorm",
1888c2ecf20Sopenharmony_ci	"tpc_vpu_mac_overflow",
1898c2ecf20Sopenharmony_ci	"tpc_vpu_addsub_overflow",
1908c2ecf20Sopenharmony_ci	"tpc_vpu_abs_overflow",
1918c2ecf20Sopenharmony_ci	"tpc_vpu_fp_dst_nan_inf",
1928c2ecf20Sopenharmony_ci	"tpc_vpu_fp_dst_denorm",
1938c2ecf20Sopenharmony_ci	"tpc_assertions",
1948c2ecf20Sopenharmony_ci	"tpc_illegal_instruction",
1958c2ecf20Sopenharmony_ci	"tpc_pc_wrap_around",
1968c2ecf20Sopenharmony_ci	"tpc_qm_sw_err",
1978c2ecf20Sopenharmony_ci	"tpc_hbw_rresp_err",
1988c2ecf20Sopenharmony_ci	"tpc_hbw_bresp_err",
1998c2ecf20Sopenharmony_ci	"tpc_lbw_rresp_err",
2008c2ecf20Sopenharmony_ci	"tpc_lbw_bresp_err"
2018c2ecf20Sopenharmony_ci};
2028c2ecf20Sopenharmony_ci
2038c2ecf20Sopenharmony_cistatic const char * const
2048c2ecf20Sopenharmony_cigaudi_qman_error_cause[GAUDI_NUM_OF_QM_ERR_CAUSE] = {
2058c2ecf20Sopenharmony_ci	"PQ AXI HBW error",
2068c2ecf20Sopenharmony_ci	"CQ AXI HBW error",
2078c2ecf20Sopenharmony_ci	"CP AXI HBW error",
2088c2ecf20Sopenharmony_ci	"CP error due to undefined OPCODE",
2098c2ecf20Sopenharmony_ci	"CP encountered STOP OPCODE",
2108c2ecf20Sopenharmony_ci	"CP AXI LBW error",
2118c2ecf20Sopenharmony_ci	"CP WRREG32 or WRBULK returned error",
2128c2ecf20Sopenharmony_ci	"N/A",
2138c2ecf20Sopenharmony_ci	"FENCE 0 inc over max value and clipped",
2148c2ecf20Sopenharmony_ci	"FENCE 1 inc over max value and clipped",
2158c2ecf20Sopenharmony_ci	"FENCE 2 inc over max value and clipped",
2168c2ecf20Sopenharmony_ci	"FENCE 3 inc over max value and clipped",
2178c2ecf20Sopenharmony_ci	"FENCE 0 dec under min value and clipped",
2188c2ecf20Sopenharmony_ci	"FENCE 1 dec under min value and clipped",
2198c2ecf20Sopenharmony_ci	"FENCE 2 dec under min value and clipped",
2208c2ecf20Sopenharmony_ci	"FENCE 3 dec under min value and clipped"
2218c2ecf20Sopenharmony_ci};
2228c2ecf20Sopenharmony_ci
2238c2ecf20Sopenharmony_cistatic const char * const
2248c2ecf20Sopenharmony_cigaudi_qman_arb_error_cause[GAUDI_NUM_OF_QM_ARB_ERR_CAUSE] = {
2258c2ecf20Sopenharmony_ci	"Choice push while full error",
2268c2ecf20Sopenharmony_ci	"Choice Q watchdog error",
2278c2ecf20Sopenharmony_ci	"MSG AXI LBW returned with error"
2288c2ecf20Sopenharmony_ci};
2298c2ecf20Sopenharmony_ci
2308c2ecf20Sopenharmony_cistatic enum hl_queue_type gaudi_queue_type[GAUDI_QUEUE_ID_SIZE] = {
2318c2ecf20Sopenharmony_ci	QUEUE_TYPE_EXT, /* GAUDI_QUEUE_ID_DMA_0_0 */
2328c2ecf20Sopenharmony_ci	QUEUE_TYPE_EXT, /* GAUDI_QUEUE_ID_DMA_0_1 */
2338c2ecf20Sopenharmony_ci	QUEUE_TYPE_EXT, /* GAUDI_QUEUE_ID_DMA_0_2 */
2348c2ecf20Sopenharmony_ci	QUEUE_TYPE_EXT, /* GAUDI_QUEUE_ID_DMA_0_3 */
2358c2ecf20Sopenharmony_ci	QUEUE_TYPE_EXT, /* GAUDI_QUEUE_ID_DMA_1_0 */
2368c2ecf20Sopenharmony_ci	QUEUE_TYPE_EXT, /* GAUDI_QUEUE_ID_DMA_1_1 */
2378c2ecf20Sopenharmony_ci	QUEUE_TYPE_EXT, /* GAUDI_QUEUE_ID_DMA_1_2 */
2388c2ecf20Sopenharmony_ci	QUEUE_TYPE_EXT, /* GAUDI_QUEUE_ID_DMA_1_3 */
2398c2ecf20Sopenharmony_ci	QUEUE_TYPE_CPU, /* GAUDI_QUEUE_ID_CPU_PQ */
2408c2ecf20Sopenharmony_ci	QUEUE_TYPE_INT, /* GAUDI_QUEUE_ID_DMA_2_0 */
2418c2ecf20Sopenharmony_ci	QUEUE_TYPE_INT, /* GAUDI_QUEUE_ID_DMA_2_1 */
2428c2ecf20Sopenharmony_ci	QUEUE_TYPE_INT, /* GAUDI_QUEUE_ID_DMA_2_2 */
2438c2ecf20Sopenharmony_ci	QUEUE_TYPE_INT, /* GAUDI_QUEUE_ID_DMA_2_3 */
2448c2ecf20Sopenharmony_ci	QUEUE_TYPE_INT, /* GAUDI_QUEUE_ID_DMA_3_0 */
2458c2ecf20Sopenharmony_ci	QUEUE_TYPE_INT, /* GAUDI_QUEUE_ID_DMA_3_1 */
2468c2ecf20Sopenharmony_ci	QUEUE_TYPE_INT, /* GAUDI_QUEUE_ID_DMA_3_2 */
2478c2ecf20Sopenharmony_ci	QUEUE_TYPE_INT, /* GAUDI_QUEUE_ID_DMA_3_3 */
2488c2ecf20Sopenharmony_ci	QUEUE_TYPE_INT, /* GAUDI_QUEUE_ID_DMA_4_0 */
2498c2ecf20Sopenharmony_ci	QUEUE_TYPE_INT, /* GAUDI_QUEUE_ID_DMA_4_1 */
2508c2ecf20Sopenharmony_ci	QUEUE_TYPE_INT, /* GAUDI_QUEUE_ID_DMA_4_2 */
2518c2ecf20Sopenharmony_ci	QUEUE_TYPE_INT, /* GAUDI_QUEUE_ID_DMA_4_3 */
2528c2ecf20Sopenharmony_ci	QUEUE_TYPE_EXT, /* GAUDI_QUEUE_ID_DMA_5_0 */
2538c2ecf20Sopenharmony_ci	QUEUE_TYPE_EXT, /* GAUDI_QUEUE_ID_DMA_5_1 */
2548c2ecf20Sopenharmony_ci	QUEUE_TYPE_EXT, /* GAUDI_QUEUE_ID_DMA_5_2 */
2558c2ecf20Sopenharmony_ci	QUEUE_TYPE_EXT, /* GAUDI_QUEUE_ID_DMA_5_3 */
2568c2ecf20Sopenharmony_ci	QUEUE_TYPE_INT, /* GAUDI_QUEUE_ID_DMA_6_0 */
2578c2ecf20Sopenharmony_ci	QUEUE_TYPE_INT, /* GAUDI_QUEUE_ID_DMA_6_1 */
2588c2ecf20Sopenharmony_ci	QUEUE_TYPE_INT, /* GAUDI_QUEUE_ID_DMA_6_2 */
2598c2ecf20Sopenharmony_ci	QUEUE_TYPE_INT, /* GAUDI_QUEUE_ID_DMA_6_3 */
2608c2ecf20Sopenharmony_ci	QUEUE_TYPE_INT, /* GAUDI_QUEUE_ID_DMA_7_0 */
2618c2ecf20Sopenharmony_ci	QUEUE_TYPE_INT, /* GAUDI_QUEUE_ID_DMA_7_1 */
2628c2ecf20Sopenharmony_ci	QUEUE_TYPE_INT, /* GAUDI_QUEUE_ID_DMA_7_2 */
2638c2ecf20Sopenharmony_ci	QUEUE_TYPE_INT, /* GAUDI_QUEUE_ID_DMA_7_3 */
2648c2ecf20Sopenharmony_ci	QUEUE_TYPE_INT, /* GAUDI_QUEUE_ID_MME_0_0 */
2658c2ecf20Sopenharmony_ci	QUEUE_TYPE_INT, /* GAUDI_QUEUE_ID_MME_0_1 */
2668c2ecf20Sopenharmony_ci	QUEUE_TYPE_INT, /* GAUDI_QUEUE_ID_MME_0_2 */
2678c2ecf20Sopenharmony_ci	QUEUE_TYPE_INT, /* GAUDI_QUEUE_ID_MME_0_3 */
2688c2ecf20Sopenharmony_ci	QUEUE_TYPE_INT, /* GAUDI_QUEUE_ID_MME_1_0 */
2698c2ecf20Sopenharmony_ci	QUEUE_TYPE_INT, /* GAUDI_QUEUE_ID_MME_1_1 */
2708c2ecf20Sopenharmony_ci	QUEUE_TYPE_INT, /* GAUDI_QUEUE_ID_MME_1_2 */
2718c2ecf20Sopenharmony_ci	QUEUE_TYPE_INT, /* GAUDI_QUEUE_ID_MME_1_3 */
2728c2ecf20Sopenharmony_ci	QUEUE_TYPE_INT, /* GAUDI_QUEUE_ID_TPC_0_0 */
2738c2ecf20Sopenharmony_ci	QUEUE_TYPE_INT, /* GAUDI_QUEUE_ID_TPC_0_1 */
2748c2ecf20Sopenharmony_ci	QUEUE_TYPE_INT, /* GAUDI_QUEUE_ID_TPC_0_2 */
2758c2ecf20Sopenharmony_ci	QUEUE_TYPE_INT, /* GAUDI_QUEUE_ID_TPC_0_3 */
2768c2ecf20Sopenharmony_ci	QUEUE_TYPE_INT, /* GAUDI_QUEUE_ID_TPC_1_0 */
2778c2ecf20Sopenharmony_ci	QUEUE_TYPE_INT, /* GAUDI_QUEUE_ID_TPC_1_1 */
2788c2ecf20Sopenharmony_ci	QUEUE_TYPE_INT, /* GAUDI_QUEUE_ID_TPC_1_2 */
2798c2ecf20Sopenharmony_ci	QUEUE_TYPE_INT, /* GAUDI_QUEUE_ID_TPC_1_3 */
2808c2ecf20Sopenharmony_ci	QUEUE_TYPE_INT, /* GAUDI_QUEUE_ID_TPC_2_0 */
2818c2ecf20Sopenharmony_ci	QUEUE_TYPE_INT, /* GAUDI_QUEUE_ID_TPC_2_1 */
2828c2ecf20Sopenharmony_ci	QUEUE_TYPE_INT, /* GAUDI_QUEUE_ID_TPC_2_2 */
2838c2ecf20Sopenharmony_ci	QUEUE_TYPE_INT, /* GAUDI_QUEUE_ID_TPC_2_3 */
2848c2ecf20Sopenharmony_ci	QUEUE_TYPE_INT, /* GAUDI_QUEUE_ID_TPC_3_0 */
2858c2ecf20Sopenharmony_ci	QUEUE_TYPE_INT, /* GAUDI_QUEUE_ID_TPC_3_1 */
2868c2ecf20Sopenharmony_ci	QUEUE_TYPE_INT, /* GAUDI_QUEUE_ID_TPC_3_2 */
2878c2ecf20Sopenharmony_ci	QUEUE_TYPE_INT, /* GAUDI_QUEUE_ID_TPC_3_3 */
2888c2ecf20Sopenharmony_ci	QUEUE_TYPE_INT, /* GAUDI_QUEUE_ID_TPC_4_0 */
2898c2ecf20Sopenharmony_ci	QUEUE_TYPE_INT, /* GAUDI_QUEUE_ID_TPC_4_1 */
2908c2ecf20Sopenharmony_ci	QUEUE_TYPE_INT, /* GAUDI_QUEUE_ID_TPC_4_2 */
2918c2ecf20Sopenharmony_ci	QUEUE_TYPE_INT, /* GAUDI_QUEUE_ID_TPC_4_3 */
2928c2ecf20Sopenharmony_ci	QUEUE_TYPE_INT, /* GAUDI_QUEUE_ID_TPC_5_0 */
2938c2ecf20Sopenharmony_ci	QUEUE_TYPE_INT, /* GAUDI_QUEUE_ID_TPC_5_1 */
2948c2ecf20Sopenharmony_ci	QUEUE_TYPE_INT, /* GAUDI_QUEUE_ID_TPC_5_2 */
2958c2ecf20Sopenharmony_ci	QUEUE_TYPE_INT, /* GAUDI_QUEUE_ID_TPC_5_3 */
2968c2ecf20Sopenharmony_ci	QUEUE_TYPE_INT, /* GAUDI_QUEUE_ID_TPC_6_0 */
2978c2ecf20Sopenharmony_ci	QUEUE_TYPE_INT, /* GAUDI_QUEUE_ID_TPC_6_1 */
2988c2ecf20Sopenharmony_ci	QUEUE_TYPE_INT, /* GAUDI_QUEUE_ID_TPC_6_2 */
2998c2ecf20Sopenharmony_ci	QUEUE_TYPE_INT, /* GAUDI_QUEUE_ID_TPC_6_3 */
3008c2ecf20Sopenharmony_ci	QUEUE_TYPE_INT, /* GAUDI_QUEUE_ID_TPC_7_0 */
3018c2ecf20Sopenharmony_ci	QUEUE_TYPE_INT, /* GAUDI_QUEUE_ID_TPC_7_1 */
3028c2ecf20Sopenharmony_ci	QUEUE_TYPE_INT, /* GAUDI_QUEUE_ID_TPC_7_2 */
3038c2ecf20Sopenharmony_ci	QUEUE_TYPE_INT, /* GAUDI_QUEUE_ID_TPC_7_3 */
3048c2ecf20Sopenharmony_ci	QUEUE_TYPE_NA,  /* GAUDI_QUEUE_ID_NIC_0_0 */
3058c2ecf20Sopenharmony_ci	QUEUE_TYPE_NA,  /* GAUDI_QUEUE_ID_NIC_0_1 */
3068c2ecf20Sopenharmony_ci	QUEUE_TYPE_NA,  /* GAUDI_QUEUE_ID_NIC_0_2 */
3078c2ecf20Sopenharmony_ci	QUEUE_TYPE_NA,  /* GAUDI_QUEUE_ID_NIC_0_3 */
3088c2ecf20Sopenharmony_ci	QUEUE_TYPE_NA,  /* GAUDI_QUEUE_ID_NIC_1_0 */
3098c2ecf20Sopenharmony_ci	QUEUE_TYPE_NA,  /* GAUDI_QUEUE_ID_NIC_1_1 */
3108c2ecf20Sopenharmony_ci	QUEUE_TYPE_NA,  /* GAUDI_QUEUE_ID_NIC_1_2 */
3118c2ecf20Sopenharmony_ci	QUEUE_TYPE_NA,  /* GAUDI_QUEUE_ID_NIC_1_3 */
3128c2ecf20Sopenharmony_ci	QUEUE_TYPE_NA,  /* GAUDI_QUEUE_ID_NIC_2_0 */
3138c2ecf20Sopenharmony_ci	QUEUE_TYPE_NA,  /* GAUDI_QUEUE_ID_NIC_2_1 */
3148c2ecf20Sopenharmony_ci	QUEUE_TYPE_NA,  /* GAUDI_QUEUE_ID_NIC_2_2 */
3158c2ecf20Sopenharmony_ci	QUEUE_TYPE_NA,  /* GAUDI_QUEUE_ID_NIC_2_3 */
3168c2ecf20Sopenharmony_ci	QUEUE_TYPE_NA,  /* GAUDI_QUEUE_ID_NIC_3_0 */
3178c2ecf20Sopenharmony_ci	QUEUE_TYPE_NA,  /* GAUDI_QUEUE_ID_NIC_3_1 */
3188c2ecf20Sopenharmony_ci	QUEUE_TYPE_NA,  /* GAUDI_QUEUE_ID_NIC_3_2 */
3198c2ecf20Sopenharmony_ci	QUEUE_TYPE_NA,  /* GAUDI_QUEUE_ID_NIC_3_3 */
3208c2ecf20Sopenharmony_ci	QUEUE_TYPE_NA,  /* GAUDI_QUEUE_ID_NIC_4_0 */
3218c2ecf20Sopenharmony_ci	QUEUE_TYPE_NA,  /* GAUDI_QUEUE_ID_NIC_4_1 */
3228c2ecf20Sopenharmony_ci	QUEUE_TYPE_NA,  /* GAUDI_QUEUE_ID_NIC_4_2 */
3238c2ecf20Sopenharmony_ci	QUEUE_TYPE_NA,  /* GAUDI_QUEUE_ID_NIC_4_3 */
3248c2ecf20Sopenharmony_ci	QUEUE_TYPE_NA,  /* GAUDI_QUEUE_ID_NIC_5_0 */
3258c2ecf20Sopenharmony_ci	QUEUE_TYPE_NA,  /* GAUDI_QUEUE_ID_NIC_5_1 */
3268c2ecf20Sopenharmony_ci	QUEUE_TYPE_NA,  /* GAUDI_QUEUE_ID_NIC_5_2 */
3278c2ecf20Sopenharmony_ci	QUEUE_TYPE_NA,  /* GAUDI_QUEUE_ID_NIC_5_3 */
3288c2ecf20Sopenharmony_ci	QUEUE_TYPE_NA,  /* GAUDI_QUEUE_ID_NIC_6_0 */
3298c2ecf20Sopenharmony_ci	QUEUE_TYPE_NA,  /* GAUDI_QUEUE_ID_NIC_6_1 */
3308c2ecf20Sopenharmony_ci	QUEUE_TYPE_NA,  /* GAUDI_QUEUE_ID_NIC_6_2 */
3318c2ecf20Sopenharmony_ci	QUEUE_TYPE_NA,  /* GAUDI_QUEUE_ID_NIC_6_3 */
3328c2ecf20Sopenharmony_ci	QUEUE_TYPE_NA,  /* GAUDI_QUEUE_ID_NIC_7_0 */
3338c2ecf20Sopenharmony_ci	QUEUE_TYPE_NA,  /* GAUDI_QUEUE_ID_NIC_7_1 */
3348c2ecf20Sopenharmony_ci	QUEUE_TYPE_NA,  /* GAUDI_QUEUE_ID_NIC_7_2 */
3358c2ecf20Sopenharmony_ci	QUEUE_TYPE_NA,  /* GAUDI_QUEUE_ID_NIC_7_3 */
3368c2ecf20Sopenharmony_ci	QUEUE_TYPE_NA,  /* GAUDI_QUEUE_ID_NIC_8_0 */
3378c2ecf20Sopenharmony_ci	QUEUE_TYPE_NA,  /* GAUDI_QUEUE_ID_NIC_8_1 */
3388c2ecf20Sopenharmony_ci	QUEUE_TYPE_NA,  /* GAUDI_QUEUE_ID_NIC_8_2 */
3398c2ecf20Sopenharmony_ci	QUEUE_TYPE_NA,  /* GAUDI_QUEUE_ID_NIC_8_3 */
3408c2ecf20Sopenharmony_ci	QUEUE_TYPE_NA,  /* GAUDI_QUEUE_ID_NIC_9_0 */
3418c2ecf20Sopenharmony_ci	QUEUE_TYPE_NA,  /* GAUDI_QUEUE_ID_NIC_9_1 */
3428c2ecf20Sopenharmony_ci	QUEUE_TYPE_NA,  /* GAUDI_QUEUE_ID_NIC_9_2 */
3438c2ecf20Sopenharmony_ci	QUEUE_TYPE_NA,  /* GAUDI_QUEUE_ID_NIC_9_3 */
3448c2ecf20Sopenharmony_ci};
3458c2ecf20Sopenharmony_ci
3468c2ecf20Sopenharmony_cistruct ecc_info_extract_params {
3478c2ecf20Sopenharmony_ci	u64 block_address;
3488c2ecf20Sopenharmony_ci	u32 num_memories;
3498c2ecf20Sopenharmony_ci	bool derr;
3508c2ecf20Sopenharmony_ci	bool disable_clock_gating;
3518c2ecf20Sopenharmony_ci};
3528c2ecf20Sopenharmony_ci
3538c2ecf20Sopenharmony_cistatic int gaudi_mmu_update_asid_hop0_addr(struct hl_device *hdev, u32 asid,
3548c2ecf20Sopenharmony_ci								u64 phys_addr);
3558c2ecf20Sopenharmony_cistatic int gaudi_send_job_on_qman0(struct hl_device *hdev,
3568c2ecf20Sopenharmony_ci					struct hl_cs_job *job);
3578c2ecf20Sopenharmony_cistatic int gaudi_memset_device_memory(struct hl_device *hdev, u64 addr,
3588c2ecf20Sopenharmony_ci					u32 size, u64 val);
3598c2ecf20Sopenharmony_cistatic int gaudi_run_tpc_kernel(struct hl_device *hdev, u64 tpc_kernel,
3608c2ecf20Sopenharmony_ci				u32 tpc_id);
3618c2ecf20Sopenharmony_cistatic int gaudi_mmu_clear_pgt_range(struct hl_device *hdev);
3628c2ecf20Sopenharmony_cistatic int gaudi_cpucp_info_get(struct hl_device *hdev);
3638c2ecf20Sopenharmony_cistatic void gaudi_disable_clock_gating(struct hl_device *hdev);
3648c2ecf20Sopenharmony_cistatic void gaudi_mmu_prepare(struct hl_device *hdev, u32 asid);
3658c2ecf20Sopenharmony_ci
3668c2ecf20Sopenharmony_cistatic int gaudi_get_fixed_properties(struct hl_device *hdev)
3678c2ecf20Sopenharmony_ci{
3688c2ecf20Sopenharmony_ci	struct asic_fixed_properties *prop = &hdev->asic_prop;
3698c2ecf20Sopenharmony_ci	u32 num_sync_stream_queues = 0;
3708c2ecf20Sopenharmony_ci	int i;
3718c2ecf20Sopenharmony_ci
3728c2ecf20Sopenharmony_ci	prop->max_queues = GAUDI_QUEUE_ID_SIZE;
3738c2ecf20Sopenharmony_ci	prop->hw_queues_props = kcalloc(prop->max_queues,
3748c2ecf20Sopenharmony_ci			sizeof(struct hw_queue_properties),
3758c2ecf20Sopenharmony_ci			GFP_KERNEL);
3768c2ecf20Sopenharmony_ci
3778c2ecf20Sopenharmony_ci	if (!prop->hw_queues_props)
3788c2ecf20Sopenharmony_ci		return -ENOMEM;
3798c2ecf20Sopenharmony_ci
3808c2ecf20Sopenharmony_ci	for (i = 0 ; i < prop->max_queues ; i++) {
3818c2ecf20Sopenharmony_ci		if (gaudi_queue_type[i] == QUEUE_TYPE_EXT) {
3828c2ecf20Sopenharmony_ci			prop->hw_queues_props[i].type = QUEUE_TYPE_EXT;
3838c2ecf20Sopenharmony_ci			prop->hw_queues_props[i].driver_only = 0;
3848c2ecf20Sopenharmony_ci			prop->hw_queues_props[i].requires_kernel_cb = 1;
3858c2ecf20Sopenharmony_ci			prop->hw_queues_props[i].supports_sync_stream = 1;
3868c2ecf20Sopenharmony_ci			num_sync_stream_queues++;
3878c2ecf20Sopenharmony_ci		} else if (gaudi_queue_type[i] == QUEUE_TYPE_CPU) {
3888c2ecf20Sopenharmony_ci			prop->hw_queues_props[i].type = QUEUE_TYPE_CPU;
3898c2ecf20Sopenharmony_ci			prop->hw_queues_props[i].driver_only = 1;
3908c2ecf20Sopenharmony_ci			prop->hw_queues_props[i].requires_kernel_cb = 0;
3918c2ecf20Sopenharmony_ci			prop->hw_queues_props[i].supports_sync_stream = 0;
3928c2ecf20Sopenharmony_ci		} else if (gaudi_queue_type[i] == QUEUE_TYPE_INT) {
3938c2ecf20Sopenharmony_ci			prop->hw_queues_props[i].type = QUEUE_TYPE_INT;
3948c2ecf20Sopenharmony_ci			prop->hw_queues_props[i].driver_only = 0;
3958c2ecf20Sopenharmony_ci			prop->hw_queues_props[i].requires_kernel_cb = 0;
3968c2ecf20Sopenharmony_ci		} else if (gaudi_queue_type[i] == QUEUE_TYPE_NA) {
3978c2ecf20Sopenharmony_ci			prop->hw_queues_props[i].type = QUEUE_TYPE_NA;
3988c2ecf20Sopenharmony_ci			prop->hw_queues_props[i].driver_only = 0;
3998c2ecf20Sopenharmony_ci			prop->hw_queues_props[i].requires_kernel_cb = 0;
4008c2ecf20Sopenharmony_ci			prop->hw_queues_props[i].supports_sync_stream = 0;
4018c2ecf20Sopenharmony_ci		}
4028c2ecf20Sopenharmony_ci	}
4038c2ecf20Sopenharmony_ci
4048c2ecf20Sopenharmony_ci	prop->completion_queues_count = NUMBER_OF_CMPLT_QUEUES;
4058c2ecf20Sopenharmony_ci	prop->sync_stream_first_sob = 0;
4068c2ecf20Sopenharmony_ci	prop->sync_stream_first_mon = 0;
4078c2ecf20Sopenharmony_ci	prop->dram_base_address = DRAM_PHYS_BASE;
4088c2ecf20Sopenharmony_ci	prop->dram_size = GAUDI_HBM_SIZE_32GB;
4098c2ecf20Sopenharmony_ci	prop->dram_end_address = prop->dram_base_address +
4108c2ecf20Sopenharmony_ci					prop->dram_size;
4118c2ecf20Sopenharmony_ci	prop->dram_user_base_address = DRAM_BASE_ADDR_USER;
4128c2ecf20Sopenharmony_ci
4138c2ecf20Sopenharmony_ci	prop->sram_base_address = SRAM_BASE_ADDR;
4148c2ecf20Sopenharmony_ci	prop->sram_size = SRAM_SIZE;
4158c2ecf20Sopenharmony_ci	prop->sram_end_address = prop->sram_base_address +
4168c2ecf20Sopenharmony_ci					prop->sram_size;
4178c2ecf20Sopenharmony_ci	prop->sram_user_base_address = prop->sram_base_address +
4188c2ecf20Sopenharmony_ci					SRAM_USER_BASE_OFFSET;
4198c2ecf20Sopenharmony_ci
4208c2ecf20Sopenharmony_ci	prop->mmu_pgt_addr = MMU_PAGE_TABLES_ADDR;
4218c2ecf20Sopenharmony_ci	if (hdev->pldm)
4228c2ecf20Sopenharmony_ci		prop->mmu_pgt_size = 0x800000; /* 8MB */
4238c2ecf20Sopenharmony_ci	else
4248c2ecf20Sopenharmony_ci		prop->mmu_pgt_size = MMU_PAGE_TABLES_SIZE;
4258c2ecf20Sopenharmony_ci	prop->mmu_pte_size = HL_PTE_SIZE;
4268c2ecf20Sopenharmony_ci	prop->mmu_hop_table_size = HOP_TABLE_SIZE;
4278c2ecf20Sopenharmony_ci	prop->mmu_hop0_tables_total_size = HOP0_TABLES_TOTAL_SIZE;
4288c2ecf20Sopenharmony_ci	prop->dram_page_size = PAGE_SIZE_2MB;
4298c2ecf20Sopenharmony_ci
4308c2ecf20Sopenharmony_ci	prop->pmmu.hop0_shift = HOP0_SHIFT;
4318c2ecf20Sopenharmony_ci	prop->pmmu.hop1_shift = HOP1_SHIFT;
4328c2ecf20Sopenharmony_ci	prop->pmmu.hop2_shift = HOP2_SHIFT;
4338c2ecf20Sopenharmony_ci	prop->pmmu.hop3_shift = HOP3_SHIFT;
4348c2ecf20Sopenharmony_ci	prop->pmmu.hop4_shift = HOP4_SHIFT;
4358c2ecf20Sopenharmony_ci	prop->pmmu.hop0_mask = HOP0_MASK;
4368c2ecf20Sopenharmony_ci	prop->pmmu.hop1_mask = HOP1_MASK;
4378c2ecf20Sopenharmony_ci	prop->pmmu.hop2_mask = HOP2_MASK;
4388c2ecf20Sopenharmony_ci	prop->pmmu.hop3_mask = HOP3_MASK;
4398c2ecf20Sopenharmony_ci	prop->pmmu.hop4_mask = HOP4_MASK;
4408c2ecf20Sopenharmony_ci	prop->pmmu.start_addr = VA_HOST_SPACE_START;
4418c2ecf20Sopenharmony_ci	prop->pmmu.end_addr =
4428c2ecf20Sopenharmony_ci			(VA_HOST_SPACE_START + VA_HOST_SPACE_SIZE / 2) - 1;
4438c2ecf20Sopenharmony_ci	prop->pmmu.page_size = PAGE_SIZE_4KB;
4448c2ecf20Sopenharmony_ci	prop->pmmu.num_hops = MMU_ARCH_5_HOPS;
4458c2ecf20Sopenharmony_ci
4468c2ecf20Sopenharmony_ci	/* PMMU and HPMMU are the same except of page size */
4478c2ecf20Sopenharmony_ci	memcpy(&prop->pmmu_huge, &prop->pmmu, sizeof(prop->pmmu));
4488c2ecf20Sopenharmony_ci	prop->pmmu_huge.page_size = PAGE_SIZE_2MB;
4498c2ecf20Sopenharmony_ci
4508c2ecf20Sopenharmony_ci	/* shifts and masks are the same in PMMU and DMMU */
4518c2ecf20Sopenharmony_ci	memcpy(&prop->dmmu, &prop->pmmu, sizeof(prop->pmmu));
4528c2ecf20Sopenharmony_ci	prop->dmmu.start_addr = (VA_HOST_SPACE_START + VA_HOST_SPACE_SIZE / 2);
4538c2ecf20Sopenharmony_ci	prop->dmmu.end_addr = VA_HOST_SPACE_END;
4548c2ecf20Sopenharmony_ci	prop->dmmu.page_size = PAGE_SIZE_2MB;
4558c2ecf20Sopenharmony_ci
4568c2ecf20Sopenharmony_ci	prop->cfg_size = CFG_SIZE;
4578c2ecf20Sopenharmony_ci	prop->max_asid = MAX_ASID;
4588c2ecf20Sopenharmony_ci	prop->num_of_events = GAUDI_EVENT_SIZE;
4598c2ecf20Sopenharmony_ci	prop->tpc_enabled_mask = TPC_ENABLED_MASK;
4608c2ecf20Sopenharmony_ci
4618c2ecf20Sopenharmony_ci	prop->max_power_default = MAX_POWER_DEFAULT_PCI;
4628c2ecf20Sopenharmony_ci
4638c2ecf20Sopenharmony_ci	prop->cb_pool_cb_cnt = GAUDI_CB_POOL_CB_CNT;
4648c2ecf20Sopenharmony_ci	prop->cb_pool_cb_size = GAUDI_CB_POOL_CB_SIZE;
4658c2ecf20Sopenharmony_ci
4668c2ecf20Sopenharmony_ci	prop->pcie_dbi_base_address = mmPCIE_DBI_BASE;
4678c2ecf20Sopenharmony_ci	prop->pcie_aux_dbi_reg_addr = CFG_BASE + mmPCIE_AUX_DBI;
4688c2ecf20Sopenharmony_ci
4698c2ecf20Sopenharmony_ci	strncpy(prop->cpucp_info.card_name, GAUDI_DEFAULT_CARD_NAME,
4708c2ecf20Sopenharmony_ci					CARD_NAME_MAX_LEN);
4718c2ecf20Sopenharmony_ci
4728c2ecf20Sopenharmony_ci	prop->max_pending_cs = GAUDI_MAX_PENDING_CS;
4738c2ecf20Sopenharmony_ci
4748c2ecf20Sopenharmony_ci	prop->first_available_user_sob[HL_GAUDI_WS_DCORE] =
4758c2ecf20Sopenharmony_ci			num_sync_stream_queues * HL_RSVD_SOBS;
4768c2ecf20Sopenharmony_ci	prop->first_available_user_mon[HL_GAUDI_WS_DCORE] =
4778c2ecf20Sopenharmony_ci			num_sync_stream_queues * HL_RSVD_MONS;
4788c2ecf20Sopenharmony_ci
4798c2ecf20Sopenharmony_ci	return 0;
4808c2ecf20Sopenharmony_ci}
4818c2ecf20Sopenharmony_ci
4828c2ecf20Sopenharmony_cistatic int gaudi_pci_bars_map(struct hl_device *hdev)
4838c2ecf20Sopenharmony_ci{
4848c2ecf20Sopenharmony_ci	static const char * const name[] = {"SRAM", "CFG", "HBM"};
4858c2ecf20Sopenharmony_ci	bool is_wc[3] = {false, false, true};
4868c2ecf20Sopenharmony_ci	int rc;
4878c2ecf20Sopenharmony_ci
4888c2ecf20Sopenharmony_ci	rc = hl_pci_bars_map(hdev, name, is_wc);
4898c2ecf20Sopenharmony_ci	if (rc)
4908c2ecf20Sopenharmony_ci		return rc;
4918c2ecf20Sopenharmony_ci
4928c2ecf20Sopenharmony_ci	hdev->rmmio = hdev->pcie_bar[CFG_BAR_ID] +
4938c2ecf20Sopenharmony_ci			(CFG_BASE - SPI_FLASH_BASE_ADDR);
4948c2ecf20Sopenharmony_ci
4958c2ecf20Sopenharmony_ci	return 0;
4968c2ecf20Sopenharmony_ci}
4978c2ecf20Sopenharmony_ci
4988c2ecf20Sopenharmony_cistatic u64 gaudi_set_hbm_bar_base(struct hl_device *hdev, u64 addr)
4998c2ecf20Sopenharmony_ci{
5008c2ecf20Sopenharmony_ci	struct gaudi_device *gaudi = hdev->asic_specific;
5018c2ecf20Sopenharmony_ci	struct hl_inbound_pci_region pci_region;
5028c2ecf20Sopenharmony_ci	u64 old_addr = addr;
5038c2ecf20Sopenharmony_ci	int rc;
5048c2ecf20Sopenharmony_ci
5058c2ecf20Sopenharmony_ci	if ((gaudi) && (gaudi->hbm_bar_cur_addr == addr))
5068c2ecf20Sopenharmony_ci		return old_addr;
5078c2ecf20Sopenharmony_ci
5088c2ecf20Sopenharmony_ci	/* Inbound Region 2 - Bar 4 - Point to HBM */
5098c2ecf20Sopenharmony_ci	pci_region.mode = PCI_BAR_MATCH_MODE;
5108c2ecf20Sopenharmony_ci	pci_region.bar = HBM_BAR_ID;
5118c2ecf20Sopenharmony_ci	pci_region.addr = addr;
5128c2ecf20Sopenharmony_ci	rc = hl_pci_set_inbound_region(hdev, 2, &pci_region);
5138c2ecf20Sopenharmony_ci	if (rc)
5148c2ecf20Sopenharmony_ci		return U64_MAX;
5158c2ecf20Sopenharmony_ci
5168c2ecf20Sopenharmony_ci	if (gaudi) {
5178c2ecf20Sopenharmony_ci		old_addr = gaudi->hbm_bar_cur_addr;
5188c2ecf20Sopenharmony_ci		gaudi->hbm_bar_cur_addr = addr;
5198c2ecf20Sopenharmony_ci	}
5208c2ecf20Sopenharmony_ci
5218c2ecf20Sopenharmony_ci	return old_addr;
5228c2ecf20Sopenharmony_ci}
5238c2ecf20Sopenharmony_ci
5248c2ecf20Sopenharmony_cistatic int gaudi_init_iatu(struct hl_device *hdev)
5258c2ecf20Sopenharmony_ci{
5268c2ecf20Sopenharmony_ci	struct hl_inbound_pci_region inbound_region;
5278c2ecf20Sopenharmony_ci	struct hl_outbound_pci_region outbound_region;
5288c2ecf20Sopenharmony_ci	int rc;
5298c2ecf20Sopenharmony_ci
5308c2ecf20Sopenharmony_ci	/* Inbound Region 0 - Bar 0 - Point to SRAM + CFG */
5318c2ecf20Sopenharmony_ci	inbound_region.mode = PCI_BAR_MATCH_MODE;
5328c2ecf20Sopenharmony_ci	inbound_region.bar = SRAM_BAR_ID;
5338c2ecf20Sopenharmony_ci	inbound_region.addr = SRAM_BASE_ADDR;
5348c2ecf20Sopenharmony_ci	rc = hl_pci_set_inbound_region(hdev, 0, &inbound_region);
5358c2ecf20Sopenharmony_ci	if (rc)
5368c2ecf20Sopenharmony_ci		goto done;
5378c2ecf20Sopenharmony_ci
5388c2ecf20Sopenharmony_ci	/* Inbound Region 1 - Bar 2 - Point to SPI FLASH */
5398c2ecf20Sopenharmony_ci	inbound_region.mode = PCI_BAR_MATCH_MODE;
5408c2ecf20Sopenharmony_ci	inbound_region.bar = CFG_BAR_ID;
5418c2ecf20Sopenharmony_ci	inbound_region.addr = SPI_FLASH_BASE_ADDR;
5428c2ecf20Sopenharmony_ci	rc = hl_pci_set_inbound_region(hdev, 1, &inbound_region);
5438c2ecf20Sopenharmony_ci	if (rc)
5448c2ecf20Sopenharmony_ci		goto done;
5458c2ecf20Sopenharmony_ci
5468c2ecf20Sopenharmony_ci	/* Inbound Region 2 - Bar 4 - Point to HBM */
5478c2ecf20Sopenharmony_ci	inbound_region.mode = PCI_BAR_MATCH_MODE;
5488c2ecf20Sopenharmony_ci	inbound_region.bar = HBM_BAR_ID;
5498c2ecf20Sopenharmony_ci	inbound_region.addr = DRAM_PHYS_BASE;
5508c2ecf20Sopenharmony_ci	rc = hl_pci_set_inbound_region(hdev, 2, &inbound_region);
5518c2ecf20Sopenharmony_ci	if (rc)
5528c2ecf20Sopenharmony_ci		goto done;
5538c2ecf20Sopenharmony_ci
5548c2ecf20Sopenharmony_ci	hdev->asic_funcs->set_dma_mask_from_fw(hdev);
5558c2ecf20Sopenharmony_ci
5568c2ecf20Sopenharmony_ci	/* Outbound Region 0 - Point to Host */
5578c2ecf20Sopenharmony_ci	outbound_region.addr = HOST_PHYS_BASE;
5588c2ecf20Sopenharmony_ci	outbound_region.size = HOST_PHYS_SIZE;
5598c2ecf20Sopenharmony_ci	rc = hl_pci_set_outbound_region(hdev, &outbound_region);
5608c2ecf20Sopenharmony_ci
5618c2ecf20Sopenharmony_cidone:
5628c2ecf20Sopenharmony_ci	return rc;
5638c2ecf20Sopenharmony_ci}
5648c2ecf20Sopenharmony_ci
5658c2ecf20Sopenharmony_cistatic int gaudi_early_init(struct hl_device *hdev)
5668c2ecf20Sopenharmony_ci{
5678c2ecf20Sopenharmony_ci	struct asic_fixed_properties *prop = &hdev->asic_prop;
5688c2ecf20Sopenharmony_ci	struct pci_dev *pdev = hdev->pdev;
5698c2ecf20Sopenharmony_ci	int rc;
5708c2ecf20Sopenharmony_ci
5718c2ecf20Sopenharmony_ci	rc = gaudi_get_fixed_properties(hdev);
5728c2ecf20Sopenharmony_ci	if (rc) {
5738c2ecf20Sopenharmony_ci		dev_err(hdev->dev, "Failed to get fixed properties\n");
5748c2ecf20Sopenharmony_ci		return rc;
5758c2ecf20Sopenharmony_ci	}
5768c2ecf20Sopenharmony_ci
5778c2ecf20Sopenharmony_ci	/* Check BAR sizes */
5788c2ecf20Sopenharmony_ci	if (pci_resource_len(pdev, SRAM_BAR_ID) != SRAM_BAR_SIZE) {
5798c2ecf20Sopenharmony_ci		dev_err(hdev->dev,
5808c2ecf20Sopenharmony_ci			"Not " HL_NAME "? BAR %d size %llu, expecting %llu\n",
5818c2ecf20Sopenharmony_ci			SRAM_BAR_ID,
5828c2ecf20Sopenharmony_ci			(unsigned long long) pci_resource_len(pdev,
5838c2ecf20Sopenharmony_ci							SRAM_BAR_ID),
5848c2ecf20Sopenharmony_ci			SRAM_BAR_SIZE);
5858c2ecf20Sopenharmony_ci		rc = -ENODEV;
5868c2ecf20Sopenharmony_ci		goto free_queue_props;
5878c2ecf20Sopenharmony_ci	}
5888c2ecf20Sopenharmony_ci
5898c2ecf20Sopenharmony_ci	if (pci_resource_len(pdev, CFG_BAR_ID) != CFG_BAR_SIZE) {
5908c2ecf20Sopenharmony_ci		dev_err(hdev->dev,
5918c2ecf20Sopenharmony_ci			"Not " HL_NAME "? BAR %d size %llu, expecting %llu\n",
5928c2ecf20Sopenharmony_ci			CFG_BAR_ID,
5938c2ecf20Sopenharmony_ci			(unsigned long long) pci_resource_len(pdev,
5948c2ecf20Sopenharmony_ci								CFG_BAR_ID),
5958c2ecf20Sopenharmony_ci			CFG_BAR_SIZE);
5968c2ecf20Sopenharmony_ci		rc = -ENODEV;
5978c2ecf20Sopenharmony_ci		goto free_queue_props;
5988c2ecf20Sopenharmony_ci	}
5998c2ecf20Sopenharmony_ci
6008c2ecf20Sopenharmony_ci	prop->dram_pci_bar_size = pci_resource_len(pdev, HBM_BAR_ID);
6018c2ecf20Sopenharmony_ci
6028c2ecf20Sopenharmony_ci	rc = hl_pci_init(hdev, mmPSOC_GLOBAL_CONF_CPU_BOOT_STATUS,
6038c2ecf20Sopenharmony_ci			mmCPU_BOOT_ERR0, GAUDI_BOOT_FIT_REQ_TIMEOUT_USEC);
6048c2ecf20Sopenharmony_ci	if (rc)
6058c2ecf20Sopenharmony_ci		goto free_queue_props;
6068c2ecf20Sopenharmony_ci
6078c2ecf20Sopenharmony_ci	/* GAUDI Firmware does not yet support security */
6088c2ecf20Sopenharmony_ci	prop->fw_security_disabled = true;
6098c2ecf20Sopenharmony_ci	dev_info(hdev->dev, "firmware-level security is disabled\n");
6108c2ecf20Sopenharmony_ci
6118c2ecf20Sopenharmony_ci	return 0;
6128c2ecf20Sopenharmony_ci
6138c2ecf20Sopenharmony_cifree_queue_props:
6148c2ecf20Sopenharmony_ci	kfree(hdev->asic_prop.hw_queues_props);
6158c2ecf20Sopenharmony_ci	return rc;
6168c2ecf20Sopenharmony_ci}
6178c2ecf20Sopenharmony_ci
6188c2ecf20Sopenharmony_cistatic int gaudi_early_fini(struct hl_device *hdev)
6198c2ecf20Sopenharmony_ci{
6208c2ecf20Sopenharmony_ci	kfree(hdev->asic_prop.hw_queues_props);
6218c2ecf20Sopenharmony_ci	hl_pci_fini(hdev);
6228c2ecf20Sopenharmony_ci
6238c2ecf20Sopenharmony_ci	return 0;
6248c2ecf20Sopenharmony_ci}
6258c2ecf20Sopenharmony_ci
6268c2ecf20Sopenharmony_ci/**
6278c2ecf20Sopenharmony_ci * gaudi_fetch_psoc_frequency - Fetch PSOC frequency values
6288c2ecf20Sopenharmony_ci *
6298c2ecf20Sopenharmony_ci * @hdev: pointer to hl_device structure
6308c2ecf20Sopenharmony_ci *
6318c2ecf20Sopenharmony_ci */
6328c2ecf20Sopenharmony_cistatic void gaudi_fetch_psoc_frequency(struct hl_device *hdev)
6338c2ecf20Sopenharmony_ci{
6348c2ecf20Sopenharmony_ci	struct asic_fixed_properties *prop = &hdev->asic_prop;
6358c2ecf20Sopenharmony_ci	u32 trace_freq = 0;
6368c2ecf20Sopenharmony_ci	u32 pll_clk = 0;
6378c2ecf20Sopenharmony_ci	u32 div_fctr = RREG32(mmPSOC_CPU_PLL_DIV_FACTOR_2);
6388c2ecf20Sopenharmony_ci	u32 div_sel = RREG32(mmPSOC_CPU_PLL_DIV_SEL_2);
6398c2ecf20Sopenharmony_ci	u32 nr = RREG32(mmPSOC_CPU_PLL_NR);
6408c2ecf20Sopenharmony_ci	u32 nf = RREG32(mmPSOC_CPU_PLL_NF);
6418c2ecf20Sopenharmony_ci	u32 od = RREG32(mmPSOC_CPU_PLL_OD);
6428c2ecf20Sopenharmony_ci
6438c2ecf20Sopenharmony_ci	if (div_sel == DIV_SEL_REF_CLK || div_sel == DIV_SEL_DIVIDED_REF) {
6448c2ecf20Sopenharmony_ci		if (div_sel == DIV_SEL_REF_CLK)
6458c2ecf20Sopenharmony_ci			trace_freq = PLL_REF_CLK;
6468c2ecf20Sopenharmony_ci		else
6478c2ecf20Sopenharmony_ci			trace_freq = PLL_REF_CLK / (div_fctr + 1);
6488c2ecf20Sopenharmony_ci	} else if (div_sel == DIV_SEL_PLL_CLK ||
6498c2ecf20Sopenharmony_ci					div_sel == DIV_SEL_DIVIDED_PLL) {
6508c2ecf20Sopenharmony_ci		pll_clk = PLL_REF_CLK * (nf + 1) / ((nr + 1) * (od + 1));
6518c2ecf20Sopenharmony_ci		if (div_sel == DIV_SEL_PLL_CLK)
6528c2ecf20Sopenharmony_ci			trace_freq = pll_clk;
6538c2ecf20Sopenharmony_ci		else
6548c2ecf20Sopenharmony_ci			trace_freq = pll_clk / (div_fctr + 1);
6558c2ecf20Sopenharmony_ci	} else {
6568c2ecf20Sopenharmony_ci		dev_warn(hdev->dev,
6578c2ecf20Sopenharmony_ci			"Received invalid div select value: %d", div_sel);
6588c2ecf20Sopenharmony_ci	}
6598c2ecf20Sopenharmony_ci
6608c2ecf20Sopenharmony_ci	prop->psoc_timestamp_frequency = trace_freq;
6618c2ecf20Sopenharmony_ci	prop->psoc_pci_pll_nr = nr;
6628c2ecf20Sopenharmony_ci	prop->psoc_pci_pll_nf = nf;
6638c2ecf20Sopenharmony_ci	prop->psoc_pci_pll_od = od;
6648c2ecf20Sopenharmony_ci	prop->psoc_pci_pll_div_factor = div_fctr;
6658c2ecf20Sopenharmony_ci}
6668c2ecf20Sopenharmony_ci
6678c2ecf20Sopenharmony_cistatic int _gaudi_init_tpc_mem(struct hl_device *hdev,
6688c2ecf20Sopenharmony_ci		dma_addr_t tpc_kernel_src_addr, u32 tpc_kernel_size)
6698c2ecf20Sopenharmony_ci{
6708c2ecf20Sopenharmony_ci	struct asic_fixed_properties *prop = &hdev->asic_prop;
6718c2ecf20Sopenharmony_ci	struct packet_lin_dma *init_tpc_mem_pkt;
6728c2ecf20Sopenharmony_ci	struct hl_cs_job *job;
6738c2ecf20Sopenharmony_ci	struct hl_cb *cb;
6748c2ecf20Sopenharmony_ci	u64 dst_addr;
6758c2ecf20Sopenharmony_ci	u32 cb_size, ctl;
6768c2ecf20Sopenharmony_ci	u8 tpc_id;
6778c2ecf20Sopenharmony_ci	int rc;
6788c2ecf20Sopenharmony_ci
6798c2ecf20Sopenharmony_ci	cb = hl_cb_kernel_create(hdev, PAGE_SIZE, false);
6808c2ecf20Sopenharmony_ci	if (!cb)
6818c2ecf20Sopenharmony_ci		return -EFAULT;
6828c2ecf20Sopenharmony_ci
6838c2ecf20Sopenharmony_ci	init_tpc_mem_pkt = cb->kernel_address;
6848c2ecf20Sopenharmony_ci	cb_size = sizeof(*init_tpc_mem_pkt);
6858c2ecf20Sopenharmony_ci	memset(init_tpc_mem_pkt, 0, cb_size);
6868c2ecf20Sopenharmony_ci
6878c2ecf20Sopenharmony_ci	init_tpc_mem_pkt->tsize = cpu_to_le32(tpc_kernel_size);
6888c2ecf20Sopenharmony_ci
6898c2ecf20Sopenharmony_ci	ctl = FIELD_PREP(GAUDI_PKT_CTL_OPCODE_MASK, PACKET_LIN_DMA);
6908c2ecf20Sopenharmony_ci	ctl |= FIELD_PREP(GAUDI_PKT_LIN_DMA_CTL_LIN_MASK, 1);
6918c2ecf20Sopenharmony_ci	ctl |= FIELD_PREP(GAUDI_PKT_CTL_RB_MASK, 1);
6928c2ecf20Sopenharmony_ci	ctl |= FIELD_PREP(GAUDI_PKT_CTL_MB_MASK, 1);
6938c2ecf20Sopenharmony_ci
6948c2ecf20Sopenharmony_ci	init_tpc_mem_pkt->ctl = cpu_to_le32(ctl);
6958c2ecf20Sopenharmony_ci
6968c2ecf20Sopenharmony_ci	init_tpc_mem_pkt->src_addr = cpu_to_le64(tpc_kernel_src_addr);
6978c2ecf20Sopenharmony_ci	dst_addr = (prop->sram_user_base_address &
6988c2ecf20Sopenharmony_ci			GAUDI_PKT_LIN_DMA_DST_ADDR_MASK) >>
6998c2ecf20Sopenharmony_ci			GAUDI_PKT_LIN_DMA_DST_ADDR_SHIFT;
7008c2ecf20Sopenharmony_ci	init_tpc_mem_pkt->dst_addr |= cpu_to_le64(dst_addr);
7018c2ecf20Sopenharmony_ci
7028c2ecf20Sopenharmony_ci	job = hl_cs_allocate_job(hdev, QUEUE_TYPE_EXT, true);
7038c2ecf20Sopenharmony_ci	if (!job) {
7048c2ecf20Sopenharmony_ci		dev_err(hdev->dev, "Failed to allocate a new job\n");
7058c2ecf20Sopenharmony_ci		rc = -ENOMEM;
7068c2ecf20Sopenharmony_ci		goto release_cb;
7078c2ecf20Sopenharmony_ci	}
7088c2ecf20Sopenharmony_ci
7098c2ecf20Sopenharmony_ci	job->id = 0;
7108c2ecf20Sopenharmony_ci	job->user_cb = cb;
7118c2ecf20Sopenharmony_ci	job->user_cb->cs_cnt++;
7128c2ecf20Sopenharmony_ci	job->user_cb_size = cb_size;
7138c2ecf20Sopenharmony_ci	job->hw_queue_id = GAUDI_QUEUE_ID_DMA_0_0;
7148c2ecf20Sopenharmony_ci	job->patched_cb = job->user_cb;
7158c2ecf20Sopenharmony_ci	job->job_cb_size = job->user_cb_size + sizeof(struct packet_msg_prot);
7168c2ecf20Sopenharmony_ci
7178c2ecf20Sopenharmony_ci	hl_debugfs_add_job(hdev, job);
7188c2ecf20Sopenharmony_ci
7198c2ecf20Sopenharmony_ci	rc = gaudi_send_job_on_qman0(hdev, job);
7208c2ecf20Sopenharmony_ci
7218c2ecf20Sopenharmony_ci	if (rc)
7228c2ecf20Sopenharmony_ci		goto free_job;
7238c2ecf20Sopenharmony_ci
7248c2ecf20Sopenharmony_ci	for (tpc_id = 0 ; tpc_id < TPC_NUMBER_OF_ENGINES ; tpc_id++) {
7258c2ecf20Sopenharmony_ci		rc = gaudi_run_tpc_kernel(hdev, dst_addr, tpc_id);
7268c2ecf20Sopenharmony_ci		if (rc)
7278c2ecf20Sopenharmony_ci			break;
7288c2ecf20Sopenharmony_ci	}
7298c2ecf20Sopenharmony_ci
7308c2ecf20Sopenharmony_cifree_job:
7318c2ecf20Sopenharmony_ci	hl_userptr_delete_list(hdev, &job->userptr_list);
7328c2ecf20Sopenharmony_ci	hl_debugfs_remove_job(hdev, job);
7338c2ecf20Sopenharmony_ci	kfree(job);
7348c2ecf20Sopenharmony_ci	cb->cs_cnt--;
7358c2ecf20Sopenharmony_ci
7368c2ecf20Sopenharmony_cirelease_cb:
7378c2ecf20Sopenharmony_ci	hl_cb_put(cb);
7388c2ecf20Sopenharmony_ci	hl_cb_destroy(hdev, &hdev->kernel_cb_mgr, cb->id << PAGE_SHIFT);
7398c2ecf20Sopenharmony_ci
7408c2ecf20Sopenharmony_ci	return rc;
7418c2ecf20Sopenharmony_ci}
7428c2ecf20Sopenharmony_ci
7438c2ecf20Sopenharmony_ci/*
7448c2ecf20Sopenharmony_ci * gaudi_init_tpc_mem() - Initialize TPC memories.
7458c2ecf20Sopenharmony_ci * @hdev: Pointer to hl_device structure.
7468c2ecf20Sopenharmony_ci *
7478c2ecf20Sopenharmony_ci * Copy TPC kernel fw from firmware file and run it to initialize TPC memories.
7488c2ecf20Sopenharmony_ci *
7498c2ecf20Sopenharmony_ci * Return: 0 for success, negative value for error.
7508c2ecf20Sopenharmony_ci */
7518c2ecf20Sopenharmony_cistatic int gaudi_init_tpc_mem(struct hl_device *hdev)
7528c2ecf20Sopenharmony_ci{
7538c2ecf20Sopenharmony_ci	const struct firmware *fw;
7548c2ecf20Sopenharmony_ci	size_t fw_size;
7558c2ecf20Sopenharmony_ci	void *cpu_addr;
7568c2ecf20Sopenharmony_ci	dma_addr_t dma_handle;
7578c2ecf20Sopenharmony_ci	int rc, count = 5;
7588c2ecf20Sopenharmony_ci
7598c2ecf20Sopenharmony_ciagain:
7608c2ecf20Sopenharmony_ci	rc = request_firmware(&fw, GAUDI_TPC_FW_FILE, hdev->dev);
7618c2ecf20Sopenharmony_ci	if (rc == -EINTR && count-- > 0) {
7628c2ecf20Sopenharmony_ci		msleep(50);
7638c2ecf20Sopenharmony_ci		goto again;
7648c2ecf20Sopenharmony_ci	}
7658c2ecf20Sopenharmony_ci
7668c2ecf20Sopenharmony_ci	if (rc) {
7678c2ecf20Sopenharmony_ci		dev_err(hdev->dev, "Failed to load firmware file %s\n",
7688c2ecf20Sopenharmony_ci				GAUDI_TPC_FW_FILE);
7698c2ecf20Sopenharmony_ci		goto out;
7708c2ecf20Sopenharmony_ci	}
7718c2ecf20Sopenharmony_ci
7728c2ecf20Sopenharmony_ci	fw_size = fw->size;
7738c2ecf20Sopenharmony_ci	cpu_addr = hdev->asic_funcs->asic_dma_alloc_coherent(hdev, fw_size,
7748c2ecf20Sopenharmony_ci			&dma_handle, GFP_KERNEL | __GFP_ZERO);
7758c2ecf20Sopenharmony_ci	if (!cpu_addr) {
7768c2ecf20Sopenharmony_ci		dev_err(hdev->dev,
7778c2ecf20Sopenharmony_ci			"Failed to allocate %zu of dma memory for TPC kernel\n",
7788c2ecf20Sopenharmony_ci			fw_size);
7798c2ecf20Sopenharmony_ci		rc = -ENOMEM;
7808c2ecf20Sopenharmony_ci		goto out;
7818c2ecf20Sopenharmony_ci	}
7828c2ecf20Sopenharmony_ci
7838c2ecf20Sopenharmony_ci	memcpy(cpu_addr, fw->data, fw_size);
7848c2ecf20Sopenharmony_ci
7858c2ecf20Sopenharmony_ci	rc = _gaudi_init_tpc_mem(hdev, dma_handle, fw_size);
7868c2ecf20Sopenharmony_ci
7878c2ecf20Sopenharmony_ci	hdev->asic_funcs->asic_dma_free_coherent(hdev, fw->size, cpu_addr,
7888c2ecf20Sopenharmony_ci			dma_handle);
7898c2ecf20Sopenharmony_ci
7908c2ecf20Sopenharmony_ciout:
7918c2ecf20Sopenharmony_ci	release_firmware(fw);
7928c2ecf20Sopenharmony_ci	return rc;
7938c2ecf20Sopenharmony_ci}
7948c2ecf20Sopenharmony_ci
7958c2ecf20Sopenharmony_cistatic int gaudi_late_init(struct hl_device *hdev)
7968c2ecf20Sopenharmony_ci{
7978c2ecf20Sopenharmony_ci	struct gaudi_device *gaudi = hdev->asic_specific;
7988c2ecf20Sopenharmony_ci	int rc;
7998c2ecf20Sopenharmony_ci
8008c2ecf20Sopenharmony_ci	rc = gaudi->cpucp_info_get(hdev);
8018c2ecf20Sopenharmony_ci	if (rc) {
8028c2ecf20Sopenharmony_ci		dev_err(hdev->dev, "Failed to get cpucp info\n");
8038c2ecf20Sopenharmony_ci		return rc;
8048c2ecf20Sopenharmony_ci	}
8058c2ecf20Sopenharmony_ci
8068c2ecf20Sopenharmony_ci	rc = hl_fw_send_pci_access_msg(hdev, CPUCP_PACKET_ENABLE_PCI_ACCESS);
8078c2ecf20Sopenharmony_ci	if (rc) {
8088c2ecf20Sopenharmony_ci		dev_err(hdev->dev, "Failed to enable PCI access from CPU\n");
8098c2ecf20Sopenharmony_ci		return rc;
8108c2ecf20Sopenharmony_ci	}
8118c2ecf20Sopenharmony_ci
8128c2ecf20Sopenharmony_ci	WREG32(mmGIC_DISTRIBUTOR__5_GICD_SETSPI_NSR, GAUDI_EVENT_INTS_REGISTER);
8138c2ecf20Sopenharmony_ci
8148c2ecf20Sopenharmony_ci	gaudi_fetch_psoc_frequency(hdev);
8158c2ecf20Sopenharmony_ci
8168c2ecf20Sopenharmony_ci	rc = gaudi_mmu_clear_pgt_range(hdev);
8178c2ecf20Sopenharmony_ci	if (rc) {
8188c2ecf20Sopenharmony_ci		dev_err(hdev->dev, "Failed to clear MMU page tables range\n");
8198c2ecf20Sopenharmony_ci		goto disable_pci_access;
8208c2ecf20Sopenharmony_ci	}
8218c2ecf20Sopenharmony_ci
8228c2ecf20Sopenharmony_ci	rc = gaudi_init_tpc_mem(hdev);
8238c2ecf20Sopenharmony_ci	if (rc) {
8248c2ecf20Sopenharmony_ci		dev_err(hdev->dev, "Failed to initialize TPC memories\n");
8258c2ecf20Sopenharmony_ci		goto disable_pci_access;
8268c2ecf20Sopenharmony_ci	}
8278c2ecf20Sopenharmony_ci
8288c2ecf20Sopenharmony_ci	return 0;
8298c2ecf20Sopenharmony_ci
8308c2ecf20Sopenharmony_cidisable_pci_access:
8318c2ecf20Sopenharmony_ci	hl_fw_send_pci_access_msg(hdev, CPUCP_PACKET_DISABLE_PCI_ACCESS);
8328c2ecf20Sopenharmony_ci
8338c2ecf20Sopenharmony_ci	return rc;
8348c2ecf20Sopenharmony_ci}
8358c2ecf20Sopenharmony_ci
8368c2ecf20Sopenharmony_cistatic void gaudi_late_fini(struct hl_device *hdev)
8378c2ecf20Sopenharmony_ci{
8388c2ecf20Sopenharmony_ci	const struct hwmon_channel_info **channel_info_arr;
8398c2ecf20Sopenharmony_ci	int i = 0;
8408c2ecf20Sopenharmony_ci
8418c2ecf20Sopenharmony_ci	if (!hdev->hl_chip_info->info)
8428c2ecf20Sopenharmony_ci		return;
8438c2ecf20Sopenharmony_ci
8448c2ecf20Sopenharmony_ci	channel_info_arr = hdev->hl_chip_info->info;
8458c2ecf20Sopenharmony_ci
8468c2ecf20Sopenharmony_ci	while (channel_info_arr[i]) {
8478c2ecf20Sopenharmony_ci		kfree(channel_info_arr[i]->config);
8488c2ecf20Sopenharmony_ci		kfree(channel_info_arr[i]);
8498c2ecf20Sopenharmony_ci		i++;
8508c2ecf20Sopenharmony_ci	}
8518c2ecf20Sopenharmony_ci
8528c2ecf20Sopenharmony_ci	kfree(channel_info_arr);
8538c2ecf20Sopenharmony_ci
8548c2ecf20Sopenharmony_ci	hdev->hl_chip_info->info = NULL;
8558c2ecf20Sopenharmony_ci}
8568c2ecf20Sopenharmony_ci
8578c2ecf20Sopenharmony_cistatic int gaudi_alloc_cpu_accessible_dma_mem(struct hl_device *hdev)
8588c2ecf20Sopenharmony_ci{
8598c2ecf20Sopenharmony_ci	dma_addr_t dma_addr_arr[GAUDI_ALLOC_CPU_MEM_RETRY_CNT] = {}, end_addr;
8608c2ecf20Sopenharmony_ci	void *virt_addr_arr[GAUDI_ALLOC_CPU_MEM_RETRY_CNT] = {};
8618c2ecf20Sopenharmony_ci	int i, j, rc = 0;
8628c2ecf20Sopenharmony_ci
8638c2ecf20Sopenharmony_ci	/*
8648c2ecf20Sopenharmony_ci	 * The device CPU works with 40-bits addresses, while bit 39 must be set
8658c2ecf20Sopenharmony_ci	 * to '1' when accessing the host.
8668c2ecf20Sopenharmony_ci	 * Bits 49:39 of the full host address are saved for a later
8678c2ecf20Sopenharmony_ci	 * configuration of the HW to perform extension to 50 bits.
8688c2ecf20Sopenharmony_ci	 * Because there is a single HW register that holds the extension bits,
8698c2ecf20Sopenharmony_ci	 * these bits must be identical in all allocated range.
8708c2ecf20Sopenharmony_ci	 */
8718c2ecf20Sopenharmony_ci
8728c2ecf20Sopenharmony_ci	for (i = 0 ; i < GAUDI_ALLOC_CPU_MEM_RETRY_CNT ; i++) {
8738c2ecf20Sopenharmony_ci		virt_addr_arr[i] =
8748c2ecf20Sopenharmony_ci			hdev->asic_funcs->asic_dma_alloc_coherent(hdev,
8758c2ecf20Sopenharmony_ci						HL_CPU_ACCESSIBLE_MEM_SIZE,
8768c2ecf20Sopenharmony_ci						&dma_addr_arr[i],
8778c2ecf20Sopenharmony_ci						GFP_KERNEL | __GFP_ZERO);
8788c2ecf20Sopenharmony_ci		if (!virt_addr_arr[i]) {
8798c2ecf20Sopenharmony_ci			rc = -ENOMEM;
8808c2ecf20Sopenharmony_ci			goto free_dma_mem_arr;
8818c2ecf20Sopenharmony_ci		}
8828c2ecf20Sopenharmony_ci
8838c2ecf20Sopenharmony_ci		end_addr = dma_addr_arr[i] + HL_CPU_ACCESSIBLE_MEM_SIZE - 1;
8848c2ecf20Sopenharmony_ci		if (GAUDI_CPU_PCI_MSB_ADDR(dma_addr_arr[i]) ==
8858c2ecf20Sopenharmony_ci				GAUDI_CPU_PCI_MSB_ADDR(end_addr))
8868c2ecf20Sopenharmony_ci			break;
8878c2ecf20Sopenharmony_ci	}
8888c2ecf20Sopenharmony_ci
8898c2ecf20Sopenharmony_ci	if (i == GAUDI_ALLOC_CPU_MEM_RETRY_CNT) {
8908c2ecf20Sopenharmony_ci		dev_err(hdev->dev,
8918c2ecf20Sopenharmony_ci			"MSB of CPU accessible DMA memory are not identical in all range\n");
8928c2ecf20Sopenharmony_ci		rc = -EFAULT;
8938c2ecf20Sopenharmony_ci		goto free_dma_mem_arr;
8948c2ecf20Sopenharmony_ci	}
8958c2ecf20Sopenharmony_ci
8968c2ecf20Sopenharmony_ci	hdev->cpu_accessible_dma_mem = virt_addr_arr[i];
8978c2ecf20Sopenharmony_ci	hdev->cpu_accessible_dma_address = dma_addr_arr[i];
8988c2ecf20Sopenharmony_ci	hdev->cpu_pci_msb_addr =
8998c2ecf20Sopenharmony_ci		GAUDI_CPU_PCI_MSB_ADDR(hdev->cpu_accessible_dma_address);
9008c2ecf20Sopenharmony_ci
9018c2ecf20Sopenharmony_ci	GAUDI_PCI_TO_CPU_ADDR(hdev->cpu_accessible_dma_address);
9028c2ecf20Sopenharmony_ci
9038c2ecf20Sopenharmony_cifree_dma_mem_arr:
9048c2ecf20Sopenharmony_ci	for (j = 0 ; j < i ; j++)
9058c2ecf20Sopenharmony_ci		hdev->asic_funcs->asic_dma_free_coherent(hdev,
9068c2ecf20Sopenharmony_ci						HL_CPU_ACCESSIBLE_MEM_SIZE,
9078c2ecf20Sopenharmony_ci						virt_addr_arr[j],
9088c2ecf20Sopenharmony_ci						dma_addr_arr[j]);
9098c2ecf20Sopenharmony_ci
9108c2ecf20Sopenharmony_ci	return rc;
9118c2ecf20Sopenharmony_ci}
9128c2ecf20Sopenharmony_ci
9138c2ecf20Sopenharmony_cistatic void gaudi_free_internal_qmans_pq_mem(struct hl_device *hdev)
9148c2ecf20Sopenharmony_ci{
9158c2ecf20Sopenharmony_ci	struct gaudi_device *gaudi = hdev->asic_specific;
9168c2ecf20Sopenharmony_ci	struct gaudi_internal_qman_info *q;
9178c2ecf20Sopenharmony_ci	u32 i;
9188c2ecf20Sopenharmony_ci
9198c2ecf20Sopenharmony_ci	for (i = 0 ; i < GAUDI_QUEUE_ID_SIZE ; i++) {
9208c2ecf20Sopenharmony_ci		q = &gaudi->internal_qmans[i];
9218c2ecf20Sopenharmony_ci		if (!q->pq_kernel_addr)
9228c2ecf20Sopenharmony_ci			continue;
9238c2ecf20Sopenharmony_ci		hdev->asic_funcs->asic_dma_free_coherent(hdev, q->pq_size,
9248c2ecf20Sopenharmony_ci							q->pq_kernel_addr,
9258c2ecf20Sopenharmony_ci							q->pq_dma_addr);
9268c2ecf20Sopenharmony_ci	}
9278c2ecf20Sopenharmony_ci}
9288c2ecf20Sopenharmony_ci
9298c2ecf20Sopenharmony_cistatic int gaudi_alloc_internal_qmans_pq_mem(struct hl_device *hdev)
9308c2ecf20Sopenharmony_ci{
9318c2ecf20Sopenharmony_ci	struct gaudi_device *gaudi = hdev->asic_specific;
9328c2ecf20Sopenharmony_ci	struct gaudi_internal_qman_info *q;
9338c2ecf20Sopenharmony_ci	int rc, i;
9348c2ecf20Sopenharmony_ci
9358c2ecf20Sopenharmony_ci	for (i = 0 ; i < GAUDI_QUEUE_ID_SIZE ; i++) {
9368c2ecf20Sopenharmony_ci		if (gaudi_queue_type[i] != QUEUE_TYPE_INT)
9378c2ecf20Sopenharmony_ci			continue;
9388c2ecf20Sopenharmony_ci
9398c2ecf20Sopenharmony_ci		q = &gaudi->internal_qmans[i];
9408c2ecf20Sopenharmony_ci
9418c2ecf20Sopenharmony_ci		switch (i) {
9428c2ecf20Sopenharmony_ci		case GAUDI_QUEUE_ID_DMA_2_0 ... GAUDI_QUEUE_ID_DMA_4_3:
9438c2ecf20Sopenharmony_ci		case GAUDI_QUEUE_ID_DMA_6_0 ... GAUDI_QUEUE_ID_DMA_7_3:
9448c2ecf20Sopenharmony_ci			q->pq_size = HBM_DMA_QMAN_SIZE_IN_BYTES;
9458c2ecf20Sopenharmony_ci			break;
9468c2ecf20Sopenharmony_ci		case GAUDI_QUEUE_ID_MME_0_0 ... GAUDI_QUEUE_ID_MME_1_3:
9478c2ecf20Sopenharmony_ci			q->pq_size = MME_QMAN_SIZE_IN_BYTES;
9488c2ecf20Sopenharmony_ci			break;
9498c2ecf20Sopenharmony_ci		case GAUDI_QUEUE_ID_TPC_0_0 ... GAUDI_QUEUE_ID_TPC_7_3:
9508c2ecf20Sopenharmony_ci			q->pq_size = TPC_QMAN_SIZE_IN_BYTES;
9518c2ecf20Sopenharmony_ci			break;
9528c2ecf20Sopenharmony_ci		default:
9538c2ecf20Sopenharmony_ci			dev_err(hdev->dev, "Bad internal queue index %d", i);
9548c2ecf20Sopenharmony_ci			rc = -EINVAL;
9558c2ecf20Sopenharmony_ci			goto free_internal_qmans_pq_mem;
9568c2ecf20Sopenharmony_ci		}
9578c2ecf20Sopenharmony_ci
9588c2ecf20Sopenharmony_ci		q->pq_kernel_addr = hdev->asic_funcs->asic_dma_alloc_coherent(
9598c2ecf20Sopenharmony_ci						hdev, q->pq_size,
9608c2ecf20Sopenharmony_ci						&q->pq_dma_addr,
9618c2ecf20Sopenharmony_ci						GFP_KERNEL | __GFP_ZERO);
9628c2ecf20Sopenharmony_ci		if (!q->pq_kernel_addr) {
9638c2ecf20Sopenharmony_ci			rc = -ENOMEM;
9648c2ecf20Sopenharmony_ci			goto free_internal_qmans_pq_mem;
9658c2ecf20Sopenharmony_ci		}
9668c2ecf20Sopenharmony_ci	}
9678c2ecf20Sopenharmony_ci
9688c2ecf20Sopenharmony_ci	return 0;
9698c2ecf20Sopenharmony_ci
9708c2ecf20Sopenharmony_cifree_internal_qmans_pq_mem:
9718c2ecf20Sopenharmony_ci	gaudi_free_internal_qmans_pq_mem(hdev);
9728c2ecf20Sopenharmony_ci	return rc;
9738c2ecf20Sopenharmony_ci}
9748c2ecf20Sopenharmony_ci
9758c2ecf20Sopenharmony_cistatic int gaudi_sw_init(struct hl_device *hdev)
9768c2ecf20Sopenharmony_ci{
9778c2ecf20Sopenharmony_ci	struct gaudi_device *gaudi;
9788c2ecf20Sopenharmony_ci	u32 i, event_id = 0;
9798c2ecf20Sopenharmony_ci	int rc;
9808c2ecf20Sopenharmony_ci
9818c2ecf20Sopenharmony_ci	/* Allocate device structure */
9828c2ecf20Sopenharmony_ci	gaudi = kzalloc(sizeof(*gaudi), GFP_KERNEL);
9838c2ecf20Sopenharmony_ci	if (!gaudi)
9848c2ecf20Sopenharmony_ci		return -ENOMEM;
9858c2ecf20Sopenharmony_ci
9868c2ecf20Sopenharmony_ci	for (i = 0 ; i < ARRAY_SIZE(gaudi_irq_map_table) ; i++) {
9878c2ecf20Sopenharmony_ci		if (gaudi_irq_map_table[i].valid) {
9888c2ecf20Sopenharmony_ci			if (event_id == GAUDI_EVENT_SIZE) {
9898c2ecf20Sopenharmony_ci				dev_err(hdev->dev,
9908c2ecf20Sopenharmony_ci					"Event array exceeds the limit of %u events\n",
9918c2ecf20Sopenharmony_ci					GAUDI_EVENT_SIZE);
9928c2ecf20Sopenharmony_ci				rc = -EINVAL;
9938c2ecf20Sopenharmony_ci				goto free_gaudi_device;
9948c2ecf20Sopenharmony_ci			}
9958c2ecf20Sopenharmony_ci
9968c2ecf20Sopenharmony_ci			gaudi->events[event_id++] =
9978c2ecf20Sopenharmony_ci					gaudi_irq_map_table[i].fc_id;
9988c2ecf20Sopenharmony_ci		}
9998c2ecf20Sopenharmony_ci	}
10008c2ecf20Sopenharmony_ci
10018c2ecf20Sopenharmony_ci	gaudi->cpucp_info_get = gaudi_cpucp_info_get;
10028c2ecf20Sopenharmony_ci
10038c2ecf20Sopenharmony_ci	gaudi->max_freq_value = GAUDI_MAX_CLK_FREQ;
10048c2ecf20Sopenharmony_ci
10058c2ecf20Sopenharmony_ci	hdev->asic_specific = gaudi;
10068c2ecf20Sopenharmony_ci
10078c2ecf20Sopenharmony_ci	/* Create DMA pool for small allocations */
10088c2ecf20Sopenharmony_ci	hdev->dma_pool = dma_pool_create(dev_name(hdev->dev),
10098c2ecf20Sopenharmony_ci			&hdev->pdev->dev, GAUDI_DMA_POOL_BLK_SIZE, 8, 0);
10108c2ecf20Sopenharmony_ci	if (!hdev->dma_pool) {
10118c2ecf20Sopenharmony_ci		dev_err(hdev->dev, "failed to create DMA pool\n");
10128c2ecf20Sopenharmony_ci		rc = -ENOMEM;
10138c2ecf20Sopenharmony_ci		goto free_gaudi_device;
10148c2ecf20Sopenharmony_ci	}
10158c2ecf20Sopenharmony_ci
10168c2ecf20Sopenharmony_ci	rc = gaudi_alloc_cpu_accessible_dma_mem(hdev);
10178c2ecf20Sopenharmony_ci	if (rc)
10188c2ecf20Sopenharmony_ci		goto free_dma_pool;
10198c2ecf20Sopenharmony_ci
10208c2ecf20Sopenharmony_ci	hdev->cpu_accessible_dma_pool = gen_pool_create(ilog2(32), -1);
10218c2ecf20Sopenharmony_ci	if (!hdev->cpu_accessible_dma_pool) {
10228c2ecf20Sopenharmony_ci		dev_err(hdev->dev,
10238c2ecf20Sopenharmony_ci			"Failed to create CPU accessible DMA pool\n");
10248c2ecf20Sopenharmony_ci		rc = -ENOMEM;
10258c2ecf20Sopenharmony_ci		goto free_cpu_dma_mem;
10268c2ecf20Sopenharmony_ci	}
10278c2ecf20Sopenharmony_ci
10288c2ecf20Sopenharmony_ci	rc = gen_pool_add(hdev->cpu_accessible_dma_pool,
10298c2ecf20Sopenharmony_ci				(uintptr_t) hdev->cpu_accessible_dma_mem,
10308c2ecf20Sopenharmony_ci				HL_CPU_ACCESSIBLE_MEM_SIZE, -1);
10318c2ecf20Sopenharmony_ci	if (rc) {
10328c2ecf20Sopenharmony_ci		dev_err(hdev->dev,
10338c2ecf20Sopenharmony_ci			"Failed to add memory to CPU accessible DMA pool\n");
10348c2ecf20Sopenharmony_ci		rc = -EFAULT;
10358c2ecf20Sopenharmony_ci		goto free_cpu_accessible_dma_pool;
10368c2ecf20Sopenharmony_ci	}
10378c2ecf20Sopenharmony_ci
10388c2ecf20Sopenharmony_ci	rc = gaudi_alloc_internal_qmans_pq_mem(hdev);
10398c2ecf20Sopenharmony_ci	if (rc)
10408c2ecf20Sopenharmony_ci		goto free_cpu_accessible_dma_pool;
10418c2ecf20Sopenharmony_ci
10428c2ecf20Sopenharmony_ci	spin_lock_init(&gaudi->hw_queues_lock);
10438c2ecf20Sopenharmony_ci	mutex_init(&gaudi->clk_gate_mutex);
10448c2ecf20Sopenharmony_ci
10458c2ecf20Sopenharmony_ci	hdev->supports_sync_stream = true;
10468c2ecf20Sopenharmony_ci	hdev->supports_coresight = true;
10478c2ecf20Sopenharmony_ci
10488c2ecf20Sopenharmony_ci	return 0;
10498c2ecf20Sopenharmony_ci
10508c2ecf20Sopenharmony_cifree_cpu_accessible_dma_pool:
10518c2ecf20Sopenharmony_ci	gen_pool_destroy(hdev->cpu_accessible_dma_pool);
10528c2ecf20Sopenharmony_cifree_cpu_dma_mem:
10538c2ecf20Sopenharmony_ci	GAUDI_CPU_TO_PCI_ADDR(hdev->cpu_accessible_dma_address,
10548c2ecf20Sopenharmony_ci				hdev->cpu_pci_msb_addr);
10558c2ecf20Sopenharmony_ci	hdev->asic_funcs->asic_dma_free_coherent(hdev,
10568c2ecf20Sopenharmony_ci			HL_CPU_ACCESSIBLE_MEM_SIZE,
10578c2ecf20Sopenharmony_ci			hdev->cpu_accessible_dma_mem,
10588c2ecf20Sopenharmony_ci			hdev->cpu_accessible_dma_address);
10598c2ecf20Sopenharmony_cifree_dma_pool:
10608c2ecf20Sopenharmony_ci	dma_pool_destroy(hdev->dma_pool);
10618c2ecf20Sopenharmony_cifree_gaudi_device:
10628c2ecf20Sopenharmony_ci	kfree(gaudi);
10638c2ecf20Sopenharmony_ci	return rc;
10648c2ecf20Sopenharmony_ci}
10658c2ecf20Sopenharmony_ci
10668c2ecf20Sopenharmony_cistatic int gaudi_sw_fini(struct hl_device *hdev)
10678c2ecf20Sopenharmony_ci{
10688c2ecf20Sopenharmony_ci	struct gaudi_device *gaudi = hdev->asic_specific;
10698c2ecf20Sopenharmony_ci
10708c2ecf20Sopenharmony_ci	gaudi_free_internal_qmans_pq_mem(hdev);
10718c2ecf20Sopenharmony_ci
10728c2ecf20Sopenharmony_ci	gen_pool_destroy(hdev->cpu_accessible_dma_pool);
10738c2ecf20Sopenharmony_ci
10748c2ecf20Sopenharmony_ci	GAUDI_CPU_TO_PCI_ADDR(hdev->cpu_accessible_dma_address,
10758c2ecf20Sopenharmony_ci					hdev->cpu_pci_msb_addr);
10768c2ecf20Sopenharmony_ci	hdev->asic_funcs->asic_dma_free_coherent(hdev,
10778c2ecf20Sopenharmony_ci			HL_CPU_ACCESSIBLE_MEM_SIZE,
10788c2ecf20Sopenharmony_ci			hdev->cpu_accessible_dma_mem,
10798c2ecf20Sopenharmony_ci			hdev->cpu_accessible_dma_address);
10808c2ecf20Sopenharmony_ci
10818c2ecf20Sopenharmony_ci	dma_pool_destroy(hdev->dma_pool);
10828c2ecf20Sopenharmony_ci
10838c2ecf20Sopenharmony_ci	mutex_destroy(&gaudi->clk_gate_mutex);
10848c2ecf20Sopenharmony_ci
10858c2ecf20Sopenharmony_ci	kfree(gaudi);
10868c2ecf20Sopenharmony_ci
10878c2ecf20Sopenharmony_ci	return 0;
10888c2ecf20Sopenharmony_ci}
10898c2ecf20Sopenharmony_ci
10908c2ecf20Sopenharmony_cistatic irqreturn_t gaudi_irq_handler_single(int irq, void *arg)
10918c2ecf20Sopenharmony_ci{
10928c2ecf20Sopenharmony_ci	struct hl_device *hdev = arg;
10938c2ecf20Sopenharmony_ci	int i;
10948c2ecf20Sopenharmony_ci
10958c2ecf20Sopenharmony_ci	if (hdev->disabled)
10968c2ecf20Sopenharmony_ci		return IRQ_HANDLED;
10978c2ecf20Sopenharmony_ci
10988c2ecf20Sopenharmony_ci	for (i = 0 ; i < hdev->asic_prop.completion_queues_count ; i++)
10998c2ecf20Sopenharmony_ci		hl_irq_handler_cq(irq, &hdev->completion_queue[i]);
11008c2ecf20Sopenharmony_ci
11018c2ecf20Sopenharmony_ci	hl_irq_handler_eq(irq, &hdev->event_queue);
11028c2ecf20Sopenharmony_ci
11038c2ecf20Sopenharmony_ci	return IRQ_HANDLED;
11048c2ecf20Sopenharmony_ci}
11058c2ecf20Sopenharmony_ci
11068c2ecf20Sopenharmony_ci/*
11078c2ecf20Sopenharmony_ci * For backward compatibility, new MSI interrupts should be set after the
11088c2ecf20Sopenharmony_ci * existing CPU and NIC interrupts.
11098c2ecf20Sopenharmony_ci */
11108c2ecf20Sopenharmony_cistatic int gaudi_pci_irq_vector(struct hl_device *hdev, unsigned int nr,
11118c2ecf20Sopenharmony_ci				bool cpu_eq)
11128c2ecf20Sopenharmony_ci{
11138c2ecf20Sopenharmony_ci	int msi_vec;
11148c2ecf20Sopenharmony_ci
11158c2ecf20Sopenharmony_ci	if ((nr != GAUDI_EVENT_QUEUE_MSI_IDX) && (cpu_eq))
11168c2ecf20Sopenharmony_ci		dev_crit(hdev->dev, "CPU EQ must use IRQ %d\n",
11178c2ecf20Sopenharmony_ci				GAUDI_EVENT_QUEUE_MSI_IDX);
11188c2ecf20Sopenharmony_ci
11198c2ecf20Sopenharmony_ci	msi_vec = ((nr < GAUDI_EVENT_QUEUE_MSI_IDX) || (cpu_eq)) ? nr :
11208c2ecf20Sopenharmony_ci			(nr + NIC_NUMBER_OF_ENGINES + 1);
11218c2ecf20Sopenharmony_ci
11228c2ecf20Sopenharmony_ci	return pci_irq_vector(hdev->pdev, msi_vec);
11238c2ecf20Sopenharmony_ci}
11248c2ecf20Sopenharmony_ci
11258c2ecf20Sopenharmony_cistatic int gaudi_enable_msi_single(struct hl_device *hdev)
11268c2ecf20Sopenharmony_ci{
11278c2ecf20Sopenharmony_ci	int rc, irq;
11288c2ecf20Sopenharmony_ci
11298c2ecf20Sopenharmony_ci	dev_info(hdev->dev, "Working in single MSI IRQ mode\n");
11308c2ecf20Sopenharmony_ci
11318c2ecf20Sopenharmony_ci	irq = gaudi_pci_irq_vector(hdev, 0, false);
11328c2ecf20Sopenharmony_ci	rc = request_irq(irq, gaudi_irq_handler_single, 0,
11338c2ecf20Sopenharmony_ci			"gaudi single msi", hdev);
11348c2ecf20Sopenharmony_ci	if (rc)
11358c2ecf20Sopenharmony_ci		dev_err(hdev->dev,
11368c2ecf20Sopenharmony_ci			"Failed to request single MSI IRQ\n");
11378c2ecf20Sopenharmony_ci
11388c2ecf20Sopenharmony_ci	return rc;
11398c2ecf20Sopenharmony_ci}
11408c2ecf20Sopenharmony_ci
11418c2ecf20Sopenharmony_cistatic int gaudi_enable_msi_multi(struct hl_device *hdev)
11428c2ecf20Sopenharmony_ci{
11438c2ecf20Sopenharmony_ci	int cq_cnt = hdev->asic_prop.completion_queues_count;
11448c2ecf20Sopenharmony_ci	int rc, i, irq_cnt_init, irq;
11458c2ecf20Sopenharmony_ci
11468c2ecf20Sopenharmony_ci	for (i = 0, irq_cnt_init = 0 ; i < cq_cnt ; i++, irq_cnt_init++) {
11478c2ecf20Sopenharmony_ci		irq = gaudi_pci_irq_vector(hdev, i, false);
11488c2ecf20Sopenharmony_ci		rc = request_irq(irq, hl_irq_handler_cq, 0, gaudi_irq_name[i],
11498c2ecf20Sopenharmony_ci				&hdev->completion_queue[i]);
11508c2ecf20Sopenharmony_ci		if (rc) {
11518c2ecf20Sopenharmony_ci			dev_err(hdev->dev, "Failed to request IRQ %d", irq);
11528c2ecf20Sopenharmony_ci			goto free_irqs;
11538c2ecf20Sopenharmony_ci		}
11548c2ecf20Sopenharmony_ci	}
11558c2ecf20Sopenharmony_ci
11568c2ecf20Sopenharmony_ci	irq = gaudi_pci_irq_vector(hdev, GAUDI_EVENT_QUEUE_MSI_IDX, true);
11578c2ecf20Sopenharmony_ci	rc = request_irq(irq, hl_irq_handler_eq, 0, gaudi_irq_name[cq_cnt],
11588c2ecf20Sopenharmony_ci				&hdev->event_queue);
11598c2ecf20Sopenharmony_ci	if (rc) {
11608c2ecf20Sopenharmony_ci		dev_err(hdev->dev, "Failed to request IRQ %d", irq);
11618c2ecf20Sopenharmony_ci		goto free_irqs;
11628c2ecf20Sopenharmony_ci	}
11638c2ecf20Sopenharmony_ci
11648c2ecf20Sopenharmony_ci	return 0;
11658c2ecf20Sopenharmony_ci
11668c2ecf20Sopenharmony_cifree_irqs:
11678c2ecf20Sopenharmony_ci	for (i = 0 ; i < irq_cnt_init ; i++)
11688c2ecf20Sopenharmony_ci		free_irq(gaudi_pci_irq_vector(hdev, i, false),
11698c2ecf20Sopenharmony_ci				&hdev->completion_queue[i]);
11708c2ecf20Sopenharmony_ci	return rc;
11718c2ecf20Sopenharmony_ci}
11728c2ecf20Sopenharmony_ci
11738c2ecf20Sopenharmony_cistatic int gaudi_enable_msi(struct hl_device *hdev)
11748c2ecf20Sopenharmony_ci{
11758c2ecf20Sopenharmony_ci	struct gaudi_device *gaudi = hdev->asic_specific;
11768c2ecf20Sopenharmony_ci	int rc;
11778c2ecf20Sopenharmony_ci
11788c2ecf20Sopenharmony_ci	if (gaudi->hw_cap_initialized & HW_CAP_MSI)
11798c2ecf20Sopenharmony_ci		return 0;
11808c2ecf20Sopenharmony_ci
11818c2ecf20Sopenharmony_ci	rc = pci_alloc_irq_vectors(hdev->pdev, 1, GAUDI_MSI_ENTRIES,
11828c2ecf20Sopenharmony_ci					PCI_IRQ_MSI);
11838c2ecf20Sopenharmony_ci	if (rc < 0) {
11848c2ecf20Sopenharmony_ci		dev_err(hdev->dev, "MSI: Failed to enable support %d\n", rc);
11858c2ecf20Sopenharmony_ci		return rc;
11868c2ecf20Sopenharmony_ci	}
11878c2ecf20Sopenharmony_ci
11888c2ecf20Sopenharmony_ci	if (rc < NUMBER_OF_INTERRUPTS) {
11898c2ecf20Sopenharmony_ci		gaudi->multi_msi_mode = false;
11908c2ecf20Sopenharmony_ci		rc = gaudi_enable_msi_single(hdev);
11918c2ecf20Sopenharmony_ci	} else {
11928c2ecf20Sopenharmony_ci		gaudi->multi_msi_mode = true;
11938c2ecf20Sopenharmony_ci		rc = gaudi_enable_msi_multi(hdev);
11948c2ecf20Sopenharmony_ci	}
11958c2ecf20Sopenharmony_ci
11968c2ecf20Sopenharmony_ci	if (rc)
11978c2ecf20Sopenharmony_ci		goto free_pci_irq_vectors;
11988c2ecf20Sopenharmony_ci
11998c2ecf20Sopenharmony_ci	gaudi->hw_cap_initialized |= HW_CAP_MSI;
12008c2ecf20Sopenharmony_ci
12018c2ecf20Sopenharmony_ci	return 0;
12028c2ecf20Sopenharmony_ci
12038c2ecf20Sopenharmony_cifree_pci_irq_vectors:
12048c2ecf20Sopenharmony_ci	pci_free_irq_vectors(hdev->pdev);
12058c2ecf20Sopenharmony_ci	return rc;
12068c2ecf20Sopenharmony_ci}
12078c2ecf20Sopenharmony_ci
12088c2ecf20Sopenharmony_cistatic void gaudi_sync_irqs(struct hl_device *hdev)
12098c2ecf20Sopenharmony_ci{
12108c2ecf20Sopenharmony_ci	struct gaudi_device *gaudi = hdev->asic_specific;
12118c2ecf20Sopenharmony_ci	int i, cq_cnt = hdev->asic_prop.completion_queues_count;
12128c2ecf20Sopenharmony_ci
12138c2ecf20Sopenharmony_ci	if (!(gaudi->hw_cap_initialized & HW_CAP_MSI))
12148c2ecf20Sopenharmony_ci		return;
12158c2ecf20Sopenharmony_ci
12168c2ecf20Sopenharmony_ci	/* Wait for all pending IRQs to be finished */
12178c2ecf20Sopenharmony_ci	if (gaudi->multi_msi_mode) {
12188c2ecf20Sopenharmony_ci		for (i = 0 ; i < cq_cnt ; i++)
12198c2ecf20Sopenharmony_ci			synchronize_irq(gaudi_pci_irq_vector(hdev, i, false));
12208c2ecf20Sopenharmony_ci
12218c2ecf20Sopenharmony_ci		synchronize_irq(gaudi_pci_irq_vector(hdev,
12228c2ecf20Sopenharmony_ci						GAUDI_EVENT_QUEUE_MSI_IDX,
12238c2ecf20Sopenharmony_ci						true));
12248c2ecf20Sopenharmony_ci	} else {
12258c2ecf20Sopenharmony_ci		synchronize_irq(gaudi_pci_irq_vector(hdev, 0, false));
12268c2ecf20Sopenharmony_ci	}
12278c2ecf20Sopenharmony_ci}
12288c2ecf20Sopenharmony_ci
12298c2ecf20Sopenharmony_cistatic void gaudi_disable_msi(struct hl_device *hdev)
12308c2ecf20Sopenharmony_ci{
12318c2ecf20Sopenharmony_ci	struct gaudi_device *gaudi = hdev->asic_specific;
12328c2ecf20Sopenharmony_ci	int i, irq, cq_cnt = hdev->asic_prop.completion_queues_count;
12338c2ecf20Sopenharmony_ci
12348c2ecf20Sopenharmony_ci	if (!(gaudi->hw_cap_initialized & HW_CAP_MSI))
12358c2ecf20Sopenharmony_ci		return;
12368c2ecf20Sopenharmony_ci
12378c2ecf20Sopenharmony_ci	gaudi_sync_irqs(hdev);
12388c2ecf20Sopenharmony_ci
12398c2ecf20Sopenharmony_ci	if (gaudi->multi_msi_mode) {
12408c2ecf20Sopenharmony_ci		irq = gaudi_pci_irq_vector(hdev, GAUDI_EVENT_QUEUE_MSI_IDX,
12418c2ecf20Sopenharmony_ci						true);
12428c2ecf20Sopenharmony_ci		free_irq(irq, &hdev->event_queue);
12438c2ecf20Sopenharmony_ci
12448c2ecf20Sopenharmony_ci		for (i = 0 ; i < cq_cnt ; i++) {
12458c2ecf20Sopenharmony_ci			irq = gaudi_pci_irq_vector(hdev, i, false);
12468c2ecf20Sopenharmony_ci			free_irq(irq, &hdev->completion_queue[i]);
12478c2ecf20Sopenharmony_ci		}
12488c2ecf20Sopenharmony_ci	} else {
12498c2ecf20Sopenharmony_ci		free_irq(gaudi_pci_irq_vector(hdev, 0, false), hdev);
12508c2ecf20Sopenharmony_ci	}
12518c2ecf20Sopenharmony_ci
12528c2ecf20Sopenharmony_ci	pci_free_irq_vectors(hdev->pdev);
12538c2ecf20Sopenharmony_ci
12548c2ecf20Sopenharmony_ci	gaudi->hw_cap_initialized &= ~HW_CAP_MSI;
12558c2ecf20Sopenharmony_ci}
12568c2ecf20Sopenharmony_ci
12578c2ecf20Sopenharmony_cistatic void gaudi_init_scrambler_sram(struct hl_device *hdev)
12588c2ecf20Sopenharmony_ci{
12598c2ecf20Sopenharmony_ci	struct gaudi_device *gaudi = hdev->asic_specific;
12608c2ecf20Sopenharmony_ci
12618c2ecf20Sopenharmony_ci	if (gaudi->hw_cap_initialized & HW_CAP_SRAM_SCRAMBLER)
12628c2ecf20Sopenharmony_ci		return;
12638c2ecf20Sopenharmony_ci
12648c2ecf20Sopenharmony_ci	if (!hdev->sram_scrambler_enable)
12658c2ecf20Sopenharmony_ci		return;
12668c2ecf20Sopenharmony_ci
12678c2ecf20Sopenharmony_ci	WREG32(mmNIF_RTR_CTRL_0_SCRAM_SRAM_EN,
12688c2ecf20Sopenharmony_ci			1 << IF_RTR_CTRL_SCRAM_SRAM_EN_VAL_SHIFT);
12698c2ecf20Sopenharmony_ci	WREG32(mmNIF_RTR_CTRL_1_SCRAM_SRAM_EN,
12708c2ecf20Sopenharmony_ci			1 << IF_RTR_CTRL_SCRAM_SRAM_EN_VAL_SHIFT);
12718c2ecf20Sopenharmony_ci	WREG32(mmNIF_RTR_CTRL_2_SCRAM_SRAM_EN,
12728c2ecf20Sopenharmony_ci			1 << IF_RTR_CTRL_SCRAM_SRAM_EN_VAL_SHIFT);
12738c2ecf20Sopenharmony_ci	WREG32(mmNIF_RTR_CTRL_3_SCRAM_SRAM_EN,
12748c2ecf20Sopenharmony_ci			1 << IF_RTR_CTRL_SCRAM_SRAM_EN_VAL_SHIFT);
12758c2ecf20Sopenharmony_ci	WREG32(mmNIF_RTR_CTRL_4_SCRAM_SRAM_EN,
12768c2ecf20Sopenharmony_ci			1 << IF_RTR_CTRL_SCRAM_SRAM_EN_VAL_SHIFT);
12778c2ecf20Sopenharmony_ci	WREG32(mmNIF_RTR_CTRL_5_SCRAM_SRAM_EN,
12788c2ecf20Sopenharmony_ci			1 << IF_RTR_CTRL_SCRAM_SRAM_EN_VAL_SHIFT);
12798c2ecf20Sopenharmony_ci	WREG32(mmNIF_RTR_CTRL_6_SCRAM_SRAM_EN,
12808c2ecf20Sopenharmony_ci			1 << IF_RTR_CTRL_SCRAM_SRAM_EN_VAL_SHIFT);
12818c2ecf20Sopenharmony_ci	WREG32(mmNIF_RTR_CTRL_7_SCRAM_SRAM_EN,
12828c2ecf20Sopenharmony_ci			1 << IF_RTR_CTRL_SCRAM_SRAM_EN_VAL_SHIFT);
12838c2ecf20Sopenharmony_ci
12848c2ecf20Sopenharmony_ci	WREG32(mmSIF_RTR_CTRL_0_SCRAM_SRAM_EN,
12858c2ecf20Sopenharmony_ci			1 << IF_RTR_CTRL_SCRAM_SRAM_EN_VAL_SHIFT);
12868c2ecf20Sopenharmony_ci	WREG32(mmSIF_RTR_CTRL_1_SCRAM_SRAM_EN,
12878c2ecf20Sopenharmony_ci			1 << IF_RTR_CTRL_SCRAM_SRAM_EN_VAL_SHIFT);
12888c2ecf20Sopenharmony_ci	WREG32(mmSIF_RTR_CTRL_2_SCRAM_SRAM_EN,
12898c2ecf20Sopenharmony_ci			1 << IF_RTR_CTRL_SCRAM_SRAM_EN_VAL_SHIFT);
12908c2ecf20Sopenharmony_ci	WREG32(mmSIF_RTR_CTRL_3_SCRAM_SRAM_EN,
12918c2ecf20Sopenharmony_ci			1 << IF_RTR_CTRL_SCRAM_SRAM_EN_VAL_SHIFT);
12928c2ecf20Sopenharmony_ci	WREG32(mmSIF_RTR_CTRL_4_SCRAM_SRAM_EN,
12938c2ecf20Sopenharmony_ci			1 << IF_RTR_CTRL_SCRAM_SRAM_EN_VAL_SHIFT);
12948c2ecf20Sopenharmony_ci	WREG32(mmSIF_RTR_CTRL_5_SCRAM_SRAM_EN,
12958c2ecf20Sopenharmony_ci			1 << IF_RTR_CTRL_SCRAM_SRAM_EN_VAL_SHIFT);
12968c2ecf20Sopenharmony_ci	WREG32(mmSIF_RTR_CTRL_6_SCRAM_SRAM_EN,
12978c2ecf20Sopenharmony_ci			1 << IF_RTR_CTRL_SCRAM_SRAM_EN_VAL_SHIFT);
12988c2ecf20Sopenharmony_ci	WREG32(mmSIF_RTR_CTRL_7_SCRAM_SRAM_EN,
12998c2ecf20Sopenharmony_ci			1 << IF_RTR_CTRL_SCRAM_SRAM_EN_VAL_SHIFT);
13008c2ecf20Sopenharmony_ci
13018c2ecf20Sopenharmony_ci	WREG32(mmDMA_IF_E_N_DOWN_CH0_SCRAM_SRAM_EN,
13028c2ecf20Sopenharmony_ci			1 << DMA_IF_DOWN_CHX_SCRAM_SRAM_EN_VAL_SHIFT);
13038c2ecf20Sopenharmony_ci	WREG32(mmDMA_IF_E_N_DOWN_CH1_SCRAM_SRAM_EN,
13048c2ecf20Sopenharmony_ci			1 << DMA_IF_DOWN_CHX_SCRAM_SRAM_EN_VAL_SHIFT);
13058c2ecf20Sopenharmony_ci	WREG32(mmDMA_IF_E_S_DOWN_CH0_SCRAM_SRAM_EN,
13068c2ecf20Sopenharmony_ci			1 << DMA_IF_DOWN_CHX_SCRAM_SRAM_EN_VAL_SHIFT);
13078c2ecf20Sopenharmony_ci	WREG32(mmDMA_IF_E_S_DOWN_CH1_SCRAM_SRAM_EN,
13088c2ecf20Sopenharmony_ci			1 << DMA_IF_DOWN_CHX_SCRAM_SRAM_EN_VAL_SHIFT);
13098c2ecf20Sopenharmony_ci	WREG32(mmDMA_IF_W_N_DOWN_CH0_SCRAM_SRAM_EN,
13108c2ecf20Sopenharmony_ci			1 << DMA_IF_DOWN_CHX_SCRAM_SRAM_EN_VAL_SHIFT);
13118c2ecf20Sopenharmony_ci	WREG32(mmDMA_IF_W_N_DOWN_CH1_SCRAM_SRAM_EN,
13128c2ecf20Sopenharmony_ci			1 << DMA_IF_DOWN_CHX_SCRAM_SRAM_EN_VAL_SHIFT);
13138c2ecf20Sopenharmony_ci	WREG32(mmDMA_IF_W_S_DOWN_CH0_SCRAM_SRAM_EN,
13148c2ecf20Sopenharmony_ci			1 << DMA_IF_DOWN_CHX_SCRAM_SRAM_EN_VAL_SHIFT);
13158c2ecf20Sopenharmony_ci	WREG32(mmDMA_IF_W_S_DOWN_CH1_SCRAM_SRAM_EN,
13168c2ecf20Sopenharmony_ci			1 << DMA_IF_DOWN_CHX_SCRAM_SRAM_EN_VAL_SHIFT);
13178c2ecf20Sopenharmony_ci
13188c2ecf20Sopenharmony_ci	gaudi->hw_cap_initialized |= HW_CAP_SRAM_SCRAMBLER;
13198c2ecf20Sopenharmony_ci}
13208c2ecf20Sopenharmony_ci
13218c2ecf20Sopenharmony_cistatic void gaudi_init_scrambler_hbm(struct hl_device *hdev)
13228c2ecf20Sopenharmony_ci{
13238c2ecf20Sopenharmony_ci	struct gaudi_device *gaudi = hdev->asic_specific;
13248c2ecf20Sopenharmony_ci
13258c2ecf20Sopenharmony_ci	if (gaudi->hw_cap_initialized & HW_CAP_HBM_SCRAMBLER)
13268c2ecf20Sopenharmony_ci		return;
13278c2ecf20Sopenharmony_ci
13288c2ecf20Sopenharmony_ci	if (!hdev->dram_scrambler_enable)
13298c2ecf20Sopenharmony_ci		return;
13308c2ecf20Sopenharmony_ci
13318c2ecf20Sopenharmony_ci	WREG32(mmNIF_RTR_CTRL_0_SCRAM_HBM_EN,
13328c2ecf20Sopenharmony_ci			1 << IF_RTR_CTRL_SCRAM_HBM_EN_VAL_SHIFT);
13338c2ecf20Sopenharmony_ci	WREG32(mmNIF_RTR_CTRL_1_SCRAM_HBM_EN,
13348c2ecf20Sopenharmony_ci			1 << IF_RTR_CTRL_SCRAM_HBM_EN_VAL_SHIFT);
13358c2ecf20Sopenharmony_ci	WREG32(mmNIF_RTR_CTRL_2_SCRAM_HBM_EN,
13368c2ecf20Sopenharmony_ci			1 << IF_RTR_CTRL_SCRAM_HBM_EN_VAL_SHIFT);
13378c2ecf20Sopenharmony_ci	WREG32(mmNIF_RTR_CTRL_3_SCRAM_HBM_EN,
13388c2ecf20Sopenharmony_ci			1 << IF_RTR_CTRL_SCRAM_HBM_EN_VAL_SHIFT);
13398c2ecf20Sopenharmony_ci	WREG32(mmNIF_RTR_CTRL_4_SCRAM_HBM_EN,
13408c2ecf20Sopenharmony_ci			1 << IF_RTR_CTRL_SCRAM_HBM_EN_VAL_SHIFT);
13418c2ecf20Sopenharmony_ci	WREG32(mmNIF_RTR_CTRL_5_SCRAM_HBM_EN,
13428c2ecf20Sopenharmony_ci			1 << IF_RTR_CTRL_SCRAM_HBM_EN_VAL_SHIFT);
13438c2ecf20Sopenharmony_ci	WREG32(mmNIF_RTR_CTRL_6_SCRAM_HBM_EN,
13448c2ecf20Sopenharmony_ci			1 << IF_RTR_CTRL_SCRAM_HBM_EN_VAL_SHIFT);
13458c2ecf20Sopenharmony_ci	WREG32(mmNIF_RTR_CTRL_7_SCRAM_HBM_EN,
13468c2ecf20Sopenharmony_ci			1 << IF_RTR_CTRL_SCRAM_HBM_EN_VAL_SHIFT);
13478c2ecf20Sopenharmony_ci
13488c2ecf20Sopenharmony_ci	WREG32(mmSIF_RTR_CTRL_0_SCRAM_HBM_EN,
13498c2ecf20Sopenharmony_ci			1 << IF_RTR_CTRL_SCRAM_HBM_EN_VAL_SHIFT);
13508c2ecf20Sopenharmony_ci	WREG32(mmSIF_RTR_CTRL_1_SCRAM_HBM_EN,
13518c2ecf20Sopenharmony_ci			1 << IF_RTR_CTRL_SCRAM_HBM_EN_VAL_SHIFT);
13528c2ecf20Sopenharmony_ci	WREG32(mmSIF_RTR_CTRL_2_SCRAM_HBM_EN,
13538c2ecf20Sopenharmony_ci			1 << IF_RTR_CTRL_SCRAM_HBM_EN_VAL_SHIFT);
13548c2ecf20Sopenharmony_ci	WREG32(mmSIF_RTR_CTRL_3_SCRAM_HBM_EN,
13558c2ecf20Sopenharmony_ci			1 << IF_RTR_CTRL_SCRAM_HBM_EN_VAL_SHIFT);
13568c2ecf20Sopenharmony_ci	WREG32(mmSIF_RTR_CTRL_4_SCRAM_HBM_EN,
13578c2ecf20Sopenharmony_ci			1 << IF_RTR_CTRL_SCRAM_HBM_EN_VAL_SHIFT);
13588c2ecf20Sopenharmony_ci	WREG32(mmSIF_RTR_CTRL_5_SCRAM_HBM_EN,
13598c2ecf20Sopenharmony_ci			1 << IF_RTR_CTRL_SCRAM_HBM_EN_VAL_SHIFT);
13608c2ecf20Sopenharmony_ci	WREG32(mmSIF_RTR_CTRL_6_SCRAM_HBM_EN,
13618c2ecf20Sopenharmony_ci			1 << IF_RTR_CTRL_SCRAM_HBM_EN_VAL_SHIFT);
13628c2ecf20Sopenharmony_ci	WREG32(mmSIF_RTR_CTRL_7_SCRAM_HBM_EN,
13638c2ecf20Sopenharmony_ci			1 << IF_RTR_CTRL_SCRAM_HBM_EN_VAL_SHIFT);
13648c2ecf20Sopenharmony_ci
13658c2ecf20Sopenharmony_ci	WREG32(mmDMA_IF_E_N_DOWN_CH0_SCRAM_HBM_EN,
13668c2ecf20Sopenharmony_ci			1 << DMA_IF_DOWN_CHX_SCRAM_HBM_EN_VAL_SHIFT);
13678c2ecf20Sopenharmony_ci	WREG32(mmDMA_IF_E_N_DOWN_CH1_SCRAM_HBM_EN,
13688c2ecf20Sopenharmony_ci			1 << DMA_IF_DOWN_CHX_SCRAM_HBM_EN_VAL_SHIFT);
13698c2ecf20Sopenharmony_ci	WREG32(mmDMA_IF_E_S_DOWN_CH0_SCRAM_HBM_EN,
13708c2ecf20Sopenharmony_ci			1 << DMA_IF_DOWN_CHX_SCRAM_HBM_EN_VAL_SHIFT);
13718c2ecf20Sopenharmony_ci	WREG32(mmDMA_IF_E_S_DOWN_CH1_SCRAM_HBM_EN,
13728c2ecf20Sopenharmony_ci			1 << DMA_IF_DOWN_CHX_SCRAM_HBM_EN_VAL_SHIFT);
13738c2ecf20Sopenharmony_ci	WREG32(mmDMA_IF_W_N_DOWN_CH0_SCRAM_HBM_EN,
13748c2ecf20Sopenharmony_ci			1 << DMA_IF_DOWN_CHX_SCRAM_HBM_EN_VAL_SHIFT);
13758c2ecf20Sopenharmony_ci	WREG32(mmDMA_IF_W_N_DOWN_CH1_SCRAM_HBM_EN,
13768c2ecf20Sopenharmony_ci			1 << DMA_IF_DOWN_CHX_SCRAM_HBM_EN_VAL_SHIFT);
13778c2ecf20Sopenharmony_ci	WREG32(mmDMA_IF_W_S_DOWN_CH0_SCRAM_HBM_EN,
13788c2ecf20Sopenharmony_ci			1 << DMA_IF_DOWN_CHX_SCRAM_HBM_EN_VAL_SHIFT);
13798c2ecf20Sopenharmony_ci	WREG32(mmDMA_IF_W_S_DOWN_CH1_SCRAM_HBM_EN,
13808c2ecf20Sopenharmony_ci			1 << DMA_IF_DOWN_CHX_SCRAM_HBM_EN_VAL_SHIFT);
13818c2ecf20Sopenharmony_ci
13828c2ecf20Sopenharmony_ci	gaudi->hw_cap_initialized |= HW_CAP_HBM_SCRAMBLER;
13838c2ecf20Sopenharmony_ci}
13848c2ecf20Sopenharmony_ci
13858c2ecf20Sopenharmony_cistatic void gaudi_init_e2e(struct hl_device *hdev)
13868c2ecf20Sopenharmony_ci{
13878c2ecf20Sopenharmony_ci	WREG32(mmSIF_RTR_CTRL_0_E2E_HBM_WR_SIZE, 247 >> 3);
13888c2ecf20Sopenharmony_ci	WREG32(mmSIF_RTR_CTRL_0_E2E_HBM_RD_SIZE, 785 >> 3);
13898c2ecf20Sopenharmony_ci	WREG32(mmSIF_RTR_CTRL_0_E2E_PCI_WR_SIZE, 49);
13908c2ecf20Sopenharmony_ci	WREG32(mmSIF_RTR_CTRL_0_E2E_PCI_RD_SIZE, 101);
13918c2ecf20Sopenharmony_ci
13928c2ecf20Sopenharmony_ci	WREG32(mmSIF_RTR_CTRL_1_E2E_HBM_WR_SIZE, 275 >> 3);
13938c2ecf20Sopenharmony_ci	WREG32(mmSIF_RTR_CTRL_1_E2E_HBM_RD_SIZE, 614 >> 3);
13948c2ecf20Sopenharmony_ci	WREG32(mmSIF_RTR_CTRL_1_E2E_PCI_WR_SIZE, 1);
13958c2ecf20Sopenharmony_ci	WREG32(mmSIF_RTR_CTRL_1_E2E_PCI_RD_SIZE, 39);
13968c2ecf20Sopenharmony_ci
13978c2ecf20Sopenharmony_ci	WREG32(mmSIF_RTR_CTRL_2_E2E_HBM_WR_SIZE, 1);
13988c2ecf20Sopenharmony_ci	WREG32(mmSIF_RTR_CTRL_2_E2E_HBM_RD_SIZE, 1);
13998c2ecf20Sopenharmony_ci	WREG32(mmSIF_RTR_CTRL_2_E2E_PCI_WR_SIZE, 1);
14008c2ecf20Sopenharmony_ci	WREG32(mmSIF_RTR_CTRL_2_E2E_PCI_RD_SIZE, 32);
14018c2ecf20Sopenharmony_ci
14028c2ecf20Sopenharmony_ci	WREG32(mmSIF_RTR_CTRL_3_E2E_HBM_WR_SIZE, 176 >> 3);
14038c2ecf20Sopenharmony_ci	WREG32(mmSIF_RTR_CTRL_3_E2E_HBM_RD_SIZE, 32 >> 3);
14048c2ecf20Sopenharmony_ci	WREG32(mmSIF_RTR_CTRL_3_E2E_PCI_WR_SIZE, 19);
14058c2ecf20Sopenharmony_ci	WREG32(mmSIF_RTR_CTRL_3_E2E_PCI_RD_SIZE, 32);
14068c2ecf20Sopenharmony_ci
14078c2ecf20Sopenharmony_ci	WREG32(mmSIF_RTR_CTRL_4_E2E_HBM_WR_SIZE, 176 >> 3);
14088c2ecf20Sopenharmony_ci	WREG32(mmSIF_RTR_CTRL_4_E2E_HBM_RD_SIZE, 32 >> 3);
14098c2ecf20Sopenharmony_ci	WREG32(mmSIF_RTR_CTRL_4_E2E_PCI_WR_SIZE, 19);
14108c2ecf20Sopenharmony_ci	WREG32(mmSIF_RTR_CTRL_4_E2E_PCI_RD_SIZE, 32);
14118c2ecf20Sopenharmony_ci
14128c2ecf20Sopenharmony_ci	WREG32(mmSIF_RTR_CTRL_5_E2E_HBM_WR_SIZE, 1);
14138c2ecf20Sopenharmony_ci	WREG32(mmSIF_RTR_CTRL_5_E2E_HBM_RD_SIZE, 1);
14148c2ecf20Sopenharmony_ci	WREG32(mmSIF_RTR_CTRL_5_E2E_PCI_WR_SIZE, 1);
14158c2ecf20Sopenharmony_ci	WREG32(mmSIF_RTR_CTRL_5_E2E_PCI_RD_SIZE, 32);
14168c2ecf20Sopenharmony_ci
14178c2ecf20Sopenharmony_ci	WREG32(mmSIF_RTR_CTRL_6_E2E_HBM_WR_SIZE, 275 >> 3);
14188c2ecf20Sopenharmony_ci	WREG32(mmSIF_RTR_CTRL_6_E2E_HBM_RD_SIZE, 614 >> 3);
14198c2ecf20Sopenharmony_ci	WREG32(mmSIF_RTR_CTRL_6_E2E_PCI_WR_SIZE, 1);
14208c2ecf20Sopenharmony_ci	WREG32(mmSIF_RTR_CTRL_6_E2E_PCI_RD_SIZE, 39);
14218c2ecf20Sopenharmony_ci
14228c2ecf20Sopenharmony_ci	WREG32(mmSIF_RTR_CTRL_7_E2E_HBM_WR_SIZE, 297 >> 3);
14238c2ecf20Sopenharmony_ci	WREG32(mmSIF_RTR_CTRL_7_E2E_HBM_RD_SIZE, 908 >> 3);
14248c2ecf20Sopenharmony_ci	WREG32(mmSIF_RTR_CTRL_7_E2E_PCI_WR_SIZE, 19);
14258c2ecf20Sopenharmony_ci	WREG32(mmSIF_RTR_CTRL_7_E2E_PCI_RD_SIZE, 19);
14268c2ecf20Sopenharmony_ci
14278c2ecf20Sopenharmony_ci	WREG32(mmNIF_RTR_CTRL_0_E2E_HBM_WR_SIZE, 318 >> 3);
14288c2ecf20Sopenharmony_ci	WREG32(mmNIF_RTR_CTRL_0_E2E_HBM_RD_SIZE, 956 >> 3);
14298c2ecf20Sopenharmony_ci	WREG32(mmNIF_RTR_CTRL_0_E2E_PCI_WR_SIZE, 79);
14308c2ecf20Sopenharmony_ci	WREG32(mmNIF_RTR_CTRL_0_E2E_PCI_RD_SIZE, 163);
14318c2ecf20Sopenharmony_ci
14328c2ecf20Sopenharmony_ci	WREG32(mmNIF_RTR_CTRL_1_E2E_HBM_WR_SIZE, 275 >> 3);
14338c2ecf20Sopenharmony_ci	WREG32(mmNIF_RTR_CTRL_1_E2E_HBM_RD_SIZE, 614 >> 3);
14348c2ecf20Sopenharmony_ci	WREG32(mmNIF_RTR_CTRL_1_E2E_PCI_WR_SIZE, 1);
14358c2ecf20Sopenharmony_ci	WREG32(mmNIF_RTR_CTRL_1_E2E_PCI_RD_SIZE, 39);
14368c2ecf20Sopenharmony_ci
14378c2ecf20Sopenharmony_ci	WREG32(mmNIF_RTR_CTRL_2_E2E_HBM_WR_SIZE, 1);
14388c2ecf20Sopenharmony_ci	WREG32(mmNIF_RTR_CTRL_2_E2E_HBM_RD_SIZE, 1);
14398c2ecf20Sopenharmony_ci	WREG32(mmNIF_RTR_CTRL_2_E2E_PCI_WR_SIZE, 1);
14408c2ecf20Sopenharmony_ci	WREG32(mmNIF_RTR_CTRL_2_E2E_PCI_RD_SIZE, 32);
14418c2ecf20Sopenharmony_ci
14428c2ecf20Sopenharmony_ci	WREG32(mmNIF_RTR_CTRL_3_E2E_HBM_WR_SIZE, 176 >> 3);
14438c2ecf20Sopenharmony_ci	WREG32(mmNIF_RTR_CTRL_3_E2E_HBM_RD_SIZE, 32 >> 3);
14448c2ecf20Sopenharmony_ci	WREG32(mmNIF_RTR_CTRL_3_E2E_PCI_WR_SIZE, 19);
14458c2ecf20Sopenharmony_ci	WREG32(mmNIF_RTR_CTRL_3_E2E_PCI_RD_SIZE, 32);
14468c2ecf20Sopenharmony_ci
14478c2ecf20Sopenharmony_ci	WREG32(mmNIF_RTR_CTRL_4_E2E_HBM_WR_SIZE, 176 >> 3);
14488c2ecf20Sopenharmony_ci	WREG32(mmNIF_RTR_CTRL_4_E2E_HBM_RD_SIZE, 32 >> 3);
14498c2ecf20Sopenharmony_ci	WREG32(mmNIF_RTR_CTRL_4_E2E_PCI_WR_SIZE, 19);
14508c2ecf20Sopenharmony_ci	WREG32(mmNIF_RTR_CTRL_4_E2E_PCI_RD_SIZE, 32);
14518c2ecf20Sopenharmony_ci
14528c2ecf20Sopenharmony_ci	WREG32(mmNIF_RTR_CTRL_5_E2E_HBM_WR_SIZE, 1);
14538c2ecf20Sopenharmony_ci	WREG32(mmNIF_RTR_CTRL_5_E2E_HBM_RD_SIZE, 1);
14548c2ecf20Sopenharmony_ci	WREG32(mmNIF_RTR_CTRL_5_E2E_PCI_WR_SIZE, 1);
14558c2ecf20Sopenharmony_ci	WREG32(mmNIF_RTR_CTRL_5_E2E_PCI_RD_SIZE, 32);
14568c2ecf20Sopenharmony_ci
14578c2ecf20Sopenharmony_ci	WREG32(mmNIF_RTR_CTRL_6_E2E_HBM_WR_SIZE, 275 >> 3);
14588c2ecf20Sopenharmony_ci	WREG32(mmNIF_RTR_CTRL_6_E2E_HBM_RD_SIZE, 614 >> 3);
14598c2ecf20Sopenharmony_ci	WREG32(mmNIF_RTR_CTRL_6_E2E_PCI_WR_SIZE, 1);
14608c2ecf20Sopenharmony_ci	WREG32(mmNIF_RTR_CTRL_6_E2E_PCI_RD_SIZE, 39);
14618c2ecf20Sopenharmony_ci
14628c2ecf20Sopenharmony_ci	WREG32(mmNIF_RTR_CTRL_7_E2E_HBM_WR_SIZE, 318 >> 3);
14638c2ecf20Sopenharmony_ci	WREG32(mmNIF_RTR_CTRL_7_E2E_HBM_RD_SIZE, 956 >> 3);
14648c2ecf20Sopenharmony_ci	WREG32(mmNIF_RTR_CTRL_7_E2E_PCI_WR_SIZE, 79);
14658c2ecf20Sopenharmony_ci	WREG32(mmNIF_RTR_CTRL_7_E2E_PCI_RD_SIZE, 79);
14668c2ecf20Sopenharmony_ci
14678c2ecf20Sopenharmony_ci	WREG32(mmDMA_IF_E_N_DOWN_CH0_E2E_HBM_WR_SIZE, 344 >> 3);
14688c2ecf20Sopenharmony_ci	WREG32(mmDMA_IF_E_N_DOWN_CH0_E2E_HBM_RD_SIZE, 1000 >> 3);
14698c2ecf20Sopenharmony_ci	WREG32(mmDMA_IF_E_N_DOWN_CH0_E2E_PCI_WR_SIZE, 162);
14708c2ecf20Sopenharmony_ci	WREG32(mmDMA_IF_E_N_DOWN_CH0_E2E_PCI_RD_SIZE, 338);
14718c2ecf20Sopenharmony_ci
14728c2ecf20Sopenharmony_ci	WREG32(mmDMA_IF_E_N_DOWN_CH1_E2E_HBM_WR_SIZE, 344 >> 3);
14738c2ecf20Sopenharmony_ci	WREG32(mmDMA_IF_E_N_DOWN_CH1_E2E_HBM_RD_SIZE, 1000 >> 3);
14748c2ecf20Sopenharmony_ci	WREG32(mmDMA_IF_E_N_DOWN_CH1_E2E_PCI_WR_SIZE, 162);
14758c2ecf20Sopenharmony_ci	WREG32(mmDMA_IF_E_N_DOWN_CH1_E2E_PCI_RD_SIZE, 338);
14768c2ecf20Sopenharmony_ci
14778c2ecf20Sopenharmony_ci	WREG32(mmDMA_IF_E_S_DOWN_CH0_E2E_HBM_WR_SIZE, 344 >> 3);
14788c2ecf20Sopenharmony_ci	WREG32(mmDMA_IF_E_S_DOWN_CH0_E2E_HBM_RD_SIZE, 1000 >> 3);
14798c2ecf20Sopenharmony_ci	WREG32(mmDMA_IF_E_S_DOWN_CH0_E2E_PCI_WR_SIZE, 162);
14808c2ecf20Sopenharmony_ci	WREG32(mmDMA_IF_E_S_DOWN_CH0_E2E_PCI_RD_SIZE, 338);
14818c2ecf20Sopenharmony_ci
14828c2ecf20Sopenharmony_ci	WREG32(mmDMA_IF_E_S_DOWN_CH1_E2E_HBM_WR_SIZE, 344 >> 3);
14838c2ecf20Sopenharmony_ci	WREG32(mmDMA_IF_E_S_DOWN_CH1_E2E_HBM_RD_SIZE, 1000 >> 3);
14848c2ecf20Sopenharmony_ci	WREG32(mmDMA_IF_E_S_DOWN_CH1_E2E_PCI_WR_SIZE, 162);
14858c2ecf20Sopenharmony_ci	WREG32(mmDMA_IF_E_S_DOWN_CH1_E2E_PCI_RD_SIZE, 338);
14868c2ecf20Sopenharmony_ci
14878c2ecf20Sopenharmony_ci	WREG32(mmDMA_IF_W_N_DOWN_CH0_E2E_HBM_WR_SIZE, 344 >> 3);
14888c2ecf20Sopenharmony_ci	WREG32(mmDMA_IF_W_N_DOWN_CH0_E2E_HBM_RD_SIZE, 1000 >> 3);
14898c2ecf20Sopenharmony_ci	WREG32(mmDMA_IF_W_N_DOWN_CH0_E2E_PCI_WR_SIZE, 162);
14908c2ecf20Sopenharmony_ci	WREG32(mmDMA_IF_W_N_DOWN_CH0_E2E_PCI_RD_SIZE, 338);
14918c2ecf20Sopenharmony_ci
14928c2ecf20Sopenharmony_ci	WREG32(mmDMA_IF_W_N_DOWN_CH1_E2E_HBM_WR_SIZE, 344 >> 3);
14938c2ecf20Sopenharmony_ci	WREG32(mmDMA_IF_W_N_DOWN_CH1_E2E_HBM_RD_SIZE, 1000 >> 3);
14948c2ecf20Sopenharmony_ci	WREG32(mmDMA_IF_W_N_DOWN_CH1_E2E_PCI_WR_SIZE, 162);
14958c2ecf20Sopenharmony_ci	WREG32(mmDMA_IF_W_N_DOWN_CH1_E2E_PCI_RD_SIZE, 338);
14968c2ecf20Sopenharmony_ci
14978c2ecf20Sopenharmony_ci	WREG32(mmDMA_IF_W_S_DOWN_CH0_E2E_HBM_WR_SIZE, 344 >> 3);
14988c2ecf20Sopenharmony_ci	WREG32(mmDMA_IF_W_S_DOWN_CH0_E2E_HBM_RD_SIZE, 1000 >> 3);
14998c2ecf20Sopenharmony_ci	WREG32(mmDMA_IF_W_S_DOWN_CH0_E2E_PCI_WR_SIZE, 162);
15008c2ecf20Sopenharmony_ci	WREG32(mmDMA_IF_W_S_DOWN_CH0_E2E_PCI_RD_SIZE, 338);
15018c2ecf20Sopenharmony_ci
15028c2ecf20Sopenharmony_ci	WREG32(mmDMA_IF_W_S_DOWN_CH1_E2E_HBM_WR_SIZE, 344 >> 3);
15038c2ecf20Sopenharmony_ci	WREG32(mmDMA_IF_W_S_DOWN_CH1_E2E_HBM_RD_SIZE, 1000 >> 3);
15048c2ecf20Sopenharmony_ci	WREG32(mmDMA_IF_W_S_DOWN_CH1_E2E_PCI_WR_SIZE, 162);
15058c2ecf20Sopenharmony_ci	WREG32(mmDMA_IF_W_S_DOWN_CH1_E2E_PCI_RD_SIZE, 338);
15068c2ecf20Sopenharmony_ci
15078c2ecf20Sopenharmony_ci	if (!hdev->dram_scrambler_enable) {
15088c2ecf20Sopenharmony_ci		WREG32(mmSIF_RTR_CTRL_0_NL_HBM_SEL_0, 0x21);
15098c2ecf20Sopenharmony_ci		WREG32(mmSIF_RTR_CTRL_0_NL_HBM_SEL_1, 0x22);
15108c2ecf20Sopenharmony_ci		WREG32(mmSIF_RTR_CTRL_0_NL_HBM_OFFSET_18, 0x1F);
15118c2ecf20Sopenharmony_ci		WREG32(mmSIF_RTR_CTRL_0_NL_HBM_PC_SEL_3, 0x20);
15128c2ecf20Sopenharmony_ci
15138c2ecf20Sopenharmony_ci		WREG32(mmSIF_RTR_CTRL_1_NL_HBM_SEL_0, 0x21);
15148c2ecf20Sopenharmony_ci		WREG32(mmSIF_RTR_CTRL_1_NL_HBM_SEL_1, 0x22);
15158c2ecf20Sopenharmony_ci		WREG32(mmSIF_RTR_CTRL_1_NL_HBM_OFFSET_18, 0x1F);
15168c2ecf20Sopenharmony_ci		WREG32(mmSIF_RTR_CTRL_1_NL_HBM_PC_SEL_3, 0x20);
15178c2ecf20Sopenharmony_ci
15188c2ecf20Sopenharmony_ci		WREG32(mmSIF_RTR_CTRL_2_NL_HBM_SEL_0, 0x21);
15198c2ecf20Sopenharmony_ci		WREG32(mmSIF_RTR_CTRL_2_NL_HBM_SEL_1, 0x22);
15208c2ecf20Sopenharmony_ci		WREG32(mmSIF_RTR_CTRL_2_NL_HBM_OFFSET_18, 0x1F);
15218c2ecf20Sopenharmony_ci		WREG32(mmSIF_RTR_CTRL_2_NL_HBM_PC_SEL_3, 0x20);
15228c2ecf20Sopenharmony_ci
15238c2ecf20Sopenharmony_ci		WREG32(mmSIF_RTR_CTRL_3_NL_HBM_SEL_0, 0x21);
15248c2ecf20Sopenharmony_ci		WREG32(mmSIF_RTR_CTRL_3_NL_HBM_SEL_1, 0x22);
15258c2ecf20Sopenharmony_ci		WREG32(mmSIF_RTR_CTRL_3_NL_HBM_OFFSET_18, 0x1F);
15268c2ecf20Sopenharmony_ci		WREG32(mmSIF_RTR_CTRL_3_NL_HBM_PC_SEL_3, 0x20);
15278c2ecf20Sopenharmony_ci
15288c2ecf20Sopenharmony_ci		WREG32(mmSIF_RTR_CTRL_4_NL_HBM_SEL_0, 0x21);
15298c2ecf20Sopenharmony_ci		WREG32(mmSIF_RTR_CTRL_4_NL_HBM_SEL_1, 0x22);
15308c2ecf20Sopenharmony_ci		WREG32(mmSIF_RTR_CTRL_4_NL_HBM_OFFSET_18, 0x1F);
15318c2ecf20Sopenharmony_ci		WREG32(mmSIF_RTR_CTRL_4_NL_HBM_PC_SEL_3, 0x20);
15328c2ecf20Sopenharmony_ci
15338c2ecf20Sopenharmony_ci		WREG32(mmSIF_RTR_CTRL_5_NL_HBM_SEL_0, 0x21);
15348c2ecf20Sopenharmony_ci		WREG32(mmSIF_RTR_CTRL_5_NL_HBM_SEL_1, 0x22);
15358c2ecf20Sopenharmony_ci		WREG32(mmSIF_RTR_CTRL_5_NL_HBM_OFFSET_18, 0x1F);
15368c2ecf20Sopenharmony_ci		WREG32(mmSIF_RTR_CTRL_5_NL_HBM_PC_SEL_3, 0x20);
15378c2ecf20Sopenharmony_ci
15388c2ecf20Sopenharmony_ci		WREG32(mmSIF_RTR_CTRL_6_NL_HBM_SEL_0, 0x21);
15398c2ecf20Sopenharmony_ci		WREG32(mmSIF_RTR_CTRL_6_NL_HBM_SEL_1, 0x22);
15408c2ecf20Sopenharmony_ci		WREG32(mmSIF_RTR_CTRL_6_NL_HBM_OFFSET_18, 0x1F);
15418c2ecf20Sopenharmony_ci		WREG32(mmSIF_RTR_CTRL_6_NL_HBM_PC_SEL_3, 0x20);
15428c2ecf20Sopenharmony_ci
15438c2ecf20Sopenharmony_ci		WREG32(mmSIF_RTR_CTRL_7_NL_HBM_SEL_0, 0x21);
15448c2ecf20Sopenharmony_ci		WREG32(mmSIF_RTR_CTRL_7_NL_HBM_SEL_1, 0x22);
15458c2ecf20Sopenharmony_ci		WREG32(mmSIF_RTR_CTRL_7_NL_HBM_OFFSET_18, 0x1F);
15468c2ecf20Sopenharmony_ci		WREG32(mmSIF_RTR_CTRL_7_NL_HBM_PC_SEL_3, 0x20);
15478c2ecf20Sopenharmony_ci
15488c2ecf20Sopenharmony_ci		WREG32(mmNIF_RTR_CTRL_0_NL_HBM_SEL_0, 0x21);
15498c2ecf20Sopenharmony_ci		WREG32(mmNIF_RTR_CTRL_0_NL_HBM_SEL_1, 0x22);
15508c2ecf20Sopenharmony_ci		WREG32(mmNIF_RTR_CTRL_0_NL_HBM_OFFSET_18, 0x1F);
15518c2ecf20Sopenharmony_ci		WREG32(mmNIF_RTR_CTRL_0_NL_HBM_PC_SEL_3, 0x20);
15528c2ecf20Sopenharmony_ci
15538c2ecf20Sopenharmony_ci		WREG32(mmNIF_RTR_CTRL_1_NL_HBM_SEL_0, 0x21);
15548c2ecf20Sopenharmony_ci		WREG32(mmNIF_RTR_CTRL_1_NL_HBM_SEL_1, 0x22);
15558c2ecf20Sopenharmony_ci		WREG32(mmNIF_RTR_CTRL_1_NL_HBM_OFFSET_18, 0x1F);
15568c2ecf20Sopenharmony_ci		WREG32(mmNIF_RTR_CTRL_1_NL_HBM_PC_SEL_3, 0x20);
15578c2ecf20Sopenharmony_ci
15588c2ecf20Sopenharmony_ci		WREG32(mmNIF_RTR_CTRL_2_NL_HBM_SEL_0, 0x21);
15598c2ecf20Sopenharmony_ci		WREG32(mmNIF_RTR_CTRL_2_NL_HBM_SEL_1, 0x22);
15608c2ecf20Sopenharmony_ci		WREG32(mmNIF_RTR_CTRL_2_NL_HBM_OFFSET_18, 0x1F);
15618c2ecf20Sopenharmony_ci		WREG32(mmNIF_RTR_CTRL_2_NL_HBM_PC_SEL_3, 0x20);
15628c2ecf20Sopenharmony_ci
15638c2ecf20Sopenharmony_ci		WREG32(mmNIF_RTR_CTRL_3_NL_HBM_SEL_0, 0x21);
15648c2ecf20Sopenharmony_ci		WREG32(mmNIF_RTR_CTRL_3_NL_HBM_SEL_1, 0x22);
15658c2ecf20Sopenharmony_ci		WREG32(mmNIF_RTR_CTRL_3_NL_HBM_OFFSET_18, 0x1F);
15668c2ecf20Sopenharmony_ci		WREG32(mmNIF_RTR_CTRL_3_NL_HBM_PC_SEL_3, 0x20);
15678c2ecf20Sopenharmony_ci
15688c2ecf20Sopenharmony_ci		WREG32(mmNIF_RTR_CTRL_4_NL_HBM_SEL_0, 0x21);
15698c2ecf20Sopenharmony_ci		WREG32(mmNIF_RTR_CTRL_4_NL_HBM_SEL_1, 0x22);
15708c2ecf20Sopenharmony_ci		WREG32(mmNIF_RTR_CTRL_4_NL_HBM_OFFSET_18, 0x1F);
15718c2ecf20Sopenharmony_ci		WREG32(mmNIF_RTR_CTRL_4_NL_HBM_PC_SEL_3, 0x20);
15728c2ecf20Sopenharmony_ci
15738c2ecf20Sopenharmony_ci		WREG32(mmNIF_RTR_CTRL_5_NL_HBM_SEL_0, 0x21);
15748c2ecf20Sopenharmony_ci		WREG32(mmNIF_RTR_CTRL_5_NL_HBM_SEL_1, 0x22);
15758c2ecf20Sopenharmony_ci		WREG32(mmNIF_RTR_CTRL_5_NL_HBM_OFFSET_18, 0x1F);
15768c2ecf20Sopenharmony_ci		WREG32(mmNIF_RTR_CTRL_5_NL_HBM_PC_SEL_3, 0x20);
15778c2ecf20Sopenharmony_ci
15788c2ecf20Sopenharmony_ci		WREG32(mmNIF_RTR_CTRL_6_NL_HBM_SEL_0, 0x21);
15798c2ecf20Sopenharmony_ci		WREG32(mmNIF_RTR_CTRL_6_NL_HBM_SEL_1, 0x22);
15808c2ecf20Sopenharmony_ci		WREG32(mmNIF_RTR_CTRL_6_NL_HBM_OFFSET_18, 0x1F);
15818c2ecf20Sopenharmony_ci		WREG32(mmNIF_RTR_CTRL_6_NL_HBM_PC_SEL_3, 0x20);
15828c2ecf20Sopenharmony_ci
15838c2ecf20Sopenharmony_ci		WREG32(mmNIF_RTR_CTRL_7_NL_HBM_SEL_0, 0x21);
15848c2ecf20Sopenharmony_ci		WREG32(mmNIF_RTR_CTRL_7_NL_HBM_SEL_1, 0x22);
15858c2ecf20Sopenharmony_ci		WREG32(mmNIF_RTR_CTRL_7_NL_HBM_OFFSET_18, 0x1F);
15868c2ecf20Sopenharmony_ci		WREG32(mmNIF_RTR_CTRL_7_NL_HBM_PC_SEL_3, 0x20);
15878c2ecf20Sopenharmony_ci
15888c2ecf20Sopenharmony_ci		WREG32(mmDMA_IF_E_N_DOWN_CH0_NL_HBM_SEL_0, 0x21);
15898c2ecf20Sopenharmony_ci		WREG32(mmDMA_IF_E_N_DOWN_CH0_NL_HBM_SEL_1, 0x22);
15908c2ecf20Sopenharmony_ci		WREG32(mmDMA_IF_E_N_DOWN_CH0_NL_HBM_OFFSET_18, 0x1F);
15918c2ecf20Sopenharmony_ci		WREG32(mmDMA_IF_E_N_DOWN_CH0_NL_HBM_PC_SEL_3, 0x20);
15928c2ecf20Sopenharmony_ci
15938c2ecf20Sopenharmony_ci		WREG32(mmDMA_IF_E_N_DOWN_CH1_NL_HBM_SEL_0, 0x21);
15948c2ecf20Sopenharmony_ci		WREG32(mmDMA_IF_E_N_DOWN_CH1_NL_HBM_SEL_1, 0x22);
15958c2ecf20Sopenharmony_ci		WREG32(mmDMA_IF_E_N_DOWN_CH1_NL_HBM_OFFSET_18, 0x1F);
15968c2ecf20Sopenharmony_ci		WREG32(mmDMA_IF_E_N_DOWN_CH1_NL_HBM_PC_SEL_3, 0x20);
15978c2ecf20Sopenharmony_ci
15988c2ecf20Sopenharmony_ci		WREG32(mmDMA_IF_E_S_DOWN_CH0_NL_HBM_SEL_0, 0x21);
15998c2ecf20Sopenharmony_ci		WREG32(mmDMA_IF_E_S_DOWN_CH0_NL_HBM_SEL_1, 0x22);
16008c2ecf20Sopenharmony_ci		WREG32(mmDMA_IF_E_S_DOWN_CH0_NL_HBM_OFFSET_18, 0x1F);
16018c2ecf20Sopenharmony_ci		WREG32(mmDMA_IF_E_S_DOWN_CH0_NL_HBM_PC_SEL_3, 0x20);
16028c2ecf20Sopenharmony_ci
16038c2ecf20Sopenharmony_ci		WREG32(mmDMA_IF_E_S_DOWN_CH1_NL_HBM_SEL_0, 0x21);
16048c2ecf20Sopenharmony_ci		WREG32(mmDMA_IF_E_S_DOWN_CH1_NL_HBM_SEL_1, 0x22);
16058c2ecf20Sopenharmony_ci		WREG32(mmDMA_IF_E_S_DOWN_CH1_NL_HBM_OFFSET_18, 0x1F);
16068c2ecf20Sopenharmony_ci		WREG32(mmDMA_IF_E_S_DOWN_CH1_NL_HBM_PC_SEL_3, 0x20);
16078c2ecf20Sopenharmony_ci
16088c2ecf20Sopenharmony_ci		WREG32(mmDMA_IF_W_N_DOWN_CH0_NL_HBM_SEL_0, 0x21);
16098c2ecf20Sopenharmony_ci		WREG32(mmDMA_IF_W_N_DOWN_CH0_NL_HBM_SEL_1, 0x22);
16108c2ecf20Sopenharmony_ci		WREG32(mmDMA_IF_W_N_DOWN_CH0_NL_HBM_OFFSET_18, 0x1F);
16118c2ecf20Sopenharmony_ci		WREG32(mmDMA_IF_W_N_DOWN_CH0_NL_HBM_PC_SEL_3, 0x20);
16128c2ecf20Sopenharmony_ci
16138c2ecf20Sopenharmony_ci		WREG32(mmDMA_IF_W_N_DOWN_CH1_NL_HBM_SEL_0, 0x21);
16148c2ecf20Sopenharmony_ci		WREG32(mmDMA_IF_W_N_DOWN_CH1_NL_HBM_SEL_1, 0x22);
16158c2ecf20Sopenharmony_ci		WREG32(mmDMA_IF_W_N_DOWN_CH1_NL_HBM_OFFSET_18, 0x1F);
16168c2ecf20Sopenharmony_ci		WREG32(mmDMA_IF_W_N_DOWN_CH1_NL_HBM_PC_SEL_3, 0x20);
16178c2ecf20Sopenharmony_ci
16188c2ecf20Sopenharmony_ci		WREG32(mmDMA_IF_W_S_DOWN_CH0_NL_HBM_SEL_0, 0x21);
16198c2ecf20Sopenharmony_ci		WREG32(mmDMA_IF_W_S_DOWN_CH0_NL_HBM_SEL_1, 0x22);
16208c2ecf20Sopenharmony_ci		WREG32(mmDMA_IF_W_S_DOWN_CH0_NL_HBM_OFFSET_18, 0x1F);
16218c2ecf20Sopenharmony_ci		WREG32(mmDMA_IF_W_S_DOWN_CH0_NL_HBM_PC_SEL_3, 0x20);
16228c2ecf20Sopenharmony_ci
16238c2ecf20Sopenharmony_ci		WREG32(mmDMA_IF_W_S_DOWN_CH1_NL_HBM_SEL_0, 0x21);
16248c2ecf20Sopenharmony_ci		WREG32(mmDMA_IF_W_S_DOWN_CH1_NL_HBM_SEL_1, 0x22);
16258c2ecf20Sopenharmony_ci		WREG32(mmDMA_IF_W_S_DOWN_CH1_NL_HBM_OFFSET_18, 0x1F);
16268c2ecf20Sopenharmony_ci		WREG32(mmDMA_IF_W_S_DOWN_CH1_NL_HBM_PC_SEL_3, 0x20);
16278c2ecf20Sopenharmony_ci	}
16288c2ecf20Sopenharmony_ci
16298c2ecf20Sopenharmony_ci	WREG32(mmSIF_RTR_CTRL_0_E2E_HBM_EN,
16308c2ecf20Sopenharmony_ci			1 << IF_RTR_CTRL_E2E_HBM_EN_VAL_SHIFT);
16318c2ecf20Sopenharmony_ci	WREG32(mmSIF_RTR_CTRL_0_E2E_PCI_EN,
16328c2ecf20Sopenharmony_ci			1 << IF_RTR_CTRL_E2E_PCI_EN_VAL_SHIFT);
16338c2ecf20Sopenharmony_ci
16348c2ecf20Sopenharmony_ci	WREG32(mmSIF_RTR_CTRL_1_E2E_HBM_EN,
16358c2ecf20Sopenharmony_ci			1 << IF_RTR_CTRL_E2E_HBM_EN_VAL_SHIFT);
16368c2ecf20Sopenharmony_ci	WREG32(mmSIF_RTR_CTRL_1_E2E_PCI_EN,
16378c2ecf20Sopenharmony_ci			1 << IF_RTR_CTRL_E2E_PCI_EN_VAL_SHIFT);
16388c2ecf20Sopenharmony_ci
16398c2ecf20Sopenharmony_ci	WREG32(mmSIF_RTR_CTRL_2_E2E_HBM_EN,
16408c2ecf20Sopenharmony_ci			1 << IF_RTR_CTRL_E2E_HBM_EN_VAL_SHIFT);
16418c2ecf20Sopenharmony_ci	WREG32(mmSIF_RTR_CTRL_2_E2E_PCI_EN,
16428c2ecf20Sopenharmony_ci			1 << IF_RTR_CTRL_E2E_PCI_EN_VAL_SHIFT);
16438c2ecf20Sopenharmony_ci
16448c2ecf20Sopenharmony_ci	WREG32(mmSIF_RTR_CTRL_3_E2E_HBM_EN,
16458c2ecf20Sopenharmony_ci			1 << IF_RTR_CTRL_E2E_HBM_EN_VAL_SHIFT);
16468c2ecf20Sopenharmony_ci	WREG32(mmSIF_RTR_CTRL_3_E2E_PCI_EN,
16478c2ecf20Sopenharmony_ci			1 << IF_RTR_CTRL_E2E_PCI_EN_VAL_SHIFT);
16488c2ecf20Sopenharmony_ci
16498c2ecf20Sopenharmony_ci	WREG32(mmSIF_RTR_CTRL_4_E2E_HBM_EN,
16508c2ecf20Sopenharmony_ci			1 << IF_RTR_CTRL_E2E_HBM_EN_VAL_SHIFT);
16518c2ecf20Sopenharmony_ci	WREG32(mmSIF_RTR_CTRL_4_E2E_PCI_EN,
16528c2ecf20Sopenharmony_ci			1 << IF_RTR_CTRL_E2E_PCI_EN_VAL_SHIFT);
16538c2ecf20Sopenharmony_ci
16548c2ecf20Sopenharmony_ci	WREG32(mmSIF_RTR_CTRL_5_E2E_HBM_EN,
16558c2ecf20Sopenharmony_ci			1 << IF_RTR_CTRL_E2E_HBM_EN_VAL_SHIFT);
16568c2ecf20Sopenharmony_ci	WREG32(mmSIF_RTR_CTRL_5_E2E_PCI_EN,
16578c2ecf20Sopenharmony_ci			1 << IF_RTR_CTRL_E2E_PCI_EN_VAL_SHIFT);
16588c2ecf20Sopenharmony_ci
16598c2ecf20Sopenharmony_ci	WREG32(mmSIF_RTR_CTRL_6_E2E_HBM_EN,
16608c2ecf20Sopenharmony_ci			1 << IF_RTR_CTRL_E2E_HBM_EN_VAL_SHIFT);
16618c2ecf20Sopenharmony_ci	WREG32(mmSIF_RTR_CTRL_6_E2E_PCI_EN,
16628c2ecf20Sopenharmony_ci			1 << IF_RTR_CTRL_E2E_PCI_EN_VAL_SHIFT);
16638c2ecf20Sopenharmony_ci
16648c2ecf20Sopenharmony_ci	WREG32(mmSIF_RTR_CTRL_7_E2E_HBM_EN,
16658c2ecf20Sopenharmony_ci			1 << IF_RTR_CTRL_E2E_HBM_EN_VAL_SHIFT);
16668c2ecf20Sopenharmony_ci	WREG32(mmSIF_RTR_CTRL_7_E2E_PCI_EN,
16678c2ecf20Sopenharmony_ci			1 << IF_RTR_CTRL_E2E_PCI_EN_VAL_SHIFT);
16688c2ecf20Sopenharmony_ci
16698c2ecf20Sopenharmony_ci	WREG32(mmNIF_RTR_CTRL_0_E2E_HBM_EN,
16708c2ecf20Sopenharmony_ci			1 << IF_RTR_CTRL_E2E_HBM_EN_VAL_SHIFT);
16718c2ecf20Sopenharmony_ci	WREG32(mmNIF_RTR_CTRL_0_E2E_PCI_EN,
16728c2ecf20Sopenharmony_ci			1 << IF_RTR_CTRL_E2E_PCI_EN_VAL_SHIFT);
16738c2ecf20Sopenharmony_ci
16748c2ecf20Sopenharmony_ci	WREG32(mmNIF_RTR_CTRL_1_E2E_HBM_EN,
16758c2ecf20Sopenharmony_ci			1 << IF_RTR_CTRL_E2E_HBM_EN_VAL_SHIFT);
16768c2ecf20Sopenharmony_ci	WREG32(mmNIF_RTR_CTRL_1_E2E_PCI_EN,
16778c2ecf20Sopenharmony_ci			1 << IF_RTR_CTRL_E2E_PCI_EN_VAL_SHIFT);
16788c2ecf20Sopenharmony_ci
16798c2ecf20Sopenharmony_ci	WREG32(mmNIF_RTR_CTRL_2_E2E_HBM_EN,
16808c2ecf20Sopenharmony_ci			1 << IF_RTR_CTRL_E2E_HBM_EN_VAL_SHIFT);
16818c2ecf20Sopenharmony_ci	WREG32(mmNIF_RTR_CTRL_2_E2E_PCI_EN,
16828c2ecf20Sopenharmony_ci			1 << IF_RTR_CTRL_E2E_PCI_EN_VAL_SHIFT);
16838c2ecf20Sopenharmony_ci
16848c2ecf20Sopenharmony_ci	WREG32(mmNIF_RTR_CTRL_3_E2E_HBM_EN,
16858c2ecf20Sopenharmony_ci			1 << IF_RTR_CTRL_E2E_HBM_EN_VAL_SHIFT);
16868c2ecf20Sopenharmony_ci	WREG32(mmNIF_RTR_CTRL_3_E2E_PCI_EN,
16878c2ecf20Sopenharmony_ci			1 << IF_RTR_CTRL_E2E_PCI_EN_VAL_SHIFT);
16888c2ecf20Sopenharmony_ci
16898c2ecf20Sopenharmony_ci	WREG32(mmNIF_RTR_CTRL_4_E2E_HBM_EN,
16908c2ecf20Sopenharmony_ci			1 << IF_RTR_CTRL_E2E_HBM_EN_VAL_SHIFT);
16918c2ecf20Sopenharmony_ci	WREG32(mmNIF_RTR_CTRL_4_E2E_PCI_EN,
16928c2ecf20Sopenharmony_ci			1 << IF_RTR_CTRL_E2E_PCI_EN_VAL_SHIFT);
16938c2ecf20Sopenharmony_ci
16948c2ecf20Sopenharmony_ci	WREG32(mmNIF_RTR_CTRL_5_E2E_HBM_EN,
16958c2ecf20Sopenharmony_ci			1 << IF_RTR_CTRL_E2E_HBM_EN_VAL_SHIFT);
16968c2ecf20Sopenharmony_ci	WREG32(mmNIF_RTR_CTRL_5_E2E_PCI_EN,
16978c2ecf20Sopenharmony_ci			1 << IF_RTR_CTRL_E2E_PCI_EN_VAL_SHIFT);
16988c2ecf20Sopenharmony_ci
16998c2ecf20Sopenharmony_ci	WREG32(mmNIF_RTR_CTRL_6_E2E_HBM_EN,
17008c2ecf20Sopenharmony_ci			1 << IF_RTR_CTRL_E2E_HBM_EN_VAL_SHIFT);
17018c2ecf20Sopenharmony_ci	WREG32(mmNIF_RTR_CTRL_6_E2E_PCI_EN,
17028c2ecf20Sopenharmony_ci			1 << IF_RTR_CTRL_E2E_PCI_EN_VAL_SHIFT);
17038c2ecf20Sopenharmony_ci
17048c2ecf20Sopenharmony_ci	WREG32(mmNIF_RTR_CTRL_7_E2E_HBM_EN,
17058c2ecf20Sopenharmony_ci			1 << IF_RTR_CTRL_E2E_HBM_EN_VAL_SHIFT);
17068c2ecf20Sopenharmony_ci	WREG32(mmNIF_RTR_CTRL_7_E2E_PCI_EN,
17078c2ecf20Sopenharmony_ci			1 << IF_RTR_CTRL_E2E_PCI_EN_VAL_SHIFT);
17088c2ecf20Sopenharmony_ci
17098c2ecf20Sopenharmony_ci	WREG32(mmDMA_IF_E_N_DOWN_CH0_E2E_HBM_EN,
17108c2ecf20Sopenharmony_ci			1 << DMA_IF_DOWN_CHX_E2E_HBM_EN_VAL_SHIFT);
17118c2ecf20Sopenharmony_ci	WREG32(mmDMA_IF_E_N_DOWN_CH0_E2E_PCI_EN,
17128c2ecf20Sopenharmony_ci			1 << DMA_IF_DOWN_CHX_E2E_PCI_EN_VAL_SHIFT);
17138c2ecf20Sopenharmony_ci
17148c2ecf20Sopenharmony_ci	WREG32(mmDMA_IF_E_N_DOWN_CH1_E2E_HBM_EN,
17158c2ecf20Sopenharmony_ci			1 << DMA_IF_DOWN_CHX_E2E_HBM_EN_VAL_SHIFT);
17168c2ecf20Sopenharmony_ci	WREG32(mmDMA_IF_E_N_DOWN_CH1_E2E_PCI_EN,
17178c2ecf20Sopenharmony_ci			1 << DMA_IF_DOWN_CHX_E2E_PCI_EN_VAL_SHIFT);
17188c2ecf20Sopenharmony_ci
17198c2ecf20Sopenharmony_ci	WREG32(mmDMA_IF_E_S_DOWN_CH0_E2E_HBM_EN,
17208c2ecf20Sopenharmony_ci			1 << DMA_IF_DOWN_CHX_E2E_HBM_EN_VAL_SHIFT);
17218c2ecf20Sopenharmony_ci	WREG32(mmDMA_IF_E_S_DOWN_CH0_E2E_PCI_EN,
17228c2ecf20Sopenharmony_ci			1 << DMA_IF_DOWN_CHX_E2E_PCI_EN_VAL_SHIFT);
17238c2ecf20Sopenharmony_ci
17248c2ecf20Sopenharmony_ci	WREG32(mmDMA_IF_E_S_DOWN_CH1_E2E_HBM_EN,
17258c2ecf20Sopenharmony_ci			1 << DMA_IF_DOWN_CHX_E2E_HBM_EN_VAL_SHIFT);
17268c2ecf20Sopenharmony_ci	WREG32(mmDMA_IF_E_S_DOWN_CH1_E2E_PCI_EN,
17278c2ecf20Sopenharmony_ci			1 << DMA_IF_DOWN_CHX_E2E_PCI_EN_VAL_SHIFT);
17288c2ecf20Sopenharmony_ci
17298c2ecf20Sopenharmony_ci	WREG32(mmDMA_IF_W_N_DOWN_CH0_E2E_HBM_EN,
17308c2ecf20Sopenharmony_ci			1 << DMA_IF_DOWN_CHX_E2E_HBM_EN_VAL_SHIFT);
17318c2ecf20Sopenharmony_ci	WREG32(mmDMA_IF_W_N_DOWN_CH0_E2E_PCI_EN,
17328c2ecf20Sopenharmony_ci			1 << DMA_IF_DOWN_CHX_E2E_PCI_EN_VAL_SHIFT);
17338c2ecf20Sopenharmony_ci
17348c2ecf20Sopenharmony_ci	WREG32(mmDMA_IF_W_N_DOWN_CH1_E2E_HBM_EN,
17358c2ecf20Sopenharmony_ci			1 << DMA_IF_DOWN_CHX_E2E_HBM_EN_VAL_SHIFT);
17368c2ecf20Sopenharmony_ci	WREG32(mmDMA_IF_W_N_DOWN_CH1_E2E_PCI_EN,
17378c2ecf20Sopenharmony_ci			1 << DMA_IF_DOWN_CHX_E2E_PCI_EN_VAL_SHIFT);
17388c2ecf20Sopenharmony_ci
17398c2ecf20Sopenharmony_ci	WREG32(mmDMA_IF_W_S_DOWN_CH0_E2E_HBM_EN,
17408c2ecf20Sopenharmony_ci			1 << DMA_IF_DOWN_CHX_E2E_HBM_EN_VAL_SHIFT);
17418c2ecf20Sopenharmony_ci	WREG32(mmDMA_IF_W_S_DOWN_CH0_E2E_PCI_EN,
17428c2ecf20Sopenharmony_ci			1 << DMA_IF_DOWN_CHX_E2E_PCI_EN_VAL_SHIFT);
17438c2ecf20Sopenharmony_ci
17448c2ecf20Sopenharmony_ci	WREG32(mmDMA_IF_W_S_DOWN_CH1_E2E_HBM_EN,
17458c2ecf20Sopenharmony_ci			1 << DMA_IF_DOWN_CHX_E2E_HBM_EN_VAL_SHIFT);
17468c2ecf20Sopenharmony_ci	WREG32(mmDMA_IF_W_S_DOWN_CH1_E2E_PCI_EN,
17478c2ecf20Sopenharmony_ci			1 << DMA_IF_DOWN_CHX_E2E_PCI_EN_VAL_SHIFT);
17488c2ecf20Sopenharmony_ci}
17498c2ecf20Sopenharmony_ci
17508c2ecf20Sopenharmony_cistatic void gaudi_init_hbm_cred(struct hl_device *hdev)
17518c2ecf20Sopenharmony_ci{
17528c2ecf20Sopenharmony_ci	uint32_t hbm0_wr, hbm1_wr, hbm0_rd, hbm1_rd;
17538c2ecf20Sopenharmony_ci
17548c2ecf20Sopenharmony_ci	hbm0_wr = 0x33333333;
17558c2ecf20Sopenharmony_ci	hbm0_rd = 0x77777777;
17568c2ecf20Sopenharmony_ci	hbm1_wr = 0x55555555;
17578c2ecf20Sopenharmony_ci	hbm1_rd = 0xDDDDDDDD;
17588c2ecf20Sopenharmony_ci
17598c2ecf20Sopenharmony_ci	WREG32(mmDMA_IF_E_N_HBM0_WR_CRED_CNT, hbm0_wr);
17608c2ecf20Sopenharmony_ci	WREG32(mmDMA_IF_E_N_HBM1_WR_CRED_CNT, hbm1_wr);
17618c2ecf20Sopenharmony_ci	WREG32(mmDMA_IF_E_N_HBM0_RD_CRED_CNT, hbm0_rd);
17628c2ecf20Sopenharmony_ci	WREG32(mmDMA_IF_E_N_HBM1_RD_CRED_CNT, hbm1_rd);
17638c2ecf20Sopenharmony_ci
17648c2ecf20Sopenharmony_ci	WREG32(mmDMA_IF_E_S_HBM0_WR_CRED_CNT, hbm0_wr);
17658c2ecf20Sopenharmony_ci	WREG32(mmDMA_IF_E_S_HBM1_WR_CRED_CNT, hbm1_wr);
17668c2ecf20Sopenharmony_ci	WREG32(mmDMA_IF_E_S_HBM0_RD_CRED_CNT, hbm0_rd);
17678c2ecf20Sopenharmony_ci	WREG32(mmDMA_IF_E_S_HBM1_RD_CRED_CNT, hbm1_rd);
17688c2ecf20Sopenharmony_ci
17698c2ecf20Sopenharmony_ci	WREG32(mmDMA_IF_W_N_HBM0_WR_CRED_CNT, hbm0_wr);
17708c2ecf20Sopenharmony_ci	WREG32(mmDMA_IF_W_N_HBM1_WR_CRED_CNT, hbm1_wr);
17718c2ecf20Sopenharmony_ci	WREG32(mmDMA_IF_W_N_HBM0_RD_CRED_CNT, hbm0_rd);
17728c2ecf20Sopenharmony_ci	WREG32(mmDMA_IF_W_N_HBM1_RD_CRED_CNT, hbm1_rd);
17738c2ecf20Sopenharmony_ci
17748c2ecf20Sopenharmony_ci	WREG32(mmDMA_IF_W_S_HBM0_WR_CRED_CNT, hbm0_wr);
17758c2ecf20Sopenharmony_ci	WREG32(mmDMA_IF_W_S_HBM1_WR_CRED_CNT, hbm1_wr);
17768c2ecf20Sopenharmony_ci	WREG32(mmDMA_IF_W_S_HBM0_RD_CRED_CNT, hbm0_rd);
17778c2ecf20Sopenharmony_ci	WREG32(mmDMA_IF_W_S_HBM1_RD_CRED_CNT, hbm1_rd);
17788c2ecf20Sopenharmony_ci
17798c2ecf20Sopenharmony_ci	WREG32(mmDMA_IF_E_N_HBM_CRED_EN_0,
17808c2ecf20Sopenharmony_ci			(1 << DMA_IF_HBM_CRED_EN_READ_CREDIT_EN_SHIFT) |
17818c2ecf20Sopenharmony_ci			(1 << DMA_IF_HBM_CRED_EN_WRITE_CREDIT_EN_SHIFT));
17828c2ecf20Sopenharmony_ci	WREG32(mmDMA_IF_E_S_HBM_CRED_EN_0,
17838c2ecf20Sopenharmony_ci			(1 << DMA_IF_HBM_CRED_EN_READ_CREDIT_EN_SHIFT) |
17848c2ecf20Sopenharmony_ci			(1 << DMA_IF_HBM_CRED_EN_WRITE_CREDIT_EN_SHIFT));
17858c2ecf20Sopenharmony_ci	WREG32(mmDMA_IF_W_N_HBM_CRED_EN_0,
17868c2ecf20Sopenharmony_ci			(1 << DMA_IF_HBM_CRED_EN_READ_CREDIT_EN_SHIFT) |
17878c2ecf20Sopenharmony_ci			(1 << DMA_IF_HBM_CRED_EN_WRITE_CREDIT_EN_SHIFT));
17888c2ecf20Sopenharmony_ci	WREG32(mmDMA_IF_W_S_HBM_CRED_EN_0,
17898c2ecf20Sopenharmony_ci			(1 << DMA_IF_HBM_CRED_EN_READ_CREDIT_EN_SHIFT) |
17908c2ecf20Sopenharmony_ci			(1 << DMA_IF_HBM_CRED_EN_WRITE_CREDIT_EN_SHIFT));
17918c2ecf20Sopenharmony_ci
17928c2ecf20Sopenharmony_ci	WREG32(mmDMA_IF_E_N_HBM_CRED_EN_1,
17938c2ecf20Sopenharmony_ci			(1 << DMA_IF_HBM_CRED_EN_READ_CREDIT_EN_SHIFT) |
17948c2ecf20Sopenharmony_ci			(1 << DMA_IF_HBM_CRED_EN_WRITE_CREDIT_EN_SHIFT));
17958c2ecf20Sopenharmony_ci	WREG32(mmDMA_IF_E_S_HBM_CRED_EN_1,
17968c2ecf20Sopenharmony_ci			(1 << DMA_IF_HBM_CRED_EN_READ_CREDIT_EN_SHIFT) |
17978c2ecf20Sopenharmony_ci			(1 << DMA_IF_HBM_CRED_EN_WRITE_CREDIT_EN_SHIFT));
17988c2ecf20Sopenharmony_ci	WREG32(mmDMA_IF_W_N_HBM_CRED_EN_1,
17998c2ecf20Sopenharmony_ci			(1 << DMA_IF_HBM_CRED_EN_READ_CREDIT_EN_SHIFT) |
18008c2ecf20Sopenharmony_ci			(1 << DMA_IF_HBM_CRED_EN_WRITE_CREDIT_EN_SHIFT));
18018c2ecf20Sopenharmony_ci	WREG32(mmDMA_IF_W_S_HBM_CRED_EN_1,
18028c2ecf20Sopenharmony_ci			(1 << DMA_IF_HBM_CRED_EN_READ_CREDIT_EN_SHIFT) |
18038c2ecf20Sopenharmony_ci			(1 << DMA_IF_HBM_CRED_EN_WRITE_CREDIT_EN_SHIFT));
18048c2ecf20Sopenharmony_ci}
18058c2ecf20Sopenharmony_ci
18068c2ecf20Sopenharmony_cistatic void gaudi_init_golden_registers(struct hl_device *hdev)
18078c2ecf20Sopenharmony_ci{
18088c2ecf20Sopenharmony_ci	u32 tpc_offset;
18098c2ecf20Sopenharmony_ci	int tpc_id, i;
18108c2ecf20Sopenharmony_ci
18118c2ecf20Sopenharmony_ci	gaudi_init_e2e(hdev);
18128c2ecf20Sopenharmony_ci
18138c2ecf20Sopenharmony_ci	gaudi_init_hbm_cred(hdev);
18148c2ecf20Sopenharmony_ci
18158c2ecf20Sopenharmony_ci	hdev->asic_funcs->disable_clock_gating(hdev);
18168c2ecf20Sopenharmony_ci
18178c2ecf20Sopenharmony_ci	for (tpc_id = 0, tpc_offset = 0;
18188c2ecf20Sopenharmony_ci				tpc_id < TPC_NUMBER_OF_ENGINES;
18198c2ecf20Sopenharmony_ci				tpc_id++, tpc_offset += TPC_CFG_OFFSET) {
18208c2ecf20Sopenharmony_ci		/* Mask all arithmetic interrupts from TPC */
18218c2ecf20Sopenharmony_ci		WREG32(mmTPC0_CFG_TPC_INTR_MASK + tpc_offset, 0x8FFF);
18228c2ecf20Sopenharmony_ci		/* Set 16 cache lines */
18238c2ecf20Sopenharmony_ci		WREG32_FIELD(TPC0_CFG_MSS_CONFIG, tpc_offset,
18248c2ecf20Sopenharmony_ci				ICACHE_FETCH_LINE_NUM, 2);
18258c2ecf20Sopenharmony_ci	}
18268c2ecf20Sopenharmony_ci
18278c2ecf20Sopenharmony_ci	/* Make sure 1st 128 bytes in SRAM are 0 for Tensor DMA */
18288c2ecf20Sopenharmony_ci	for (i = 0 ; i < 128 ; i += 8)
18298c2ecf20Sopenharmony_ci		writeq(0, hdev->pcie_bar[SRAM_BAR_ID] + i);
18308c2ecf20Sopenharmony_ci
18318c2ecf20Sopenharmony_ci	WREG32(mmMME0_CTRL_EUS_ROLLUP_CNT_ADD, 3);
18328c2ecf20Sopenharmony_ci	WREG32(mmMME1_CTRL_EUS_ROLLUP_CNT_ADD, 3);
18338c2ecf20Sopenharmony_ci	WREG32(mmMME2_CTRL_EUS_ROLLUP_CNT_ADD, 3);
18348c2ecf20Sopenharmony_ci	WREG32(mmMME3_CTRL_EUS_ROLLUP_CNT_ADD, 3);
18358c2ecf20Sopenharmony_ci}
18368c2ecf20Sopenharmony_ci
18378c2ecf20Sopenharmony_cistatic void gaudi_init_pci_dma_qman(struct hl_device *hdev, int dma_id,
18388c2ecf20Sopenharmony_ci					int qman_id, dma_addr_t qman_pq_addr)
18398c2ecf20Sopenharmony_ci{
18408c2ecf20Sopenharmony_ci	u32 mtr_base_en_lo, mtr_base_en_hi, mtr_base_ws_lo, mtr_base_ws_hi;
18418c2ecf20Sopenharmony_ci	u32 so_base_en_lo, so_base_en_hi, so_base_ws_lo, so_base_ws_hi;
18428c2ecf20Sopenharmony_ci	u32 q_off, dma_qm_offset;
18438c2ecf20Sopenharmony_ci	u32 dma_qm_err_cfg;
18448c2ecf20Sopenharmony_ci
18458c2ecf20Sopenharmony_ci	dma_qm_offset = dma_id * DMA_QMAN_OFFSET;
18468c2ecf20Sopenharmony_ci
18478c2ecf20Sopenharmony_ci	mtr_base_en_lo = lower_32_bits(CFG_BASE +
18488c2ecf20Sopenharmony_ci				mmSYNC_MNGR_E_N_SYNC_MNGR_OBJS_MON_PAY_ADDRL_0);
18498c2ecf20Sopenharmony_ci	mtr_base_en_hi = upper_32_bits(CFG_BASE +
18508c2ecf20Sopenharmony_ci				mmSYNC_MNGR_E_N_SYNC_MNGR_OBJS_MON_PAY_ADDRL_0);
18518c2ecf20Sopenharmony_ci	so_base_en_lo = lower_32_bits(CFG_BASE +
18528c2ecf20Sopenharmony_ci				mmSYNC_MNGR_E_N_SYNC_MNGR_OBJS_SOB_OBJ_0);
18538c2ecf20Sopenharmony_ci	so_base_en_hi = upper_32_bits(CFG_BASE +
18548c2ecf20Sopenharmony_ci				mmSYNC_MNGR_E_N_SYNC_MNGR_OBJS_SOB_OBJ_0);
18558c2ecf20Sopenharmony_ci	mtr_base_ws_lo = lower_32_bits(CFG_BASE +
18568c2ecf20Sopenharmony_ci				mmSYNC_MNGR_W_S_SYNC_MNGR_OBJS_MON_PAY_ADDRL_0);
18578c2ecf20Sopenharmony_ci	mtr_base_ws_hi = upper_32_bits(CFG_BASE +
18588c2ecf20Sopenharmony_ci				mmSYNC_MNGR_W_S_SYNC_MNGR_OBJS_MON_PAY_ADDRL_0);
18598c2ecf20Sopenharmony_ci	so_base_ws_lo = lower_32_bits(CFG_BASE +
18608c2ecf20Sopenharmony_ci				mmSYNC_MNGR_W_S_SYNC_MNGR_OBJS_SOB_OBJ_0);
18618c2ecf20Sopenharmony_ci	so_base_ws_hi = upper_32_bits(CFG_BASE +
18628c2ecf20Sopenharmony_ci				mmSYNC_MNGR_W_S_SYNC_MNGR_OBJS_SOB_OBJ_0);
18638c2ecf20Sopenharmony_ci
18648c2ecf20Sopenharmony_ci	q_off = dma_qm_offset + qman_id * 4;
18658c2ecf20Sopenharmony_ci
18668c2ecf20Sopenharmony_ci	WREG32(mmDMA0_QM_PQ_BASE_LO_0 + q_off, lower_32_bits(qman_pq_addr));
18678c2ecf20Sopenharmony_ci	WREG32(mmDMA0_QM_PQ_BASE_HI_0 + q_off, upper_32_bits(qman_pq_addr));
18688c2ecf20Sopenharmony_ci
18698c2ecf20Sopenharmony_ci	WREG32(mmDMA0_QM_PQ_SIZE_0 + q_off, ilog2(HL_QUEUE_LENGTH));
18708c2ecf20Sopenharmony_ci	WREG32(mmDMA0_QM_PQ_PI_0 + q_off, 0);
18718c2ecf20Sopenharmony_ci	WREG32(mmDMA0_QM_PQ_CI_0 + q_off, 0);
18728c2ecf20Sopenharmony_ci
18738c2ecf20Sopenharmony_ci	WREG32(mmDMA0_QM_CP_LDMA_TSIZE_OFFSET_0 + q_off, QMAN_LDMA_SIZE_OFFSET);
18748c2ecf20Sopenharmony_ci	WREG32(mmDMA0_QM_CP_LDMA_SRC_BASE_LO_OFFSET_0 + q_off,
18758c2ecf20Sopenharmony_ci							QMAN_LDMA_SRC_OFFSET);
18768c2ecf20Sopenharmony_ci	WREG32(mmDMA0_QM_CP_LDMA_DST_BASE_LO_OFFSET_0 + q_off,
18778c2ecf20Sopenharmony_ci							QMAN_LDMA_DST_OFFSET);
18788c2ecf20Sopenharmony_ci
18798c2ecf20Sopenharmony_ci	WREG32(mmDMA0_QM_CP_MSG_BASE0_ADDR_LO_0 + q_off, mtr_base_en_lo);
18808c2ecf20Sopenharmony_ci	WREG32(mmDMA0_QM_CP_MSG_BASE0_ADDR_HI_0 + q_off, mtr_base_en_hi);
18818c2ecf20Sopenharmony_ci	WREG32(mmDMA0_QM_CP_MSG_BASE1_ADDR_LO_0 + q_off, so_base_en_lo);
18828c2ecf20Sopenharmony_ci	WREG32(mmDMA0_QM_CP_MSG_BASE1_ADDR_HI_0 + q_off, so_base_en_hi);
18838c2ecf20Sopenharmony_ci	WREG32(mmDMA0_QM_CP_MSG_BASE2_ADDR_LO_0 + q_off, mtr_base_ws_lo);
18848c2ecf20Sopenharmony_ci	WREG32(mmDMA0_QM_CP_MSG_BASE2_ADDR_HI_0 + q_off, mtr_base_ws_hi);
18858c2ecf20Sopenharmony_ci	WREG32(mmDMA0_QM_CP_MSG_BASE3_ADDR_LO_0 + q_off, so_base_ws_lo);
18868c2ecf20Sopenharmony_ci	WREG32(mmDMA0_QM_CP_MSG_BASE3_ADDR_HI_0 + q_off, so_base_ws_hi);
18878c2ecf20Sopenharmony_ci
18888c2ecf20Sopenharmony_ci	WREG32(mmDMA0_QM_CP_BARRIER_CFG_0 + q_off, 0x100);
18898c2ecf20Sopenharmony_ci
18908c2ecf20Sopenharmony_ci	/* The following configuration is needed only once per QMAN */
18918c2ecf20Sopenharmony_ci	if (qman_id == 0) {
18928c2ecf20Sopenharmony_ci		/* Configure RAZWI IRQ */
18938c2ecf20Sopenharmony_ci		dma_qm_err_cfg = PCI_DMA_QMAN_GLBL_ERR_CFG_MSG_EN_MASK;
18948c2ecf20Sopenharmony_ci		if (hdev->stop_on_err) {
18958c2ecf20Sopenharmony_ci			dma_qm_err_cfg |=
18968c2ecf20Sopenharmony_ci				PCI_DMA_QMAN_GLBL_ERR_CFG_STOP_ON_ERR_EN_MASK;
18978c2ecf20Sopenharmony_ci		}
18988c2ecf20Sopenharmony_ci
18998c2ecf20Sopenharmony_ci		WREG32(mmDMA0_QM_GLBL_ERR_CFG + dma_qm_offset, dma_qm_err_cfg);
19008c2ecf20Sopenharmony_ci		WREG32(mmDMA0_QM_GLBL_ERR_ADDR_LO + dma_qm_offset,
19018c2ecf20Sopenharmony_ci			lower_32_bits(CFG_BASE +
19028c2ecf20Sopenharmony_ci					mmGIC_DISTRIBUTOR__5_GICD_SETSPI_NSR));
19038c2ecf20Sopenharmony_ci		WREG32(mmDMA0_QM_GLBL_ERR_ADDR_HI + dma_qm_offset,
19048c2ecf20Sopenharmony_ci			upper_32_bits(CFG_BASE +
19058c2ecf20Sopenharmony_ci					mmGIC_DISTRIBUTOR__5_GICD_SETSPI_NSR));
19068c2ecf20Sopenharmony_ci		WREG32(mmDMA0_QM_GLBL_ERR_WDATA + dma_qm_offset,
19078c2ecf20Sopenharmony_ci			gaudi_irq_map_table[GAUDI_EVENT_DMA0_QM].cpu_id +
19088c2ecf20Sopenharmony_ci									dma_id);
19098c2ecf20Sopenharmony_ci
19108c2ecf20Sopenharmony_ci		WREG32(mmDMA0_QM_ARB_ERR_MSG_EN + dma_qm_offset,
19118c2ecf20Sopenharmony_ci				QM_ARB_ERR_MSG_EN_MASK);
19128c2ecf20Sopenharmony_ci
19138c2ecf20Sopenharmony_ci		/* Increase ARB WDT to support streams architecture */
19148c2ecf20Sopenharmony_ci		WREG32(mmDMA0_QM_ARB_SLV_CHOISE_WDT + dma_qm_offset,
19158c2ecf20Sopenharmony_ci				GAUDI_ARB_WDT_TIMEOUT);
19168c2ecf20Sopenharmony_ci
19178c2ecf20Sopenharmony_ci		WREG32(mmDMA0_QM_GLBL_PROT + dma_qm_offset,
19188c2ecf20Sopenharmony_ci				QMAN_EXTERNAL_MAKE_TRUSTED);
19198c2ecf20Sopenharmony_ci
19208c2ecf20Sopenharmony_ci		WREG32(mmDMA0_QM_GLBL_CFG1 + dma_qm_offset, 0);
19218c2ecf20Sopenharmony_ci	}
19228c2ecf20Sopenharmony_ci}
19238c2ecf20Sopenharmony_ci
19248c2ecf20Sopenharmony_cistatic void gaudi_init_dma_core(struct hl_device *hdev, int dma_id)
19258c2ecf20Sopenharmony_ci{
19268c2ecf20Sopenharmony_ci	u32 dma_offset = dma_id * DMA_CORE_OFFSET;
19278c2ecf20Sopenharmony_ci	u32 dma_err_cfg = 1 << DMA0_CORE_ERR_CFG_ERR_MSG_EN_SHIFT;
19288c2ecf20Sopenharmony_ci
19298c2ecf20Sopenharmony_ci	/* Set to maximum possible according to physical size */
19308c2ecf20Sopenharmony_ci	WREG32(mmDMA0_CORE_RD_MAX_OUTSTAND + dma_offset, 0);
19318c2ecf20Sopenharmony_ci	WREG32(mmDMA0_CORE_RD_MAX_SIZE + dma_offset, 0);
19328c2ecf20Sopenharmony_ci
19338c2ecf20Sopenharmony_ci	/* WA for H/W bug H3-2116 */
19348c2ecf20Sopenharmony_ci	WREG32(mmDMA0_CORE_LBW_MAX_OUTSTAND + dma_offset, 15);
19358c2ecf20Sopenharmony_ci
19368c2ecf20Sopenharmony_ci	/* STOP_ON bit implies no completion to operation in case of RAZWI */
19378c2ecf20Sopenharmony_ci	if (hdev->stop_on_err)
19388c2ecf20Sopenharmony_ci		dma_err_cfg |= 1 << DMA0_CORE_ERR_CFG_STOP_ON_ERR_SHIFT;
19398c2ecf20Sopenharmony_ci
19408c2ecf20Sopenharmony_ci	WREG32(mmDMA0_CORE_ERR_CFG + dma_offset, dma_err_cfg);
19418c2ecf20Sopenharmony_ci	WREG32(mmDMA0_CORE_ERRMSG_ADDR_LO + dma_offset,
19428c2ecf20Sopenharmony_ci		lower_32_bits(CFG_BASE + mmGIC_DISTRIBUTOR__5_GICD_SETSPI_NSR));
19438c2ecf20Sopenharmony_ci	WREG32(mmDMA0_CORE_ERRMSG_ADDR_HI + dma_offset,
19448c2ecf20Sopenharmony_ci		upper_32_bits(CFG_BASE + mmGIC_DISTRIBUTOR__5_GICD_SETSPI_NSR));
19458c2ecf20Sopenharmony_ci	WREG32(mmDMA0_CORE_ERRMSG_WDATA + dma_offset,
19468c2ecf20Sopenharmony_ci		gaudi_irq_map_table[GAUDI_EVENT_DMA0_CORE].cpu_id + dma_id);
19478c2ecf20Sopenharmony_ci	WREG32(mmDMA0_CORE_PROT + dma_offset,
19488c2ecf20Sopenharmony_ci			1 << DMA0_CORE_PROT_ERR_VAL_SHIFT);
19498c2ecf20Sopenharmony_ci	/* If the channel is secured, it should be in MMU bypass mode */
19508c2ecf20Sopenharmony_ci	WREG32(mmDMA0_CORE_SECURE_PROPS + dma_offset,
19518c2ecf20Sopenharmony_ci			1 << DMA0_CORE_SECURE_PROPS_MMBP_SHIFT);
19528c2ecf20Sopenharmony_ci	WREG32(mmDMA0_CORE_CFG_0 + dma_offset, 1 << DMA0_CORE_CFG_0_EN_SHIFT);
19538c2ecf20Sopenharmony_ci}
19548c2ecf20Sopenharmony_ci
19558c2ecf20Sopenharmony_cistatic void gaudi_enable_qman(struct hl_device *hdev, int dma_id,
19568c2ecf20Sopenharmony_ci				u32 enable_mask)
19578c2ecf20Sopenharmony_ci{
19588c2ecf20Sopenharmony_ci	u32 dma_qm_offset = dma_id * DMA_QMAN_OFFSET;
19598c2ecf20Sopenharmony_ci
19608c2ecf20Sopenharmony_ci	WREG32(mmDMA0_QM_GLBL_CFG0 + dma_qm_offset, enable_mask);
19618c2ecf20Sopenharmony_ci}
19628c2ecf20Sopenharmony_ci
19638c2ecf20Sopenharmony_cistatic void gaudi_init_pci_dma_qmans(struct hl_device *hdev)
19648c2ecf20Sopenharmony_ci{
19658c2ecf20Sopenharmony_ci	struct gaudi_device *gaudi = hdev->asic_specific;
19668c2ecf20Sopenharmony_ci	struct hl_hw_queue *q;
19678c2ecf20Sopenharmony_ci	int i, j, dma_id, cpu_skip, nic_skip, cq_id = 0, q_idx, msi_vec = 0;
19688c2ecf20Sopenharmony_ci
19698c2ecf20Sopenharmony_ci	if (gaudi->hw_cap_initialized & HW_CAP_PCI_DMA)
19708c2ecf20Sopenharmony_ci		return;
19718c2ecf20Sopenharmony_ci
19728c2ecf20Sopenharmony_ci	for (i = 0 ; i < PCI_DMA_NUMBER_OF_CHNLS ; i++) {
19738c2ecf20Sopenharmony_ci		dma_id = gaudi_dma_assignment[i];
19748c2ecf20Sopenharmony_ci		/*
19758c2ecf20Sopenharmony_ci		 * For queues after the CPU Q need to add 1 to get the correct
19768c2ecf20Sopenharmony_ci		 * queue. In addition, need to add the CPU EQ and NIC IRQs in
19778c2ecf20Sopenharmony_ci		 * order to get the correct MSI register.
19788c2ecf20Sopenharmony_ci		 */
19798c2ecf20Sopenharmony_ci		if (dma_id > 1) {
19808c2ecf20Sopenharmony_ci			cpu_skip = 1;
19818c2ecf20Sopenharmony_ci			nic_skip = NIC_NUMBER_OF_ENGINES;
19828c2ecf20Sopenharmony_ci		} else {
19838c2ecf20Sopenharmony_ci			cpu_skip = 0;
19848c2ecf20Sopenharmony_ci			nic_skip = 0;
19858c2ecf20Sopenharmony_ci		}
19868c2ecf20Sopenharmony_ci
19878c2ecf20Sopenharmony_ci		for (j = 0 ; j < QMAN_STREAMS ; j++) {
19888c2ecf20Sopenharmony_ci			q_idx = 4 * dma_id + j + cpu_skip;
19898c2ecf20Sopenharmony_ci			q = &hdev->kernel_queues[q_idx];
19908c2ecf20Sopenharmony_ci			q->cq_id = cq_id++;
19918c2ecf20Sopenharmony_ci			q->msi_vec = nic_skip + cpu_skip + msi_vec++;
19928c2ecf20Sopenharmony_ci			gaudi_init_pci_dma_qman(hdev, dma_id, j,
19938c2ecf20Sopenharmony_ci						q->bus_address);
19948c2ecf20Sopenharmony_ci		}
19958c2ecf20Sopenharmony_ci
19968c2ecf20Sopenharmony_ci		gaudi_init_dma_core(hdev, dma_id);
19978c2ecf20Sopenharmony_ci
19988c2ecf20Sopenharmony_ci		gaudi_enable_qman(hdev, dma_id, PCI_DMA_QMAN_ENABLE);
19998c2ecf20Sopenharmony_ci	}
20008c2ecf20Sopenharmony_ci
20018c2ecf20Sopenharmony_ci	gaudi->hw_cap_initialized |= HW_CAP_PCI_DMA;
20028c2ecf20Sopenharmony_ci}
20038c2ecf20Sopenharmony_ci
20048c2ecf20Sopenharmony_cistatic void gaudi_init_hbm_dma_qman(struct hl_device *hdev, int dma_id,
20058c2ecf20Sopenharmony_ci					int qman_id, u64 qman_base_addr)
20068c2ecf20Sopenharmony_ci{
20078c2ecf20Sopenharmony_ci	u32 mtr_base_lo, mtr_base_hi;
20088c2ecf20Sopenharmony_ci	u32 so_base_lo, so_base_hi;
20098c2ecf20Sopenharmony_ci	u32 q_off, dma_qm_offset;
20108c2ecf20Sopenharmony_ci	u32 dma_qm_err_cfg;
20118c2ecf20Sopenharmony_ci
20128c2ecf20Sopenharmony_ci	dma_qm_offset = dma_id * DMA_QMAN_OFFSET;
20138c2ecf20Sopenharmony_ci
20148c2ecf20Sopenharmony_ci	mtr_base_lo = lower_32_bits(CFG_BASE +
20158c2ecf20Sopenharmony_ci				mmSYNC_MNGR_E_N_SYNC_MNGR_OBJS_MON_PAY_ADDRL_0);
20168c2ecf20Sopenharmony_ci	mtr_base_hi = upper_32_bits(CFG_BASE +
20178c2ecf20Sopenharmony_ci				mmSYNC_MNGR_E_N_SYNC_MNGR_OBJS_MON_PAY_ADDRL_0);
20188c2ecf20Sopenharmony_ci	so_base_lo = lower_32_bits(CFG_BASE +
20198c2ecf20Sopenharmony_ci				mmSYNC_MNGR_E_N_SYNC_MNGR_OBJS_SOB_OBJ_0);
20208c2ecf20Sopenharmony_ci	so_base_hi = upper_32_bits(CFG_BASE +
20218c2ecf20Sopenharmony_ci				mmSYNC_MNGR_E_N_SYNC_MNGR_OBJS_SOB_OBJ_0);
20228c2ecf20Sopenharmony_ci
20238c2ecf20Sopenharmony_ci	q_off = dma_qm_offset + qman_id * 4;
20248c2ecf20Sopenharmony_ci
20258c2ecf20Sopenharmony_ci	if (qman_id < 4) {
20268c2ecf20Sopenharmony_ci		WREG32(mmDMA0_QM_PQ_BASE_LO_0 + q_off,
20278c2ecf20Sopenharmony_ci					lower_32_bits(qman_base_addr));
20288c2ecf20Sopenharmony_ci		WREG32(mmDMA0_QM_PQ_BASE_HI_0 + q_off,
20298c2ecf20Sopenharmony_ci					upper_32_bits(qman_base_addr));
20308c2ecf20Sopenharmony_ci
20318c2ecf20Sopenharmony_ci		WREG32(mmDMA0_QM_PQ_SIZE_0 + q_off, ilog2(HBM_DMA_QMAN_LENGTH));
20328c2ecf20Sopenharmony_ci		WREG32(mmDMA0_QM_PQ_PI_0 + q_off, 0);
20338c2ecf20Sopenharmony_ci		WREG32(mmDMA0_QM_PQ_CI_0 + q_off, 0);
20348c2ecf20Sopenharmony_ci
20358c2ecf20Sopenharmony_ci		WREG32(mmDMA0_QM_CP_LDMA_TSIZE_OFFSET_0 + q_off,
20368c2ecf20Sopenharmony_ci							QMAN_CPDMA_SIZE_OFFSET);
20378c2ecf20Sopenharmony_ci		WREG32(mmDMA0_QM_CP_LDMA_SRC_BASE_LO_OFFSET_0 + q_off,
20388c2ecf20Sopenharmony_ci							QMAN_CPDMA_SRC_OFFSET);
20398c2ecf20Sopenharmony_ci		WREG32(mmDMA0_QM_CP_LDMA_DST_BASE_LO_OFFSET_0 + q_off,
20408c2ecf20Sopenharmony_ci							QMAN_CPDMA_DST_OFFSET);
20418c2ecf20Sopenharmony_ci	} else {
20428c2ecf20Sopenharmony_ci		WREG32(mmDMA0_QM_CP_LDMA_TSIZE_OFFSET_0 + q_off,
20438c2ecf20Sopenharmony_ci							QMAN_LDMA_SIZE_OFFSET);
20448c2ecf20Sopenharmony_ci		WREG32(mmDMA0_QM_CP_LDMA_SRC_BASE_LO_OFFSET_0 + q_off,
20458c2ecf20Sopenharmony_ci							QMAN_LDMA_SRC_OFFSET);
20468c2ecf20Sopenharmony_ci		WREG32(mmDMA0_QM_CP_LDMA_DST_BASE_LO_OFFSET_0 + q_off,
20478c2ecf20Sopenharmony_ci							QMAN_LDMA_DST_OFFSET);
20488c2ecf20Sopenharmony_ci
20498c2ecf20Sopenharmony_ci		/* Configure RAZWI IRQ */
20508c2ecf20Sopenharmony_ci		dma_qm_err_cfg = HBM_DMA_QMAN_GLBL_ERR_CFG_MSG_EN_MASK;
20518c2ecf20Sopenharmony_ci		if (hdev->stop_on_err) {
20528c2ecf20Sopenharmony_ci			dma_qm_err_cfg |=
20538c2ecf20Sopenharmony_ci				HBM_DMA_QMAN_GLBL_ERR_CFG_STOP_ON_ERR_EN_MASK;
20548c2ecf20Sopenharmony_ci		}
20558c2ecf20Sopenharmony_ci		WREG32(mmDMA0_QM_GLBL_ERR_CFG + dma_qm_offset, dma_qm_err_cfg);
20568c2ecf20Sopenharmony_ci
20578c2ecf20Sopenharmony_ci		WREG32(mmDMA0_QM_GLBL_ERR_ADDR_LO + dma_qm_offset,
20588c2ecf20Sopenharmony_ci			lower_32_bits(CFG_BASE +
20598c2ecf20Sopenharmony_ci					mmGIC_DISTRIBUTOR__5_GICD_SETSPI_NSR));
20608c2ecf20Sopenharmony_ci		WREG32(mmDMA0_QM_GLBL_ERR_ADDR_HI + dma_qm_offset,
20618c2ecf20Sopenharmony_ci			upper_32_bits(CFG_BASE +
20628c2ecf20Sopenharmony_ci					mmGIC_DISTRIBUTOR__5_GICD_SETSPI_NSR));
20638c2ecf20Sopenharmony_ci		WREG32(mmDMA0_QM_GLBL_ERR_WDATA + dma_qm_offset,
20648c2ecf20Sopenharmony_ci			gaudi_irq_map_table[GAUDI_EVENT_DMA0_QM].cpu_id +
20658c2ecf20Sopenharmony_ci									dma_id);
20668c2ecf20Sopenharmony_ci
20678c2ecf20Sopenharmony_ci		WREG32(mmDMA0_QM_ARB_ERR_MSG_EN + dma_qm_offset,
20688c2ecf20Sopenharmony_ci				QM_ARB_ERR_MSG_EN_MASK);
20698c2ecf20Sopenharmony_ci
20708c2ecf20Sopenharmony_ci		/* Increase ARB WDT to support streams architecture */
20718c2ecf20Sopenharmony_ci		WREG32(mmDMA0_QM_ARB_SLV_CHOISE_WDT + dma_qm_offset,
20728c2ecf20Sopenharmony_ci				GAUDI_ARB_WDT_TIMEOUT);
20738c2ecf20Sopenharmony_ci
20748c2ecf20Sopenharmony_ci		WREG32(mmDMA0_QM_GLBL_CFG1 + dma_qm_offset, 0);
20758c2ecf20Sopenharmony_ci		WREG32(mmDMA0_QM_GLBL_PROT + dma_qm_offset,
20768c2ecf20Sopenharmony_ci				QMAN_INTERNAL_MAKE_TRUSTED);
20778c2ecf20Sopenharmony_ci	}
20788c2ecf20Sopenharmony_ci
20798c2ecf20Sopenharmony_ci	WREG32(mmDMA0_QM_CP_MSG_BASE0_ADDR_LO_0 + q_off, mtr_base_lo);
20808c2ecf20Sopenharmony_ci	WREG32(mmDMA0_QM_CP_MSG_BASE0_ADDR_HI_0 + q_off, mtr_base_hi);
20818c2ecf20Sopenharmony_ci	WREG32(mmDMA0_QM_CP_MSG_BASE1_ADDR_LO_0 + q_off, so_base_lo);
20828c2ecf20Sopenharmony_ci	WREG32(mmDMA0_QM_CP_MSG_BASE1_ADDR_HI_0 + q_off, so_base_hi);
20838c2ecf20Sopenharmony_ci}
20848c2ecf20Sopenharmony_ci
20858c2ecf20Sopenharmony_cistatic void gaudi_init_hbm_dma_qmans(struct hl_device *hdev)
20868c2ecf20Sopenharmony_ci{
20878c2ecf20Sopenharmony_ci	struct gaudi_device *gaudi = hdev->asic_specific;
20888c2ecf20Sopenharmony_ci	struct gaudi_internal_qman_info *q;
20898c2ecf20Sopenharmony_ci	u64 qman_base_addr;
20908c2ecf20Sopenharmony_ci	int i, j, dma_id, internal_q_index;
20918c2ecf20Sopenharmony_ci
20928c2ecf20Sopenharmony_ci	if (gaudi->hw_cap_initialized & HW_CAP_HBM_DMA)
20938c2ecf20Sopenharmony_ci		return;
20948c2ecf20Sopenharmony_ci
20958c2ecf20Sopenharmony_ci	for (i = 0 ; i < HBM_DMA_NUMBER_OF_CHNLS ; i++) {
20968c2ecf20Sopenharmony_ci		dma_id = gaudi_dma_assignment[GAUDI_HBM_DMA_1 + i];
20978c2ecf20Sopenharmony_ci
20988c2ecf20Sopenharmony_ci		for (j = 0 ; j < QMAN_STREAMS ; j++) {
20998c2ecf20Sopenharmony_ci			 /*
21008c2ecf20Sopenharmony_ci			  * Add the CPU queue in order to get the correct queue
21018c2ecf20Sopenharmony_ci			  * number as all internal queue are placed after it
21028c2ecf20Sopenharmony_ci			  */
21038c2ecf20Sopenharmony_ci			internal_q_index = dma_id * QMAN_STREAMS + j + 1;
21048c2ecf20Sopenharmony_ci
21058c2ecf20Sopenharmony_ci			q = &gaudi->internal_qmans[internal_q_index];
21068c2ecf20Sopenharmony_ci			qman_base_addr = (u64) q->pq_dma_addr;
21078c2ecf20Sopenharmony_ci			gaudi_init_hbm_dma_qman(hdev, dma_id, j,
21088c2ecf20Sopenharmony_ci						qman_base_addr);
21098c2ecf20Sopenharmony_ci		}
21108c2ecf20Sopenharmony_ci
21118c2ecf20Sopenharmony_ci		/* Initializing lower CP for HBM DMA QMAN */
21128c2ecf20Sopenharmony_ci		gaudi_init_hbm_dma_qman(hdev, dma_id, 4, 0);
21138c2ecf20Sopenharmony_ci
21148c2ecf20Sopenharmony_ci		gaudi_init_dma_core(hdev, dma_id);
21158c2ecf20Sopenharmony_ci
21168c2ecf20Sopenharmony_ci		gaudi_enable_qman(hdev, dma_id, HBM_DMA_QMAN_ENABLE);
21178c2ecf20Sopenharmony_ci	}
21188c2ecf20Sopenharmony_ci
21198c2ecf20Sopenharmony_ci	gaudi->hw_cap_initialized |= HW_CAP_HBM_DMA;
21208c2ecf20Sopenharmony_ci}
21218c2ecf20Sopenharmony_ci
21228c2ecf20Sopenharmony_cistatic void gaudi_init_mme_qman(struct hl_device *hdev, u32 mme_offset,
21238c2ecf20Sopenharmony_ci					int qman_id, u64 qman_base_addr)
21248c2ecf20Sopenharmony_ci{
21258c2ecf20Sopenharmony_ci	u32 mtr_base_lo, mtr_base_hi;
21268c2ecf20Sopenharmony_ci	u32 so_base_lo, so_base_hi;
21278c2ecf20Sopenharmony_ci	u32 q_off, mme_id;
21288c2ecf20Sopenharmony_ci	u32 mme_qm_err_cfg;
21298c2ecf20Sopenharmony_ci
21308c2ecf20Sopenharmony_ci	mtr_base_lo = lower_32_bits(CFG_BASE +
21318c2ecf20Sopenharmony_ci				mmSYNC_MNGR_E_N_SYNC_MNGR_OBJS_MON_PAY_ADDRL_0);
21328c2ecf20Sopenharmony_ci	mtr_base_hi = upper_32_bits(CFG_BASE +
21338c2ecf20Sopenharmony_ci				mmSYNC_MNGR_E_N_SYNC_MNGR_OBJS_MON_PAY_ADDRL_0);
21348c2ecf20Sopenharmony_ci	so_base_lo = lower_32_bits(CFG_BASE +
21358c2ecf20Sopenharmony_ci				mmSYNC_MNGR_E_N_SYNC_MNGR_OBJS_SOB_OBJ_0);
21368c2ecf20Sopenharmony_ci	so_base_hi = upper_32_bits(CFG_BASE +
21378c2ecf20Sopenharmony_ci				mmSYNC_MNGR_E_N_SYNC_MNGR_OBJS_SOB_OBJ_0);
21388c2ecf20Sopenharmony_ci
21398c2ecf20Sopenharmony_ci	q_off = mme_offset + qman_id * 4;
21408c2ecf20Sopenharmony_ci
21418c2ecf20Sopenharmony_ci	if (qman_id < 4) {
21428c2ecf20Sopenharmony_ci		WREG32(mmMME0_QM_PQ_BASE_LO_0 + q_off,
21438c2ecf20Sopenharmony_ci					lower_32_bits(qman_base_addr));
21448c2ecf20Sopenharmony_ci		WREG32(mmMME0_QM_PQ_BASE_HI_0 + q_off,
21458c2ecf20Sopenharmony_ci					upper_32_bits(qman_base_addr));
21468c2ecf20Sopenharmony_ci
21478c2ecf20Sopenharmony_ci		WREG32(mmMME0_QM_PQ_SIZE_0 + q_off, ilog2(MME_QMAN_LENGTH));
21488c2ecf20Sopenharmony_ci		WREG32(mmMME0_QM_PQ_PI_0 + q_off, 0);
21498c2ecf20Sopenharmony_ci		WREG32(mmMME0_QM_PQ_CI_0 + q_off, 0);
21508c2ecf20Sopenharmony_ci
21518c2ecf20Sopenharmony_ci		WREG32(mmMME0_QM_CP_LDMA_TSIZE_OFFSET_0 + q_off,
21528c2ecf20Sopenharmony_ci							QMAN_CPDMA_SIZE_OFFSET);
21538c2ecf20Sopenharmony_ci		WREG32(mmMME0_QM_CP_LDMA_SRC_BASE_LO_OFFSET_0 + q_off,
21548c2ecf20Sopenharmony_ci							QMAN_CPDMA_SRC_OFFSET);
21558c2ecf20Sopenharmony_ci		WREG32(mmMME0_QM_CP_LDMA_DST_BASE_LO_OFFSET_0 + q_off,
21568c2ecf20Sopenharmony_ci							QMAN_CPDMA_DST_OFFSET);
21578c2ecf20Sopenharmony_ci	} else {
21588c2ecf20Sopenharmony_ci		WREG32(mmMME0_QM_CP_LDMA_TSIZE_OFFSET_0 + q_off,
21598c2ecf20Sopenharmony_ci							QMAN_LDMA_SIZE_OFFSET);
21608c2ecf20Sopenharmony_ci		WREG32(mmMME0_QM_CP_LDMA_SRC_BASE_LO_OFFSET_0 + q_off,
21618c2ecf20Sopenharmony_ci							QMAN_LDMA_SRC_OFFSET);
21628c2ecf20Sopenharmony_ci		WREG32(mmMME0_QM_CP_LDMA_DST_BASE_LO_OFFSET_0 + q_off,
21638c2ecf20Sopenharmony_ci							QMAN_LDMA_DST_OFFSET);
21648c2ecf20Sopenharmony_ci
21658c2ecf20Sopenharmony_ci		/* Configure RAZWI IRQ */
21668c2ecf20Sopenharmony_ci		mme_id = mme_offset /
21678c2ecf20Sopenharmony_ci				(mmMME1_QM_GLBL_CFG0 - mmMME0_QM_GLBL_CFG0) / 2;
21688c2ecf20Sopenharmony_ci
21698c2ecf20Sopenharmony_ci		mme_qm_err_cfg = MME_QMAN_GLBL_ERR_CFG_MSG_EN_MASK;
21708c2ecf20Sopenharmony_ci		if (hdev->stop_on_err) {
21718c2ecf20Sopenharmony_ci			mme_qm_err_cfg |=
21728c2ecf20Sopenharmony_ci				MME_QMAN_GLBL_ERR_CFG_STOP_ON_ERR_EN_MASK;
21738c2ecf20Sopenharmony_ci		}
21748c2ecf20Sopenharmony_ci		WREG32(mmMME0_QM_GLBL_ERR_CFG + mme_offset, mme_qm_err_cfg);
21758c2ecf20Sopenharmony_ci		WREG32(mmMME0_QM_GLBL_ERR_ADDR_LO + mme_offset,
21768c2ecf20Sopenharmony_ci			lower_32_bits(CFG_BASE +
21778c2ecf20Sopenharmony_ci					mmGIC_DISTRIBUTOR__5_GICD_SETSPI_NSR));
21788c2ecf20Sopenharmony_ci		WREG32(mmMME0_QM_GLBL_ERR_ADDR_HI + mme_offset,
21798c2ecf20Sopenharmony_ci			upper_32_bits(CFG_BASE +
21808c2ecf20Sopenharmony_ci					mmGIC_DISTRIBUTOR__5_GICD_SETSPI_NSR));
21818c2ecf20Sopenharmony_ci		WREG32(mmMME0_QM_GLBL_ERR_WDATA + mme_offset,
21828c2ecf20Sopenharmony_ci			gaudi_irq_map_table[GAUDI_EVENT_MME0_QM].cpu_id +
21838c2ecf20Sopenharmony_ci									mme_id);
21848c2ecf20Sopenharmony_ci
21858c2ecf20Sopenharmony_ci		WREG32(mmMME0_QM_ARB_ERR_MSG_EN + mme_offset,
21868c2ecf20Sopenharmony_ci				QM_ARB_ERR_MSG_EN_MASK);
21878c2ecf20Sopenharmony_ci
21888c2ecf20Sopenharmony_ci		/* Increase ARB WDT to support streams architecture */
21898c2ecf20Sopenharmony_ci		WREG32(mmMME0_QM_ARB_SLV_CHOISE_WDT + mme_offset,
21908c2ecf20Sopenharmony_ci				GAUDI_ARB_WDT_TIMEOUT);
21918c2ecf20Sopenharmony_ci
21928c2ecf20Sopenharmony_ci		WREG32(mmMME0_QM_GLBL_CFG1 + mme_offset, 0);
21938c2ecf20Sopenharmony_ci		WREG32(mmMME0_QM_GLBL_PROT + mme_offset,
21948c2ecf20Sopenharmony_ci				QMAN_INTERNAL_MAKE_TRUSTED);
21958c2ecf20Sopenharmony_ci	}
21968c2ecf20Sopenharmony_ci
21978c2ecf20Sopenharmony_ci	WREG32(mmMME0_QM_CP_MSG_BASE0_ADDR_LO_0 + q_off, mtr_base_lo);
21988c2ecf20Sopenharmony_ci	WREG32(mmMME0_QM_CP_MSG_BASE0_ADDR_HI_0 + q_off, mtr_base_hi);
21998c2ecf20Sopenharmony_ci	WREG32(mmMME0_QM_CP_MSG_BASE1_ADDR_LO_0 + q_off, so_base_lo);
22008c2ecf20Sopenharmony_ci	WREG32(mmMME0_QM_CP_MSG_BASE1_ADDR_HI_0 + q_off, so_base_hi);
22018c2ecf20Sopenharmony_ci}
22028c2ecf20Sopenharmony_ci
22038c2ecf20Sopenharmony_cistatic void gaudi_init_mme_qmans(struct hl_device *hdev)
22048c2ecf20Sopenharmony_ci{
22058c2ecf20Sopenharmony_ci	struct gaudi_device *gaudi = hdev->asic_specific;
22068c2ecf20Sopenharmony_ci	struct gaudi_internal_qman_info *q;
22078c2ecf20Sopenharmony_ci	u64 qman_base_addr;
22088c2ecf20Sopenharmony_ci	u32 mme_offset;
22098c2ecf20Sopenharmony_ci	int i, internal_q_index;
22108c2ecf20Sopenharmony_ci
22118c2ecf20Sopenharmony_ci	if (gaudi->hw_cap_initialized & HW_CAP_MME)
22128c2ecf20Sopenharmony_ci		return;
22138c2ecf20Sopenharmony_ci
22148c2ecf20Sopenharmony_ci	/*
22158c2ecf20Sopenharmony_ci	 * map GAUDI_QUEUE_ID_MME_0_X to the N_W_MME (mmMME2_QM_BASE)
22168c2ecf20Sopenharmony_ci	 * and GAUDI_QUEUE_ID_MME_1_X to the S_W_MME (mmMME0_QM_BASE)
22178c2ecf20Sopenharmony_ci	 */
22188c2ecf20Sopenharmony_ci
22198c2ecf20Sopenharmony_ci	mme_offset = mmMME2_QM_GLBL_CFG0 - mmMME0_QM_GLBL_CFG0;
22208c2ecf20Sopenharmony_ci
22218c2ecf20Sopenharmony_ci	for (i = 0 ; i < MME_NUMBER_OF_QMANS ; i++) {
22228c2ecf20Sopenharmony_ci		internal_q_index = GAUDI_QUEUE_ID_MME_0_0 + i;
22238c2ecf20Sopenharmony_ci		q = &gaudi->internal_qmans[internal_q_index];
22248c2ecf20Sopenharmony_ci		qman_base_addr = (u64) q->pq_dma_addr;
22258c2ecf20Sopenharmony_ci		gaudi_init_mme_qman(hdev, mme_offset, (i & 0x3),
22268c2ecf20Sopenharmony_ci					qman_base_addr);
22278c2ecf20Sopenharmony_ci		if (i == 3)
22288c2ecf20Sopenharmony_ci			mme_offset = 0;
22298c2ecf20Sopenharmony_ci	}
22308c2ecf20Sopenharmony_ci
22318c2ecf20Sopenharmony_ci	/* Initializing lower CP for MME QMANs */
22328c2ecf20Sopenharmony_ci	mme_offset = mmMME2_QM_GLBL_CFG0 - mmMME0_QM_GLBL_CFG0;
22338c2ecf20Sopenharmony_ci	gaudi_init_mme_qman(hdev, mme_offset, 4, 0);
22348c2ecf20Sopenharmony_ci	gaudi_init_mme_qman(hdev, 0, 4, 0);
22358c2ecf20Sopenharmony_ci
22368c2ecf20Sopenharmony_ci	WREG32(mmMME2_QM_GLBL_CFG0, QMAN_MME_ENABLE);
22378c2ecf20Sopenharmony_ci	WREG32(mmMME0_QM_GLBL_CFG0, QMAN_MME_ENABLE);
22388c2ecf20Sopenharmony_ci
22398c2ecf20Sopenharmony_ci	gaudi->hw_cap_initialized |= HW_CAP_MME;
22408c2ecf20Sopenharmony_ci}
22418c2ecf20Sopenharmony_ci
22428c2ecf20Sopenharmony_cistatic void gaudi_init_tpc_qman(struct hl_device *hdev, u32 tpc_offset,
22438c2ecf20Sopenharmony_ci				int qman_id, u64 qman_base_addr)
22448c2ecf20Sopenharmony_ci{
22458c2ecf20Sopenharmony_ci	u32 mtr_base_lo, mtr_base_hi;
22468c2ecf20Sopenharmony_ci	u32 so_base_lo, so_base_hi;
22478c2ecf20Sopenharmony_ci	u32 q_off, tpc_id;
22488c2ecf20Sopenharmony_ci	u32 tpc_qm_err_cfg;
22498c2ecf20Sopenharmony_ci
22508c2ecf20Sopenharmony_ci	mtr_base_lo = lower_32_bits(CFG_BASE +
22518c2ecf20Sopenharmony_ci				mmSYNC_MNGR_E_N_SYNC_MNGR_OBJS_MON_PAY_ADDRL_0);
22528c2ecf20Sopenharmony_ci	mtr_base_hi = upper_32_bits(CFG_BASE +
22538c2ecf20Sopenharmony_ci				mmSYNC_MNGR_E_N_SYNC_MNGR_OBJS_MON_PAY_ADDRL_0);
22548c2ecf20Sopenharmony_ci	so_base_lo = lower_32_bits(CFG_BASE +
22558c2ecf20Sopenharmony_ci				mmSYNC_MNGR_E_N_SYNC_MNGR_OBJS_SOB_OBJ_0);
22568c2ecf20Sopenharmony_ci	so_base_hi = upper_32_bits(CFG_BASE +
22578c2ecf20Sopenharmony_ci				mmSYNC_MNGR_E_N_SYNC_MNGR_OBJS_SOB_OBJ_0);
22588c2ecf20Sopenharmony_ci
22598c2ecf20Sopenharmony_ci	q_off = tpc_offset + qman_id * 4;
22608c2ecf20Sopenharmony_ci
22618c2ecf20Sopenharmony_ci	if (qman_id < 4) {
22628c2ecf20Sopenharmony_ci		WREG32(mmTPC0_QM_PQ_BASE_LO_0 + q_off,
22638c2ecf20Sopenharmony_ci					lower_32_bits(qman_base_addr));
22648c2ecf20Sopenharmony_ci		WREG32(mmTPC0_QM_PQ_BASE_HI_0 + q_off,
22658c2ecf20Sopenharmony_ci					upper_32_bits(qman_base_addr));
22668c2ecf20Sopenharmony_ci
22678c2ecf20Sopenharmony_ci		WREG32(mmTPC0_QM_PQ_SIZE_0 + q_off, ilog2(TPC_QMAN_LENGTH));
22688c2ecf20Sopenharmony_ci		WREG32(mmTPC0_QM_PQ_PI_0 + q_off, 0);
22698c2ecf20Sopenharmony_ci		WREG32(mmTPC0_QM_PQ_CI_0 + q_off, 0);
22708c2ecf20Sopenharmony_ci
22718c2ecf20Sopenharmony_ci		WREG32(mmTPC0_QM_CP_LDMA_TSIZE_OFFSET_0 + q_off,
22728c2ecf20Sopenharmony_ci							QMAN_CPDMA_SIZE_OFFSET);
22738c2ecf20Sopenharmony_ci		WREG32(mmTPC0_QM_CP_LDMA_SRC_BASE_LO_OFFSET_0 + q_off,
22748c2ecf20Sopenharmony_ci							QMAN_CPDMA_SRC_OFFSET);
22758c2ecf20Sopenharmony_ci		WREG32(mmTPC0_QM_CP_LDMA_DST_BASE_LO_OFFSET_0 + q_off,
22768c2ecf20Sopenharmony_ci							QMAN_CPDMA_DST_OFFSET);
22778c2ecf20Sopenharmony_ci	} else {
22788c2ecf20Sopenharmony_ci		WREG32(mmTPC0_QM_CP_LDMA_TSIZE_OFFSET_0 + q_off,
22798c2ecf20Sopenharmony_ci							QMAN_LDMA_SIZE_OFFSET);
22808c2ecf20Sopenharmony_ci		WREG32(mmTPC0_QM_CP_LDMA_SRC_BASE_LO_OFFSET_0 + q_off,
22818c2ecf20Sopenharmony_ci							QMAN_LDMA_SRC_OFFSET);
22828c2ecf20Sopenharmony_ci		WREG32(mmTPC0_QM_CP_LDMA_DST_BASE_LO_OFFSET_0 + q_off,
22838c2ecf20Sopenharmony_ci							QMAN_LDMA_DST_OFFSET);
22848c2ecf20Sopenharmony_ci
22858c2ecf20Sopenharmony_ci		/* Configure RAZWI IRQ */
22868c2ecf20Sopenharmony_ci		tpc_id = tpc_offset /
22878c2ecf20Sopenharmony_ci				(mmTPC1_QM_GLBL_CFG0 - mmTPC0_QM_GLBL_CFG0);
22888c2ecf20Sopenharmony_ci
22898c2ecf20Sopenharmony_ci		tpc_qm_err_cfg = TPC_QMAN_GLBL_ERR_CFG_MSG_EN_MASK;
22908c2ecf20Sopenharmony_ci		if (hdev->stop_on_err) {
22918c2ecf20Sopenharmony_ci			tpc_qm_err_cfg |=
22928c2ecf20Sopenharmony_ci				TPC_QMAN_GLBL_ERR_CFG_STOP_ON_ERR_EN_MASK;
22938c2ecf20Sopenharmony_ci		}
22948c2ecf20Sopenharmony_ci
22958c2ecf20Sopenharmony_ci		WREG32(mmTPC0_QM_GLBL_ERR_CFG + tpc_offset, tpc_qm_err_cfg);
22968c2ecf20Sopenharmony_ci		WREG32(mmTPC0_QM_GLBL_ERR_ADDR_LO + tpc_offset,
22978c2ecf20Sopenharmony_ci			lower_32_bits(CFG_BASE +
22988c2ecf20Sopenharmony_ci				mmGIC_DISTRIBUTOR__5_GICD_SETSPI_NSR));
22998c2ecf20Sopenharmony_ci		WREG32(mmTPC0_QM_GLBL_ERR_ADDR_HI + tpc_offset,
23008c2ecf20Sopenharmony_ci			upper_32_bits(CFG_BASE +
23018c2ecf20Sopenharmony_ci				mmGIC_DISTRIBUTOR__5_GICD_SETSPI_NSR));
23028c2ecf20Sopenharmony_ci		WREG32(mmTPC0_QM_GLBL_ERR_WDATA + tpc_offset,
23038c2ecf20Sopenharmony_ci			gaudi_irq_map_table[GAUDI_EVENT_TPC0_QM].cpu_id +
23048c2ecf20Sopenharmony_ci									tpc_id);
23058c2ecf20Sopenharmony_ci
23068c2ecf20Sopenharmony_ci		WREG32(mmTPC0_QM_ARB_ERR_MSG_EN + tpc_offset,
23078c2ecf20Sopenharmony_ci				QM_ARB_ERR_MSG_EN_MASK);
23088c2ecf20Sopenharmony_ci
23098c2ecf20Sopenharmony_ci		/* Increase ARB WDT to support streams architecture */
23108c2ecf20Sopenharmony_ci		WREG32(mmTPC0_QM_ARB_SLV_CHOISE_WDT + tpc_offset,
23118c2ecf20Sopenharmony_ci				GAUDI_ARB_WDT_TIMEOUT);
23128c2ecf20Sopenharmony_ci
23138c2ecf20Sopenharmony_ci		WREG32(mmTPC0_QM_GLBL_CFG1 + tpc_offset, 0);
23148c2ecf20Sopenharmony_ci		WREG32(mmTPC0_QM_GLBL_PROT + tpc_offset,
23158c2ecf20Sopenharmony_ci				QMAN_INTERNAL_MAKE_TRUSTED);
23168c2ecf20Sopenharmony_ci	}
23178c2ecf20Sopenharmony_ci
23188c2ecf20Sopenharmony_ci	WREG32(mmTPC0_QM_CP_MSG_BASE0_ADDR_LO_0 + q_off, mtr_base_lo);
23198c2ecf20Sopenharmony_ci	WREG32(mmTPC0_QM_CP_MSG_BASE0_ADDR_HI_0 + q_off, mtr_base_hi);
23208c2ecf20Sopenharmony_ci	WREG32(mmTPC0_QM_CP_MSG_BASE1_ADDR_LO_0 + q_off, so_base_lo);
23218c2ecf20Sopenharmony_ci	WREG32(mmTPC0_QM_CP_MSG_BASE1_ADDR_HI_0 + q_off, so_base_hi);
23228c2ecf20Sopenharmony_ci}
23238c2ecf20Sopenharmony_ci
23248c2ecf20Sopenharmony_cistatic void gaudi_init_tpc_qmans(struct hl_device *hdev)
23258c2ecf20Sopenharmony_ci{
23268c2ecf20Sopenharmony_ci	struct gaudi_device *gaudi = hdev->asic_specific;
23278c2ecf20Sopenharmony_ci	struct gaudi_internal_qman_info *q;
23288c2ecf20Sopenharmony_ci	u64 qman_base_addr;
23298c2ecf20Sopenharmony_ci	u32 so_base_hi, tpc_offset = 0;
23308c2ecf20Sopenharmony_ci	u32 tpc_delta = mmTPC1_CFG_SM_BASE_ADDRESS_HIGH -
23318c2ecf20Sopenharmony_ci			mmTPC0_CFG_SM_BASE_ADDRESS_HIGH;
23328c2ecf20Sopenharmony_ci	int i, tpc_id, internal_q_index;
23338c2ecf20Sopenharmony_ci
23348c2ecf20Sopenharmony_ci	if (gaudi->hw_cap_initialized & HW_CAP_TPC_MASK)
23358c2ecf20Sopenharmony_ci		return;
23368c2ecf20Sopenharmony_ci
23378c2ecf20Sopenharmony_ci	so_base_hi = upper_32_bits(CFG_BASE +
23388c2ecf20Sopenharmony_ci				mmSYNC_MNGR_E_N_SYNC_MNGR_OBJS_SOB_OBJ_0);
23398c2ecf20Sopenharmony_ci
23408c2ecf20Sopenharmony_ci	for (tpc_id = 0 ; tpc_id < TPC_NUMBER_OF_ENGINES ; tpc_id++) {
23418c2ecf20Sopenharmony_ci		for (i = 0 ; i < QMAN_STREAMS ; i++) {
23428c2ecf20Sopenharmony_ci			internal_q_index = GAUDI_QUEUE_ID_TPC_0_0 +
23438c2ecf20Sopenharmony_ci						tpc_id * QMAN_STREAMS + i;
23448c2ecf20Sopenharmony_ci			q = &gaudi->internal_qmans[internal_q_index];
23458c2ecf20Sopenharmony_ci			qman_base_addr = (u64) q->pq_dma_addr;
23468c2ecf20Sopenharmony_ci			gaudi_init_tpc_qman(hdev, tpc_offset, i,
23478c2ecf20Sopenharmony_ci						qman_base_addr);
23488c2ecf20Sopenharmony_ci
23498c2ecf20Sopenharmony_ci			if (i == 3) {
23508c2ecf20Sopenharmony_ci				/* Initializing lower CP for TPC QMAN */
23518c2ecf20Sopenharmony_ci				gaudi_init_tpc_qman(hdev, tpc_offset, 4, 0);
23528c2ecf20Sopenharmony_ci
23538c2ecf20Sopenharmony_ci				/* Enable the QMAN and TPC channel */
23548c2ecf20Sopenharmony_ci				WREG32(mmTPC0_QM_GLBL_CFG0 + tpc_offset,
23558c2ecf20Sopenharmony_ci						QMAN_TPC_ENABLE);
23568c2ecf20Sopenharmony_ci			}
23578c2ecf20Sopenharmony_ci		}
23588c2ecf20Sopenharmony_ci
23598c2ecf20Sopenharmony_ci		WREG32(mmTPC0_CFG_SM_BASE_ADDRESS_HIGH + tpc_id * tpc_delta,
23608c2ecf20Sopenharmony_ci				so_base_hi);
23618c2ecf20Sopenharmony_ci
23628c2ecf20Sopenharmony_ci		tpc_offset += mmTPC1_QM_GLBL_CFG0 - mmTPC0_QM_GLBL_CFG0;
23638c2ecf20Sopenharmony_ci
23648c2ecf20Sopenharmony_ci		gaudi->hw_cap_initialized |=
23658c2ecf20Sopenharmony_ci				FIELD_PREP(HW_CAP_TPC_MASK, 1 << tpc_id);
23668c2ecf20Sopenharmony_ci	}
23678c2ecf20Sopenharmony_ci}
23688c2ecf20Sopenharmony_ci
23698c2ecf20Sopenharmony_cistatic void gaudi_disable_pci_dma_qmans(struct hl_device *hdev)
23708c2ecf20Sopenharmony_ci{
23718c2ecf20Sopenharmony_ci	struct gaudi_device *gaudi = hdev->asic_specific;
23728c2ecf20Sopenharmony_ci
23738c2ecf20Sopenharmony_ci	if (!(gaudi->hw_cap_initialized & HW_CAP_PCI_DMA))
23748c2ecf20Sopenharmony_ci		return;
23758c2ecf20Sopenharmony_ci
23768c2ecf20Sopenharmony_ci	WREG32(mmDMA0_QM_GLBL_CFG0, 0);
23778c2ecf20Sopenharmony_ci	WREG32(mmDMA1_QM_GLBL_CFG0, 0);
23788c2ecf20Sopenharmony_ci	WREG32(mmDMA5_QM_GLBL_CFG0, 0);
23798c2ecf20Sopenharmony_ci}
23808c2ecf20Sopenharmony_ci
23818c2ecf20Sopenharmony_cistatic void gaudi_disable_hbm_dma_qmans(struct hl_device *hdev)
23828c2ecf20Sopenharmony_ci{
23838c2ecf20Sopenharmony_ci	struct gaudi_device *gaudi = hdev->asic_specific;
23848c2ecf20Sopenharmony_ci
23858c2ecf20Sopenharmony_ci	if (!(gaudi->hw_cap_initialized & HW_CAP_HBM_DMA))
23868c2ecf20Sopenharmony_ci		return;
23878c2ecf20Sopenharmony_ci
23888c2ecf20Sopenharmony_ci	WREG32(mmDMA2_QM_GLBL_CFG0, 0);
23898c2ecf20Sopenharmony_ci	WREG32(mmDMA3_QM_GLBL_CFG0, 0);
23908c2ecf20Sopenharmony_ci	WREG32(mmDMA4_QM_GLBL_CFG0, 0);
23918c2ecf20Sopenharmony_ci	WREG32(mmDMA6_QM_GLBL_CFG0, 0);
23928c2ecf20Sopenharmony_ci	WREG32(mmDMA7_QM_GLBL_CFG0, 0);
23938c2ecf20Sopenharmony_ci}
23948c2ecf20Sopenharmony_ci
23958c2ecf20Sopenharmony_cistatic void gaudi_disable_mme_qmans(struct hl_device *hdev)
23968c2ecf20Sopenharmony_ci{
23978c2ecf20Sopenharmony_ci	struct gaudi_device *gaudi = hdev->asic_specific;
23988c2ecf20Sopenharmony_ci
23998c2ecf20Sopenharmony_ci	if (!(gaudi->hw_cap_initialized & HW_CAP_MME))
24008c2ecf20Sopenharmony_ci		return;
24018c2ecf20Sopenharmony_ci
24028c2ecf20Sopenharmony_ci	WREG32(mmMME2_QM_GLBL_CFG0, 0);
24038c2ecf20Sopenharmony_ci	WREG32(mmMME0_QM_GLBL_CFG0, 0);
24048c2ecf20Sopenharmony_ci}
24058c2ecf20Sopenharmony_ci
24068c2ecf20Sopenharmony_cistatic void gaudi_disable_tpc_qmans(struct hl_device *hdev)
24078c2ecf20Sopenharmony_ci{
24088c2ecf20Sopenharmony_ci	struct gaudi_device *gaudi = hdev->asic_specific;
24098c2ecf20Sopenharmony_ci	u32 tpc_offset = 0;
24108c2ecf20Sopenharmony_ci	int tpc_id;
24118c2ecf20Sopenharmony_ci
24128c2ecf20Sopenharmony_ci	if (!(gaudi->hw_cap_initialized & HW_CAP_TPC_MASK))
24138c2ecf20Sopenharmony_ci		return;
24148c2ecf20Sopenharmony_ci
24158c2ecf20Sopenharmony_ci	for (tpc_id = 0 ; tpc_id < TPC_NUMBER_OF_ENGINES ; tpc_id++) {
24168c2ecf20Sopenharmony_ci		WREG32(mmTPC0_QM_GLBL_CFG0 + tpc_offset, 0);
24178c2ecf20Sopenharmony_ci		tpc_offset += mmTPC1_QM_GLBL_CFG0 - mmTPC0_QM_GLBL_CFG0;
24188c2ecf20Sopenharmony_ci	}
24198c2ecf20Sopenharmony_ci}
24208c2ecf20Sopenharmony_ci
24218c2ecf20Sopenharmony_cistatic void gaudi_stop_pci_dma_qmans(struct hl_device *hdev)
24228c2ecf20Sopenharmony_ci{
24238c2ecf20Sopenharmony_ci	struct gaudi_device *gaudi = hdev->asic_specific;
24248c2ecf20Sopenharmony_ci
24258c2ecf20Sopenharmony_ci	if (!(gaudi->hw_cap_initialized & HW_CAP_PCI_DMA))
24268c2ecf20Sopenharmony_ci		return;
24278c2ecf20Sopenharmony_ci
24288c2ecf20Sopenharmony_ci	/* Stop upper CPs of QMANs 0.0 to 1.3 and 5.0 to 5.3 */
24298c2ecf20Sopenharmony_ci	WREG32(mmDMA0_QM_GLBL_CFG1, 0xF << DMA0_QM_GLBL_CFG1_CP_STOP_SHIFT);
24308c2ecf20Sopenharmony_ci	WREG32(mmDMA1_QM_GLBL_CFG1, 0xF << DMA0_QM_GLBL_CFG1_CP_STOP_SHIFT);
24318c2ecf20Sopenharmony_ci	WREG32(mmDMA5_QM_GLBL_CFG1, 0xF << DMA0_QM_GLBL_CFG1_CP_STOP_SHIFT);
24328c2ecf20Sopenharmony_ci}
24338c2ecf20Sopenharmony_ci
24348c2ecf20Sopenharmony_cistatic void gaudi_stop_hbm_dma_qmans(struct hl_device *hdev)
24358c2ecf20Sopenharmony_ci{
24368c2ecf20Sopenharmony_ci	struct gaudi_device *gaudi = hdev->asic_specific;
24378c2ecf20Sopenharmony_ci
24388c2ecf20Sopenharmony_ci	if (!(gaudi->hw_cap_initialized & HW_CAP_HBM_DMA))
24398c2ecf20Sopenharmony_ci		return;
24408c2ecf20Sopenharmony_ci
24418c2ecf20Sopenharmony_ci	/* Stop CPs of HBM DMA QMANs */
24428c2ecf20Sopenharmony_ci
24438c2ecf20Sopenharmony_ci	WREG32(mmDMA2_QM_GLBL_CFG1, 0x1F << DMA0_QM_GLBL_CFG1_CP_STOP_SHIFT);
24448c2ecf20Sopenharmony_ci	WREG32(mmDMA3_QM_GLBL_CFG1, 0x1F << DMA0_QM_GLBL_CFG1_CP_STOP_SHIFT);
24458c2ecf20Sopenharmony_ci	WREG32(mmDMA4_QM_GLBL_CFG1, 0x1F << DMA0_QM_GLBL_CFG1_CP_STOP_SHIFT);
24468c2ecf20Sopenharmony_ci	WREG32(mmDMA6_QM_GLBL_CFG1, 0x1F << DMA0_QM_GLBL_CFG1_CP_STOP_SHIFT);
24478c2ecf20Sopenharmony_ci	WREG32(mmDMA7_QM_GLBL_CFG1, 0x1F << DMA0_QM_GLBL_CFG1_CP_STOP_SHIFT);
24488c2ecf20Sopenharmony_ci}
24498c2ecf20Sopenharmony_ci
24508c2ecf20Sopenharmony_cistatic void gaudi_stop_mme_qmans(struct hl_device *hdev)
24518c2ecf20Sopenharmony_ci{
24528c2ecf20Sopenharmony_ci	struct gaudi_device *gaudi = hdev->asic_specific;
24538c2ecf20Sopenharmony_ci
24548c2ecf20Sopenharmony_ci	if (!(gaudi->hw_cap_initialized & HW_CAP_MME))
24558c2ecf20Sopenharmony_ci		return;
24568c2ecf20Sopenharmony_ci
24578c2ecf20Sopenharmony_ci	/* Stop CPs of MME QMANs */
24588c2ecf20Sopenharmony_ci	WREG32(mmMME2_QM_GLBL_CFG1, 0x1F << MME0_QM_GLBL_CFG1_CP_STOP_SHIFT);
24598c2ecf20Sopenharmony_ci	WREG32(mmMME0_QM_GLBL_CFG1, 0x1F << MME0_QM_GLBL_CFG1_CP_STOP_SHIFT);
24608c2ecf20Sopenharmony_ci}
24618c2ecf20Sopenharmony_ci
24628c2ecf20Sopenharmony_cistatic void gaudi_stop_tpc_qmans(struct hl_device *hdev)
24638c2ecf20Sopenharmony_ci{
24648c2ecf20Sopenharmony_ci	struct gaudi_device *gaudi = hdev->asic_specific;
24658c2ecf20Sopenharmony_ci
24668c2ecf20Sopenharmony_ci	if (!(gaudi->hw_cap_initialized & HW_CAP_TPC_MASK))
24678c2ecf20Sopenharmony_ci		return;
24688c2ecf20Sopenharmony_ci
24698c2ecf20Sopenharmony_ci	WREG32(mmTPC0_QM_GLBL_CFG1, 0x1F << TPC0_QM_GLBL_CFG1_CP_STOP_SHIFT);
24708c2ecf20Sopenharmony_ci	WREG32(mmTPC1_QM_GLBL_CFG1, 0x1F << TPC0_QM_GLBL_CFG1_CP_STOP_SHIFT);
24718c2ecf20Sopenharmony_ci	WREG32(mmTPC2_QM_GLBL_CFG1, 0x1F << TPC0_QM_GLBL_CFG1_CP_STOP_SHIFT);
24728c2ecf20Sopenharmony_ci	WREG32(mmTPC3_QM_GLBL_CFG1, 0x1F << TPC0_QM_GLBL_CFG1_CP_STOP_SHIFT);
24738c2ecf20Sopenharmony_ci	WREG32(mmTPC4_QM_GLBL_CFG1, 0x1F << TPC0_QM_GLBL_CFG1_CP_STOP_SHIFT);
24748c2ecf20Sopenharmony_ci	WREG32(mmTPC5_QM_GLBL_CFG1, 0x1F << TPC0_QM_GLBL_CFG1_CP_STOP_SHIFT);
24758c2ecf20Sopenharmony_ci	WREG32(mmTPC6_QM_GLBL_CFG1, 0x1F << TPC0_QM_GLBL_CFG1_CP_STOP_SHIFT);
24768c2ecf20Sopenharmony_ci	WREG32(mmTPC7_QM_GLBL_CFG1, 0x1F << TPC0_QM_GLBL_CFG1_CP_STOP_SHIFT);
24778c2ecf20Sopenharmony_ci}
24788c2ecf20Sopenharmony_ci
24798c2ecf20Sopenharmony_cistatic void gaudi_pci_dma_stall(struct hl_device *hdev)
24808c2ecf20Sopenharmony_ci{
24818c2ecf20Sopenharmony_ci	struct gaudi_device *gaudi = hdev->asic_specific;
24828c2ecf20Sopenharmony_ci
24838c2ecf20Sopenharmony_ci	if (!(gaudi->hw_cap_initialized & HW_CAP_PCI_DMA))
24848c2ecf20Sopenharmony_ci		return;
24858c2ecf20Sopenharmony_ci
24868c2ecf20Sopenharmony_ci	WREG32(mmDMA0_CORE_CFG_1, 1 << DMA0_CORE_CFG_1_HALT_SHIFT);
24878c2ecf20Sopenharmony_ci	WREG32(mmDMA1_CORE_CFG_1, 1 << DMA0_CORE_CFG_1_HALT_SHIFT);
24888c2ecf20Sopenharmony_ci	WREG32(mmDMA5_CORE_CFG_1, 1 << DMA0_CORE_CFG_1_HALT_SHIFT);
24898c2ecf20Sopenharmony_ci}
24908c2ecf20Sopenharmony_ci
24918c2ecf20Sopenharmony_cistatic void gaudi_hbm_dma_stall(struct hl_device *hdev)
24928c2ecf20Sopenharmony_ci{
24938c2ecf20Sopenharmony_ci	struct gaudi_device *gaudi = hdev->asic_specific;
24948c2ecf20Sopenharmony_ci
24958c2ecf20Sopenharmony_ci	if (!(gaudi->hw_cap_initialized & HW_CAP_HBM_DMA))
24968c2ecf20Sopenharmony_ci		return;
24978c2ecf20Sopenharmony_ci
24988c2ecf20Sopenharmony_ci	WREG32(mmDMA2_CORE_CFG_1, 1 << DMA0_CORE_CFG_1_HALT_SHIFT);
24998c2ecf20Sopenharmony_ci	WREG32(mmDMA3_CORE_CFG_1, 1 << DMA0_CORE_CFG_1_HALT_SHIFT);
25008c2ecf20Sopenharmony_ci	WREG32(mmDMA4_CORE_CFG_1, 1 << DMA0_CORE_CFG_1_HALT_SHIFT);
25018c2ecf20Sopenharmony_ci	WREG32(mmDMA6_CORE_CFG_1, 1 << DMA0_CORE_CFG_1_HALT_SHIFT);
25028c2ecf20Sopenharmony_ci	WREG32(mmDMA7_CORE_CFG_1, 1 << DMA0_CORE_CFG_1_HALT_SHIFT);
25038c2ecf20Sopenharmony_ci}
25048c2ecf20Sopenharmony_ci
25058c2ecf20Sopenharmony_cistatic void gaudi_mme_stall(struct hl_device *hdev)
25068c2ecf20Sopenharmony_ci{
25078c2ecf20Sopenharmony_ci	struct gaudi_device *gaudi = hdev->asic_specific;
25088c2ecf20Sopenharmony_ci
25098c2ecf20Sopenharmony_ci	if (!(gaudi->hw_cap_initialized & HW_CAP_MME))
25108c2ecf20Sopenharmony_ci		return;
25118c2ecf20Sopenharmony_ci
25128c2ecf20Sopenharmony_ci	/* WA for H3-1800 bug: do ACC and SBAB writes twice */
25138c2ecf20Sopenharmony_ci	WREG32(mmMME0_ACC_ACC_STALL, 1 << MME_ACC_ACC_STALL_R_SHIFT);
25148c2ecf20Sopenharmony_ci	WREG32(mmMME0_ACC_ACC_STALL, 1 << MME_ACC_ACC_STALL_R_SHIFT);
25158c2ecf20Sopenharmony_ci	WREG32(mmMME0_SBAB_SB_STALL, 1 << MME_SBAB_SB_STALL_R_SHIFT);
25168c2ecf20Sopenharmony_ci	WREG32(mmMME0_SBAB_SB_STALL, 1 << MME_SBAB_SB_STALL_R_SHIFT);
25178c2ecf20Sopenharmony_ci	WREG32(mmMME1_ACC_ACC_STALL, 1 << MME_ACC_ACC_STALL_R_SHIFT);
25188c2ecf20Sopenharmony_ci	WREG32(mmMME1_ACC_ACC_STALL, 1 << MME_ACC_ACC_STALL_R_SHIFT);
25198c2ecf20Sopenharmony_ci	WREG32(mmMME1_SBAB_SB_STALL, 1 << MME_SBAB_SB_STALL_R_SHIFT);
25208c2ecf20Sopenharmony_ci	WREG32(mmMME1_SBAB_SB_STALL, 1 << MME_SBAB_SB_STALL_R_SHIFT);
25218c2ecf20Sopenharmony_ci	WREG32(mmMME2_ACC_ACC_STALL, 1 << MME_ACC_ACC_STALL_R_SHIFT);
25228c2ecf20Sopenharmony_ci	WREG32(mmMME2_ACC_ACC_STALL, 1 << MME_ACC_ACC_STALL_R_SHIFT);
25238c2ecf20Sopenharmony_ci	WREG32(mmMME2_SBAB_SB_STALL, 1 << MME_SBAB_SB_STALL_R_SHIFT);
25248c2ecf20Sopenharmony_ci	WREG32(mmMME2_SBAB_SB_STALL, 1 << MME_SBAB_SB_STALL_R_SHIFT);
25258c2ecf20Sopenharmony_ci	WREG32(mmMME3_ACC_ACC_STALL, 1 << MME_ACC_ACC_STALL_R_SHIFT);
25268c2ecf20Sopenharmony_ci	WREG32(mmMME3_ACC_ACC_STALL, 1 << MME_ACC_ACC_STALL_R_SHIFT);
25278c2ecf20Sopenharmony_ci	WREG32(mmMME3_SBAB_SB_STALL, 1 << MME_SBAB_SB_STALL_R_SHIFT);
25288c2ecf20Sopenharmony_ci	WREG32(mmMME3_SBAB_SB_STALL, 1 << MME_SBAB_SB_STALL_R_SHIFT);
25298c2ecf20Sopenharmony_ci}
25308c2ecf20Sopenharmony_ci
25318c2ecf20Sopenharmony_cistatic void gaudi_tpc_stall(struct hl_device *hdev)
25328c2ecf20Sopenharmony_ci{
25338c2ecf20Sopenharmony_ci	struct gaudi_device *gaudi = hdev->asic_specific;
25348c2ecf20Sopenharmony_ci
25358c2ecf20Sopenharmony_ci	if (!(gaudi->hw_cap_initialized & HW_CAP_TPC_MASK))
25368c2ecf20Sopenharmony_ci		return;
25378c2ecf20Sopenharmony_ci
25388c2ecf20Sopenharmony_ci	WREG32(mmTPC0_CFG_TPC_STALL, 1 << TPC0_CFG_TPC_STALL_V_SHIFT);
25398c2ecf20Sopenharmony_ci	WREG32(mmTPC1_CFG_TPC_STALL, 1 << TPC0_CFG_TPC_STALL_V_SHIFT);
25408c2ecf20Sopenharmony_ci	WREG32(mmTPC2_CFG_TPC_STALL, 1 << TPC0_CFG_TPC_STALL_V_SHIFT);
25418c2ecf20Sopenharmony_ci	WREG32(mmTPC3_CFG_TPC_STALL, 1 << TPC0_CFG_TPC_STALL_V_SHIFT);
25428c2ecf20Sopenharmony_ci	WREG32(mmTPC4_CFG_TPC_STALL, 1 << TPC0_CFG_TPC_STALL_V_SHIFT);
25438c2ecf20Sopenharmony_ci	WREG32(mmTPC5_CFG_TPC_STALL, 1 << TPC0_CFG_TPC_STALL_V_SHIFT);
25448c2ecf20Sopenharmony_ci	WREG32(mmTPC6_CFG_TPC_STALL, 1 << TPC0_CFG_TPC_STALL_V_SHIFT);
25458c2ecf20Sopenharmony_ci	WREG32(mmTPC7_CFG_TPC_STALL, 1 << TPC0_CFG_TPC_STALL_V_SHIFT);
25468c2ecf20Sopenharmony_ci}
25478c2ecf20Sopenharmony_ci
25488c2ecf20Sopenharmony_cistatic void gaudi_set_clock_gating(struct hl_device *hdev)
25498c2ecf20Sopenharmony_ci{
25508c2ecf20Sopenharmony_ci	struct gaudi_device *gaudi = hdev->asic_specific;
25518c2ecf20Sopenharmony_ci	u32 qman_offset;
25528c2ecf20Sopenharmony_ci	bool enable;
25538c2ecf20Sopenharmony_ci	int i;
25548c2ecf20Sopenharmony_ci
25558c2ecf20Sopenharmony_ci	/* In case we are during debug session, don't enable the clock gate
25568c2ecf20Sopenharmony_ci	 * as it may interfere
25578c2ecf20Sopenharmony_ci	 */
25588c2ecf20Sopenharmony_ci	if (hdev->in_debug)
25598c2ecf20Sopenharmony_ci		return;
25608c2ecf20Sopenharmony_ci
25618c2ecf20Sopenharmony_ci	for (i = GAUDI_PCI_DMA_1, qman_offset = 0 ; i < GAUDI_HBM_DMA_1 ; i++) {
25628c2ecf20Sopenharmony_ci		enable = !!(hdev->clock_gating_mask &
25638c2ecf20Sopenharmony_ci				(BIT_ULL(gaudi_dma_assignment[i])));
25648c2ecf20Sopenharmony_ci
25658c2ecf20Sopenharmony_ci		qman_offset = gaudi_dma_assignment[i] * DMA_QMAN_OFFSET;
25668c2ecf20Sopenharmony_ci		WREG32(mmDMA0_QM_CGM_CFG1 + qman_offset,
25678c2ecf20Sopenharmony_ci				enable ? QMAN_CGM1_PWR_GATE_EN : 0);
25688c2ecf20Sopenharmony_ci		WREG32(mmDMA0_QM_CGM_CFG + qman_offset,
25698c2ecf20Sopenharmony_ci				enable ? QMAN_UPPER_CP_CGM_PWR_GATE_EN : 0);
25708c2ecf20Sopenharmony_ci	}
25718c2ecf20Sopenharmony_ci
25728c2ecf20Sopenharmony_ci	for (i = GAUDI_HBM_DMA_1 ; i < GAUDI_DMA_MAX ; i++) {
25738c2ecf20Sopenharmony_ci		enable = !!(hdev->clock_gating_mask &
25748c2ecf20Sopenharmony_ci				(BIT_ULL(gaudi_dma_assignment[i])));
25758c2ecf20Sopenharmony_ci
25768c2ecf20Sopenharmony_ci		qman_offset = gaudi_dma_assignment[i] * DMA_QMAN_OFFSET;
25778c2ecf20Sopenharmony_ci		WREG32(mmDMA0_QM_CGM_CFG1 + qman_offset,
25788c2ecf20Sopenharmony_ci				enable ? QMAN_CGM1_PWR_GATE_EN : 0);
25798c2ecf20Sopenharmony_ci		WREG32(mmDMA0_QM_CGM_CFG + qman_offset,
25808c2ecf20Sopenharmony_ci				enable ? QMAN_COMMON_CP_CGM_PWR_GATE_EN : 0);
25818c2ecf20Sopenharmony_ci	}
25828c2ecf20Sopenharmony_ci
25838c2ecf20Sopenharmony_ci	enable = !!(hdev->clock_gating_mask & (BIT_ULL(GAUDI_ENGINE_ID_MME_0)));
25848c2ecf20Sopenharmony_ci	WREG32(mmMME0_QM_CGM_CFG1, enable ? QMAN_CGM1_PWR_GATE_EN : 0);
25858c2ecf20Sopenharmony_ci	WREG32(mmMME0_QM_CGM_CFG, enable ? QMAN_COMMON_CP_CGM_PWR_GATE_EN : 0);
25868c2ecf20Sopenharmony_ci
25878c2ecf20Sopenharmony_ci	enable = !!(hdev->clock_gating_mask & (BIT_ULL(GAUDI_ENGINE_ID_MME_2)));
25888c2ecf20Sopenharmony_ci	WREG32(mmMME2_QM_CGM_CFG1, enable ? QMAN_CGM1_PWR_GATE_EN : 0);
25898c2ecf20Sopenharmony_ci	WREG32(mmMME2_QM_CGM_CFG, enable ? QMAN_COMMON_CP_CGM_PWR_GATE_EN : 0);
25908c2ecf20Sopenharmony_ci
25918c2ecf20Sopenharmony_ci	for (i = 0, qman_offset = 0 ; i < TPC_NUMBER_OF_ENGINES ; i++) {
25928c2ecf20Sopenharmony_ci		enable = !!(hdev->clock_gating_mask &
25938c2ecf20Sopenharmony_ci				(BIT_ULL(GAUDI_ENGINE_ID_TPC_0 + i)));
25948c2ecf20Sopenharmony_ci
25958c2ecf20Sopenharmony_ci		WREG32(mmTPC0_QM_CGM_CFG1 + qman_offset,
25968c2ecf20Sopenharmony_ci				enable ? QMAN_CGM1_PWR_GATE_EN : 0);
25978c2ecf20Sopenharmony_ci		WREG32(mmTPC0_QM_CGM_CFG + qman_offset,
25988c2ecf20Sopenharmony_ci				enable ? QMAN_COMMON_CP_CGM_PWR_GATE_EN : 0);
25998c2ecf20Sopenharmony_ci
26008c2ecf20Sopenharmony_ci		qman_offset += TPC_QMAN_OFFSET;
26018c2ecf20Sopenharmony_ci	}
26028c2ecf20Sopenharmony_ci
26038c2ecf20Sopenharmony_ci	gaudi->hw_cap_initialized |= HW_CAP_CLK_GATE;
26048c2ecf20Sopenharmony_ci}
26058c2ecf20Sopenharmony_ci
26068c2ecf20Sopenharmony_cistatic void gaudi_disable_clock_gating(struct hl_device *hdev)
26078c2ecf20Sopenharmony_ci{
26088c2ecf20Sopenharmony_ci	struct gaudi_device *gaudi = hdev->asic_specific;
26098c2ecf20Sopenharmony_ci	u32 qman_offset;
26108c2ecf20Sopenharmony_ci	int i;
26118c2ecf20Sopenharmony_ci
26128c2ecf20Sopenharmony_ci	if (!(gaudi->hw_cap_initialized & HW_CAP_CLK_GATE))
26138c2ecf20Sopenharmony_ci		return;
26148c2ecf20Sopenharmony_ci
26158c2ecf20Sopenharmony_ci	for (i = 0, qman_offset = 0 ; i < DMA_NUMBER_OF_CHANNELS ; i++) {
26168c2ecf20Sopenharmony_ci		WREG32(mmDMA0_QM_CGM_CFG + qman_offset, 0);
26178c2ecf20Sopenharmony_ci		WREG32(mmDMA0_QM_CGM_CFG1 + qman_offset, 0);
26188c2ecf20Sopenharmony_ci
26198c2ecf20Sopenharmony_ci		qman_offset += (mmDMA1_QM_CGM_CFG - mmDMA0_QM_CGM_CFG);
26208c2ecf20Sopenharmony_ci	}
26218c2ecf20Sopenharmony_ci
26228c2ecf20Sopenharmony_ci	WREG32(mmMME0_QM_CGM_CFG, 0);
26238c2ecf20Sopenharmony_ci	WREG32(mmMME0_QM_CGM_CFG1, 0);
26248c2ecf20Sopenharmony_ci	WREG32(mmMME2_QM_CGM_CFG, 0);
26258c2ecf20Sopenharmony_ci	WREG32(mmMME2_QM_CGM_CFG1, 0);
26268c2ecf20Sopenharmony_ci
26278c2ecf20Sopenharmony_ci	for (i = 0, qman_offset = 0 ; i < TPC_NUMBER_OF_ENGINES ; i++) {
26288c2ecf20Sopenharmony_ci		WREG32(mmTPC0_QM_CGM_CFG + qman_offset, 0);
26298c2ecf20Sopenharmony_ci		WREG32(mmTPC0_QM_CGM_CFG1 + qman_offset, 0);
26308c2ecf20Sopenharmony_ci
26318c2ecf20Sopenharmony_ci		qman_offset += (mmTPC1_QM_CGM_CFG - mmTPC0_QM_CGM_CFG);
26328c2ecf20Sopenharmony_ci	}
26338c2ecf20Sopenharmony_ci
26348c2ecf20Sopenharmony_ci	gaudi->hw_cap_initialized &= ~(HW_CAP_CLK_GATE);
26358c2ecf20Sopenharmony_ci}
26368c2ecf20Sopenharmony_ci
26378c2ecf20Sopenharmony_cistatic void gaudi_enable_timestamp(struct hl_device *hdev)
26388c2ecf20Sopenharmony_ci{
26398c2ecf20Sopenharmony_ci	/* Disable the timestamp counter */
26408c2ecf20Sopenharmony_ci	WREG32(mmPSOC_TIMESTAMP_BASE - CFG_BASE, 0);
26418c2ecf20Sopenharmony_ci
26428c2ecf20Sopenharmony_ci	/* Zero the lower/upper parts of the 64-bit counter */
26438c2ecf20Sopenharmony_ci	WREG32(mmPSOC_TIMESTAMP_BASE - CFG_BASE + 0xC, 0);
26448c2ecf20Sopenharmony_ci	WREG32(mmPSOC_TIMESTAMP_BASE - CFG_BASE + 0x8, 0);
26458c2ecf20Sopenharmony_ci
26468c2ecf20Sopenharmony_ci	/* Enable the counter */
26478c2ecf20Sopenharmony_ci	WREG32(mmPSOC_TIMESTAMP_BASE - CFG_BASE, 1);
26488c2ecf20Sopenharmony_ci}
26498c2ecf20Sopenharmony_ci
26508c2ecf20Sopenharmony_cistatic void gaudi_disable_timestamp(struct hl_device *hdev)
26518c2ecf20Sopenharmony_ci{
26528c2ecf20Sopenharmony_ci	/* Disable the timestamp counter */
26538c2ecf20Sopenharmony_ci	WREG32(mmPSOC_TIMESTAMP_BASE - CFG_BASE, 0);
26548c2ecf20Sopenharmony_ci}
26558c2ecf20Sopenharmony_ci
26568c2ecf20Sopenharmony_cistatic void gaudi_halt_engines(struct hl_device *hdev, bool hard_reset)
26578c2ecf20Sopenharmony_ci{
26588c2ecf20Sopenharmony_ci	u32 wait_timeout_ms;
26598c2ecf20Sopenharmony_ci
26608c2ecf20Sopenharmony_ci	dev_info(hdev->dev,
26618c2ecf20Sopenharmony_ci		"Halting compute engines and disabling interrupts\n");
26628c2ecf20Sopenharmony_ci
26638c2ecf20Sopenharmony_ci	if (hdev->pldm)
26648c2ecf20Sopenharmony_ci		wait_timeout_ms = GAUDI_PLDM_RESET_WAIT_MSEC;
26658c2ecf20Sopenharmony_ci	else
26668c2ecf20Sopenharmony_ci		wait_timeout_ms = GAUDI_RESET_WAIT_MSEC;
26678c2ecf20Sopenharmony_ci
26688c2ecf20Sopenharmony_ci
26698c2ecf20Sopenharmony_ci	gaudi_stop_mme_qmans(hdev);
26708c2ecf20Sopenharmony_ci	gaudi_stop_tpc_qmans(hdev);
26718c2ecf20Sopenharmony_ci	gaudi_stop_hbm_dma_qmans(hdev);
26728c2ecf20Sopenharmony_ci	gaudi_stop_pci_dma_qmans(hdev);
26738c2ecf20Sopenharmony_ci
26748c2ecf20Sopenharmony_ci	hdev->asic_funcs->disable_clock_gating(hdev);
26758c2ecf20Sopenharmony_ci
26768c2ecf20Sopenharmony_ci	msleep(wait_timeout_ms);
26778c2ecf20Sopenharmony_ci
26788c2ecf20Sopenharmony_ci	gaudi_pci_dma_stall(hdev);
26798c2ecf20Sopenharmony_ci	gaudi_hbm_dma_stall(hdev);
26808c2ecf20Sopenharmony_ci	gaudi_tpc_stall(hdev);
26818c2ecf20Sopenharmony_ci	gaudi_mme_stall(hdev);
26828c2ecf20Sopenharmony_ci
26838c2ecf20Sopenharmony_ci	msleep(wait_timeout_ms);
26848c2ecf20Sopenharmony_ci
26858c2ecf20Sopenharmony_ci	gaudi_disable_mme_qmans(hdev);
26868c2ecf20Sopenharmony_ci	gaudi_disable_tpc_qmans(hdev);
26878c2ecf20Sopenharmony_ci	gaudi_disable_hbm_dma_qmans(hdev);
26888c2ecf20Sopenharmony_ci	gaudi_disable_pci_dma_qmans(hdev);
26898c2ecf20Sopenharmony_ci
26908c2ecf20Sopenharmony_ci	gaudi_disable_timestamp(hdev);
26918c2ecf20Sopenharmony_ci
26928c2ecf20Sopenharmony_ci	gaudi_disable_msi(hdev);
26938c2ecf20Sopenharmony_ci}
26948c2ecf20Sopenharmony_ci
26958c2ecf20Sopenharmony_cistatic int gaudi_mmu_init(struct hl_device *hdev)
26968c2ecf20Sopenharmony_ci{
26978c2ecf20Sopenharmony_ci	struct asic_fixed_properties *prop = &hdev->asic_prop;
26988c2ecf20Sopenharmony_ci	struct gaudi_device *gaudi = hdev->asic_specific;
26998c2ecf20Sopenharmony_ci	u64 hop0_addr;
27008c2ecf20Sopenharmony_ci	int rc, i;
27018c2ecf20Sopenharmony_ci
27028c2ecf20Sopenharmony_ci	if (!hdev->mmu_enable)
27038c2ecf20Sopenharmony_ci		return 0;
27048c2ecf20Sopenharmony_ci
27058c2ecf20Sopenharmony_ci	if (gaudi->hw_cap_initialized & HW_CAP_MMU)
27068c2ecf20Sopenharmony_ci		return 0;
27078c2ecf20Sopenharmony_ci
27088c2ecf20Sopenharmony_ci	hdev->dram_supports_virtual_memory = false;
27098c2ecf20Sopenharmony_ci
27108c2ecf20Sopenharmony_ci	for (i = 0 ; i < prop->max_asid ; i++) {
27118c2ecf20Sopenharmony_ci		hop0_addr = prop->mmu_pgt_addr +
27128c2ecf20Sopenharmony_ci				(i * prop->mmu_hop_table_size);
27138c2ecf20Sopenharmony_ci
27148c2ecf20Sopenharmony_ci		rc = gaudi_mmu_update_asid_hop0_addr(hdev, i, hop0_addr);
27158c2ecf20Sopenharmony_ci		if (rc) {
27168c2ecf20Sopenharmony_ci			dev_err(hdev->dev,
27178c2ecf20Sopenharmony_ci				"failed to set hop0 addr for asid %d\n", i);
27188c2ecf20Sopenharmony_ci			goto err;
27198c2ecf20Sopenharmony_ci		}
27208c2ecf20Sopenharmony_ci	}
27218c2ecf20Sopenharmony_ci
27228c2ecf20Sopenharmony_ci	/* init MMU cache manage page */
27238c2ecf20Sopenharmony_ci	WREG32(mmSTLB_CACHE_INV_BASE_39_8, MMU_CACHE_MNG_ADDR >> 8);
27248c2ecf20Sopenharmony_ci	WREG32(mmSTLB_CACHE_INV_BASE_49_40, MMU_CACHE_MNG_ADDR >> 40);
27258c2ecf20Sopenharmony_ci
27268c2ecf20Sopenharmony_ci	hdev->asic_funcs->mmu_invalidate_cache(hdev, true, 0);
27278c2ecf20Sopenharmony_ci
27288c2ecf20Sopenharmony_ci	WREG32(mmMMU_UP_MMU_ENABLE, 1);
27298c2ecf20Sopenharmony_ci	WREG32(mmMMU_UP_SPI_MASK, 0xF);
27308c2ecf20Sopenharmony_ci
27318c2ecf20Sopenharmony_ci	WREG32(mmSTLB_HOP_CONFIGURATION,
27328c2ecf20Sopenharmony_ci			hdev->mmu_huge_page_opt ? 0x30440 : 0x40440);
27338c2ecf20Sopenharmony_ci
27348c2ecf20Sopenharmony_ci	/*
27358c2ecf20Sopenharmony_ci	 * The H/W expects the first PI after init to be 1. After wraparound
27368c2ecf20Sopenharmony_ci	 * we'll write 0.
27378c2ecf20Sopenharmony_ci	 */
27388c2ecf20Sopenharmony_ci	gaudi->mmu_cache_inv_pi = 1;
27398c2ecf20Sopenharmony_ci
27408c2ecf20Sopenharmony_ci	gaudi->hw_cap_initialized |= HW_CAP_MMU;
27418c2ecf20Sopenharmony_ci
27428c2ecf20Sopenharmony_ci	return 0;
27438c2ecf20Sopenharmony_ci
27448c2ecf20Sopenharmony_cierr:
27458c2ecf20Sopenharmony_ci	return rc;
27468c2ecf20Sopenharmony_ci}
27478c2ecf20Sopenharmony_ci
27488c2ecf20Sopenharmony_cistatic int gaudi_load_firmware_to_device(struct hl_device *hdev)
27498c2ecf20Sopenharmony_ci{
27508c2ecf20Sopenharmony_ci	void __iomem *dst;
27518c2ecf20Sopenharmony_ci
27528c2ecf20Sopenharmony_ci	/* HBM scrambler must be initialized before pushing F/W to HBM */
27538c2ecf20Sopenharmony_ci	gaudi_init_scrambler_hbm(hdev);
27548c2ecf20Sopenharmony_ci
27558c2ecf20Sopenharmony_ci	dst = hdev->pcie_bar[HBM_BAR_ID] + LINUX_FW_OFFSET;
27568c2ecf20Sopenharmony_ci
27578c2ecf20Sopenharmony_ci	return hl_fw_load_fw_to_device(hdev, GAUDI_LINUX_FW_FILE, dst);
27588c2ecf20Sopenharmony_ci}
27598c2ecf20Sopenharmony_ci
27608c2ecf20Sopenharmony_cistatic int gaudi_load_boot_fit_to_device(struct hl_device *hdev)
27618c2ecf20Sopenharmony_ci{
27628c2ecf20Sopenharmony_ci	void __iomem *dst;
27638c2ecf20Sopenharmony_ci
27648c2ecf20Sopenharmony_ci	dst = hdev->pcie_bar[SRAM_BAR_ID] + BOOT_FIT_SRAM_OFFSET;
27658c2ecf20Sopenharmony_ci
27668c2ecf20Sopenharmony_ci	return hl_fw_load_fw_to_device(hdev, GAUDI_BOOT_FIT_FILE, dst);
27678c2ecf20Sopenharmony_ci}
27688c2ecf20Sopenharmony_ci
27698c2ecf20Sopenharmony_cistatic void gaudi_read_device_fw_version(struct hl_device *hdev,
27708c2ecf20Sopenharmony_ci					enum hl_fw_component fwc)
27718c2ecf20Sopenharmony_ci{
27728c2ecf20Sopenharmony_ci	const char *name;
27738c2ecf20Sopenharmony_ci	u32 ver_off;
27748c2ecf20Sopenharmony_ci	char *dest;
27758c2ecf20Sopenharmony_ci
27768c2ecf20Sopenharmony_ci	switch (fwc) {
27778c2ecf20Sopenharmony_ci	case FW_COMP_UBOOT:
27788c2ecf20Sopenharmony_ci		ver_off = RREG32(mmUBOOT_VER_OFFSET);
27798c2ecf20Sopenharmony_ci		dest = hdev->asic_prop.uboot_ver;
27808c2ecf20Sopenharmony_ci		name = "U-Boot";
27818c2ecf20Sopenharmony_ci		break;
27828c2ecf20Sopenharmony_ci	case FW_COMP_PREBOOT:
27838c2ecf20Sopenharmony_ci		ver_off = RREG32(mmPREBOOT_VER_OFFSET);
27848c2ecf20Sopenharmony_ci		dest = hdev->asic_prop.preboot_ver;
27858c2ecf20Sopenharmony_ci		name = "Preboot";
27868c2ecf20Sopenharmony_ci		break;
27878c2ecf20Sopenharmony_ci	default:
27888c2ecf20Sopenharmony_ci		dev_warn(hdev->dev, "Undefined FW component: %d\n", fwc);
27898c2ecf20Sopenharmony_ci		return;
27908c2ecf20Sopenharmony_ci	}
27918c2ecf20Sopenharmony_ci
27928c2ecf20Sopenharmony_ci	ver_off &= ~((u32)SRAM_BASE_ADDR);
27938c2ecf20Sopenharmony_ci
27948c2ecf20Sopenharmony_ci	if (ver_off < SRAM_SIZE - VERSION_MAX_LEN) {
27958c2ecf20Sopenharmony_ci		memcpy_fromio(dest, hdev->pcie_bar[SRAM_BAR_ID] + ver_off,
27968c2ecf20Sopenharmony_ci							VERSION_MAX_LEN);
27978c2ecf20Sopenharmony_ci	} else {
27988c2ecf20Sopenharmony_ci		dev_err(hdev->dev, "%s version offset (0x%x) is above SRAM\n",
27998c2ecf20Sopenharmony_ci								name, ver_off);
28008c2ecf20Sopenharmony_ci		strcpy(dest, "unavailable");
28018c2ecf20Sopenharmony_ci	}
28028c2ecf20Sopenharmony_ci}
28038c2ecf20Sopenharmony_ci
28048c2ecf20Sopenharmony_cistatic int gaudi_init_cpu(struct hl_device *hdev)
28058c2ecf20Sopenharmony_ci{
28068c2ecf20Sopenharmony_ci	struct gaudi_device *gaudi = hdev->asic_specific;
28078c2ecf20Sopenharmony_ci	int rc;
28088c2ecf20Sopenharmony_ci
28098c2ecf20Sopenharmony_ci	if (!hdev->cpu_enable)
28108c2ecf20Sopenharmony_ci		return 0;
28118c2ecf20Sopenharmony_ci
28128c2ecf20Sopenharmony_ci	if (gaudi->hw_cap_initialized & HW_CAP_CPU)
28138c2ecf20Sopenharmony_ci		return 0;
28148c2ecf20Sopenharmony_ci
28158c2ecf20Sopenharmony_ci	/*
28168c2ecf20Sopenharmony_ci	 * The device CPU works with 40 bits addresses.
28178c2ecf20Sopenharmony_ci	 * This register sets the extension to 50 bits.
28188c2ecf20Sopenharmony_ci	 */
28198c2ecf20Sopenharmony_ci	WREG32(mmCPU_IF_CPU_MSB_ADDR, hdev->cpu_pci_msb_addr);
28208c2ecf20Sopenharmony_ci
28218c2ecf20Sopenharmony_ci	rc = hl_fw_init_cpu(hdev, mmPSOC_GLOBAL_CONF_CPU_BOOT_STATUS,
28228c2ecf20Sopenharmony_ci			mmPSOC_GLOBAL_CONF_KMD_MSG_TO_CPU,
28238c2ecf20Sopenharmony_ci			mmCPU_CMD_STATUS_TO_HOST,
28248c2ecf20Sopenharmony_ci			mmCPU_BOOT_ERR0,
28258c2ecf20Sopenharmony_ci			!hdev->bmc_enable, GAUDI_CPU_TIMEOUT_USEC,
28268c2ecf20Sopenharmony_ci			GAUDI_BOOT_FIT_REQ_TIMEOUT_USEC);
28278c2ecf20Sopenharmony_ci
28288c2ecf20Sopenharmony_ci	if (rc)
28298c2ecf20Sopenharmony_ci		return rc;
28308c2ecf20Sopenharmony_ci
28318c2ecf20Sopenharmony_ci	gaudi->hw_cap_initialized |= HW_CAP_CPU;
28328c2ecf20Sopenharmony_ci
28338c2ecf20Sopenharmony_ci	return 0;
28348c2ecf20Sopenharmony_ci}
28358c2ecf20Sopenharmony_ci
28368c2ecf20Sopenharmony_cistatic int gaudi_init_cpu_queues(struct hl_device *hdev, u32 cpu_timeout)
28378c2ecf20Sopenharmony_ci{
28388c2ecf20Sopenharmony_ci	struct gaudi_device *gaudi = hdev->asic_specific;
28398c2ecf20Sopenharmony_ci	struct hl_eq *eq;
28408c2ecf20Sopenharmony_ci	u32 status;
28418c2ecf20Sopenharmony_ci	struct hl_hw_queue *cpu_pq =
28428c2ecf20Sopenharmony_ci			&hdev->kernel_queues[GAUDI_QUEUE_ID_CPU_PQ];
28438c2ecf20Sopenharmony_ci	int err;
28448c2ecf20Sopenharmony_ci
28458c2ecf20Sopenharmony_ci	if (!hdev->cpu_queues_enable)
28468c2ecf20Sopenharmony_ci		return 0;
28478c2ecf20Sopenharmony_ci
28488c2ecf20Sopenharmony_ci	if (gaudi->hw_cap_initialized & HW_CAP_CPU_Q)
28498c2ecf20Sopenharmony_ci		return 0;
28508c2ecf20Sopenharmony_ci
28518c2ecf20Sopenharmony_ci	eq = &hdev->event_queue;
28528c2ecf20Sopenharmony_ci
28538c2ecf20Sopenharmony_ci	WREG32(mmCPU_IF_PQ_BASE_ADDR_LOW, lower_32_bits(cpu_pq->bus_address));
28548c2ecf20Sopenharmony_ci	WREG32(mmCPU_IF_PQ_BASE_ADDR_HIGH, upper_32_bits(cpu_pq->bus_address));
28558c2ecf20Sopenharmony_ci
28568c2ecf20Sopenharmony_ci	WREG32(mmCPU_IF_EQ_BASE_ADDR_LOW, lower_32_bits(eq->bus_address));
28578c2ecf20Sopenharmony_ci	WREG32(mmCPU_IF_EQ_BASE_ADDR_HIGH, upper_32_bits(eq->bus_address));
28588c2ecf20Sopenharmony_ci
28598c2ecf20Sopenharmony_ci	WREG32(mmCPU_IF_CQ_BASE_ADDR_LOW,
28608c2ecf20Sopenharmony_ci			lower_32_bits(hdev->cpu_accessible_dma_address));
28618c2ecf20Sopenharmony_ci	WREG32(mmCPU_IF_CQ_BASE_ADDR_HIGH,
28628c2ecf20Sopenharmony_ci			upper_32_bits(hdev->cpu_accessible_dma_address));
28638c2ecf20Sopenharmony_ci
28648c2ecf20Sopenharmony_ci	WREG32(mmCPU_IF_PQ_LENGTH, HL_QUEUE_SIZE_IN_BYTES);
28658c2ecf20Sopenharmony_ci	WREG32(mmCPU_IF_EQ_LENGTH, HL_EQ_SIZE_IN_BYTES);
28668c2ecf20Sopenharmony_ci	WREG32(mmCPU_IF_CQ_LENGTH, HL_CPU_ACCESSIBLE_MEM_SIZE);
28678c2ecf20Sopenharmony_ci
28688c2ecf20Sopenharmony_ci	/* Used for EQ CI */
28698c2ecf20Sopenharmony_ci	WREG32(mmCPU_IF_EQ_RD_OFFS, 0);
28708c2ecf20Sopenharmony_ci
28718c2ecf20Sopenharmony_ci	WREG32(mmCPU_IF_PF_PQ_PI, 0);
28728c2ecf20Sopenharmony_ci
28738c2ecf20Sopenharmony_ci	if (gaudi->multi_msi_mode)
28748c2ecf20Sopenharmony_ci		WREG32(mmCPU_IF_QUEUE_INIT, PQ_INIT_STATUS_READY_FOR_CP);
28758c2ecf20Sopenharmony_ci	else
28768c2ecf20Sopenharmony_ci		WREG32(mmCPU_IF_QUEUE_INIT,
28778c2ecf20Sopenharmony_ci			PQ_INIT_STATUS_READY_FOR_CP_SINGLE_MSI);
28788c2ecf20Sopenharmony_ci
28798c2ecf20Sopenharmony_ci	WREG32(mmGIC_DISTRIBUTOR__5_GICD_SETSPI_NSR, GAUDI_EVENT_PI_UPDATE);
28808c2ecf20Sopenharmony_ci
28818c2ecf20Sopenharmony_ci	err = hl_poll_timeout(
28828c2ecf20Sopenharmony_ci		hdev,
28838c2ecf20Sopenharmony_ci		mmCPU_IF_QUEUE_INIT,
28848c2ecf20Sopenharmony_ci		status,
28858c2ecf20Sopenharmony_ci		(status == PQ_INIT_STATUS_READY_FOR_HOST),
28868c2ecf20Sopenharmony_ci		1000,
28878c2ecf20Sopenharmony_ci		cpu_timeout);
28888c2ecf20Sopenharmony_ci
28898c2ecf20Sopenharmony_ci	if (err) {
28908c2ecf20Sopenharmony_ci		dev_err(hdev->dev,
28918c2ecf20Sopenharmony_ci			"Failed to communicate with Device CPU (CPU-CP timeout)\n");
28928c2ecf20Sopenharmony_ci		return -EIO;
28938c2ecf20Sopenharmony_ci	}
28948c2ecf20Sopenharmony_ci
28958c2ecf20Sopenharmony_ci	gaudi->hw_cap_initialized |= HW_CAP_CPU_Q;
28968c2ecf20Sopenharmony_ci	return 0;
28978c2ecf20Sopenharmony_ci}
28988c2ecf20Sopenharmony_ci
28998c2ecf20Sopenharmony_cistatic void gaudi_pre_hw_init(struct hl_device *hdev)
29008c2ecf20Sopenharmony_ci{
29018c2ecf20Sopenharmony_ci	/* Perform read from the device to make sure device is up */
29028c2ecf20Sopenharmony_ci	RREG32(mmHW_STATE);
29038c2ecf20Sopenharmony_ci
29048c2ecf20Sopenharmony_ci	/* Set the access through PCI bars (Linux driver only) as
29058c2ecf20Sopenharmony_ci	 * secured
29068c2ecf20Sopenharmony_ci	 */
29078c2ecf20Sopenharmony_ci	WREG32(mmPCIE_WRAP_LBW_PROT_OVR,
29088c2ecf20Sopenharmony_ci			(PCIE_WRAP_LBW_PROT_OVR_RD_EN_MASK |
29098c2ecf20Sopenharmony_ci			PCIE_WRAP_LBW_PROT_OVR_WR_EN_MASK));
29108c2ecf20Sopenharmony_ci
29118c2ecf20Sopenharmony_ci	/* Perform read to flush the waiting writes to ensure
29128c2ecf20Sopenharmony_ci	 * configuration was set in the device
29138c2ecf20Sopenharmony_ci	 */
29148c2ecf20Sopenharmony_ci	RREG32(mmPCIE_WRAP_LBW_PROT_OVR);
29158c2ecf20Sopenharmony_ci
29168c2ecf20Sopenharmony_ci	/*
29178c2ecf20Sopenharmony_ci	 * Let's mark in the H/W that we have reached this point. We check
29188c2ecf20Sopenharmony_ci	 * this value in the reset_before_init function to understand whether
29198c2ecf20Sopenharmony_ci	 * we need to reset the chip before doing H/W init. This register is
29208c2ecf20Sopenharmony_ci	 * cleared by the H/W upon H/W reset
29218c2ecf20Sopenharmony_ci	 */
29228c2ecf20Sopenharmony_ci	WREG32(mmHW_STATE, HL_DEVICE_HW_STATE_DIRTY);
29238c2ecf20Sopenharmony_ci
29248c2ecf20Sopenharmony_ci	/* Configure the reset registers. Must be done as early as possible
29258c2ecf20Sopenharmony_ci	 * in case we fail during H/W initialization
29268c2ecf20Sopenharmony_ci	 */
29278c2ecf20Sopenharmony_ci	WREG32(mmPSOC_GLOBAL_CONF_SOFT_RST_CFG_H,
29288c2ecf20Sopenharmony_ci					(CFG_RST_H_DMA_MASK |
29298c2ecf20Sopenharmony_ci					CFG_RST_H_MME_MASK |
29308c2ecf20Sopenharmony_ci					CFG_RST_H_SM_MASK |
29318c2ecf20Sopenharmony_ci					CFG_RST_H_TPC_7_MASK));
29328c2ecf20Sopenharmony_ci
29338c2ecf20Sopenharmony_ci	WREG32(mmPSOC_GLOBAL_CONF_SOFT_RST_CFG_L, CFG_RST_L_TPC_MASK);
29348c2ecf20Sopenharmony_ci
29358c2ecf20Sopenharmony_ci	WREG32(mmPSOC_GLOBAL_CONF_SW_ALL_RST_CFG_H,
29368c2ecf20Sopenharmony_ci					(CFG_RST_H_HBM_MASK |
29378c2ecf20Sopenharmony_ci					CFG_RST_H_TPC_7_MASK |
29388c2ecf20Sopenharmony_ci					CFG_RST_H_NIC_MASK |
29398c2ecf20Sopenharmony_ci					CFG_RST_H_SM_MASK |
29408c2ecf20Sopenharmony_ci					CFG_RST_H_DMA_MASK |
29418c2ecf20Sopenharmony_ci					CFG_RST_H_MME_MASK |
29428c2ecf20Sopenharmony_ci					CFG_RST_H_CPU_MASK |
29438c2ecf20Sopenharmony_ci					CFG_RST_H_MMU_MASK));
29448c2ecf20Sopenharmony_ci
29458c2ecf20Sopenharmony_ci	WREG32(mmPSOC_GLOBAL_CONF_SW_ALL_RST_CFG_L,
29468c2ecf20Sopenharmony_ci					(CFG_RST_L_IF_MASK |
29478c2ecf20Sopenharmony_ci					CFG_RST_L_PSOC_MASK |
29488c2ecf20Sopenharmony_ci					CFG_RST_L_TPC_MASK));
29498c2ecf20Sopenharmony_ci}
29508c2ecf20Sopenharmony_ci
29518c2ecf20Sopenharmony_cistatic int gaudi_hw_init(struct hl_device *hdev)
29528c2ecf20Sopenharmony_ci{
29538c2ecf20Sopenharmony_ci	int rc;
29548c2ecf20Sopenharmony_ci
29558c2ecf20Sopenharmony_ci	dev_info(hdev->dev, "Starting initialization of H/W\n");
29568c2ecf20Sopenharmony_ci
29578c2ecf20Sopenharmony_ci	gaudi_pre_hw_init(hdev);
29588c2ecf20Sopenharmony_ci
29598c2ecf20Sopenharmony_ci	gaudi_init_pci_dma_qmans(hdev);
29608c2ecf20Sopenharmony_ci
29618c2ecf20Sopenharmony_ci	gaudi_init_hbm_dma_qmans(hdev);
29628c2ecf20Sopenharmony_ci
29638c2ecf20Sopenharmony_ci	rc = gaudi_init_cpu(hdev);
29648c2ecf20Sopenharmony_ci	if (rc) {
29658c2ecf20Sopenharmony_ci		dev_err(hdev->dev, "failed to initialize CPU\n");
29668c2ecf20Sopenharmony_ci		return rc;
29678c2ecf20Sopenharmony_ci	}
29688c2ecf20Sopenharmony_ci
29698c2ecf20Sopenharmony_ci	/* SRAM scrambler must be initialized after CPU is running from HBM */
29708c2ecf20Sopenharmony_ci	gaudi_init_scrambler_sram(hdev);
29718c2ecf20Sopenharmony_ci
29728c2ecf20Sopenharmony_ci	/* This is here just in case we are working without CPU */
29738c2ecf20Sopenharmony_ci	gaudi_init_scrambler_hbm(hdev);
29748c2ecf20Sopenharmony_ci
29758c2ecf20Sopenharmony_ci	gaudi_init_golden_registers(hdev);
29768c2ecf20Sopenharmony_ci
29778c2ecf20Sopenharmony_ci	rc = gaudi_mmu_init(hdev);
29788c2ecf20Sopenharmony_ci	if (rc)
29798c2ecf20Sopenharmony_ci		return rc;
29808c2ecf20Sopenharmony_ci
29818c2ecf20Sopenharmony_ci	gaudi_init_security(hdev);
29828c2ecf20Sopenharmony_ci
29838c2ecf20Sopenharmony_ci	gaudi_init_mme_qmans(hdev);
29848c2ecf20Sopenharmony_ci
29858c2ecf20Sopenharmony_ci	gaudi_init_tpc_qmans(hdev);
29868c2ecf20Sopenharmony_ci
29878c2ecf20Sopenharmony_ci	hdev->asic_funcs->set_clock_gating(hdev);
29888c2ecf20Sopenharmony_ci
29898c2ecf20Sopenharmony_ci	gaudi_enable_timestamp(hdev);
29908c2ecf20Sopenharmony_ci
29918c2ecf20Sopenharmony_ci	/* MSI must be enabled before CPU queues are initialized */
29928c2ecf20Sopenharmony_ci	rc = gaudi_enable_msi(hdev);
29938c2ecf20Sopenharmony_ci	if (rc)
29948c2ecf20Sopenharmony_ci		goto disable_queues;
29958c2ecf20Sopenharmony_ci
29968c2ecf20Sopenharmony_ci	/* must be called after MSI was enabled */
29978c2ecf20Sopenharmony_ci	rc = gaudi_init_cpu_queues(hdev, GAUDI_CPU_TIMEOUT_USEC);
29988c2ecf20Sopenharmony_ci	if (rc) {
29998c2ecf20Sopenharmony_ci		dev_err(hdev->dev, "failed to initialize CPU H/W queues %d\n",
30008c2ecf20Sopenharmony_ci			rc);
30018c2ecf20Sopenharmony_ci		goto disable_msi;
30028c2ecf20Sopenharmony_ci	}
30038c2ecf20Sopenharmony_ci
30048c2ecf20Sopenharmony_ci	/* Perform read from the device to flush all configuration */
30058c2ecf20Sopenharmony_ci	RREG32(mmHW_STATE);
30068c2ecf20Sopenharmony_ci
30078c2ecf20Sopenharmony_ci	return 0;
30088c2ecf20Sopenharmony_ci
30098c2ecf20Sopenharmony_cidisable_msi:
30108c2ecf20Sopenharmony_ci	gaudi_disable_msi(hdev);
30118c2ecf20Sopenharmony_cidisable_queues:
30128c2ecf20Sopenharmony_ci	gaudi_disable_mme_qmans(hdev);
30138c2ecf20Sopenharmony_ci	gaudi_disable_pci_dma_qmans(hdev);
30148c2ecf20Sopenharmony_ci
30158c2ecf20Sopenharmony_ci	return rc;
30168c2ecf20Sopenharmony_ci}
30178c2ecf20Sopenharmony_ci
30188c2ecf20Sopenharmony_cistatic void gaudi_hw_fini(struct hl_device *hdev, bool hard_reset)
30198c2ecf20Sopenharmony_ci{
30208c2ecf20Sopenharmony_ci	struct gaudi_device *gaudi = hdev->asic_specific;
30218c2ecf20Sopenharmony_ci	u32 status, reset_timeout_ms, cpu_timeout_ms, boot_strap = 0;
30228c2ecf20Sopenharmony_ci
30238c2ecf20Sopenharmony_ci	if (!hard_reset) {
30248c2ecf20Sopenharmony_ci		dev_err(hdev->dev, "GAUDI doesn't support soft-reset\n");
30258c2ecf20Sopenharmony_ci		return;
30268c2ecf20Sopenharmony_ci	}
30278c2ecf20Sopenharmony_ci
30288c2ecf20Sopenharmony_ci	if (hdev->pldm) {
30298c2ecf20Sopenharmony_ci		reset_timeout_ms = GAUDI_PLDM_HRESET_TIMEOUT_MSEC;
30308c2ecf20Sopenharmony_ci		cpu_timeout_ms = GAUDI_PLDM_RESET_WAIT_MSEC;
30318c2ecf20Sopenharmony_ci	} else {
30328c2ecf20Sopenharmony_ci		reset_timeout_ms = GAUDI_RESET_TIMEOUT_MSEC;
30338c2ecf20Sopenharmony_ci		cpu_timeout_ms = GAUDI_CPU_RESET_WAIT_MSEC;
30348c2ecf20Sopenharmony_ci	}
30358c2ecf20Sopenharmony_ci
30368c2ecf20Sopenharmony_ci	/* Set device to handle FLR by H/W as we will put the device CPU to
30378c2ecf20Sopenharmony_ci	 * halt mode
30388c2ecf20Sopenharmony_ci	 */
30398c2ecf20Sopenharmony_ci	WREG32(mmPCIE_AUX_FLR_CTRL, (PCIE_AUX_FLR_CTRL_HW_CTRL_MASK |
30408c2ecf20Sopenharmony_ci					PCIE_AUX_FLR_CTRL_INT_MASK_MASK));
30418c2ecf20Sopenharmony_ci
30428c2ecf20Sopenharmony_ci	/* I don't know what is the state of the CPU so make sure it is
30438c2ecf20Sopenharmony_ci	 * stopped in any means necessary
30448c2ecf20Sopenharmony_ci	 */
30458c2ecf20Sopenharmony_ci	WREG32(mmPSOC_GLOBAL_CONF_KMD_MSG_TO_CPU, KMD_MSG_GOTO_WFE);
30468c2ecf20Sopenharmony_ci	WREG32(mmGIC_DISTRIBUTOR__5_GICD_SETSPI_NSR, GAUDI_EVENT_HALT_MACHINE);
30478c2ecf20Sopenharmony_ci
30488c2ecf20Sopenharmony_ci	msleep(cpu_timeout_ms);
30498c2ecf20Sopenharmony_ci
30508c2ecf20Sopenharmony_ci	/* Tell ASIC not to re-initialize PCIe */
30518c2ecf20Sopenharmony_ci	WREG32(mmPREBOOT_PCIE_EN, LKD_HARD_RESET_MAGIC);
30528c2ecf20Sopenharmony_ci
30538c2ecf20Sopenharmony_ci	boot_strap = RREG32(mmPSOC_GLOBAL_CONF_BOOT_STRAP_PINS);
30548c2ecf20Sopenharmony_ci
30558c2ecf20Sopenharmony_ci	/* H/W bug WA:
30568c2ecf20Sopenharmony_ci	 * rdata[31:0] = strap_read_val;
30578c2ecf20Sopenharmony_ci	 * wdata[31:0] = rdata[30:21],1'b0,rdata[20:0]
30588c2ecf20Sopenharmony_ci	 */
30598c2ecf20Sopenharmony_ci	boot_strap = (((boot_strap & 0x7FE00000) << 1) |
30608c2ecf20Sopenharmony_ci			(boot_strap & 0x001FFFFF));
30618c2ecf20Sopenharmony_ci	WREG32(mmPSOC_GLOBAL_CONF_BOOT_STRAP_PINS, boot_strap & ~0x2);
30628c2ecf20Sopenharmony_ci
30638c2ecf20Sopenharmony_ci	/* Restart BTL/BLR upon hard-reset */
30648c2ecf20Sopenharmony_ci	WREG32(mmPSOC_GLOBAL_CONF_BOOT_SEQ_RE_START, 1);
30658c2ecf20Sopenharmony_ci
30668c2ecf20Sopenharmony_ci	WREG32(mmPSOC_GLOBAL_CONF_SW_ALL_RST,
30678c2ecf20Sopenharmony_ci			1 << PSOC_GLOBAL_CONF_SW_ALL_RST_IND_SHIFT);
30688c2ecf20Sopenharmony_ci	dev_info(hdev->dev,
30698c2ecf20Sopenharmony_ci		"Issued HARD reset command, going to wait %dms\n",
30708c2ecf20Sopenharmony_ci		reset_timeout_ms);
30718c2ecf20Sopenharmony_ci
30728c2ecf20Sopenharmony_ci	/*
30738c2ecf20Sopenharmony_ci	 * After hard reset, we can't poll the BTM_FSM register because the PSOC
30748c2ecf20Sopenharmony_ci	 * itself is in reset. Need to wait until the reset is deasserted
30758c2ecf20Sopenharmony_ci	 */
30768c2ecf20Sopenharmony_ci	msleep(reset_timeout_ms);
30778c2ecf20Sopenharmony_ci
30788c2ecf20Sopenharmony_ci	status = RREG32(mmPSOC_GLOBAL_CONF_BTM_FSM);
30798c2ecf20Sopenharmony_ci	if (status & PSOC_GLOBAL_CONF_BTM_FSM_STATE_MASK)
30808c2ecf20Sopenharmony_ci		dev_err(hdev->dev,
30818c2ecf20Sopenharmony_ci			"Timeout while waiting for device to reset 0x%x\n",
30828c2ecf20Sopenharmony_ci			status);
30838c2ecf20Sopenharmony_ci
30848c2ecf20Sopenharmony_ci	WREG32(mmPSOC_GLOBAL_CONF_BOOT_STRAP_PINS, boot_strap);
30858c2ecf20Sopenharmony_ci
30868c2ecf20Sopenharmony_ci	gaudi->hw_cap_initialized &= ~(HW_CAP_CPU | HW_CAP_CPU_Q |
30878c2ecf20Sopenharmony_ci					HW_CAP_HBM | HW_CAP_PCI_DMA |
30888c2ecf20Sopenharmony_ci					HW_CAP_MME | HW_CAP_TPC_MASK |
30898c2ecf20Sopenharmony_ci					HW_CAP_HBM_DMA | HW_CAP_PLL |
30908c2ecf20Sopenharmony_ci					HW_CAP_MMU |
30918c2ecf20Sopenharmony_ci					HW_CAP_SRAM_SCRAMBLER |
30928c2ecf20Sopenharmony_ci					HW_CAP_HBM_SCRAMBLER |
30938c2ecf20Sopenharmony_ci					HW_CAP_CLK_GATE);
30948c2ecf20Sopenharmony_ci
30958c2ecf20Sopenharmony_ci	memset(gaudi->events_stat, 0, sizeof(gaudi->events_stat));
30968c2ecf20Sopenharmony_ci}
30978c2ecf20Sopenharmony_ci
30988c2ecf20Sopenharmony_cistatic int gaudi_suspend(struct hl_device *hdev)
30998c2ecf20Sopenharmony_ci{
31008c2ecf20Sopenharmony_ci	int rc;
31018c2ecf20Sopenharmony_ci
31028c2ecf20Sopenharmony_ci	rc = hl_fw_send_pci_access_msg(hdev, CPUCP_PACKET_DISABLE_PCI_ACCESS);
31038c2ecf20Sopenharmony_ci	if (rc)
31048c2ecf20Sopenharmony_ci		dev_err(hdev->dev, "Failed to disable PCI access from CPU\n");
31058c2ecf20Sopenharmony_ci
31068c2ecf20Sopenharmony_ci	return rc;
31078c2ecf20Sopenharmony_ci}
31088c2ecf20Sopenharmony_ci
31098c2ecf20Sopenharmony_cistatic int gaudi_resume(struct hl_device *hdev)
31108c2ecf20Sopenharmony_ci{
31118c2ecf20Sopenharmony_ci	return gaudi_init_iatu(hdev);
31128c2ecf20Sopenharmony_ci}
31138c2ecf20Sopenharmony_ci
31148c2ecf20Sopenharmony_cistatic int gaudi_cb_mmap(struct hl_device *hdev, struct vm_area_struct *vma,
31158c2ecf20Sopenharmony_ci			void *cpu_addr, dma_addr_t dma_addr, size_t size)
31168c2ecf20Sopenharmony_ci{
31178c2ecf20Sopenharmony_ci	int rc;
31188c2ecf20Sopenharmony_ci
31198c2ecf20Sopenharmony_ci	vma->vm_flags |= VM_IO | VM_PFNMAP | VM_DONTEXPAND | VM_DONTDUMP |
31208c2ecf20Sopenharmony_ci			VM_DONTCOPY | VM_NORESERVE;
31218c2ecf20Sopenharmony_ci
31228c2ecf20Sopenharmony_ci	rc = dma_mmap_coherent(hdev->dev, vma, cpu_addr,
31238c2ecf20Sopenharmony_ci				(dma_addr - HOST_PHYS_BASE), size);
31248c2ecf20Sopenharmony_ci	if (rc)
31258c2ecf20Sopenharmony_ci		dev_err(hdev->dev, "dma_mmap_coherent error %d", rc);
31268c2ecf20Sopenharmony_ci
31278c2ecf20Sopenharmony_ci	return rc;
31288c2ecf20Sopenharmony_ci}
31298c2ecf20Sopenharmony_ci
31308c2ecf20Sopenharmony_cistatic void gaudi_ring_doorbell(struct hl_device *hdev, u32 hw_queue_id, u32 pi)
31318c2ecf20Sopenharmony_ci{
31328c2ecf20Sopenharmony_ci	struct gaudi_device *gaudi = hdev->asic_specific;
31338c2ecf20Sopenharmony_ci	u32 db_reg_offset, db_value, dma_qm_offset, q_off;
31348c2ecf20Sopenharmony_ci	int dma_id;
31358c2ecf20Sopenharmony_ci	bool invalid_queue = false;
31368c2ecf20Sopenharmony_ci
31378c2ecf20Sopenharmony_ci	switch (hw_queue_id) {
31388c2ecf20Sopenharmony_ci	case GAUDI_QUEUE_ID_DMA_0_0...GAUDI_QUEUE_ID_DMA_0_3:
31398c2ecf20Sopenharmony_ci		dma_id = gaudi_dma_assignment[GAUDI_PCI_DMA_1];
31408c2ecf20Sopenharmony_ci		dma_qm_offset = dma_id * DMA_QMAN_OFFSET;
31418c2ecf20Sopenharmony_ci		q_off = dma_qm_offset + (hw_queue_id & 0x3) * 4;
31428c2ecf20Sopenharmony_ci		db_reg_offset = mmDMA0_QM_PQ_PI_0 + q_off;
31438c2ecf20Sopenharmony_ci		break;
31448c2ecf20Sopenharmony_ci
31458c2ecf20Sopenharmony_ci	case GAUDI_QUEUE_ID_DMA_1_0...GAUDI_QUEUE_ID_DMA_1_3:
31468c2ecf20Sopenharmony_ci		dma_id = gaudi_dma_assignment[GAUDI_PCI_DMA_2];
31478c2ecf20Sopenharmony_ci		dma_qm_offset = dma_id * DMA_QMAN_OFFSET;
31488c2ecf20Sopenharmony_ci		q_off = dma_qm_offset + (hw_queue_id & 0x3) * 4;
31498c2ecf20Sopenharmony_ci		db_reg_offset = mmDMA0_QM_PQ_PI_0 + q_off;
31508c2ecf20Sopenharmony_ci		break;
31518c2ecf20Sopenharmony_ci
31528c2ecf20Sopenharmony_ci	case GAUDI_QUEUE_ID_DMA_2_0...GAUDI_QUEUE_ID_DMA_2_3:
31538c2ecf20Sopenharmony_ci		dma_id = gaudi_dma_assignment[GAUDI_HBM_DMA_1];
31548c2ecf20Sopenharmony_ci		dma_qm_offset = dma_id * DMA_QMAN_OFFSET;
31558c2ecf20Sopenharmony_ci		q_off = dma_qm_offset + ((hw_queue_id - 1) & 0x3) * 4;
31568c2ecf20Sopenharmony_ci		db_reg_offset = mmDMA0_QM_PQ_PI_0 + q_off;
31578c2ecf20Sopenharmony_ci		break;
31588c2ecf20Sopenharmony_ci
31598c2ecf20Sopenharmony_ci	case GAUDI_QUEUE_ID_DMA_3_0...GAUDI_QUEUE_ID_DMA_3_3:
31608c2ecf20Sopenharmony_ci		dma_id = gaudi_dma_assignment[GAUDI_HBM_DMA_2];
31618c2ecf20Sopenharmony_ci		dma_qm_offset = dma_id * DMA_QMAN_OFFSET;
31628c2ecf20Sopenharmony_ci		q_off = dma_qm_offset + ((hw_queue_id - 1) & 0x3) * 4;
31638c2ecf20Sopenharmony_ci		db_reg_offset = mmDMA0_QM_PQ_PI_0 + q_off;
31648c2ecf20Sopenharmony_ci		break;
31658c2ecf20Sopenharmony_ci
31668c2ecf20Sopenharmony_ci	case GAUDI_QUEUE_ID_DMA_4_0...GAUDI_QUEUE_ID_DMA_4_3:
31678c2ecf20Sopenharmony_ci		dma_id = gaudi_dma_assignment[GAUDI_HBM_DMA_3];
31688c2ecf20Sopenharmony_ci		dma_qm_offset = dma_id * DMA_QMAN_OFFSET;
31698c2ecf20Sopenharmony_ci		q_off = dma_qm_offset + ((hw_queue_id - 1) & 0x3) * 4;
31708c2ecf20Sopenharmony_ci		db_reg_offset = mmDMA0_QM_PQ_PI_0 + q_off;
31718c2ecf20Sopenharmony_ci		break;
31728c2ecf20Sopenharmony_ci
31738c2ecf20Sopenharmony_ci	case GAUDI_QUEUE_ID_DMA_5_0...GAUDI_QUEUE_ID_DMA_5_3:
31748c2ecf20Sopenharmony_ci		dma_id = gaudi_dma_assignment[GAUDI_PCI_DMA_3];
31758c2ecf20Sopenharmony_ci		dma_qm_offset = dma_id * DMA_QMAN_OFFSET;
31768c2ecf20Sopenharmony_ci		q_off = dma_qm_offset + ((hw_queue_id - 1) & 0x3) * 4;
31778c2ecf20Sopenharmony_ci		db_reg_offset = mmDMA0_QM_PQ_PI_0 + q_off;
31788c2ecf20Sopenharmony_ci		break;
31798c2ecf20Sopenharmony_ci
31808c2ecf20Sopenharmony_ci	case GAUDI_QUEUE_ID_DMA_6_0...GAUDI_QUEUE_ID_DMA_6_3:
31818c2ecf20Sopenharmony_ci		dma_id = gaudi_dma_assignment[GAUDI_HBM_DMA_4];
31828c2ecf20Sopenharmony_ci		dma_qm_offset = dma_id * DMA_QMAN_OFFSET;
31838c2ecf20Sopenharmony_ci		q_off = dma_qm_offset + ((hw_queue_id - 1) & 0x3) * 4;
31848c2ecf20Sopenharmony_ci		db_reg_offset = mmDMA0_QM_PQ_PI_0 + q_off;
31858c2ecf20Sopenharmony_ci		break;
31868c2ecf20Sopenharmony_ci
31878c2ecf20Sopenharmony_ci	case GAUDI_QUEUE_ID_DMA_7_0...GAUDI_QUEUE_ID_DMA_7_3:
31888c2ecf20Sopenharmony_ci		dma_id = gaudi_dma_assignment[GAUDI_HBM_DMA_5];
31898c2ecf20Sopenharmony_ci		dma_qm_offset = dma_id * DMA_QMAN_OFFSET;
31908c2ecf20Sopenharmony_ci		q_off = dma_qm_offset + ((hw_queue_id - 1) & 0x3) * 4;
31918c2ecf20Sopenharmony_ci		db_reg_offset = mmDMA0_QM_PQ_PI_0 + q_off;
31928c2ecf20Sopenharmony_ci		break;
31938c2ecf20Sopenharmony_ci
31948c2ecf20Sopenharmony_ci	case GAUDI_QUEUE_ID_CPU_PQ:
31958c2ecf20Sopenharmony_ci		if (gaudi->hw_cap_initialized & HW_CAP_CPU_Q)
31968c2ecf20Sopenharmony_ci			db_reg_offset = mmCPU_IF_PF_PQ_PI;
31978c2ecf20Sopenharmony_ci		else
31988c2ecf20Sopenharmony_ci			invalid_queue = true;
31998c2ecf20Sopenharmony_ci		break;
32008c2ecf20Sopenharmony_ci
32018c2ecf20Sopenharmony_ci	case GAUDI_QUEUE_ID_MME_0_0:
32028c2ecf20Sopenharmony_ci		db_reg_offset = mmMME2_QM_PQ_PI_0;
32038c2ecf20Sopenharmony_ci		break;
32048c2ecf20Sopenharmony_ci
32058c2ecf20Sopenharmony_ci	case GAUDI_QUEUE_ID_MME_0_1:
32068c2ecf20Sopenharmony_ci		db_reg_offset = mmMME2_QM_PQ_PI_1;
32078c2ecf20Sopenharmony_ci		break;
32088c2ecf20Sopenharmony_ci
32098c2ecf20Sopenharmony_ci	case GAUDI_QUEUE_ID_MME_0_2:
32108c2ecf20Sopenharmony_ci		db_reg_offset = mmMME2_QM_PQ_PI_2;
32118c2ecf20Sopenharmony_ci		break;
32128c2ecf20Sopenharmony_ci
32138c2ecf20Sopenharmony_ci	case GAUDI_QUEUE_ID_MME_0_3:
32148c2ecf20Sopenharmony_ci		db_reg_offset = mmMME2_QM_PQ_PI_3;
32158c2ecf20Sopenharmony_ci		break;
32168c2ecf20Sopenharmony_ci
32178c2ecf20Sopenharmony_ci	case GAUDI_QUEUE_ID_MME_1_0:
32188c2ecf20Sopenharmony_ci		db_reg_offset = mmMME0_QM_PQ_PI_0;
32198c2ecf20Sopenharmony_ci		break;
32208c2ecf20Sopenharmony_ci
32218c2ecf20Sopenharmony_ci	case GAUDI_QUEUE_ID_MME_1_1:
32228c2ecf20Sopenharmony_ci		db_reg_offset = mmMME0_QM_PQ_PI_1;
32238c2ecf20Sopenharmony_ci		break;
32248c2ecf20Sopenharmony_ci
32258c2ecf20Sopenharmony_ci	case GAUDI_QUEUE_ID_MME_1_2:
32268c2ecf20Sopenharmony_ci		db_reg_offset = mmMME0_QM_PQ_PI_2;
32278c2ecf20Sopenharmony_ci		break;
32288c2ecf20Sopenharmony_ci
32298c2ecf20Sopenharmony_ci	case GAUDI_QUEUE_ID_MME_1_3:
32308c2ecf20Sopenharmony_ci		db_reg_offset = mmMME0_QM_PQ_PI_3;
32318c2ecf20Sopenharmony_ci		break;
32328c2ecf20Sopenharmony_ci
32338c2ecf20Sopenharmony_ci	case GAUDI_QUEUE_ID_TPC_0_0:
32348c2ecf20Sopenharmony_ci		db_reg_offset = mmTPC0_QM_PQ_PI_0;
32358c2ecf20Sopenharmony_ci		break;
32368c2ecf20Sopenharmony_ci
32378c2ecf20Sopenharmony_ci	case GAUDI_QUEUE_ID_TPC_0_1:
32388c2ecf20Sopenharmony_ci		db_reg_offset = mmTPC0_QM_PQ_PI_1;
32398c2ecf20Sopenharmony_ci		break;
32408c2ecf20Sopenharmony_ci
32418c2ecf20Sopenharmony_ci	case GAUDI_QUEUE_ID_TPC_0_2:
32428c2ecf20Sopenharmony_ci		db_reg_offset = mmTPC0_QM_PQ_PI_2;
32438c2ecf20Sopenharmony_ci		break;
32448c2ecf20Sopenharmony_ci
32458c2ecf20Sopenharmony_ci	case GAUDI_QUEUE_ID_TPC_0_3:
32468c2ecf20Sopenharmony_ci		db_reg_offset = mmTPC0_QM_PQ_PI_3;
32478c2ecf20Sopenharmony_ci		break;
32488c2ecf20Sopenharmony_ci
32498c2ecf20Sopenharmony_ci	case GAUDI_QUEUE_ID_TPC_1_0:
32508c2ecf20Sopenharmony_ci		db_reg_offset = mmTPC1_QM_PQ_PI_0;
32518c2ecf20Sopenharmony_ci		break;
32528c2ecf20Sopenharmony_ci
32538c2ecf20Sopenharmony_ci	case GAUDI_QUEUE_ID_TPC_1_1:
32548c2ecf20Sopenharmony_ci		db_reg_offset = mmTPC1_QM_PQ_PI_1;
32558c2ecf20Sopenharmony_ci		break;
32568c2ecf20Sopenharmony_ci
32578c2ecf20Sopenharmony_ci	case GAUDI_QUEUE_ID_TPC_1_2:
32588c2ecf20Sopenharmony_ci		db_reg_offset = mmTPC1_QM_PQ_PI_2;
32598c2ecf20Sopenharmony_ci		break;
32608c2ecf20Sopenharmony_ci
32618c2ecf20Sopenharmony_ci	case GAUDI_QUEUE_ID_TPC_1_3:
32628c2ecf20Sopenharmony_ci		db_reg_offset = mmTPC1_QM_PQ_PI_3;
32638c2ecf20Sopenharmony_ci		break;
32648c2ecf20Sopenharmony_ci
32658c2ecf20Sopenharmony_ci	case GAUDI_QUEUE_ID_TPC_2_0:
32668c2ecf20Sopenharmony_ci		db_reg_offset = mmTPC2_QM_PQ_PI_0;
32678c2ecf20Sopenharmony_ci		break;
32688c2ecf20Sopenharmony_ci
32698c2ecf20Sopenharmony_ci	case GAUDI_QUEUE_ID_TPC_2_1:
32708c2ecf20Sopenharmony_ci		db_reg_offset = mmTPC2_QM_PQ_PI_1;
32718c2ecf20Sopenharmony_ci		break;
32728c2ecf20Sopenharmony_ci
32738c2ecf20Sopenharmony_ci	case GAUDI_QUEUE_ID_TPC_2_2:
32748c2ecf20Sopenharmony_ci		db_reg_offset = mmTPC2_QM_PQ_PI_2;
32758c2ecf20Sopenharmony_ci		break;
32768c2ecf20Sopenharmony_ci
32778c2ecf20Sopenharmony_ci	case GAUDI_QUEUE_ID_TPC_2_3:
32788c2ecf20Sopenharmony_ci		db_reg_offset = mmTPC2_QM_PQ_PI_3;
32798c2ecf20Sopenharmony_ci		break;
32808c2ecf20Sopenharmony_ci
32818c2ecf20Sopenharmony_ci	case GAUDI_QUEUE_ID_TPC_3_0:
32828c2ecf20Sopenharmony_ci		db_reg_offset = mmTPC3_QM_PQ_PI_0;
32838c2ecf20Sopenharmony_ci		break;
32848c2ecf20Sopenharmony_ci
32858c2ecf20Sopenharmony_ci	case GAUDI_QUEUE_ID_TPC_3_1:
32868c2ecf20Sopenharmony_ci		db_reg_offset = mmTPC3_QM_PQ_PI_1;
32878c2ecf20Sopenharmony_ci		break;
32888c2ecf20Sopenharmony_ci
32898c2ecf20Sopenharmony_ci	case GAUDI_QUEUE_ID_TPC_3_2:
32908c2ecf20Sopenharmony_ci		db_reg_offset = mmTPC3_QM_PQ_PI_2;
32918c2ecf20Sopenharmony_ci		break;
32928c2ecf20Sopenharmony_ci
32938c2ecf20Sopenharmony_ci	case GAUDI_QUEUE_ID_TPC_3_3:
32948c2ecf20Sopenharmony_ci		db_reg_offset = mmTPC3_QM_PQ_PI_3;
32958c2ecf20Sopenharmony_ci		break;
32968c2ecf20Sopenharmony_ci
32978c2ecf20Sopenharmony_ci	case GAUDI_QUEUE_ID_TPC_4_0:
32988c2ecf20Sopenharmony_ci		db_reg_offset = mmTPC4_QM_PQ_PI_0;
32998c2ecf20Sopenharmony_ci		break;
33008c2ecf20Sopenharmony_ci
33018c2ecf20Sopenharmony_ci	case GAUDI_QUEUE_ID_TPC_4_1:
33028c2ecf20Sopenharmony_ci		db_reg_offset = mmTPC4_QM_PQ_PI_1;
33038c2ecf20Sopenharmony_ci		break;
33048c2ecf20Sopenharmony_ci
33058c2ecf20Sopenharmony_ci	case GAUDI_QUEUE_ID_TPC_4_2:
33068c2ecf20Sopenharmony_ci		db_reg_offset = mmTPC4_QM_PQ_PI_2;
33078c2ecf20Sopenharmony_ci		break;
33088c2ecf20Sopenharmony_ci
33098c2ecf20Sopenharmony_ci	case GAUDI_QUEUE_ID_TPC_4_3:
33108c2ecf20Sopenharmony_ci		db_reg_offset = mmTPC4_QM_PQ_PI_3;
33118c2ecf20Sopenharmony_ci		break;
33128c2ecf20Sopenharmony_ci
33138c2ecf20Sopenharmony_ci	case GAUDI_QUEUE_ID_TPC_5_0:
33148c2ecf20Sopenharmony_ci		db_reg_offset = mmTPC5_QM_PQ_PI_0;
33158c2ecf20Sopenharmony_ci		break;
33168c2ecf20Sopenharmony_ci
33178c2ecf20Sopenharmony_ci	case GAUDI_QUEUE_ID_TPC_5_1:
33188c2ecf20Sopenharmony_ci		db_reg_offset = mmTPC5_QM_PQ_PI_1;
33198c2ecf20Sopenharmony_ci		break;
33208c2ecf20Sopenharmony_ci
33218c2ecf20Sopenharmony_ci	case GAUDI_QUEUE_ID_TPC_5_2:
33228c2ecf20Sopenharmony_ci		db_reg_offset = mmTPC5_QM_PQ_PI_2;
33238c2ecf20Sopenharmony_ci		break;
33248c2ecf20Sopenharmony_ci
33258c2ecf20Sopenharmony_ci	case GAUDI_QUEUE_ID_TPC_5_3:
33268c2ecf20Sopenharmony_ci		db_reg_offset = mmTPC5_QM_PQ_PI_3;
33278c2ecf20Sopenharmony_ci		break;
33288c2ecf20Sopenharmony_ci
33298c2ecf20Sopenharmony_ci	case GAUDI_QUEUE_ID_TPC_6_0:
33308c2ecf20Sopenharmony_ci		db_reg_offset = mmTPC6_QM_PQ_PI_0;
33318c2ecf20Sopenharmony_ci		break;
33328c2ecf20Sopenharmony_ci
33338c2ecf20Sopenharmony_ci	case GAUDI_QUEUE_ID_TPC_6_1:
33348c2ecf20Sopenharmony_ci		db_reg_offset = mmTPC6_QM_PQ_PI_1;
33358c2ecf20Sopenharmony_ci		break;
33368c2ecf20Sopenharmony_ci
33378c2ecf20Sopenharmony_ci	case GAUDI_QUEUE_ID_TPC_6_2:
33388c2ecf20Sopenharmony_ci		db_reg_offset = mmTPC6_QM_PQ_PI_2;
33398c2ecf20Sopenharmony_ci		break;
33408c2ecf20Sopenharmony_ci
33418c2ecf20Sopenharmony_ci	case GAUDI_QUEUE_ID_TPC_6_3:
33428c2ecf20Sopenharmony_ci		db_reg_offset = mmTPC6_QM_PQ_PI_3;
33438c2ecf20Sopenharmony_ci		break;
33448c2ecf20Sopenharmony_ci
33458c2ecf20Sopenharmony_ci	case GAUDI_QUEUE_ID_TPC_7_0:
33468c2ecf20Sopenharmony_ci		db_reg_offset = mmTPC7_QM_PQ_PI_0;
33478c2ecf20Sopenharmony_ci		break;
33488c2ecf20Sopenharmony_ci
33498c2ecf20Sopenharmony_ci	case GAUDI_QUEUE_ID_TPC_7_1:
33508c2ecf20Sopenharmony_ci		db_reg_offset = mmTPC7_QM_PQ_PI_1;
33518c2ecf20Sopenharmony_ci		break;
33528c2ecf20Sopenharmony_ci
33538c2ecf20Sopenharmony_ci	case GAUDI_QUEUE_ID_TPC_7_2:
33548c2ecf20Sopenharmony_ci		db_reg_offset = mmTPC7_QM_PQ_PI_2;
33558c2ecf20Sopenharmony_ci		break;
33568c2ecf20Sopenharmony_ci
33578c2ecf20Sopenharmony_ci	case GAUDI_QUEUE_ID_TPC_7_3:
33588c2ecf20Sopenharmony_ci		db_reg_offset = mmTPC7_QM_PQ_PI_3;
33598c2ecf20Sopenharmony_ci		break;
33608c2ecf20Sopenharmony_ci
33618c2ecf20Sopenharmony_ci	default:
33628c2ecf20Sopenharmony_ci		invalid_queue = true;
33638c2ecf20Sopenharmony_ci	}
33648c2ecf20Sopenharmony_ci
33658c2ecf20Sopenharmony_ci	if (invalid_queue) {
33668c2ecf20Sopenharmony_ci		/* Should never get here */
33678c2ecf20Sopenharmony_ci		dev_err(hdev->dev, "h/w queue %d is invalid. Can't set pi\n",
33688c2ecf20Sopenharmony_ci			hw_queue_id);
33698c2ecf20Sopenharmony_ci		return;
33708c2ecf20Sopenharmony_ci	}
33718c2ecf20Sopenharmony_ci
33728c2ecf20Sopenharmony_ci	db_value = pi;
33738c2ecf20Sopenharmony_ci
33748c2ecf20Sopenharmony_ci	/* ring the doorbell */
33758c2ecf20Sopenharmony_ci	WREG32(db_reg_offset, db_value);
33768c2ecf20Sopenharmony_ci
33778c2ecf20Sopenharmony_ci	if (hw_queue_id == GAUDI_QUEUE_ID_CPU_PQ)
33788c2ecf20Sopenharmony_ci		WREG32(mmGIC_DISTRIBUTOR__5_GICD_SETSPI_NSR,
33798c2ecf20Sopenharmony_ci				GAUDI_EVENT_PI_UPDATE);
33808c2ecf20Sopenharmony_ci}
33818c2ecf20Sopenharmony_ci
33828c2ecf20Sopenharmony_cistatic void gaudi_pqe_write(struct hl_device *hdev, __le64 *pqe,
33838c2ecf20Sopenharmony_ci				struct hl_bd *bd)
33848c2ecf20Sopenharmony_ci{
33858c2ecf20Sopenharmony_ci	__le64 *pbd = (__le64 *) bd;
33868c2ecf20Sopenharmony_ci
33878c2ecf20Sopenharmony_ci	/* The QMANs are on the host memory so a simple copy suffice */
33888c2ecf20Sopenharmony_ci	pqe[0] = pbd[0];
33898c2ecf20Sopenharmony_ci	pqe[1] = pbd[1];
33908c2ecf20Sopenharmony_ci}
33918c2ecf20Sopenharmony_ci
33928c2ecf20Sopenharmony_cistatic void *gaudi_dma_alloc_coherent(struct hl_device *hdev, size_t size,
33938c2ecf20Sopenharmony_ci					dma_addr_t *dma_handle, gfp_t flags)
33948c2ecf20Sopenharmony_ci{
33958c2ecf20Sopenharmony_ci	void *kernel_addr = dma_alloc_coherent(&hdev->pdev->dev, size,
33968c2ecf20Sopenharmony_ci						dma_handle, flags);
33978c2ecf20Sopenharmony_ci
33988c2ecf20Sopenharmony_ci	/* Shift to the device's base physical address of host memory */
33998c2ecf20Sopenharmony_ci	if (kernel_addr)
34008c2ecf20Sopenharmony_ci		*dma_handle += HOST_PHYS_BASE;
34018c2ecf20Sopenharmony_ci
34028c2ecf20Sopenharmony_ci	return kernel_addr;
34038c2ecf20Sopenharmony_ci}
34048c2ecf20Sopenharmony_ci
34058c2ecf20Sopenharmony_cistatic void gaudi_dma_free_coherent(struct hl_device *hdev, size_t size,
34068c2ecf20Sopenharmony_ci		void *cpu_addr, dma_addr_t dma_handle)
34078c2ecf20Sopenharmony_ci{
34088c2ecf20Sopenharmony_ci	/* Cancel the device's base physical address of host memory */
34098c2ecf20Sopenharmony_ci	dma_addr_t fixed_dma_handle = dma_handle - HOST_PHYS_BASE;
34108c2ecf20Sopenharmony_ci
34118c2ecf20Sopenharmony_ci	dma_free_coherent(&hdev->pdev->dev, size, cpu_addr, fixed_dma_handle);
34128c2ecf20Sopenharmony_ci}
34138c2ecf20Sopenharmony_ci
34148c2ecf20Sopenharmony_cistatic void *gaudi_get_int_queue_base(struct hl_device *hdev,
34158c2ecf20Sopenharmony_ci				u32 queue_id, dma_addr_t *dma_handle,
34168c2ecf20Sopenharmony_ci				u16 *queue_len)
34178c2ecf20Sopenharmony_ci{
34188c2ecf20Sopenharmony_ci	struct gaudi_device *gaudi = hdev->asic_specific;
34198c2ecf20Sopenharmony_ci	struct gaudi_internal_qman_info *q;
34208c2ecf20Sopenharmony_ci
34218c2ecf20Sopenharmony_ci	if (queue_id >= GAUDI_QUEUE_ID_SIZE ||
34228c2ecf20Sopenharmony_ci			gaudi_queue_type[queue_id] != QUEUE_TYPE_INT) {
34238c2ecf20Sopenharmony_ci		dev_err(hdev->dev, "Got invalid queue id %d\n", queue_id);
34248c2ecf20Sopenharmony_ci		return NULL;
34258c2ecf20Sopenharmony_ci	}
34268c2ecf20Sopenharmony_ci
34278c2ecf20Sopenharmony_ci	q = &gaudi->internal_qmans[queue_id];
34288c2ecf20Sopenharmony_ci	*dma_handle = q->pq_dma_addr;
34298c2ecf20Sopenharmony_ci	*queue_len = q->pq_size / QMAN_PQ_ENTRY_SIZE;
34308c2ecf20Sopenharmony_ci
34318c2ecf20Sopenharmony_ci	return q->pq_kernel_addr;
34328c2ecf20Sopenharmony_ci}
34338c2ecf20Sopenharmony_ci
34348c2ecf20Sopenharmony_cistatic int gaudi_send_cpu_message(struct hl_device *hdev, u32 *msg,
34358c2ecf20Sopenharmony_ci				u16 len, u32 timeout, long *result)
34368c2ecf20Sopenharmony_ci{
34378c2ecf20Sopenharmony_ci	struct gaudi_device *gaudi = hdev->asic_specific;
34388c2ecf20Sopenharmony_ci
34398c2ecf20Sopenharmony_ci	if (!(gaudi->hw_cap_initialized & HW_CAP_CPU_Q)) {
34408c2ecf20Sopenharmony_ci		if (result)
34418c2ecf20Sopenharmony_ci			*result = 0;
34428c2ecf20Sopenharmony_ci		return 0;
34438c2ecf20Sopenharmony_ci	}
34448c2ecf20Sopenharmony_ci
34458c2ecf20Sopenharmony_ci	if (!timeout)
34468c2ecf20Sopenharmony_ci		timeout = GAUDI_MSG_TO_CPU_TIMEOUT_USEC;
34478c2ecf20Sopenharmony_ci
34488c2ecf20Sopenharmony_ci	return hl_fw_send_cpu_message(hdev, GAUDI_QUEUE_ID_CPU_PQ, msg, len,
34498c2ecf20Sopenharmony_ci						timeout, result);
34508c2ecf20Sopenharmony_ci}
34518c2ecf20Sopenharmony_ci
34528c2ecf20Sopenharmony_cistatic int gaudi_test_queue(struct hl_device *hdev, u32 hw_queue_id)
34538c2ecf20Sopenharmony_ci{
34548c2ecf20Sopenharmony_ci	struct packet_msg_prot *fence_pkt;
34558c2ecf20Sopenharmony_ci	dma_addr_t pkt_dma_addr;
34568c2ecf20Sopenharmony_ci	u32 fence_val, tmp, timeout_usec;
34578c2ecf20Sopenharmony_ci	dma_addr_t fence_dma_addr;
34588c2ecf20Sopenharmony_ci	u32 *fence_ptr;
34598c2ecf20Sopenharmony_ci	int rc;
34608c2ecf20Sopenharmony_ci
34618c2ecf20Sopenharmony_ci	if (hdev->pldm)
34628c2ecf20Sopenharmony_ci		timeout_usec = GAUDI_PLDM_TEST_QUEUE_WAIT_USEC;
34638c2ecf20Sopenharmony_ci	else
34648c2ecf20Sopenharmony_ci		timeout_usec = GAUDI_TEST_QUEUE_WAIT_USEC;
34658c2ecf20Sopenharmony_ci
34668c2ecf20Sopenharmony_ci	fence_val = GAUDI_QMAN0_FENCE_VAL;
34678c2ecf20Sopenharmony_ci
34688c2ecf20Sopenharmony_ci	fence_ptr = hdev->asic_funcs->asic_dma_pool_zalloc(hdev, 4, GFP_KERNEL,
34698c2ecf20Sopenharmony_ci							&fence_dma_addr);
34708c2ecf20Sopenharmony_ci	if (!fence_ptr) {
34718c2ecf20Sopenharmony_ci		dev_err(hdev->dev,
34728c2ecf20Sopenharmony_ci			"Failed to allocate memory for H/W queue %d testing\n",
34738c2ecf20Sopenharmony_ci			hw_queue_id);
34748c2ecf20Sopenharmony_ci		return -ENOMEM;
34758c2ecf20Sopenharmony_ci	}
34768c2ecf20Sopenharmony_ci
34778c2ecf20Sopenharmony_ci	*fence_ptr = 0;
34788c2ecf20Sopenharmony_ci
34798c2ecf20Sopenharmony_ci	fence_pkt = hdev->asic_funcs->asic_dma_pool_zalloc(hdev,
34808c2ecf20Sopenharmony_ci					sizeof(struct packet_msg_prot),
34818c2ecf20Sopenharmony_ci					GFP_KERNEL, &pkt_dma_addr);
34828c2ecf20Sopenharmony_ci	if (!fence_pkt) {
34838c2ecf20Sopenharmony_ci		dev_err(hdev->dev,
34848c2ecf20Sopenharmony_ci			"Failed to allocate packet for H/W queue %d testing\n",
34858c2ecf20Sopenharmony_ci			hw_queue_id);
34868c2ecf20Sopenharmony_ci		rc = -ENOMEM;
34878c2ecf20Sopenharmony_ci		goto free_fence_ptr;
34888c2ecf20Sopenharmony_ci	}
34898c2ecf20Sopenharmony_ci
34908c2ecf20Sopenharmony_ci	tmp = FIELD_PREP(GAUDI_PKT_CTL_OPCODE_MASK, PACKET_MSG_PROT);
34918c2ecf20Sopenharmony_ci	tmp |= FIELD_PREP(GAUDI_PKT_CTL_EB_MASK, 1);
34928c2ecf20Sopenharmony_ci	tmp |= FIELD_PREP(GAUDI_PKT_CTL_MB_MASK, 1);
34938c2ecf20Sopenharmony_ci
34948c2ecf20Sopenharmony_ci	fence_pkt->ctl = cpu_to_le32(tmp);
34958c2ecf20Sopenharmony_ci	fence_pkt->value = cpu_to_le32(fence_val);
34968c2ecf20Sopenharmony_ci	fence_pkt->addr = cpu_to_le64(fence_dma_addr);
34978c2ecf20Sopenharmony_ci
34988c2ecf20Sopenharmony_ci	rc = hl_hw_queue_send_cb_no_cmpl(hdev, hw_queue_id,
34998c2ecf20Sopenharmony_ci					sizeof(struct packet_msg_prot),
35008c2ecf20Sopenharmony_ci					pkt_dma_addr);
35018c2ecf20Sopenharmony_ci	if (rc) {
35028c2ecf20Sopenharmony_ci		dev_err(hdev->dev,
35038c2ecf20Sopenharmony_ci			"Failed to send fence packet to H/W queue %d\n",
35048c2ecf20Sopenharmony_ci			hw_queue_id);
35058c2ecf20Sopenharmony_ci		goto free_pkt;
35068c2ecf20Sopenharmony_ci	}
35078c2ecf20Sopenharmony_ci
35088c2ecf20Sopenharmony_ci	rc = hl_poll_timeout_memory(hdev, fence_ptr, tmp, (tmp == fence_val),
35098c2ecf20Sopenharmony_ci					1000, timeout_usec, true);
35108c2ecf20Sopenharmony_ci
35118c2ecf20Sopenharmony_ci	hl_hw_queue_inc_ci_kernel(hdev, hw_queue_id);
35128c2ecf20Sopenharmony_ci
35138c2ecf20Sopenharmony_ci	if (rc == -ETIMEDOUT) {
35148c2ecf20Sopenharmony_ci		dev_err(hdev->dev,
35158c2ecf20Sopenharmony_ci			"H/W queue %d test failed (scratch(0x%08llX) == 0x%08X)\n",
35168c2ecf20Sopenharmony_ci			hw_queue_id, (unsigned long long) fence_dma_addr, tmp);
35178c2ecf20Sopenharmony_ci		rc = -EIO;
35188c2ecf20Sopenharmony_ci	}
35198c2ecf20Sopenharmony_ci
35208c2ecf20Sopenharmony_cifree_pkt:
35218c2ecf20Sopenharmony_ci	hdev->asic_funcs->asic_dma_pool_free(hdev, (void *) fence_pkt,
35228c2ecf20Sopenharmony_ci					pkt_dma_addr);
35238c2ecf20Sopenharmony_cifree_fence_ptr:
35248c2ecf20Sopenharmony_ci	hdev->asic_funcs->asic_dma_pool_free(hdev, (void *) fence_ptr,
35258c2ecf20Sopenharmony_ci					fence_dma_addr);
35268c2ecf20Sopenharmony_ci	return rc;
35278c2ecf20Sopenharmony_ci}
35288c2ecf20Sopenharmony_ci
35298c2ecf20Sopenharmony_cistatic int gaudi_test_cpu_queue(struct hl_device *hdev)
35308c2ecf20Sopenharmony_ci{
35318c2ecf20Sopenharmony_ci	struct gaudi_device *gaudi = hdev->asic_specific;
35328c2ecf20Sopenharmony_ci
35338c2ecf20Sopenharmony_ci	/*
35348c2ecf20Sopenharmony_ci	 * check capability here as send_cpu_message() won't update the result
35358c2ecf20Sopenharmony_ci	 * value if no capability
35368c2ecf20Sopenharmony_ci	 */
35378c2ecf20Sopenharmony_ci	if (!(gaudi->hw_cap_initialized & HW_CAP_CPU_Q))
35388c2ecf20Sopenharmony_ci		return 0;
35398c2ecf20Sopenharmony_ci
35408c2ecf20Sopenharmony_ci	return hl_fw_test_cpu_queue(hdev);
35418c2ecf20Sopenharmony_ci}
35428c2ecf20Sopenharmony_ci
35438c2ecf20Sopenharmony_cistatic int gaudi_test_queues(struct hl_device *hdev)
35448c2ecf20Sopenharmony_ci{
35458c2ecf20Sopenharmony_ci	int i, rc, ret_val = 0;
35468c2ecf20Sopenharmony_ci
35478c2ecf20Sopenharmony_ci	for (i = 0 ; i < hdev->asic_prop.max_queues ; i++) {
35488c2ecf20Sopenharmony_ci		if (hdev->asic_prop.hw_queues_props[i].type == QUEUE_TYPE_EXT) {
35498c2ecf20Sopenharmony_ci			rc = gaudi_test_queue(hdev, i);
35508c2ecf20Sopenharmony_ci			if (rc)
35518c2ecf20Sopenharmony_ci				ret_val = -EINVAL;
35528c2ecf20Sopenharmony_ci		}
35538c2ecf20Sopenharmony_ci	}
35548c2ecf20Sopenharmony_ci
35558c2ecf20Sopenharmony_ci	rc = gaudi_test_cpu_queue(hdev);
35568c2ecf20Sopenharmony_ci	if (rc)
35578c2ecf20Sopenharmony_ci		ret_val = -EINVAL;
35588c2ecf20Sopenharmony_ci
35598c2ecf20Sopenharmony_ci	return ret_val;
35608c2ecf20Sopenharmony_ci}
35618c2ecf20Sopenharmony_ci
35628c2ecf20Sopenharmony_cistatic void *gaudi_dma_pool_zalloc(struct hl_device *hdev, size_t size,
35638c2ecf20Sopenharmony_ci		gfp_t mem_flags, dma_addr_t *dma_handle)
35648c2ecf20Sopenharmony_ci{
35658c2ecf20Sopenharmony_ci	void *kernel_addr;
35668c2ecf20Sopenharmony_ci
35678c2ecf20Sopenharmony_ci	if (size > GAUDI_DMA_POOL_BLK_SIZE)
35688c2ecf20Sopenharmony_ci		return NULL;
35698c2ecf20Sopenharmony_ci
35708c2ecf20Sopenharmony_ci	kernel_addr = dma_pool_zalloc(hdev->dma_pool, mem_flags, dma_handle);
35718c2ecf20Sopenharmony_ci
35728c2ecf20Sopenharmony_ci	/* Shift to the device's base physical address of host memory */
35738c2ecf20Sopenharmony_ci	if (kernel_addr)
35748c2ecf20Sopenharmony_ci		*dma_handle += HOST_PHYS_BASE;
35758c2ecf20Sopenharmony_ci
35768c2ecf20Sopenharmony_ci	return kernel_addr;
35778c2ecf20Sopenharmony_ci}
35788c2ecf20Sopenharmony_ci
35798c2ecf20Sopenharmony_cistatic void gaudi_dma_pool_free(struct hl_device *hdev, void *vaddr,
35808c2ecf20Sopenharmony_ci			dma_addr_t dma_addr)
35818c2ecf20Sopenharmony_ci{
35828c2ecf20Sopenharmony_ci	/* Cancel the device's base physical address of host memory */
35838c2ecf20Sopenharmony_ci	dma_addr_t fixed_dma_addr = dma_addr - HOST_PHYS_BASE;
35848c2ecf20Sopenharmony_ci
35858c2ecf20Sopenharmony_ci	dma_pool_free(hdev->dma_pool, vaddr, fixed_dma_addr);
35868c2ecf20Sopenharmony_ci}
35878c2ecf20Sopenharmony_ci
35888c2ecf20Sopenharmony_cistatic void *gaudi_cpu_accessible_dma_pool_alloc(struct hl_device *hdev,
35898c2ecf20Sopenharmony_ci					size_t size, dma_addr_t *dma_handle)
35908c2ecf20Sopenharmony_ci{
35918c2ecf20Sopenharmony_ci	return hl_fw_cpu_accessible_dma_pool_alloc(hdev, size, dma_handle);
35928c2ecf20Sopenharmony_ci}
35938c2ecf20Sopenharmony_ci
35948c2ecf20Sopenharmony_cistatic void gaudi_cpu_accessible_dma_pool_free(struct hl_device *hdev,
35958c2ecf20Sopenharmony_ci						size_t size, void *vaddr)
35968c2ecf20Sopenharmony_ci{
35978c2ecf20Sopenharmony_ci	hl_fw_cpu_accessible_dma_pool_free(hdev, size, vaddr);
35988c2ecf20Sopenharmony_ci}
35998c2ecf20Sopenharmony_ci
36008c2ecf20Sopenharmony_cistatic int gaudi_dma_map_sg(struct hl_device *hdev, struct scatterlist *sgl,
36018c2ecf20Sopenharmony_ci			int nents, enum dma_data_direction dir)
36028c2ecf20Sopenharmony_ci{
36038c2ecf20Sopenharmony_ci	struct scatterlist *sg;
36048c2ecf20Sopenharmony_ci	int i;
36058c2ecf20Sopenharmony_ci
36068c2ecf20Sopenharmony_ci	if (!dma_map_sg(&hdev->pdev->dev, sgl, nents, dir))
36078c2ecf20Sopenharmony_ci		return -ENOMEM;
36088c2ecf20Sopenharmony_ci
36098c2ecf20Sopenharmony_ci	/* Shift to the device's base physical address of host memory */
36108c2ecf20Sopenharmony_ci	for_each_sg(sgl, sg, nents, i)
36118c2ecf20Sopenharmony_ci		sg->dma_address += HOST_PHYS_BASE;
36128c2ecf20Sopenharmony_ci
36138c2ecf20Sopenharmony_ci	return 0;
36148c2ecf20Sopenharmony_ci}
36158c2ecf20Sopenharmony_ci
36168c2ecf20Sopenharmony_cistatic void gaudi_dma_unmap_sg(struct hl_device *hdev, struct scatterlist *sgl,
36178c2ecf20Sopenharmony_ci			int nents, enum dma_data_direction dir)
36188c2ecf20Sopenharmony_ci{
36198c2ecf20Sopenharmony_ci	struct scatterlist *sg;
36208c2ecf20Sopenharmony_ci	int i;
36218c2ecf20Sopenharmony_ci
36228c2ecf20Sopenharmony_ci	/* Cancel the device's base physical address of host memory */
36238c2ecf20Sopenharmony_ci	for_each_sg(sgl, sg, nents, i)
36248c2ecf20Sopenharmony_ci		sg->dma_address -= HOST_PHYS_BASE;
36258c2ecf20Sopenharmony_ci
36268c2ecf20Sopenharmony_ci	dma_unmap_sg(&hdev->pdev->dev, sgl, nents, dir);
36278c2ecf20Sopenharmony_ci}
36288c2ecf20Sopenharmony_ci
36298c2ecf20Sopenharmony_cistatic u32 gaudi_get_dma_desc_list_size(struct hl_device *hdev,
36308c2ecf20Sopenharmony_ci					struct sg_table *sgt)
36318c2ecf20Sopenharmony_ci{
36328c2ecf20Sopenharmony_ci	struct scatterlist *sg, *sg_next_iter;
36338c2ecf20Sopenharmony_ci	u32 count, dma_desc_cnt;
36348c2ecf20Sopenharmony_ci	u64 len, len_next;
36358c2ecf20Sopenharmony_ci	dma_addr_t addr, addr_next;
36368c2ecf20Sopenharmony_ci
36378c2ecf20Sopenharmony_ci	dma_desc_cnt = 0;
36388c2ecf20Sopenharmony_ci
36398c2ecf20Sopenharmony_ci	for_each_sg(sgt->sgl, sg, sgt->nents, count) {
36408c2ecf20Sopenharmony_ci
36418c2ecf20Sopenharmony_ci		len = sg_dma_len(sg);
36428c2ecf20Sopenharmony_ci		addr = sg_dma_address(sg);
36438c2ecf20Sopenharmony_ci
36448c2ecf20Sopenharmony_ci		if (len == 0)
36458c2ecf20Sopenharmony_ci			break;
36468c2ecf20Sopenharmony_ci
36478c2ecf20Sopenharmony_ci		while ((count + 1) < sgt->nents) {
36488c2ecf20Sopenharmony_ci			sg_next_iter = sg_next(sg);
36498c2ecf20Sopenharmony_ci			len_next = sg_dma_len(sg_next_iter);
36508c2ecf20Sopenharmony_ci			addr_next = sg_dma_address(sg_next_iter);
36518c2ecf20Sopenharmony_ci
36528c2ecf20Sopenharmony_ci			if (len_next == 0)
36538c2ecf20Sopenharmony_ci				break;
36548c2ecf20Sopenharmony_ci
36558c2ecf20Sopenharmony_ci			if ((addr + len == addr_next) &&
36568c2ecf20Sopenharmony_ci				(len + len_next <= DMA_MAX_TRANSFER_SIZE)) {
36578c2ecf20Sopenharmony_ci				len += len_next;
36588c2ecf20Sopenharmony_ci				count++;
36598c2ecf20Sopenharmony_ci				sg = sg_next_iter;
36608c2ecf20Sopenharmony_ci			} else {
36618c2ecf20Sopenharmony_ci				break;
36628c2ecf20Sopenharmony_ci			}
36638c2ecf20Sopenharmony_ci		}
36648c2ecf20Sopenharmony_ci
36658c2ecf20Sopenharmony_ci		dma_desc_cnt++;
36668c2ecf20Sopenharmony_ci	}
36678c2ecf20Sopenharmony_ci
36688c2ecf20Sopenharmony_ci	return dma_desc_cnt * sizeof(struct packet_lin_dma);
36698c2ecf20Sopenharmony_ci}
36708c2ecf20Sopenharmony_ci
36718c2ecf20Sopenharmony_cistatic int gaudi_pin_memory_before_cs(struct hl_device *hdev,
36728c2ecf20Sopenharmony_ci				struct hl_cs_parser *parser,
36738c2ecf20Sopenharmony_ci				struct packet_lin_dma *user_dma_pkt,
36748c2ecf20Sopenharmony_ci				u64 addr, enum dma_data_direction dir)
36758c2ecf20Sopenharmony_ci{
36768c2ecf20Sopenharmony_ci	struct hl_userptr *userptr;
36778c2ecf20Sopenharmony_ci	int rc;
36788c2ecf20Sopenharmony_ci
36798c2ecf20Sopenharmony_ci	if (hl_userptr_is_pinned(hdev, addr, le32_to_cpu(user_dma_pkt->tsize),
36808c2ecf20Sopenharmony_ci			parser->job_userptr_list, &userptr))
36818c2ecf20Sopenharmony_ci		goto already_pinned;
36828c2ecf20Sopenharmony_ci
36838c2ecf20Sopenharmony_ci	userptr = kzalloc(sizeof(*userptr), GFP_ATOMIC);
36848c2ecf20Sopenharmony_ci	if (!userptr)
36858c2ecf20Sopenharmony_ci		return -ENOMEM;
36868c2ecf20Sopenharmony_ci
36878c2ecf20Sopenharmony_ci	rc = hl_pin_host_memory(hdev, addr, le32_to_cpu(user_dma_pkt->tsize),
36888c2ecf20Sopenharmony_ci				userptr);
36898c2ecf20Sopenharmony_ci	if (rc)
36908c2ecf20Sopenharmony_ci		goto free_userptr;
36918c2ecf20Sopenharmony_ci
36928c2ecf20Sopenharmony_ci	list_add_tail(&userptr->job_node, parser->job_userptr_list);
36938c2ecf20Sopenharmony_ci
36948c2ecf20Sopenharmony_ci	rc = hdev->asic_funcs->asic_dma_map_sg(hdev, userptr->sgt->sgl,
36958c2ecf20Sopenharmony_ci					userptr->sgt->nents, dir);
36968c2ecf20Sopenharmony_ci	if (rc) {
36978c2ecf20Sopenharmony_ci		dev_err(hdev->dev, "failed to map sgt with DMA region\n");
36988c2ecf20Sopenharmony_ci		goto unpin_memory;
36998c2ecf20Sopenharmony_ci	}
37008c2ecf20Sopenharmony_ci
37018c2ecf20Sopenharmony_ci	userptr->dma_mapped = true;
37028c2ecf20Sopenharmony_ci	userptr->dir = dir;
37038c2ecf20Sopenharmony_ci
37048c2ecf20Sopenharmony_cialready_pinned:
37058c2ecf20Sopenharmony_ci	parser->patched_cb_size +=
37068c2ecf20Sopenharmony_ci			gaudi_get_dma_desc_list_size(hdev, userptr->sgt);
37078c2ecf20Sopenharmony_ci
37088c2ecf20Sopenharmony_ci	return 0;
37098c2ecf20Sopenharmony_ci
37108c2ecf20Sopenharmony_ciunpin_memory:
37118c2ecf20Sopenharmony_ci	list_del(&userptr->job_node);
37128c2ecf20Sopenharmony_ci	hl_unpin_host_memory(hdev, userptr);
37138c2ecf20Sopenharmony_cifree_userptr:
37148c2ecf20Sopenharmony_ci	kfree(userptr);
37158c2ecf20Sopenharmony_ci	return rc;
37168c2ecf20Sopenharmony_ci}
37178c2ecf20Sopenharmony_ci
37188c2ecf20Sopenharmony_cistatic int gaudi_validate_dma_pkt_host(struct hl_device *hdev,
37198c2ecf20Sopenharmony_ci				struct hl_cs_parser *parser,
37208c2ecf20Sopenharmony_ci				struct packet_lin_dma *user_dma_pkt,
37218c2ecf20Sopenharmony_ci				bool src_in_host)
37228c2ecf20Sopenharmony_ci{
37238c2ecf20Sopenharmony_ci	enum dma_data_direction dir;
37248c2ecf20Sopenharmony_ci	bool skip_host_mem_pin = false, user_memset;
37258c2ecf20Sopenharmony_ci	u64 addr;
37268c2ecf20Sopenharmony_ci	int rc = 0;
37278c2ecf20Sopenharmony_ci
37288c2ecf20Sopenharmony_ci	user_memset = (le32_to_cpu(user_dma_pkt->ctl) &
37298c2ecf20Sopenharmony_ci			GAUDI_PKT_LIN_DMA_CTL_MEMSET_MASK) >>
37308c2ecf20Sopenharmony_ci			GAUDI_PKT_LIN_DMA_CTL_MEMSET_SHIFT;
37318c2ecf20Sopenharmony_ci
37328c2ecf20Sopenharmony_ci	if (src_in_host) {
37338c2ecf20Sopenharmony_ci		if (user_memset)
37348c2ecf20Sopenharmony_ci			skip_host_mem_pin = true;
37358c2ecf20Sopenharmony_ci
37368c2ecf20Sopenharmony_ci		dev_dbg(hdev->dev, "DMA direction is HOST --> DEVICE\n");
37378c2ecf20Sopenharmony_ci		dir = DMA_TO_DEVICE;
37388c2ecf20Sopenharmony_ci		addr = le64_to_cpu(user_dma_pkt->src_addr);
37398c2ecf20Sopenharmony_ci	} else {
37408c2ecf20Sopenharmony_ci		dev_dbg(hdev->dev, "DMA direction is DEVICE --> HOST\n");
37418c2ecf20Sopenharmony_ci		dir = DMA_FROM_DEVICE;
37428c2ecf20Sopenharmony_ci		addr = (le64_to_cpu(user_dma_pkt->dst_addr) &
37438c2ecf20Sopenharmony_ci				GAUDI_PKT_LIN_DMA_DST_ADDR_MASK) >>
37448c2ecf20Sopenharmony_ci				GAUDI_PKT_LIN_DMA_DST_ADDR_SHIFT;
37458c2ecf20Sopenharmony_ci	}
37468c2ecf20Sopenharmony_ci
37478c2ecf20Sopenharmony_ci	if (skip_host_mem_pin)
37488c2ecf20Sopenharmony_ci		parser->patched_cb_size += sizeof(*user_dma_pkt);
37498c2ecf20Sopenharmony_ci	else
37508c2ecf20Sopenharmony_ci		rc = gaudi_pin_memory_before_cs(hdev, parser, user_dma_pkt,
37518c2ecf20Sopenharmony_ci						addr, dir);
37528c2ecf20Sopenharmony_ci
37538c2ecf20Sopenharmony_ci	return rc;
37548c2ecf20Sopenharmony_ci}
37558c2ecf20Sopenharmony_ci
37568c2ecf20Sopenharmony_cistatic int gaudi_validate_dma_pkt_no_mmu(struct hl_device *hdev,
37578c2ecf20Sopenharmony_ci				struct hl_cs_parser *parser,
37588c2ecf20Sopenharmony_ci				struct packet_lin_dma *user_dma_pkt)
37598c2ecf20Sopenharmony_ci{
37608c2ecf20Sopenharmony_ci	bool src_in_host = false;
37618c2ecf20Sopenharmony_ci	u64 dst_addr = (le64_to_cpu(user_dma_pkt->dst_addr) &
37628c2ecf20Sopenharmony_ci			GAUDI_PKT_LIN_DMA_DST_ADDR_MASK) >>
37638c2ecf20Sopenharmony_ci			GAUDI_PKT_LIN_DMA_DST_ADDR_SHIFT;
37648c2ecf20Sopenharmony_ci
37658c2ecf20Sopenharmony_ci	dev_dbg(hdev->dev, "DMA packet details:\n");
37668c2ecf20Sopenharmony_ci	dev_dbg(hdev->dev, "source == 0x%llx\n",
37678c2ecf20Sopenharmony_ci				le64_to_cpu(user_dma_pkt->src_addr));
37688c2ecf20Sopenharmony_ci	dev_dbg(hdev->dev, "destination == 0x%llx\n", dst_addr);
37698c2ecf20Sopenharmony_ci	dev_dbg(hdev->dev, "size == %u\n", le32_to_cpu(user_dma_pkt->tsize));
37708c2ecf20Sopenharmony_ci
37718c2ecf20Sopenharmony_ci	/*
37728c2ecf20Sopenharmony_ci	 * Special handling for DMA with size 0. Bypass all validations
37738c2ecf20Sopenharmony_ci	 * because no transactions will be done except for WR_COMP, which
37748c2ecf20Sopenharmony_ci	 * is not a security issue
37758c2ecf20Sopenharmony_ci	 */
37768c2ecf20Sopenharmony_ci	if (!le32_to_cpu(user_dma_pkt->tsize)) {
37778c2ecf20Sopenharmony_ci		parser->patched_cb_size += sizeof(*user_dma_pkt);
37788c2ecf20Sopenharmony_ci		return 0;
37798c2ecf20Sopenharmony_ci	}
37808c2ecf20Sopenharmony_ci
37818c2ecf20Sopenharmony_ci	if (parser->hw_queue_id <= GAUDI_QUEUE_ID_DMA_0_3)
37828c2ecf20Sopenharmony_ci		src_in_host = true;
37838c2ecf20Sopenharmony_ci
37848c2ecf20Sopenharmony_ci	return gaudi_validate_dma_pkt_host(hdev, parser, user_dma_pkt,
37858c2ecf20Sopenharmony_ci						src_in_host);
37868c2ecf20Sopenharmony_ci}
37878c2ecf20Sopenharmony_ci
37888c2ecf20Sopenharmony_cistatic int gaudi_validate_load_and_exe_pkt(struct hl_device *hdev,
37898c2ecf20Sopenharmony_ci					struct hl_cs_parser *parser,
37908c2ecf20Sopenharmony_ci					struct packet_load_and_exe *user_pkt)
37918c2ecf20Sopenharmony_ci{
37928c2ecf20Sopenharmony_ci	u32 cfg;
37938c2ecf20Sopenharmony_ci
37948c2ecf20Sopenharmony_ci	cfg = le32_to_cpu(user_pkt->cfg);
37958c2ecf20Sopenharmony_ci
37968c2ecf20Sopenharmony_ci	if (cfg & GAUDI_PKT_LOAD_AND_EXE_CFG_DST_MASK) {
37978c2ecf20Sopenharmony_ci		dev_err(hdev->dev,
37988c2ecf20Sopenharmony_ci			"User not allowed to use Load and Execute\n");
37998c2ecf20Sopenharmony_ci		return -EPERM;
38008c2ecf20Sopenharmony_ci	}
38018c2ecf20Sopenharmony_ci
38028c2ecf20Sopenharmony_ci	parser->patched_cb_size += sizeof(struct packet_load_and_exe);
38038c2ecf20Sopenharmony_ci
38048c2ecf20Sopenharmony_ci	return 0;
38058c2ecf20Sopenharmony_ci}
38068c2ecf20Sopenharmony_ci
38078c2ecf20Sopenharmony_cistatic int gaudi_validate_cb(struct hl_device *hdev,
38088c2ecf20Sopenharmony_ci			struct hl_cs_parser *parser, bool is_mmu)
38098c2ecf20Sopenharmony_ci{
38108c2ecf20Sopenharmony_ci	u32 cb_parsed_length = 0;
38118c2ecf20Sopenharmony_ci	int rc = 0;
38128c2ecf20Sopenharmony_ci
38138c2ecf20Sopenharmony_ci	parser->patched_cb_size = 0;
38148c2ecf20Sopenharmony_ci
38158c2ecf20Sopenharmony_ci	/* cb_user_size is more than 0 so loop will always be executed */
38168c2ecf20Sopenharmony_ci	while (cb_parsed_length < parser->user_cb_size) {
38178c2ecf20Sopenharmony_ci		enum packet_id pkt_id;
38188c2ecf20Sopenharmony_ci		u16 pkt_size;
38198c2ecf20Sopenharmony_ci		struct gaudi_packet *user_pkt;
38208c2ecf20Sopenharmony_ci
38218c2ecf20Sopenharmony_ci		user_pkt = parser->user_cb->kernel_address + cb_parsed_length;
38228c2ecf20Sopenharmony_ci
38238c2ecf20Sopenharmony_ci		pkt_id = (enum packet_id) (
38248c2ecf20Sopenharmony_ci				(le64_to_cpu(user_pkt->header) &
38258c2ecf20Sopenharmony_ci				PACKET_HEADER_PACKET_ID_MASK) >>
38268c2ecf20Sopenharmony_ci					PACKET_HEADER_PACKET_ID_SHIFT);
38278c2ecf20Sopenharmony_ci
38288c2ecf20Sopenharmony_ci		if (!validate_packet_id(pkt_id)) {
38298c2ecf20Sopenharmony_ci			dev_err(hdev->dev, "Invalid packet id %u\n", pkt_id);
38308c2ecf20Sopenharmony_ci			rc = -EINVAL;
38318c2ecf20Sopenharmony_ci			break;
38328c2ecf20Sopenharmony_ci		}
38338c2ecf20Sopenharmony_ci
38348c2ecf20Sopenharmony_ci		pkt_size = gaudi_packet_sizes[pkt_id];
38358c2ecf20Sopenharmony_ci		cb_parsed_length += pkt_size;
38368c2ecf20Sopenharmony_ci		if (cb_parsed_length > parser->user_cb_size) {
38378c2ecf20Sopenharmony_ci			dev_err(hdev->dev,
38388c2ecf20Sopenharmony_ci				"packet 0x%x is out of CB boundary\n", pkt_id);
38398c2ecf20Sopenharmony_ci			rc = -EINVAL;
38408c2ecf20Sopenharmony_ci			break;
38418c2ecf20Sopenharmony_ci		}
38428c2ecf20Sopenharmony_ci
38438c2ecf20Sopenharmony_ci		switch (pkt_id) {
38448c2ecf20Sopenharmony_ci		case PACKET_MSG_PROT:
38458c2ecf20Sopenharmony_ci			dev_err(hdev->dev,
38468c2ecf20Sopenharmony_ci				"User not allowed to use MSG_PROT\n");
38478c2ecf20Sopenharmony_ci			rc = -EPERM;
38488c2ecf20Sopenharmony_ci			break;
38498c2ecf20Sopenharmony_ci
38508c2ecf20Sopenharmony_ci		case PACKET_CP_DMA:
38518c2ecf20Sopenharmony_ci			dev_err(hdev->dev, "User not allowed to use CP_DMA\n");
38528c2ecf20Sopenharmony_ci			rc = -EPERM;
38538c2ecf20Sopenharmony_ci			break;
38548c2ecf20Sopenharmony_ci
38558c2ecf20Sopenharmony_ci		case PACKET_STOP:
38568c2ecf20Sopenharmony_ci			dev_err(hdev->dev, "User not allowed to use STOP\n");
38578c2ecf20Sopenharmony_ci			rc = -EPERM;
38588c2ecf20Sopenharmony_ci			break;
38598c2ecf20Sopenharmony_ci
38608c2ecf20Sopenharmony_ci		case PACKET_WREG_BULK:
38618c2ecf20Sopenharmony_ci			dev_err(hdev->dev,
38628c2ecf20Sopenharmony_ci				"User not allowed to use WREG_BULK\n");
38638c2ecf20Sopenharmony_ci			rc = -EPERM;
38648c2ecf20Sopenharmony_ci			break;
38658c2ecf20Sopenharmony_ci
38668c2ecf20Sopenharmony_ci		case PACKET_LOAD_AND_EXE:
38678c2ecf20Sopenharmony_ci			rc = gaudi_validate_load_and_exe_pkt(hdev, parser,
38688c2ecf20Sopenharmony_ci				(struct packet_load_and_exe *) user_pkt);
38698c2ecf20Sopenharmony_ci			break;
38708c2ecf20Sopenharmony_ci
38718c2ecf20Sopenharmony_ci		case PACKET_LIN_DMA:
38728c2ecf20Sopenharmony_ci			parser->contains_dma_pkt = true;
38738c2ecf20Sopenharmony_ci			if (is_mmu)
38748c2ecf20Sopenharmony_ci				parser->patched_cb_size += pkt_size;
38758c2ecf20Sopenharmony_ci			else
38768c2ecf20Sopenharmony_ci				rc = gaudi_validate_dma_pkt_no_mmu(hdev, parser,
38778c2ecf20Sopenharmony_ci					(struct packet_lin_dma *) user_pkt);
38788c2ecf20Sopenharmony_ci			break;
38798c2ecf20Sopenharmony_ci
38808c2ecf20Sopenharmony_ci		case PACKET_WREG_32:
38818c2ecf20Sopenharmony_ci		case PACKET_MSG_LONG:
38828c2ecf20Sopenharmony_ci		case PACKET_MSG_SHORT:
38838c2ecf20Sopenharmony_ci		case PACKET_REPEAT:
38848c2ecf20Sopenharmony_ci		case PACKET_FENCE:
38858c2ecf20Sopenharmony_ci		case PACKET_NOP:
38868c2ecf20Sopenharmony_ci		case PACKET_ARB_POINT:
38878c2ecf20Sopenharmony_ci			parser->patched_cb_size += pkt_size;
38888c2ecf20Sopenharmony_ci			break;
38898c2ecf20Sopenharmony_ci
38908c2ecf20Sopenharmony_ci		default:
38918c2ecf20Sopenharmony_ci			dev_err(hdev->dev, "Invalid packet header 0x%x\n",
38928c2ecf20Sopenharmony_ci				pkt_id);
38938c2ecf20Sopenharmony_ci			rc = -EINVAL;
38948c2ecf20Sopenharmony_ci			break;
38958c2ecf20Sopenharmony_ci		}
38968c2ecf20Sopenharmony_ci
38978c2ecf20Sopenharmony_ci		if (rc)
38988c2ecf20Sopenharmony_ci			break;
38998c2ecf20Sopenharmony_ci	}
39008c2ecf20Sopenharmony_ci
39018c2ecf20Sopenharmony_ci	/*
39028c2ecf20Sopenharmony_ci	 * The new CB should have space at the end for two MSG_PROT packets:
39038c2ecf20Sopenharmony_ci	 * 1. A packet that will act as a completion packet
39048c2ecf20Sopenharmony_ci	 * 2. A packet that will generate MSI-X interrupt
39058c2ecf20Sopenharmony_ci	 */
39068c2ecf20Sopenharmony_ci	parser->patched_cb_size += sizeof(struct packet_msg_prot) * 2;
39078c2ecf20Sopenharmony_ci
39088c2ecf20Sopenharmony_ci	return rc;
39098c2ecf20Sopenharmony_ci}
39108c2ecf20Sopenharmony_ci
39118c2ecf20Sopenharmony_cistatic int gaudi_patch_dma_packet(struct hl_device *hdev,
39128c2ecf20Sopenharmony_ci				struct hl_cs_parser *parser,
39138c2ecf20Sopenharmony_ci				struct packet_lin_dma *user_dma_pkt,
39148c2ecf20Sopenharmony_ci				struct packet_lin_dma *new_dma_pkt,
39158c2ecf20Sopenharmony_ci				u32 *new_dma_pkt_size)
39168c2ecf20Sopenharmony_ci{
39178c2ecf20Sopenharmony_ci	struct hl_userptr *userptr;
39188c2ecf20Sopenharmony_ci	struct scatterlist *sg, *sg_next_iter;
39198c2ecf20Sopenharmony_ci	u32 count, dma_desc_cnt, user_wrcomp_en_mask, ctl;
39208c2ecf20Sopenharmony_ci	u64 len, len_next;
39218c2ecf20Sopenharmony_ci	dma_addr_t dma_addr, dma_addr_next;
39228c2ecf20Sopenharmony_ci	u64 device_memory_addr, addr;
39238c2ecf20Sopenharmony_ci	enum dma_data_direction dir;
39248c2ecf20Sopenharmony_ci	struct sg_table *sgt;
39258c2ecf20Sopenharmony_ci	bool src_in_host = false;
39268c2ecf20Sopenharmony_ci	bool skip_host_mem_pin = false;
39278c2ecf20Sopenharmony_ci	bool user_memset;
39288c2ecf20Sopenharmony_ci
39298c2ecf20Sopenharmony_ci	ctl = le32_to_cpu(user_dma_pkt->ctl);
39308c2ecf20Sopenharmony_ci
39318c2ecf20Sopenharmony_ci	if (parser->hw_queue_id <= GAUDI_QUEUE_ID_DMA_0_3)
39328c2ecf20Sopenharmony_ci		src_in_host = true;
39338c2ecf20Sopenharmony_ci
39348c2ecf20Sopenharmony_ci	user_memset = (ctl & GAUDI_PKT_LIN_DMA_CTL_MEMSET_MASK) >>
39358c2ecf20Sopenharmony_ci			GAUDI_PKT_LIN_DMA_CTL_MEMSET_SHIFT;
39368c2ecf20Sopenharmony_ci
39378c2ecf20Sopenharmony_ci	if (src_in_host) {
39388c2ecf20Sopenharmony_ci		addr = le64_to_cpu(user_dma_pkt->src_addr);
39398c2ecf20Sopenharmony_ci		device_memory_addr = le64_to_cpu(user_dma_pkt->dst_addr);
39408c2ecf20Sopenharmony_ci		dir = DMA_TO_DEVICE;
39418c2ecf20Sopenharmony_ci		if (user_memset)
39428c2ecf20Sopenharmony_ci			skip_host_mem_pin = true;
39438c2ecf20Sopenharmony_ci	} else {
39448c2ecf20Sopenharmony_ci		addr = le64_to_cpu(user_dma_pkt->dst_addr);
39458c2ecf20Sopenharmony_ci		device_memory_addr = le64_to_cpu(user_dma_pkt->src_addr);
39468c2ecf20Sopenharmony_ci		dir = DMA_FROM_DEVICE;
39478c2ecf20Sopenharmony_ci	}
39488c2ecf20Sopenharmony_ci
39498c2ecf20Sopenharmony_ci	if ((!skip_host_mem_pin) &&
39508c2ecf20Sopenharmony_ci		(!hl_userptr_is_pinned(hdev, addr,
39518c2ecf20Sopenharmony_ci					le32_to_cpu(user_dma_pkt->tsize),
39528c2ecf20Sopenharmony_ci					parser->job_userptr_list, &userptr))) {
39538c2ecf20Sopenharmony_ci		dev_err(hdev->dev, "Userptr 0x%llx + 0x%x NOT mapped\n",
39548c2ecf20Sopenharmony_ci				addr, user_dma_pkt->tsize);
39558c2ecf20Sopenharmony_ci		return -EFAULT;
39568c2ecf20Sopenharmony_ci	}
39578c2ecf20Sopenharmony_ci
39588c2ecf20Sopenharmony_ci	if ((user_memset) && (dir == DMA_TO_DEVICE)) {
39598c2ecf20Sopenharmony_ci		memcpy(new_dma_pkt, user_dma_pkt, sizeof(*user_dma_pkt));
39608c2ecf20Sopenharmony_ci		*new_dma_pkt_size = sizeof(*user_dma_pkt);
39618c2ecf20Sopenharmony_ci		return 0;
39628c2ecf20Sopenharmony_ci	}
39638c2ecf20Sopenharmony_ci
39648c2ecf20Sopenharmony_ci	user_wrcomp_en_mask = ctl & GAUDI_PKT_LIN_DMA_CTL_WRCOMP_EN_MASK;
39658c2ecf20Sopenharmony_ci
39668c2ecf20Sopenharmony_ci	sgt = userptr->sgt;
39678c2ecf20Sopenharmony_ci	dma_desc_cnt = 0;
39688c2ecf20Sopenharmony_ci
39698c2ecf20Sopenharmony_ci	for_each_sg(sgt->sgl, sg, sgt->nents, count) {
39708c2ecf20Sopenharmony_ci		len = sg_dma_len(sg);
39718c2ecf20Sopenharmony_ci		dma_addr = sg_dma_address(sg);
39728c2ecf20Sopenharmony_ci
39738c2ecf20Sopenharmony_ci		if (len == 0)
39748c2ecf20Sopenharmony_ci			break;
39758c2ecf20Sopenharmony_ci
39768c2ecf20Sopenharmony_ci		while ((count + 1) < sgt->nents) {
39778c2ecf20Sopenharmony_ci			sg_next_iter = sg_next(sg);
39788c2ecf20Sopenharmony_ci			len_next = sg_dma_len(sg_next_iter);
39798c2ecf20Sopenharmony_ci			dma_addr_next = sg_dma_address(sg_next_iter);
39808c2ecf20Sopenharmony_ci
39818c2ecf20Sopenharmony_ci			if (len_next == 0)
39828c2ecf20Sopenharmony_ci				break;
39838c2ecf20Sopenharmony_ci
39848c2ecf20Sopenharmony_ci			if ((dma_addr + len == dma_addr_next) &&
39858c2ecf20Sopenharmony_ci				(len + len_next <= DMA_MAX_TRANSFER_SIZE)) {
39868c2ecf20Sopenharmony_ci				len += len_next;
39878c2ecf20Sopenharmony_ci				count++;
39888c2ecf20Sopenharmony_ci				sg = sg_next_iter;
39898c2ecf20Sopenharmony_ci			} else {
39908c2ecf20Sopenharmony_ci				break;
39918c2ecf20Sopenharmony_ci			}
39928c2ecf20Sopenharmony_ci		}
39938c2ecf20Sopenharmony_ci
39948c2ecf20Sopenharmony_ci		ctl = le32_to_cpu(user_dma_pkt->ctl);
39958c2ecf20Sopenharmony_ci		if (likely(dma_desc_cnt))
39968c2ecf20Sopenharmony_ci			ctl &= ~GAUDI_PKT_CTL_EB_MASK;
39978c2ecf20Sopenharmony_ci		ctl &= ~GAUDI_PKT_LIN_DMA_CTL_WRCOMP_EN_MASK;
39988c2ecf20Sopenharmony_ci		new_dma_pkt->ctl = cpu_to_le32(ctl);
39998c2ecf20Sopenharmony_ci		new_dma_pkt->tsize = cpu_to_le32(len);
40008c2ecf20Sopenharmony_ci
40018c2ecf20Sopenharmony_ci		if (dir == DMA_TO_DEVICE) {
40028c2ecf20Sopenharmony_ci			new_dma_pkt->src_addr = cpu_to_le64(dma_addr);
40038c2ecf20Sopenharmony_ci			new_dma_pkt->dst_addr = cpu_to_le64(device_memory_addr);
40048c2ecf20Sopenharmony_ci		} else {
40058c2ecf20Sopenharmony_ci			new_dma_pkt->src_addr = cpu_to_le64(device_memory_addr);
40068c2ecf20Sopenharmony_ci			new_dma_pkt->dst_addr = cpu_to_le64(dma_addr);
40078c2ecf20Sopenharmony_ci		}
40088c2ecf20Sopenharmony_ci
40098c2ecf20Sopenharmony_ci		if (!user_memset)
40108c2ecf20Sopenharmony_ci			device_memory_addr += len;
40118c2ecf20Sopenharmony_ci		dma_desc_cnt++;
40128c2ecf20Sopenharmony_ci		new_dma_pkt++;
40138c2ecf20Sopenharmony_ci	}
40148c2ecf20Sopenharmony_ci
40158c2ecf20Sopenharmony_ci	if (!dma_desc_cnt) {
40168c2ecf20Sopenharmony_ci		dev_err(hdev->dev,
40178c2ecf20Sopenharmony_ci			"Error of 0 SG entries when patching DMA packet\n");
40188c2ecf20Sopenharmony_ci		return -EFAULT;
40198c2ecf20Sopenharmony_ci	}
40208c2ecf20Sopenharmony_ci
40218c2ecf20Sopenharmony_ci	/* Fix the last dma packet - wrcomp must be as user set it */
40228c2ecf20Sopenharmony_ci	new_dma_pkt--;
40238c2ecf20Sopenharmony_ci	new_dma_pkt->ctl |= cpu_to_le32(user_wrcomp_en_mask);
40248c2ecf20Sopenharmony_ci
40258c2ecf20Sopenharmony_ci	*new_dma_pkt_size = dma_desc_cnt * sizeof(struct packet_lin_dma);
40268c2ecf20Sopenharmony_ci
40278c2ecf20Sopenharmony_ci	return 0;
40288c2ecf20Sopenharmony_ci}
40298c2ecf20Sopenharmony_ci
40308c2ecf20Sopenharmony_cistatic int gaudi_patch_cb(struct hl_device *hdev,
40318c2ecf20Sopenharmony_ci				struct hl_cs_parser *parser)
40328c2ecf20Sopenharmony_ci{
40338c2ecf20Sopenharmony_ci	u32 cb_parsed_length = 0;
40348c2ecf20Sopenharmony_ci	u32 cb_patched_cur_length = 0;
40358c2ecf20Sopenharmony_ci	int rc = 0;
40368c2ecf20Sopenharmony_ci
40378c2ecf20Sopenharmony_ci	/* cb_user_size is more than 0 so loop will always be executed */
40388c2ecf20Sopenharmony_ci	while (cb_parsed_length < parser->user_cb_size) {
40398c2ecf20Sopenharmony_ci		enum packet_id pkt_id;
40408c2ecf20Sopenharmony_ci		u16 pkt_size;
40418c2ecf20Sopenharmony_ci		u32 new_pkt_size = 0;
40428c2ecf20Sopenharmony_ci		struct gaudi_packet *user_pkt, *kernel_pkt;
40438c2ecf20Sopenharmony_ci
40448c2ecf20Sopenharmony_ci		user_pkt = parser->user_cb->kernel_address + cb_parsed_length;
40458c2ecf20Sopenharmony_ci		kernel_pkt = parser->patched_cb->kernel_address +
40468c2ecf20Sopenharmony_ci					cb_patched_cur_length;
40478c2ecf20Sopenharmony_ci
40488c2ecf20Sopenharmony_ci		pkt_id = (enum packet_id) (
40498c2ecf20Sopenharmony_ci				(le64_to_cpu(user_pkt->header) &
40508c2ecf20Sopenharmony_ci				PACKET_HEADER_PACKET_ID_MASK) >>
40518c2ecf20Sopenharmony_ci					PACKET_HEADER_PACKET_ID_SHIFT);
40528c2ecf20Sopenharmony_ci
40538c2ecf20Sopenharmony_ci		if (!validate_packet_id(pkt_id)) {
40548c2ecf20Sopenharmony_ci			dev_err(hdev->dev, "Invalid packet id %u\n", pkt_id);
40558c2ecf20Sopenharmony_ci			rc = -EINVAL;
40568c2ecf20Sopenharmony_ci			break;
40578c2ecf20Sopenharmony_ci		}
40588c2ecf20Sopenharmony_ci
40598c2ecf20Sopenharmony_ci		pkt_size = gaudi_packet_sizes[pkt_id];
40608c2ecf20Sopenharmony_ci		cb_parsed_length += pkt_size;
40618c2ecf20Sopenharmony_ci		if (cb_parsed_length > parser->user_cb_size) {
40628c2ecf20Sopenharmony_ci			dev_err(hdev->dev,
40638c2ecf20Sopenharmony_ci				"packet 0x%x is out of CB boundary\n", pkt_id);
40648c2ecf20Sopenharmony_ci			rc = -EINVAL;
40658c2ecf20Sopenharmony_ci			break;
40668c2ecf20Sopenharmony_ci		}
40678c2ecf20Sopenharmony_ci
40688c2ecf20Sopenharmony_ci		switch (pkt_id) {
40698c2ecf20Sopenharmony_ci		case PACKET_LIN_DMA:
40708c2ecf20Sopenharmony_ci			rc = gaudi_patch_dma_packet(hdev, parser,
40718c2ecf20Sopenharmony_ci					(struct packet_lin_dma *) user_pkt,
40728c2ecf20Sopenharmony_ci					(struct packet_lin_dma *) kernel_pkt,
40738c2ecf20Sopenharmony_ci					&new_pkt_size);
40748c2ecf20Sopenharmony_ci			cb_patched_cur_length += new_pkt_size;
40758c2ecf20Sopenharmony_ci			break;
40768c2ecf20Sopenharmony_ci
40778c2ecf20Sopenharmony_ci		case PACKET_MSG_PROT:
40788c2ecf20Sopenharmony_ci			dev_err(hdev->dev,
40798c2ecf20Sopenharmony_ci				"User not allowed to use MSG_PROT\n");
40808c2ecf20Sopenharmony_ci			rc = -EPERM;
40818c2ecf20Sopenharmony_ci			break;
40828c2ecf20Sopenharmony_ci
40838c2ecf20Sopenharmony_ci		case PACKET_CP_DMA:
40848c2ecf20Sopenharmony_ci			dev_err(hdev->dev, "User not allowed to use CP_DMA\n");
40858c2ecf20Sopenharmony_ci			rc = -EPERM;
40868c2ecf20Sopenharmony_ci			break;
40878c2ecf20Sopenharmony_ci
40888c2ecf20Sopenharmony_ci		case PACKET_STOP:
40898c2ecf20Sopenharmony_ci			dev_err(hdev->dev, "User not allowed to use STOP\n");
40908c2ecf20Sopenharmony_ci			rc = -EPERM;
40918c2ecf20Sopenharmony_ci			break;
40928c2ecf20Sopenharmony_ci
40938c2ecf20Sopenharmony_ci		case PACKET_WREG_32:
40948c2ecf20Sopenharmony_ci		case PACKET_WREG_BULK:
40958c2ecf20Sopenharmony_ci		case PACKET_MSG_LONG:
40968c2ecf20Sopenharmony_ci		case PACKET_MSG_SHORT:
40978c2ecf20Sopenharmony_ci		case PACKET_REPEAT:
40988c2ecf20Sopenharmony_ci		case PACKET_FENCE:
40998c2ecf20Sopenharmony_ci		case PACKET_NOP:
41008c2ecf20Sopenharmony_ci		case PACKET_ARB_POINT:
41018c2ecf20Sopenharmony_ci		case PACKET_LOAD_AND_EXE:
41028c2ecf20Sopenharmony_ci			memcpy(kernel_pkt, user_pkt, pkt_size);
41038c2ecf20Sopenharmony_ci			cb_patched_cur_length += pkt_size;
41048c2ecf20Sopenharmony_ci			break;
41058c2ecf20Sopenharmony_ci
41068c2ecf20Sopenharmony_ci		default:
41078c2ecf20Sopenharmony_ci			dev_err(hdev->dev, "Invalid packet header 0x%x\n",
41088c2ecf20Sopenharmony_ci				pkt_id);
41098c2ecf20Sopenharmony_ci			rc = -EINVAL;
41108c2ecf20Sopenharmony_ci			break;
41118c2ecf20Sopenharmony_ci		}
41128c2ecf20Sopenharmony_ci
41138c2ecf20Sopenharmony_ci		if (rc)
41148c2ecf20Sopenharmony_ci			break;
41158c2ecf20Sopenharmony_ci	}
41168c2ecf20Sopenharmony_ci
41178c2ecf20Sopenharmony_ci	return rc;
41188c2ecf20Sopenharmony_ci}
41198c2ecf20Sopenharmony_ci
41208c2ecf20Sopenharmony_cistatic int gaudi_parse_cb_mmu(struct hl_device *hdev,
41218c2ecf20Sopenharmony_ci		struct hl_cs_parser *parser)
41228c2ecf20Sopenharmony_ci{
41238c2ecf20Sopenharmony_ci	u64 patched_cb_handle;
41248c2ecf20Sopenharmony_ci	u32 patched_cb_size;
41258c2ecf20Sopenharmony_ci	struct hl_cb *user_cb;
41268c2ecf20Sopenharmony_ci	int rc;
41278c2ecf20Sopenharmony_ci
41288c2ecf20Sopenharmony_ci	/*
41298c2ecf20Sopenharmony_ci	 * The new CB should have space at the end for two MSG_PROT pkt:
41308c2ecf20Sopenharmony_ci	 * 1. A packet that will act as a completion packet
41318c2ecf20Sopenharmony_ci	 * 2. A packet that will generate MSI interrupt
41328c2ecf20Sopenharmony_ci	 */
41338c2ecf20Sopenharmony_ci	parser->patched_cb_size = parser->user_cb_size +
41348c2ecf20Sopenharmony_ci			sizeof(struct packet_msg_prot) * 2;
41358c2ecf20Sopenharmony_ci
41368c2ecf20Sopenharmony_ci	rc = hl_cb_create(hdev, &hdev->kernel_cb_mgr, hdev->kernel_ctx,
41378c2ecf20Sopenharmony_ci				parser->patched_cb_size, false, false,
41388c2ecf20Sopenharmony_ci				&patched_cb_handle);
41398c2ecf20Sopenharmony_ci
41408c2ecf20Sopenharmony_ci	if (rc) {
41418c2ecf20Sopenharmony_ci		dev_err(hdev->dev,
41428c2ecf20Sopenharmony_ci			"Failed to allocate patched CB for DMA CS %d\n",
41438c2ecf20Sopenharmony_ci			rc);
41448c2ecf20Sopenharmony_ci		return rc;
41458c2ecf20Sopenharmony_ci	}
41468c2ecf20Sopenharmony_ci
41478c2ecf20Sopenharmony_ci	patched_cb_handle >>= PAGE_SHIFT;
41488c2ecf20Sopenharmony_ci	parser->patched_cb = hl_cb_get(hdev, &hdev->kernel_cb_mgr,
41498c2ecf20Sopenharmony_ci				(u32) patched_cb_handle);
41508c2ecf20Sopenharmony_ci	/* hl_cb_get should never fail here so use kernel WARN */
41518c2ecf20Sopenharmony_ci	WARN(!parser->patched_cb, "DMA CB handle invalid 0x%x\n",
41528c2ecf20Sopenharmony_ci			(u32) patched_cb_handle);
41538c2ecf20Sopenharmony_ci	if (!parser->patched_cb) {
41548c2ecf20Sopenharmony_ci		rc = -EFAULT;
41558c2ecf20Sopenharmony_ci		goto out;
41568c2ecf20Sopenharmony_ci	}
41578c2ecf20Sopenharmony_ci
41588c2ecf20Sopenharmony_ci	/*
41598c2ecf20Sopenharmony_ci	 * The check that parser->user_cb_size <= parser->user_cb->size was done
41608c2ecf20Sopenharmony_ci	 * in validate_queue_index().
41618c2ecf20Sopenharmony_ci	 */
41628c2ecf20Sopenharmony_ci	memcpy(parser->patched_cb->kernel_address,
41638c2ecf20Sopenharmony_ci		parser->user_cb->kernel_address,
41648c2ecf20Sopenharmony_ci		parser->user_cb_size);
41658c2ecf20Sopenharmony_ci
41668c2ecf20Sopenharmony_ci	patched_cb_size = parser->patched_cb_size;
41678c2ecf20Sopenharmony_ci
41688c2ecf20Sopenharmony_ci	/* Validate patched CB instead of user CB */
41698c2ecf20Sopenharmony_ci	user_cb = parser->user_cb;
41708c2ecf20Sopenharmony_ci	parser->user_cb = parser->patched_cb;
41718c2ecf20Sopenharmony_ci	rc = gaudi_validate_cb(hdev, parser, true);
41728c2ecf20Sopenharmony_ci	parser->user_cb = user_cb;
41738c2ecf20Sopenharmony_ci
41748c2ecf20Sopenharmony_ci	if (rc) {
41758c2ecf20Sopenharmony_ci		hl_cb_put(parser->patched_cb);
41768c2ecf20Sopenharmony_ci		goto out;
41778c2ecf20Sopenharmony_ci	}
41788c2ecf20Sopenharmony_ci
41798c2ecf20Sopenharmony_ci	if (patched_cb_size != parser->patched_cb_size) {
41808c2ecf20Sopenharmony_ci		dev_err(hdev->dev, "user CB size mismatch\n");
41818c2ecf20Sopenharmony_ci		hl_cb_put(parser->patched_cb);
41828c2ecf20Sopenharmony_ci		rc = -EINVAL;
41838c2ecf20Sopenharmony_ci		goto out;
41848c2ecf20Sopenharmony_ci	}
41858c2ecf20Sopenharmony_ci
41868c2ecf20Sopenharmony_ciout:
41878c2ecf20Sopenharmony_ci	/*
41888c2ecf20Sopenharmony_ci	 * Always call cb destroy here because we still have 1 reference
41898c2ecf20Sopenharmony_ci	 * to it by calling cb_get earlier. After the job will be completed,
41908c2ecf20Sopenharmony_ci	 * cb_put will release it, but here we want to remove it from the
41918c2ecf20Sopenharmony_ci	 * idr
41928c2ecf20Sopenharmony_ci	 */
41938c2ecf20Sopenharmony_ci	hl_cb_destroy(hdev, &hdev->kernel_cb_mgr,
41948c2ecf20Sopenharmony_ci					patched_cb_handle << PAGE_SHIFT);
41958c2ecf20Sopenharmony_ci
41968c2ecf20Sopenharmony_ci	return rc;
41978c2ecf20Sopenharmony_ci}
41988c2ecf20Sopenharmony_ci
41998c2ecf20Sopenharmony_cistatic int gaudi_parse_cb_no_mmu(struct hl_device *hdev,
42008c2ecf20Sopenharmony_ci		struct hl_cs_parser *parser)
42018c2ecf20Sopenharmony_ci{
42028c2ecf20Sopenharmony_ci	u64 patched_cb_handle;
42038c2ecf20Sopenharmony_ci	int rc;
42048c2ecf20Sopenharmony_ci
42058c2ecf20Sopenharmony_ci	rc = gaudi_validate_cb(hdev, parser, false);
42068c2ecf20Sopenharmony_ci
42078c2ecf20Sopenharmony_ci	if (rc)
42088c2ecf20Sopenharmony_ci		goto free_userptr;
42098c2ecf20Sopenharmony_ci
42108c2ecf20Sopenharmony_ci	rc = hl_cb_create(hdev, &hdev->kernel_cb_mgr, hdev->kernel_ctx,
42118c2ecf20Sopenharmony_ci				parser->patched_cb_size, false, false,
42128c2ecf20Sopenharmony_ci				&patched_cb_handle);
42138c2ecf20Sopenharmony_ci	if (rc) {
42148c2ecf20Sopenharmony_ci		dev_err(hdev->dev,
42158c2ecf20Sopenharmony_ci			"Failed to allocate patched CB for DMA CS %d\n", rc);
42168c2ecf20Sopenharmony_ci		goto free_userptr;
42178c2ecf20Sopenharmony_ci	}
42188c2ecf20Sopenharmony_ci
42198c2ecf20Sopenharmony_ci	patched_cb_handle >>= PAGE_SHIFT;
42208c2ecf20Sopenharmony_ci	parser->patched_cb = hl_cb_get(hdev, &hdev->kernel_cb_mgr,
42218c2ecf20Sopenharmony_ci				(u32) patched_cb_handle);
42228c2ecf20Sopenharmony_ci	/* hl_cb_get should never fail here so use kernel WARN */
42238c2ecf20Sopenharmony_ci	WARN(!parser->patched_cb, "DMA CB handle invalid 0x%x\n",
42248c2ecf20Sopenharmony_ci			(u32) patched_cb_handle);
42258c2ecf20Sopenharmony_ci	if (!parser->patched_cb) {
42268c2ecf20Sopenharmony_ci		rc = -EFAULT;
42278c2ecf20Sopenharmony_ci		goto out;
42288c2ecf20Sopenharmony_ci	}
42298c2ecf20Sopenharmony_ci
42308c2ecf20Sopenharmony_ci	rc = gaudi_patch_cb(hdev, parser);
42318c2ecf20Sopenharmony_ci
42328c2ecf20Sopenharmony_ci	if (rc)
42338c2ecf20Sopenharmony_ci		hl_cb_put(parser->patched_cb);
42348c2ecf20Sopenharmony_ci
42358c2ecf20Sopenharmony_ciout:
42368c2ecf20Sopenharmony_ci	/*
42378c2ecf20Sopenharmony_ci	 * Always call cb destroy here because we still have 1 reference
42388c2ecf20Sopenharmony_ci	 * to it by calling cb_get earlier. After the job will be completed,
42398c2ecf20Sopenharmony_ci	 * cb_put will release it, but here we want to remove it from the
42408c2ecf20Sopenharmony_ci	 * idr
42418c2ecf20Sopenharmony_ci	 */
42428c2ecf20Sopenharmony_ci	hl_cb_destroy(hdev, &hdev->kernel_cb_mgr,
42438c2ecf20Sopenharmony_ci				patched_cb_handle << PAGE_SHIFT);
42448c2ecf20Sopenharmony_ci
42458c2ecf20Sopenharmony_cifree_userptr:
42468c2ecf20Sopenharmony_ci	if (rc)
42478c2ecf20Sopenharmony_ci		hl_userptr_delete_list(hdev, parser->job_userptr_list);
42488c2ecf20Sopenharmony_ci	return rc;
42498c2ecf20Sopenharmony_ci}
42508c2ecf20Sopenharmony_ci
42518c2ecf20Sopenharmony_cistatic int gaudi_parse_cb_no_ext_queue(struct hl_device *hdev,
42528c2ecf20Sopenharmony_ci					struct hl_cs_parser *parser)
42538c2ecf20Sopenharmony_ci{
42548c2ecf20Sopenharmony_ci	struct asic_fixed_properties *asic_prop = &hdev->asic_prop;
42558c2ecf20Sopenharmony_ci
42568c2ecf20Sopenharmony_ci	/* For internal queue jobs just check if CB address is valid */
42578c2ecf20Sopenharmony_ci	if (hl_mem_area_inside_range((u64) (uintptr_t) parser->user_cb,
42588c2ecf20Sopenharmony_ci					parser->user_cb_size,
42598c2ecf20Sopenharmony_ci					asic_prop->sram_user_base_address,
42608c2ecf20Sopenharmony_ci					asic_prop->sram_end_address))
42618c2ecf20Sopenharmony_ci		return 0;
42628c2ecf20Sopenharmony_ci
42638c2ecf20Sopenharmony_ci	if (hl_mem_area_inside_range((u64) (uintptr_t) parser->user_cb,
42648c2ecf20Sopenharmony_ci					parser->user_cb_size,
42658c2ecf20Sopenharmony_ci					asic_prop->dram_user_base_address,
42668c2ecf20Sopenharmony_ci					asic_prop->dram_end_address))
42678c2ecf20Sopenharmony_ci		return 0;
42688c2ecf20Sopenharmony_ci
42698c2ecf20Sopenharmony_ci	/* PMMU and HPMMU addresses are equal, check only one of them */
42708c2ecf20Sopenharmony_ci	if (hl_mem_area_inside_range((u64) (uintptr_t) parser->user_cb,
42718c2ecf20Sopenharmony_ci					parser->user_cb_size,
42728c2ecf20Sopenharmony_ci					asic_prop->pmmu.start_addr,
42738c2ecf20Sopenharmony_ci					asic_prop->pmmu.end_addr))
42748c2ecf20Sopenharmony_ci		return 0;
42758c2ecf20Sopenharmony_ci
42768c2ecf20Sopenharmony_ci	dev_err(hdev->dev,
42778c2ecf20Sopenharmony_ci		"CB address 0x%px + 0x%x for internal QMAN is not valid\n",
42788c2ecf20Sopenharmony_ci		parser->user_cb, parser->user_cb_size);
42798c2ecf20Sopenharmony_ci
42808c2ecf20Sopenharmony_ci	return -EFAULT;
42818c2ecf20Sopenharmony_ci}
42828c2ecf20Sopenharmony_ci
42838c2ecf20Sopenharmony_cistatic int gaudi_cs_parser(struct hl_device *hdev, struct hl_cs_parser *parser)
42848c2ecf20Sopenharmony_ci{
42858c2ecf20Sopenharmony_ci	struct gaudi_device *gaudi = hdev->asic_specific;
42868c2ecf20Sopenharmony_ci
42878c2ecf20Sopenharmony_ci	if (parser->queue_type == QUEUE_TYPE_INT)
42888c2ecf20Sopenharmony_ci		return gaudi_parse_cb_no_ext_queue(hdev, parser);
42898c2ecf20Sopenharmony_ci
42908c2ecf20Sopenharmony_ci	if (gaudi->hw_cap_initialized & HW_CAP_MMU)
42918c2ecf20Sopenharmony_ci		return gaudi_parse_cb_mmu(hdev, parser);
42928c2ecf20Sopenharmony_ci	else
42938c2ecf20Sopenharmony_ci		return gaudi_parse_cb_no_mmu(hdev, parser);
42948c2ecf20Sopenharmony_ci}
42958c2ecf20Sopenharmony_ci
42968c2ecf20Sopenharmony_cistatic void gaudi_add_end_of_cb_packets(struct hl_device *hdev,
42978c2ecf20Sopenharmony_ci					void *kernel_address, u32 len,
42988c2ecf20Sopenharmony_ci					u64 cq_addr, u32 cq_val, u32 msi_vec,
42998c2ecf20Sopenharmony_ci					bool eb)
43008c2ecf20Sopenharmony_ci{
43018c2ecf20Sopenharmony_ci	struct gaudi_device *gaudi = hdev->asic_specific;
43028c2ecf20Sopenharmony_ci	struct packet_msg_prot *cq_pkt;
43038c2ecf20Sopenharmony_ci	u32 tmp;
43048c2ecf20Sopenharmony_ci
43058c2ecf20Sopenharmony_ci	cq_pkt = kernel_address + len - (sizeof(struct packet_msg_prot) * 2);
43068c2ecf20Sopenharmony_ci
43078c2ecf20Sopenharmony_ci	tmp = FIELD_PREP(GAUDI_PKT_CTL_OPCODE_MASK, PACKET_MSG_PROT);
43088c2ecf20Sopenharmony_ci	tmp |= FIELD_PREP(GAUDI_PKT_CTL_MB_MASK, 1);
43098c2ecf20Sopenharmony_ci
43108c2ecf20Sopenharmony_ci	if (eb)
43118c2ecf20Sopenharmony_ci		tmp |= FIELD_PREP(GAUDI_PKT_CTL_EB_MASK, 1);
43128c2ecf20Sopenharmony_ci
43138c2ecf20Sopenharmony_ci	cq_pkt->ctl = cpu_to_le32(tmp);
43148c2ecf20Sopenharmony_ci	cq_pkt->value = cpu_to_le32(cq_val);
43158c2ecf20Sopenharmony_ci	cq_pkt->addr = cpu_to_le64(cq_addr);
43168c2ecf20Sopenharmony_ci
43178c2ecf20Sopenharmony_ci	cq_pkt++;
43188c2ecf20Sopenharmony_ci
43198c2ecf20Sopenharmony_ci	tmp = FIELD_PREP(GAUDI_PKT_CTL_OPCODE_MASK, PACKET_MSG_PROT);
43208c2ecf20Sopenharmony_ci	tmp |= FIELD_PREP(GAUDI_PKT_CTL_MB_MASK, 1);
43218c2ecf20Sopenharmony_ci	cq_pkt->ctl = cpu_to_le32(tmp);
43228c2ecf20Sopenharmony_ci	cq_pkt->value = cpu_to_le32(1);
43238c2ecf20Sopenharmony_ci
43248c2ecf20Sopenharmony_ci	if (!gaudi->multi_msi_mode)
43258c2ecf20Sopenharmony_ci		msi_vec = 0;
43268c2ecf20Sopenharmony_ci
43278c2ecf20Sopenharmony_ci	cq_pkt->addr = cpu_to_le64(CFG_BASE + mmPCIE_MSI_INTR_0 + msi_vec * 4);
43288c2ecf20Sopenharmony_ci}
43298c2ecf20Sopenharmony_ci
43308c2ecf20Sopenharmony_cistatic void gaudi_update_eq_ci(struct hl_device *hdev, u32 val)
43318c2ecf20Sopenharmony_ci{
43328c2ecf20Sopenharmony_ci	WREG32(mmCPU_IF_EQ_RD_OFFS, val);
43338c2ecf20Sopenharmony_ci}
43348c2ecf20Sopenharmony_ci
43358c2ecf20Sopenharmony_cistatic int gaudi_memset_device_memory(struct hl_device *hdev, u64 addr,
43368c2ecf20Sopenharmony_ci					u32 size, u64 val)
43378c2ecf20Sopenharmony_ci{
43388c2ecf20Sopenharmony_ci	struct packet_lin_dma *lin_dma_pkt;
43398c2ecf20Sopenharmony_ci	struct hl_cs_job *job;
43408c2ecf20Sopenharmony_ci	u32 cb_size, ctl, err_cause;
43418c2ecf20Sopenharmony_ci	struct hl_cb *cb;
43428c2ecf20Sopenharmony_ci	int rc;
43438c2ecf20Sopenharmony_ci
43448c2ecf20Sopenharmony_ci	cb = hl_cb_kernel_create(hdev, PAGE_SIZE, false);
43458c2ecf20Sopenharmony_ci	if (!cb)
43468c2ecf20Sopenharmony_ci		return -EFAULT;
43478c2ecf20Sopenharmony_ci
43488c2ecf20Sopenharmony_ci	lin_dma_pkt = cb->kernel_address;
43498c2ecf20Sopenharmony_ci	memset(lin_dma_pkt, 0, sizeof(*lin_dma_pkt));
43508c2ecf20Sopenharmony_ci	cb_size = sizeof(*lin_dma_pkt);
43518c2ecf20Sopenharmony_ci
43528c2ecf20Sopenharmony_ci	ctl = FIELD_PREP(GAUDI_PKT_CTL_OPCODE_MASK, PACKET_LIN_DMA);
43538c2ecf20Sopenharmony_ci	ctl |= FIELD_PREP(GAUDI_PKT_LIN_DMA_CTL_MEMSET_MASK, 1);
43548c2ecf20Sopenharmony_ci	ctl |= FIELD_PREP(GAUDI_PKT_LIN_DMA_CTL_LIN_MASK, 1);
43558c2ecf20Sopenharmony_ci	ctl |= FIELD_PREP(GAUDI_PKT_CTL_MB_MASK, 1);
43568c2ecf20Sopenharmony_ci	ctl |= FIELD_PREP(GAUDI_PKT_CTL_RB_MASK, 1);
43578c2ecf20Sopenharmony_ci
43588c2ecf20Sopenharmony_ci	lin_dma_pkt->ctl = cpu_to_le32(ctl);
43598c2ecf20Sopenharmony_ci	lin_dma_pkt->src_addr = cpu_to_le64(val);
43608c2ecf20Sopenharmony_ci	lin_dma_pkt->dst_addr |= cpu_to_le64(addr);
43618c2ecf20Sopenharmony_ci	lin_dma_pkt->tsize = cpu_to_le32(size);
43628c2ecf20Sopenharmony_ci
43638c2ecf20Sopenharmony_ci	job = hl_cs_allocate_job(hdev, QUEUE_TYPE_EXT, true);
43648c2ecf20Sopenharmony_ci	if (!job) {
43658c2ecf20Sopenharmony_ci		dev_err(hdev->dev, "Failed to allocate a new job\n");
43668c2ecf20Sopenharmony_ci		rc = -ENOMEM;
43678c2ecf20Sopenharmony_ci		goto release_cb;
43688c2ecf20Sopenharmony_ci	}
43698c2ecf20Sopenharmony_ci
43708c2ecf20Sopenharmony_ci	/* Verify DMA is OK */
43718c2ecf20Sopenharmony_ci	err_cause = RREG32(mmDMA0_CORE_ERR_CAUSE);
43728c2ecf20Sopenharmony_ci	if (err_cause && !hdev->init_done) {
43738c2ecf20Sopenharmony_ci		dev_dbg(hdev->dev,
43748c2ecf20Sopenharmony_ci			"Clearing DMA0 engine from errors (cause 0x%x)\n",
43758c2ecf20Sopenharmony_ci			err_cause);
43768c2ecf20Sopenharmony_ci		WREG32(mmDMA0_CORE_ERR_CAUSE, err_cause);
43778c2ecf20Sopenharmony_ci	}
43788c2ecf20Sopenharmony_ci
43798c2ecf20Sopenharmony_ci	job->id = 0;
43808c2ecf20Sopenharmony_ci	job->user_cb = cb;
43818c2ecf20Sopenharmony_ci	job->user_cb->cs_cnt++;
43828c2ecf20Sopenharmony_ci	job->user_cb_size = cb_size;
43838c2ecf20Sopenharmony_ci	job->hw_queue_id = GAUDI_QUEUE_ID_DMA_0_0;
43848c2ecf20Sopenharmony_ci	job->patched_cb = job->user_cb;
43858c2ecf20Sopenharmony_ci	job->job_cb_size = job->user_cb_size + sizeof(struct packet_msg_prot);
43868c2ecf20Sopenharmony_ci
43878c2ecf20Sopenharmony_ci	hl_debugfs_add_job(hdev, job);
43888c2ecf20Sopenharmony_ci
43898c2ecf20Sopenharmony_ci	rc = gaudi_send_job_on_qman0(hdev, job);
43908c2ecf20Sopenharmony_ci	hl_debugfs_remove_job(hdev, job);
43918c2ecf20Sopenharmony_ci	kfree(job);
43928c2ecf20Sopenharmony_ci	cb->cs_cnt--;
43938c2ecf20Sopenharmony_ci
43948c2ecf20Sopenharmony_ci	/* Verify DMA is OK */
43958c2ecf20Sopenharmony_ci	err_cause = RREG32(mmDMA0_CORE_ERR_CAUSE);
43968c2ecf20Sopenharmony_ci	if (err_cause) {
43978c2ecf20Sopenharmony_ci		dev_err(hdev->dev, "DMA Failed, cause 0x%x\n", err_cause);
43988c2ecf20Sopenharmony_ci		rc = -EIO;
43998c2ecf20Sopenharmony_ci		if (!hdev->init_done) {
44008c2ecf20Sopenharmony_ci			dev_dbg(hdev->dev,
44018c2ecf20Sopenharmony_ci				"Clearing DMA0 engine from errors (cause 0x%x)\n",
44028c2ecf20Sopenharmony_ci				err_cause);
44038c2ecf20Sopenharmony_ci			WREG32(mmDMA0_CORE_ERR_CAUSE, err_cause);
44048c2ecf20Sopenharmony_ci		}
44058c2ecf20Sopenharmony_ci	}
44068c2ecf20Sopenharmony_ci
44078c2ecf20Sopenharmony_cirelease_cb:
44088c2ecf20Sopenharmony_ci	hl_cb_put(cb);
44098c2ecf20Sopenharmony_ci	hl_cb_destroy(hdev, &hdev->kernel_cb_mgr, cb->id << PAGE_SHIFT);
44108c2ecf20Sopenharmony_ci
44118c2ecf20Sopenharmony_ci	return rc;
44128c2ecf20Sopenharmony_ci}
44138c2ecf20Sopenharmony_ci
44148c2ecf20Sopenharmony_cistatic void gaudi_restore_sm_registers(struct hl_device *hdev)
44158c2ecf20Sopenharmony_ci{
44168c2ecf20Sopenharmony_ci	int i;
44178c2ecf20Sopenharmony_ci
44188c2ecf20Sopenharmony_ci	for (i = 0 ; i < NUM_OF_SOB_IN_BLOCK << 2 ; i += 4) {
44198c2ecf20Sopenharmony_ci		WREG32(mmSYNC_MNGR_E_N_SYNC_MNGR_OBJS_SOB_OBJ_0 + i, 0);
44208c2ecf20Sopenharmony_ci		WREG32(mmSYNC_MNGR_E_S_SYNC_MNGR_OBJS_SOB_OBJ_0 + i, 0);
44218c2ecf20Sopenharmony_ci		WREG32(mmSYNC_MNGR_W_N_SYNC_MNGR_OBJS_SOB_OBJ_0 + i, 0);
44228c2ecf20Sopenharmony_ci	}
44238c2ecf20Sopenharmony_ci
44248c2ecf20Sopenharmony_ci	for (i = 0 ; i < NUM_OF_MONITORS_IN_BLOCK << 2 ; i += 4) {
44258c2ecf20Sopenharmony_ci		WREG32(mmSYNC_MNGR_E_N_SYNC_MNGR_OBJS_MON_STATUS_0 + i, 0);
44268c2ecf20Sopenharmony_ci		WREG32(mmSYNC_MNGR_E_S_SYNC_MNGR_OBJS_MON_STATUS_0 + i, 0);
44278c2ecf20Sopenharmony_ci		WREG32(mmSYNC_MNGR_W_N_SYNC_MNGR_OBJS_MON_STATUS_0 + i, 0);
44288c2ecf20Sopenharmony_ci	}
44298c2ecf20Sopenharmony_ci
44308c2ecf20Sopenharmony_ci	i = GAUDI_FIRST_AVAILABLE_W_S_SYNC_OBJECT * 4;
44318c2ecf20Sopenharmony_ci
44328c2ecf20Sopenharmony_ci	for (; i < NUM_OF_SOB_IN_BLOCK << 2 ; i += 4)
44338c2ecf20Sopenharmony_ci		WREG32(mmSYNC_MNGR_W_S_SYNC_MNGR_OBJS_SOB_OBJ_0 + i, 0);
44348c2ecf20Sopenharmony_ci
44358c2ecf20Sopenharmony_ci	i = GAUDI_FIRST_AVAILABLE_W_S_MONITOR * 4;
44368c2ecf20Sopenharmony_ci
44378c2ecf20Sopenharmony_ci	for (; i < NUM_OF_MONITORS_IN_BLOCK << 2 ; i += 4)
44388c2ecf20Sopenharmony_ci		WREG32(mmSYNC_MNGR_W_S_SYNC_MNGR_OBJS_MON_STATUS_0 + i, 0);
44398c2ecf20Sopenharmony_ci}
44408c2ecf20Sopenharmony_ci
44418c2ecf20Sopenharmony_cistatic void gaudi_restore_dma_registers(struct hl_device *hdev)
44428c2ecf20Sopenharmony_ci{
44438c2ecf20Sopenharmony_ci	u32 sob_delta = mmSYNC_MNGR_E_N_SYNC_MNGR_OBJS_SOB_OBJ_1 -
44448c2ecf20Sopenharmony_ci			mmSYNC_MNGR_E_N_SYNC_MNGR_OBJS_SOB_OBJ_0;
44458c2ecf20Sopenharmony_ci	int i;
44468c2ecf20Sopenharmony_ci
44478c2ecf20Sopenharmony_ci	for (i = 0 ; i < DMA_NUMBER_OF_CHANNELS ; i++) {
44488c2ecf20Sopenharmony_ci		u64 sob_addr = CFG_BASE +
44498c2ecf20Sopenharmony_ci				mmSYNC_MNGR_E_N_SYNC_MNGR_OBJS_SOB_OBJ_0 +
44508c2ecf20Sopenharmony_ci				(i * sob_delta);
44518c2ecf20Sopenharmony_ci		u32 dma_offset = i * DMA_CORE_OFFSET;
44528c2ecf20Sopenharmony_ci
44538c2ecf20Sopenharmony_ci		WREG32(mmDMA0_CORE_WR_COMP_ADDR_LO + dma_offset,
44548c2ecf20Sopenharmony_ci				lower_32_bits(sob_addr));
44558c2ecf20Sopenharmony_ci		WREG32(mmDMA0_CORE_WR_COMP_ADDR_HI + dma_offset,
44568c2ecf20Sopenharmony_ci				upper_32_bits(sob_addr));
44578c2ecf20Sopenharmony_ci		WREG32(mmDMA0_CORE_WR_COMP_WDATA + dma_offset, 0x80000001);
44588c2ecf20Sopenharmony_ci
44598c2ecf20Sopenharmony_ci		/* For DMAs 2-7, need to restore WR_AWUSER_31_11 as it can be
44608c2ecf20Sopenharmony_ci		 * modified by the user for SRAM reduction
44618c2ecf20Sopenharmony_ci		 */
44628c2ecf20Sopenharmony_ci		if (i > 1)
44638c2ecf20Sopenharmony_ci			WREG32(mmDMA0_CORE_WR_AWUSER_31_11 + dma_offset,
44648c2ecf20Sopenharmony_ci								0x00000001);
44658c2ecf20Sopenharmony_ci	}
44668c2ecf20Sopenharmony_ci}
44678c2ecf20Sopenharmony_ci
44688c2ecf20Sopenharmony_cistatic void gaudi_restore_qm_registers(struct hl_device *hdev)
44698c2ecf20Sopenharmony_ci{
44708c2ecf20Sopenharmony_ci	u32 qman_offset;
44718c2ecf20Sopenharmony_ci	int i;
44728c2ecf20Sopenharmony_ci
44738c2ecf20Sopenharmony_ci	for (i = 0 ; i < DMA_NUMBER_OF_CHANNELS ; i++) {
44748c2ecf20Sopenharmony_ci		qman_offset = i * DMA_QMAN_OFFSET;
44758c2ecf20Sopenharmony_ci		WREG32(mmDMA0_QM_ARB_CFG_0 + qman_offset, 0);
44768c2ecf20Sopenharmony_ci	}
44778c2ecf20Sopenharmony_ci
44788c2ecf20Sopenharmony_ci	for (i = 0 ; i < MME_NUMBER_OF_MASTER_ENGINES ; i++) {
44798c2ecf20Sopenharmony_ci		qman_offset = i * (mmMME2_QM_BASE - mmMME0_QM_BASE);
44808c2ecf20Sopenharmony_ci		WREG32(mmMME0_QM_ARB_CFG_0 + qman_offset, 0);
44818c2ecf20Sopenharmony_ci	}
44828c2ecf20Sopenharmony_ci
44838c2ecf20Sopenharmony_ci	for (i = 0 ; i < TPC_NUMBER_OF_ENGINES ; i++) {
44848c2ecf20Sopenharmony_ci		qman_offset = i * TPC_QMAN_OFFSET;
44858c2ecf20Sopenharmony_ci		WREG32(mmTPC0_QM_ARB_CFG_0 + qman_offset, 0);
44868c2ecf20Sopenharmony_ci	}
44878c2ecf20Sopenharmony_ci}
44888c2ecf20Sopenharmony_ci
44898c2ecf20Sopenharmony_cistatic void gaudi_restore_user_registers(struct hl_device *hdev)
44908c2ecf20Sopenharmony_ci{
44918c2ecf20Sopenharmony_ci	gaudi_restore_sm_registers(hdev);
44928c2ecf20Sopenharmony_ci	gaudi_restore_dma_registers(hdev);
44938c2ecf20Sopenharmony_ci	gaudi_restore_qm_registers(hdev);
44948c2ecf20Sopenharmony_ci}
44958c2ecf20Sopenharmony_ci
44968c2ecf20Sopenharmony_cistatic int gaudi_context_switch(struct hl_device *hdev, u32 asid)
44978c2ecf20Sopenharmony_ci{
44988c2ecf20Sopenharmony_ci	struct asic_fixed_properties *prop = &hdev->asic_prop;
44998c2ecf20Sopenharmony_ci	u64 addr = prop->sram_user_base_address;
45008c2ecf20Sopenharmony_ci	u32 size = hdev->pldm ? 0x10000 :
45018c2ecf20Sopenharmony_ci			(prop->sram_size - SRAM_USER_BASE_OFFSET);
45028c2ecf20Sopenharmony_ci	u64 val = 0x7777777777777777ull;
45038c2ecf20Sopenharmony_ci	int rc;
45048c2ecf20Sopenharmony_ci
45058c2ecf20Sopenharmony_ci	rc = gaudi_memset_device_memory(hdev, addr, size, val);
45068c2ecf20Sopenharmony_ci	if (rc) {
45078c2ecf20Sopenharmony_ci		dev_err(hdev->dev, "Failed to clear SRAM in context switch\n");
45088c2ecf20Sopenharmony_ci		return rc;
45098c2ecf20Sopenharmony_ci	}
45108c2ecf20Sopenharmony_ci
45118c2ecf20Sopenharmony_ci	gaudi_mmu_prepare(hdev, asid);
45128c2ecf20Sopenharmony_ci
45138c2ecf20Sopenharmony_ci	gaudi_restore_user_registers(hdev);
45148c2ecf20Sopenharmony_ci
45158c2ecf20Sopenharmony_ci	return 0;
45168c2ecf20Sopenharmony_ci}
45178c2ecf20Sopenharmony_ci
45188c2ecf20Sopenharmony_cistatic int gaudi_mmu_clear_pgt_range(struct hl_device *hdev)
45198c2ecf20Sopenharmony_ci{
45208c2ecf20Sopenharmony_ci	struct asic_fixed_properties *prop = &hdev->asic_prop;
45218c2ecf20Sopenharmony_ci	struct gaudi_device *gaudi = hdev->asic_specific;
45228c2ecf20Sopenharmony_ci	u64 addr = prop->mmu_pgt_addr;
45238c2ecf20Sopenharmony_ci	u32 size = prop->mmu_pgt_size + MMU_CACHE_MNG_SIZE;
45248c2ecf20Sopenharmony_ci
45258c2ecf20Sopenharmony_ci	if (!(gaudi->hw_cap_initialized & HW_CAP_MMU))
45268c2ecf20Sopenharmony_ci		return 0;
45278c2ecf20Sopenharmony_ci
45288c2ecf20Sopenharmony_ci	return gaudi_memset_device_memory(hdev, addr, size, 0);
45298c2ecf20Sopenharmony_ci}
45308c2ecf20Sopenharmony_ci
45318c2ecf20Sopenharmony_cistatic void gaudi_restore_phase_topology(struct hl_device *hdev)
45328c2ecf20Sopenharmony_ci{
45338c2ecf20Sopenharmony_ci
45348c2ecf20Sopenharmony_ci}
45358c2ecf20Sopenharmony_ci
45368c2ecf20Sopenharmony_cistatic int gaudi_debugfs_read32(struct hl_device *hdev, u64 addr, u32 *val)
45378c2ecf20Sopenharmony_ci{
45388c2ecf20Sopenharmony_ci	struct asic_fixed_properties *prop = &hdev->asic_prop;
45398c2ecf20Sopenharmony_ci	struct gaudi_device *gaudi = hdev->asic_specific;
45408c2ecf20Sopenharmony_ci	u64 hbm_bar_addr;
45418c2ecf20Sopenharmony_ci	int rc = 0;
45428c2ecf20Sopenharmony_ci
45438c2ecf20Sopenharmony_ci	if ((addr >= CFG_BASE) && (addr < CFG_BASE + CFG_SIZE)) {
45448c2ecf20Sopenharmony_ci
45458c2ecf20Sopenharmony_ci		if ((gaudi->hw_cap_initialized & HW_CAP_CLK_GATE) &&
45468c2ecf20Sopenharmony_ci				(hdev->clock_gating_mask &
45478c2ecf20Sopenharmony_ci						GAUDI_CLK_GATE_DEBUGFS_MASK)) {
45488c2ecf20Sopenharmony_ci
45498c2ecf20Sopenharmony_ci			dev_err_ratelimited(hdev->dev,
45508c2ecf20Sopenharmony_ci				"Can't read register - clock gating is enabled!\n");
45518c2ecf20Sopenharmony_ci			rc = -EFAULT;
45528c2ecf20Sopenharmony_ci		} else {
45538c2ecf20Sopenharmony_ci			*val = RREG32(addr - CFG_BASE);
45548c2ecf20Sopenharmony_ci		}
45558c2ecf20Sopenharmony_ci
45568c2ecf20Sopenharmony_ci	} else if ((addr >= SRAM_BASE_ADDR) &&
45578c2ecf20Sopenharmony_ci			(addr < SRAM_BASE_ADDR + SRAM_BAR_SIZE)) {
45588c2ecf20Sopenharmony_ci		*val = readl(hdev->pcie_bar[SRAM_BAR_ID] +
45598c2ecf20Sopenharmony_ci				(addr - SRAM_BASE_ADDR));
45608c2ecf20Sopenharmony_ci	} else if (addr < DRAM_PHYS_BASE + hdev->asic_prop.dram_size) {
45618c2ecf20Sopenharmony_ci		u64 bar_base_addr = DRAM_PHYS_BASE +
45628c2ecf20Sopenharmony_ci				(addr & ~(prop->dram_pci_bar_size - 0x1ull));
45638c2ecf20Sopenharmony_ci
45648c2ecf20Sopenharmony_ci		hbm_bar_addr = gaudi_set_hbm_bar_base(hdev, bar_base_addr);
45658c2ecf20Sopenharmony_ci		if (hbm_bar_addr != U64_MAX) {
45668c2ecf20Sopenharmony_ci			*val = readl(hdev->pcie_bar[HBM_BAR_ID] +
45678c2ecf20Sopenharmony_ci						(addr - bar_base_addr));
45688c2ecf20Sopenharmony_ci
45698c2ecf20Sopenharmony_ci			hbm_bar_addr = gaudi_set_hbm_bar_base(hdev,
45708c2ecf20Sopenharmony_ci						hbm_bar_addr);
45718c2ecf20Sopenharmony_ci		}
45728c2ecf20Sopenharmony_ci		if (hbm_bar_addr == U64_MAX)
45738c2ecf20Sopenharmony_ci			rc = -EIO;
45748c2ecf20Sopenharmony_ci	} else if (addr >= HOST_PHYS_BASE && !iommu_present(&pci_bus_type)) {
45758c2ecf20Sopenharmony_ci		*val = *(u32 *) phys_to_virt(addr - HOST_PHYS_BASE);
45768c2ecf20Sopenharmony_ci	} else {
45778c2ecf20Sopenharmony_ci		rc = -EFAULT;
45788c2ecf20Sopenharmony_ci	}
45798c2ecf20Sopenharmony_ci
45808c2ecf20Sopenharmony_ci	return rc;
45818c2ecf20Sopenharmony_ci}
45828c2ecf20Sopenharmony_ci
45838c2ecf20Sopenharmony_cistatic int gaudi_debugfs_write32(struct hl_device *hdev, u64 addr, u32 val)
45848c2ecf20Sopenharmony_ci{
45858c2ecf20Sopenharmony_ci	struct asic_fixed_properties *prop = &hdev->asic_prop;
45868c2ecf20Sopenharmony_ci	struct gaudi_device *gaudi = hdev->asic_specific;
45878c2ecf20Sopenharmony_ci	u64 hbm_bar_addr;
45888c2ecf20Sopenharmony_ci	int rc = 0;
45898c2ecf20Sopenharmony_ci
45908c2ecf20Sopenharmony_ci	if ((addr >= CFG_BASE) && (addr < CFG_BASE + CFG_SIZE)) {
45918c2ecf20Sopenharmony_ci
45928c2ecf20Sopenharmony_ci		if ((gaudi->hw_cap_initialized & HW_CAP_CLK_GATE) &&
45938c2ecf20Sopenharmony_ci				(hdev->clock_gating_mask &
45948c2ecf20Sopenharmony_ci						GAUDI_CLK_GATE_DEBUGFS_MASK)) {
45958c2ecf20Sopenharmony_ci
45968c2ecf20Sopenharmony_ci			dev_err_ratelimited(hdev->dev,
45978c2ecf20Sopenharmony_ci				"Can't write register - clock gating is enabled!\n");
45988c2ecf20Sopenharmony_ci			rc = -EFAULT;
45998c2ecf20Sopenharmony_ci		} else {
46008c2ecf20Sopenharmony_ci			WREG32(addr - CFG_BASE, val);
46018c2ecf20Sopenharmony_ci		}
46028c2ecf20Sopenharmony_ci
46038c2ecf20Sopenharmony_ci	} else if ((addr >= SRAM_BASE_ADDR) &&
46048c2ecf20Sopenharmony_ci			(addr < SRAM_BASE_ADDR + SRAM_BAR_SIZE)) {
46058c2ecf20Sopenharmony_ci		writel(val, hdev->pcie_bar[SRAM_BAR_ID] +
46068c2ecf20Sopenharmony_ci					(addr - SRAM_BASE_ADDR));
46078c2ecf20Sopenharmony_ci	} else if (addr < DRAM_PHYS_BASE + hdev->asic_prop.dram_size) {
46088c2ecf20Sopenharmony_ci		u64 bar_base_addr = DRAM_PHYS_BASE +
46098c2ecf20Sopenharmony_ci				(addr & ~(prop->dram_pci_bar_size - 0x1ull));
46108c2ecf20Sopenharmony_ci
46118c2ecf20Sopenharmony_ci		hbm_bar_addr = gaudi_set_hbm_bar_base(hdev, bar_base_addr);
46128c2ecf20Sopenharmony_ci		if (hbm_bar_addr != U64_MAX) {
46138c2ecf20Sopenharmony_ci			writel(val, hdev->pcie_bar[HBM_BAR_ID] +
46148c2ecf20Sopenharmony_ci						(addr - bar_base_addr));
46158c2ecf20Sopenharmony_ci
46168c2ecf20Sopenharmony_ci			hbm_bar_addr = gaudi_set_hbm_bar_base(hdev,
46178c2ecf20Sopenharmony_ci						hbm_bar_addr);
46188c2ecf20Sopenharmony_ci		}
46198c2ecf20Sopenharmony_ci		if (hbm_bar_addr == U64_MAX)
46208c2ecf20Sopenharmony_ci			rc = -EIO;
46218c2ecf20Sopenharmony_ci	} else if (addr >= HOST_PHYS_BASE && !iommu_present(&pci_bus_type)) {
46228c2ecf20Sopenharmony_ci		*(u32 *) phys_to_virt(addr - HOST_PHYS_BASE) = val;
46238c2ecf20Sopenharmony_ci	} else {
46248c2ecf20Sopenharmony_ci		rc = -EFAULT;
46258c2ecf20Sopenharmony_ci	}
46268c2ecf20Sopenharmony_ci
46278c2ecf20Sopenharmony_ci	return rc;
46288c2ecf20Sopenharmony_ci}
46298c2ecf20Sopenharmony_ci
46308c2ecf20Sopenharmony_cistatic int gaudi_debugfs_read64(struct hl_device *hdev, u64 addr, u64 *val)
46318c2ecf20Sopenharmony_ci{
46328c2ecf20Sopenharmony_ci	struct asic_fixed_properties *prop = &hdev->asic_prop;
46338c2ecf20Sopenharmony_ci	struct gaudi_device *gaudi = hdev->asic_specific;
46348c2ecf20Sopenharmony_ci	u64 hbm_bar_addr;
46358c2ecf20Sopenharmony_ci	int rc = 0;
46368c2ecf20Sopenharmony_ci
46378c2ecf20Sopenharmony_ci	if ((addr >= CFG_BASE) && (addr <= CFG_BASE + CFG_SIZE - sizeof(u64))) {
46388c2ecf20Sopenharmony_ci
46398c2ecf20Sopenharmony_ci		if ((gaudi->hw_cap_initialized & HW_CAP_CLK_GATE) &&
46408c2ecf20Sopenharmony_ci				(hdev->clock_gating_mask &
46418c2ecf20Sopenharmony_ci						GAUDI_CLK_GATE_DEBUGFS_MASK)) {
46428c2ecf20Sopenharmony_ci
46438c2ecf20Sopenharmony_ci			dev_err_ratelimited(hdev->dev,
46448c2ecf20Sopenharmony_ci				"Can't read register - clock gating is enabled!\n");
46458c2ecf20Sopenharmony_ci			rc = -EFAULT;
46468c2ecf20Sopenharmony_ci		} else {
46478c2ecf20Sopenharmony_ci			u32 val_l = RREG32(addr - CFG_BASE);
46488c2ecf20Sopenharmony_ci			u32 val_h = RREG32(addr + sizeof(u32) - CFG_BASE);
46498c2ecf20Sopenharmony_ci
46508c2ecf20Sopenharmony_ci			*val = (((u64) val_h) << 32) | val_l;
46518c2ecf20Sopenharmony_ci		}
46528c2ecf20Sopenharmony_ci
46538c2ecf20Sopenharmony_ci	} else if ((addr >= SRAM_BASE_ADDR) &&
46548c2ecf20Sopenharmony_ci		   (addr <= SRAM_BASE_ADDR + SRAM_BAR_SIZE - sizeof(u64))) {
46558c2ecf20Sopenharmony_ci		*val = readq(hdev->pcie_bar[SRAM_BAR_ID] +
46568c2ecf20Sopenharmony_ci				(addr - SRAM_BASE_ADDR));
46578c2ecf20Sopenharmony_ci	} else if (addr <=
46588c2ecf20Sopenharmony_ci		    DRAM_PHYS_BASE + hdev->asic_prop.dram_size - sizeof(u64)) {
46598c2ecf20Sopenharmony_ci		u64 bar_base_addr = DRAM_PHYS_BASE +
46608c2ecf20Sopenharmony_ci				(addr & ~(prop->dram_pci_bar_size - 0x1ull));
46618c2ecf20Sopenharmony_ci
46628c2ecf20Sopenharmony_ci		hbm_bar_addr = gaudi_set_hbm_bar_base(hdev, bar_base_addr);
46638c2ecf20Sopenharmony_ci		if (hbm_bar_addr != U64_MAX) {
46648c2ecf20Sopenharmony_ci			*val = readq(hdev->pcie_bar[HBM_BAR_ID] +
46658c2ecf20Sopenharmony_ci						(addr - bar_base_addr));
46668c2ecf20Sopenharmony_ci
46678c2ecf20Sopenharmony_ci			hbm_bar_addr = gaudi_set_hbm_bar_base(hdev,
46688c2ecf20Sopenharmony_ci						hbm_bar_addr);
46698c2ecf20Sopenharmony_ci		}
46708c2ecf20Sopenharmony_ci		if (hbm_bar_addr == U64_MAX)
46718c2ecf20Sopenharmony_ci			rc = -EIO;
46728c2ecf20Sopenharmony_ci	} else if (addr >= HOST_PHYS_BASE && !iommu_present(&pci_bus_type)) {
46738c2ecf20Sopenharmony_ci		*val = *(u64 *) phys_to_virt(addr - HOST_PHYS_BASE);
46748c2ecf20Sopenharmony_ci	} else {
46758c2ecf20Sopenharmony_ci		rc = -EFAULT;
46768c2ecf20Sopenharmony_ci	}
46778c2ecf20Sopenharmony_ci
46788c2ecf20Sopenharmony_ci	return rc;
46798c2ecf20Sopenharmony_ci}
46808c2ecf20Sopenharmony_ci
46818c2ecf20Sopenharmony_cistatic int gaudi_debugfs_write64(struct hl_device *hdev, u64 addr, u64 val)
46828c2ecf20Sopenharmony_ci{
46838c2ecf20Sopenharmony_ci	struct asic_fixed_properties *prop = &hdev->asic_prop;
46848c2ecf20Sopenharmony_ci	struct gaudi_device *gaudi = hdev->asic_specific;
46858c2ecf20Sopenharmony_ci	u64 hbm_bar_addr;
46868c2ecf20Sopenharmony_ci	int rc = 0;
46878c2ecf20Sopenharmony_ci
46888c2ecf20Sopenharmony_ci	if ((addr >= CFG_BASE) && (addr <= CFG_BASE + CFG_SIZE - sizeof(u64))) {
46898c2ecf20Sopenharmony_ci
46908c2ecf20Sopenharmony_ci		if ((gaudi->hw_cap_initialized & HW_CAP_CLK_GATE) &&
46918c2ecf20Sopenharmony_ci				(hdev->clock_gating_mask &
46928c2ecf20Sopenharmony_ci						GAUDI_CLK_GATE_DEBUGFS_MASK)) {
46938c2ecf20Sopenharmony_ci
46948c2ecf20Sopenharmony_ci			dev_err_ratelimited(hdev->dev,
46958c2ecf20Sopenharmony_ci				"Can't write register - clock gating is enabled!\n");
46968c2ecf20Sopenharmony_ci			rc = -EFAULT;
46978c2ecf20Sopenharmony_ci		} else {
46988c2ecf20Sopenharmony_ci			WREG32(addr - CFG_BASE, lower_32_bits(val));
46998c2ecf20Sopenharmony_ci			WREG32(addr + sizeof(u32) - CFG_BASE,
47008c2ecf20Sopenharmony_ci				upper_32_bits(val));
47018c2ecf20Sopenharmony_ci		}
47028c2ecf20Sopenharmony_ci
47038c2ecf20Sopenharmony_ci	} else if ((addr >= SRAM_BASE_ADDR) &&
47048c2ecf20Sopenharmony_ci		   (addr <= SRAM_BASE_ADDR + SRAM_BAR_SIZE - sizeof(u64))) {
47058c2ecf20Sopenharmony_ci		writeq(val, hdev->pcie_bar[SRAM_BAR_ID] +
47068c2ecf20Sopenharmony_ci					(addr - SRAM_BASE_ADDR));
47078c2ecf20Sopenharmony_ci	} else if (addr <=
47088c2ecf20Sopenharmony_ci		    DRAM_PHYS_BASE + hdev->asic_prop.dram_size - sizeof(u64)) {
47098c2ecf20Sopenharmony_ci		u64 bar_base_addr = DRAM_PHYS_BASE +
47108c2ecf20Sopenharmony_ci				(addr & ~(prop->dram_pci_bar_size - 0x1ull));
47118c2ecf20Sopenharmony_ci
47128c2ecf20Sopenharmony_ci		hbm_bar_addr = gaudi_set_hbm_bar_base(hdev, bar_base_addr);
47138c2ecf20Sopenharmony_ci		if (hbm_bar_addr != U64_MAX) {
47148c2ecf20Sopenharmony_ci			writeq(val, hdev->pcie_bar[HBM_BAR_ID] +
47158c2ecf20Sopenharmony_ci						(addr - bar_base_addr));
47168c2ecf20Sopenharmony_ci
47178c2ecf20Sopenharmony_ci			hbm_bar_addr = gaudi_set_hbm_bar_base(hdev,
47188c2ecf20Sopenharmony_ci						hbm_bar_addr);
47198c2ecf20Sopenharmony_ci		}
47208c2ecf20Sopenharmony_ci		if (hbm_bar_addr == U64_MAX)
47218c2ecf20Sopenharmony_ci			rc = -EIO;
47228c2ecf20Sopenharmony_ci	} else if (addr >= HOST_PHYS_BASE && !iommu_present(&pci_bus_type)) {
47238c2ecf20Sopenharmony_ci		*(u64 *) phys_to_virt(addr - HOST_PHYS_BASE) = val;
47248c2ecf20Sopenharmony_ci	} else {
47258c2ecf20Sopenharmony_ci		rc = -EFAULT;
47268c2ecf20Sopenharmony_ci	}
47278c2ecf20Sopenharmony_ci
47288c2ecf20Sopenharmony_ci	return rc;
47298c2ecf20Sopenharmony_ci}
47308c2ecf20Sopenharmony_ci
47318c2ecf20Sopenharmony_cistatic u64 gaudi_read_pte(struct hl_device *hdev, u64 addr)
47328c2ecf20Sopenharmony_ci{
47338c2ecf20Sopenharmony_ci	struct gaudi_device *gaudi = hdev->asic_specific;
47348c2ecf20Sopenharmony_ci
47358c2ecf20Sopenharmony_ci	if (hdev->hard_reset_pending)
47368c2ecf20Sopenharmony_ci		return U64_MAX;
47378c2ecf20Sopenharmony_ci
47388c2ecf20Sopenharmony_ci	return readq(hdev->pcie_bar[HBM_BAR_ID] +
47398c2ecf20Sopenharmony_ci			(addr - gaudi->hbm_bar_cur_addr));
47408c2ecf20Sopenharmony_ci}
47418c2ecf20Sopenharmony_ci
47428c2ecf20Sopenharmony_cistatic void gaudi_write_pte(struct hl_device *hdev, u64 addr, u64 val)
47438c2ecf20Sopenharmony_ci{
47448c2ecf20Sopenharmony_ci	struct gaudi_device *gaudi = hdev->asic_specific;
47458c2ecf20Sopenharmony_ci
47468c2ecf20Sopenharmony_ci	if (hdev->hard_reset_pending)
47478c2ecf20Sopenharmony_ci		return;
47488c2ecf20Sopenharmony_ci
47498c2ecf20Sopenharmony_ci	writeq(val, hdev->pcie_bar[HBM_BAR_ID] +
47508c2ecf20Sopenharmony_ci			(addr - gaudi->hbm_bar_cur_addr));
47518c2ecf20Sopenharmony_ci}
47528c2ecf20Sopenharmony_ci
47538c2ecf20Sopenharmony_civoid gaudi_mmu_prepare_reg(struct hl_device *hdev, u64 reg, u32 asid)
47548c2ecf20Sopenharmony_ci{
47558c2ecf20Sopenharmony_ci	/* mask to zero the MMBP and ASID bits */
47568c2ecf20Sopenharmony_ci	WREG32_AND(reg, ~0x7FF);
47578c2ecf20Sopenharmony_ci	WREG32_OR(reg, asid);
47588c2ecf20Sopenharmony_ci}
47598c2ecf20Sopenharmony_ci
47608c2ecf20Sopenharmony_cistatic void gaudi_mmu_prepare(struct hl_device *hdev, u32 asid)
47618c2ecf20Sopenharmony_ci{
47628c2ecf20Sopenharmony_ci	struct gaudi_device *gaudi = hdev->asic_specific;
47638c2ecf20Sopenharmony_ci
47648c2ecf20Sopenharmony_ci	if (!(gaudi->hw_cap_initialized & HW_CAP_MMU))
47658c2ecf20Sopenharmony_ci		return;
47668c2ecf20Sopenharmony_ci
47678c2ecf20Sopenharmony_ci	if (asid & ~DMA0_QM_GLBL_NON_SECURE_PROPS_0_ASID_MASK) {
47688c2ecf20Sopenharmony_ci		WARN(1, "asid %u is too big\n", asid);
47698c2ecf20Sopenharmony_ci		return;
47708c2ecf20Sopenharmony_ci	}
47718c2ecf20Sopenharmony_ci
47728c2ecf20Sopenharmony_ci	mutex_lock(&gaudi->clk_gate_mutex);
47738c2ecf20Sopenharmony_ci
47748c2ecf20Sopenharmony_ci	hdev->asic_funcs->disable_clock_gating(hdev);
47758c2ecf20Sopenharmony_ci
47768c2ecf20Sopenharmony_ci	gaudi_mmu_prepare_reg(hdev, mmDMA0_QM_GLBL_NON_SECURE_PROPS_0, asid);
47778c2ecf20Sopenharmony_ci	gaudi_mmu_prepare_reg(hdev, mmDMA0_QM_GLBL_NON_SECURE_PROPS_1, asid);
47788c2ecf20Sopenharmony_ci	gaudi_mmu_prepare_reg(hdev, mmDMA0_QM_GLBL_NON_SECURE_PROPS_2, asid);
47798c2ecf20Sopenharmony_ci	gaudi_mmu_prepare_reg(hdev, mmDMA0_QM_GLBL_NON_SECURE_PROPS_3, asid);
47808c2ecf20Sopenharmony_ci	gaudi_mmu_prepare_reg(hdev, mmDMA0_QM_GLBL_NON_SECURE_PROPS_4, asid);
47818c2ecf20Sopenharmony_ci
47828c2ecf20Sopenharmony_ci	gaudi_mmu_prepare_reg(hdev, mmDMA1_QM_GLBL_NON_SECURE_PROPS_0, asid);
47838c2ecf20Sopenharmony_ci	gaudi_mmu_prepare_reg(hdev, mmDMA1_QM_GLBL_NON_SECURE_PROPS_1, asid);
47848c2ecf20Sopenharmony_ci	gaudi_mmu_prepare_reg(hdev, mmDMA1_QM_GLBL_NON_SECURE_PROPS_2, asid);
47858c2ecf20Sopenharmony_ci	gaudi_mmu_prepare_reg(hdev, mmDMA1_QM_GLBL_NON_SECURE_PROPS_3, asid);
47868c2ecf20Sopenharmony_ci	gaudi_mmu_prepare_reg(hdev, mmDMA1_QM_GLBL_NON_SECURE_PROPS_4, asid);
47878c2ecf20Sopenharmony_ci
47888c2ecf20Sopenharmony_ci	gaudi_mmu_prepare_reg(hdev, mmDMA2_QM_GLBL_NON_SECURE_PROPS_0, asid);
47898c2ecf20Sopenharmony_ci	gaudi_mmu_prepare_reg(hdev, mmDMA2_QM_GLBL_NON_SECURE_PROPS_1, asid);
47908c2ecf20Sopenharmony_ci	gaudi_mmu_prepare_reg(hdev, mmDMA2_QM_GLBL_NON_SECURE_PROPS_2, asid);
47918c2ecf20Sopenharmony_ci	gaudi_mmu_prepare_reg(hdev, mmDMA2_QM_GLBL_NON_SECURE_PROPS_3, asid);
47928c2ecf20Sopenharmony_ci	gaudi_mmu_prepare_reg(hdev, mmDMA2_QM_GLBL_NON_SECURE_PROPS_4, asid);
47938c2ecf20Sopenharmony_ci
47948c2ecf20Sopenharmony_ci	gaudi_mmu_prepare_reg(hdev, mmDMA3_QM_GLBL_NON_SECURE_PROPS_0, asid);
47958c2ecf20Sopenharmony_ci	gaudi_mmu_prepare_reg(hdev, mmDMA3_QM_GLBL_NON_SECURE_PROPS_1, asid);
47968c2ecf20Sopenharmony_ci	gaudi_mmu_prepare_reg(hdev, mmDMA3_QM_GLBL_NON_SECURE_PROPS_2, asid);
47978c2ecf20Sopenharmony_ci	gaudi_mmu_prepare_reg(hdev, mmDMA3_QM_GLBL_NON_SECURE_PROPS_3, asid);
47988c2ecf20Sopenharmony_ci	gaudi_mmu_prepare_reg(hdev, mmDMA3_QM_GLBL_NON_SECURE_PROPS_4, asid);
47998c2ecf20Sopenharmony_ci
48008c2ecf20Sopenharmony_ci	gaudi_mmu_prepare_reg(hdev, mmDMA4_QM_GLBL_NON_SECURE_PROPS_0, asid);
48018c2ecf20Sopenharmony_ci	gaudi_mmu_prepare_reg(hdev, mmDMA4_QM_GLBL_NON_SECURE_PROPS_1, asid);
48028c2ecf20Sopenharmony_ci	gaudi_mmu_prepare_reg(hdev, mmDMA4_QM_GLBL_NON_SECURE_PROPS_2, asid);
48038c2ecf20Sopenharmony_ci	gaudi_mmu_prepare_reg(hdev, mmDMA4_QM_GLBL_NON_SECURE_PROPS_3, asid);
48048c2ecf20Sopenharmony_ci	gaudi_mmu_prepare_reg(hdev, mmDMA4_QM_GLBL_NON_SECURE_PROPS_4, asid);
48058c2ecf20Sopenharmony_ci
48068c2ecf20Sopenharmony_ci	gaudi_mmu_prepare_reg(hdev, mmDMA5_QM_GLBL_NON_SECURE_PROPS_0, asid);
48078c2ecf20Sopenharmony_ci	gaudi_mmu_prepare_reg(hdev, mmDMA5_QM_GLBL_NON_SECURE_PROPS_1, asid);
48088c2ecf20Sopenharmony_ci	gaudi_mmu_prepare_reg(hdev, mmDMA5_QM_GLBL_NON_SECURE_PROPS_2, asid);
48098c2ecf20Sopenharmony_ci	gaudi_mmu_prepare_reg(hdev, mmDMA5_QM_GLBL_NON_SECURE_PROPS_3, asid);
48108c2ecf20Sopenharmony_ci	gaudi_mmu_prepare_reg(hdev, mmDMA5_QM_GLBL_NON_SECURE_PROPS_4, asid);
48118c2ecf20Sopenharmony_ci
48128c2ecf20Sopenharmony_ci	gaudi_mmu_prepare_reg(hdev, mmDMA6_QM_GLBL_NON_SECURE_PROPS_0, asid);
48138c2ecf20Sopenharmony_ci	gaudi_mmu_prepare_reg(hdev, mmDMA6_QM_GLBL_NON_SECURE_PROPS_1, asid);
48148c2ecf20Sopenharmony_ci	gaudi_mmu_prepare_reg(hdev, mmDMA6_QM_GLBL_NON_SECURE_PROPS_2, asid);
48158c2ecf20Sopenharmony_ci	gaudi_mmu_prepare_reg(hdev, mmDMA6_QM_GLBL_NON_SECURE_PROPS_3, asid);
48168c2ecf20Sopenharmony_ci	gaudi_mmu_prepare_reg(hdev, mmDMA6_QM_GLBL_NON_SECURE_PROPS_4, asid);
48178c2ecf20Sopenharmony_ci
48188c2ecf20Sopenharmony_ci	gaudi_mmu_prepare_reg(hdev, mmDMA7_QM_GLBL_NON_SECURE_PROPS_0, asid);
48198c2ecf20Sopenharmony_ci	gaudi_mmu_prepare_reg(hdev, mmDMA7_QM_GLBL_NON_SECURE_PROPS_1, asid);
48208c2ecf20Sopenharmony_ci	gaudi_mmu_prepare_reg(hdev, mmDMA7_QM_GLBL_NON_SECURE_PROPS_2, asid);
48218c2ecf20Sopenharmony_ci	gaudi_mmu_prepare_reg(hdev, mmDMA7_QM_GLBL_NON_SECURE_PROPS_3, asid);
48228c2ecf20Sopenharmony_ci	gaudi_mmu_prepare_reg(hdev, mmDMA7_QM_GLBL_NON_SECURE_PROPS_4, asid);
48238c2ecf20Sopenharmony_ci
48248c2ecf20Sopenharmony_ci	gaudi_mmu_prepare_reg(hdev, mmDMA0_CORE_NON_SECURE_PROPS, asid);
48258c2ecf20Sopenharmony_ci	gaudi_mmu_prepare_reg(hdev, mmDMA1_CORE_NON_SECURE_PROPS, asid);
48268c2ecf20Sopenharmony_ci	gaudi_mmu_prepare_reg(hdev, mmDMA2_CORE_NON_SECURE_PROPS, asid);
48278c2ecf20Sopenharmony_ci	gaudi_mmu_prepare_reg(hdev, mmDMA3_CORE_NON_SECURE_PROPS, asid);
48288c2ecf20Sopenharmony_ci	gaudi_mmu_prepare_reg(hdev, mmDMA4_CORE_NON_SECURE_PROPS, asid);
48298c2ecf20Sopenharmony_ci	gaudi_mmu_prepare_reg(hdev, mmDMA5_CORE_NON_SECURE_PROPS, asid);
48308c2ecf20Sopenharmony_ci	gaudi_mmu_prepare_reg(hdev, mmDMA6_CORE_NON_SECURE_PROPS, asid);
48318c2ecf20Sopenharmony_ci	gaudi_mmu_prepare_reg(hdev, mmDMA7_CORE_NON_SECURE_PROPS, asid);
48328c2ecf20Sopenharmony_ci
48338c2ecf20Sopenharmony_ci	gaudi_mmu_prepare_reg(hdev, mmTPC0_QM_GLBL_NON_SECURE_PROPS_0, asid);
48348c2ecf20Sopenharmony_ci	gaudi_mmu_prepare_reg(hdev, mmTPC0_QM_GLBL_NON_SECURE_PROPS_1, asid);
48358c2ecf20Sopenharmony_ci	gaudi_mmu_prepare_reg(hdev, mmTPC0_QM_GLBL_NON_SECURE_PROPS_2, asid);
48368c2ecf20Sopenharmony_ci	gaudi_mmu_prepare_reg(hdev, mmTPC0_QM_GLBL_NON_SECURE_PROPS_3, asid);
48378c2ecf20Sopenharmony_ci	gaudi_mmu_prepare_reg(hdev, mmTPC0_QM_GLBL_NON_SECURE_PROPS_4, asid);
48388c2ecf20Sopenharmony_ci	gaudi_mmu_prepare_reg(hdev, mmTPC0_CFG_ARUSER_LO, asid);
48398c2ecf20Sopenharmony_ci	gaudi_mmu_prepare_reg(hdev, mmTPC0_CFG_AWUSER_LO, asid);
48408c2ecf20Sopenharmony_ci
48418c2ecf20Sopenharmony_ci	gaudi_mmu_prepare_reg(hdev, mmTPC1_QM_GLBL_NON_SECURE_PROPS_0, asid);
48428c2ecf20Sopenharmony_ci	gaudi_mmu_prepare_reg(hdev, mmTPC1_QM_GLBL_NON_SECURE_PROPS_1, asid);
48438c2ecf20Sopenharmony_ci	gaudi_mmu_prepare_reg(hdev, mmTPC1_QM_GLBL_NON_SECURE_PROPS_2, asid);
48448c2ecf20Sopenharmony_ci	gaudi_mmu_prepare_reg(hdev, mmTPC1_QM_GLBL_NON_SECURE_PROPS_3, asid);
48458c2ecf20Sopenharmony_ci	gaudi_mmu_prepare_reg(hdev, mmTPC1_QM_GLBL_NON_SECURE_PROPS_4, asid);
48468c2ecf20Sopenharmony_ci	gaudi_mmu_prepare_reg(hdev, mmTPC1_CFG_ARUSER_LO, asid);
48478c2ecf20Sopenharmony_ci	gaudi_mmu_prepare_reg(hdev, mmTPC1_CFG_AWUSER_LO, asid);
48488c2ecf20Sopenharmony_ci
48498c2ecf20Sopenharmony_ci	gaudi_mmu_prepare_reg(hdev, mmTPC2_QM_GLBL_NON_SECURE_PROPS_0, asid);
48508c2ecf20Sopenharmony_ci	gaudi_mmu_prepare_reg(hdev, mmTPC2_QM_GLBL_NON_SECURE_PROPS_1, asid);
48518c2ecf20Sopenharmony_ci	gaudi_mmu_prepare_reg(hdev, mmTPC2_QM_GLBL_NON_SECURE_PROPS_2, asid);
48528c2ecf20Sopenharmony_ci	gaudi_mmu_prepare_reg(hdev, mmTPC2_QM_GLBL_NON_SECURE_PROPS_3, asid);
48538c2ecf20Sopenharmony_ci	gaudi_mmu_prepare_reg(hdev, mmTPC2_QM_GLBL_NON_SECURE_PROPS_4, asid);
48548c2ecf20Sopenharmony_ci	gaudi_mmu_prepare_reg(hdev, mmTPC2_CFG_ARUSER_LO, asid);
48558c2ecf20Sopenharmony_ci	gaudi_mmu_prepare_reg(hdev, mmTPC2_CFG_AWUSER_LO, asid);
48568c2ecf20Sopenharmony_ci
48578c2ecf20Sopenharmony_ci	gaudi_mmu_prepare_reg(hdev, mmTPC3_QM_GLBL_NON_SECURE_PROPS_0, asid);
48588c2ecf20Sopenharmony_ci	gaudi_mmu_prepare_reg(hdev, mmTPC3_QM_GLBL_NON_SECURE_PROPS_1, asid);
48598c2ecf20Sopenharmony_ci	gaudi_mmu_prepare_reg(hdev, mmTPC3_QM_GLBL_NON_SECURE_PROPS_2, asid);
48608c2ecf20Sopenharmony_ci	gaudi_mmu_prepare_reg(hdev, mmTPC3_QM_GLBL_NON_SECURE_PROPS_3, asid);
48618c2ecf20Sopenharmony_ci	gaudi_mmu_prepare_reg(hdev, mmTPC3_QM_GLBL_NON_SECURE_PROPS_4, asid);
48628c2ecf20Sopenharmony_ci	gaudi_mmu_prepare_reg(hdev, mmTPC3_CFG_ARUSER_LO, asid);
48638c2ecf20Sopenharmony_ci	gaudi_mmu_prepare_reg(hdev, mmTPC3_CFG_AWUSER_LO, asid);
48648c2ecf20Sopenharmony_ci
48658c2ecf20Sopenharmony_ci	gaudi_mmu_prepare_reg(hdev, mmTPC4_QM_GLBL_NON_SECURE_PROPS_0, asid);
48668c2ecf20Sopenharmony_ci	gaudi_mmu_prepare_reg(hdev, mmTPC4_QM_GLBL_NON_SECURE_PROPS_1, asid);
48678c2ecf20Sopenharmony_ci	gaudi_mmu_prepare_reg(hdev, mmTPC4_QM_GLBL_NON_SECURE_PROPS_2, asid);
48688c2ecf20Sopenharmony_ci	gaudi_mmu_prepare_reg(hdev, mmTPC4_QM_GLBL_NON_SECURE_PROPS_3, asid);
48698c2ecf20Sopenharmony_ci	gaudi_mmu_prepare_reg(hdev, mmTPC4_QM_GLBL_NON_SECURE_PROPS_4, asid);
48708c2ecf20Sopenharmony_ci	gaudi_mmu_prepare_reg(hdev, mmTPC4_CFG_ARUSER_LO, asid);
48718c2ecf20Sopenharmony_ci	gaudi_mmu_prepare_reg(hdev, mmTPC4_CFG_AWUSER_LO, asid);
48728c2ecf20Sopenharmony_ci
48738c2ecf20Sopenharmony_ci	gaudi_mmu_prepare_reg(hdev, mmTPC5_QM_GLBL_NON_SECURE_PROPS_0, asid);
48748c2ecf20Sopenharmony_ci	gaudi_mmu_prepare_reg(hdev, mmTPC5_QM_GLBL_NON_SECURE_PROPS_1, asid);
48758c2ecf20Sopenharmony_ci	gaudi_mmu_prepare_reg(hdev, mmTPC5_QM_GLBL_NON_SECURE_PROPS_2, asid);
48768c2ecf20Sopenharmony_ci	gaudi_mmu_prepare_reg(hdev, mmTPC5_QM_GLBL_NON_SECURE_PROPS_3, asid);
48778c2ecf20Sopenharmony_ci	gaudi_mmu_prepare_reg(hdev, mmTPC5_QM_GLBL_NON_SECURE_PROPS_4, asid);
48788c2ecf20Sopenharmony_ci	gaudi_mmu_prepare_reg(hdev, mmTPC5_CFG_ARUSER_LO, asid);
48798c2ecf20Sopenharmony_ci	gaudi_mmu_prepare_reg(hdev, mmTPC5_CFG_AWUSER_LO, asid);
48808c2ecf20Sopenharmony_ci
48818c2ecf20Sopenharmony_ci	gaudi_mmu_prepare_reg(hdev, mmTPC6_QM_GLBL_NON_SECURE_PROPS_0, asid);
48828c2ecf20Sopenharmony_ci	gaudi_mmu_prepare_reg(hdev, mmTPC6_QM_GLBL_NON_SECURE_PROPS_1, asid);
48838c2ecf20Sopenharmony_ci	gaudi_mmu_prepare_reg(hdev, mmTPC6_QM_GLBL_NON_SECURE_PROPS_2, asid);
48848c2ecf20Sopenharmony_ci	gaudi_mmu_prepare_reg(hdev, mmTPC6_QM_GLBL_NON_SECURE_PROPS_3, asid);
48858c2ecf20Sopenharmony_ci	gaudi_mmu_prepare_reg(hdev, mmTPC6_QM_GLBL_NON_SECURE_PROPS_4, asid);
48868c2ecf20Sopenharmony_ci	gaudi_mmu_prepare_reg(hdev, mmTPC6_CFG_ARUSER_LO, asid);
48878c2ecf20Sopenharmony_ci	gaudi_mmu_prepare_reg(hdev, mmTPC6_CFG_AWUSER_LO, asid);
48888c2ecf20Sopenharmony_ci
48898c2ecf20Sopenharmony_ci	gaudi_mmu_prepare_reg(hdev, mmTPC7_QM_GLBL_NON_SECURE_PROPS_0, asid);
48908c2ecf20Sopenharmony_ci	gaudi_mmu_prepare_reg(hdev, mmTPC7_QM_GLBL_NON_SECURE_PROPS_1, asid);
48918c2ecf20Sopenharmony_ci	gaudi_mmu_prepare_reg(hdev, mmTPC7_QM_GLBL_NON_SECURE_PROPS_2, asid);
48928c2ecf20Sopenharmony_ci	gaudi_mmu_prepare_reg(hdev, mmTPC7_QM_GLBL_NON_SECURE_PROPS_3, asid);
48938c2ecf20Sopenharmony_ci	gaudi_mmu_prepare_reg(hdev, mmTPC7_QM_GLBL_NON_SECURE_PROPS_4, asid);
48948c2ecf20Sopenharmony_ci	gaudi_mmu_prepare_reg(hdev, mmTPC7_CFG_ARUSER_LO, asid);
48958c2ecf20Sopenharmony_ci	gaudi_mmu_prepare_reg(hdev, mmTPC7_CFG_AWUSER_LO, asid);
48968c2ecf20Sopenharmony_ci
48978c2ecf20Sopenharmony_ci	gaudi_mmu_prepare_reg(hdev, mmMME0_QM_GLBL_NON_SECURE_PROPS_0, asid);
48988c2ecf20Sopenharmony_ci	gaudi_mmu_prepare_reg(hdev, mmMME0_QM_GLBL_NON_SECURE_PROPS_1, asid);
48998c2ecf20Sopenharmony_ci	gaudi_mmu_prepare_reg(hdev, mmMME0_QM_GLBL_NON_SECURE_PROPS_2, asid);
49008c2ecf20Sopenharmony_ci	gaudi_mmu_prepare_reg(hdev, mmMME0_QM_GLBL_NON_SECURE_PROPS_3, asid);
49018c2ecf20Sopenharmony_ci	gaudi_mmu_prepare_reg(hdev, mmMME0_QM_GLBL_NON_SECURE_PROPS_4, asid);
49028c2ecf20Sopenharmony_ci	gaudi_mmu_prepare_reg(hdev, mmMME2_QM_GLBL_NON_SECURE_PROPS_0, asid);
49038c2ecf20Sopenharmony_ci	gaudi_mmu_prepare_reg(hdev, mmMME2_QM_GLBL_NON_SECURE_PROPS_1, asid);
49048c2ecf20Sopenharmony_ci	gaudi_mmu_prepare_reg(hdev, mmMME2_QM_GLBL_NON_SECURE_PROPS_2, asid);
49058c2ecf20Sopenharmony_ci	gaudi_mmu_prepare_reg(hdev, mmMME2_QM_GLBL_NON_SECURE_PROPS_3, asid);
49068c2ecf20Sopenharmony_ci	gaudi_mmu_prepare_reg(hdev, mmMME2_QM_GLBL_NON_SECURE_PROPS_4, asid);
49078c2ecf20Sopenharmony_ci
49088c2ecf20Sopenharmony_ci	gaudi_mmu_prepare_reg(hdev, mmMME0_SBAB_ARUSER0, asid);
49098c2ecf20Sopenharmony_ci	gaudi_mmu_prepare_reg(hdev, mmMME0_SBAB_ARUSER1, asid);
49108c2ecf20Sopenharmony_ci	gaudi_mmu_prepare_reg(hdev, mmMME1_SBAB_ARUSER0, asid);
49118c2ecf20Sopenharmony_ci	gaudi_mmu_prepare_reg(hdev, mmMME1_SBAB_ARUSER1, asid);
49128c2ecf20Sopenharmony_ci	gaudi_mmu_prepare_reg(hdev, mmMME2_SBAB_ARUSER0, asid);
49138c2ecf20Sopenharmony_ci	gaudi_mmu_prepare_reg(hdev, mmMME2_SBAB_ARUSER1, asid);
49148c2ecf20Sopenharmony_ci	gaudi_mmu_prepare_reg(hdev, mmMME3_SBAB_ARUSER0, asid);
49158c2ecf20Sopenharmony_ci	gaudi_mmu_prepare_reg(hdev, mmMME3_SBAB_ARUSER1, asid);
49168c2ecf20Sopenharmony_ci	gaudi_mmu_prepare_reg(hdev, mmMME0_ACC_WBC, asid);
49178c2ecf20Sopenharmony_ci	gaudi_mmu_prepare_reg(hdev, mmMME1_ACC_WBC, asid);
49188c2ecf20Sopenharmony_ci	gaudi_mmu_prepare_reg(hdev, mmMME2_ACC_WBC, asid);
49198c2ecf20Sopenharmony_ci	gaudi_mmu_prepare_reg(hdev, mmMME3_ACC_WBC, asid);
49208c2ecf20Sopenharmony_ci
49218c2ecf20Sopenharmony_ci	hdev->asic_funcs->set_clock_gating(hdev);
49228c2ecf20Sopenharmony_ci
49238c2ecf20Sopenharmony_ci	mutex_unlock(&gaudi->clk_gate_mutex);
49248c2ecf20Sopenharmony_ci}
49258c2ecf20Sopenharmony_ci
49268c2ecf20Sopenharmony_cistatic int gaudi_send_job_on_qman0(struct hl_device *hdev,
49278c2ecf20Sopenharmony_ci		struct hl_cs_job *job)
49288c2ecf20Sopenharmony_ci{
49298c2ecf20Sopenharmony_ci	struct packet_msg_prot *fence_pkt;
49308c2ecf20Sopenharmony_ci	u32 *fence_ptr;
49318c2ecf20Sopenharmony_ci	dma_addr_t fence_dma_addr;
49328c2ecf20Sopenharmony_ci	struct hl_cb *cb;
49338c2ecf20Sopenharmony_ci	u32 tmp, timeout, dma_offset;
49348c2ecf20Sopenharmony_ci	int rc;
49358c2ecf20Sopenharmony_ci
49368c2ecf20Sopenharmony_ci	if (hdev->pldm)
49378c2ecf20Sopenharmony_ci		timeout = GAUDI_PLDM_QMAN0_TIMEOUT_USEC;
49388c2ecf20Sopenharmony_ci	else
49398c2ecf20Sopenharmony_ci		timeout = HL_DEVICE_TIMEOUT_USEC;
49408c2ecf20Sopenharmony_ci
49418c2ecf20Sopenharmony_ci	if (!hdev->asic_funcs->is_device_idle(hdev, NULL, NULL)) {
49428c2ecf20Sopenharmony_ci		dev_err_ratelimited(hdev->dev,
49438c2ecf20Sopenharmony_ci			"Can't send driver job on QMAN0 because the device is not idle\n");
49448c2ecf20Sopenharmony_ci		return -EBUSY;
49458c2ecf20Sopenharmony_ci	}
49468c2ecf20Sopenharmony_ci
49478c2ecf20Sopenharmony_ci	fence_ptr = hdev->asic_funcs->asic_dma_pool_zalloc(hdev, 4, GFP_KERNEL,
49488c2ecf20Sopenharmony_ci							&fence_dma_addr);
49498c2ecf20Sopenharmony_ci	if (!fence_ptr) {
49508c2ecf20Sopenharmony_ci		dev_err(hdev->dev,
49518c2ecf20Sopenharmony_ci			"Failed to allocate fence memory for QMAN0\n");
49528c2ecf20Sopenharmony_ci		return -ENOMEM;
49538c2ecf20Sopenharmony_ci	}
49548c2ecf20Sopenharmony_ci
49558c2ecf20Sopenharmony_ci	cb = job->patched_cb;
49568c2ecf20Sopenharmony_ci
49578c2ecf20Sopenharmony_ci	fence_pkt = cb->kernel_address +
49588c2ecf20Sopenharmony_ci			job->job_cb_size - sizeof(struct packet_msg_prot);
49598c2ecf20Sopenharmony_ci
49608c2ecf20Sopenharmony_ci	tmp = FIELD_PREP(GAUDI_PKT_CTL_OPCODE_MASK, PACKET_MSG_PROT);
49618c2ecf20Sopenharmony_ci	tmp |= FIELD_PREP(GAUDI_PKT_CTL_EB_MASK, 1);
49628c2ecf20Sopenharmony_ci	tmp |= FIELD_PREP(GAUDI_PKT_CTL_MB_MASK, 1);
49638c2ecf20Sopenharmony_ci
49648c2ecf20Sopenharmony_ci	fence_pkt->ctl = cpu_to_le32(tmp);
49658c2ecf20Sopenharmony_ci	fence_pkt->value = cpu_to_le32(GAUDI_QMAN0_FENCE_VAL);
49668c2ecf20Sopenharmony_ci	fence_pkt->addr = cpu_to_le64(fence_dma_addr);
49678c2ecf20Sopenharmony_ci
49688c2ecf20Sopenharmony_ci	dma_offset = gaudi_dma_assignment[GAUDI_PCI_DMA_1] * DMA_CORE_OFFSET;
49698c2ecf20Sopenharmony_ci
49708c2ecf20Sopenharmony_ci	WREG32_OR(mmDMA0_CORE_PROT + dma_offset, BIT(DMA0_CORE_PROT_VAL_SHIFT));
49718c2ecf20Sopenharmony_ci
49728c2ecf20Sopenharmony_ci	rc = hl_hw_queue_send_cb_no_cmpl(hdev, GAUDI_QUEUE_ID_DMA_0_0,
49738c2ecf20Sopenharmony_ci					job->job_cb_size, cb->bus_address);
49748c2ecf20Sopenharmony_ci	if (rc) {
49758c2ecf20Sopenharmony_ci		dev_err(hdev->dev, "Failed to send CB on QMAN0, %d\n", rc);
49768c2ecf20Sopenharmony_ci		goto free_fence_ptr;
49778c2ecf20Sopenharmony_ci	}
49788c2ecf20Sopenharmony_ci
49798c2ecf20Sopenharmony_ci	rc = hl_poll_timeout_memory(hdev, fence_ptr, tmp,
49808c2ecf20Sopenharmony_ci				(tmp == GAUDI_QMAN0_FENCE_VAL), 1000,
49818c2ecf20Sopenharmony_ci				timeout, true);
49828c2ecf20Sopenharmony_ci
49838c2ecf20Sopenharmony_ci	hl_hw_queue_inc_ci_kernel(hdev, GAUDI_QUEUE_ID_DMA_0_0);
49848c2ecf20Sopenharmony_ci
49858c2ecf20Sopenharmony_ci	if (rc == -ETIMEDOUT) {
49868c2ecf20Sopenharmony_ci		dev_err(hdev->dev, "QMAN0 Job timeout (0x%x)\n", tmp);
49878c2ecf20Sopenharmony_ci		goto free_fence_ptr;
49888c2ecf20Sopenharmony_ci	}
49898c2ecf20Sopenharmony_ci
49908c2ecf20Sopenharmony_cifree_fence_ptr:
49918c2ecf20Sopenharmony_ci	WREG32_AND(mmDMA0_CORE_PROT + dma_offset,
49928c2ecf20Sopenharmony_ci			~BIT(DMA0_CORE_PROT_VAL_SHIFT));
49938c2ecf20Sopenharmony_ci
49948c2ecf20Sopenharmony_ci	hdev->asic_funcs->asic_dma_pool_free(hdev, (void *) fence_ptr,
49958c2ecf20Sopenharmony_ci					fence_dma_addr);
49968c2ecf20Sopenharmony_ci	return rc;
49978c2ecf20Sopenharmony_ci}
49988c2ecf20Sopenharmony_ci
49998c2ecf20Sopenharmony_cistatic void gaudi_get_event_desc(u16 event_type, char *desc, size_t size)
50008c2ecf20Sopenharmony_ci{
50018c2ecf20Sopenharmony_ci	if (event_type >= GAUDI_EVENT_SIZE)
50028c2ecf20Sopenharmony_ci		goto event_not_supported;
50038c2ecf20Sopenharmony_ci
50048c2ecf20Sopenharmony_ci	if (!gaudi_irq_map_table[event_type].valid)
50058c2ecf20Sopenharmony_ci		goto event_not_supported;
50068c2ecf20Sopenharmony_ci
50078c2ecf20Sopenharmony_ci	snprintf(desc, size, gaudi_irq_map_table[event_type].name);
50088c2ecf20Sopenharmony_ci
50098c2ecf20Sopenharmony_ci	return;
50108c2ecf20Sopenharmony_ci
50118c2ecf20Sopenharmony_cievent_not_supported:
50128c2ecf20Sopenharmony_ci	snprintf(desc, size, "N/A");
50138c2ecf20Sopenharmony_ci}
50148c2ecf20Sopenharmony_ci
50158c2ecf20Sopenharmony_cistatic const char *gaudi_get_razwi_initiator_dma_name(struct hl_device *hdev,
50168c2ecf20Sopenharmony_ci							u32 x_y, bool is_write)
50178c2ecf20Sopenharmony_ci{
50188c2ecf20Sopenharmony_ci	u32 dma_id[2], dma_offset, err_cause[2], mask, i;
50198c2ecf20Sopenharmony_ci
50208c2ecf20Sopenharmony_ci	mask = is_write ? DMA0_CORE_ERR_CAUSE_HBW_WR_ERR_MASK :
50218c2ecf20Sopenharmony_ci				DMA0_CORE_ERR_CAUSE_HBW_RD_ERR_MASK;
50228c2ecf20Sopenharmony_ci
50238c2ecf20Sopenharmony_ci	switch (x_y) {
50248c2ecf20Sopenharmony_ci	case RAZWI_INITIATOR_ID_X_Y_DMA_IF_W_S_0:
50258c2ecf20Sopenharmony_ci	case RAZWI_INITIATOR_ID_X_Y_DMA_IF_W_S_1:
50268c2ecf20Sopenharmony_ci		dma_id[0] = 0;
50278c2ecf20Sopenharmony_ci		dma_id[1] = 2;
50288c2ecf20Sopenharmony_ci		break;
50298c2ecf20Sopenharmony_ci	case RAZWI_INITIATOR_ID_X_Y_DMA_IF_E_S_0:
50308c2ecf20Sopenharmony_ci	case RAZWI_INITIATOR_ID_X_Y_DMA_IF_E_S_1:
50318c2ecf20Sopenharmony_ci		dma_id[0] = 1;
50328c2ecf20Sopenharmony_ci		dma_id[1] = 3;
50338c2ecf20Sopenharmony_ci		break;
50348c2ecf20Sopenharmony_ci	case RAZWI_INITIATOR_ID_X_Y_DMA_IF_W_N_0:
50358c2ecf20Sopenharmony_ci	case RAZWI_INITIATOR_ID_X_Y_DMA_IF_W_N_1:
50368c2ecf20Sopenharmony_ci		dma_id[0] = 4;
50378c2ecf20Sopenharmony_ci		dma_id[1] = 6;
50388c2ecf20Sopenharmony_ci		break;
50398c2ecf20Sopenharmony_ci	case RAZWI_INITIATOR_ID_X_Y_DMA_IF_E_N_0:
50408c2ecf20Sopenharmony_ci	case RAZWI_INITIATOR_ID_X_Y_DMA_IF_E_N_1:
50418c2ecf20Sopenharmony_ci		dma_id[0] = 5;
50428c2ecf20Sopenharmony_ci		dma_id[1] = 7;
50438c2ecf20Sopenharmony_ci		break;
50448c2ecf20Sopenharmony_ci	default:
50458c2ecf20Sopenharmony_ci		goto unknown_initiator;
50468c2ecf20Sopenharmony_ci	}
50478c2ecf20Sopenharmony_ci
50488c2ecf20Sopenharmony_ci	for (i = 0 ; i < 2 ; i++) {
50498c2ecf20Sopenharmony_ci		dma_offset = dma_id[i] * DMA_CORE_OFFSET;
50508c2ecf20Sopenharmony_ci		err_cause[i] = RREG32(mmDMA0_CORE_ERR_CAUSE + dma_offset);
50518c2ecf20Sopenharmony_ci	}
50528c2ecf20Sopenharmony_ci
50538c2ecf20Sopenharmony_ci	switch (x_y) {
50548c2ecf20Sopenharmony_ci	case RAZWI_INITIATOR_ID_X_Y_DMA_IF_W_S_0:
50558c2ecf20Sopenharmony_ci	case RAZWI_INITIATOR_ID_X_Y_DMA_IF_W_S_1:
50568c2ecf20Sopenharmony_ci		if ((err_cause[0] & mask) && !(err_cause[1] & mask))
50578c2ecf20Sopenharmony_ci			return "DMA0";
50588c2ecf20Sopenharmony_ci		else if (!(err_cause[0] & mask) && (err_cause[1] & mask))
50598c2ecf20Sopenharmony_ci			return "DMA2";
50608c2ecf20Sopenharmony_ci		else
50618c2ecf20Sopenharmony_ci			return "DMA0 or DMA2";
50628c2ecf20Sopenharmony_ci	case RAZWI_INITIATOR_ID_X_Y_DMA_IF_E_S_0:
50638c2ecf20Sopenharmony_ci	case RAZWI_INITIATOR_ID_X_Y_DMA_IF_E_S_1:
50648c2ecf20Sopenharmony_ci		if ((err_cause[0] & mask) && !(err_cause[1] & mask))
50658c2ecf20Sopenharmony_ci			return "DMA1";
50668c2ecf20Sopenharmony_ci		else if (!(err_cause[0] & mask) && (err_cause[1] & mask))
50678c2ecf20Sopenharmony_ci			return "DMA3";
50688c2ecf20Sopenharmony_ci		else
50698c2ecf20Sopenharmony_ci			return "DMA1 or DMA3";
50708c2ecf20Sopenharmony_ci	case RAZWI_INITIATOR_ID_X_Y_DMA_IF_W_N_0:
50718c2ecf20Sopenharmony_ci	case RAZWI_INITIATOR_ID_X_Y_DMA_IF_W_N_1:
50728c2ecf20Sopenharmony_ci		if ((err_cause[0] & mask) && !(err_cause[1] & mask))
50738c2ecf20Sopenharmony_ci			return "DMA4";
50748c2ecf20Sopenharmony_ci		else if (!(err_cause[0] & mask) && (err_cause[1] & mask))
50758c2ecf20Sopenharmony_ci			return "DMA6";
50768c2ecf20Sopenharmony_ci		else
50778c2ecf20Sopenharmony_ci			return "DMA4 or DMA6";
50788c2ecf20Sopenharmony_ci	case RAZWI_INITIATOR_ID_X_Y_DMA_IF_E_N_0:
50798c2ecf20Sopenharmony_ci	case RAZWI_INITIATOR_ID_X_Y_DMA_IF_E_N_1:
50808c2ecf20Sopenharmony_ci		if ((err_cause[0] & mask) && !(err_cause[1] & mask))
50818c2ecf20Sopenharmony_ci			return "DMA5";
50828c2ecf20Sopenharmony_ci		else if (!(err_cause[0] & mask) && (err_cause[1] & mask))
50838c2ecf20Sopenharmony_ci			return "DMA7";
50848c2ecf20Sopenharmony_ci		else
50858c2ecf20Sopenharmony_ci			return "DMA5 or DMA7";
50868c2ecf20Sopenharmony_ci	}
50878c2ecf20Sopenharmony_ci
50888c2ecf20Sopenharmony_ciunknown_initiator:
50898c2ecf20Sopenharmony_ci	return "unknown initiator";
50908c2ecf20Sopenharmony_ci}
50918c2ecf20Sopenharmony_ci
50928c2ecf20Sopenharmony_cistatic const char *gaudi_get_razwi_initiator_name(struct hl_device *hdev,
50938c2ecf20Sopenharmony_ci							bool is_write)
50948c2ecf20Sopenharmony_ci{
50958c2ecf20Sopenharmony_ci	u32 val, x_y, axi_id;
50968c2ecf20Sopenharmony_ci
50978c2ecf20Sopenharmony_ci	val = is_write ? RREG32(mmMMU_UP_RAZWI_WRITE_ID) :
50988c2ecf20Sopenharmony_ci				RREG32(mmMMU_UP_RAZWI_READ_ID);
50998c2ecf20Sopenharmony_ci	x_y = val & ((RAZWI_INITIATOR_Y_MASK << RAZWI_INITIATOR_Y_SHIFT) |
51008c2ecf20Sopenharmony_ci			(RAZWI_INITIATOR_X_MASK << RAZWI_INITIATOR_X_SHIFT));
51018c2ecf20Sopenharmony_ci	axi_id = val & (RAZWI_INITIATOR_AXI_ID_MASK <<
51028c2ecf20Sopenharmony_ci			RAZWI_INITIATOR_AXI_ID_SHIFT);
51038c2ecf20Sopenharmony_ci
51048c2ecf20Sopenharmony_ci	switch (x_y) {
51058c2ecf20Sopenharmony_ci	case RAZWI_INITIATOR_ID_X_Y_TPC0_NIC0:
51068c2ecf20Sopenharmony_ci		if (axi_id == RAZWI_INITIATOR_ID_AXI_ID(AXI_ID_TPC))
51078c2ecf20Sopenharmony_ci			return "TPC0";
51088c2ecf20Sopenharmony_ci		if (axi_id == RAZWI_INITIATOR_ID_AXI_ID(AXI_ID_NIC))
51098c2ecf20Sopenharmony_ci			return "NIC0";
51108c2ecf20Sopenharmony_ci		break;
51118c2ecf20Sopenharmony_ci	case RAZWI_INITIATOR_ID_X_Y_TPC1:
51128c2ecf20Sopenharmony_ci		return "TPC1";
51138c2ecf20Sopenharmony_ci	case RAZWI_INITIATOR_ID_X_Y_MME0_0:
51148c2ecf20Sopenharmony_ci	case RAZWI_INITIATOR_ID_X_Y_MME0_1:
51158c2ecf20Sopenharmony_ci		return "MME0";
51168c2ecf20Sopenharmony_ci	case RAZWI_INITIATOR_ID_X_Y_MME1_0:
51178c2ecf20Sopenharmony_ci	case RAZWI_INITIATOR_ID_X_Y_MME1_1:
51188c2ecf20Sopenharmony_ci		return "MME1";
51198c2ecf20Sopenharmony_ci	case RAZWI_INITIATOR_ID_X_Y_TPC2:
51208c2ecf20Sopenharmony_ci		return "TPC2";
51218c2ecf20Sopenharmony_ci	case RAZWI_INITIATOR_ID_X_Y_TPC3_PCI_CPU_PSOC:
51228c2ecf20Sopenharmony_ci		if (axi_id == RAZWI_INITIATOR_ID_AXI_ID(AXI_ID_TPC))
51238c2ecf20Sopenharmony_ci			return "TPC3";
51248c2ecf20Sopenharmony_ci		if (axi_id == RAZWI_INITIATOR_ID_AXI_ID(AXI_ID_PCI))
51258c2ecf20Sopenharmony_ci			return "PCI";
51268c2ecf20Sopenharmony_ci		if (axi_id == RAZWI_INITIATOR_ID_AXI_ID(AXI_ID_CPU))
51278c2ecf20Sopenharmony_ci			return "CPU";
51288c2ecf20Sopenharmony_ci		if (axi_id == RAZWI_INITIATOR_ID_AXI_ID(AXI_ID_PSOC))
51298c2ecf20Sopenharmony_ci			return "PSOC";
51308c2ecf20Sopenharmony_ci		break;
51318c2ecf20Sopenharmony_ci	case RAZWI_INITIATOR_ID_X_Y_DMA_IF_W_S_0:
51328c2ecf20Sopenharmony_ci	case RAZWI_INITIATOR_ID_X_Y_DMA_IF_W_S_1:
51338c2ecf20Sopenharmony_ci	case RAZWI_INITIATOR_ID_X_Y_DMA_IF_E_S_0:
51348c2ecf20Sopenharmony_ci	case RAZWI_INITIATOR_ID_X_Y_DMA_IF_E_S_1:
51358c2ecf20Sopenharmony_ci	case RAZWI_INITIATOR_ID_X_Y_DMA_IF_W_N_0:
51368c2ecf20Sopenharmony_ci	case RAZWI_INITIATOR_ID_X_Y_DMA_IF_W_N_1:
51378c2ecf20Sopenharmony_ci	case RAZWI_INITIATOR_ID_X_Y_DMA_IF_E_N_0:
51388c2ecf20Sopenharmony_ci	case RAZWI_INITIATOR_ID_X_Y_DMA_IF_E_N_1:
51398c2ecf20Sopenharmony_ci		return gaudi_get_razwi_initiator_dma_name(hdev, x_y, is_write);
51408c2ecf20Sopenharmony_ci	case RAZWI_INITIATOR_ID_X_Y_TPC4_NIC1_NIC2:
51418c2ecf20Sopenharmony_ci		if (axi_id == RAZWI_INITIATOR_ID_AXI_ID(AXI_ID_TPC))
51428c2ecf20Sopenharmony_ci			return "TPC4";
51438c2ecf20Sopenharmony_ci		if (axi_id == RAZWI_INITIATOR_ID_AXI_ID(AXI_ID_NIC))
51448c2ecf20Sopenharmony_ci			return "NIC1";
51458c2ecf20Sopenharmony_ci		if (axi_id == RAZWI_INITIATOR_ID_AXI_ID(AXI_ID_NIC_FT))
51468c2ecf20Sopenharmony_ci			return "NIC2";
51478c2ecf20Sopenharmony_ci		break;
51488c2ecf20Sopenharmony_ci	case RAZWI_INITIATOR_ID_X_Y_TPC5:
51498c2ecf20Sopenharmony_ci		return "TPC5";
51508c2ecf20Sopenharmony_ci	case RAZWI_INITIATOR_ID_X_Y_MME2_0:
51518c2ecf20Sopenharmony_ci	case RAZWI_INITIATOR_ID_X_Y_MME2_1:
51528c2ecf20Sopenharmony_ci		return "MME2";
51538c2ecf20Sopenharmony_ci	case RAZWI_INITIATOR_ID_X_Y_MME3_0:
51548c2ecf20Sopenharmony_ci	case RAZWI_INITIATOR_ID_X_Y_MME3_1:
51558c2ecf20Sopenharmony_ci		return "MME3";
51568c2ecf20Sopenharmony_ci	case RAZWI_INITIATOR_ID_X_Y_TPC6:
51578c2ecf20Sopenharmony_ci		return "TPC6";
51588c2ecf20Sopenharmony_ci	case RAZWI_INITIATOR_ID_X_Y_TPC7_NIC4_NIC5:
51598c2ecf20Sopenharmony_ci		if (axi_id == RAZWI_INITIATOR_ID_AXI_ID(AXI_ID_TPC))
51608c2ecf20Sopenharmony_ci			return "TPC7";
51618c2ecf20Sopenharmony_ci		if (axi_id == RAZWI_INITIATOR_ID_AXI_ID(AXI_ID_NIC))
51628c2ecf20Sopenharmony_ci			return "NIC4";
51638c2ecf20Sopenharmony_ci		if (axi_id == RAZWI_INITIATOR_ID_AXI_ID(AXI_ID_NIC_FT))
51648c2ecf20Sopenharmony_ci			return "NIC5";
51658c2ecf20Sopenharmony_ci		break;
51668c2ecf20Sopenharmony_ci	default:
51678c2ecf20Sopenharmony_ci		break;
51688c2ecf20Sopenharmony_ci	}
51698c2ecf20Sopenharmony_ci
51708c2ecf20Sopenharmony_ci	dev_err(hdev->dev,
51718c2ecf20Sopenharmony_ci		"Unknown RAZWI initiator ID 0x%x [Y=%d, X=%d, AXI_ID=%d]\n",
51728c2ecf20Sopenharmony_ci		val,
51738c2ecf20Sopenharmony_ci		(val >> RAZWI_INITIATOR_Y_SHIFT) & RAZWI_INITIATOR_Y_MASK,
51748c2ecf20Sopenharmony_ci		(val >> RAZWI_INITIATOR_X_SHIFT) & RAZWI_INITIATOR_X_MASK,
51758c2ecf20Sopenharmony_ci		(val >> RAZWI_INITIATOR_AXI_ID_SHIFT) &
51768c2ecf20Sopenharmony_ci			RAZWI_INITIATOR_AXI_ID_MASK);
51778c2ecf20Sopenharmony_ci
51788c2ecf20Sopenharmony_ci	return "unknown initiator";
51798c2ecf20Sopenharmony_ci}
51808c2ecf20Sopenharmony_ci
51818c2ecf20Sopenharmony_cistatic void gaudi_print_razwi_info(struct hl_device *hdev)
51828c2ecf20Sopenharmony_ci{
51838c2ecf20Sopenharmony_ci	if (RREG32(mmMMU_UP_RAZWI_WRITE_VLD)) {
51848c2ecf20Sopenharmony_ci		dev_err_ratelimited(hdev->dev,
51858c2ecf20Sopenharmony_ci			"RAZWI event caused by illegal write of %s\n",
51868c2ecf20Sopenharmony_ci			gaudi_get_razwi_initiator_name(hdev, true));
51878c2ecf20Sopenharmony_ci		WREG32(mmMMU_UP_RAZWI_WRITE_VLD, 0);
51888c2ecf20Sopenharmony_ci	}
51898c2ecf20Sopenharmony_ci
51908c2ecf20Sopenharmony_ci	if (RREG32(mmMMU_UP_RAZWI_READ_VLD)) {
51918c2ecf20Sopenharmony_ci		dev_err_ratelimited(hdev->dev,
51928c2ecf20Sopenharmony_ci			"RAZWI event caused by illegal read of %s\n",
51938c2ecf20Sopenharmony_ci			gaudi_get_razwi_initiator_name(hdev, false));
51948c2ecf20Sopenharmony_ci		WREG32(mmMMU_UP_RAZWI_READ_VLD, 0);
51958c2ecf20Sopenharmony_ci	}
51968c2ecf20Sopenharmony_ci}
51978c2ecf20Sopenharmony_ci
51988c2ecf20Sopenharmony_cistatic void gaudi_print_mmu_error_info(struct hl_device *hdev)
51998c2ecf20Sopenharmony_ci{
52008c2ecf20Sopenharmony_ci	struct gaudi_device *gaudi = hdev->asic_specific;
52018c2ecf20Sopenharmony_ci	u64 addr;
52028c2ecf20Sopenharmony_ci	u32 val;
52038c2ecf20Sopenharmony_ci
52048c2ecf20Sopenharmony_ci	if (!(gaudi->hw_cap_initialized & HW_CAP_MMU))
52058c2ecf20Sopenharmony_ci		return;
52068c2ecf20Sopenharmony_ci
52078c2ecf20Sopenharmony_ci	val = RREG32(mmMMU_UP_PAGE_ERROR_CAPTURE);
52088c2ecf20Sopenharmony_ci	if (val & MMU_UP_PAGE_ERROR_CAPTURE_ENTRY_VALID_MASK) {
52098c2ecf20Sopenharmony_ci		addr = val & MMU_UP_PAGE_ERROR_CAPTURE_VA_49_32_MASK;
52108c2ecf20Sopenharmony_ci		addr <<= 32;
52118c2ecf20Sopenharmony_ci		addr |= RREG32(mmMMU_UP_PAGE_ERROR_CAPTURE_VA);
52128c2ecf20Sopenharmony_ci
52138c2ecf20Sopenharmony_ci		dev_err_ratelimited(hdev->dev, "MMU page fault on va 0x%llx\n",
52148c2ecf20Sopenharmony_ci					addr);
52158c2ecf20Sopenharmony_ci
52168c2ecf20Sopenharmony_ci		WREG32(mmMMU_UP_PAGE_ERROR_CAPTURE, 0);
52178c2ecf20Sopenharmony_ci	}
52188c2ecf20Sopenharmony_ci
52198c2ecf20Sopenharmony_ci	val = RREG32(mmMMU_UP_ACCESS_ERROR_CAPTURE);
52208c2ecf20Sopenharmony_ci	if (val & MMU_UP_ACCESS_ERROR_CAPTURE_ENTRY_VALID_MASK) {
52218c2ecf20Sopenharmony_ci		addr = val & MMU_UP_ACCESS_ERROR_CAPTURE_VA_49_32_MASK;
52228c2ecf20Sopenharmony_ci		addr <<= 32;
52238c2ecf20Sopenharmony_ci		addr |= RREG32(mmMMU_UP_ACCESS_ERROR_CAPTURE_VA);
52248c2ecf20Sopenharmony_ci
52258c2ecf20Sopenharmony_ci		dev_err_ratelimited(hdev->dev,
52268c2ecf20Sopenharmony_ci				"MMU access error on va 0x%llx\n", addr);
52278c2ecf20Sopenharmony_ci
52288c2ecf20Sopenharmony_ci		WREG32(mmMMU_UP_ACCESS_ERROR_CAPTURE, 0);
52298c2ecf20Sopenharmony_ci	}
52308c2ecf20Sopenharmony_ci}
52318c2ecf20Sopenharmony_ci
52328c2ecf20Sopenharmony_ci/*
52338c2ecf20Sopenharmony_ci *  +-------------------+------------------------------------------------------+
52348c2ecf20Sopenharmony_ci *  | Configuration Reg |                     Description                      |
52358c2ecf20Sopenharmony_ci *  |      Address      |                                                      |
52368c2ecf20Sopenharmony_ci *  +-------------------+------------------------------------------------------+
52378c2ecf20Sopenharmony_ci *  |  0xF30 - 0xF3F    |ECC single error indication (1 bit per memory wrapper)|
52388c2ecf20Sopenharmony_ci *  |                   |0xF30 memory wrappers 31:0 (MSB to LSB)               |
52398c2ecf20Sopenharmony_ci *  |                   |0xF34 memory wrappers 63:32                           |
52408c2ecf20Sopenharmony_ci *  |                   |0xF38 memory wrappers 95:64                           |
52418c2ecf20Sopenharmony_ci *  |                   |0xF3C memory wrappers 127:96                          |
52428c2ecf20Sopenharmony_ci *  +-------------------+------------------------------------------------------+
52438c2ecf20Sopenharmony_ci *  |  0xF40 - 0xF4F    |ECC double error indication (1 bit per memory wrapper)|
52448c2ecf20Sopenharmony_ci *  |                   |0xF40 memory wrappers 31:0 (MSB to LSB)               |
52458c2ecf20Sopenharmony_ci *  |                   |0xF44 memory wrappers 63:32                           |
52468c2ecf20Sopenharmony_ci *  |                   |0xF48 memory wrappers 95:64                           |
52478c2ecf20Sopenharmony_ci *  |                   |0xF4C memory wrappers 127:96                          |
52488c2ecf20Sopenharmony_ci *  +-------------------+------------------------------------------------------+
52498c2ecf20Sopenharmony_ci */
52508c2ecf20Sopenharmony_cistatic int gaudi_extract_ecc_info(struct hl_device *hdev,
52518c2ecf20Sopenharmony_ci		struct ecc_info_extract_params *params, u64 *ecc_address,
52528c2ecf20Sopenharmony_ci		u64 *ecc_syndrom, u8 *memory_wrapper_idx)
52538c2ecf20Sopenharmony_ci{
52548c2ecf20Sopenharmony_ci	struct gaudi_device *gaudi = hdev->asic_specific;
52558c2ecf20Sopenharmony_ci	u32 i, num_mem_regs, reg, err_bit;
52568c2ecf20Sopenharmony_ci	u64 err_addr, err_word = 0;
52578c2ecf20Sopenharmony_ci	int rc = 0;
52588c2ecf20Sopenharmony_ci
52598c2ecf20Sopenharmony_ci	num_mem_regs = params->num_memories / 32 +
52608c2ecf20Sopenharmony_ci			((params->num_memories % 32) ? 1 : 0);
52618c2ecf20Sopenharmony_ci
52628c2ecf20Sopenharmony_ci	if (params->block_address >= CFG_BASE)
52638c2ecf20Sopenharmony_ci		params->block_address -= CFG_BASE;
52648c2ecf20Sopenharmony_ci
52658c2ecf20Sopenharmony_ci	if (params->derr)
52668c2ecf20Sopenharmony_ci		err_addr = params->block_address + GAUDI_ECC_DERR0_OFFSET;
52678c2ecf20Sopenharmony_ci	else
52688c2ecf20Sopenharmony_ci		err_addr = params->block_address + GAUDI_ECC_SERR0_OFFSET;
52698c2ecf20Sopenharmony_ci
52708c2ecf20Sopenharmony_ci	if (params->disable_clock_gating) {
52718c2ecf20Sopenharmony_ci		mutex_lock(&gaudi->clk_gate_mutex);
52728c2ecf20Sopenharmony_ci		hdev->asic_funcs->disable_clock_gating(hdev);
52738c2ecf20Sopenharmony_ci	}
52748c2ecf20Sopenharmony_ci
52758c2ecf20Sopenharmony_ci	/* Set invalid wrapper index */
52768c2ecf20Sopenharmony_ci	*memory_wrapper_idx = 0xFF;
52778c2ecf20Sopenharmony_ci
52788c2ecf20Sopenharmony_ci	/* Iterate through memory wrappers, a single bit must be set */
52798c2ecf20Sopenharmony_ci	for (i = 0 ; i < num_mem_regs ; i++) {
52808c2ecf20Sopenharmony_ci		err_addr += i * 4;
52818c2ecf20Sopenharmony_ci		err_word = RREG32(err_addr);
52828c2ecf20Sopenharmony_ci		if (err_word) {
52838c2ecf20Sopenharmony_ci			err_bit = __ffs(err_word);
52848c2ecf20Sopenharmony_ci			*memory_wrapper_idx = err_bit + (32 * i);
52858c2ecf20Sopenharmony_ci			break;
52868c2ecf20Sopenharmony_ci		}
52878c2ecf20Sopenharmony_ci	}
52888c2ecf20Sopenharmony_ci
52898c2ecf20Sopenharmony_ci	if (*memory_wrapper_idx == 0xFF) {
52908c2ecf20Sopenharmony_ci		dev_err(hdev->dev, "ECC error information cannot be found\n");
52918c2ecf20Sopenharmony_ci		rc = -EINVAL;
52928c2ecf20Sopenharmony_ci		goto enable_clk_gate;
52938c2ecf20Sopenharmony_ci	}
52948c2ecf20Sopenharmony_ci
52958c2ecf20Sopenharmony_ci	WREG32(params->block_address + GAUDI_ECC_MEM_SEL_OFFSET,
52968c2ecf20Sopenharmony_ci			*memory_wrapper_idx);
52978c2ecf20Sopenharmony_ci
52988c2ecf20Sopenharmony_ci	*ecc_address =
52998c2ecf20Sopenharmony_ci		RREG32(params->block_address + GAUDI_ECC_ADDRESS_OFFSET);
53008c2ecf20Sopenharmony_ci	*ecc_syndrom =
53018c2ecf20Sopenharmony_ci		RREG32(params->block_address + GAUDI_ECC_SYNDROME_OFFSET);
53028c2ecf20Sopenharmony_ci
53038c2ecf20Sopenharmony_ci	/* Clear error indication */
53048c2ecf20Sopenharmony_ci	reg = RREG32(params->block_address + GAUDI_ECC_MEM_INFO_CLR_OFFSET);
53058c2ecf20Sopenharmony_ci	if (params->derr)
53068c2ecf20Sopenharmony_ci		reg |= FIELD_PREP(GAUDI_ECC_MEM_INFO_CLR_DERR_MASK, 1);
53078c2ecf20Sopenharmony_ci	else
53088c2ecf20Sopenharmony_ci		reg |= FIELD_PREP(GAUDI_ECC_MEM_INFO_CLR_SERR_MASK, 1);
53098c2ecf20Sopenharmony_ci
53108c2ecf20Sopenharmony_ci	WREG32(params->block_address + GAUDI_ECC_MEM_INFO_CLR_OFFSET, reg);
53118c2ecf20Sopenharmony_ci
53128c2ecf20Sopenharmony_cienable_clk_gate:
53138c2ecf20Sopenharmony_ci	if (params->disable_clock_gating) {
53148c2ecf20Sopenharmony_ci		hdev->asic_funcs->set_clock_gating(hdev);
53158c2ecf20Sopenharmony_ci
53168c2ecf20Sopenharmony_ci		mutex_unlock(&gaudi->clk_gate_mutex);
53178c2ecf20Sopenharmony_ci	}
53188c2ecf20Sopenharmony_ci
53198c2ecf20Sopenharmony_ci	return rc;
53208c2ecf20Sopenharmony_ci}
53218c2ecf20Sopenharmony_ci
53228c2ecf20Sopenharmony_cistatic void gaudi_handle_qman_err_generic(struct hl_device *hdev,
53238c2ecf20Sopenharmony_ci					  const char *qm_name,
53248c2ecf20Sopenharmony_ci					  u64 glbl_sts_addr,
53258c2ecf20Sopenharmony_ci					  u64 arb_err_addr)
53268c2ecf20Sopenharmony_ci{
53278c2ecf20Sopenharmony_ci	u32 i, j, glbl_sts_val, arb_err_val, glbl_sts_clr_val;
53288c2ecf20Sopenharmony_ci	char reg_desc[32];
53298c2ecf20Sopenharmony_ci
53308c2ecf20Sopenharmony_ci	/* Iterate through all stream GLBL_STS1 registers + Lower CP */
53318c2ecf20Sopenharmony_ci	for (i = 0 ; i < QMAN_STREAMS + 1 ; i++) {
53328c2ecf20Sopenharmony_ci		glbl_sts_clr_val = 0;
53338c2ecf20Sopenharmony_ci		glbl_sts_val = RREG32(glbl_sts_addr + 4 * i);
53348c2ecf20Sopenharmony_ci
53358c2ecf20Sopenharmony_ci		if (!glbl_sts_val)
53368c2ecf20Sopenharmony_ci			continue;
53378c2ecf20Sopenharmony_ci
53388c2ecf20Sopenharmony_ci		if (i == QMAN_STREAMS)
53398c2ecf20Sopenharmony_ci			snprintf(reg_desc, ARRAY_SIZE(reg_desc), "LowerCP");
53408c2ecf20Sopenharmony_ci		else
53418c2ecf20Sopenharmony_ci			snprintf(reg_desc, ARRAY_SIZE(reg_desc), "stream%u", i);
53428c2ecf20Sopenharmony_ci
53438c2ecf20Sopenharmony_ci		for (j = 0 ; j < GAUDI_NUM_OF_QM_ERR_CAUSE ; j++) {
53448c2ecf20Sopenharmony_ci			if (glbl_sts_val & BIT(j)) {
53458c2ecf20Sopenharmony_ci				dev_err_ratelimited(hdev->dev,
53468c2ecf20Sopenharmony_ci						"%s %s. err cause: %s\n",
53478c2ecf20Sopenharmony_ci						qm_name, reg_desc,
53488c2ecf20Sopenharmony_ci						gaudi_qman_error_cause[j]);
53498c2ecf20Sopenharmony_ci				glbl_sts_clr_val |= BIT(j);
53508c2ecf20Sopenharmony_ci			}
53518c2ecf20Sopenharmony_ci		}
53528c2ecf20Sopenharmony_ci
53538c2ecf20Sopenharmony_ci		/* Write 1 clear errors */
53548c2ecf20Sopenharmony_ci		WREG32(glbl_sts_addr + 4 * i, glbl_sts_clr_val);
53558c2ecf20Sopenharmony_ci	}
53568c2ecf20Sopenharmony_ci
53578c2ecf20Sopenharmony_ci	arb_err_val = RREG32(arb_err_addr);
53588c2ecf20Sopenharmony_ci
53598c2ecf20Sopenharmony_ci	if (!arb_err_val)
53608c2ecf20Sopenharmony_ci		return;
53618c2ecf20Sopenharmony_ci
53628c2ecf20Sopenharmony_ci	for (j = 0 ; j < GAUDI_NUM_OF_QM_ARB_ERR_CAUSE ; j++) {
53638c2ecf20Sopenharmony_ci		if (arb_err_val & BIT(j)) {
53648c2ecf20Sopenharmony_ci			dev_err_ratelimited(hdev->dev,
53658c2ecf20Sopenharmony_ci					"%s ARB_ERR. err cause: %s\n",
53668c2ecf20Sopenharmony_ci					qm_name,
53678c2ecf20Sopenharmony_ci					gaudi_qman_arb_error_cause[j]);
53688c2ecf20Sopenharmony_ci		}
53698c2ecf20Sopenharmony_ci	}
53708c2ecf20Sopenharmony_ci}
53718c2ecf20Sopenharmony_ci
53728c2ecf20Sopenharmony_cistatic void gaudi_handle_ecc_event(struct hl_device *hdev, u16 event_type,
53738c2ecf20Sopenharmony_ci		struct hl_eq_ecc_data *ecc_data)
53748c2ecf20Sopenharmony_ci{
53758c2ecf20Sopenharmony_ci	struct ecc_info_extract_params params;
53768c2ecf20Sopenharmony_ci	u64 ecc_address = 0, ecc_syndrom = 0;
53778c2ecf20Sopenharmony_ci	u8 index, memory_wrapper_idx = 0;
53788c2ecf20Sopenharmony_ci	bool extract_info_from_fw;
53798c2ecf20Sopenharmony_ci	int rc;
53808c2ecf20Sopenharmony_ci
53818c2ecf20Sopenharmony_ci	switch (event_type) {
53828c2ecf20Sopenharmony_ci	case GAUDI_EVENT_PCIE_CORE_SERR ... GAUDI_EVENT_PCIE_PHY_DERR:
53838c2ecf20Sopenharmony_ci	case GAUDI_EVENT_DMA0_SERR_ECC ... GAUDI_EVENT_MMU_DERR:
53848c2ecf20Sopenharmony_ci		extract_info_from_fw = true;
53858c2ecf20Sopenharmony_ci		break;
53868c2ecf20Sopenharmony_ci	case GAUDI_EVENT_TPC0_SERR ... GAUDI_EVENT_TPC7_SERR:
53878c2ecf20Sopenharmony_ci		index = event_type - GAUDI_EVENT_TPC0_SERR;
53888c2ecf20Sopenharmony_ci		params.block_address = mmTPC0_CFG_BASE + index * TPC_CFG_OFFSET;
53898c2ecf20Sopenharmony_ci		params.num_memories = 90;
53908c2ecf20Sopenharmony_ci		params.derr = false;
53918c2ecf20Sopenharmony_ci		params.disable_clock_gating = true;
53928c2ecf20Sopenharmony_ci		extract_info_from_fw = false;
53938c2ecf20Sopenharmony_ci		break;
53948c2ecf20Sopenharmony_ci	case GAUDI_EVENT_TPC0_DERR ... GAUDI_EVENT_TPC7_DERR:
53958c2ecf20Sopenharmony_ci		index = event_type - GAUDI_EVENT_TPC0_DERR;
53968c2ecf20Sopenharmony_ci		params.block_address =
53978c2ecf20Sopenharmony_ci			mmTPC0_CFG_BASE + index * TPC_CFG_OFFSET;
53988c2ecf20Sopenharmony_ci		params.num_memories = 90;
53998c2ecf20Sopenharmony_ci		params.derr = true;
54008c2ecf20Sopenharmony_ci		params.disable_clock_gating = true;
54018c2ecf20Sopenharmony_ci		extract_info_from_fw = false;
54028c2ecf20Sopenharmony_ci		break;
54038c2ecf20Sopenharmony_ci	case GAUDI_EVENT_MME0_ACC_SERR:
54048c2ecf20Sopenharmony_ci	case GAUDI_EVENT_MME1_ACC_SERR:
54058c2ecf20Sopenharmony_ci	case GAUDI_EVENT_MME2_ACC_SERR:
54068c2ecf20Sopenharmony_ci	case GAUDI_EVENT_MME3_ACC_SERR:
54078c2ecf20Sopenharmony_ci		index = (event_type - GAUDI_EVENT_MME0_ACC_SERR) / 4;
54088c2ecf20Sopenharmony_ci		params.block_address = mmMME0_ACC_BASE + index * MME_ACC_OFFSET;
54098c2ecf20Sopenharmony_ci		params.num_memories = 128;
54108c2ecf20Sopenharmony_ci		params.derr = false;
54118c2ecf20Sopenharmony_ci		params.disable_clock_gating = true;
54128c2ecf20Sopenharmony_ci		extract_info_from_fw = false;
54138c2ecf20Sopenharmony_ci		break;
54148c2ecf20Sopenharmony_ci	case GAUDI_EVENT_MME0_ACC_DERR:
54158c2ecf20Sopenharmony_ci	case GAUDI_EVENT_MME1_ACC_DERR:
54168c2ecf20Sopenharmony_ci	case GAUDI_EVENT_MME2_ACC_DERR:
54178c2ecf20Sopenharmony_ci	case GAUDI_EVENT_MME3_ACC_DERR:
54188c2ecf20Sopenharmony_ci		index = (event_type - GAUDI_EVENT_MME0_ACC_DERR) / 4;
54198c2ecf20Sopenharmony_ci		params.block_address = mmMME0_ACC_BASE + index * MME_ACC_OFFSET;
54208c2ecf20Sopenharmony_ci		params.num_memories = 128;
54218c2ecf20Sopenharmony_ci		params.derr = true;
54228c2ecf20Sopenharmony_ci		params.disable_clock_gating = true;
54238c2ecf20Sopenharmony_ci		extract_info_from_fw = false;
54248c2ecf20Sopenharmony_ci		break;
54258c2ecf20Sopenharmony_ci	case GAUDI_EVENT_MME0_SBAB_SERR:
54268c2ecf20Sopenharmony_ci	case GAUDI_EVENT_MME1_SBAB_SERR:
54278c2ecf20Sopenharmony_ci	case GAUDI_EVENT_MME2_SBAB_SERR:
54288c2ecf20Sopenharmony_ci	case GAUDI_EVENT_MME3_SBAB_SERR:
54298c2ecf20Sopenharmony_ci		index = (event_type - GAUDI_EVENT_MME0_SBAB_SERR) / 4;
54308c2ecf20Sopenharmony_ci		params.block_address =
54318c2ecf20Sopenharmony_ci			mmMME0_SBAB_BASE + index * MME_ACC_OFFSET;
54328c2ecf20Sopenharmony_ci		params.num_memories = 33;
54338c2ecf20Sopenharmony_ci		params.derr = false;
54348c2ecf20Sopenharmony_ci		params.disable_clock_gating = true;
54358c2ecf20Sopenharmony_ci		extract_info_from_fw = false;
54368c2ecf20Sopenharmony_ci		break;
54378c2ecf20Sopenharmony_ci	case GAUDI_EVENT_MME0_SBAB_DERR:
54388c2ecf20Sopenharmony_ci	case GAUDI_EVENT_MME1_SBAB_DERR:
54398c2ecf20Sopenharmony_ci	case GAUDI_EVENT_MME2_SBAB_DERR:
54408c2ecf20Sopenharmony_ci	case GAUDI_EVENT_MME3_SBAB_DERR:
54418c2ecf20Sopenharmony_ci		index = (event_type - GAUDI_EVENT_MME0_SBAB_DERR) / 4;
54428c2ecf20Sopenharmony_ci		params.block_address =
54438c2ecf20Sopenharmony_ci			mmMME0_SBAB_BASE + index * MME_ACC_OFFSET;
54448c2ecf20Sopenharmony_ci		params.num_memories = 33;
54458c2ecf20Sopenharmony_ci		params.derr = true;
54468c2ecf20Sopenharmony_ci		params.disable_clock_gating = true;
54478c2ecf20Sopenharmony_ci		extract_info_from_fw = false;
54488c2ecf20Sopenharmony_ci		break;
54498c2ecf20Sopenharmony_ci	default:
54508c2ecf20Sopenharmony_ci		return;
54518c2ecf20Sopenharmony_ci	}
54528c2ecf20Sopenharmony_ci
54538c2ecf20Sopenharmony_ci	if (extract_info_from_fw) {
54548c2ecf20Sopenharmony_ci		ecc_address = le64_to_cpu(ecc_data->ecc_address);
54558c2ecf20Sopenharmony_ci		ecc_syndrom = le64_to_cpu(ecc_data->ecc_syndrom);
54568c2ecf20Sopenharmony_ci		memory_wrapper_idx = ecc_data->memory_wrapper_idx;
54578c2ecf20Sopenharmony_ci	} else {
54588c2ecf20Sopenharmony_ci		rc = gaudi_extract_ecc_info(hdev, &params, &ecc_address,
54598c2ecf20Sopenharmony_ci				&ecc_syndrom, &memory_wrapper_idx);
54608c2ecf20Sopenharmony_ci		if (rc)
54618c2ecf20Sopenharmony_ci			return;
54628c2ecf20Sopenharmony_ci	}
54638c2ecf20Sopenharmony_ci
54648c2ecf20Sopenharmony_ci	dev_err(hdev->dev,
54658c2ecf20Sopenharmony_ci		"ECC error detected. address: %#llx. Syndrom: %#llx. block id %u\n",
54668c2ecf20Sopenharmony_ci		ecc_address, ecc_syndrom, memory_wrapper_idx);
54678c2ecf20Sopenharmony_ci}
54688c2ecf20Sopenharmony_ci
54698c2ecf20Sopenharmony_cistatic void gaudi_handle_qman_err(struct hl_device *hdev, u16 event_type)
54708c2ecf20Sopenharmony_ci{
54718c2ecf20Sopenharmony_ci	u64 glbl_sts_addr, arb_err_addr;
54728c2ecf20Sopenharmony_ci	u8 index;
54738c2ecf20Sopenharmony_ci	char desc[32];
54748c2ecf20Sopenharmony_ci
54758c2ecf20Sopenharmony_ci	switch (event_type) {
54768c2ecf20Sopenharmony_ci	case GAUDI_EVENT_TPC0_QM ... GAUDI_EVENT_TPC7_QM:
54778c2ecf20Sopenharmony_ci		index = event_type - GAUDI_EVENT_TPC0_QM;
54788c2ecf20Sopenharmony_ci		glbl_sts_addr =
54798c2ecf20Sopenharmony_ci			mmTPC0_QM_GLBL_STS1_0 + index * TPC_QMAN_OFFSET;
54808c2ecf20Sopenharmony_ci		arb_err_addr =
54818c2ecf20Sopenharmony_ci			mmTPC0_QM_ARB_ERR_CAUSE + index * TPC_QMAN_OFFSET;
54828c2ecf20Sopenharmony_ci		snprintf(desc, ARRAY_SIZE(desc), "%s%d", "TPC_QM", index);
54838c2ecf20Sopenharmony_ci		break;
54848c2ecf20Sopenharmony_ci	case GAUDI_EVENT_MME0_QM ... GAUDI_EVENT_MME2_QM:
54858c2ecf20Sopenharmony_ci		index = event_type - GAUDI_EVENT_MME0_QM;
54868c2ecf20Sopenharmony_ci		glbl_sts_addr =
54878c2ecf20Sopenharmony_ci			mmMME0_QM_GLBL_STS1_0 + index * MME_QMAN_OFFSET;
54888c2ecf20Sopenharmony_ci		arb_err_addr =
54898c2ecf20Sopenharmony_ci			mmMME0_QM_ARB_ERR_CAUSE + index * MME_QMAN_OFFSET;
54908c2ecf20Sopenharmony_ci		snprintf(desc, ARRAY_SIZE(desc), "%s%d", "MME_QM", index);
54918c2ecf20Sopenharmony_ci		break;
54928c2ecf20Sopenharmony_ci	case GAUDI_EVENT_DMA0_QM ... GAUDI_EVENT_DMA7_QM:
54938c2ecf20Sopenharmony_ci		index = event_type - GAUDI_EVENT_DMA0_QM;
54948c2ecf20Sopenharmony_ci		glbl_sts_addr =
54958c2ecf20Sopenharmony_ci			mmDMA0_QM_GLBL_STS1_0 + index * DMA_QMAN_OFFSET;
54968c2ecf20Sopenharmony_ci		arb_err_addr =
54978c2ecf20Sopenharmony_ci			mmDMA0_QM_ARB_ERR_CAUSE + index * DMA_QMAN_OFFSET;
54988c2ecf20Sopenharmony_ci		snprintf(desc, ARRAY_SIZE(desc), "%s%d", "DMA_QM", index);
54998c2ecf20Sopenharmony_ci		break;
55008c2ecf20Sopenharmony_ci	default:
55018c2ecf20Sopenharmony_ci		return;
55028c2ecf20Sopenharmony_ci	}
55038c2ecf20Sopenharmony_ci
55048c2ecf20Sopenharmony_ci	gaudi_handle_qman_err_generic(hdev, desc, glbl_sts_addr, arb_err_addr);
55058c2ecf20Sopenharmony_ci}
55068c2ecf20Sopenharmony_ci
55078c2ecf20Sopenharmony_cistatic void gaudi_print_irq_info(struct hl_device *hdev, u16 event_type,
55088c2ecf20Sopenharmony_ci					bool razwi)
55098c2ecf20Sopenharmony_ci{
55108c2ecf20Sopenharmony_ci	char desc[64] = "";
55118c2ecf20Sopenharmony_ci
55128c2ecf20Sopenharmony_ci	gaudi_get_event_desc(event_type, desc, sizeof(desc));
55138c2ecf20Sopenharmony_ci	dev_err_ratelimited(hdev->dev, "Received H/W interrupt %d [\"%s\"]\n",
55148c2ecf20Sopenharmony_ci		event_type, desc);
55158c2ecf20Sopenharmony_ci
55168c2ecf20Sopenharmony_ci	if (razwi) {
55178c2ecf20Sopenharmony_ci		gaudi_print_razwi_info(hdev);
55188c2ecf20Sopenharmony_ci		gaudi_print_mmu_error_info(hdev);
55198c2ecf20Sopenharmony_ci	}
55208c2ecf20Sopenharmony_ci}
55218c2ecf20Sopenharmony_ci
55228c2ecf20Sopenharmony_cistatic int gaudi_soft_reset_late_init(struct hl_device *hdev)
55238c2ecf20Sopenharmony_ci{
55248c2ecf20Sopenharmony_ci	struct gaudi_device *gaudi = hdev->asic_specific;
55258c2ecf20Sopenharmony_ci
55268c2ecf20Sopenharmony_ci	/* Unmask all IRQs since some could have been received
55278c2ecf20Sopenharmony_ci	 * during the soft reset
55288c2ecf20Sopenharmony_ci	 */
55298c2ecf20Sopenharmony_ci	return hl_fw_unmask_irq_arr(hdev, gaudi->events, sizeof(gaudi->events));
55308c2ecf20Sopenharmony_ci}
55318c2ecf20Sopenharmony_ci
55328c2ecf20Sopenharmony_cistatic int gaudi_hbm_read_interrupts(struct hl_device *hdev, int device)
55338c2ecf20Sopenharmony_ci{
55348c2ecf20Sopenharmony_ci	int ch, err = 0;
55358c2ecf20Sopenharmony_ci	u32 base, val, val2;
55368c2ecf20Sopenharmony_ci
55378c2ecf20Sopenharmony_ci	base = GAUDI_HBM_CFG_BASE + device * GAUDI_HBM_CFG_OFFSET;
55388c2ecf20Sopenharmony_ci	for (ch = 0 ; ch < GAUDI_HBM_CHANNELS ; ch++) {
55398c2ecf20Sopenharmony_ci		val = RREG32_MASK(base + ch * 0x1000 + 0x06C, 0x0000FFFF);
55408c2ecf20Sopenharmony_ci		val = (val & 0xFF) | ((val >> 8) & 0xFF);
55418c2ecf20Sopenharmony_ci		if (val) {
55428c2ecf20Sopenharmony_ci			err = 1;
55438c2ecf20Sopenharmony_ci			dev_err(hdev->dev,
55448c2ecf20Sopenharmony_ci				"HBM%d pc%d interrupts info: WR_PAR=%d, RD_PAR=%d, CA_PAR=%d, SERR=%d, DERR=%d\n",
55458c2ecf20Sopenharmony_ci				device, ch * 2, val & 0x1, (val >> 1) & 0x1,
55468c2ecf20Sopenharmony_ci				(val >> 2) & 0x1, (val >> 3) & 0x1,
55478c2ecf20Sopenharmony_ci				(val >> 4) & 0x1);
55488c2ecf20Sopenharmony_ci
55498c2ecf20Sopenharmony_ci			val2 = RREG32(base + ch * 0x1000 + 0x060);
55508c2ecf20Sopenharmony_ci			dev_err(hdev->dev,
55518c2ecf20Sopenharmony_ci				"HBM%d pc%d ECC info: 1ST_ERR_ADDR=0x%x, 1ST_ERR_TYPE=%d, SEC_CONT_CNT=%d, SEC_CNT=%d, DED_CNT=%d\n",
55528c2ecf20Sopenharmony_ci				device, ch * 2,
55538c2ecf20Sopenharmony_ci				RREG32(base + ch * 0x1000 + 0x064),
55548c2ecf20Sopenharmony_ci				(val2 & 0x200) >> 9, (val2 & 0xFC00) >> 10,
55558c2ecf20Sopenharmony_ci				(val2 & 0xFF0000) >> 16,
55568c2ecf20Sopenharmony_ci				(val2 & 0xFF000000) >> 24);
55578c2ecf20Sopenharmony_ci		}
55588c2ecf20Sopenharmony_ci
55598c2ecf20Sopenharmony_ci		val = RREG32_MASK(base + ch * 0x1000 + 0x07C, 0x0000FFFF);
55608c2ecf20Sopenharmony_ci		val = (val & 0xFF) | ((val >> 8) & 0xFF);
55618c2ecf20Sopenharmony_ci		if (val) {
55628c2ecf20Sopenharmony_ci			err = 1;
55638c2ecf20Sopenharmony_ci			dev_err(hdev->dev,
55648c2ecf20Sopenharmony_ci				"HBM%d pc%d interrupts info: WR_PAR=%d, RD_PAR=%d, CA_PAR=%d, SERR=%d, DERR=%d\n",
55658c2ecf20Sopenharmony_ci				device, ch * 2 + 1, val & 0x1, (val >> 1) & 0x1,
55668c2ecf20Sopenharmony_ci				(val >> 2) & 0x1, (val >> 3) & 0x1,
55678c2ecf20Sopenharmony_ci				(val >> 4) & 0x1);
55688c2ecf20Sopenharmony_ci
55698c2ecf20Sopenharmony_ci			val2 = RREG32(base + ch * 0x1000 + 0x070);
55708c2ecf20Sopenharmony_ci			dev_err(hdev->dev,
55718c2ecf20Sopenharmony_ci				"HBM%d pc%d ECC info: 1ST_ERR_ADDR=0x%x, 1ST_ERR_TYPE=%d, SEC_CONT_CNT=%d, SEC_CNT=%d, DED_CNT=%d\n",
55728c2ecf20Sopenharmony_ci				device, ch * 2 + 1,
55738c2ecf20Sopenharmony_ci				RREG32(base + ch * 0x1000 + 0x074),
55748c2ecf20Sopenharmony_ci				(val2 & 0x200) >> 9, (val2 & 0xFC00) >> 10,
55758c2ecf20Sopenharmony_ci				(val2 & 0xFF0000) >> 16,
55768c2ecf20Sopenharmony_ci				(val2 & 0xFF000000) >> 24);
55778c2ecf20Sopenharmony_ci		}
55788c2ecf20Sopenharmony_ci
55798c2ecf20Sopenharmony_ci		/* Clear interrupts */
55808c2ecf20Sopenharmony_ci		RMWREG32(base + (ch * 0x1000) + 0x060, 0x1C8, 0x1FF);
55818c2ecf20Sopenharmony_ci		RMWREG32(base + (ch * 0x1000) + 0x070, 0x1C8, 0x1FF);
55828c2ecf20Sopenharmony_ci		WREG32(base + (ch * 0x1000) + 0x06C, 0x1F1F);
55838c2ecf20Sopenharmony_ci		WREG32(base + (ch * 0x1000) + 0x07C, 0x1F1F);
55848c2ecf20Sopenharmony_ci		RMWREG32(base + (ch * 0x1000) + 0x060, 0x0, 0xF);
55858c2ecf20Sopenharmony_ci		RMWREG32(base + (ch * 0x1000) + 0x070, 0x0, 0xF);
55868c2ecf20Sopenharmony_ci	}
55878c2ecf20Sopenharmony_ci
55888c2ecf20Sopenharmony_ci	val  = RREG32(base + 0x8F30);
55898c2ecf20Sopenharmony_ci	val2 = RREG32(base + 0x8F34);
55908c2ecf20Sopenharmony_ci	if (val | val2) {
55918c2ecf20Sopenharmony_ci		err = 1;
55928c2ecf20Sopenharmony_ci		dev_err(hdev->dev,
55938c2ecf20Sopenharmony_ci			"HBM %d MC SRAM SERR info: Reg 0x8F30=0x%x, Reg 0x8F34=0x%x\n",
55948c2ecf20Sopenharmony_ci			device, val, val2);
55958c2ecf20Sopenharmony_ci	}
55968c2ecf20Sopenharmony_ci	val  = RREG32(base + 0x8F40);
55978c2ecf20Sopenharmony_ci	val2 = RREG32(base + 0x8F44);
55988c2ecf20Sopenharmony_ci	if (val | val2) {
55998c2ecf20Sopenharmony_ci		err = 1;
56008c2ecf20Sopenharmony_ci		dev_err(hdev->dev,
56018c2ecf20Sopenharmony_ci			"HBM %d MC SRAM DERR info: Reg 0x8F40=0x%x, Reg 0x8F44=0x%x\n",
56028c2ecf20Sopenharmony_ci			device, val, val2);
56038c2ecf20Sopenharmony_ci	}
56048c2ecf20Sopenharmony_ci
56058c2ecf20Sopenharmony_ci	return err;
56068c2ecf20Sopenharmony_ci}
56078c2ecf20Sopenharmony_ci
56088c2ecf20Sopenharmony_cistatic int gaudi_hbm_event_to_dev(u16 hbm_event_type)
56098c2ecf20Sopenharmony_ci{
56108c2ecf20Sopenharmony_ci	switch (hbm_event_type) {
56118c2ecf20Sopenharmony_ci	case GAUDI_EVENT_HBM0_SPI_0:
56128c2ecf20Sopenharmony_ci	case GAUDI_EVENT_HBM0_SPI_1:
56138c2ecf20Sopenharmony_ci		return 0;
56148c2ecf20Sopenharmony_ci	case GAUDI_EVENT_HBM1_SPI_0:
56158c2ecf20Sopenharmony_ci	case GAUDI_EVENT_HBM1_SPI_1:
56168c2ecf20Sopenharmony_ci		return 1;
56178c2ecf20Sopenharmony_ci	case GAUDI_EVENT_HBM2_SPI_0:
56188c2ecf20Sopenharmony_ci	case GAUDI_EVENT_HBM2_SPI_1:
56198c2ecf20Sopenharmony_ci		return 2;
56208c2ecf20Sopenharmony_ci	case GAUDI_EVENT_HBM3_SPI_0:
56218c2ecf20Sopenharmony_ci	case GAUDI_EVENT_HBM3_SPI_1:
56228c2ecf20Sopenharmony_ci		return 3;
56238c2ecf20Sopenharmony_ci	default:
56248c2ecf20Sopenharmony_ci		break;
56258c2ecf20Sopenharmony_ci	}
56268c2ecf20Sopenharmony_ci
56278c2ecf20Sopenharmony_ci	/* Should never happen */
56288c2ecf20Sopenharmony_ci	return 0;
56298c2ecf20Sopenharmony_ci}
56308c2ecf20Sopenharmony_ci
56318c2ecf20Sopenharmony_cistatic bool gaudi_tpc_read_interrupts(struct hl_device *hdev, u8 tpc_id,
56328c2ecf20Sopenharmony_ci					char *interrupt_name)
56338c2ecf20Sopenharmony_ci{
56348c2ecf20Sopenharmony_ci	struct gaudi_device *gaudi = hdev->asic_specific;
56358c2ecf20Sopenharmony_ci	u32 tpc_offset = tpc_id * TPC_CFG_OFFSET, tpc_interrupts_cause, i;
56368c2ecf20Sopenharmony_ci	bool soft_reset_required = false;
56378c2ecf20Sopenharmony_ci
56388c2ecf20Sopenharmony_ci	/* Accessing the TPC_INTR_CAUSE registers requires disabling the clock
56398c2ecf20Sopenharmony_ci	 * gating, and thus cannot be done in CPU-CP and should be done instead
56408c2ecf20Sopenharmony_ci	 * by the driver.
56418c2ecf20Sopenharmony_ci	 */
56428c2ecf20Sopenharmony_ci
56438c2ecf20Sopenharmony_ci	mutex_lock(&gaudi->clk_gate_mutex);
56448c2ecf20Sopenharmony_ci
56458c2ecf20Sopenharmony_ci	hdev->asic_funcs->disable_clock_gating(hdev);
56468c2ecf20Sopenharmony_ci
56478c2ecf20Sopenharmony_ci	tpc_interrupts_cause = RREG32(mmTPC0_CFG_TPC_INTR_CAUSE + tpc_offset) &
56488c2ecf20Sopenharmony_ci				TPC0_CFG_TPC_INTR_CAUSE_CAUSE_MASK;
56498c2ecf20Sopenharmony_ci
56508c2ecf20Sopenharmony_ci	for (i = 0 ; i < GAUDI_NUM_OF_TPC_INTR_CAUSE ; i++)
56518c2ecf20Sopenharmony_ci		if (tpc_interrupts_cause & BIT(i)) {
56528c2ecf20Sopenharmony_ci			dev_err_ratelimited(hdev->dev,
56538c2ecf20Sopenharmony_ci					"TPC%d_%s interrupt cause: %s\n",
56548c2ecf20Sopenharmony_ci					tpc_id, interrupt_name,
56558c2ecf20Sopenharmony_ci					gaudi_tpc_interrupts_cause[i]);
56568c2ecf20Sopenharmony_ci			/* If this is QM error, we need to soft-reset */
56578c2ecf20Sopenharmony_ci			if (i == 15)
56588c2ecf20Sopenharmony_ci				soft_reset_required = true;
56598c2ecf20Sopenharmony_ci		}
56608c2ecf20Sopenharmony_ci
56618c2ecf20Sopenharmony_ci	/* Clear interrupts */
56628c2ecf20Sopenharmony_ci	WREG32(mmTPC0_CFG_TPC_INTR_CAUSE + tpc_offset, 0);
56638c2ecf20Sopenharmony_ci
56648c2ecf20Sopenharmony_ci	hdev->asic_funcs->set_clock_gating(hdev);
56658c2ecf20Sopenharmony_ci
56668c2ecf20Sopenharmony_ci	mutex_unlock(&gaudi->clk_gate_mutex);
56678c2ecf20Sopenharmony_ci
56688c2ecf20Sopenharmony_ci	return soft_reset_required;
56698c2ecf20Sopenharmony_ci}
56708c2ecf20Sopenharmony_ci
56718c2ecf20Sopenharmony_cistatic int tpc_dec_event_to_tpc_id(u16 tpc_dec_event_type)
56728c2ecf20Sopenharmony_ci{
56738c2ecf20Sopenharmony_ci	return (tpc_dec_event_type - GAUDI_EVENT_TPC0_DEC) >> 1;
56748c2ecf20Sopenharmony_ci}
56758c2ecf20Sopenharmony_ci
56768c2ecf20Sopenharmony_cistatic int tpc_krn_event_to_tpc_id(u16 tpc_dec_event_type)
56778c2ecf20Sopenharmony_ci{
56788c2ecf20Sopenharmony_ci	return (tpc_dec_event_type - GAUDI_EVENT_TPC0_KRN_ERR) / 6;
56798c2ecf20Sopenharmony_ci}
56808c2ecf20Sopenharmony_ci
56818c2ecf20Sopenharmony_cistatic void gaudi_print_clk_change_info(struct hl_device *hdev,
56828c2ecf20Sopenharmony_ci					u16 event_type)
56838c2ecf20Sopenharmony_ci{
56848c2ecf20Sopenharmony_ci	switch (event_type) {
56858c2ecf20Sopenharmony_ci	case GAUDI_EVENT_FIX_POWER_ENV_S:
56868c2ecf20Sopenharmony_ci		hdev->clk_throttling_reason |= HL_CLK_THROTTLE_POWER;
56878c2ecf20Sopenharmony_ci		dev_info_ratelimited(hdev->dev,
56888c2ecf20Sopenharmony_ci			"Clock throttling due to power consumption\n");
56898c2ecf20Sopenharmony_ci		break;
56908c2ecf20Sopenharmony_ci
56918c2ecf20Sopenharmony_ci	case GAUDI_EVENT_FIX_POWER_ENV_E:
56928c2ecf20Sopenharmony_ci		hdev->clk_throttling_reason &= ~HL_CLK_THROTTLE_POWER;
56938c2ecf20Sopenharmony_ci		dev_info_ratelimited(hdev->dev,
56948c2ecf20Sopenharmony_ci			"Power envelop is safe, back to optimal clock\n");
56958c2ecf20Sopenharmony_ci		break;
56968c2ecf20Sopenharmony_ci
56978c2ecf20Sopenharmony_ci	case GAUDI_EVENT_FIX_THERMAL_ENV_S:
56988c2ecf20Sopenharmony_ci		hdev->clk_throttling_reason |= HL_CLK_THROTTLE_THERMAL;
56998c2ecf20Sopenharmony_ci		dev_info_ratelimited(hdev->dev,
57008c2ecf20Sopenharmony_ci			"Clock throttling due to overheating\n");
57018c2ecf20Sopenharmony_ci		break;
57028c2ecf20Sopenharmony_ci
57038c2ecf20Sopenharmony_ci	case GAUDI_EVENT_FIX_THERMAL_ENV_E:
57048c2ecf20Sopenharmony_ci		hdev->clk_throttling_reason &= ~HL_CLK_THROTTLE_THERMAL;
57058c2ecf20Sopenharmony_ci		dev_info_ratelimited(hdev->dev,
57068c2ecf20Sopenharmony_ci			"Thermal envelop is safe, back to optimal clock\n");
57078c2ecf20Sopenharmony_ci		break;
57088c2ecf20Sopenharmony_ci
57098c2ecf20Sopenharmony_ci	default:
57108c2ecf20Sopenharmony_ci		dev_err(hdev->dev, "Received invalid clock change event %d\n",
57118c2ecf20Sopenharmony_ci			event_type);
57128c2ecf20Sopenharmony_ci		break;
57138c2ecf20Sopenharmony_ci	}
57148c2ecf20Sopenharmony_ci}
57158c2ecf20Sopenharmony_ci
57168c2ecf20Sopenharmony_cistatic void gaudi_handle_eqe(struct hl_device *hdev,
57178c2ecf20Sopenharmony_ci				struct hl_eq_entry *eq_entry)
57188c2ecf20Sopenharmony_ci{
57198c2ecf20Sopenharmony_ci	struct gaudi_device *gaudi = hdev->asic_specific;
57208c2ecf20Sopenharmony_ci	u32 ctl = le32_to_cpu(eq_entry->hdr.ctl);
57218c2ecf20Sopenharmony_ci	u16 event_type = ((ctl & EQ_CTL_EVENT_TYPE_MASK)
57228c2ecf20Sopenharmony_ci			>> EQ_CTL_EVENT_TYPE_SHIFT);
57238c2ecf20Sopenharmony_ci	u8 cause;
57248c2ecf20Sopenharmony_ci	bool reset_required;
57258c2ecf20Sopenharmony_ci
57268c2ecf20Sopenharmony_ci	if (event_type >= GAUDI_EVENT_SIZE) {
57278c2ecf20Sopenharmony_ci		dev_err(hdev->dev, "Event type %u exceeds maximum of %u",
57288c2ecf20Sopenharmony_ci				event_type, GAUDI_EVENT_SIZE - 1);
57298c2ecf20Sopenharmony_ci		return;
57308c2ecf20Sopenharmony_ci	}
57318c2ecf20Sopenharmony_ci
57328c2ecf20Sopenharmony_ci	gaudi->events_stat[event_type]++;
57338c2ecf20Sopenharmony_ci	gaudi->events_stat_aggregate[event_type]++;
57348c2ecf20Sopenharmony_ci
57358c2ecf20Sopenharmony_ci	switch (event_type) {
57368c2ecf20Sopenharmony_ci	case GAUDI_EVENT_PCIE_CORE_DERR:
57378c2ecf20Sopenharmony_ci	case GAUDI_EVENT_PCIE_IF_DERR:
57388c2ecf20Sopenharmony_ci	case GAUDI_EVENT_PCIE_PHY_DERR:
57398c2ecf20Sopenharmony_ci	case GAUDI_EVENT_TPC0_DERR ... GAUDI_EVENT_TPC7_DERR:
57408c2ecf20Sopenharmony_ci	case GAUDI_EVENT_MME0_ACC_DERR:
57418c2ecf20Sopenharmony_ci	case GAUDI_EVENT_MME0_SBAB_DERR:
57428c2ecf20Sopenharmony_ci	case GAUDI_EVENT_MME1_ACC_DERR:
57438c2ecf20Sopenharmony_ci	case GAUDI_EVENT_MME1_SBAB_DERR:
57448c2ecf20Sopenharmony_ci	case GAUDI_EVENT_MME2_ACC_DERR:
57458c2ecf20Sopenharmony_ci	case GAUDI_EVENT_MME2_SBAB_DERR:
57468c2ecf20Sopenharmony_ci	case GAUDI_EVENT_MME3_ACC_DERR:
57478c2ecf20Sopenharmony_ci	case GAUDI_EVENT_MME3_SBAB_DERR:
57488c2ecf20Sopenharmony_ci	case GAUDI_EVENT_DMA0_DERR_ECC ... GAUDI_EVENT_DMA7_DERR_ECC:
57498c2ecf20Sopenharmony_ci		fallthrough;
57508c2ecf20Sopenharmony_ci	case GAUDI_EVENT_CPU_IF_ECC_DERR:
57518c2ecf20Sopenharmony_ci	case GAUDI_EVENT_PSOC_MEM_DERR:
57528c2ecf20Sopenharmony_ci	case GAUDI_EVENT_PSOC_CORESIGHT_DERR:
57538c2ecf20Sopenharmony_ci	case GAUDI_EVENT_SRAM0_DERR ... GAUDI_EVENT_SRAM28_DERR:
57548c2ecf20Sopenharmony_ci	case GAUDI_EVENT_DMA_IF0_DERR ... GAUDI_EVENT_DMA_IF3_DERR:
57558c2ecf20Sopenharmony_ci	case GAUDI_EVENT_HBM_0_DERR ... GAUDI_EVENT_HBM_3_DERR:
57568c2ecf20Sopenharmony_ci	case GAUDI_EVENT_MMU_DERR:
57578c2ecf20Sopenharmony_ci		gaudi_print_irq_info(hdev, event_type, true);
57588c2ecf20Sopenharmony_ci		gaudi_handle_ecc_event(hdev, event_type, &eq_entry->ecc_data);
57598c2ecf20Sopenharmony_ci		if (hdev->hard_reset_on_fw_events)
57608c2ecf20Sopenharmony_ci			hl_device_reset(hdev, true, false);
57618c2ecf20Sopenharmony_ci		break;
57628c2ecf20Sopenharmony_ci
57638c2ecf20Sopenharmony_ci	case GAUDI_EVENT_GIC500:
57648c2ecf20Sopenharmony_ci	case GAUDI_EVENT_AXI_ECC:
57658c2ecf20Sopenharmony_ci	case GAUDI_EVENT_L2_RAM_ECC:
57668c2ecf20Sopenharmony_ci	case GAUDI_EVENT_PLL0 ... GAUDI_EVENT_PLL17:
57678c2ecf20Sopenharmony_ci		gaudi_print_irq_info(hdev, event_type, false);
57688c2ecf20Sopenharmony_ci		if (hdev->hard_reset_on_fw_events)
57698c2ecf20Sopenharmony_ci			hl_device_reset(hdev, true, false);
57708c2ecf20Sopenharmony_ci		break;
57718c2ecf20Sopenharmony_ci
57728c2ecf20Sopenharmony_ci	case GAUDI_EVENT_HBM0_SPI_0:
57738c2ecf20Sopenharmony_ci	case GAUDI_EVENT_HBM1_SPI_0:
57748c2ecf20Sopenharmony_ci	case GAUDI_EVENT_HBM2_SPI_0:
57758c2ecf20Sopenharmony_ci	case GAUDI_EVENT_HBM3_SPI_0:
57768c2ecf20Sopenharmony_ci		gaudi_print_irq_info(hdev, event_type, false);
57778c2ecf20Sopenharmony_ci		gaudi_hbm_read_interrupts(hdev,
57788c2ecf20Sopenharmony_ci					  gaudi_hbm_event_to_dev(event_type));
57798c2ecf20Sopenharmony_ci		if (hdev->hard_reset_on_fw_events)
57808c2ecf20Sopenharmony_ci			hl_device_reset(hdev, true, false);
57818c2ecf20Sopenharmony_ci		break;
57828c2ecf20Sopenharmony_ci
57838c2ecf20Sopenharmony_ci	case GAUDI_EVENT_HBM0_SPI_1:
57848c2ecf20Sopenharmony_ci	case GAUDI_EVENT_HBM1_SPI_1:
57858c2ecf20Sopenharmony_ci	case GAUDI_EVENT_HBM2_SPI_1:
57868c2ecf20Sopenharmony_ci	case GAUDI_EVENT_HBM3_SPI_1:
57878c2ecf20Sopenharmony_ci		gaudi_print_irq_info(hdev, event_type, false);
57888c2ecf20Sopenharmony_ci		gaudi_hbm_read_interrupts(hdev,
57898c2ecf20Sopenharmony_ci					  gaudi_hbm_event_to_dev(event_type));
57908c2ecf20Sopenharmony_ci		break;
57918c2ecf20Sopenharmony_ci
57928c2ecf20Sopenharmony_ci	case GAUDI_EVENT_TPC0_DEC:
57938c2ecf20Sopenharmony_ci	case GAUDI_EVENT_TPC1_DEC:
57948c2ecf20Sopenharmony_ci	case GAUDI_EVENT_TPC2_DEC:
57958c2ecf20Sopenharmony_ci	case GAUDI_EVENT_TPC3_DEC:
57968c2ecf20Sopenharmony_ci	case GAUDI_EVENT_TPC4_DEC:
57978c2ecf20Sopenharmony_ci	case GAUDI_EVENT_TPC5_DEC:
57988c2ecf20Sopenharmony_ci	case GAUDI_EVENT_TPC6_DEC:
57998c2ecf20Sopenharmony_ci	case GAUDI_EVENT_TPC7_DEC:
58008c2ecf20Sopenharmony_ci		gaudi_print_irq_info(hdev, event_type, true);
58018c2ecf20Sopenharmony_ci		reset_required = gaudi_tpc_read_interrupts(hdev,
58028c2ecf20Sopenharmony_ci					tpc_dec_event_to_tpc_id(event_type),
58038c2ecf20Sopenharmony_ci					"AXI_SLV_DEC_Error");
58048c2ecf20Sopenharmony_ci		if (reset_required) {
58058c2ecf20Sopenharmony_ci			dev_err(hdev->dev, "hard reset required due to %s\n",
58068c2ecf20Sopenharmony_ci				gaudi_irq_map_table[event_type].name);
58078c2ecf20Sopenharmony_ci
58088c2ecf20Sopenharmony_ci			if (hdev->hard_reset_on_fw_events)
58098c2ecf20Sopenharmony_ci				hl_device_reset(hdev, true, false);
58108c2ecf20Sopenharmony_ci		} else {
58118c2ecf20Sopenharmony_ci			hl_fw_unmask_irq(hdev, event_type);
58128c2ecf20Sopenharmony_ci		}
58138c2ecf20Sopenharmony_ci		break;
58148c2ecf20Sopenharmony_ci
58158c2ecf20Sopenharmony_ci	case GAUDI_EVENT_TPC0_KRN_ERR:
58168c2ecf20Sopenharmony_ci	case GAUDI_EVENT_TPC1_KRN_ERR:
58178c2ecf20Sopenharmony_ci	case GAUDI_EVENT_TPC2_KRN_ERR:
58188c2ecf20Sopenharmony_ci	case GAUDI_EVENT_TPC3_KRN_ERR:
58198c2ecf20Sopenharmony_ci	case GAUDI_EVENT_TPC4_KRN_ERR:
58208c2ecf20Sopenharmony_ci	case GAUDI_EVENT_TPC5_KRN_ERR:
58218c2ecf20Sopenharmony_ci	case GAUDI_EVENT_TPC6_KRN_ERR:
58228c2ecf20Sopenharmony_ci	case GAUDI_EVENT_TPC7_KRN_ERR:
58238c2ecf20Sopenharmony_ci		gaudi_print_irq_info(hdev, event_type, true);
58248c2ecf20Sopenharmony_ci		reset_required = gaudi_tpc_read_interrupts(hdev,
58258c2ecf20Sopenharmony_ci					tpc_krn_event_to_tpc_id(event_type),
58268c2ecf20Sopenharmony_ci					"KRN_ERR");
58278c2ecf20Sopenharmony_ci		if (reset_required) {
58288c2ecf20Sopenharmony_ci			dev_err(hdev->dev, "hard reset required due to %s\n",
58298c2ecf20Sopenharmony_ci				gaudi_irq_map_table[event_type].name);
58308c2ecf20Sopenharmony_ci
58318c2ecf20Sopenharmony_ci			if (hdev->hard_reset_on_fw_events)
58328c2ecf20Sopenharmony_ci				hl_device_reset(hdev, true, false);
58338c2ecf20Sopenharmony_ci		} else {
58348c2ecf20Sopenharmony_ci			hl_fw_unmask_irq(hdev, event_type);
58358c2ecf20Sopenharmony_ci		}
58368c2ecf20Sopenharmony_ci		break;
58378c2ecf20Sopenharmony_ci
58388c2ecf20Sopenharmony_ci	case GAUDI_EVENT_PCIE_CORE_SERR:
58398c2ecf20Sopenharmony_ci	case GAUDI_EVENT_PCIE_IF_SERR:
58408c2ecf20Sopenharmony_ci	case GAUDI_EVENT_PCIE_PHY_SERR:
58418c2ecf20Sopenharmony_ci	case GAUDI_EVENT_TPC0_SERR ... GAUDI_EVENT_TPC7_SERR:
58428c2ecf20Sopenharmony_ci	case GAUDI_EVENT_MME0_ACC_SERR:
58438c2ecf20Sopenharmony_ci	case GAUDI_EVENT_MME0_SBAB_SERR:
58448c2ecf20Sopenharmony_ci	case GAUDI_EVENT_MME1_ACC_SERR:
58458c2ecf20Sopenharmony_ci	case GAUDI_EVENT_MME1_SBAB_SERR:
58468c2ecf20Sopenharmony_ci	case GAUDI_EVENT_MME2_ACC_SERR:
58478c2ecf20Sopenharmony_ci	case GAUDI_EVENT_MME2_SBAB_SERR:
58488c2ecf20Sopenharmony_ci	case GAUDI_EVENT_MME3_ACC_SERR:
58498c2ecf20Sopenharmony_ci	case GAUDI_EVENT_MME3_SBAB_SERR:
58508c2ecf20Sopenharmony_ci	case GAUDI_EVENT_DMA0_SERR_ECC ... GAUDI_EVENT_DMA7_SERR_ECC:
58518c2ecf20Sopenharmony_ci	case GAUDI_EVENT_CPU_IF_ECC_SERR:
58528c2ecf20Sopenharmony_ci	case GAUDI_EVENT_PSOC_MEM_SERR:
58538c2ecf20Sopenharmony_ci	case GAUDI_EVENT_PSOC_CORESIGHT_SERR:
58548c2ecf20Sopenharmony_ci	case GAUDI_EVENT_SRAM0_SERR ... GAUDI_EVENT_SRAM28_SERR:
58558c2ecf20Sopenharmony_ci	case GAUDI_EVENT_DMA_IF0_SERR ... GAUDI_EVENT_DMA_IF3_SERR:
58568c2ecf20Sopenharmony_ci	case GAUDI_EVENT_HBM_0_SERR ... GAUDI_EVENT_HBM_3_SERR:
58578c2ecf20Sopenharmony_ci		fallthrough;
58588c2ecf20Sopenharmony_ci	case GAUDI_EVENT_MMU_SERR:
58598c2ecf20Sopenharmony_ci		gaudi_print_irq_info(hdev, event_type, true);
58608c2ecf20Sopenharmony_ci		gaudi_handle_ecc_event(hdev, event_type, &eq_entry->ecc_data);
58618c2ecf20Sopenharmony_ci		hl_fw_unmask_irq(hdev, event_type);
58628c2ecf20Sopenharmony_ci		break;
58638c2ecf20Sopenharmony_ci
58648c2ecf20Sopenharmony_ci	case GAUDI_EVENT_PCIE_DEC:
58658c2ecf20Sopenharmony_ci	case GAUDI_EVENT_MME0_WBC_RSP:
58668c2ecf20Sopenharmony_ci	case GAUDI_EVENT_MME0_SBAB0_RSP:
58678c2ecf20Sopenharmony_ci	case GAUDI_EVENT_MME1_WBC_RSP:
58688c2ecf20Sopenharmony_ci	case GAUDI_EVENT_MME1_SBAB0_RSP:
58698c2ecf20Sopenharmony_ci	case GAUDI_EVENT_MME2_WBC_RSP:
58708c2ecf20Sopenharmony_ci	case GAUDI_EVENT_MME2_SBAB0_RSP:
58718c2ecf20Sopenharmony_ci	case GAUDI_EVENT_MME3_WBC_RSP:
58728c2ecf20Sopenharmony_ci	case GAUDI_EVENT_MME3_SBAB0_RSP:
58738c2ecf20Sopenharmony_ci	case GAUDI_EVENT_CPU_AXI_SPLITTER:
58748c2ecf20Sopenharmony_ci	case GAUDI_EVENT_PSOC_AXI_DEC:
58758c2ecf20Sopenharmony_ci	case GAUDI_EVENT_PSOC_PRSTN_FALL:
58768c2ecf20Sopenharmony_ci	case GAUDI_EVENT_MMU_PAGE_FAULT:
58778c2ecf20Sopenharmony_ci	case GAUDI_EVENT_MMU_WR_PERM:
58788c2ecf20Sopenharmony_ci	case GAUDI_EVENT_RAZWI_OR_ADC:
58798c2ecf20Sopenharmony_ci	case GAUDI_EVENT_TPC0_QM ... GAUDI_EVENT_TPC7_QM:
58808c2ecf20Sopenharmony_ci	case GAUDI_EVENT_MME0_QM ... GAUDI_EVENT_MME2_QM:
58818c2ecf20Sopenharmony_ci	case GAUDI_EVENT_DMA0_QM ... GAUDI_EVENT_DMA7_QM:
58828c2ecf20Sopenharmony_ci		fallthrough;
58838c2ecf20Sopenharmony_ci	case GAUDI_EVENT_DMA0_CORE ... GAUDI_EVENT_DMA7_CORE:
58848c2ecf20Sopenharmony_ci		gaudi_print_irq_info(hdev, event_type, true);
58858c2ecf20Sopenharmony_ci		gaudi_handle_qman_err(hdev, event_type);
58868c2ecf20Sopenharmony_ci		hl_fw_unmask_irq(hdev, event_type);
58878c2ecf20Sopenharmony_ci		break;
58888c2ecf20Sopenharmony_ci
58898c2ecf20Sopenharmony_ci	case GAUDI_EVENT_RAZWI_OR_ADC_SW:
58908c2ecf20Sopenharmony_ci		gaudi_print_irq_info(hdev, event_type, true);
58918c2ecf20Sopenharmony_ci		if (hdev->hard_reset_on_fw_events)
58928c2ecf20Sopenharmony_ci			hl_device_reset(hdev, true, false);
58938c2ecf20Sopenharmony_ci		break;
58948c2ecf20Sopenharmony_ci
58958c2ecf20Sopenharmony_ci	case GAUDI_EVENT_TPC0_BMON_SPMU:
58968c2ecf20Sopenharmony_ci	case GAUDI_EVENT_TPC1_BMON_SPMU:
58978c2ecf20Sopenharmony_ci	case GAUDI_EVENT_TPC2_BMON_SPMU:
58988c2ecf20Sopenharmony_ci	case GAUDI_EVENT_TPC3_BMON_SPMU:
58998c2ecf20Sopenharmony_ci	case GAUDI_EVENT_TPC4_BMON_SPMU:
59008c2ecf20Sopenharmony_ci	case GAUDI_EVENT_TPC5_BMON_SPMU:
59018c2ecf20Sopenharmony_ci	case GAUDI_EVENT_TPC6_BMON_SPMU:
59028c2ecf20Sopenharmony_ci	case GAUDI_EVENT_TPC7_BMON_SPMU:
59038c2ecf20Sopenharmony_ci	case GAUDI_EVENT_DMA_BM_CH0 ... GAUDI_EVENT_DMA_BM_CH7:
59048c2ecf20Sopenharmony_ci		gaudi_print_irq_info(hdev, event_type, false);
59058c2ecf20Sopenharmony_ci		hl_fw_unmask_irq(hdev, event_type);
59068c2ecf20Sopenharmony_ci		break;
59078c2ecf20Sopenharmony_ci
59088c2ecf20Sopenharmony_ci	case GAUDI_EVENT_FIX_POWER_ENV_S ... GAUDI_EVENT_FIX_THERMAL_ENV_E:
59098c2ecf20Sopenharmony_ci		gaudi_print_clk_change_info(hdev, event_type);
59108c2ecf20Sopenharmony_ci		hl_fw_unmask_irq(hdev, event_type);
59118c2ecf20Sopenharmony_ci		break;
59128c2ecf20Sopenharmony_ci
59138c2ecf20Sopenharmony_ci	case GAUDI_EVENT_PSOC_GPIO_U16_0:
59148c2ecf20Sopenharmony_ci		cause = le64_to_cpu(eq_entry->data[0]) & 0xFF;
59158c2ecf20Sopenharmony_ci		dev_err(hdev->dev,
59168c2ecf20Sopenharmony_ci			"Received high temp H/W interrupt %d (cause %d)\n",
59178c2ecf20Sopenharmony_ci			event_type, cause);
59188c2ecf20Sopenharmony_ci		break;
59198c2ecf20Sopenharmony_ci
59208c2ecf20Sopenharmony_ci	default:
59218c2ecf20Sopenharmony_ci		dev_err(hdev->dev, "Received invalid H/W interrupt %d\n",
59228c2ecf20Sopenharmony_ci				event_type);
59238c2ecf20Sopenharmony_ci		break;
59248c2ecf20Sopenharmony_ci	}
59258c2ecf20Sopenharmony_ci}
59268c2ecf20Sopenharmony_ci
59278c2ecf20Sopenharmony_cistatic void *gaudi_get_events_stat(struct hl_device *hdev, bool aggregate,
59288c2ecf20Sopenharmony_ci					u32 *size)
59298c2ecf20Sopenharmony_ci{
59308c2ecf20Sopenharmony_ci	struct gaudi_device *gaudi = hdev->asic_specific;
59318c2ecf20Sopenharmony_ci
59328c2ecf20Sopenharmony_ci	if (aggregate) {
59338c2ecf20Sopenharmony_ci		*size = (u32) sizeof(gaudi->events_stat_aggregate);
59348c2ecf20Sopenharmony_ci		return gaudi->events_stat_aggregate;
59358c2ecf20Sopenharmony_ci	}
59368c2ecf20Sopenharmony_ci
59378c2ecf20Sopenharmony_ci	*size = (u32) sizeof(gaudi->events_stat);
59388c2ecf20Sopenharmony_ci	return gaudi->events_stat;
59398c2ecf20Sopenharmony_ci}
59408c2ecf20Sopenharmony_ci
59418c2ecf20Sopenharmony_cistatic int gaudi_mmu_invalidate_cache(struct hl_device *hdev, bool is_hard,
59428c2ecf20Sopenharmony_ci					u32 flags)
59438c2ecf20Sopenharmony_ci{
59448c2ecf20Sopenharmony_ci	struct gaudi_device *gaudi = hdev->asic_specific;
59458c2ecf20Sopenharmony_ci	u32 status, timeout_usec;
59468c2ecf20Sopenharmony_ci	int rc;
59478c2ecf20Sopenharmony_ci
59488c2ecf20Sopenharmony_ci	if (!(gaudi->hw_cap_initialized & HW_CAP_MMU) ||
59498c2ecf20Sopenharmony_ci		hdev->hard_reset_pending)
59508c2ecf20Sopenharmony_ci		return 0;
59518c2ecf20Sopenharmony_ci
59528c2ecf20Sopenharmony_ci	if (hdev->pldm)
59538c2ecf20Sopenharmony_ci		timeout_usec = GAUDI_PLDM_MMU_TIMEOUT_USEC;
59548c2ecf20Sopenharmony_ci	else
59558c2ecf20Sopenharmony_ci		timeout_usec = MMU_CONFIG_TIMEOUT_USEC;
59568c2ecf20Sopenharmony_ci
59578c2ecf20Sopenharmony_ci	mutex_lock(&hdev->mmu_cache_lock);
59588c2ecf20Sopenharmony_ci
59598c2ecf20Sopenharmony_ci	/* L0 & L1 invalidation */
59608c2ecf20Sopenharmony_ci	WREG32(mmSTLB_INV_PS, 3);
59618c2ecf20Sopenharmony_ci	WREG32(mmSTLB_CACHE_INV, gaudi->mmu_cache_inv_pi++);
59628c2ecf20Sopenharmony_ci	WREG32(mmSTLB_INV_PS, 2);
59638c2ecf20Sopenharmony_ci
59648c2ecf20Sopenharmony_ci	rc = hl_poll_timeout(
59658c2ecf20Sopenharmony_ci		hdev,
59668c2ecf20Sopenharmony_ci		mmSTLB_INV_PS,
59678c2ecf20Sopenharmony_ci		status,
59688c2ecf20Sopenharmony_ci		!status,
59698c2ecf20Sopenharmony_ci		1000,
59708c2ecf20Sopenharmony_ci		timeout_usec);
59718c2ecf20Sopenharmony_ci
59728c2ecf20Sopenharmony_ci	WREG32(mmSTLB_INV_SET, 0);
59738c2ecf20Sopenharmony_ci
59748c2ecf20Sopenharmony_ci	mutex_unlock(&hdev->mmu_cache_lock);
59758c2ecf20Sopenharmony_ci
59768c2ecf20Sopenharmony_ci	if (rc) {
59778c2ecf20Sopenharmony_ci		dev_err_ratelimited(hdev->dev,
59788c2ecf20Sopenharmony_ci					"MMU cache invalidation timeout\n");
59798c2ecf20Sopenharmony_ci		hl_device_reset(hdev, true, false);
59808c2ecf20Sopenharmony_ci	}
59818c2ecf20Sopenharmony_ci
59828c2ecf20Sopenharmony_ci	return rc;
59838c2ecf20Sopenharmony_ci}
59848c2ecf20Sopenharmony_ci
59858c2ecf20Sopenharmony_cistatic int gaudi_mmu_invalidate_cache_range(struct hl_device *hdev,
59868c2ecf20Sopenharmony_ci				bool is_hard, u32 asid, u64 va, u64 size)
59878c2ecf20Sopenharmony_ci{
59888c2ecf20Sopenharmony_ci	struct gaudi_device *gaudi = hdev->asic_specific;
59898c2ecf20Sopenharmony_ci	u32 status, timeout_usec;
59908c2ecf20Sopenharmony_ci	u32 inv_data;
59918c2ecf20Sopenharmony_ci	u32 pi;
59928c2ecf20Sopenharmony_ci	int rc;
59938c2ecf20Sopenharmony_ci
59948c2ecf20Sopenharmony_ci	if (!(gaudi->hw_cap_initialized & HW_CAP_MMU) ||
59958c2ecf20Sopenharmony_ci		hdev->hard_reset_pending)
59968c2ecf20Sopenharmony_ci		return 0;
59978c2ecf20Sopenharmony_ci
59988c2ecf20Sopenharmony_ci	mutex_lock(&hdev->mmu_cache_lock);
59998c2ecf20Sopenharmony_ci
60008c2ecf20Sopenharmony_ci	if (hdev->pldm)
60018c2ecf20Sopenharmony_ci		timeout_usec = GAUDI_PLDM_MMU_TIMEOUT_USEC;
60028c2ecf20Sopenharmony_ci	else
60038c2ecf20Sopenharmony_ci		timeout_usec = MMU_CONFIG_TIMEOUT_USEC;
60048c2ecf20Sopenharmony_ci
60058c2ecf20Sopenharmony_ci	/*
60068c2ecf20Sopenharmony_ci	 * TODO: currently invalidate entire L0 & L1 as in regular hard
60078c2ecf20Sopenharmony_ci	 * invalidation. Need to apply invalidation of specific cache
60088c2ecf20Sopenharmony_ci	 * lines with mask of ASID & VA & size.
60098c2ecf20Sopenharmony_ci	 * Note that L1 with be flushed entirely in any case.
60108c2ecf20Sopenharmony_ci	 */
60118c2ecf20Sopenharmony_ci
60128c2ecf20Sopenharmony_ci	/* L0 & L1 invalidation */
60138c2ecf20Sopenharmony_ci	inv_data = RREG32(mmSTLB_CACHE_INV);
60148c2ecf20Sopenharmony_ci	/* PI is 8 bit */
60158c2ecf20Sopenharmony_ci	pi = ((inv_data & STLB_CACHE_INV_PRODUCER_INDEX_MASK) + 1) & 0xFF;
60168c2ecf20Sopenharmony_ci	WREG32(mmSTLB_CACHE_INV,
60178c2ecf20Sopenharmony_ci		(inv_data & STLB_CACHE_INV_INDEX_MASK_MASK) | pi);
60188c2ecf20Sopenharmony_ci
60198c2ecf20Sopenharmony_ci	rc = hl_poll_timeout(
60208c2ecf20Sopenharmony_ci		hdev,
60218c2ecf20Sopenharmony_ci		mmSTLB_INV_CONSUMER_INDEX,
60228c2ecf20Sopenharmony_ci		status,
60238c2ecf20Sopenharmony_ci		status == pi,
60248c2ecf20Sopenharmony_ci		1000,
60258c2ecf20Sopenharmony_ci		timeout_usec);
60268c2ecf20Sopenharmony_ci
60278c2ecf20Sopenharmony_ci	mutex_unlock(&hdev->mmu_cache_lock);
60288c2ecf20Sopenharmony_ci
60298c2ecf20Sopenharmony_ci	if (rc) {
60308c2ecf20Sopenharmony_ci		dev_err_ratelimited(hdev->dev,
60318c2ecf20Sopenharmony_ci					"MMU cache invalidation timeout\n");
60328c2ecf20Sopenharmony_ci		hl_device_reset(hdev, true, false);
60338c2ecf20Sopenharmony_ci	}
60348c2ecf20Sopenharmony_ci
60358c2ecf20Sopenharmony_ci	return rc;
60368c2ecf20Sopenharmony_ci}
60378c2ecf20Sopenharmony_ci
60388c2ecf20Sopenharmony_cistatic int gaudi_mmu_update_asid_hop0_addr(struct hl_device *hdev,
60398c2ecf20Sopenharmony_ci					u32 asid, u64 phys_addr)
60408c2ecf20Sopenharmony_ci{
60418c2ecf20Sopenharmony_ci	u32 status, timeout_usec;
60428c2ecf20Sopenharmony_ci	int rc;
60438c2ecf20Sopenharmony_ci
60448c2ecf20Sopenharmony_ci	if (hdev->pldm)
60458c2ecf20Sopenharmony_ci		timeout_usec = GAUDI_PLDM_MMU_TIMEOUT_USEC;
60468c2ecf20Sopenharmony_ci	else
60478c2ecf20Sopenharmony_ci		timeout_usec = MMU_CONFIG_TIMEOUT_USEC;
60488c2ecf20Sopenharmony_ci
60498c2ecf20Sopenharmony_ci	WREG32(MMU_ASID, asid);
60508c2ecf20Sopenharmony_ci	WREG32(MMU_HOP0_PA43_12, phys_addr >> MMU_HOP0_PA43_12_SHIFT);
60518c2ecf20Sopenharmony_ci	WREG32(MMU_HOP0_PA49_44, phys_addr >> MMU_HOP0_PA49_44_SHIFT);
60528c2ecf20Sopenharmony_ci	WREG32(MMU_BUSY, 0x80000000);
60538c2ecf20Sopenharmony_ci
60548c2ecf20Sopenharmony_ci	rc = hl_poll_timeout(
60558c2ecf20Sopenharmony_ci		hdev,
60568c2ecf20Sopenharmony_ci		MMU_BUSY,
60578c2ecf20Sopenharmony_ci		status,
60588c2ecf20Sopenharmony_ci		!(status & 0x80000000),
60598c2ecf20Sopenharmony_ci		1000,
60608c2ecf20Sopenharmony_ci		timeout_usec);
60618c2ecf20Sopenharmony_ci
60628c2ecf20Sopenharmony_ci	if (rc) {
60638c2ecf20Sopenharmony_ci		dev_err(hdev->dev,
60648c2ecf20Sopenharmony_ci			"Timeout during MMU hop0 config of asid %d\n", asid);
60658c2ecf20Sopenharmony_ci		return rc;
60668c2ecf20Sopenharmony_ci	}
60678c2ecf20Sopenharmony_ci
60688c2ecf20Sopenharmony_ci	return 0;
60698c2ecf20Sopenharmony_ci}
60708c2ecf20Sopenharmony_ci
60718c2ecf20Sopenharmony_cistatic int gaudi_send_heartbeat(struct hl_device *hdev)
60728c2ecf20Sopenharmony_ci{
60738c2ecf20Sopenharmony_ci	struct gaudi_device *gaudi = hdev->asic_specific;
60748c2ecf20Sopenharmony_ci
60758c2ecf20Sopenharmony_ci	if (!(gaudi->hw_cap_initialized & HW_CAP_CPU_Q))
60768c2ecf20Sopenharmony_ci		return 0;
60778c2ecf20Sopenharmony_ci
60788c2ecf20Sopenharmony_ci	return hl_fw_send_heartbeat(hdev);
60798c2ecf20Sopenharmony_ci}
60808c2ecf20Sopenharmony_ci
60818c2ecf20Sopenharmony_cistatic int gaudi_cpucp_info_get(struct hl_device *hdev)
60828c2ecf20Sopenharmony_ci{
60838c2ecf20Sopenharmony_ci	struct gaudi_device *gaudi = hdev->asic_specific;
60848c2ecf20Sopenharmony_ci	struct asic_fixed_properties *prop = &hdev->asic_prop;
60858c2ecf20Sopenharmony_ci	int rc;
60868c2ecf20Sopenharmony_ci
60878c2ecf20Sopenharmony_ci	if (!(gaudi->hw_cap_initialized & HW_CAP_CPU_Q))
60888c2ecf20Sopenharmony_ci		return 0;
60898c2ecf20Sopenharmony_ci
60908c2ecf20Sopenharmony_ci	rc = hl_fw_cpucp_info_get(hdev);
60918c2ecf20Sopenharmony_ci	if (rc)
60928c2ecf20Sopenharmony_ci		return rc;
60938c2ecf20Sopenharmony_ci
60948c2ecf20Sopenharmony_ci	if (!strlen(prop->cpucp_info.card_name))
60958c2ecf20Sopenharmony_ci		strncpy(prop->cpucp_info.card_name, GAUDI_DEFAULT_CARD_NAME,
60968c2ecf20Sopenharmony_ci				CARD_NAME_MAX_LEN);
60978c2ecf20Sopenharmony_ci
60988c2ecf20Sopenharmony_ci	hdev->card_type = le32_to_cpu(hdev->asic_prop.cpucp_info.card_type);
60998c2ecf20Sopenharmony_ci
61008c2ecf20Sopenharmony_ci	if (hdev->card_type == cpucp_card_type_pci)
61018c2ecf20Sopenharmony_ci		prop->max_power_default = MAX_POWER_DEFAULT_PCI;
61028c2ecf20Sopenharmony_ci	else if (hdev->card_type == cpucp_card_type_pmc)
61038c2ecf20Sopenharmony_ci		prop->max_power_default = MAX_POWER_DEFAULT_PMC;
61048c2ecf20Sopenharmony_ci
61058c2ecf20Sopenharmony_ci	hdev->max_power = prop->max_power_default;
61068c2ecf20Sopenharmony_ci
61078c2ecf20Sopenharmony_ci	return 0;
61088c2ecf20Sopenharmony_ci}
61098c2ecf20Sopenharmony_ci
61108c2ecf20Sopenharmony_cistatic bool gaudi_is_device_idle(struct hl_device *hdev, u64 *mask,
61118c2ecf20Sopenharmony_ci					struct seq_file *s)
61128c2ecf20Sopenharmony_ci{
61138c2ecf20Sopenharmony_ci	struct gaudi_device *gaudi = hdev->asic_specific;
61148c2ecf20Sopenharmony_ci	const char *fmt = "%-5d%-9s%#-14x%#-12x%#x\n";
61158c2ecf20Sopenharmony_ci	const char *mme_slave_fmt = "%-5d%-9s%-14s%-12s%#x\n";
61168c2ecf20Sopenharmony_ci	u32 qm_glbl_sts0, qm_cgm_sts, dma_core_sts0, tpc_cfg_sts, mme_arch_sts;
61178c2ecf20Sopenharmony_ci	bool is_idle = true, is_eng_idle, is_slave;
61188c2ecf20Sopenharmony_ci	u64 offset;
61198c2ecf20Sopenharmony_ci	int i, dma_id;
61208c2ecf20Sopenharmony_ci
61218c2ecf20Sopenharmony_ci	mutex_lock(&gaudi->clk_gate_mutex);
61228c2ecf20Sopenharmony_ci
61238c2ecf20Sopenharmony_ci	hdev->asic_funcs->disable_clock_gating(hdev);
61248c2ecf20Sopenharmony_ci
61258c2ecf20Sopenharmony_ci	if (s)
61268c2ecf20Sopenharmony_ci		seq_puts(s,
61278c2ecf20Sopenharmony_ci			"\nDMA  is_idle  QM_GLBL_STS0  QM_CGM_STS  DMA_CORE_STS0\n"
61288c2ecf20Sopenharmony_ci			"---  -------  ------------  ----------  -------------\n");
61298c2ecf20Sopenharmony_ci
61308c2ecf20Sopenharmony_ci	for (i = 0 ; i < DMA_NUMBER_OF_CHNLS ; i++) {
61318c2ecf20Sopenharmony_ci		dma_id = gaudi_dma_assignment[i];
61328c2ecf20Sopenharmony_ci		offset = dma_id * DMA_QMAN_OFFSET;
61338c2ecf20Sopenharmony_ci
61348c2ecf20Sopenharmony_ci		qm_glbl_sts0 = RREG32(mmDMA0_QM_GLBL_STS0 + offset);
61358c2ecf20Sopenharmony_ci		qm_cgm_sts = RREG32(mmDMA0_QM_CGM_STS + offset);
61368c2ecf20Sopenharmony_ci		dma_core_sts0 = RREG32(mmDMA0_CORE_STS0 + offset);
61378c2ecf20Sopenharmony_ci		is_eng_idle = IS_QM_IDLE(qm_glbl_sts0, qm_cgm_sts) &&
61388c2ecf20Sopenharmony_ci				IS_DMA_IDLE(dma_core_sts0);
61398c2ecf20Sopenharmony_ci		is_idle &= is_eng_idle;
61408c2ecf20Sopenharmony_ci
61418c2ecf20Sopenharmony_ci		if (mask)
61428c2ecf20Sopenharmony_ci			*mask |= ((u64) !is_eng_idle) <<
61438c2ecf20Sopenharmony_ci					(GAUDI_ENGINE_ID_DMA_0 + dma_id);
61448c2ecf20Sopenharmony_ci		if (s)
61458c2ecf20Sopenharmony_ci			seq_printf(s, fmt, dma_id,
61468c2ecf20Sopenharmony_ci				is_eng_idle ? "Y" : "N", qm_glbl_sts0,
61478c2ecf20Sopenharmony_ci				qm_cgm_sts, dma_core_sts0);
61488c2ecf20Sopenharmony_ci	}
61498c2ecf20Sopenharmony_ci
61508c2ecf20Sopenharmony_ci	if (s)
61518c2ecf20Sopenharmony_ci		seq_puts(s,
61528c2ecf20Sopenharmony_ci			"\nTPC  is_idle  QM_GLBL_STS0  QM_CGM_STS  CFG_STATUS\n"
61538c2ecf20Sopenharmony_ci			"---  -------  ------------  ----------  ----------\n");
61548c2ecf20Sopenharmony_ci
61558c2ecf20Sopenharmony_ci	for (i = 0 ; i < TPC_NUMBER_OF_ENGINES ; i++) {
61568c2ecf20Sopenharmony_ci		offset = i * TPC_QMAN_OFFSET;
61578c2ecf20Sopenharmony_ci		qm_glbl_sts0 = RREG32(mmTPC0_QM_GLBL_STS0 + offset);
61588c2ecf20Sopenharmony_ci		qm_cgm_sts = RREG32(mmTPC0_QM_CGM_STS + offset);
61598c2ecf20Sopenharmony_ci		tpc_cfg_sts = RREG32(mmTPC0_CFG_STATUS + offset);
61608c2ecf20Sopenharmony_ci		is_eng_idle = IS_QM_IDLE(qm_glbl_sts0, qm_cgm_sts) &&
61618c2ecf20Sopenharmony_ci				IS_TPC_IDLE(tpc_cfg_sts);
61628c2ecf20Sopenharmony_ci		is_idle &= is_eng_idle;
61638c2ecf20Sopenharmony_ci
61648c2ecf20Sopenharmony_ci		if (mask)
61658c2ecf20Sopenharmony_ci			*mask |= ((u64) !is_eng_idle) <<
61668c2ecf20Sopenharmony_ci						(GAUDI_ENGINE_ID_TPC_0 + i);
61678c2ecf20Sopenharmony_ci		if (s)
61688c2ecf20Sopenharmony_ci			seq_printf(s, fmt, i,
61698c2ecf20Sopenharmony_ci				is_eng_idle ? "Y" : "N",
61708c2ecf20Sopenharmony_ci				qm_glbl_sts0, qm_cgm_sts, tpc_cfg_sts);
61718c2ecf20Sopenharmony_ci	}
61728c2ecf20Sopenharmony_ci
61738c2ecf20Sopenharmony_ci	if (s)
61748c2ecf20Sopenharmony_ci		seq_puts(s,
61758c2ecf20Sopenharmony_ci			"\nMME  is_idle  QM_GLBL_STS0  QM_CGM_STS  ARCH_STATUS\n"
61768c2ecf20Sopenharmony_ci			"---  -------  ------------  ----------  -----------\n");
61778c2ecf20Sopenharmony_ci
61788c2ecf20Sopenharmony_ci	for (i = 0 ; i < MME_NUMBER_OF_ENGINES ; i++) {
61798c2ecf20Sopenharmony_ci		offset = i * MME_QMAN_OFFSET;
61808c2ecf20Sopenharmony_ci		mme_arch_sts = RREG32(mmMME0_CTRL_ARCH_STATUS + offset);
61818c2ecf20Sopenharmony_ci		is_eng_idle = IS_MME_IDLE(mme_arch_sts);
61828c2ecf20Sopenharmony_ci
61838c2ecf20Sopenharmony_ci		/* MME 1 & 3 are slaves, no need to check their QMANs */
61848c2ecf20Sopenharmony_ci		is_slave = i % 2;
61858c2ecf20Sopenharmony_ci		if (!is_slave) {
61868c2ecf20Sopenharmony_ci			qm_glbl_sts0 = RREG32(mmMME0_QM_GLBL_STS0 + offset);
61878c2ecf20Sopenharmony_ci			qm_cgm_sts = RREG32(mmMME0_QM_CGM_STS + offset);
61888c2ecf20Sopenharmony_ci			is_eng_idle &= IS_QM_IDLE(qm_glbl_sts0, qm_cgm_sts);
61898c2ecf20Sopenharmony_ci		}
61908c2ecf20Sopenharmony_ci
61918c2ecf20Sopenharmony_ci		is_idle &= is_eng_idle;
61928c2ecf20Sopenharmony_ci
61938c2ecf20Sopenharmony_ci		if (mask)
61948c2ecf20Sopenharmony_ci			*mask |= ((u64) !is_eng_idle) <<
61958c2ecf20Sopenharmony_ci						(GAUDI_ENGINE_ID_MME_0 + i);
61968c2ecf20Sopenharmony_ci		if (s) {
61978c2ecf20Sopenharmony_ci			if (!is_slave)
61988c2ecf20Sopenharmony_ci				seq_printf(s, fmt, i,
61998c2ecf20Sopenharmony_ci					is_eng_idle ? "Y" : "N",
62008c2ecf20Sopenharmony_ci					qm_glbl_sts0, qm_cgm_sts, mme_arch_sts);
62018c2ecf20Sopenharmony_ci			else
62028c2ecf20Sopenharmony_ci				seq_printf(s, mme_slave_fmt, i,
62038c2ecf20Sopenharmony_ci					is_eng_idle ? "Y" : "N", "-",
62048c2ecf20Sopenharmony_ci					"-", mme_arch_sts);
62058c2ecf20Sopenharmony_ci		}
62068c2ecf20Sopenharmony_ci	}
62078c2ecf20Sopenharmony_ci
62088c2ecf20Sopenharmony_ci	if (s)
62098c2ecf20Sopenharmony_ci		seq_puts(s, "\n");
62108c2ecf20Sopenharmony_ci
62118c2ecf20Sopenharmony_ci	hdev->asic_funcs->set_clock_gating(hdev);
62128c2ecf20Sopenharmony_ci
62138c2ecf20Sopenharmony_ci	mutex_unlock(&gaudi->clk_gate_mutex);
62148c2ecf20Sopenharmony_ci
62158c2ecf20Sopenharmony_ci	return is_idle;
62168c2ecf20Sopenharmony_ci}
62178c2ecf20Sopenharmony_ci
62188c2ecf20Sopenharmony_cistatic void gaudi_hw_queues_lock(struct hl_device *hdev)
62198c2ecf20Sopenharmony_ci	__acquires(&gaudi->hw_queues_lock)
62208c2ecf20Sopenharmony_ci{
62218c2ecf20Sopenharmony_ci	struct gaudi_device *gaudi = hdev->asic_specific;
62228c2ecf20Sopenharmony_ci
62238c2ecf20Sopenharmony_ci	spin_lock(&gaudi->hw_queues_lock);
62248c2ecf20Sopenharmony_ci}
62258c2ecf20Sopenharmony_ci
62268c2ecf20Sopenharmony_cistatic void gaudi_hw_queues_unlock(struct hl_device *hdev)
62278c2ecf20Sopenharmony_ci	__releases(&gaudi->hw_queues_lock)
62288c2ecf20Sopenharmony_ci{
62298c2ecf20Sopenharmony_ci	struct gaudi_device *gaudi = hdev->asic_specific;
62308c2ecf20Sopenharmony_ci
62318c2ecf20Sopenharmony_ci	spin_unlock(&gaudi->hw_queues_lock);
62328c2ecf20Sopenharmony_ci}
62338c2ecf20Sopenharmony_ci
62348c2ecf20Sopenharmony_cistatic u32 gaudi_get_pci_id(struct hl_device *hdev)
62358c2ecf20Sopenharmony_ci{
62368c2ecf20Sopenharmony_ci	return hdev->pdev->device;
62378c2ecf20Sopenharmony_ci}
62388c2ecf20Sopenharmony_ci
62398c2ecf20Sopenharmony_cistatic int gaudi_get_eeprom_data(struct hl_device *hdev, void *data,
62408c2ecf20Sopenharmony_ci				size_t max_size)
62418c2ecf20Sopenharmony_ci{
62428c2ecf20Sopenharmony_ci	struct gaudi_device *gaudi = hdev->asic_specific;
62438c2ecf20Sopenharmony_ci
62448c2ecf20Sopenharmony_ci	if (!(gaudi->hw_cap_initialized & HW_CAP_CPU_Q))
62458c2ecf20Sopenharmony_ci		return 0;
62468c2ecf20Sopenharmony_ci
62478c2ecf20Sopenharmony_ci	return hl_fw_get_eeprom_data(hdev, data, max_size);
62488c2ecf20Sopenharmony_ci}
62498c2ecf20Sopenharmony_ci
62508c2ecf20Sopenharmony_ci/*
62518c2ecf20Sopenharmony_ci * this function should be used only during initialization and/or after reset,
62528c2ecf20Sopenharmony_ci * when there are no active users.
62538c2ecf20Sopenharmony_ci */
62548c2ecf20Sopenharmony_cistatic int gaudi_run_tpc_kernel(struct hl_device *hdev, u64 tpc_kernel,
62558c2ecf20Sopenharmony_ci				u32 tpc_id)
62568c2ecf20Sopenharmony_ci{
62578c2ecf20Sopenharmony_ci	struct gaudi_device *gaudi = hdev->asic_specific;
62588c2ecf20Sopenharmony_ci	u64 kernel_timeout;
62598c2ecf20Sopenharmony_ci	u32 status, offset;
62608c2ecf20Sopenharmony_ci	int rc;
62618c2ecf20Sopenharmony_ci
62628c2ecf20Sopenharmony_ci	offset = tpc_id * (mmTPC1_CFG_STATUS - mmTPC0_CFG_STATUS);
62638c2ecf20Sopenharmony_ci
62648c2ecf20Sopenharmony_ci	if (hdev->pldm)
62658c2ecf20Sopenharmony_ci		kernel_timeout = GAUDI_PLDM_TPC_KERNEL_WAIT_USEC;
62668c2ecf20Sopenharmony_ci	else
62678c2ecf20Sopenharmony_ci		kernel_timeout = HL_DEVICE_TIMEOUT_USEC;
62688c2ecf20Sopenharmony_ci
62698c2ecf20Sopenharmony_ci	mutex_lock(&gaudi->clk_gate_mutex);
62708c2ecf20Sopenharmony_ci
62718c2ecf20Sopenharmony_ci	hdev->asic_funcs->disable_clock_gating(hdev);
62728c2ecf20Sopenharmony_ci
62738c2ecf20Sopenharmony_ci	WREG32(mmTPC0_CFG_QM_KERNEL_BASE_ADDRESS_LOW + offset,
62748c2ecf20Sopenharmony_ci			lower_32_bits(tpc_kernel));
62758c2ecf20Sopenharmony_ci	WREG32(mmTPC0_CFG_QM_KERNEL_BASE_ADDRESS_HIGH + offset,
62768c2ecf20Sopenharmony_ci			upper_32_bits(tpc_kernel));
62778c2ecf20Sopenharmony_ci
62788c2ecf20Sopenharmony_ci	WREG32(mmTPC0_CFG_ICACHE_BASE_ADDERESS_LOW + offset,
62798c2ecf20Sopenharmony_ci			lower_32_bits(tpc_kernel));
62808c2ecf20Sopenharmony_ci	WREG32(mmTPC0_CFG_ICACHE_BASE_ADDERESS_HIGH + offset,
62818c2ecf20Sopenharmony_ci			upper_32_bits(tpc_kernel));
62828c2ecf20Sopenharmony_ci	/* set a valid LUT pointer, content is of no significance */
62838c2ecf20Sopenharmony_ci	WREG32(mmTPC0_CFG_LUT_FUNC256_BASE_ADDR_LO + offset,
62848c2ecf20Sopenharmony_ci			lower_32_bits(tpc_kernel));
62858c2ecf20Sopenharmony_ci	WREG32(mmTPC0_CFG_LUT_FUNC256_BASE_ADDR_HI + offset,
62868c2ecf20Sopenharmony_ci			upper_32_bits(tpc_kernel));
62878c2ecf20Sopenharmony_ci
62888c2ecf20Sopenharmony_ci	WREG32(mmTPC0_CFG_QM_SYNC_OBJECT_ADDR + offset,
62898c2ecf20Sopenharmony_ci			lower_32_bits(CFG_BASE +
62908c2ecf20Sopenharmony_ci				mmSYNC_MNGR_E_N_SYNC_MNGR_OBJS_SOB_OBJ_0));
62918c2ecf20Sopenharmony_ci
62928c2ecf20Sopenharmony_ci	WREG32(mmTPC0_CFG_TPC_CMD + offset,
62938c2ecf20Sopenharmony_ci			(1 << TPC0_CFG_TPC_CMD_ICACHE_INVALIDATE_SHIFT |
62948c2ecf20Sopenharmony_ci			1 << TPC0_CFG_TPC_CMD_ICACHE_PREFETCH_64KB_SHIFT));
62958c2ecf20Sopenharmony_ci	/* wait a bit for the engine to start executing */
62968c2ecf20Sopenharmony_ci	usleep_range(1000, 1500);
62978c2ecf20Sopenharmony_ci
62988c2ecf20Sopenharmony_ci	/* wait until engine has finished executing */
62998c2ecf20Sopenharmony_ci	rc = hl_poll_timeout(
63008c2ecf20Sopenharmony_ci		hdev,
63018c2ecf20Sopenharmony_ci		mmTPC0_CFG_STATUS + offset,
63028c2ecf20Sopenharmony_ci		status,
63038c2ecf20Sopenharmony_ci		(status & TPC0_CFG_STATUS_VECTOR_PIPE_EMPTY_MASK) ==
63048c2ecf20Sopenharmony_ci				TPC0_CFG_STATUS_VECTOR_PIPE_EMPTY_MASK,
63058c2ecf20Sopenharmony_ci		1000,
63068c2ecf20Sopenharmony_ci		kernel_timeout);
63078c2ecf20Sopenharmony_ci
63088c2ecf20Sopenharmony_ci	if (rc) {
63098c2ecf20Sopenharmony_ci		dev_err(hdev->dev,
63108c2ecf20Sopenharmony_ci			"Timeout while waiting for TPC%d icache prefetch\n",
63118c2ecf20Sopenharmony_ci			tpc_id);
63128c2ecf20Sopenharmony_ci		hdev->asic_funcs->set_clock_gating(hdev);
63138c2ecf20Sopenharmony_ci		mutex_unlock(&gaudi->clk_gate_mutex);
63148c2ecf20Sopenharmony_ci		return -EIO;
63158c2ecf20Sopenharmony_ci	}
63168c2ecf20Sopenharmony_ci
63178c2ecf20Sopenharmony_ci	WREG32(mmTPC0_CFG_TPC_EXECUTE + offset,
63188c2ecf20Sopenharmony_ci			1 << TPC0_CFG_TPC_EXECUTE_V_SHIFT);
63198c2ecf20Sopenharmony_ci
63208c2ecf20Sopenharmony_ci	/* wait a bit for the engine to start executing */
63218c2ecf20Sopenharmony_ci	usleep_range(1000, 1500);
63228c2ecf20Sopenharmony_ci
63238c2ecf20Sopenharmony_ci	/* wait until engine has finished executing */
63248c2ecf20Sopenharmony_ci	rc = hl_poll_timeout(
63258c2ecf20Sopenharmony_ci		hdev,
63268c2ecf20Sopenharmony_ci		mmTPC0_CFG_STATUS + offset,
63278c2ecf20Sopenharmony_ci		status,
63288c2ecf20Sopenharmony_ci		(status & TPC0_CFG_STATUS_VECTOR_PIPE_EMPTY_MASK) ==
63298c2ecf20Sopenharmony_ci				TPC0_CFG_STATUS_VECTOR_PIPE_EMPTY_MASK,
63308c2ecf20Sopenharmony_ci		1000,
63318c2ecf20Sopenharmony_ci		kernel_timeout);
63328c2ecf20Sopenharmony_ci
63338c2ecf20Sopenharmony_ci	if (rc) {
63348c2ecf20Sopenharmony_ci		dev_err(hdev->dev,
63358c2ecf20Sopenharmony_ci			"Timeout while waiting for TPC%d vector pipe\n",
63368c2ecf20Sopenharmony_ci			tpc_id);
63378c2ecf20Sopenharmony_ci		hdev->asic_funcs->set_clock_gating(hdev);
63388c2ecf20Sopenharmony_ci		mutex_unlock(&gaudi->clk_gate_mutex);
63398c2ecf20Sopenharmony_ci		return -EIO;
63408c2ecf20Sopenharmony_ci	}
63418c2ecf20Sopenharmony_ci
63428c2ecf20Sopenharmony_ci	rc = hl_poll_timeout(
63438c2ecf20Sopenharmony_ci		hdev,
63448c2ecf20Sopenharmony_ci		mmTPC0_CFG_WQ_INFLIGHT_CNTR + offset,
63458c2ecf20Sopenharmony_ci		status,
63468c2ecf20Sopenharmony_ci		(status == 0),
63478c2ecf20Sopenharmony_ci		1000,
63488c2ecf20Sopenharmony_ci		kernel_timeout);
63498c2ecf20Sopenharmony_ci
63508c2ecf20Sopenharmony_ci	hdev->asic_funcs->set_clock_gating(hdev);
63518c2ecf20Sopenharmony_ci	mutex_unlock(&gaudi->clk_gate_mutex);
63528c2ecf20Sopenharmony_ci
63538c2ecf20Sopenharmony_ci	if (rc) {
63548c2ecf20Sopenharmony_ci		dev_err(hdev->dev,
63558c2ecf20Sopenharmony_ci			"Timeout while waiting for TPC%d kernel to execute\n",
63568c2ecf20Sopenharmony_ci			tpc_id);
63578c2ecf20Sopenharmony_ci		return -EIO;
63588c2ecf20Sopenharmony_ci	}
63598c2ecf20Sopenharmony_ci
63608c2ecf20Sopenharmony_ci	return 0;
63618c2ecf20Sopenharmony_ci}
63628c2ecf20Sopenharmony_ci
63638c2ecf20Sopenharmony_cistatic enum hl_device_hw_state gaudi_get_hw_state(struct hl_device *hdev)
63648c2ecf20Sopenharmony_ci{
63658c2ecf20Sopenharmony_ci	return RREG32(mmHW_STATE);
63668c2ecf20Sopenharmony_ci}
63678c2ecf20Sopenharmony_ci
63688c2ecf20Sopenharmony_cistatic int gaudi_ctx_init(struct hl_ctx *ctx)
63698c2ecf20Sopenharmony_ci{
63708c2ecf20Sopenharmony_ci	return 0;
63718c2ecf20Sopenharmony_ci}
63728c2ecf20Sopenharmony_ci
63738c2ecf20Sopenharmony_cistatic u32 gaudi_get_queue_id_for_cq(struct hl_device *hdev, u32 cq_idx)
63748c2ecf20Sopenharmony_ci{
63758c2ecf20Sopenharmony_ci	return gaudi_cq_assignment[cq_idx];
63768c2ecf20Sopenharmony_ci}
63778c2ecf20Sopenharmony_ci
63788c2ecf20Sopenharmony_cistatic u32 gaudi_get_signal_cb_size(struct hl_device *hdev)
63798c2ecf20Sopenharmony_ci{
63808c2ecf20Sopenharmony_ci	return sizeof(struct packet_msg_short) +
63818c2ecf20Sopenharmony_ci			sizeof(struct packet_msg_prot) * 2;
63828c2ecf20Sopenharmony_ci}
63838c2ecf20Sopenharmony_ci
63848c2ecf20Sopenharmony_cistatic u32 gaudi_get_wait_cb_size(struct hl_device *hdev)
63858c2ecf20Sopenharmony_ci{
63868c2ecf20Sopenharmony_ci	return sizeof(struct packet_msg_short) * 4 +
63878c2ecf20Sopenharmony_ci			sizeof(struct packet_fence) +
63888c2ecf20Sopenharmony_ci			sizeof(struct packet_msg_prot) * 2;
63898c2ecf20Sopenharmony_ci}
63908c2ecf20Sopenharmony_ci
63918c2ecf20Sopenharmony_cistatic void gaudi_gen_signal_cb(struct hl_device *hdev, void *data, u16 sob_id)
63928c2ecf20Sopenharmony_ci{
63938c2ecf20Sopenharmony_ci	struct hl_cb *cb = (struct hl_cb *) data;
63948c2ecf20Sopenharmony_ci	struct packet_msg_short *pkt;
63958c2ecf20Sopenharmony_ci	u32 value, ctl;
63968c2ecf20Sopenharmony_ci
63978c2ecf20Sopenharmony_ci	pkt = cb->kernel_address;
63988c2ecf20Sopenharmony_ci	memset(pkt, 0, sizeof(*pkt));
63998c2ecf20Sopenharmony_ci
64008c2ecf20Sopenharmony_ci	/* Inc by 1, Mode ADD */
64018c2ecf20Sopenharmony_ci	value = FIELD_PREP(GAUDI_PKT_SHORT_VAL_SOB_SYNC_VAL_MASK, 1);
64028c2ecf20Sopenharmony_ci	value |= FIELD_PREP(GAUDI_PKT_SHORT_VAL_SOB_MOD_MASK, 1);
64038c2ecf20Sopenharmony_ci
64048c2ecf20Sopenharmony_ci	ctl = FIELD_PREP(GAUDI_PKT_SHORT_CTL_ADDR_MASK, sob_id * 4);
64058c2ecf20Sopenharmony_ci	ctl |= FIELD_PREP(GAUDI_PKT_SHORT_CTL_OP_MASK, 0); /* write the value */
64068c2ecf20Sopenharmony_ci	ctl |= FIELD_PREP(GAUDI_PKT_SHORT_CTL_BASE_MASK, 3); /* W_S SOB base */
64078c2ecf20Sopenharmony_ci	ctl |= FIELD_PREP(GAUDI_PKT_SHORT_CTL_OPCODE_MASK, PACKET_MSG_SHORT);
64088c2ecf20Sopenharmony_ci	ctl |= FIELD_PREP(GAUDI_PKT_SHORT_CTL_EB_MASK, 1);
64098c2ecf20Sopenharmony_ci	ctl |= FIELD_PREP(GAUDI_PKT_SHORT_CTL_RB_MASK, 1);
64108c2ecf20Sopenharmony_ci	ctl |= FIELD_PREP(GAUDI_PKT_SHORT_CTL_MB_MASK, 1);
64118c2ecf20Sopenharmony_ci
64128c2ecf20Sopenharmony_ci	pkt->value = cpu_to_le32(value);
64138c2ecf20Sopenharmony_ci	pkt->ctl = cpu_to_le32(ctl);
64148c2ecf20Sopenharmony_ci}
64158c2ecf20Sopenharmony_ci
64168c2ecf20Sopenharmony_cistatic u32 gaudi_add_mon_msg_short(struct packet_msg_short *pkt, u32 value,
64178c2ecf20Sopenharmony_ci					u16 addr)
64188c2ecf20Sopenharmony_ci{
64198c2ecf20Sopenharmony_ci	u32 ctl, pkt_size = sizeof(*pkt);
64208c2ecf20Sopenharmony_ci
64218c2ecf20Sopenharmony_ci	memset(pkt, 0, pkt_size);
64228c2ecf20Sopenharmony_ci
64238c2ecf20Sopenharmony_ci	ctl = FIELD_PREP(GAUDI_PKT_SHORT_CTL_ADDR_MASK, addr);
64248c2ecf20Sopenharmony_ci	ctl |= FIELD_PREP(GAUDI_PKT_SHORT_CTL_BASE_MASK, 2);  /* W_S MON base */
64258c2ecf20Sopenharmony_ci	ctl |= FIELD_PREP(GAUDI_PKT_SHORT_CTL_OPCODE_MASK, PACKET_MSG_SHORT);
64268c2ecf20Sopenharmony_ci	ctl |= FIELD_PREP(GAUDI_PKT_SHORT_CTL_EB_MASK, 0);
64278c2ecf20Sopenharmony_ci	ctl |= FIELD_PREP(GAUDI_PKT_SHORT_CTL_RB_MASK, 1);
64288c2ecf20Sopenharmony_ci	ctl |= FIELD_PREP(GAUDI_PKT_SHORT_CTL_MB_MASK, 0); /* last pkt MB */
64298c2ecf20Sopenharmony_ci
64308c2ecf20Sopenharmony_ci	pkt->value = cpu_to_le32(value);
64318c2ecf20Sopenharmony_ci	pkt->ctl = cpu_to_le32(ctl);
64328c2ecf20Sopenharmony_ci
64338c2ecf20Sopenharmony_ci	return pkt_size;
64348c2ecf20Sopenharmony_ci}
64358c2ecf20Sopenharmony_ci
64368c2ecf20Sopenharmony_cistatic u32 gaudi_add_arm_monitor_pkt(struct packet_msg_short *pkt, u16 sob_id,
64378c2ecf20Sopenharmony_ci					u16 sob_val, u16 addr)
64388c2ecf20Sopenharmony_ci{
64398c2ecf20Sopenharmony_ci	u32 ctl, value, pkt_size = sizeof(*pkt);
64408c2ecf20Sopenharmony_ci	u8 mask = ~(1 << (sob_id & 0x7));
64418c2ecf20Sopenharmony_ci
64428c2ecf20Sopenharmony_ci	memset(pkt, 0, pkt_size);
64438c2ecf20Sopenharmony_ci
64448c2ecf20Sopenharmony_ci	value = FIELD_PREP(GAUDI_PKT_SHORT_VAL_MON_SYNC_GID_MASK, sob_id / 8);
64458c2ecf20Sopenharmony_ci	value |= FIELD_PREP(GAUDI_PKT_SHORT_VAL_MON_SYNC_VAL_MASK, sob_val);
64468c2ecf20Sopenharmony_ci	value |= FIELD_PREP(GAUDI_PKT_SHORT_VAL_MON_MODE_MASK,
64478c2ecf20Sopenharmony_ci			0); /* GREATER OR EQUAL*/
64488c2ecf20Sopenharmony_ci	value |= FIELD_PREP(GAUDI_PKT_SHORT_VAL_MON_MASK_MASK, mask);
64498c2ecf20Sopenharmony_ci
64508c2ecf20Sopenharmony_ci	ctl = FIELD_PREP(GAUDI_PKT_SHORT_CTL_ADDR_MASK, addr);
64518c2ecf20Sopenharmony_ci	ctl |= FIELD_PREP(GAUDI_PKT_SHORT_CTL_OP_MASK, 0); /* write the value */
64528c2ecf20Sopenharmony_ci	ctl |= FIELD_PREP(GAUDI_PKT_SHORT_CTL_BASE_MASK, 2); /* W_S MON base */
64538c2ecf20Sopenharmony_ci	ctl |= FIELD_PREP(GAUDI_PKT_SHORT_CTL_OPCODE_MASK, PACKET_MSG_SHORT);
64548c2ecf20Sopenharmony_ci	ctl |= FIELD_PREP(GAUDI_PKT_SHORT_CTL_EB_MASK, 0);
64558c2ecf20Sopenharmony_ci	ctl |= FIELD_PREP(GAUDI_PKT_SHORT_CTL_RB_MASK, 1);
64568c2ecf20Sopenharmony_ci	ctl |= FIELD_PREP(GAUDI_PKT_SHORT_CTL_MB_MASK, 1);
64578c2ecf20Sopenharmony_ci
64588c2ecf20Sopenharmony_ci	pkt->value = cpu_to_le32(value);
64598c2ecf20Sopenharmony_ci	pkt->ctl = cpu_to_le32(ctl);
64608c2ecf20Sopenharmony_ci
64618c2ecf20Sopenharmony_ci	return pkt_size;
64628c2ecf20Sopenharmony_ci}
64638c2ecf20Sopenharmony_ci
64648c2ecf20Sopenharmony_cistatic u32 gaudi_add_fence_pkt(struct packet_fence *pkt)
64658c2ecf20Sopenharmony_ci{
64668c2ecf20Sopenharmony_ci	u32 ctl, cfg, pkt_size = sizeof(*pkt);
64678c2ecf20Sopenharmony_ci
64688c2ecf20Sopenharmony_ci	memset(pkt, 0, pkt_size);
64698c2ecf20Sopenharmony_ci
64708c2ecf20Sopenharmony_ci	cfg = FIELD_PREP(GAUDI_PKT_FENCE_CFG_DEC_VAL_MASK, 1);
64718c2ecf20Sopenharmony_ci	cfg |= FIELD_PREP(GAUDI_PKT_FENCE_CFG_TARGET_VAL_MASK, 1);
64728c2ecf20Sopenharmony_ci	cfg |= FIELD_PREP(GAUDI_PKT_FENCE_CFG_ID_MASK, 2);
64738c2ecf20Sopenharmony_ci
64748c2ecf20Sopenharmony_ci	ctl = FIELD_PREP(GAUDI_PKT_FENCE_CTL_OPCODE_MASK, PACKET_FENCE);
64758c2ecf20Sopenharmony_ci	ctl |= FIELD_PREP(GAUDI_PKT_SHORT_CTL_EB_MASK, 0);
64768c2ecf20Sopenharmony_ci	ctl |= FIELD_PREP(GAUDI_PKT_SHORT_CTL_RB_MASK, 1);
64778c2ecf20Sopenharmony_ci	ctl |= FIELD_PREP(GAUDI_PKT_SHORT_CTL_MB_MASK, 1);
64788c2ecf20Sopenharmony_ci
64798c2ecf20Sopenharmony_ci	pkt->cfg = cpu_to_le32(cfg);
64808c2ecf20Sopenharmony_ci	pkt->ctl = cpu_to_le32(ctl);
64818c2ecf20Sopenharmony_ci
64828c2ecf20Sopenharmony_ci	return pkt_size;
64838c2ecf20Sopenharmony_ci}
64848c2ecf20Sopenharmony_ci
64858c2ecf20Sopenharmony_cistatic void gaudi_gen_wait_cb(struct hl_device *hdev, void *data, u16 sob_id,
64868c2ecf20Sopenharmony_ci			u16 sob_val, u16 mon_id, u32 q_idx)
64878c2ecf20Sopenharmony_ci{
64888c2ecf20Sopenharmony_ci	struct hl_cb *cb = (struct hl_cb *) data;
64898c2ecf20Sopenharmony_ci	void *buf = cb->kernel_address;
64908c2ecf20Sopenharmony_ci	u64 monitor_base, fence_addr = 0;
64918c2ecf20Sopenharmony_ci	u32 size = 0;
64928c2ecf20Sopenharmony_ci	u16 msg_addr_offset;
64938c2ecf20Sopenharmony_ci
64948c2ecf20Sopenharmony_ci	switch (q_idx) {
64958c2ecf20Sopenharmony_ci	case GAUDI_QUEUE_ID_DMA_0_0:
64968c2ecf20Sopenharmony_ci		fence_addr = mmDMA0_QM_CP_FENCE2_RDATA_0;
64978c2ecf20Sopenharmony_ci		break;
64988c2ecf20Sopenharmony_ci	case GAUDI_QUEUE_ID_DMA_0_1:
64998c2ecf20Sopenharmony_ci		fence_addr = mmDMA0_QM_CP_FENCE2_RDATA_1;
65008c2ecf20Sopenharmony_ci		break;
65018c2ecf20Sopenharmony_ci	case GAUDI_QUEUE_ID_DMA_0_2:
65028c2ecf20Sopenharmony_ci		fence_addr = mmDMA0_QM_CP_FENCE2_RDATA_2;
65038c2ecf20Sopenharmony_ci		break;
65048c2ecf20Sopenharmony_ci	case GAUDI_QUEUE_ID_DMA_0_3:
65058c2ecf20Sopenharmony_ci		fence_addr = mmDMA0_QM_CP_FENCE2_RDATA_3;
65068c2ecf20Sopenharmony_ci		break;
65078c2ecf20Sopenharmony_ci	case GAUDI_QUEUE_ID_DMA_1_0:
65088c2ecf20Sopenharmony_ci		fence_addr = mmDMA1_QM_CP_FENCE2_RDATA_0;
65098c2ecf20Sopenharmony_ci		break;
65108c2ecf20Sopenharmony_ci	case GAUDI_QUEUE_ID_DMA_1_1:
65118c2ecf20Sopenharmony_ci		fence_addr = mmDMA1_QM_CP_FENCE2_RDATA_1;
65128c2ecf20Sopenharmony_ci		break;
65138c2ecf20Sopenharmony_ci	case GAUDI_QUEUE_ID_DMA_1_2:
65148c2ecf20Sopenharmony_ci		fence_addr = mmDMA1_QM_CP_FENCE2_RDATA_2;
65158c2ecf20Sopenharmony_ci		break;
65168c2ecf20Sopenharmony_ci	case GAUDI_QUEUE_ID_DMA_1_3:
65178c2ecf20Sopenharmony_ci		fence_addr = mmDMA1_QM_CP_FENCE2_RDATA_3;
65188c2ecf20Sopenharmony_ci		break;
65198c2ecf20Sopenharmony_ci	case GAUDI_QUEUE_ID_DMA_5_0:
65208c2ecf20Sopenharmony_ci		fence_addr = mmDMA5_QM_CP_FENCE2_RDATA_0;
65218c2ecf20Sopenharmony_ci		break;
65228c2ecf20Sopenharmony_ci	case GAUDI_QUEUE_ID_DMA_5_1:
65238c2ecf20Sopenharmony_ci		fence_addr = mmDMA5_QM_CP_FENCE2_RDATA_1;
65248c2ecf20Sopenharmony_ci		break;
65258c2ecf20Sopenharmony_ci	case GAUDI_QUEUE_ID_DMA_5_2:
65268c2ecf20Sopenharmony_ci		fence_addr = mmDMA5_QM_CP_FENCE2_RDATA_2;
65278c2ecf20Sopenharmony_ci		break;
65288c2ecf20Sopenharmony_ci	case GAUDI_QUEUE_ID_DMA_5_3:
65298c2ecf20Sopenharmony_ci		fence_addr = mmDMA5_QM_CP_FENCE2_RDATA_3;
65308c2ecf20Sopenharmony_ci		break;
65318c2ecf20Sopenharmony_ci	default:
65328c2ecf20Sopenharmony_ci		/* queue index should be valid here */
65338c2ecf20Sopenharmony_ci		dev_crit(hdev->dev, "wrong queue id %d for wait packet\n",
65348c2ecf20Sopenharmony_ci				q_idx);
65358c2ecf20Sopenharmony_ci		return;
65368c2ecf20Sopenharmony_ci	}
65378c2ecf20Sopenharmony_ci
65388c2ecf20Sopenharmony_ci	fence_addr += CFG_BASE;
65398c2ecf20Sopenharmony_ci
65408c2ecf20Sopenharmony_ci	/*
65418c2ecf20Sopenharmony_ci	 * monitor_base should be the content of the base0 address registers,
65428c2ecf20Sopenharmony_ci	 * so it will be added to the msg short offsets
65438c2ecf20Sopenharmony_ci	 */
65448c2ecf20Sopenharmony_ci	monitor_base = mmSYNC_MNGR_W_S_SYNC_MNGR_OBJS_MON_PAY_ADDRL_0;
65458c2ecf20Sopenharmony_ci
65468c2ecf20Sopenharmony_ci	/* First monitor config packet: low address of the sync */
65478c2ecf20Sopenharmony_ci	msg_addr_offset =
65488c2ecf20Sopenharmony_ci		(mmSYNC_MNGR_W_S_SYNC_MNGR_OBJS_MON_PAY_ADDRL_0 + mon_id * 4) -
65498c2ecf20Sopenharmony_ci				monitor_base;
65508c2ecf20Sopenharmony_ci
65518c2ecf20Sopenharmony_ci	size += gaudi_add_mon_msg_short(buf + size, (u32) fence_addr,
65528c2ecf20Sopenharmony_ci					msg_addr_offset);
65538c2ecf20Sopenharmony_ci
65548c2ecf20Sopenharmony_ci	/* Second monitor config packet: high address of the sync */
65558c2ecf20Sopenharmony_ci	msg_addr_offset =
65568c2ecf20Sopenharmony_ci		(mmSYNC_MNGR_W_S_SYNC_MNGR_OBJS_MON_PAY_ADDRH_0 + mon_id * 4) -
65578c2ecf20Sopenharmony_ci				monitor_base;
65588c2ecf20Sopenharmony_ci
65598c2ecf20Sopenharmony_ci	size += gaudi_add_mon_msg_short(buf + size, (u32) (fence_addr >> 32),
65608c2ecf20Sopenharmony_ci					msg_addr_offset);
65618c2ecf20Sopenharmony_ci
65628c2ecf20Sopenharmony_ci	/*
65638c2ecf20Sopenharmony_ci	 * Third monitor config packet: the payload, i.e. what to write when the
65648c2ecf20Sopenharmony_ci	 * sync triggers
65658c2ecf20Sopenharmony_ci	 */
65668c2ecf20Sopenharmony_ci	msg_addr_offset =
65678c2ecf20Sopenharmony_ci		(mmSYNC_MNGR_W_S_SYNC_MNGR_OBJS_MON_PAY_DATA_0 + mon_id * 4) -
65688c2ecf20Sopenharmony_ci				monitor_base;
65698c2ecf20Sopenharmony_ci
65708c2ecf20Sopenharmony_ci	size += gaudi_add_mon_msg_short(buf + size, 1, msg_addr_offset);
65718c2ecf20Sopenharmony_ci
65728c2ecf20Sopenharmony_ci	/* Fourth monitor config packet: bind the monitor to a sync object */
65738c2ecf20Sopenharmony_ci	msg_addr_offset =
65748c2ecf20Sopenharmony_ci		(mmSYNC_MNGR_W_S_SYNC_MNGR_OBJS_MON_ARM_0 + mon_id * 4) -
65758c2ecf20Sopenharmony_ci				monitor_base;
65768c2ecf20Sopenharmony_ci	size += gaudi_add_arm_monitor_pkt(buf + size, sob_id, sob_val,
65778c2ecf20Sopenharmony_ci						msg_addr_offset);
65788c2ecf20Sopenharmony_ci
65798c2ecf20Sopenharmony_ci	/* Fence packet */
65808c2ecf20Sopenharmony_ci	size += gaudi_add_fence_pkt(buf + size);
65818c2ecf20Sopenharmony_ci}
65828c2ecf20Sopenharmony_ci
65838c2ecf20Sopenharmony_cistatic void gaudi_reset_sob(struct hl_device *hdev, void *data)
65848c2ecf20Sopenharmony_ci{
65858c2ecf20Sopenharmony_ci	struct hl_hw_sob *hw_sob = (struct hl_hw_sob *) data;
65868c2ecf20Sopenharmony_ci
65878c2ecf20Sopenharmony_ci	dev_dbg(hdev->dev, "reset SOB, q_idx: %d, sob_id: %d\n", hw_sob->q_idx,
65888c2ecf20Sopenharmony_ci		hw_sob->sob_id);
65898c2ecf20Sopenharmony_ci
65908c2ecf20Sopenharmony_ci	WREG32(mmSYNC_MNGR_W_S_SYNC_MNGR_OBJS_SOB_OBJ_0 + hw_sob->sob_id * 4,
65918c2ecf20Sopenharmony_ci		0);
65928c2ecf20Sopenharmony_ci
65938c2ecf20Sopenharmony_ci	kref_init(&hw_sob->kref);
65948c2ecf20Sopenharmony_ci}
65958c2ecf20Sopenharmony_ci
65968c2ecf20Sopenharmony_cistatic void gaudi_set_dma_mask_from_fw(struct hl_device *hdev)
65978c2ecf20Sopenharmony_ci{
65988c2ecf20Sopenharmony_ci	if (RREG32(mmPSOC_GLOBAL_CONF_NON_RST_FLOPS_0) ==
65998c2ecf20Sopenharmony_ci							HL_POWER9_HOST_MAGIC) {
66008c2ecf20Sopenharmony_ci		hdev->power9_64bit_dma_enable = 1;
66018c2ecf20Sopenharmony_ci		hdev->dma_mask = 64;
66028c2ecf20Sopenharmony_ci	} else {
66038c2ecf20Sopenharmony_ci		hdev->power9_64bit_dma_enable = 0;
66048c2ecf20Sopenharmony_ci		hdev->dma_mask = 48;
66058c2ecf20Sopenharmony_ci	}
66068c2ecf20Sopenharmony_ci}
66078c2ecf20Sopenharmony_ci
66088c2ecf20Sopenharmony_cistatic u64 gaudi_get_device_time(struct hl_device *hdev)
66098c2ecf20Sopenharmony_ci{
66108c2ecf20Sopenharmony_ci	u64 device_time = ((u64) RREG32(mmPSOC_TIMESTAMP_CNTCVU)) << 32;
66118c2ecf20Sopenharmony_ci
66128c2ecf20Sopenharmony_ci	return device_time | RREG32(mmPSOC_TIMESTAMP_CNTCVL);
66138c2ecf20Sopenharmony_ci}
66148c2ecf20Sopenharmony_ci
66158c2ecf20Sopenharmony_cistatic const struct hl_asic_funcs gaudi_funcs = {
66168c2ecf20Sopenharmony_ci	.early_init = gaudi_early_init,
66178c2ecf20Sopenharmony_ci	.early_fini = gaudi_early_fini,
66188c2ecf20Sopenharmony_ci	.late_init = gaudi_late_init,
66198c2ecf20Sopenharmony_ci	.late_fini = gaudi_late_fini,
66208c2ecf20Sopenharmony_ci	.sw_init = gaudi_sw_init,
66218c2ecf20Sopenharmony_ci	.sw_fini = gaudi_sw_fini,
66228c2ecf20Sopenharmony_ci	.hw_init = gaudi_hw_init,
66238c2ecf20Sopenharmony_ci	.hw_fini = gaudi_hw_fini,
66248c2ecf20Sopenharmony_ci	.halt_engines = gaudi_halt_engines,
66258c2ecf20Sopenharmony_ci	.suspend = gaudi_suspend,
66268c2ecf20Sopenharmony_ci	.resume = gaudi_resume,
66278c2ecf20Sopenharmony_ci	.cb_mmap = gaudi_cb_mmap,
66288c2ecf20Sopenharmony_ci	.ring_doorbell = gaudi_ring_doorbell,
66298c2ecf20Sopenharmony_ci	.pqe_write = gaudi_pqe_write,
66308c2ecf20Sopenharmony_ci	.asic_dma_alloc_coherent = gaudi_dma_alloc_coherent,
66318c2ecf20Sopenharmony_ci	.asic_dma_free_coherent = gaudi_dma_free_coherent,
66328c2ecf20Sopenharmony_ci	.get_int_queue_base = gaudi_get_int_queue_base,
66338c2ecf20Sopenharmony_ci	.test_queues = gaudi_test_queues,
66348c2ecf20Sopenharmony_ci	.asic_dma_pool_zalloc = gaudi_dma_pool_zalloc,
66358c2ecf20Sopenharmony_ci	.asic_dma_pool_free = gaudi_dma_pool_free,
66368c2ecf20Sopenharmony_ci	.cpu_accessible_dma_pool_alloc = gaudi_cpu_accessible_dma_pool_alloc,
66378c2ecf20Sopenharmony_ci	.cpu_accessible_dma_pool_free = gaudi_cpu_accessible_dma_pool_free,
66388c2ecf20Sopenharmony_ci	.hl_dma_unmap_sg = gaudi_dma_unmap_sg,
66398c2ecf20Sopenharmony_ci	.cs_parser = gaudi_cs_parser,
66408c2ecf20Sopenharmony_ci	.asic_dma_map_sg = gaudi_dma_map_sg,
66418c2ecf20Sopenharmony_ci	.get_dma_desc_list_size = gaudi_get_dma_desc_list_size,
66428c2ecf20Sopenharmony_ci	.add_end_of_cb_packets = gaudi_add_end_of_cb_packets,
66438c2ecf20Sopenharmony_ci	.update_eq_ci = gaudi_update_eq_ci,
66448c2ecf20Sopenharmony_ci	.context_switch = gaudi_context_switch,
66458c2ecf20Sopenharmony_ci	.restore_phase_topology = gaudi_restore_phase_topology,
66468c2ecf20Sopenharmony_ci	.debugfs_read32 = gaudi_debugfs_read32,
66478c2ecf20Sopenharmony_ci	.debugfs_write32 = gaudi_debugfs_write32,
66488c2ecf20Sopenharmony_ci	.debugfs_read64 = gaudi_debugfs_read64,
66498c2ecf20Sopenharmony_ci	.debugfs_write64 = gaudi_debugfs_write64,
66508c2ecf20Sopenharmony_ci	.add_device_attr = gaudi_add_device_attr,
66518c2ecf20Sopenharmony_ci	.handle_eqe = gaudi_handle_eqe,
66528c2ecf20Sopenharmony_ci	.set_pll_profile = gaudi_set_pll_profile,
66538c2ecf20Sopenharmony_ci	.get_events_stat = gaudi_get_events_stat,
66548c2ecf20Sopenharmony_ci	.read_pte = gaudi_read_pte,
66558c2ecf20Sopenharmony_ci	.write_pte = gaudi_write_pte,
66568c2ecf20Sopenharmony_ci	.mmu_invalidate_cache = gaudi_mmu_invalidate_cache,
66578c2ecf20Sopenharmony_ci	.mmu_invalidate_cache_range = gaudi_mmu_invalidate_cache_range,
66588c2ecf20Sopenharmony_ci	.send_heartbeat = gaudi_send_heartbeat,
66598c2ecf20Sopenharmony_ci	.set_clock_gating = gaudi_set_clock_gating,
66608c2ecf20Sopenharmony_ci	.disable_clock_gating = gaudi_disable_clock_gating,
66618c2ecf20Sopenharmony_ci	.debug_coresight = gaudi_debug_coresight,
66628c2ecf20Sopenharmony_ci	.is_device_idle = gaudi_is_device_idle,
66638c2ecf20Sopenharmony_ci	.soft_reset_late_init = gaudi_soft_reset_late_init,
66648c2ecf20Sopenharmony_ci	.hw_queues_lock = gaudi_hw_queues_lock,
66658c2ecf20Sopenharmony_ci	.hw_queues_unlock = gaudi_hw_queues_unlock,
66668c2ecf20Sopenharmony_ci	.get_pci_id = gaudi_get_pci_id,
66678c2ecf20Sopenharmony_ci	.get_eeprom_data = gaudi_get_eeprom_data,
66688c2ecf20Sopenharmony_ci	.send_cpu_message = gaudi_send_cpu_message,
66698c2ecf20Sopenharmony_ci	.get_hw_state = gaudi_get_hw_state,
66708c2ecf20Sopenharmony_ci	.pci_bars_map = gaudi_pci_bars_map,
66718c2ecf20Sopenharmony_ci	.init_iatu = gaudi_init_iatu,
66728c2ecf20Sopenharmony_ci	.rreg = hl_rreg,
66738c2ecf20Sopenharmony_ci	.wreg = hl_wreg,
66748c2ecf20Sopenharmony_ci	.halt_coresight = gaudi_halt_coresight,
66758c2ecf20Sopenharmony_ci	.ctx_init = gaudi_ctx_init,
66768c2ecf20Sopenharmony_ci	.get_clk_rate = gaudi_get_clk_rate,
66778c2ecf20Sopenharmony_ci	.get_queue_id_for_cq = gaudi_get_queue_id_for_cq,
66788c2ecf20Sopenharmony_ci	.read_device_fw_version = gaudi_read_device_fw_version,
66798c2ecf20Sopenharmony_ci	.load_firmware_to_device = gaudi_load_firmware_to_device,
66808c2ecf20Sopenharmony_ci	.load_boot_fit_to_device = gaudi_load_boot_fit_to_device,
66818c2ecf20Sopenharmony_ci	.get_signal_cb_size = gaudi_get_signal_cb_size,
66828c2ecf20Sopenharmony_ci	.get_wait_cb_size = gaudi_get_wait_cb_size,
66838c2ecf20Sopenharmony_ci	.gen_signal_cb = gaudi_gen_signal_cb,
66848c2ecf20Sopenharmony_ci	.gen_wait_cb = gaudi_gen_wait_cb,
66858c2ecf20Sopenharmony_ci	.reset_sob = gaudi_reset_sob,
66868c2ecf20Sopenharmony_ci	.set_dma_mask_from_fw = gaudi_set_dma_mask_from_fw,
66878c2ecf20Sopenharmony_ci	.get_device_time = gaudi_get_device_time
66888c2ecf20Sopenharmony_ci};
66898c2ecf20Sopenharmony_ci
66908c2ecf20Sopenharmony_ci/**
66918c2ecf20Sopenharmony_ci * gaudi_set_asic_funcs - set GAUDI function pointers
66928c2ecf20Sopenharmony_ci *
66938c2ecf20Sopenharmony_ci * @hdev: pointer to hl_device structure
66948c2ecf20Sopenharmony_ci *
66958c2ecf20Sopenharmony_ci */
66968c2ecf20Sopenharmony_civoid gaudi_set_asic_funcs(struct hl_device *hdev)
66978c2ecf20Sopenharmony_ci{
66988c2ecf20Sopenharmony_ci	hdev->asic_funcs = &gaudi_funcs;
66998c2ecf20Sopenharmony_ci}
6700