162306a36Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0
262306a36Sopenharmony_ci
362306a36Sopenharmony_ci/*
462306a36Sopenharmony_ci * Copyright 2016-2022 HabanaLabs, Ltd.
562306a36Sopenharmony_ci * All Rights Reserved.
662306a36Sopenharmony_ci */
762306a36Sopenharmony_ci
862306a36Sopenharmony_ci#include "goyaP.h"
962306a36Sopenharmony_ci#include "../include/hw_ip/mmu/mmu_general.h"
1062306a36Sopenharmony_ci#include "../include/hw_ip/mmu/mmu_v1_0.h"
1162306a36Sopenharmony_ci#include "../include/goya/asic_reg/goya_masks.h"
1262306a36Sopenharmony_ci#include "../include/goya/goya_reg_map.h"
1362306a36Sopenharmony_ci
1462306a36Sopenharmony_ci#include <linux/pci.h>
1562306a36Sopenharmony_ci#include <linux/hwmon.h>
1662306a36Sopenharmony_ci#include <linux/iommu.h>
1762306a36Sopenharmony_ci#include <linux/seq_file.h>
1862306a36Sopenharmony_ci
1962306a36Sopenharmony_ci/*
2062306a36Sopenharmony_ci * GOYA security scheme:
2162306a36Sopenharmony_ci *
2262306a36Sopenharmony_ci * 1. Host is protected by:
2362306a36Sopenharmony_ci *        - Range registers (When MMU is enabled, DMA RR does NOT protect host)
2462306a36Sopenharmony_ci *        - MMU
2562306a36Sopenharmony_ci *
2662306a36Sopenharmony_ci * 2. DRAM is protected by:
2762306a36Sopenharmony_ci *        - Range registers (protect the first 512MB)
2862306a36Sopenharmony_ci *        - MMU (isolation between users)
2962306a36Sopenharmony_ci *
3062306a36Sopenharmony_ci * 3. Configuration is protected by:
3162306a36Sopenharmony_ci *        - Range registers
3262306a36Sopenharmony_ci *        - Protection bits
3362306a36Sopenharmony_ci *
3462306a36Sopenharmony_ci * When MMU is disabled:
3562306a36Sopenharmony_ci *
3662306a36Sopenharmony_ci * QMAN DMA: PQ, CQ, CP, DMA are secured.
3762306a36Sopenharmony_ci * PQ, CB and the data are on the host.
3862306a36Sopenharmony_ci *
3962306a36Sopenharmony_ci * QMAN TPC/MME:
4062306a36Sopenharmony_ci * PQ, CQ and CP are not secured.
4162306a36Sopenharmony_ci * PQ, CB and the data are on the SRAM/DRAM.
4262306a36Sopenharmony_ci *
4362306a36Sopenharmony_ci * Since QMAN DMA is secured, the driver is parsing the DMA CB:
4462306a36Sopenharmony_ci *     - checks DMA pointer
4562306a36Sopenharmony_ci *     - WREG, MSG_PROT are not allowed.
4662306a36Sopenharmony_ci *     - MSG_LONG/SHORT are allowed.
4762306a36Sopenharmony_ci *
4862306a36Sopenharmony_ci * A read/write transaction by the QMAN to a protected area will succeed if
4962306a36Sopenharmony_ci * and only if the QMAN's CP is secured and MSG_PROT is used
5062306a36Sopenharmony_ci *
5162306a36Sopenharmony_ci *
5262306a36Sopenharmony_ci * When MMU is enabled:
5362306a36Sopenharmony_ci *
5462306a36Sopenharmony_ci * QMAN DMA: PQ, CQ and CP are secured.
5562306a36Sopenharmony_ci * MMU is set to bypass on the Secure props register of the QMAN.
5662306a36Sopenharmony_ci * The reasons we don't enable MMU for PQ, CQ and CP are:
5762306a36Sopenharmony_ci *     - PQ entry is in kernel address space and the driver doesn't map it.
5862306a36Sopenharmony_ci *     - CP writes to MSIX register and to kernel address space (completion
5962306a36Sopenharmony_ci *       queue).
6062306a36Sopenharmony_ci *
6162306a36Sopenharmony_ci * DMA is not secured but because CP is secured, the driver still needs to parse
6262306a36Sopenharmony_ci * the CB, but doesn't need to check the DMA addresses.
6362306a36Sopenharmony_ci *
6462306a36Sopenharmony_ci * For QMAN DMA 0, DMA is also secured because only the driver uses this DMA and
6562306a36Sopenharmony_ci * the driver doesn't map memory in MMU.
6662306a36Sopenharmony_ci *
6762306a36Sopenharmony_ci * QMAN TPC/MME: PQ, CQ and CP aren't secured (no change from MMU disabled mode)
6862306a36Sopenharmony_ci *
6962306a36Sopenharmony_ci * DMA RR does NOT protect host because DMA is not secured
7062306a36Sopenharmony_ci *
7162306a36Sopenharmony_ci */
7262306a36Sopenharmony_ci
7362306a36Sopenharmony_ci#define GOYA_BOOT_FIT_FILE	"habanalabs/goya/goya-boot-fit.itb"
7462306a36Sopenharmony_ci#define GOYA_LINUX_FW_FILE	"habanalabs/goya/goya-fit.itb"
7562306a36Sopenharmony_ci
7662306a36Sopenharmony_ci#define GOYA_MMU_REGS_NUM		63
7762306a36Sopenharmony_ci
7862306a36Sopenharmony_ci#define GOYA_DMA_POOL_BLK_SIZE		0x100		/* 256 bytes */
7962306a36Sopenharmony_ci
8062306a36Sopenharmony_ci#define GOYA_RESET_TIMEOUT_MSEC		500		/* 500ms */
8162306a36Sopenharmony_ci#define GOYA_PLDM_RESET_TIMEOUT_MSEC	20000		/* 20s */
8262306a36Sopenharmony_ci#define GOYA_RESET_WAIT_MSEC		1		/* 1ms */
8362306a36Sopenharmony_ci#define GOYA_CPU_RESET_WAIT_MSEC	100		/* 100ms */
8462306a36Sopenharmony_ci#define GOYA_PLDM_RESET_WAIT_MSEC	1000		/* 1s */
8562306a36Sopenharmony_ci#define GOYA_TEST_QUEUE_WAIT_USEC	100000		/* 100ms */
8662306a36Sopenharmony_ci#define GOYA_PLDM_MMU_TIMEOUT_USEC	(MMU_CONFIG_TIMEOUT_USEC * 100)
8762306a36Sopenharmony_ci#define GOYA_PLDM_QMAN0_TIMEOUT_USEC	(HL_DEVICE_TIMEOUT_USEC * 30)
8862306a36Sopenharmony_ci#define GOYA_BOOT_FIT_REQ_TIMEOUT_USEC	1000000		/* 1s */
8962306a36Sopenharmony_ci#define GOYA_MSG_TO_CPU_TIMEOUT_USEC	4000000		/* 4s */
9062306a36Sopenharmony_ci#define GOYA_WAIT_FOR_BL_TIMEOUT_USEC	15000000	/* 15s */
9162306a36Sopenharmony_ci
9262306a36Sopenharmony_ci#define GOYA_QMAN0_FENCE_VAL		0xD169B243
9362306a36Sopenharmony_ci
9462306a36Sopenharmony_ci#define GOYA_MAX_STRING_LEN		20
9562306a36Sopenharmony_ci
9662306a36Sopenharmony_ci#define GOYA_CB_POOL_CB_CNT		512
9762306a36Sopenharmony_ci#define GOYA_CB_POOL_CB_SIZE		0x20000		/* 128KB */
9862306a36Sopenharmony_ci
9962306a36Sopenharmony_ci#define IS_QM_IDLE(engine, qm_glbl_sts0) \
10062306a36Sopenharmony_ci	(((qm_glbl_sts0) & engine##_QM_IDLE_MASK) == engine##_QM_IDLE_MASK)
10162306a36Sopenharmony_ci#define IS_DMA_QM_IDLE(qm_glbl_sts0)	IS_QM_IDLE(DMA, qm_glbl_sts0)
10262306a36Sopenharmony_ci#define IS_TPC_QM_IDLE(qm_glbl_sts0)	IS_QM_IDLE(TPC, qm_glbl_sts0)
10362306a36Sopenharmony_ci#define IS_MME_QM_IDLE(qm_glbl_sts0)	IS_QM_IDLE(MME, qm_glbl_sts0)
10462306a36Sopenharmony_ci
10562306a36Sopenharmony_ci#define IS_CMDQ_IDLE(engine, cmdq_glbl_sts0) \
10662306a36Sopenharmony_ci	(((cmdq_glbl_sts0) & engine##_CMDQ_IDLE_MASK) == \
10762306a36Sopenharmony_ci			engine##_CMDQ_IDLE_MASK)
10862306a36Sopenharmony_ci#define IS_TPC_CMDQ_IDLE(cmdq_glbl_sts0) \
10962306a36Sopenharmony_ci	IS_CMDQ_IDLE(TPC, cmdq_glbl_sts0)
11062306a36Sopenharmony_ci#define IS_MME_CMDQ_IDLE(cmdq_glbl_sts0) \
11162306a36Sopenharmony_ci	IS_CMDQ_IDLE(MME, cmdq_glbl_sts0)
11262306a36Sopenharmony_ci
11362306a36Sopenharmony_ci#define IS_DMA_IDLE(dma_core_sts0) \
11462306a36Sopenharmony_ci	!((dma_core_sts0) & DMA_CH_0_STS0_DMA_BUSY_MASK)
11562306a36Sopenharmony_ci
11662306a36Sopenharmony_ci#define IS_TPC_IDLE(tpc_cfg_sts) \
11762306a36Sopenharmony_ci	(((tpc_cfg_sts) & TPC_CFG_IDLE_MASK) == TPC_CFG_IDLE_MASK)
11862306a36Sopenharmony_ci
11962306a36Sopenharmony_ci#define IS_MME_IDLE(mme_arch_sts) \
12062306a36Sopenharmony_ci	(((mme_arch_sts) & MME_ARCH_IDLE_MASK) == MME_ARCH_IDLE_MASK)
12162306a36Sopenharmony_ci
12262306a36Sopenharmony_cistatic const char goya_irq_name[GOYA_MSIX_ENTRIES][GOYA_MAX_STRING_LEN] = {
12362306a36Sopenharmony_ci		"goya cq 0", "goya cq 1", "goya cq 2", "goya cq 3",
12462306a36Sopenharmony_ci		"goya cq 4", "goya cpu eq"
12562306a36Sopenharmony_ci};
12662306a36Sopenharmony_ci
12762306a36Sopenharmony_cistatic u16 goya_packet_sizes[MAX_PACKET_ID] = {
12862306a36Sopenharmony_ci	[PACKET_WREG_32]	= sizeof(struct packet_wreg32),
12962306a36Sopenharmony_ci	[PACKET_WREG_BULK]	= sizeof(struct packet_wreg_bulk),
13062306a36Sopenharmony_ci	[PACKET_MSG_LONG]	= sizeof(struct packet_msg_long),
13162306a36Sopenharmony_ci	[PACKET_MSG_SHORT]	= sizeof(struct packet_msg_short),
13262306a36Sopenharmony_ci	[PACKET_CP_DMA]		= sizeof(struct packet_cp_dma),
13362306a36Sopenharmony_ci	[PACKET_MSG_PROT]	= sizeof(struct packet_msg_prot),
13462306a36Sopenharmony_ci	[PACKET_FENCE]		= sizeof(struct packet_fence),
13562306a36Sopenharmony_ci	[PACKET_LIN_DMA]	= sizeof(struct packet_lin_dma),
13662306a36Sopenharmony_ci	[PACKET_NOP]		= sizeof(struct packet_nop),
13762306a36Sopenharmony_ci	[PACKET_STOP]		= sizeof(struct packet_stop)
13862306a36Sopenharmony_ci};
13962306a36Sopenharmony_ci
14062306a36Sopenharmony_cistatic inline bool validate_packet_id(enum packet_id id)
14162306a36Sopenharmony_ci{
14262306a36Sopenharmony_ci	switch (id) {
14362306a36Sopenharmony_ci	case PACKET_WREG_32:
14462306a36Sopenharmony_ci	case PACKET_WREG_BULK:
14562306a36Sopenharmony_ci	case PACKET_MSG_LONG:
14662306a36Sopenharmony_ci	case PACKET_MSG_SHORT:
14762306a36Sopenharmony_ci	case PACKET_CP_DMA:
14862306a36Sopenharmony_ci	case PACKET_MSG_PROT:
14962306a36Sopenharmony_ci	case PACKET_FENCE:
15062306a36Sopenharmony_ci	case PACKET_LIN_DMA:
15162306a36Sopenharmony_ci	case PACKET_NOP:
15262306a36Sopenharmony_ci	case PACKET_STOP:
15362306a36Sopenharmony_ci		return true;
15462306a36Sopenharmony_ci	default:
15562306a36Sopenharmony_ci		return false;
15662306a36Sopenharmony_ci	}
15762306a36Sopenharmony_ci}
15862306a36Sopenharmony_ci
15962306a36Sopenharmony_cistatic u64 goya_mmu_regs[GOYA_MMU_REGS_NUM] = {
16062306a36Sopenharmony_ci	mmDMA_QM_0_GLBL_NON_SECURE_PROPS,
16162306a36Sopenharmony_ci	mmDMA_QM_1_GLBL_NON_SECURE_PROPS,
16262306a36Sopenharmony_ci	mmDMA_QM_2_GLBL_NON_SECURE_PROPS,
16362306a36Sopenharmony_ci	mmDMA_QM_3_GLBL_NON_SECURE_PROPS,
16462306a36Sopenharmony_ci	mmDMA_QM_4_GLBL_NON_SECURE_PROPS,
16562306a36Sopenharmony_ci	mmTPC0_QM_GLBL_SECURE_PROPS,
16662306a36Sopenharmony_ci	mmTPC0_QM_GLBL_NON_SECURE_PROPS,
16762306a36Sopenharmony_ci	mmTPC0_CMDQ_GLBL_SECURE_PROPS,
16862306a36Sopenharmony_ci	mmTPC0_CMDQ_GLBL_NON_SECURE_PROPS,
16962306a36Sopenharmony_ci	mmTPC0_CFG_ARUSER,
17062306a36Sopenharmony_ci	mmTPC0_CFG_AWUSER,
17162306a36Sopenharmony_ci	mmTPC1_QM_GLBL_SECURE_PROPS,
17262306a36Sopenharmony_ci	mmTPC1_QM_GLBL_NON_SECURE_PROPS,
17362306a36Sopenharmony_ci	mmTPC1_CMDQ_GLBL_SECURE_PROPS,
17462306a36Sopenharmony_ci	mmTPC1_CMDQ_GLBL_NON_SECURE_PROPS,
17562306a36Sopenharmony_ci	mmTPC1_CFG_ARUSER,
17662306a36Sopenharmony_ci	mmTPC1_CFG_AWUSER,
17762306a36Sopenharmony_ci	mmTPC2_QM_GLBL_SECURE_PROPS,
17862306a36Sopenharmony_ci	mmTPC2_QM_GLBL_NON_SECURE_PROPS,
17962306a36Sopenharmony_ci	mmTPC2_CMDQ_GLBL_SECURE_PROPS,
18062306a36Sopenharmony_ci	mmTPC2_CMDQ_GLBL_NON_SECURE_PROPS,
18162306a36Sopenharmony_ci	mmTPC2_CFG_ARUSER,
18262306a36Sopenharmony_ci	mmTPC2_CFG_AWUSER,
18362306a36Sopenharmony_ci	mmTPC3_QM_GLBL_SECURE_PROPS,
18462306a36Sopenharmony_ci	mmTPC3_QM_GLBL_NON_SECURE_PROPS,
18562306a36Sopenharmony_ci	mmTPC3_CMDQ_GLBL_SECURE_PROPS,
18662306a36Sopenharmony_ci	mmTPC3_CMDQ_GLBL_NON_SECURE_PROPS,
18762306a36Sopenharmony_ci	mmTPC3_CFG_ARUSER,
18862306a36Sopenharmony_ci	mmTPC3_CFG_AWUSER,
18962306a36Sopenharmony_ci	mmTPC4_QM_GLBL_SECURE_PROPS,
19062306a36Sopenharmony_ci	mmTPC4_QM_GLBL_NON_SECURE_PROPS,
19162306a36Sopenharmony_ci	mmTPC4_CMDQ_GLBL_SECURE_PROPS,
19262306a36Sopenharmony_ci	mmTPC4_CMDQ_GLBL_NON_SECURE_PROPS,
19362306a36Sopenharmony_ci	mmTPC4_CFG_ARUSER,
19462306a36Sopenharmony_ci	mmTPC4_CFG_AWUSER,
19562306a36Sopenharmony_ci	mmTPC5_QM_GLBL_SECURE_PROPS,
19662306a36Sopenharmony_ci	mmTPC5_QM_GLBL_NON_SECURE_PROPS,
19762306a36Sopenharmony_ci	mmTPC5_CMDQ_GLBL_SECURE_PROPS,
19862306a36Sopenharmony_ci	mmTPC5_CMDQ_GLBL_NON_SECURE_PROPS,
19962306a36Sopenharmony_ci	mmTPC5_CFG_ARUSER,
20062306a36Sopenharmony_ci	mmTPC5_CFG_AWUSER,
20162306a36Sopenharmony_ci	mmTPC6_QM_GLBL_SECURE_PROPS,
20262306a36Sopenharmony_ci	mmTPC6_QM_GLBL_NON_SECURE_PROPS,
20362306a36Sopenharmony_ci	mmTPC6_CMDQ_GLBL_SECURE_PROPS,
20462306a36Sopenharmony_ci	mmTPC6_CMDQ_GLBL_NON_SECURE_PROPS,
20562306a36Sopenharmony_ci	mmTPC6_CFG_ARUSER,
20662306a36Sopenharmony_ci	mmTPC6_CFG_AWUSER,
20762306a36Sopenharmony_ci	mmTPC7_QM_GLBL_SECURE_PROPS,
20862306a36Sopenharmony_ci	mmTPC7_QM_GLBL_NON_SECURE_PROPS,
20962306a36Sopenharmony_ci	mmTPC7_CMDQ_GLBL_SECURE_PROPS,
21062306a36Sopenharmony_ci	mmTPC7_CMDQ_GLBL_NON_SECURE_PROPS,
21162306a36Sopenharmony_ci	mmTPC7_CFG_ARUSER,
21262306a36Sopenharmony_ci	mmTPC7_CFG_AWUSER,
21362306a36Sopenharmony_ci	mmMME_QM_GLBL_SECURE_PROPS,
21462306a36Sopenharmony_ci	mmMME_QM_GLBL_NON_SECURE_PROPS,
21562306a36Sopenharmony_ci	mmMME_CMDQ_GLBL_SECURE_PROPS,
21662306a36Sopenharmony_ci	mmMME_CMDQ_GLBL_NON_SECURE_PROPS,
21762306a36Sopenharmony_ci	mmMME_SBA_CONTROL_DATA,
21862306a36Sopenharmony_ci	mmMME_SBB_CONTROL_DATA,
21962306a36Sopenharmony_ci	mmMME_SBC_CONTROL_DATA,
22062306a36Sopenharmony_ci	mmMME_WBC_CONTROL_DATA,
22162306a36Sopenharmony_ci	mmPCIE_WRAP_PSOC_ARUSER,
22262306a36Sopenharmony_ci	mmPCIE_WRAP_PSOC_AWUSER
22362306a36Sopenharmony_ci};
22462306a36Sopenharmony_ci
22562306a36Sopenharmony_cistatic u32 goya_all_events[] = {
22662306a36Sopenharmony_ci	GOYA_ASYNC_EVENT_ID_PCIE_IF,
22762306a36Sopenharmony_ci	GOYA_ASYNC_EVENT_ID_TPC0_ECC,
22862306a36Sopenharmony_ci	GOYA_ASYNC_EVENT_ID_TPC1_ECC,
22962306a36Sopenharmony_ci	GOYA_ASYNC_EVENT_ID_TPC2_ECC,
23062306a36Sopenharmony_ci	GOYA_ASYNC_EVENT_ID_TPC3_ECC,
23162306a36Sopenharmony_ci	GOYA_ASYNC_EVENT_ID_TPC4_ECC,
23262306a36Sopenharmony_ci	GOYA_ASYNC_EVENT_ID_TPC5_ECC,
23362306a36Sopenharmony_ci	GOYA_ASYNC_EVENT_ID_TPC6_ECC,
23462306a36Sopenharmony_ci	GOYA_ASYNC_EVENT_ID_TPC7_ECC,
23562306a36Sopenharmony_ci	GOYA_ASYNC_EVENT_ID_MME_ECC,
23662306a36Sopenharmony_ci	GOYA_ASYNC_EVENT_ID_MME_ECC_EXT,
23762306a36Sopenharmony_ci	GOYA_ASYNC_EVENT_ID_MMU_ECC,
23862306a36Sopenharmony_ci	GOYA_ASYNC_EVENT_ID_DMA_MACRO,
23962306a36Sopenharmony_ci	GOYA_ASYNC_EVENT_ID_DMA_ECC,
24062306a36Sopenharmony_ci	GOYA_ASYNC_EVENT_ID_CPU_IF_ECC,
24162306a36Sopenharmony_ci	GOYA_ASYNC_EVENT_ID_PSOC_MEM,
24262306a36Sopenharmony_ci	GOYA_ASYNC_EVENT_ID_PSOC_CORESIGHT,
24362306a36Sopenharmony_ci	GOYA_ASYNC_EVENT_ID_SRAM0,
24462306a36Sopenharmony_ci	GOYA_ASYNC_EVENT_ID_SRAM1,
24562306a36Sopenharmony_ci	GOYA_ASYNC_EVENT_ID_SRAM2,
24662306a36Sopenharmony_ci	GOYA_ASYNC_EVENT_ID_SRAM3,
24762306a36Sopenharmony_ci	GOYA_ASYNC_EVENT_ID_SRAM4,
24862306a36Sopenharmony_ci	GOYA_ASYNC_EVENT_ID_SRAM5,
24962306a36Sopenharmony_ci	GOYA_ASYNC_EVENT_ID_SRAM6,
25062306a36Sopenharmony_ci	GOYA_ASYNC_EVENT_ID_SRAM7,
25162306a36Sopenharmony_ci	GOYA_ASYNC_EVENT_ID_SRAM8,
25262306a36Sopenharmony_ci	GOYA_ASYNC_EVENT_ID_SRAM9,
25362306a36Sopenharmony_ci	GOYA_ASYNC_EVENT_ID_SRAM10,
25462306a36Sopenharmony_ci	GOYA_ASYNC_EVENT_ID_SRAM11,
25562306a36Sopenharmony_ci	GOYA_ASYNC_EVENT_ID_SRAM12,
25662306a36Sopenharmony_ci	GOYA_ASYNC_EVENT_ID_SRAM13,
25762306a36Sopenharmony_ci	GOYA_ASYNC_EVENT_ID_SRAM14,
25862306a36Sopenharmony_ci	GOYA_ASYNC_EVENT_ID_SRAM15,
25962306a36Sopenharmony_ci	GOYA_ASYNC_EVENT_ID_SRAM16,
26062306a36Sopenharmony_ci	GOYA_ASYNC_EVENT_ID_SRAM17,
26162306a36Sopenharmony_ci	GOYA_ASYNC_EVENT_ID_SRAM18,
26262306a36Sopenharmony_ci	GOYA_ASYNC_EVENT_ID_SRAM19,
26362306a36Sopenharmony_ci	GOYA_ASYNC_EVENT_ID_SRAM20,
26462306a36Sopenharmony_ci	GOYA_ASYNC_EVENT_ID_SRAM21,
26562306a36Sopenharmony_ci	GOYA_ASYNC_EVENT_ID_SRAM22,
26662306a36Sopenharmony_ci	GOYA_ASYNC_EVENT_ID_SRAM23,
26762306a36Sopenharmony_ci	GOYA_ASYNC_EVENT_ID_SRAM24,
26862306a36Sopenharmony_ci	GOYA_ASYNC_EVENT_ID_SRAM25,
26962306a36Sopenharmony_ci	GOYA_ASYNC_EVENT_ID_SRAM26,
27062306a36Sopenharmony_ci	GOYA_ASYNC_EVENT_ID_SRAM27,
27162306a36Sopenharmony_ci	GOYA_ASYNC_EVENT_ID_SRAM28,
27262306a36Sopenharmony_ci	GOYA_ASYNC_EVENT_ID_SRAM29,
27362306a36Sopenharmony_ci	GOYA_ASYNC_EVENT_ID_GIC500,
27462306a36Sopenharmony_ci	GOYA_ASYNC_EVENT_ID_PLL0,
27562306a36Sopenharmony_ci	GOYA_ASYNC_EVENT_ID_PLL1,
27662306a36Sopenharmony_ci	GOYA_ASYNC_EVENT_ID_PLL3,
27762306a36Sopenharmony_ci	GOYA_ASYNC_EVENT_ID_PLL4,
27862306a36Sopenharmony_ci	GOYA_ASYNC_EVENT_ID_PLL5,
27962306a36Sopenharmony_ci	GOYA_ASYNC_EVENT_ID_PLL6,
28062306a36Sopenharmony_ci	GOYA_ASYNC_EVENT_ID_AXI_ECC,
28162306a36Sopenharmony_ci	GOYA_ASYNC_EVENT_ID_L2_RAM_ECC,
28262306a36Sopenharmony_ci	GOYA_ASYNC_EVENT_ID_PSOC_GPIO_05_SW_RESET,
28362306a36Sopenharmony_ci	GOYA_ASYNC_EVENT_ID_PSOC_GPIO_10_VRHOT_ICRIT,
28462306a36Sopenharmony_ci	GOYA_ASYNC_EVENT_ID_PCIE_DEC,
28562306a36Sopenharmony_ci	GOYA_ASYNC_EVENT_ID_TPC0_DEC,
28662306a36Sopenharmony_ci	GOYA_ASYNC_EVENT_ID_TPC1_DEC,
28762306a36Sopenharmony_ci	GOYA_ASYNC_EVENT_ID_TPC2_DEC,
28862306a36Sopenharmony_ci	GOYA_ASYNC_EVENT_ID_TPC3_DEC,
28962306a36Sopenharmony_ci	GOYA_ASYNC_EVENT_ID_TPC4_DEC,
29062306a36Sopenharmony_ci	GOYA_ASYNC_EVENT_ID_TPC5_DEC,
29162306a36Sopenharmony_ci	GOYA_ASYNC_EVENT_ID_TPC6_DEC,
29262306a36Sopenharmony_ci	GOYA_ASYNC_EVENT_ID_TPC7_DEC,
29362306a36Sopenharmony_ci	GOYA_ASYNC_EVENT_ID_MME_WACS,
29462306a36Sopenharmony_ci	GOYA_ASYNC_EVENT_ID_MME_WACSD,
29562306a36Sopenharmony_ci	GOYA_ASYNC_EVENT_ID_CPU_AXI_SPLITTER,
29662306a36Sopenharmony_ci	GOYA_ASYNC_EVENT_ID_PSOC_AXI_DEC,
29762306a36Sopenharmony_ci	GOYA_ASYNC_EVENT_ID_PSOC,
29862306a36Sopenharmony_ci	GOYA_ASYNC_EVENT_ID_TPC0_KRN_ERR,
29962306a36Sopenharmony_ci	GOYA_ASYNC_EVENT_ID_TPC1_KRN_ERR,
30062306a36Sopenharmony_ci	GOYA_ASYNC_EVENT_ID_TPC2_KRN_ERR,
30162306a36Sopenharmony_ci	GOYA_ASYNC_EVENT_ID_TPC3_KRN_ERR,
30262306a36Sopenharmony_ci	GOYA_ASYNC_EVENT_ID_TPC4_KRN_ERR,
30362306a36Sopenharmony_ci	GOYA_ASYNC_EVENT_ID_TPC5_KRN_ERR,
30462306a36Sopenharmony_ci	GOYA_ASYNC_EVENT_ID_TPC6_KRN_ERR,
30562306a36Sopenharmony_ci	GOYA_ASYNC_EVENT_ID_TPC7_KRN_ERR,
30662306a36Sopenharmony_ci	GOYA_ASYNC_EVENT_ID_TPC0_CMDQ,
30762306a36Sopenharmony_ci	GOYA_ASYNC_EVENT_ID_TPC1_CMDQ,
30862306a36Sopenharmony_ci	GOYA_ASYNC_EVENT_ID_TPC2_CMDQ,
30962306a36Sopenharmony_ci	GOYA_ASYNC_EVENT_ID_TPC3_CMDQ,
31062306a36Sopenharmony_ci	GOYA_ASYNC_EVENT_ID_TPC4_CMDQ,
31162306a36Sopenharmony_ci	GOYA_ASYNC_EVENT_ID_TPC5_CMDQ,
31262306a36Sopenharmony_ci	GOYA_ASYNC_EVENT_ID_TPC6_CMDQ,
31362306a36Sopenharmony_ci	GOYA_ASYNC_EVENT_ID_TPC7_CMDQ,
31462306a36Sopenharmony_ci	GOYA_ASYNC_EVENT_ID_TPC0_QM,
31562306a36Sopenharmony_ci	GOYA_ASYNC_EVENT_ID_TPC1_QM,
31662306a36Sopenharmony_ci	GOYA_ASYNC_EVENT_ID_TPC2_QM,
31762306a36Sopenharmony_ci	GOYA_ASYNC_EVENT_ID_TPC3_QM,
31862306a36Sopenharmony_ci	GOYA_ASYNC_EVENT_ID_TPC4_QM,
31962306a36Sopenharmony_ci	GOYA_ASYNC_EVENT_ID_TPC5_QM,
32062306a36Sopenharmony_ci	GOYA_ASYNC_EVENT_ID_TPC6_QM,
32162306a36Sopenharmony_ci	GOYA_ASYNC_EVENT_ID_TPC7_QM,
32262306a36Sopenharmony_ci	GOYA_ASYNC_EVENT_ID_MME_QM,
32362306a36Sopenharmony_ci	GOYA_ASYNC_EVENT_ID_MME_CMDQ,
32462306a36Sopenharmony_ci	GOYA_ASYNC_EVENT_ID_DMA0_QM,
32562306a36Sopenharmony_ci	GOYA_ASYNC_EVENT_ID_DMA1_QM,
32662306a36Sopenharmony_ci	GOYA_ASYNC_EVENT_ID_DMA2_QM,
32762306a36Sopenharmony_ci	GOYA_ASYNC_EVENT_ID_DMA3_QM,
32862306a36Sopenharmony_ci	GOYA_ASYNC_EVENT_ID_DMA4_QM,
32962306a36Sopenharmony_ci	GOYA_ASYNC_EVENT_ID_DMA0_CH,
33062306a36Sopenharmony_ci	GOYA_ASYNC_EVENT_ID_DMA1_CH,
33162306a36Sopenharmony_ci	GOYA_ASYNC_EVENT_ID_DMA2_CH,
33262306a36Sopenharmony_ci	GOYA_ASYNC_EVENT_ID_DMA3_CH,
33362306a36Sopenharmony_ci	GOYA_ASYNC_EVENT_ID_DMA4_CH,
33462306a36Sopenharmony_ci	GOYA_ASYNC_EVENT_ID_TPC0_BMON_SPMU,
33562306a36Sopenharmony_ci	GOYA_ASYNC_EVENT_ID_TPC1_BMON_SPMU,
33662306a36Sopenharmony_ci	GOYA_ASYNC_EVENT_ID_TPC2_BMON_SPMU,
33762306a36Sopenharmony_ci	GOYA_ASYNC_EVENT_ID_TPC3_BMON_SPMU,
33862306a36Sopenharmony_ci	GOYA_ASYNC_EVENT_ID_TPC4_BMON_SPMU,
33962306a36Sopenharmony_ci	GOYA_ASYNC_EVENT_ID_TPC5_BMON_SPMU,
34062306a36Sopenharmony_ci	GOYA_ASYNC_EVENT_ID_TPC6_BMON_SPMU,
34162306a36Sopenharmony_ci	GOYA_ASYNC_EVENT_ID_TPC7_BMON_SPMU,
34262306a36Sopenharmony_ci	GOYA_ASYNC_EVENT_ID_DMA_BM_CH0,
34362306a36Sopenharmony_ci	GOYA_ASYNC_EVENT_ID_DMA_BM_CH1,
34462306a36Sopenharmony_ci	GOYA_ASYNC_EVENT_ID_DMA_BM_CH2,
34562306a36Sopenharmony_ci	GOYA_ASYNC_EVENT_ID_DMA_BM_CH3,
34662306a36Sopenharmony_ci	GOYA_ASYNC_EVENT_ID_DMA_BM_CH4,
34762306a36Sopenharmony_ci	GOYA_ASYNC_EVENT_ID_FIX_POWER_ENV_S,
34862306a36Sopenharmony_ci	GOYA_ASYNC_EVENT_ID_FIX_POWER_ENV_E,
34962306a36Sopenharmony_ci	GOYA_ASYNC_EVENT_ID_FIX_THERMAL_ENV_S,
35062306a36Sopenharmony_ci	GOYA_ASYNC_EVENT_ID_FIX_THERMAL_ENV_E
35162306a36Sopenharmony_ci};
35262306a36Sopenharmony_ci
35362306a36Sopenharmony_cistatic s64 goya_state_dump_specs_props[SP_MAX] = {0};
35462306a36Sopenharmony_ci
35562306a36Sopenharmony_cistatic int goya_mmu_clear_pgt_range(struct hl_device *hdev);
35662306a36Sopenharmony_cistatic int goya_mmu_set_dram_default_page(struct hl_device *hdev);
35762306a36Sopenharmony_cistatic int goya_mmu_add_mappings_for_device_cpu(struct hl_device *hdev);
35862306a36Sopenharmony_cistatic void goya_mmu_prepare(struct hl_device *hdev, u32 asid);
35962306a36Sopenharmony_ci
36062306a36Sopenharmony_ciint goya_set_fixed_properties(struct hl_device *hdev)
36162306a36Sopenharmony_ci{
36262306a36Sopenharmony_ci	struct asic_fixed_properties *prop = &hdev->asic_prop;
36362306a36Sopenharmony_ci	int i;
36462306a36Sopenharmony_ci
36562306a36Sopenharmony_ci	prop->max_queues = GOYA_QUEUE_ID_SIZE;
36662306a36Sopenharmony_ci	prop->hw_queues_props = kcalloc(prop->max_queues,
36762306a36Sopenharmony_ci			sizeof(struct hw_queue_properties),
36862306a36Sopenharmony_ci			GFP_KERNEL);
36962306a36Sopenharmony_ci
37062306a36Sopenharmony_ci	if (!prop->hw_queues_props)
37162306a36Sopenharmony_ci		return -ENOMEM;
37262306a36Sopenharmony_ci
37362306a36Sopenharmony_ci	for (i = 0 ; i < NUMBER_OF_EXT_HW_QUEUES ; i++) {
37462306a36Sopenharmony_ci		prop->hw_queues_props[i].type = QUEUE_TYPE_EXT;
37562306a36Sopenharmony_ci		prop->hw_queues_props[i].driver_only = 0;
37662306a36Sopenharmony_ci		prop->hw_queues_props[i].cb_alloc_flags = CB_ALLOC_KERNEL;
37762306a36Sopenharmony_ci	}
37862306a36Sopenharmony_ci
37962306a36Sopenharmony_ci	for (; i < NUMBER_OF_EXT_HW_QUEUES + NUMBER_OF_CPU_HW_QUEUES ; i++) {
38062306a36Sopenharmony_ci		prop->hw_queues_props[i].type = QUEUE_TYPE_CPU;
38162306a36Sopenharmony_ci		prop->hw_queues_props[i].driver_only = 1;
38262306a36Sopenharmony_ci		prop->hw_queues_props[i].cb_alloc_flags = CB_ALLOC_KERNEL;
38362306a36Sopenharmony_ci	}
38462306a36Sopenharmony_ci
38562306a36Sopenharmony_ci	for (; i < NUMBER_OF_EXT_HW_QUEUES + NUMBER_OF_CPU_HW_QUEUES +
38662306a36Sopenharmony_ci			NUMBER_OF_INT_HW_QUEUES; i++) {
38762306a36Sopenharmony_ci		prop->hw_queues_props[i].type = QUEUE_TYPE_INT;
38862306a36Sopenharmony_ci		prop->hw_queues_props[i].driver_only = 0;
38962306a36Sopenharmony_ci		prop->hw_queues_props[i].cb_alloc_flags = CB_ALLOC_USER;
39062306a36Sopenharmony_ci	}
39162306a36Sopenharmony_ci
39262306a36Sopenharmony_ci	prop->cfg_base_address = CFG_BASE;
39362306a36Sopenharmony_ci	prop->device_dma_offset_for_host_access = HOST_PHYS_BASE;
39462306a36Sopenharmony_ci	prop->host_base_address = HOST_PHYS_BASE;
39562306a36Sopenharmony_ci	prop->host_end_address = prop->host_base_address + HOST_PHYS_SIZE;
39662306a36Sopenharmony_ci	prop->completion_queues_count = NUMBER_OF_CMPLT_QUEUES;
39762306a36Sopenharmony_ci	prop->completion_mode = HL_COMPLETION_MODE_JOB;
39862306a36Sopenharmony_ci	prop->dram_base_address = DRAM_PHYS_BASE;
39962306a36Sopenharmony_ci	prop->dram_size = DRAM_PHYS_DEFAULT_SIZE;
40062306a36Sopenharmony_ci	prop->dram_end_address = prop->dram_base_address + prop->dram_size;
40162306a36Sopenharmony_ci	prop->dram_user_base_address = DRAM_BASE_ADDR_USER;
40262306a36Sopenharmony_ci
40362306a36Sopenharmony_ci	prop->sram_base_address = SRAM_BASE_ADDR;
40462306a36Sopenharmony_ci	prop->sram_size = SRAM_SIZE;
40562306a36Sopenharmony_ci	prop->sram_end_address = prop->sram_base_address + prop->sram_size;
40662306a36Sopenharmony_ci	prop->sram_user_base_address = prop->sram_base_address +
40762306a36Sopenharmony_ci						SRAM_USER_BASE_OFFSET;
40862306a36Sopenharmony_ci
40962306a36Sopenharmony_ci	prop->mmu_pgt_addr = MMU_PAGE_TABLES_ADDR;
41062306a36Sopenharmony_ci	prop->mmu_dram_default_page_addr = MMU_DRAM_DEFAULT_PAGE_ADDR;
41162306a36Sopenharmony_ci	if (hdev->pldm)
41262306a36Sopenharmony_ci		prop->mmu_pgt_size = 0x800000; /* 8MB */
41362306a36Sopenharmony_ci	else
41462306a36Sopenharmony_ci		prop->mmu_pgt_size = MMU_PAGE_TABLES_SIZE;
41562306a36Sopenharmony_ci	prop->mmu_pte_size = HL_PTE_SIZE;
41662306a36Sopenharmony_ci	prop->mmu_hop_table_size = HOP_TABLE_SIZE_512_PTE;
41762306a36Sopenharmony_ci	prop->mmu_hop0_tables_total_size = HOP0_512_PTE_TABLES_TOTAL_SIZE;
41862306a36Sopenharmony_ci	prop->dram_page_size = PAGE_SIZE_2MB;
41962306a36Sopenharmony_ci	prop->device_mem_alloc_default_page_size = prop->dram_page_size;
42062306a36Sopenharmony_ci	prop->dram_supports_virtual_memory = true;
42162306a36Sopenharmony_ci
42262306a36Sopenharmony_ci	prop->dmmu.hop_shifts[MMU_HOP0] = MMU_V1_0_HOP0_SHIFT;
42362306a36Sopenharmony_ci	prop->dmmu.hop_shifts[MMU_HOP1] = MMU_V1_0_HOP1_SHIFT;
42462306a36Sopenharmony_ci	prop->dmmu.hop_shifts[MMU_HOP2] = MMU_V1_0_HOP2_SHIFT;
42562306a36Sopenharmony_ci	prop->dmmu.hop_shifts[MMU_HOP3] = MMU_V1_0_HOP3_SHIFT;
42662306a36Sopenharmony_ci	prop->dmmu.hop_shifts[MMU_HOP4] = MMU_V1_0_HOP4_SHIFT;
42762306a36Sopenharmony_ci	prop->dmmu.hop_masks[MMU_HOP0] = MMU_V1_0_HOP0_MASK;
42862306a36Sopenharmony_ci	prop->dmmu.hop_masks[MMU_HOP1] = MMU_V1_0_HOP1_MASK;
42962306a36Sopenharmony_ci	prop->dmmu.hop_masks[MMU_HOP2] = MMU_V1_0_HOP2_MASK;
43062306a36Sopenharmony_ci	prop->dmmu.hop_masks[MMU_HOP3] = MMU_V1_0_HOP3_MASK;
43162306a36Sopenharmony_ci	prop->dmmu.hop_masks[MMU_HOP4] = MMU_V1_0_HOP4_MASK;
43262306a36Sopenharmony_ci	prop->dmmu.start_addr = VA_DDR_SPACE_START;
43362306a36Sopenharmony_ci	prop->dmmu.end_addr = VA_DDR_SPACE_END;
43462306a36Sopenharmony_ci	prop->dmmu.page_size = PAGE_SIZE_2MB;
43562306a36Sopenharmony_ci	prop->dmmu.num_hops = MMU_ARCH_5_HOPS;
43662306a36Sopenharmony_ci	prop->dmmu.last_mask = LAST_MASK;
43762306a36Sopenharmony_ci	/* TODO: will be duplicated until implementing per-MMU props */
43862306a36Sopenharmony_ci	prop->dmmu.hop_table_size = prop->mmu_hop_table_size;
43962306a36Sopenharmony_ci	prop->dmmu.hop0_tables_total_size = prop->mmu_hop0_tables_total_size;
44062306a36Sopenharmony_ci
44162306a36Sopenharmony_ci	/* shifts and masks are the same in PMMU and DMMU */
44262306a36Sopenharmony_ci	memcpy(&prop->pmmu, &prop->dmmu, sizeof(prop->dmmu));
44362306a36Sopenharmony_ci	prop->pmmu.start_addr = VA_HOST_SPACE_START;
44462306a36Sopenharmony_ci	prop->pmmu.end_addr = VA_HOST_SPACE_END;
44562306a36Sopenharmony_ci	prop->pmmu.page_size = PAGE_SIZE_4KB;
44662306a36Sopenharmony_ci	prop->pmmu.num_hops = MMU_ARCH_5_HOPS;
44762306a36Sopenharmony_ci	prop->pmmu.last_mask = LAST_MASK;
44862306a36Sopenharmony_ci	/* TODO: will be duplicated until implementing per-MMU props */
44962306a36Sopenharmony_ci	prop->pmmu.hop_table_size = prop->mmu_hop_table_size;
45062306a36Sopenharmony_ci	prop->pmmu.hop0_tables_total_size = prop->mmu_hop0_tables_total_size;
45162306a36Sopenharmony_ci
45262306a36Sopenharmony_ci	/* PMMU and HPMMU are the same except of page size */
45362306a36Sopenharmony_ci	memcpy(&prop->pmmu_huge, &prop->pmmu, sizeof(prop->pmmu));
45462306a36Sopenharmony_ci	prop->pmmu_huge.page_size = PAGE_SIZE_2MB;
45562306a36Sopenharmony_ci
45662306a36Sopenharmony_ci	prop->dram_size_for_default_page_mapping = VA_DDR_SPACE_END;
45762306a36Sopenharmony_ci	prop->cfg_size = CFG_SIZE;
45862306a36Sopenharmony_ci	prop->max_asid = MAX_ASID;
45962306a36Sopenharmony_ci	prop->num_of_events = GOYA_ASYNC_EVENT_ID_SIZE;
46062306a36Sopenharmony_ci	prop->high_pll = PLL_HIGH_DEFAULT;
46162306a36Sopenharmony_ci	prop->cb_pool_cb_cnt = GOYA_CB_POOL_CB_CNT;
46262306a36Sopenharmony_ci	prop->cb_pool_cb_size = GOYA_CB_POOL_CB_SIZE;
46362306a36Sopenharmony_ci	prop->max_power_default = MAX_POWER_DEFAULT;
46462306a36Sopenharmony_ci	prop->dc_power_default = DC_POWER_DEFAULT;
46562306a36Sopenharmony_ci	prop->tpc_enabled_mask = TPC_ENABLED_MASK;
46662306a36Sopenharmony_ci	prop->pcie_dbi_base_address = mmPCIE_DBI_BASE;
46762306a36Sopenharmony_ci	prop->pcie_aux_dbi_reg_addr = CFG_BASE + mmPCIE_AUX_DBI;
46862306a36Sopenharmony_ci
46962306a36Sopenharmony_ci	strncpy(prop->cpucp_info.card_name, GOYA_DEFAULT_CARD_NAME,
47062306a36Sopenharmony_ci		CARD_NAME_MAX_LEN);
47162306a36Sopenharmony_ci
47262306a36Sopenharmony_ci	prop->max_pending_cs = GOYA_MAX_PENDING_CS;
47362306a36Sopenharmony_ci
47462306a36Sopenharmony_ci	prop->first_available_user_interrupt = USHRT_MAX;
47562306a36Sopenharmony_ci	prop->tpc_interrupt_id = USHRT_MAX;
47662306a36Sopenharmony_ci	prop->eq_interrupt_id = GOYA_EVENT_QUEUE_MSIX_IDX;
47762306a36Sopenharmony_ci
47862306a36Sopenharmony_ci	for (i = 0 ; i < HL_MAX_DCORES ; i++)
47962306a36Sopenharmony_ci		prop->first_available_cq[i] = USHRT_MAX;
48062306a36Sopenharmony_ci
48162306a36Sopenharmony_ci	prop->fw_cpu_boot_dev_sts0_valid = false;
48262306a36Sopenharmony_ci	prop->fw_cpu_boot_dev_sts1_valid = false;
48362306a36Sopenharmony_ci	prop->hard_reset_done_by_fw = false;
48462306a36Sopenharmony_ci	prop->gic_interrupts_enable = true;
48562306a36Sopenharmony_ci
48662306a36Sopenharmony_ci	prop->server_type = HL_SERVER_TYPE_UNKNOWN;
48762306a36Sopenharmony_ci
48862306a36Sopenharmony_ci	prop->clk_pll_index = HL_GOYA_MME_PLL;
48962306a36Sopenharmony_ci
49062306a36Sopenharmony_ci	prop->use_get_power_for_reset_history = true;
49162306a36Sopenharmony_ci
49262306a36Sopenharmony_ci	prop->configurable_stop_on_err = true;
49362306a36Sopenharmony_ci
49462306a36Sopenharmony_ci	prop->set_max_power_on_device_init = true;
49562306a36Sopenharmony_ci
49662306a36Sopenharmony_ci	prop->dma_mask = 48;
49762306a36Sopenharmony_ci
49862306a36Sopenharmony_ci	return 0;
49962306a36Sopenharmony_ci}
50062306a36Sopenharmony_ci
50162306a36Sopenharmony_ci/*
50262306a36Sopenharmony_ci * goya_pci_bars_map - Map PCI BARS of Goya device
50362306a36Sopenharmony_ci *
50462306a36Sopenharmony_ci * @hdev: pointer to hl_device structure
50562306a36Sopenharmony_ci *
50662306a36Sopenharmony_ci * Request PCI regions and map them to kernel virtual addresses.
50762306a36Sopenharmony_ci * Returns 0 on success
50862306a36Sopenharmony_ci *
50962306a36Sopenharmony_ci */
51062306a36Sopenharmony_cistatic int goya_pci_bars_map(struct hl_device *hdev)
51162306a36Sopenharmony_ci{
51262306a36Sopenharmony_ci	static const char * const name[] = {"SRAM_CFG", "MSIX", "DDR"};
51362306a36Sopenharmony_ci	bool is_wc[3] = {false, false, true};
51462306a36Sopenharmony_ci	int rc;
51562306a36Sopenharmony_ci
51662306a36Sopenharmony_ci	rc = hl_pci_bars_map(hdev, name, is_wc);
51762306a36Sopenharmony_ci	if (rc)
51862306a36Sopenharmony_ci		return rc;
51962306a36Sopenharmony_ci
52062306a36Sopenharmony_ci	hdev->rmmio = hdev->pcie_bar[SRAM_CFG_BAR_ID] +
52162306a36Sopenharmony_ci			(CFG_BASE - SRAM_BASE_ADDR);
52262306a36Sopenharmony_ci
52362306a36Sopenharmony_ci	return 0;
52462306a36Sopenharmony_ci}
52562306a36Sopenharmony_ci
52662306a36Sopenharmony_cistatic u64 goya_set_ddr_bar_base(struct hl_device *hdev, u64 addr)
52762306a36Sopenharmony_ci{
52862306a36Sopenharmony_ci	struct goya_device *goya = hdev->asic_specific;
52962306a36Sopenharmony_ci	struct hl_inbound_pci_region pci_region;
53062306a36Sopenharmony_ci	u64 old_addr = addr;
53162306a36Sopenharmony_ci	int rc;
53262306a36Sopenharmony_ci
53362306a36Sopenharmony_ci	if ((goya) && (goya->ddr_bar_cur_addr == addr))
53462306a36Sopenharmony_ci		return old_addr;
53562306a36Sopenharmony_ci
53662306a36Sopenharmony_ci	/* Inbound Region 1 - Bar 4 - Point to DDR */
53762306a36Sopenharmony_ci	pci_region.mode = PCI_BAR_MATCH_MODE;
53862306a36Sopenharmony_ci	pci_region.bar = DDR_BAR_ID;
53962306a36Sopenharmony_ci	pci_region.addr = addr;
54062306a36Sopenharmony_ci	rc = hl_pci_set_inbound_region(hdev, 1, &pci_region);
54162306a36Sopenharmony_ci	if (rc)
54262306a36Sopenharmony_ci		return U64_MAX;
54362306a36Sopenharmony_ci
54462306a36Sopenharmony_ci	if (goya) {
54562306a36Sopenharmony_ci		old_addr = goya->ddr_bar_cur_addr;
54662306a36Sopenharmony_ci		goya->ddr_bar_cur_addr = addr;
54762306a36Sopenharmony_ci	}
54862306a36Sopenharmony_ci
54962306a36Sopenharmony_ci	return old_addr;
55062306a36Sopenharmony_ci}
55162306a36Sopenharmony_ci
55262306a36Sopenharmony_ci/*
55362306a36Sopenharmony_ci * goya_init_iatu - Initialize the iATU unit inside the PCI controller
55462306a36Sopenharmony_ci *
55562306a36Sopenharmony_ci * @hdev: pointer to hl_device structure
55662306a36Sopenharmony_ci *
55762306a36Sopenharmony_ci * This is needed in case the firmware doesn't initialize the iATU
55862306a36Sopenharmony_ci *
55962306a36Sopenharmony_ci */
56062306a36Sopenharmony_cistatic int goya_init_iatu(struct hl_device *hdev)
56162306a36Sopenharmony_ci{
56262306a36Sopenharmony_ci	struct hl_inbound_pci_region inbound_region;
56362306a36Sopenharmony_ci	struct hl_outbound_pci_region outbound_region;
56462306a36Sopenharmony_ci	int rc;
56562306a36Sopenharmony_ci
56662306a36Sopenharmony_ci	if (hdev->asic_prop.iatu_done_by_fw)
56762306a36Sopenharmony_ci		return 0;
56862306a36Sopenharmony_ci
56962306a36Sopenharmony_ci	/* Inbound Region 0 - Bar 0 - Point to SRAM and CFG */
57062306a36Sopenharmony_ci	inbound_region.mode = PCI_BAR_MATCH_MODE;
57162306a36Sopenharmony_ci	inbound_region.bar = SRAM_CFG_BAR_ID;
57262306a36Sopenharmony_ci	inbound_region.addr = SRAM_BASE_ADDR;
57362306a36Sopenharmony_ci	rc = hl_pci_set_inbound_region(hdev, 0, &inbound_region);
57462306a36Sopenharmony_ci	if (rc)
57562306a36Sopenharmony_ci		goto done;
57662306a36Sopenharmony_ci
57762306a36Sopenharmony_ci	/* Inbound Region 1 - Bar 4 - Point to DDR */
57862306a36Sopenharmony_ci	inbound_region.mode = PCI_BAR_MATCH_MODE;
57962306a36Sopenharmony_ci	inbound_region.bar = DDR_BAR_ID;
58062306a36Sopenharmony_ci	inbound_region.addr = DRAM_PHYS_BASE;
58162306a36Sopenharmony_ci	rc = hl_pci_set_inbound_region(hdev, 1, &inbound_region);
58262306a36Sopenharmony_ci	if (rc)
58362306a36Sopenharmony_ci		goto done;
58462306a36Sopenharmony_ci
58562306a36Sopenharmony_ci	/* Outbound Region 0 - Point to Host  */
58662306a36Sopenharmony_ci	outbound_region.addr = HOST_PHYS_BASE;
58762306a36Sopenharmony_ci	outbound_region.size = HOST_PHYS_SIZE;
58862306a36Sopenharmony_ci	rc = hl_pci_set_outbound_region(hdev, &outbound_region);
58962306a36Sopenharmony_ci
59062306a36Sopenharmony_cidone:
59162306a36Sopenharmony_ci	return rc;
59262306a36Sopenharmony_ci}
59362306a36Sopenharmony_ci
59462306a36Sopenharmony_cistatic enum hl_device_hw_state goya_get_hw_state(struct hl_device *hdev)
59562306a36Sopenharmony_ci{
59662306a36Sopenharmony_ci	return RREG32(mmHW_STATE);
59762306a36Sopenharmony_ci}
59862306a36Sopenharmony_ci
59962306a36Sopenharmony_ci/*
60062306a36Sopenharmony_ci * goya_early_init - GOYA early initialization code
60162306a36Sopenharmony_ci *
60262306a36Sopenharmony_ci * @hdev: pointer to hl_device structure
60362306a36Sopenharmony_ci *
60462306a36Sopenharmony_ci * Verify PCI bars
60562306a36Sopenharmony_ci * Set DMA masks
60662306a36Sopenharmony_ci * PCI controller initialization
60762306a36Sopenharmony_ci * Map PCI bars
60862306a36Sopenharmony_ci *
60962306a36Sopenharmony_ci */
61062306a36Sopenharmony_cistatic int goya_early_init(struct hl_device *hdev)
61162306a36Sopenharmony_ci{
61262306a36Sopenharmony_ci	struct asic_fixed_properties *prop = &hdev->asic_prop;
61362306a36Sopenharmony_ci	struct pci_dev *pdev = hdev->pdev;
61462306a36Sopenharmony_ci	resource_size_t pci_bar_size;
61562306a36Sopenharmony_ci	u32 fw_boot_status, val;
61662306a36Sopenharmony_ci	int rc;
61762306a36Sopenharmony_ci
61862306a36Sopenharmony_ci	rc = goya_set_fixed_properties(hdev);
61962306a36Sopenharmony_ci	if (rc) {
62062306a36Sopenharmony_ci		dev_err(hdev->dev, "Failed to get fixed properties\n");
62162306a36Sopenharmony_ci		return rc;
62262306a36Sopenharmony_ci	}
62362306a36Sopenharmony_ci
62462306a36Sopenharmony_ci	/* Check BAR sizes */
62562306a36Sopenharmony_ci	pci_bar_size = pci_resource_len(pdev, SRAM_CFG_BAR_ID);
62662306a36Sopenharmony_ci
62762306a36Sopenharmony_ci	if (pci_bar_size != CFG_BAR_SIZE) {
62862306a36Sopenharmony_ci		dev_err(hdev->dev, "Not " HL_NAME "? BAR %d size %pa, expecting %llu\n",
62962306a36Sopenharmony_ci			SRAM_CFG_BAR_ID, &pci_bar_size, CFG_BAR_SIZE);
63062306a36Sopenharmony_ci		rc = -ENODEV;
63162306a36Sopenharmony_ci		goto free_queue_props;
63262306a36Sopenharmony_ci	}
63362306a36Sopenharmony_ci
63462306a36Sopenharmony_ci	pci_bar_size = pci_resource_len(pdev, MSIX_BAR_ID);
63562306a36Sopenharmony_ci
63662306a36Sopenharmony_ci	if (pci_bar_size != MSIX_BAR_SIZE) {
63762306a36Sopenharmony_ci		dev_err(hdev->dev, "Not " HL_NAME "? BAR %d size %pa, expecting %llu\n",
63862306a36Sopenharmony_ci			MSIX_BAR_ID, &pci_bar_size, MSIX_BAR_SIZE);
63962306a36Sopenharmony_ci		rc = -ENODEV;
64062306a36Sopenharmony_ci		goto free_queue_props;
64162306a36Sopenharmony_ci	}
64262306a36Sopenharmony_ci
64362306a36Sopenharmony_ci	prop->dram_pci_bar_size = pci_resource_len(pdev, DDR_BAR_ID);
64462306a36Sopenharmony_ci	hdev->dram_pci_bar_start = pci_resource_start(pdev, DDR_BAR_ID);
64562306a36Sopenharmony_ci
64662306a36Sopenharmony_ci	/* If FW security is enabled at this point it means no access to ELBI */
64762306a36Sopenharmony_ci	if (hdev->asic_prop.fw_security_enabled) {
64862306a36Sopenharmony_ci		hdev->asic_prop.iatu_done_by_fw = true;
64962306a36Sopenharmony_ci		goto pci_init;
65062306a36Sopenharmony_ci	}
65162306a36Sopenharmony_ci
65262306a36Sopenharmony_ci	rc = hl_pci_elbi_read(hdev, CFG_BASE + mmCPU_BOOT_DEV_STS0,
65362306a36Sopenharmony_ci				&fw_boot_status);
65462306a36Sopenharmony_ci	if (rc)
65562306a36Sopenharmony_ci		goto free_queue_props;
65662306a36Sopenharmony_ci
65762306a36Sopenharmony_ci	/* Check whether FW is configuring iATU */
65862306a36Sopenharmony_ci	if ((fw_boot_status & CPU_BOOT_DEV_STS0_ENABLED) &&
65962306a36Sopenharmony_ci			(fw_boot_status & CPU_BOOT_DEV_STS0_FW_IATU_CONF_EN))
66062306a36Sopenharmony_ci		hdev->asic_prop.iatu_done_by_fw = true;
66162306a36Sopenharmony_ci
66262306a36Sopenharmony_cipci_init:
66362306a36Sopenharmony_ci	rc = hl_pci_init(hdev);
66462306a36Sopenharmony_ci	if (rc)
66562306a36Sopenharmony_ci		goto free_queue_props;
66662306a36Sopenharmony_ci
66762306a36Sopenharmony_ci	/* Before continuing in the initialization, we need to read the preboot
66862306a36Sopenharmony_ci	 * version to determine whether we run with a security-enabled firmware
66962306a36Sopenharmony_ci	 */
67062306a36Sopenharmony_ci	rc = hl_fw_read_preboot_status(hdev);
67162306a36Sopenharmony_ci	if (rc) {
67262306a36Sopenharmony_ci		if (hdev->reset_on_preboot_fail)
67362306a36Sopenharmony_ci			/* we are already on failure flow, so don't check if hw_fini fails. */
67462306a36Sopenharmony_ci			hdev->asic_funcs->hw_fini(hdev, true, false);
67562306a36Sopenharmony_ci		goto pci_fini;
67662306a36Sopenharmony_ci	}
67762306a36Sopenharmony_ci
67862306a36Sopenharmony_ci	if (goya_get_hw_state(hdev) == HL_DEVICE_HW_STATE_DIRTY) {
67962306a36Sopenharmony_ci		dev_dbg(hdev->dev, "H/W state is dirty, must reset before initializing\n");
68062306a36Sopenharmony_ci		rc = hdev->asic_funcs->hw_fini(hdev, true, false);
68162306a36Sopenharmony_ci		if (rc) {
68262306a36Sopenharmony_ci			dev_err(hdev->dev, "failed to reset HW in dirty state (%d)\n", rc);
68362306a36Sopenharmony_ci			goto pci_fini;
68462306a36Sopenharmony_ci		}
68562306a36Sopenharmony_ci	}
68662306a36Sopenharmony_ci
68762306a36Sopenharmony_ci	if (!hdev->pldm) {
68862306a36Sopenharmony_ci		val = RREG32(mmPSOC_GLOBAL_CONF_BOOT_STRAP_PINS);
68962306a36Sopenharmony_ci		if (val & PSOC_GLOBAL_CONF_BOOT_STRAP_PINS_SRIOV_EN_MASK)
69062306a36Sopenharmony_ci			dev_warn(hdev->dev,
69162306a36Sopenharmony_ci				"PCI strap is not configured correctly, PCI bus errors may occur\n");
69262306a36Sopenharmony_ci	}
69362306a36Sopenharmony_ci
69462306a36Sopenharmony_ci	return 0;
69562306a36Sopenharmony_ci
69662306a36Sopenharmony_cipci_fini:
69762306a36Sopenharmony_ci	hl_pci_fini(hdev);
69862306a36Sopenharmony_cifree_queue_props:
69962306a36Sopenharmony_ci	kfree(hdev->asic_prop.hw_queues_props);
70062306a36Sopenharmony_ci	return rc;
70162306a36Sopenharmony_ci}
70262306a36Sopenharmony_ci
70362306a36Sopenharmony_ci/*
70462306a36Sopenharmony_ci * goya_early_fini - GOYA early finalization code
70562306a36Sopenharmony_ci *
70662306a36Sopenharmony_ci * @hdev: pointer to hl_device structure
70762306a36Sopenharmony_ci *
70862306a36Sopenharmony_ci * Unmap PCI bars
70962306a36Sopenharmony_ci *
71062306a36Sopenharmony_ci */
71162306a36Sopenharmony_cistatic int goya_early_fini(struct hl_device *hdev)
71262306a36Sopenharmony_ci{
71362306a36Sopenharmony_ci	kfree(hdev->asic_prop.hw_queues_props);
71462306a36Sopenharmony_ci	hl_pci_fini(hdev);
71562306a36Sopenharmony_ci
71662306a36Sopenharmony_ci	return 0;
71762306a36Sopenharmony_ci}
71862306a36Sopenharmony_ci
71962306a36Sopenharmony_cistatic void goya_mmu_prepare_reg(struct hl_device *hdev, u64 reg, u32 asid)
72062306a36Sopenharmony_ci{
72162306a36Sopenharmony_ci	/* mask to zero the MMBP and ASID bits */
72262306a36Sopenharmony_ci	WREG32_AND(reg, ~0x7FF);
72362306a36Sopenharmony_ci	WREG32_OR(reg, asid);
72462306a36Sopenharmony_ci}
72562306a36Sopenharmony_ci
72662306a36Sopenharmony_cistatic void goya_qman0_set_security(struct hl_device *hdev, bool secure)
72762306a36Sopenharmony_ci{
72862306a36Sopenharmony_ci	struct goya_device *goya = hdev->asic_specific;
72962306a36Sopenharmony_ci
73062306a36Sopenharmony_ci	if (!(goya->hw_cap_initialized & HW_CAP_MMU))
73162306a36Sopenharmony_ci		return;
73262306a36Sopenharmony_ci
73362306a36Sopenharmony_ci	if (secure)
73462306a36Sopenharmony_ci		WREG32(mmDMA_QM_0_GLBL_PROT, QMAN_DMA_FULLY_TRUSTED);
73562306a36Sopenharmony_ci	else
73662306a36Sopenharmony_ci		WREG32(mmDMA_QM_0_GLBL_PROT, QMAN_DMA_PARTLY_TRUSTED);
73762306a36Sopenharmony_ci
73862306a36Sopenharmony_ci	RREG32(mmDMA_QM_0_GLBL_PROT);
73962306a36Sopenharmony_ci}
74062306a36Sopenharmony_ci
74162306a36Sopenharmony_ci/*
74262306a36Sopenharmony_ci * goya_fetch_psoc_frequency - Fetch PSOC frequency values
74362306a36Sopenharmony_ci *
74462306a36Sopenharmony_ci * @hdev: pointer to hl_device structure
74562306a36Sopenharmony_ci *
74662306a36Sopenharmony_ci */
74762306a36Sopenharmony_cistatic void goya_fetch_psoc_frequency(struct hl_device *hdev)
74862306a36Sopenharmony_ci{
74962306a36Sopenharmony_ci	struct asic_fixed_properties *prop = &hdev->asic_prop;
75062306a36Sopenharmony_ci	u32 nr = 0, nf = 0, od = 0, div_fctr = 0, pll_clk, div_sel;
75162306a36Sopenharmony_ci	u16 pll_freq_arr[HL_PLL_NUM_OUTPUTS], freq;
75262306a36Sopenharmony_ci	int rc;
75362306a36Sopenharmony_ci
75462306a36Sopenharmony_ci	if (hdev->asic_prop.fw_security_enabled) {
75562306a36Sopenharmony_ci		struct goya_device *goya = hdev->asic_specific;
75662306a36Sopenharmony_ci
75762306a36Sopenharmony_ci		if (!(goya->hw_cap_initialized & HW_CAP_CPU_Q))
75862306a36Sopenharmony_ci			return;
75962306a36Sopenharmony_ci
76062306a36Sopenharmony_ci		rc = hl_fw_cpucp_pll_info_get(hdev, HL_GOYA_PCI_PLL,
76162306a36Sopenharmony_ci				pll_freq_arr);
76262306a36Sopenharmony_ci
76362306a36Sopenharmony_ci		if (rc)
76462306a36Sopenharmony_ci			return;
76562306a36Sopenharmony_ci
76662306a36Sopenharmony_ci		freq = pll_freq_arr[1];
76762306a36Sopenharmony_ci	} else {
76862306a36Sopenharmony_ci		div_fctr = RREG32(mmPSOC_PCI_PLL_DIV_FACTOR_1);
76962306a36Sopenharmony_ci		div_sel = RREG32(mmPSOC_PCI_PLL_DIV_SEL_1);
77062306a36Sopenharmony_ci		nr = RREG32(mmPSOC_PCI_PLL_NR);
77162306a36Sopenharmony_ci		nf = RREG32(mmPSOC_PCI_PLL_NF);
77262306a36Sopenharmony_ci		od = RREG32(mmPSOC_PCI_PLL_OD);
77362306a36Sopenharmony_ci
77462306a36Sopenharmony_ci		if (div_sel == DIV_SEL_REF_CLK ||
77562306a36Sopenharmony_ci				div_sel == DIV_SEL_DIVIDED_REF) {
77662306a36Sopenharmony_ci			if (div_sel == DIV_SEL_REF_CLK)
77762306a36Sopenharmony_ci				freq = PLL_REF_CLK;
77862306a36Sopenharmony_ci			else
77962306a36Sopenharmony_ci				freq = PLL_REF_CLK / (div_fctr + 1);
78062306a36Sopenharmony_ci		} else if (div_sel == DIV_SEL_PLL_CLK ||
78162306a36Sopenharmony_ci				div_sel == DIV_SEL_DIVIDED_PLL) {
78262306a36Sopenharmony_ci			pll_clk = PLL_REF_CLK * (nf + 1) /
78362306a36Sopenharmony_ci					((nr + 1) * (od + 1));
78462306a36Sopenharmony_ci			if (div_sel == DIV_SEL_PLL_CLK)
78562306a36Sopenharmony_ci				freq = pll_clk;
78662306a36Sopenharmony_ci			else
78762306a36Sopenharmony_ci				freq = pll_clk / (div_fctr + 1);
78862306a36Sopenharmony_ci		} else {
78962306a36Sopenharmony_ci			dev_warn(hdev->dev,
79062306a36Sopenharmony_ci				"Received invalid div select value: %d",
79162306a36Sopenharmony_ci				div_sel);
79262306a36Sopenharmony_ci			freq = 0;
79362306a36Sopenharmony_ci		}
79462306a36Sopenharmony_ci	}
79562306a36Sopenharmony_ci
79662306a36Sopenharmony_ci	prop->psoc_timestamp_frequency = freq;
79762306a36Sopenharmony_ci	prop->psoc_pci_pll_nr = nr;
79862306a36Sopenharmony_ci	prop->psoc_pci_pll_nf = nf;
79962306a36Sopenharmony_ci	prop->psoc_pci_pll_od = od;
80062306a36Sopenharmony_ci	prop->psoc_pci_pll_div_factor = div_fctr;
80162306a36Sopenharmony_ci}
80262306a36Sopenharmony_ci
80362306a36Sopenharmony_ci/*
80462306a36Sopenharmony_ci * goya_set_frequency - set the frequency of the device
80562306a36Sopenharmony_ci *
80662306a36Sopenharmony_ci * @hdev: pointer to habanalabs device structure
80762306a36Sopenharmony_ci * @freq: the new frequency value
80862306a36Sopenharmony_ci *
80962306a36Sopenharmony_ci * Change the frequency if needed. This function has no protection against
81062306a36Sopenharmony_ci * concurrency, therefore it is assumed that the calling function has protected
81162306a36Sopenharmony_ci * itself against the case of calling this function from multiple threads with
81262306a36Sopenharmony_ci * different values
81362306a36Sopenharmony_ci *
81462306a36Sopenharmony_ci * Returns 0 if no change was done, otherwise returns 1
81562306a36Sopenharmony_ci */
81662306a36Sopenharmony_ciint goya_set_frequency(struct hl_device *hdev, enum hl_pll_frequency freq)
81762306a36Sopenharmony_ci{
81862306a36Sopenharmony_ci	struct goya_device *goya = hdev->asic_specific;
81962306a36Sopenharmony_ci
82062306a36Sopenharmony_ci	if ((goya->pm_mng_profile == PM_MANUAL) ||
82162306a36Sopenharmony_ci			(goya->curr_pll_profile == freq))
82262306a36Sopenharmony_ci		return 0;
82362306a36Sopenharmony_ci
82462306a36Sopenharmony_ci	dev_dbg(hdev->dev, "Changing device frequency to %s\n",
82562306a36Sopenharmony_ci		freq == PLL_HIGH ? "high" : "low");
82662306a36Sopenharmony_ci
82762306a36Sopenharmony_ci	goya_set_pll_profile(hdev, freq);
82862306a36Sopenharmony_ci
82962306a36Sopenharmony_ci	goya->curr_pll_profile = freq;
83062306a36Sopenharmony_ci
83162306a36Sopenharmony_ci	return 1;
83262306a36Sopenharmony_ci}
83362306a36Sopenharmony_ci
83462306a36Sopenharmony_cistatic void goya_set_freq_to_low_job(struct work_struct *work)
83562306a36Sopenharmony_ci{
83662306a36Sopenharmony_ci	struct goya_work_freq *goya_work = container_of(work,
83762306a36Sopenharmony_ci						struct goya_work_freq,
83862306a36Sopenharmony_ci						work_freq.work);
83962306a36Sopenharmony_ci	struct hl_device *hdev = goya_work->hdev;
84062306a36Sopenharmony_ci
84162306a36Sopenharmony_ci	mutex_lock(&hdev->fpriv_list_lock);
84262306a36Sopenharmony_ci
84362306a36Sopenharmony_ci	if (!hdev->is_compute_ctx_active)
84462306a36Sopenharmony_ci		goya_set_frequency(hdev, PLL_LOW);
84562306a36Sopenharmony_ci
84662306a36Sopenharmony_ci	mutex_unlock(&hdev->fpriv_list_lock);
84762306a36Sopenharmony_ci
84862306a36Sopenharmony_ci	schedule_delayed_work(&goya_work->work_freq,
84962306a36Sopenharmony_ci			usecs_to_jiffies(HL_PLL_LOW_JOB_FREQ_USEC));
85062306a36Sopenharmony_ci}
85162306a36Sopenharmony_ci
85262306a36Sopenharmony_ciint goya_late_init(struct hl_device *hdev)
85362306a36Sopenharmony_ci{
85462306a36Sopenharmony_ci	struct asic_fixed_properties *prop = &hdev->asic_prop;
85562306a36Sopenharmony_ci	struct goya_device *goya = hdev->asic_specific;
85662306a36Sopenharmony_ci	int rc;
85762306a36Sopenharmony_ci
85862306a36Sopenharmony_ci	goya_fetch_psoc_frequency(hdev);
85962306a36Sopenharmony_ci
86062306a36Sopenharmony_ci	rc = goya_mmu_clear_pgt_range(hdev);
86162306a36Sopenharmony_ci	if (rc) {
86262306a36Sopenharmony_ci		dev_err(hdev->dev,
86362306a36Sopenharmony_ci			"Failed to clear MMU page tables range %d\n", rc);
86462306a36Sopenharmony_ci		return rc;
86562306a36Sopenharmony_ci	}
86662306a36Sopenharmony_ci
86762306a36Sopenharmony_ci	rc = goya_mmu_set_dram_default_page(hdev);
86862306a36Sopenharmony_ci	if (rc) {
86962306a36Sopenharmony_ci		dev_err(hdev->dev, "Failed to set DRAM default page %d\n", rc);
87062306a36Sopenharmony_ci		return rc;
87162306a36Sopenharmony_ci	}
87262306a36Sopenharmony_ci
87362306a36Sopenharmony_ci	rc = goya_mmu_add_mappings_for_device_cpu(hdev);
87462306a36Sopenharmony_ci	if (rc)
87562306a36Sopenharmony_ci		return rc;
87662306a36Sopenharmony_ci
87762306a36Sopenharmony_ci	rc = goya_init_cpu_queues(hdev);
87862306a36Sopenharmony_ci	if (rc)
87962306a36Sopenharmony_ci		return rc;
88062306a36Sopenharmony_ci
88162306a36Sopenharmony_ci	rc = goya_test_cpu_queue(hdev);
88262306a36Sopenharmony_ci	if (rc)
88362306a36Sopenharmony_ci		return rc;
88462306a36Sopenharmony_ci
88562306a36Sopenharmony_ci	rc = goya_cpucp_info_get(hdev);
88662306a36Sopenharmony_ci	if (rc) {
88762306a36Sopenharmony_ci		dev_err(hdev->dev, "Failed to get cpucp info %d\n", rc);
88862306a36Sopenharmony_ci		return rc;
88962306a36Sopenharmony_ci	}
89062306a36Sopenharmony_ci
89162306a36Sopenharmony_ci	/* Now that we have the DRAM size in ASIC prop, we need to check
89262306a36Sopenharmony_ci	 * its size and configure the DMA_IF DDR wrap protection (which is in
89362306a36Sopenharmony_ci	 * the MMU block) accordingly. The value is the log2 of the DRAM size
89462306a36Sopenharmony_ci	 */
89562306a36Sopenharmony_ci	WREG32(mmMMU_LOG2_DDR_SIZE, ilog2(prop->dram_size));
89662306a36Sopenharmony_ci
89762306a36Sopenharmony_ci	rc = hl_fw_send_pci_access_msg(hdev, CPUCP_PACKET_ENABLE_PCI_ACCESS, 0x0);
89862306a36Sopenharmony_ci	if (rc) {
89962306a36Sopenharmony_ci		dev_err(hdev->dev,
90062306a36Sopenharmony_ci			"Failed to enable PCI access from CPU %d\n", rc);
90162306a36Sopenharmony_ci		return rc;
90262306a36Sopenharmony_ci	}
90362306a36Sopenharmony_ci
90462306a36Sopenharmony_ci	/* force setting to low frequency */
90562306a36Sopenharmony_ci	goya->curr_pll_profile = PLL_LOW;
90662306a36Sopenharmony_ci
90762306a36Sopenharmony_ci	goya->pm_mng_profile = PM_AUTO;
90862306a36Sopenharmony_ci
90962306a36Sopenharmony_ci	goya_set_pll_profile(hdev, PLL_LOW);
91062306a36Sopenharmony_ci
91162306a36Sopenharmony_ci	schedule_delayed_work(&goya->goya_work->work_freq,
91262306a36Sopenharmony_ci		usecs_to_jiffies(HL_PLL_LOW_JOB_FREQ_USEC));
91362306a36Sopenharmony_ci
91462306a36Sopenharmony_ci	return 0;
91562306a36Sopenharmony_ci}
91662306a36Sopenharmony_ci
91762306a36Sopenharmony_ci/*
91862306a36Sopenharmony_ci * goya_late_fini - GOYA late tear-down code
91962306a36Sopenharmony_ci *
92062306a36Sopenharmony_ci * @hdev: pointer to hl_device structure
92162306a36Sopenharmony_ci *
92262306a36Sopenharmony_ci * Free sensors allocated structures
92362306a36Sopenharmony_ci */
92462306a36Sopenharmony_civoid goya_late_fini(struct hl_device *hdev)
92562306a36Sopenharmony_ci{
92662306a36Sopenharmony_ci	struct goya_device *goya = hdev->asic_specific;
92762306a36Sopenharmony_ci
92862306a36Sopenharmony_ci	cancel_delayed_work_sync(&goya->goya_work->work_freq);
92962306a36Sopenharmony_ci
93062306a36Sopenharmony_ci	hl_hwmon_release_resources(hdev);
93162306a36Sopenharmony_ci}
93262306a36Sopenharmony_ci
93362306a36Sopenharmony_cistatic void goya_set_pci_memory_regions(struct hl_device *hdev)
93462306a36Sopenharmony_ci{
93562306a36Sopenharmony_ci	struct asic_fixed_properties *prop = &hdev->asic_prop;
93662306a36Sopenharmony_ci	struct pci_mem_region *region;
93762306a36Sopenharmony_ci
93862306a36Sopenharmony_ci	/* CFG */
93962306a36Sopenharmony_ci	region = &hdev->pci_mem_region[PCI_REGION_CFG];
94062306a36Sopenharmony_ci	region->region_base = CFG_BASE;
94162306a36Sopenharmony_ci	region->region_size = CFG_SIZE;
94262306a36Sopenharmony_ci	region->offset_in_bar = CFG_BASE - SRAM_BASE_ADDR;
94362306a36Sopenharmony_ci	region->bar_size = CFG_BAR_SIZE;
94462306a36Sopenharmony_ci	region->bar_id = SRAM_CFG_BAR_ID;
94562306a36Sopenharmony_ci	region->used = 1;
94662306a36Sopenharmony_ci
94762306a36Sopenharmony_ci	/* SRAM */
94862306a36Sopenharmony_ci	region = &hdev->pci_mem_region[PCI_REGION_SRAM];
94962306a36Sopenharmony_ci	region->region_base = SRAM_BASE_ADDR;
95062306a36Sopenharmony_ci	region->region_size = SRAM_SIZE;
95162306a36Sopenharmony_ci	region->offset_in_bar = 0;
95262306a36Sopenharmony_ci	region->bar_size = CFG_BAR_SIZE;
95362306a36Sopenharmony_ci	region->bar_id = SRAM_CFG_BAR_ID;
95462306a36Sopenharmony_ci	region->used = 1;
95562306a36Sopenharmony_ci
95662306a36Sopenharmony_ci	/* DRAM */
95762306a36Sopenharmony_ci	region = &hdev->pci_mem_region[PCI_REGION_DRAM];
95862306a36Sopenharmony_ci	region->region_base = DRAM_PHYS_BASE;
95962306a36Sopenharmony_ci	region->region_size = hdev->asic_prop.dram_size;
96062306a36Sopenharmony_ci	region->offset_in_bar = 0;
96162306a36Sopenharmony_ci	region->bar_size = prop->dram_pci_bar_size;
96262306a36Sopenharmony_ci	region->bar_id = DDR_BAR_ID;
96362306a36Sopenharmony_ci	region->used = 1;
96462306a36Sopenharmony_ci}
96562306a36Sopenharmony_ci
96662306a36Sopenharmony_ci/*
96762306a36Sopenharmony_ci * goya_sw_init - Goya software initialization code
96862306a36Sopenharmony_ci *
96962306a36Sopenharmony_ci * @hdev: pointer to hl_device structure
97062306a36Sopenharmony_ci *
97162306a36Sopenharmony_ci */
97262306a36Sopenharmony_cistatic int goya_sw_init(struct hl_device *hdev)
97362306a36Sopenharmony_ci{
97462306a36Sopenharmony_ci	struct goya_device *goya;
97562306a36Sopenharmony_ci	int rc;
97662306a36Sopenharmony_ci
97762306a36Sopenharmony_ci	/* Allocate device structure */
97862306a36Sopenharmony_ci	goya = kzalloc(sizeof(*goya), GFP_KERNEL);
97962306a36Sopenharmony_ci	if (!goya)
98062306a36Sopenharmony_ci		return -ENOMEM;
98162306a36Sopenharmony_ci
98262306a36Sopenharmony_ci	/* according to goya_init_iatu */
98362306a36Sopenharmony_ci	goya->ddr_bar_cur_addr = DRAM_PHYS_BASE;
98462306a36Sopenharmony_ci
98562306a36Sopenharmony_ci	goya->mme_clk = GOYA_PLL_FREQ_LOW;
98662306a36Sopenharmony_ci	goya->tpc_clk = GOYA_PLL_FREQ_LOW;
98762306a36Sopenharmony_ci	goya->ic_clk = GOYA_PLL_FREQ_LOW;
98862306a36Sopenharmony_ci
98962306a36Sopenharmony_ci	hdev->asic_specific = goya;
99062306a36Sopenharmony_ci
99162306a36Sopenharmony_ci	/* Create DMA pool for small allocations */
99262306a36Sopenharmony_ci	hdev->dma_pool = dma_pool_create(dev_name(hdev->dev),
99362306a36Sopenharmony_ci			&hdev->pdev->dev, GOYA_DMA_POOL_BLK_SIZE, 8, 0);
99462306a36Sopenharmony_ci	if (!hdev->dma_pool) {
99562306a36Sopenharmony_ci		dev_err(hdev->dev, "failed to create DMA pool\n");
99662306a36Sopenharmony_ci		rc = -ENOMEM;
99762306a36Sopenharmony_ci		goto free_goya_device;
99862306a36Sopenharmony_ci	}
99962306a36Sopenharmony_ci
100062306a36Sopenharmony_ci	hdev->cpu_accessible_dma_mem = hl_asic_dma_alloc_coherent(hdev, HL_CPU_ACCESSIBLE_MEM_SIZE,
100162306a36Sopenharmony_ci							&hdev->cpu_accessible_dma_address,
100262306a36Sopenharmony_ci							GFP_KERNEL | __GFP_ZERO);
100362306a36Sopenharmony_ci
100462306a36Sopenharmony_ci	if (!hdev->cpu_accessible_dma_mem) {
100562306a36Sopenharmony_ci		rc = -ENOMEM;
100662306a36Sopenharmony_ci		goto free_dma_pool;
100762306a36Sopenharmony_ci	}
100862306a36Sopenharmony_ci
100962306a36Sopenharmony_ci	dev_dbg(hdev->dev, "cpu accessible memory at bus address %pad\n",
101062306a36Sopenharmony_ci		&hdev->cpu_accessible_dma_address);
101162306a36Sopenharmony_ci
101262306a36Sopenharmony_ci	hdev->cpu_accessible_dma_pool = gen_pool_create(ilog2(32), -1);
101362306a36Sopenharmony_ci	if (!hdev->cpu_accessible_dma_pool) {
101462306a36Sopenharmony_ci		dev_err(hdev->dev,
101562306a36Sopenharmony_ci			"Failed to create CPU accessible DMA pool\n");
101662306a36Sopenharmony_ci		rc = -ENOMEM;
101762306a36Sopenharmony_ci		goto free_cpu_dma_mem;
101862306a36Sopenharmony_ci	}
101962306a36Sopenharmony_ci
102062306a36Sopenharmony_ci	rc = gen_pool_add(hdev->cpu_accessible_dma_pool,
102162306a36Sopenharmony_ci				(uintptr_t) hdev->cpu_accessible_dma_mem,
102262306a36Sopenharmony_ci				HL_CPU_ACCESSIBLE_MEM_SIZE, -1);
102362306a36Sopenharmony_ci	if (rc) {
102462306a36Sopenharmony_ci		dev_err(hdev->dev,
102562306a36Sopenharmony_ci			"Failed to add memory to CPU accessible DMA pool\n");
102662306a36Sopenharmony_ci		rc = -EFAULT;
102762306a36Sopenharmony_ci		goto free_cpu_accessible_dma_pool;
102862306a36Sopenharmony_ci	}
102962306a36Sopenharmony_ci
103062306a36Sopenharmony_ci	spin_lock_init(&goya->hw_queues_lock);
103162306a36Sopenharmony_ci	hdev->supports_coresight = true;
103262306a36Sopenharmony_ci	hdev->asic_prop.supports_compute_reset = true;
103362306a36Sopenharmony_ci	hdev->asic_prop.allow_inference_soft_reset = true;
103462306a36Sopenharmony_ci	hdev->supports_wait_for_multi_cs = false;
103562306a36Sopenharmony_ci	hdev->supports_ctx_switch = true;
103662306a36Sopenharmony_ci
103762306a36Sopenharmony_ci	hdev->asic_funcs->set_pci_memory_regions(hdev);
103862306a36Sopenharmony_ci
103962306a36Sopenharmony_ci	goya->goya_work = kmalloc(sizeof(struct goya_work_freq), GFP_KERNEL);
104062306a36Sopenharmony_ci	if (!goya->goya_work) {
104162306a36Sopenharmony_ci		rc = -ENOMEM;
104262306a36Sopenharmony_ci		goto free_cpu_accessible_dma_pool;
104362306a36Sopenharmony_ci	}
104462306a36Sopenharmony_ci
104562306a36Sopenharmony_ci	goya->goya_work->hdev = hdev;
104662306a36Sopenharmony_ci	INIT_DELAYED_WORK(&goya->goya_work->work_freq, goya_set_freq_to_low_job);
104762306a36Sopenharmony_ci
104862306a36Sopenharmony_ci	return 0;
104962306a36Sopenharmony_ci
105062306a36Sopenharmony_cifree_cpu_accessible_dma_pool:
105162306a36Sopenharmony_ci	gen_pool_destroy(hdev->cpu_accessible_dma_pool);
105262306a36Sopenharmony_cifree_cpu_dma_mem:
105362306a36Sopenharmony_ci	hl_asic_dma_free_coherent(hdev, HL_CPU_ACCESSIBLE_MEM_SIZE, hdev->cpu_accessible_dma_mem,
105462306a36Sopenharmony_ci					hdev->cpu_accessible_dma_address);
105562306a36Sopenharmony_cifree_dma_pool:
105662306a36Sopenharmony_ci	dma_pool_destroy(hdev->dma_pool);
105762306a36Sopenharmony_cifree_goya_device:
105862306a36Sopenharmony_ci	kfree(goya);
105962306a36Sopenharmony_ci
106062306a36Sopenharmony_ci	return rc;
106162306a36Sopenharmony_ci}
106262306a36Sopenharmony_ci
106362306a36Sopenharmony_ci/*
106462306a36Sopenharmony_ci * goya_sw_fini - Goya software tear-down code
106562306a36Sopenharmony_ci *
106662306a36Sopenharmony_ci * @hdev: pointer to hl_device structure
106762306a36Sopenharmony_ci *
106862306a36Sopenharmony_ci */
106962306a36Sopenharmony_cistatic int goya_sw_fini(struct hl_device *hdev)
107062306a36Sopenharmony_ci{
107162306a36Sopenharmony_ci	struct goya_device *goya = hdev->asic_specific;
107262306a36Sopenharmony_ci
107362306a36Sopenharmony_ci	gen_pool_destroy(hdev->cpu_accessible_dma_pool);
107462306a36Sopenharmony_ci
107562306a36Sopenharmony_ci	hl_asic_dma_free_coherent(hdev, HL_CPU_ACCESSIBLE_MEM_SIZE, hdev->cpu_accessible_dma_mem,
107662306a36Sopenharmony_ci					hdev->cpu_accessible_dma_address);
107762306a36Sopenharmony_ci
107862306a36Sopenharmony_ci	dma_pool_destroy(hdev->dma_pool);
107962306a36Sopenharmony_ci
108062306a36Sopenharmony_ci	kfree(goya->goya_work);
108162306a36Sopenharmony_ci	kfree(goya);
108262306a36Sopenharmony_ci
108362306a36Sopenharmony_ci	return 0;
108462306a36Sopenharmony_ci}
108562306a36Sopenharmony_ci
108662306a36Sopenharmony_cistatic void goya_init_dma_qman(struct hl_device *hdev, int dma_id,
108762306a36Sopenharmony_ci		dma_addr_t bus_address)
108862306a36Sopenharmony_ci{
108962306a36Sopenharmony_ci	struct goya_device *goya = hdev->asic_specific;
109062306a36Sopenharmony_ci	u32 mtr_base_lo, mtr_base_hi;
109162306a36Sopenharmony_ci	u32 so_base_lo, so_base_hi;
109262306a36Sopenharmony_ci	u32 gic_base_lo, gic_base_hi;
109362306a36Sopenharmony_ci	u32 reg_off = dma_id * (mmDMA_QM_1_PQ_PI - mmDMA_QM_0_PQ_PI);
109462306a36Sopenharmony_ci	u32 dma_err_cfg = QMAN_DMA_ERR_MSG_EN;
109562306a36Sopenharmony_ci
109662306a36Sopenharmony_ci	mtr_base_lo = lower_32_bits(CFG_BASE + mmSYNC_MNGR_MON_PAY_ADDRL_0);
109762306a36Sopenharmony_ci	mtr_base_hi = upper_32_bits(CFG_BASE + mmSYNC_MNGR_MON_PAY_ADDRL_0);
109862306a36Sopenharmony_ci	so_base_lo = lower_32_bits(CFG_BASE + mmSYNC_MNGR_SOB_OBJ_0);
109962306a36Sopenharmony_ci	so_base_hi = upper_32_bits(CFG_BASE + mmSYNC_MNGR_SOB_OBJ_0);
110062306a36Sopenharmony_ci
110162306a36Sopenharmony_ci	gic_base_lo =
110262306a36Sopenharmony_ci		lower_32_bits(CFG_BASE + mmGIC_DISTRIBUTOR__5_GICD_SETSPI_NSR);
110362306a36Sopenharmony_ci	gic_base_hi =
110462306a36Sopenharmony_ci		upper_32_bits(CFG_BASE + mmGIC_DISTRIBUTOR__5_GICD_SETSPI_NSR);
110562306a36Sopenharmony_ci
110662306a36Sopenharmony_ci	WREG32(mmDMA_QM_0_PQ_BASE_LO + reg_off, lower_32_bits(bus_address));
110762306a36Sopenharmony_ci	WREG32(mmDMA_QM_0_PQ_BASE_HI + reg_off, upper_32_bits(bus_address));
110862306a36Sopenharmony_ci
110962306a36Sopenharmony_ci	WREG32(mmDMA_QM_0_PQ_SIZE + reg_off, ilog2(HL_QUEUE_LENGTH));
111062306a36Sopenharmony_ci	WREG32(mmDMA_QM_0_PQ_PI + reg_off, 0);
111162306a36Sopenharmony_ci	WREG32(mmDMA_QM_0_PQ_CI + reg_off, 0);
111262306a36Sopenharmony_ci
111362306a36Sopenharmony_ci	WREG32(mmDMA_QM_0_CP_MSG_BASE0_ADDR_LO + reg_off, mtr_base_lo);
111462306a36Sopenharmony_ci	WREG32(mmDMA_QM_0_CP_MSG_BASE0_ADDR_HI + reg_off, mtr_base_hi);
111562306a36Sopenharmony_ci	WREG32(mmDMA_QM_0_CP_MSG_BASE1_ADDR_LO + reg_off, so_base_lo);
111662306a36Sopenharmony_ci	WREG32(mmDMA_QM_0_CP_MSG_BASE1_ADDR_HI + reg_off, so_base_hi);
111762306a36Sopenharmony_ci	WREG32(mmDMA_QM_0_GLBL_ERR_ADDR_LO + reg_off, gic_base_lo);
111862306a36Sopenharmony_ci	WREG32(mmDMA_QM_0_GLBL_ERR_ADDR_HI + reg_off, gic_base_hi);
111962306a36Sopenharmony_ci	WREG32(mmDMA_QM_0_GLBL_ERR_WDATA + reg_off,
112062306a36Sopenharmony_ci			GOYA_ASYNC_EVENT_ID_DMA0_QM + dma_id);
112162306a36Sopenharmony_ci
112262306a36Sopenharmony_ci	/* PQ has buffer of 2 cache lines, while CQ has 8 lines */
112362306a36Sopenharmony_ci	WREG32(mmDMA_QM_0_PQ_CFG1 + reg_off, 0x00020002);
112462306a36Sopenharmony_ci	WREG32(mmDMA_QM_0_CQ_CFG1 + reg_off, 0x00080008);
112562306a36Sopenharmony_ci
112662306a36Sopenharmony_ci	if (goya->hw_cap_initialized & HW_CAP_MMU)
112762306a36Sopenharmony_ci		WREG32(mmDMA_QM_0_GLBL_PROT + reg_off, QMAN_DMA_PARTLY_TRUSTED);
112862306a36Sopenharmony_ci	else
112962306a36Sopenharmony_ci		WREG32(mmDMA_QM_0_GLBL_PROT + reg_off, QMAN_DMA_FULLY_TRUSTED);
113062306a36Sopenharmony_ci
113162306a36Sopenharmony_ci	if (hdev->stop_on_err)
113262306a36Sopenharmony_ci		dma_err_cfg |= 1 << DMA_QM_0_GLBL_ERR_CFG_DMA_STOP_ON_ERR_SHIFT;
113362306a36Sopenharmony_ci
113462306a36Sopenharmony_ci	WREG32(mmDMA_QM_0_GLBL_ERR_CFG + reg_off, dma_err_cfg);
113562306a36Sopenharmony_ci	WREG32(mmDMA_QM_0_GLBL_CFG0 + reg_off, QMAN_DMA_ENABLE);
113662306a36Sopenharmony_ci}
113762306a36Sopenharmony_ci
113862306a36Sopenharmony_cistatic void goya_init_dma_ch(struct hl_device *hdev, int dma_id)
113962306a36Sopenharmony_ci{
114062306a36Sopenharmony_ci	u32 gic_base_lo, gic_base_hi;
114162306a36Sopenharmony_ci	u64 sob_addr;
114262306a36Sopenharmony_ci	u32 reg_off = dma_id * (mmDMA_CH_1_CFG1 - mmDMA_CH_0_CFG1);
114362306a36Sopenharmony_ci
114462306a36Sopenharmony_ci	gic_base_lo =
114562306a36Sopenharmony_ci		lower_32_bits(CFG_BASE + mmGIC_DISTRIBUTOR__5_GICD_SETSPI_NSR);
114662306a36Sopenharmony_ci	gic_base_hi =
114762306a36Sopenharmony_ci		upper_32_bits(CFG_BASE + mmGIC_DISTRIBUTOR__5_GICD_SETSPI_NSR);
114862306a36Sopenharmony_ci
114962306a36Sopenharmony_ci	WREG32(mmDMA_CH_0_ERRMSG_ADDR_LO + reg_off, gic_base_lo);
115062306a36Sopenharmony_ci	WREG32(mmDMA_CH_0_ERRMSG_ADDR_HI + reg_off, gic_base_hi);
115162306a36Sopenharmony_ci	WREG32(mmDMA_CH_0_ERRMSG_WDATA + reg_off,
115262306a36Sopenharmony_ci			GOYA_ASYNC_EVENT_ID_DMA0_CH + dma_id);
115362306a36Sopenharmony_ci
115462306a36Sopenharmony_ci	if (dma_id)
115562306a36Sopenharmony_ci		sob_addr = CFG_BASE + mmSYNC_MNGR_SOB_OBJ_1000 +
115662306a36Sopenharmony_ci				(dma_id - 1) * 4;
115762306a36Sopenharmony_ci	else
115862306a36Sopenharmony_ci		sob_addr = CFG_BASE + mmSYNC_MNGR_SOB_OBJ_1007;
115962306a36Sopenharmony_ci
116062306a36Sopenharmony_ci	WREG32(mmDMA_CH_0_WR_COMP_ADDR_HI + reg_off, upper_32_bits(sob_addr));
116162306a36Sopenharmony_ci	WREG32(mmDMA_CH_0_WR_COMP_WDATA + reg_off, 0x80000001);
116262306a36Sopenharmony_ci}
116362306a36Sopenharmony_ci
116462306a36Sopenharmony_ci/*
116562306a36Sopenharmony_ci * goya_init_dma_qmans - Initialize QMAN DMA registers
116662306a36Sopenharmony_ci *
116762306a36Sopenharmony_ci * @hdev: pointer to hl_device structure
116862306a36Sopenharmony_ci *
116962306a36Sopenharmony_ci * Initialize the H/W registers of the QMAN DMA channels
117062306a36Sopenharmony_ci *
117162306a36Sopenharmony_ci */
117262306a36Sopenharmony_civoid goya_init_dma_qmans(struct hl_device *hdev)
117362306a36Sopenharmony_ci{
117462306a36Sopenharmony_ci	struct goya_device *goya = hdev->asic_specific;
117562306a36Sopenharmony_ci	struct hl_hw_queue *q;
117662306a36Sopenharmony_ci	int i;
117762306a36Sopenharmony_ci
117862306a36Sopenharmony_ci	if (goya->hw_cap_initialized & HW_CAP_DMA)
117962306a36Sopenharmony_ci		return;
118062306a36Sopenharmony_ci
118162306a36Sopenharmony_ci	q = &hdev->kernel_queues[0];
118262306a36Sopenharmony_ci
118362306a36Sopenharmony_ci	for (i = 0 ; i < NUMBER_OF_EXT_HW_QUEUES ; i++, q++) {
118462306a36Sopenharmony_ci		q->cq_id = q->msi_vec = i;
118562306a36Sopenharmony_ci		goya_init_dma_qman(hdev, i, q->bus_address);
118662306a36Sopenharmony_ci		goya_init_dma_ch(hdev, i);
118762306a36Sopenharmony_ci	}
118862306a36Sopenharmony_ci
118962306a36Sopenharmony_ci	goya->hw_cap_initialized |= HW_CAP_DMA;
119062306a36Sopenharmony_ci}
119162306a36Sopenharmony_ci
119262306a36Sopenharmony_ci/*
119362306a36Sopenharmony_ci * goya_disable_external_queues - Disable external queues
119462306a36Sopenharmony_ci *
119562306a36Sopenharmony_ci * @hdev: pointer to hl_device structure
119662306a36Sopenharmony_ci *
119762306a36Sopenharmony_ci */
119862306a36Sopenharmony_cistatic void goya_disable_external_queues(struct hl_device *hdev)
119962306a36Sopenharmony_ci{
120062306a36Sopenharmony_ci	struct goya_device *goya = hdev->asic_specific;
120162306a36Sopenharmony_ci
120262306a36Sopenharmony_ci	if (!(goya->hw_cap_initialized & HW_CAP_DMA))
120362306a36Sopenharmony_ci		return;
120462306a36Sopenharmony_ci
120562306a36Sopenharmony_ci	WREG32(mmDMA_QM_0_GLBL_CFG0, 0);
120662306a36Sopenharmony_ci	WREG32(mmDMA_QM_1_GLBL_CFG0, 0);
120762306a36Sopenharmony_ci	WREG32(mmDMA_QM_2_GLBL_CFG0, 0);
120862306a36Sopenharmony_ci	WREG32(mmDMA_QM_3_GLBL_CFG0, 0);
120962306a36Sopenharmony_ci	WREG32(mmDMA_QM_4_GLBL_CFG0, 0);
121062306a36Sopenharmony_ci}
121162306a36Sopenharmony_ci
121262306a36Sopenharmony_cistatic int goya_stop_queue(struct hl_device *hdev, u32 cfg_reg,
121362306a36Sopenharmony_ci				u32 cp_sts_reg, u32 glbl_sts0_reg)
121462306a36Sopenharmony_ci{
121562306a36Sopenharmony_ci	int rc;
121662306a36Sopenharmony_ci	u32 status;
121762306a36Sopenharmony_ci
121862306a36Sopenharmony_ci	/* use the values of TPC0 as they are all the same*/
121962306a36Sopenharmony_ci
122062306a36Sopenharmony_ci	WREG32(cfg_reg, 1 << TPC0_QM_GLBL_CFG1_CP_STOP_SHIFT);
122162306a36Sopenharmony_ci
122262306a36Sopenharmony_ci	status = RREG32(cp_sts_reg);
122362306a36Sopenharmony_ci	if (status & TPC0_QM_CP_STS_FENCE_IN_PROGRESS_MASK) {
122462306a36Sopenharmony_ci		rc = hl_poll_timeout(
122562306a36Sopenharmony_ci			hdev,
122662306a36Sopenharmony_ci			cp_sts_reg,
122762306a36Sopenharmony_ci			status,
122862306a36Sopenharmony_ci			!(status & TPC0_QM_CP_STS_FENCE_IN_PROGRESS_MASK),
122962306a36Sopenharmony_ci			1000,
123062306a36Sopenharmony_ci			QMAN_FENCE_TIMEOUT_USEC);
123162306a36Sopenharmony_ci
123262306a36Sopenharmony_ci		/* if QMAN is stuck in fence no need to check for stop */
123362306a36Sopenharmony_ci		if (rc)
123462306a36Sopenharmony_ci			return 0;
123562306a36Sopenharmony_ci	}
123662306a36Sopenharmony_ci
123762306a36Sopenharmony_ci	rc = hl_poll_timeout(
123862306a36Sopenharmony_ci		hdev,
123962306a36Sopenharmony_ci		glbl_sts0_reg,
124062306a36Sopenharmony_ci		status,
124162306a36Sopenharmony_ci		(status & TPC0_QM_GLBL_STS0_CP_IS_STOP_MASK),
124262306a36Sopenharmony_ci		1000,
124362306a36Sopenharmony_ci		QMAN_STOP_TIMEOUT_USEC);
124462306a36Sopenharmony_ci
124562306a36Sopenharmony_ci	if (rc) {
124662306a36Sopenharmony_ci		dev_err(hdev->dev,
124762306a36Sopenharmony_ci			"Timeout while waiting for QMAN to stop\n");
124862306a36Sopenharmony_ci		return -EINVAL;
124962306a36Sopenharmony_ci	}
125062306a36Sopenharmony_ci
125162306a36Sopenharmony_ci	return 0;
125262306a36Sopenharmony_ci}
125362306a36Sopenharmony_ci
125462306a36Sopenharmony_ci/*
125562306a36Sopenharmony_ci * goya_stop_external_queues - Stop external queues
125662306a36Sopenharmony_ci *
125762306a36Sopenharmony_ci * @hdev: pointer to hl_device structure
125862306a36Sopenharmony_ci *
125962306a36Sopenharmony_ci * Returns 0 on success
126062306a36Sopenharmony_ci *
126162306a36Sopenharmony_ci */
126262306a36Sopenharmony_cistatic int goya_stop_external_queues(struct hl_device *hdev)
126362306a36Sopenharmony_ci{
126462306a36Sopenharmony_ci	int rc, retval = 0;
126562306a36Sopenharmony_ci
126662306a36Sopenharmony_ci	struct goya_device *goya = hdev->asic_specific;
126762306a36Sopenharmony_ci
126862306a36Sopenharmony_ci	if (!(goya->hw_cap_initialized & HW_CAP_DMA))
126962306a36Sopenharmony_ci		return retval;
127062306a36Sopenharmony_ci
127162306a36Sopenharmony_ci	rc = goya_stop_queue(hdev,
127262306a36Sopenharmony_ci			mmDMA_QM_0_GLBL_CFG1,
127362306a36Sopenharmony_ci			mmDMA_QM_0_CP_STS,
127462306a36Sopenharmony_ci			mmDMA_QM_0_GLBL_STS0);
127562306a36Sopenharmony_ci
127662306a36Sopenharmony_ci	if (rc) {
127762306a36Sopenharmony_ci		dev_err(hdev->dev, "failed to stop DMA QMAN 0\n");
127862306a36Sopenharmony_ci		retval = -EIO;
127962306a36Sopenharmony_ci	}
128062306a36Sopenharmony_ci
128162306a36Sopenharmony_ci	rc = goya_stop_queue(hdev,
128262306a36Sopenharmony_ci			mmDMA_QM_1_GLBL_CFG1,
128362306a36Sopenharmony_ci			mmDMA_QM_1_CP_STS,
128462306a36Sopenharmony_ci			mmDMA_QM_1_GLBL_STS0);
128562306a36Sopenharmony_ci
128662306a36Sopenharmony_ci	if (rc) {
128762306a36Sopenharmony_ci		dev_err(hdev->dev, "failed to stop DMA QMAN 1\n");
128862306a36Sopenharmony_ci		retval = -EIO;
128962306a36Sopenharmony_ci	}
129062306a36Sopenharmony_ci
129162306a36Sopenharmony_ci	rc = goya_stop_queue(hdev,
129262306a36Sopenharmony_ci			mmDMA_QM_2_GLBL_CFG1,
129362306a36Sopenharmony_ci			mmDMA_QM_2_CP_STS,
129462306a36Sopenharmony_ci			mmDMA_QM_2_GLBL_STS0);
129562306a36Sopenharmony_ci
129662306a36Sopenharmony_ci	if (rc) {
129762306a36Sopenharmony_ci		dev_err(hdev->dev, "failed to stop DMA QMAN 2\n");
129862306a36Sopenharmony_ci		retval = -EIO;
129962306a36Sopenharmony_ci	}
130062306a36Sopenharmony_ci
130162306a36Sopenharmony_ci	rc = goya_stop_queue(hdev,
130262306a36Sopenharmony_ci			mmDMA_QM_3_GLBL_CFG1,
130362306a36Sopenharmony_ci			mmDMA_QM_3_CP_STS,
130462306a36Sopenharmony_ci			mmDMA_QM_3_GLBL_STS0);
130562306a36Sopenharmony_ci
130662306a36Sopenharmony_ci	if (rc) {
130762306a36Sopenharmony_ci		dev_err(hdev->dev, "failed to stop DMA QMAN 3\n");
130862306a36Sopenharmony_ci		retval = -EIO;
130962306a36Sopenharmony_ci	}
131062306a36Sopenharmony_ci
131162306a36Sopenharmony_ci	rc = goya_stop_queue(hdev,
131262306a36Sopenharmony_ci			mmDMA_QM_4_GLBL_CFG1,
131362306a36Sopenharmony_ci			mmDMA_QM_4_CP_STS,
131462306a36Sopenharmony_ci			mmDMA_QM_4_GLBL_STS0);
131562306a36Sopenharmony_ci
131662306a36Sopenharmony_ci	if (rc) {
131762306a36Sopenharmony_ci		dev_err(hdev->dev, "failed to stop DMA QMAN 4\n");
131862306a36Sopenharmony_ci		retval = -EIO;
131962306a36Sopenharmony_ci	}
132062306a36Sopenharmony_ci
132162306a36Sopenharmony_ci	return retval;
132262306a36Sopenharmony_ci}
132362306a36Sopenharmony_ci
132462306a36Sopenharmony_ci/*
132562306a36Sopenharmony_ci * goya_init_cpu_queues - Initialize PQ/CQ/EQ of CPU
132662306a36Sopenharmony_ci *
132762306a36Sopenharmony_ci * @hdev: pointer to hl_device structure
132862306a36Sopenharmony_ci *
132962306a36Sopenharmony_ci * Returns 0 on success
133062306a36Sopenharmony_ci *
133162306a36Sopenharmony_ci */
133262306a36Sopenharmony_ciint goya_init_cpu_queues(struct hl_device *hdev)
133362306a36Sopenharmony_ci{
133462306a36Sopenharmony_ci	struct goya_device *goya = hdev->asic_specific;
133562306a36Sopenharmony_ci	struct asic_fixed_properties *prop = &hdev->asic_prop;
133662306a36Sopenharmony_ci	struct hl_eq *eq;
133762306a36Sopenharmony_ci	u32 status;
133862306a36Sopenharmony_ci	struct hl_hw_queue *cpu_pq = &hdev->kernel_queues[GOYA_QUEUE_ID_CPU_PQ];
133962306a36Sopenharmony_ci	int err;
134062306a36Sopenharmony_ci
134162306a36Sopenharmony_ci	if (!hdev->cpu_queues_enable)
134262306a36Sopenharmony_ci		return 0;
134362306a36Sopenharmony_ci
134462306a36Sopenharmony_ci	if (goya->hw_cap_initialized & HW_CAP_CPU_Q)
134562306a36Sopenharmony_ci		return 0;
134662306a36Sopenharmony_ci
134762306a36Sopenharmony_ci	eq = &hdev->event_queue;
134862306a36Sopenharmony_ci
134962306a36Sopenharmony_ci	WREG32(mmCPU_PQ_BASE_ADDR_LOW, lower_32_bits(cpu_pq->bus_address));
135062306a36Sopenharmony_ci	WREG32(mmCPU_PQ_BASE_ADDR_HIGH, upper_32_bits(cpu_pq->bus_address));
135162306a36Sopenharmony_ci
135262306a36Sopenharmony_ci	WREG32(mmCPU_EQ_BASE_ADDR_LOW, lower_32_bits(eq->bus_address));
135362306a36Sopenharmony_ci	WREG32(mmCPU_EQ_BASE_ADDR_HIGH, upper_32_bits(eq->bus_address));
135462306a36Sopenharmony_ci
135562306a36Sopenharmony_ci	WREG32(mmCPU_CQ_BASE_ADDR_LOW,
135662306a36Sopenharmony_ci			lower_32_bits(VA_CPU_ACCESSIBLE_MEM_ADDR));
135762306a36Sopenharmony_ci	WREG32(mmCPU_CQ_BASE_ADDR_HIGH,
135862306a36Sopenharmony_ci			upper_32_bits(VA_CPU_ACCESSIBLE_MEM_ADDR));
135962306a36Sopenharmony_ci
136062306a36Sopenharmony_ci	WREG32(mmCPU_PQ_LENGTH, HL_QUEUE_SIZE_IN_BYTES);
136162306a36Sopenharmony_ci	WREG32(mmCPU_EQ_LENGTH, HL_EQ_SIZE_IN_BYTES);
136262306a36Sopenharmony_ci	WREG32(mmCPU_CQ_LENGTH, HL_CPU_ACCESSIBLE_MEM_SIZE);
136362306a36Sopenharmony_ci
136462306a36Sopenharmony_ci	/* Used for EQ CI */
136562306a36Sopenharmony_ci	WREG32(mmCPU_EQ_CI, 0);
136662306a36Sopenharmony_ci
136762306a36Sopenharmony_ci	WREG32(mmCPU_IF_PF_PQ_PI, 0);
136862306a36Sopenharmony_ci
136962306a36Sopenharmony_ci	WREG32(mmCPU_PQ_INIT_STATUS, PQ_INIT_STATUS_READY_FOR_CP);
137062306a36Sopenharmony_ci
137162306a36Sopenharmony_ci	WREG32(mmGIC_DISTRIBUTOR__5_GICD_SETSPI_NSR,
137262306a36Sopenharmony_ci			GOYA_ASYNC_EVENT_ID_PI_UPDATE);
137362306a36Sopenharmony_ci
137462306a36Sopenharmony_ci	err = hl_poll_timeout(
137562306a36Sopenharmony_ci		hdev,
137662306a36Sopenharmony_ci		mmCPU_PQ_INIT_STATUS,
137762306a36Sopenharmony_ci		status,
137862306a36Sopenharmony_ci		(status == PQ_INIT_STATUS_READY_FOR_HOST),
137962306a36Sopenharmony_ci		1000,
138062306a36Sopenharmony_ci		GOYA_CPU_TIMEOUT_USEC);
138162306a36Sopenharmony_ci
138262306a36Sopenharmony_ci	if (err) {
138362306a36Sopenharmony_ci		dev_err(hdev->dev,
138462306a36Sopenharmony_ci			"Failed to setup communication with device CPU\n");
138562306a36Sopenharmony_ci		return -EIO;
138662306a36Sopenharmony_ci	}
138762306a36Sopenharmony_ci
138862306a36Sopenharmony_ci	/* update FW application security bits */
138962306a36Sopenharmony_ci	if (prop->fw_cpu_boot_dev_sts0_valid)
139062306a36Sopenharmony_ci		prop->fw_app_cpu_boot_dev_sts0 = RREG32(mmCPU_BOOT_DEV_STS0);
139162306a36Sopenharmony_ci
139262306a36Sopenharmony_ci	if (prop->fw_cpu_boot_dev_sts1_valid)
139362306a36Sopenharmony_ci		prop->fw_app_cpu_boot_dev_sts1 = RREG32(mmCPU_BOOT_DEV_STS1);
139462306a36Sopenharmony_ci
139562306a36Sopenharmony_ci	goya->hw_cap_initialized |= HW_CAP_CPU_Q;
139662306a36Sopenharmony_ci	return 0;
139762306a36Sopenharmony_ci}
139862306a36Sopenharmony_ci
139962306a36Sopenharmony_cistatic void goya_set_pll_refclk(struct hl_device *hdev)
140062306a36Sopenharmony_ci{
140162306a36Sopenharmony_ci	WREG32(mmCPU_PLL_DIV_SEL_0, 0x0);
140262306a36Sopenharmony_ci	WREG32(mmCPU_PLL_DIV_SEL_1, 0x0);
140362306a36Sopenharmony_ci	WREG32(mmCPU_PLL_DIV_SEL_2, 0x0);
140462306a36Sopenharmony_ci	WREG32(mmCPU_PLL_DIV_SEL_3, 0x0);
140562306a36Sopenharmony_ci
140662306a36Sopenharmony_ci	WREG32(mmIC_PLL_DIV_SEL_0, 0x0);
140762306a36Sopenharmony_ci	WREG32(mmIC_PLL_DIV_SEL_1, 0x0);
140862306a36Sopenharmony_ci	WREG32(mmIC_PLL_DIV_SEL_2, 0x0);
140962306a36Sopenharmony_ci	WREG32(mmIC_PLL_DIV_SEL_3, 0x0);
141062306a36Sopenharmony_ci
141162306a36Sopenharmony_ci	WREG32(mmMC_PLL_DIV_SEL_0, 0x0);
141262306a36Sopenharmony_ci	WREG32(mmMC_PLL_DIV_SEL_1, 0x0);
141362306a36Sopenharmony_ci	WREG32(mmMC_PLL_DIV_SEL_2, 0x0);
141462306a36Sopenharmony_ci	WREG32(mmMC_PLL_DIV_SEL_3, 0x0);
141562306a36Sopenharmony_ci
141662306a36Sopenharmony_ci	WREG32(mmPSOC_MME_PLL_DIV_SEL_0, 0x0);
141762306a36Sopenharmony_ci	WREG32(mmPSOC_MME_PLL_DIV_SEL_1, 0x0);
141862306a36Sopenharmony_ci	WREG32(mmPSOC_MME_PLL_DIV_SEL_2, 0x0);
141962306a36Sopenharmony_ci	WREG32(mmPSOC_MME_PLL_DIV_SEL_3, 0x0);
142062306a36Sopenharmony_ci
142162306a36Sopenharmony_ci	WREG32(mmPSOC_PCI_PLL_DIV_SEL_0, 0x0);
142262306a36Sopenharmony_ci	WREG32(mmPSOC_PCI_PLL_DIV_SEL_1, 0x0);
142362306a36Sopenharmony_ci	WREG32(mmPSOC_PCI_PLL_DIV_SEL_2, 0x0);
142462306a36Sopenharmony_ci	WREG32(mmPSOC_PCI_PLL_DIV_SEL_3, 0x0);
142562306a36Sopenharmony_ci
142662306a36Sopenharmony_ci	WREG32(mmPSOC_EMMC_PLL_DIV_SEL_0, 0x0);
142762306a36Sopenharmony_ci	WREG32(mmPSOC_EMMC_PLL_DIV_SEL_1, 0x0);
142862306a36Sopenharmony_ci	WREG32(mmPSOC_EMMC_PLL_DIV_SEL_2, 0x0);
142962306a36Sopenharmony_ci	WREG32(mmPSOC_EMMC_PLL_DIV_SEL_3, 0x0);
143062306a36Sopenharmony_ci
143162306a36Sopenharmony_ci	WREG32(mmTPC_PLL_DIV_SEL_0, 0x0);
143262306a36Sopenharmony_ci	WREG32(mmTPC_PLL_DIV_SEL_1, 0x0);
143362306a36Sopenharmony_ci	WREG32(mmTPC_PLL_DIV_SEL_2, 0x0);
143462306a36Sopenharmony_ci	WREG32(mmTPC_PLL_DIV_SEL_3, 0x0);
143562306a36Sopenharmony_ci}
143662306a36Sopenharmony_ci
143762306a36Sopenharmony_cistatic void goya_disable_clk_rlx(struct hl_device *hdev)
143862306a36Sopenharmony_ci{
143962306a36Sopenharmony_ci	WREG32(mmPSOC_MME_PLL_CLK_RLX_0, 0x100010);
144062306a36Sopenharmony_ci	WREG32(mmIC_PLL_CLK_RLX_0, 0x100010);
144162306a36Sopenharmony_ci}
144262306a36Sopenharmony_ci
144362306a36Sopenharmony_cistatic void _goya_tpc_mbist_workaround(struct hl_device *hdev, u8 tpc_id)
144462306a36Sopenharmony_ci{
144562306a36Sopenharmony_ci	u64 tpc_eml_address;
144662306a36Sopenharmony_ci	u32 val, tpc_offset, tpc_eml_offset, tpc_slm_offset;
144762306a36Sopenharmony_ci	int err, slm_index;
144862306a36Sopenharmony_ci
144962306a36Sopenharmony_ci	tpc_offset = tpc_id * 0x40000;
145062306a36Sopenharmony_ci	tpc_eml_offset = tpc_id * 0x200000;
145162306a36Sopenharmony_ci	tpc_eml_address = (mmTPC0_EML_CFG_BASE + tpc_eml_offset - CFG_BASE);
145262306a36Sopenharmony_ci	tpc_slm_offset = tpc_eml_address + 0x100000;
145362306a36Sopenharmony_ci
145462306a36Sopenharmony_ci	/*
145562306a36Sopenharmony_ci	 * Workaround for Bug H2 #2443 :
145662306a36Sopenharmony_ci	 * "TPC SB is not initialized on chip reset"
145762306a36Sopenharmony_ci	 */
145862306a36Sopenharmony_ci
145962306a36Sopenharmony_ci	val = RREG32(mmTPC0_CFG_FUNC_MBIST_CNTRL + tpc_offset);
146062306a36Sopenharmony_ci	if (val & TPC0_CFG_FUNC_MBIST_CNTRL_MBIST_ACTIVE_MASK)
146162306a36Sopenharmony_ci		dev_warn(hdev->dev, "TPC%d MBIST ACTIVE is not cleared\n",
146262306a36Sopenharmony_ci			tpc_id);
146362306a36Sopenharmony_ci
146462306a36Sopenharmony_ci	WREG32(mmTPC0_CFG_FUNC_MBIST_PAT + tpc_offset, val & 0xFFFFF000);
146562306a36Sopenharmony_ci
146662306a36Sopenharmony_ci	WREG32(mmTPC0_CFG_FUNC_MBIST_MEM_0 + tpc_offset, 0x37FF);
146762306a36Sopenharmony_ci	WREG32(mmTPC0_CFG_FUNC_MBIST_MEM_1 + tpc_offset, 0x303F);
146862306a36Sopenharmony_ci	WREG32(mmTPC0_CFG_FUNC_MBIST_MEM_2 + tpc_offset, 0x71FF);
146962306a36Sopenharmony_ci	WREG32(mmTPC0_CFG_FUNC_MBIST_MEM_3 + tpc_offset, 0x71FF);
147062306a36Sopenharmony_ci	WREG32(mmTPC0_CFG_FUNC_MBIST_MEM_4 + tpc_offset, 0x70FF);
147162306a36Sopenharmony_ci	WREG32(mmTPC0_CFG_FUNC_MBIST_MEM_5 + tpc_offset, 0x70FF);
147262306a36Sopenharmony_ci	WREG32(mmTPC0_CFG_FUNC_MBIST_MEM_6 + tpc_offset, 0x70FF);
147362306a36Sopenharmony_ci	WREG32(mmTPC0_CFG_FUNC_MBIST_MEM_7 + tpc_offset, 0x70FF);
147462306a36Sopenharmony_ci	WREG32(mmTPC0_CFG_FUNC_MBIST_MEM_8 + tpc_offset, 0x70FF);
147562306a36Sopenharmony_ci	WREG32(mmTPC0_CFG_FUNC_MBIST_MEM_9 + tpc_offset, 0x70FF);
147662306a36Sopenharmony_ci
147762306a36Sopenharmony_ci	WREG32_OR(mmTPC0_CFG_FUNC_MBIST_CNTRL + tpc_offset,
147862306a36Sopenharmony_ci		1 << TPC0_CFG_FUNC_MBIST_CNTRL_MBIST_START_SHIFT);
147962306a36Sopenharmony_ci
148062306a36Sopenharmony_ci	err = hl_poll_timeout(
148162306a36Sopenharmony_ci		hdev,
148262306a36Sopenharmony_ci		mmTPC0_CFG_FUNC_MBIST_CNTRL + tpc_offset,
148362306a36Sopenharmony_ci		val,
148462306a36Sopenharmony_ci		(val & TPC0_CFG_FUNC_MBIST_CNTRL_MBIST_DONE_MASK),
148562306a36Sopenharmony_ci		1000,
148662306a36Sopenharmony_ci		HL_DEVICE_TIMEOUT_USEC);
148762306a36Sopenharmony_ci
148862306a36Sopenharmony_ci	if (err)
148962306a36Sopenharmony_ci		dev_err(hdev->dev,
149062306a36Sopenharmony_ci			"Timeout while waiting for TPC%d MBIST DONE\n", tpc_id);
149162306a36Sopenharmony_ci
149262306a36Sopenharmony_ci	WREG32_OR(mmTPC0_EML_CFG_DBG_CNT + tpc_eml_offset,
149362306a36Sopenharmony_ci		1 << TPC0_EML_CFG_DBG_CNT_CORE_RST_SHIFT);
149462306a36Sopenharmony_ci
149562306a36Sopenharmony_ci	msleep(GOYA_RESET_WAIT_MSEC);
149662306a36Sopenharmony_ci
149762306a36Sopenharmony_ci	WREG32_AND(mmTPC0_EML_CFG_DBG_CNT + tpc_eml_offset,
149862306a36Sopenharmony_ci		~(1 << TPC0_EML_CFG_DBG_CNT_CORE_RST_SHIFT));
149962306a36Sopenharmony_ci
150062306a36Sopenharmony_ci	msleep(GOYA_RESET_WAIT_MSEC);
150162306a36Sopenharmony_ci
150262306a36Sopenharmony_ci	for (slm_index = 0 ; slm_index < 256 ; slm_index++)
150362306a36Sopenharmony_ci		WREG32(tpc_slm_offset + (slm_index << 2), 0);
150462306a36Sopenharmony_ci
150562306a36Sopenharmony_ci	val = RREG32(tpc_slm_offset);
150662306a36Sopenharmony_ci}
150762306a36Sopenharmony_ci
150862306a36Sopenharmony_cistatic void goya_tpc_mbist_workaround(struct hl_device *hdev)
150962306a36Sopenharmony_ci{
151062306a36Sopenharmony_ci	struct goya_device *goya = hdev->asic_specific;
151162306a36Sopenharmony_ci	int i;
151262306a36Sopenharmony_ci
151362306a36Sopenharmony_ci	if (hdev->pldm)
151462306a36Sopenharmony_ci		return;
151562306a36Sopenharmony_ci
151662306a36Sopenharmony_ci	if (goya->hw_cap_initialized & HW_CAP_TPC_MBIST)
151762306a36Sopenharmony_ci		return;
151862306a36Sopenharmony_ci
151962306a36Sopenharmony_ci	/* Workaround for H2 #2443 */
152062306a36Sopenharmony_ci
152162306a36Sopenharmony_ci	for (i = 0 ; i < TPC_MAX_NUM ; i++)
152262306a36Sopenharmony_ci		_goya_tpc_mbist_workaround(hdev, i);
152362306a36Sopenharmony_ci
152462306a36Sopenharmony_ci	goya->hw_cap_initialized |= HW_CAP_TPC_MBIST;
152562306a36Sopenharmony_ci}
152662306a36Sopenharmony_ci
152762306a36Sopenharmony_ci/*
152862306a36Sopenharmony_ci * goya_init_golden_registers - Initialize golden registers
152962306a36Sopenharmony_ci *
153062306a36Sopenharmony_ci * @hdev: pointer to hl_device structure
153162306a36Sopenharmony_ci *
153262306a36Sopenharmony_ci * Initialize the H/W registers of the device
153362306a36Sopenharmony_ci *
153462306a36Sopenharmony_ci */
153562306a36Sopenharmony_cistatic void goya_init_golden_registers(struct hl_device *hdev)
153662306a36Sopenharmony_ci{
153762306a36Sopenharmony_ci	struct goya_device *goya = hdev->asic_specific;
153862306a36Sopenharmony_ci	u32 polynom[10], tpc_intr_mask, offset;
153962306a36Sopenharmony_ci	int i;
154062306a36Sopenharmony_ci
154162306a36Sopenharmony_ci	if (goya->hw_cap_initialized & HW_CAP_GOLDEN)
154262306a36Sopenharmony_ci		return;
154362306a36Sopenharmony_ci
154462306a36Sopenharmony_ci	polynom[0] = 0x00020080;
154562306a36Sopenharmony_ci	polynom[1] = 0x00401000;
154662306a36Sopenharmony_ci	polynom[2] = 0x00200800;
154762306a36Sopenharmony_ci	polynom[3] = 0x00002000;
154862306a36Sopenharmony_ci	polynom[4] = 0x00080200;
154962306a36Sopenharmony_ci	polynom[5] = 0x00040100;
155062306a36Sopenharmony_ci	polynom[6] = 0x00100400;
155162306a36Sopenharmony_ci	polynom[7] = 0x00004000;
155262306a36Sopenharmony_ci	polynom[8] = 0x00010000;
155362306a36Sopenharmony_ci	polynom[9] = 0x00008000;
155462306a36Sopenharmony_ci
155562306a36Sopenharmony_ci	/* Mask all arithmetic interrupts from TPC */
155662306a36Sopenharmony_ci	tpc_intr_mask = 0x7FFF;
155762306a36Sopenharmony_ci
155862306a36Sopenharmony_ci	for (i = 0, offset = 0 ; i < 6 ; i++, offset += 0x20000) {
155962306a36Sopenharmony_ci		WREG32(mmSRAM_Y0_X0_RTR_HBW_RD_RQ_L_ARB + offset, 0x302);
156062306a36Sopenharmony_ci		WREG32(mmSRAM_Y0_X1_RTR_HBW_RD_RQ_L_ARB + offset, 0x302);
156162306a36Sopenharmony_ci		WREG32(mmSRAM_Y0_X2_RTR_HBW_RD_RQ_L_ARB + offset, 0x302);
156262306a36Sopenharmony_ci		WREG32(mmSRAM_Y0_X3_RTR_HBW_RD_RQ_L_ARB + offset, 0x302);
156362306a36Sopenharmony_ci		WREG32(mmSRAM_Y0_X4_RTR_HBW_RD_RQ_L_ARB + offset, 0x302);
156462306a36Sopenharmony_ci
156562306a36Sopenharmony_ci		WREG32(mmSRAM_Y0_X0_RTR_HBW_DATA_L_ARB + offset, 0x204);
156662306a36Sopenharmony_ci		WREG32(mmSRAM_Y0_X1_RTR_HBW_DATA_L_ARB + offset, 0x204);
156762306a36Sopenharmony_ci		WREG32(mmSRAM_Y0_X2_RTR_HBW_DATA_L_ARB + offset, 0x204);
156862306a36Sopenharmony_ci		WREG32(mmSRAM_Y0_X3_RTR_HBW_DATA_L_ARB + offset, 0x204);
156962306a36Sopenharmony_ci		WREG32(mmSRAM_Y0_X4_RTR_HBW_DATA_L_ARB + offset, 0x204);
157062306a36Sopenharmony_ci
157162306a36Sopenharmony_ci
157262306a36Sopenharmony_ci		WREG32(mmSRAM_Y0_X0_RTR_HBW_DATA_E_ARB + offset, 0x206);
157362306a36Sopenharmony_ci		WREG32(mmSRAM_Y0_X1_RTR_HBW_DATA_E_ARB + offset, 0x206);
157462306a36Sopenharmony_ci		WREG32(mmSRAM_Y0_X2_RTR_HBW_DATA_E_ARB + offset, 0x206);
157562306a36Sopenharmony_ci		WREG32(mmSRAM_Y0_X3_RTR_HBW_DATA_E_ARB + offset, 0x207);
157662306a36Sopenharmony_ci		WREG32(mmSRAM_Y0_X4_RTR_HBW_DATA_E_ARB + offset, 0x207);
157762306a36Sopenharmony_ci
157862306a36Sopenharmony_ci		WREG32(mmSRAM_Y0_X0_RTR_HBW_DATA_W_ARB + offset, 0x207);
157962306a36Sopenharmony_ci		WREG32(mmSRAM_Y0_X1_RTR_HBW_DATA_W_ARB + offset, 0x207);
158062306a36Sopenharmony_ci		WREG32(mmSRAM_Y0_X2_RTR_HBW_DATA_W_ARB + offset, 0x206);
158162306a36Sopenharmony_ci		WREG32(mmSRAM_Y0_X3_RTR_HBW_DATA_W_ARB + offset, 0x206);
158262306a36Sopenharmony_ci		WREG32(mmSRAM_Y0_X4_RTR_HBW_DATA_W_ARB + offset, 0x206);
158362306a36Sopenharmony_ci
158462306a36Sopenharmony_ci		WREG32(mmSRAM_Y0_X0_RTR_HBW_WR_RS_E_ARB + offset, 0x101);
158562306a36Sopenharmony_ci		WREG32(mmSRAM_Y0_X1_RTR_HBW_WR_RS_E_ARB + offset, 0x102);
158662306a36Sopenharmony_ci		WREG32(mmSRAM_Y0_X2_RTR_HBW_WR_RS_E_ARB + offset, 0x103);
158762306a36Sopenharmony_ci		WREG32(mmSRAM_Y0_X3_RTR_HBW_WR_RS_E_ARB + offset, 0x104);
158862306a36Sopenharmony_ci		WREG32(mmSRAM_Y0_X4_RTR_HBW_WR_RS_E_ARB + offset, 0x105);
158962306a36Sopenharmony_ci
159062306a36Sopenharmony_ci		WREG32(mmSRAM_Y0_X0_RTR_HBW_WR_RS_W_ARB + offset, 0x105);
159162306a36Sopenharmony_ci		WREG32(mmSRAM_Y0_X1_RTR_HBW_WR_RS_W_ARB + offset, 0x104);
159262306a36Sopenharmony_ci		WREG32(mmSRAM_Y0_X2_RTR_HBW_WR_RS_W_ARB + offset, 0x103);
159362306a36Sopenharmony_ci		WREG32(mmSRAM_Y0_X3_RTR_HBW_WR_RS_W_ARB + offset, 0x102);
159462306a36Sopenharmony_ci		WREG32(mmSRAM_Y0_X4_RTR_HBW_WR_RS_W_ARB + offset, 0x101);
159562306a36Sopenharmony_ci	}
159662306a36Sopenharmony_ci
159762306a36Sopenharmony_ci	WREG32(mmMME_STORE_MAX_CREDIT, 0x21);
159862306a36Sopenharmony_ci	WREG32(mmMME_AGU, 0x0f0f0f10);
159962306a36Sopenharmony_ci	WREG32(mmMME_SEI_MASK, ~0x0);
160062306a36Sopenharmony_ci
160162306a36Sopenharmony_ci	WREG32(mmMME6_RTR_HBW_RD_RQ_N_ARB, 0x01010101);
160262306a36Sopenharmony_ci	WREG32(mmMME5_RTR_HBW_RD_RQ_N_ARB, 0x01040101);
160362306a36Sopenharmony_ci	WREG32(mmMME4_RTR_HBW_RD_RQ_N_ARB, 0x01030101);
160462306a36Sopenharmony_ci	WREG32(mmMME3_RTR_HBW_RD_RQ_N_ARB, 0x01020101);
160562306a36Sopenharmony_ci	WREG32(mmMME2_RTR_HBW_RD_RQ_N_ARB, 0x01010101);
160662306a36Sopenharmony_ci	WREG32(mmMME1_RTR_HBW_RD_RQ_N_ARB, 0x07010701);
160762306a36Sopenharmony_ci	WREG32(mmMME6_RTR_HBW_RD_RQ_S_ARB, 0x04010401);
160862306a36Sopenharmony_ci	WREG32(mmMME5_RTR_HBW_RD_RQ_S_ARB, 0x04050401);
160962306a36Sopenharmony_ci	WREG32(mmMME4_RTR_HBW_RD_RQ_S_ARB, 0x03070301);
161062306a36Sopenharmony_ci	WREG32(mmMME3_RTR_HBW_RD_RQ_S_ARB, 0x01030101);
161162306a36Sopenharmony_ci	WREG32(mmMME2_RTR_HBW_RD_RQ_S_ARB, 0x01040101);
161262306a36Sopenharmony_ci	WREG32(mmMME1_RTR_HBW_RD_RQ_S_ARB, 0x01050105);
161362306a36Sopenharmony_ci	WREG32(mmMME6_RTR_HBW_RD_RQ_W_ARB, 0x01010501);
161462306a36Sopenharmony_ci	WREG32(mmMME5_RTR_HBW_RD_RQ_W_ARB, 0x01010501);
161562306a36Sopenharmony_ci	WREG32(mmMME4_RTR_HBW_RD_RQ_W_ARB, 0x01040301);
161662306a36Sopenharmony_ci	WREG32(mmMME3_RTR_HBW_RD_RQ_W_ARB, 0x01030401);
161762306a36Sopenharmony_ci	WREG32(mmMME2_RTR_HBW_RD_RQ_W_ARB, 0x01040101);
161862306a36Sopenharmony_ci	WREG32(mmMME1_RTR_HBW_RD_RQ_W_ARB, 0x01050101);
161962306a36Sopenharmony_ci	WREG32(mmMME6_RTR_HBW_WR_RQ_N_ARB, 0x02020202);
162062306a36Sopenharmony_ci	WREG32(mmMME5_RTR_HBW_WR_RQ_N_ARB, 0x01070101);
162162306a36Sopenharmony_ci	WREG32(mmMME4_RTR_HBW_WR_RQ_N_ARB, 0x02020201);
162262306a36Sopenharmony_ci	WREG32(mmMME3_RTR_HBW_WR_RQ_N_ARB, 0x07020701);
162362306a36Sopenharmony_ci	WREG32(mmMME2_RTR_HBW_WR_RQ_N_ARB, 0x01020101);
162462306a36Sopenharmony_ci	WREG32(mmMME1_RTR_HBW_WR_RQ_S_ARB, 0x01010101);
162562306a36Sopenharmony_ci	WREG32(mmMME6_RTR_HBW_WR_RQ_S_ARB, 0x01070101);
162662306a36Sopenharmony_ci	WREG32(mmMME5_RTR_HBW_WR_RQ_S_ARB, 0x01070101);
162762306a36Sopenharmony_ci	WREG32(mmMME4_RTR_HBW_WR_RQ_S_ARB, 0x07020701);
162862306a36Sopenharmony_ci	WREG32(mmMME3_RTR_HBW_WR_RQ_S_ARB, 0x02020201);
162962306a36Sopenharmony_ci	WREG32(mmMME2_RTR_HBW_WR_RQ_S_ARB, 0x01070101);
163062306a36Sopenharmony_ci	WREG32(mmMME1_RTR_HBW_WR_RQ_S_ARB, 0x01020102);
163162306a36Sopenharmony_ci	WREG32(mmMME6_RTR_HBW_WR_RQ_W_ARB, 0x01020701);
163262306a36Sopenharmony_ci	WREG32(mmMME5_RTR_HBW_WR_RQ_W_ARB, 0x01020701);
163362306a36Sopenharmony_ci	WREG32(mmMME4_RTR_HBW_WR_RQ_W_ARB, 0x07020707);
163462306a36Sopenharmony_ci	WREG32(mmMME3_RTR_HBW_WR_RQ_W_ARB, 0x01020201);
163562306a36Sopenharmony_ci	WREG32(mmMME2_RTR_HBW_WR_RQ_W_ARB, 0x01070201);
163662306a36Sopenharmony_ci	WREG32(mmMME1_RTR_HBW_WR_RQ_W_ARB, 0x01070201);
163762306a36Sopenharmony_ci	WREG32(mmMME6_RTR_HBW_RD_RS_N_ARB, 0x01070102);
163862306a36Sopenharmony_ci	WREG32(mmMME5_RTR_HBW_RD_RS_N_ARB, 0x01070102);
163962306a36Sopenharmony_ci	WREG32(mmMME4_RTR_HBW_RD_RS_N_ARB, 0x01060102);
164062306a36Sopenharmony_ci	WREG32(mmMME3_RTR_HBW_RD_RS_N_ARB, 0x01040102);
164162306a36Sopenharmony_ci	WREG32(mmMME2_RTR_HBW_RD_RS_N_ARB, 0x01020102);
164262306a36Sopenharmony_ci	WREG32(mmMME1_RTR_HBW_RD_RS_N_ARB, 0x01020107);
164362306a36Sopenharmony_ci	WREG32(mmMME6_RTR_HBW_RD_RS_S_ARB, 0x01020106);
164462306a36Sopenharmony_ci	WREG32(mmMME5_RTR_HBW_RD_RS_S_ARB, 0x01020102);
164562306a36Sopenharmony_ci	WREG32(mmMME4_RTR_HBW_RD_RS_S_ARB, 0x01040102);
164662306a36Sopenharmony_ci	WREG32(mmMME3_RTR_HBW_RD_RS_S_ARB, 0x01060102);
164762306a36Sopenharmony_ci	WREG32(mmMME2_RTR_HBW_RD_RS_S_ARB, 0x01070102);
164862306a36Sopenharmony_ci	WREG32(mmMME1_RTR_HBW_RD_RS_S_ARB, 0x01070102);
164962306a36Sopenharmony_ci	WREG32(mmMME6_RTR_HBW_RD_RS_E_ARB, 0x01020702);
165062306a36Sopenharmony_ci	WREG32(mmMME5_RTR_HBW_RD_RS_E_ARB, 0x01020702);
165162306a36Sopenharmony_ci	WREG32(mmMME4_RTR_HBW_RD_RS_E_ARB, 0x01040602);
165262306a36Sopenharmony_ci	WREG32(mmMME3_RTR_HBW_RD_RS_E_ARB, 0x01060402);
165362306a36Sopenharmony_ci	WREG32(mmMME2_RTR_HBW_RD_RS_E_ARB, 0x01070202);
165462306a36Sopenharmony_ci	WREG32(mmMME1_RTR_HBW_RD_RS_E_ARB, 0x01070102);
165562306a36Sopenharmony_ci	WREG32(mmMME6_RTR_HBW_RD_RS_W_ARB, 0x01060401);
165662306a36Sopenharmony_ci	WREG32(mmMME5_RTR_HBW_RD_RS_W_ARB, 0x01060401);
165762306a36Sopenharmony_ci	WREG32(mmMME4_RTR_HBW_RD_RS_W_ARB, 0x01060401);
165862306a36Sopenharmony_ci	WREG32(mmMME3_RTR_HBW_RD_RS_W_ARB, 0x01060401);
165962306a36Sopenharmony_ci	WREG32(mmMME2_RTR_HBW_RD_RS_W_ARB, 0x01060401);
166062306a36Sopenharmony_ci	WREG32(mmMME1_RTR_HBW_RD_RS_W_ARB, 0x01060401);
166162306a36Sopenharmony_ci	WREG32(mmMME6_RTR_HBW_WR_RS_N_ARB, 0x01050101);
166262306a36Sopenharmony_ci	WREG32(mmMME5_RTR_HBW_WR_RS_N_ARB, 0x01040101);
166362306a36Sopenharmony_ci	WREG32(mmMME4_RTR_HBW_WR_RS_N_ARB, 0x01030101);
166462306a36Sopenharmony_ci	WREG32(mmMME3_RTR_HBW_WR_RS_N_ARB, 0x01020101);
166562306a36Sopenharmony_ci	WREG32(mmMME2_RTR_HBW_WR_RS_N_ARB, 0x01010101);
166662306a36Sopenharmony_ci	WREG32(mmMME1_RTR_HBW_WR_RS_N_ARB, 0x01010107);
166762306a36Sopenharmony_ci	WREG32(mmMME6_RTR_HBW_WR_RS_S_ARB, 0x01010107);
166862306a36Sopenharmony_ci	WREG32(mmMME5_RTR_HBW_WR_RS_S_ARB, 0x01010101);
166962306a36Sopenharmony_ci	WREG32(mmMME4_RTR_HBW_WR_RS_S_ARB, 0x01020101);
167062306a36Sopenharmony_ci	WREG32(mmMME3_RTR_HBW_WR_RS_S_ARB, 0x01030101);
167162306a36Sopenharmony_ci	WREG32(mmMME2_RTR_HBW_WR_RS_S_ARB, 0x01040101);
167262306a36Sopenharmony_ci	WREG32(mmMME1_RTR_HBW_WR_RS_S_ARB, 0x01050101);
167362306a36Sopenharmony_ci	WREG32(mmMME6_RTR_HBW_WR_RS_E_ARB, 0x01010501);
167462306a36Sopenharmony_ci	WREG32(mmMME5_RTR_HBW_WR_RS_E_ARB, 0x01010501);
167562306a36Sopenharmony_ci	WREG32(mmMME4_RTR_HBW_WR_RS_E_ARB, 0x01040301);
167662306a36Sopenharmony_ci	WREG32(mmMME3_RTR_HBW_WR_RS_E_ARB, 0x01030401);
167762306a36Sopenharmony_ci	WREG32(mmMME2_RTR_HBW_WR_RS_E_ARB, 0x01040101);
167862306a36Sopenharmony_ci	WREG32(mmMME1_RTR_HBW_WR_RS_E_ARB, 0x01050101);
167962306a36Sopenharmony_ci	WREG32(mmMME6_RTR_HBW_WR_RS_W_ARB, 0x01010101);
168062306a36Sopenharmony_ci	WREG32(mmMME5_RTR_HBW_WR_RS_W_ARB, 0x01010101);
168162306a36Sopenharmony_ci	WREG32(mmMME4_RTR_HBW_WR_RS_W_ARB, 0x01010101);
168262306a36Sopenharmony_ci	WREG32(mmMME3_RTR_HBW_WR_RS_W_ARB, 0x01010101);
168362306a36Sopenharmony_ci	WREG32(mmMME2_RTR_HBW_WR_RS_W_ARB, 0x01010101);
168462306a36Sopenharmony_ci	WREG32(mmMME1_RTR_HBW_WR_RS_W_ARB, 0x01010101);
168562306a36Sopenharmony_ci
168662306a36Sopenharmony_ci	WREG32(mmTPC1_RTR_HBW_RD_RQ_N_ARB, 0x01010101);
168762306a36Sopenharmony_ci	WREG32(mmTPC1_RTR_HBW_RD_RQ_S_ARB, 0x01010101);
168862306a36Sopenharmony_ci	WREG32(mmTPC1_RTR_HBW_RD_RQ_E_ARB, 0x01060101);
168962306a36Sopenharmony_ci	WREG32(mmTPC1_RTR_HBW_WR_RQ_N_ARB, 0x02020102);
169062306a36Sopenharmony_ci	WREG32(mmTPC1_RTR_HBW_WR_RQ_S_ARB, 0x01010101);
169162306a36Sopenharmony_ci	WREG32(mmTPC1_RTR_HBW_WR_RQ_E_ARB, 0x02070202);
169262306a36Sopenharmony_ci	WREG32(mmTPC1_RTR_HBW_RD_RS_N_ARB, 0x01020201);
169362306a36Sopenharmony_ci	WREG32(mmTPC1_RTR_HBW_RD_RS_S_ARB, 0x01070201);
169462306a36Sopenharmony_ci	WREG32(mmTPC1_RTR_HBW_RD_RS_W_ARB, 0x01070202);
169562306a36Sopenharmony_ci	WREG32(mmTPC1_RTR_HBW_WR_RS_N_ARB, 0x01010101);
169662306a36Sopenharmony_ci	WREG32(mmTPC1_RTR_HBW_WR_RS_S_ARB, 0x01050101);
169762306a36Sopenharmony_ci	WREG32(mmTPC1_RTR_HBW_WR_RS_W_ARB, 0x01050101);
169862306a36Sopenharmony_ci
169962306a36Sopenharmony_ci	WREG32(mmTPC2_RTR_HBW_RD_RQ_N_ARB, 0x01020101);
170062306a36Sopenharmony_ci	WREG32(mmTPC2_RTR_HBW_RD_RQ_S_ARB, 0x01050101);
170162306a36Sopenharmony_ci	WREG32(mmTPC2_RTR_HBW_RD_RQ_E_ARB, 0x01010201);
170262306a36Sopenharmony_ci	WREG32(mmTPC2_RTR_HBW_WR_RQ_N_ARB, 0x02040102);
170362306a36Sopenharmony_ci	WREG32(mmTPC2_RTR_HBW_WR_RQ_S_ARB, 0x01050101);
170462306a36Sopenharmony_ci	WREG32(mmTPC2_RTR_HBW_WR_RQ_E_ARB, 0x02060202);
170562306a36Sopenharmony_ci	WREG32(mmTPC2_RTR_HBW_RD_RS_N_ARB, 0x01020201);
170662306a36Sopenharmony_ci	WREG32(mmTPC2_RTR_HBW_RD_RS_S_ARB, 0x01070201);
170762306a36Sopenharmony_ci	WREG32(mmTPC2_RTR_HBW_RD_RS_W_ARB, 0x01070202);
170862306a36Sopenharmony_ci	WREG32(mmTPC2_RTR_HBW_WR_RS_N_ARB, 0x01010101);
170962306a36Sopenharmony_ci	WREG32(mmTPC2_RTR_HBW_WR_RS_S_ARB, 0x01040101);
171062306a36Sopenharmony_ci	WREG32(mmTPC2_RTR_HBW_WR_RS_W_ARB, 0x01040101);
171162306a36Sopenharmony_ci
171262306a36Sopenharmony_ci	WREG32(mmTPC3_RTR_HBW_RD_RQ_N_ARB, 0x01030101);
171362306a36Sopenharmony_ci	WREG32(mmTPC3_RTR_HBW_RD_RQ_S_ARB, 0x01040101);
171462306a36Sopenharmony_ci	WREG32(mmTPC3_RTR_HBW_RD_RQ_E_ARB, 0x01040301);
171562306a36Sopenharmony_ci	WREG32(mmTPC3_RTR_HBW_WR_RQ_N_ARB, 0x02060102);
171662306a36Sopenharmony_ci	WREG32(mmTPC3_RTR_HBW_WR_RQ_S_ARB, 0x01040101);
171762306a36Sopenharmony_ci	WREG32(mmTPC3_RTR_HBW_WR_RQ_E_ARB, 0x01040301);
171862306a36Sopenharmony_ci	WREG32(mmTPC3_RTR_HBW_RD_RS_N_ARB, 0x01040201);
171962306a36Sopenharmony_ci	WREG32(mmTPC3_RTR_HBW_RD_RS_S_ARB, 0x01060201);
172062306a36Sopenharmony_ci	WREG32(mmTPC3_RTR_HBW_RD_RS_W_ARB, 0x01060402);
172162306a36Sopenharmony_ci	WREG32(mmTPC3_RTR_HBW_WR_RS_N_ARB, 0x01020101);
172262306a36Sopenharmony_ci	WREG32(mmTPC3_RTR_HBW_WR_RS_S_ARB, 0x01030101);
172362306a36Sopenharmony_ci	WREG32(mmTPC3_RTR_HBW_WR_RS_W_ARB, 0x01030401);
172462306a36Sopenharmony_ci
172562306a36Sopenharmony_ci	WREG32(mmTPC4_RTR_HBW_RD_RQ_N_ARB, 0x01040101);
172662306a36Sopenharmony_ci	WREG32(mmTPC4_RTR_HBW_RD_RQ_S_ARB, 0x01030101);
172762306a36Sopenharmony_ci	WREG32(mmTPC4_RTR_HBW_RD_RQ_E_ARB, 0x01030401);
172862306a36Sopenharmony_ci	WREG32(mmTPC4_RTR_HBW_WR_RQ_N_ARB, 0x02070102);
172962306a36Sopenharmony_ci	WREG32(mmTPC4_RTR_HBW_WR_RQ_S_ARB, 0x01030101);
173062306a36Sopenharmony_ci	WREG32(mmTPC4_RTR_HBW_WR_RQ_E_ARB, 0x02060702);
173162306a36Sopenharmony_ci	WREG32(mmTPC4_RTR_HBW_RD_RS_N_ARB, 0x01060201);
173262306a36Sopenharmony_ci	WREG32(mmTPC4_RTR_HBW_RD_RS_S_ARB, 0x01040201);
173362306a36Sopenharmony_ci	WREG32(mmTPC4_RTR_HBW_RD_RS_W_ARB, 0x01040602);
173462306a36Sopenharmony_ci	WREG32(mmTPC4_RTR_HBW_WR_RS_N_ARB, 0x01030101);
173562306a36Sopenharmony_ci	WREG32(mmTPC4_RTR_HBW_WR_RS_S_ARB, 0x01020101);
173662306a36Sopenharmony_ci	WREG32(mmTPC4_RTR_HBW_WR_RS_W_ARB, 0x01040301);
173762306a36Sopenharmony_ci
173862306a36Sopenharmony_ci	WREG32(mmTPC5_RTR_HBW_RD_RQ_N_ARB, 0x01050101);
173962306a36Sopenharmony_ci	WREG32(mmTPC5_RTR_HBW_RD_RQ_S_ARB, 0x01020101);
174062306a36Sopenharmony_ci	WREG32(mmTPC5_RTR_HBW_RD_RQ_E_ARB, 0x01200501);
174162306a36Sopenharmony_ci	WREG32(mmTPC5_RTR_HBW_WR_RQ_N_ARB, 0x02070102);
174262306a36Sopenharmony_ci	WREG32(mmTPC5_RTR_HBW_WR_RQ_S_ARB, 0x01020101);
174362306a36Sopenharmony_ci	WREG32(mmTPC5_RTR_HBW_WR_RQ_E_ARB, 0x02020602);
174462306a36Sopenharmony_ci	WREG32(mmTPC5_RTR_HBW_RD_RS_N_ARB, 0x01070201);
174562306a36Sopenharmony_ci	WREG32(mmTPC5_RTR_HBW_RD_RS_S_ARB, 0x01020201);
174662306a36Sopenharmony_ci	WREG32(mmTPC5_RTR_HBW_RD_RS_W_ARB, 0x01020702);
174762306a36Sopenharmony_ci	WREG32(mmTPC5_RTR_HBW_WR_RS_N_ARB, 0x01040101);
174862306a36Sopenharmony_ci	WREG32(mmTPC5_RTR_HBW_WR_RS_S_ARB, 0x01010101);
174962306a36Sopenharmony_ci	WREG32(mmTPC5_RTR_HBW_WR_RS_W_ARB, 0x01010501);
175062306a36Sopenharmony_ci
175162306a36Sopenharmony_ci	WREG32(mmTPC6_RTR_HBW_RD_RQ_N_ARB, 0x01010101);
175262306a36Sopenharmony_ci	WREG32(mmTPC6_RTR_HBW_RD_RQ_S_ARB, 0x01010101);
175362306a36Sopenharmony_ci	WREG32(mmTPC6_RTR_HBW_RD_RQ_E_ARB, 0x01010601);
175462306a36Sopenharmony_ci	WREG32(mmTPC6_RTR_HBW_WR_RQ_N_ARB, 0x01010101);
175562306a36Sopenharmony_ci	WREG32(mmTPC6_RTR_HBW_WR_RQ_S_ARB, 0x01010101);
175662306a36Sopenharmony_ci	WREG32(mmTPC6_RTR_HBW_WR_RQ_E_ARB, 0x02020702);
175762306a36Sopenharmony_ci	WREG32(mmTPC6_RTR_HBW_RD_RS_N_ARB, 0x01010101);
175862306a36Sopenharmony_ci	WREG32(mmTPC6_RTR_HBW_RD_RS_S_ARB, 0x01010101);
175962306a36Sopenharmony_ci	WREG32(mmTPC6_RTR_HBW_RD_RS_W_ARB, 0x01020702);
176062306a36Sopenharmony_ci	WREG32(mmTPC6_RTR_HBW_WR_RS_N_ARB, 0x01050101);
176162306a36Sopenharmony_ci	WREG32(mmTPC6_RTR_HBW_WR_RS_S_ARB, 0x01010101);
176262306a36Sopenharmony_ci	WREG32(mmTPC6_RTR_HBW_WR_RS_W_ARB, 0x01010501);
176362306a36Sopenharmony_ci
176462306a36Sopenharmony_ci	for (i = 0, offset = 0 ; i < 10 ; i++, offset += 4) {
176562306a36Sopenharmony_ci		WREG32(mmMME1_RTR_SPLIT_COEF_0 + offset, polynom[i] >> 7);
176662306a36Sopenharmony_ci		WREG32(mmMME2_RTR_SPLIT_COEF_0 + offset, polynom[i] >> 7);
176762306a36Sopenharmony_ci		WREG32(mmMME3_RTR_SPLIT_COEF_0 + offset, polynom[i] >> 7);
176862306a36Sopenharmony_ci		WREG32(mmMME4_RTR_SPLIT_COEF_0 + offset, polynom[i] >> 7);
176962306a36Sopenharmony_ci		WREG32(mmMME5_RTR_SPLIT_COEF_0 + offset, polynom[i] >> 7);
177062306a36Sopenharmony_ci		WREG32(mmMME6_RTR_SPLIT_COEF_0 + offset, polynom[i] >> 7);
177162306a36Sopenharmony_ci
177262306a36Sopenharmony_ci		WREG32(mmTPC0_NRTR_SPLIT_COEF_0 + offset, polynom[i] >> 7);
177362306a36Sopenharmony_ci		WREG32(mmTPC1_RTR_SPLIT_COEF_0 + offset, polynom[i] >> 7);
177462306a36Sopenharmony_ci		WREG32(mmTPC2_RTR_SPLIT_COEF_0 + offset, polynom[i] >> 7);
177562306a36Sopenharmony_ci		WREG32(mmTPC3_RTR_SPLIT_COEF_0 + offset, polynom[i] >> 7);
177662306a36Sopenharmony_ci		WREG32(mmTPC4_RTR_SPLIT_COEF_0 + offset, polynom[i] >> 7);
177762306a36Sopenharmony_ci		WREG32(mmTPC5_RTR_SPLIT_COEF_0 + offset, polynom[i] >> 7);
177862306a36Sopenharmony_ci		WREG32(mmTPC6_RTR_SPLIT_COEF_0 + offset, polynom[i] >> 7);
177962306a36Sopenharmony_ci		WREG32(mmTPC7_NRTR_SPLIT_COEF_0 + offset, polynom[i] >> 7);
178062306a36Sopenharmony_ci
178162306a36Sopenharmony_ci		WREG32(mmPCI_NRTR_SPLIT_COEF_0 + offset, polynom[i] >> 7);
178262306a36Sopenharmony_ci		WREG32(mmDMA_NRTR_SPLIT_COEF_0 + offset, polynom[i] >> 7);
178362306a36Sopenharmony_ci	}
178462306a36Sopenharmony_ci
178562306a36Sopenharmony_ci	for (i = 0, offset = 0 ; i < 6 ; i++, offset += 0x40000) {
178662306a36Sopenharmony_ci		WREG32(mmMME1_RTR_SCRAMB_EN + offset,
178762306a36Sopenharmony_ci				1 << MME1_RTR_SCRAMB_EN_VAL_SHIFT);
178862306a36Sopenharmony_ci		WREG32(mmMME1_RTR_NON_LIN_SCRAMB + offset,
178962306a36Sopenharmony_ci				1 << MME1_RTR_NON_LIN_SCRAMB_EN_SHIFT);
179062306a36Sopenharmony_ci	}
179162306a36Sopenharmony_ci
179262306a36Sopenharmony_ci	for (i = 0, offset = 0 ; i < 8 ; i++, offset += 0x40000) {
179362306a36Sopenharmony_ci		/*
179462306a36Sopenharmony_ci		 * Workaround for Bug H2 #2441 :
179562306a36Sopenharmony_ci		 * "ST.NOP set trace event illegal opcode"
179662306a36Sopenharmony_ci		 */
179762306a36Sopenharmony_ci		WREG32(mmTPC0_CFG_TPC_INTR_MASK + offset, tpc_intr_mask);
179862306a36Sopenharmony_ci
179962306a36Sopenharmony_ci		WREG32(mmTPC0_NRTR_SCRAMB_EN + offset,
180062306a36Sopenharmony_ci				1 << TPC0_NRTR_SCRAMB_EN_VAL_SHIFT);
180162306a36Sopenharmony_ci		WREG32(mmTPC0_NRTR_NON_LIN_SCRAMB + offset,
180262306a36Sopenharmony_ci				1 << TPC0_NRTR_NON_LIN_SCRAMB_EN_SHIFT);
180362306a36Sopenharmony_ci
180462306a36Sopenharmony_ci		WREG32_FIELD(TPC0_CFG_MSS_CONFIG, offset,
180562306a36Sopenharmony_ci				ICACHE_FETCH_LINE_NUM, 2);
180662306a36Sopenharmony_ci	}
180762306a36Sopenharmony_ci
180862306a36Sopenharmony_ci	WREG32(mmDMA_NRTR_SCRAMB_EN, 1 << DMA_NRTR_SCRAMB_EN_VAL_SHIFT);
180962306a36Sopenharmony_ci	WREG32(mmDMA_NRTR_NON_LIN_SCRAMB,
181062306a36Sopenharmony_ci			1 << DMA_NRTR_NON_LIN_SCRAMB_EN_SHIFT);
181162306a36Sopenharmony_ci
181262306a36Sopenharmony_ci	WREG32(mmPCI_NRTR_SCRAMB_EN, 1 << PCI_NRTR_SCRAMB_EN_VAL_SHIFT);
181362306a36Sopenharmony_ci	WREG32(mmPCI_NRTR_NON_LIN_SCRAMB,
181462306a36Sopenharmony_ci			1 << PCI_NRTR_NON_LIN_SCRAMB_EN_SHIFT);
181562306a36Sopenharmony_ci
181662306a36Sopenharmony_ci	/*
181762306a36Sopenharmony_ci	 * Workaround for H2 #HW-23 bug
181862306a36Sopenharmony_ci	 * Set DMA max outstanding read requests to 240 on DMA CH 1.
181962306a36Sopenharmony_ci	 * This limitation is still large enough to not affect Gen4 bandwidth.
182062306a36Sopenharmony_ci	 * We need to only limit that DMA channel because the user can only read
182162306a36Sopenharmony_ci	 * from Host using DMA CH 1
182262306a36Sopenharmony_ci	 */
182362306a36Sopenharmony_ci	WREG32(mmDMA_CH_1_CFG0, 0x0fff00F0);
182462306a36Sopenharmony_ci
182562306a36Sopenharmony_ci	WREG32(mmTPC_PLL_CLK_RLX_0, 0x200020);
182662306a36Sopenharmony_ci
182762306a36Sopenharmony_ci	goya->hw_cap_initialized |= HW_CAP_GOLDEN;
182862306a36Sopenharmony_ci}
182962306a36Sopenharmony_ci
183062306a36Sopenharmony_cistatic void goya_init_mme_qman(struct hl_device *hdev)
183162306a36Sopenharmony_ci{
183262306a36Sopenharmony_ci	u32 mtr_base_lo, mtr_base_hi;
183362306a36Sopenharmony_ci	u32 so_base_lo, so_base_hi;
183462306a36Sopenharmony_ci	u32 gic_base_lo, gic_base_hi;
183562306a36Sopenharmony_ci	u64 qman_base_addr;
183662306a36Sopenharmony_ci
183762306a36Sopenharmony_ci	mtr_base_lo = lower_32_bits(CFG_BASE + mmSYNC_MNGR_MON_PAY_ADDRL_0);
183862306a36Sopenharmony_ci	mtr_base_hi = upper_32_bits(CFG_BASE + mmSYNC_MNGR_MON_PAY_ADDRL_0);
183962306a36Sopenharmony_ci	so_base_lo = lower_32_bits(CFG_BASE + mmSYNC_MNGR_SOB_OBJ_0);
184062306a36Sopenharmony_ci	so_base_hi = upper_32_bits(CFG_BASE + mmSYNC_MNGR_SOB_OBJ_0);
184162306a36Sopenharmony_ci
184262306a36Sopenharmony_ci	gic_base_lo =
184362306a36Sopenharmony_ci		lower_32_bits(CFG_BASE + mmGIC_DISTRIBUTOR__5_GICD_SETSPI_NSR);
184462306a36Sopenharmony_ci	gic_base_hi =
184562306a36Sopenharmony_ci		upper_32_bits(CFG_BASE + mmGIC_DISTRIBUTOR__5_GICD_SETSPI_NSR);
184662306a36Sopenharmony_ci
184762306a36Sopenharmony_ci	qman_base_addr = hdev->asic_prop.sram_base_address +
184862306a36Sopenharmony_ci				MME_QMAN_BASE_OFFSET;
184962306a36Sopenharmony_ci
185062306a36Sopenharmony_ci	WREG32(mmMME_QM_PQ_BASE_LO, lower_32_bits(qman_base_addr));
185162306a36Sopenharmony_ci	WREG32(mmMME_QM_PQ_BASE_HI, upper_32_bits(qman_base_addr));
185262306a36Sopenharmony_ci	WREG32(mmMME_QM_PQ_SIZE, ilog2(MME_QMAN_LENGTH));
185362306a36Sopenharmony_ci	WREG32(mmMME_QM_PQ_PI, 0);
185462306a36Sopenharmony_ci	WREG32(mmMME_QM_PQ_CI, 0);
185562306a36Sopenharmony_ci	WREG32(mmMME_QM_CP_LDMA_SRC_BASE_LO_OFFSET, 0x10C0);
185662306a36Sopenharmony_ci	WREG32(mmMME_QM_CP_LDMA_SRC_BASE_HI_OFFSET, 0x10C4);
185762306a36Sopenharmony_ci	WREG32(mmMME_QM_CP_LDMA_TSIZE_OFFSET, 0x10C8);
185862306a36Sopenharmony_ci	WREG32(mmMME_QM_CP_LDMA_COMMIT_OFFSET, 0x10CC);
185962306a36Sopenharmony_ci
186062306a36Sopenharmony_ci	WREG32(mmMME_QM_CP_MSG_BASE0_ADDR_LO, mtr_base_lo);
186162306a36Sopenharmony_ci	WREG32(mmMME_QM_CP_MSG_BASE0_ADDR_HI, mtr_base_hi);
186262306a36Sopenharmony_ci	WREG32(mmMME_QM_CP_MSG_BASE1_ADDR_LO, so_base_lo);
186362306a36Sopenharmony_ci	WREG32(mmMME_QM_CP_MSG_BASE1_ADDR_HI, so_base_hi);
186462306a36Sopenharmony_ci
186562306a36Sopenharmony_ci	/* QMAN CQ has 8 cache lines */
186662306a36Sopenharmony_ci	WREG32(mmMME_QM_CQ_CFG1, 0x00080008);
186762306a36Sopenharmony_ci
186862306a36Sopenharmony_ci	WREG32(mmMME_QM_GLBL_ERR_ADDR_LO, gic_base_lo);
186962306a36Sopenharmony_ci	WREG32(mmMME_QM_GLBL_ERR_ADDR_HI, gic_base_hi);
187062306a36Sopenharmony_ci
187162306a36Sopenharmony_ci	WREG32(mmMME_QM_GLBL_ERR_WDATA, GOYA_ASYNC_EVENT_ID_MME_QM);
187262306a36Sopenharmony_ci
187362306a36Sopenharmony_ci	WREG32(mmMME_QM_GLBL_ERR_CFG, QMAN_MME_ERR_MSG_EN);
187462306a36Sopenharmony_ci
187562306a36Sopenharmony_ci	WREG32(mmMME_QM_GLBL_PROT, QMAN_MME_ERR_PROT);
187662306a36Sopenharmony_ci
187762306a36Sopenharmony_ci	WREG32(mmMME_QM_GLBL_CFG0, QMAN_MME_ENABLE);
187862306a36Sopenharmony_ci}
187962306a36Sopenharmony_ci
188062306a36Sopenharmony_cistatic void goya_init_mme_cmdq(struct hl_device *hdev)
188162306a36Sopenharmony_ci{
188262306a36Sopenharmony_ci	u32 mtr_base_lo, mtr_base_hi;
188362306a36Sopenharmony_ci	u32 so_base_lo, so_base_hi;
188462306a36Sopenharmony_ci	u32 gic_base_lo, gic_base_hi;
188562306a36Sopenharmony_ci
188662306a36Sopenharmony_ci	mtr_base_lo = lower_32_bits(CFG_BASE + mmSYNC_MNGR_MON_PAY_ADDRL_0);
188762306a36Sopenharmony_ci	mtr_base_hi = upper_32_bits(CFG_BASE + mmSYNC_MNGR_MON_PAY_ADDRL_0);
188862306a36Sopenharmony_ci	so_base_lo = lower_32_bits(CFG_BASE + mmSYNC_MNGR_SOB_OBJ_0);
188962306a36Sopenharmony_ci	so_base_hi = upper_32_bits(CFG_BASE + mmSYNC_MNGR_SOB_OBJ_0);
189062306a36Sopenharmony_ci
189162306a36Sopenharmony_ci	gic_base_lo =
189262306a36Sopenharmony_ci		lower_32_bits(CFG_BASE + mmGIC_DISTRIBUTOR__5_GICD_SETSPI_NSR);
189362306a36Sopenharmony_ci	gic_base_hi =
189462306a36Sopenharmony_ci		upper_32_bits(CFG_BASE + mmGIC_DISTRIBUTOR__5_GICD_SETSPI_NSR);
189562306a36Sopenharmony_ci
189662306a36Sopenharmony_ci	WREG32(mmMME_CMDQ_CP_MSG_BASE0_ADDR_LO, mtr_base_lo);
189762306a36Sopenharmony_ci	WREG32(mmMME_CMDQ_CP_MSG_BASE0_ADDR_HI, mtr_base_hi);
189862306a36Sopenharmony_ci	WREG32(mmMME_CMDQ_CP_MSG_BASE1_ADDR_LO,	so_base_lo);
189962306a36Sopenharmony_ci	WREG32(mmMME_CMDQ_CP_MSG_BASE1_ADDR_HI, so_base_hi);
190062306a36Sopenharmony_ci
190162306a36Sopenharmony_ci	/* CMDQ CQ has 20 cache lines */
190262306a36Sopenharmony_ci	WREG32(mmMME_CMDQ_CQ_CFG1, 0x00140014);
190362306a36Sopenharmony_ci
190462306a36Sopenharmony_ci	WREG32(mmMME_CMDQ_GLBL_ERR_ADDR_LO, gic_base_lo);
190562306a36Sopenharmony_ci	WREG32(mmMME_CMDQ_GLBL_ERR_ADDR_HI, gic_base_hi);
190662306a36Sopenharmony_ci
190762306a36Sopenharmony_ci	WREG32(mmMME_CMDQ_GLBL_ERR_WDATA, GOYA_ASYNC_EVENT_ID_MME_CMDQ);
190862306a36Sopenharmony_ci
190962306a36Sopenharmony_ci	WREG32(mmMME_CMDQ_GLBL_ERR_CFG, CMDQ_MME_ERR_MSG_EN);
191062306a36Sopenharmony_ci
191162306a36Sopenharmony_ci	WREG32(mmMME_CMDQ_GLBL_PROT, CMDQ_MME_ERR_PROT);
191262306a36Sopenharmony_ci
191362306a36Sopenharmony_ci	WREG32(mmMME_CMDQ_GLBL_CFG0, CMDQ_MME_ENABLE);
191462306a36Sopenharmony_ci}
191562306a36Sopenharmony_ci
191662306a36Sopenharmony_civoid goya_init_mme_qmans(struct hl_device *hdev)
191762306a36Sopenharmony_ci{
191862306a36Sopenharmony_ci	struct goya_device *goya = hdev->asic_specific;
191962306a36Sopenharmony_ci	u32 so_base_lo, so_base_hi;
192062306a36Sopenharmony_ci
192162306a36Sopenharmony_ci	if (goya->hw_cap_initialized & HW_CAP_MME)
192262306a36Sopenharmony_ci		return;
192362306a36Sopenharmony_ci
192462306a36Sopenharmony_ci	so_base_lo = lower_32_bits(CFG_BASE + mmSYNC_MNGR_SOB_OBJ_0);
192562306a36Sopenharmony_ci	so_base_hi = upper_32_bits(CFG_BASE + mmSYNC_MNGR_SOB_OBJ_0);
192662306a36Sopenharmony_ci
192762306a36Sopenharmony_ci	WREG32(mmMME_SM_BASE_ADDRESS_LOW, so_base_lo);
192862306a36Sopenharmony_ci	WREG32(mmMME_SM_BASE_ADDRESS_HIGH, so_base_hi);
192962306a36Sopenharmony_ci
193062306a36Sopenharmony_ci	goya_init_mme_qman(hdev);
193162306a36Sopenharmony_ci	goya_init_mme_cmdq(hdev);
193262306a36Sopenharmony_ci
193362306a36Sopenharmony_ci	goya->hw_cap_initialized |= HW_CAP_MME;
193462306a36Sopenharmony_ci}
193562306a36Sopenharmony_ci
193662306a36Sopenharmony_cistatic void goya_init_tpc_qman(struct hl_device *hdev, u32 base_off, int tpc_id)
193762306a36Sopenharmony_ci{
193862306a36Sopenharmony_ci	u32 mtr_base_lo, mtr_base_hi;
193962306a36Sopenharmony_ci	u32 so_base_lo, so_base_hi;
194062306a36Sopenharmony_ci	u32 gic_base_lo, gic_base_hi;
194162306a36Sopenharmony_ci	u64 qman_base_addr;
194262306a36Sopenharmony_ci	u32 reg_off = tpc_id * (mmTPC1_QM_PQ_PI - mmTPC0_QM_PQ_PI);
194362306a36Sopenharmony_ci
194462306a36Sopenharmony_ci	mtr_base_lo = lower_32_bits(CFG_BASE + mmSYNC_MNGR_MON_PAY_ADDRL_0);
194562306a36Sopenharmony_ci	mtr_base_hi = upper_32_bits(CFG_BASE + mmSYNC_MNGR_MON_PAY_ADDRL_0);
194662306a36Sopenharmony_ci	so_base_lo = lower_32_bits(CFG_BASE + mmSYNC_MNGR_SOB_OBJ_0);
194762306a36Sopenharmony_ci	so_base_hi = upper_32_bits(CFG_BASE + mmSYNC_MNGR_SOB_OBJ_0);
194862306a36Sopenharmony_ci
194962306a36Sopenharmony_ci	gic_base_lo =
195062306a36Sopenharmony_ci		lower_32_bits(CFG_BASE + mmGIC_DISTRIBUTOR__5_GICD_SETSPI_NSR);
195162306a36Sopenharmony_ci	gic_base_hi =
195262306a36Sopenharmony_ci		upper_32_bits(CFG_BASE + mmGIC_DISTRIBUTOR__5_GICD_SETSPI_NSR);
195362306a36Sopenharmony_ci
195462306a36Sopenharmony_ci	qman_base_addr = hdev->asic_prop.sram_base_address + base_off;
195562306a36Sopenharmony_ci
195662306a36Sopenharmony_ci	WREG32(mmTPC0_QM_PQ_BASE_LO + reg_off, lower_32_bits(qman_base_addr));
195762306a36Sopenharmony_ci	WREG32(mmTPC0_QM_PQ_BASE_HI + reg_off, upper_32_bits(qman_base_addr));
195862306a36Sopenharmony_ci	WREG32(mmTPC0_QM_PQ_SIZE + reg_off, ilog2(TPC_QMAN_LENGTH));
195962306a36Sopenharmony_ci	WREG32(mmTPC0_QM_PQ_PI + reg_off, 0);
196062306a36Sopenharmony_ci	WREG32(mmTPC0_QM_PQ_CI + reg_off, 0);
196162306a36Sopenharmony_ci	WREG32(mmTPC0_QM_CP_LDMA_SRC_BASE_LO_OFFSET + reg_off, 0x10C0);
196262306a36Sopenharmony_ci	WREG32(mmTPC0_QM_CP_LDMA_SRC_BASE_HI_OFFSET + reg_off, 0x10C4);
196362306a36Sopenharmony_ci	WREG32(mmTPC0_QM_CP_LDMA_TSIZE_OFFSET + reg_off, 0x10C8);
196462306a36Sopenharmony_ci	WREG32(mmTPC0_QM_CP_LDMA_COMMIT_OFFSET + reg_off, 0x10CC);
196562306a36Sopenharmony_ci
196662306a36Sopenharmony_ci	WREG32(mmTPC0_QM_CP_MSG_BASE0_ADDR_LO + reg_off, mtr_base_lo);
196762306a36Sopenharmony_ci	WREG32(mmTPC0_QM_CP_MSG_BASE0_ADDR_HI + reg_off, mtr_base_hi);
196862306a36Sopenharmony_ci	WREG32(mmTPC0_QM_CP_MSG_BASE1_ADDR_LO + reg_off, so_base_lo);
196962306a36Sopenharmony_ci	WREG32(mmTPC0_QM_CP_MSG_BASE1_ADDR_HI + reg_off, so_base_hi);
197062306a36Sopenharmony_ci
197162306a36Sopenharmony_ci	WREG32(mmTPC0_QM_CQ_CFG1 + reg_off, 0x00080008);
197262306a36Sopenharmony_ci
197362306a36Sopenharmony_ci	WREG32(mmTPC0_QM_GLBL_ERR_ADDR_LO + reg_off, gic_base_lo);
197462306a36Sopenharmony_ci	WREG32(mmTPC0_QM_GLBL_ERR_ADDR_HI + reg_off, gic_base_hi);
197562306a36Sopenharmony_ci
197662306a36Sopenharmony_ci	WREG32(mmTPC0_QM_GLBL_ERR_WDATA + reg_off,
197762306a36Sopenharmony_ci			GOYA_ASYNC_EVENT_ID_TPC0_QM + tpc_id);
197862306a36Sopenharmony_ci
197962306a36Sopenharmony_ci	WREG32(mmTPC0_QM_GLBL_ERR_CFG + reg_off, QMAN_TPC_ERR_MSG_EN);
198062306a36Sopenharmony_ci
198162306a36Sopenharmony_ci	WREG32(mmTPC0_QM_GLBL_PROT + reg_off, QMAN_TPC_ERR_PROT);
198262306a36Sopenharmony_ci
198362306a36Sopenharmony_ci	WREG32(mmTPC0_QM_GLBL_CFG0 + reg_off, QMAN_TPC_ENABLE);
198462306a36Sopenharmony_ci}
198562306a36Sopenharmony_ci
198662306a36Sopenharmony_cistatic void goya_init_tpc_cmdq(struct hl_device *hdev, int tpc_id)
198762306a36Sopenharmony_ci{
198862306a36Sopenharmony_ci	u32 mtr_base_lo, mtr_base_hi;
198962306a36Sopenharmony_ci	u32 so_base_lo, so_base_hi;
199062306a36Sopenharmony_ci	u32 gic_base_lo, gic_base_hi;
199162306a36Sopenharmony_ci	u32 reg_off = tpc_id * (mmTPC1_CMDQ_CQ_CFG1 - mmTPC0_CMDQ_CQ_CFG1);
199262306a36Sopenharmony_ci
199362306a36Sopenharmony_ci	mtr_base_lo = lower_32_bits(CFG_BASE + mmSYNC_MNGR_MON_PAY_ADDRL_0);
199462306a36Sopenharmony_ci	mtr_base_hi = upper_32_bits(CFG_BASE + mmSYNC_MNGR_MON_PAY_ADDRL_0);
199562306a36Sopenharmony_ci	so_base_lo = lower_32_bits(CFG_BASE + mmSYNC_MNGR_SOB_OBJ_0);
199662306a36Sopenharmony_ci	so_base_hi = upper_32_bits(CFG_BASE + mmSYNC_MNGR_SOB_OBJ_0);
199762306a36Sopenharmony_ci
199862306a36Sopenharmony_ci	gic_base_lo =
199962306a36Sopenharmony_ci		lower_32_bits(CFG_BASE + mmGIC_DISTRIBUTOR__5_GICD_SETSPI_NSR);
200062306a36Sopenharmony_ci	gic_base_hi =
200162306a36Sopenharmony_ci		upper_32_bits(CFG_BASE + mmGIC_DISTRIBUTOR__5_GICD_SETSPI_NSR);
200262306a36Sopenharmony_ci
200362306a36Sopenharmony_ci	WREG32(mmTPC0_CMDQ_CP_MSG_BASE0_ADDR_LO + reg_off, mtr_base_lo);
200462306a36Sopenharmony_ci	WREG32(mmTPC0_CMDQ_CP_MSG_BASE0_ADDR_HI + reg_off, mtr_base_hi);
200562306a36Sopenharmony_ci	WREG32(mmTPC0_CMDQ_CP_MSG_BASE1_ADDR_LO + reg_off, so_base_lo);
200662306a36Sopenharmony_ci	WREG32(mmTPC0_CMDQ_CP_MSG_BASE1_ADDR_HI + reg_off, so_base_hi);
200762306a36Sopenharmony_ci
200862306a36Sopenharmony_ci	WREG32(mmTPC0_CMDQ_CQ_CFG1 + reg_off, 0x00140014);
200962306a36Sopenharmony_ci
201062306a36Sopenharmony_ci	WREG32(mmTPC0_CMDQ_GLBL_ERR_ADDR_LO + reg_off, gic_base_lo);
201162306a36Sopenharmony_ci	WREG32(mmTPC0_CMDQ_GLBL_ERR_ADDR_HI + reg_off, gic_base_hi);
201262306a36Sopenharmony_ci
201362306a36Sopenharmony_ci	WREG32(mmTPC0_CMDQ_GLBL_ERR_WDATA + reg_off,
201462306a36Sopenharmony_ci			GOYA_ASYNC_EVENT_ID_TPC0_CMDQ + tpc_id);
201562306a36Sopenharmony_ci
201662306a36Sopenharmony_ci	WREG32(mmTPC0_CMDQ_GLBL_ERR_CFG + reg_off, CMDQ_TPC_ERR_MSG_EN);
201762306a36Sopenharmony_ci
201862306a36Sopenharmony_ci	WREG32(mmTPC0_CMDQ_GLBL_PROT + reg_off, CMDQ_TPC_ERR_PROT);
201962306a36Sopenharmony_ci
202062306a36Sopenharmony_ci	WREG32(mmTPC0_CMDQ_GLBL_CFG0 + reg_off, CMDQ_TPC_ENABLE);
202162306a36Sopenharmony_ci}
202262306a36Sopenharmony_ci
202362306a36Sopenharmony_civoid goya_init_tpc_qmans(struct hl_device *hdev)
202462306a36Sopenharmony_ci{
202562306a36Sopenharmony_ci	struct goya_device *goya = hdev->asic_specific;
202662306a36Sopenharmony_ci	u32 so_base_lo, so_base_hi;
202762306a36Sopenharmony_ci	u32 cfg_off = mmTPC1_CFG_SM_BASE_ADDRESS_LOW -
202862306a36Sopenharmony_ci			mmTPC0_CFG_SM_BASE_ADDRESS_LOW;
202962306a36Sopenharmony_ci	int i;
203062306a36Sopenharmony_ci
203162306a36Sopenharmony_ci	if (goya->hw_cap_initialized & HW_CAP_TPC)
203262306a36Sopenharmony_ci		return;
203362306a36Sopenharmony_ci
203462306a36Sopenharmony_ci	so_base_lo = lower_32_bits(CFG_BASE + mmSYNC_MNGR_SOB_OBJ_0);
203562306a36Sopenharmony_ci	so_base_hi = upper_32_bits(CFG_BASE + mmSYNC_MNGR_SOB_OBJ_0);
203662306a36Sopenharmony_ci
203762306a36Sopenharmony_ci	for (i = 0 ; i < TPC_MAX_NUM ; i++) {
203862306a36Sopenharmony_ci		WREG32(mmTPC0_CFG_SM_BASE_ADDRESS_LOW + i * cfg_off,
203962306a36Sopenharmony_ci				so_base_lo);
204062306a36Sopenharmony_ci		WREG32(mmTPC0_CFG_SM_BASE_ADDRESS_HIGH + i * cfg_off,
204162306a36Sopenharmony_ci				so_base_hi);
204262306a36Sopenharmony_ci	}
204362306a36Sopenharmony_ci
204462306a36Sopenharmony_ci	goya_init_tpc_qman(hdev, TPC0_QMAN_BASE_OFFSET, 0);
204562306a36Sopenharmony_ci	goya_init_tpc_qman(hdev, TPC1_QMAN_BASE_OFFSET, 1);
204662306a36Sopenharmony_ci	goya_init_tpc_qman(hdev, TPC2_QMAN_BASE_OFFSET, 2);
204762306a36Sopenharmony_ci	goya_init_tpc_qman(hdev, TPC3_QMAN_BASE_OFFSET, 3);
204862306a36Sopenharmony_ci	goya_init_tpc_qman(hdev, TPC4_QMAN_BASE_OFFSET, 4);
204962306a36Sopenharmony_ci	goya_init_tpc_qman(hdev, TPC5_QMAN_BASE_OFFSET, 5);
205062306a36Sopenharmony_ci	goya_init_tpc_qman(hdev, TPC6_QMAN_BASE_OFFSET, 6);
205162306a36Sopenharmony_ci	goya_init_tpc_qman(hdev, TPC7_QMAN_BASE_OFFSET, 7);
205262306a36Sopenharmony_ci
205362306a36Sopenharmony_ci	for (i = 0 ; i < TPC_MAX_NUM ; i++)
205462306a36Sopenharmony_ci		goya_init_tpc_cmdq(hdev, i);
205562306a36Sopenharmony_ci
205662306a36Sopenharmony_ci	goya->hw_cap_initialized |= HW_CAP_TPC;
205762306a36Sopenharmony_ci}
205862306a36Sopenharmony_ci
205962306a36Sopenharmony_ci/*
206062306a36Sopenharmony_ci * goya_disable_internal_queues - Disable internal queues
206162306a36Sopenharmony_ci *
206262306a36Sopenharmony_ci * @hdev: pointer to hl_device structure
206362306a36Sopenharmony_ci *
206462306a36Sopenharmony_ci */
206562306a36Sopenharmony_cistatic void goya_disable_internal_queues(struct hl_device *hdev)
206662306a36Sopenharmony_ci{
206762306a36Sopenharmony_ci	struct goya_device *goya = hdev->asic_specific;
206862306a36Sopenharmony_ci
206962306a36Sopenharmony_ci	if (!(goya->hw_cap_initialized & HW_CAP_MME))
207062306a36Sopenharmony_ci		goto disable_tpc;
207162306a36Sopenharmony_ci
207262306a36Sopenharmony_ci	WREG32(mmMME_QM_GLBL_CFG0, 0);
207362306a36Sopenharmony_ci	WREG32(mmMME_CMDQ_GLBL_CFG0, 0);
207462306a36Sopenharmony_ci
207562306a36Sopenharmony_cidisable_tpc:
207662306a36Sopenharmony_ci	if (!(goya->hw_cap_initialized & HW_CAP_TPC))
207762306a36Sopenharmony_ci		return;
207862306a36Sopenharmony_ci
207962306a36Sopenharmony_ci	WREG32(mmTPC0_QM_GLBL_CFG0, 0);
208062306a36Sopenharmony_ci	WREG32(mmTPC0_CMDQ_GLBL_CFG0, 0);
208162306a36Sopenharmony_ci
208262306a36Sopenharmony_ci	WREG32(mmTPC1_QM_GLBL_CFG0, 0);
208362306a36Sopenharmony_ci	WREG32(mmTPC1_CMDQ_GLBL_CFG0, 0);
208462306a36Sopenharmony_ci
208562306a36Sopenharmony_ci	WREG32(mmTPC2_QM_GLBL_CFG0, 0);
208662306a36Sopenharmony_ci	WREG32(mmTPC2_CMDQ_GLBL_CFG0, 0);
208762306a36Sopenharmony_ci
208862306a36Sopenharmony_ci	WREG32(mmTPC3_QM_GLBL_CFG0, 0);
208962306a36Sopenharmony_ci	WREG32(mmTPC3_CMDQ_GLBL_CFG0, 0);
209062306a36Sopenharmony_ci
209162306a36Sopenharmony_ci	WREG32(mmTPC4_QM_GLBL_CFG0, 0);
209262306a36Sopenharmony_ci	WREG32(mmTPC4_CMDQ_GLBL_CFG0, 0);
209362306a36Sopenharmony_ci
209462306a36Sopenharmony_ci	WREG32(mmTPC5_QM_GLBL_CFG0, 0);
209562306a36Sopenharmony_ci	WREG32(mmTPC5_CMDQ_GLBL_CFG0, 0);
209662306a36Sopenharmony_ci
209762306a36Sopenharmony_ci	WREG32(mmTPC6_QM_GLBL_CFG0, 0);
209862306a36Sopenharmony_ci	WREG32(mmTPC6_CMDQ_GLBL_CFG0, 0);
209962306a36Sopenharmony_ci
210062306a36Sopenharmony_ci	WREG32(mmTPC7_QM_GLBL_CFG0, 0);
210162306a36Sopenharmony_ci	WREG32(mmTPC7_CMDQ_GLBL_CFG0, 0);
210262306a36Sopenharmony_ci}
210362306a36Sopenharmony_ci
210462306a36Sopenharmony_ci/*
210562306a36Sopenharmony_ci * goya_stop_internal_queues - Stop internal queues
210662306a36Sopenharmony_ci *
210762306a36Sopenharmony_ci * @hdev: pointer to hl_device structure
210862306a36Sopenharmony_ci *
210962306a36Sopenharmony_ci * Returns 0 on success
211062306a36Sopenharmony_ci *
211162306a36Sopenharmony_ci */
211262306a36Sopenharmony_cistatic int goya_stop_internal_queues(struct hl_device *hdev)
211362306a36Sopenharmony_ci{
211462306a36Sopenharmony_ci	struct goya_device *goya = hdev->asic_specific;
211562306a36Sopenharmony_ci	int rc, retval = 0;
211662306a36Sopenharmony_ci
211762306a36Sopenharmony_ci	if (!(goya->hw_cap_initialized & HW_CAP_MME))
211862306a36Sopenharmony_ci		goto stop_tpc;
211962306a36Sopenharmony_ci
212062306a36Sopenharmony_ci	/*
212162306a36Sopenharmony_ci	 * Each queue (QMAN) is a separate H/W logic. That means that each
212262306a36Sopenharmony_ci	 * QMAN can be stopped independently and failure to stop one does NOT
212362306a36Sopenharmony_ci	 * mandate we should not try to stop other QMANs
212462306a36Sopenharmony_ci	 */
212562306a36Sopenharmony_ci
212662306a36Sopenharmony_ci	rc = goya_stop_queue(hdev,
212762306a36Sopenharmony_ci			mmMME_QM_GLBL_CFG1,
212862306a36Sopenharmony_ci			mmMME_QM_CP_STS,
212962306a36Sopenharmony_ci			mmMME_QM_GLBL_STS0);
213062306a36Sopenharmony_ci
213162306a36Sopenharmony_ci	if (rc) {
213262306a36Sopenharmony_ci		dev_err(hdev->dev, "failed to stop MME QMAN\n");
213362306a36Sopenharmony_ci		retval = -EIO;
213462306a36Sopenharmony_ci	}
213562306a36Sopenharmony_ci
213662306a36Sopenharmony_ci	rc = goya_stop_queue(hdev,
213762306a36Sopenharmony_ci			mmMME_CMDQ_GLBL_CFG1,
213862306a36Sopenharmony_ci			mmMME_CMDQ_CP_STS,
213962306a36Sopenharmony_ci			mmMME_CMDQ_GLBL_STS0);
214062306a36Sopenharmony_ci
214162306a36Sopenharmony_ci	if (rc) {
214262306a36Sopenharmony_ci		dev_err(hdev->dev, "failed to stop MME CMDQ\n");
214362306a36Sopenharmony_ci		retval = -EIO;
214462306a36Sopenharmony_ci	}
214562306a36Sopenharmony_ci
214662306a36Sopenharmony_cistop_tpc:
214762306a36Sopenharmony_ci	if (!(goya->hw_cap_initialized & HW_CAP_TPC))
214862306a36Sopenharmony_ci		return retval;
214962306a36Sopenharmony_ci
215062306a36Sopenharmony_ci	rc = goya_stop_queue(hdev,
215162306a36Sopenharmony_ci			mmTPC0_QM_GLBL_CFG1,
215262306a36Sopenharmony_ci			mmTPC0_QM_CP_STS,
215362306a36Sopenharmony_ci			mmTPC0_QM_GLBL_STS0);
215462306a36Sopenharmony_ci
215562306a36Sopenharmony_ci	if (rc) {
215662306a36Sopenharmony_ci		dev_err(hdev->dev, "failed to stop TPC 0 QMAN\n");
215762306a36Sopenharmony_ci		retval = -EIO;
215862306a36Sopenharmony_ci	}
215962306a36Sopenharmony_ci
216062306a36Sopenharmony_ci	rc = goya_stop_queue(hdev,
216162306a36Sopenharmony_ci			mmTPC0_CMDQ_GLBL_CFG1,
216262306a36Sopenharmony_ci			mmTPC0_CMDQ_CP_STS,
216362306a36Sopenharmony_ci			mmTPC0_CMDQ_GLBL_STS0);
216462306a36Sopenharmony_ci
216562306a36Sopenharmony_ci	if (rc) {
216662306a36Sopenharmony_ci		dev_err(hdev->dev, "failed to stop TPC 0 CMDQ\n");
216762306a36Sopenharmony_ci		retval = -EIO;
216862306a36Sopenharmony_ci	}
216962306a36Sopenharmony_ci
217062306a36Sopenharmony_ci	rc = goya_stop_queue(hdev,
217162306a36Sopenharmony_ci			mmTPC1_QM_GLBL_CFG1,
217262306a36Sopenharmony_ci			mmTPC1_QM_CP_STS,
217362306a36Sopenharmony_ci			mmTPC1_QM_GLBL_STS0);
217462306a36Sopenharmony_ci
217562306a36Sopenharmony_ci	if (rc) {
217662306a36Sopenharmony_ci		dev_err(hdev->dev, "failed to stop TPC 1 QMAN\n");
217762306a36Sopenharmony_ci		retval = -EIO;
217862306a36Sopenharmony_ci	}
217962306a36Sopenharmony_ci
218062306a36Sopenharmony_ci	rc = goya_stop_queue(hdev,
218162306a36Sopenharmony_ci			mmTPC1_CMDQ_GLBL_CFG1,
218262306a36Sopenharmony_ci			mmTPC1_CMDQ_CP_STS,
218362306a36Sopenharmony_ci			mmTPC1_CMDQ_GLBL_STS0);
218462306a36Sopenharmony_ci
218562306a36Sopenharmony_ci	if (rc) {
218662306a36Sopenharmony_ci		dev_err(hdev->dev, "failed to stop TPC 1 CMDQ\n");
218762306a36Sopenharmony_ci		retval = -EIO;
218862306a36Sopenharmony_ci	}
218962306a36Sopenharmony_ci
219062306a36Sopenharmony_ci	rc = goya_stop_queue(hdev,
219162306a36Sopenharmony_ci			mmTPC2_QM_GLBL_CFG1,
219262306a36Sopenharmony_ci			mmTPC2_QM_CP_STS,
219362306a36Sopenharmony_ci			mmTPC2_QM_GLBL_STS0);
219462306a36Sopenharmony_ci
219562306a36Sopenharmony_ci	if (rc) {
219662306a36Sopenharmony_ci		dev_err(hdev->dev, "failed to stop TPC 2 QMAN\n");
219762306a36Sopenharmony_ci		retval = -EIO;
219862306a36Sopenharmony_ci	}
219962306a36Sopenharmony_ci
220062306a36Sopenharmony_ci	rc = goya_stop_queue(hdev,
220162306a36Sopenharmony_ci			mmTPC2_CMDQ_GLBL_CFG1,
220262306a36Sopenharmony_ci			mmTPC2_CMDQ_CP_STS,
220362306a36Sopenharmony_ci			mmTPC2_CMDQ_GLBL_STS0);
220462306a36Sopenharmony_ci
220562306a36Sopenharmony_ci	if (rc) {
220662306a36Sopenharmony_ci		dev_err(hdev->dev, "failed to stop TPC 2 CMDQ\n");
220762306a36Sopenharmony_ci		retval = -EIO;
220862306a36Sopenharmony_ci	}
220962306a36Sopenharmony_ci
221062306a36Sopenharmony_ci	rc = goya_stop_queue(hdev,
221162306a36Sopenharmony_ci			mmTPC3_QM_GLBL_CFG1,
221262306a36Sopenharmony_ci			mmTPC3_QM_CP_STS,
221362306a36Sopenharmony_ci			mmTPC3_QM_GLBL_STS0);
221462306a36Sopenharmony_ci
221562306a36Sopenharmony_ci	if (rc) {
221662306a36Sopenharmony_ci		dev_err(hdev->dev, "failed to stop TPC 3 QMAN\n");
221762306a36Sopenharmony_ci		retval = -EIO;
221862306a36Sopenharmony_ci	}
221962306a36Sopenharmony_ci
222062306a36Sopenharmony_ci	rc = goya_stop_queue(hdev,
222162306a36Sopenharmony_ci			mmTPC3_CMDQ_GLBL_CFG1,
222262306a36Sopenharmony_ci			mmTPC3_CMDQ_CP_STS,
222362306a36Sopenharmony_ci			mmTPC3_CMDQ_GLBL_STS0);
222462306a36Sopenharmony_ci
222562306a36Sopenharmony_ci	if (rc) {
222662306a36Sopenharmony_ci		dev_err(hdev->dev, "failed to stop TPC 3 CMDQ\n");
222762306a36Sopenharmony_ci		retval = -EIO;
222862306a36Sopenharmony_ci	}
222962306a36Sopenharmony_ci
223062306a36Sopenharmony_ci	rc = goya_stop_queue(hdev,
223162306a36Sopenharmony_ci			mmTPC4_QM_GLBL_CFG1,
223262306a36Sopenharmony_ci			mmTPC4_QM_CP_STS,
223362306a36Sopenharmony_ci			mmTPC4_QM_GLBL_STS0);
223462306a36Sopenharmony_ci
223562306a36Sopenharmony_ci	if (rc) {
223662306a36Sopenharmony_ci		dev_err(hdev->dev, "failed to stop TPC 4 QMAN\n");
223762306a36Sopenharmony_ci		retval = -EIO;
223862306a36Sopenharmony_ci	}
223962306a36Sopenharmony_ci
224062306a36Sopenharmony_ci	rc = goya_stop_queue(hdev,
224162306a36Sopenharmony_ci			mmTPC4_CMDQ_GLBL_CFG1,
224262306a36Sopenharmony_ci			mmTPC4_CMDQ_CP_STS,
224362306a36Sopenharmony_ci			mmTPC4_CMDQ_GLBL_STS0);
224462306a36Sopenharmony_ci
224562306a36Sopenharmony_ci	if (rc) {
224662306a36Sopenharmony_ci		dev_err(hdev->dev, "failed to stop TPC 4 CMDQ\n");
224762306a36Sopenharmony_ci		retval = -EIO;
224862306a36Sopenharmony_ci	}
224962306a36Sopenharmony_ci
225062306a36Sopenharmony_ci	rc = goya_stop_queue(hdev,
225162306a36Sopenharmony_ci			mmTPC5_QM_GLBL_CFG1,
225262306a36Sopenharmony_ci			mmTPC5_QM_CP_STS,
225362306a36Sopenharmony_ci			mmTPC5_QM_GLBL_STS0);
225462306a36Sopenharmony_ci
225562306a36Sopenharmony_ci	if (rc) {
225662306a36Sopenharmony_ci		dev_err(hdev->dev, "failed to stop TPC 5 QMAN\n");
225762306a36Sopenharmony_ci		retval = -EIO;
225862306a36Sopenharmony_ci	}
225962306a36Sopenharmony_ci
226062306a36Sopenharmony_ci	rc = goya_stop_queue(hdev,
226162306a36Sopenharmony_ci			mmTPC5_CMDQ_GLBL_CFG1,
226262306a36Sopenharmony_ci			mmTPC5_CMDQ_CP_STS,
226362306a36Sopenharmony_ci			mmTPC5_CMDQ_GLBL_STS0);
226462306a36Sopenharmony_ci
226562306a36Sopenharmony_ci	if (rc) {
226662306a36Sopenharmony_ci		dev_err(hdev->dev, "failed to stop TPC 5 CMDQ\n");
226762306a36Sopenharmony_ci		retval = -EIO;
226862306a36Sopenharmony_ci	}
226962306a36Sopenharmony_ci
227062306a36Sopenharmony_ci	rc = goya_stop_queue(hdev,
227162306a36Sopenharmony_ci			mmTPC6_QM_GLBL_CFG1,
227262306a36Sopenharmony_ci			mmTPC6_QM_CP_STS,
227362306a36Sopenharmony_ci			mmTPC6_QM_GLBL_STS0);
227462306a36Sopenharmony_ci
227562306a36Sopenharmony_ci	if (rc) {
227662306a36Sopenharmony_ci		dev_err(hdev->dev, "failed to stop TPC 6 QMAN\n");
227762306a36Sopenharmony_ci		retval = -EIO;
227862306a36Sopenharmony_ci	}
227962306a36Sopenharmony_ci
228062306a36Sopenharmony_ci	rc = goya_stop_queue(hdev,
228162306a36Sopenharmony_ci			mmTPC6_CMDQ_GLBL_CFG1,
228262306a36Sopenharmony_ci			mmTPC6_CMDQ_CP_STS,
228362306a36Sopenharmony_ci			mmTPC6_CMDQ_GLBL_STS0);
228462306a36Sopenharmony_ci
228562306a36Sopenharmony_ci	if (rc) {
228662306a36Sopenharmony_ci		dev_err(hdev->dev, "failed to stop TPC 6 CMDQ\n");
228762306a36Sopenharmony_ci		retval = -EIO;
228862306a36Sopenharmony_ci	}
228962306a36Sopenharmony_ci
229062306a36Sopenharmony_ci	rc = goya_stop_queue(hdev,
229162306a36Sopenharmony_ci			mmTPC7_QM_GLBL_CFG1,
229262306a36Sopenharmony_ci			mmTPC7_QM_CP_STS,
229362306a36Sopenharmony_ci			mmTPC7_QM_GLBL_STS0);
229462306a36Sopenharmony_ci
229562306a36Sopenharmony_ci	if (rc) {
229662306a36Sopenharmony_ci		dev_err(hdev->dev, "failed to stop TPC 7 QMAN\n");
229762306a36Sopenharmony_ci		retval = -EIO;
229862306a36Sopenharmony_ci	}
229962306a36Sopenharmony_ci
230062306a36Sopenharmony_ci	rc = goya_stop_queue(hdev,
230162306a36Sopenharmony_ci			mmTPC7_CMDQ_GLBL_CFG1,
230262306a36Sopenharmony_ci			mmTPC7_CMDQ_CP_STS,
230362306a36Sopenharmony_ci			mmTPC7_CMDQ_GLBL_STS0);
230462306a36Sopenharmony_ci
230562306a36Sopenharmony_ci	if (rc) {
230662306a36Sopenharmony_ci		dev_err(hdev->dev, "failed to stop TPC 7 CMDQ\n");
230762306a36Sopenharmony_ci		retval = -EIO;
230862306a36Sopenharmony_ci	}
230962306a36Sopenharmony_ci
231062306a36Sopenharmony_ci	return retval;
231162306a36Sopenharmony_ci}
231262306a36Sopenharmony_ci
231362306a36Sopenharmony_cistatic void goya_dma_stall(struct hl_device *hdev)
231462306a36Sopenharmony_ci{
231562306a36Sopenharmony_ci	struct goya_device *goya = hdev->asic_specific;
231662306a36Sopenharmony_ci
231762306a36Sopenharmony_ci	if (!(goya->hw_cap_initialized & HW_CAP_DMA))
231862306a36Sopenharmony_ci		return;
231962306a36Sopenharmony_ci
232062306a36Sopenharmony_ci	WREG32(mmDMA_QM_0_GLBL_CFG1, 1 << DMA_QM_0_GLBL_CFG1_DMA_STOP_SHIFT);
232162306a36Sopenharmony_ci	WREG32(mmDMA_QM_1_GLBL_CFG1, 1 << DMA_QM_1_GLBL_CFG1_DMA_STOP_SHIFT);
232262306a36Sopenharmony_ci	WREG32(mmDMA_QM_2_GLBL_CFG1, 1 << DMA_QM_2_GLBL_CFG1_DMA_STOP_SHIFT);
232362306a36Sopenharmony_ci	WREG32(mmDMA_QM_3_GLBL_CFG1, 1 << DMA_QM_3_GLBL_CFG1_DMA_STOP_SHIFT);
232462306a36Sopenharmony_ci	WREG32(mmDMA_QM_4_GLBL_CFG1, 1 << DMA_QM_4_GLBL_CFG1_DMA_STOP_SHIFT);
232562306a36Sopenharmony_ci}
232662306a36Sopenharmony_ci
232762306a36Sopenharmony_cistatic void goya_tpc_stall(struct hl_device *hdev)
232862306a36Sopenharmony_ci{
232962306a36Sopenharmony_ci	struct goya_device *goya = hdev->asic_specific;
233062306a36Sopenharmony_ci
233162306a36Sopenharmony_ci	if (!(goya->hw_cap_initialized & HW_CAP_TPC))
233262306a36Sopenharmony_ci		return;
233362306a36Sopenharmony_ci
233462306a36Sopenharmony_ci	WREG32(mmTPC0_CFG_TPC_STALL, 1 << TPC0_CFG_TPC_STALL_V_SHIFT);
233562306a36Sopenharmony_ci	WREG32(mmTPC1_CFG_TPC_STALL, 1 << TPC1_CFG_TPC_STALL_V_SHIFT);
233662306a36Sopenharmony_ci	WREG32(mmTPC2_CFG_TPC_STALL, 1 << TPC2_CFG_TPC_STALL_V_SHIFT);
233762306a36Sopenharmony_ci	WREG32(mmTPC3_CFG_TPC_STALL, 1 << TPC3_CFG_TPC_STALL_V_SHIFT);
233862306a36Sopenharmony_ci	WREG32(mmTPC4_CFG_TPC_STALL, 1 << TPC4_CFG_TPC_STALL_V_SHIFT);
233962306a36Sopenharmony_ci	WREG32(mmTPC5_CFG_TPC_STALL, 1 << TPC5_CFG_TPC_STALL_V_SHIFT);
234062306a36Sopenharmony_ci	WREG32(mmTPC6_CFG_TPC_STALL, 1 << TPC6_CFG_TPC_STALL_V_SHIFT);
234162306a36Sopenharmony_ci	WREG32(mmTPC7_CFG_TPC_STALL, 1 << TPC7_CFG_TPC_STALL_V_SHIFT);
234262306a36Sopenharmony_ci}
234362306a36Sopenharmony_ci
234462306a36Sopenharmony_cistatic void goya_mme_stall(struct hl_device *hdev)
234562306a36Sopenharmony_ci{
234662306a36Sopenharmony_ci	struct goya_device *goya = hdev->asic_specific;
234762306a36Sopenharmony_ci
234862306a36Sopenharmony_ci	if (!(goya->hw_cap_initialized & HW_CAP_MME))
234962306a36Sopenharmony_ci		return;
235062306a36Sopenharmony_ci
235162306a36Sopenharmony_ci	WREG32(mmMME_STALL, 0xFFFFFFFF);
235262306a36Sopenharmony_ci}
235362306a36Sopenharmony_ci
235462306a36Sopenharmony_cistatic int goya_enable_msix(struct hl_device *hdev)
235562306a36Sopenharmony_ci{
235662306a36Sopenharmony_ci	struct goya_device *goya = hdev->asic_specific;
235762306a36Sopenharmony_ci	int cq_cnt = hdev->asic_prop.completion_queues_count;
235862306a36Sopenharmony_ci	int rc, i, irq_cnt_init, irq;
235962306a36Sopenharmony_ci
236062306a36Sopenharmony_ci	if (goya->hw_cap_initialized & HW_CAP_MSIX)
236162306a36Sopenharmony_ci		return 0;
236262306a36Sopenharmony_ci
236362306a36Sopenharmony_ci	rc = pci_alloc_irq_vectors(hdev->pdev, GOYA_MSIX_ENTRIES,
236462306a36Sopenharmony_ci				GOYA_MSIX_ENTRIES, PCI_IRQ_MSIX);
236562306a36Sopenharmony_ci	if (rc < 0) {
236662306a36Sopenharmony_ci		dev_err(hdev->dev,
236762306a36Sopenharmony_ci			"MSI-X: Failed to enable support -- %d/%d\n",
236862306a36Sopenharmony_ci			GOYA_MSIX_ENTRIES, rc);
236962306a36Sopenharmony_ci		return rc;
237062306a36Sopenharmony_ci	}
237162306a36Sopenharmony_ci
237262306a36Sopenharmony_ci	for (i = 0, irq_cnt_init = 0 ; i < cq_cnt ; i++, irq_cnt_init++) {
237362306a36Sopenharmony_ci		irq = pci_irq_vector(hdev->pdev, i);
237462306a36Sopenharmony_ci		rc = request_irq(irq, hl_irq_handler_cq, 0, goya_irq_name[i],
237562306a36Sopenharmony_ci				&hdev->completion_queue[i]);
237662306a36Sopenharmony_ci		if (rc) {
237762306a36Sopenharmony_ci			dev_err(hdev->dev, "Failed to request IRQ %d", irq);
237862306a36Sopenharmony_ci			goto free_irqs;
237962306a36Sopenharmony_ci		}
238062306a36Sopenharmony_ci	}
238162306a36Sopenharmony_ci
238262306a36Sopenharmony_ci	irq = pci_irq_vector(hdev->pdev, GOYA_EVENT_QUEUE_MSIX_IDX);
238362306a36Sopenharmony_ci
238462306a36Sopenharmony_ci	rc = request_irq(irq, hl_irq_handler_eq, 0,
238562306a36Sopenharmony_ci			goya_irq_name[GOYA_EVENT_QUEUE_MSIX_IDX],
238662306a36Sopenharmony_ci			&hdev->event_queue);
238762306a36Sopenharmony_ci	if (rc) {
238862306a36Sopenharmony_ci		dev_err(hdev->dev, "Failed to request IRQ %d", irq);
238962306a36Sopenharmony_ci		goto free_irqs;
239062306a36Sopenharmony_ci	}
239162306a36Sopenharmony_ci
239262306a36Sopenharmony_ci	goya->hw_cap_initialized |= HW_CAP_MSIX;
239362306a36Sopenharmony_ci	return 0;
239462306a36Sopenharmony_ci
239562306a36Sopenharmony_cifree_irqs:
239662306a36Sopenharmony_ci	for (i = 0 ; i < irq_cnt_init ; i++)
239762306a36Sopenharmony_ci		free_irq(pci_irq_vector(hdev->pdev, i),
239862306a36Sopenharmony_ci			&hdev->completion_queue[i]);
239962306a36Sopenharmony_ci
240062306a36Sopenharmony_ci	pci_free_irq_vectors(hdev->pdev);
240162306a36Sopenharmony_ci	return rc;
240262306a36Sopenharmony_ci}
240362306a36Sopenharmony_ci
240462306a36Sopenharmony_cistatic void goya_sync_irqs(struct hl_device *hdev)
240562306a36Sopenharmony_ci{
240662306a36Sopenharmony_ci	struct goya_device *goya = hdev->asic_specific;
240762306a36Sopenharmony_ci	int i;
240862306a36Sopenharmony_ci
240962306a36Sopenharmony_ci	if (!(goya->hw_cap_initialized & HW_CAP_MSIX))
241062306a36Sopenharmony_ci		return;
241162306a36Sopenharmony_ci
241262306a36Sopenharmony_ci	/* Wait for all pending IRQs to be finished */
241362306a36Sopenharmony_ci	for (i = 0 ; i < hdev->asic_prop.completion_queues_count ; i++)
241462306a36Sopenharmony_ci		synchronize_irq(pci_irq_vector(hdev->pdev, i));
241562306a36Sopenharmony_ci
241662306a36Sopenharmony_ci	synchronize_irq(pci_irq_vector(hdev->pdev, GOYA_EVENT_QUEUE_MSIX_IDX));
241762306a36Sopenharmony_ci}
241862306a36Sopenharmony_ci
241962306a36Sopenharmony_cistatic void goya_disable_msix(struct hl_device *hdev)
242062306a36Sopenharmony_ci{
242162306a36Sopenharmony_ci	struct goya_device *goya = hdev->asic_specific;
242262306a36Sopenharmony_ci	int i, irq;
242362306a36Sopenharmony_ci
242462306a36Sopenharmony_ci	if (!(goya->hw_cap_initialized & HW_CAP_MSIX))
242562306a36Sopenharmony_ci		return;
242662306a36Sopenharmony_ci
242762306a36Sopenharmony_ci	goya_sync_irqs(hdev);
242862306a36Sopenharmony_ci
242962306a36Sopenharmony_ci	irq = pci_irq_vector(hdev->pdev, GOYA_EVENT_QUEUE_MSIX_IDX);
243062306a36Sopenharmony_ci	free_irq(irq, &hdev->event_queue);
243162306a36Sopenharmony_ci
243262306a36Sopenharmony_ci	for (i = 0 ; i < hdev->asic_prop.completion_queues_count ; i++) {
243362306a36Sopenharmony_ci		irq = pci_irq_vector(hdev->pdev, i);
243462306a36Sopenharmony_ci		free_irq(irq, &hdev->completion_queue[i]);
243562306a36Sopenharmony_ci	}
243662306a36Sopenharmony_ci
243762306a36Sopenharmony_ci	pci_free_irq_vectors(hdev->pdev);
243862306a36Sopenharmony_ci
243962306a36Sopenharmony_ci	goya->hw_cap_initialized &= ~HW_CAP_MSIX;
244062306a36Sopenharmony_ci}
244162306a36Sopenharmony_ci
244262306a36Sopenharmony_cistatic void goya_enable_timestamp(struct hl_device *hdev)
244362306a36Sopenharmony_ci{
244462306a36Sopenharmony_ci	/* Disable the timestamp counter */
244562306a36Sopenharmony_ci	WREG32(mmPSOC_TIMESTAMP_BASE - CFG_BASE, 0);
244662306a36Sopenharmony_ci
244762306a36Sopenharmony_ci	/* Zero the lower/upper parts of the 64-bit counter */
244862306a36Sopenharmony_ci	WREG32(mmPSOC_TIMESTAMP_BASE - CFG_BASE + 0xC, 0);
244962306a36Sopenharmony_ci	WREG32(mmPSOC_TIMESTAMP_BASE - CFG_BASE + 0x8, 0);
245062306a36Sopenharmony_ci
245162306a36Sopenharmony_ci	/* Enable the counter */
245262306a36Sopenharmony_ci	WREG32(mmPSOC_TIMESTAMP_BASE - CFG_BASE, 1);
245362306a36Sopenharmony_ci}
245462306a36Sopenharmony_ci
245562306a36Sopenharmony_cistatic void goya_disable_timestamp(struct hl_device *hdev)
245662306a36Sopenharmony_ci{
245762306a36Sopenharmony_ci	/* Disable the timestamp counter */
245862306a36Sopenharmony_ci	WREG32(mmPSOC_TIMESTAMP_BASE - CFG_BASE, 0);
245962306a36Sopenharmony_ci}
246062306a36Sopenharmony_ci
246162306a36Sopenharmony_cistatic void goya_halt_engines(struct hl_device *hdev, bool hard_reset, bool fw_reset)
246262306a36Sopenharmony_ci{
246362306a36Sopenharmony_ci	u32 wait_timeout_ms;
246462306a36Sopenharmony_ci
246562306a36Sopenharmony_ci	if (hdev->pldm)
246662306a36Sopenharmony_ci		wait_timeout_ms = GOYA_PLDM_RESET_WAIT_MSEC;
246762306a36Sopenharmony_ci	else
246862306a36Sopenharmony_ci		wait_timeout_ms = GOYA_RESET_WAIT_MSEC;
246962306a36Sopenharmony_ci
247062306a36Sopenharmony_ci	goya_stop_external_queues(hdev);
247162306a36Sopenharmony_ci	goya_stop_internal_queues(hdev);
247262306a36Sopenharmony_ci
247362306a36Sopenharmony_ci	msleep(wait_timeout_ms);
247462306a36Sopenharmony_ci
247562306a36Sopenharmony_ci	goya_dma_stall(hdev);
247662306a36Sopenharmony_ci	goya_tpc_stall(hdev);
247762306a36Sopenharmony_ci	goya_mme_stall(hdev);
247862306a36Sopenharmony_ci
247962306a36Sopenharmony_ci	msleep(wait_timeout_ms);
248062306a36Sopenharmony_ci
248162306a36Sopenharmony_ci	goya_disable_external_queues(hdev);
248262306a36Sopenharmony_ci	goya_disable_internal_queues(hdev);
248362306a36Sopenharmony_ci
248462306a36Sopenharmony_ci	goya_disable_timestamp(hdev);
248562306a36Sopenharmony_ci
248662306a36Sopenharmony_ci	if (hard_reset) {
248762306a36Sopenharmony_ci		goya_disable_msix(hdev);
248862306a36Sopenharmony_ci		goya_mmu_remove_device_cpu_mappings(hdev);
248962306a36Sopenharmony_ci	} else {
249062306a36Sopenharmony_ci		goya_sync_irqs(hdev);
249162306a36Sopenharmony_ci	}
249262306a36Sopenharmony_ci}
249362306a36Sopenharmony_ci
249462306a36Sopenharmony_ci/*
249562306a36Sopenharmony_ci * goya_load_firmware_to_device() - Load LINUX FW code to device.
249662306a36Sopenharmony_ci * @hdev: Pointer to hl_device structure.
249762306a36Sopenharmony_ci *
249862306a36Sopenharmony_ci * Copy LINUX fw code from firmware file to HBM BAR.
249962306a36Sopenharmony_ci *
250062306a36Sopenharmony_ci * Return: 0 on success, non-zero for failure.
250162306a36Sopenharmony_ci */
250262306a36Sopenharmony_cistatic int goya_load_firmware_to_device(struct hl_device *hdev)
250362306a36Sopenharmony_ci{
250462306a36Sopenharmony_ci	void __iomem *dst;
250562306a36Sopenharmony_ci
250662306a36Sopenharmony_ci	dst = hdev->pcie_bar[DDR_BAR_ID] + LINUX_FW_OFFSET;
250762306a36Sopenharmony_ci
250862306a36Sopenharmony_ci	return hl_fw_load_fw_to_device(hdev, GOYA_LINUX_FW_FILE, dst, 0, 0);
250962306a36Sopenharmony_ci}
251062306a36Sopenharmony_ci
251162306a36Sopenharmony_ci/*
251262306a36Sopenharmony_ci * goya_load_boot_fit_to_device() - Load boot fit to device.
251362306a36Sopenharmony_ci * @hdev: Pointer to hl_device structure.
251462306a36Sopenharmony_ci *
251562306a36Sopenharmony_ci * Copy boot fit file to SRAM BAR.
251662306a36Sopenharmony_ci *
251762306a36Sopenharmony_ci * Return: 0 on success, non-zero for failure.
251862306a36Sopenharmony_ci */
251962306a36Sopenharmony_cistatic int goya_load_boot_fit_to_device(struct hl_device *hdev)
252062306a36Sopenharmony_ci{
252162306a36Sopenharmony_ci	void __iomem *dst;
252262306a36Sopenharmony_ci
252362306a36Sopenharmony_ci	dst = hdev->pcie_bar[SRAM_CFG_BAR_ID] + BOOT_FIT_SRAM_OFFSET;
252462306a36Sopenharmony_ci
252562306a36Sopenharmony_ci	return hl_fw_load_fw_to_device(hdev, GOYA_BOOT_FIT_FILE, dst, 0, 0);
252662306a36Sopenharmony_ci}
252762306a36Sopenharmony_ci
252862306a36Sopenharmony_cistatic void goya_init_dynamic_firmware_loader(struct hl_device *hdev)
252962306a36Sopenharmony_ci{
253062306a36Sopenharmony_ci	struct dynamic_fw_load_mgr *dynamic_loader;
253162306a36Sopenharmony_ci	struct cpu_dyn_regs *dyn_regs;
253262306a36Sopenharmony_ci
253362306a36Sopenharmony_ci	dynamic_loader = &hdev->fw_loader.dynamic_loader;
253462306a36Sopenharmony_ci
253562306a36Sopenharmony_ci	/*
253662306a36Sopenharmony_ci	 * here we update initial values for few specific dynamic regs (as
253762306a36Sopenharmony_ci	 * before reading the first descriptor from FW those value has to be
253862306a36Sopenharmony_ci	 * hard-coded) in later stages of the protocol those values will be
253962306a36Sopenharmony_ci	 * updated automatically by reading the FW descriptor so data there
254062306a36Sopenharmony_ci	 * will always be up-to-date
254162306a36Sopenharmony_ci	 */
254262306a36Sopenharmony_ci	dyn_regs = &dynamic_loader->comm_desc.cpu_dyn_regs;
254362306a36Sopenharmony_ci	dyn_regs->kmd_msg_to_cpu =
254462306a36Sopenharmony_ci				cpu_to_le32(mmPSOC_GLOBAL_CONF_KMD_MSG_TO_CPU);
254562306a36Sopenharmony_ci	dyn_regs->cpu_cmd_status_to_host =
254662306a36Sopenharmony_ci				cpu_to_le32(mmCPU_CMD_STATUS_TO_HOST);
254762306a36Sopenharmony_ci
254862306a36Sopenharmony_ci	dynamic_loader->wait_for_bl_timeout = GOYA_WAIT_FOR_BL_TIMEOUT_USEC;
254962306a36Sopenharmony_ci}
255062306a36Sopenharmony_ci
255162306a36Sopenharmony_cistatic void goya_init_static_firmware_loader(struct hl_device *hdev)
255262306a36Sopenharmony_ci{
255362306a36Sopenharmony_ci	struct static_fw_load_mgr *static_loader;
255462306a36Sopenharmony_ci
255562306a36Sopenharmony_ci	static_loader = &hdev->fw_loader.static_loader;
255662306a36Sopenharmony_ci
255762306a36Sopenharmony_ci	static_loader->preboot_version_max_off = SRAM_SIZE - VERSION_MAX_LEN;
255862306a36Sopenharmony_ci	static_loader->boot_fit_version_max_off = SRAM_SIZE - VERSION_MAX_LEN;
255962306a36Sopenharmony_ci	static_loader->kmd_msg_to_cpu_reg = mmPSOC_GLOBAL_CONF_KMD_MSG_TO_CPU;
256062306a36Sopenharmony_ci	static_loader->cpu_cmd_status_to_host_reg = mmCPU_CMD_STATUS_TO_HOST;
256162306a36Sopenharmony_ci	static_loader->cpu_boot_status_reg = mmPSOC_GLOBAL_CONF_CPU_BOOT_STATUS;
256262306a36Sopenharmony_ci	static_loader->cpu_boot_dev_status0_reg = mmCPU_BOOT_DEV_STS0;
256362306a36Sopenharmony_ci	static_loader->cpu_boot_dev_status1_reg = mmCPU_BOOT_DEV_STS1;
256462306a36Sopenharmony_ci	static_loader->boot_err0_reg = mmCPU_BOOT_ERR0;
256562306a36Sopenharmony_ci	static_loader->boot_err1_reg = mmCPU_BOOT_ERR1;
256662306a36Sopenharmony_ci	static_loader->preboot_version_offset_reg = mmPREBOOT_VER_OFFSET;
256762306a36Sopenharmony_ci	static_loader->boot_fit_version_offset_reg = mmUBOOT_VER_OFFSET;
256862306a36Sopenharmony_ci	static_loader->sram_offset_mask = ~(lower_32_bits(SRAM_BASE_ADDR));
256962306a36Sopenharmony_ci}
257062306a36Sopenharmony_ci
257162306a36Sopenharmony_cistatic void goya_init_firmware_preload_params(struct hl_device *hdev)
257262306a36Sopenharmony_ci{
257362306a36Sopenharmony_ci	struct pre_fw_load_props *pre_fw_load = &hdev->fw_loader.pre_fw_load;
257462306a36Sopenharmony_ci
257562306a36Sopenharmony_ci	pre_fw_load->cpu_boot_status_reg = mmPSOC_GLOBAL_CONF_CPU_BOOT_STATUS;
257662306a36Sopenharmony_ci	pre_fw_load->sts_boot_dev_sts0_reg = mmCPU_BOOT_DEV_STS0;
257762306a36Sopenharmony_ci	pre_fw_load->sts_boot_dev_sts1_reg = mmCPU_BOOT_DEV_STS1;
257862306a36Sopenharmony_ci	pre_fw_load->boot_err0_reg = mmCPU_BOOT_ERR0;
257962306a36Sopenharmony_ci	pre_fw_load->boot_err1_reg = mmCPU_BOOT_ERR1;
258062306a36Sopenharmony_ci	pre_fw_load->wait_for_preboot_timeout = GOYA_BOOT_FIT_REQ_TIMEOUT_USEC;
258162306a36Sopenharmony_ci}
258262306a36Sopenharmony_ci
258362306a36Sopenharmony_cistatic void goya_init_firmware_loader(struct hl_device *hdev)
258462306a36Sopenharmony_ci{
258562306a36Sopenharmony_ci	struct asic_fixed_properties *prop = &hdev->asic_prop;
258662306a36Sopenharmony_ci	struct fw_load_mgr *fw_loader = &hdev->fw_loader;
258762306a36Sopenharmony_ci
258862306a36Sopenharmony_ci	/* fill common fields */
258962306a36Sopenharmony_ci	fw_loader->fw_comp_loaded = FW_TYPE_NONE;
259062306a36Sopenharmony_ci	fw_loader->boot_fit_img.image_name = GOYA_BOOT_FIT_FILE;
259162306a36Sopenharmony_ci	fw_loader->linux_img.image_name = GOYA_LINUX_FW_FILE;
259262306a36Sopenharmony_ci	fw_loader->cpu_timeout = GOYA_CPU_TIMEOUT_USEC;
259362306a36Sopenharmony_ci	fw_loader->boot_fit_timeout = GOYA_BOOT_FIT_REQ_TIMEOUT_USEC;
259462306a36Sopenharmony_ci	fw_loader->skip_bmc = false;
259562306a36Sopenharmony_ci	fw_loader->sram_bar_id = SRAM_CFG_BAR_ID;
259662306a36Sopenharmony_ci	fw_loader->dram_bar_id = DDR_BAR_ID;
259762306a36Sopenharmony_ci
259862306a36Sopenharmony_ci	if (prop->dynamic_fw_load)
259962306a36Sopenharmony_ci		goya_init_dynamic_firmware_loader(hdev);
260062306a36Sopenharmony_ci	else
260162306a36Sopenharmony_ci		goya_init_static_firmware_loader(hdev);
260262306a36Sopenharmony_ci}
260362306a36Sopenharmony_ci
260462306a36Sopenharmony_cistatic int goya_init_cpu(struct hl_device *hdev)
260562306a36Sopenharmony_ci{
260662306a36Sopenharmony_ci	struct goya_device *goya = hdev->asic_specific;
260762306a36Sopenharmony_ci	int rc;
260862306a36Sopenharmony_ci
260962306a36Sopenharmony_ci	if (!(hdev->fw_components & FW_TYPE_PREBOOT_CPU))
261062306a36Sopenharmony_ci		return 0;
261162306a36Sopenharmony_ci
261262306a36Sopenharmony_ci	if (goya->hw_cap_initialized & HW_CAP_CPU)
261362306a36Sopenharmony_ci		return 0;
261462306a36Sopenharmony_ci
261562306a36Sopenharmony_ci	/*
261662306a36Sopenharmony_ci	 * Before pushing u-boot/linux to device, need to set the ddr bar to
261762306a36Sopenharmony_ci	 * base address of dram
261862306a36Sopenharmony_ci	 */
261962306a36Sopenharmony_ci	if (goya_set_ddr_bar_base(hdev, DRAM_PHYS_BASE) == U64_MAX) {
262062306a36Sopenharmony_ci		dev_err(hdev->dev,
262162306a36Sopenharmony_ci			"failed to map DDR bar to DRAM base address\n");
262262306a36Sopenharmony_ci		return -EIO;
262362306a36Sopenharmony_ci	}
262462306a36Sopenharmony_ci
262562306a36Sopenharmony_ci	rc = hl_fw_init_cpu(hdev);
262662306a36Sopenharmony_ci
262762306a36Sopenharmony_ci	if (rc)
262862306a36Sopenharmony_ci		return rc;
262962306a36Sopenharmony_ci
263062306a36Sopenharmony_ci	goya->hw_cap_initialized |= HW_CAP_CPU;
263162306a36Sopenharmony_ci
263262306a36Sopenharmony_ci	return 0;
263362306a36Sopenharmony_ci}
263462306a36Sopenharmony_ci
263562306a36Sopenharmony_cistatic int goya_mmu_update_asid_hop0_addr(struct hl_device *hdev, u32 asid,
263662306a36Sopenharmony_ci						u64 phys_addr)
263762306a36Sopenharmony_ci{
263862306a36Sopenharmony_ci	u32 status, timeout_usec;
263962306a36Sopenharmony_ci	int rc;
264062306a36Sopenharmony_ci
264162306a36Sopenharmony_ci	if (hdev->pldm)
264262306a36Sopenharmony_ci		timeout_usec = GOYA_PLDM_MMU_TIMEOUT_USEC;
264362306a36Sopenharmony_ci	else
264462306a36Sopenharmony_ci		timeout_usec = MMU_CONFIG_TIMEOUT_USEC;
264562306a36Sopenharmony_ci
264662306a36Sopenharmony_ci	WREG32(MMU_HOP0_PA43_12, phys_addr >> MMU_HOP0_PA43_12_SHIFT);
264762306a36Sopenharmony_ci	WREG32(MMU_HOP0_PA49_44, phys_addr >> MMU_HOP0_PA49_44_SHIFT);
264862306a36Sopenharmony_ci	WREG32(MMU_ASID_BUSY, 0x80000000 | asid);
264962306a36Sopenharmony_ci
265062306a36Sopenharmony_ci	rc = hl_poll_timeout(
265162306a36Sopenharmony_ci		hdev,
265262306a36Sopenharmony_ci		MMU_ASID_BUSY,
265362306a36Sopenharmony_ci		status,
265462306a36Sopenharmony_ci		!(status & 0x80000000),
265562306a36Sopenharmony_ci		1000,
265662306a36Sopenharmony_ci		timeout_usec);
265762306a36Sopenharmony_ci
265862306a36Sopenharmony_ci	if (rc) {
265962306a36Sopenharmony_ci		dev_err(hdev->dev,
266062306a36Sopenharmony_ci			"Timeout during MMU hop0 config of asid %d\n", asid);
266162306a36Sopenharmony_ci		return rc;
266262306a36Sopenharmony_ci	}
266362306a36Sopenharmony_ci
266462306a36Sopenharmony_ci	return 0;
266562306a36Sopenharmony_ci}
266662306a36Sopenharmony_ci
266762306a36Sopenharmony_ciint goya_mmu_init(struct hl_device *hdev)
266862306a36Sopenharmony_ci{
266962306a36Sopenharmony_ci	struct asic_fixed_properties *prop = &hdev->asic_prop;
267062306a36Sopenharmony_ci	struct goya_device *goya = hdev->asic_specific;
267162306a36Sopenharmony_ci	u64 hop0_addr;
267262306a36Sopenharmony_ci	int rc, i;
267362306a36Sopenharmony_ci
267462306a36Sopenharmony_ci	if (goya->hw_cap_initialized & HW_CAP_MMU)
267562306a36Sopenharmony_ci		return 0;
267662306a36Sopenharmony_ci
267762306a36Sopenharmony_ci	hdev->dram_default_page_mapping = true;
267862306a36Sopenharmony_ci
267962306a36Sopenharmony_ci	for (i = 0 ; i < prop->max_asid ; i++) {
268062306a36Sopenharmony_ci		hop0_addr = prop->mmu_pgt_addr +
268162306a36Sopenharmony_ci				(i * prop->mmu_hop_table_size);
268262306a36Sopenharmony_ci
268362306a36Sopenharmony_ci		rc = goya_mmu_update_asid_hop0_addr(hdev, i, hop0_addr);
268462306a36Sopenharmony_ci		if (rc) {
268562306a36Sopenharmony_ci			dev_err(hdev->dev,
268662306a36Sopenharmony_ci				"failed to set hop0 addr for asid %d\n", i);
268762306a36Sopenharmony_ci			goto err;
268862306a36Sopenharmony_ci		}
268962306a36Sopenharmony_ci	}
269062306a36Sopenharmony_ci
269162306a36Sopenharmony_ci	goya->hw_cap_initialized |= HW_CAP_MMU;
269262306a36Sopenharmony_ci
269362306a36Sopenharmony_ci	/* init MMU cache manage page */
269462306a36Sopenharmony_ci	WREG32(mmSTLB_CACHE_INV_BASE_39_8,
269562306a36Sopenharmony_ci				lower_32_bits(MMU_CACHE_MNG_ADDR >> 8));
269662306a36Sopenharmony_ci	WREG32(mmSTLB_CACHE_INV_BASE_49_40, MMU_CACHE_MNG_ADDR >> 40);
269762306a36Sopenharmony_ci
269862306a36Sopenharmony_ci	/* Remove follower feature due to performance bug */
269962306a36Sopenharmony_ci	WREG32_AND(mmSTLB_STLB_FEATURE_EN,
270062306a36Sopenharmony_ci			(~STLB_STLB_FEATURE_EN_FOLLOWER_EN_MASK));
270162306a36Sopenharmony_ci
270262306a36Sopenharmony_ci	hl_mmu_invalidate_cache(hdev, true, MMU_OP_USERPTR | MMU_OP_PHYS_PACK);
270362306a36Sopenharmony_ci
270462306a36Sopenharmony_ci	WREG32(mmMMU_MMU_ENABLE, 1);
270562306a36Sopenharmony_ci	WREG32(mmMMU_SPI_MASK, 0xF);
270662306a36Sopenharmony_ci
270762306a36Sopenharmony_ci	return 0;
270862306a36Sopenharmony_ci
270962306a36Sopenharmony_cierr:
271062306a36Sopenharmony_ci	return rc;
271162306a36Sopenharmony_ci}
271262306a36Sopenharmony_ci
271362306a36Sopenharmony_ci/*
271462306a36Sopenharmony_ci * goya_hw_init - Goya hardware initialization code
271562306a36Sopenharmony_ci *
271662306a36Sopenharmony_ci * @hdev: pointer to hl_device structure
271762306a36Sopenharmony_ci *
271862306a36Sopenharmony_ci * Returns 0 on success
271962306a36Sopenharmony_ci *
272062306a36Sopenharmony_ci */
272162306a36Sopenharmony_cistatic int goya_hw_init(struct hl_device *hdev)
272262306a36Sopenharmony_ci{
272362306a36Sopenharmony_ci	struct asic_fixed_properties *prop = &hdev->asic_prop;
272462306a36Sopenharmony_ci	int rc;
272562306a36Sopenharmony_ci
272662306a36Sopenharmony_ci	/* Perform read from the device to make sure device is up */
272762306a36Sopenharmony_ci	RREG32(mmPCIE_DBI_DEVICE_ID_VENDOR_ID_REG);
272862306a36Sopenharmony_ci
272962306a36Sopenharmony_ci	/*
273062306a36Sopenharmony_ci	 * Let's mark in the H/W that we have reached this point. We check
273162306a36Sopenharmony_ci	 * this value in the reset_before_init function to understand whether
273262306a36Sopenharmony_ci	 * we need to reset the chip before doing H/W init. This register is
273362306a36Sopenharmony_ci	 * cleared by the H/W upon H/W reset
273462306a36Sopenharmony_ci	 */
273562306a36Sopenharmony_ci	WREG32(mmHW_STATE, HL_DEVICE_HW_STATE_DIRTY);
273662306a36Sopenharmony_ci
273762306a36Sopenharmony_ci	rc = goya_init_cpu(hdev);
273862306a36Sopenharmony_ci	if (rc) {
273962306a36Sopenharmony_ci		dev_err(hdev->dev, "failed to initialize CPU\n");
274062306a36Sopenharmony_ci		return rc;
274162306a36Sopenharmony_ci	}
274262306a36Sopenharmony_ci
274362306a36Sopenharmony_ci	goya_tpc_mbist_workaround(hdev);
274462306a36Sopenharmony_ci
274562306a36Sopenharmony_ci	goya_init_golden_registers(hdev);
274662306a36Sopenharmony_ci
274762306a36Sopenharmony_ci	/*
274862306a36Sopenharmony_ci	 * After CPU initialization is finished, change DDR bar mapping inside
274962306a36Sopenharmony_ci	 * iATU to point to the start address of the MMU page tables
275062306a36Sopenharmony_ci	 */
275162306a36Sopenharmony_ci	if (goya_set_ddr_bar_base(hdev, (MMU_PAGE_TABLES_ADDR &
275262306a36Sopenharmony_ci			~(prop->dram_pci_bar_size - 0x1ull))) == U64_MAX) {
275362306a36Sopenharmony_ci		dev_err(hdev->dev,
275462306a36Sopenharmony_ci			"failed to map DDR bar to MMU page tables\n");
275562306a36Sopenharmony_ci		return -EIO;
275662306a36Sopenharmony_ci	}
275762306a36Sopenharmony_ci
275862306a36Sopenharmony_ci	rc = goya_mmu_init(hdev);
275962306a36Sopenharmony_ci	if (rc)
276062306a36Sopenharmony_ci		return rc;
276162306a36Sopenharmony_ci
276262306a36Sopenharmony_ci	goya_init_security(hdev);
276362306a36Sopenharmony_ci
276462306a36Sopenharmony_ci	goya_init_dma_qmans(hdev);
276562306a36Sopenharmony_ci
276662306a36Sopenharmony_ci	goya_init_mme_qmans(hdev);
276762306a36Sopenharmony_ci
276862306a36Sopenharmony_ci	goya_init_tpc_qmans(hdev);
276962306a36Sopenharmony_ci
277062306a36Sopenharmony_ci	goya_enable_timestamp(hdev);
277162306a36Sopenharmony_ci
277262306a36Sopenharmony_ci	/* MSI-X must be enabled before CPU queues are initialized */
277362306a36Sopenharmony_ci	rc = goya_enable_msix(hdev);
277462306a36Sopenharmony_ci	if (rc)
277562306a36Sopenharmony_ci		goto disable_queues;
277662306a36Sopenharmony_ci
277762306a36Sopenharmony_ci	/* Perform read from the device to flush all MSI-X configuration */
277862306a36Sopenharmony_ci	RREG32(mmPCIE_DBI_DEVICE_ID_VENDOR_ID_REG);
277962306a36Sopenharmony_ci
278062306a36Sopenharmony_ci	return 0;
278162306a36Sopenharmony_ci
278262306a36Sopenharmony_cidisable_queues:
278362306a36Sopenharmony_ci	goya_disable_internal_queues(hdev);
278462306a36Sopenharmony_ci	goya_disable_external_queues(hdev);
278562306a36Sopenharmony_ci
278662306a36Sopenharmony_ci	return rc;
278762306a36Sopenharmony_ci}
278862306a36Sopenharmony_ci
278962306a36Sopenharmony_cistatic int goya_hw_fini(struct hl_device *hdev, bool hard_reset, bool fw_reset)
279062306a36Sopenharmony_ci{
279162306a36Sopenharmony_ci	struct goya_device *goya = hdev->asic_specific;
279262306a36Sopenharmony_ci	u32 reset_timeout_ms, cpu_timeout_ms, status;
279362306a36Sopenharmony_ci
279462306a36Sopenharmony_ci	if (hdev->pldm) {
279562306a36Sopenharmony_ci		reset_timeout_ms = GOYA_PLDM_RESET_TIMEOUT_MSEC;
279662306a36Sopenharmony_ci		cpu_timeout_ms = GOYA_PLDM_RESET_WAIT_MSEC;
279762306a36Sopenharmony_ci	} else {
279862306a36Sopenharmony_ci		reset_timeout_ms = GOYA_RESET_TIMEOUT_MSEC;
279962306a36Sopenharmony_ci		cpu_timeout_ms = GOYA_CPU_RESET_WAIT_MSEC;
280062306a36Sopenharmony_ci	}
280162306a36Sopenharmony_ci
280262306a36Sopenharmony_ci	if (hard_reset) {
280362306a36Sopenharmony_ci		/* I don't know what is the state of the CPU so make sure it is
280462306a36Sopenharmony_ci		 * stopped in any means necessary
280562306a36Sopenharmony_ci		 */
280662306a36Sopenharmony_ci		WREG32(mmPSOC_GLOBAL_CONF_UBOOT_MAGIC, KMD_MSG_GOTO_WFE);
280762306a36Sopenharmony_ci		WREG32(mmGIC_DISTRIBUTOR__5_GICD_SETSPI_NSR,
280862306a36Sopenharmony_ci			GOYA_ASYNC_EVENT_ID_HALT_MACHINE);
280962306a36Sopenharmony_ci
281062306a36Sopenharmony_ci		msleep(cpu_timeout_ms);
281162306a36Sopenharmony_ci
281262306a36Sopenharmony_ci		goya_set_ddr_bar_base(hdev, DRAM_PHYS_BASE);
281362306a36Sopenharmony_ci		goya_disable_clk_rlx(hdev);
281462306a36Sopenharmony_ci		goya_set_pll_refclk(hdev);
281562306a36Sopenharmony_ci
281662306a36Sopenharmony_ci		WREG32(mmPSOC_GLOBAL_CONF_SW_ALL_RST_CFG, RESET_ALL);
281762306a36Sopenharmony_ci		dev_dbg(hdev->dev,
281862306a36Sopenharmony_ci			"Issued HARD reset command, going to wait %dms\n",
281962306a36Sopenharmony_ci			reset_timeout_ms);
282062306a36Sopenharmony_ci	} else {
282162306a36Sopenharmony_ci		WREG32(mmPSOC_GLOBAL_CONF_SW_ALL_RST_CFG, DMA_MME_TPC_RESET);
282262306a36Sopenharmony_ci		dev_dbg(hdev->dev,
282362306a36Sopenharmony_ci			"Issued SOFT reset command, going to wait %dms\n",
282462306a36Sopenharmony_ci			reset_timeout_ms);
282562306a36Sopenharmony_ci	}
282662306a36Sopenharmony_ci
282762306a36Sopenharmony_ci	/*
282862306a36Sopenharmony_ci	 * After hard reset, we can't poll the BTM_FSM register because the PSOC
282962306a36Sopenharmony_ci	 * itself is in reset. In either reset we need to wait until the reset
283062306a36Sopenharmony_ci	 * is deasserted
283162306a36Sopenharmony_ci	 */
283262306a36Sopenharmony_ci	msleep(reset_timeout_ms);
283362306a36Sopenharmony_ci
283462306a36Sopenharmony_ci	status = RREG32(mmPSOC_GLOBAL_CONF_BTM_FSM);
283562306a36Sopenharmony_ci	if (status & PSOC_GLOBAL_CONF_BTM_FSM_STATE_MASK) {
283662306a36Sopenharmony_ci		dev_err(hdev->dev, "Timeout while waiting for device to reset 0x%x\n", status);
283762306a36Sopenharmony_ci		return -ETIMEDOUT;
283862306a36Sopenharmony_ci	}
283962306a36Sopenharmony_ci
284062306a36Sopenharmony_ci	if (!hard_reset && goya) {
284162306a36Sopenharmony_ci		goya->hw_cap_initialized &= ~(HW_CAP_DMA | HW_CAP_MME |
284262306a36Sopenharmony_ci						HW_CAP_GOLDEN | HW_CAP_TPC);
284362306a36Sopenharmony_ci		WREG32(mmGIC_DISTRIBUTOR__5_GICD_SETSPI_NSR,
284462306a36Sopenharmony_ci				GOYA_ASYNC_EVENT_ID_SOFT_RESET);
284562306a36Sopenharmony_ci		return 0;
284662306a36Sopenharmony_ci	}
284762306a36Sopenharmony_ci
284862306a36Sopenharmony_ci	/* Chicken bit to re-initiate boot sequencer flow */
284962306a36Sopenharmony_ci	WREG32(mmPSOC_GLOBAL_CONF_BOOT_SEQ_RE_START,
285062306a36Sopenharmony_ci		1 << PSOC_GLOBAL_CONF_BOOT_SEQ_RE_START_IND_SHIFT);
285162306a36Sopenharmony_ci	/* Move boot manager FSM to pre boot sequencer init state */
285262306a36Sopenharmony_ci	WREG32(mmPSOC_GLOBAL_CONF_SW_BTM_FSM,
285362306a36Sopenharmony_ci			0xA << PSOC_GLOBAL_CONF_SW_BTM_FSM_CTRL_SHIFT);
285462306a36Sopenharmony_ci
285562306a36Sopenharmony_ci	if (goya) {
285662306a36Sopenharmony_ci		goya->hw_cap_initialized &= ~(HW_CAP_CPU | HW_CAP_CPU_Q |
285762306a36Sopenharmony_ci				HW_CAP_DDR_0 | HW_CAP_DDR_1 |
285862306a36Sopenharmony_ci				HW_CAP_DMA | HW_CAP_MME |
285962306a36Sopenharmony_ci				HW_CAP_MMU | HW_CAP_TPC_MBIST |
286062306a36Sopenharmony_ci				HW_CAP_GOLDEN | HW_CAP_TPC);
286162306a36Sopenharmony_ci
286262306a36Sopenharmony_ci		memset(goya->events_stat, 0, sizeof(goya->events_stat));
286362306a36Sopenharmony_ci	}
286462306a36Sopenharmony_ci	return 0;
286562306a36Sopenharmony_ci}
286662306a36Sopenharmony_ci
286762306a36Sopenharmony_ciint goya_suspend(struct hl_device *hdev)
286862306a36Sopenharmony_ci{
286962306a36Sopenharmony_ci	int rc;
287062306a36Sopenharmony_ci
287162306a36Sopenharmony_ci	rc = hl_fw_send_pci_access_msg(hdev, CPUCP_PACKET_DISABLE_PCI_ACCESS, 0x0);
287262306a36Sopenharmony_ci	if (rc)
287362306a36Sopenharmony_ci		dev_err(hdev->dev, "Failed to disable PCI access from CPU\n");
287462306a36Sopenharmony_ci
287562306a36Sopenharmony_ci	return rc;
287662306a36Sopenharmony_ci}
287762306a36Sopenharmony_ci
287862306a36Sopenharmony_ciint goya_resume(struct hl_device *hdev)
287962306a36Sopenharmony_ci{
288062306a36Sopenharmony_ci	return goya_init_iatu(hdev);
288162306a36Sopenharmony_ci}
288262306a36Sopenharmony_ci
288362306a36Sopenharmony_cistatic int goya_mmap(struct hl_device *hdev, struct vm_area_struct *vma,
288462306a36Sopenharmony_ci			void *cpu_addr, dma_addr_t dma_addr, size_t size)
288562306a36Sopenharmony_ci{
288662306a36Sopenharmony_ci	int rc;
288762306a36Sopenharmony_ci
288862306a36Sopenharmony_ci	vm_flags_set(vma, VM_IO | VM_PFNMAP | VM_DONTEXPAND | VM_DONTDUMP |
288962306a36Sopenharmony_ci			VM_DONTCOPY | VM_NORESERVE);
289062306a36Sopenharmony_ci
289162306a36Sopenharmony_ci	rc = dma_mmap_coherent(hdev->dev, vma, cpu_addr,
289262306a36Sopenharmony_ci				(dma_addr - HOST_PHYS_BASE), size);
289362306a36Sopenharmony_ci	if (rc)
289462306a36Sopenharmony_ci		dev_err(hdev->dev, "dma_mmap_coherent error %d", rc);
289562306a36Sopenharmony_ci
289662306a36Sopenharmony_ci	return rc;
289762306a36Sopenharmony_ci}
289862306a36Sopenharmony_ci
289962306a36Sopenharmony_civoid goya_ring_doorbell(struct hl_device *hdev, u32 hw_queue_id, u32 pi)
290062306a36Sopenharmony_ci{
290162306a36Sopenharmony_ci	u32 db_reg_offset, db_value;
290262306a36Sopenharmony_ci
290362306a36Sopenharmony_ci	switch (hw_queue_id) {
290462306a36Sopenharmony_ci	case GOYA_QUEUE_ID_DMA_0:
290562306a36Sopenharmony_ci		db_reg_offset = mmDMA_QM_0_PQ_PI;
290662306a36Sopenharmony_ci		break;
290762306a36Sopenharmony_ci
290862306a36Sopenharmony_ci	case GOYA_QUEUE_ID_DMA_1:
290962306a36Sopenharmony_ci		db_reg_offset = mmDMA_QM_1_PQ_PI;
291062306a36Sopenharmony_ci		break;
291162306a36Sopenharmony_ci
291262306a36Sopenharmony_ci	case GOYA_QUEUE_ID_DMA_2:
291362306a36Sopenharmony_ci		db_reg_offset = mmDMA_QM_2_PQ_PI;
291462306a36Sopenharmony_ci		break;
291562306a36Sopenharmony_ci
291662306a36Sopenharmony_ci	case GOYA_QUEUE_ID_DMA_3:
291762306a36Sopenharmony_ci		db_reg_offset = mmDMA_QM_3_PQ_PI;
291862306a36Sopenharmony_ci		break;
291962306a36Sopenharmony_ci
292062306a36Sopenharmony_ci	case GOYA_QUEUE_ID_DMA_4:
292162306a36Sopenharmony_ci		db_reg_offset = mmDMA_QM_4_PQ_PI;
292262306a36Sopenharmony_ci		break;
292362306a36Sopenharmony_ci
292462306a36Sopenharmony_ci	case GOYA_QUEUE_ID_CPU_PQ:
292562306a36Sopenharmony_ci		db_reg_offset = mmCPU_IF_PF_PQ_PI;
292662306a36Sopenharmony_ci		break;
292762306a36Sopenharmony_ci
292862306a36Sopenharmony_ci	case GOYA_QUEUE_ID_MME:
292962306a36Sopenharmony_ci		db_reg_offset = mmMME_QM_PQ_PI;
293062306a36Sopenharmony_ci		break;
293162306a36Sopenharmony_ci
293262306a36Sopenharmony_ci	case GOYA_QUEUE_ID_TPC0:
293362306a36Sopenharmony_ci		db_reg_offset = mmTPC0_QM_PQ_PI;
293462306a36Sopenharmony_ci		break;
293562306a36Sopenharmony_ci
293662306a36Sopenharmony_ci	case GOYA_QUEUE_ID_TPC1:
293762306a36Sopenharmony_ci		db_reg_offset = mmTPC1_QM_PQ_PI;
293862306a36Sopenharmony_ci		break;
293962306a36Sopenharmony_ci
294062306a36Sopenharmony_ci	case GOYA_QUEUE_ID_TPC2:
294162306a36Sopenharmony_ci		db_reg_offset = mmTPC2_QM_PQ_PI;
294262306a36Sopenharmony_ci		break;
294362306a36Sopenharmony_ci
294462306a36Sopenharmony_ci	case GOYA_QUEUE_ID_TPC3:
294562306a36Sopenharmony_ci		db_reg_offset = mmTPC3_QM_PQ_PI;
294662306a36Sopenharmony_ci		break;
294762306a36Sopenharmony_ci
294862306a36Sopenharmony_ci	case GOYA_QUEUE_ID_TPC4:
294962306a36Sopenharmony_ci		db_reg_offset = mmTPC4_QM_PQ_PI;
295062306a36Sopenharmony_ci		break;
295162306a36Sopenharmony_ci
295262306a36Sopenharmony_ci	case GOYA_QUEUE_ID_TPC5:
295362306a36Sopenharmony_ci		db_reg_offset = mmTPC5_QM_PQ_PI;
295462306a36Sopenharmony_ci		break;
295562306a36Sopenharmony_ci
295662306a36Sopenharmony_ci	case GOYA_QUEUE_ID_TPC6:
295762306a36Sopenharmony_ci		db_reg_offset = mmTPC6_QM_PQ_PI;
295862306a36Sopenharmony_ci		break;
295962306a36Sopenharmony_ci
296062306a36Sopenharmony_ci	case GOYA_QUEUE_ID_TPC7:
296162306a36Sopenharmony_ci		db_reg_offset = mmTPC7_QM_PQ_PI;
296262306a36Sopenharmony_ci		break;
296362306a36Sopenharmony_ci
296462306a36Sopenharmony_ci	default:
296562306a36Sopenharmony_ci		/* Should never get here */
296662306a36Sopenharmony_ci		dev_err(hdev->dev, "H/W queue %d is invalid. Can't set pi\n",
296762306a36Sopenharmony_ci			hw_queue_id);
296862306a36Sopenharmony_ci		return;
296962306a36Sopenharmony_ci	}
297062306a36Sopenharmony_ci
297162306a36Sopenharmony_ci	db_value = pi;
297262306a36Sopenharmony_ci
297362306a36Sopenharmony_ci	/* ring the doorbell */
297462306a36Sopenharmony_ci	WREG32(db_reg_offset, db_value);
297562306a36Sopenharmony_ci
297662306a36Sopenharmony_ci	if (hw_queue_id == GOYA_QUEUE_ID_CPU_PQ) {
297762306a36Sopenharmony_ci		/* make sure device CPU will read latest data from host */
297862306a36Sopenharmony_ci		mb();
297962306a36Sopenharmony_ci		WREG32(mmGIC_DISTRIBUTOR__5_GICD_SETSPI_NSR,
298062306a36Sopenharmony_ci				GOYA_ASYNC_EVENT_ID_PI_UPDATE);
298162306a36Sopenharmony_ci	}
298262306a36Sopenharmony_ci}
298362306a36Sopenharmony_ci
298462306a36Sopenharmony_civoid goya_pqe_write(struct hl_device *hdev, __le64 *pqe, struct hl_bd *bd)
298562306a36Sopenharmony_ci{
298662306a36Sopenharmony_ci	/* The QMANs are on the SRAM so need to copy to IO space */
298762306a36Sopenharmony_ci	memcpy_toio((void __iomem *) pqe, bd, sizeof(struct hl_bd));
298862306a36Sopenharmony_ci}
298962306a36Sopenharmony_ci
299062306a36Sopenharmony_cistatic void *goya_dma_alloc_coherent(struct hl_device *hdev, size_t size,
299162306a36Sopenharmony_ci					dma_addr_t *dma_handle, gfp_t flags)
299262306a36Sopenharmony_ci{
299362306a36Sopenharmony_ci	void *kernel_addr = dma_alloc_coherent(&hdev->pdev->dev, size,
299462306a36Sopenharmony_ci						dma_handle, flags);
299562306a36Sopenharmony_ci
299662306a36Sopenharmony_ci	/* Shift to the device's base physical address of host memory */
299762306a36Sopenharmony_ci	if (kernel_addr)
299862306a36Sopenharmony_ci		*dma_handle += HOST_PHYS_BASE;
299962306a36Sopenharmony_ci
300062306a36Sopenharmony_ci	return kernel_addr;
300162306a36Sopenharmony_ci}
300262306a36Sopenharmony_ci
300362306a36Sopenharmony_cistatic void goya_dma_free_coherent(struct hl_device *hdev, size_t size,
300462306a36Sopenharmony_ci					void *cpu_addr, dma_addr_t dma_handle)
300562306a36Sopenharmony_ci{
300662306a36Sopenharmony_ci	/* Cancel the device's base physical address of host memory */
300762306a36Sopenharmony_ci	dma_addr_t fixed_dma_handle = dma_handle - HOST_PHYS_BASE;
300862306a36Sopenharmony_ci
300962306a36Sopenharmony_ci	dma_free_coherent(&hdev->pdev->dev, size, cpu_addr, fixed_dma_handle);
301062306a36Sopenharmony_ci}
301162306a36Sopenharmony_ci
301262306a36Sopenharmony_ciint goya_scrub_device_mem(struct hl_device *hdev)
301362306a36Sopenharmony_ci{
301462306a36Sopenharmony_ci	return 0;
301562306a36Sopenharmony_ci}
301662306a36Sopenharmony_ci
301762306a36Sopenharmony_civoid *goya_get_int_queue_base(struct hl_device *hdev, u32 queue_id,
301862306a36Sopenharmony_ci				dma_addr_t *dma_handle,	u16 *queue_len)
301962306a36Sopenharmony_ci{
302062306a36Sopenharmony_ci	void *base;
302162306a36Sopenharmony_ci	u32 offset;
302262306a36Sopenharmony_ci
302362306a36Sopenharmony_ci	*dma_handle = hdev->asic_prop.sram_base_address;
302462306a36Sopenharmony_ci
302562306a36Sopenharmony_ci	base = (__force void *) hdev->pcie_bar[SRAM_CFG_BAR_ID];
302662306a36Sopenharmony_ci
302762306a36Sopenharmony_ci	switch (queue_id) {
302862306a36Sopenharmony_ci	case GOYA_QUEUE_ID_MME:
302962306a36Sopenharmony_ci		offset = MME_QMAN_BASE_OFFSET;
303062306a36Sopenharmony_ci		*queue_len = MME_QMAN_LENGTH;
303162306a36Sopenharmony_ci		break;
303262306a36Sopenharmony_ci	case GOYA_QUEUE_ID_TPC0:
303362306a36Sopenharmony_ci		offset = TPC0_QMAN_BASE_OFFSET;
303462306a36Sopenharmony_ci		*queue_len = TPC_QMAN_LENGTH;
303562306a36Sopenharmony_ci		break;
303662306a36Sopenharmony_ci	case GOYA_QUEUE_ID_TPC1:
303762306a36Sopenharmony_ci		offset = TPC1_QMAN_BASE_OFFSET;
303862306a36Sopenharmony_ci		*queue_len = TPC_QMAN_LENGTH;
303962306a36Sopenharmony_ci		break;
304062306a36Sopenharmony_ci	case GOYA_QUEUE_ID_TPC2:
304162306a36Sopenharmony_ci		offset = TPC2_QMAN_BASE_OFFSET;
304262306a36Sopenharmony_ci		*queue_len = TPC_QMAN_LENGTH;
304362306a36Sopenharmony_ci		break;
304462306a36Sopenharmony_ci	case GOYA_QUEUE_ID_TPC3:
304562306a36Sopenharmony_ci		offset = TPC3_QMAN_BASE_OFFSET;
304662306a36Sopenharmony_ci		*queue_len = TPC_QMAN_LENGTH;
304762306a36Sopenharmony_ci		break;
304862306a36Sopenharmony_ci	case GOYA_QUEUE_ID_TPC4:
304962306a36Sopenharmony_ci		offset = TPC4_QMAN_BASE_OFFSET;
305062306a36Sopenharmony_ci		*queue_len = TPC_QMAN_LENGTH;
305162306a36Sopenharmony_ci		break;
305262306a36Sopenharmony_ci	case GOYA_QUEUE_ID_TPC5:
305362306a36Sopenharmony_ci		offset = TPC5_QMAN_BASE_OFFSET;
305462306a36Sopenharmony_ci		*queue_len = TPC_QMAN_LENGTH;
305562306a36Sopenharmony_ci		break;
305662306a36Sopenharmony_ci	case GOYA_QUEUE_ID_TPC6:
305762306a36Sopenharmony_ci		offset = TPC6_QMAN_BASE_OFFSET;
305862306a36Sopenharmony_ci		*queue_len = TPC_QMAN_LENGTH;
305962306a36Sopenharmony_ci		break;
306062306a36Sopenharmony_ci	case GOYA_QUEUE_ID_TPC7:
306162306a36Sopenharmony_ci		offset = TPC7_QMAN_BASE_OFFSET;
306262306a36Sopenharmony_ci		*queue_len = TPC_QMAN_LENGTH;
306362306a36Sopenharmony_ci		break;
306462306a36Sopenharmony_ci	default:
306562306a36Sopenharmony_ci		dev_err(hdev->dev, "Got invalid queue id %d\n", queue_id);
306662306a36Sopenharmony_ci		return NULL;
306762306a36Sopenharmony_ci	}
306862306a36Sopenharmony_ci
306962306a36Sopenharmony_ci	base += offset;
307062306a36Sopenharmony_ci	*dma_handle += offset;
307162306a36Sopenharmony_ci
307262306a36Sopenharmony_ci	return base;
307362306a36Sopenharmony_ci}
307462306a36Sopenharmony_ci
307562306a36Sopenharmony_cistatic int goya_send_job_on_qman0(struct hl_device *hdev, struct hl_cs_job *job)
307662306a36Sopenharmony_ci{
307762306a36Sopenharmony_ci	struct packet_msg_prot *fence_pkt;
307862306a36Sopenharmony_ci	u32 *fence_ptr;
307962306a36Sopenharmony_ci	dma_addr_t fence_dma_addr;
308062306a36Sopenharmony_ci	struct hl_cb *cb;
308162306a36Sopenharmony_ci	u32 tmp, timeout;
308262306a36Sopenharmony_ci	int rc;
308362306a36Sopenharmony_ci
308462306a36Sopenharmony_ci	if (hdev->pldm)
308562306a36Sopenharmony_ci		timeout = GOYA_PLDM_QMAN0_TIMEOUT_USEC;
308662306a36Sopenharmony_ci	else
308762306a36Sopenharmony_ci		timeout = HL_DEVICE_TIMEOUT_USEC;
308862306a36Sopenharmony_ci
308962306a36Sopenharmony_ci	if (!hdev->asic_funcs->is_device_idle(hdev, NULL, 0, NULL)) {
309062306a36Sopenharmony_ci		dev_err_ratelimited(hdev->dev,
309162306a36Sopenharmony_ci			"Can't send driver job on QMAN0 because the device is not idle\n");
309262306a36Sopenharmony_ci		return -EBUSY;
309362306a36Sopenharmony_ci	}
309462306a36Sopenharmony_ci
309562306a36Sopenharmony_ci	fence_ptr = hl_asic_dma_pool_zalloc(hdev, 4, GFP_KERNEL, &fence_dma_addr);
309662306a36Sopenharmony_ci	if (!fence_ptr) {
309762306a36Sopenharmony_ci		dev_err(hdev->dev,
309862306a36Sopenharmony_ci			"Failed to allocate fence memory for QMAN0\n");
309962306a36Sopenharmony_ci		return -ENOMEM;
310062306a36Sopenharmony_ci	}
310162306a36Sopenharmony_ci
310262306a36Sopenharmony_ci	goya_qman0_set_security(hdev, true);
310362306a36Sopenharmony_ci
310462306a36Sopenharmony_ci	cb = job->patched_cb;
310562306a36Sopenharmony_ci
310662306a36Sopenharmony_ci	fence_pkt = cb->kernel_address +
310762306a36Sopenharmony_ci			job->job_cb_size - sizeof(struct packet_msg_prot);
310862306a36Sopenharmony_ci
310962306a36Sopenharmony_ci	tmp = (PACKET_MSG_PROT << GOYA_PKT_CTL_OPCODE_SHIFT) |
311062306a36Sopenharmony_ci			(1 << GOYA_PKT_CTL_EB_SHIFT) |
311162306a36Sopenharmony_ci			(1 << GOYA_PKT_CTL_MB_SHIFT);
311262306a36Sopenharmony_ci	fence_pkt->ctl = cpu_to_le32(tmp);
311362306a36Sopenharmony_ci	fence_pkt->value = cpu_to_le32(GOYA_QMAN0_FENCE_VAL);
311462306a36Sopenharmony_ci	fence_pkt->addr = cpu_to_le64(fence_dma_addr);
311562306a36Sopenharmony_ci
311662306a36Sopenharmony_ci	rc = hl_hw_queue_send_cb_no_cmpl(hdev, GOYA_QUEUE_ID_DMA_0,
311762306a36Sopenharmony_ci					job->job_cb_size, cb->bus_address);
311862306a36Sopenharmony_ci	if (rc) {
311962306a36Sopenharmony_ci		dev_err(hdev->dev, "Failed to send CB on QMAN0, %d\n", rc);
312062306a36Sopenharmony_ci		goto free_fence_ptr;
312162306a36Sopenharmony_ci	}
312262306a36Sopenharmony_ci
312362306a36Sopenharmony_ci	rc = hl_poll_timeout_memory(hdev, fence_ptr, tmp,
312462306a36Sopenharmony_ci				(tmp == GOYA_QMAN0_FENCE_VAL), 1000,
312562306a36Sopenharmony_ci				timeout, true);
312662306a36Sopenharmony_ci
312762306a36Sopenharmony_ci	hl_hw_queue_inc_ci_kernel(hdev, GOYA_QUEUE_ID_DMA_0);
312862306a36Sopenharmony_ci
312962306a36Sopenharmony_ci	if (rc == -ETIMEDOUT) {
313062306a36Sopenharmony_ci		dev_err(hdev->dev, "QMAN0 Job timeout (0x%x)\n", tmp);
313162306a36Sopenharmony_ci		goto free_fence_ptr;
313262306a36Sopenharmony_ci	}
313362306a36Sopenharmony_ci
313462306a36Sopenharmony_cifree_fence_ptr:
313562306a36Sopenharmony_ci	hl_asic_dma_pool_free(hdev, (void *) fence_ptr, fence_dma_addr);
313662306a36Sopenharmony_ci
313762306a36Sopenharmony_ci	goya_qman0_set_security(hdev, false);
313862306a36Sopenharmony_ci
313962306a36Sopenharmony_ci	return rc;
314062306a36Sopenharmony_ci}
314162306a36Sopenharmony_ci
314262306a36Sopenharmony_ciint goya_send_cpu_message(struct hl_device *hdev, u32 *msg, u16 len,
314362306a36Sopenharmony_ci				u32 timeout, u64 *result)
314462306a36Sopenharmony_ci{
314562306a36Sopenharmony_ci	struct goya_device *goya = hdev->asic_specific;
314662306a36Sopenharmony_ci
314762306a36Sopenharmony_ci	if (!(goya->hw_cap_initialized & HW_CAP_CPU_Q)) {
314862306a36Sopenharmony_ci		if (result)
314962306a36Sopenharmony_ci			*result = 0;
315062306a36Sopenharmony_ci		return 0;
315162306a36Sopenharmony_ci	}
315262306a36Sopenharmony_ci
315362306a36Sopenharmony_ci	if (!timeout)
315462306a36Sopenharmony_ci		timeout = GOYA_MSG_TO_CPU_TIMEOUT_USEC;
315562306a36Sopenharmony_ci
315662306a36Sopenharmony_ci	return hl_fw_send_cpu_message(hdev, GOYA_QUEUE_ID_CPU_PQ, msg, len,
315762306a36Sopenharmony_ci					timeout, result);
315862306a36Sopenharmony_ci}
315962306a36Sopenharmony_ci
316062306a36Sopenharmony_ciint goya_test_queue(struct hl_device *hdev, u32 hw_queue_id)
316162306a36Sopenharmony_ci{
316262306a36Sopenharmony_ci	struct packet_msg_prot *fence_pkt;
316362306a36Sopenharmony_ci	dma_addr_t pkt_dma_addr;
316462306a36Sopenharmony_ci	u32 fence_val, tmp;
316562306a36Sopenharmony_ci	dma_addr_t fence_dma_addr;
316662306a36Sopenharmony_ci	u32 *fence_ptr;
316762306a36Sopenharmony_ci	int rc;
316862306a36Sopenharmony_ci
316962306a36Sopenharmony_ci	fence_val = GOYA_QMAN0_FENCE_VAL;
317062306a36Sopenharmony_ci
317162306a36Sopenharmony_ci	fence_ptr = hl_asic_dma_pool_zalloc(hdev, 4, GFP_KERNEL, &fence_dma_addr);
317262306a36Sopenharmony_ci	if (!fence_ptr) {
317362306a36Sopenharmony_ci		dev_err(hdev->dev,
317462306a36Sopenharmony_ci			"Failed to allocate memory for H/W queue %d testing\n",
317562306a36Sopenharmony_ci			hw_queue_id);
317662306a36Sopenharmony_ci		return -ENOMEM;
317762306a36Sopenharmony_ci	}
317862306a36Sopenharmony_ci
317962306a36Sopenharmony_ci	*fence_ptr = 0;
318062306a36Sopenharmony_ci
318162306a36Sopenharmony_ci	fence_pkt = hl_asic_dma_pool_zalloc(hdev, sizeof(struct packet_msg_prot), GFP_KERNEL,
318262306a36Sopenharmony_ci						&pkt_dma_addr);
318362306a36Sopenharmony_ci	if (!fence_pkt) {
318462306a36Sopenharmony_ci		dev_err(hdev->dev,
318562306a36Sopenharmony_ci			"Failed to allocate packet for H/W queue %d testing\n",
318662306a36Sopenharmony_ci			hw_queue_id);
318762306a36Sopenharmony_ci		rc = -ENOMEM;
318862306a36Sopenharmony_ci		goto free_fence_ptr;
318962306a36Sopenharmony_ci	}
319062306a36Sopenharmony_ci
319162306a36Sopenharmony_ci	tmp = (PACKET_MSG_PROT << GOYA_PKT_CTL_OPCODE_SHIFT) |
319262306a36Sopenharmony_ci			(1 << GOYA_PKT_CTL_EB_SHIFT) |
319362306a36Sopenharmony_ci			(1 << GOYA_PKT_CTL_MB_SHIFT);
319462306a36Sopenharmony_ci	fence_pkt->ctl = cpu_to_le32(tmp);
319562306a36Sopenharmony_ci	fence_pkt->value = cpu_to_le32(fence_val);
319662306a36Sopenharmony_ci	fence_pkt->addr = cpu_to_le64(fence_dma_addr);
319762306a36Sopenharmony_ci
319862306a36Sopenharmony_ci	rc = hl_hw_queue_send_cb_no_cmpl(hdev, hw_queue_id,
319962306a36Sopenharmony_ci					sizeof(struct packet_msg_prot),
320062306a36Sopenharmony_ci					pkt_dma_addr);
320162306a36Sopenharmony_ci	if (rc) {
320262306a36Sopenharmony_ci		dev_err(hdev->dev,
320362306a36Sopenharmony_ci			"Failed to send fence packet to H/W queue %d\n",
320462306a36Sopenharmony_ci			hw_queue_id);
320562306a36Sopenharmony_ci		goto free_pkt;
320662306a36Sopenharmony_ci	}
320762306a36Sopenharmony_ci
320862306a36Sopenharmony_ci	rc = hl_poll_timeout_memory(hdev, fence_ptr, tmp, (tmp == fence_val),
320962306a36Sopenharmony_ci					1000, GOYA_TEST_QUEUE_WAIT_USEC, true);
321062306a36Sopenharmony_ci
321162306a36Sopenharmony_ci	hl_hw_queue_inc_ci_kernel(hdev, hw_queue_id);
321262306a36Sopenharmony_ci
321362306a36Sopenharmony_ci	if (rc == -ETIMEDOUT) {
321462306a36Sopenharmony_ci		dev_err(hdev->dev,
321562306a36Sopenharmony_ci			"H/W queue %d test failed (scratch(0x%08llX) == 0x%08X)\n",
321662306a36Sopenharmony_ci			hw_queue_id, (unsigned long long) fence_dma_addr, tmp);
321762306a36Sopenharmony_ci		rc = -EIO;
321862306a36Sopenharmony_ci	}
321962306a36Sopenharmony_ci
322062306a36Sopenharmony_cifree_pkt:
322162306a36Sopenharmony_ci	hl_asic_dma_pool_free(hdev, (void *) fence_pkt, pkt_dma_addr);
322262306a36Sopenharmony_cifree_fence_ptr:
322362306a36Sopenharmony_ci	hl_asic_dma_pool_free(hdev, (void *) fence_ptr, fence_dma_addr);
322462306a36Sopenharmony_ci	return rc;
322562306a36Sopenharmony_ci}
322662306a36Sopenharmony_ci
322762306a36Sopenharmony_ciint goya_test_cpu_queue(struct hl_device *hdev)
322862306a36Sopenharmony_ci{
322962306a36Sopenharmony_ci	struct goya_device *goya = hdev->asic_specific;
323062306a36Sopenharmony_ci
323162306a36Sopenharmony_ci	/*
323262306a36Sopenharmony_ci	 * check capability here as send_cpu_message() won't update the result
323362306a36Sopenharmony_ci	 * value if no capability
323462306a36Sopenharmony_ci	 */
323562306a36Sopenharmony_ci	if (!(goya->hw_cap_initialized & HW_CAP_CPU_Q))
323662306a36Sopenharmony_ci		return 0;
323762306a36Sopenharmony_ci
323862306a36Sopenharmony_ci	return hl_fw_test_cpu_queue(hdev);
323962306a36Sopenharmony_ci}
324062306a36Sopenharmony_ci
324162306a36Sopenharmony_ciint goya_test_queues(struct hl_device *hdev)
324262306a36Sopenharmony_ci{
324362306a36Sopenharmony_ci	int i, rc, ret_val = 0;
324462306a36Sopenharmony_ci
324562306a36Sopenharmony_ci	for (i = 0 ; i < NUMBER_OF_EXT_HW_QUEUES ; i++) {
324662306a36Sopenharmony_ci		rc = goya_test_queue(hdev, i);
324762306a36Sopenharmony_ci		if (rc)
324862306a36Sopenharmony_ci			ret_val = -EINVAL;
324962306a36Sopenharmony_ci	}
325062306a36Sopenharmony_ci
325162306a36Sopenharmony_ci	return ret_val;
325262306a36Sopenharmony_ci}
325362306a36Sopenharmony_ci
325462306a36Sopenharmony_cistatic void *goya_dma_pool_zalloc(struct hl_device *hdev, size_t size,
325562306a36Sopenharmony_ci					gfp_t mem_flags, dma_addr_t *dma_handle)
325662306a36Sopenharmony_ci{
325762306a36Sopenharmony_ci	void *kernel_addr;
325862306a36Sopenharmony_ci
325962306a36Sopenharmony_ci	if (size > GOYA_DMA_POOL_BLK_SIZE)
326062306a36Sopenharmony_ci		return NULL;
326162306a36Sopenharmony_ci
326262306a36Sopenharmony_ci	kernel_addr =  dma_pool_zalloc(hdev->dma_pool, mem_flags, dma_handle);
326362306a36Sopenharmony_ci
326462306a36Sopenharmony_ci	/* Shift to the device's base physical address of host memory */
326562306a36Sopenharmony_ci	if (kernel_addr)
326662306a36Sopenharmony_ci		*dma_handle += HOST_PHYS_BASE;
326762306a36Sopenharmony_ci
326862306a36Sopenharmony_ci	return kernel_addr;
326962306a36Sopenharmony_ci}
327062306a36Sopenharmony_ci
327162306a36Sopenharmony_cistatic void goya_dma_pool_free(struct hl_device *hdev, void *vaddr,
327262306a36Sopenharmony_ci				dma_addr_t dma_addr)
327362306a36Sopenharmony_ci{
327462306a36Sopenharmony_ci	/* Cancel the device's base physical address of host memory */
327562306a36Sopenharmony_ci	dma_addr_t fixed_dma_addr = dma_addr - HOST_PHYS_BASE;
327662306a36Sopenharmony_ci
327762306a36Sopenharmony_ci	dma_pool_free(hdev->dma_pool, vaddr, fixed_dma_addr);
327862306a36Sopenharmony_ci}
327962306a36Sopenharmony_ci
328062306a36Sopenharmony_civoid *goya_cpu_accessible_dma_pool_alloc(struct hl_device *hdev, size_t size,
328162306a36Sopenharmony_ci					dma_addr_t *dma_handle)
328262306a36Sopenharmony_ci{
328362306a36Sopenharmony_ci	void *vaddr;
328462306a36Sopenharmony_ci
328562306a36Sopenharmony_ci	vaddr = hl_fw_cpu_accessible_dma_pool_alloc(hdev, size, dma_handle);
328662306a36Sopenharmony_ci	*dma_handle = (*dma_handle) - hdev->cpu_accessible_dma_address +
328762306a36Sopenharmony_ci			VA_CPU_ACCESSIBLE_MEM_ADDR;
328862306a36Sopenharmony_ci
328962306a36Sopenharmony_ci	return vaddr;
329062306a36Sopenharmony_ci}
329162306a36Sopenharmony_ci
329262306a36Sopenharmony_civoid goya_cpu_accessible_dma_pool_free(struct hl_device *hdev, size_t size,
329362306a36Sopenharmony_ci					void *vaddr)
329462306a36Sopenharmony_ci{
329562306a36Sopenharmony_ci	hl_fw_cpu_accessible_dma_pool_free(hdev, size, vaddr);
329662306a36Sopenharmony_ci}
329762306a36Sopenharmony_ci
329862306a36Sopenharmony_ciu32 goya_get_dma_desc_list_size(struct hl_device *hdev, struct sg_table *sgt)
329962306a36Sopenharmony_ci{
330062306a36Sopenharmony_ci	struct scatterlist *sg, *sg_next_iter;
330162306a36Sopenharmony_ci	u32 count, dma_desc_cnt;
330262306a36Sopenharmony_ci	u64 len, len_next;
330362306a36Sopenharmony_ci	dma_addr_t addr, addr_next;
330462306a36Sopenharmony_ci
330562306a36Sopenharmony_ci	dma_desc_cnt = 0;
330662306a36Sopenharmony_ci
330762306a36Sopenharmony_ci	for_each_sgtable_dma_sg(sgt, sg, count) {
330862306a36Sopenharmony_ci		len = sg_dma_len(sg);
330962306a36Sopenharmony_ci		addr = sg_dma_address(sg);
331062306a36Sopenharmony_ci
331162306a36Sopenharmony_ci		if (len == 0)
331262306a36Sopenharmony_ci			break;
331362306a36Sopenharmony_ci
331462306a36Sopenharmony_ci		while ((count + 1) < sgt->nents) {
331562306a36Sopenharmony_ci			sg_next_iter = sg_next(sg);
331662306a36Sopenharmony_ci			len_next = sg_dma_len(sg_next_iter);
331762306a36Sopenharmony_ci			addr_next = sg_dma_address(sg_next_iter);
331862306a36Sopenharmony_ci
331962306a36Sopenharmony_ci			if (len_next == 0)
332062306a36Sopenharmony_ci				break;
332162306a36Sopenharmony_ci
332262306a36Sopenharmony_ci			if ((addr + len == addr_next) &&
332362306a36Sopenharmony_ci				(len + len_next <= DMA_MAX_TRANSFER_SIZE)) {
332462306a36Sopenharmony_ci				len += len_next;
332562306a36Sopenharmony_ci				count++;
332662306a36Sopenharmony_ci				sg = sg_next_iter;
332762306a36Sopenharmony_ci			} else {
332862306a36Sopenharmony_ci				break;
332962306a36Sopenharmony_ci			}
333062306a36Sopenharmony_ci		}
333162306a36Sopenharmony_ci
333262306a36Sopenharmony_ci		dma_desc_cnt++;
333362306a36Sopenharmony_ci	}
333462306a36Sopenharmony_ci
333562306a36Sopenharmony_ci	return dma_desc_cnt * sizeof(struct packet_lin_dma);
333662306a36Sopenharmony_ci}
333762306a36Sopenharmony_ci
333862306a36Sopenharmony_cistatic int goya_pin_memory_before_cs(struct hl_device *hdev,
333962306a36Sopenharmony_ci				struct hl_cs_parser *parser,
334062306a36Sopenharmony_ci				struct packet_lin_dma *user_dma_pkt,
334162306a36Sopenharmony_ci				u64 addr, enum dma_data_direction dir)
334262306a36Sopenharmony_ci{
334362306a36Sopenharmony_ci	struct hl_userptr *userptr;
334462306a36Sopenharmony_ci	int rc;
334562306a36Sopenharmony_ci
334662306a36Sopenharmony_ci	if (hl_userptr_is_pinned(hdev, addr, le32_to_cpu(user_dma_pkt->tsize),
334762306a36Sopenharmony_ci			parser->job_userptr_list, &userptr))
334862306a36Sopenharmony_ci		goto already_pinned;
334962306a36Sopenharmony_ci
335062306a36Sopenharmony_ci	userptr = kzalloc(sizeof(*userptr), GFP_KERNEL);
335162306a36Sopenharmony_ci	if (!userptr)
335262306a36Sopenharmony_ci		return -ENOMEM;
335362306a36Sopenharmony_ci
335462306a36Sopenharmony_ci	rc = hl_pin_host_memory(hdev, addr, le32_to_cpu(user_dma_pkt->tsize),
335562306a36Sopenharmony_ci				userptr);
335662306a36Sopenharmony_ci	if (rc)
335762306a36Sopenharmony_ci		goto free_userptr;
335862306a36Sopenharmony_ci
335962306a36Sopenharmony_ci	list_add_tail(&userptr->job_node, parser->job_userptr_list);
336062306a36Sopenharmony_ci
336162306a36Sopenharmony_ci	rc = hdev->asic_funcs->asic_dma_map_sgtable(hdev, userptr->sgt, dir);
336262306a36Sopenharmony_ci	if (rc) {
336362306a36Sopenharmony_ci		dev_err(hdev->dev, "failed to map sgt with DMA region\n");
336462306a36Sopenharmony_ci		goto unpin_memory;
336562306a36Sopenharmony_ci	}
336662306a36Sopenharmony_ci
336762306a36Sopenharmony_ci	userptr->dma_mapped = true;
336862306a36Sopenharmony_ci	userptr->dir = dir;
336962306a36Sopenharmony_ci
337062306a36Sopenharmony_cialready_pinned:
337162306a36Sopenharmony_ci	parser->patched_cb_size +=
337262306a36Sopenharmony_ci			goya_get_dma_desc_list_size(hdev, userptr->sgt);
337362306a36Sopenharmony_ci
337462306a36Sopenharmony_ci	return 0;
337562306a36Sopenharmony_ci
337662306a36Sopenharmony_ciunpin_memory:
337762306a36Sopenharmony_ci	list_del(&userptr->job_node);
337862306a36Sopenharmony_ci	hl_unpin_host_memory(hdev, userptr);
337962306a36Sopenharmony_cifree_userptr:
338062306a36Sopenharmony_ci	kfree(userptr);
338162306a36Sopenharmony_ci	return rc;
338262306a36Sopenharmony_ci}
338362306a36Sopenharmony_ci
338462306a36Sopenharmony_cistatic int goya_validate_dma_pkt_host(struct hl_device *hdev,
338562306a36Sopenharmony_ci				struct hl_cs_parser *parser,
338662306a36Sopenharmony_ci				struct packet_lin_dma *user_dma_pkt)
338762306a36Sopenharmony_ci{
338862306a36Sopenharmony_ci	u64 device_memory_addr, addr;
338962306a36Sopenharmony_ci	enum dma_data_direction dir;
339062306a36Sopenharmony_ci	enum hl_goya_dma_direction user_dir;
339162306a36Sopenharmony_ci	bool sram_addr = true;
339262306a36Sopenharmony_ci	bool skip_host_mem_pin = false;
339362306a36Sopenharmony_ci	bool user_memset;
339462306a36Sopenharmony_ci	u32 ctl;
339562306a36Sopenharmony_ci	int rc = 0;
339662306a36Sopenharmony_ci
339762306a36Sopenharmony_ci	ctl = le32_to_cpu(user_dma_pkt->ctl);
339862306a36Sopenharmony_ci
339962306a36Sopenharmony_ci	user_dir = (ctl & GOYA_PKT_LIN_DMA_CTL_DMA_DIR_MASK) >>
340062306a36Sopenharmony_ci			GOYA_PKT_LIN_DMA_CTL_DMA_DIR_SHIFT;
340162306a36Sopenharmony_ci
340262306a36Sopenharmony_ci	user_memset = (ctl & GOYA_PKT_LIN_DMA_CTL_MEMSET_MASK) >>
340362306a36Sopenharmony_ci			GOYA_PKT_LIN_DMA_CTL_MEMSET_SHIFT;
340462306a36Sopenharmony_ci
340562306a36Sopenharmony_ci	switch (user_dir) {
340662306a36Sopenharmony_ci	case HL_DMA_HOST_TO_DRAM:
340762306a36Sopenharmony_ci		dev_dbg(hdev->dev, "DMA direction is HOST --> DRAM\n");
340862306a36Sopenharmony_ci		dir = DMA_TO_DEVICE;
340962306a36Sopenharmony_ci		sram_addr = false;
341062306a36Sopenharmony_ci		addr = le64_to_cpu(user_dma_pkt->src_addr);
341162306a36Sopenharmony_ci		device_memory_addr = le64_to_cpu(user_dma_pkt->dst_addr);
341262306a36Sopenharmony_ci		if (user_memset)
341362306a36Sopenharmony_ci			skip_host_mem_pin = true;
341462306a36Sopenharmony_ci		break;
341562306a36Sopenharmony_ci
341662306a36Sopenharmony_ci	case HL_DMA_DRAM_TO_HOST:
341762306a36Sopenharmony_ci		dev_dbg(hdev->dev, "DMA direction is DRAM --> HOST\n");
341862306a36Sopenharmony_ci		dir = DMA_FROM_DEVICE;
341962306a36Sopenharmony_ci		sram_addr = false;
342062306a36Sopenharmony_ci		addr = le64_to_cpu(user_dma_pkt->dst_addr);
342162306a36Sopenharmony_ci		device_memory_addr = le64_to_cpu(user_dma_pkt->src_addr);
342262306a36Sopenharmony_ci		break;
342362306a36Sopenharmony_ci
342462306a36Sopenharmony_ci	case HL_DMA_HOST_TO_SRAM:
342562306a36Sopenharmony_ci		dev_dbg(hdev->dev, "DMA direction is HOST --> SRAM\n");
342662306a36Sopenharmony_ci		dir = DMA_TO_DEVICE;
342762306a36Sopenharmony_ci		addr = le64_to_cpu(user_dma_pkt->src_addr);
342862306a36Sopenharmony_ci		device_memory_addr = le64_to_cpu(user_dma_pkt->dst_addr);
342962306a36Sopenharmony_ci		if (user_memset)
343062306a36Sopenharmony_ci			skip_host_mem_pin = true;
343162306a36Sopenharmony_ci		break;
343262306a36Sopenharmony_ci
343362306a36Sopenharmony_ci	case HL_DMA_SRAM_TO_HOST:
343462306a36Sopenharmony_ci		dev_dbg(hdev->dev, "DMA direction is SRAM --> HOST\n");
343562306a36Sopenharmony_ci		dir = DMA_FROM_DEVICE;
343662306a36Sopenharmony_ci		addr = le64_to_cpu(user_dma_pkt->dst_addr);
343762306a36Sopenharmony_ci		device_memory_addr = le64_to_cpu(user_dma_pkt->src_addr);
343862306a36Sopenharmony_ci		break;
343962306a36Sopenharmony_ci	default:
344062306a36Sopenharmony_ci		dev_err(hdev->dev, "DMA direction %d is unsupported/undefined\n", user_dir);
344162306a36Sopenharmony_ci		return -EFAULT;
344262306a36Sopenharmony_ci	}
344362306a36Sopenharmony_ci
344462306a36Sopenharmony_ci	if (sram_addr) {
344562306a36Sopenharmony_ci		if (!hl_mem_area_inside_range(device_memory_addr,
344662306a36Sopenharmony_ci				le32_to_cpu(user_dma_pkt->tsize),
344762306a36Sopenharmony_ci				hdev->asic_prop.sram_user_base_address,
344862306a36Sopenharmony_ci				hdev->asic_prop.sram_end_address)) {
344962306a36Sopenharmony_ci
345062306a36Sopenharmony_ci			dev_err(hdev->dev,
345162306a36Sopenharmony_ci				"SRAM address 0x%llx + 0x%x is invalid\n",
345262306a36Sopenharmony_ci				device_memory_addr,
345362306a36Sopenharmony_ci				user_dma_pkt->tsize);
345462306a36Sopenharmony_ci			return -EFAULT;
345562306a36Sopenharmony_ci		}
345662306a36Sopenharmony_ci	} else {
345762306a36Sopenharmony_ci		if (!hl_mem_area_inside_range(device_memory_addr,
345862306a36Sopenharmony_ci				le32_to_cpu(user_dma_pkt->tsize),
345962306a36Sopenharmony_ci				hdev->asic_prop.dram_user_base_address,
346062306a36Sopenharmony_ci				hdev->asic_prop.dram_end_address)) {
346162306a36Sopenharmony_ci
346262306a36Sopenharmony_ci			dev_err(hdev->dev,
346362306a36Sopenharmony_ci				"DRAM address 0x%llx + 0x%x is invalid\n",
346462306a36Sopenharmony_ci				device_memory_addr,
346562306a36Sopenharmony_ci				user_dma_pkt->tsize);
346662306a36Sopenharmony_ci			return -EFAULT;
346762306a36Sopenharmony_ci		}
346862306a36Sopenharmony_ci	}
346962306a36Sopenharmony_ci
347062306a36Sopenharmony_ci	if (skip_host_mem_pin)
347162306a36Sopenharmony_ci		parser->patched_cb_size += sizeof(*user_dma_pkt);
347262306a36Sopenharmony_ci	else {
347362306a36Sopenharmony_ci		if ((dir == DMA_TO_DEVICE) &&
347462306a36Sopenharmony_ci				(parser->hw_queue_id > GOYA_QUEUE_ID_DMA_1)) {
347562306a36Sopenharmony_ci			dev_err(hdev->dev,
347662306a36Sopenharmony_ci				"Can't DMA from host on queue other then 1\n");
347762306a36Sopenharmony_ci			return -EFAULT;
347862306a36Sopenharmony_ci		}
347962306a36Sopenharmony_ci
348062306a36Sopenharmony_ci		rc = goya_pin_memory_before_cs(hdev, parser, user_dma_pkt,
348162306a36Sopenharmony_ci						addr, dir);
348262306a36Sopenharmony_ci	}
348362306a36Sopenharmony_ci
348462306a36Sopenharmony_ci	return rc;
348562306a36Sopenharmony_ci}
348662306a36Sopenharmony_ci
348762306a36Sopenharmony_cistatic int goya_validate_dma_pkt_no_host(struct hl_device *hdev,
348862306a36Sopenharmony_ci				struct hl_cs_parser *parser,
348962306a36Sopenharmony_ci				struct packet_lin_dma *user_dma_pkt)
349062306a36Sopenharmony_ci{
349162306a36Sopenharmony_ci	u64 sram_memory_addr, dram_memory_addr;
349262306a36Sopenharmony_ci	enum hl_goya_dma_direction user_dir;
349362306a36Sopenharmony_ci	u32 ctl;
349462306a36Sopenharmony_ci
349562306a36Sopenharmony_ci	ctl = le32_to_cpu(user_dma_pkt->ctl);
349662306a36Sopenharmony_ci	user_dir = (ctl & GOYA_PKT_LIN_DMA_CTL_DMA_DIR_MASK) >>
349762306a36Sopenharmony_ci			GOYA_PKT_LIN_DMA_CTL_DMA_DIR_SHIFT;
349862306a36Sopenharmony_ci
349962306a36Sopenharmony_ci	if (user_dir == HL_DMA_DRAM_TO_SRAM) {
350062306a36Sopenharmony_ci		dev_dbg(hdev->dev, "DMA direction is DRAM --> SRAM\n");
350162306a36Sopenharmony_ci		dram_memory_addr = le64_to_cpu(user_dma_pkt->src_addr);
350262306a36Sopenharmony_ci		sram_memory_addr = le64_to_cpu(user_dma_pkt->dst_addr);
350362306a36Sopenharmony_ci	} else {
350462306a36Sopenharmony_ci		dev_dbg(hdev->dev, "DMA direction is SRAM --> DRAM\n");
350562306a36Sopenharmony_ci		sram_memory_addr = le64_to_cpu(user_dma_pkt->src_addr);
350662306a36Sopenharmony_ci		dram_memory_addr = le64_to_cpu(user_dma_pkt->dst_addr);
350762306a36Sopenharmony_ci	}
350862306a36Sopenharmony_ci
350962306a36Sopenharmony_ci	if (!hl_mem_area_inside_range(sram_memory_addr,
351062306a36Sopenharmony_ci				le32_to_cpu(user_dma_pkt->tsize),
351162306a36Sopenharmony_ci				hdev->asic_prop.sram_user_base_address,
351262306a36Sopenharmony_ci				hdev->asic_prop.sram_end_address)) {
351362306a36Sopenharmony_ci		dev_err(hdev->dev, "SRAM address 0x%llx + 0x%x is invalid\n",
351462306a36Sopenharmony_ci			sram_memory_addr, user_dma_pkt->tsize);
351562306a36Sopenharmony_ci		return -EFAULT;
351662306a36Sopenharmony_ci	}
351762306a36Sopenharmony_ci
351862306a36Sopenharmony_ci	if (!hl_mem_area_inside_range(dram_memory_addr,
351962306a36Sopenharmony_ci				le32_to_cpu(user_dma_pkt->tsize),
352062306a36Sopenharmony_ci				hdev->asic_prop.dram_user_base_address,
352162306a36Sopenharmony_ci				hdev->asic_prop.dram_end_address)) {
352262306a36Sopenharmony_ci		dev_err(hdev->dev, "DRAM address 0x%llx + 0x%x is invalid\n",
352362306a36Sopenharmony_ci			dram_memory_addr, user_dma_pkt->tsize);
352462306a36Sopenharmony_ci		return -EFAULT;
352562306a36Sopenharmony_ci	}
352662306a36Sopenharmony_ci
352762306a36Sopenharmony_ci	parser->patched_cb_size += sizeof(*user_dma_pkt);
352862306a36Sopenharmony_ci
352962306a36Sopenharmony_ci	return 0;
353062306a36Sopenharmony_ci}
353162306a36Sopenharmony_ci
353262306a36Sopenharmony_cistatic int goya_validate_dma_pkt_no_mmu(struct hl_device *hdev,
353362306a36Sopenharmony_ci				struct hl_cs_parser *parser,
353462306a36Sopenharmony_ci				struct packet_lin_dma *user_dma_pkt)
353562306a36Sopenharmony_ci{
353662306a36Sopenharmony_ci	enum hl_goya_dma_direction user_dir;
353762306a36Sopenharmony_ci	u32 ctl;
353862306a36Sopenharmony_ci	int rc;
353962306a36Sopenharmony_ci
354062306a36Sopenharmony_ci	dev_dbg(hdev->dev, "DMA packet details:\n");
354162306a36Sopenharmony_ci	dev_dbg(hdev->dev, "source == 0x%llx\n",
354262306a36Sopenharmony_ci		le64_to_cpu(user_dma_pkt->src_addr));
354362306a36Sopenharmony_ci	dev_dbg(hdev->dev, "destination == 0x%llx\n",
354462306a36Sopenharmony_ci		le64_to_cpu(user_dma_pkt->dst_addr));
354562306a36Sopenharmony_ci	dev_dbg(hdev->dev, "size == %u\n", le32_to_cpu(user_dma_pkt->tsize));
354662306a36Sopenharmony_ci
354762306a36Sopenharmony_ci	ctl = le32_to_cpu(user_dma_pkt->ctl);
354862306a36Sopenharmony_ci	user_dir = (ctl & GOYA_PKT_LIN_DMA_CTL_DMA_DIR_MASK) >>
354962306a36Sopenharmony_ci			GOYA_PKT_LIN_DMA_CTL_DMA_DIR_SHIFT;
355062306a36Sopenharmony_ci
355162306a36Sopenharmony_ci	/*
355262306a36Sopenharmony_ci	 * Special handling for DMA with size 0. The H/W has a bug where
355362306a36Sopenharmony_ci	 * this can cause the QMAN DMA to get stuck, so block it here.
355462306a36Sopenharmony_ci	 */
355562306a36Sopenharmony_ci	if (user_dma_pkt->tsize == 0) {
355662306a36Sopenharmony_ci		dev_err(hdev->dev,
355762306a36Sopenharmony_ci			"Got DMA with size 0, might reset the device\n");
355862306a36Sopenharmony_ci		return -EINVAL;
355962306a36Sopenharmony_ci	}
356062306a36Sopenharmony_ci
356162306a36Sopenharmony_ci	if ((user_dir == HL_DMA_DRAM_TO_SRAM) || (user_dir == HL_DMA_SRAM_TO_DRAM))
356262306a36Sopenharmony_ci		rc = goya_validate_dma_pkt_no_host(hdev, parser, user_dma_pkt);
356362306a36Sopenharmony_ci	else
356462306a36Sopenharmony_ci		rc = goya_validate_dma_pkt_host(hdev, parser, user_dma_pkt);
356562306a36Sopenharmony_ci
356662306a36Sopenharmony_ci	return rc;
356762306a36Sopenharmony_ci}
356862306a36Sopenharmony_ci
356962306a36Sopenharmony_cistatic int goya_validate_dma_pkt_mmu(struct hl_device *hdev,
357062306a36Sopenharmony_ci				struct hl_cs_parser *parser,
357162306a36Sopenharmony_ci				struct packet_lin_dma *user_dma_pkt)
357262306a36Sopenharmony_ci{
357362306a36Sopenharmony_ci	dev_dbg(hdev->dev, "DMA packet details:\n");
357462306a36Sopenharmony_ci	dev_dbg(hdev->dev, "source == 0x%llx\n",
357562306a36Sopenharmony_ci		le64_to_cpu(user_dma_pkt->src_addr));
357662306a36Sopenharmony_ci	dev_dbg(hdev->dev, "destination == 0x%llx\n",
357762306a36Sopenharmony_ci		le64_to_cpu(user_dma_pkt->dst_addr));
357862306a36Sopenharmony_ci	dev_dbg(hdev->dev, "size == %u\n", le32_to_cpu(user_dma_pkt->tsize));
357962306a36Sopenharmony_ci
358062306a36Sopenharmony_ci	/*
358162306a36Sopenharmony_ci	 * WA for HW-23.
358262306a36Sopenharmony_ci	 * We can't allow user to read from Host using QMANs other than 1.
358362306a36Sopenharmony_ci	 * PMMU and HPMMU addresses are equal, check only one of them.
358462306a36Sopenharmony_ci	 */
358562306a36Sopenharmony_ci	if (parser->hw_queue_id != GOYA_QUEUE_ID_DMA_1 &&
358662306a36Sopenharmony_ci		hl_mem_area_inside_range(le64_to_cpu(user_dma_pkt->src_addr),
358762306a36Sopenharmony_ci				le32_to_cpu(user_dma_pkt->tsize),
358862306a36Sopenharmony_ci				hdev->asic_prop.pmmu.start_addr,
358962306a36Sopenharmony_ci				hdev->asic_prop.pmmu.end_addr)) {
359062306a36Sopenharmony_ci		dev_err(hdev->dev,
359162306a36Sopenharmony_ci			"Can't DMA from host on queue other then 1\n");
359262306a36Sopenharmony_ci		return -EFAULT;
359362306a36Sopenharmony_ci	}
359462306a36Sopenharmony_ci
359562306a36Sopenharmony_ci	if (user_dma_pkt->tsize == 0) {
359662306a36Sopenharmony_ci		dev_err(hdev->dev,
359762306a36Sopenharmony_ci			"Got DMA with size 0, might reset the device\n");
359862306a36Sopenharmony_ci		return -EINVAL;
359962306a36Sopenharmony_ci	}
360062306a36Sopenharmony_ci
360162306a36Sopenharmony_ci	parser->patched_cb_size += sizeof(*user_dma_pkt);
360262306a36Sopenharmony_ci
360362306a36Sopenharmony_ci	return 0;
360462306a36Sopenharmony_ci}
360562306a36Sopenharmony_ci
360662306a36Sopenharmony_cistatic int goya_validate_wreg32(struct hl_device *hdev,
360762306a36Sopenharmony_ci				struct hl_cs_parser *parser,
360862306a36Sopenharmony_ci				struct packet_wreg32 *wreg_pkt)
360962306a36Sopenharmony_ci{
361062306a36Sopenharmony_ci	struct goya_device *goya = hdev->asic_specific;
361162306a36Sopenharmony_ci	u32 sob_start_addr, sob_end_addr;
361262306a36Sopenharmony_ci	u16 reg_offset;
361362306a36Sopenharmony_ci
361462306a36Sopenharmony_ci	reg_offset = le32_to_cpu(wreg_pkt->ctl) &
361562306a36Sopenharmony_ci			GOYA_PKT_WREG32_CTL_REG_OFFSET_MASK;
361662306a36Sopenharmony_ci
361762306a36Sopenharmony_ci	dev_dbg(hdev->dev, "WREG32 packet details:\n");
361862306a36Sopenharmony_ci	dev_dbg(hdev->dev, "reg_offset == 0x%x\n", reg_offset);
361962306a36Sopenharmony_ci	dev_dbg(hdev->dev, "value      == 0x%x\n",
362062306a36Sopenharmony_ci		le32_to_cpu(wreg_pkt->value));
362162306a36Sopenharmony_ci
362262306a36Sopenharmony_ci	if (reg_offset != (mmDMA_CH_0_WR_COMP_ADDR_LO & 0x1FFF)) {
362362306a36Sopenharmony_ci		dev_err(hdev->dev, "WREG32 packet with illegal address 0x%x\n",
362462306a36Sopenharmony_ci			reg_offset);
362562306a36Sopenharmony_ci		return -EPERM;
362662306a36Sopenharmony_ci	}
362762306a36Sopenharmony_ci
362862306a36Sopenharmony_ci	/*
362962306a36Sopenharmony_ci	 * With MMU, DMA channels are not secured, so it doesn't matter where
363062306a36Sopenharmony_ci	 * the WR COMP will be written to because it will go out with
363162306a36Sopenharmony_ci	 * non-secured property
363262306a36Sopenharmony_ci	 */
363362306a36Sopenharmony_ci	if (goya->hw_cap_initialized & HW_CAP_MMU)
363462306a36Sopenharmony_ci		return 0;
363562306a36Sopenharmony_ci
363662306a36Sopenharmony_ci	sob_start_addr = lower_32_bits(CFG_BASE + mmSYNC_MNGR_SOB_OBJ_0);
363762306a36Sopenharmony_ci	sob_end_addr = lower_32_bits(CFG_BASE + mmSYNC_MNGR_SOB_OBJ_1023);
363862306a36Sopenharmony_ci
363962306a36Sopenharmony_ci	if ((le32_to_cpu(wreg_pkt->value) < sob_start_addr) ||
364062306a36Sopenharmony_ci			(le32_to_cpu(wreg_pkt->value) > sob_end_addr)) {
364162306a36Sopenharmony_ci
364262306a36Sopenharmony_ci		dev_err(hdev->dev, "WREG32 packet with illegal value 0x%x\n",
364362306a36Sopenharmony_ci			wreg_pkt->value);
364462306a36Sopenharmony_ci		return -EPERM;
364562306a36Sopenharmony_ci	}
364662306a36Sopenharmony_ci
364762306a36Sopenharmony_ci	return 0;
364862306a36Sopenharmony_ci}
364962306a36Sopenharmony_ci
365062306a36Sopenharmony_cistatic int goya_validate_cb(struct hl_device *hdev,
365162306a36Sopenharmony_ci			struct hl_cs_parser *parser, bool is_mmu)
365262306a36Sopenharmony_ci{
365362306a36Sopenharmony_ci	u32 cb_parsed_length = 0;
365462306a36Sopenharmony_ci	int rc = 0;
365562306a36Sopenharmony_ci
365662306a36Sopenharmony_ci	parser->patched_cb_size = 0;
365762306a36Sopenharmony_ci
365862306a36Sopenharmony_ci	/* cb_user_size is more than 0 so loop will always be executed */
365962306a36Sopenharmony_ci	while (cb_parsed_length < parser->user_cb_size) {
366062306a36Sopenharmony_ci		enum packet_id pkt_id;
366162306a36Sopenharmony_ci		u16 pkt_size;
366262306a36Sopenharmony_ci		struct goya_packet *user_pkt;
366362306a36Sopenharmony_ci
366462306a36Sopenharmony_ci		user_pkt = parser->user_cb->kernel_address + cb_parsed_length;
366562306a36Sopenharmony_ci
366662306a36Sopenharmony_ci		pkt_id = (enum packet_id) (
366762306a36Sopenharmony_ci				(le64_to_cpu(user_pkt->header) &
366862306a36Sopenharmony_ci				PACKET_HEADER_PACKET_ID_MASK) >>
366962306a36Sopenharmony_ci					PACKET_HEADER_PACKET_ID_SHIFT);
367062306a36Sopenharmony_ci
367162306a36Sopenharmony_ci		if (!validate_packet_id(pkt_id)) {
367262306a36Sopenharmony_ci			dev_err(hdev->dev, "Invalid packet id %u\n", pkt_id);
367362306a36Sopenharmony_ci			rc = -EINVAL;
367462306a36Sopenharmony_ci			break;
367562306a36Sopenharmony_ci		}
367662306a36Sopenharmony_ci
367762306a36Sopenharmony_ci		pkt_size = goya_packet_sizes[pkt_id];
367862306a36Sopenharmony_ci		cb_parsed_length += pkt_size;
367962306a36Sopenharmony_ci		if (cb_parsed_length > parser->user_cb_size) {
368062306a36Sopenharmony_ci			dev_err(hdev->dev,
368162306a36Sopenharmony_ci				"packet 0x%x is out of CB boundary\n", pkt_id);
368262306a36Sopenharmony_ci			rc = -EINVAL;
368362306a36Sopenharmony_ci			break;
368462306a36Sopenharmony_ci		}
368562306a36Sopenharmony_ci
368662306a36Sopenharmony_ci		switch (pkt_id) {
368762306a36Sopenharmony_ci		case PACKET_WREG_32:
368862306a36Sopenharmony_ci			/*
368962306a36Sopenharmony_ci			 * Although it is validated after copy in patch_cb(),
369062306a36Sopenharmony_ci			 * need to validate here as well because patch_cb() is
369162306a36Sopenharmony_ci			 * not called in MMU path while this function is called
369262306a36Sopenharmony_ci			 */
369362306a36Sopenharmony_ci			rc = goya_validate_wreg32(hdev,
369462306a36Sopenharmony_ci				parser, (struct packet_wreg32 *) user_pkt);
369562306a36Sopenharmony_ci			parser->patched_cb_size += pkt_size;
369662306a36Sopenharmony_ci			break;
369762306a36Sopenharmony_ci
369862306a36Sopenharmony_ci		case PACKET_WREG_BULK:
369962306a36Sopenharmony_ci			dev_err(hdev->dev,
370062306a36Sopenharmony_ci				"User not allowed to use WREG_BULK\n");
370162306a36Sopenharmony_ci			rc = -EPERM;
370262306a36Sopenharmony_ci			break;
370362306a36Sopenharmony_ci
370462306a36Sopenharmony_ci		case PACKET_MSG_PROT:
370562306a36Sopenharmony_ci			dev_err(hdev->dev,
370662306a36Sopenharmony_ci				"User not allowed to use MSG_PROT\n");
370762306a36Sopenharmony_ci			rc = -EPERM;
370862306a36Sopenharmony_ci			break;
370962306a36Sopenharmony_ci
371062306a36Sopenharmony_ci		case PACKET_CP_DMA:
371162306a36Sopenharmony_ci			dev_err(hdev->dev, "User not allowed to use CP_DMA\n");
371262306a36Sopenharmony_ci			rc = -EPERM;
371362306a36Sopenharmony_ci			break;
371462306a36Sopenharmony_ci
371562306a36Sopenharmony_ci		case PACKET_STOP:
371662306a36Sopenharmony_ci			dev_err(hdev->dev, "User not allowed to use STOP\n");
371762306a36Sopenharmony_ci			rc = -EPERM;
371862306a36Sopenharmony_ci			break;
371962306a36Sopenharmony_ci
372062306a36Sopenharmony_ci		case PACKET_LIN_DMA:
372162306a36Sopenharmony_ci			if (is_mmu)
372262306a36Sopenharmony_ci				rc = goya_validate_dma_pkt_mmu(hdev, parser,
372362306a36Sopenharmony_ci					(struct packet_lin_dma *) user_pkt);
372462306a36Sopenharmony_ci			else
372562306a36Sopenharmony_ci				rc = goya_validate_dma_pkt_no_mmu(hdev, parser,
372662306a36Sopenharmony_ci					(struct packet_lin_dma *) user_pkt);
372762306a36Sopenharmony_ci			break;
372862306a36Sopenharmony_ci
372962306a36Sopenharmony_ci		case PACKET_MSG_LONG:
373062306a36Sopenharmony_ci		case PACKET_MSG_SHORT:
373162306a36Sopenharmony_ci		case PACKET_FENCE:
373262306a36Sopenharmony_ci		case PACKET_NOP:
373362306a36Sopenharmony_ci			parser->patched_cb_size += pkt_size;
373462306a36Sopenharmony_ci			break;
373562306a36Sopenharmony_ci
373662306a36Sopenharmony_ci		default:
373762306a36Sopenharmony_ci			dev_err(hdev->dev, "Invalid packet header 0x%x\n",
373862306a36Sopenharmony_ci				pkt_id);
373962306a36Sopenharmony_ci			rc = -EINVAL;
374062306a36Sopenharmony_ci			break;
374162306a36Sopenharmony_ci		}
374262306a36Sopenharmony_ci
374362306a36Sopenharmony_ci		if (rc)
374462306a36Sopenharmony_ci			break;
374562306a36Sopenharmony_ci	}
374662306a36Sopenharmony_ci
374762306a36Sopenharmony_ci	/*
374862306a36Sopenharmony_ci	 * The new CB should have space at the end for two MSG_PROT packets:
374962306a36Sopenharmony_ci	 * 1. A packet that will act as a completion packet
375062306a36Sopenharmony_ci	 * 2. A packet that will generate MSI-X interrupt
375162306a36Sopenharmony_ci	 */
375262306a36Sopenharmony_ci	parser->patched_cb_size += sizeof(struct packet_msg_prot) * 2;
375362306a36Sopenharmony_ci
375462306a36Sopenharmony_ci	return rc;
375562306a36Sopenharmony_ci}
375662306a36Sopenharmony_ci
375762306a36Sopenharmony_cistatic int goya_patch_dma_packet(struct hl_device *hdev,
375862306a36Sopenharmony_ci				struct hl_cs_parser *parser,
375962306a36Sopenharmony_ci				struct packet_lin_dma *user_dma_pkt,
376062306a36Sopenharmony_ci				struct packet_lin_dma *new_dma_pkt,
376162306a36Sopenharmony_ci				u32 *new_dma_pkt_size)
376262306a36Sopenharmony_ci{
376362306a36Sopenharmony_ci	struct hl_userptr *userptr;
376462306a36Sopenharmony_ci	struct scatterlist *sg, *sg_next_iter;
376562306a36Sopenharmony_ci	u32 count, dma_desc_cnt;
376662306a36Sopenharmony_ci	u64 len, len_next;
376762306a36Sopenharmony_ci	dma_addr_t dma_addr, dma_addr_next;
376862306a36Sopenharmony_ci	enum hl_goya_dma_direction user_dir;
376962306a36Sopenharmony_ci	u64 device_memory_addr, addr;
377062306a36Sopenharmony_ci	enum dma_data_direction dir;
377162306a36Sopenharmony_ci	struct sg_table *sgt;
377262306a36Sopenharmony_ci	bool skip_host_mem_pin = false;
377362306a36Sopenharmony_ci	bool user_memset;
377462306a36Sopenharmony_ci	u32 user_rdcomp_mask, user_wrcomp_mask, ctl;
377562306a36Sopenharmony_ci
377662306a36Sopenharmony_ci	ctl = le32_to_cpu(user_dma_pkt->ctl);
377762306a36Sopenharmony_ci
377862306a36Sopenharmony_ci	user_dir = (ctl & GOYA_PKT_LIN_DMA_CTL_DMA_DIR_MASK) >>
377962306a36Sopenharmony_ci			GOYA_PKT_LIN_DMA_CTL_DMA_DIR_SHIFT;
378062306a36Sopenharmony_ci
378162306a36Sopenharmony_ci	user_memset = (ctl & GOYA_PKT_LIN_DMA_CTL_MEMSET_MASK) >>
378262306a36Sopenharmony_ci			GOYA_PKT_LIN_DMA_CTL_MEMSET_SHIFT;
378362306a36Sopenharmony_ci
378462306a36Sopenharmony_ci	if ((user_dir == HL_DMA_DRAM_TO_SRAM) || (user_dir == HL_DMA_SRAM_TO_DRAM) ||
378562306a36Sopenharmony_ci			(user_dma_pkt->tsize == 0)) {
378662306a36Sopenharmony_ci		memcpy(new_dma_pkt, user_dma_pkt, sizeof(*new_dma_pkt));
378762306a36Sopenharmony_ci		*new_dma_pkt_size = sizeof(*new_dma_pkt);
378862306a36Sopenharmony_ci		return 0;
378962306a36Sopenharmony_ci	}
379062306a36Sopenharmony_ci
379162306a36Sopenharmony_ci	if ((user_dir == HL_DMA_HOST_TO_DRAM) || (user_dir == HL_DMA_HOST_TO_SRAM)) {
379262306a36Sopenharmony_ci		addr = le64_to_cpu(user_dma_pkt->src_addr);
379362306a36Sopenharmony_ci		device_memory_addr = le64_to_cpu(user_dma_pkt->dst_addr);
379462306a36Sopenharmony_ci		dir = DMA_TO_DEVICE;
379562306a36Sopenharmony_ci		if (user_memset)
379662306a36Sopenharmony_ci			skip_host_mem_pin = true;
379762306a36Sopenharmony_ci	} else {
379862306a36Sopenharmony_ci		addr = le64_to_cpu(user_dma_pkt->dst_addr);
379962306a36Sopenharmony_ci		device_memory_addr = le64_to_cpu(user_dma_pkt->src_addr);
380062306a36Sopenharmony_ci		dir = DMA_FROM_DEVICE;
380162306a36Sopenharmony_ci	}
380262306a36Sopenharmony_ci
380362306a36Sopenharmony_ci	if ((!skip_host_mem_pin) &&
380462306a36Sopenharmony_ci		(hl_userptr_is_pinned(hdev, addr,
380562306a36Sopenharmony_ci			le32_to_cpu(user_dma_pkt->tsize),
380662306a36Sopenharmony_ci			parser->job_userptr_list, &userptr) == false)) {
380762306a36Sopenharmony_ci		dev_err(hdev->dev, "Userptr 0x%llx + 0x%x NOT mapped\n",
380862306a36Sopenharmony_ci				addr, user_dma_pkt->tsize);
380962306a36Sopenharmony_ci		return -EFAULT;
381062306a36Sopenharmony_ci	}
381162306a36Sopenharmony_ci
381262306a36Sopenharmony_ci	if ((user_memset) && (dir == DMA_TO_DEVICE)) {
381362306a36Sopenharmony_ci		memcpy(new_dma_pkt, user_dma_pkt, sizeof(*user_dma_pkt));
381462306a36Sopenharmony_ci		*new_dma_pkt_size = sizeof(*user_dma_pkt);
381562306a36Sopenharmony_ci		return 0;
381662306a36Sopenharmony_ci	}
381762306a36Sopenharmony_ci
381862306a36Sopenharmony_ci	user_rdcomp_mask = ctl & GOYA_PKT_LIN_DMA_CTL_RDCOMP_MASK;
381962306a36Sopenharmony_ci
382062306a36Sopenharmony_ci	user_wrcomp_mask = ctl & GOYA_PKT_LIN_DMA_CTL_WRCOMP_MASK;
382162306a36Sopenharmony_ci
382262306a36Sopenharmony_ci	sgt = userptr->sgt;
382362306a36Sopenharmony_ci	dma_desc_cnt = 0;
382462306a36Sopenharmony_ci
382562306a36Sopenharmony_ci	for_each_sgtable_dma_sg(sgt, sg, count) {
382662306a36Sopenharmony_ci		len = sg_dma_len(sg);
382762306a36Sopenharmony_ci		dma_addr = sg_dma_address(sg);
382862306a36Sopenharmony_ci
382962306a36Sopenharmony_ci		if (len == 0)
383062306a36Sopenharmony_ci			break;
383162306a36Sopenharmony_ci
383262306a36Sopenharmony_ci		while ((count + 1) < sgt->nents) {
383362306a36Sopenharmony_ci			sg_next_iter = sg_next(sg);
383462306a36Sopenharmony_ci			len_next = sg_dma_len(sg_next_iter);
383562306a36Sopenharmony_ci			dma_addr_next = sg_dma_address(sg_next_iter);
383662306a36Sopenharmony_ci
383762306a36Sopenharmony_ci			if (len_next == 0)
383862306a36Sopenharmony_ci				break;
383962306a36Sopenharmony_ci
384062306a36Sopenharmony_ci			if ((dma_addr + len == dma_addr_next) &&
384162306a36Sopenharmony_ci				(len + len_next <= DMA_MAX_TRANSFER_SIZE)) {
384262306a36Sopenharmony_ci				len += len_next;
384362306a36Sopenharmony_ci				count++;
384462306a36Sopenharmony_ci				sg = sg_next_iter;
384562306a36Sopenharmony_ci			} else {
384662306a36Sopenharmony_ci				break;
384762306a36Sopenharmony_ci			}
384862306a36Sopenharmony_ci		}
384962306a36Sopenharmony_ci
385062306a36Sopenharmony_ci		ctl = le32_to_cpu(user_dma_pkt->ctl);
385162306a36Sopenharmony_ci		if (likely(dma_desc_cnt))
385262306a36Sopenharmony_ci			ctl &= ~GOYA_PKT_CTL_EB_MASK;
385362306a36Sopenharmony_ci		ctl &= ~(GOYA_PKT_LIN_DMA_CTL_RDCOMP_MASK |
385462306a36Sopenharmony_ci				GOYA_PKT_LIN_DMA_CTL_WRCOMP_MASK);
385562306a36Sopenharmony_ci		new_dma_pkt->ctl = cpu_to_le32(ctl);
385662306a36Sopenharmony_ci		new_dma_pkt->tsize = cpu_to_le32((u32) len);
385762306a36Sopenharmony_ci
385862306a36Sopenharmony_ci		if (dir == DMA_TO_DEVICE) {
385962306a36Sopenharmony_ci			new_dma_pkt->src_addr = cpu_to_le64(dma_addr);
386062306a36Sopenharmony_ci			new_dma_pkt->dst_addr = cpu_to_le64(device_memory_addr);
386162306a36Sopenharmony_ci		} else {
386262306a36Sopenharmony_ci			new_dma_pkt->src_addr = cpu_to_le64(device_memory_addr);
386362306a36Sopenharmony_ci			new_dma_pkt->dst_addr = cpu_to_le64(dma_addr);
386462306a36Sopenharmony_ci		}
386562306a36Sopenharmony_ci
386662306a36Sopenharmony_ci		if (!user_memset)
386762306a36Sopenharmony_ci			device_memory_addr += len;
386862306a36Sopenharmony_ci		dma_desc_cnt++;
386962306a36Sopenharmony_ci		new_dma_pkt++;
387062306a36Sopenharmony_ci	}
387162306a36Sopenharmony_ci
387262306a36Sopenharmony_ci	if (!dma_desc_cnt) {
387362306a36Sopenharmony_ci		dev_err(hdev->dev,
387462306a36Sopenharmony_ci			"Error of 0 SG entries when patching DMA packet\n");
387562306a36Sopenharmony_ci		return -EFAULT;
387662306a36Sopenharmony_ci	}
387762306a36Sopenharmony_ci
387862306a36Sopenharmony_ci	/* Fix the last dma packet - rdcomp/wrcomp must be as user set them */
387962306a36Sopenharmony_ci	new_dma_pkt--;
388062306a36Sopenharmony_ci	new_dma_pkt->ctl |= cpu_to_le32(user_rdcomp_mask | user_wrcomp_mask);
388162306a36Sopenharmony_ci
388262306a36Sopenharmony_ci	*new_dma_pkt_size = dma_desc_cnt * sizeof(struct packet_lin_dma);
388362306a36Sopenharmony_ci
388462306a36Sopenharmony_ci	return 0;
388562306a36Sopenharmony_ci}
388662306a36Sopenharmony_ci
388762306a36Sopenharmony_cistatic int goya_patch_cb(struct hl_device *hdev,
388862306a36Sopenharmony_ci				struct hl_cs_parser *parser)
388962306a36Sopenharmony_ci{
389062306a36Sopenharmony_ci	u32 cb_parsed_length = 0;
389162306a36Sopenharmony_ci	u32 cb_patched_cur_length = 0;
389262306a36Sopenharmony_ci	int rc = 0;
389362306a36Sopenharmony_ci
389462306a36Sopenharmony_ci	/* cb_user_size is more than 0 so loop will always be executed */
389562306a36Sopenharmony_ci	while (cb_parsed_length < parser->user_cb_size) {
389662306a36Sopenharmony_ci		enum packet_id pkt_id;
389762306a36Sopenharmony_ci		u16 pkt_size;
389862306a36Sopenharmony_ci		u32 new_pkt_size = 0;
389962306a36Sopenharmony_ci		struct goya_packet *user_pkt, *kernel_pkt;
390062306a36Sopenharmony_ci
390162306a36Sopenharmony_ci		user_pkt = parser->user_cb->kernel_address + cb_parsed_length;
390262306a36Sopenharmony_ci		kernel_pkt = parser->patched_cb->kernel_address +
390362306a36Sopenharmony_ci					cb_patched_cur_length;
390462306a36Sopenharmony_ci
390562306a36Sopenharmony_ci		pkt_id = (enum packet_id) (
390662306a36Sopenharmony_ci				(le64_to_cpu(user_pkt->header) &
390762306a36Sopenharmony_ci				PACKET_HEADER_PACKET_ID_MASK) >>
390862306a36Sopenharmony_ci					PACKET_HEADER_PACKET_ID_SHIFT);
390962306a36Sopenharmony_ci
391062306a36Sopenharmony_ci		if (!validate_packet_id(pkt_id)) {
391162306a36Sopenharmony_ci			dev_err(hdev->dev, "Invalid packet id %u\n", pkt_id);
391262306a36Sopenharmony_ci			rc = -EINVAL;
391362306a36Sopenharmony_ci			break;
391462306a36Sopenharmony_ci		}
391562306a36Sopenharmony_ci
391662306a36Sopenharmony_ci		pkt_size = goya_packet_sizes[pkt_id];
391762306a36Sopenharmony_ci		cb_parsed_length += pkt_size;
391862306a36Sopenharmony_ci		if (cb_parsed_length > parser->user_cb_size) {
391962306a36Sopenharmony_ci			dev_err(hdev->dev,
392062306a36Sopenharmony_ci				"packet 0x%x is out of CB boundary\n", pkt_id);
392162306a36Sopenharmony_ci			rc = -EINVAL;
392262306a36Sopenharmony_ci			break;
392362306a36Sopenharmony_ci		}
392462306a36Sopenharmony_ci
392562306a36Sopenharmony_ci		switch (pkt_id) {
392662306a36Sopenharmony_ci		case PACKET_LIN_DMA:
392762306a36Sopenharmony_ci			rc = goya_patch_dma_packet(hdev, parser,
392862306a36Sopenharmony_ci					(struct packet_lin_dma *) user_pkt,
392962306a36Sopenharmony_ci					(struct packet_lin_dma *) kernel_pkt,
393062306a36Sopenharmony_ci					&new_pkt_size);
393162306a36Sopenharmony_ci			cb_patched_cur_length += new_pkt_size;
393262306a36Sopenharmony_ci			break;
393362306a36Sopenharmony_ci
393462306a36Sopenharmony_ci		case PACKET_WREG_32:
393562306a36Sopenharmony_ci			memcpy(kernel_pkt, user_pkt, pkt_size);
393662306a36Sopenharmony_ci			cb_patched_cur_length += pkt_size;
393762306a36Sopenharmony_ci			rc = goya_validate_wreg32(hdev, parser,
393862306a36Sopenharmony_ci					(struct packet_wreg32 *) kernel_pkt);
393962306a36Sopenharmony_ci			break;
394062306a36Sopenharmony_ci
394162306a36Sopenharmony_ci		case PACKET_WREG_BULK:
394262306a36Sopenharmony_ci			dev_err(hdev->dev,
394362306a36Sopenharmony_ci				"User not allowed to use WREG_BULK\n");
394462306a36Sopenharmony_ci			rc = -EPERM;
394562306a36Sopenharmony_ci			break;
394662306a36Sopenharmony_ci
394762306a36Sopenharmony_ci		case PACKET_MSG_PROT:
394862306a36Sopenharmony_ci			dev_err(hdev->dev,
394962306a36Sopenharmony_ci				"User not allowed to use MSG_PROT\n");
395062306a36Sopenharmony_ci			rc = -EPERM;
395162306a36Sopenharmony_ci			break;
395262306a36Sopenharmony_ci
395362306a36Sopenharmony_ci		case PACKET_CP_DMA:
395462306a36Sopenharmony_ci			dev_err(hdev->dev, "User not allowed to use CP_DMA\n");
395562306a36Sopenharmony_ci			rc = -EPERM;
395662306a36Sopenharmony_ci			break;
395762306a36Sopenharmony_ci
395862306a36Sopenharmony_ci		case PACKET_STOP:
395962306a36Sopenharmony_ci			dev_err(hdev->dev, "User not allowed to use STOP\n");
396062306a36Sopenharmony_ci			rc = -EPERM;
396162306a36Sopenharmony_ci			break;
396262306a36Sopenharmony_ci
396362306a36Sopenharmony_ci		case PACKET_MSG_LONG:
396462306a36Sopenharmony_ci		case PACKET_MSG_SHORT:
396562306a36Sopenharmony_ci		case PACKET_FENCE:
396662306a36Sopenharmony_ci		case PACKET_NOP:
396762306a36Sopenharmony_ci			memcpy(kernel_pkt, user_pkt, pkt_size);
396862306a36Sopenharmony_ci			cb_patched_cur_length += pkt_size;
396962306a36Sopenharmony_ci			break;
397062306a36Sopenharmony_ci
397162306a36Sopenharmony_ci		default:
397262306a36Sopenharmony_ci			dev_err(hdev->dev, "Invalid packet header 0x%x\n",
397362306a36Sopenharmony_ci				pkt_id);
397462306a36Sopenharmony_ci			rc = -EINVAL;
397562306a36Sopenharmony_ci			break;
397662306a36Sopenharmony_ci		}
397762306a36Sopenharmony_ci
397862306a36Sopenharmony_ci		if (rc)
397962306a36Sopenharmony_ci			break;
398062306a36Sopenharmony_ci	}
398162306a36Sopenharmony_ci
398262306a36Sopenharmony_ci	return rc;
398362306a36Sopenharmony_ci}
398462306a36Sopenharmony_ci
398562306a36Sopenharmony_cistatic int goya_parse_cb_mmu(struct hl_device *hdev,
398662306a36Sopenharmony_ci		struct hl_cs_parser *parser)
398762306a36Sopenharmony_ci{
398862306a36Sopenharmony_ci	u64 handle;
398962306a36Sopenharmony_ci	u32 patched_cb_size;
399062306a36Sopenharmony_ci	struct hl_cb *user_cb;
399162306a36Sopenharmony_ci	int rc;
399262306a36Sopenharmony_ci
399362306a36Sopenharmony_ci	/*
399462306a36Sopenharmony_ci	 * The new CB should have space at the end for two MSG_PROT pkt:
399562306a36Sopenharmony_ci	 * 1. A packet that will act as a completion packet
399662306a36Sopenharmony_ci	 * 2. A packet that will generate MSI-X interrupt
399762306a36Sopenharmony_ci	 */
399862306a36Sopenharmony_ci	parser->patched_cb_size = parser->user_cb_size +
399962306a36Sopenharmony_ci			sizeof(struct packet_msg_prot) * 2;
400062306a36Sopenharmony_ci
400162306a36Sopenharmony_ci	rc = hl_cb_create(hdev, &hdev->kernel_mem_mgr, hdev->kernel_ctx,
400262306a36Sopenharmony_ci				parser->patched_cb_size, false, false,
400362306a36Sopenharmony_ci				&handle);
400462306a36Sopenharmony_ci
400562306a36Sopenharmony_ci	if (rc) {
400662306a36Sopenharmony_ci		dev_err(hdev->dev,
400762306a36Sopenharmony_ci			"Failed to allocate patched CB for DMA CS %d\n",
400862306a36Sopenharmony_ci			rc);
400962306a36Sopenharmony_ci		return rc;
401062306a36Sopenharmony_ci	}
401162306a36Sopenharmony_ci
401262306a36Sopenharmony_ci	parser->patched_cb = hl_cb_get(&hdev->kernel_mem_mgr, handle);
401362306a36Sopenharmony_ci	/* hl_cb_get should never fail here */
401462306a36Sopenharmony_ci	if (!parser->patched_cb) {
401562306a36Sopenharmony_ci		dev_crit(hdev->dev, "DMA CB handle invalid 0x%llx\n", handle);
401662306a36Sopenharmony_ci		rc = -EFAULT;
401762306a36Sopenharmony_ci		goto out;
401862306a36Sopenharmony_ci	}
401962306a36Sopenharmony_ci
402062306a36Sopenharmony_ci	/*
402162306a36Sopenharmony_ci	 * The check that parser->user_cb_size <= parser->user_cb->size was done
402262306a36Sopenharmony_ci	 * in validate_queue_index().
402362306a36Sopenharmony_ci	 */
402462306a36Sopenharmony_ci	memcpy(parser->patched_cb->kernel_address,
402562306a36Sopenharmony_ci		parser->user_cb->kernel_address,
402662306a36Sopenharmony_ci		parser->user_cb_size);
402762306a36Sopenharmony_ci
402862306a36Sopenharmony_ci	patched_cb_size = parser->patched_cb_size;
402962306a36Sopenharmony_ci
403062306a36Sopenharmony_ci	/* validate patched CB instead of user CB */
403162306a36Sopenharmony_ci	user_cb = parser->user_cb;
403262306a36Sopenharmony_ci	parser->user_cb = parser->patched_cb;
403362306a36Sopenharmony_ci	rc = goya_validate_cb(hdev, parser, true);
403462306a36Sopenharmony_ci	parser->user_cb = user_cb;
403562306a36Sopenharmony_ci
403662306a36Sopenharmony_ci	if (rc) {
403762306a36Sopenharmony_ci		hl_cb_put(parser->patched_cb);
403862306a36Sopenharmony_ci		goto out;
403962306a36Sopenharmony_ci	}
404062306a36Sopenharmony_ci
404162306a36Sopenharmony_ci	if (patched_cb_size != parser->patched_cb_size) {
404262306a36Sopenharmony_ci		dev_err(hdev->dev, "user CB size mismatch\n");
404362306a36Sopenharmony_ci		hl_cb_put(parser->patched_cb);
404462306a36Sopenharmony_ci		rc = -EINVAL;
404562306a36Sopenharmony_ci		goto out;
404662306a36Sopenharmony_ci	}
404762306a36Sopenharmony_ci
404862306a36Sopenharmony_ciout:
404962306a36Sopenharmony_ci	/*
405062306a36Sopenharmony_ci	 * Always call cb destroy here because we still have 1 reference
405162306a36Sopenharmony_ci	 * to it by calling cb_get earlier. After the job will be completed,
405262306a36Sopenharmony_ci	 * cb_put will release it, but here we want to remove it from the
405362306a36Sopenharmony_ci	 * idr
405462306a36Sopenharmony_ci	 */
405562306a36Sopenharmony_ci	hl_cb_destroy(&hdev->kernel_mem_mgr, handle);
405662306a36Sopenharmony_ci
405762306a36Sopenharmony_ci	return rc;
405862306a36Sopenharmony_ci}
405962306a36Sopenharmony_ci
406062306a36Sopenharmony_cistatic int goya_parse_cb_no_mmu(struct hl_device *hdev,
406162306a36Sopenharmony_ci				struct hl_cs_parser *parser)
406262306a36Sopenharmony_ci{
406362306a36Sopenharmony_ci	u64 handle;
406462306a36Sopenharmony_ci	int rc;
406562306a36Sopenharmony_ci
406662306a36Sopenharmony_ci	rc = goya_validate_cb(hdev, parser, false);
406762306a36Sopenharmony_ci
406862306a36Sopenharmony_ci	if (rc)
406962306a36Sopenharmony_ci		goto free_userptr;
407062306a36Sopenharmony_ci
407162306a36Sopenharmony_ci	rc = hl_cb_create(hdev, &hdev->kernel_mem_mgr, hdev->kernel_ctx,
407262306a36Sopenharmony_ci				parser->patched_cb_size, false, false,
407362306a36Sopenharmony_ci				&handle);
407462306a36Sopenharmony_ci	if (rc) {
407562306a36Sopenharmony_ci		dev_err(hdev->dev,
407662306a36Sopenharmony_ci			"Failed to allocate patched CB for DMA CS %d\n", rc);
407762306a36Sopenharmony_ci		goto free_userptr;
407862306a36Sopenharmony_ci	}
407962306a36Sopenharmony_ci
408062306a36Sopenharmony_ci	parser->patched_cb = hl_cb_get(&hdev->kernel_mem_mgr, handle);
408162306a36Sopenharmony_ci	/* hl_cb_get should never fail here */
408262306a36Sopenharmony_ci	if (!parser->patched_cb) {
408362306a36Sopenharmony_ci		dev_crit(hdev->dev, "DMA CB handle invalid 0x%llx\n", handle);
408462306a36Sopenharmony_ci		rc = -EFAULT;
408562306a36Sopenharmony_ci		goto out;
408662306a36Sopenharmony_ci	}
408762306a36Sopenharmony_ci
408862306a36Sopenharmony_ci	rc = goya_patch_cb(hdev, parser);
408962306a36Sopenharmony_ci
409062306a36Sopenharmony_ci	if (rc)
409162306a36Sopenharmony_ci		hl_cb_put(parser->patched_cb);
409262306a36Sopenharmony_ci
409362306a36Sopenharmony_ciout:
409462306a36Sopenharmony_ci	/*
409562306a36Sopenharmony_ci	 * Always call cb destroy here because we still have 1 reference
409662306a36Sopenharmony_ci	 * to it by calling cb_get earlier. After the job will be completed,
409762306a36Sopenharmony_ci	 * cb_put will release it, but here we want to remove it from the
409862306a36Sopenharmony_ci	 * idr
409962306a36Sopenharmony_ci	 */
410062306a36Sopenharmony_ci	hl_cb_destroy(&hdev->kernel_mem_mgr, handle);
410162306a36Sopenharmony_ci
410262306a36Sopenharmony_cifree_userptr:
410362306a36Sopenharmony_ci	if (rc)
410462306a36Sopenharmony_ci		hl_userptr_delete_list(hdev, parser->job_userptr_list);
410562306a36Sopenharmony_ci	return rc;
410662306a36Sopenharmony_ci}
410762306a36Sopenharmony_ci
410862306a36Sopenharmony_cistatic int goya_parse_cb_no_ext_queue(struct hl_device *hdev,
410962306a36Sopenharmony_ci					struct hl_cs_parser *parser)
411062306a36Sopenharmony_ci{
411162306a36Sopenharmony_ci	struct asic_fixed_properties *asic_prop = &hdev->asic_prop;
411262306a36Sopenharmony_ci	struct goya_device *goya = hdev->asic_specific;
411362306a36Sopenharmony_ci
411462306a36Sopenharmony_ci	if (goya->hw_cap_initialized & HW_CAP_MMU)
411562306a36Sopenharmony_ci		return 0;
411662306a36Sopenharmony_ci
411762306a36Sopenharmony_ci	/* For internal queue jobs, just check if CB address is valid */
411862306a36Sopenharmony_ci	if (hl_mem_area_inside_range(
411962306a36Sopenharmony_ci			(u64) (uintptr_t) parser->user_cb,
412062306a36Sopenharmony_ci			parser->user_cb_size,
412162306a36Sopenharmony_ci			asic_prop->sram_user_base_address,
412262306a36Sopenharmony_ci			asic_prop->sram_end_address))
412362306a36Sopenharmony_ci		return 0;
412462306a36Sopenharmony_ci
412562306a36Sopenharmony_ci	if (hl_mem_area_inside_range(
412662306a36Sopenharmony_ci			(u64) (uintptr_t) parser->user_cb,
412762306a36Sopenharmony_ci			parser->user_cb_size,
412862306a36Sopenharmony_ci			asic_prop->dram_user_base_address,
412962306a36Sopenharmony_ci			asic_prop->dram_end_address))
413062306a36Sopenharmony_ci		return 0;
413162306a36Sopenharmony_ci
413262306a36Sopenharmony_ci	dev_err(hdev->dev,
413362306a36Sopenharmony_ci		"Internal CB address 0x%px + 0x%x is not in SRAM nor in DRAM\n",
413462306a36Sopenharmony_ci		parser->user_cb, parser->user_cb_size);
413562306a36Sopenharmony_ci
413662306a36Sopenharmony_ci	return -EFAULT;
413762306a36Sopenharmony_ci}
413862306a36Sopenharmony_ci
413962306a36Sopenharmony_ciint goya_cs_parser(struct hl_device *hdev, struct hl_cs_parser *parser)
414062306a36Sopenharmony_ci{
414162306a36Sopenharmony_ci	struct goya_device *goya = hdev->asic_specific;
414262306a36Sopenharmony_ci
414362306a36Sopenharmony_ci	if (parser->queue_type == QUEUE_TYPE_INT)
414462306a36Sopenharmony_ci		return goya_parse_cb_no_ext_queue(hdev, parser);
414562306a36Sopenharmony_ci
414662306a36Sopenharmony_ci	if (goya->hw_cap_initialized & HW_CAP_MMU)
414762306a36Sopenharmony_ci		return goya_parse_cb_mmu(hdev, parser);
414862306a36Sopenharmony_ci	else
414962306a36Sopenharmony_ci		return goya_parse_cb_no_mmu(hdev, parser);
415062306a36Sopenharmony_ci}
415162306a36Sopenharmony_ci
415262306a36Sopenharmony_civoid goya_add_end_of_cb_packets(struct hl_device *hdev, void *kernel_address,
415362306a36Sopenharmony_ci				u32 len, u32 original_len, u64 cq_addr, u32 cq_val,
415462306a36Sopenharmony_ci				u32 msix_vec, bool eb)
415562306a36Sopenharmony_ci{
415662306a36Sopenharmony_ci	struct packet_msg_prot *cq_pkt;
415762306a36Sopenharmony_ci	u32 tmp;
415862306a36Sopenharmony_ci
415962306a36Sopenharmony_ci	cq_pkt = kernel_address + len - (sizeof(struct packet_msg_prot) * 2);
416062306a36Sopenharmony_ci
416162306a36Sopenharmony_ci	tmp = (PACKET_MSG_PROT << GOYA_PKT_CTL_OPCODE_SHIFT) |
416262306a36Sopenharmony_ci			(1 << GOYA_PKT_CTL_EB_SHIFT) |
416362306a36Sopenharmony_ci			(1 << GOYA_PKT_CTL_MB_SHIFT);
416462306a36Sopenharmony_ci	cq_pkt->ctl = cpu_to_le32(tmp);
416562306a36Sopenharmony_ci	cq_pkt->value = cpu_to_le32(cq_val);
416662306a36Sopenharmony_ci	cq_pkt->addr = cpu_to_le64(cq_addr);
416762306a36Sopenharmony_ci
416862306a36Sopenharmony_ci	cq_pkt++;
416962306a36Sopenharmony_ci
417062306a36Sopenharmony_ci	tmp = (PACKET_MSG_PROT << GOYA_PKT_CTL_OPCODE_SHIFT) |
417162306a36Sopenharmony_ci			(1 << GOYA_PKT_CTL_MB_SHIFT);
417262306a36Sopenharmony_ci	cq_pkt->ctl = cpu_to_le32(tmp);
417362306a36Sopenharmony_ci	cq_pkt->value = cpu_to_le32(msix_vec & 0x7FF);
417462306a36Sopenharmony_ci	cq_pkt->addr = cpu_to_le64(CFG_BASE + mmPCIE_DBI_MSIX_DOORBELL_OFF);
417562306a36Sopenharmony_ci}
417662306a36Sopenharmony_ci
417762306a36Sopenharmony_civoid goya_update_eq_ci(struct hl_device *hdev, u32 val)
417862306a36Sopenharmony_ci{
417962306a36Sopenharmony_ci	WREG32(mmCPU_EQ_CI, val);
418062306a36Sopenharmony_ci}
418162306a36Sopenharmony_ci
418262306a36Sopenharmony_civoid goya_restore_phase_topology(struct hl_device *hdev)
418362306a36Sopenharmony_ci{
418462306a36Sopenharmony_ci
418562306a36Sopenharmony_ci}
418662306a36Sopenharmony_ci
418762306a36Sopenharmony_cistatic void goya_clear_sm_regs(struct hl_device *hdev)
418862306a36Sopenharmony_ci{
418962306a36Sopenharmony_ci	int i, num_of_sob_in_longs, num_of_mon_in_longs;
419062306a36Sopenharmony_ci
419162306a36Sopenharmony_ci	num_of_sob_in_longs =
419262306a36Sopenharmony_ci		((mmSYNC_MNGR_SOB_OBJ_1023 - mmSYNC_MNGR_SOB_OBJ_0) + 4);
419362306a36Sopenharmony_ci
419462306a36Sopenharmony_ci	num_of_mon_in_longs =
419562306a36Sopenharmony_ci		((mmSYNC_MNGR_MON_STATUS_255 - mmSYNC_MNGR_MON_STATUS_0) + 4);
419662306a36Sopenharmony_ci
419762306a36Sopenharmony_ci	for (i = 0 ; i < num_of_sob_in_longs ; i += 4)
419862306a36Sopenharmony_ci		WREG32(mmSYNC_MNGR_SOB_OBJ_0 + i, 0);
419962306a36Sopenharmony_ci
420062306a36Sopenharmony_ci	for (i = 0 ; i < num_of_mon_in_longs ; i += 4)
420162306a36Sopenharmony_ci		WREG32(mmSYNC_MNGR_MON_STATUS_0 + i, 0);
420262306a36Sopenharmony_ci
420362306a36Sopenharmony_ci	/* Flush all WREG to prevent race */
420462306a36Sopenharmony_ci	i = RREG32(mmSYNC_MNGR_SOB_OBJ_0);
420562306a36Sopenharmony_ci}
420662306a36Sopenharmony_ci
420762306a36Sopenharmony_cistatic int goya_debugfs_read_dma(struct hl_device *hdev, u64 addr, u32 size, void *blob_addr)
420862306a36Sopenharmony_ci{
420962306a36Sopenharmony_ci	dev_err(hdev->dev, "Reading via DMA is unimplemented yet\n");
421062306a36Sopenharmony_ci	return -EPERM;
421162306a36Sopenharmony_ci}
421262306a36Sopenharmony_ci
421362306a36Sopenharmony_cistatic u64 goya_read_pte(struct hl_device *hdev, u64 addr)
421462306a36Sopenharmony_ci{
421562306a36Sopenharmony_ci	struct goya_device *goya = hdev->asic_specific;
421662306a36Sopenharmony_ci
421762306a36Sopenharmony_ci	if (hdev->reset_info.hard_reset_pending)
421862306a36Sopenharmony_ci		return U64_MAX;
421962306a36Sopenharmony_ci
422062306a36Sopenharmony_ci	return readq(hdev->pcie_bar[DDR_BAR_ID] +
422162306a36Sopenharmony_ci			(addr - goya->ddr_bar_cur_addr));
422262306a36Sopenharmony_ci}
422362306a36Sopenharmony_ci
422462306a36Sopenharmony_cistatic void goya_write_pte(struct hl_device *hdev, u64 addr, u64 val)
422562306a36Sopenharmony_ci{
422662306a36Sopenharmony_ci	struct goya_device *goya = hdev->asic_specific;
422762306a36Sopenharmony_ci
422862306a36Sopenharmony_ci	if (hdev->reset_info.hard_reset_pending)
422962306a36Sopenharmony_ci		return;
423062306a36Sopenharmony_ci
423162306a36Sopenharmony_ci	writeq(val, hdev->pcie_bar[DDR_BAR_ID] +
423262306a36Sopenharmony_ci			(addr - goya->ddr_bar_cur_addr));
423362306a36Sopenharmony_ci}
423462306a36Sopenharmony_ci
423562306a36Sopenharmony_cistatic const char *_goya_get_event_desc(u16 event_type)
423662306a36Sopenharmony_ci{
423762306a36Sopenharmony_ci	switch (event_type) {
423862306a36Sopenharmony_ci	case GOYA_ASYNC_EVENT_ID_PCIE_IF:
423962306a36Sopenharmony_ci		return "PCIe_if";
424062306a36Sopenharmony_ci	case GOYA_ASYNC_EVENT_ID_TPC0_ECC:
424162306a36Sopenharmony_ci	case GOYA_ASYNC_EVENT_ID_TPC1_ECC:
424262306a36Sopenharmony_ci	case GOYA_ASYNC_EVENT_ID_TPC2_ECC:
424362306a36Sopenharmony_ci	case GOYA_ASYNC_EVENT_ID_TPC3_ECC:
424462306a36Sopenharmony_ci	case GOYA_ASYNC_EVENT_ID_TPC4_ECC:
424562306a36Sopenharmony_ci	case GOYA_ASYNC_EVENT_ID_TPC5_ECC:
424662306a36Sopenharmony_ci	case GOYA_ASYNC_EVENT_ID_TPC6_ECC:
424762306a36Sopenharmony_ci	case GOYA_ASYNC_EVENT_ID_TPC7_ECC:
424862306a36Sopenharmony_ci		return "TPC%d_ecc";
424962306a36Sopenharmony_ci	case GOYA_ASYNC_EVENT_ID_MME_ECC:
425062306a36Sopenharmony_ci		return "MME_ecc";
425162306a36Sopenharmony_ci	case GOYA_ASYNC_EVENT_ID_MME_ECC_EXT:
425262306a36Sopenharmony_ci		return "MME_ecc_ext";
425362306a36Sopenharmony_ci	case GOYA_ASYNC_EVENT_ID_MMU_ECC:
425462306a36Sopenharmony_ci		return "MMU_ecc";
425562306a36Sopenharmony_ci	case GOYA_ASYNC_EVENT_ID_DMA_MACRO:
425662306a36Sopenharmony_ci		return "DMA_macro";
425762306a36Sopenharmony_ci	case GOYA_ASYNC_EVENT_ID_DMA_ECC:
425862306a36Sopenharmony_ci		return "DMA_ecc";
425962306a36Sopenharmony_ci	case GOYA_ASYNC_EVENT_ID_CPU_IF_ECC:
426062306a36Sopenharmony_ci		return "CPU_if_ecc";
426162306a36Sopenharmony_ci	case GOYA_ASYNC_EVENT_ID_PSOC_MEM:
426262306a36Sopenharmony_ci		return "PSOC_mem";
426362306a36Sopenharmony_ci	case GOYA_ASYNC_EVENT_ID_PSOC_CORESIGHT:
426462306a36Sopenharmony_ci		return "PSOC_coresight";
426562306a36Sopenharmony_ci	case GOYA_ASYNC_EVENT_ID_SRAM0 ... GOYA_ASYNC_EVENT_ID_SRAM29:
426662306a36Sopenharmony_ci		return "SRAM%d";
426762306a36Sopenharmony_ci	case GOYA_ASYNC_EVENT_ID_GIC500:
426862306a36Sopenharmony_ci		return "GIC500";
426962306a36Sopenharmony_ci	case GOYA_ASYNC_EVENT_ID_PLL0 ... GOYA_ASYNC_EVENT_ID_PLL6:
427062306a36Sopenharmony_ci		return "PLL%d";
427162306a36Sopenharmony_ci	case GOYA_ASYNC_EVENT_ID_AXI_ECC:
427262306a36Sopenharmony_ci		return "AXI_ecc";
427362306a36Sopenharmony_ci	case GOYA_ASYNC_EVENT_ID_L2_RAM_ECC:
427462306a36Sopenharmony_ci		return "L2_ram_ecc";
427562306a36Sopenharmony_ci	case GOYA_ASYNC_EVENT_ID_PSOC_GPIO_05_SW_RESET:
427662306a36Sopenharmony_ci		return "PSOC_gpio_05_sw_reset";
427762306a36Sopenharmony_ci	case GOYA_ASYNC_EVENT_ID_PSOC_GPIO_10_VRHOT_ICRIT:
427862306a36Sopenharmony_ci		return "PSOC_gpio_10_vrhot_icrit";
427962306a36Sopenharmony_ci	case GOYA_ASYNC_EVENT_ID_PCIE_DEC:
428062306a36Sopenharmony_ci		return "PCIe_dec";
428162306a36Sopenharmony_ci	case GOYA_ASYNC_EVENT_ID_TPC0_DEC:
428262306a36Sopenharmony_ci	case GOYA_ASYNC_EVENT_ID_TPC1_DEC:
428362306a36Sopenharmony_ci	case GOYA_ASYNC_EVENT_ID_TPC2_DEC:
428462306a36Sopenharmony_ci	case GOYA_ASYNC_EVENT_ID_TPC3_DEC:
428562306a36Sopenharmony_ci	case GOYA_ASYNC_EVENT_ID_TPC4_DEC:
428662306a36Sopenharmony_ci	case GOYA_ASYNC_EVENT_ID_TPC5_DEC:
428762306a36Sopenharmony_ci	case GOYA_ASYNC_EVENT_ID_TPC6_DEC:
428862306a36Sopenharmony_ci	case GOYA_ASYNC_EVENT_ID_TPC7_DEC:
428962306a36Sopenharmony_ci		return "TPC%d_dec";
429062306a36Sopenharmony_ci	case GOYA_ASYNC_EVENT_ID_MME_WACS:
429162306a36Sopenharmony_ci		return "MME_wacs";
429262306a36Sopenharmony_ci	case GOYA_ASYNC_EVENT_ID_MME_WACSD:
429362306a36Sopenharmony_ci		return "MME_wacsd";
429462306a36Sopenharmony_ci	case GOYA_ASYNC_EVENT_ID_CPU_AXI_SPLITTER:
429562306a36Sopenharmony_ci		return "CPU_axi_splitter";
429662306a36Sopenharmony_ci	case GOYA_ASYNC_EVENT_ID_PSOC_AXI_DEC:
429762306a36Sopenharmony_ci		return "PSOC_axi_dec";
429862306a36Sopenharmony_ci	case GOYA_ASYNC_EVENT_ID_PSOC:
429962306a36Sopenharmony_ci		return "PSOC";
430062306a36Sopenharmony_ci	case GOYA_ASYNC_EVENT_ID_TPC0_KRN_ERR:
430162306a36Sopenharmony_ci	case GOYA_ASYNC_EVENT_ID_TPC1_KRN_ERR:
430262306a36Sopenharmony_ci	case GOYA_ASYNC_EVENT_ID_TPC2_KRN_ERR:
430362306a36Sopenharmony_ci	case GOYA_ASYNC_EVENT_ID_TPC3_KRN_ERR:
430462306a36Sopenharmony_ci	case GOYA_ASYNC_EVENT_ID_TPC4_KRN_ERR:
430562306a36Sopenharmony_ci	case GOYA_ASYNC_EVENT_ID_TPC5_KRN_ERR:
430662306a36Sopenharmony_ci	case GOYA_ASYNC_EVENT_ID_TPC6_KRN_ERR:
430762306a36Sopenharmony_ci	case GOYA_ASYNC_EVENT_ID_TPC7_KRN_ERR:
430862306a36Sopenharmony_ci		return "TPC%d_krn_err";
430962306a36Sopenharmony_ci	case GOYA_ASYNC_EVENT_ID_TPC0_CMDQ ... GOYA_ASYNC_EVENT_ID_TPC7_CMDQ:
431062306a36Sopenharmony_ci		return "TPC%d_cq";
431162306a36Sopenharmony_ci	case GOYA_ASYNC_EVENT_ID_TPC0_QM ... GOYA_ASYNC_EVENT_ID_TPC7_QM:
431262306a36Sopenharmony_ci		return "TPC%d_qm";
431362306a36Sopenharmony_ci	case GOYA_ASYNC_EVENT_ID_MME_QM:
431462306a36Sopenharmony_ci		return "MME_qm";
431562306a36Sopenharmony_ci	case GOYA_ASYNC_EVENT_ID_MME_CMDQ:
431662306a36Sopenharmony_ci		return "MME_cq";
431762306a36Sopenharmony_ci	case GOYA_ASYNC_EVENT_ID_DMA0_QM ... GOYA_ASYNC_EVENT_ID_DMA4_QM:
431862306a36Sopenharmony_ci		return "DMA%d_qm";
431962306a36Sopenharmony_ci	case GOYA_ASYNC_EVENT_ID_DMA0_CH ... GOYA_ASYNC_EVENT_ID_DMA4_CH:
432062306a36Sopenharmony_ci		return "DMA%d_ch";
432162306a36Sopenharmony_ci	case GOYA_ASYNC_EVENT_ID_TPC0_BMON_SPMU:
432262306a36Sopenharmony_ci	case GOYA_ASYNC_EVENT_ID_TPC1_BMON_SPMU:
432362306a36Sopenharmony_ci	case GOYA_ASYNC_EVENT_ID_TPC2_BMON_SPMU:
432462306a36Sopenharmony_ci	case GOYA_ASYNC_EVENT_ID_TPC3_BMON_SPMU:
432562306a36Sopenharmony_ci	case GOYA_ASYNC_EVENT_ID_TPC4_BMON_SPMU:
432662306a36Sopenharmony_ci	case GOYA_ASYNC_EVENT_ID_TPC5_BMON_SPMU:
432762306a36Sopenharmony_ci	case GOYA_ASYNC_EVENT_ID_TPC6_BMON_SPMU:
432862306a36Sopenharmony_ci	case GOYA_ASYNC_EVENT_ID_TPC7_BMON_SPMU:
432962306a36Sopenharmony_ci		return "TPC%d_bmon_spmu";
433062306a36Sopenharmony_ci	case GOYA_ASYNC_EVENT_ID_DMA_BM_CH0 ... GOYA_ASYNC_EVENT_ID_DMA_BM_CH4:
433162306a36Sopenharmony_ci		return "DMA_bm_ch%d";
433262306a36Sopenharmony_ci	case GOYA_ASYNC_EVENT_ID_FIX_POWER_ENV_S:
433362306a36Sopenharmony_ci		return "POWER_ENV_S";
433462306a36Sopenharmony_ci	case GOYA_ASYNC_EVENT_ID_FIX_POWER_ENV_E:
433562306a36Sopenharmony_ci		return "POWER_ENV_E";
433662306a36Sopenharmony_ci	case GOYA_ASYNC_EVENT_ID_FIX_THERMAL_ENV_S:
433762306a36Sopenharmony_ci		return "THERMAL_ENV_S";
433862306a36Sopenharmony_ci	case GOYA_ASYNC_EVENT_ID_FIX_THERMAL_ENV_E:
433962306a36Sopenharmony_ci		return "THERMAL_ENV_E";
434062306a36Sopenharmony_ci	case GOYA_ASYNC_EVENT_PKT_QUEUE_OUT_SYNC:
434162306a36Sopenharmony_ci		return "QUEUE_OUT_OF_SYNC";
434262306a36Sopenharmony_ci	default:
434362306a36Sopenharmony_ci		return "N/A";
434462306a36Sopenharmony_ci	}
434562306a36Sopenharmony_ci}
434662306a36Sopenharmony_ci
434762306a36Sopenharmony_cistatic void goya_get_event_desc(u16 event_type, char *desc, size_t size)
434862306a36Sopenharmony_ci{
434962306a36Sopenharmony_ci	u8 index;
435062306a36Sopenharmony_ci
435162306a36Sopenharmony_ci	switch (event_type) {
435262306a36Sopenharmony_ci	case GOYA_ASYNC_EVENT_ID_TPC0_ECC:
435362306a36Sopenharmony_ci	case GOYA_ASYNC_EVENT_ID_TPC1_ECC:
435462306a36Sopenharmony_ci	case GOYA_ASYNC_EVENT_ID_TPC2_ECC:
435562306a36Sopenharmony_ci	case GOYA_ASYNC_EVENT_ID_TPC3_ECC:
435662306a36Sopenharmony_ci	case GOYA_ASYNC_EVENT_ID_TPC4_ECC:
435762306a36Sopenharmony_ci	case GOYA_ASYNC_EVENT_ID_TPC5_ECC:
435862306a36Sopenharmony_ci	case GOYA_ASYNC_EVENT_ID_TPC6_ECC:
435962306a36Sopenharmony_ci	case GOYA_ASYNC_EVENT_ID_TPC7_ECC:
436062306a36Sopenharmony_ci		index = (event_type - GOYA_ASYNC_EVENT_ID_TPC0_ECC) / 3;
436162306a36Sopenharmony_ci		snprintf(desc, size, _goya_get_event_desc(event_type), index);
436262306a36Sopenharmony_ci		break;
436362306a36Sopenharmony_ci	case GOYA_ASYNC_EVENT_ID_SRAM0 ... GOYA_ASYNC_EVENT_ID_SRAM29:
436462306a36Sopenharmony_ci		index = event_type - GOYA_ASYNC_EVENT_ID_SRAM0;
436562306a36Sopenharmony_ci		snprintf(desc, size, _goya_get_event_desc(event_type), index);
436662306a36Sopenharmony_ci		break;
436762306a36Sopenharmony_ci	case GOYA_ASYNC_EVENT_ID_PLL0 ... GOYA_ASYNC_EVENT_ID_PLL6:
436862306a36Sopenharmony_ci		index = event_type - GOYA_ASYNC_EVENT_ID_PLL0;
436962306a36Sopenharmony_ci		snprintf(desc, size, _goya_get_event_desc(event_type), index);
437062306a36Sopenharmony_ci		break;
437162306a36Sopenharmony_ci	case GOYA_ASYNC_EVENT_ID_TPC0_DEC:
437262306a36Sopenharmony_ci	case GOYA_ASYNC_EVENT_ID_TPC1_DEC:
437362306a36Sopenharmony_ci	case GOYA_ASYNC_EVENT_ID_TPC2_DEC:
437462306a36Sopenharmony_ci	case GOYA_ASYNC_EVENT_ID_TPC3_DEC:
437562306a36Sopenharmony_ci	case GOYA_ASYNC_EVENT_ID_TPC4_DEC:
437662306a36Sopenharmony_ci	case GOYA_ASYNC_EVENT_ID_TPC5_DEC:
437762306a36Sopenharmony_ci	case GOYA_ASYNC_EVENT_ID_TPC6_DEC:
437862306a36Sopenharmony_ci	case GOYA_ASYNC_EVENT_ID_TPC7_DEC:
437962306a36Sopenharmony_ci		index = (event_type - GOYA_ASYNC_EVENT_ID_TPC0_DEC) / 3;
438062306a36Sopenharmony_ci		snprintf(desc, size, _goya_get_event_desc(event_type), index);
438162306a36Sopenharmony_ci		break;
438262306a36Sopenharmony_ci	case GOYA_ASYNC_EVENT_ID_TPC0_KRN_ERR:
438362306a36Sopenharmony_ci	case GOYA_ASYNC_EVENT_ID_TPC1_KRN_ERR:
438462306a36Sopenharmony_ci	case GOYA_ASYNC_EVENT_ID_TPC2_KRN_ERR:
438562306a36Sopenharmony_ci	case GOYA_ASYNC_EVENT_ID_TPC3_KRN_ERR:
438662306a36Sopenharmony_ci	case GOYA_ASYNC_EVENT_ID_TPC4_KRN_ERR:
438762306a36Sopenharmony_ci	case GOYA_ASYNC_EVENT_ID_TPC5_KRN_ERR:
438862306a36Sopenharmony_ci	case GOYA_ASYNC_EVENT_ID_TPC6_KRN_ERR:
438962306a36Sopenharmony_ci	case GOYA_ASYNC_EVENT_ID_TPC7_KRN_ERR:
439062306a36Sopenharmony_ci		index = (event_type - GOYA_ASYNC_EVENT_ID_TPC0_KRN_ERR) / 10;
439162306a36Sopenharmony_ci		snprintf(desc, size, _goya_get_event_desc(event_type), index);
439262306a36Sopenharmony_ci		break;
439362306a36Sopenharmony_ci	case GOYA_ASYNC_EVENT_ID_TPC0_CMDQ ... GOYA_ASYNC_EVENT_ID_TPC7_CMDQ:
439462306a36Sopenharmony_ci		index = event_type - GOYA_ASYNC_EVENT_ID_TPC0_CMDQ;
439562306a36Sopenharmony_ci		snprintf(desc, size, _goya_get_event_desc(event_type), index);
439662306a36Sopenharmony_ci		break;
439762306a36Sopenharmony_ci	case GOYA_ASYNC_EVENT_ID_TPC0_QM ... GOYA_ASYNC_EVENT_ID_TPC7_QM:
439862306a36Sopenharmony_ci		index = event_type - GOYA_ASYNC_EVENT_ID_TPC0_QM;
439962306a36Sopenharmony_ci		snprintf(desc, size, _goya_get_event_desc(event_type), index);
440062306a36Sopenharmony_ci		break;
440162306a36Sopenharmony_ci	case GOYA_ASYNC_EVENT_ID_DMA0_QM ... GOYA_ASYNC_EVENT_ID_DMA4_QM:
440262306a36Sopenharmony_ci		index = event_type - GOYA_ASYNC_EVENT_ID_DMA0_QM;
440362306a36Sopenharmony_ci		snprintf(desc, size, _goya_get_event_desc(event_type), index);
440462306a36Sopenharmony_ci		break;
440562306a36Sopenharmony_ci	case GOYA_ASYNC_EVENT_ID_DMA0_CH ... GOYA_ASYNC_EVENT_ID_DMA4_CH:
440662306a36Sopenharmony_ci		index = event_type - GOYA_ASYNC_EVENT_ID_DMA0_CH;
440762306a36Sopenharmony_ci		snprintf(desc, size, _goya_get_event_desc(event_type), index);
440862306a36Sopenharmony_ci		break;
440962306a36Sopenharmony_ci	case GOYA_ASYNC_EVENT_ID_TPC0_BMON_SPMU:
441062306a36Sopenharmony_ci	case GOYA_ASYNC_EVENT_ID_TPC1_BMON_SPMU:
441162306a36Sopenharmony_ci	case GOYA_ASYNC_EVENT_ID_TPC2_BMON_SPMU:
441262306a36Sopenharmony_ci	case GOYA_ASYNC_EVENT_ID_TPC3_BMON_SPMU:
441362306a36Sopenharmony_ci	case GOYA_ASYNC_EVENT_ID_TPC4_BMON_SPMU:
441462306a36Sopenharmony_ci	case GOYA_ASYNC_EVENT_ID_TPC5_BMON_SPMU:
441562306a36Sopenharmony_ci	case GOYA_ASYNC_EVENT_ID_TPC6_BMON_SPMU:
441662306a36Sopenharmony_ci	case GOYA_ASYNC_EVENT_ID_TPC7_BMON_SPMU:
441762306a36Sopenharmony_ci		index = (event_type - GOYA_ASYNC_EVENT_ID_TPC0_BMON_SPMU) / 10;
441862306a36Sopenharmony_ci		snprintf(desc, size, _goya_get_event_desc(event_type), index);
441962306a36Sopenharmony_ci		break;
442062306a36Sopenharmony_ci	case GOYA_ASYNC_EVENT_ID_DMA_BM_CH0 ... GOYA_ASYNC_EVENT_ID_DMA_BM_CH4:
442162306a36Sopenharmony_ci		index = event_type - GOYA_ASYNC_EVENT_ID_DMA_BM_CH0;
442262306a36Sopenharmony_ci		snprintf(desc, size, _goya_get_event_desc(event_type), index);
442362306a36Sopenharmony_ci		break;
442462306a36Sopenharmony_ci	case GOYA_ASYNC_EVENT_PKT_QUEUE_OUT_SYNC:
442562306a36Sopenharmony_ci		snprintf(desc, size, _goya_get_event_desc(event_type));
442662306a36Sopenharmony_ci		break;
442762306a36Sopenharmony_ci	default:
442862306a36Sopenharmony_ci		snprintf(desc, size, _goya_get_event_desc(event_type));
442962306a36Sopenharmony_ci		break;
443062306a36Sopenharmony_ci	}
443162306a36Sopenharmony_ci}
443262306a36Sopenharmony_ci
443362306a36Sopenharmony_cistatic void goya_print_razwi_info(struct hl_device *hdev)
443462306a36Sopenharmony_ci{
443562306a36Sopenharmony_ci	if (RREG32(mmDMA_MACRO_RAZWI_LBW_WT_VLD)) {
443662306a36Sopenharmony_ci		dev_err_ratelimited(hdev->dev, "Illegal write to LBW\n");
443762306a36Sopenharmony_ci		WREG32(mmDMA_MACRO_RAZWI_LBW_WT_VLD, 0);
443862306a36Sopenharmony_ci	}
443962306a36Sopenharmony_ci
444062306a36Sopenharmony_ci	if (RREG32(mmDMA_MACRO_RAZWI_LBW_RD_VLD)) {
444162306a36Sopenharmony_ci		dev_err_ratelimited(hdev->dev, "Illegal read from LBW\n");
444262306a36Sopenharmony_ci		WREG32(mmDMA_MACRO_RAZWI_LBW_RD_VLD, 0);
444362306a36Sopenharmony_ci	}
444462306a36Sopenharmony_ci
444562306a36Sopenharmony_ci	if (RREG32(mmDMA_MACRO_RAZWI_HBW_WT_VLD)) {
444662306a36Sopenharmony_ci		dev_err_ratelimited(hdev->dev, "Illegal write to HBW\n");
444762306a36Sopenharmony_ci		WREG32(mmDMA_MACRO_RAZWI_HBW_WT_VLD, 0);
444862306a36Sopenharmony_ci	}
444962306a36Sopenharmony_ci
445062306a36Sopenharmony_ci	if (RREG32(mmDMA_MACRO_RAZWI_HBW_RD_VLD)) {
445162306a36Sopenharmony_ci		dev_err_ratelimited(hdev->dev, "Illegal read from HBW\n");
445262306a36Sopenharmony_ci		WREG32(mmDMA_MACRO_RAZWI_HBW_RD_VLD, 0);
445362306a36Sopenharmony_ci	}
445462306a36Sopenharmony_ci}
445562306a36Sopenharmony_ci
445662306a36Sopenharmony_cistatic void goya_print_mmu_error_info(struct hl_device *hdev)
445762306a36Sopenharmony_ci{
445862306a36Sopenharmony_ci	struct goya_device *goya = hdev->asic_specific;
445962306a36Sopenharmony_ci	u64 addr;
446062306a36Sopenharmony_ci	u32 val;
446162306a36Sopenharmony_ci
446262306a36Sopenharmony_ci	if (!(goya->hw_cap_initialized & HW_CAP_MMU))
446362306a36Sopenharmony_ci		return;
446462306a36Sopenharmony_ci
446562306a36Sopenharmony_ci	val = RREG32(mmMMU_PAGE_ERROR_CAPTURE);
446662306a36Sopenharmony_ci	if (val & MMU_PAGE_ERROR_CAPTURE_ENTRY_VALID_MASK) {
446762306a36Sopenharmony_ci		addr = val & MMU_PAGE_ERROR_CAPTURE_VA_49_32_MASK;
446862306a36Sopenharmony_ci		addr <<= 32;
446962306a36Sopenharmony_ci		addr |= RREG32(mmMMU_PAGE_ERROR_CAPTURE_VA);
447062306a36Sopenharmony_ci
447162306a36Sopenharmony_ci		dev_err_ratelimited(hdev->dev, "MMU page fault on va 0x%llx\n",
447262306a36Sopenharmony_ci					addr);
447362306a36Sopenharmony_ci
447462306a36Sopenharmony_ci		WREG32(mmMMU_PAGE_ERROR_CAPTURE, 0);
447562306a36Sopenharmony_ci	}
447662306a36Sopenharmony_ci}
447762306a36Sopenharmony_ci
447862306a36Sopenharmony_cistatic void goya_print_out_of_sync_info(struct hl_device *hdev,
447962306a36Sopenharmony_ci					struct cpucp_pkt_sync_err *sync_err)
448062306a36Sopenharmony_ci{
448162306a36Sopenharmony_ci	struct hl_hw_queue *q = &hdev->kernel_queues[GOYA_QUEUE_ID_CPU_PQ];
448262306a36Sopenharmony_ci
448362306a36Sopenharmony_ci	dev_err(hdev->dev, "Out of sync with FW, FW: pi=%u, ci=%u, LKD: pi=%u, ci=%d\n",
448462306a36Sopenharmony_ci		le32_to_cpu(sync_err->pi), le32_to_cpu(sync_err->ci), q->pi, atomic_read(&q->ci));
448562306a36Sopenharmony_ci}
448662306a36Sopenharmony_ci
448762306a36Sopenharmony_cistatic void goya_print_irq_info(struct hl_device *hdev, u16 event_type,
448862306a36Sopenharmony_ci				bool razwi)
448962306a36Sopenharmony_ci{
449062306a36Sopenharmony_ci	char desc[20] = "";
449162306a36Sopenharmony_ci
449262306a36Sopenharmony_ci	goya_get_event_desc(event_type, desc, sizeof(desc));
449362306a36Sopenharmony_ci	dev_err_ratelimited(hdev->dev, "Received H/W interrupt %d [\"%s\"]\n",
449462306a36Sopenharmony_ci		event_type, desc);
449562306a36Sopenharmony_ci
449662306a36Sopenharmony_ci	if (razwi) {
449762306a36Sopenharmony_ci		goya_print_razwi_info(hdev);
449862306a36Sopenharmony_ci		goya_print_mmu_error_info(hdev);
449962306a36Sopenharmony_ci	}
450062306a36Sopenharmony_ci}
450162306a36Sopenharmony_ci
450262306a36Sopenharmony_cistatic int goya_unmask_irq_arr(struct hl_device *hdev, u32 *irq_arr,
450362306a36Sopenharmony_ci		size_t irq_arr_size)
450462306a36Sopenharmony_ci{
450562306a36Sopenharmony_ci	struct cpucp_unmask_irq_arr_packet *pkt;
450662306a36Sopenharmony_ci	size_t total_pkt_size;
450762306a36Sopenharmony_ci	u64 result;
450862306a36Sopenharmony_ci	int rc;
450962306a36Sopenharmony_ci	int irq_num_entries, irq_arr_index;
451062306a36Sopenharmony_ci	__le32 *goya_irq_arr;
451162306a36Sopenharmony_ci
451262306a36Sopenharmony_ci	total_pkt_size = sizeof(struct cpucp_unmask_irq_arr_packet) +
451362306a36Sopenharmony_ci			irq_arr_size;
451462306a36Sopenharmony_ci
451562306a36Sopenharmony_ci	/* data should be aligned to 8 bytes in order to CPU-CP to copy it */
451662306a36Sopenharmony_ci	total_pkt_size = (total_pkt_size + 0x7) & ~0x7;
451762306a36Sopenharmony_ci
451862306a36Sopenharmony_ci	/* total_pkt_size is casted to u16 later on */
451962306a36Sopenharmony_ci	if (total_pkt_size > USHRT_MAX) {
452062306a36Sopenharmony_ci		dev_err(hdev->dev, "too many elements in IRQ array\n");
452162306a36Sopenharmony_ci		return -EINVAL;
452262306a36Sopenharmony_ci	}
452362306a36Sopenharmony_ci
452462306a36Sopenharmony_ci	pkt = kzalloc(total_pkt_size, GFP_KERNEL);
452562306a36Sopenharmony_ci	if (!pkt)
452662306a36Sopenharmony_ci		return -ENOMEM;
452762306a36Sopenharmony_ci
452862306a36Sopenharmony_ci	irq_num_entries = irq_arr_size / sizeof(irq_arr[0]);
452962306a36Sopenharmony_ci	pkt->length = cpu_to_le32(irq_num_entries);
453062306a36Sopenharmony_ci
453162306a36Sopenharmony_ci	/* We must perform any necessary endianness conversation on the irq
453262306a36Sopenharmony_ci	 * array being passed to the goya hardware
453362306a36Sopenharmony_ci	 */
453462306a36Sopenharmony_ci	for (irq_arr_index = 0, goya_irq_arr = (__le32 *) &pkt->irqs;
453562306a36Sopenharmony_ci			irq_arr_index < irq_num_entries ; irq_arr_index++)
453662306a36Sopenharmony_ci		goya_irq_arr[irq_arr_index] =
453762306a36Sopenharmony_ci				cpu_to_le32(irq_arr[irq_arr_index]);
453862306a36Sopenharmony_ci
453962306a36Sopenharmony_ci	pkt->cpucp_pkt.ctl = cpu_to_le32(CPUCP_PACKET_UNMASK_RAZWI_IRQ_ARRAY <<
454062306a36Sopenharmony_ci						CPUCP_PKT_CTL_OPCODE_SHIFT);
454162306a36Sopenharmony_ci
454262306a36Sopenharmony_ci	rc = hdev->asic_funcs->send_cpu_message(hdev, (u32 *) pkt,
454362306a36Sopenharmony_ci						total_pkt_size,	0, &result);
454462306a36Sopenharmony_ci
454562306a36Sopenharmony_ci	if (rc)
454662306a36Sopenharmony_ci		dev_err(hdev->dev, "failed to unmask IRQ array\n");
454762306a36Sopenharmony_ci
454862306a36Sopenharmony_ci	kfree(pkt);
454962306a36Sopenharmony_ci
455062306a36Sopenharmony_ci	return rc;
455162306a36Sopenharmony_ci}
455262306a36Sopenharmony_ci
455362306a36Sopenharmony_cistatic int goya_compute_reset_late_init(struct hl_device *hdev)
455462306a36Sopenharmony_ci{
455562306a36Sopenharmony_ci	/*
455662306a36Sopenharmony_ci	 * Unmask all IRQs since some could have been received
455762306a36Sopenharmony_ci	 * during the soft reset
455862306a36Sopenharmony_ci	 */
455962306a36Sopenharmony_ci	return goya_unmask_irq_arr(hdev, goya_all_events,
456062306a36Sopenharmony_ci					sizeof(goya_all_events));
456162306a36Sopenharmony_ci}
456262306a36Sopenharmony_ci
456362306a36Sopenharmony_cistatic int goya_unmask_irq(struct hl_device *hdev, u16 event_type)
456462306a36Sopenharmony_ci{
456562306a36Sopenharmony_ci	struct cpucp_packet pkt;
456662306a36Sopenharmony_ci	u64 result;
456762306a36Sopenharmony_ci	int rc;
456862306a36Sopenharmony_ci
456962306a36Sopenharmony_ci	memset(&pkt, 0, sizeof(pkt));
457062306a36Sopenharmony_ci
457162306a36Sopenharmony_ci	pkt.ctl = cpu_to_le32(CPUCP_PACKET_UNMASK_RAZWI_IRQ <<
457262306a36Sopenharmony_ci				CPUCP_PKT_CTL_OPCODE_SHIFT);
457362306a36Sopenharmony_ci	pkt.value = cpu_to_le64(event_type);
457462306a36Sopenharmony_ci
457562306a36Sopenharmony_ci	rc = hdev->asic_funcs->send_cpu_message(hdev, (u32 *) &pkt, sizeof(pkt),
457662306a36Sopenharmony_ci						0, &result);
457762306a36Sopenharmony_ci
457862306a36Sopenharmony_ci	if (rc)
457962306a36Sopenharmony_ci		dev_err(hdev->dev, "failed to unmask RAZWI IRQ %d", event_type);
458062306a36Sopenharmony_ci
458162306a36Sopenharmony_ci	return rc;
458262306a36Sopenharmony_ci}
458362306a36Sopenharmony_ci
458462306a36Sopenharmony_cistatic void goya_print_clk_change_info(struct hl_device *hdev, u16 event_type)
458562306a36Sopenharmony_ci{
458662306a36Sopenharmony_ci	ktime_t zero_time = ktime_set(0, 0);
458762306a36Sopenharmony_ci
458862306a36Sopenharmony_ci	mutex_lock(&hdev->clk_throttling.lock);
458962306a36Sopenharmony_ci
459062306a36Sopenharmony_ci	switch (event_type) {
459162306a36Sopenharmony_ci	case GOYA_ASYNC_EVENT_ID_FIX_POWER_ENV_S:
459262306a36Sopenharmony_ci		hdev->clk_throttling.current_reason |= HL_CLK_THROTTLE_POWER;
459362306a36Sopenharmony_ci		hdev->clk_throttling.aggregated_reason |= HL_CLK_THROTTLE_POWER;
459462306a36Sopenharmony_ci		hdev->clk_throttling.timestamp[HL_CLK_THROTTLE_TYPE_POWER].start = ktime_get();
459562306a36Sopenharmony_ci		hdev->clk_throttling.timestamp[HL_CLK_THROTTLE_TYPE_POWER].end = zero_time;
459662306a36Sopenharmony_ci		dev_info_ratelimited(hdev->dev,
459762306a36Sopenharmony_ci			"Clock throttling due to power consumption\n");
459862306a36Sopenharmony_ci		break;
459962306a36Sopenharmony_ci
460062306a36Sopenharmony_ci	case GOYA_ASYNC_EVENT_ID_FIX_POWER_ENV_E:
460162306a36Sopenharmony_ci		hdev->clk_throttling.current_reason &= ~HL_CLK_THROTTLE_POWER;
460262306a36Sopenharmony_ci		hdev->clk_throttling.timestamp[HL_CLK_THROTTLE_TYPE_POWER].end = ktime_get();
460362306a36Sopenharmony_ci		dev_info_ratelimited(hdev->dev,
460462306a36Sopenharmony_ci			"Power envelop is safe, back to optimal clock\n");
460562306a36Sopenharmony_ci		break;
460662306a36Sopenharmony_ci
460762306a36Sopenharmony_ci	case GOYA_ASYNC_EVENT_ID_FIX_THERMAL_ENV_S:
460862306a36Sopenharmony_ci		hdev->clk_throttling.current_reason |= HL_CLK_THROTTLE_THERMAL;
460962306a36Sopenharmony_ci		hdev->clk_throttling.aggregated_reason |= HL_CLK_THROTTLE_THERMAL;
461062306a36Sopenharmony_ci		hdev->clk_throttling.timestamp[HL_CLK_THROTTLE_TYPE_THERMAL].start = ktime_get();
461162306a36Sopenharmony_ci		hdev->clk_throttling.timestamp[HL_CLK_THROTTLE_TYPE_THERMAL].end = zero_time;
461262306a36Sopenharmony_ci		dev_info_ratelimited(hdev->dev,
461362306a36Sopenharmony_ci			"Clock throttling due to overheating\n");
461462306a36Sopenharmony_ci		break;
461562306a36Sopenharmony_ci
461662306a36Sopenharmony_ci	case GOYA_ASYNC_EVENT_ID_FIX_THERMAL_ENV_E:
461762306a36Sopenharmony_ci		hdev->clk_throttling.current_reason &= ~HL_CLK_THROTTLE_THERMAL;
461862306a36Sopenharmony_ci		hdev->clk_throttling.timestamp[HL_CLK_THROTTLE_TYPE_THERMAL].end = ktime_get();
461962306a36Sopenharmony_ci		dev_info_ratelimited(hdev->dev,
462062306a36Sopenharmony_ci			"Thermal envelop is safe, back to optimal clock\n");
462162306a36Sopenharmony_ci		break;
462262306a36Sopenharmony_ci
462362306a36Sopenharmony_ci	default:
462462306a36Sopenharmony_ci		dev_err(hdev->dev, "Received invalid clock change event %d\n",
462562306a36Sopenharmony_ci			event_type);
462662306a36Sopenharmony_ci		break;
462762306a36Sopenharmony_ci	}
462862306a36Sopenharmony_ci
462962306a36Sopenharmony_ci	mutex_unlock(&hdev->clk_throttling.lock);
463062306a36Sopenharmony_ci}
463162306a36Sopenharmony_ci
463262306a36Sopenharmony_civoid goya_handle_eqe(struct hl_device *hdev, struct hl_eq_entry *eq_entry)
463362306a36Sopenharmony_ci{
463462306a36Sopenharmony_ci	u32 ctl = le32_to_cpu(eq_entry->hdr.ctl);
463562306a36Sopenharmony_ci	u16 event_type = ((ctl & EQ_CTL_EVENT_TYPE_MASK)
463662306a36Sopenharmony_ci				>> EQ_CTL_EVENT_TYPE_SHIFT);
463762306a36Sopenharmony_ci	struct goya_device *goya = hdev->asic_specific;
463862306a36Sopenharmony_ci
463962306a36Sopenharmony_ci	if (event_type >= GOYA_ASYNC_EVENT_ID_SIZE) {
464062306a36Sopenharmony_ci		dev_err(hdev->dev, "Event type %u exceeds maximum of %u",
464162306a36Sopenharmony_ci				event_type, GOYA_ASYNC_EVENT_ID_SIZE - 1);
464262306a36Sopenharmony_ci		return;
464362306a36Sopenharmony_ci	}
464462306a36Sopenharmony_ci
464562306a36Sopenharmony_ci	goya->events_stat[event_type]++;
464662306a36Sopenharmony_ci	goya->events_stat_aggregate[event_type]++;
464762306a36Sopenharmony_ci
464862306a36Sopenharmony_ci	switch (event_type) {
464962306a36Sopenharmony_ci	case GOYA_ASYNC_EVENT_ID_PCIE_IF:
465062306a36Sopenharmony_ci	case GOYA_ASYNC_EVENT_ID_TPC0_ECC:
465162306a36Sopenharmony_ci	case GOYA_ASYNC_EVENT_ID_TPC1_ECC:
465262306a36Sopenharmony_ci	case GOYA_ASYNC_EVENT_ID_TPC2_ECC:
465362306a36Sopenharmony_ci	case GOYA_ASYNC_EVENT_ID_TPC3_ECC:
465462306a36Sopenharmony_ci	case GOYA_ASYNC_EVENT_ID_TPC4_ECC:
465562306a36Sopenharmony_ci	case GOYA_ASYNC_EVENT_ID_TPC5_ECC:
465662306a36Sopenharmony_ci	case GOYA_ASYNC_EVENT_ID_TPC6_ECC:
465762306a36Sopenharmony_ci	case GOYA_ASYNC_EVENT_ID_TPC7_ECC:
465862306a36Sopenharmony_ci	case GOYA_ASYNC_EVENT_ID_MME_ECC:
465962306a36Sopenharmony_ci	case GOYA_ASYNC_EVENT_ID_MME_ECC_EXT:
466062306a36Sopenharmony_ci	case GOYA_ASYNC_EVENT_ID_MMU_ECC:
466162306a36Sopenharmony_ci	case GOYA_ASYNC_EVENT_ID_DMA_MACRO:
466262306a36Sopenharmony_ci	case GOYA_ASYNC_EVENT_ID_DMA_ECC:
466362306a36Sopenharmony_ci	case GOYA_ASYNC_EVENT_ID_CPU_IF_ECC:
466462306a36Sopenharmony_ci	case GOYA_ASYNC_EVENT_ID_PSOC_MEM:
466562306a36Sopenharmony_ci	case GOYA_ASYNC_EVENT_ID_PSOC_CORESIGHT:
466662306a36Sopenharmony_ci	case GOYA_ASYNC_EVENT_ID_SRAM0 ... GOYA_ASYNC_EVENT_ID_SRAM29:
466762306a36Sopenharmony_ci	case GOYA_ASYNC_EVENT_ID_GIC500:
466862306a36Sopenharmony_ci	case GOYA_ASYNC_EVENT_ID_PLL0 ... GOYA_ASYNC_EVENT_ID_PLL6:
466962306a36Sopenharmony_ci	case GOYA_ASYNC_EVENT_ID_AXI_ECC:
467062306a36Sopenharmony_ci	case GOYA_ASYNC_EVENT_ID_L2_RAM_ECC:
467162306a36Sopenharmony_ci		goya_print_irq_info(hdev, event_type, false);
467262306a36Sopenharmony_ci		if (hdev->hard_reset_on_fw_events)
467362306a36Sopenharmony_ci			hl_device_reset(hdev, (HL_DRV_RESET_HARD |
467462306a36Sopenharmony_ci						HL_DRV_RESET_FW_FATAL_ERR));
467562306a36Sopenharmony_ci		break;
467662306a36Sopenharmony_ci
467762306a36Sopenharmony_ci	case GOYA_ASYNC_EVENT_ID_PSOC_GPIO_05_SW_RESET:
467862306a36Sopenharmony_ci		goya_print_irq_info(hdev, event_type, false);
467962306a36Sopenharmony_ci		if (hdev->hard_reset_on_fw_events)
468062306a36Sopenharmony_ci			hl_device_reset(hdev, HL_DRV_RESET_HARD);
468162306a36Sopenharmony_ci		break;
468262306a36Sopenharmony_ci
468362306a36Sopenharmony_ci	case GOYA_ASYNC_EVENT_ID_PCIE_DEC:
468462306a36Sopenharmony_ci	case GOYA_ASYNC_EVENT_ID_TPC0_DEC:
468562306a36Sopenharmony_ci	case GOYA_ASYNC_EVENT_ID_TPC1_DEC:
468662306a36Sopenharmony_ci	case GOYA_ASYNC_EVENT_ID_TPC2_DEC:
468762306a36Sopenharmony_ci	case GOYA_ASYNC_EVENT_ID_TPC3_DEC:
468862306a36Sopenharmony_ci	case GOYA_ASYNC_EVENT_ID_TPC4_DEC:
468962306a36Sopenharmony_ci	case GOYA_ASYNC_EVENT_ID_TPC5_DEC:
469062306a36Sopenharmony_ci	case GOYA_ASYNC_EVENT_ID_TPC6_DEC:
469162306a36Sopenharmony_ci	case GOYA_ASYNC_EVENT_ID_TPC7_DEC:
469262306a36Sopenharmony_ci	case GOYA_ASYNC_EVENT_ID_MME_WACS:
469362306a36Sopenharmony_ci	case GOYA_ASYNC_EVENT_ID_MME_WACSD:
469462306a36Sopenharmony_ci	case GOYA_ASYNC_EVENT_ID_CPU_AXI_SPLITTER:
469562306a36Sopenharmony_ci	case GOYA_ASYNC_EVENT_ID_PSOC_AXI_DEC:
469662306a36Sopenharmony_ci	case GOYA_ASYNC_EVENT_ID_PSOC:
469762306a36Sopenharmony_ci	case GOYA_ASYNC_EVENT_ID_TPC0_KRN_ERR:
469862306a36Sopenharmony_ci	case GOYA_ASYNC_EVENT_ID_TPC1_KRN_ERR:
469962306a36Sopenharmony_ci	case GOYA_ASYNC_EVENT_ID_TPC2_KRN_ERR:
470062306a36Sopenharmony_ci	case GOYA_ASYNC_EVENT_ID_TPC3_KRN_ERR:
470162306a36Sopenharmony_ci	case GOYA_ASYNC_EVENT_ID_TPC4_KRN_ERR:
470262306a36Sopenharmony_ci	case GOYA_ASYNC_EVENT_ID_TPC5_KRN_ERR:
470362306a36Sopenharmony_ci	case GOYA_ASYNC_EVENT_ID_TPC6_KRN_ERR:
470462306a36Sopenharmony_ci	case GOYA_ASYNC_EVENT_ID_TPC7_KRN_ERR:
470562306a36Sopenharmony_ci	case GOYA_ASYNC_EVENT_ID_TPC0_CMDQ ... GOYA_ASYNC_EVENT_ID_TPC7_QM:
470662306a36Sopenharmony_ci	case GOYA_ASYNC_EVENT_ID_MME_QM:
470762306a36Sopenharmony_ci	case GOYA_ASYNC_EVENT_ID_MME_CMDQ:
470862306a36Sopenharmony_ci	case GOYA_ASYNC_EVENT_ID_DMA0_QM ... GOYA_ASYNC_EVENT_ID_DMA4_QM:
470962306a36Sopenharmony_ci	case GOYA_ASYNC_EVENT_ID_DMA0_CH ... GOYA_ASYNC_EVENT_ID_DMA4_CH:
471062306a36Sopenharmony_ci		goya_print_irq_info(hdev, event_type, true);
471162306a36Sopenharmony_ci		goya_unmask_irq(hdev, event_type);
471262306a36Sopenharmony_ci		break;
471362306a36Sopenharmony_ci
471462306a36Sopenharmony_ci	case GOYA_ASYNC_EVENT_ID_PSOC_GPIO_10_VRHOT_ICRIT:
471562306a36Sopenharmony_ci	case GOYA_ASYNC_EVENT_ID_TPC0_BMON_SPMU:
471662306a36Sopenharmony_ci	case GOYA_ASYNC_EVENT_ID_TPC1_BMON_SPMU:
471762306a36Sopenharmony_ci	case GOYA_ASYNC_EVENT_ID_TPC2_BMON_SPMU:
471862306a36Sopenharmony_ci	case GOYA_ASYNC_EVENT_ID_TPC3_BMON_SPMU:
471962306a36Sopenharmony_ci	case GOYA_ASYNC_EVENT_ID_TPC4_BMON_SPMU:
472062306a36Sopenharmony_ci	case GOYA_ASYNC_EVENT_ID_TPC5_BMON_SPMU:
472162306a36Sopenharmony_ci	case GOYA_ASYNC_EVENT_ID_TPC6_BMON_SPMU:
472262306a36Sopenharmony_ci	case GOYA_ASYNC_EVENT_ID_TPC7_BMON_SPMU:
472362306a36Sopenharmony_ci	case GOYA_ASYNC_EVENT_ID_DMA_BM_CH0 ... GOYA_ASYNC_EVENT_ID_DMA_BM_CH4:
472462306a36Sopenharmony_ci		goya_print_irq_info(hdev, event_type, false);
472562306a36Sopenharmony_ci		goya_unmask_irq(hdev, event_type);
472662306a36Sopenharmony_ci		break;
472762306a36Sopenharmony_ci
472862306a36Sopenharmony_ci	case GOYA_ASYNC_EVENT_ID_FIX_POWER_ENV_S:
472962306a36Sopenharmony_ci	case GOYA_ASYNC_EVENT_ID_FIX_POWER_ENV_E:
473062306a36Sopenharmony_ci	case GOYA_ASYNC_EVENT_ID_FIX_THERMAL_ENV_S:
473162306a36Sopenharmony_ci	case GOYA_ASYNC_EVENT_ID_FIX_THERMAL_ENV_E:
473262306a36Sopenharmony_ci		goya_print_clk_change_info(hdev, event_type);
473362306a36Sopenharmony_ci		goya_unmask_irq(hdev, event_type);
473462306a36Sopenharmony_ci		break;
473562306a36Sopenharmony_ci
473662306a36Sopenharmony_ci	case GOYA_ASYNC_EVENT_PKT_QUEUE_OUT_SYNC:
473762306a36Sopenharmony_ci		goya_print_irq_info(hdev, event_type, false);
473862306a36Sopenharmony_ci		goya_print_out_of_sync_info(hdev, &eq_entry->pkt_sync_err);
473962306a36Sopenharmony_ci		if (hdev->hard_reset_on_fw_events)
474062306a36Sopenharmony_ci			hl_device_reset(hdev, HL_DRV_RESET_HARD);
474162306a36Sopenharmony_ci		else
474262306a36Sopenharmony_ci			hl_fw_unmask_irq(hdev, event_type);
474362306a36Sopenharmony_ci		break;
474462306a36Sopenharmony_ci
474562306a36Sopenharmony_ci	default:
474662306a36Sopenharmony_ci		dev_err(hdev->dev, "Received invalid H/W interrupt %d\n",
474762306a36Sopenharmony_ci				event_type);
474862306a36Sopenharmony_ci		break;
474962306a36Sopenharmony_ci	}
475062306a36Sopenharmony_ci}
475162306a36Sopenharmony_ci
475262306a36Sopenharmony_civoid *goya_get_events_stat(struct hl_device *hdev, bool aggregate, u32 *size)
475362306a36Sopenharmony_ci{
475462306a36Sopenharmony_ci	struct goya_device *goya = hdev->asic_specific;
475562306a36Sopenharmony_ci
475662306a36Sopenharmony_ci	if (aggregate) {
475762306a36Sopenharmony_ci		*size = (u32) sizeof(goya->events_stat_aggregate);
475862306a36Sopenharmony_ci		return goya->events_stat_aggregate;
475962306a36Sopenharmony_ci	}
476062306a36Sopenharmony_ci
476162306a36Sopenharmony_ci	*size = (u32) sizeof(goya->events_stat);
476262306a36Sopenharmony_ci	return goya->events_stat;
476362306a36Sopenharmony_ci}
476462306a36Sopenharmony_ci
476562306a36Sopenharmony_cistatic int goya_memset_device_memory(struct hl_device *hdev, u64 addr, u64 size,
476662306a36Sopenharmony_ci				u64 val, bool is_dram)
476762306a36Sopenharmony_ci{
476862306a36Sopenharmony_ci	struct packet_lin_dma *lin_dma_pkt;
476962306a36Sopenharmony_ci	struct hl_cs_job *job;
477062306a36Sopenharmony_ci	u32 cb_size, ctl;
477162306a36Sopenharmony_ci	struct hl_cb *cb;
477262306a36Sopenharmony_ci	int rc, lin_dma_pkts_cnt;
477362306a36Sopenharmony_ci
477462306a36Sopenharmony_ci	lin_dma_pkts_cnt = DIV_ROUND_UP_ULL(size, SZ_2G);
477562306a36Sopenharmony_ci	cb_size = lin_dma_pkts_cnt * sizeof(struct packet_lin_dma) +
477662306a36Sopenharmony_ci						sizeof(struct packet_msg_prot);
477762306a36Sopenharmony_ci	cb = hl_cb_kernel_create(hdev, cb_size, false);
477862306a36Sopenharmony_ci	if (!cb)
477962306a36Sopenharmony_ci		return -ENOMEM;
478062306a36Sopenharmony_ci
478162306a36Sopenharmony_ci	lin_dma_pkt = cb->kernel_address;
478262306a36Sopenharmony_ci
478362306a36Sopenharmony_ci	do {
478462306a36Sopenharmony_ci		memset(lin_dma_pkt, 0, sizeof(*lin_dma_pkt));
478562306a36Sopenharmony_ci
478662306a36Sopenharmony_ci		ctl = ((PACKET_LIN_DMA << GOYA_PKT_CTL_OPCODE_SHIFT) |
478762306a36Sopenharmony_ci				(1 << GOYA_PKT_LIN_DMA_CTL_MEMSET_SHIFT) |
478862306a36Sopenharmony_ci				(1 << GOYA_PKT_LIN_DMA_CTL_WO_SHIFT) |
478962306a36Sopenharmony_ci				(1 << GOYA_PKT_CTL_RB_SHIFT) |
479062306a36Sopenharmony_ci				(1 << GOYA_PKT_CTL_MB_SHIFT));
479162306a36Sopenharmony_ci		ctl |= (is_dram ? HL_DMA_HOST_TO_DRAM : HL_DMA_HOST_TO_SRAM) <<
479262306a36Sopenharmony_ci				GOYA_PKT_LIN_DMA_CTL_DMA_DIR_SHIFT;
479362306a36Sopenharmony_ci		lin_dma_pkt->ctl = cpu_to_le32(ctl);
479462306a36Sopenharmony_ci
479562306a36Sopenharmony_ci		lin_dma_pkt->src_addr = cpu_to_le64(val);
479662306a36Sopenharmony_ci		lin_dma_pkt->dst_addr = cpu_to_le64(addr);
479762306a36Sopenharmony_ci		if (lin_dma_pkts_cnt > 1)
479862306a36Sopenharmony_ci			lin_dma_pkt->tsize = cpu_to_le32(SZ_2G);
479962306a36Sopenharmony_ci		else
480062306a36Sopenharmony_ci			lin_dma_pkt->tsize = cpu_to_le32(size);
480162306a36Sopenharmony_ci
480262306a36Sopenharmony_ci		size -= SZ_2G;
480362306a36Sopenharmony_ci		addr += SZ_2G;
480462306a36Sopenharmony_ci		lin_dma_pkt++;
480562306a36Sopenharmony_ci	} while (--lin_dma_pkts_cnt);
480662306a36Sopenharmony_ci
480762306a36Sopenharmony_ci	job = hl_cs_allocate_job(hdev, QUEUE_TYPE_EXT, true);
480862306a36Sopenharmony_ci	if (!job) {
480962306a36Sopenharmony_ci		dev_err(hdev->dev, "Failed to allocate a new job\n");
481062306a36Sopenharmony_ci		rc = -ENOMEM;
481162306a36Sopenharmony_ci		goto release_cb;
481262306a36Sopenharmony_ci	}
481362306a36Sopenharmony_ci
481462306a36Sopenharmony_ci	job->id = 0;
481562306a36Sopenharmony_ci	job->user_cb = cb;
481662306a36Sopenharmony_ci	atomic_inc(&job->user_cb->cs_cnt);
481762306a36Sopenharmony_ci	job->user_cb_size = cb_size;
481862306a36Sopenharmony_ci	job->hw_queue_id = GOYA_QUEUE_ID_DMA_0;
481962306a36Sopenharmony_ci	job->patched_cb = job->user_cb;
482062306a36Sopenharmony_ci	job->job_cb_size = job->user_cb_size;
482162306a36Sopenharmony_ci
482262306a36Sopenharmony_ci	hl_debugfs_add_job(hdev, job);
482362306a36Sopenharmony_ci
482462306a36Sopenharmony_ci	rc = goya_send_job_on_qman0(hdev, job);
482562306a36Sopenharmony_ci
482662306a36Sopenharmony_ci	hl_debugfs_remove_job(hdev, job);
482762306a36Sopenharmony_ci	kfree(job);
482862306a36Sopenharmony_ci	atomic_dec(&cb->cs_cnt);
482962306a36Sopenharmony_ci
483062306a36Sopenharmony_cirelease_cb:
483162306a36Sopenharmony_ci	hl_cb_put(cb);
483262306a36Sopenharmony_ci	hl_cb_destroy(&hdev->kernel_mem_mgr, cb->buf->handle);
483362306a36Sopenharmony_ci
483462306a36Sopenharmony_ci	return rc;
483562306a36Sopenharmony_ci}
483662306a36Sopenharmony_ci
483762306a36Sopenharmony_ciint goya_context_switch(struct hl_device *hdev, u32 asid)
483862306a36Sopenharmony_ci{
483962306a36Sopenharmony_ci	struct asic_fixed_properties *prop = &hdev->asic_prop;
484062306a36Sopenharmony_ci	u64 addr = prop->sram_base_address, sob_addr;
484162306a36Sopenharmony_ci	u32 size = hdev->pldm ? 0x10000 : prop->sram_size;
484262306a36Sopenharmony_ci	u64 val = 0x7777777777777777ull;
484362306a36Sopenharmony_ci	int rc, dma_id;
484462306a36Sopenharmony_ci	u32 channel_off = mmDMA_CH_1_WR_COMP_ADDR_LO -
484562306a36Sopenharmony_ci					mmDMA_CH_0_WR_COMP_ADDR_LO;
484662306a36Sopenharmony_ci
484762306a36Sopenharmony_ci	rc = goya_memset_device_memory(hdev, addr, size, val, false);
484862306a36Sopenharmony_ci	if (rc) {
484962306a36Sopenharmony_ci		dev_err(hdev->dev, "Failed to clear SRAM in context switch\n");
485062306a36Sopenharmony_ci		return rc;
485162306a36Sopenharmony_ci	}
485262306a36Sopenharmony_ci
485362306a36Sopenharmony_ci	/* we need to reset registers that the user is allowed to change */
485462306a36Sopenharmony_ci	sob_addr = CFG_BASE + mmSYNC_MNGR_SOB_OBJ_1007;
485562306a36Sopenharmony_ci	WREG32(mmDMA_CH_0_WR_COMP_ADDR_LO, lower_32_bits(sob_addr));
485662306a36Sopenharmony_ci
485762306a36Sopenharmony_ci	for (dma_id = 1 ; dma_id < NUMBER_OF_EXT_HW_QUEUES ; dma_id++) {
485862306a36Sopenharmony_ci		sob_addr = CFG_BASE + mmSYNC_MNGR_SOB_OBJ_1000 +
485962306a36Sopenharmony_ci							(dma_id - 1) * 4;
486062306a36Sopenharmony_ci		WREG32(mmDMA_CH_0_WR_COMP_ADDR_LO + channel_off * dma_id,
486162306a36Sopenharmony_ci						lower_32_bits(sob_addr));
486262306a36Sopenharmony_ci	}
486362306a36Sopenharmony_ci
486462306a36Sopenharmony_ci	WREG32(mmTPC_PLL_CLK_RLX_0, 0x200020);
486562306a36Sopenharmony_ci
486662306a36Sopenharmony_ci	goya_clear_sm_regs(hdev);
486762306a36Sopenharmony_ci
486862306a36Sopenharmony_ci	return 0;
486962306a36Sopenharmony_ci}
487062306a36Sopenharmony_ci
487162306a36Sopenharmony_cistatic int goya_mmu_clear_pgt_range(struct hl_device *hdev)
487262306a36Sopenharmony_ci{
487362306a36Sopenharmony_ci	struct asic_fixed_properties *prop = &hdev->asic_prop;
487462306a36Sopenharmony_ci	struct goya_device *goya = hdev->asic_specific;
487562306a36Sopenharmony_ci	u64 addr = prop->mmu_pgt_addr;
487662306a36Sopenharmony_ci	u32 size = prop->mmu_pgt_size + MMU_DRAM_DEFAULT_PAGE_SIZE +
487762306a36Sopenharmony_ci			MMU_CACHE_MNG_SIZE;
487862306a36Sopenharmony_ci
487962306a36Sopenharmony_ci	if (!(goya->hw_cap_initialized & HW_CAP_MMU))
488062306a36Sopenharmony_ci		return 0;
488162306a36Sopenharmony_ci
488262306a36Sopenharmony_ci	return goya_memset_device_memory(hdev, addr, size, 0, true);
488362306a36Sopenharmony_ci}
488462306a36Sopenharmony_ci
488562306a36Sopenharmony_cistatic int goya_mmu_set_dram_default_page(struct hl_device *hdev)
488662306a36Sopenharmony_ci{
488762306a36Sopenharmony_ci	struct goya_device *goya = hdev->asic_specific;
488862306a36Sopenharmony_ci	u64 addr = hdev->asic_prop.mmu_dram_default_page_addr;
488962306a36Sopenharmony_ci	u32 size = MMU_DRAM_DEFAULT_PAGE_SIZE;
489062306a36Sopenharmony_ci	u64 val = 0x9999999999999999ull;
489162306a36Sopenharmony_ci
489262306a36Sopenharmony_ci	if (!(goya->hw_cap_initialized & HW_CAP_MMU))
489362306a36Sopenharmony_ci		return 0;
489462306a36Sopenharmony_ci
489562306a36Sopenharmony_ci	return goya_memset_device_memory(hdev, addr, size, val, true);
489662306a36Sopenharmony_ci}
489762306a36Sopenharmony_ci
489862306a36Sopenharmony_cistatic int goya_mmu_add_mappings_for_device_cpu(struct hl_device *hdev)
489962306a36Sopenharmony_ci{
490062306a36Sopenharmony_ci	struct asic_fixed_properties *prop = &hdev->asic_prop;
490162306a36Sopenharmony_ci	struct goya_device *goya = hdev->asic_specific;
490262306a36Sopenharmony_ci	s64 off, cpu_off;
490362306a36Sopenharmony_ci	int rc;
490462306a36Sopenharmony_ci
490562306a36Sopenharmony_ci	if (!(goya->hw_cap_initialized & HW_CAP_MMU))
490662306a36Sopenharmony_ci		return 0;
490762306a36Sopenharmony_ci
490862306a36Sopenharmony_ci	for (off = 0 ; off < CPU_FW_IMAGE_SIZE ; off += PAGE_SIZE_2MB) {
490962306a36Sopenharmony_ci		rc = hl_mmu_map_page(hdev->kernel_ctx,
491062306a36Sopenharmony_ci			prop->dram_base_address + off,
491162306a36Sopenharmony_ci			prop->dram_base_address + off, PAGE_SIZE_2MB,
491262306a36Sopenharmony_ci			(off + PAGE_SIZE_2MB) == CPU_FW_IMAGE_SIZE);
491362306a36Sopenharmony_ci		if (rc) {
491462306a36Sopenharmony_ci			dev_err(hdev->dev, "Map failed for address 0x%llx\n",
491562306a36Sopenharmony_ci				prop->dram_base_address + off);
491662306a36Sopenharmony_ci			goto unmap;
491762306a36Sopenharmony_ci		}
491862306a36Sopenharmony_ci	}
491962306a36Sopenharmony_ci
492062306a36Sopenharmony_ci	if (!(hdev->cpu_accessible_dma_address & (PAGE_SIZE_2MB - 1))) {
492162306a36Sopenharmony_ci		rc = hl_mmu_map_page(hdev->kernel_ctx,
492262306a36Sopenharmony_ci			VA_CPU_ACCESSIBLE_MEM_ADDR,
492362306a36Sopenharmony_ci			hdev->cpu_accessible_dma_address,
492462306a36Sopenharmony_ci			PAGE_SIZE_2MB, true);
492562306a36Sopenharmony_ci
492662306a36Sopenharmony_ci		if (rc) {
492762306a36Sopenharmony_ci			dev_err(hdev->dev,
492862306a36Sopenharmony_ci				"Map failed for CPU accessible memory\n");
492962306a36Sopenharmony_ci			off -= PAGE_SIZE_2MB;
493062306a36Sopenharmony_ci			goto unmap;
493162306a36Sopenharmony_ci		}
493262306a36Sopenharmony_ci	} else {
493362306a36Sopenharmony_ci		for (cpu_off = 0 ; cpu_off < SZ_2M ; cpu_off += PAGE_SIZE_4KB) {
493462306a36Sopenharmony_ci			rc = hl_mmu_map_page(hdev->kernel_ctx,
493562306a36Sopenharmony_ci				VA_CPU_ACCESSIBLE_MEM_ADDR + cpu_off,
493662306a36Sopenharmony_ci				hdev->cpu_accessible_dma_address + cpu_off,
493762306a36Sopenharmony_ci				PAGE_SIZE_4KB, true);
493862306a36Sopenharmony_ci			if (rc) {
493962306a36Sopenharmony_ci				dev_err(hdev->dev,
494062306a36Sopenharmony_ci					"Map failed for CPU accessible memory\n");
494162306a36Sopenharmony_ci				cpu_off -= PAGE_SIZE_4KB;
494262306a36Sopenharmony_ci				goto unmap_cpu;
494362306a36Sopenharmony_ci			}
494462306a36Sopenharmony_ci		}
494562306a36Sopenharmony_ci	}
494662306a36Sopenharmony_ci
494762306a36Sopenharmony_ci	goya_mmu_prepare_reg(hdev, mmCPU_IF_ARUSER_OVR, HL_KERNEL_ASID_ID);
494862306a36Sopenharmony_ci	goya_mmu_prepare_reg(hdev, mmCPU_IF_AWUSER_OVR, HL_KERNEL_ASID_ID);
494962306a36Sopenharmony_ci	WREG32(mmCPU_IF_ARUSER_OVR_EN, 0x7FF);
495062306a36Sopenharmony_ci	WREG32(mmCPU_IF_AWUSER_OVR_EN, 0x7FF);
495162306a36Sopenharmony_ci
495262306a36Sopenharmony_ci	/* Make sure configuration is flushed to device */
495362306a36Sopenharmony_ci	RREG32(mmCPU_IF_AWUSER_OVR_EN);
495462306a36Sopenharmony_ci
495562306a36Sopenharmony_ci	goya->device_cpu_mmu_mappings_done = true;
495662306a36Sopenharmony_ci
495762306a36Sopenharmony_ci	return 0;
495862306a36Sopenharmony_ci
495962306a36Sopenharmony_ciunmap_cpu:
496062306a36Sopenharmony_ci	for (; cpu_off >= 0 ; cpu_off -= PAGE_SIZE_4KB)
496162306a36Sopenharmony_ci		if (hl_mmu_unmap_page(hdev->kernel_ctx,
496262306a36Sopenharmony_ci				VA_CPU_ACCESSIBLE_MEM_ADDR + cpu_off,
496362306a36Sopenharmony_ci				PAGE_SIZE_4KB, true))
496462306a36Sopenharmony_ci			dev_warn_ratelimited(hdev->dev,
496562306a36Sopenharmony_ci				"failed to unmap address 0x%llx\n",
496662306a36Sopenharmony_ci				VA_CPU_ACCESSIBLE_MEM_ADDR + cpu_off);
496762306a36Sopenharmony_ciunmap:
496862306a36Sopenharmony_ci	for (; off >= 0 ; off -= PAGE_SIZE_2MB)
496962306a36Sopenharmony_ci		if (hl_mmu_unmap_page(hdev->kernel_ctx,
497062306a36Sopenharmony_ci				prop->dram_base_address + off, PAGE_SIZE_2MB,
497162306a36Sopenharmony_ci				true))
497262306a36Sopenharmony_ci			dev_warn_ratelimited(hdev->dev,
497362306a36Sopenharmony_ci				"failed to unmap address 0x%llx\n",
497462306a36Sopenharmony_ci				prop->dram_base_address + off);
497562306a36Sopenharmony_ci
497662306a36Sopenharmony_ci	return rc;
497762306a36Sopenharmony_ci}
497862306a36Sopenharmony_ci
497962306a36Sopenharmony_civoid goya_mmu_remove_device_cpu_mappings(struct hl_device *hdev)
498062306a36Sopenharmony_ci{
498162306a36Sopenharmony_ci	struct asic_fixed_properties *prop = &hdev->asic_prop;
498262306a36Sopenharmony_ci	struct goya_device *goya = hdev->asic_specific;
498362306a36Sopenharmony_ci	u32 off, cpu_off;
498462306a36Sopenharmony_ci
498562306a36Sopenharmony_ci	if (!(goya->hw_cap_initialized & HW_CAP_MMU))
498662306a36Sopenharmony_ci		return;
498762306a36Sopenharmony_ci
498862306a36Sopenharmony_ci	if (!goya->device_cpu_mmu_mappings_done)
498962306a36Sopenharmony_ci		return;
499062306a36Sopenharmony_ci
499162306a36Sopenharmony_ci	WREG32(mmCPU_IF_ARUSER_OVR_EN, 0);
499262306a36Sopenharmony_ci	WREG32(mmCPU_IF_AWUSER_OVR_EN, 0);
499362306a36Sopenharmony_ci
499462306a36Sopenharmony_ci	if (!(hdev->cpu_accessible_dma_address & (PAGE_SIZE_2MB - 1))) {
499562306a36Sopenharmony_ci		if (hl_mmu_unmap_page(hdev->kernel_ctx,
499662306a36Sopenharmony_ci				VA_CPU_ACCESSIBLE_MEM_ADDR,
499762306a36Sopenharmony_ci				PAGE_SIZE_2MB, true))
499862306a36Sopenharmony_ci			dev_warn(hdev->dev,
499962306a36Sopenharmony_ci				"Failed to unmap CPU accessible memory\n");
500062306a36Sopenharmony_ci	} else {
500162306a36Sopenharmony_ci		for (cpu_off = 0 ; cpu_off < SZ_2M ; cpu_off += PAGE_SIZE_4KB)
500262306a36Sopenharmony_ci			if (hl_mmu_unmap_page(hdev->kernel_ctx,
500362306a36Sopenharmony_ci					VA_CPU_ACCESSIBLE_MEM_ADDR + cpu_off,
500462306a36Sopenharmony_ci					PAGE_SIZE_4KB,
500562306a36Sopenharmony_ci					(cpu_off + PAGE_SIZE_4KB) >= SZ_2M))
500662306a36Sopenharmony_ci				dev_warn_ratelimited(hdev->dev,
500762306a36Sopenharmony_ci					"failed to unmap address 0x%llx\n",
500862306a36Sopenharmony_ci					VA_CPU_ACCESSIBLE_MEM_ADDR + cpu_off);
500962306a36Sopenharmony_ci	}
501062306a36Sopenharmony_ci
501162306a36Sopenharmony_ci	for (off = 0 ; off < CPU_FW_IMAGE_SIZE ; off += PAGE_SIZE_2MB)
501262306a36Sopenharmony_ci		if (hl_mmu_unmap_page(hdev->kernel_ctx,
501362306a36Sopenharmony_ci				prop->dram_base_address + off, PAGE_SIZE_2MB,
501462306a36Sopenharmony_ci				(off + PAGE_SIZE_2MB) >= CPU_FW_IMAGE_SIZE))
501562306a36Sopenharmony_ci			dev_warn_ratelimited(hdev->dev,
501662306a36Sopenharmony_ci					"Failed to unmap address 0x%llx\n",
501762306a36Sopenharmony_ci					prop->dram_base_address + off);
501862306a36Sopenharmony_ci
501962306a36Sopenharmony_ci	goya->device_cpu_mmu_mappings_done = false;
502062306a36Sopenharmony_ci}
502162306a36Sopenharmony_ci
502262306a36Sopenharmony_cistatic void goya_mmu_prepare(struct hl_device *hdev, u32 asid)
502362306a36Sopenharmony_ci{
502462306a36Sopenharmony_ci	struct goya_device *goya = hdev->asic_specific;
502562306a36Sopenharmony_ci	int i;
502662306a36Sopenharmony_ci
502762306a36Sopenharmony_ci	if (!(goya->hw_cap_initialized & HW_CAP_MMU))
502862306a36Sopenharmony_ci		return;
502962306a36Sopenharmony_ci
503062306a36Sopenharmony_ci	if (asid & ~MME_QM_GLBL_SECURE_PROPS_ASID_MASK) {
503162306a36Sopenharmony_ci		dev_crit(hdev->dev, "asid %u is too big\n", asid);
503262306a36Sopenharmony_ci		return;
503362306a36Sopenharmony_ci	}
503462306a36Sopenharmony_ci
503562306a36Sopenharmony_ci	/* zero the MMBP and ASID bits and then set the ASID */
503662306a36Sopenharmony_ci	for (i = 0 ; i < GOYA_MMU_REGS_NUM ; i++)
503762306a36Sopenharmony_ci		goya_mmu_prepare_reg(hdev, goya_mmu_regs[i], asid);
503862306a36Sopenharmony_ci}
503962306a36Sopenharmony_ci
504062306a36Sopenharmony_cistatic int goya_mmu_invalidate_cache(struct hl_device *hdev, bool is_hard,
504162306a36Sopenharmony_ci					u32 flags)
504262306a36Sopenharmony_ci{
504362306a36Sopenharmony_ci	struct goya_device *goya = hdev->asic_specific;
504462306a36Sopenharmony_ci	u32 status, timeout_usec;
504562306a36Sopenharmony_ci	int rc;
504662306a36Sopenharmony_ci
504762306a36Sopenharmony_ci	if (!(goya->hw_cap_initialized & HW_CAP_MMU) ||
504862306a36Sopenharmony_ci		hdev->reset_info.hard_reset_pending)
504962306a36Sopenharmony_ci		return 0;
505062306a36Sopenharmony_ci
505162306a36Sopenharmony_ci	/* no need in L1 only invalidation in Goya */
505262306a36Sopenharmony_ci	if (!is_hard)
505362306a36Sopenharmony_ci		return 0;
505462306a36Sopenharmony_ci
505562306a36Sopenharmony_ci	if (hdev->pldm)
505662306a36Sopenharmony_ci		timeout_usec = GOYA_PLDM_MMU_TIMEOUT_USEC;
505762306a36Sopenharmony_ci	else
505862306a36Sopenharmony_ci		timeout_usec = MMU_CONFIG_TIMEOUT_USEC;
505962306a36Sopenharmony_ci
506062306a36Sopenharmony_ci	/* L0 & L1 invalidation */
506162306a36Sopenharmony_ci	WREG32(mmSTLB_INV_ALL_START, 1);
506262306a36Sopenharmony_ci
506362306a36Sopenharmony_ci	rc = hl_poll_timeout(
506462306a36Sopenharmony_ci		hdev,
506562306a36Sopenharmony_ci		mmSTLB_INV_ALL_START,
506662306a36Sopenharmony_ci		status,
506762306a36Sopenharmony_ci		!status,
506862306a36Sopenharmony_ci		1000,
506962306a36Sopenharmony_ci		timeout_usec);
507062306a36Sopenharmony_ci
507162306a36Sopenharmony_ci	return rc;
507262306a36Sopenharmony_ci}
507362306a36Sopenharmony_ci
507462306a36Sopenharmony_cistatic int goya_mmu_invalidate_cache_range(struct hl_device *hdev,
507562306a36Sopenharmony_ci						bool is_hard, u32 flags,
507662306a36Sopenharmony_ci						u32 asid, u64 va, u64 size)
507762306a36Sopenharmony_ci{
507862306a36Sopenharmony_ci	/* Treat as invalidate all because there is no range invalidation
507962306a36Sopenharmony_ci	 * in Goya
508062306a36Sopenharmony_ci	 */
508162306a36Sopenharmony_ci	return hl_mmu_invalidate_cache(hdev, is_hard, flags);
508262306a36Sopenharmony_ci}
508362306a36Sopenharmony_ci
508462306a36Sopenharmony_ciint goya_send_heartbeat(struct hl_device *hdev)
508562306a36Sopenharmony_ci{
508662306a36Sopenharmony_ci	struct goya_device *goya = hdev->asic_specific;
508762306a36Sopenharmony_ci
508862306a36Sopenharmony_ci	if (!(goya->hw_cap_initialized & HW_CAP_CPU_Q))
508962306a36Sopenharmony_ci		return 0;
509062306a36Sopenharmony_ci
509162306a36Sopenharmony_ci	return hl_fw_send_heartbeat(hdev);
509262306a36Sopenharmony_ci}
509362306a36Sopenharmony_ci
509462306a36Sopenharmony_ciint goya_cpucp_info_get(struct hl_device *hdev)
509562306a36Sopenharmony_ci{
509662306a36Sopenharmony_ci	struct goya_device *goya = hdev->asic_specific;
509762306a36Sopenharmony_ci	struct asic_fixed_properties *prop = &hdev->asic_prop;
509862306a36Sopenharmony_ci	u64 dram_size;
509962306a36Sopenharmony_ci	int rc;
510062306a36Sopenharmony_ci
510162306a36Sopenharmony_ci	if (!(goya->hw_cap_initialized & HW_CAP_CPU_Q))
510262306a36Sopenharmony_ci		return 0;
510362306a36Sopenharmony_ci
510462306a36Sopenharmony_ci	rc = hl_fw_cpucp_handshake(hdev, mmCPU_BOOT_DEV_STS0,
510562306a36Sopenharmony_ci					mmCPU_BOOT_DEV_STS1, mmCPU_BOOT_ERR0,
510662306a36Sopenharmony_ci					mmCPU_BOOT_ERR1);
510762306a36Sopenharmony_ci	if (rc)
510862306a36Sopenharmony_ci		return rc;
510962306a36Sopenharmony_ci
511062306a36Sopenharmony_ci	dram_size = le64_to_cpu(prop->cpucp_info.dram_size);
511162306a36Sopenharmony_ci	if (dram_size) {
511262306a36Sopenharmony_ci		if ((!is_power_of_2(dram_size)) ||
511362306a36Sopenharmony_ci				(dram_size < DRAM_PHYS_DEFAULT_SIZE)) {
511462306a36Sopenharmony_ci			dev_err(hdev->dev,
511562306a36Sopenharmony_ci				"F/W reported invalid DRAM size %llu. Trying to use default size\n",
511662306a36Sopenharmony_ci				dram_size);
511762306a36Sopenharmony_ci			dram_size = DRAM_PHYS_DEFAULT_SIZE;
511862306a36Sopenharmony_ci		}
511962306a36Sopenharmony_ci
512062306a36Sopenharmony_ci		prop->dram_size = dram_size;
512162306a36Sopenharmony_ci		prop->dram_end_address = prop->dram_base_address + dram_size;
512262306a36Sopenharmony_ci	}
512362306a36Sopenharmony_ci
512462306a36Sopenharmony_ci	if (!strlen(prop->cpucp_info.card_name))
512562306a36Sopenharmony_ci		strncpy(prop->cpucp_info.card_name, GOYA_DEFAULT_CARD_NAME,
512662306a36Sopenharmony_ci				CARD_NAME_MAX_LEN);
512762306a36Sopenharmony_ci
512862306a36Sopenharmony_ci	return 0;
512962306a36Sopenharmony_ci}
513062306a36Sopenharmony_ci
513162306a36Sopenharmony_cistatic bool goya_is_device_idle(struct hl_device *hdev, u64 *mask_arr, u8 mask_len,
513262306a36Sopenharmony_ci				struct engines_data *e)
513362306a36Sopenharmony_ci{
513462306a36Sopenharmony_ci	const char *fmt = "%-5d%-9s%#-14x%#-16x%#x\n";
513562306a36Sopenharmony_ci	const char *dma_fmt = "%-5d%-9s%#-14x%#x\n";
513662306a36Sopenharmony_ci	unsigned long *mask = (unsigned long *)mask_arr;
513762306a36Sopenharmony_ci	u32 qm_glbl_sts0, cmdq_glbl_sts0, dma_core_sts0, tpc_cfg_sts,
513862306a36Sopenharmony_ci		mme_arch_sts;
513962306a36Sopenharmony_ci	bool is_idle = true, is_eng_idle;
514062306a36Sopenharmony_ci	u64 offset;
514162306a36Sopenharmony_ci	int i;
514262306a36Sopenharmony_ci
514362306a36Sopenharmony_ci	if (e)
514462306a36Sopenharmony_ci		hl_engine_data_sprintf(e, "\nDMA  is_idle  QM_GLBL_STS0  DMA_CORE_STS0\n"
514562306a36Sopenharmony_ci					"---  -------  ------------  -------------\n");
514662306a36Sopenharmony_ci
514762306a36Sopenharmony_ci	offset = mmDMA_QM_1_GLBL_STS0 - mmDMA_QM_0_GLBL_STS0;
514862306a36Sopenharmony_ci
514962306a36Sopenharmony_ci	for (i = 0 ; i < DMA_MAX_NUM ; i++) {
515062306a36Sopenharmony_ci		qm_glbl_sts0 = RREG32(mmDMA_QM_0_GLBL_STS0 + i * offset);
515162306a36Sopenharmony_ci		dma_core_sts0 = RREG32(mmDMA_CH_0_STS0 + i * offset);
515262306a36Sopenharmony_ci		is_eng_idle = IS_DMA_QM_IDLE(qm_glbl_sts0) &&
515362306a36Sopenharmony_ci				IS_DMA_IDLE(dma_core_sts0);
515462306a36Sopenharmony_ci		is_idle &= is_eng_idle;
515562306a36Sopenharmony_ci
515662306a36Sopenharmony_ci		if (mask && !is_eng_idle)
515762306a36Sopenharmony_ci			set_bit(GOYA_ENGINE_ID_DMA_0 + i, mask);
515862306a36Sopenharmony_ci		if (e)
515962306a36Sopenharmony_ci			hl_engine_data_sprintf(e, dma_fmt, i, is_eng_idle ? "Y" : "N",
516062306a36Sopenharmony_ci					qm_glbl_sts0, dma_core_sts0);
516162306a36Sopenharmony_ci	}
516262306a36Sopenharmony_ci
516362306a36Sopenharmony_ci	if (e)
516462306a36Sopenharmony_ci		hl_engine_data_sprintf(e,
516562306a36Sopenharmony_ci			"\nTPC  is_idle  QM_GLBL_STS0  CMDQ_GLBL_STS0  CFG_STATUS\n"
516662306a36Sopenharmony_ci			"---  -------  ------------  --------------  ----------\n");
516762306a36Sopenharmony_ci
516862306a36Sopenharmony_ci	offset = mmTPC1_QM_GLBL_STS0 - mmTPC0_QM_GLBL_STS0;
516962306a36Sopenharmony_ci
517062306a36Sopenharmony_ci	for (i = 0 ; i < TPC_MAX_NUM ; i++) {
517162306a36Sopenharmony_ci		qm_glbl_sts0 = RREG32(mmTPC0_QM_GLBL_STS0 + i * offset);
517262306a36Sopenharmony_ci		cmdq_glbl_sts0 = RREG32(mmTPC0_CMDQ_GLBL_STS0 + i * offset);
517362306a36Sopenharmony_ci		tpc_cfg_sts = RREG32(mmTPC0_CFG_STATUS + i * offset);
517462306a36Sopenharmony_ci		is_eng_idle = IS_TPC_QM_IDLE(qm_glbl_sts0) &&
517562306a36Sopenharmony_ci				IS_TPC_CMDQ_IDLE(cmdq_glbl_sts0) &&
517662306a36Sopenharmony_ci				IS_TPC_IDLE(tpc_cfg_sts);
517762306a36Sopenharmony_ci		is_idle &= is_eng_idle;
517862306a36Sopenharmony_ci
517962306a36Sopenharmony_ci		if (mask && !is_eng_idle)
518062306a36Sopenharmony_ci			set_bit(GOYA_ENGINE_ID_TPC_0 + i, mask);
518162306a36Sopenharmony_ci		if (e)
518262306a36Sopenharmony_ci			hl_engine_data_sprintf(e, fmt, i, is_eng_idle ? "Y" : "N",
518362306a36Sopenharmony_ci				qm_glbl_sts0, cmdq_glbl_sts0, tpc_cfg_sts);
518462306a36Sopenharmony_ci	}
518562306a36Sopenharmony_ci
518662306a36Sopenharmony_ci	if (e)
518762306a36Sopenharmony_ci		hl_engine_data_sprintf(e,
518862306a36Sopenharmony_ci			"\nMME  is_idle  QM_GLBL_STS0  CMDQ_GLBL_STS0  ARCH_STATUS\n"
518962306a36Sopenharmony_ci			"---  -------  ------------  --------------  -----------\n");
519062306a36Sopenharmony_ci
519162306a36Sopenharmony_ci	qm_glbl_sts0 = RREG32(mmMME_QM_GLBL_STS0);
519262306a36Sopenharmony_ci	cmdq_glbl_sts0 = RREG32(mmMME_CMDQ_GLBL_STS0);
519362306a36Sopenharmony_ci	mme_arch_sts = RREG32(mmMME_ARCH_STATUS);
519462306a36Sopenharmony_ci	is_eng_idle = IS_MME_QM_IDLE(qm_glbl_sts0) &&
519562306a36Sopenharmony_ci			IS_MME_CMDQ_IDLE(cmdq_glbl_sts0) &&
519662306a36Sopenharmony_ci			IS_MME_IDLE(mme_arch_sts);
519762306a36Sopenharmony_ci	is_idle &= is_eng_idle;
519862306a36Sopenharmony_ci
519962306a36Sopenharmony_ci	if (mask && !is_eng_idle)
520062306a36Sopenharmony_ci		set_bit(GOYA_ENGINE_ID_MME_0, mask);
520162306a36Sopenharmony_ci	if (e) {
520262306a36Sopenharmony_ci		hl_engine_data_sprintf(e, fmt, 0, is_eng_idle ? "Y" : "N", qm_glbl_sts0,
520362306a36Sopenharmony_ci				cmdq_glbl_sts0, mme_arch_sts);
520462306a36Sopenharmony_ci		hl_engine_data_sprintf(e, "\n");
520562306a36Sopenharmony_ci	}
520662306a36Sopenharmony_ci
520762306a36Sopenharmony_ci	return is_idle;
520862306a36Sopenharmony_ci}
520962306a36Sopenharmony_ci
521062306a36Sopenharmony_cistatic void goya_hw_queues_lock(struct hl_device *hdev)
521162306a36Sopenharmony_ci	__acquires(&goya->hw_queues_lock)
521262306a36Sopenharmony_ci{
521362306a36Sopenharmony_ci	struct goya_device *goya = hdev->asic_specific;
521462306a36Sopenharmony_ci
521562306a36Sopenharmony_ci	spin_lock(&goya->hw_queues_lock);
521662306a36Sopenharmony_ci}
521762306a36Sopenharmony_ci
521862306a36Sopenharmony_cistatic void goya_hw_queues_unlock(struct hl_device *hdev)
521962306a36Sopenharmony_ci	__releases(&goya->hw_queues_lock)
522062306a36Sopenharmony_ci{
522162306a36Sopenharmony_ci	struct goya_device *goya = hdev->asic_specific;
522262306a36Sopenharmony_ci
522362306a36Sopenharmony_ci	spin_unlock(&goya->hw_queues_lock);
522462306a36Sopenharmony_ci}
522562306a36Sopenharmony_ci
522662306a36Sopenharmony_cistatic u32 goya_get_pci_id(struct hl_device *hdev)
522762306a36Sopenharmony_ci{
522862306a36Sopenharmony_ci	return hdev->pdev->device;
522962306a36Sopenharmony_ci}
523062306a36Sopenharmony_ci
523162306a36Sopenharmony_cistatic int goya_get_eeprom_data(struct hl_device *hdev, void *data,
523262306a36Sopenharmony_ci				size_t max_size)
523362306a36Sopenharmony_ci{
523462306a36Sopenharmony_ci	struct goya_device *goya = hdev->asic_specific;
523562306a36Sopenharmony_ci
523662306a36Sopenharmony_ci	if (!(goya->hw_cap_initialized & HW_CAP_CPU_Q))
523762306a36Sopenharmony_ci		return 0;
523862306a36Sopenharmony_ci
523962306a36Sopenharmony_ci	return hl_fw_get_eeprom_data(hdev, data, max_size);
524062306a36Sopenharmony_ci}
524162306a36Sopenharmony_ci
524262306a36Sopenharmony_cistatic void goya_cpu_init_scrambler_dram(struct hl_device *hdev)
524362306a36Sopenharmony_ci{
524462306a36Sopenharmony_ci
524562306a36Sopenharmony_ci}
524662306a36Sopenharmony_ci
524762306a36Sopenharmony_cistatic int goya_ctx_init(struct hl_ctx *ctx)
524862306a36Sopenharmony_ci{
524962306a36Sopenharmony_ci	if (ctx->asid != HL_KERNEL_ASID_ID)
525062306a36Sopenharmony_ci		goya_mmu_prepare(ctx->hdev, ctx->asid);
525162306a36Sopenharmony_ci
525262306a36Sopenharmony_ci	return 0;
525362306a36Sopenharmony_ci}
525462306a36Sopenharmony_ci
525562306a36Sopenharmony_cistatic int goya_pre_schedule_cs(struct hl_cs *cs)
525662306a36Sopenharmony_ci{
525762306a36Sopenharmony_ci	return 0;
525862306a36Sopenharmony_ci}
525962306a36Sopenharmony_ci
526062306a36Sopenharmony_ciu32 goya_get_queue_id_for_cq(struct hl_device *hdev, u32 cq_idx)
526162306a36Sopenharmony_ci{
526262306a36Sopenharmony_ci	return cq_idx;
526362306a36Sopenharmony_ci}
526462306a36Sopenharmony_ci
526562306a36Sopenharmony_cistatic u32 goya_get_signal_cb_size(struct hl_device *hdev)
526662306a36Sopenharmony_ci{
526762306a36Sopenharmony_ci	return 0;
526862306a36Sopenharmony_ci}
526962306a36Sopenharmony_ci
527062306a36Sopenharmony_cistatic u32 goya_get_wait_cb_size(struct hl_device *hdev)
527162306a36Sopenharmony_ci{
527262306a36Sopenharmony_ci	return 0;
527362306a36Sopenharmony_ci}
527462306a36Sopenharmony_ci
527562306a36Sopenharmony_cistatic u32 goya_gen_signal_cb(struct hl_device *hdev, void *data, u16 sob_id,
527662306a36Sopenharmony_ci				u32 size, bool eb)
527762306a36Sopenharmony_ci{
527862306a36Sopenharmony_ci	return 0;
527962306a36Sopenharmony_ci}
528062306a36Sopenharmony_ci
528162306a36Sopenharmony_cistatic u32 goya_gen_wait_cb(struct hl_device *hdev,
528262306a36Sopenharmony_ci		struct hl_gen_wait_properties *prop)
528362306a36Sopenharmony_ci{
528462306a36Sopenharmony_ci	return 0;
528562306a36Sopenharmony_ci}
528662306a36Sopenharmony_ci
528762306a36Sopenharmony_cistatic void goya_reset_sob(struct hl_device *hdev, void *data)
528862306a36Sopenharmony_ci{
528962306a36Sopenharmony_ci
529062306a36Sopenharmony_ci}
529162306a36Sopenharmony_ci
529262306a36Sopenharmony_cistatic void goya_reset_sob_group(struct hl_device *hdev, u16 sob_group)
529362306a36Sopenharmony_ci{
529462306a36Sopenharmony_ci
529562306a36Sopenharmony_ci}
529662306a36Sopenharmony_ci
529762306a36Sopenharmony_ciu64 goya_get_device_time(struct hl_device *hdev)
529862306a36Sopenharmony_ci{
529962306a36Sopenharmony_ci	u64 device_time = ((u64) RREG32(mmPSOC_TIMESTAMP_CNTCVU)) << 32;
530062306a36Sopenharmony_ci
530162306a36Sopenharmony_ci	return device_time | RREG32(mmPSOC_TIMESTAMP_CNTCVL);
530262306a36Sopenharmony_ci}
530362306a36Sopenharmony_ci
530462306a36Sopenharmony_cistatic int goya_collective_wait_init_cs(struct hl_cs *cs)
530562306a36Sopenharmony_ci{
530662306a36Sopenharmony_ci	return 0;
530762306a36Sopenharmony_ci}
530862306a36Sopenharmony_ci
530962306a36Sopenharmony_cistatic int goya_collective_wait_create_jobs(struct hl_device *hdev,
531062306a36Sopenharmony_ci		struct hl_ctx *ctx, struct hl_cs *cs, u32 wait_queue_id,
531162306a36Sopenharmony_ci		u32 collective_engine_id, u32 encaps_signal_offset)
531262306a36Sopenharmony_ci{
531362306a36Sopenharmony_ci	return -EINVAL;
531462306a36Sopenharmony_ci}
531562306a36Sopenharmony_ci
531662306a36Sopenharmony_cistatic void goya_ctx_fini(struct hl_ctx *ctx)
531762306a36Sopenharmony_ci{
531862306a36Sopenharmony_ci
531962306a36Sopenharmony_ci}
532062306a36Sopenharmony_ci
532162306a36Sopenharmony_cistatic int goya_get_hw_block_id(struct hl_device *hdev, u64 block_addr,
532262306a36Sopenharmony_ci			u32 *block_size, u32 *block_id)
532362306a36Sopenharmony_ci{
532462306a36Sopenharmony_ci	return -EPERM;
532562306a36Sopenharmony_ci}
532662306a36Sopenharmony_ci
532762306a36Sopenharmony_cistatic int goya_block_mmap(struct hl_device *hdev, struct vm_area_struct *vma,
532862306a36Sopenharmony_ci				u32 block_id, u32 block_size)
532962306a36Sopenharmony_ci{
533062306a36Sopenharmony_ci	return -EPERM;
533162306a36Sopenharmony_ci}
533262306a36Sopenharmony_ci
533362306a36Sopenharmony_cistatic void goya_enable_events_from_fw(struct hl_device *hdev)
533462306a36Sopenharmony_ci{
533562306a36Sopenharmony_ci	WREG32(mmGIC_DISTRIBUTOR__5_GICD_SETSPI_NSR,
533662306a36Sopenharmony_ci			GOYA_ASYNC_EVENT_ID_INTS_REGISTER);
533762306a36Sopenharmony_ci}
533862306a36Sopenharmony_ci
533962306a36Sopenharmony_cistatic int goya_ack_mmu_page_fault_or_access_error(struct hl_device *hdev, u64 mmu_cap_mask)
534062306a36Sopenharmony_ci{
534162306a36Sopenharmony_ci	return -EINVAL;
534262306a36Sopenharmony_ci}
534362306a36Sopenharmony_ci
534462306a36Sopenharmony_cistatic int goya_map_pll_idx_to_fw_idx(u32 pll_idx)
534562306a36Sopenharmony_ci{
534662306a36Sopenharmony_ci	switch (pll_idx) {
534762306a36Sopenharmony_ci	case HL_GOYA_CPU_PLL: return CPU_PLL;
534862306a36Sopenharmony_ci	case HL_GOYA_PCI_PLL: return PCI_PLL;
534962306a36Sopenharmony_ci	case HL_GOYA_MME_PLL: return MME_PLL;
535062306a36Sopenharmony_ci	case HL_GOYA_TPC_PLL: return TPC_PLL;
535162306a36Sopenharmony_ci	case HL_GOYA_IC_PLL: return IC_PLL;
535262306a36Sopenharmony_ci	case HL_GOYA_MC_PLL: return MC_PLL;
535362306a36Sopenharmony_ci	case HL_GOYA_EMMC_PLL: return EMMC_PLL;
535462306a36Sopenharmony_ci	default: return -EINVAL;
535562306a36Sopenharmony_ci	}
535662306a36Sopenharmony_ci}
535762306a36Sopenharmony_ci
535862306a36Sopenharmony_cistatic int goya_gen_sync_to_engine_map(struct hl_device *hdev,
535962306a36Sopenharmony_ci				struct hl_sync_to_engine_map *map)
536062306a36Sopenharmony_ci{
536162306a36Sopenharmony_ci	/* Not implemented */
536262306a36Sopenharmony_ci	return 0;
536362306a36Sopenharmony_ci}
536462306a36Sopenharmony_ci
536562306a36Sopenharmony_cistatic int goya_monitor_valid(struct hl_mon_state_dump *mon)
536662306a36Sopenharmony_ci{
536762306a36Sopenharmony_ci	/* Not implemented */
536862306a36Sopenharmony_ci	return 0;
536962306a36Sopenharmony_ci}
537062306a36Sopenharmony_ci
537162306a36Sopenharmony_cistatic int goya_print_single_monitor(char **buf, size_t *size, size_t *offset,
537262306a36Sopenharmony_ci				struct hl_device *hdev,
537362306a36Sopenharmony_ci				struct hl_mon_state_dump *mon)
537462306a36Sopenharmony_ci{
537562306a36Sopenharmony_ci	/* Not implemented */
537662306a36Sopenharmony_ci	return 0;
537762306a36Sopenharmony_ci}
537862306a36Sopenharmony_ci
537962306a36Sopenharmony_ci
538062306a36Sopenharmony_cistatic int goya_print_fences_single_engine(
538162306a36Sopenharmony_ci	struct hl_device *hdev, u64 base_offset, u64 status_base_offset,
538262306a36Sopenharmony_ci	enum hl_sync_engine_type engine_type, u32 engine_id, char **buf,
538362306a36Sopenharmony_ci	size_t *size, size_t *offset)
538462306a36Sopenharmony_ci{
538562306a36Sopenharmony_ci	/* Not implemented */
538662306a36Sopenharmony_ci	return 0;
538762306a36Sopenharmony_ci}
538862306a36Sopenharmony_ci
538962306a36Sopenharmony_ci
539062306a36Sopenharmony_cistatic struct hl_state_dump_specs_funcs goya_state_dump_funcs = {
539162306a36Sopenharmony_ci	.monitor_valid = goya_monitor_valid,
539262306a36Sopenharmony_ci	.print_single_monitor = goya_print_single_monitor,
539362306a36Sopenharmony_ci	.gen_sync_to_engine_map = goya_gen_sync_to_engine_map,
539462306a36Sopenharmony_ci	.print_fences_single_engine = goya_print_fences_single_engine,
539562306a36Sopenharmony_ci};
539662306a36Sopenharmony_ci
539762306a36Sopenharmony_cistatic void goya_state_dump_init(struct hl_device *hdev)
539862306a36Sopenharmony_ci{
539962306a36Sopenharmony_ci	/* Not implemented */
540062306a36Sopenharmony_ci	hdev->state_dump_specs.props = goya_state_dump_specs_props;
540162306a36Sopenharmony_ci	hdev->state_dump_specs.funcs = goya_state_dump_funcs;
540262306a36Sopenharmony_ci}
540362306a36Sopenharmony_ci
540462306a36Sopenharmony_cistatic u32 goya_get_sob_addr(struct hl_device *hdev, u32 sob_id)
540562306a36Sopenharmony_ci{
540662306a36Sopenharmony_ci	return 0;
540762306a36Sopenharmony_ci}
540862306a36Sopenharmony_ci
540962306a36Sopenharmony_cistatic u32 *goya_get_stream_master_qid_arr(void)
541062306a36Sopenharmony_ci{
541162306a36Sopenharmony_ci	return NULL;
541262306a36Sopenharmony_ci}
541362306a36Sopenharmony_ci
541462306a36Sopenharmony_cistatic int goya_get_monitor_dump(struct hl_device *hdev, void *data)
541562306a36Sopenharmony_ci{
541662306a36Sopenharmony_ci	return -EOPNOTSUPP;
541762306a36Sopenharmony_ci}
541862306a36Sopenharmony_ci
541962306a36Sopenharmony_cistatic void goya_check_if_razwi_happened(struct hl_device *hdev)
542062306a36Sopenharmony_ci{
542162306a36Sopenharmony_ci}
542262306a36Sopenharmony_ci
542362306a36Sopenharmony_cistatic int goya_scrub_device_dram(struct hl_device *hdev, u64 val)
542462306a36Sopenharmony_ci{
542562306a36Sopenharmony_ci	return -EOPNOTSUPP;
542662306a36Sopenharmony_ci}
542762306a36Sopenharmony_ci
542862306a36Sopenharmony_cistatic int goya_set_dram_properties(struct hl_device *hdev)
542962306a36Sopenharmony_ci{
543062306a36Sopenharmony_ci	return 0;
543162306a36Sopenharmony_ci}
543262306a36Sopenharmony_ci
543362306a36Sopenharmony_cistatic int goya_set_binning_masks(struct hl_device *hdev)
543462306a36Sopenharmony_ci{
543562306a36Sopenharmony_ci	return 0;
543662306a36Sopenharmony_ci}
543762306a36Sopenharmony_ci
543862306a36Sopenharmony_cistatic int goya_send_device_activity(struct hl_device *hdev, bool open)
543962306a36Sopenharmony_ci{
544062306a36Sopenharmony_ci	return 0;
544162306a36Sopenharmony_ci}
544262306a36Sopenharmony_ci
544362306a36Sopenharmony_cistatic const struct hl_asic_funcs goya_funcs = {
544462306a36Sopenharmony_ci	.early_init = goya_early_init,
544562306a36Sopenharmony_ci	.early_fini = goya_early_fini,
544662306a36Sopenharmony_ci	.late_init = goya_late_init,
544762306a36Sopenharmony_ci	.late_fini = goya_late_fini,
544862306a36Sopenharmony_ci	.sw_init = goya_sw_init,
544962306a36Sopenharmony_ci	.sw_fini = goya_sw_fini,
545062306a36Sopenharmony_ci	.hw_init = goya_hw_init,
545162306a36Sopenharmony_ci	.hw_fini = goya_hw_fini,
545262306a36Sopenharmony_ci	.halt_engines = goya_halt_engines,
545362306a36Sopenharmony_ci	.suspend = goya_suspend,
545462306a36Sopenharmony_ci	.resume = goya_resume,
545562306a36Sopenharmony_ci	.mmap = goya_mmap,
545662306a36Sopenharmony_ci	.ring_doorbell = goya_ring_doorbell,
545762306a36Sopenharmony_ci	.pqe_write = goya_pqe_write,
545862306a36Sopenharmony_ci	.asic_dma_alloc_coherent = goya_dma_alloc_coherent,
545962306a36Sopenharmony_ci	.asic_dma_free_coherent = goya_dma_free_coherent,
546062306a36Sopenharmony_ci	.scrub_device_mem = goya_scrub_device_mem,
546162306a36Sopenharmony_ci	.scrub_device_dram = goya_scrub_device_dram,
546262306a36Sopenharmony_ci	.get_int_queue_base = goya_get_int_queue_base,
546362306a36Sopenharmony_ci	.test_queues = goya_test_queues,
546462306a36Sopenharmony_ci	.asic_dma_pool_zalloc = goya_dma_pool_zalloc,
546562306a36Sopenharmony_ci	.asic_dma_pool_free = goya_dma_pool_free,
546662306a36Sopenharmony_ci	.cpu_accessible_dma_pool_alloc = goya_cpu_accessible_dma_pool_alloc,
546762306a36Sopenharmony_ci	.cpu_accessible_dma_pool_free = goya_cpu_accessible_dma_pool_free,
546862306a36Sopenharmony_ci	.hl_dma_unmap_sgtable = hl_dma_unmap_sgtable,
546962306a36Sopenharmony_ci	.cs_parser = goya_cs_parser,
547062306a36Sopenharmony_ci	.asic_dma_map_sgtable = hl_dma_map_sgtable,
547162306a36Sopenharmony_ci	.add_end_of_cb_packets = goya_add_end_of_cb_packets,
547262306a36Sopenharmony_ci	.update_eq_ci = goya_update_eq_ci,
547362306a36Sopenharmony_ci	.context_switch = goya_context_switch,
547462306a36Sopenharmony_ci	.restore_phase_topology = goya_restore_phase_topology,
547562306a36Sopenharmony_ci	.debugfs_read_dma = goya_debugfs_read_dma,
547662306a36Sopenharmony_ci	.add_device_attr = goya_add_device_attr,
547762306a36Sopenharmony_ci	.handle_eqe = goya_handle_eqe,
547862306a36Sopenharmony_ci	.get_events_stat = goya_get_events_stat,
547962306a36Sopenharmony_ci	.read_pte = goya_read_pte,
548062306a36Sopenharmony_ci	.write_pte = goya_write_pte,
548162306a36Sopenharmony_ci	.mmu_invalidate_cache = goya_mmu_invalidate_cache,
548262306a36Sopenharmony_ci	.mmu_invalidate_cache_range = goya_mmu_invalidate_cache_range,
548362306a36Sopenharmony_ci	.mmu_prefetch_cache_range = NULL,
548462306a36Sopenharmony_ci	.send_heartbeat = goya_send_heartbeat,
548562306a36Sopenharmony_ci	.debug_coresight = goya_debug_coresight,
548662306a36Sopenharmony_ci	.is_device_idle = goya_is_device_idle,
548762306a36Sopenharmony_ci	.compute_reset_late_init = goya_compute_reset_late_init,
548862306a36Sopenharmony_ci	.hw_queues_lock = goya_hw_queues_lock,
548962306a36Sopenharmony_ci	.hw_queues_unlock = goya_hw_queues_unlock,
549062306a36Sopenharmony_ci	.get_pci_id = goya_get_pci_id,
549162306a36Sopenharmony_ci	.get_eeprom_data = goya_get_eeprom_data,
549262306a36Sopenharmony_ci	.get_monitor_dump = goya_get_monitor_dump,
549362306a36Sopenharmony_ci	.send_cpu_message = goya_send_cpu_message,
549462306a36Sopenharmony_ci	.pci_bars_map = goya_pci_bars_map,
549562306a36Sopenharmony_ci	.init_iatu = goya_init_iatu,
549662306a36Sopenharmony_ci	.rreg = hl_rreg,
549762306a36Sopenharmony_ci	.wreg = hl_wreg,
549862306a36Sopenharmony_ci	.halt_coresight = goya_halt_coresight,
549962306a36Sopenharmony_ci	.ctx_init = goya_ctx_init,
550062306a36Sopenharmony_ci	.ctx_fini = goya_ctx_fini,
550162306a36Sopenharmony_ci	.pre_schedule_cs = goya_pre_schedule_cs,
550262306a36Sopenharmony_ci	.get_queue_id_for_cq = goya_get_queue_id_for_cq,
550362306a36Sopenharmony_ci	.load_firmware_to_device = goya_load_firmware_to_device,
550462306a36Sopenharmony_ci	.load_boot_fit_to_device = goya_load_boot_fit_to_device,
550562306a36Sopenharmony_ci	.get_signal_cb_size = goya_get_signal_cb_size,
550662306a36Sopenharmony_ci	.get_wait_cb_size = goya_get_wait_cb_size,
550762306a36Sopenharmony_ci	.gen_signal_cb = goya_gen_signal_cb,
550862306a36Sopenharmony_ci	.gen_wait_cb = goya_gen_wait_cb,
550962306a36Sopenharmony_ci	.reset_sob = goya_reset_sob,
551062306a36Sopenharmony_ci	.reset_sob_group = goya_reset_sob_group,
551162306a36Sopenharmony_ci	.get_device_time = goya_get_device_time,
551262306a36Sopenharmony_ci	.pb_print_security_errors = NULL,
551362306a36Sopenharmony_ci	.collective_wait_init_cs = goya_collective_wait_init_cs,
551462306a36Sopenharmony_ci	.collective_wait_create_jobs = goya_collective_wait_create_jobs,
551562306a36Sopenharmony_ci	.get_dec_base_addr = NULL,
551662306a36Sopenharmony_ci	.scramble_addr = hl_mmu_scramble_addr,
551762306a36Sopenharmony_ci	.descramble_addr = hl_mmu_descramble_addr,
551862306a36Sopenharmony_ci	.ack_protection_bits_errors = goya_ack_protection_bits_errors,
551962306a36Sopenharmony_ci	.get_hw_block_id = goya_get_hw_block_id,
552062306a36Sopenharmony_ci	.hw_block_mmap = goya_block_mmap,
552162306a36Sopenharmony_ci	.enable_events_from_fw = goya_enable_events_from_fw,
552262306a36Sopenharmony_ci	.ack_mmu_errors = goya_ack_mmu_page_fault_or_access_error,
552362306a36Sopenharmony_ci	.map_pll_idx_to_fw_idx = goya_map_pll_idx_to_fw_idx,
552462306a36Sopenharmony_ci	.init_firmware_preload_params = goya_init_firmware_preload_params,
552562306a36Sopenharmony_ci	.init_firmware_loader = goya_init_firmware_loader,
552662306a36Sopenharmony_ci	.init_cpu_scrambler_dram = goya_cpu_init_scrambler_dram,
552762306a36Sopenharmony_ci	.state_dump_init = goya_state_dump_init,
552862306a36Sopenharmony_ci	.get_sob_addr = &goya_get_sob_addr,
552962306a36Sopenharmony_ci	.set_pci_memory_regions = goya_set_pci_memory_regions,
553062306a36Sopenharmony_ci	.get_stream_master_qid_arr = goya_get_stream_master_qid_arr,
553162306a36Sopenharmony_ci	.check_if_razwi_happened = goya_check_if_razwi_happened,
553262306a36Sopenharmony_ci	.mmu_get_real_page_size = hl_mmu_get_real_page_size,
553362306a36Sopenharmony_ci	.access_dev_mem = hl_access_dev_mem,
553462306a36Sopenharmony_ci	.set_dram_bar_base = goya_set_ddr_bar_base,
553562306a36Sopenharmony_ci	.send_device_activity = goya_send_device_activity,
553662306a36Sopenharmony_ci	.set_dram_properties = goya_set_dram_properties,
553762306a36Sopenharmony_ci	.set_binning_masks = goya_set_binning_masks,
553862306a36Sopenharmony_ci};
553962306a36Sopenharmony_ci
554062306a36Sopenharmony_ci/*
554162306a36Sopenharmony_ci * goya_set_asic_funcs - set Goya function pointers
554262306a36Sopenharmony_ci *
554362306a36Sopenharmony_ci * @*hdev: pointer to hl_device structure
554462306a36Sopenharmony_ci *
554562306a36Sopenharmony_ci */
554662306a36Sopenharmony_civoid goya_set_asic_funcs(struct hl_device *hdev)
554762306a36Sopenharmony_ci{
554862306a36Sopenharmony_ci	hdev->asic_funcs = &goya_funcs;
554962306a36Sopenharmony_ci}
5550