/* SPDX-License-Identifier: GPL-2.0-only */ /* * Copyright (c) 2020-2021, The Linux Foundation. All rights reserved. * Copyright (c) 2022-2024, Qualcomm Innovation Center, Inc. All rights reserved. */ #ifndef __ADRENO_HFI_H #define __ADRENO_HFI_H #include "kgsl_util.h" #define HW_FENCE_QUEUE_SIZE SZ_4K #define HFI_QUEUE_SIZE SZ_4K /* bytes, must be base 4dw */ #define MAX_RCVD_PAYLOAD_SIZE 16 /* dwords */ #define MAX_RCVD_SIZE (MAX_RCVD_PAYLOAD_SIZE + 3) /* dwords */ #define HFI_MAX_MSG_SIZE (SZ_1K) #define HFI_CMD_ID 0 #define HFI_MSG_ID 1 #define HFI_DBG_ID 2 #define HFI_DSP_ID_0 3 #define HFI_CMD_IDX 0 #define HFI_MSG_IDX 1 #define HFI_DBG_IDX 2 #define HFI_DSP_IDX_BASE 3 #define HFI_DSP_IDX_0 3 #define HFI_CMD_IDX_LEGACY 0 #define HFI_DSP_IDX_0_LEGACY 1 #define HFI_MSG_IDX_LEGACY 4 #define HFI_DBG_IDX_LEGACY 5 #define HFI_QUEUE_STATUS_DISABLED 0 #define HFI_QUEUE_STATUS_ENABLED 1 /* HTOF queue priority, 1 is highest priority */ #define HFI_CMD_PRI 10 #define HFI_MSG_PRI 10 #define HFI_DBG_PRI 40 #define HFI_DSP_PRI_0 20 #define HFI_IRQ_SIDEMSGQ_MASK BIT(1) #define HFI_IRQ_DBGQ_MASK BIT(2) #define HFI_IRQ_CM3_FAULT_MASK BIT(15) #define HFI_IRQ_OOB_MASK GENMASK(31, 16) #define HFI_IRQ_MASK (HFI_IRQ_SIDEMSGQ_MASK |\ HFI_IRQ_DBGQ_MASK |\ HFI_IRQ_CM3_FAULT_MASK) #define DCVS_ACK_NONBLOCK 0 #define DCVS_ACK_BLOCK 1 #define HFI_FEATURE_DCVS 0 #define HFI_FEATURE_HWSCHED 1 #define HFI_FEATURE_PREEMPTION 2 #define HFI_FEATURE_CLOCKS_ON 3 #define HFI_FEATURE_BUS_ON 4 #define HFI_FEATURE_RAIL_ON 5 #define HFI_FEATURE_HWCG 6 #define HFI_FEATURE_LM 7 #define HFI_FEATURE_THROTTLE 8 #define HFI_FEATURE_IFPC 9 #define HFI_FEATURE_NAP 10 #define HFI_FEATURE_BCL 11 #define HFI_FEATURE_ACD 12 #define HFI_FEATURE_DIDT 13 #define HFI_FEATURE_DEPRECATED 14 #define HFI_FEATURE_CB 15 #define HFI_FEATURE_KPROF 16 #define HFI_FEATURE_BAIL_OUT_TIMER 17 #define HFI_FEATURE_GMU_STATS 18 #define HFI_FEATURE_DBQ 19 #define HFI_FEATURE_MINBW 20 #define HFI_FEATURE_CLX 21 #define HFI_FEATURE_LSR 23 #define HFI_FEATURE_LPAC 24 #define HFI_FEATURE_HW_FENCE 25 #define HFI_FEATURE_PERF_NORETAIN 26 #define HFI_FEATURE_DMS 27 #define HFI_FEATURE_AQE 29 /* Types to be used with H2F_MSG_TABLE */ enum hfi_table_type { HFI_TABLE_BW_VOTE = 0, HFI_TABLE_GPU_PERF = 1, HFI_TABLE_DIDT = 2, HFI_TABLE_ACD = 3, HFI_TABLE_CLX_V1 = 4, HFI_TABLE_CLX_V2 = 5, HFI_TABLE_THERM = 6, HFI_TABLE_DCVS_DATA = 7, HFI_TABLE_MAX, }; /* A6xx uses a different value for KPROF */ #define HFI_FEATURE_A6XX_KPROF 14 /* For Gen7 & Gen8 ACD */ #define F_PWR_ACD_CALIBRATE 78 #define HFI_VALUE_FT_POLICY 100 #define HFI_VALUE_RB_MAX_CMDS 101 #define HFI_VALUE_CTX_MAX_CMDS 102 #define HFI_VALUE_ADDRESS 103 #define HFI_VALUE_MAX_GPU_PERF_INDEX 104 #define HFI_VALUE_MIN_GPU_PERF_INDEX 105 #define HFI_VALUE_MAX_BW_PERF_INDEX 106 #define HFI_VALUE_MIN_BW_PERF_INDEX 107 #define HFI_VALUE_MAX_GPU_THERMAL_INDEX 108 #define HFI_VALUE_GPUCLK 109 #define HFI_VALUE_CLK_TIME 110 #define HFI_VALUE_LOG_GROUP 111 #define HFI_VALUE_LOG_EVENT_ON 112 #define HFI_VALUE_LOG_EVENT_OFF 113 #define HFI_VALUE_DCVS_OBJ 114 #define HFI_VALUE_LM_CS0 115 #define HFI_VALUE_DBG 116 #define HFI_VALUE_BIN_TIME 117 #define HFI_VALUE_LOG_STREAM_ENABLE 119 #define HFI_VALUE_PREEMPT_COUNT 120 #define HFI_VALUE_CONTEXT_QUEUE 121 #define HFI_VALUE_GMU_AB_VOTE 122 #define HFI_VALUE_RB_GPU_QOS 123 #define HFI_VALUE_RB_IB_RULE 124 #define HFI_VALUE_GMU_WARMBOOT 125 #define HFI_VALUE_GLOBAL_TOKEN 0xFFFFFFFF #define HFI_CTXT_FLAG_PMODE BIT(0) #define HFI_CTXT_FLAG_SWITCH_INTERNAL BIT(1) #define HFI_CTXT_FLAG_SWITCH BIT(3) #define HFI_CTXT_FLAG_NOTIFY BIT(5) #define HFI_CTXT_FLAG_NO_FAULT_TOLERANCE BIT(9) #define HFI_CTXT_FLAG_PWR_RULE BIT(11) #define HFI_CTXT_FLAG_PRIORITY_MASK GENMASK(15, 12) #define HFI_CTXT_FLAG_IFH_NOP BIT(16) #define HFI_CTXT_FLAG_SECURE BIT(17) #define HFI_CTXT_FLAG_TYPE_MASK GENMASK(24, 20) #define HFI_CTXT_FLAG_TYPE_ANY 0 #define HFI_CTXT_FLAG_TYPE_GL 1 #define HFI_CTXT_FLAG_TYPE_CL 2 #define HFI_CTXT_FLAG_TYPE_C2D 3 #define HFI_CTXT_FLAG_TYPE_RS 4 #define HFI_CTXT_FLAG_TYPE_VK 5 #define HFI_CTXT_FLAG_TYPE_UNKNOWN 0x1e #define HFI_CTXT_FLAG_PREEMPT_STYLE_MASK GENMASK(27, 25) #define HFI_CTXT_FLAG_PREEMPT_STYLE_ANY 0 #define HFI_CTXT_FLAG_PREEMPT_STYLE_RB 1 #define HFI_CTXT_FLAG_PREEMPT_STYLE_FG 2 /* Default sampling interval in units of 50 us */ #define HFI_FEATURE_GMU_STATS_INTERVAL 4 enum hfi_mem_kind { /** @HFI_MEMKIND_GENERIC: Used for requesting generic memory */ HFI_MEMKIND_GENERIC = 0, /** @HFI_MEMKIND_RB: Used for requesting ringbuffer memory */ HFI_MEMKIND_RB, /** @HFI_MEMKIND_SCRATCH: Used for requesting scratch memory */ HFI_MEMKIND_SCRATCH, /** * @HFI_MEMKIND_CSW_SMMU_INFO: Used for requesting SMMU record for * preemption context switching */ HFI_MEMKIND_CSW_SMMU_INFO, /** * @HFI_MEMKIND_CSW_PRIV_NON_SECURE: Used for requesting privileged non * secure preemption records */ HFI_MEMKIND_CSW_PRIV_NON_SECURE, /** * @HFI_MEMKIND_CSW_PRIV_SECURE: Used for requesting privileged secure * preemption records */ HFI_MEMKIND_CSW_PRIV_SECURE, /** * @HFI_MEMKIND_CSW_NON_PRIV: Used for requesting non privileged per * context preemption buffer */ HFI_MEMKIND_CSW_NON_PRIV, /** * @HFI_MEMKIND_CSW_COUNTER: Used for requesting preemption performance * counter save/restore buffer */ HFI_MEMKIND_CSW_COUNTER, /** * @HFI_MEMKIND_CTXTREC_PREEMPT_CNTR: Used for requesting preemption * counter buffer */ HFI_MEMKIND_CTXTREC_PREEMPT_CNTR, /** @HFI_MEMKIND_SYSLOG: Used for requesting system log memory */ HFI_MEMKIND_SYS_LOG, /** @HFI_MEMKIND_CRASH_DUMP: Used for requesting carsh dumper memory */ HFI_MEMKIND_CRASH_DUMP, /** * @HFI_MEMKIND_MMIO_DPU: Used for requesting Display processing unit's * register space */ HFI_MEMKIND_MMIO_DPU, /** * @HFI_MEMKIND_MMIO_TCSR: Used for requesting Top CSR(contains SoC * doorbells) register space */ HFI_MEMKIND_MMIO_TCSR, /** * @HFI_MEMKIND_MMIO_QDSS_STM: Used for requesting QDSS STM register * space */ HFI_MEMKIND_MMIO_QDSS_STM, /** @HFI_MEMKIND_PROFILE: Used for kernel profiling */ HFI_MEMKIND_PROFILE, /** @HFI_MEMKIND_USER_PROFILING_IBS: Used for user profiling */ HFI_MEMKIND_USER_PROFILE_IBS, /** @MEMKIND_CMD_BUFFER: Used for composing ringbuffer content */ HFI_MEMKIND_CMD_BUFFER, /** * @HFI_MEMKIND_GPU_BUSY_DATA_BUFFER: Used for GPU busy buffer for * all the contexts */ HFI_MEMKIND_GPU_BUSY_DATA_BUFFER, /** @HFI_MEMKIND_GPU_BUSY_CMD_BUFFER: Used for GPU busy cmd buffer * (Only readable to GPU) */ HFI_MEMKIND_GPU_BUSY_CMD_BUFFER, /** *@MEMKIND_MMIO_IPC_CORE: Used for IPC_core region mapping to GMU space * for EVA to GPU communication. */ HFI_MEMKIND_MMIO_IPC_CORE, /** @HFIMEMKIND_MMIO_IPCC_AOSS: Used for IPCC AOSS, second memory region */ HFI_MEMKIND_MMIO_IPCC_AOSS, /** * @MEMKIND_CSW_LPAC_PRIV_NON_SECURE: Used for privileged nonsecure * memory for LPAC context record */ HFI_MEMKIND_CSW_LPAC_PRIV_NON_SECURE, /** @HFI_MEMKIND_MEMSTORE: Buffer used to query a context's GPU sop/eop timestamps */ HFI_MEMKIND_MEMSTORE, /** @HFI_MEMKIND_HW_FENCE: Hardware fence Tx/Rx headers and queues */ HFI_MEMKIND_HW_FENCE, /** @HFI_MEMKIND_PREEMPT_SCRATCH: Used for Preemption scratch memory */ HFI_MEMKIND_PREEMPT_SCRATCH, /** * @HFI_MEMKIND_AQE_BUFFER: Sandbox memory used by AQE to switch * between LPAC and GC */ HFI_MEMKIND_AQE_BUFFER, HFI_MEMKIND_MAX, }; static const char * const hfi_memkind_strings[] = { [HFI_MEMKIND_GENERIC] = "GMU GENERIC", [HFI_MEMKIND_RB] = "GMU RB", [HFI_MEMKIND_SCRATCH] = "GMU SCRATCH", [HFI_MEMKIND_CSW_SMMU_INFO] = "GMU SMMU INFO", [HFI_MEMKIND_CSW_PRIV_NON_SECURE] = "GMU CSW PRIV NON SECURE", [HFI_MEMKIND_CSW_PRIV_SECURE] = "GMU CSW PRIV SECURE", [HFI_MEMKIND_CSW_NON_PRIV] = "GMU CSW NON PRIV", [HFI_MEMKIND_CSW_COUNTER] = "GMU CSW COUNTER", [HFI_MEMKIND_CTXTREC_PREEMPT_CNTR] = "GMU PREEMPT CNTR", [HFI_MEMKIND_SYS_LOG] = "GMU SYS LOG", [HFI_MEMKIND_CRASH_DUMP] = "GMU CRASHDUMP", [HFI_MEMKIND_MMIO_DPU] = "GMU MMIO DPU", [HFI_MEMKIND_MMIO_TCSR] = "GMU MMIO TCSR", [HFI_MEMKIND_MMIO_QDSS_STM] = "GMU MMIO QDSS STM", [HFI_MEMKIND_PROFILE] = "GMU KERNEL PROFILING", [HFI_MEMKIND_USER_PROFILE_IBS] = "GMU USER PROFILING", [HFI_MEMKIND_CMD_BUFFER] = "GMU CMD BUFFER", [HFI_MEMKIND_GPU_BUSY_DATA_BUFFER] = "GMU BUSY DATA BUFFER", [HFI_MEMKIND_GPU_BUSY_CMD_BUFFER] = "GMU BUSY CMD BUFFER", [HFI_MEMKIND_MMIO_IPC_CORE] = "GMU MMIO IPC", [HFI_MEMKIND_MMIO_IPCC_AOSS] = "GMU MMIO IPCC AOSS", [HFI_MEMKIND_CSW_LPAC_PRIV_NON_SECURE] = "GMU CSW LPAC PRIV NON SECURE", [HFI_MEMKIND_MEMSTORE] = "GMU MEMSTORE", [HFI_MEMKIND_HW_FENCE] = "GMU HW FENCE", [HFI_MEMKIND_PREEMPT_SCRATCH] = "GMU PREEMPTION", [HFI_MEMKIND_AQE_BUFFER] = "GMU AQE BUFFER", [HFI_MEMKIND_MAX] = "GMU UNKNOWN", }; /* CP/GFX pipeline can access */ #define HFI_MEMFLAG_GFX_ACC BIT(0) /* Buffer has APRIV protection in GFX PTEs */ #define HFI_MEMFLAG_GFX_PRIV BIT(1) /* Buffer is read-write for GFX PTEs. A 0 indicates read-only */ #define HFI_MEMFLAG_GFX_WRITEABLE BIT(2) /* GMU can access */ #define HFI_MEMFLAG_GMU_ACC BIT(3) /* Buffer has APRIV protection in GMU PTEs */ #define HFI_MEMFLAG_GMU_PRIV BIT(4) /* Buffer is read-write for GMU PTEs. A 0 indicates read-only */ #define HFI_MEMFLAG_GMU_WRITEABLE BIT(5) /* Buffer is located in GMU's non-cached bufferable VA range */ #define HFI_MEMFLAG_GMU_BUFFERABLE BIT(6) /* Buffer is located in GMU's cacheable VA range */ #define HFI_MEMFLAG_GMU_CACHEABLE BIT(7) /* Host can access */ #define HFI_MEMFLAG_HOST_ACC BIT(8) /* Host initializes(zero-init) the buffer */ #define HFI_MEMFLAG_HOST_INIT BIT(9) /* Gfx buffer needs to be secure */ #define HFI_MEMFLAG_GFX_SECURE BIT(12) /** * struct hfi_queue_table_header - HFI queue table structure * @version: HFI protocol version * @size: queue table size in dwords * @qhdr0_offset: first queue header offset (dwords) in this table * @qhdr_size: queue header size * @num_q: number of queues defined in this table * @num_active_q: number of active queues */ struct hfi_queue_table_header { u32 version; u32 size; u32 qhdr0_offset; u32 qhdr_size; u32 num_q; u32 num_active_q; } __packed; /** * struct gmu_context_queue_header - GMU context queue header structure */ struct gmu_context_queue_header { /** @version: Version of the header */ u32 version; /** @start_addr: GMU VA of start of the queue */ u32 start_addr; /** @queue_size: queue size in dwords */ u32 queue_size; /** @out_fence_ts: Timestamp of last hardware fence sent to Tx Queue */ volatile u32 out_fence_ts; /** @sync_obj_ts: Timestamp of last sync object that GMU has digested */ volatile u32 sync_obj_ts; /** @read_index: Read index of the queue */ volatile u32 read_index; /** @write_index: Write index of the queue */ volatile u32 write_index; /** * @hw_fence_buffer_va: GMU VA of the buffer to store output hardware fences for this * context */ u32 hw_fence_buffer_va; /** * @hw_fence_buffer_size: Size of the buffer to store output hardware fences for this * context */ u32 hw_fence_buffer_size; u32 unused1; u32 unused2; u32 unused3; } __packed; /** * struct hfi_queue_header - HFI queue header structure * @status: active: 1; inactive: 0 * @start_addr: starting address of the queue in GMU VA space * @type: queue type encoded the priority, ID and send/recevie types * @queue_size: size of the queue * @msg_size: size of the message if each message has fixed size. * Otherwise, 0 means variable size of message in the queue. * @read_index: read index of the queue * @write_index: write index of the queue */ struct hfi_queue_header { u32 status; u32 start_addr; u32 type; u32 queue_size; u32 msg_size; u32 unused0; u32 unused1; u32 unused2; u32 unused3; u32 unused4; volatile u32 read_index; volatile u32 write_index; } __packed; #define HFI_MSG_CMD 0 /* V1 and V2 */ #define HFI_MSG_ACK 1 /* V2 only */ /* Used to NOP a command when executing warmboot sequence */ #define HFI_MSG_NOP BIT(18) /* Used to record a command when executing coldboot sequence */ #define HFI_MSG_RECORD BIT(19) #define HFI_V1_MSG_POST 1 /* V1 only */ #define HFI_V1_MSG_ACK 2/* V1 only */ #define MSG_HDR_SET_SIZE(hdr, size) \ (((size & 0xFF) << 8) | hdr) #define CREATE_MSG_HDR(id, type) \ (((type) << 16) | ((id) & 0xFF)) #define ACK_MSG_HDR(id) CREATE_MSG_HDR(id, HFI_MSG_ACK) #define HFI_QUEUE_DEFAULT_CNT 3 #define HFI_QUEUE_DISPATCH_MAX_CNT 14 #define HFI_QUEUE_HDR_MAX (HFI_QUEUE_DEFAULT_CNT + HFI_QUEUE_DISPATCH_MAX_CNT) struct hfi_queue_table { struct hfi_queue_table_header qtbl_hdr; struct hfi_queue_header qhdr[HFI_QUEUE_HDR_MAX]; } __packed; #define HFI_QUEUE_OFFSET(i) \ (ALIGN(sizeof(struct hfi_queue_table), SZ_16) + \ ((i) * HFI_QUEUE_SIZE)) #define GMU_QUEUE_START_ADDR(gmuaddr, i) \ (gmuaddr + HFI_QUEUE_OFFSET(i)) #define HOST_QUEUE_START_ADDR(hfi_mem, i) \ ((hfi_mem)->hostptr + HFI_QUEUE_OFFSET(i)) #define MSG_HDR_GET_ID(hdr) ((hdr) & 0xFF) #define MSG_HDR_GET_SIZE(hdr) (((hdr) >> 8) & 0xFF) #define MSG_HDR_GET_TYPE(hdr) (((hdr) >> 16) & 0xF) #define MSG_HDR_GET_SEQNUM(hdr) (((hdr) >> 20) & 0xFFF) /* Clear the HFI_MSG_RECORD bit from both headers since some acks may have it set, and some not. */ #define CMP_HFI_ACK_HDR(sent, rcvd) ((sent &= ~HFI_MSG_RECORD) == (rcvd &= ~HFI_MSG_RECORD)) #define MSG_HDR_SET_SEQNUM(hdr, num) \ (((hdr) & 0xFFFFF) | ((num) << 20)) #define MSG_HDR_SET_SEQNUM_SIZE(hdr, seqnum, sizedwords) \ (FIELD_PREP(GENMASK(31, 20), seqnum) | FIELD_PREP(GENMASK(15, 8), sizedwords) | hdr) #define MSG_HDR_SET_TYPE(hdr, type) \ (((hdr) & 0xFFFFF) | ((type) << 16)) #define QUEUE_HDR_TYPE(id, prio, rtype, stype) \ (((id) & 0xFF) | (((prio) & 0xFF) << 8) | \ (((rtype) & 0xFF) << 16) | (((stype) & 0xFF) << 24)) #define HFI_RSP_TIMEOUT 1000 /* msec */ #define HFI_IRQ_MSGQ_MASK BIT(0) enum hfi_msg_type { H2F_MSG_INIT = 0, H2F_MSG_FW_VER = 1, H2F_MSG_LM_CFG = 2, H2F_MSG_BW_VOTE_TBL = 3, H2F_MSG_PERF_TBL = 4, H2F_MSG_TEST = 5, H2F_MSG_ACD_TBL = 7, H2F_MSG_CLX_TBL = 8, H2F_MSG_START = 10, H2F_MSG_FEATURE_CTRL = 11, H2F_MSG_GET_VALUE = 12, H2F_MSG_SET_VALUE = 13, H2F_MSG_CORE_FW_START = 14, H2F_MSG_TABLE = 15, F2H_MSG_MEM_ALLOC = 20, H2F_MSG_GX_BW_PERF_VOTE = 30, H2F_MSG_FW_HALT = 32, H2F_MSG_PREPARE_SLUMBER = 33, F2H_MSG_ERR = 100, F2H_MSG_DEBUG = 101, F2H_MSG_LOG_BLOCK = 102, F2H_MSG_GMU_CNTR_REGISTER = 110, F2H_MSG_GMU_CNTR_RELEASE = 111, F2H_MSG_ACK = 126, /* Deprecated for v2.0*/ H2F_MSG_ACK = 127, /* Deprecated for v2.0*/ H2F_MSG_REGISTER_CONTEXT = 128, H2F_MSG_UNREGISTER_CONTEXT = 129, H2F_MSG_ISSUE_CMD = 130, H2F_MSG_ISSUE_CMD_RAW = 131, H2F_MSG_TS_NOTIFY = 132, F2H_MSG_TS_RETIRE = 133, H2F_MSG_CONTEXT_POINTERS = 134, H2F_MSG_ISSUE_LPAC_CMD_RAW = 135, H2F_MSG_CONTEXT_RULE = 140, /* AKA constraint */ H2F_MSG_ISSUE_RECURRING_CMD = 141, F2H_MSG_CONTEXT_BAD = 150, H2F_MSG_HW_FENCE_INFO = 151, H2F_MSG_ISSUE_SYNCOBJ = 152, F2H_MSG_SYNCOBJ_QUERY = 153, H2F_MSG_WARMBOOT_CMD = 154, F2H_MSG_PROCESS_TRACE = 155, HFI_MAX_ID, }; enum gmu_ret_type { GMU_SUCCESS = 0, GMU_ERROR_FATAL, GMU_ERROR_MEM_FAIL, GMU_ERROR_INVAL_PARAM, GMU_ERROR_NULL_PTR, GMU_ERROR_OUT_OF_BOUNDS, GMU_ERROR_TIMEOUT, GMU_ERROR_NOT_SUPPORTED, GMU_ERROR_NO_ENTRY, }; /* H2F */ struct hfi_gmu_init_cmd { u32 hdr; u32 seg_id; u32 dbg_buffer_addr; u32 dbg_buffer_size; u32 boot_state; } __packed; /* H2F */ struct hfi_fw_version_cmd { u32 hdr; u32 supported_ver; } __packed; /* H2F */ struct hfi_bwtable_cmd { u32 hdr; u32 bw_level_num; u32 cnoc_cmds_num; u32 ddr_cmds_num; u32 cnoc_wait_bitmask; u32 ddr_wait_bitmask; u32 cnoc_cmd_addrs[MAX_CNOC_CMDS]; u32 cnoc_cmd_data[MAX_CNOC_LEVELS][MAX_CNOC_CMDS]; u32 ddr_cmd_addrs[MAX_BW_CMDS]; u32 ddr_cmd_data[MAX_BW_LEVELS][MAX_BW_CMDS]; } __packed; struct opp_gx_desc { u32 vote; /* This is 'acdLvl' in gmu fw which is now repurposed for cx vote */ u32 cx_vote; u32 freq; } __packed; struct opp_desc { u32 vote; u32 freq; } __packed; /* H2F */ struct hfi_dcvstable_v1_cmd { u32 hdr; u32 gpu_level_num; u32 gmu_level_num; struct opp_desc gx_votes[MAX_GX_LEVELS_LEGACY]; struct opp_desc cx_votes[MAX_CX_LEVELS]; } __packed; /* H2F */ struct hfi_dcvstable_cmd { u32 hdr; u32 gpu_level_num; u32 gmu_level_num; struct opp_gx_desc gx_votes[MAX_GX_LEVELS_LEGACY]; struct opp_desc cx_votes[MAX_CX_LEVELS]; } __packed; /* H2F */ struct hfi_table_entry { u32 count; u32 stride; u32 data[]; } __packed; struct hfi_table_cmd { u32 hdr; u32 version; u32 type; struct hfi_table_entry entry[]; } __packed; #define MAX_ACD_STRIDE 2 #define MAX_ACD_NUM_LEVELS KGSL_MAX_PWRLEVELS /* H2F */ struct hfi_acd_table_cmd { u32 hdr; u32 version; u32 enable_by_level; u32 stride; u32 num_levels; u32 data[MAX_ACD_NUM_LEVELS * MAX_ACD_STRIDE]; } __packed; struct hfi_clx_table_v1_cmd { /** @hdr: HFI header message */ u32 hdr; /** * @data0: bits[0:15] Feature enable control * bits[16:31] Revision control */ u32 data0; /** * @data1: bits[0:15] Migration time * bits[16:21] Current rating * bits[22:27] Phases for domain * bits[28:28] Path notifications * bits[29:31] Extra feature bits */ u32 data1; /** @clxt: CLX time in microseconds */ u32 clxt; /** @clxh: CLH time in microseconds */ u32 clxh; /** @urgmode: Urgent HW throttle mode of operation */ u32 urgmode; /** @lkgen: Enable leakage current estimate */ u32 lkgen; } __packed; #define CLX_DOMAINS_V2 2 struct clx_domain_v2 { /** * @data0: bits[0:15] Migration time * bits[16:21] Current rating * bits[22:27] Phases for domain * bits[28:28] Path notifications * bits[29:31] Extra feature bits */ u32 data0; /** @clxt: CLX time in microseconds */ u32 clxt; /** @clxh: CLH time in microseconds */ u32 clxh; /** @urgmode: Urgent HW throttle mode of operation */ u32 urgmode; /** @lkgen: Enable leakage current estimate */ u32 lkgen; /** @currbudget: Current Budget */ u32 currbudget; } __packed; /* H2F */ struct hfi_clx_table_v2_cmd { /** @hdr: HFI header message */ u32 hdr; /** @version: Version identifier for the format used for domains */ u32 version; /** @domain: GFX and MXC Domain information */ struct clx_domain_v2 domain[CLX_DOMAINS_V2]; } __packed; /* H2F */ struct hfi_test_cmd { u32 hdr; u32 data; } __packed; /* H2F */ struct hfi_start_cmd { u32 hdr; } __packed; /* H2F */ struct hfi_feature_ctrl_cmd { u32 hdr; u32 feature; u32 enable; u32 data; } __packed; /* H2F */ struct hfi_get_value_cmd { u32 hdr; u32 type; u32 subtype; } __packed; /* Internal */ struct hfi_get_value_req { struct hfi_get_value_cmd cmd; u32 data[16]; } __packed; /* F2H */ struct hfi_get_value_reply_cmd { u32 hdr; u32 req_hdr; u32 data[16]; } __packed; /* H2F */ struct hfi_set_value_cmd { u32 hdr; u32 type; u32 subtype; u32 data; } __packed; /* H2F */ struct hfi_core_fw_start_cmd { u32 hdr; u32 handle; } __packed; struct hfi_mem_alloc_desc_legacy { u64 gpu_addr; u32 flags; u32 mem_kind; u32 host_mem_handle; u32 gmu_mem_handle; u32 gmu_addr; u32 size; /* Bytes */ } __packed; struct hfi_mem_alloc_desc { u64 gpu_addr; u32 flags; u32 mem_kind; u32 host_mem_handle; u32 gmu_mem_handle; u32 gmu_addr; u32 size; /* Bytes */ /** * @align: bits[0:7] specify alignment requirement of the GMU VA specified as a power of * two. bits[8:15] specify alignment requirement for the size of the GMU mapping. For * example, a decimal value of 20 = (1 << 20) = 1 MB alignment */ u32 align; } __packed; struct hfi_mem_alloc_entry { struct hfi_mem_alloc_desc desc; struct kgsl_memdesc *md; }; /* F2H */ struct hfi_mem_alloc_cmd_legacy { u32 hdr; u32 reserved; /* Padding to ensure alignment of 'desc' below */ struct hfi_mem_alloc_desc_legacy desc; } __packed; struct hfi_mem_alloc_cmd { u32 hdr; u32 version; struct hfi_mem_alloc_desc desc; } __packed; /* H2F */ struct hfi_mem_alloc_reply_cmd { u32 hdr; u32 req_hdr; struct hfi_mem_alloc_desc desc; } __packed; /* H2F */ struct hfi_gx_bw_perf_vote_cmd { u32 hdr; u32 ack_type; u32 freq; u32 bw; } __packed; /* H2F */ struct hfi_fw_halt_cmd { u32 hdr; u32 en_halt; } __packed; /* H2F */ struct hfi_prep_slumber_cmd { u32 hdr; u32 bw; u32 freq; } __packed; /* F2H */ struct hfi_err_cmd { u32 hdr; u32 error_code; u32 data[16]; } __packed; /* F2H */ struct hfi_debug_cmd { u32 hdr; u32 type; u32 timestamp; u32 data; } __packed; /* F2H */ struct hfi_trace_cmd { u32 hdr; u32 version; u64 identifier; } __packed; /* Trace packet definition */ struct gmu_trace_packet { u32 hdr; u32 trace_id; u64 ticks; u32 payload[]; } __packed; /* F2H */ struct hfi_gmu_cntr_register_cmd { u32 hdr; u32 group_id; u32 countable; } __packed; /* H2F */ struct hfi_gmu_cntr_register_reply_cmd { u32 hdr; u32 req_hdr; u32 group_id; u32 countable; u32 cntr_lo; u32 cntr_hi; } __packed; /* F2H */ struct hfi_gmu_cntr_release_cmd { u32 hdr; u32 group_id; u32 countable; } __packed; /* H2F */ struct hfi_register_ctxt_cmd { u32 hdr; u32 ctxt_id; u32 flags; u64 pt_addr; u32 ctxt_idr; u32 ctxt_bank; } __packed; /* H2F */ struct hfi_unregister_ctxt_cmd { u32 hdr; u32 ctxt_id; u32 ts; } __packed; struct hfi_issue_ib { u64 addr; u32 size; } __packed; /* H2F */ /* The length of *buf will be embedded in the hdr */ struct hfi_issue_cmd_raw_cmd { u32 hdr; u32 *buf; } __packed; /* Internal */ struct hfi_issue_cmd_raw_req { u32 queue; u32 ctxt_id; u32 len; u32 *buf; } __packed; /* H2F */ struct hfi_ts_notify_cmd { u32 hdr; u32 ctxt_id; u32 ts; } __packed; #define CMDBATCH_SUCCESS 0 #define CMDBATCH_RETIRED 1 #define CMDBATCH_ERROR 2 #define CMDBATCH_SKIP 3 #define CMDBATCH_PROFILING BIT(4) #define CMDBATCH_EOF BIT(8) #define CMDBATCH_INDIRECT BIT(9) #define CMDBATCH_RECURRING_START BIT(18) #define CMDBATCH_RECURRING_STOP BIT(19) /* This indicates that the SYNCOBJ is kgsl output fence */ #define GMU_SYNCOBJ_FLAG_KGSL_FENCE_BIT 0 /* This indicates that the SYNCOBJ is signaled */ #define GMU_SYNCOBJ_FLAG_SIGNALED_BIT 1 /* This indicates that the SYNCOBJ's software status is queried */ #define GMU_SYNCOBJ_FLAG_QUERY_SW_STATUS_BIT 2 /* This indicates that the SYNCOBJ's software status is signaled */ #define GMU_SYNCOBJ_FLAG_SW_STATUS_SIGNALED_BIT 3 /* This indicates that the SYNCOBJ's software status is pending */ #define GMU_SYNCOBJ_FLAG_SW_STATUS_PENDING_BIT 4 #define GMU_SYNCOBJ_FLAGS \ { BIT(GMU_SYNCOBJ_FLAG_KGSL_FENCE_BIT), "KGSL"}, \ { BIT(GMU_SYNCOBJ_FLAG_SIGNALED_BIT), "SIGNALED"}, \ { BIT(GMU_SYNCOBJ_FLAG_QUERY_SW_STATUS_BIT), "QUERIED"}, \ { BIT(GMU_SYNCOBJ_FLAG_SW_STATUS_SIGNALED_BIT), "SW_SIGNALED"}, \ { BIT(GMU_SYNCOBJ_FLAG_SW_STATUS_PENDING_BIT), "SW_PENDING"} /* F2H */ struct hfi_ts_retire_cmd { u32 hdr; u32 ctxt_id; u32 ts; u32 type; u64 submitted_to_rb; u64 sop; u64 eop; u64 retired_on_gmu; u64 active; u32 version; } __packed; /* H2F */ struct hfi_context_pointers_cmd { u32 hdr; u32 ctxt_id; u64 sop_addr; u64 eop_addr; u64 user_ctxt_record_addr; u32 version; u32 gmu_context_queue_addr; } __packed; /* H2F */ struct hfi_context_rule_cmd { u32 hdr; u32 ctxt_id; u32 type; u32 status; } __packed; struct fault_info { u32 ctxt_id; u32 policy; u32 ts; } __packed; /* F2H */ struct hfi_context_bad_cmd { u32 hdr; u32 version; struct fault_info gc; struct fault_info lpac; u32 error; u32 payload[]; } __packed; /* F2H */ struct hfi_context_bad_cmd_legacy { u32 hdr; u32 ctxt_id; u32 policy; u32 ts; u32 error; u32 payload[]; } __packed; /* H2F */ struct hfi_context_bad_reply_cmd { u32 hdr; u32 req_hdr; } __packed; /* H2F */ struct hfi_submit_cmd { u32 hdr; u32 ctxt_id; u32 flags; u32 ts; u32 profile_gpuaddr_lo; u32 profile_gpuaddr_hi; u32 numibs; u32 big_ib_gmu_va; } __packed; struct hfi_syncobj { u64 ctxt_id; u64 seq_no; u64 flags; } __packed; struct hfi_submit_syncobj { u32 hdr; u32 version; u32 flags; u32 timestamp; u32 num_syncobj; } __packed; struct hfi_log_block { u32 hdr; u32 version; u32 start_index; u32 stop_index; } __packed; enum hfi_warmboot_cmd_type { HFI_WARMBOOT_SET_SCRATCH = 0, HFI_WARMBOOT_EXEC_SCRATCH, HFI_WARMBOOT_QUERY_SCRATCH, }; struct hfi_warmboot_scratch_cmd { /** @hdr: Header for the scratch command packet */ u32 hdr; /** @version: Version of the scratch command packet */ u32 version; /** @flags: Set, Execute or Query scratch flag */ u32 flags; /** @scratch_addr: Address of the scratch */ u32 scratch_addr; /** @scratch_size: Size of the scratch in bytes*/ u32 scratch_size; } __packed; /* Request GMU to add this fence to TxQueue without checking whether this is retired or not */ #define HW_FENCE_FLAG_SKIP_MEMSTORE 0x1 struct hfi_hw_fence_info { /** @hdr: Header for the fence info packet */ u32 hdr; /** @version: Version of the fence info packet */ u32 version; /** @gmu_ctxt_id: GMU Context id to which this fence belongs */ u32 gmu_ctxt_id; /** @error: Any error code associated with this fence */ u32 error; /** @ctxt_id: Context id for which hw fence is to be triggered */ u64 ctxt_id; /** @ts: Timestamp for which hw fence is to be triggered */ u64 ts; /** @flags: Flags on how to handle this hfi packet */ u64 flags; /** @hash_index: Index of the hw fence in hw fence table */ u64 hash_index; } __packed; /* The software fence corresponding to the queried hardware fence has not signaled */ #define ADRENO_HW_FENCE_SW_STATUS_PENDING BIT(0) /* The software fence corresponding to the queried hardware fence has signaled */ #define ADRENO_HW_FENCE_SW_STATUS_SIGNALED BIT(1) struct hfi_syncobj_query { /** * @query_bitmask: Bitmask representing the sync object descriptors to be queried. For * example, to query the second sync object descriptor(index=1) in a sync object, * bit(1) should be set in this bitmask. */ u32 query_bitmask; } __packed; #define MAX_SYNCOBJ_QUERY_BITS 128 #define BITS_PER_SYNCOBJ_QUERY 32 #define MAX_SYNCOBJ_QUERY_DWORDS (MAX_SYNCOBJ_QUERY_BITS / BITS_PER_SYNCOBJ_QUERY) struct hfi_syncobj_query_cmd { /** @hdr: Header for the fence info packet */ u32 hdr; /** @version: Version of the fence info packet */ u32 version; /** @gmu_ctxt_id: GMU Context id to which this SYNC object belongs */ u32 gmu_ctxt_id; /** @sync_obj_ts: Timestamp of this SYNC object */ u32 sync_obj_ts; /** @queries: Array of query bitmasks */ struct hfi_syncobj_query queries[MAX_SYNCOBJ_QUERY_DWORDS]; } __packed; /** * struct pending_cmd - data structure to track outstanding HFI * command messages */ struct pending_cmd { /** @sent_hdr: Header of the un-ack'd hfi packet */ u32 sent_hdr; /** @results: Array to store the ack packet */ u32 results[MAX_RCVD_SIZE]; /** @complete: Completion to signal hfi ack has been received */ struct completion complete; /** @node: to add it to the list of hfi packets waiting for ack */ struct list_head node; }; static inline int _CMD_MSG_HDR(u32 *hdr, int id, size_t size) { if (WARN_ON(size > HFI_MAX_MSG_SIZE)) return -EMSGSIZE; *hdr = CREATE_MSG_HDR(id, HFI_MSG_CMD); return 0; } #define CMD_MSG_HDR(cmd, id) \ _CMD_MSG_HDR(&(cmd).hdr, id, sizeof(cmd)) #define RECORD_MSG_HDR(hdr) \ ((hdr) | HFI_MSG_RECORD) #define CLEAR_RECORD_MSG_HDR(hdr) \ ((hdr) & (~(HFI_MSG_RECORD | HFI_MSG_NOP))) #define RECORD_NOP_MSG_HDR(hdr) \ ((hdr) | (HFI_MSG_RECORD | HFI_MSG_NOP)) /* Maximum number of IBs in a submission */ #define HWSCHED_MAX_DISPATCH_NUMIBS \ ((HFI_MAX_MSG_SIZE - sizeof(struct hfi_submit_cmd)) \ / sizeof(struct hfi_issue_ib)) /** * struct payload_section - Container of keys values * * There may be a variable number of payload sections appended * to the context bad HFI message. Each payload section contains * a variable number of key-value pairs, both key and value being * single dword each. */ struct payload_section { /** @type: Type of the payload */ u16 type; /** @dwords: Number of dwords in the data array. */ u16 dwords; /** @data: A sequence of key-value pairs. Each pair is 2 dwords. */ u32 data[]; } __packed; /* IDs for context bad hfi payloads */ #define PAYLOAD_FAULT_REGS 1 #define PAYLOAD_RB 2 #define PAYLOAD_PREEMPT_TIMEOUT 3 /* Keys for PAYLOAD_FAULT_REGS type payload */ #define KEY_CP_OPCODE_ERROR 1 #define KEY_CP_PROTECTED_ERROR 2 #define KEY_CP_HW_FAULT 3 #define KEY_CP_BV_OPCODE_ERROR 4 #define KEY_CP_BV_PROTECTED_ERROR 5 #define KEY_CP_BV_HW_FAULT 6 #define KEY_CP_LPAC_OPCODE_ERROR 7 #define KEY_CP_LPAC_PROTECTED_ERROR 8 #define KEY_CP_LPAC_HW_FAULT 9 #define KEY_SWFUSE_VIOLATION_FAULT 10 #define KEY_AQE0_OPCODE_ERROR 11 #define KEY_AQE0_HW_FAULT 12 #define KEY_AQE1_OPCODE_ERROR 13 #define KEY_AQE1_HW_FAULT 14 #define KEY_CP_AHB_ERROR 30 #define KEY_TSB_WRITE_ERROR 31 /* Keys for PAYLOAD_RB type payload */ #define KEY_RB_ID 1 #define KEY_RB_RPTR 2 #define KEY_RB_WPTR 3 #define KEY_RB_SIZEDWORDS 4 #define KEY_RB_QUEUED_TS 5 #define KEY_RB_RETIRED_TS 6 #define KEY_RB_GPUADDR_LO 7 #define KEY_RB_GPUADDR_HI 8 /* Keys for PAYLOAD_PREEMPT_TIMEOUT type payload */ #define KEY_PREEMPT_TIMEOUT_CUR_RB_ID 1 #define KEY_PREEMPT_TIMEOUT_NEXT_RB_ID 2 /* Types of errors that trigger context bad HFI */ /* GPU encountered a CP HW error */ #define GMU_CP_HW_ERROR 600 /* GPU encountered a GPU Hang interrupt */ #define GMU_GPU_HW_HANG 601 /* Preemption didn't complete in given time */ #define GMU_GPU_PREEMPT_TIMEOUT 602 /* Fault due to Long IB timeout */ #define GMU_GPU_SW_HANG 603 /* GPU encountered a bad opcode */ #define GMU_CP_OPCODE_ERROR 604 /* GPU encountered protected mode error */ #define GMU_CP_PROTECTED_ERROR 605 /* GPU encountered an illegal instruction */ #define GMU_CP_ILLEGAL_INST_ERROR 606 /* GPU encountered a CP ucode error */ #define GMU_CP_UCODE_ERROR 607 /* GPU encountered a CP hw fault error */ #define GMU_CP_HW_FAULT_ERROR 608 /* GPU encountered a GPC error */ #define GMU_CP_GPC_ERROR 609 /* GPU BV encountered a bad opcode */ #define GMU_CP_BV_OPCODE_ERROR 610 /* GPU BV encountered protected mode error */ #define GMU_CP_BV_PROTECTED_ERROR 611 /* GPU BV encountered a CP hw fault error */ #define GMU_CP_BV_HW_FAULT_ERROR 612 /* GPU BV encountered a CP ucode error */ #define GMU_CP_BV_UCODE_ERROR 613 /* GPU BV encountered an illegal instruction */ #define GMU_CP_BV_ILLEGAL_INST_ERROR 614 /* GPU encountered a bad LPAC opcode */ #define GMU_CP_LPAC_OPCODE_ERROR 615 /* GPU LPAC encountered a CP ucode error */ #define GMU_CP_LPAC_UCODE_ERROR 616 /* GPU LPAC encountered a CP hw fault error */ #define GMU_CP_LPAC_HW_FAULT_ERROR 617 /* GPU LPAC encountered protected mode error */ #define GMU_CP_LPAC_PROTECTED_ERROR 618 /* GPU LPAC encountered an illegal instruction */ #define GMU_CP_LPAC_ILLEGAL_INST_ERROR 619 /* Fault due to LPAC Long IB timeout */ #define GMU_GPU_LPAC_SW_HANG 620 /* Fault due to software fuse violation interrupt */ #define GMU_GPU_SW_FUSE_VIOLATION 621 /* AQE related error codes */ #define GMU_GPU_AQE0_OPCODE_ERRROR 622 #define GMU_GPU_AQE0_UCODE_ERROR 623 #define GMU_GPU_AQE0_HW_FAULT_ERROR 624 #define GMU_GPU_AQE0_ILLEGAL_INST_ERROR 625 #define GMU_GPU_AQE1_OPCODE_ERRROR 626 #define GMU_GPU_AQE1_UCODE_ERROR 627 #define GMU_GPU_AQE1_HW_FAULT_ERROR 628 #define GMU_GPU_AQE1_ILLEGAL_INST_ERROR 629 /* GMU encountered a sync object which is signaled via software but not via hardware */ #define GMU_SYNCOBJ_TIMEOUT_ERROR 630 /* Non fatal GPU error codes */ #define GMU_CP_AHB_ERROR 650 #define GMU_ATB_ASYNC_FIFO_OVERFLOW 651 #define GMU_RBBM_ATB_BUF_OVERFLOW 652 #define GMU_UCHE_OOB_ACCESS 653 #define GMU_UCHE_TRAP_INTR 654 #define GMU_TSB_WRITE_ERROR 655 /* GPU encountered an unknown CP error */ #define GMU_CP_UNKNOWN_ERROR 700 /** * hfi_update_read_idx - Update the read index of an hfi queue * hdr: Pointer to the hfi queue header * index: New read index * * This function makes sure that kgsl has consumed f2h packets * before GMU sees the updated read index. This avoids a corner * case where GMU might over-write f2h packets that have not yet * been consumed by kgsl. */ static inline void hfi_update_read_idx(struct hfi_queue_header *hdr, u32 index) { /* * This is to make sure packets are consumed before gmu sees the updated * read index */ mb(); hdr->read_index = index; } /** * hfi_update_write_idx - Update the write index of a GMU queue * write_idx: Pointer to the write index * index: New write index * * This function makes sure that the h2f packets are written out * to memory before GMU sees the updated write index. This avoids * corner cases where GMU might fetch stale entries that can happen * if write index is updated before new packets have been written * out to memory. */ static inline void hfi_update_write_idx(volatile u32 *write_idx, u32 index) { /* * This is to make sure packets are written out before gmu sees the * updated write index */ wmb(); *write_idx = index; /* * Memory barrier to make sure write index is written before an * interrupt is raised */ wmb(); } /** * hfi_get_mem_alloc_desc - Get the descriptor from F2H_MSG_MEM_ALLOC packet * rcvd: Pointer to the F2H_MSG_MEM_ALLOC packet * out: Pointer to copy the descriptor data to * * This function checks for the F2H_MSG_MEM_ALLOC packet version and based on that gets the * descriptor data from the packet. */ static inline void hfi_get_mem_alloc_desc(void *rcvd, struct hfi_mem_alloc_desc *out) { struct hfi_mem_alloc_cmd_legacy *in_legacy = (struct hfi_mem_alloc_cmd_legacy *)rcvd; struct hfi_mem_alloc_cmd *in = (struct hfi_mem_alloc_cmd *)rcvd; if (in->version > 0) memcpy(out, &in->desc, sizeof(in->desc)); else memcpy(out, &in_legacy->desc, sizeof(in_legacy->desc)); } /** * hfi_get_gmu_va_alignment - Get the alignment (in bytes) for a GMU VA * align: Alignment specified as a power of two (2^n) in bits[0:7] * * This function derives the GMU VA alignment in bytes from bits[0:7] in the passed in value, which * is specified in terms of power of two (2^n). For example, va_align = 20 means (1 << 20) = 1MB * alignment. The minimum alignment (in bytes) is SZ_4K i.e. anything less than (or equal to) a * va_align value of ilog2(SZ_4K) will default to SZ_4K alignment. */ static inline u32 hfi_get_gmu_va_alignment(u32 align) { u32 va_align = FIELD_GET(GENMASK(7, 0), align); return (va_align > ilog2(SZ_4K)) ? (1 << va_align) : SZ_4K; } /** * hfi_get_gmu_sz_alignment - Get the alignment (in bytes) for GMU mapping size * align: Alignment specified as a power of two (2^n) in bits[8:15] * * This function derives the GMU VA size alignment in bytes from bits[8:15] in the passed in value, * which is specified in terms of power of two (2^n). For example, sz_align = 20 means * (1 << 20) = 1MB alignment. The minimum alignment (in bytes) is SZ_4K i.e. anything less * than (or equal to) a sz_align value of ilog2(SZ_4K) will default to SZ_4K alignment. */ static inline u32 hfi_get_gmu_sz_alignment(u32 align) { u32 sz_align = FIELD_GET(GENMASK(15, 8), align); return (sz_align > ilog2(SZ_4K)) ? (1 << sz_align) : SZ_4K; } /** * adreno_hwsched_wait_ack_completion - Wait for HFI ack asynchronously * adreno_dev: Pointer to the adreno device * dev: Pointer to the device structure * ack: Pointer to the pending ack * process_msgq: Function pointer to the msgq processing function * * This function waits for the completion structure, which gets signaled asynchronously. In case * there is a timeout, process the msgq one last time. If the ack is present, log an error and move * on. If the ack isn't present, log an error, take a snapshot and return -ETIMEDOUT. * * Return: 0 on success and -ETIMEDOUT on failure */ int adreno_hwsched_wait_ack_completion(struct adreno_device *adreno_dev, struct device *dev, struct pending_cmd *ack, void (*process_msgq)(struct adreno_device *adreno_dev)); /** * adreno_hwsched_ctxt_unregister_wait_completion - Wait for HFI ack for context unregister * adreno_dev: Pointer to the adreno device * dev: Pointer to the device structure * ack: Pointer to the pending ack * process_msgq: Function pointer to the msgq processing function * cmd: Pointer to the hfi packet header and data * * This function waits for the completion structure for context unregister hfi ack, * which gets signaled asynchronously. In case there is a timeout, process the msgq * one last time. If the ack is present, log an error and move on. If the ack isn't * present, log an error and return -ETIMEDOUT. * * Return: 0 on success and -ETIMEDOUT on failure */ int adreno_hwsched_ctxt_unregister_wait_completion( struct adreno_device *adreno_dev, struct device *dev, struct pending_cmd *ack, void (*process_msgq)(struct adreno_device *adreno_dev), struct hfi_unregister_ctxt_cmd *cmd); /** * hfi_get_minidump_string - Get the va-minidump string from entry * mem_kind: mem_kind type * hfi_minidump_str: Pointer to the output string * size: Max size of the hfi_minidump_str * rb_id: Pointer to the rb_id count * * This function return 0 on valid mem_kind and copies the VA-MINIDUMP string to * hfi_minidump_str else return error */ static inline int hfi_get_minidump_string(u32 mem_kind, char *hfi_minidump_str, size_t size, u32 *rb_id) { /* Extend this if the VA mindump need more hfi alloc entries */ switch (mem_kind) { case HFI_MEMKIND_RB: snprintf(hfi_minidump_str, size, KGSL_GMU_RB_ENTRY"_%d", (*rb_id)++); break; case HFI_MEMKIND_SCRATCH: snprintf(hfi_minidump_str, size, KGSL_SCRATCH_ENTRY); break; case HFI_MEMKIND_PROFILE: snprintf(hfi_minidump_str, size, KGSL_GMU_KERNEL_PROF_ENTRY); break; case HFI_MEMKIND_USER_PROFILE_IBS: snprintf(hfi_minidump_str, size, KGSL_GMU_USER_PROF_ENTRY); break; case HFI_MEMKIND_CMD_BUFFER: snprintf(hfi_minidump_str, size, KGSL_GMU_CMD_BUFFER_ENTRY); break; default: return -EINVAL; } return 0; } #endif