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