mirror of
https://github.com/physwizz/a155-U-u1.git
synced 2025-02-15 00:18:03 +00:00
1017 lines
29 KiB
C
1017 lines
29 KiB
C
/* SPDX-License-Identifier: GPL-2.0 */
|
|
/*
|
|
* Copyright (c) 2015 MediaTek Inc.
|
|
*/
|
|
|
|
#ifndef __CMDQ_HELPER_EXT_H__
|
|
#define __CMDQ_HELPER_EXT_H__
|
|
|
|
#include <linux/kernel.h>
|
|
#include <linux/printk.h>
|
|
#include <linux/soc/mediatek/mtk-cmdq-ext.h>
|
|
#include <linux/trace_events.h>
|
|
|
|
#include "mdp_def.h"
|
|
|
|
#if IS_ENABLED(CONFIG_MTK_AEE_FEATURE)
|
|
#include <mt-plat/aee.h>
|
|
#endif
|
|
|
|
#define CMDQ_EVENT_ENUM cmdq_event
|
|
|
|
#define CMDQ_PHYS_TO_AREG(addr) ((addr) & 0xFFFFFFFF) /* truncate directly */
|
|
#define CMDQ_AREG_TO_PHYS(addr) ((addr) | 0L)
|
|
|
|
struct cmdqRecStruct;
|
|
|
|
enum TASK_STATE_ENUM {
|
|
TASK_STATE_IDLE, /* free task */
|
|
TASK_STATE_BUSY, /* task running on a thread */
|
|
TASK_STATE_KILLED, /* task process being killed */
|
|
TASK_STATE_ERROR, /* task execution error */
|
|
TASK_STATE_ERR_IRQ, /* task execution invalid instruction */
|
|
TASK_STATE_DONE, /* task finished */
|
|
TASK_STATE_WAITING, /* allocated but waiting for available thread */
|
|
TASK_STATE_TIMEOUT, /* task timeout */
|
|
};
|
|
|
|
|
|
#define CMDQ_LONGSTRING_MAX (180)
|
|
#define CMDQ_DELAY_RELEASE_RESOURCE_MS (1000)
|
|
|
|
#define CMDQ_THREAD_SEC_PRIMARY_DISP (CMDQ_MIN_SECURE_THREAD_ID)
|
|
#define CMDQ_THREAD_SEC_SUB_DISP (CMDQ_MIN_SECURE_THREAD_ID + 1)
|
|
#define CMDQ_THREAD_SEC_MDP (CMDQ_MIN_SECURE_THREAD_ID + 2)
|
|
#define CMDQ_THREAD_SEC_ISP (CMDQ_MIN_SECURE_THREAD_ID + 3)
|
|
|
|
/* max count of input */
|
|
#define CMDQ_MAX_COMMAND_SIZE (0x80000000)
|
|
#define CMDQ_MAX_SIMULATE_COMMAND_SIZE (0x80000)
|
|
#define CMDQ_MAX_DUMP_REG_COUNT (4096)
|
|
#define CMDQ_MAX_WRITE_ADDR_COUNT (PAGE_SIZE / sizeof(u32))
|
|
#define CMDQ_MAX_DBG_STR_LEN (1024)
|
|
#define CMDQ_MAX_USER_PROP_SIZE (1024)
|
|
|
|
extern struct cmdq_client *cmdq_clients[CMDQ_MAX_THREAD_COUNT];
|
|
extern struct ContextStruct cmdq_ctx; /* cmdq driver context */
|
|
extern struct CmdqCBkStruct *cmdq_group_cb;
|
|
extern struct CmdqDebugCBkStruct cmdq_debug_cb;
|
|
|
|
#define CMDQ_LOG_PQ(string, args...) \
|
|
do { \
|
|
if (cmdq_core_should_pqrb_log()) { \
|
|
pr_notice("[MDP][PQ]"string, ##args); \
|
|
} \
|
|
} while (0)
|
|
|
|
#define CMDQ_LOG_CLOCK(string, args...) \
|
|
do { \
|
|
if (cmdq_core_should_clock_log()) { \
|
|
pr_notice("[MDP]"string, ##args); \
|
|
} \
|
|
} while (0)
|
|
|
|
#define CMDQ_LOG(string, args...) \
|
|
do { \
|
|
pr_notice("[MDP]"string, ##args); \
|
|
cmdq_core_save_first_dump("[MDP]"string, ##args); \
|
|
} while (0)
|
|
|
|
#define CMDQ_MSG(string, args...) \
|
|
do { \
|
|
if (cmdq_core_should_print_msg()) { \
|
|
pr_notice("[MDP]"string, ##args); \
|
|
} \
|
|
} while (0)
|
|
|
|
#define CMDQ_VERBOSE(string, args...) \
|
|
do { \
|
|
if (cmdq_core_should_print_msg()) { \
|
|
pr_debug("[MDP]"string, ##args); \
|
|
} \
|
|
} while (0)
|
|
|
|
|
|
#define CMDQ_ERR(string, args...) \
|
|
do { \
|
|
pr_notice("[MDP][ERR]"string, ##args); \
|
|
cmdq_core_save_first_dump("[MDP]"string, ##args); \
|
|
} while (0)
|
|
|
|
#define CMDQ_CHECK_AND_BREAK_STATUS(status)\
|
|
{ \
|
|
if (status < 0) \
|
|
break; \
|
|
}
|
|
|
|
#if IS_ENABLED(CONFIG_MTK_AEE_FEATURE)
|
|
#define CMDQ_AEE_EX(DB_OPTs, tag, string, args...) \
|
|
{ \
|
|
do { \
|
|
char dispatchedTag[50]; \
|
|
int ret = snprintf(dispatchedTag, 50, "CRDISPATCH_KEY:%s", tag); \
|
|
if (unlikely(ret < 0)) \
|
|
pr_notice("CMDQ_AEE snprintf fail"); \
|
|
else \
|
|
pr_notice("[MDP][AEE]"string, ##args); \
|
|
cmdq_core_save_first_dump("[MDP][AEE]"string, ##args); \
|
|
aee_kernel_warning_api(__FILE__, __LINE__, \
|
|
DB_OPT_DEFAULT | DB_OPT_PROC_CMDQ_INFO | \
|
|
DB_OPT_MMPROFILE_BUFFER | DB_OPT_FTRACE | DB_OPTs, \
|
|
dispatchedTag, "error: "string, ##args); \
|
|
} while (0); \
|
|
}
|
|
|
|
#define CMDQ_AEE(tag, string, args...) \
|
|
do { \
|
|
if (cmdq_core_aee_enable()) \
|
|
CMDQ_AEE_EX(DB_OPT_DUMP_DISPLAY, tag, string, ##args) \
|
|
} while (0)
|
|
|
|
#else
|
|
#define CMDQ_AEE(tag, string, args...) \
|
|
{ \
|
|
do { \
|
|
char dispatchedTag[50]; \
|
|
int ret = snprintf(dispatchedTag, 50, "CRDISPATCH_KEY:%s", tag); \
|
|
if (unlikely(ret < 0)) \
|
|
pr_notice("CMDQ_AEE snprintf fail"); \
|
|
pr_debug("[MDP][AEE] AEE not READY!!!"); \
|
|
pr_debug("[MDP][AEE]"string, ##args); \
|
|
cmdq_core_save_first_dump("[MDP][AEE]"string, ##args); \
|
|
} while (0); \
|
|
}
|
|
#endif
|
|
|
|
/*#define CMDQ_PROFILE*/
|
|
|
|
/* typedef unsigned long long CMDQ_TIME; */
|
|
#define CMDQ_TIME unsigned long long
|
|
|
|
#ifdef CMDQ_PROFILE
|
|
#define CMDQ_PROF_INIT() \
|
|
{ \
|
|
do {if (cmdq_core_met_enabled()) met_tag_init(); } while (0); \
|
|
}
|
|
|
|
#define CMDQ_PROF_START(args...) \
|
|
{ \
|
|
do {if (cmdq_core_met_enabled()) met_tag_start(args); \
|
|
} while (0); \
|
|
}
|
|
|
|
#define CMDQ_PROF_END(args...) \
|
|
{ \
|
|
do {if (cmdq_core_met_enabled()) met_tag_end(args); \
|
|
} while (0); \
|
|
}
|
|
#define CMDQ_PROF_ONESHOT(args...) \
|
|
{ \
|
|
do {if (cmdq_core_met_enabled()) met_tag_oneshot(args); \
|
|
} while (0); \
|
|
}
|
|
#else
|
|
#define CMDQ_PROF_INIT()
|
|
#define CMDQ_PROF_START(args...)
|
|
#define CMDQ_PROF_END(args...)
|
|
#define CMDQ_PROF_ONESHOT(args...)
|
|
#endif
|
|
|
|
#if IS_ENABLED(CONFIG_MMPROFILE)
|
|
#define CMDQ_PROF_MMP(args...)\
|
|
{\
|
|
do {if (1) mmprofile_log_ex(args); } while (0); \
|
|
}
|
|
#else
|
|
#define CMDQ_PROF_MMP(args...)
|
|
#endif
|
|
|
|
/* CMDQ FTRACE */
|
|
#define TRACE_MSG_LEN 1024
|
|
|
|
#define CMDQ_TRACE_FORCE_BEGIN_TID(tid, fmt, args...) \
|
|
tracing_mark_write("B|%d|" fmt "\n", tid, ##args)
|
|
|
|
#define CMDQ_TRACE_FORCE_BEGIN(fmt, args...) \
|
|
CMDQ_TRACE_FORCE_BEGIN_TID(current->tgid, fmt, ##args)
|
|
|
|
#define CMDQ_TRACE_FORCE_END() \
|
|
tracing_mark_write("E\n")
|
|
|
|
#define CMDQ_SYSTRACE_BEGIN(fmt, args...) do { \
|
|
if (cmdq_core_ftrace_enabled()) { \
|
|
CMDQ_TRACE_FORCE_BEGIN(fmt, ##args); \
|
|
} \
|
|
} while (0)
|
|
|
|
#define CMDQ_SYSTRACE_END() do { \
|
|
if (cmdq_core_ftrace_enabled()) { \
|
|
CMDQ_TRACE_FORCE_END(); \
|
|
} \
|
|
} while (0)
|
|
|
|
#define CMDQ_GET_TIME_IN_MS(start, end, duration) \
|
|
{ \
|
|
CMDQ_TIME _duration = end - start; \
|
|
do_div(_duration, 1000000); \
|
|
duration = (s32)_duration; \
|
|
}
|
|
|
|
#define CMDQ_GET_TIME_IN_US_PART(start, end, duration) \
|
|
{ \
|
|
CMDQ_TIME _duration = end - start; \
|
|
do_div(_duration, 1000); \
|
|
duration = (s32)_duration; \
|
|
}
|
|
|
|
#define CMDQ_INC_TIME_IN_US(start, end, target) \
|
|
{ \
|
|
CMDQ_TIME _duration = end - start; \
|
|
do_div(_duration, 1000); \
|
|
target += (s32)_duration; \
|
|
}
|
|
|
|
#define GENERATE_ENUM(_enum, _string) _enum,
|
|
#define GENERATE_STRING(_enum, _string) (#_string),
|
|
|
|
#define CMDQ_TASK_PRIVATE(task) \
|
|
((struct task_private *)task->privateData)
|
|
#define CMDQ_TASK_IS_INTERNAL(task) \
|
|
(task->privateData && (CMDQ_TASK_PRIVATE(task)->internal))
|
|
|
|
/* engineFlag are bit fields defined in CMDQ_ENG_ENUM */
|
|
typedef s32(*CmdqClockOnCB) (u64 engineFlag);
|
|
|
|
/* engineFlag are bit fields defined in CMDQ_ENG_ENUM */
|
|
typedef s32(*CmdqDumpInfoCB) (u64 engineFlag, int level);
|
|
|
|
/* engineFlag are bit fields defined in CMDQ_ENG_ENUM */
|
|
typedef s32(*CmdqResetEngCB) (u64 engineFlag);
|
|
|
|
/* engineFlag are bit fields defined in CMDQ_ENG_ENUM */
|
|
typedef s32(*CmdqClockOffCB) (u64 engineFlag);
|
|
|
|
/* data are user data passed to APIs */
|
|
typedef s32(*CmdqInterruptCB) (unsigned long data);
|
|
|
|
/* data are user data passed to APIs */
|
|
typedef s32(*CmdqAsyncFlushCB) (unsigned long data);
|
|
|
|
/* resource event can be indicated to resource unit */
|
|
typedef s32(*CmdqResourceReleaseCB) (enum cmdq_event resourceEvent);
|
|
|
|
/* resource event can be indicated to resource unit */
|
|
typedef s32(*CmdqResourceAvailableCB) (
|
|
enum cmdq_event resourceEvent);
|
|
|
|
/* PMQOS */
|
|
/* task begin for pmqos */
|
|
typedef void(*CmdqBeginTaskCB) (struct cmdqRecStruct *handle,
|
|
struct cmdqRecStruct **handle_list, u32 size);
|
|
|
|
/* task end for pmqos */
|
|
typedef void(*CmdqEndTaskCB) (struct cmdqRecStruct *handle,
|
|
struct cmdqRecStruct **handle_list, u32 size);
|
|
|
|
/* TaskID is passed down from IOCTL */
|
|
/* client should fill "regCount" and "regAddress" */
|
|
/* the buffer pointed by (*regAddress) must be valid until */
|
|
/* CmdqDebugRegDumpEndCB() is called. */
|
|
typedef s32(*CmdqDebugRegDumpBeginCB) (u32 taskID, u32 *regCount,
|
|
u32 **regAddress);
|
|
typedef s32(*CmdqDebugRegDumpEndCB) (u32 taskID, u32 regCount,
|
|
u32 *regValues);
|
|
|
|
/* dispatch module can be change by callback */
|
|
typedef const char*(*CmdqDispatchModuleCB) (u64 engineFlag);
|
|
|
|
struct NGTaskInfoStruct;
|
|
|
|
/* finished task can be get by callback */
|
|
typedef void(*CmdqTrackTaskCB) (const struct cmdqRecStruct *pTask);
|
|
|
|
/* finished task can be get by callback */
|
|
typedef void(*CmdqErrorResetCB) (u64 engineFlag);
|
|
|
|
struct CmdqCBkStruct {
|
|
CmdqClockOnCB clockOn;
|
|
CmdqDumpInfoCB dumpInfo;
|
|
CmdqResetEngCB resetEng;
|
|
CmdqClockOffCB clockOff;
|
|
CmdqDispatchModuleCB dispatchMod;
|
|
CmdqTrackTaskCB trackTask;
|
|
CmdqErrorResetCB errorReset;
|
|
CmdqBeginTaskCB beginTask;
|
|
CmdqEndTaskCB endTask;
|
|
};
|
|
|
|
struct CmdqDebugCBkStruct {
|
|
/* Debug Register Dump */
|
|
CmdqDebugRegDumpBeginCB beginDebugRegDump;
|
|
CmdqDebugRegDumpEndCB endDebugRegDump;
|
|
};
|
|
|
|
enum CMDQ_CLT_ENUM {
|
|
CMDQ_CLT_UNKN,
|
|
CMDQ_CLT_MDP,
|
|
CMDQ_CLT_CMDQ,
|
|
CMDQ_CLT_GNRL,
|
|
CMDQ_CLT_DISP,
|
|
CMDQ_CLT_MAX /* ALWAYS keep at the end */
|
|
};
|
|
|
|
/* sync with request in atf */
|
|
enum cmdq_smc_request {
|
|
CMDQ_ENABLE_DEBUG,
|
|
};
|
|
|
|
/* handle to gce life cycle callback */
|
|
typedef void (*cmdq_core_handle_cb)(struct cmdqRecStruct *handle);
|
|
|
|
#define subsys_lsb_bit (16)
|
|
|
|
enum CMDQ_LOG_LEVEL_ENUM {
|
|
CMDQ_LOG_LEVEL_NORMAL = 0,
|
|
CMDQ_LOG_LEVEL_MSG = 1,
|
|
CMDQ_LOG_LEVEL_FULL_ERROR = 2,
|
|
CMDQ_LOG_LEVEL_EXTENSION = 3,
|
|
CMDQ_LOG_LEVEL_PMQOS = 4,
|
|
CMDQ_LOG_LEVEL_SECURE = 5,
|
|
CMDQ_LOG_LEVEL_PQ_READBACK = 6,
|
|
CMDQ_LOG_LEVEL_CLOCK = 7,
|
|
|
|
CMDQ_LOG_LEVEL_MAX /* ALWAYS keep at the end */
|
|
};
|
|
|
|
enum CMDQ_PROFILE_LEVEL {
|
|
CMDQ_PROFILE_OFF = 0,
|
|
CMDQ_PROFILE_MET = 1,
|
|
CMDQ_PROFILE_FTRACE = 2,
|
|
CMDQ_PROFILE_EXEC = 3,
|
|
CMDQ_PROFILE_PQRB_ONCE = 4,
|
|
CMDQ_PROFILE_PQRB = 5,
|
|
|
|
CMDQ_PROFILE_MAX /* ALWAYS keep at the end */
|
|
};
|
|
|
|
|
|
#define CMDQ_FEATURE_OFF_VALUE (0)
|
|
#define FOREACH_FEATURE(FEATURE) \
|
|
FEATURE(CMDQ_FEATURE_SRAM_SHARE, "SRAM Share") \
|
|
|
|
enum CMDQ_FEATURE_TYPE_ENUM {
|
|
FOREACH_FEATURE(GENERATE_ENUM)
|
|
CMDQ_FEATURE_TYPE_MAX, /* ALWAYS keep at the end */
|
|
};
|
|
|
|
#ifdef CMDQ_INSTRUCTION_COUNT
|
|
/* GCE instructions count information */
|
|
enum CMDQ_STAT_ENUM {
|
|
CMDQ_STAT_WRITE = 0,
|
|
CMDQ_STAT_WRITE_W_MASK = 1,
|
|
CMDQ_STAT_READ = 2,
|
|
CMDQ_STAT_POLLING = 3,
|
|
CMDQ_STAT_MOVE = 4,
|
|
CMDQ_STAT_SYNC = 5,
|
|
CMDQ_STAT_PREFETCH_EN = 6,
|
|
CMDQ_STAT_PREFETCH_DIS = 7,
|
|
CMDQ_STAT_EOC = 8,
|
|
CMDQ_STAT_JUMP = 9,
|
|
|
|
CMDQ_STAT_MAX /* ALWAYS keep at the end */
|
|
};
|
|
|
|
enum CMDQ_MODULE_STAT_ENUM {
|
|
CMDQ_MODULE_STAT_MMSYS_CONFIG = 0,
|
|
CMDQ_MODULE_STAT_MDP_RDMA = 1,
|
|
CMDQ_MODULE_STAT_MDP_RSZ0 = 2,
|
|
CMDQ_MODULE_STAT_MDP_RSZ1 = 3,
|
|
CMDQ_MODULE_STAT_MDP_WDMA = 4,
|
|
CMDQ_MODULE_STAT_MDP_WROT = 5,
|
|
CMDQ_MODULE_STAT_MDP_TDSHP = 6,
|
|
CMDQ_MODULE_STAT_MM_MUTEX = 7,
|
|
CMDQ_MODULE_STAT_VENC = 8,
|
|
CMDQ_MODULE_STAT_DISP_OVL0 = 9,
|
|
CMDQ_MODULE_STAT_DISP_OVL1 = 10,
|
|
CMDQ_MODULE_STAT_DISP_RDMA0 = 11,
|
|
CMDQ_MODULE_STAT_DISP_RDMA1 = 12,
|
|
CMDQ_MODULE_STAT_DISP_WDMA0 = 13,
|
|
CMDQ_MODULE_STAT_DISP_COLOR = 14,
|
|
CMDQ_MODULE_STAT_DISP_CCORR = 15,
|
|
CMDQ_MODULE_STAT_DISP_AAL = 16,
|
|
CMDQ_MODULE_STAT_DISP_GAMMA = 17,
|
|
CMDQ_MODULE_STAT_DISP_DITHER = 18,
|
|
CMDQ_MODULE_STAT_DISP_UFOE = 19,
|
|
CMDQ_MODULE_STAT_DISP_PWM = 20,
|
|
CMDQ_MODULE_STAT_DISP_WDMA1 = 21,
|
|
CMDQ_MODULE_STAT_DISP_MUTEX = 22,
|
|
CMDQ_MODULE_STAT_DISP_DSI0 = 23,
|
|
CMDQ_MODULE_STAT_DISP_DPI0 = 24,
|
|
CMDQ_MODULE_STAT_DISP_OD = 25,
|
|
CMDQ_MODULE_STAT_CAM0 = 26,
|
|
CMDQ_MODULE_STAT_CAM1 = 27,
|
|
CMDQ_MODULE_STAT_CAM2 = 28,
|
|
CMDQ_MODULE_STAT_CAM3 = 29,
|
|
CMDQ_MODULE_STAT_SODI = 30,
|
|
CMDQ_MODULE_STAT_GPR = 31,
|
|
CMDQ_MODULE_STAT_OTHERS = 32,
|
|
|
|
CMDQ_MODULE_STAT_MAX /* ALWAYS keep at the end */
|
|
};
|
|
|
|
enum CMDQ_EVENT_STAT_ENUM {
|
|
CMDQ_EVENT_STAT_HW = 0,
|
|
CMDQ_EVENT_STAT_SW = 1,
|
|
|
|
CMDQ_EVENT_STAT_MAX /* ALWAYS keep at the end */
|
|
};
|
|
|
|
#define CMDQ_MAX_OTHERINSTRUCTION_MAX (16)
|
|
|
|
struct CmdqModulePAStatStruct {
|
|
long start[CMDQ_MODULE_STAT_MAX];
|
|
};
|
|
#endif
|
|
|
|
/* record NG handle info for dump */
|
|
struct cmdq_ng_handle_info {
|
|
const struct cmdqRecStruct *nghandle;
|
|
u64 engine_flag;
|
|
u32 scenario;
|
|
u32 *va_start; /* original buffer va start */
|
|
u32 *va_pc; /* hw pc for original buffer */
|
|
u32 *buffer;
|
|
u32 buffer_size;
|
|
u32 dump_size;
|
|
const char *module;
|
|
s32 irq_flag;
|
|
u32 inst[2];
|
|
};
|
|
|
|
struct EngineStruct {
|
|
s32 userCount;
|
|
s32 currOwner;
|
|
s32 resetCount;
|
|
s32 failCount;
|
|
};
|
|
|
|
struct ThreadStruct {
|
|
u32 taskCount;
|
|
u32 waitCookie;
|
|
u32 nextCookie;
|
|
/* keep used engine to look up while dispatch thread */
|
|
u64 engineFlag;
|
|
CmdqInterruptCB loopCallback; /* LOOP execution */
|
|
unsigned long loopData; /* LOOP execution */
|
|
//struct TaskStruct *pCurTask[CMDQ_MAX_TASK_IN_THREAD];
|
|
|
|
/* 1 to describe thread is available to dispatch a task.
|
|
* 0: not available
|
|
* .note thread's taskCount increase when attatch a task to it.
|
|
* used it to prevent 2 tasks, which uses different engines,
|
|
* acquire same HW thread when dispatching happened before
|
|
* attaches task to thread
|
|
* .note it is align task attachment, so use cmdqExecLock
|
|
* to ensure atomic access
|
|
*/
|
|
u32 allowDispatching;
|
|
};
|
|
|
|
struct cmdq_core_thread {
|
|
bool used; /* true if thread static allocated */
|
|
u32 acquire; /* acquired ref count */
|
|
s32 scenario;
|
|
u32 handle_count;
|
|
struct mutex thread_mutex;
|
|
};
|
|
|
|
struct RecordStruct {
|
|
pid_t user; /* calling SW thread tid */
|
|
s32 scenario; /* task scenario */
|
|
s32 priority; /* task priority (not thread priority) */
|
|
s32 thread; /* allocated thread */
|
|
s32 reorder;
|
|
s32 size;
|
|
u64 engineFlag; /* task engine flag */
|
|
|
|
bool is_secure; /* true for secure task */
|
|
|
|
CMDQ_TIME submit; /* epoch time of IOCTL/Kernel API call */
|
|
CMDQ_TIME trigger; /* epoch time of enable HW thread */
|
|
/* epoch time of start waiting for task completion */
|
|
CMDQ_TIME beginWait;
|
|
CMDQ_TIME gotIRQ; /* epoch time of IRQ event */
|
|
CMDQ_TIME wakedUp; /* epoch time of SW thread leaving wait state */
|
|
CMDQ_TIME done; /* epoch time of task finish */
|
|
|
|
u32 durAlloc; /* allocae time duration */
|
|
u32 durReclaim; /* allocae time duration */
|
|
u32 durRelease; /* release time duration */
|
|
|
|
u32 start; /* buffer start address */
|
|
u32 end; /* command end address */
|
|
u32 jump; /* last jump destination */
|
|
|
|
/* Custom profile marker */
|
|
u32 profileMarkerCount;
|
|
unsigned long long profileMarkerTimeNS[CMDQ_MAX_PROFILE_MARKER_IN_TASK];
|
|
const char *profileMarkerTag[CMDQ_MAX_PROFILE_MARKER_IN_TASK];
|
|
|
|
/* GCE instructions count information */
|
|
#ifdef CMDQ_INSTRUCTION_COUNT
|
|
unsigned short instructionStat[CMDQ_STAT_MAX];
|
|
unsigned short writeModule[CMDQ_MODULE_STAT_MAX];
|
|
unsigned short writewmaskModule[CMDQ_MODULE_STAT_MAX];
|
|
unsigned short readModlule[CMDQ_MODULE_STAT_MAX];
|
|
unsigned short pollModule[CMDQ_MODULE_STAT_MAX];
|
|
unsigned short eventCount[CMDQ_EVENT_STAT_MAX];
|
|
u32 otherInstr[CMDQ_MAX_OTHERINSTRUCTION_MAX];
|
|
u32 otherInstrNUM;
|
|
#endif
|
|
};
|
|
|
|
struct ErrorStruct {
|
|
struct RecordStruct errorRec; /* the record of the error task */
|
|
u64 ts_nsec; /* kernel time of attach_error_task */
|
|
};
|
|
|
|
struct WriteAddrStruct {
|
|
struct list_head list_node;
|
|
u32 count;
|
|
void *va;
|
|
dma_addr_t pa;
|
|
pid_t user;
|
|
void *fp;
|
|
bool pool;
|
|
};
|
|
|
|
/* resource unit between each module */
|
|
struct ResourceUnitStruct {
|
|
struct list_head list_entry;
|
|
CMDQ_TIME notify; /* notify time from module prepare */
|
|
CMDQ_TIME lock; /* lock time from module lock */
|
|
CMDQ_TIME unlock; /* unlock time from module unlock*/
|
|
CMDQ_TIME delay; /* delay start time from module release*/
|
|
CMDQ_TIME acquire; /* acquire time from module acquire */
|
|
CMDQ_TIME release; /* release time from module release */
|
|
bool used; /* indicate resource is in use by owner or not */
|
|
bool lend; /* indicate resource is lend by client or not */
|
|
bool delaying; /* indicate resource is in delay check or not */
|
|
enum cmdq_event lockEvent; /* SW token to lock in GCE thread */
|
|
u32 engine_id; /* which engine is resource */
|
|
u64 engine_flag; /* engine flag */
|
|
CmdqResourceAvailableCB availableCB;
|
|
CmdqResourceReleaseCB releaseCB;
|
|
/* Delay Work item when delay check is used */
|
|
struct delayed_work delayCheckWork;
|
|
};
|
|
|
|
/**
|
|
* shared memory between normal and secure world
|
|
*/
|
|
struct cmdqSecSharedMemoryStruct {
|
|
void *pVABase; /* virtual address of command buffer */
|
|
dma_addr_t MVABase; /* physical address of command buffer */
|
|
uint32_t size; /* buffer size */
|
|
};
|
|
|
|
struct ContextStruct {
|
|
/* handle information */
|
|
struct list_head handle_active;
|
|
|
|
/* Write Address management */
|
|
struct list_head writeAddrList;
|
|
atomic_t write_addr_cnt;
|
|
|
|
/* Basic information */
|
|
struct cmdq_core_thread thread[CMDQ_MAX_THREAD_COUNT];
|
|
|
|
/* auto-release workqueue per thread */
|
|
struct workqueue_struct **taskThreadAutoReleaseWQ;
|
|
|
|
/* Profile information */
|
|
s32 enableProfile;
|
|
s32 lastID;
|
|
s32 recNum;
|
|
struct RecordStruct record[CMDQ_MAX_RECORD_COUNT];
|
|
|
|
/* Error information */
|
|
s32 logLevel;
|
|
s32 errNum;
|
|
struct ErrorStruct error[CMDQ_MAX_ERROR_COUNT];
|
|
bool aee;
|
|
|
|
void *inst_check_buffer;
|
|
|
|
#ifdef CMDQ_INSTRUCTION_COUNT
|
|
/* GCE instructions count information */
|
|
s32 instructionCountLevel;
|
|
#endif
|
|
};
|
|
|
|
/* Command dump information */
|
|
struct DumpCommandBufferStruct {
|
|
u64 scenario;
|
|
u32 bufferSize;
|
|
u32 count;
|
|
char *cmdqString;
|
|
};
|
|
|
|
struct cmdq_event_table {
|
|
u16 event; /* cmdq event enum value */
|
|
const char *event_name;
|
|
const char *dts_name;
|
|
};
|
|
|
|
struct cmdq_subsys_dts_name {
|
|
const char *name;
|
|
const char *group;
|
|
};
|
|
|
|
struct task_private {
|
|
void *node_private_data;
|
|
bool internal; /* internal used only task */
|
|
bool ignore_timeout; /* timeout is expected */
|
|
};
|
|
|
|
enum cmdq_thread_dispatch {
|
|
CMDQ_THREAD_NOTSET = 0,
|
|
CMDQ_THREAD_STATIC,
|
|
CMDQ_THREAD_ACQUIRE,
|
|
CMDQ_THREAD_DYNAMIC,
|
|
};
|
|
|
|
enum CMDQ_SPM_MODE {
|
|
CMDQ_CG_MODE,
|
|
CMDQ_PD_MODE,
|
|
};
|
|
|
|
/* secure world wsm metadata type in message ex,
|
|
* must sync with cmdq_sec_meta_type in cmdq_sec_iwc_common.h
|
|
*/
|
|
enum cmdq_sec_rec_meta_type {
|
|
CMDQ_SEC_METAEX_NONE,
|
|
CMDQ_SEC_METAEX_FD,
|
|
CMDQ_SEC_METAEX_CQ,
|
|
};
|
|
|
|
struct mdp_readback_engine {
|
|
u32 engine;
|
|
u32 start;
|
|
u32 count;
|
|
u32 param;
|
|
};
|
|
|
|
struct cmdqRecStruct {
|
|
struct list_head list_entry;
|
|
struct cmdq_pkt *pkt;
|
|
struct cmdq_pkt *pkt_rb; /* pkt for readback command */
|
|
u32 *cmd_end;
|
|
u64 engineFlag;
|
|
s32 scenario;
|
|
/* running task after start loop */
|
|
void *running_task;
|
|
bool jump_replace; /* jump replace or not */
|
|
bool finalized; /* set to true after flush() or startLoop() */
|
|
CmdqInterruptCB loop_cb;
|
|
unsigned long loop_user_data;
|
|
CmdqAsyncFlushCB async_callback;
|
|
u64 async_user_data;
|
|
u32 sram_base; /* Original PA address of SRAM buffer content */
|
|
void *node_private;
|
|
void *user_private;
|
|
u32 mdp_extension;
|
|
struct mdp_readback_engine readback_engs[CMDQ_MAX_READBACK_ENG];
|
|
u32 readback_cnt;
|
|
|
|
struct cmdqSecDataStruct secData; /* secure execution data */
|
|
void *sec_isp_msg1;
|
|
void *sec_isp_msg2;
|
|
|
|
/* for CPR conditional and variable use */
|
|
struct cmdq_v3_replace_struct replace_instr;
|
|
u8 local_var_num;
|
|
struct cmdq_stack_node *if_stack_node;
|
|
struct cmdq_stack_node *while_stack_node;
|
|
CMDQ_VARIABLE arg_source; /* poll source, wait_timeout event */
|
|
CMDQ_VARIABLE arg_value; /* poll value, wait_timeout start */
|
|
CMDQ_VARIABLE arg_timeout; /* wait_timeout timeout */
|
|
|
|
/* task executing data */
|
|
atomic_t exec;
|
|
enum TASK_STATE_ENUM state; /* task life cycle */
|
|
s32 thread;
|
|
s32 thread_rb; /* pkt for readback command */
|
|
enum cmdq_thread_dispatch thd_dispatch;
|
|
/* work item when auto release is used */
|
|
struct work_struct auto_release_work;
|
|
|
|
/* register backup at end of task */
|
|
u32 reg_count;
|
|
u32 *reg_values;
|
|
dma_addr_t reg_values_pa;
|
|
|
|
/* user space data */
|
|
u32 user_reg_count;
|
|
u32 user_token;
|
|
pid_t caller_pid;
|
|
char caller_name[TASK_COMM_LEN];
|
|
char *user_debug_str;
|
|
|
|
/* profile marker */
|
|
struct cmdqProfileMarkerStruct profileMarker;
|
|
|
|
/* flag to enable/disable clock */
|
|
u64 engine_clk;
|
|
u64 res_flag_acquire;
|
|
u64 res_flag_release;
|
|
|
|
/* controller interface */
|
|
const struct cmdq_controller *ctrl;
|
|
cmdq_core_handle_cb prepare;
|
|
cmdq_core_handle_cb unprepare;
|
|
cmdq_core_handle_cb stop;
|
|
|
|
/* debug information */
|
|
u32 error_irq_pc;
|
|
bool dumpAllocTime; /* flag to print static info to kernel log. */
|
|
bool profile_exec;
|
|
s32 reorder;
|
|
CMDQ_TIME submit;
|
|
CMDQ_TIME trigger;
|
|
CMDQ_TIME beginWait;
|
|
CMDQ_TIME gotIRQ;
|
|
CMDQ_TIME wakedUp;
|
|
CMDQ_TIME entrySec; /* time stamp of entry secure world */
|
|
CMDQ_TIME exitSec; /* time stamp of exit secure world */
|
|
u32 durAlloc; /* allocae time duration */
|
|
u32 durReclaim; /* allocae time duration */
|
|
u32 durRelease; /* release time duration */
|
|
|
|
/* PMQoS information */
|
|
void *prop_addr;
|
|
u32 prop_size;
|
|
|
|
/* secure world */
|
|
struct iwcCmdqSecStatus_t *secStatus;
|
|
u32 irq;
|
|
void *sec_client_meta;
|
|
enum cmdq_sec_rec_meta_type sec_meta_type;
|
|
u32 sec_meta_size;
|
|
};
|
|
|
|
/* TODO: add controller support */
|
|
struct cmdq_controller {
|
|
s32 (*get_thread_id)(s32 scenario);
|
|
s32 (*handle_wait_result)(struct cmdqRecStruct *handle, s32 thread);
|
|
bool change_jump;
|
|
};
|
|
|
|
/* subsys and event mapping */
|
|
|
|
struct cmdq_subsys_dts_name *cmdq_subsys_get_dts(void);
|
|
u32 cmdq_subsys_get_size(void);
|
|
struct cmdq_event_table *cmdq_event_get_table(void);
|
|
u32 cmdq_event_get_table_size(void);
|
|
|
|
/* CMDQ core feature functions */
|
|
|
|
bool cmdq_core_check_user_valid(void *src, u32 size);
|
|
bool cmdq_core_check_pkt_valid(struct cmdq_pkt *pkt);
|
|
|
|
void cmdq_core_deinit_group_cb(void);
|
|
|
|
u32 mdp_get_group_isp(void);
|
|
|
|
u32 mdp_get_group_wpe(void);
|
|
|
|
s32 cmdqCoreRegisterCB(u32 engGroup,
|
|
CmdqClockOnCB clockOn,
|
|
CmdqDumpInfoCB dumpInfo,
|
|
CmdqResetEngCB resetEng, CmdqClockOffCB clockOff);
|
|
|
|
s32 cmdqCoreRegisterDispatchModCB(
|
|
u32 engGroup,
|
|
CmdqDispatchModuleCB dispatchMod);
|
|
|
|
s32 cmdqCoreRegisterDebugRegDumpCB(
|
|
CmdqDebugRegDumpBeginCB beginCB,
|
|
CmdqDebugRegDumpEndCB endCB);
|
|
|
|
s32 cmdqCoreRegisterTrackTaskCB(u32 engGroup,
|
|
CmdqTrackTaskCB trackTask);
|
|
|
|
s32 cmdqCoreRegisterErrorResetCB(u32 engGroup,
|
|
CmdqErrorResetCB errorReset);
|
|
|
|
void cmdq_core_register_status_dump(struct notifier_block *notifier);
|
|
void cmdq_core_remove_status_dump(struct notifier_block *notifier);
|
|
|
|
/* PMQoS register function */
|
|
s32 cmdq_core_register_task_cycle_cb(u32 group,
|
|
CmdqBeginTaskCB beginTask, CmdqEndTaskCB endTask);
|
|
|
|
const char *cmdq_core_parse_op(u32 op_code);
|
|
s32 cmdq_core_interpret_instruction(char *textBuf, s32 bufLen,
|
|
const u32 op, const u32 arg_a, const u32 arg_b);
|
|
s32 cmdq_core_parse_instruction(const u32 *pCmd, char *textBuf, int bufLen);
|
|
|
|
bool cmdq_core_should_print_msg(void);
|
|
bool cmdq_core_should_full_error(void);
|
|
bool cmdq_core_should_pmqos_log(void);
|
|
bool cmdq_core_should_secure_log(void);
|
|
bool cmdq_core_should_pqrb_log(void);
|
|
bool cmdq_core_should_clock_log(void);
|
|
bool cmdq_core_aee_enable(void);
|
|
void cmdq_core_set_aee(bool enable);
|
|
|
|
bool cmdq_core_ftrace_enabled(void);
|
|
bool cmdq_core_profile_exec_enabled(void);
|
|
bool cmdq_core_profile_pqreadback_once_enabled(void);
|
|
bool cmdq_core_profile_pqreadback_enabled(void);
|
|
void cmdq_long_string_init(bool force, char *buf, u32 *offset, s32 *max_size);
|
|
void cmdq_long_string(char *buf, u32 *offset, s32 *max_size,
|
|
const char *string, ...);
|
|
|
|
s32 cmdq_core_reg_dump_begin(u32 taskID, u32 *regCount,
|
|
u32 **regAddress);
|
|
s32 cmdq_core_reg_dump_end(u32 taskID, u32 regCount, u32 *regValues);
|
|
|
|
int cmdq_core_print_record_seq(struct seq_file *m, void *v);
|
|
int cmdq_core_print_status_seq(struct seq_file *m, void *v);
|
|
|
|
void cmdq_core_dump_trigger_loop_thread(const char *tag);
|
|
|
|
/* cmdq_core_save_first_dump - save a CMDQ first error dump to file */
|
|
s32 cmdq_core_save_first_dump(const char *format, ...);
|
|
const char *cmdq_core_query_first_err_mod(void);
|
|
|
|
/* Allocate/Free HW use buffer, e.g. command buffer forCMDQ HW */
|
|
void *cmdq_core_alloc_hw_buffer_clt(struct device *dev, size_t size,
|
|
dma_addr_t *dma_handle, const gfp_t flag, enum CMDQ_CLT_ENUM clt,
|
|
bool *pool);
|
|
void cmdq_core_free_hw_buffer_clt(struct device *dev, size_t size,
|
|
void *cpu_addr, dma_addr_t dma_handle, enum CMDQ_CLT_ENUM clt,
|
|
bool pool);
|
|
void *cmdq_core_alloc_hw_buffer(struct device *dev,
|
|
size_t size, dma_addr_t *dma_handle, const gfp_t flag);
|
|
void cmdq_core_free_hw_buffer(struct device *dev, size_t size,
|
|
void *cpu_addr, dma_addr_t dma_handle);
|
|
s32 cmdq_core_alloc_pool_buf(struct cmdq_pkt_buffer *buf);
|
|
s32 cmdq_core_free_pool_buf(struct cmdq_pkt_buffer *buf);
|
|
void cmdq_delay_dump_thread(bool dump_sram);
|
|
u32 cmdq_core_get_delay_start_cpr(void);
|
|
s32 cmdq_delay_get_id_by_scenario(enum CMDQ_SCENARIO_ENUM scenario);
|
|
|
|
int cmdqCoreWriteAddressVcpAlloc(u32 count, dma_addr_t *vcp_paStart,
|
|
enum CMDQ_CLT_ENUM clt, void *fp,
|
|
dma_addr_t vcp_iova_base, void *vcp_va_base, u32 rb_slot_index);
|
|
int cmdqCoreWriteAddressVcpFree(dma_addr_t paStart, enum CMDQ_CLT_ENUM clt);
|
|
int cmdqCoreWriteAddressVcpFreeByNode(void *fp, enum CMDQ_CLT_ENUM clt);
|
|
|
|
int cmdqCoreAllocWriteAddress(u32 count, dma_addr_t *paStart,
|
|
enum CMDQ_CLT_ENUM clt, void *fp);
|
|
u32 cmdqCoreReadWriteAddress(dma_addr_t pa);
|
|
void cmdqCoreReadWriteAddressBatch(dma_addr_t *addrs, u32 count, u32 *val_out);
|
|
u32 cmdqCoreWriteWriteAddress(dma_addr_t pa, u32 value);
|
|
int cmdqCoreFreeWriteAddress(dma_addr_t paStart, enum CMDQ_CLT_ENUM clt);
|
|
int cmdqCoreFreeWriteAddressByNode(void *fp, enum CMDQ_CLT_ENUM clt);
|
|
|
|
/* Get and HW information from device tree */
|
|
void cmdq_core_init_dts_data(void);
|
|
struct cmdqDTSDataStruct *cmdq_core_get_dts_data(void);
|
|
|
|
/* Get and set HW event form device tree */
|
|
void cmdq_core_set_event_table(enum cmdq_event event, const s32 value);
|
|
s32 cmdq_core_get_event_value(enum cmdq_event event);
|
|
const char *cmdq_core_get_event_name_enum(enum cmdq_event event);
|
|
const char *cmdq_core_get_event_name(u32 hw_event);
|
|
|
|
/* Immediately clear CMDQ event to 0 with CPU */
|
|
void cmdqCoreClearEvent(enum cmdq_event event);
|
|
|
|
/* Immediately set CMDQ event to 1 with CPU */
|
|
void cmdqCoreSetEvent(enum cmdq_event event);
|
|
|
|
/* Get event value with CPU. This is for debug purpose only
|
|
* since it does not guarantee atomicity.
|
|
*/
|
|
u32 cmdqCoreGetEvent(enum cmdq_event event);
|
|
|
|
|
|
/* GCE capability */
|
|
void cmdq_core_reset_gce(void);
|
|
void cmdq_core_set_addon_subsys(u32 msb, s32 subsys_id, u32 mask);
|
|
u32 cmdq_core_subsys_to_reg_addr(u32 arg_a);
|
|
const char *cmdq_core_parse_subsys_from_reg_addr(u32 reg_addr);
|
|
s32 cmdq_core_subsys_from_phys_addr(u32 physAddr);
|
|
|
|
s32 cmdq_core_print_error(char *buf);
|
|
void cmdq_core_set_log_level(const s32 value);
|
|
ssize_t cmdq_core_print_profile_enable(struct device *dev,
|
|
struct device_attribute *attr, char *buf);
|
|
ssize_t cmdq_core_write_profile_enable(struct device *dev,
|
|
struct device_attribute *attr, const char *buf, size_t size);
|
|
|
|
void cmdq_core_dump_tasks_info(void);
|
|
struct cmdqRecStruct *cmdq_core_get_valid_handle(unsigned long job);
|
|
u32 *cmdq_core_get_pc_inst(const struct cmdqRecStruct *handle,
|
|
s32 thread, u32 insts[2], u32 *pa_out);
|
|
void cmdq_core_dump_handle_buffer(const struct cmdq_pkt *pkt,
|
|
const char *tag);
|
|
u32 *cmdq_core_dump_pc(const struct cmdqRecStruct *handle,
|
|
int thread, const char *tag);
|
|
|
|
s32 cmdq_core_is_group_flag(u32 engGroup, u64 engineFlag);
|
|
s32 cmdq_core_acquire_thread(enum CMDQ_SCENARIO_ENUM scenario, bool exclusive);
|
|
void cmdq_core_release_thread(s32 scenario, s32 thread);
|
|
|
|
bool cmdq_thread_in_use(void);
|
|
|
|
s32 cmdq_core_suspend_hw_thread(s32 thread);
|
|
|
|
u64 cmdq_core_get_gpr64(const enum cmdq_gpr_reg regID);
|
|
void cmdq_core_set_gpr64(const enum cmdq_gpr_reg regID, const u64 value);
|
|
|
|
void cmdq_core_release_handle_by_file_node(void *file_node);
|
|
s32 cmdq_core_remove(void);
|
|
s32 cmdq_core_suspend(void);
|
|
s32 cmdq_core_resume(void);
|
|
s32 cmdq_core_resume_notifier(void);
|
|
|
|
void cmdq_core_set_spm_mode(enum CMDQ_SPM_MODE mode);
|
|
|
|
struct ContextStruct *cmdq_core_get_context(void);
|
|
struct CmdqCBkStruct *cmdq_core_get_group_cb(void);
|
|
dma_addr_t cmdq_core_get_pc(s32 thread);
|
|
dma_addr_t cmdq_core_get_end(s32 thread);
|
|
const struct cmdq_controller *cmdq_core_get_controller(void);
|
|
|
|
|
|
/* mailbox pkt flush functions */
|
|
|
|
s32 cmdq_pkt_get_cmd_by_pc(const struct cmdqRecStruct *handle, u32 pc,
|
|
u32 *inst_out, u32 size);
|
|
|
|
void cmdq_pkt_get_first_buffer(struct cmdqRecStruct *handle,
|
|
void **va_out, dma_addr_t *pa_out);
|
|
|
|
void *cmdq_pkt_get_first_va(const struct cmdqRecStruct *handle);
|
|
|
|
s32 cmdq_pkt_alloc_single_buffer_list(struct cmdqRecStruct *handle,
|
|
struct cmdq_pkt_buffer **buf_out);
|
|
|
|
s32 cmdq_pkt_extend_cmd_buffer(struct cmdqRecStruct *handle);
|
|
|
|
s32 cmdq_pkt_copy_cmd(struct cmdqRecStruct *handle, void *src, const u32 size,
|
|
const bool is_copy_from_user);
|
|
|
|
void cmdq_pkt_release_handle(struct cmdqRecStruct *handle);
|
|
|
|
s32 cmdq_pkt_dump_command(struct cmdqRecStruct *handle);
|
|
|
|
s32 cmdq_pkt_wait_flush_ex_result(struct cmdqRecStruct *handle);
|
|
|
|
s32 cmdq_pkt_auto_release_task(struct cmdqRecStruct *handle,
|
|
bool destroy);
|
|
|
|
s32 cmdq_pkt_flush_ex(struct cmdqRecStruct *handle);
|
|
|
|
/*
|
|
* cmdq_pkt_flush_async() - trigger CMDQ to asynchronously execute the CMDQ
|
|
* packet and call back at the end of done packet
|
|
* @client: the CMDQ mailbox client
|
|
* @pkt: the CMDQ packet
|
|
* @cb: called at the end of done packet
|
|
* @data: this data will pass back to cb
|
|
*
|
|
* Return: 0 for success; else the error code is returned
|
|
*
|
|
* Trigger CMDQ to asynchronously execute the CMDQ packet and call back
|
|
* at the end of done packet. Note that this is an ASYNC function. When the
|
|
* function returned, it may or may not be finished.
|
|
*/
|
|
s32 cmdq_pkt_flush_async_ex(struct cmdqRecStruct *handle,
|
|
CmdqAsyncFlushCB cb, u64 user_data, bool auto_release);
|
|
|
|
s32 cmdq_pkt_stop(struct cmdqRecStruct *handle);
|
|
|
|
/* mailbox helper functions */
|
|
struct device *cmdq_mbox_dev_get(void);
|
|
s32 cmdq_helper_mbox_register(struct device *dev);
|
|
struct cmdq_client *cmdq_helper_mbox_client(u32 idx);
|
|
struct cmdq_base *cmdq_helper_mbox_base(void);
|
|
void cmdq_helper_mbox_clear_pools(void);
|
|
void cmdq_core_initialize(void);
|
|
void cmdq_core_late_init(void);
|
|
void cmdq_core_deinitialize(void);
|
|
unsigned long cmdq_get_tracing_mark(void);
|
|
int tracing_mark_write(char *fmt, ...);
|
|
void cmdq_helper_ext_deinit(void);
|
|
|
|
struct cmdqSecSharedMemoryStruct *cmdq_core_get_secure_shared_memory(void);
|
|
void cmdq_core_attach_error_handle(const struct cmdqRecStruct *handle,
|
|
s32 thread);
|
|
|
|
#endif
|