cmdq_test.c 97 KB

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