cmdq_core.h 30 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952
  1. #ifndef __CMDQ_CORE_H__
  2. #define __CMDQ_CORE_H__
  3. #include <linux/list.h>
  4. #include <linux/time.h>
  5. #ifdef CMDQ_AEE_READY
  6. #include <mt-plat/aee.h>
  7. #endif
  8. #include <linux/device.h>
  9. #include <linux/printk.h>
  10. #include <linux/sched.h>
  11. #include "cmdq_def.h"
  12. /* */
  13. /* address conversion for 4GB ram support: */
  14. /* .address register: 32 bit */
  15. /* .physical address: 32 bit, or 64 bit for CONFIG_ARCH_DMA_ADDR_T_64BIT enabled */
  16. /* */
  17. /* when 33 bit enabled(4GB ram), 0x_0_xxxx_xxxx and 0x_1_xxxx_xxxx access is same for CPU */
  18. /* */
  19. /* */
  20. /* 0x0 0x0_4000_0000 0x1_0000_0000 0x1_4000_0000 */
  21. /* |---1GB HW addr---|------3GB DRAM------|----1GB DRAM(new)----|-----3GB DRAM(same)------| */
  22. /* | | */
  23. /* |<--------------4GB RAM support---------------->| */
  24. /* */
  25. #define CMDQ_PHYS_TO_AREG(addr) ((addr) & 0xFFFFFFFF) /* truncate directly */
  26. #define CMDQ_AREG_TO_PHYS(addr) ((addr) | 0L)
  27. #define CMDQ_LONGSTRING_MAX (180)
  28. #define CMDQ_DELAY_RELEASE_RESOURCE_MS (1000)
  29. #define CMDQ_ENG_ISP_GROUP_BITS ((1LL << CMDQ_ENG_ISP_IMGI) | \
  30. (1LL << CMDQ_ENG_ISP_IMGO) | \
  31. (1LL << CMDQ_ENG_ISP_IMG2O))
  32. #define CMDQ_ENG_MDP_GROUP_BITS ((1LL << CMDQ_ENG_MDP_CAMIN) | \
  33. (1LL << CMDQ_ENG_MDP_RDMA0) | \
  34. (1LL << CMDQ_ENG_MDP_RDMA1) | \
  35. (1LL << CMDQ_ENG_MDP_RSZ0) | \
  36. (1LL << CMDQ_ENG_MDP_RSZ1) | \
  37. (1LL << CMDQ_ENG_MDP_RSZ2) | \
  38. (1LL << CMDQ_ENG_MDP_TDSHP0) | \
  39. (1LL << CMDQ_ENG_MDP_TDSHP1) | \
  40. (1LL << CMDQ_ENG_MDP_COLOR0) | \
  41. (1LL << CMDQ_ENG_MDP_WROT0) | \
  42. (1LL << CMDQ_ENG_MDP_WROT1) | \
  43. (1LL << CMDQ_ENG_MDP_WDMA))
  44. #define CMDQ_ENG_DISP_GROUP_BITS ((1LL << CMDQ_ENG_DISP_UFOE) | \
  45. (1LL << CMDQ_ENG_DISP_AAL) | \
  46. (1LL << CMDQ_ENG_DISP_COLOR0) | \
  47. (1LL << CMDQ_ENG_DISP_COLOR1) | \
  48. (1LL << CMDQ_ENG_DISP_RDMA0) | \
  49. (1LL << CMDQ_ENG_DISP_RDMA1) | \
  50. (1LL << CMDQ_ENG_DISP_RDMA2) | \
  51. (1LL << CMDQ_ENG_DISP_WDMA0) | \
  52. (1LL << CMDQ_ENG_DISP_WDMA1) | \
  53. (1LL << CMDQ_ENG_DISP_OVL0) | \
  54. (1LL << CMDQ_ENG_DISP_OVL1) | \
  55. (1LL << CMDQ_ENG_DISP_OVL2) | \
  56. (1LL << CMDQ_ENG_DISP_2L_OVL0) | \
  57. (1LL << CMDQ_ENG_DISP_2L_OVL1) | \
  58. (1LL << CMDQ_ENG_DISP_2L_OVL2) | \
  59. (1LL << CMDQ_ENG_DISP_GAMMA) | \
  60. (1LL << CMDQ_ENG_DISP_MERGE) | \
  61. (1LL << CMDQ_ENG_DISP_SPLIT0) | \
  62. (1LL << CMDQ_ENG_DISP_SPLIT1) | \
  63. (1LL << CMDQ_ENG_DISP_DSI0_VDO) | \
  64. (1LL << CMDQ_ENG_DISP_DSI1_VDO) | \
  65. (1LL << CMDQ_ENG_DISP_DSI0_CMD) | \
  66. (1LL << CMDQ_ENG_DISP_DSI1_CMD) | \
  67. (1LL << CMDQ_ENG_DISP_DSI0) | \
  68. (1LL << CMDQ_ENG_DISP_DSI1) | \
  69. (1LL << CMDQ_ENG_DISP_DPI))
  70. #define CMDQ_ENG_VENC_GROUP_BITS ((1LL << CMDQ_ENG_VIDEO_ENC))
  71. #define CMDQ_ENG_JPEG_GROUP_BITS ((1LL << CMDQ_ENG_JPEG_ENC) | \
  72. (1LL << CMDQ_ENG_JPEG_REMDC) | \
  73. (1LL << CMDQ_ENG_JPEG_DEC))
  74. #define CMDQ_ENG_DPE_GROUP_BITS (1LL << CMDQ_ENG_DPE)
  75. #ifdef CMDQ_DUMP_FIRSTERROR
  76. #define CMDQ_MAX_FIRSTERROR (32*1024)
  77. typedef struct DumpFirstErrorStruct {
  78. pid_t callerPid;
  79. char callerName[TASK_COMM_LEN];
  80. unsigned long long savetime; /* epoch time of first error occur */
  81. char cmdqString[CMDQ_MAX_FIRSTERROR];
  82. uint32_t cmdqCount;
  83. int32_t cmdqMaxSize;
  84. bool flag;
  85. struct timeval savetv;
  86. } DumpFirstErrorStruct;
  87. #endif
  88. #define CMDQ_LOG(string, args...) \
  89. { \
  90. if (1) { \
  91. pr_err("[CMDQ]"string, ##args); \
  92. cmdq_core_save_first_dump("[CMDQ]"string, ##args); \
  93. } \
  94. }
  95. #define CMDQ_MSG(string, args...) \
  96. { \
  97. if (cmdq_core_should_print_msg()) { \
  98. pr_warn("[CMDQ]"string, ##args); \
  99. } \
  100. }
  101. #define CMDQ_VERBOSE(string, args...) \
  102. { \
  103. if (cmdq_core_should_print_msg()) { \
  104. pr_debug("[CMDQ]"string, ##args); \
  105. } \
  106. }
  107. #define CMDQ_ERR(string, args...) \
  108. { \
  109. if (1) { \
  110. pr_err("[CMDQ][ERR]"string, ##args); \
  111. cmdq_core_save_first_dump("[CMDQ][ERR]"string, ##args); \
  112. } \
  113. }
  114. #ifdef CMDQ_AEE_READY
  115. #define CMDQ_AEE_EX(DB_OPTs, tag, string, args...) \
  116. { \
  117. do { \
  118. char dispatchedTag[50]; \
  119. snprintf(dispatchedTag, 50, "CRDISPATCH_KEY:%s", tag); \
  120. pr_err("[CMDQ][AEE]"string, ##args); \
  121. cmdq_core_save_first_dump("[CMDQ][AEE]"string, ##args); \
  122. cmdq_core_turnoff_first_dump(); \
  123. aee_kernel_warning_api(__FILE__, __LINE__, \
  124. DB_OPT_DEFAULT | DB_OPT_PROC_CMDQ_INFO | DB_OPT_MMPROFILE_BUFFER | DB_OPTs, \
  125. dispatchedTag, "error: "string, ##args); \
  126. } while (0); \
  127. }
  128. #define CMDQ_AEE(tag, string, args...) \
  129. { \
  130. CMDQ_AEE_EX(DB_OPT_DUMP_DISPLAY, tag, string, ##args) \
  131. }
  132. #else
  133. #define CMDQ_AEE(tag, string, args...) \
  134. { \
  135. do { \
  136. char dispatchedTag[50]; \
  137. snprintf(dispatchedTag, 50, "CRDISPATCH_KEY:%s", tag); \
  138. pr_err("[CMDQ][AEE] AEE not READY!!!"); \
  139. pr_err("[CMDQ][AEE]"string, ##args); \
  140. cmdq_core_save_first_dump("[CMDQ][AEE]"string, ##args); \
  141. cmdq_core_turnoff_first_dump(); \
  142. } while (0); \
  143. }
  144. #endif
  145. /*#define CMDQ_PROFILE*/
  146. typedef unsigned long long CMDQ_TIME;
  147. #ifdef CMDQ_PROFILE
  148. #define CMDQ_PROF_INIT() \
  149. { \
  150. do {if (0 < cmdq_core_profile_enabled()) met_tag_init(); } while (0); \
  151. }
  152. #define CMDQ_PROF_START(args...) \
  153. { \
  154. do {if (0 < cmdq_core_profile_enabled()) met_tag_start(args); } while (0); \
  155. }
  156. #define CMDQ_PROF_END(args...) \
  157. { \
  158. do {if (0 < cmdq_core_profile_enabled()) met_tag_end(args); } while (0); \
  159. }
  160. #define CMDQ_PROF_ONESHOT(args...) \
  161. { \
  162. do {if (0 < cmdq_core_profile_enabled()) met_tag_oneshot(args); } while (0); \
  163. }
  164. #else
  165. #define CMDQ_PROF_INIT()
  166. #define CMDQ_PROF_START(args...)
  167. #define CMDQ_PROF_END(args...)
  168. #define CMDQ_PROF_ONESHOT(args...)
  169. #endif
  170. #ifdef CMDQ_PROFILE_MMP
  171. #define CMDQ_PROF_MMP(args...)\
  172. {\
  173. do {if (1) MMProfileLogEx(args); } while (0); \
  174. }
  175. #else
  176. #define CMDQ_PROF_MMP(args...)
  177. #endif
  178. #define CMDQ_GET_TIME_IN_MS(start, end, duration) \
  179. { \
  180. CMDQ_TIME _duration = end - start; \
  181. do_div(_duration, 1000000); \
  182. duration = (int32_t)_duration; \
  183. }
  184. #define CMDQ_GET_TIME_IN_US_PART(start, end, duration) \
  185. { \
  186. CMDQ_TIME _duration = end - start; \
  187. do_div(_duration, 1000); \
  188. duration = (int32_t)_duration; \
  189. }
  190. #define CMDQ_ENG_ISP_GROUP_FLAG(flag) ((flag) & (CMDQ_ENG_ISP_GROUP_BITS))
  191. #define CMDQ_ENG_MDP_GROUP_FLAG(flag) ((flag) & (CMDQ_ENG_MDP_GROUP_BITS))
  192. #define CMDQ_ENG_DISP_GROUP_FLAG(flag) ((flag) & (CMDQ_ENG_DISP_GROUP_BITS))
  193. #define CMDQ_ENG_JPEG_GROUP_FLAG(flag) ((flag) & (CMDQ_ENG_JPEG_GROUP_BITS))
  194. #define CMDQ_ENG_VENC_GROUP_FLAG(flag) ((flag) & (CMDQ_ENG_VENC_GROUP_BITS))
  195. #define CMDQ_ENG_DPE_GROUP_FLAG(flag) ((flag) & (CMDQ_ENG_DPE_GROUP_BITS))
  196. #define GENERATE_ENUM(_enum, _string) _enum,
  197. #define GENERATE_STRING(_enum, _string) (#_string),
  198. #define CMDQ_FOREACH_GROUP(ACTION_struct)\
  199. ACTION_struct(CMDQ_GROUP_ISP, ISP) \
  200. ACTION_struct(CMDQ_GROUP_MDP, MDP) \
  201. ACTION_struct(CMDQ_GROUP_DISP, DISP) \
  202. ACTION_struct(CMDQ_GROUP_JPEG, JPEG) \
  203. ACTION_struct(CMDQ_GROUP_VENC, VENC) \
  204. ACTION_struct(CMDQ_GROUP_DPE, DPE)
  205. typedef enum CMDQ_GROUP_ENUM {
  206. CMDQ_FOREACH_GROUP(GENERATE_ENUM)
  207. CMDQ_MAX_GROUP_COUNT, /* ALWAYS keep at the end */
  208. } CMDQ_GROUP_ENUM;
  209. /* engineFlag are bit fields defined in CMDQ_ENG_ENUM */
  210. typedef int32_t(*CmdqClockOnCB) (uint64_t engineFlag);
  211. /* engineFlag are bit fields defined in CMDQ_ENG_ENUM */
  212. typedef int32_t(*CmdqDumpInfoCB) (uint64_t engineFlag, int level);
  213. /* engineFlag are bit fields defined in CMDQ_ENG_ENUM */
  214. typedef int32_t(*CmdqResetEngCB) (uint64_t engineFlag);
  215. /* engineFlag are bit fields defined in CMDQ_ENG_ENUM */
  216. typedef int32_t(*CmdqClockOffCB) (uint64_t engineFlag);
  217. /* data are user data passed to APIs */
  218. typedef int32_t(*CmdqInterruptCB) (unsigned long data);
  219. /* data are user data passed to APIs */
  220. typedef int32_t(*CmdqAsyncFlushCB) (unsigned long data);
  221. /* resource event can be indicated to resource unit */
  222. typedef int32_t(*CmdqResourceReleaseCB) (CMDQ_EVENT_ENUM resourceEvent);
  223. /* resource event can be indicated to resource unit */
  224. typedef int32_t(*CmdqResourceAvailableCB) (CMDQ_EVENT_ENUM resourceEvent);
  225. /* TaskID is passed down from IOCTL */
  226. /* client should fill "regCount" and "regAddress" */
  227. /* the buffer pointed by (*regAddress) must be valid until */
  228. /* CmdqDebugRegDumpEndCB() is called. */
  229. typedef int32_t(*CmdqDebugRegDumpBeginCB) (uint32_t taskID, uint32_t *regCount,
  230. uint32_t **regAddress);
  231. typedef int32_t(*CmdqDebugRegDumpEndCB) (uint32_t taskID, uint32_t regCount, uint32_t *regValues);
  232. typedef struct CmdqCBkStruct {
  233. CmdqClockOnCB clockOn;
  234. CmdqDumpInfoCB dumpInfo;
  235. CmdqResetEngCB resetEng;
  236. CmdqClockOffCB clockOff;
  237. } CmdqCBkStruct;
  238. typedef struct CmdqDebugCBkStruct {
  239. /* Debug Register Dump */
  240. CmdqDebugRegDumpBeginCB beginDebugRegDump;
  241. CmdqDebugRegDumpEndCB endDebugRegDump;
  242. } CmdqDebugCBkStruct;
  243. typedef enum CMDQ_CODE_ENUM {
  244. /* these are actual HW op code */
  245. CMDQ_CODE_READ = 0x01,
  246. CMDQ_CODE_MOVE = 0x02,
  247. CMDQ_CODE_WRITE = 0x04,
  248. CMDQ_CODE_POLL = 0x08,
  249. CMDQ_CODE_JUMP = 0x10,
  250. CMDQ_CODE_WFE = 0x20, /* wait for event and clear */
  251. CMDQ_CODE_EOC = 0x40, /* end of command */
  252. /* these are pseudo op code defined by SW */
  253. /* for instruction generation */
  254. CMDQ_CODE_SET_TOKEN = 0x21, /* set event */
  255. CMDQ_CODE_WAIT_NO_CLEAR = 0x22, /* wait event, but don't clear it */
  256. CMDQ_CODE_CLEAR_TOKEN = 0x23, /* clear event */
  257. CMDQ_CODE_RAW = 0x24, /* allow entirely custom argA/argB */
  258. CMDQ_CODE_PREFETCH_ENABLE = 0x41, /* enable prefetch marker */
  259. CMDQ_CODE_PREFETCH_DISABLE = 0x42, /* disable prefetch marker */
  260. } CMDQ_CODE_ENUM;
  261. typedef enum CMDQ_LOG_LEVEL_ENUM {
  262. CMDQ_LOG_LEVEL_NORMAL = 0,
  263. CMDQ_LOG_LEVEL_MSG = 1,
  264. CMDQ_LOG_LEVEL_FULL_ERROR = 2,
  265. CMDQ_LOG_LEVEL_EXTENSION = 3,
  266. CMDQ_LOG_LEVEL_MAX /* ALWAYS keep at the end */
  267. } CMDQ_LOG_LEVEL_ENUM;
  268. typedef enum TASK_STATE_ENUM {
  269. TASK_STATE_IDLE, /* free task */
  270. TASK_STATE_BUSY, /* task running on a thread */
  271. TASK_STATE_KILLED, /* task process being killed */
  272. TASK_STATE_ERROR, /* task execution error */
  273. TASK_STATE_ERR_IRQ, /* task execution invalid instruction */
  274. TASK_STATE_DONE, /* task finished */
  275. TASK_STATE_WAITING, /* allocated but waiting for available thread */
  276. } TASK_STATE_ENUM;
  277. #define CMDQ_FEATURE_OFF_VALUE (0)
  278. #define FOREACH_FEATURE(FEATURE) \
  279. FEATURE(CMDQ_FEATURE_SRAM_SHARE, "SRAM Share") \
  280. typedef enum CMDQ_FEATURE_TYPE_ENUM {
  281. FOREACH_FEATURE(GENERATE_ENUM)
  282. CMDQ_FEATURE_TYPE_MAX, /* ALWAYS keep at the end */
  283. } CMDQ_FEATURE_TYPE_ENUM;
  284. #ifdef CMDQ_INSTRUCTION_COUNT
  285. /* GCE instructions count information */
  286. typedef enum CMDQ_STAT_ENUM {
  287. CMDQ_STAT_WRITE = 0,
  288. CMDQ_STAT_WRITE_W_MASK = 1,
  289. CMDQ_STAT_READ = 2,
  290. CMDQ_STAT_POLLING = 3,
  291. CMDQ_STAT_MOVE = 4,
  292. CMDQ_STAT_SYNC = 5,
  293. CMDQ_STAT_PREFETCH_EN = 6,
  294. CMDQ_STAT_PREFETCH_DIS = 7,
  295. CMDQ_STAT_EOC = 8,
  296. CMDQ_STAT_JUMP = 9,
  297. CMDQ_STAT_MAX /* ALWAYS keep at the end */
  298. } CMDQ_STAT_ENUM;
  299. typedef enum CMDQ_MODULE_STAT_ENUM {
  300. CMDQ_MODULE_STAT_MMSYS_CONFIG = 0,
  301. CMDQ_MODULE_STAT_MDP_RDMA = 1,
  302. CMDQ_MODULE_STAT_MDP_RSZ0 = 2,
  303. CMDQ_MODULE_STAT_MDP_RSZ1 = 3,
  304. CMDQ_MODULE_STAT_MDP_WDMA = 4,
  305. CMDQ_MODULE_STAT_MDP_WROT = 5,
  306. CMDQ_MODULE_STAT_MDP_TDSHP = 6,
  307. CMDQ_MODULE_STAT_MM_MUTEX = 7,
  308. CMDQ_MODULE_STAT_VENC = 8,
  309. CMDQ_MODULE_STAT_DISP_OVL0 = 9,
  310. CMDQ_MODULE_STAT_DISP_OVL1 = 10,
  311. CMDQ_MODULE_STAT_DISP_RDMA0 = 11,
  312. CMDQ_MODULE_STAT_DISP_RDMA1 = 12,
  313. CMDQ_MODULE_STAT_DISP_WDMA0 = 13,
  314. CMDQ_MODULE_STAT_DISP_COLOR = 14,
  315. CMDQ_MODULE_STAT_DISP_CCORR = 15,
  316. CMDQ_MODULE_STAT_DISP_AAL = 16,
  317. CMDQ_MODULE_STAT_DISP_GAMMA = 17,
  318. CMDQ_MODULE_STAT_DISP_DITHER = 18,
  319. CMDQ_MODULE_STAT_DISP_UFOE = 19,
  320. CMDQ_MODULE_STAT_DISP_PWM = 20,
  321. CMDQ_MODULE_STAT_DISP_WDMA1 = 21,
  322. CMDQ_MODULE_STAT_DISP_MUTEX = 22,
  323. CMDQ_MODULE_STAT_DISP_DSI0 = 23,
  324. CMDQ_MODULE_STAT_DISP_DPI0 = 24,
  325. CMDQ_MODULE_STAT_DISP_OD = 25,
  326. CMDQ_MODULE_STAT_CAM0 = 26,
  327. CMDQ_MODULE_STAT_CAM1 = 27,
  328. CMDQ_MODULE_STAT_CAM2 = 28,
  329. CMDQ_MODULE_STAT_CAM3 = 29,
  330. CMDQ_MODULE_STAT_SODI = 30,
  331. CMDQ_MODULE_STAT_GPR = 31,
  332. CMDQ_MODULE_STAT_OTHERS = 32,
  333. CMDQ_MODULE_STAT_MAX /* ALWAYS keep at the end */
  334. } CMDQ_MODULE_STAT_ENUM;
  335. typedef enum CMDQ_EVENT_STAT_ENUM {
  336. CMDQ_EVENT_STAT_HW = 0,
  337. CMDQ_EVENT_STAT_SW = 1,
  338. CMDQ_EVENT_STAT_MAX /* ALWAYS keep at the end */
  339. } CMDQ_EVENT_STAT_ENUM;
  340. #define CMDQ_MAX_OTHERINSTRUCTION_MAX (16)
  341. typedef struct CmdqModulePAStatStruct {
  342. long start[CMDQ_MODULE_STAT_MAX];
  343. long end[CMDQ_MODULE_STAT_MAX];
  344. } CmdqModulePAStatStruct;
  345. #endif
  346. typedef struct TaskStruct {
  347. struct list_head listEntry;
  348. /* For buffer state */
  349. TASK_STATE_ENUM taskState; /* task life cycle */
  350. uint32_t *pVABase; /* virtual address of command buffer */
  351. dma_addr_t MVABase; /* physical address of command buffer */
  352. uint32_t bufferSize; /* size of allocated command buffer */
  353. bool useEmergencyBuf; /* is the command buffer emergency buffer? */
  354. /* For execution */
  355. int32_t scenario;
  356. int32_t priority;
  357. uint64_t engineFlag;
  358. int32_t commandSize;
  359. uint32_t *pCMDEnd;
  360. int32_t reorder;
  361. int32_t thread; /* ASYNC: CMDQ_INVALID_THREAD if not running */
  362. int32_t irqFlag; /* ASYNC: flag of IRQ received */
  363. CmdqInterruptCB loopCallback; /* LOOP execution */
  364. unsigned long loopData; /* LOOP execution */
  365. CmdqAsyncFlushCB flushCallback; /* Callback on AsyncFlush (fire-and-forget) tasks */
  366. unsigned long flushData; /* for callbacks & error handling */
  367. struct work_struct autoReleaseWork; /* Work item when auto release is used */
  368. bool useWorkQueue;
  369. /* Output section for "read from reg to mem" */
  370. uint32_t regCount;
  371. uint32_t *regResults;
  372. dma_addr_t regResultsMVA;
  373. /* For register backup */
  374. uint32_t regCountUserSpace; /* this is to separate backup request from user space and kernel space. */
  375. uint32_t regUserToken; /* user data store for callback beginDebugRegDump / endDebugRegDump */
  376. /* For seucre execution */
  377. cmdqSecDataStruct secData;
  378. /* For statistics & debug */
  379. CMDQ_TIME submit; /* ASYNC: task submit time (as soon as task acquired) */
  380. CMDQ_TIME trigger;
  381. CMDQ_TIME beginWait;
  382. CMDQ_TIME gotIRQ;
  383. CMDQ_TIME wakedUp;
  384. CMDQ_TIME entrySec; /* time stamp of entry secure world */
  385. CMDQ_TIME exitSec; /* time stamp of exit secure world */
  386. uint32_t *profileData; /* store GPT counter when it starts and ends */
  387. dma_addr_t profileDataPA;
  388. void *privateData; /* this is used to track associated file handle */
  389. pid_t callerPid;
  390. char callerName[TASK_COMM_LEN];
  391. /* Custom profile marker */
  392. #ifdef CMDQ_PROFILE_MARKER_SUPPORT
  393. cmdqProfileMarkerStruct profileMarker;
  394. #endif
  395. } TaskStruct;
  396. typedef struct EngineStruct {
  397. int32_t userCount;
  398. int32_t currOwner;
  399. int32_t resetCount;
  400. int32_t failCount;
  401. } EngineStruct;
  402. typedef struct ThreadStruct {
  403. uint32_t taskCount;
  404. uint32_t waitCookie;
  405. uint32_t nextCookie;
  406. uint64_t engineFlag; /* keep used engine to look up while dispatch thread */
  407. CmdqInterruptCB loopCallback; /* LOOP execution */
  408. unsigned long loopData; /* LOOP execution */
  409. TaskStruct * pCurTask[CMDQ_MAX_TASK_IN_THREAD];
  410. /* 1 to describe thread is available to dispatch a task. 0: not available */
  411. /* .note thread's taskCount increase when attatch a task to it. */
  412. /* used it to prevent 2 tasks, which uses different engines, */
  413. /* acquire same HW thread when dispatching happened before attaches task to thread */
  414. /* .note it is align task attachment, so use cmdqExecLock to ensure atomic access */
  415. uint32_t allowDispatching;
  416. } ThreadStruct;
  417. typedef struct RecordStruct {
  418. pid_t user; /* calling SW thread tid */
  419. int32_t scenario; /* task scenario */
  420. int32_t priority; /* task priority (not thread priority) */
  421. int32_t thread; /* allocated thread */
  422. int32_t reorder;
  423. int32_t size;
  424. uint32_t writeTimeNS; /* if profile enabled, the time of command execution */
  425. uint64_t engineFlag; /* task engine flag */
  426. bool isSecure; /* true for secure task */
  427. CMDQ_TIME submit; /* epoch time of IOCTL/Kernel API call */
  428. CMDQ_TIME trigger; /* epoch time of enable HW thread */
  429. CMDQ_TIME beginWait; /* epoch time of start waiting for task completion */
  430. CMDQ_TIME gotIRQ; /* epoch time of IRQ event */
  431. CMDQ_TIME wakedUp; /* epoch time of SW thread leaving wait state */
  432. CMDQ_TIME done; /* epoch time of task finish */
  433. unsigned long long writeTimeNSBegin;
  434. unsigned long long writeTimeNSEnd;
  435. /* Custom profile marker */
  436. #ifdef CMDQ_PROFILE_MARKER_SUPPORT
  437. uint32_t profileMarkerCount;
  438. unsigned long long profileMarkerTimeNS[CMDQ_MAX_PROFILE_MARKER_IN_TASK];
  439. const char *profileMarkerTag[CMDQ_MAX_PROFILE_MARKER_IN_TASK];
  440. #endif
  441. /* GCE instructions count information */
  442. #ifdef CMDQ_INSTRUCTION_COUNT
  443. unsigned short instructionStat[CMDQ_STAT_MAX];
  444. unsigned short writeModule[CMDQ_MODULE_STAT_MAX];
  445. unsigned short writewmaskModule[CMDQ_MODULE_STAT_MAX];
  446. unsigned short readModlule[CMDQ_MODULE_STAT_MAX];
  447. unsigned short pollModule[CMDQ_MODULE_STAT_MAX];
  448. unsigned short eventCount[CMDQ_EVENT_STAT_MAX];
  449. uint32_t otherInstr[CMDQ_MAX_OTHERINSTRUCTION_MAX];
  450. uint32_t otherInstrNUM;
  451. #endif
  452. } RecordStruct;
  453. typedef struct ErrorStruct {
  454. RecordStruct errorRec; /* the record of the error task */
  455. u64 ts_nsec; /* kernel time of attach_error_task */
  456. } ErrorStruct;
  457. typedef struct WriteAddrStruct {
  458. struct list_head list_node;
  459. uint32_t count;
  460. void *va;
  461. dma_addr_t pa;
  462. pid_t user;
  463. } WriteAddrStruct;
  464. typedef struct EmergencyBufferStruct {
  465. bool used;
  466. uint32_t size;
  467. void *va;
  468. dma_addr_t pa;
  469. } EmergencyBufferStruct;
  470. /**
  471. * shared memory between normal and secure world
  472. */
  473. typedef struct cmdqSecSharedMemoryStruct {
  474. void *pVABase; /* virtual address of command buffer */
  475. dma_addr_t MVABase; /* physical address of command buffer */
  476. uint32_t size; /* buffer size */
  477. } cmdqSecSharedMemoryStruct, *cmdqSecSharedMemoryHandle;
  478. /**
  479. * resource unit between each module
  480. */
  481. typedef struct ResourceUnitStruct {
  482. struct list_head listEntry;
  483. CMDQ_TIME notify; /* notify time from module prepare */
  484. CMDQ_TIME lock; /* lock time from module lock */
  485. CMDQ_TIME unlock; /* unlock time from module unlock*/
  486. CMDQ_TIME delay; /* delay start time from module release*/
  487. CMDQ_TIME acquire; /* acquire time from module acquire */
  488. CMDQ_TIME release; /* release time from module release */
  489. bool used; /* indicate resource is in use or not */
  490. bool delaying; /* indicate resource is in delay check or not */
  491. CMDQ_EVENT_ENUM lockEvent; /* SW token to lock in GCE thread */
  492. uint64_t engine; /* which engine is resource */
  493. CmdqResourceAvailableCB availableCB;
  494. CmdqResourceReleaseCB releaseCB;
  495. struct delayed_work delayCheckWork; /* Delay Work item when delay check is used */
  496. } ResourceUnitStruct;
  497. typedef struct ContextStruct {
  498. /* Task information */
  499. struct kmem_cache *taskCache; /* TaskStruct object cache */
  500. struct list_head taskFreeList; /* Unused free tasks */
  501. struct list_head taskActiveList; /* Active tasks */
  502. struct list_head taskWaitList; /* Tasks waiting for available thread */
  503. struct work_struct taskConsumeWaitQueueItem;
  504. struct workqueue_struct *taskAutoReleaseWQ; /* auto-release workqueue */
  505. struct workqueue_struct *taskConsumeWQ; /* task consumption workqueue (for queued tasks) */
  506. struct workqueue_struct *resourceCheckWQ; /* delay resource check workqueue */
  507. /* Write Address management */
  508. struct list_head writeAddrList;
  509. /* Basic information */
  510. EngineStruct engine[CMDQ_MAX_ENGINE_COUNT];
  511. ThreadStruct thread[CMDQ_MAX_THREAD_COUNT];
  512. /* auto-release workqueue per thread */
  513. struct workqueue_struct *taskThreadAutoReleaseWQ[CMDQ_MAX_THREAD_COUNT];
  514. /* Secure path shared information */
  515. cmdqSecSharedMemoryHandle hSecSharedMem;
  516. void *hNotifyLoop;
  517. /* Profile information */
  518. int32_t enableProfile;
  519. int32_t lastID;
  520. int32_t recNum;
  521. RecordStruct record[CMDQ_MAX_RECORD_COUNT];
  522. /* Error information */
  523. int32_t logLevel;
  524. int32_t errNum;
  525. ErrorStruct error[CMDQ_MAX_ERROR_COUNT];
  526. /* feature option information */
  527. uint32_t features[CMDQ_FEATURE_TYPE_MAX];
  528. /* Resource manager information */
  529. struct list_head resourceList; /* all resource list */
  530. #ifdef CMDQ_INSTRUCTION_COUNT
  531. /* GCE instructions count information */
  532. int32_t instructionCountLevel;
  533. #endif
  534. } ContextStruct;
  535. /* Command dump information */
  536. typedef struct DumpCommandBufferStruct {
  537. uint64_t scenario;
  538. uint32_t bufferSize;
  539. uint32_t count;
  540. char *cmdqString;
  541. } DumpCommandBufferStruct;
  542. #ifdef __cplusplus
  543. extern "C" {
  544. #endif
  545. void cmdqCoreInitGroupCB(void);
  546. void cmdqCoreDeinitGroupCB(void);
  547. int32_t cmdqCoreRegisterCB(CMDQ_GROUP_ENUM engGroup,
  548. CmdqClockOnCB clockOn,
  549. CmdqDumpInfoCB dumpInfo,
  550. CmdqResetEngCB resetEng, CmdqClockOffCB clockOff);
  551. int32_t cmdqCoreRegisterDebugRegDumpCB(CmdqDebugRegDumpBeginCB beginCB,
  552. CmdqDebugRegDumpEndCB endCB);
  553. int32_t cmdqCoreSuspend(void);
  554. int32_t cmdqCoreResume(void);
  555. int32_t cmdqCoreResumedNotifier(void);
  556. void cmdqCoreHandleIRQ(int32_t index);
  557. /**
  558. * Wait for completion of the given CmdQ task
  559. *
  560. * Parameter:
  561. * scenario: The Scnerio enumeration
  562. * priority: Desied task priority
  563. * engineFlag: HW engine involved in the CMDs
  564. * pCMDBlock: The command buffer
  565. * blockSize: Size of the command buffer
  566. * ppTaskOut: output pointer to a pTask for the resulting task
  567. * if fail, this gives NULL
  568. * loopCB: Assign this CB if your command loops itself.
  569. * since this disables thread completion handling, do not set this CB
  570. * if it is not intended to be a HW looping thread.
  571. * loopData: The user data passed to loopCB
  572. *
  573. * Return:
  574. * >=0 for success; else the error code is returned
  575. */
  576. int32_t cmdqCoreSubmitTaskAsync(cmdqCommandStruct *pCommandDesc,
  577. CmdqInterruptCB loopCB,
  578. unsigned long loopData, TaskStruct **ppTaskOut);
  579. /**
  580. * Wait for completion of the given CmdQ task
  581. *
  582. * Parameter:
  583. * pTask: Task returned from successful cmdqCoreSubmitTaskAsync
  584. * additional cleanup will be performed.
  585. *
  586. * timeout: SW timeout error will be generated after this threshold
  587. * Return:
  588. * >=0 for success; else the error code is returned
  589. */
  590. int32_t cmdqCoreWaitAndReleaseTask(TaskStruct *pTask, long timeout_jiffies);
  591. /**
  592. * Wait for completion of the given CmdQ task, and retrieve
  593. * read register result.
  594. *
  595. * Parameter:
  596. * pTask: Task returned from successful cmdqCoreSubmitTaskAsync
  597. * additional cleanup will be performed.
  598. *
  599. * timeout: SW timeout error will be generated after this threshold
  600. * Return:
  601. * >=0 for success; else the error code is returned
  602. */
  603. int32_t cmdqCoreWaitResultAndReleaseTask(TaskStruct *pTask, cmdqRegValueStruct *pResult,
  604. long timeout_jiffies);
  605. /**
  606. * Stop task and release it immediately
  607. *
  608. * Parameter:
  609. * pTask: Task returned from successful cmdqCoreSubmitTaskAsync
  610. * additional cleanup will be performed.
  611. *
  612. * Return:
  613. * >=0 for success; else the error code is returned
  614. */
  615. int32_t cmdqCoreReleaseTask(TaskStruct *pTask);
  616. /**
  617. * Register the task in the auto-release queue. It will be released
  618. * upon finishing. You MUST NOT perform further operations on this task.
  619. *
  620. * Parameter:
  621. * pTask: Task returned from successful cmdqCoreSubmitTaskAsync.
  622. * additional cleanup will be performed.
  623. * Return:
  624. * >=0 for success; else the error code is returned
  625. */
  626. int32_t cmdqCoreAutoReleaseTask(TaskStruct *pTask);
  627. /**
  628. * Create CMDQ Task and block wait for its completion
  629. *
  630. * Return:
  631. * >=0 for success; else the error code is returned
  632. */
  633. int32_t cmdqCoreSubmitTask(cmdqCommandStruct *pCommandDesc);
  634. /**
  635. * Helper function checking validity of a task pointer
  636. *
  637. * Return:
  638. * false if NOT a valid pointer
  639. * true if valid
  640. */
  641. bool cmdqIsValidTaskPtr(void *pTask);
  642. /**
  643. * Immediately clear CMDQ event to 0 with CPU
  644. *
  645. */
  646. void cmdqCoreClearEvent(CMDQ_EVENT_ENUM event);
  647. /**
  648. * Immediately set CMDQ event to 1 with CPU
  649. *
  650. */
  651. void cmdqCoreSetEvent(CMDQ_EVENT_ENUM event);
  652. /**
  653. * Get event value with CPU. This is for debug purpose only
  654. * since it does not guarantee atomicity.
  655. *
  656. */
  657. uint32_t cmdqCoreGetEvent(CMDQ_EVENT_ENUM event);
  658. int32_t cmdqCoreInitialize(void);
  659. #ifdef CMDQ_SECURE_PATH_SUPPORT
  660. int32_t cmdqCoreLateInitialize(void);
  661. #endif
  662. void cmdqCoreDeInitialize(void);
  663. /**
  664. * Allocate/Free HW use buffer, e.g. command buffer forCMDQ HW
  665. */
  666. void *cmdq_core_alloc_hw_buffer(struct device *dev, size_t size, dma_addr_t *dma_handle,
  667. const gfp_t flag);
  668. void cmdq_core_free_hw_buffer(struct device *dev, size_t size, void *cpu_addr,
  669. dma_addr_t dma_handle);
  670. cmdqSecSharedMemoryHandle cmdq_core_get_secure_shared_memory(void);
  671. /*
  672. * GCE capability
  673. */
  674. uint32_t cmdq_core_subsys_to_reg_addr(uint32_t argA);
  675. const char *cmdq_core_parse_subsys_from_reg_addr(uint32_t reg_addr);
  676. int32_t cmdq_core_subsys_from_phys_addr(uint32_t physAddr);
  677. int32_t cmdq_core_suspend_HW_thread(int32_t thread, uint32_t lineNum);
  678. /**
  679. * Event
  680. */
  681. void cmdq_core_reset_hw_events(void);
  682. /**
  683. * Get and HW information from device tree
  684. */
  685. void cmdq_core_init_DTS_data(void);
  686. cmdqDTSDataStruct *cmdq_core_get_whole_DTS_Data(void);
  687. /**
  688. * Get and set HW event form device tree
  689. */
  690. void cmdq_core_set_event_table(CMDQ_EVENT_ENUM event, const int32_t value);
  691. int32_t cmdq_core_get_event_value(CMDQ_EVENT_ENUM event);
  692. const char *cmdq_core_get_event_name_ENUM(CMDQ_EVENT_ENUM event);
  693. const char *cmdq_core_get_event_name(CMDQ_EVENT_ENUM event);
  694. /**
  695. * Utilities
  696. */
  697. void cmdq_core_set_log_level(const int32_t value);
  698. ssize_t cmdqCorePrintLogLevel(struct device *dev, struct device_attribute *attr, char *buf);
  699. ssize_t cmdqCoreWriteLogLevel(struct device *dev,
  700. struct device_attribute *attr, const char *buf, size_t size);
  701. ssize_t cmdqCorePrintProfileEnable(struct device *dev, struct device_attribute *attr,
  702. char *buf);
  703. ssize_t cmdqCoreWriteProfileEnable(struct device *dev, struct device_attribute *attr,
  704. const char *buf, size_t size);
  705. void cmdq_core_dump_secure_metadata(cmdqSecDataStruct *pSecData);
  706. int32_t cmdqCoreDebugRegDumpBegin(uint32_t taskID, uint32_t *regCount,
  707. uint32_t **regAddress);
  708. int32_t cmdqCoreDebugRegDumpEnd(uint32_t taskID, uint32_t regCount, uint32_t *regValues);
  709. int32_t cmdqCoreDebugDumpCommand(TaskStruct *pTask);
  710. int32_t cmdqCoreQueryUsage(int32_t *pCount);
  711. int cmdqCorePrintRecordSeq(struct seq_file *m, void *v);
  712. int cmdqCorePrintErrorSeq(struct seq_file *m, void *v);
  713. int cmdqCorePrintStatusSeq(struct seq_file *m, void *v);
  714. ssize_t cmdqCorePrintRecord(struct device *dev, struct device_attribute *attr, char *buf);
  715. ssize_t cmdqCorePrintError(struct device *dev, struct device_attribute *attr, char *buf);
  716. ssize_t cmdqCorePrintStatus(struct device *dev, struct device_attribute *attr, char *buf);
  717. void cmdq_core_fix_command_scenario_for_user_space(cmdqCommandStruct *pCommand);
  718. bool cmdq_core_is_request_from_user_space(const CMDQ_SCENARIO_ENUM scenario);
  719. unsigned long long cmdq_core_get_GPR64(const CMDQ_DATA_REGISTER_ENUM regID);
  720. void cmdq_core_set_GPR64(const CMDQ_DATA_REGISTER_ENUM regID,
  721. const unsigned long long value);
  722. uint32_t cmdqCoreReadDataRegister(CMDQ_DATA_REGISTER_ENUM regID);
  723. int cmdqCoreAllocWriteAddress(uint32_t count, dma_addr_t *paStart);
  724. int cmdqCoreFreeWriteAddress(dma_addr_t paStart);
  725. uint32_t cmdqCoreReadWriteAddress(dma_addr_t pa);
  726. uint32_t cmdqCoreWriteWriteAddress(dma_addr_t pa, uint32_t value);
  727. int32_t cmdq_core_profile_enabled(void);
  728. bool cmdq_core_should_print_msg(void);
  729. bool cmdq_core_should_full_error(void);
  730. int32_t cmdq_core_enable_emergency_buffer_test(const bool enable);
  731. int32_t cmdq_core_parse_instruction(const uint32_t *pCmd, char *textBuf, int bufLen);
  732. void cmdq_core_add_consume_task(void);
  733. /* file_node is a pointer to cmdqFileNodeStruct that is */
  734. /* created when opening the device file. */
  735. void cmdq_core_release_task_by_file_node(void *file_node);
  736. void cmdq_core_longstring_init(char *buf, uint32_t *offset, int32_t *maxSize);
  737. void cmdqCoreLongString(bool forceLog, char *buf, uint32_t *offset, int32_t *maxSize,
  738. const char *string, ...);
  739. /* Command Buffer Dump */
  740. void cmdq_core_set_command_buffer_dump(int32_t scenario, int32_t bufferSize);
  741. /* test case initialization */
  742. void cmdq_test_init_setting(void);
  743. #ifdef CMDQ_INSTRUCTION_COUNT
  744. CmdqModulePAStatStruct *cmdq_core_Initial_and_get_module_stat(void);
  745. ssize_t cmdqCorePrintInstructionCountLevel(struct device *dev,
  746. struct device_attribute *attr, char *buf);
  747. ssize_t cmdqCoreWriteInstructionCountLevel(struct device *dev,
  748. struct device_attribute *attr, const char *buf,
  749. size_t size);
  750. void cmdq_core_set_instruction_count_level(const int32_t value);
  751. int cmdqCorePrintInstructionCountSeq(struct seq_file *m, void *v);
  752. #endif /* CMDQ_INSTRUCTION_COUNT */
  753. #ifdef CMDQ_DUMP_FIRSTERROR
  754. /**
  755. * Save first error dump
  756. */
  757. void cmdq_core_turnoff_first_dump(void);
  758. /**
  759. * cmdq_core_save_first_dump - save a CMDQ first error dump to file
  760. */
  761. int32_t cmdq_core_save_first_dump(const char *string, ...);
  762. /**
  763. * cmdq_core_save_hex_first_dump - save a CMDQ first error hex dump to file
  764. * @prefix_str: string to prefix each line with;
  765. * caller supplies trailing spaces for alignment if desired
  766. * @rowsize: number of bytes to print per line; must be 16 or 32
  767. * @groupsize: number of bytes to print at a time (1, 2, 4, 8; default = 1)
  768. * @buf: data blob to dump
  769. * @len: number of bytes in the @buf
  770. *
  771. * Given a buffer of u8 data, cmdq_core_save_hex_first_dump() save a CMDQ first error hex dump
  772. * to the file , with an optional leading prefix.
  773. *
  774. * cmdq_core_save_hex_first_dump() works on one "line" of output at a time, i.e.,
  775. * 16 or 32 bytes of input data converted to hex.
  776. * cmdq_core_save_hex_first_dump() iterates over the entire input @buf, breaking it into
  777. * "line size" chunks to format and print.
  778. *
  779. * E.g.:
  780. * cmdq_core_save_hex_first_dump("", 16, 4,
  781. * pTask->pVABase, (pTask->commandSize));
  782. *
  783. * Example output using 4-byte mode:
  784. * ed7e4510: ff7fffff 02000000 00800000 0804401d
  785. * ed7e4520: fffffffe 02000000 00000001 04044001
  786. * ed7e4530: 80008001 20000043
  787. */
  788. void cmdq_core_save_hex_first_dump(const char *prefix_str,
  789. int rowsize, int groupsize, const void *buf, size_t len);
  790. #endif /* CMDQ_DUMP_FIRSTERROR */
  791. void cmdqCoreLockResource(uint64_t engineFlag, bool fromNotify);
  792. bool cmdqCoreAcquireResource(CMDQ_EVENT_ENUM resourceEvent);
  793. void cmdqCoreReleaseResource(CMDQ_EVENT_ENUM resourceEvent);
  794. void cmdqCoreSetResourceCallback(CMDQ_EVENT_ENUM resourceEvent,
  795. CmdqResourceAvailableCB resourceAvailable,
  796. CmdqResourceReleaseCB resourceRelease);
  797. void cmdq_core_dump_dts_setting(void);
  798. uint32_t cmdq_core_thread_prefetch_size(const int32_t thread);
  799. void cmdq_core_dump_feature(void);
  800. void cmdq_core_set_feature(CMDQ_FEATURE_TYPE_ENUM featureOption, uint32_t value);
  801. uint32_t cmdq_core_get_feature(CMDQ_FEATURE_TYPE_ENUM featureOption);
  802. bool cmdq_core_is_feature_off(CMDQ_FEATURE_TYPE_ENUM featureOption);
  803. #ifdef __cplusplus
  804. }
  805. #endif
  806. #endif /* __CMDQ_CORE_H__ */