cmdq_test.c 97 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647264826492650265126522653265426552656265726582659266026612662266326642665266626672668266926702671267226732674267526762677267826792680268126822683268426852686268726882689269026912692269326942695269626972698269927002701270227032704270527062707270827092710271127122713271427152716271727182719272027212722272327242725272627272728272927302731273227332734273527362737273827392740274127422743274427452746274727482749275027512752275327542755275627572758275927602761276227632764276527662767276827692770277127722773277427752776277727782779278027812782278327842785278627872788278927902791279227932794279527962797279827992800280128022803280428052806280728082809281028112812281328142815281628172818281928202821282228232824282528262827282828292830283128322833283428352836283728382839284028412842284328442845284628472848284928502851285228532854285528562857285828592860286128622863286428652866286728682869287028712872287328742875287628772878287928802881288228832884288528862887288828892890289128922893289428952896289728982899290029012902290329042905290629072908290929102911291229132914291529162917291829192920292129222923292429252926292729282929293029312932293329342935293629372938293929402941294229432944294529462947294829492950295129522953295429552956295729582959296029612962296329642965296629672968296929702971297229732974297529762977297829792980298129822983298429852986298729882989299029912992299329942995299629972998299930003001300230033004300530063007300830093010301130123013301430153016301730183019302030213022302330243025302630273028302930303031303230333034303530363037303830393040304130423043304430453046304730483049305030513052305330543055305630573058305930603061306230633064306530663067306830693070307130723073307430753076307730783079308030813082308330843085308630873088308930903091309230933094309530963097309830993100310131023103310431053106310731083109311031113112311331143115311631173118311931203121312231233124312531263127312831293130313131323133313431353136313731383139314031413142314331443145314631473148314931503151315231533154315531563157315831593160316131623163316431653166316731683169317031713172317331743175317631773178317931803181318231833184318531863187318831893190319131923193319431953196319731983199320032013202320332043205320632073208320932103211321232133214321532163217321832193220322132223223322432253226322732283229323032313232323332343235323632373238323932403241324232433244324532463247324832493250325132523253325432553256325732583259326032613262326332643265326632673268326932703271327232733274327532763277327832793280328132823283328432853286328732883289329032913292329332943295329632973298329933003301330233033304330533063307330833093310331133123313331433153316331733183319332033213322332333243325332633273328332933303331333233333334333533363337333833393340334133423343334433453346334733483349335033513352335333543355335633573358335933603361336233633364336533663367336833693370337133723373337433753376337733783379338033813382338333843385338633873388338933903391339233933394339533963397339833993400340134023403340434053406340734083409341034113412341334143415341634173418341934203421342234233424342534263427342834293430343134323433343434353436343734383439344034413442344334443445344634473448344934503451345234533454345534563457345834593460346134623463346434653466346734683469347034713472347334743475347634773478347934803481348234833484348534863487348834893490349134923493349434953496349734983499350035013502350335043505350635073508350935103511351235133514351535163517351835193520352135223523352435253526352735283529353035313532353335343535353635373538353935403541354235433544354535463547354835493550355135523553355435553556355735583559356035613562356335643565356635673568356935703571357235733574357535763577357835793580358135823583358435853586358735883589359035913592359335943595359635973598359936003601
  1. #include <linux/kernel.h>
  2. #include <linux/module.h>
  3. #include <linux/fs.h>
  4. #include <linux/proc_fs.h>
  5. #include <linux/timer.h>
  6. #include <linux/workqueue.h>
  7. #include <linux/dma-mapping.h>
  8. #include <linux/uaccess.h>
  9. #include <linux/kthread.h>
  10. #include <linux/delay.h>
  11. #include "cmdq_record_private.h"
  12. #include "cmdq_reg.h"
  13. #include "cmdq_virtual.h"
  14. #include "cmdq_mdp_common.h"
  15. #include "cmdq_device.h"
  16. #ifndef CMDQ_USE_CCF
  17. #include <mach/mt_clkmgr.h>
  18. #endif /* !defined(CMDQ_USE_CCF) */
  19. #define CMDQ_TEST
  20. #ifdef CMDQ_TEST
  21. #define CMDQ_TESTCASE_PARAMETER_MAX 4
  22. #define CMDQ_MONITOR_EVENT_MAX 10
  23. /* test configuration */
  24. static DEFINE_MUTEX(gCmdqTestProcLock);
  25. typedef enum CMDQ_TEST_TYPE_ENUM {
  26. CMDQ_TEST_TYPE_NORMAL = 0,
  27. CMDQ_TEST_TYPE_SECURE = 1,
  28. CMDQ_TEST_TYPE_MONITOR_EVENT = 2,
  29. CMDQ_TEST_TYPE_MONITOR_POLL = 3,
  30. CMDQ_TEST_TYPE_OPEN_COMMAND_DUMP = 4,
  31. CMDQ_TEST_TYPE_DUMP_DTS = 5,
  32. CMDQ_TEST_TYPE_FEATURE_CONFIG = 6,
  33. CMDQ_TEST_TYPE_MAX /* ALWAYS keep at the end */
  34. } CMDQ_TEST_TYPE_ENUM;
  35. typedef enum CMDQ_MOITOR_TYPE_ENUM {
  36. CMDQ_MOITOR_TYPE_FLUSH = 0,
  37. CMDQ_MOITOR_TYPE_WFE = 1, /* wait for event and clear */
  38. CMDQ_MOITOR_TYPE_WAIT_NO_CLEAR = 2,
  39. CMDQ_MOITOR_TYPE_QUERYREGISTER = 3,
  40. CMDQ_MOITOR_TYPE_MAX /* ALWAYS keep at the end */
  41. } CMDQ_MOITOR_TYPE_ENUM;
  42. typedef struct cmdqMonitorEventStruct {
  43. bool status;
  44. cmdqRecHandle cmdqHandle;
  45. cmdqBackupSlotHandle slotHandle;
  46. uint32_t monitorNUM;
  47. uint32_t waitType[CMDQ_MONITOR_EVENT_MAX];
  48. uint64_t monitorEvent[CMDQ_MONITOR_EVENT_MAX];
  49. uint32_t previousValue[CMDQ_MONITOR_EVENT_MAX];
  50. } cmdqMonitorEventStruct;
  51. typedef struct cmdqMonitorPollStruct {
  52. bool status;
  53. cmdqRecHandle cmdqHandle;
  54. cmdqBackupSlotHandle slotHandle;
  55. uint64_t pollReg;
  56. uint64_t pollValue;
  57. uint64_t pollMask;
  58. uint32_t delayTime;
  59. struct delayed_work delayContinueWork;
  60. } cmdqMonitorPollStruct;
  61. static int64_t gCmdqTestConfig[CMDQ_MONITOR_EVENT_MAX];
  62. static bool gCmdqTestSecure;
  63. static cmdqMonitorEventStruct gEventMonitor;
  64. static cmdqMonitorPollStruct gPollMonitor;
  65. #ifdef _CMDQ_TEST_PROC_
  66. static struct proc_dir_entry *gCmdqTestProcEntry;
  67. #endif
  68. static int32_t _test_submit_async(cmdqRecHandle handle, TaskStruct **ppTask)
  69. {
  70. cmdqCommandStruct desc = {
  71. .scenario = handle->scenario,
  72. .priority = handle->priority,
  73. .engineFlag = handle->engineFlag,
  74. .pVABase = (cmdqU32Ptr_t) (unsigned long)handle->pBuffer,
  75. .blockSize = handle->blockSize,
  76. };
  77. /* secure path */
  78. cmdq_rec_setup_sec_data_of_command_desc_by_rec_handle(&desc, handle);
  79. /* profile marker */
  80. cmdq_rec_setup_profile_marker_data(&desc, handle);
  81. return cmdqCoreSubmitTaskAsync(&desc, NULL, 0, ppTask);
  82. }
  83. static void testcase_scenario(void)
  84. {
  85. cmdqRecHandle hRec;
  86. int32_t ret;
  87. int i = 0;
  88. CMDQ_MSG("%s\n", __func__);
  89. /* make sure each scenario runs properly with empty commands */
  90. for (i = 0; i < CMDQ_MAX_SCENARIO_COUNT; ++i) {
  91. if (cmdq_core_is_request_from_user_space(i))
  92. continue;
  93. CMDQ_MSG("testcase_scenario id:%d\n", i);
  94. cmdqRecCreate((CMDQ_SCENARIO_ENUM) i, &hRec);
  95. cmdqRecReset(hRec);
  96. cmdqRecSetSecure(hRec, false);
  97. ret = cmdqRecFlush(hRec);
  98. }
  99. cmdqRecDestroy(hRec);
  100. CMDQ_MSG("%s END\n", __func__);
  101. }
  102. static struct timer_list timer;
  103. static void _testcase_sync_token_timer_func(unsigned long data)
  104. {
  105. CMDQ_MSG("%s\n", __func__);
  106. /* trigger sync event */
  107. CMDQ_MSG("trigger event=0x%08lx\n", (1L << 16) | data);
  108. CMDQ_REG_SET32(CMDQ_SYNC_TOKEN_UPD, (1L << 16) | data);
  109. }
  110. static void _testcase_sync_token_timer_loop_func(unsigned long data)
  111. {
  112. CMDQ_MSG("%s\n", __func__);
  113. /* trigger sync event */
  114. CMDQ_MSG("trigger event=0x%08lx\n", (1L << 16) | data);
  115. CMDQ_REG_SET32(CMDQ_SYNC_TOKEN_UPD, (1L << 16) | data);
  116. /* repeate timeout until user delete it */
  117. mod_timer(&timer, jiffies + msecs_to_jiffies(10));
  118. }
  119. static void testcase_sync_token(void)
  120. {
  121. cmdqRecHandle hRec;
  122. int32_t ret = 0;
  123. CMDQ_MSG("%s\n", __func__);
  124. cmdqRecCreate(CMDQ_SCENARIO_SUB_DISP, &hRec);
  125. do {
  126. cmdqRecReset(hRec);
  127. cmdqRecSetSecure(hRec, gCmdqTestSecure);
  128. /* setup timer to trigger sync token */
  129. setup_timer(&timer, &_testcase_sync_token_timer_func, CMDQ_SYNC_TOKEN_USER_0);
  130. mod_timer(&timer, jiffies + msecs_to_jiffies(1000));
  131. /* wait for sync token */
  132. cmdqRecWait(hRec, CMDQ_SYNC_TOKEN_USER_0);
  133. CMDQ_MSG("start waiting\n");
  134. ret = cmdqRecFlush(hRec);
  135. CMDQ_MSG("waiting done\n");
  136. /* clear token */
  137. CMDQ_REG_SET32(CMDQ_SYNC_TOKEN_UPD, CMDQ_SYNC_TOKEN_USER_0);
  138. del_timer(&timer);
  139. } while (0);
  140. CMDQ_MSG("%s, timeout case\n", __func__);
  141. /* */
  142. /* test for timeout */
  143. /* */
  144. do {
  145. cmdqRecReset(hRec);
  146. cmdqRecSetSecure(hRec, gCmdqTestSecure);
  147. /* wait for sync token */
  148. cmdqRecWait(hRec, CMDQ_SYNC_TOKEN_USER_0);
  149. CMDQ_MSG("start waiting\n");
  150. ret = cmdqRecFlush(hRec);
  151. CMDQ_MSG("waiting done\n");
  152. /* clear token */
  153. CMDQ_REG_SET32(CMDQ_SYNC_TOKEN_UPD, CMDQ_SYNC_TOKEN_USER_0);
  154. BUG_ON(ret >= 0);
  155. } while (0);
  156. cmdqRecDestroy(hRec);
  157. CMDQ_MSG("%s END\n", __func__);
  158. }
  159. static struct timer_list timer_reqA;
  160. static struct timer_list timer_reqB;
  161. static void testcase_async_suspend_resume(void)
  162. {
  163. cmdqRecHandle hReqA;
  164. TaskStruct *pTaskA;
  165. int32_t ret = 0;
  166. CMDQ_MSG("%s\n", __func__);
  167. /* setup timer to trigger sync token */
  168. /* setup_timer(&timer_reqA, &_testcase_sync_token_timer_func, CMDQ_SYNC_TOKEN_USER_0); */
  169. /* mod_timer(&timer_reqA, jiffies + msecs_to_jiffies(300)); */
  170. CMDQ_REG_SET32(CMDQ_SYNC_TOKEN_UPD, CMDQ_SYNC_TOKEN_USER_0);
  171. do {
  172. /* let this thread wait for user token, then finish */
  173. cmdqRecCreate(CMDQ_SCENARIO_PRIMARY_ALL, &hReqA);
  174. cmdqRecReset(hReqA);
  175. cmdqRecSetSecure(hReqA, gCmdqTestSecure);
  176. cmdqRecWait(hReqA, CMDQ_SYNC_TOKEN_USER_0);
  177. cmdq_append_command(hReqA, CMDQ_CODE_EOC, 0, 1);
  178. cmdq_append_command(hReqA, CMDQ_CODE_JUMP, 0, 8);
  179. ret = _test_submit_async(hReqA, &pTaskA);
  180. CMDQ_MSG("%s pTask %p, engine:0x%llx, scenario:%d\n",
  181. __func__, pTaskA, pTaskA->engineFlag, pTaskA->scenario);
  182. CMDQ_MSG("%s start suspend+resume thread 0========\n", __func__);
  183. cmdq_core_suspend_HW_thread(0, __LINE__);
  184. CMDQ_REG_SET32(CMDQ_THR_SUSPEND_TASK(0), 0x00); /* resume */
  185. CMDQ_REG_SET32(CMDQ_SYNC_TOKEN_UPD, (1L << 16) | CMDQ_SYNC_TOKEN_USER_0);
  186. msleep_interruptible(500);
  187. CMDQ_MSG("%s start wait A========\n", __func__);
  188. ret = cmdqCoreWaitAndReleaseTask(pTaskA, 500);
  189. } while (0);
  190. /* clear token */
  191. CMDQ_REG_SET32(CMDQ_SYNC_TOKEN_UPD, CMDQ_SYNC_TOKEN_USER_0);
  192. cmdqRecDestroy(hReqA);
  193. /* del_timer(&timer_reqA); */
  194. CMDQ_MSG("%s END\n", __func__);
  195. }
  196. static void testcase_errors(void)
  197. {
  198. cmdqRecHandle hReq;
  199. cmdqRecHandle hLoop;
  200. TaskStruct *pTask;
  201. int32_t ret;
  202. const unsigned long MMSYS_DUMMY_REG = CMDQ_TEST_MMSYS_DUMMY_VA;
  203. const uint32_t UNKNOWN_OP = 0x50;
  204. uint32_t *pCommand;
  205. ret = 0;
  206. do {
  207. /* SW timeout */
  208. CMDQ_MSG("%s line:%d\n", __func__, __LINE__);
  209. cmdqRecCreate(CMDQ_SCENARIO_TRIGGER_LOOP, &hLoop);
  210. cmdqRecReset(hLoop);
  211. cmdqRecSetSecure(hLoop, false);
  212. cmdqRecPoll(hLoop, CMDQ_TEST_MMSYS_DUMMY_PA, 1, 0xFFFFFFFF);
  213. cmdqRecStartLoop(hLoop);
  214. CMDQ_MSG("=============== INIFINITE Wait ===================\n");
  215. cmdqCoreClearEvent(CMDQ_EVENT_MDP_RSZ0_EOF);
  216. cmdqRecCreate(CMDQ_SCENARIO_PRIMARY_DISP, &hReq);
  217. /* turn on ALL engine flag to test dump */
  218. for (ret = 0; ret < CMDQ_MAX_ENGINE_COUNT; ++ret)
  219. hReq->engineFlag |= 1LL << ret;
  220. cmdqRecReset(hReq);
  221. cmdqRecSetSecure(hReq, gCmdqTestSecure);
  222. cmdqRecWait(hReq, CMDQ_EVENT_MDP_RSZ0_EOF);
  223. cmdqRecFlush(hReq);
  224. CMDQ_MSG("=============== INIFINITE JUMP ===================\n");
  225. /* HW timeout */
  226. CMDQ_MSG("%s line:%d\n", __func__, __LINE__);
  227. cmdqCoreClearEvent(CMDQ_EVENT_MDP_RSZ0_EOF);
  228. cmdqRecReset(hReq);
  229. cmdqRecSetSecure(hReq, gCmdqTestSecure);
  230. cmdqRecWait(hReq, CMDQ_EVENT_MDP_RSZ0_EOF);
  231. cmdq_append_command(hReq, CMDQ_CODE_JUMP, 0, 8); /* JUMP to connect tasks */
  232. ret = _test_submit_async(hReq, &pTask);
  233. msleep_interruptible(500);
  234. ret = cmdqCoreWaitAndReleaseTask(pTask, 8000);
  235. CMDQ_MSG("================ POLL INIFINITE ====================\n");
  236. CMDQ_MSG("testReg: %lx\n", MMSYS_DUMMY_REG);
  237. CMDQ_REG_SET32(MMSYS_DUMMY_REG, 0x0);
  238. cmdqRecReset(hReq);
  239. cmdqRecSetSecure(hReq, gCmdqTestSecure);
  240. cmdqRecPoll(hReq, CMDQ_TEST_MMSYS_DUMMY_PA, 1, 0xFFFFFFFF);
  241. cmdqRecFlush(hReq);
  242. CMDQ_MSG("================= INVALID INSTR =================\n");
  243. /* invalid instruction */
  244. CMDQ_MSG("%s line:%d\n", __func__, __LINE__);
  245. cmdqRecReset(hReq);
  246. cmdqRecSetSecure(hReq, gCmdqTestSecure);
  247. cmdq_append_command(hReq, CMDQ_CODE_JUMP, -1, 0);
  248. cmdqRecFlush(hReq);
  249. CMDQ_MSG("================= INVALID INSTR: UNKNOWN OP(0x%x) =================\n",
  250. UNKNOWN_OP);
  251. CMDQ_MSG("%s line:%d\n", __func__, __LINE__);
  252. /* invalid instruction is asserted when unknown OP */
  253. cmdqRecReset(hReq);
  254. cmdqRecSetSecure(hReq, gCmdqTestSecure);
  255. {
  256. pCommand = (uint32_t *) ((uint8_t *) hReq->pBuffer + hReq->blockSize);
  257. *pCommand++ = 0x0;
  258. *pCommand++ = (UNKNOWN_OP << 24);
  259. hReq->blockSize += 8;
  260. }
  261. cmdqRecFlush(hReq);
  262. } while (0);
  263. cmdqRecDestroy(hReq);
  264. cmdqRecDestroy(hLoop);
  265. CMDQ_MSG("%s END\n", __func__);
  266. }
  267. static int32_t finishCallback(unsigned long data)
  268. {
  269. CMDQ_LOG("callback() with data=0x%08lx\n", data);
  270. return 0;
  271. }
  272. static void testcase_fire_and_forget(void)
  273. {
  274. cmdqRecHandle hReqA, hReqB;
  275. CMDQ_MSG("%s\n", __func__);
  276. do {
  277. cmdqRecCreate(CMDQ_SCENARIO_DEBUG, &hReqA);
  278. cmdqRecCreate(CMDQ_SCENARIO_DEBUG, &hReqB);
  279. cmdqRecReset(hReqA);
  280. cmdqRecReset(hReqB);
  281. cmdqRecSetSecure(hReqA, gCmdqTestSecure);
  282. cmdqRecSetSecure(hReqB, gCmdqTestSecure);
  283. CMDQ_MSG("%s %d\n", __func__, __LINE__);
  284. cmdqRecFlushAsync(hReqA);
  285. CMDQ_MSG("%s %d\n", __func__, __LINE__);
  286. cmdqRecFlushAsyncCallback(hReqB, finishCallback, 443);
  287. CMDQ_MSG("%s %d\n", __func__, __LINE__);
  288. } while (0);
  289. cmdqRecDestroy(hReqA);
  290. cmdqRecDestroy(hReqB);
  291. CMDQ_MSG("%s END\n", __func__);
  292. }
  293. static struct timer_list timer_reqA;
  294. static struct timer_list timer_reqB;
  295. static void testcase_async_request(void)
  296. {
  297. cmdqRecHandle hReqA, hReqB;
  298. TaskStruct *pTaskA, *pTaskB;
  299. int32_t ret = 0;
  300. CMDQ_MSG("%s\n", __func__);
  301. /* setup timer to trigger sync token */
  302. setup_timer(&timer_reqA, &_testcase_sync_token_timer_func, CMDQ_SYNC_TOKEN_USER_0);
  303. mod_timer(&timer_reqA, jiffies + msecs_to_jiffies(1000));
  304. setup_timer(&timer_reqB, &_testcase_sync_token_timer_func, CMDQ_SYNC_TOKEN_USER_1);
  305. /* mod_timer(&timer_reqB, jiffies + msecs_to_jiffies(1300)); */
  306. /* clear token */
  307. CMDQ_REG_SET32(CMDQ_SYNC_TOKEN_UPD, CMDQ_SYNC_TOKEN_USER_0);
  308. CMDQ_REG_SET32(CMDQ_SYNC_TOKEN_UPD, CMDQ_SYNC_TOKEN_USER_1);
  309. do {
  310. cmdqRecCreate(CMDQ_SCENARIO_SUB_DISP, &hReqA);
  311. cmdqRecReset(hReqA);
  312. cmdqRecSetSecure(hReqA, gCmdqTestSecure);
  313. cmdqRecWait(hReqA, CMDQ_SYNC_TOKEN_USER_0);
  314. cmdq_append_command(hReqA, CMDQ_CODE_EOC, 0, 1);
  315. cmdq_append_command(hReqA, CMDQ_CODE_JUMP, 0, 8);
  316. cmdqRecCreate(CMDQ_SCENARIO_SUB_DISP, &hReqB);
  317. cmdqRecReset(hReqB);
  318. cmdqRecSetSecure(hReqB, gCmdqTestSecure);
  319. cmdqRecWait(hReqB, CMDQ_SYNC_TOKEN_USER_1);
  320. cmdq_append_command(hReqB, CMDQ_CODE_EOC, 0, 1);
  321. cmdq_append_command(hReqB, CMDQ_CODE_JUMP, 0, 8);
  322. ret = _test_submit_async(hReqA, &pTaskA);
  323. ret = _test_submit_async(hReqB, &pTaskB);
  324. CMDQ_MSG("%s start wait sleep========\n", __func__);
  325. msleep_interruptible(500);
  326. CMDQ_MSG("%s start wait A========\n", __func__);
  327. ret = cmdqCoreWaitAndReleaseTask(pTaskA, 500);
  328. CMDQ_MSG("%s start wait B, this should timeout========\n", __func__);
  329. ret = cmdqCoreWaitAndReleaseTask(pTaskB, 600);
  330. CMDQ_MSG("%s wait B get %d ========\n", __func__, ret);
  331. } while (0);
  332. /* clear token */
  333. CMDQ_REG_SET32(CMDQ_SYNC_TOKEN_UPD, CMDQ_SYNC_TOKEN_USER_0);
  334. CMDQ_REG_SET32(CMDQ_SYNC_TOKEN_UPD, CMDQ_SYNC_TOKEN_USER_1);
  335. cmdqRecDestroy(hReqA);
  336. cmdqRecDestroy(hReqB);
  337. del_timer(&timer_reqA);
  338. del_timer(&timer_reqB);
  339. CMDQ_MSG("%s END\n", __func__);
  340. }
  341. static void testcase_multiple_async_request(void)
  342. {
  343. #define TEST_REQ_COUNT 24
  344. cmdqRecHandle hReq[TEST_REQ_COUNT] = { 0 };
  345. TaskStruct *pTask[TEST_REQ_COUNT] = { 0 };
  346. int32_t ret = 0;
  347. int i;
  348. CMDQ_MSG("%s\n", __func__);
  349. setup_timer(&timer, &_testcase_sync_token_timer_loop_func, CMDQ_SYNC_TOKEN_USER_0);
  350. mod_timer(&timer, jiffies + msecs_to_jiffies(10));
  351. /* Queue multiple async request */
  352. /* to test dynamic task allocation */
  353. CMDQ_REG_SET32(CMDQ_SYNC_TOKEN_UPD, CMDQ_SYNC_TOKEN_USER_0);
  354. for (i = 0; i < TEST_REQ_COUNT; ++i) {
  355. ret = cmdqRecCreate(CMDQ_SCENARIO_DEBUG, &hReq[i]);
  356. if (0 > ret) {
  357. CMDQ_ERR("%s cmdqRecCreate failed:%d, i:%d\n ", __func__, ret, i);
  358. continue;
  359. }
  360. cmdqRecReset(hReq[i]);
  361. /* specify engine flag in order to dispatch all tasks to the same HW thread */
  362. hReq[i]->engineFlag = (1LL << CMDQ_ENG_MDP_CAMIN);
  363. cmdqRecSetSecure(hReq[i], gCmdqTestSecure);
  364. cmdqRecWait(hReq[i], CMDQ_SYNC_TOKEN_USER_0);
  365. cmdq_rec_finalize_command(hReq[i], false);
  366. /* higher priority for later tasks */
  367. hReq[i]->priority = i;
  368. _test_submit_async(hReq[i], &pTask[i]);
  369. CMDQ_MSG("======== create task[%2d]=0x%p done ========\n", i, pTask[i]);
  370. }
  371. /* release token and wait them */
  372. for (i = 0; i < TEST_REQ_COUNT; ++i) {
  373. if (NULL == pTask[i]) {
  374. CMDQ_ERR("%s pTask[%d] is NULL\n ", __func__, i);
  375. continue;
  376. }
  377. msleep_interruptible(100);
  378. CMDQ_LOG("======== wait task[%2d]=0x%p ========\n", i, pTask[i]);
  379. ret = cmdqCoreWaitAndReleaseTask(pTask[i], 1000);
  380. cmdqRecDestroy(hReq[i]);
  381. }
  382. /* clear token */
  383. CMDQ_REG_SET32(CMDQ_SYNC_TOKEN_UPD, CMDQ_SYNC_TOKEN_USER_0);
  384. del_timer(&timer);
  385. CMDQ_MSG("%s END\n", __func__);
  386. }
  387. static void testcase_async_request_partial_engine(void)
  388. {
  389. int32_t ret = 0;
  390. int i;
  391. CMDQ_SCENARIO_ENUM scn[] = { CMDQ_SCENARIO_PRIMARY_DISP,
  392. CMDQ_SCENARIO_JPEG_DEC,
  393. CMDQ_SCENARIO_PRIMARY_MEMOUT,
  394. CMDQ_SCENARIO_SUB_DISP,
  395. CMDQ_SCENARIO_DEBUG,
  396. };
  397. struct timer_list timers[sizeof(scn) / sizeof(scn[0])];
  398. cmdqRecHandle hReq;
  399. TaskStruct *pTasks[(sizeof(scn) / sizeof(scn[0]))] = { 0 };
  400. CMDQ_MSG("%s\n", __func__);
  401. /* setup timer to trigger sync token */
  402. for (i = 0; i < (sizeof(scn) / sizeof(scn[0])); ++i) {
  403. setup_timer(&timers[i], &_testcase_sync_token_timer_func,
  404. CMDQ_SYNC_TOKEN_USER_0 + i);
  405. mod_timer(&timers[i], jiffies + msecs_to_jiffies(400 * (1 + i)));
  406. CMDQ_REG_SET32(CMDQ_SYNC_TOKEN_UPD, CMDQ_SYNC_TOKEN_USER_0 + i);
  407. cmdqRecCreate(scn[i], &hReq);
  408. cmdqRecReset(hReq);
  409. cmdqRecSetSecure(hReq, false);
  410. cmdqRecWait(hReq, CMDQ_SYNC_TOKEN_USER_0 + i);
  411. cmdq_rec_finalize_command(hReq, false);
  412. CMDQ_MSG("TEST: SUBMIT scneario %d\n", scn[i]);
  413. ret = _test_submit_async(hReq, &pTasks[i]);
  414. }
  415. cmdqRecDestroy(hReq);
  416. /* wait for task completion */
  417. for (i = 0; i < (sizeof(scn) / sizeof(scn[0])); ++i)
  418. ret = cmdqCoreWaitAndReleaseTask(pTasks[i], msecs_to_jiffies(3000));
  419. /* clear token */
  420. for (i = 0; i < (sizeof(scn) / sizeof(scn[0])); ++i) {
  421. CMDQ_REG_SET32(CMDQ_SYNC_TOKEN_UPD, CMDQ_SYNC_TOKEN_USER_0 + i);
  422. del_timer(&timers[i]);
  423. }
  424. CMDQ_MSG("%s END\n", __func__);
  425. }
  426. static void _testcase_unlock_all_event_timer_func(unsigned long data)
  427. {
  428. uint32_t token = 0;
  429. CMDQ_MSG("%s\n", __func__);
  430. /* trigger sync event */
  431. CMDQ_MSG("trigger events\n");
  432. for (token = 0; token < CMDQ_SYNC_TOKEN_MAX; ++token) {
  433. /* 3 threads waiting, so update 3 times */
  434. CMDQ_REG_SET32(CMDQ_SYNC_TOKEN_UPD, (1L << 16) | token);
  435. CMDQ_REG_SET32(CMDQ_SYNC_TOKEN_UPD, (1L << 16) | token);
  436. CMDQ_REG_SET32(CMDQ_SYNC_TOKEN_UPD, (1L << 16) | token);
  437. }
  438. }
  439. static void testcase_sync_token_threaded(void)
  440. {
  441. CMDQ_SCENARIO_ENUM scn[] = { CMDQ_SCENARIO_PRIMARY_DISP, /* high prio */
  442. CMDQ_SCENARIO_JPEG_DEC, /* normal prio */
  443. CMDQ_SCENARIO_TRIGGER_LOOP /* normal prio */
  444. };
  445. int32_t ret = 0;
  446. int i = 0;
  447. uint32_t token = 0;
  448. struct timer_list eventTimer;
  449. cmdqRecHandle hReq[(sizeof(scn) / sizeof(scn[0]))] = { 0 };
  450. TaskStruct *pTasks[(sizeof(scn) / sizeof(scn[0]))] = { 0 };
  451. CMDQ_MSG("%s\n", __func__);
  452. /* setup timer to trigger sync token */
  453. for (i = 0; i < (sizeof(scn) / sizeof(scn[0])); ++i) {
  454. setup_timer(&eventTimer, &_testcase_unlock_all_event_timer_func, 0);
  455. mod_timer(&eventTimer, jiffies + msecs_to_jiffies(500));
  456. /* */
  457. /* 3 threads, all wait & clear 511 events */
  458. /* */
  459. cmdqRecCreate(scn[i], &hReq[i]);
  460. cmdqRecReset(hReq[i]);
  461. cmdqRecSetSecure(hReq[i], false);
  462. for (token = 0; token < CMDQ_SYNC_TOKEN_MAX; ++token)
  463. cmdqRecWait(hReq[i], (CMDQ_EVENT_ENUM) token);
  464. cmdq_rec_finalize_command(hReq[i], false);
  465. CMDQ_MSG("TEST: SUBMIT scneario %d\n", scn[i]);
  466. ret = _test_submit_async(hReq[i], &pTasks[i]);
  467. }
  468. /* wait for task completion */
  469. msleep_interruptible(1000);
  470. for (i = 0; i < (sizeof(scn) / sizeof(scn[0])); ++i)
  471. ret = cmdqCoreWaitAndReleaseTask(pTasks[i], msecs_to_jiffies(5000));
  472. /* clear token */
  473. for (i = 0; i < (sizeof(scn) / sizeof(scn[0])); ++i)
  474. cmdqRecDestroy(hReq[i]);
  475. del_timer(&eventTimer);
  476. CMDQ_MSG("%s END\n", __func__);
  477. }
  478. static struct timer_list g_loopTimer;
  479. static int g_loopIter;
  480. static cmdqRecHandle hLoopReq;
  481. static void _testcase_loop_timer_func(unsigned long data)
  482. {
  483. CMDQ_REG_SET32(CMDQ_SYNC_TOKEN_UPD, (1L << 16) | data);
  484. mod_timer(&g_loopTimer, jiffies + msecs_to_jiffies(300));
  485. g_loopIter++;
  486. }
  487. static void testcase_loop(void)
  488. {
  489. int status = 0;
  490. CMDQ_MSG("%s\n", __func__);
  491. cmdqRecCreate(CMDQ_SCENARIO_TRIGGER_LOOP, &hLoopReq);
  492. cmdqRecReset(hLoopReq);
  493. cmdqRecSetSecure(hLoopReq, false);
  494. cmdqRecWait(hLoopReq, CMDQ_SYNC_TOKEN_USER_0);
  495. setup_timer(&g_loopTimer, &_testcase_loop_timer_func, CMDQ_SYNC_TOKEN_USER_0);
  496. mod_timer(&g_loopTimer, jiffies + msecs_to_jiffies(300));
  497. CMDQ_REG_SET32(CMDQ_SYNC_TOKEN_UPD, CMDQ_SYNC_TOKEN_USER_0);
  498. g_loopIter = 0;
  499. /* should success */
  500. status = cmdqRecStartLoop(hLoopReq);
  501. BUG_ON(status != 0);
  502. /* should fail because already started */
  503. CMDQ_MSG("============testcase_loop start loop\n");
  504. status = cmdqRecStartLoop(hLoopReq);
  505. BUG_ON(status >= 0);
  506. cmdqRecDumpCommand(hLoopReq);
  507. /* WAIT */
  508. while (g_loopIter < 20)
  509. msleep_interruptible(2000);
  510. msleep_interruptible(2000);
  511. CMDQ_MSG("============testcase_loop stop timer\n");
  512. cmdqRecDestroy(hLoopReq);
  513. del_timer(&g_loopTimer);
  514. CMDQ_MSG("%s\n", __func__);
  515. }
  516. static unsigned long gLoopCount = 0L;
  517. static void _testcase_trigger_func(unsigned long data)
  518. {
  519. /* trigger sync event */
  520. CMDQ_MSG("_testcase_trigger_func");
  521. CMDQ_REG_SET32(CMDQ_SYNC_TOKEN_UPD, (1L << 16) | CMDQ_SYNC_TOKEN_USER_0);
  522. CMDQ_REG_SET32(CMDQ_SYNC_TOKEN_UPD, (1L << 16) | CMDQ_SYNC_TOKEN_USER_1);
  523. /* start again */
  524. mod_timer(&timer, jiffies + msecs_to_jiffies(1000));
  525. gLoopCount++;
  526. }
  527. /*
  528. static void leave_loop_func(struct work_struct *w)
  529. {
  530. CMDQ_MSG("leave_loop_func: cancel loop");
  531. cmdqRecStopLoop(hLoopConfig);
  532. hLoopConfig = NULL;
  533. return;
  534. }
  535. DECLARE_WORK(leave_loop, leave_loop_func);
  536. int32_t my_irq_callback(unsigned long data)
  537. {
  538. CMDQ_MSG("%s data=%d\n", __FUNCTION__, data);
  539. ++gLoopCount;
  540. switch(data)
  541. {
  542. case 1:
  543. if(gLoopCount < 20)
  544. {
  545. return 0;
  546. }
  547. else
  548. {
  549. return -1;
  550. }
  551. break;
  552. case 2:
  553. if(gLoopCount > 40)
  554. {
  555. // insert stopping cal
  556. schedule_work(&leave_loop);
  557. }
  558. break;
  559. }
  560. return 0;
  561. }
  562. */
  563. static void testcase_trigger_thread(void)
  564. {
  565. cmdqRecHandle hTrigger, hConfig;
  566. int32_t ret = 0;
  567. int index = 0;
  568. CMDQ_MSG("%s\n", __func__);
  569. /* setup timer to trigger sync token for every 1 sec */
  570. setup_timer(&timer, &_testcase_trigger_func, 0);
  571. mod_timer(&timer, jiffies + msecs_to_jiffies(1000));
  572. do {
  573. /* THREAD 1, trigger loop */
  574. cmdqRecCreate(CMDQ_SCENARIO_TRIGGER_LOOP, &hTrigger);
  575. cmdqRecReset(hTrigger);
  576. /* * WAIT and CLEAR config dirty */
  577. /* cmdqRecWait(hTrigger, CMDQ_SYNC_TOKEN_CONFIG_DIRTY); */
  578. /* * WAIT and CLEAR TE */
  579. /* cmdqRecWait(hTrigger, CMDQ_EVENT_MDP_DSI0_TE_SOF); */
  580. /* * WAIT and CLEAR stream done */
  581. /* cmdqRecWait(hTrigger, CMDQ_EVENT_MUTEX0_STREAM_EOF); */
  582. /* * WRITE mutex enable */
  583. /* cmdqRecWait(hTrigger, MM_MUTEX_BASE + 0x20); */
  584. cmdqRecWait(hTrigger, CMDQ_SYNC_TOKEN_USER_0);
  585. /* * RUN forever but each IRQ trigger is bypass to my_irq_callback */
  586. ret = cmdqRecStartLoop(hTrigger);
  587. /* THREAD 2, config thread */
  588. cmdqRecCreate(CMDQ_SCENARIO_JPEG_DEC, &hConfig);
  589. hConfig->priority = CMDQ_THR_PRIO_NORMAL;
  590. cmdqRecReset(hConfig);
  591. /* insert tons of instructions */
  592. for (index = 0; index < 10; ++index)
  593. cmdq_append_command(hConfig, CMDQ_CODE_MOVE, 0, 0x1);
  594. ret = cmdqRecFlush(hConfig);
  595. CMDQ_MSG("flush 0\n");
  596. hConfig->priority = CMDQ_THR_PRIO_DISPLAY_CONFIG;
  597. cmdqRecReset(hConfig);
  598. /* insert tons of instructions */
  599. for (index = 0; index < 10; ++index)
  600. cmdq_append_command(hConfig, CMDQ_CODE_MOVE, 0, 0x1);
  601. ret = cmdqRecFlush(hConfig);
  602. CMDQ_MSG("flush 1\n");
  603. cmdqRecReset(hConfig);
  604. /* insert tons of instructions */
  605. for (index = 0; index < 500; ++index)
  606. cmdq_append_command(hConfig, CMDQ_CODE_MOVE, 0, 0x1);
  607. ret = cmdqRecFlush(hConfig);
  608. CMDQ_MSG("flush 2\n");
  609. /* WAIT */
  610. while (gLoopCount < 20)
  611. msleep_interruptible(2000);
  612. } while (0);
  613. del_timer(&timer);
  614. cmdqRecDestroy(hTrigger);
  615. cmdqRecDestroy(hConfig);
  616. CMDQ_MSG("%s END\n", __func__);
  617. }
  618. static void testcase_prefetch_scenarios(void)
  619. {
  620. /* make sure both prefetch and non-prefetch cases */
  621. /* handle 248+ instructions properly */
  622. cmdqRecHandle hConfig;
  623. int32_t ret = 0;
  624. int index = 0, scn = 0;
  625. const int INSTRUCTION_COUNT = 500;
  626. CMDQ_MSG("%s\n", __func__);
  627. /* make sure each scenario runs properly with 248+ commands */
  628. for (scn = 0; scn < CMDQ_MAX_SCENARIO_COUNT; ++scn) {
  629. if (cmdq_core_is_request_from_user_space(scn))
  630. continue;
  631. CMDQ_MSG("testcase_prefetch_scenarios scenario:%d\n", scn);
  632. cmdqRecCreate((CMDQ_SCENARIO_ENUM) scn, &hConfig);
  633. cmdqRecReset(hConfig);
  634. /* insert tons of instructions */
  635. for (index = 0; index < INSTRUCTION_COUNT; ++index)
  636. cmdq_append_command(hConfig, CMDQ_CODE_MOVE, 0, 0x1);
  637. ret = cmdqRecFlush(hConfig);
  638. BUG_ON(ret < 0);
  639. }
  640. cmdqRecDestroy(hConfig);
  641. CMDQ_MSG("%s END\n", __func__);
  642. }
  643. #ifndef CMDQ_USE_CCF
  644. void testcase_clkmgr_impl(cgCLKID gateId,
  645. char *name,
  646. const unsigned long testWriteReg,
  647. const uint32_t testWriteValue,
  648. const unsigned long testReadReg, const bool verifyWriteResult)
  649. {
  650. /* clkmgr is not available on FPGA */
  651. #ifndef CONFIG_MTK_FPGA
  652. uint32_t value = 0;
  653. CMDQ_MSG("====== %s:%s ======\n", __func__, name);
  654. CMDQ_VERBOSE("clk:%d, name:%s\n", gateId, name);
  655. CMDQ_VERBOSE("write reg(0x%lx) to 0x%08x, read reg(0x%lx), verify write result:%d\n",
  656. testWriteReg, testWriteValue, testReadReg, verifyWriteResult);
  657. /* turn on CLK, function should work */
  658. CMDQ_MSG("enable_clock\n");
  659. enable_clock(gateId, name);
  660. CMDQ_REG_SET32(testWriteReg, testWriteValue);
  661. value = CMDQ_REG_GET32(testReadReg);
  662. if ((true == verifyWriteResult) && (testWriteValue != value)) {
  663. CMDQ_ERR("when enable clock reg(0x%lx) = 0x%08x\n", testReadReg, value);
  664. /* BUG(); */
  665. }
  666. /* turn off CLK, function should not work and access register should not cause hang */
  667. CMDQ_MSG("disable_clock\n");
  668. disable_clock(gateId, name);
  669. CMDQ_REG_SET32(testWriteReg, testWriteValue);
  670. value = CMDQ_REG_GET32(testReadReg);
  671. if (0 != value) {
  672. CMDQ_ERR("when disable clock reg(0x%lx) = 0x%08x\n", testReadReg, value);
  673. /* BUG(); */
  674. }
  675. #endif
  676. }
  677. #endif /* !defined(CMDQ_USE_CCF) */
  678. static void testcase_clkmgr(void)
  679. {
  680. CMDQ_MSG("%s\n", __func__);
  681. #if defined(CMDQ_PWR_AWARE) && !defined(CMDQ_USE_CCF)
  682. testcase_clkmgr_impl(MT_CG_INFRA_GCE,
  683. "CMDQ_TEST",
  684. CMDQ_GPR_R32(CMDQ_DATA_REG_DEBUG),
  685. 0xFFFFDEAD, CMDQ_GPR_R32(CMDQ_DATA_REG_DEBUG), true);
  686. cmdq_mdp_get_func()->testcaseClkmgrMdp();
  687. #endif /* !defined(CMDQ_USE_CCF) */
  688. CMDQ_MSG("%s END\n", __func__);
  689. }
  690. static void testcase_dram_access(void)
  691. {
  692. #ifdef CMDQ_GPR_SUPPORT
  693. cmdqRecHandle handle;
  694. uint32_t *regResults;
  695. dma_addr_t regResultsMVA;
  696. dma_addr_t dstMVA;
  697. uint32_t argA;
  698. uint32_t subsysCode;
  699. uint32_t *pCmdEnd = NULL;
  700. unsigned long long data64;
  701. CMDQ_MSG("%s\n", __func__);
  702. regResults = cmdq_core_alloc_hw_buffer(cmdq_dev_get(),
  703. sizeof(uint32_t) * 2, &regResultsMVA, GFP_KERNEL);
  704. /* set up intput */
  705. regResults[0] = 0xdeaddead; /* this is read-from */
  706. regResults[1] = 0xffffffff; /* this is write-to */
  707. cmdqRecCreate(CMDQ_SCENARIO_DEBUG, &handle);
  708. cmdqRecReset(handle);
  709. cmdqRecSetSecure(handle, gCmdqTestSecure);
  710. /* */
  711. /* READ from DRAME: register to read from */
  712. /* */
  713. /* note that we force convert to physical reg address. */
  714. /* if it is already physical address, it won't be affected (at least on this platform) */
  715. argA = CMDQ_TEST_MMSYS_DUMMY_PA;
  716. subsysCode = cmdq_core_subsys_from_phys_addr(argA);
  717. pCmdEnd = (uint32_t *) (((char *)handle->pBuffer) + handle->blockSize);
  718. CMDQ_MSG("pCmdEnd initial=0x%p, reg MVA=%pa, size=%d\n",
  719. pCmdEnd, &regResultsMVA, handle->blockSize);
  720. /* Move &(regResults[0]) to CMDQ_DATA_REG_DEBUG_DST */
  721. *pCmdEnd = (uint32_t) CMDQ_PHYS_TO_AREG(regResultsMVA);
  722. pCmdEnd += 1;
  723. *pCmdEnd = (CMDQ_CODE_MOVE << 24) |
  724. #ifdef CONFIG_ARCH_DMA_ADDR_T_64BIT
  725. ((regResultsMVA >> 32) & 0xffff) |
  726. #endif
  727. ((CMDQ_DATA_REG_DEBUG_DST & 0x1f) << 16) | (4 << 21);
  728. pCmdEnd += 1;
  729. /* */
  730. /* WRITE to DRAME: */
  731. /* from src_addr(CMDQ_DATA_REG_DEBUG_DST) to external RAM (regResults[1]) */
  732. /* */
  733. /* Read data from *CMDQ_DATA_REG_DEBUG_DST to CMDQ_DATA_REG_DEBUG */
  734. *pCmdEnd = CMDQ_DATA_REG_DEBUG;
  735. pCmdEnd += 1;
  736. *pCmdEnd =
  737. (CMDQ_CODE_READ << 24) | (0 & 0xffff) | ((CMDQ_DATA_REG_DEBUG_DST & 0x1f) << 16) | (6 <<
  738. 21);
  739. pCmdEnd += 1;
  740. /* Load dst_addr to GPR: Move &(regResults[1]) to CMDQ_DATA_REG_DEBUG_DST */
  741. dstMVA = regResultsMVA + 4; /* note regResults is a uint32_t array */
  742. *pCmdEnd = ((uint32_t) dstMVA);
  743. pCmdEnd += 1;
  744. *pCmdEnd = (CMDQ_CODE_MOVE << 24) |
  745. #ifdef CONFIG_ARCH_DMA_ADDR_T_64BIT
  746. ((dstMVA >> 32) & 0xffff) |
  747. #endif
  748. ((CMDQ_DATA_REG_DEBUG_DST & 0x1f) << 16) | (4 << 21);
  749. pCmdEnd += 1;
  750. /* Write from CMDQ_DATA_REG_DEBUG to *CMDQ_DATA_REG_DEBUG_DST */
  751. *pCmdEnd = CMDQ_DATA_REG_DEBUG;
  752. pCmdEnd += 1;
  753. *pCmdEnd = (CMDQ_CODE_WRITE << 24) |
  754. (0 & 0xffff) | ((CMDQ_DATA_REG_DEBUG_DST & 0x1f) << 16) | (6 << 21);
  755. pCmdEnd += 1;
  756. handle->blockSize += 4 * 8; /* 4 * 64-bit instructions */
  757. cmdqRecDumpCommand(handle);
  758. cmdqRecFlush(handle);
  759. cmdqRecDumpCommand(handle);
  760. cmdqRecDestroy(handle);
  761. data64 = 0LL;
  762. data64 = CMDQ_REG_GET64_GPR_PX(CMDQ_DATA_REG_DEBUG_DST);
  763. CMDQ_MSG("regResults=[0x%08x, 0x%08x]\n", regResults[0], regResults[1]);
  764. CMDQ_MSG("CMDQ_DATA_REG_DEBUG=0x%08x, CMDQ_DATA_REG_DEBUG_DST=0x%llx\n",
  765. CMDQ_REG_GET32(CMDQ_GPR_R32(CMDQ_DATA_REG_DEBUG)), data64);
  766. if (regResults[1] != regResults[0]) {
  767. /* Test DRAM access fail */
  768. CMDQ_ERR("ERROR!!!!!!\n");
  769. } else {
  770. /* Test DRAM access success */
  771. CMDQ_MSG("OK!!!!!!\n");
  772. }
  773. cmdq_core_free_hw_buffer(cmdq_dev_get(), 2 * sizeof(uint32_t), regResults,
  774. regResultsMVA);
  775. CMDQ_MSG("%s END\n", __func__);
  776. #else
  777. CMDQ_ERR("func:%s failed since CMDQ doesn't support GPR\n", __func__);
  778. #endif
  779. }
  780. static void testcase_long_command(void)
  781. {
  782. int i;
  783. cmdqRecHandle handle;
  784. uint32_t data;
  785. uint32_t pattern = 0x0;
  786. const unsigned long MMSYS_DUMMY_REG = CMDQ_TEST_MMSYS_DUMMY_VA;
  787. CMDQ_MSG("%s\n", __func__);
  788. CMDQ_REG_SET32(MMSYS_DUMMY_REG, 0xdeaddead);
  789. cmdqRecCreate(CMDQ_SCENARIO_DEBUG, &handle);
  790. cmdqRecReset(handle);
  791. cmdqRecSetSecure(handle, gCmdqTestSecure);
  792. /* build a 64KB instruction buffer */
  793. for (i = 0; i < 64 * 1024 / 8; ++i) {
  794. pattern = i;
  795. cmdqRecWrite(handle, CMDQ_TEST_MMSYS_DUMMY_PA, pattern, ~0);
  796. }
  797. cmdqRecFlush(handle);
  798. cmdqRecDestroy(handle);
  799. /* verify data */
  800. do {
  801. if (true == gCmdqTestSecure) {
  802. CMDQ_LOG("%s, timeout case in secure path\n", __func__);
  803. break;
  804. }
  805. data = CMDQ_REG_GET32(CMDQ_TEST_MMSYS_DUMMY_VA);
  806. if (pattern != data) {
  807. CMDQ_ERR("TEST FAIL: reg value is 0x%08x, not pattern 0x%08x\n", data,
  808. pattern);
  809. }
  810. } while (0);
  811. CMDQ_MSG("%s END\n", __func__);
  812. }
  813. static void testcase_perisys_apb(void)
  814. {
  815. #ifdef CMDQ_GPR_SUPPORT
  816. /* write value to PERISYS register */
  817. /* we use MSDC debug to test: */
  818. /* write SEL, read OUT. */
  819. const uint32_t MSDC_SW_DBG_SEL_PA = 0x11230000 + 0xA0;
  820. const uint32_t MSDC_SW_DBG_OUT_PA = 0x11230000 + 0xA4;
  821. const uint32_t AUDIO_TOP_CONF0_PA = 0x11220000;
  822. #ifdef CMDQ_OF_SUPPORT
  823. const unsigned long MSDC_VA_BASE = cmdq_dev_alloc_module_base_VA_by_name("mediatek,MSDC0");
  824. const unsigned long AUDIO_VA_BASE = cmdq_dev_alloc_module_base_VA_by_name("mediatek,AUDIO");
  825. const unsigned long MSDC_SW_DBG_OUT = MSDC_VA_BASE + 0xA4;
  826. const unsigned long AUDIO_TOP_CONF0 = AUDIO_VA_BASE;
  827. /* CMDQ_LOG("MSDC_VA_BASE: VA:%lx, PA: 0x%08x\n", MSDC_VA_BASE, 0x11230000); */
  828. /* CMDQ_LOG("AUDIO_VA_BASE: VA:%lx, PA: 0x%08x\n", AUDIO_TOP_CONF0_PA, 0x11220000); */
  829. #else
  830. const uint32_t MSDC_SW_DBG_OUT = 0xF1230000 + 0xA4;
  831. const uint32_t AUDIO_TOP_CONF0 = 0xF1220000;
  832. #endif
  833. const uint32_t AUDIO_TOP_MASK = ~0 & ~(1 << 28 |
  834. 1 << 21 |
  835. 1 << 17 |
  836. 1 << 16 |
  837. 1 << 15 |
  838. 1 << 11 |
  839. 1 << 10 |
  840. 1 << 7 | 1 << 5 | 1 << 4 | 1 << 3 | 1 << 1 | 1 << 0);
  841. cmdqRecHandle handle = NULL;
  842. uint32_t data = 0;
  843. uint32_t dataRead = 0;
  844. CMDQ_MSG("%s\n", __func__);
  845. cmdqRecCreate(CMDQ_SCENARIO_DEBUG, &handle);
  846. cmdqRecReset(handle);
  847. cmdqRecSetSecure(handle, false);
  848. cmdqRecWrite(handle, MSDC_SW_DBG_SEL_PA, 1, ~0);
  849. cmdqRecFlush(handle);
  850. /* verify data */
  851. data = CMDQ_REG_GET32(MSDC_SW_DBG_OUT);
  852. CMDQ_MSG("MSDC_SW_DBG_OUT = 0x%08x=====\n", data);
  853. /* test read from AP_DMA_GLOBAL_SLOW_DOWN to CMDQ GPR */
  854. cmdqRecReset(handle);
  855. cmdqRecSetSecure(handle, false);
  856. cmdqRecReadToDataRegister(handle, MSDC_SW_DBG_OUT_PA, CMDQ_DATA_REG_PQ_COLOR);
  857. cmdqRecFlush(handle);
  858. /* verify data */
  859. dataRead = CMDQ_REG_GET32(CMDQ_GPR_R32(CMDQ_DATA_REG_PQ_COLOR));
  860. if (data != dataRead) {
  861. /* test fail */
  862. CMDQ_ERR("TEST FAIL: CMDQ_DATA_REG_PQ_COLOR is 0x%08x, different=====\n", dataRead);
  863. }
  864. CMDQ_REG_SET32(AUDIO_TOP_CONF0, ~0);
  865. data = CMDQ_REG_GET32(AUDIO_TOP_CONF0);
  866. CMDQ_MSG("write 0xFFFFFFFF to AUDIO_TOP_CONF0 = 0x%08x=====\n", data);
  867. CMDQ_REG_SET32(AUDIO_TOP_CONF0, 0);
  868. data = CMDQ_REG_GET32(AUDIO_TOP_CONF0);
  869. CMDQ_MSG("Before AUDIO_TOP_CONF0 = 0x%08x=====\n", data);
  870. cmdqRecReset(handle);
  871. cmdqRecWrite(handle, AUDIO_TOP_CONF0_PA, ~0, AUDIO_TOP_MASK);
  872. cmdqRecFlush(handle);
  873. /* verify data */
  874. data = CMDQ_REG_GET32(AUDIO_TOP_CONF0);
  875. CMDQ_MSG("after AUDIO_TOP_CONF0 = 0x%08x=====\n", data);
  876. if (data != AUDIO_TOP_MASK) {
  877. /* test fail */
  878. CMDQ_ERR("TEST FAIL: AUDIO_TOP_CONF0 is 0x%08x=====\n", data);
  879. }
  880. cmdqRecDestroy(handle);
  881. #ifdef CMDQ_OF_SUPPORT
  882. /* release registers map */
  883. cmdq_dev_free_module_base_VA(MSDC_VA_BASE);
  884. cmdq_dev_free_module_base_VA(AUDIO_VA_BASE);
  885. #endif
  886. CMDQ_MSG("%s END\n", __func__);
  887. return;
  888. #else
  889. CMDQ_ERR("func:%s failed since CMDQ doesn't support GPR\n", __func__);
  890. #endif /* CMDQ_GPR_SUPPORT */
  891. }
  892. static void testcase_write_address(void)
  893. {
  894. dma_addr_t pa = 0;
  895. uint32_t value = 0;
  896. CMDQ_MSG("%s\n", __func__);
  897. cmdqCoreAllocWriteAddress(3, &pa);
  898. CMDQ_LOG("ALLOC: 0x%pa\n", &pa);
  899. value = cmdqCoreReadWriteAddress(pa);
  900. CMDQ_LOG("value 0: 0x%08x\n", value);
  901. value = cmdqCoreReadWriteAddress(pa + 1);
  902. CMDQ_LOG("value 1: 0x%08x\n", value);
  903. value = cmdqCoreReadWriteAddress(pa + 2);
  904. CMDQ_LOG("value 2: 0x%08x\n", value);
  905. value = cmdqCoreReadWriteAddress(pa + 3);
  906. CMDQ_LOG("value 3: 0x%08x\n", value);
  907. value = cmdqCoreReadWriteAddress(pa + 4);
  908. CMDQ_LOG("value 4: 0x%08x\n", value);
  909. value = cmdqCoreReadWriteAddress(pa + (4 * 20));
  910. CMDQ_LOG("value 80: 0x%08x\n", value);
  911. /* free invalid start address fist to verify error handle */
  912. CMDQ_LOG("cmdqCoreFreeWriteAddress, pa:0, it's a error case\n");
  913. cmdqCoreFreeWriteAddress(0);
  914. /* ok case */
  915. CMDQ_LOG("cmdqCoreFreeWriteAddress, pa:%pa, it's a ok case\n", &pa);
  916. cmdqCoreFreeWriteAddress(pa);
  917. CMDQ_MSG("%s END\n", __func__);
  918. }
  919. static void testcase_write_from_data_reg(void)
  920. {
  921. #ifdef CMDQ_GPR_SUPPORT
  922. cmdqRecHandle handle;
  923. uint32_t value;
  924. const uint32_t PATTERN = 0xFFFFDEAD;
  925. const uint32_t srcGprId = CMDQ_DATA_REG_DEBUG;
  926. const uint32_t dstRegPA = CMDQ_TEST_MMSYS_DUMMY_PA;
  927. const unsigned long dstRegVA = CMDQ_TEST_MMSYS_DUMMY_VA;
  928. CMDQ_MSG("%s\n", __func__);
  929. /* clean dst register value */
  930. CMDQ_REG_SET32(dstRegVA, 0x0);
  931. /* init GPR as value 0xFFFFDEAD */
  932. CMDQ_REG_SET32(CMDQ_GPR_R32(srcGprId), PATTERN);
  933. value = CMDQ_REG_GET32(CMDQ_GPR_R32(srcGprId));
  934. if (PATTERN != value) {
  935. CMDQ_ERR("init CMDQ_DATA_REG_DEBUG to 0x%08x failed, value: 0x%08x\n", PATTERN,
  936. value);
  937. }
  938. /* write GPR data reg to hw register */
  939. cmdqRecCreate(CMDQ_SCENARIO_DEBUG, &handle);
  940. cmdqRecReset(handle);
  941. cmdqRecSetSecure(handle, gCmdqTestSecure);
  942. cmdqRecWriteFromDataRegister(handle, srcGprId, dstRegPA);
  943. cmdqRecFlush(handle);
  944. cmdqRecDumpCommand(handle);
  945. cmdqRecDestroy(handle);
  946. /* verify */
  947. value = CMDQ_REG_GET32(dstRegVA);
  948. if (PATTERN != value) {
  949. CMDQ_ERR("%s failed, dstReg value is not 0x%08x, value: 0x%08x\n", __func__,
  950. PATTERN, value);
  951. }
  952. CMDQ_MSG("%s END\n", __func__);
  953. #else
  954. CMDQ_ERR("func:%s failed since CMDQ doesn't support GPR\n", __func__);
  955. #endif
  956. }
  957. static void testcase_read_to_data_reg(void)
  958. {
  959. #ifdef CMDQ_GPR_SUPPORT
  960. cmdqRecHandle handle;
  961. uint32_t data;
  962. unsigned long long data64;
  963. unsigned long MMSYS_DUMMY_REG = CMDQ_TEST_MMSYS_DUMMY_VA;
  964. CMDQ_MSG("%s\n", __func__);
  965. /* init GPR 64 */
  966. CMDQ_REG_SET64_GPR_PX(CMDQ_DATA_REG_PQ_COLOR_DST, 0x1234567890ABCDEFULL);
  967. cmdqRecCreate(CMDQ_SCENARIO_DEBUG, &handle);
  968. cmdqRecReset(handle);
  969. cmdqRecSetSecure(handle, gCmdqTestSecure);
  970. CMDQ_REG_SET32(MMSYS_DUMMY_REG, 0xdeaddead);
  971. CMDQ_REG_SET32(CMDQ_GPR_R32(CMDQ_DATA_REG_PQ_COLOR), 0xbeefbeef); /* R4 */
  972. CMDQ_REG_SET32(CMDQ_GPR_R32(CMDQ_DATA_REG_2D_SHARPNESS_0), 0x0); /* R5 */
  973. cmdq_get_func()->dumpGPR();
  974. /* [read 64 bit test] move data from GPR to GPR_Px: COLOR to COLOR_DST (64 bit) */
  975. #if 1
  976. cmdqRecReadToDataRegister(handle, CMDQ_GPR_R32_PA(CMDQ_DATA_REG_PQ_COLOR),
  977. CMDQ_DATA_REG_PQ_COLOR_DST);
  978. #else
  979. /* 64 bit behavior of Read OP depends APB bus implementation */
  980. /* (CMDQ uses APB to access HW register, use AXI to access DRAM) */
  981. /* from DE's suggestion, */
  982. /* 1. for read HW register case, it's better to separate 1 x 64 bit length read to 2 x 32 bit length read */
  983. /* 2. for GPRx each assignment case, it's better performance to use MOVE op to read GPR_x1 to GPR_x2 */
  984. /* when Read 64 length failed, try to use move to clear up if APB issue */
  985. const uint32_t srcDataReg = CMDQ_DATA_REG_PQ_COLOR;
  986. const uint32_t dstDataReg = CMDQ_DATA_REG_PQ_COLOR_DST;
  987. /* argA, 22 bit 1: argB is GPR */
  988. /* argA, 23 bit 1: argA is GPR */
  989. cmdq_append_command(handle,
  990. CMDQ_CODE_RAW,
  991. (CMDQ_CODE_MOVE << 24) | (dstDataReg << 16) | (4 << 21) | (2 << 21),
  992. srcDataReg);
  993. #endif
  994. /* [read 32 bit test] move data from register value to GPR_Rx: MM_DUMMY_REG to COLOR(32 bit) */
  995. cmdqRecReadToDataRegister(handle, CMDQ_TEST_MMSYS_DUMMY_PA, CMDQ_DATA_REG_PQ_COLOR);
  996. cmdqRecFlush(handle);
  997. cmdqRecDumpCommand(handle);
  998. cmdqRecDestroy(handle);
  999. cmdq_get_func()->dumpGPR();
  1000. /* verify data */
  1001. data = CMDQ_REG_GET32(CMDQ_GPR_R32(CMDQ_DATA_REG_PQ_COLOR));
  1002. if (data != 0xdeaddead) {
  1003. /* Print error status */
  1004. CMDQ_ERR("[Read 32 bit from GPR_Rx]TEST FAIL: PQ reg value is 0x%08x\n", data);
  1005. }
  1006. data64 = 0LL;
  1007. data64 = CMDQ_REG_GET64_GPR_PX(CMDQ_DATA_REG_PQ_COLOR_DST);
  1008. if (0xbeefbeef != data64) {
  1009. CMDQ_ERR("[Read 64 bit from GPR_Px]TEST FAIL: PQ_DST reg value is 0x%llx\n",
  1010. data64);
  1011. }
  1012. CMDQ_MSG("%s END\n", __func__);
  1013. return;
  1014. #else
  1015. CMDQ_ERR("func:%s failed since CMDQ doesn't support GPR\n", __func__);
  1016. return;
  1017. #endif
  1018. }
  1019. static void testcase_write_reg_from_slot(void)
  1020. {
  1021. #ifdef CMDQ_GPR_SUPPORT
  1022. const uint32_t PATTEN = 0xBCBCBCBC;
  1023. cmdqRecHandle handle;
  1024. cmdqBackupSlotHandle hSlot = 0;
  1025. uint32_t value = 0;
  1026. long long value64 = 0LL;
  1027. const CMDQ_DATA_REGISTER_ENUM dstRegId = CMDQ_DATA_REG_DEBUG;
  1028. const CMDQ_DATA_REGISTER_ENUM srcRegId = CMDQ_DATA_REG_DEBUG_DST;
  1029. CMDQ_MSG("%s\n", __func__);
  1030. /* init */
  1031. CMDQ_REG_SET32(CMDQ_TEST_MMSYS_DUMMY_VA, 0xdeaddead);
  1032. CMDQ_REG_SET32(CMDQ_GPR_R32(dstRegId), 0xdeaddead);
  1033. CMDQ_REG_SET64_GPR_PX(srcRegId, 0xdeaddeaddeaddead);
  1034. cmdqBackupAllocateSlot(&hSlot, 1);
  1035. cmdqBackupWriteSlot(hSlot, 0, PATTEN);
  1036. cmdqBackupReadSlot(hSlot, 0, &value);
  1037. if (PATTEN != value) {
  1038. /* Print error status */
  1039. CMDQ_ERR("%s, slot init failed\n", __func__);
  1040. }
  1041. /* Create cmdqRec */
  1042. cmdqRecCreate(CMDQ_SCENARIO_DEBUG, &handle);
  1043. /* Reset command buffer */
  1044. cmdqRecReset(handle);
  1045. cmdqRecSetSecure(handle, gCmdqTestSecure);
  1046. /* Insert commands to write register with slot's value */
  1047. cmdqRecBackupWriteRegisterFromSlot(handle, hSlot, 0, CMDQ_TEST_MMSYS_DUMMY_PA);
  1048. /* Execute commands */
  1049. cmdqRecFlush(handle);
  1050. /* debug dump command instructions */
  1051. cmdqRecDumpCommand(handle);
  1052. /* we can destroy cmdqRec handle after flush. */
  1053. cmdqRecDestroy(handle);
  1054. /* verify */
  1055. value = CMDQ_REG_GET32(CMDQ_TEST_MMSYS_DUMMY_VA);
  1056. if (PATTEN != value) {
  1057. /* Print error status */
  1058. CMDQ_ERR("%s failed, value:0x%x\n", __func__, value);
  1059. }
  1060. value = CMDQ_REG_GET32(CMDQ_GPR_R32(dstRegId));
  1061. value64 = CMDQ_REG_GET64_GPR_PX(srcRegId);
  1062. CMDQ_LOG("srcGPR(%x):0x%llx\n", srcRegId, value64);
  1063. CMDQ_LOG("dstGPR(%x):0x%08x\n", dstRegId, value);
  1064. /* release result free slot */
  1065. cmdqBackupFreeSlot(hSlot);
  1066. CMDQ_MSG("%s END\n", __func__);
  1067. return;
  1068. #else
  1069. CMDQ_ERR("func:%s failed since CMDQ doesn't support GPR\n", __func__);
  1070. return;
  1071. #endif
  1072. }
  1073. static void testcase_backup_reg_to_slot(void)
  1074. {
  1075. #ifdef CMDQ_GPR_SUPPORT
  1076. cmdqRecHandle handle;
  1077. unsigned long MMSYS_DUMMY_REG = CMDQ_TEST_MMSYS_DUMMY_VA;
  1078. cmdqBackupSlotHandle hSlot = 0;
  1079. int i;
  1080. uint32_t value = 0;
  1081. CMDQ_MSG("%s\n", __func__);
  1082. CMDQ_REG_SET32(MMSYS_DUMMY_REG, 0xdeaddead);
  1083. /* Create cmdqRec */
  1084. cmdqRecCreate(CMDQ_SCENARIO_DEBUG, &handle);
  1085. /* Create Slot */
  1086. cmdqBackupAllocateSlot(&hSlot, 5);
  1087. for (i = 0; i < 5; ++i)
  1088. cmdqBackupWriteSlot(hSlot, i, i);
  1089. for (i = 0; i < 5; ++i) {
  1090. cmdqBackupReadSlot(hSlot, i, &value);
  1091. if (value != i) {
  1092. /* Print error status */
  1093. CMDQ_ERR("testcase_cmdqBackupWriteSlot FAILED!!!!!\n");
  1094. }
  1095. CMDQ_LOG("testcase_cmdqBackupWriteSlot OK!!!!!\n");
  1096. }
  1097. /* Reset command buffer */
  1098. cmdqRecReset(handle);
  1099. cmdqRecSetSecure(handle, gCmdqTestSecure);
  1100. /* Insert commands to backup registers */
  1101. for (i = 0; i < 5; ++i)
  1102. cmdqRecBackupRegisterToSlot(handle, hSlot, i, CMDQ_TEST_MMSYS_DUMMY_PA);
  1103. /* Execute commands */
  1104. cmdqRecFlush(handle);
  1105. /* debug dump command instructions */
  1106. cmdqRecDumpCommand(handle);
  1107. /* we can destroy cmdqRec handle after flush. */
  1108. cmdqRecDestroy(handle);
  1109. /* verify data by reading it back from slot */
  1110. for (i = 0; i < 5; ++i) {
  1111. cmdqBackupReadSlot(hSlot, i, &value);
  1112. CMDQ_LOG("backup slot %d = 0x%08x\n", i, value);
  1113. if (value != 0xdeaddead) {
  1114. /* content error */
  1115. CMDQ_ERR("content error!!!!!!!!!!!!!!!!!!!!\n");
  1116. }
  1117. }
  1118. /* release result free slot */
  1119. cmdqBackupFreeSlot(hSlot);
  1120. CMDQ_MSG("%s END\n", __func__);
  1121. return;
  1122. #else
  1123. CMDQ_ERR("func:%s failed since CMDQ doesn't support GPR\n", __func__);
  1124. return;
  1125. #endif
  1126. }
  1127. static void testcase_update_value_to_slot(void)
  1128. {
  1129. int32_t i;
  1130. uint32_t value;
  1131. cmdqRecHandle handle;
  1132. cmdqBackupSlotHandle hSlot = 0;
  1133. const uint32_t PATTERNS[] = {
  1134. 0xDEAD0000, 0xDEAD0001, 0xDEAD0002, 0xDEAD0003, 0xDEAD0004
  1135. };
  1136. CMDQ_MSG("%s\n", __func__);
  1137. /* Create Slot */
  1138. cmdqBackupAllocateSlot(&hSlot, 5);
  1139. /*use CMDQ to update slot value */
  1140. cmdqRecCreate(CMDQ_SCENARIO_DEBUG, &handle);
  1141. cmdqRecReset(handle);
  1142. cmdqRecSetSecure(handle, gCmdqTestSecure);
  1143. for (i = 0; i < 5; ++i)
  1144. cmdqRecBackupUpdateSlot(handle, hSlot, i, PATTERNS[i]);
  1145. cmdqRecFlush(handle);
  1146. cmdqRecDumpCommand(handle);
  1147. cmdqRecDestroy(handle);
  1148. /* CPU verify value by reading it back from slot */
  1149. for (i = 0; i < 5; ++i) {
  1150. cmdqBackupReadSlot(hSlot, i, &value);
  1151. if (PATTERNS[i] != value) {
  1152. CMDQ_ERR("slot[%d] = 0x%08x...content error! It should be 0x%08x\n",
  1153. i, value, PATTERNS[i]);
  1154. } else {
  1155. CMDQ_LOG("slot[%d] = 0x%08x\n", i, value);
  1156. }
  1157. }
  1158. /* release result free slot */
  1159. cmdqBackupFreeSlot(hSlot);
  1160. CMDQ_MSG("%s END\n", __func__);
  1161. }
  1162. static void testcase_poll(void)
  1163. {
  1164. cmdqRecHandle handle;
  1165. uint32_t value = 0;
  1166. uint32_t pollingVal = 0x00003001;
  1167. CMDQ_MSG("%s\n", __func__);
  1168. CMDQ_REG_SET32(CMDQ_TEST_MMSYS_DUMMY_VA, ~0);
  1169. /* it's too slow that set value after enable CMDQ */
  1170. /* sw timeout will be hanppened before CPU schedule to set value..., so we set value here */
  1171. CMDQ_REG_SET32(CMDQ_TEST_MMSYS_DUMMY_VA, pollingVal);
  1172. value = CMDQ_REG_GET32(CMDQ_TEST_MMSYS_DUMMY_VA);
  1173. CMDQ_MSG("target value is 0x%08x\n", value);
  1174. cmdqRecCreate(CMDQ_SCENARIO_DEBUG, &handle);
  1175. cmdqRecReset(handle);
  1176. cmdqRecSetSecure(handle, gCmdqTestSecure);
  1177. cmdqRecPoll(handle, CMDQ_TEST_MMSYS_DUMMY_PA, pollingVal, ~0);
  1178. cmdqRecFlush(handle);
  1179. cmdqRecDestroy(handle);
  1180. /* value check */
  1181. value = CMDQ_REG_GET32(CMDQ_TEST_MMSYS_DUMMY_VA);
  1182. if (pollingVal != value) {
  1183. /* Print error status */
  1184. CMDQ_ERR("polling target value is 0x%08x\n", value);
  1185. }
  1186. CMDQ_MSG("%s END\n", __func__);
  1187. }
  1188. static void testcase_write_with_mask(void)
  1189. {
  1190. cmdqRecHandle handle;
  1191. const uint32_t PATTERN = (1 << 0) | (1 << 2) | (1 << 16);
  1192. const uint32_t MASK = (1 << 16);
  1193. const uint32_t EXPECT_RESULT = PATTERN & MASK;
  1194. uint32_t value = 0;
  1195. CMDQ_MSG("%s\n", __func__);
  1196. /* set to 0x0 */
  1197. CMDQ_REG_SET32(CMDQ_TEST_MMSYS_DUMMY_VA, 0x0);
  1198. /* use CMDQ to set to PATTERN */
  1199. cmdqRecCreate(CMDQ_SCENARIO_DEBUG, &handle);
  1200. cmdqRecReset(handle);
  1201. cmdqRecSetSecure(handle, gCmdqTestSecure);
  1202. cmdqRecWrite(handle, CMDQ_TEST_MMSYS_DUMMY_PA, PATTERN, MASK);
  1203. cmdqRecFlush(handle);
  1204. cmdqRecDestroy(handle);
  1205. /* value check */
  1206. value = CMDQ_REG_GET32(CMDQ_TEST_MMSYS_DUMMY_VA);
  1207. if (EXPECT_RESULT != value) {
  1208. /* test fail */
  1209. CMDQ_ERR("TEST FAIL: wrote value is 0x%08x, not 0x%08x\n", value, EXPECT_RESULT);
  1210. }
  1211. CMDQ_MSG("%s END\n", __func__);
  1212. }
  1213. static void testcase_write(void)
  1214. {
  1215. cmdqRecHandle handle;
  1216. const uint32_t PATTERN = (1 << 0) | (1 << 2) | (1 << 16);
  1217. uint32_t value = 0;
  1218. CMDQ_MSG("%s\n", __func__);
  1219. /* set to 0xFFFFFFFF */
  1220. CMDQ_REG_SET32(CMDQ_TEST_MMSYS_DUMMY_VA, ~0);
  1221. /* use CMDQ to set to PATTERN */
  1222. cmdqRecCreate(CMDQ_SCENARIO_DEBUG, &handle);
  1223. cmdqRecReset(handle);
  1224. cmdqRecSetSecure(handle, gCmdqTestSecure);
  1225. cmdqRecWrite(handle, CMDQ_TEST_MMSYS_DUMMY_PA, PATTERN, ~0);
  1226. cmdqRecFlush(handle);
  1227. cmdqRecDestroy(handle);
  1228. /* value check */
  1229. value = CMDQ_REG_GET32(CMDQ_TEST_MMSYS_DUMMY_VA);
  1230. if (value != PATTERN) {
  1231. /* test fail */
  1232. CMDQ_ERR("TEST FAIL: wrote value is 0x%08x, not 0x%08x\n", value, PATTERN);
  1233. }
  1234. CMDQ_MSG("%s END\n", __func__);
  1235. }
  1236. static void testcase_prefetch(void)
  1237. {
  1238. cmdqRecHandle handle;
  1239. int i;
  1240. uint32_t value = 0;
  1241. const uint32_t PATTERN = (1 << 0) | (1 << 2) | (1 << 16); /* 0xDEADDEAD; */
  1242. const uint32_t testRegPA = CMDQ_TEST_MMSYS_DUMMY_PA;
  1243. const unsigned long testRegVA = CMDQ_TEST_MMSYS_DUMMY_VA;
  1244. const uint32_t REP_COUNT = 500;
  1245. CMDQ_MSG("%s\n", __func__);
  1246. /* set to 0xFFFFFFFF */
  1247. CMDQ_REG_SET32(testRegVA, ~0);
  1248. /* No prefetch. */
  1249. /* use CMDQ to set to PATTERN */
  1250. cmdqRecCreate(CMDQ_SCENARIO_DEBUG, &handle);
  1251. cmdqRecReset(handle);
  1252. cmdqRecSetSecure(handle, false);
  1253. for (i = 0; i < REP_COUNT; ++i)
  1254. cmdqRecWrite(handle, testRegPA, PATTERN, ~0);
  1255. cmdqRecFlushAsync(handle);
  1256. cmdqRecFlushAsync(handle);
  1257. cmdqRecFlushAsync(handle);
  1258. msleep_interruptible(1000);
  1259. /* use prefetch */
  1260. cmdqRecCreate(CMDQ_SCENARIO_DEBUG_PREFETCH, &handle);
  1261. cmdqRecReset(handle);
  1262. cmdqRecSetSecure(handle, false);
  1263. for (i = 0; i < REP_COUNT; ++i)
  1264. cmdqRecWrite(handle, testRegPA, PATTERN, ~0);
  1265. cmdqRecFlushAsync(handle);
  1266. cmdqRecFlushAsync(handle);
  1267. cmdqRecFlushAsync(handle);
  1268. msleep_interruptible(1000);
  1269. cmdqRecDestroy(handle);
  1270. /* value check */
  1271. value = CMDQ_REG_GET32(testRegVA);
  1272. if (value != PATTERN) {
  1273. /* test fail */
  1274. CMDQ_ERR("TEST FAIL: wrote value is 0x%08x, not 0x%08x\n", value, PATTERN);
  1275. }
  1276. CMDQ_MSG("%s END\n", __func__);
  1277. }
  1278. static void testcase_backup_register(void)
  1279. {
  1280. #ifdef CMDQ_GPR_SUPPORT
  1281. const unsigned long MMSYS_DUMMY_REG = CMDQ_TEST_MMSYS_DUMMY_VA;
  1282. cmdqRecHandle handle;
  1283. int ret = 0;
  1284. uint32_t regAddr[3] = { CMDQ_TEST_MMSYS_DUMMY_PA,
  1285. CMDQ_GPR_R32_PA(CMDQ_DATA_REG_PQ_COLOR),
  1286. CMDQ_GPR_R32_PA(CMDQ_DATA_REG_2D_SHARPNESS_0)
  1287. };
  1288. uint32_t regValue[3] = { 0 };
  1289. CMDQ_MSG("%s\n", __func__);
  1290. CMDQ_REG_SET32(MMSYS_DUMMY_REG, 0xAAAAAAAA);
  1291. CMDQ_REG_SET32(CMDQ_GPR_R32(CMDQ_DATA_REG_PQ_COLOR), 0xBBBBBBBB);
  1292. CMDQ_REG_SET32(CMDQ_GPR_R32(CMDQ_DATA_REG_2D_SHARPNESS_0), 0xCCCCCCCC);
  1293. cmdqRecCreate(CMDQ_SCENARIO_DEBUG, &handle);
  1294. cmdqRecReset(handle);
  1295. cmdqRecSetSecure(handle, gCmdqTestSecure);
  1296. ret = cmdqRecFlushAndReadRegister(handle, 3, regAddr, regValue);
  1297. cmdqRecDestroy(handle);
  1298. if (regValue[0] != 0xAAAAAAAA) {
  1299. /* Print error status */
  1300. CMDQ_ERR("regValue[0] is 0x%08x, wrong!\n", regValue[0]);
  1301. }
  1302. if (regValue[1] != 0xBBBBBBBB) {
  1303. /* Print error status */
  1304. CMDQ_ERR("regValue[1] is 0x%08x, wrong!\n", regValue[1]);
  1305. }
  1306. if (regValue[2] != 0xCCCCCCCC) {
  1307. /* Print error status */
  1308. CMDQ_ERR("regValue[2] is 0x%08x, wrong!\n", regValue[2]);
  1309. }
  1310. CMDQ_MSG("%s END\n", __func__);
  1311. #else
  1312. CMDQ_ERR("func:%s failed since CMDQ doesn't support GPR\n", __func__);
  1313. #endif
  1314. }
  1315. static void testcase_get_result(void)
  1316. {
  1317. #ifdef CMDQ_GPR_SUPPORT
  1318. const unsigned long MMSYS_DUMMY_REG = CMDQ_TEST_MMSYS_DUMMY_VA;
  1319. int i;
  1320. cmdqRecHandle handle;
  1321. int ret = 0;
  1322. cmdqCommandStruct desc = { 0 };
  1323. int registers[1] = { CMDQ_TEST_MMSYS_DUMMY_PA };
  1324. int result[1] = { 0 };
  1325. CMDQ_MSG("%s\n", __func__);
  1326. /* make sure each scenario runs properly with empty commands */
  1327. /* use CMDQ_SCENARIO_PRIMARY_ALL to test */
  1328. /* because it has COLOR0 HW flag */
  1329. cmdqRecCreate(CMDQ_SCENARIO_PRIMARY_ALL, &handle);
  1330. cmdqRecReset(handle);
  1331. cmdqRecSetSecure(handle, gCmdqTestSecure);
  1332. /* insert dummy commands */
  1333. cmdq_rec_finalize_command(handle, false);
  1334. /* init desc attributes after finalize command to ensure correct size and buffer addr */
  1335. desc.scenario = handle->scenario;
  1336. desc.priority = handle->priority;
  1337. desc.engineFlag = handle->engineFlag;
  1338. desc.pVABase = (cmdqU32Ptr_t) (unsigned long)handle->pBuffer;
  1339. desc.blockSize = handle->blockSize;
  1340. desc.regRequest.count = 1;
  1341. desc.regRequest.regAddresses = (cmdqU32Ptr_t) (unsigned long)registers;
  1342. desc.regValue.count = 1;
  1343. desc.regValue.regValues = (cmdqU32Ptr_t) (unsigned long)result;
  1344. desc.secData.isSecure = handle->secData.isSecure;
  1345. desc.secData.addrMetadataCount = 0;
  1346. desc.secData.addrMetadataMaxCount = 0;
  1347. desc.secData.waitCookie = 0;
  1348. desc.secData.resetExecCnt = false;
  1349. CMDQ_REG_SET32(MMSYS_DUMMY_REG, 0xdeaddead);
  1350. /* manually raise the dirty flag */
  1351. cmdqCoreSetEvent(CMDQ_EVENT_MUTEX0_STREAM_EOF);
  1352. cmdqCoreSetEvent(CMDQ_EVENT_MUTEX1_STREAM_EOF);
  1353. cmdqCoreSetEvent(CMDQ_EVENT_MUTEX2_STREAM_EOF);
  1354. cmdqCoreSetEvent(CMDQ_EVENT_MUTEX3_STREAM_EOF);
  1355. for (i = 0; i < 1; ++i) {
  1356. ret = cmdqCoreSubmitTask(&desc);
  1357. if (CMDQ_U32_PTR(desc.regValue.regValues)[0] != 0xdeaddead) {
  1358. CMDQ_ERR("TEST FAIL: reg value is 0x%08x\n",
  1359. CMDQ_U32_PTR(desc.regValue.regValues)[0]);
  1360. }
  1361. }
  1362. cmdqRecDestroy(handle);
  1363. CMDQ_MSG("%s END\n", __func__);
  1364. return;
  1365. #else
  1366. CMDQ_ERR("func:%s failed since CMDQ doesn't support GPR\n", __func__);
  1367. #endif
  1368. }
  1369. static void testcase_emergency_buffer(void)
  1370. {
  1371. /* ensure to define CMDQ_TEST_EMERGENCY_BUFFER in cmdq_core.c */
  1372. const uint32_t longCommandSize = 160 * 1024;
  1373. const uint32_t submitTaskCount = 4;
  1374. cmdqRecHandle handle;
  1375. int32_t i;
  1376. CMDQ_MSG("%s\n", __func__);
  1377. /* force to use emergency buffer */
  1378. if (0 > cmdq_core_enable_emergency_buffer_test(true))
  1379. return;
  1380. /* prepare long command */
  1381. cmdqRecCreate(CMDQ_SCENARIO_DEBUG, &handle);
  1382. cmdqRecReset(handle);
  1383. cmdqRecSetSecure(handle, false);
  1384. for (i = 0; i < (longCommandSize / CMDQ_INST_SIZE); i++)
  1385. cmdqRecReadToDataRegister(handle, CMDQ_TEST_MMSYS_DUMMY_PA, CMDQ_DATA_REG_PQ_COLOR);
  1386. /* submit */
  1387. for (i = 0; i < submitTaskCount; i++) {
  1388. CMDQ_LOG("async submit large command(size: %d), count:%d\n", longCommandSize, i);
  1389. cmdqRecFlushAsync(handle);
  1390. }
  1391. msleep_interruptible(1000);
  1392. /* reset to apply normal memory allocation flow */
  1393. cmdq_core_enable_emergency_buffer_test(false);
  1394. cmdqRecDestroy(handle);
  1395. CMDQ_MSG("%s END\n", __func__);
  1396. }
  1397. static int _testcase_simplest_command_loop_submit(const uint32_t loop, CMDQ_SCENARIO_ENUM scenario,
  1398. const long long engineFlag,
  1399. const bool isSecureTask)
  1400. {
  1401. cmdqRecHandle handle;
  1402. int32_t i;
  1403. CMDQ_MSG("%s\n", __func__);
  1404. cmdqRecCreate(scenario, &handle);
  1405. for (i = 0; i < loop; i++) {
  1406. CMDQ_MSG("pid: %d, flush:%4d, engineFlag:0x%llx, isSecureTask:%d\n",
  1407. current->pid, i, engineFlag, isSecureTask);
  1408. cmdqRecReset(handle);
  1409. cmdqRecSetSecure(handle, isSecureTask);
  1410. handle->engineFlag = engineFlag;
  1411. cmdqRecFlush(handle);
  1412. }
  1413. cmdqRecDestroy(handle);
  1414. CMDQ_MSG("%s END\n", __func__);
  1415. return 0;
  1416. }
  1417. /* threadfn: int (*threadfn)(void *data) */
  1418. static int _testcase_thread_dispatch(void *data)
  1419. {
  1420. long long engineFlag;
  1421. engineFlag = *((long long *)data);
  1422. _testcase_simplest_command_loop_submit(1000, CMDQ_SCENARIO_DEBUG, engineFlag, false);
  1423. return 0;
  1424. }
  1425. static void testcase_thread_dispatch(void)
  1426. {
  1427. char threadName[20];
  1428. struct task_struct *pKThread1;
  1429. struct task_struct *pKThread2;
  1430. const long long engineFlag1 = (0x1 << CMDQ_ENG_ISP_IMGI) | (0x1 << CMDQ_ENG_ISP_IMGO);
  1431. const long long engineFlag2 = (0x1 << CMDQ_ENG_MDP_RDMA0) | (0x1 << CMDQ_ENG_MDP_WDMA);
  1432. CMDQ_MSG("%s\n", __func__);
  1433. CMDQ_MSG("=============== 2 THREAD with different engines ===============\n");
  1434. sprintf(threadName, "cmdqKTHR_%llx", engineFlag1);
  1435. pKThread1 = kthread_run(_testcase_thread_dispatch, (void *)(&engineFlag1), threadName);
  1436. if (IS_ERR(pKThread1)) {
  1437. CMDQ_ERR("create thread failed, thread:%s\n", threadName);
  1438. return;
  1439. }
  1440. sprintf(threadName, "cmdqKTHR_%llx", engineFlag2);
  1441. pKThread2 = kthread_run(_testcase_thread_dispatch, (void *)(&engineFlag2), threadName);
  1442. if (IS_ERR(pKThread2)) {
  1443. CMDQ_ERR("create thread failed, thread:%s\n", threadName);
  1444. return;
  1445. }
  1446. msleep_interruptible(5 * 1000);
  1447. /* ensure both thread execute all command */
  1448. _testcase_simplest_command_loop_submit(1, CMDQ_SCENARIO_DEBUG, engineFlag1, false);
  1449. _testcase_simplest_command_loop_submit(1, CMDQ_SCENARIO_DEBUG, engineFlag2, false);
  1450. CMDQ_MSG("%s END\n", __func__);
  1451. }
  1452. static int _testcase_full_thread_array(void *data)
  1453. {
  1454. /* this testcase will be passed only when cmdqSecDr support async config mode because */
  1455. /* never execute event setting till IWC back to NWd */
  1456. cmdqRecHandle handle;
  1457. int32_t i;
  1458. /* clearn event first */
  1459. CMDQ_REG_SET32(CMDQ_SYNC_TOKEN_UPD, CMDQ_SYNC_TOKEN_USER_0);
  1460. cmdqRecCreate(CMDQ_SCENARIO_DEBUG, &handle);
  1461. /* specify engine flag in order to dispatch all tasks to the same HW thread */
  1462. handle->engineFlag = (1LL << CMDQ_ENG_MDP_RDMA0);
  1463. cmdqRecReset(handle);
  1464. cmdqRecSetSecure(handle, gCmdqTestSecure);
  1465. cmdqRecWaitNoClear(handle, CMDQ_SYNC_TOKEN_USER_0);
  1466. for (i = 0; i < 50; i++) {
  1467. CMDQ_LOG("pid: %d, flush:%6d\n", current->pid, i);
  1468. if (40 == i) {
  1469. CMDQ_LOG("set token: %d to 1\n", CMDQ_SYNC_TOKEN_USER_0);
  1470. cmdqCoreSetEvent(CMDQ_SYNC_TOKEN_USER_0);
  1471. }
  1472. cmdqRecFlushAsync(handle);
  1473. }
  1474. cmdqRecDestroy(handle);
  1475. return 0;
  1476. }
  1477. static void testcase_full_thread_array(void)
  1478. {
  1479. char threadName[20];
  1480. struct task_struct *pKThread;
  1481. CMDQ_MSG("%s\n", __func__);
  1482. sprintf(threadName, "cmdqKTHR");
  1483. pKThread = kthread_run(_testcase_full_thread_array, NULL, threadName);
  1484. if (IS_ERR(pKThread)) {
  1485. /* create thread failed */
  1486. CMDQ_ERR("create thread failed, thread:%s\n", threadName);
  1487. }
  1488. msleep_interruptible(5 * 1000);
  1489. CMDQ_MSG("%s END\n", __func__);
  1490. }
  1491. static void testcase_module_full_dump(void)
  1492. {
  1493. cmdqRecHandle handle;
  1494. const bool alreadyEnableLog = cmdq_core_should_print_msg();
  1495. CMDQ_MSG("%s\n", __func__);
  1496. /* enable full dump */
  1497. if (false == alreadyEnableLog)
  1498. cmdq_core_set_log_level(1);
  1499. cmdqRecCreate(CMDQ_SCENARIO_DEBUG, &handle);
  1500. /* clean SW token to invoke SW timeout latter */
  1501. CMDQ_REG_SET32(CMDQ_SYNC_TOKEN_UPD, CMDQ_SYNC_TOKEN_USER_0);
  1502. /* turn on ALL except DISP engine flag to test dump */
  1503. handle->engineFlag = ~(CMDQ_ENG_DISP_GROUP_BITS);
  1504. CMDQ_LOG("%s, engine: 0x%llx, it's a timeout case\n", __func__, handle->engineFlag);
  1505. cmdqRecReset(handle);
  1506. cmdqRecSetSecure(handle, false);
  1507. cmdqRecWaitNoClear(handle, CMDQ_SYNC_TOKEN_USER_0);
  1508. cmdqRecFlush(handle);
  1509. /* disable full dump */
  1510. if (false == alreadyEnableLog)
  1511. cmdq_core_set_log_level(0);
  1512. CMDQ_MSG("%s END\n", __func__);
  1513. }
  1514. static void testcase_profile_marker(void)
  1515. {
  1516. cmdqRecHandle handle;
  1517. /* const uint32_t PATTERN = (1 << 0) | (1 << 2) | (1 << 16); */
  1518. /* uint32_t value = 0; */
  1519. CMDQ_MSG("%s\n", __func__);
  1520. CMDQ_MSG("%s: write op without profile marker\n", __func__);
  1521. cmdqRecCreate(CMDQ_SCENARIO_DEBUG, &handle);
  1522. cmdqRecReset(handle);
  1523. cmdqRecWrite(handle, CMDQ_TEST_MMSYS_DUMMY_PA, 0xBCBCBCBC, ~0);
  1524. cmdqRecFlush(handle);
  1525. CMDQ_MSG("%s: write op with profile marker\n", __func__);
  1526. cmdqRecReset(handle);
  1527. cmdqRecWrite(handle, CMDQ_TEST_MMSYS_DUMMY_PA, 0x11111111, ~0);
  1528. cmdqRecProfileMarker(handle, "WRI_BEGIN");
  1529. cmdqRecWrite(handle, CMDQ_TEST_MMSYS_DUMMY_PA, 0x22222222, ~0);
  1530. cmdqRecProfileMarker(handle, "WRI_END");
  1531. cmdqRecDumpCommand(handle);
  1532. cmdqRecFlush(handle);
  1533. cmdqRecDestroy(handle);
  1534. CMDQ_MSG("%s END\n", __func__);
  1535. }
  1536. static void testcase_estimate_command_exec_time(void)
  1537. {
  1538. cmdqRecHandle handle;
  1539. cmdqBackupSlotHandle hSlot = 0;
  1540. cmdqBackupAllocateSlot(&hSlot, 1);
  1541. cmdqRecCreate(CMDQ_SCENARIO_DEBUG, &handle);
  1542. cmdqRecReset(handle);
  1543. CMDQ_MSG("%s\n", __func__);
  1544. CMDQ_LOG("=====write(1), write_w_mask(2), poll(2), wait(2), sync(1), eof(1), jump(1)\n");
  1545. cmdqRecWrite(handle, CMDQ_TEST_MMSYS_DUMMY_PA, 0xBBBBBBBA, ~0);
  1546. cmdqRecWrite(handle, CMDQ_TEST_MMSYS_DUMMY_PA, 0xBBBBBBBB, 0x1);
  1547. cmdqRecWrite(handle, CMDQ_TEST_MMSYS_DUMMY_PA, 0xBBBBBBBC, 0x3);
  1548. cmdqRecPoll(handle, CMDQ_TEST_MMSYS_DUMMY_PA, 0xCCCCCCCA, ~0);
  1549. cmdqRecPoll(handle, CMDQ_TEST_MMSYS_DUMMY_PA, 0xCCCCCCCB, 0x1);
  1550. cmdqRecWait(handle, CMDQ_SYNC_TOKEN_USER_0);
  1551. cmdqRecWaitNoClear(handle, CMDQ_SYNC_TOKEN_USER_0);
  1552. cmdqRecClearEventToken(handle, CMDQ_SYNC_TOKEN_USER_1);
  1553. cmdqRecDumpCommand(handle);
  1554. cmdqRecEstimateCommandExecTime(handle);
  1555. CMDQ_LOG("=====slots...\n");
  1556. cmdqRecReset(handle);
  1557. cmdqRecBackupRegisterToSlot(handle, hSlot, 0, CMDQ_TEST_MMSYS_DUMMY_PA);
  1558. cmdqRecBackupWriteRegisterFromSlot(handle, hSlot, 0, CMDQ_TEST_MMSYS_DUMMY_PA);
  1559. cmdqRecBackupUpdateSlot(handle, hSlot, 0, 0xDEADDEAD);
  1560. cmdqRecDumpCommand(handle);
  1561. cmdqRecEstimateCommandExecTime(handle);
  1562. CMDQ_MSG("%s END\n", __func__);
  1563. cmdqBackupFreeSlot(hSlot);
  1564. cmdqRecDestroy(handle);
  1565. }
  1566. #ifdef CMDQ_SECURE_PATH_SUPPORT
  1567. #include "cmdq_sec.h"
  1568. #include "cmdq_sec_iwc_common.h"
  1569. #include "cmdqSecTl_Api.h"
  1570. int32_t cmdq_sec_submit_to_secure_world_async_unlocked(uint32_t iwcCommand,
  1571. TaskStruct *pTask, int32_t thread,
  1572. CmdqSecFillIwcCB iwcFillCB, void *data);
  1573. #endif
  1574. void testcase_secure_basic(void)
  1575. {
  1576. #ifdef CMDQ_SECURE_PATH_SUPPORT
  1577. int32_t status = 0;
  1578. CMDQ_MSG("%s\n", __func__);
  1579. do {
  1580. CMDQ_MSG("=========== Hello cmdqSecTl ===========\n ");
  1581. status =
  1582. cmdq_sec_submit_to_secure_world_async_unlocked(CMD_CMDQ_TL_TEST_HELLO_TL, NULL,
  1583. CMDQ_INVALID_THREAD, NULL, NULL);
  1584. if (0 > status) {
  1585. /* entry cmdqSecTL failed */
  1586. CMDQ_ERR("entry cmdqSecTL failed, status:%d\n", status);
  1587. }
  1588. CMDQ_MSG("=========== Hello cmdqSecDr ===========\n ");
  1589. status =
  1590. cmdq_sec_submit_to_secure_world_async_unlocked(CMD_CMDQ_TL_TEST_DUMMY, NULL,
  1591. CMDQ_INVALID_THREAD, NULL, NULL);
  1592. if (0 > status) {
  1593. /* entry cmdqSecDr failed */
  1594. CMDQ_ERR("entry cmdqSecDr failed, status:%d\n", status);
  1595. }
  1596. } while (0);
  1597. CMDQ_MSG("%s END\n", __func__);
  1598. #endif
  1599. }
  1600. void testcase_secure_disp_scenario(void)
  1601. {
  1602. #ifdef CMDQ_SECURE_PATH_SUPPORT
  1603. /* note: this case used to verify command compose in secure world. */
  1604. /* It must test when DISP driver has switched primary DISP to secure path, */
  1605. /* otherwise we should disable "enable GCE" in SWd in order to prevent phone hang */
  1606. cmdqRecHandle hDISP;
  1607. cmdqRecHandle hDisableDISP;
  1608. const uint32_t PATTERN = (1 << 0) | (1 << 2) | (1 << 16);
  1609. CMDQ_MSG("%s\n", __func__);
  1610. CMDQ_LOG("=========== secure primary path ===========\n");
  1611. cmdqRecCreate(CMDQ_SCENARIO_PRIMARY_DISP, &hDISP);
  1612. cmdqRecReset(hDISP);
  1613. cmdqRecSetSecure(hDISP, true);
  1614. cmdqRecWrite(hDISP, CMDQ_TEST_MMSYS_DUMMY_PA, PATTERN, ~0);
  1615. cmdqRecFlush(hDISP);
  1616. cmdqRecDestroy(hDISP);
  1617. CMDQ_LOG("=========== disp secure primary path ===========\n");
  1618. cmdqRecCreate(CMDQ_SCENARIO_DISP_PRIMARY_DISABLE_SECURE_PATH, &hDisableDISP);
  1619. cmdqRecReset(hDisableDISP);
  1620. cmdqRecSetSecure(hDisableDISP, true);
  1621. cmdqRecWrite(hDisableDISP, CMDQ_TEST_MMSYS_DUMMY_PA, PATTERN, ~0);
  1622. cmdqRecFlush(hDisableDISP);
  1623. cmdqRecDestroy(hDisableDISP);
  1624. CMDQ_MSG("%s END\n", __func__);
  1625. #endif
  1626. }
  1627. void testcase_secure_meta_data(void)
  1628. {
  1629. #ifdef CMDQ_SECURE_PATH_SUPPORT
  1630. cmdqRecHandle hReqMDP;
  1631. cmdqRecHandle hReqDISP;
  1632. const uint32_t PATTERN_MDP = (1 << 0) | (1 << 2) | (1 << 16);
  1633. const uint32_t PATTERN_DISP = 0xBCBCBCBC;
  1634. uint32_t value = 0;
  1635. CMDQ_MSG("%s\n", __func__);
  1636. /* set to 0xFFFFFFFF */
  1637. CMDQ_REG_SET32(CMDQ_TEST_MMSYS_DUMMY_VA, ~0);
  1638. CMDQ_MSG("=========== MDP case ===========\n");
  1639. cmdqRecCreate(CMDQ_SCENARIO_DEBUG, &hReqMDP);
  1640. cmdqRecReset(hReqMDP);
  1641. cmdqRecSetSecure(hReqMDP, true);
  1642. /* specify use MDP engine */
  1643. hReqMDP->engineFlag =
  1644. (1LL << CMDQ_ENG_MDP_RDMA0) | (1LL << CMDQ_ENG_MDP_WDMA) | (1LL << CMDQ_ENG_MDP_WROT0);
  1645. /* enable secure test */
  1646. cmdqRecSecureEnableDAPC(hReqMDP,
  1647. (1LL << CMDQ_ENG_MDP_RDMA0) | (1LL << CMDQ_ENG_MDP_WDMA) |
  1648. (1LL << CMDQ_ENG_MDP_WROT0));
  1649. cmdqRecSecureEnablePortSecurity(hReqMDP,
  1650. (1LL << CMDQ_ENG_MDP_RDMA0) | (1LL << CMDQ_ENG_MDP_WDMA) |
  1651. (1LL << CMDQ_ENG_MDP_WROT0));
  1652. /* record command */
  1653. cmdqRecWrite(hReqMDP, CMDQ_TEST_MMSYS_DUMMY_PA, PATTERN_MDP, ~0);
  1654. cmdqRecFlush(hReqMDP);
  1655. cmdqRecDestroy(hReqMDP);
  1656. /* value check */
  1657. value = CMDQ_REG_GET32(CMDQ_TEST_MMSYS_DUMMY_VA);
  1658. if (value != PATTERN_MDP) {
  1659. /* test fail */
  1660. CMDQ_ERR("TEST FAIL: wrote value is 0x%08x, not 0x%08x\n", value, PATTERN_MDP);
  1661. }
  1662. CMDQ_MSG("=========== DISP case ===========\n");
  1663. cmdqRecCreate(CMDQ_SCENARIO_SUB_DISP, &hReqDISP);
  1664. cmdqRecReset(hReqDISP);
  1665. cmdqRecSetSecure(hReqDISP, true);
  1666. /* enable secure test */
  1667. cmdqRecSecureEnableDAPC(hReqDISP, (1LL << CMDQ_ENG_DISP_WDMA1));
  1668. cmdqRecSecureEnablePortSecurity(hReqDISP, (1LL << CMDQ_ENG_DISP_WDMA1));
  1669. /* record command */
  1670. cmdqRecWrite(hReqDISP, CMDQ_TEST_MMSYS_DUMMY_PA, PATTERN_DISP, ~0);
  1671. cmdqRecFlush(hReqDISP);
  1672. cmdqRecDestroy(hReqDISP);
  1673. /* value check */
  1674. value = CMDQ_REG_GET32(CMDQ_TEST_MMSYS_DUMMY_VA);
  1675. if (value != PATTERN_DISP) {
  1676. /* test fail */
  1677. CMDQ_ERR("TEST FAIL: wrote value is 0x%08x, not 0x%08x\n", value, PATTERN_DISP);
  1678. }
  1679. CMDQ_MSG("%s END\n", __func__);
  1680. #else
  1681. CMDQ_ERR("%s failed since not support secure path\n", __func__);
  1682. #endif
  1683. }
  1684. void testcase_submit_after_error_happened(void)
  1685. {
  1686. cmdqRecHandle handle;
  1687. const unsigned long MMSYS_DUMMY_REG = CMDQ_TEST_MMSYS_DUMMY_VA;
  1688. const uint32_t pollingVal = 0x00003001;
  1689. CMDQ_MSG("%s\n", __func__);
  1690. CMDQ_MSG("=========== timeout case ===========\n");
  1691. /* let poll INIFINITE */
  1692. /* CMDQ_REG_SET32(MMSYS_DUMMY_REG, pollingVal); */
  1693. CMDQ_REG_SET32(MMSYS_DUMMY_REG, ~0);
  1694. cmdqRecCreate(CMDQ_SCENARIO_DEBUG, &handle);
  1695. cmdqRecReset(handle);
  1696. cmdqRecSetSecure(handle, gCmdqTestSecure);
  1697. cmdqRecPoll(handle, CMDQ_TEST_MMSYS_DUMMY_PA, pollingVal, ~0);
  1698. cmdqRecFlush(handle);
  1699. CMDQ_MSG("=========== okay case ===========\n");
  1700. _testcase_simplest_command_loop_submit(1, CMDQ_SCENARIO_DEBUG, 0, gCmdqTestSecure);
  1701. /* clear up */
  1702. cmdqRecDestroy(handle);
  1703. CMDQ_MSG("%s END\n", __func__);
  1704. }
  1705. void testcase_write_stress_test(void)
  1706. {
  1707. int32_t loop;
  1708. CMDQ_MSG("%s\n", __func__);
  1709. loop = 1;
  1710. CMDQ_MSG("=============== loop x %d ===============\n", loop);
  1711. _testcase_simplest_command_loop_submit(loop, CMDQ_SCENARIO_DEBUG, 0, gCmdqTestSecure);
  1712. loop = 100;
  1713. CMDQ_MSG("=============== loop x %d ===============\n", loop);
  1714. _testcase_simplest_command_loop_submit(loop, CMDQ_SCENARIO_DEBUG, 0, gCmdqTestSecure);
  1715. CMDQ_MSG("%s END\n", __func__);
  1716. }
  1717. void testcase_prefetch_multiple_command(void)
  1718. {
  1719. #define TEST_PREFETCH_MARKER_LOOP 2
  1720. int32_t i;
  1721. int32_t ret;
  1722. cmdqRecHandle handle[TEST_PREFETCH_MARKER_LOOP] = { 0 };
  1723. TaskStruct *pTask[TEST_PREFETCH_MARKER_LOOP] = { 0 };
  1724. /* clear token */
  1725. CMDQ_REG_SET32(CMDQ_SYNC_TOKEN_UPD, CMDQ_SYNC_TOKEN_USER_0);
  1726. CMDQ_MSG("%s\n", __func__);
  1727. for (i = 0; i < TEST_PREFETCH_MARKER_LOOP; i++) {
  1728. CMDQ_MSG("=============== flush:%d/%d ===============\n",
  1729. i, TEST_PREFETCH_MARKER_LOOP);
  1730. cmdqRecCreate(CMDQ_SCENARIO_DEBUG_PREFETCH, &(handle[i]));
  1731. cmdqRecReset(handle[i]);
  1732. cmdqRecSetSecure(handle[i], false);
  1733. /* record instructions which needs prefetch */
  1734. cmdqRecEnablePrefetch(handle[i]);
  1735. cmdqRecWait(handle[i], CMDQ_SYNC_TOKEN_USER_0);
  1736. cmdqRecDisablePrefetch(handle[i]);
  1737. /* record instructions which does not need prefetch */
  1738. cmdqRecWrite(handle[i], CMDQ_TEST_MMSYS_DUMMY_PA, 0x3000, ~0);
  1739. cmdq_rec_finalize_command(handle[i], false);
  1740. cmdqRecDumpCommand(handle[i]);
  1741. ret = _test_submit_async(handle[i], &pTask[i]);
  1742. }
  1743. for (i = 0; i < TEST_PREFETCH_MARKER_LOOP; ++i) {
  1744. if (NULL == pTask[i]) {
  1745. CMDQ_ERR("%s pTask[%d] is NULL\n ", __func__, i);
  1746. continue;
  1747. }
  1748. cmdqCoreSetEvent(CMDQ_SYNC_TOKEN_USER_0);
  1749. msleep_interruptible(100);
  1750. CMDQ_MSG("wait 0x%p, i:%2d========\n", pTask[i], i);
  1751. ret = cmdqCoreWaitAndReleaseTask(pTask[i], 500);
  1752. cmdqRecDestroy(handle[i]);
  1753. }
  1754. CMDQ_MSG("%s END\n", __func__);
  1755. }
  1756. #ifdef CMDQ_SECURE_PATH_SUPPORT
  1757. static int _testcase_concurrency(void *data)
  1758. {
  1759. uint32_t securePath;
  1760. securePath = *((uint32_t *) data);
  1761. CMDQ_MSG("start secure(%d) path\n", securePath);
  1762. _testcase_simplest_command_loop_submit(1000, CMDQ_SCENARIO_DEBUG,
  1763. (0x1 << CMDQ_ENG_MDP_RSZ0), securePath);
  1764. return 0;
  1765. }
  1766. #endif
  1767. static void testcase_concurrency_for_normal_path_and_secure_path(void)
  1768. {
  1769. #ifdef CMDQ_SECURE_PATH_SUPPORT
  1770. struct task_struct *pKThread1;
  1771. struct task_struct *pKThread2;
  1772. const uint32_t securePath[2] = { 0, 1 };
  1773. CMDQ_MSG("%s\n", __func__);
  1774. pKThread1 = kthread_run(_testcase_concurrency, (void *)(&securePath[0]), "cmdqNormal");
  1775. if (IS_ERR(pKThread1)) {
  1776. CMDQ_ERR("create cmdqNormal failed\n");
  1777. return;
  1778. }
  1779. pKThread2 = kthread_run(_testcase_concurrency, (void *)(&securePath[1]), "cmdqSecure");
  1780. if (IS_ERR(pKThread2)) {
  1781. CMDQ_ERR("create cmdqSecure failed\n");
  1782. return;
  1783. }
  1784. msleep_interruptible(5 * 1000);
  1785. /* ensure both thread execute all command */
  1786. _testcase_simplest_command_loop_submit(1, CMDQ_SCENARIO_DEBUG, 0x0, false);
  1787. CMDQ_MSG("%s END\n", __func__);
  1788. return;
  1789. #endif
  1790. }
  1791. void testcase_async_write_stress_test(void)
  1792. {
  1793. #if 0
  1794. #define LOOP 100
  1795. int32_t i;
  1796. int32_t ret;
  1797. cmdqRecHandle handle[LOOP] = { 0 };
  1798. TaskStruct *pTask[LOOP] = { 0 };
  1799. /* clear token */
  1800. CMDQ_REG_SET32(CMDQ_SYNC_TOKEN_UPD, CMDQ_SYNC_TOKEN_USER_0);
  1801. CMDQ_MSG("%s\n", __func__);
  1802. for (i = 0; i < LOOP; i++) {
  1803. CMDQ_MSG("=============== flush:%d/%d ===============\n", i, LOOP);
  1804. cmdqRecCreate(CMDQ_SCENARIO_DEBUG, &(handle[i]));
  1805. cmdqRecReset(handle[i]);
  1806. cmdqRecSetSecure(handle[i], gCmdqTestSecure);
  1807. cmdqRecWait(handle[i], CMDQ_SYNC_TOKEN_USER_0);
  1808. cmdq_rec_finalize_command(handle[i], false);
  1809. ret = _test_submit_async(handle[i], &pTask[i]);
  1810. }
  1811. /* release token and wait them */
  1812. for (i = 0; i < LOOP; ++i) {
  1813. if (NULL == pTask[i]) {
  1814. CMDQ_ERR("%s pTask[%d] is NULL\n ", __func__, i);
  1815. continue;
  1816. }
  1817. cmdqCoreSetEvent(CMDQ_SYNC_TOKEN_USER_0);
  1818. msleep_interruptible(100);
  1819. CMDQ_MSG("wait 0x%p, i:%2d========\n", pTask[i], i);
  1820. ret = cmdqCoreWaitAndReleaseTask(pTask[i], 500);
  1821. cmdqRecDestroy(handle[i]);
  1822. }
  1823. CMDQ_MSG("%s END\n", __func__);
  1824. #endif
  1825. }
  1826. static void testcase_nonsuspend_irq(void)
  1827. {
  1828. cmdqRecHandle handle, handle2;
  1829. TaskStruct *pTask, *pTask2;
  1830. const uint32_t PATTERN = (1 << 0) | (1 << 2) | (1 << 16);
  1831. uint32_t value = 0;
  1832. CMDQ_MSG("%s\n", __func__);
  1833. /* clear token */
  1834. CMDQ_REG_SET32(CMDQ_SYNC_TOKEN_UPD, CMDQ_SYNC_TOKEN_USER_0);
  1835. /* set to 0xFFFFFFFF */
  1836. CMDQ_REG_SET32(CMDQ_TEST_MMSYS_DUMMY_VA, ~0);
  1837. /* use CMDQ to set to PATTERN */
  1838. cmdqRecCreate(CMDQ_SCENARIO_DEBUG, &handle);
  1839. cmdqRecReset(handle);
  1840. cmdqRecSetSecure(handle, gCmdqTestSecure);
  1841. handle->engineFlag = (1LL << CMDQ_ENG_MDP_RDMA0);
  1842. cmdqRecWrite(handle, CMDQ_TEST_MMSYS_DUMMY_PA, PATTERN, ~0);
  1843. cmdqRecWait(handle, CMDQ_SYNC_TOKEN_USER_0);
  1844. cmdq_rec_finalize_command(handle, false);
  1845. cmdqRecCreate(CMDQ_SCENARIO_DEBUG, &handle2);
  1846. cmdqRecReset(handle2);
  1847. cmdqRecSetSecure(handle2, gCmdqTestSecure);
  1848. handle2->engineFlag = (1LL << CMDQ_ENG_MDP_RDMA0);
  1849. /* force GCE to wait in second command before EOC */
  1850. cmdqRecWait(handle2, CMDQ_SYNC_TOKEN_USER_0);
  1851. cmdq_rec_finalize_command(handle2, false);
  1852. _test_submit_async(handle, &pTask);
  1853. _test_submit_async(handle2, &pTask2);
  1854. msleep_interruptible(500);
  1855. cmdqCoreSetEvent(CMDQ_SYNC_TOKEN_USER_0);
  1856. /* test code: use to trigger GCE continue test command, put in cmdq_core::handleIRQ to test */
  1857. cmdqCoreSetEvent(CMDQ_SYNC_TOKEN_USER_0);
  1858. CMDQ_MSG("IRQ: After set user sw token\n");
  1859. cmdqCoreWaitAndReleaseTask(pTask, 500);
  1860. cmdqCoreWaitAndReleaseTask(pTask2, 500);
  1861. cmdqRecDestroy(handle);
  1862. cmdqRecDestroy(handle2);
  1863. /* value check */
  1864. value = CMDQ_REG_GET32(CMDQ_TEST_MMSYS_DUMMY_VA);
  1865. if (value != PATTERN) {
  1866. /* test fail */
  1867. CMDQ_ERR("TEST FAIL: wrote value is 0x%08x, not 0x%08x\n", value, PATTERN);
  1868. }
  1869. CMDQ_MSG("%s END\n", __func__);
  1870. }
  1871. static void testcase_module_full_mdp_engine(void)
  1872. {
  1873. cmdqRecHandle handle;
  1874. const bool alreadyEnableLog = cmdq_core_should_print_msg();
  1875. CMDQ_MSG("%s\n", __func__);
  1876. /* enable full dump */
  1877. if (false == alreadyEnableLog)
  1878. cmdq_core_set_log_level(1);
  1879. cmdqRecCreate(CMDQ_SCENARIO_DEBUG, &handle);
  1880. /* turn on ALL except DISP engine flag to test clock operation */
  1881. handle->engineFlag = ~(CMDQ_ENG_DISP_GROUP_BITS);
  1882. CMDQ_LOG("%s, engine: 0x%llx, it's a engine clock test case\n",
  1883. __func__, handle->engineFlag);
  1884. cmdqRecReset(handle);
  1885. cmdqRecSetSecure(handle, false);
  1886. cmdqRecFlush(handle);
  1887. /* disable full dump */
  1888. if (false == alreadyEnableLog)
  1889. cmdq_core_set_log_level(0);
  1890. CMDQ_MSG("%s END\n", __func__);
  1891. }
  1892. static void testcase_trigger_engine_dispatch_check(void)
  1893. {
  1894. cmdqRecHandle handle, handle2, hTrigger;
  1895. TaskStruct *pTask;
  1896. const uint32_t PATTERN = (1 << 0) | (1 << 2) | (1 << 16);
  1897. uint32_t value = 0;
  1898. uint32_t loopIndex = 0;
  1899. CMDQ_MSG("%s\n", __func__);
  1900. /* Create first task and run without wait */
  1901. /* set to 0xFFFFFFFF */
  1902. CMDQ_REG_SET32(CMDQ_TEST_MMSYS_DUMMY_VA, ~0);
  1903. /* use CMDQ to set to PATTERN */
  1904. cmdqRecCreate(CMDQ_SCENARIO_DEBUG, &handle);
  1905. cmdqRecReset(handle);
  1906. cmdqRecSetSecure(handle, gCmdqTestSecure);
  1907. handle->engineFlag = (1LL << CMDQ_ENG_MDP_RDMA0);
  1908. cmdq_rec_finalize_command(handle, false);
  1909. _test_submit_async(handle, &pTask);
  1910. /* Create trigger loop */
  1911. cmdqRecCreate(CMDQ_SCENARIO_TRIGGER_LOOP, &hTrigger);
  1912. cmdqRecReset(hTrigger);
  1913. cmdqRecWait(hTrigger, CMDQ_SYNC_TOKEN_USER_0);
  1914. cmdqRecStartLoop(hTrigger);
  1915. /* Sleep to let trigger loop run fow a while */
  1916. CMDQ_MSG("%s before start sleep and trigger token\n", __func__);
  1917. for (loopIndex = 0; loopIndex < 10; loopIndex++) {
  1918. msleep_interruptible(500);
  1919. cmdqCoreSetEvent(CMDQ_SYNC_TOKEN_USER_0);
  1920. CMDQ_MSG("%s after sleep 5000 and send (%d)\n", __func__, loopIndex);
  1921. }
  1922. /* Create second task and should run well */
  1923. cmdqRecCreate(CMDQ_SCENARIO_DEBUG, &handle2);
  1924. cmdqRecReset(handle2);
  1925. cmdqRecSetSecure(handle2, gCmdqTestSecure);
  1926. handle2->engineFlag = (1LL << CMDQ_ENG_MDP_RDMA0);
  1927. cmdqRecWrite(handle2, CMDQ_TEST_MMSYS_DUMMY_PA, PATTERN, ~0);
  1928. cmdqRecFlush(handle2);
  1929. cmdqRecDestroy(handle2);
  1930. /* Call wait to release first task */
  1931. cmdqCoreWaitAndReleaseTask(pTask, 500);
  1932. cmdqRecDestroy(handle);
  1933. cmdqRecDestroy(hTrigger);
  1934. /* value check */
  1935. value = CMDQ_REG_GET32(CMDQ_TEST_MMSYS_DUMMY_VA);
  1936. if (value != PATTERN) {
  1937. /* test fail */
  1938. CMDQ_ERR("TEST FAIL: wrote value is 0x%08x, not 0x%08x\n", value, PATTERN);
  1939. }
  1940. CMDQ_MSG("%s END\n", __func__);
  1941. }
  1942. static void testcase_complicated_engine_thread(void)
  1943. {
  1944. #define TASK_COUNT 6
  1945. cmdqRecHandle handle[TASK_COUNT] = { 0 };
  1946. TaskStruct *pTask[TASK_COUNT] = { 0 };
  1947. uint64_t engineFlag[TASK_COUNT] = { 0 };
  1948. uint32_t taskIndex = 0;
  1949. CMDQ_MSG("%s\n", __func__);
  1950. /* clear token */
  1951. CMDQ_REG_SET32(CMDQ_SYNC_TOKEN_UPD, CMDQ_SYNC_TOKEN_USER_0);
  1952. /* config engine flag for test */
  1953. engineFlag[0] = (1LL << CMDQ_ENG_MDP_RDMA0);
  1954. engineFlag[1] = (1LL << CMDQ_ENG_MDP_RDMA0) | (1LL << CMDQ_ENG_MDP_RSZ0);
  1955. engineFlag[2] = (1LL << CMDQ_ENG_MDP_RSZ0);
  1956. engineFlag[3] = (1LL << CMDQ_ENG_MDP_TDSHP0);
  1957. engineFlag[4] = (1LL << CMDQ_ENG_MDP_RDMA0) | (1LL << CMDQ_ENG_MDP_TDSHP0);
  1958. engineFlag[5] = (1LL << CMDQ_ENG_MDP_TDSHP0) | (1LL << CMDQ_ENG_MDP_RSZ0);
  1959. for (taskIndex = 0; taskIndex < TASK_COUNT; taskIndex++) {
  1960. /* Create task and run with wait */
  1961. cmdqRecCreate(CMDQ_SCENARIO_DEBUG, &handle[taskIndex]);
  1962. cmdqRecReset(handle[taskIndex]);
  1963. cmdqRecSetSecure(handle[taskIndex], gCmdqTestSecure);
  1964. handle[taskIndex]->engineFlag = engineFlag[taskIndex];
  1965. cmdqRecWait(handle[taskIndex], CMDQ_SYNC_TOKEN_USER_0);
  1966. cmdq_rec_finalize_command(handle[taskIndex], false);
  1967. _test_submit_async(handle[taskIndex], &pTask[taskIndex]);
  1968. }
  1969. for (taskIndex = 0; taskIndex < TASK_COUNT; taskIndex++) {
  1970. cmdqCoreSetEvent(CMDQ_SYNC_TOKEN_USER_0);
  1971. /* Call wait to release task */
  1972. cmdqCoreWaitAndReleaseTask(pTask[taskIndex], 500);
  1973. cmdqRecDestroy(handle[taskIndex]);
  1974. msleep_interruptible(1000);
  1975. }
  1976. CMDQ_MSG("%s END\n", __func__);
  1977. }
  1978. static void testcase_append_task_verify(void)
  1979. {
  1980. cmdqRecHandle handle, handle2;
  1981. TaskStruct *pTask, *pTask2;
  1982. const uint32_t PATTERN = (1 << 0) | (1 << 2) | (1 << 16);
  1983. uint32_t value = 0;
  1984. uint32_t loopIndex = 0;
  1985. CMDQ_MSG("%s\n", __func__);
  1986. cmdqRecCreate(CMDQ_SCENARIO_DEBUG_PREFETCH, &handle);
  1987. cmdqRecCreate(CMDQ_SCENARIO_DEBUG_PREFETCH, &handle2);
  1988. for (loopIndex = 0; loopIndex < 2; loopIndex++) {
  1989. /* clear token */
  1990. CMDQ_REG_SET32(CMDQ_SYNC_TOKEN_UPD, CMDQ_SYNC_TOKEN_USER_0);
  1991. /* clear dummy register */
  1992. CMDQ_REG_SET32(CMDQ_TEST_MMSYS_DUMMY_VA, ~0);
  1993. /* Create first task and run with wait */
  1994. /* use CMDQ to set to PATTERN */
  1995. cmdqRecReset(handle);
  1996. cmdqRecSetSecure(handle, gCmdqTestSecure);
  1997. if (loopIndex == 1)
  1998. cmdqRecEnablePrefetch(handle);
  1999. cmdqRecWait(handle, CMDQ_SYNC_TOKEN_USER_0);
  2000. if (loopIndex == 1)
  2001. cmdqRecDisablePrefetch(handle);
  2002. cmdq_rec_finalize_command(handle, false);
  2003. /* Create second task and should run well */
  2004. cmdqRecReset(handle2);
  2005. cmdqRecSetSecure(handle2, gCmdqTestSecure);
  2006. if (loopIndex == 1)
  2007. cmdqRecEnablePrefetch(handle2);
  2008. cmdqRecWrite(handle2, CMDQ_TEST_MMSYS_DUMMY_PA, PATTERN, ~0);
  2009. if (loopIndex == 1)
  2010. cmdqRecDisablePrefetch(handle2);
  2011. cmdq_rec_finalize_command(handle2, false);
  2012. _test_submit_async(handle, &pTask);
  2013. _test_submit_async(handle2, &pTask2);
  2014. cmdqCoreSetEvent(CMDQ_SYNC_TOKEN_USER_0);
  2015. /* Call wait to release first task */
  2016. cmdqCoreWaitAndReleaseTask(pTask, 500);
  2017. cmdqCoreWaitAndReleaseTask(pTask2, 500);
  2018. /* value check */
  2019. value = CMDQ_REG_GET32(CMDQ_TEST_MMSYS_DUMMY_VA);
  2020. if (value != PATTERN) {
  2021. /* test fail */
  2022. CMDQ_ERR("TEST FAIL: wrote value is 0x%08x, not 0x%08x\n", value, PATTERN);
  2023. }
  2024. }
  2025. cmdqRecDestroy(handle);
  2026. cmdqRecDestroy(handle2);
  2027. CMDQ_MSG("%s END\n", __func__);
  2028. }
  2029. static void testcase_manual_suspend_resume_test(void)
  2030. {
  2031. cmdqRecHandle handle;
  2032. TaskStruct *pTask, *pTask2;
  2033. CMDQ_MSG("%s\n", __func__);
  2034. /* clear token */
  2035. CMDQ_REG_SET32(CMDQ_SYNC_TOKEN_UPD, CMDQ_SYNC_TOKEN_USER_0);
  2036. cmdqRecCreate(CMDQ_SCENARIO_DEBUG, &handle);
  2037. cmdqRecReset(handle);
  2038. cmdqRecSetSecure(handle, false);
  2039. cmdqRecWait(handle, CMDQ_SYNC_TOKEN_USER_0);
  2040. cmdq_rec_finalize_command(handle, false);
  2041. _test_submit_async(handle, &pTask);
  2042. /* Manual suspend and resume */
  2043. cmdqCoreSuspend();
  2044. cmdqCoreResumedNotifier();
  2045. _test_submit_async(handle, &pTask2);
  2046. cmdqCoreSetEvent(CMDQ_SYNC_TOKEN_USER_0);
  2047. /* Call wait to release second task */
  2048. cmdqCoreWaitAndReleaseTask(pTask2, 500);
  2049. cmdqRecDestroy(handle);
  2050. CMDQ_MSG("%s END\n", __func__);
  2051. }
  2052. static void testcase_timeout_wait_early_test(void)
  2053. {
  2054. cmdqRecHandle handle;
  2055. TaskStruct *pTask;
  2056. CMDQ_MSG("%s\n", __func__);
  2057. /* clear token */
  2058. CMDQ_REG_SET32(CMDQ_SYNC_TOKEN_UPD, CMDQ_SYNC_TOKEN_USER_0);
  2059. cmdqRecCreate(CMDQ_SCENARIO_PRIMARY_DISP, &handle);
  2060. cmdqRecReset(handle);
  2061. cmdqRecSetSecure(handle, false);
  2062. cmdqRecWaitNoClear(handle, CMDQ_SYNC_TOKEN_USER_0);
  2063. cmdq_rec_finalize_command(handle, false);
  2064. _test_submit_async(handle, &pTask);
  2065. cmdqRecFlush(handle);
  2066. cmdqCoreSetEvent(CMDQ_SYNC_TOKEN_USER_0);
  2067. /* Call wait to release first task */
  2068. cmdqCoreWaitAndReleaseTask(pTask, 500);
  2069. cmdqRecDestroy(handle);
  2070. CMDQ_MSG("%s END\n", __func__);
  2071. }
  2072. static void testcase_timeout_reorder_test(void)
  2073. {
  2074. cmdqRecHandle handle;
  2075. CMDQ_MSG("%s\n", __func__);
  2076. /* clear token */
  2077. CMDQ_REG_SET32(CMDQ_SYNC_TOKEN_UPD, CMDQ_SYNC_TOKEN_USER_0);
  2078. cmdqRecCreate(CMDQ_SCENARIO_PRIMARY_DISP, &handle);
  2079. cmdqRecReset(handle);
  2080. cmdqRecSetSecure(handle, false);
  2081. cmdqRecWait(handle, CMDQ_SYNC_TOKEN_USER_0);
  2082. cmdq_rec_finalize_command(handle, false);
  2083. handle->priority = 0;
  2084. cmdqRecFlushAsync(handle);
  2085. handle->priority = 2;
  2086. cmdqRecFlushAsync(handle);
  2087. handle->priority = 4;
  2088. cmdqRecFlushAsync(handle);
  2089. cmdqRecDestroy(handle);
  2090. CMDQ_MSG("%s END\n", __func__);
  2091. }
  2092. static void testcase_error_irq(void)
  2093. {
  2094. cmdqRecHandle handle;
  2095. const uint32_t PATTERN = (1 << 0) | (1 << 2) | (1 << 16);
  2096. uint32_t value = 0;
  2097. TaskStruct *pTask;
  2098. CMDQ_MSG("%s\n", __func__);
  2099. /* set to 0xFFFFFFFF */
  2100. CMDQ_REG_SET32(CMDQ_TEST_MMSYS_DUMMY_VA, ~0);
  2101. /* clear token */
  2102. CMDQ_REG_SET32(CMDQ_SYNC_TOKEN_UPD, CMDQ_SYNC_TOKEN_USER_0);
  2103. cmdqRecCreate(CMDQ_SCENARIO_DEBUG, &handle);
  2104. /* wait and block instruction */
  2105. cmdqRecReset(handle);
  2106. cmdqRecSetSecure(handle, gCmdqTestSecure);
  2107. handle->engineFlag = (1LL << CMDQ_ENG_MDP_RDMA0);
  2108. cmdqRecWait(handle, CMDQ_SYNC_TOKEN_USER_0);
  2109. cmdqRecFlushAsync(handle);
  2110. /* invalid instruction */
  2111. cmdqRecReset(handle);
  2112. cmdqRecSetSecure(handle, gCmdqTestSecure);
  2113. handle->engineFlag = (1LL << CMDQ_ENG_MDP_RDMA0);
  2114. cmdq_append_command(handle, CMDQ_CODE_JUMP, -1, 0);
  2115. cmdqRecDumpCommand(handle);
  2116. cmdqRecFlushAsync(handle);
  2117. /* Normal command */
  2118. cmdqRecReset(handle);
  2119. cmdqRecSetSecure(handle, gCmdqTestSecure);
  2120. handle->engineFlag = (1LL << CMDQ_ENG_MDP_RDMA0);
  2121. cmdqRecWrite(handle, CMDQ_TEST_MMSYS_DUMMY_PA, PATTERN, ~0);
  2122. cmdqRecFlushAsync(handle);
  2123. /* invalid instruction is asserted when unknown OP */
  2124. cmdqRecReset(handle);
  2125. cmdqRecSetSecure(handle, gCmdqTestSecure);
  2126. handle->engineFlag = (1LL << CMDQ_ENG_MDP_RDMA0);
  2127. {
  2128. const uint32_t UNKNOWN_OP = 0x50;
  2129. uint32_t *pCommand;
  2130. pCommand = (uint32_t *) ((uint8_t *) handle->pBuffer + handle->blockSize);
  2131. *pCommand++ = 0x0;
  2132. *pCommand++ = (UNKNOWN_OP << 24);
  2133. handle->blockSize += 8;
  2134. }
  2135. cmdqRecFlushAsync(handle);
  2136. /* use CMDQ to set to PATTERN */
  2137. cmdqRecReset(handle);
  2138. cmdqRecSetSecure(handle, gCmdqTestSecure);
  2139. handle->engineFlag = (1LL << CMDQ_ENG_MDP_RDMA0);
  2140. cmdqRecWrite(handle, CMDQ_TEST_MMSYS_DUMMY_PA, PATTERN, ~0);
  2141. cmdq_rec_finalize_command(handle, false);
  2142. _test_submit_async(handle, &pTask);
  2143. cmdqCoreSetEvent(CMDQ_SYNC_TOKEN_USER_0);
  2144. cmdqCoreWaitAndReleaseTask(pTask, 500);
  2145. cmdqRecDestroy(handle);
  2146. /* value check */
  2147. value = CMDQ_REG_GET32(CMDQ_TEST_MMSYS_DUMMY_VA);
  2148. if (value != PATTERN) {
  2149. /* test fail */
  2150. CMDQ_ERR("TEST FAIL: wrote value is 0x%08x, not 0x%08x\n", value, PATTERN);
  2151. }
  2152. CMDQ_MSG("%s END\n", __func__);
  2153. }
  2154. static void testcase_open_buffer_dump(int32_t scenario, int32_t bufferSize)
  2155. {
  2156. CMDQ_MSG("%s\n", __func__);
  2157. CMDQ_LOG("[TESTCASE]CONFIG: bufferSize: %d, scenario: %d\n", bufferSize, scenario);
  2158. cmdq_core_set_command_buffer_dump(scenario, bufferSize);
  2159. CMDQ_MSG("%s END\n", __func__);
  2160. }
  2161. static void testcase_check_dts_correctness(void)
  2162. {
  2163. CMDQ_MSG("%s\n", __func__);
  2164. cmdq_dev_test_dts_correctness();
  2165. CMDQ_MSG("%s END\n", __func__);
  2166. }
  2167. static int32_t testcase_monitor_callback(unsigned long data)
  2168. {
  2169. uint32_t i;
  2170. uint32_t monitorValue[CMDQ_MONITOR_EVENT_MAX];
  2171. uint32_t durationTime[CMDQ_MONITOR_EVENT_MAX];
  2172. if (false == gEventMonitor.status)
  2173. return 0;
  2174. for (i = 0; i < gEventMonitor.monitorNUM; i++) {
  2175. /* Read monitor time */
  2176. cmdqBackupReadSlot(gEventMonitor.slotHandle, i, &monitorValue[i]);
  2177. switch (gEventMonitor.waitType[i]) {
  2178. case CMDQ_MOITOR_TYPE_WFE:
  2179. durationTime[i] = (monitorValue[i] - gEventMonitor.previousValue[i]) * 76;
  2180. CMDQ_LOG("[MONITOR][WFE] event: %s, duration: (%u ns)\n",
  2181. cmdq_core_get_event_name_ENUM(gEventMonitor.monitorEvent[i]), durationTime[i]);
  2182. CMDQ_MSG("[MONITOR][WFE] time:(%u ns)\n", monitorValue[i]);
  2183. break;
  2184. case CMDQ_MOITOR_TYPE_WAIT_NO_CLEAR:
  2185. durationTime[i] = (monitorValue[i] - gEventMonitor.previousValue[i]) * 76;
  2186. CMDQ_LOG("[MONITOR][Wait] event: %s, duration: (%u ns)\n",
  2187. cmdq_core_get_event_name_ENUM(gEventMonitor.monitorEvent[i]), durationTime[i]);
  2188. CMDQ_MSG("[MONITOR] time:(%u ns)\n", monitorValue[i]);
  2189. break;
  2190. case CMDQ_MOITOR_TYPE_QUERYREGISTER:
  2191. CMDQ_LOG("[MONITOR] Register:0x08%llx, value:(0x04%x)\n", gEventMonitor.monitorEvent[i],
  2192. monitorValue[i]);
  2193. break;
  2194. }
  2195. /* Update previous monitor time */
  2196. gEventMonitor.previousValue[i] = monitorValue[i];
  2197. }
  2198. return 0;
  2199. }
  2200. static void testcase_monitor_trigger_initialization(void)
  2201. {
  2202. /* Create Slot*/
  2203. cmdqBackupAllocateSlot(&gEventMonitor.slotHandle, CMDQ_MONITOR_EVENT_MAX);
  2204. /* Create CMDQ handle */
  2205. cmdqRecCreate(CMDQ_SCENARIO_HIGHP_TRIGGER_LOOP, &gEventMonitor.cmdqHandle);
  2206. cmdqRecReset(gEventMonitor.cmdqHandle);
  2207. /* Insert enable pre-fetch instruction */
  2208. cmdqRecEnablePrefetch(gEventMonitor.cmdqHandle);
  2209. }
  2210. static void testcase_monitor_trigger(uint32_t waitType, uint64_t monitorEvent)
  2211. {
  2212. int32_t eventID;
  2213. bool successAddInstruction = false;
  2214. CMDQ_MSG("%s\n", __func__);
  2215. if (true == gEventMonitor.status) {
  2216. /* Reset monitor status */
  2217. gEventMonitor.status = false;
  2218. CMDQ_LOG("stop monitor thread\n");
  2219. /* Stop trigger loop */
  2220. cmdqRecStopLoop(gEventMonitor.cmdqHandle);
  2221. /* Destroy slot & CMDQ handle */
  2222. cmdqBackupFreeSlot(gEventMonitor.slotHandle);
  2223. /* Dump CMDQ command */
  2224. cmdqRecDestroy(gEventMonitor.cmdqHandle);
  2225. /* Reset global variable */
  2226. memset(&(gEventMonitor), 0x0, sizeof(gEventMonitor));
  2227. }
  2228. if (0 == gEventMonitor.monitorNUM) {
  2229. /* Monitor trigger thread initialization */
  2230. testcase_monitor_trigger_initialization();
  2231. } else if (gEventMonitor.monitorNUM >= CMDQ_MONITOR_EVENT_MAX) {
  2232. waitType = CMDQ_MOITOR_TYPE_FLUSH;
  2233. CMDQ_LOG("[MONITOR] reach MAX monitor number: %d, force flush\n", gEventMonitor.monitorNUM);
  2234. }
  2235. switch (waitType) {
  2236. case CMDQ_MOITOR_TYPE_FLUSH:
  2237. if (gEventMonitor.monitorNUM > 0) {
  2238. CMDQ_LOG("start monitor thread\n");
  2239. /* Insert disable pre-fetch instruction */
  2240. cmdqRecDisablePrefetch(gEventMonitor.cmdqHandle);
  2241. /* Set monitor status */
  2242. gEventMonitor.status = true;
  2243. /* Start trigger loop */
  2244. cmdqRecStartLoopWithCallback(gEventMonitor.cmdqHandle, &testcase_monitor_callback, 0);
  2245. cmdqRecDumpCommand(gEventMonitor.cmdqHandle);
  2246. }
  2247. break;
  2248. case CMDQ_MOITOR_TYPE_WFE:
  2249. eventID = (int32_t)monitorEvent;
  2250. if (eventID >= 0 && eventID < CMDQ_SYNC_TOKEN_MAX) {
  2251. cmdqRecWait(gEventMonitor.cmdqHandle, eventID);
  2252. cmdqRecBackupRegisterToSlot(gEventMonitor.cmdqHandle, gEventMonitor.slotHandle,
  2253. gEventMonitor.monitorNUM, CMDQ_APXGPT2_COUNT);
  2254. successAddInstruction = true;
  2255. }
  2256. break;
  2257. case CMDQ_MOITOR_TYPE_WAIT_NO_CLEAR:
  2258. eventID = (int32_t)monitorEvent;
  2259. if (eventID >= 0 && eventID < CMDQ_SYNC_TOKEN_MAX) {
  2260. cmdqRecWaitNoClear(gEventMonitor.cmdqHandle, eventID);
  2261. cmdqRecBackupRegisterToSlot(gEventMonitor.cmdqHandle, gEventMonitor.slotHandle,
  2262. gEventMonitor.monitorNUM, CMDQ_APXGPT2_COUNT);
  2263. successAddInstruction = true;
  2264. }
  2265. break;
  2266. case CMDQ_MOITOR_TYPE_QUERYREGISTER:
  2267. cmdqRecBackupRegisterToSlot(gEventMonitor.cmdqHandle, gEventMonitor.slotHandle,
  2268. gEventMonitor.monitorNUM, monitorEvent);
  2269. successAddInstruction = true;
  2270. break;
  2271. }
  2272. if (true == successAddInstruction) {
  2273. gEventMonitor.waitType[gEventMonitor.monitorNUM] = waitType;
  2274. gEventMonitor.monitorEvent[gEventMonitor.monitorNUM] = monitorEvent;
  2275. gEventMonitor.monitorNUM++;
  2276. }
  2277. CMDQ_MSG("%s\n", __func__);
  2278. }
  2279. static void testcase_poll_monitor_delay_continue(struct work_struct *workItem)
  2280. {
  2281. /* set event to start next polling */
  2282. cmdqCoreSetEvent(CMDQ_SYNC_TOKEN_POLL_MONITOR);
  2283. CMDQ_LOG("monitor after delay: (%d)ms, start polling again\n", gPollMonitor.delayTime);
  2284. }
  2285. static int32_t testcase_poll_monitor_callback(unsigned long data)
  2286. {
  2287. uint32_t pollTime;
  2288. if (false == gPollMonitor.status)
  2289. return 0;
  2290. cmdqBackupReadSlot(gPollMonitor.slotHandle, 0, &pollTime);
  2291. CMDQ_LOG("monitor, time: (%u ns), regAddr: 0x%08llx, regValue: 0x%08llx, regMask=0x%08llx\n",
  2292. pollTime, gPollMonitor.pollReg, gPollMonitor.pollValue, gPollMonitor.pollMask);
  2293. schedule_delayed_work(&gPollMonitor.delayContinueWork, gPollMonitor.delayTime);
  2294. return 0;
  2295. }
  2296. static void testcase_poll_monitor_trigger(uint64_t pollReg, uint64_t pollValue, uint64_t pollMask)
  2297. {
  2298. CMDQ_MSG("%s\n", __func__);
  2299. if (true == gPollMonitor.status) {
  2300. /* Reset monitor status */
  2301. gPollMonitor.status = false;
  2302. CMDQ_LOG("stop polling monitor thread: regAddr: 0x%08llx\n", gPollMonitor.pollReg);
  2303. /* Stop trigger loop */
  2304. cmdqRecStopLoop(gPollMonitor.cmdqHandle);
  2305. /* Destroy slot & CMDQ handle */
  2306. cmdqBackupFreeSlot(gPollMonitor.slotHandle);
  2307. cmdqRecDestroy(gPollMonitor.cmdqHandle);
  2308. /* Reset global variable */
  2309. memset(&(gPollMonitor), 0x0, sizeof(gPollMonitor));
  2310. }
  2311. if (-1 == pollReg)
  2312. return;
  2313. CMDQ_LOG("start polling monitor thread, regAddr=0x%08llx, regValue=0x%08llx, regMask=0x%08llx\n",
  2314. pollReg, pollValue, pollMask);
  2315. /* Set event to start first polling */
  2316. cmdqCoreSetEvent(CMDQ_SYNC_TOKEN_POLL_MONITOR);
  2317. /* Create slot */
  2318. cmdqBackupAllocateSlot(&gPollMonitor.slotHandle, 1);
  2319. /* Create CMDQ handle */
  2320. cmdqRecCreate(CMDQ_SCENARIO_LOWP_TRIGGER_LOOP, &gPollMonitor.cmdqHandle);
  2321. cmdqRecReset(gPollMonitor.cmdqHandle);
  2322. /* Insert monitor thread command */
  2323. cmdqRecWait(gPollMonitor.cmdqHandle, CMDQ_SYNC_TOKEN_POLL_MONITOR);
  2324. if (0 == cmdqRecPoll(gPollMonitor.cmdqHandle, pollReg, pollValue, pollMask)) {
  2325. cmdqRecBackupRegisterToSlot(gPollMonitor.cmdqHandle, gPollMonitor.slotHandle, 0, CMDQ_APXGPT2_COUNT);
  2326. /* Set value to global variable */
  2327. gPollMonitor.pollReg = pollReg;
  2328. gPollMonitor.pollValue = pollValue;
  2329. gPollMonitor.pollMask = pollMask;
  2330. gPollMonitor.delayTime = 1;
  2331. gPollMonitor.status = true;
  2332. INIT_DELAYED_WORK(&gPollMonitor.delayContinueWork, testcase_poll_monitor_delay_continue);
  2333. /* Start trigger loop */
  2334. cmdqRecStartLoopWithCallback(gPollMonitor.cmdqHandle, &testcase_poll_monitor_callback, 0);
  2335. /* Dump CMDQ command */
  2336. cmdqRecDumpCommand(gPollMonitor.cmdqHandle);
  2337. } else {
  2338. /* Destroy slot & CMDQ handle */
  2339. cmdqBackupFreeSlot(gPollMonitor.slotHandle);
  2340. cmdqRecDestroy(gPollMonitor.cmdqHandle);
  2341. }
  2342. CMDQ_MSG("%s\n", __func__);
  2343. }
  2344. static void testcase_acquire_resource(bool acquireExpected)
  2345. {
  2346. cmdqRecHandle handle;
  2347. const uint32_t PATTERN = (1 << 0) | (1 << 2) | (1 << 16);
  2348. uint32_t value = 0;
  2349. int32_t acquireResult;
  2350. CMDQ_MSG("%s\n", __func__);
  2351. /* set to 0xFFFFFFFF */
  2352. CMDQ_REG_SET32(CMDQ_TEST_MMSYS_DUMMY_VA, ~0);
  2353. /* use CMDQ to set to PATTERN */
  2354. cmdqRecCreate(CMDQ_SCENARIO_PRIMARY_DISP, &handle);
  2355. cmdqRecReset(handle);
  2356. cmdqRecSetSecure(handle, gCmdqTestSecure);
  2357. acquireResult = cmdqRecWriteForResource(handle, CMDQ_SYNC_RESOURCE_WROT0,
  2358. CMDQ_TEST_MMSYS_DUMMY_PA, PATTERN, ~0);
  2359. if (acquireResult < 0) {
  2360. /* Do error handle for acquire resource fail */
  2361. if (acquireExpected) {
  2362. /* print error message */
  2363. CMDQ_ERR("Acquire resource fail: it's not expected!\n");
  2364. } else {
  2365. /* print message */
  2366. CMDQ_LOG("Acquire resource fail: it's expected!\n");
  2367. }
  2368. } else {
  2369. if (!acquireExpected) {
  2370. /* print error message */
  2371. CMDQ_ERR("Acquire resource success: it's not expected!\n");
  2372. } else {
  2373. /* print message */
  2374. CMDQ_LOG("Acquire resource success: it's expected!\n");
  2375. }
  2376. }
  2377. cmdqRecFlush(handle);
  2378. cmdqRecDestroy(handle);
  2379. /* value check */
  2380. value = CMDQ_REG_GET32(CMDQ_TEST_MMSYS_DUMMY_VA);
  2381. if (value != PATTERN && acquireExpected) {
  2382. /* test fail */
  2383. CMDQ_ERR("TEST FAIL: wrote value is 0x%08x, not 0x%08x\n", value, PATTERN);
  2384. }
  2385. CMDQ_MSG("%s END\n", __func__);
  2386. }
  2387. static int32_t testcase_res_release_cb(CMDQ_EVENT_ENUM resourceEvent)
  2388. {
  2389. cmdqRecHandle handle;
  2390. const uint32_t PATTERN = (1 << 0) | (1 << 2) | (1 << 16);
  2391. CMDQ_MSG("%s\n", __func__);
  2392. /* Flush release command immedately with wait MUTEX event */
  2393. /* set to 0xFFFFFFFF */
  2394. CMDQ_REG_SET32(CMDQ_TEST_MMSYS_DUMMY_VA, ~0);
  2395. /* use CMDQ to set to PATTERN */
  2396. cmdqRecCreate(CMDQ_SCENARIO_PRIMARY_DISP, &handle);
  2397. cmdqRecReset(handle);
  2398. cmdqRecSetSecure(handle, gCmdqTestSecure);
  2399. /* simulate display need to wait single */
  2400. cmdqRecWaitNoClear(handle, CMDQ_SYNC_TOKEN_USER_0);
  2401. /* simulate release resource via write register */
  2402. /* cmdqRecWrite(handle, CMDQ_TEST_MMSYS_DUMMY_PA, PATTERN, ~0);
  2403. cmdqRecReleaseResource(handle, resourceEvent); */
  2404. cmdqRecWriteAndReleaseResource(handle, resourceEvent,
  2405. CMDQ_TEST_MMSYS_DUMMY_PA, PATTERN, ~0);
  2406. cmdqRecFlushAsync(handle);
  2407. cmdqRecDestroy(handle);
  2408. CMDQ_MSG("%s END\n", __func__);
  2409. return 0;
  2410. }
  2411. static int32_t testcase_res_available_cb(CMDQ_EVENT_ENUM resourceEvent)
  2412. {
  2413. CMDQ_MSG("%s\n", __func__);
  2414. testcase_acquire_resource(true);
  2415. CMDQ_MSG("%s END\n", __func__);
  2416. return 0;
  2417. }
  2418. static void testcase_notify_and_delay_submit(uint32_t delayTimeMS)
  2419. {
  2420. cmdqRecHandle handle;
  2421. const uint32_t PATTERN = (1 << 0) | (1 << 2) | (1 << 16);
  2422. uint32_t value = 0;
  2423. const uint64_t engineFlag = (1LL << CMDQ_ENG_MDP_WROT0);
  2424. uint32_t contDelay;
  2425. CMDQ_MSG("%s\n", __func__);
  2426. /* clear token */
  2427. CMDQ_REG_SET32(CMDQ_SYNC_TOKEN_UPD, CMDQ_SYNC_TOKEN_USER_0);
  2428. cmdqCoreSetResourceCallback(CMDQ_SYNC_RESOURCE_WROT0,
  2429. testcase_res_available_cb, testcase_res_release_cb);
  2430. testcase_acquire_resource(true);
  2431. /* notify and delay time*/
  2432. if (delayTimeMS > 0) {
  2433. CMDQ_MSG("Before delay for acquire\n");
  2434. msleep_interruptible(delayTimeMS);
  2435. CMDQ_MSG("Before lock and delay\n");
  2436. cmdqCoreLockResource(engineFlag, true);
  2437. msleep_interruptible(delayTimeMS);
  2438. CMDQ_MSG("After lock and delay\n");
  2439. }
  2440. /* set to 0xFFFFFFFF */
  2441. CMDQ_REG_SET32(CMDQ_TEST_MMSYS_DUMMY_VA, ~0);
  2442. /* use CMDQ to set to PATTERN */
  2443. cmdqRecCreate(CMDQ_SCENARIO_DEBUG, &handle);
  2444. cmdqRecReset(handle);
  2445. cmdqRecSetSecure(handle, gCmdqTestSecure);
  2446. handle->engineFlag = engineFlag;
  2447. cmdqRecWaitNoClear(handle, CMDQ_SYNC_RESOURCE_WROT0);
  2448. cmdqRecWrite(handle, CMDQ_TEST_MMSYS_DUMMY_PA, PATTERN, ~0);
  2449. cmdqRecFlushAsync(handle);
  2450. cmdqCoreSetEvent(CMDQ_SYNC_TOKEN_USER_0);
  2451. msleep_interruptible(2000);
  2452. /* Delay and continue sent */
  2453. for (contDelay = 300; contDelay < CMDQ_DELAY_RELEASE_RESOURCE_MS*1.2; contDelay += 300) {
  2454. CMDQ_MSG("Before delay and flush\n");
  2455. msleep_interruptible(contDelay);
  2456. CMDQ_MSG("After delay\n");
  2457. cmdqRecFlush(handle);
  2458. CMDQ_MSG("After flush\n");
  2459. }
  2460. /* Simulate DISP acquire fail case, acquire immediate after flush MDP */
  2461. cmdqRecFlushAsync(handle);
  2462. testcase_acquire_resource(false);
  2463. cmdqRecFlushAsync(handle);
  2464. cmdqRecDestroy(handle);
  2465. /* value check */
  2466. value = CMDQ_REG_GET32(CMDQ_TEST_MMSYS_DUMMY_VA);
  2467. if (value != PATTERN) {
  2468. /* test fail */
  2469. CMDQ_ERR("TEST FAIL: wrote value is 0x%08x, not 0x%08x\n", value, PATTERN);
  2470. }
  2471. CMDQ_MSG("%s END\n", __func__);
  2472. }
  2473. void testcase_prefetch_round(uint32_t loopCount, uint32_t cmdCount, bool withMask, bool withWait)
  2474. {
  2475. #define TEST_PREFETCH_LOOP 3
  2476. int32_t i, j, k;
  2477. int32_t ret;
  2478. cmdqRecHandle handle[TEST_PREFETCH_LOOP] = {0};
  2479. TaskStruct *pTask[TEST_PREFETCH_LOOP] = { 0 };
  2480. /* clear token */
  2481. CMDQ_REG_SET32(CMDQ_SYNC_TOKEN_UPD, CMDQ_SYNC_TOKEN_USER_0);
  2482. CMDQ_MSG("%s: count:%d, withMask:%d, withWait:%d\n", __func__, cmdCount, withMask, withWait);
  2483. for (i = 0; i < TEST_PREFETCH_LOOP; i++) {
  2484. CMDQ_MSG("=============== flush:%d/%d ===============\n", i, TEST_PREFETCH_LOOP);
  2485. for (k = 0; k < loopCount; k++) {
  2486. CMDQ_MSG("=============== loop:%d/%d ===============\n", k, loopCount);
  2487. cmdqRecCreate(CMDQ_SCENARIO_DEBUG_PREFETCH, &(handle[i]));
  2488. cmdqRecReset(handle[i]);
  2489. cmdqRecSetSecure(handle[i], false);
  2490. /* record instructions which needs prefetch */
  2491. if (i == 1)
  2492. cmdqRecEnablePrefetch(handle[i]); /* use pre-fetch with marker */
  2493. if (withWait)
  2494. cmdqRecWait(handle[i], CMDQ_SYNC_TOKEN_USER_0);
  2495. cmdqRecProfileMarker(handle[i], "ANA_BEGIN");
  2496. for (j = 0; j < cmdCount; j++) {
  2497. /* record instructions which does not need prefetch */
  2498. if (withMask)
  2499. cmdqRecWrite(handle[i], CMDQ_TEST_MMSYS_DUMMY_PA, 0x3210, ~0xfff0);
  2500. else
  2501. cmdqRecWrite(handle[i], CMDQ_TEST_MMSYS_DUMMY_PA, 0x3210, ~0);
  2502. }
  2503. if (i == 1)
  2504. cmdqRecDisablePrefetch(handle[i]); /* disable pre-fetch with marker */
  2505. cmdqRecProfileMarker(handle[i], "ANA_END");
  2506. cmdq_rec_finalize_command(handle[i], false);
  2507. ret = _test_submit_async(handle[i], &pTask[i]);
  2508. if (withWait) {
  2509. msleep_interruptible(500);
  2510. cmdqCoreSetEvent(CMDQ_SYNC_TOKEN_USER_0);
  2511. }
  2512. CMDQ_MSG("wait 0x%p, i:%2d========\n", pTask[i], i);
  2513. ret = cmdqCoreWaitAndReleaseTask(pTask[i], 500);
  2514. cmdqRecDestroy(handle[i]);
  2515. }
  2516. }
  2517. CMDQ_MSG("%s END\n", __func__);
  2518. }
  2519. typedef enum CMDQ_TESTCASE_ENUM {
  2520. CMDQ_TESTCASE_ALL = 0,
  2521. CMDQ_TESTCASE_BASIC = 1,
  2522. CMDQ_TESTCASE_ERROR = 2,
  2523. CMDQ_TESTCASE_FPGA = 3,
  2524. CMDQ_TESTCASE_READ_REG_REQUEST, /* user request get some registers' value when task execution */
  2525. CMDQ_TESTCASE_GPR,
  2526. CMDQ_TESTCASE_SW_TIMEOUT_HANDLE,
  2527. CMDQ_TESTCASE_END, /* always at the end */
  2528. } CMDQ_TESTCASE_ENUM;
  2529. static void testcase_general_handling(int32_t testID)
  2530. {
  2531. switch (testID) {
  2532. case 121:
  2533. testcase_prefetch_round(1, 100, false, true);
  2534. testcase_prefetch_round(1, 100, false, false);
  2535. testcase_prefetch_round(1, 160, false, true);
  2536. testcase_prefetch_round(1, 160, false, false);
  2537. testcase_prefetch_round(1, 180, false, true);
  2538. testcase_prefetch_round(1, 180, false, false);
  2539. break;
  2540. case 120:
  2541. testcase_notify_and_delay_submit(16);
  2542. break;
  2543. case 119:
  2544. testcase_check_dts_correctness();
  2545. break;
  2546. case 118:
  2547. testcase_error_irq();
  2548. break;
  2549. case 117:
  2550. testcase_timeout_reorder_test();
  2551. break;
  2552. case 116:
  2553. testcase_timeout_wait_early_test();
  2554. break;
  2555. case 115:
  2556. testcase_manual_suspend_resume_test();
  2557. break;
  2558. case 114:
  2559. testcase_append_task_verify();
  2560. break;
  2561. case 113:
  2562. testcase_trigger_engine_dispatch_check();
  2563. break;
  2564. case 112:
  2565. testcase_complicated_engine_thread();
  2566. break;
  2567. case 111:
  2568. testcase_module_full_mdp_engine();
  2569. break;
  2570. case 110:
  2571. testcase_nonsuspend_irq();
  2572. break;
  2573. case 109:
  2574. testcase_estimate_command_exec_time();
  2575. break;
  2576. case 108:
  2577. testcase_profile_marker();
  2578. break;
  2579. case 107:
  2580. testcase_prefetch_multiple_command();
  2581. break;
  2582. case 106:
  2583. testcase_concurrency_for_normal_path_and_secure_path();
  2584. break;
  2585. case 105:
  2586. testcase_async_write_stress_test();
  2587. break;
  2588. case 104:
  2589. testcase_submit_after_error_happened();
  2590. break;
  2591. case 103:
  2592. testcase_secure_meta_data();
  2593. break;
  2594. case 102:
  2595. testcase_secure_disp_scenario();
  2596. break;
  2597. case 101:
  2598. testcase_write_stress_test();
  2599. break;
  2600. case 100:
  2601. testcase_secure_basic();
  2602. break;
  2603. case 99:
  2604. testcase_write();
  2605. testcase_write_with_mask();
  2606. break;
  2607. case 98:
  2608. testcase_errors();
  2609. break;
  2610. case 97:
  2611. testcase_scenario();
  2612. break;
  2613. case 96:
  2614. testcase_sync_token();
  2615. break;
  2616. case 95:
  2617. testcase_write_address();
  2618. break;
  2619. case 94:
  2620. testcase_async_request();
  2621. break;
  2622. case 93:
  2623. testcase_async_suspend_resume();
  2624. break;
  2625. case 92:
  2626. testcase_async_request_partial_engine();
  2627. break;
  2628. case 91:
  2629. testcase_prefetch_scenarios();
  2630. break;
  2631. case 90:
  2632. testcase_loop();
  2633. break;
  2634. case 89:
  2635. testcase_trigger_thread();
  2636. break;
  2637. case 88:
  2638. testcase_multiple_async_request();
  2639. break;
  2640. case 87:
  2641. testcase_get_result();
  2642. break;
  2643. case 86:
  2644. testcase_read_to_data_reg();
  2645. break;
  2646. case 85:
  2647. testcase_dram_access();
  2648. break;
  2649. case 84:
  2650. testcase_backup_register();
  2651. break;
  2652. case 83:
  2653. testcase_fire_and_forget();
  2654. break;
  2655. case 82:
  2656. testcase_sync_token_threaded();
  2657. break;
  2658. case 81:
  2659. testcase_long_command();
  2660. break;
  2661. case 80:
  2662. testcase_clkmgr();
  2663. break;
  2664. case 79:
  2665. testcase_perisys_apb();
  2666. break;
  2667. case 78:
  2668. testcase_backup_reg_to_slot();
  2669. break;
  2670. case 77:
  2671. testcase_thread_dispatch();
  2672. break;
  2673. case 76:
  2674. testcase_emergency_buffer();
  2675. break;
  2676. case 75:
  2677. testcase_full_thread_array();
  2678. break;
  2679. case 74:
  2680. testcase_module_full_dump();
  2681. break;
  2682. case 73:
  2683. testcase_write_from_data_reg();
  2684. break;
  2685. case 72:
  2686. testcase_update_value_to_slot();
  2687. break;
  2688. case 71:
  2689. testcase_poll();
  2690. break;
  2691. case 70:
  2692. testcase_write_reg_from_slot();
  2693. break;
  2694. case CMDQ_TESTCASE_FPGA:
  2695. testcase_write();
  2696. testcase_write_with_mask();
  2697. testcase_poll();
  2698. testcase_scenario();
  2699. testcase_estimate_command_exec_time();
  2700. testcase_prefetch_multiple_command();
  2701. testcase_write_stress_test();
  2702. testcase_async_suspend_resume();
  2703. testcase_async_request_partial_engine();
  2704. testcase_prefetch_scenarios();
  2705. testcase_loop();
  2706. testcase_trigger_thread();
  2707. testcase_multiple_async_request();
  2708. testcase_get_result();
  2709. testcase_dram_access();
  2710. testcase_backup_register();
  2711. testcase_fire_and_forget();
  2712. testcase_sync_token_threaded();
  2713. testcase_long_command();
  2714. testcase_backup_reg_to_slot();
  2715. testcase_write_from_data_reg();
  2716. testcase_update_value_to_slot();
  2717. break;
  2718. case CMDQ_TESTCASE_ERROR:
  2719. testcase_errors();
  2720. break;
  2721. case CMDQ_TESTCASE_BASIC:
  2722. testcase_write();
  2723. testcase_poll();
  2724. testcase_scenario();
  2725. break;
  2726. case CMDQ_TESTCASE_READ_REG_REQUEST:
  2727. testcase_get_result();
  2728. break;
  2729. case CMDQ_TESTCASE_GPR:
  2730. testcase_read_to_data_reg(); /* must verify! */
  2731. testcase_dram_access();
  2732. break;
  2733. case CMDQ_TESTCASE_ALL:
  2734. testcase_multiple_async_request();
  2735. testcase_read_to_data_reg();
  2736. testcase_get_result();
  2737. testcase_errors();
  2738. testcase_scenario();
  2739. testcase_sync_token();
  2740. testcase_write();
  2741. testcase_poll();
  2742. testcase_write_address();
  2743. testcase_async_request();
  2744. testcase_async_suspend_resume();
  2745. testcase_async_request_partial_engine();
  2746. testcase_prefetch_scenarios();
  2747. testcase_loop();
  2748. testcase_trigger_thread();
  2749. testcase_prefetch();
  2750. /* testcase_sync_token_threaded(); */
  2751. testcase_long_command();
  2752. /* testcase_clkmgr(); */
  2753. testcase_dram_access();
  2754. testcase_perisys_apb();
  2755. testcase_backup_register();
  2756. testcase_fire_and_forget();
  2757. testcase_backup_reg_to_slot();
  2758. testcase_emergency_buffer();
  2759. testcase_thread_dispatch();
  2760. testcase_full_thread_array();
  2761. testcase_module_full_dump();
  2762. break;
  2763. default:
  2764. CMDQ_LOG("[TESTCASE]CONFIG Not Found: gCmdqTestSecure: %d, testType: %lld\n",
  2765. gCmdqTestSecure, gCmdqTestConfig[0]);
  2766. break;
  2767. }
  2768. }
  2769. ssize_t cmdq_test_proc(struct file *fp, char __user *u, size_t s, loff_t *l)
  2770. {
  2771. int64_t testParameter[CMDQ_TESTCASE_PARAMETER_MAX];
  2772. mutex_lock(&gCmdqTestProcLock);
  2773. /* make sure the following section is protected */
  2774. smp_mb();
  2775. CMDQ_LOG("[TESTCASE]CONFIG: gCmdqTestSecure: %d, testType: %lld\n",
  2776. gCmdqTestSecure, gCmdqTestConfig[0]);
  2777. CMDQ_LOG("[TESTCASE]CONFIG PARAMETER: [1]: %lld, [2]: %lld, [3]: %lld\n",
  2778. gCmdqTestConfig[1], gCmdqTestConfig[2], gCmdqTestConfig[3]);
  2779. memcpy(testParameter, gCmdqTestConfig, sizeof(testParameter));
  2780. mutex_unlock(&gCmdqTestProcLock);
  2781. /* trigger test case here */
  2782. CMDQ_MSG("//\n//\n//\ncmdq_test_proc\n");
  2783. cmdq_get_func()->testSetup();
  2784. switch (testParameter[0]) {
  2785. case CMDQ_TEST_TYPE_NORMAL:
  2786. case CMDQ_TEST_TYPE_SECURE:
  2787. testcase_general_handling((int32_t)testParameter[1]);
  2788. break;
  2789. case CMDQ_TEST_TYPE_MONITOR_EVENT:
  2790. /* (wait type, event ID or back register) */
  2791. testcase_monitor_trigger((uint32_t)testParameter[1], (uint64_t)testParameter[2]);
  2792. break;
  2793. case CMDQ_TEST_TYPE_MONITOR_POLL:
  2794. /* (poll register, poll value, poll mask) */
  2795. testcase_poll_monitor_trigger((uint64_t)testParameter[1], (uint64_t)testParameter[2],
  2796. (uint64_t)testParameter[3]);
  2797. break;
  2798. case CMDQ_TEST_TYPE_OPEN_COMMAND_DUMP:
  2799. /* (scenario, buffersize) */
  2800. testcase_open_buffer_dump((int32_t)testParameter[1], (int32_t)testParameter[2]);
  2801. break;
  2802. case CMDQ_TEST_TYPE_DUMP_DTS:
  2803. cmdq_core_dump_dts_setting();
  2804. break;
  2805. case CMDQ_TEST_TYPE_FEATURE_CONFIG:
  2806. if (0 > (int32_t)testParameter[1])
  2807. cmdq_core_dump_feature();
  2808. else
  2809. cmdq_core_set_feature((int32_t)testParameter[1], (uint32_t)testParameter[2]);
  2810. default:
  2811. break;
  2812. }
  2813. cmdq_get_func()->testCleanup();
  2814. CMDQ_MSG("cmdq_test_proc ended\n");
  2815. return 0;
  2816. }
  2817. static ssize_t cmdq_write_test_proc_config(struct file *file,
  2818. const char __user *userBuf, size_t count, loff_t *data)
  2819. {
  2820. char desc[50];
  2821. long long int testConfig[CMDQ_TESTCASE_PARAMETER_MAX];
  2822. int32_t len = 0;
  2823. do {
  2824. /* copy user input */
  2825. len = (count < (sizeof(desc) - 1)) ? count : (sizeof(desc) - 1);
  2826. if (copy_from_user(desc, userBuf, count)) {
  2827. CMDQ_ERR("TEST_CONFIG: data fail\n");
  2828. break;
  2829. }
  2830. desc[len] = '\0';
  2831. /* Set initial test config value */
  2832. memset(testConfig, -1, sizeof(testConfig));
  2833. /* process and update config */
  2834. if (0 >= sscanf(desc, "%lld %lld %lld %lld", &testConfig[0], &testConfig[1],
  2835. &testConfig[2], &testConfig[3])) {
  2836. /* sscanf returns the number of items in argument list successfully filled. */
  2837. CMDQ_ERR("TEST_CONFIG: sscanf failed\n");
  2838. break;
  2839. }
  2840. if ((testConfig[0] < 0) || (testConfig[0] >= CMDQ_TEST_TYPE_MAX)) {
  2841. CMDQ_ERR("TEST_CONFIG: testType:%lld, newTestSuit:%lld\n", testConfig[0], testConfig[1]);
  2842. break;
  2843. }
  2844. mutex_lock(&gCmdqTestProcLock);
  2845. /* set memory barrier for lock */
  2846. smp_mb();
  2847. memcpy(&gCmdqTestConfig, &testConfig, sizeof(testConfig));
  2848. if (testConfig[0] == CMDQ_TEST_TYPE_NORMAL)
  2849. gCmdqTestSecure = false;
  2850. else
  2851. gCmdqTestSecure = true;
  2852. mutex_unlock(&gCmdqTestProcLock);
  2853. } while (0);
  2854. return count;
  2855. }
  2856. void cmdq_test_init_setting(void)
  2857. {
  2858. memset(&(gEventMonitor), 0x0, sizeof(gEventMonitor));
  2859. memset(&(gPollMonitor), 0x0, sizeof(gPollMonitor));
  2860. }
  2861. static int cmdq_test_open(struct inode *pInode, struct file *pFile)
  2862. {
  2863. return 0;
  2864. }
  2865. static const struct file_operations cmdq_fops = {
  2866. .owner = THIS_MODULE,
  2867. .open = cmdq_test_open,
  2868. .read = cmdq_test_proc,
  2869. .write = cmdq_write_test_proc_config,
  2870. };
  2871. static int __init cmdq_test_init(void)
  2872. {
  2873. #ifdef _CMDQ_TEST_PROC_
  2874. CMDQ_MSG("cmdq_test_init\n");
  2875. /* Mout proc entry for debug */
  2876. gCmdqTestProcEntry = proc_mkdir("cmdq_test", NULL);
  2877. if (NULL != gCmdqTestProcEntry) {
  2878. if (NULL == proc_create("test", 0660, gCmdqTestProcEntry, &cmdq_fops)) {
  2879. /* cmdq_test_init failed */
  2880. CMDQ_MSG("cmdq_test_init failed\n");
  2881. }
  2882. }
  2883. #endif
  2884. return 0;
  2885. }
  2886. static void __exit cmdq_test_exit(void)
  2887. {
  2888. #ifdef _CMDQ_TEST_PROC_
  2889. CMDQ_MSG("cmdq_test_exit\n");
  2890. if (NULL != gCmdqTestProcEntry) {
  2891. proc_remove(gCmdqTestProcEntry);
  2892. gCmdqTestProcEntry = NULL;
  2893. }
  2894. #endif
  2895. }
  2896. module_init(cmdq_test_init);
  2897. module_exit(cmdq_test_exit);
  2898. MODULE_LICENSE("GPL");
  2899. #endif /* CMDQ_TEST */