android_kernel_samsung_sm86.../qcom/opensource/graphics-kernel/adreno_hfi.h
David Wronek 880d405719 Add 'qcom/opensource/graphics-kernel/' from commit 'b4fdc4c04295ac59109ae19d64747522740c3f14'
git-subtree-dir: qcom/opensource/graphics-kernel
git-subtree-mainline: 992813d9c1
git-subtree-split: b4fdc4c042
Change-Id:
repo: https://git.codelinaro.org/clo/la/platform/vendor/qcom/opensource/graphics-kernel
tag: GRAPHICS.LA.14.0.r1-07700-lanai.0
2024-10-06 16:44:56 +02:00

1415 lines
37 KiB
C

/* 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