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