Merge tag 'efi-2020-07-rc6' of https://gitlab.denx.de/u-boot/custodians/u-boot-efi
[oweals/u-boot.git] / drivers / ram / stm32mp1 / stm32mp1_tests.c
1 // SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause
2 /*
3  * Copyright (C) 2019, STMicroelectronics - All Rights Reserved
4  */
5 #include <common.h>
6 #include <console.h>
7 #include <init.h>
8 #include <log.h>
9 #include <rand.h>
10 #include <watchdog.h>
11 #include <asm/io.h>
12 #include <linux/log2.h>
13 #include "stm32mp1_tests.h"
14
15 #define ADDR_INVALID    0xFFFFFFFF
16
17 DECLARE_GLOBAL_DATA_PTR;
18
19 static int get_bufsize(char *string, int argc, char *argv[], int arg_nb,
20                        size_t *bufsize, size_t default_size)
21 {
22         unsigned long value;
23
24         if (argc > arg_nb) {
25                 if (strict_strtoul(argv[arg_nb], 0, &value) < 0) {
26                         sprintf(string, "invalid %d parameter %s",
27                                 arg_nb, argv[arg_nb]);
28                         return -1;
29                 }
30                 if (value > STM32_DDR_SIZE || value == 0) {
31                         sprintf(string, "invalid size %s", argv[arg_nb]);
32                         return -1;
33                 }
34                 if (value & 0x3) {
35                         sprintf(string, "unaligned size %s",
36                                 argv[arg_nb]);
37                         return -1;
38                 }
39                 *bufsize = value;
40         } else {
41                 if (default_size != STM32_DDR_SIZE)
42                         *bufsize = default_size;
43                 else
44                         *bufsize = get_ram_size((long *)STM32_DDR_BASE,
45                                                 STM32_DDR_SIZE);
46         }
47         return 0;
48 }
49
50 static int get_nb_loop(char *string, int argc, char *argv[], int arg_nb,
51                        u32 *nb_loop, u32 default_nb_loop)
52 {
53         unsigned long value;
54
55         if (argc > arg_nb) {
56                 if (strict_strtoul(argv[arg_nb], 0, &value) < 0) {
57                         sprintf(string, "invalid %d parameter %s",
58                                 arg_nb, argv[arg_nb]);
59                         return -1;
60                 }
61                 if (value == 0)
62                         printf("WARNING: infinite loop requested\n");
63                 *nb_loop = value;
64         } else {
65                 *nb_loop = default_nb_loop;
66         }
67
68         return 0;
69 }
70
71 static int get_addr(char *string, int argc, char *argv[], int arg_nb,
72                     u32 *addr)
73 {
74         unsigned long value;
75
76         if (argc > arg_nb) {
77                 if (strict_strtoul(argv[arg_nb], 16, &value) < 0) {
78                         sprintf(string, "invalid %d parameter %s",
79                                 arg_nb, argv[arg_nb]);
80                         return -1;
81                 }
82                 if (value < STM32_DDR_BASE) {
83                         sprintf(string, "too low address %s", argv[arg_nb]);
84                         return -1;
85                 }
86                 if (value & 0x3 && value != ADDR_INVALID) {
87                         sprintf(string, "unaligned address %s",
88                                 argv[arg_nb]);
89                         return -1;
90                 }
91                 *addr = value;
92         } else {
93                 *addr = STM32_DDR_BASE;
94         }
95
96         return 0;
97 }
98
99 static int get_pattern(char *string, int argc, char *argv[], int arg_nb,
100                        u32 *pattern, u32 default_pattern)
101 {
102         unsigned long value;
103
104         if (argc > arg_nb) {
105                 if (strict_strtoul(argv[arg_nb], 16, &value) < 0) {
106                         sprintf(string, "invalid %d parameter %s",
107                                 arg_nb, argv[arg_nb]);
108                         return -1;
109                 }
110                 *pattern = value;
111         } else {
112                 *pattern = default_pattern;
113         }
114
115         return 0;
116 }
117
118 static u32 check_addr(u32 addr, u32 value)
119 {
120         u32 data = readl(addr);
121
122         if (value !=  data) {
123                 printf("0x%08x: 0x%08x <=> 0x%08x", addr, data, value);
124                 data = readl(addr);
125                 printf("(2nd read: 0x%08x)", data);
126                 if (value == data)
127                         printf("- read error");
128                 else
129                         printf("- write error");
130                 printf("\n");
131                 return -1;
132         }
133         return 0;
134 }
135
136 static int progress(u32 offset)
137 {
138         if (!(offset & 0xFFFFFF)) {
139                 putc('.');
140                 if (ctrlc()) {
141                         printf("\ntest interrupted!\n");
142                         return 1;
143                 }
144         }
145         return 0;
146 }
147
148 static int test_loop_end(u32 *loop, u32 nb_loop, u32 progress)
149 {
150         (*loop)++;
151         if (nb_loop && *loop >= nb_loop)
152                 return 1;
153         if ((*loop) % progress)
154                 return 0;
155         /* allow to interrupt the test only for progress step */
156         if (ctrlc()) {
157                 printf("test interrupted!\n");
158                 return 1;
159         }
160         printf("loop #%d\n", *loop);
161         WATCHDOG_RESET();
162
163         return 0;
164 }
165
166 /**********************************************************************
167  *
168  * Function:    memTestDataBus()
169  *
170  * Description: Test the data bus wiring in a memory region by
171  *              performing a walking 1's test at a fixed address
172  *              within that region.  The address is selected
173  *              by the caller.
174  *
175  * Notes:
176  *
177  * Returns:     0 if the test succeeds.
178  *              A non-zero result is the first pattern that failed.
179  *
180  **********************************************************************/
181 static u32 databus(u32 *address)
182 {
183         u32 pattern;
184         u32 read_value;
185
186         /* Perform a walking 1's test at the given address. */
187         for (pattern = 1; pattern != 0; pattern <<= 1) {
188                 /* Write the test pattern. */
189                 writel(pattern, address);
190
191                 /* Read it back (immediately is okay for this test). */
192                 read_value = readl(address);
193                 debug("%x: %x <=> %x\n",
194                       (u32)address, read_value, pattern);
195
196                 if (read_value != pattern)
197                         return pattern;
198         }
199
200         return 0;
201 }
202
203 /**********************************************************************
204  *
205  * Function:    memTestAddressBus()
206  *
207  * Description: Test the address bus wiring in a memory region by
208  *              performing a walking 1's test on the relevant bits
209  *              of the address and checking for aliasing. This test
210  *              will find single-bit address failures such as stuck
211  *              -high, stuck-low, and shorted pins.  The base address
212  *              and size of the region are selected by the caller.
213  *
214  * Notes:       For best results, the selected base address should
215  *              have enough LSB 0's to guarantee single address bit
216  *              changes.  For example, to test a 64-Kbyte region,
217  *              select a base address on a 64-Kbyte boundary.  Also,
218  *              select the region size as a power-of-two--if at all
219  *              possible.
220  *
221  * Returns:     NULL if the test succeeds.
222  *              A non-zero result is the first address at which an
223  *              aliasing problem was uncovered.  By examining the
224  *              contents of memory, it may be possible to gather
225  *              additional information about the problem.
226  *
227  **********************************************************************/
228 static u32 *addressbus(u32 *address, u32 nb_bytes)
229 {
230         u32 mask = (nb_bytes / sizeof(u32) - 1);
231         u32 offset;
232         u32 test_offset;
233         u32 read_value;
234
235         u32 pattern     = 0xAAAAAAAA;
236         u32 antipattern = 0x55555555;
237
238         /* Write the default pattern at each of the power-of-two offsets. */
239         for (offset = 1; (offset & mask) != 0; offset <<= 1)
240                 writel(pattern, &address[offset]);
241
242         /* Check for address bits stuck high. */
243         test_offset = 0;
244         writel(antipattern, &address[test_offset]);
245
246         for (offset = 1; (offset & mask) != 0; offset <<= 1) {
247                 read_value = readl(&address[offset]);
248                 debug("%x: %x <=> %x\n",
249                       (u32)&address[offset], read_value, pattern);
250                 if (read_value != pattern)
251                         return &address[offset];
252         }
253
254         writel(pattern, &address[test_offset]);
255
256         /* Check for address bits stuck low or shorted. */
257         for (test_offset = 1; (test_offset & mask) != 0; test_offset <<= 1) {
258                 writel(antipattern, &address[test_offset]);
259                 if (readl(&address[0]) != pattern)
260                         return &address[test_offset];
261
262                 for (offset = 1; (offset & mask) != 0; offset <<= 1) {
263                         if (readl(&address[offset]) != pattern &&
264                             offset != test_offset)
265                                 return &address[test_offset];
266                 }
267                 writel(pattern, &address[test_offset]);
268         }
269
270         return NULL;
271 }
272
273 /**********************************************************************
274  *
275  * Function:    memTestDevice()
276  *
277  * Description: Test the integrity of a physical memory device by
278  *              performing an increment/decrement test over the
279  *              entire region.  In the process every storage bit
280  *              in the device is tested as a zero and a one.  The
281  *              base address and the size of the region are
282  *              selected by the caller.
283  *
284  * Notes:
285  *
286  * Returns:     NULL if the test succeeds.
287  *
288  *              A non-zero result is the first address at which an
289  *              incorrect value was read back.  By examining the
290  *              contents of memory, it may be possible to gather
291  *              additional information about the problem.
292  *
293  **********************************************************************/
294 static u32 *memdevice(u32 *address, u32 nb_bytes)
295 {
296         u32 offset;
297         u32 nb_words = nb_bytes / sizeof(u32);
298
299         u32 pattern;
300         u32 antipattern;
301
302         puts("Fill with pattern");
303         /* Fill memory with a known pattern. */
304         for (pattern = 1, offset = 0; offset < nb_words; pattern++, offset++) {
305                 writel(pattern, &address[offset]);
306                 if (progress(offset))
307                         return NULL;
308         }
309
310         puts("\nCheck and invert pattern");
311         /* Check each location and invert it for the second pass. */
312         for (pattern = 1, offset = 0; offset < nb_words; pattern++, offset++) {
313                 if (readl(&address[offset]) != pattern)
314                         return &address[offset];
315
316                 antipattern = ~pattern;
317                 writel(antipattern, &address[offset]);
318                 if (progress(offset))
319                         return NULL;
320         }
321
322         puts("\nCheck inverted pattern");
323         /* Check each location for the inverted pattern and zero it. */
324         for (pattern = 1, offset = 0; offset < nb_words; pattern++, offset++) {
325                 antipattern = ~pattern;
326                 if (readl(&address[offset]) != antipattern)
327                         return &address[offset];
328                 if (progress(offset))
329                         return NULL;
330         }
331         printf("\n");
332
333         return NULL;
334 }
335
336 static enum test_result databuswalk0(struct stm32mp1_ddrctl *ctl,
337                                      struct stm32mp1_ddrphy *phy,
338                                      char *string, int argc, char *argv[])
339 {
340         int i;
341         u32 loop = 0, nb_loop;
342         u32 addr;
343         u32 error = 0;
344         u32 data;
345
346         if (get_nb_loop(string, argc, argv, 0, &nb_loop, 100))
347                 return TEST_ERROR;
348         if (get_addr(string, argc, argv, 1, &addr))
349                 return TEST_ERROR;
350
351         printf("running %d loops at 0x%x\n", nb_loop, addr);
352         while (!error) {
353                 for (i = 0; i < 32; i++)
354                         writel(~(1 << i), addr + 4 * i);
355                 for (i = 0; i < 32; i++) {
356                         data = readl(addr + 4 * i);
357                         if (~(1 << i) !=  data) {
358                                 error |= 1 << i;
359                                 debug("%x: error %x expected %x => error:%x\n",
360                                       addr + 4 * i, data, ~(1 << i), error);
361                         }
362                 }
363                 if (test_loop_end(&loop, nb_loop, 1000))
364                         break;
365                 for (i = 0; i < 32; i++)
366                         writel(0, addr + 4 * i);
367         }
368         if (error) {
369                 sprintf(string, "loop %d: error for bits 0x%x",
370                         loop, error);
371                 return TEST_FAILED;
372         }
373         sprintf(string, "no error for %d loops", loop);
374         return TEST_PASSED;
375 }
376
377 static enum test_result databuswalk1(struct stm32mp1_ddrctl *ctl,
378                                      struct stm32mp1_ddrphy *phy,
379                                      char *string, int argc, char *argv[])
380 {
381         int i;
382         u32 loop = 0, nb_loop;
383         u32 addr;
384         u32 error = 0;
385         u32 data;
386
387         if (get_nb_loop(string, argc, argv, 0, &nb_loop, 100))
388                 return TEST_ERROR;
389         if (get_addr(string, argc, argv, 1, &addr))
390                 return TEST_ERROR;
391         printf("running %d loops at 0x%x\n", nb_loop, addr);
392         while (!error) {
393                 for (i = 0; i < 32; i++)
394                         writel(1 << i, addr + 4 * i);
395                 for (i = 0; i < 32; i++) {
396                         data = readl(addr + 4 * i);
397                         if ((1 << i) !=  data) {
398                                 error |= 1 << i;
399                                 debug("%x: error %x expected %x => error:%x\n",
400                                       addr + 4 * i, data, (1 << i), error);
401                         }
402                 }
403                 if (test_loop_end(&loop, nb_loop, 1000))
404                         break;
405                 for (i = 0; i < 32; i++)
406                         writel(0, addr + 4 * i);
407         }
408         if (error) {
409                 sprintf(string, "loop %d: error for bits 0x%x",
410                         loop, error);
411                 return TEST_FAILED;
412         }
413         sprintf(string, "no error for %d loops", loop);
414         return TEST_PASSED;
415 }
416
417 static enum test_result test_databus(struct stm32mp1_ddrctl *ctl,
418                                      struct stm32mp1_ddrphy *phy,
419                                      char *string, int argc, char *argv[])
420 {
421         u32 addr;
422         u32 error;
423
424         if (get_addr(string, argc, argv, 0, &addr))
425                 return TEST_ERROR;
426         error = databus((u32 *)addr);
427         if (error) {
428                 sprintf(string, "0x%x: error for bits 0x%x",
429                         addr, error);
430                 return TEST_FAILED;
431         }
432         sprintf(string, "address 0x%x", addr);
433         return TEST_PASSED;
434 }
435
436 static enum test_result test_addressbus(struct stm32mp1_ddrctl *ctl,
437                                         struct stm32mp1_ddrphy *phy,
438                                         char *string, int argc, char *argv[])
439 {
440         u32 addr;
441         u32 bufsize;
442         u32 error;
443
444         if (get_bufsize(string, argc, argv, 0, &bufsize, 4 * 1024))
445                 return TEST_ERROR;
446         if (!is_power_of_2(bufsize)) {
447                 sprintf(string, "size 0x%x is not a power of 2",
448                         (u32)bufsize);
449                 return TEST_ERROR;
450         }
451         if (get_addr(string, argc, argv, 1, &addr))
452                 return TEST_ERROR;
453
454         error = (u32)addressbus((u32 *)addr, bufsize);
455         if (error) {
456                 sprintf(string, "0x%x: error for address 0x%x",
457                         addr, error);
458                 return TEST_FAILED;
459         }
460         sprintf(string, "address 0x%x, size 0x%x",
461                 addr, bufsize);
462         return TEST_PASSED;
463 }
464
465 static enum test_result test_memdevice(struct stm32mp1_ddrctl *ctl,
466                                        struct stm32mp1_ddrphy *phy,
467                                        char *string, int argc, char *argv[])
468 {
469         u32 addr;
470         size_t bufsize;
471         u32 error;
472
473         if (get_bufsize(string, argc, argv, 0, &bufsize, 4 * 1024))
474                 return TEST_ERROR;
475         if (get_addr(string, argc, argv, 1, &addr))
476                 return TEST_ERROR;
477         error = (u32)memdevice((u32 *)addr, (unsigned long)bufsize);
478         if (error) {
479                 sprintf(string, "0x%x: error for address 0x%x",
480                         addr, error);
481                 return TEST_FAILED;
482         }
483         sprintf(string, "address 0x%x, size 0x%x",
484                 addr, bufsize);
485         return TEST_PASSED;
486 }
487
488 /**********************************************************************
489  *
490  * Function:    sso
491  *
492  * Description: Test the Simultaneous Switching Output.
493  *              Verifies succes sive reads and writes to the same memory word,
494  *              holding one bit constant while toggling all other data bits
495  *              simultaneously
496  *              => stress the data bus over an address range
497  *
498  *              The CPU writes to each address in the given range.
499  *              For each bit, first the CPU holds the bit at 1 while
500  *              toggling the other bits, and then the CPU holds the bit at 0
501  *              while toggling the other bits.
502  *              After each write, the CPU reads the address that was written
503  *              to verify that it contains the correct data
504  *
505  **********************************************************************/
506 static enum test_result test_sso(struct stm32mp1_ddrctl *ctl,
507                                  struct stm32mp1_ddrphy *phy,
508                                  char *string, int argc, char *argv[])
509 {
510         int i, j;
511         u32 addr, bufsize, remaining, offset;
512         u32 error = 0;
513         u32 data;
514
515         if (get_bufsize(string, argc, argv, 0, &bufsize, 4))
516                 return TEST_ERROR;
517         if (get_addr(string, argc, argv, 1, &addr))
518                 return TEST_ERROR;
519
520         printf("running sso at 0x%x length 0x%x", addr, bufsize);
521         offset = addr;
522         remaining = bufsize;
523         while (remaining) {
524                 for (i = 0; i < 32; i++) {
525                         /* write pattern. */
526                         for (j = 0; j < 6; j++) {
527                                 switch (j) {
528                                 case 0:
529                                 case 2:
530                                         data = 1 << i;
531                                         break;
532                                 case 3:
533                                 case 5:
534                                         data = ~(1 << i);
535                                         break;
536                                 case 1:
537                                         data = ~0x0;
538                                         break;
539                                 case 4:
540                                         data = 0x0;
541                                         break;
542                                 }
543
544                                 writel(data, offset);
545                                 error = check_addr(offset, data);
546                                 if (error)
547                                         goto end;
548                         }
549                 }
550                 offset += 4;
551                 remaining -= 4;
552                 if (progress(offset << 7))
553                         goto end;
554         }
555         puts("\n");
556
557 end:
558         if (error) {
559                 sprintf(string, "error for pattern 0x%x @0x%x",
560                         data, offset);
561                 return TEST_FAILED;
562         }
563         sprintf(string, "no error for sso at 0x%x length 0x%x", addr, bufsize);
564         return TEST_PASSED;
565 }
566
567 /**********************************************************************
568  *
569  * Function:    Random
570  *
571  * Description: Verifies r/w with pseudo-ramdom value on one region
572  *              + write the region (individual access)
573  *              + memcopy to the 2nd region (try to use burst)
574  *              + verify the 2 regions
575  *
576  **********************************************************************/
577 static enum test_result test_random(struct stm32mp1_ddrctl *ctl,
578                                     struct stm32mp1_ddrphy *phy,
579                                     char *string, int argc, char *argv[])
580 {
581         u32 addr, offset, value = 0;
582         size_t bufsize;
583         u32 loop = 0, nb_loop;
584         u32 error = 0;
585         unsigned int seed;
586
587         if (get_bufsize(string, argc, argv, 0, &bufsize, 8 * 1024))
588                 return TEST_ERROR;
589         if (get_nb_loop(string, argc, argv, 1, &nb_loop, 1))
590                 return TEST_ERROR;
591         if (get_addr(string, argc, argv, 2, &addr))
592                 return TEST_ERROR;
593
594         bufsize /= 2;
595         printf("running %d loops copy from 0x%x to 0x%x (buffer size=0x%x)\n",
596                nb_loop, addr, addr + bufsize, bufsize);
597         while (!error) {
598                 seed = rand();
599                 for (offset = 0; offset < bufsize; offset += 4)
600                         writel(rand(), addr + offset);
601
602                 memcpy((void *)addr + bufsize, (void *)addr, bufsize);
603
604                 srand(seed);
605                 for (offset = 0; offset < 2 * bufsize; offset += 4) {
606                         if (offset == bufsize)
607                                 srand(seed);
608                         value = rand();
609                         error = check_addr(addr + offset, value);
610                         if (error)
611                                 break;
612                         if (progress(offset))
613                                 return TEST_FAILED;
614                 }
615                 if (test_loop_end(&loop, nb_loop, 100))
616                         break;
617         }
618         putc('\n');
619
620         if (error) {
621                 sprintf(string,
622                         "loop %d: error for address 0x%x: 0x%x expected 0x%x",
623                         loop, offset, readl(offset), value);
624                 return TEST_FAILED;
625         }
626         sprintf(string, "no error for %d loops, size 0x%x",
627                 loop, bufsize);
628         return TEST_PASSED;
629 }
630
631 /**********************************************************************
632  *
633  * Function:    noise
634  *
635  * Description: Verifies r/w while forcing switching of all data bus lines.
636  *              optimised 4 iteration write/read/write/read cycles...
637  *              for pattern and inversed pattern
638  *
639  **********************************************************************/
640 void do_noise(u32 addr, u32 pattern, u32 *result)
641 {
642         __asm__("push {R0-R11}");
643         __asm__("mov r0, %0" : : "r" (addr));
644         __asm__("mov r1, %0" : : "r" (pattern));
645         __asm__("mov r11, %0" : : "r" (result));
646
647         __asm__("mvn r2, r1");
648
649         __asm__("str r1, [r0]");
650         __asm__("ldr r3, [r0]");
651         __asm__("str r2, [r0]");
652         __asm__("ldr r4, [r0]");
653
654         __asm__("str r1, [r0]");
655         __asm__("ldr r5, [r0]");
656         __asm__("str r2, [r0]");
657         __asm__("ldr r6, [r0]");
658
659         __asm__("str r1, [r0]");
660         __asm__("ldr r7, [r0]");
661         __asm__("str r2, [r0]");
662         __asm__("ldr r8, [r0]");
663
664         __asm__("str r1, [r0]");
665         __asm__("ldr r9, [r0]");
666         __asm__("str r2, [r0]");
667         __asm__("ldr r10, [r0]");
668
669         __asm__("stmia R11!, {R3-R10}");
670
671         __asm__("pop {R0-R11}");
672 }
673
674 static enum test_result test_noise(struct stm32mp1_ddrctl *ctl,
675                                    struct stm32mp1_ddrphy *phy,
676                                    char *string, int argc, char *argv[])
677 {
678         u32 addr, pattern;
679         u32 result[8];
680         int i;
681         enum test_result res = TEST_PASSED;
682
683         if (get_pattern(string, argc, argv, 0, &pattern, 0xFFFFFFFF))
684                 return TEST_ERROR;
685         if (get_addr(string, argc, argv, 1, &addr))
686                 return TEST_ERROR;
687
688         printf("running noise for 0x%x at 0x%x\n", pattern, addr);
689
690         do_noise(addr, pattern, result);
691
692         for (i = 0; i < 0x8;) {
693                 if (check_addr((u32)&result[i++], pattern))
694                         res = TEST_FAILED;
695                 if (check_addr((u32)&result[i++], ~pattern))
696                         res = TEST_FAILED;
697         }
698
699         return res;
700 }
701
702 /**********************************************************************
703  *
704  * Function:    noise_burst
705  *
706  * Description: Verifies r/w while forcing switching of all data bus lines.
707  *              optimised write loop witrh store multiple to use burst
708  *              for pattern and inversed pattern
709  *
710  **********************************************************************/
711 void do_noise_burst(u32 addr, u32 pattern, size_t bufsize)
712 {
713         __asm__("push {R0-R9}");
714         __asm__("mov r0, %0" : : "r" (addr));
715         __asm__("mov r1, %0" : : "r" (pattern));
716         __asm__("mov r9, %0" : : "r" (bufsize));
717
718         __asm__("mvn r2, r1");
719         __asm__("mov r3, r1");
720         __asm__("mov r4, r2");
721         __asm__("mov r5, r1");
722         __asm__("mov r6, r2");
723         __asm__("mov r7, r1");
724         __asm__("mov r8, r2");
725
726         __asm__("loop1:");
727         __asm__("stmia R0!, {R1-R8}");
728         __asm__("stmia R0!, {R1-R8}");
729         __asm__("stmia R0!, {R1-R8}");
730         __asm__("stmia R0!, {R1-R8}");
731         __asm__("subs r9, r9, #128");
732         __asm__("bge loop1");
733         __asm__("pop {R0-R9}");
734 }
735
736 /* chunk size enough to allow interruption with Ctrl-C*/
737 #define CHUNK_SIZE      0x8000000
738 static enum test_result test_noise_burst(struct stm32mp1_ddrctl *ctl,
739                                          struct stm32mp1_ddrphy *phy,
740                                          char *string, int argc, char *argv[])
741 {
742         u32 addr, offset, pattern;
743         size_t bufsize, remaining, size;
744         int i;
745         enum test_result res = TEST_PASSED;
746
747         if (get_bufsize(string, argc, argv, 0, &bufsize, 4 * 1024))
748                 return TEST_ERROR;
749         if (get_pattern(string, argc, argv, 1, &pattern, 0xFFFFFFFF))
750                 return TEST_ERROR;
751         if (get_addr(string, argc, argv, 2, &addr))
752                 return TEST_ERROR;
753
754         printf("running noise burst for 0x%x at 0x%x + 0x%x",
755                pattern, addr, bufsize);
756
757         offset = addr;
758         remaining = bufsize;
759         size = CHUNK_SIZE;
760         while (remaining) {
761                 if (remaining < size)
762                         size = remaining;
763                 do_noise_burst(offset, pattern, size);
764                 remaining -= size;
765                 offset += size;
766                 if (progress(offset)) {
767                         res = TEST_FAILED;
768                         goto end;
769                 }
770         }
771         puts("\ncheck buffer");
772         for (i = 0; i < bufsize;) {
773                 if (check_addr(addr + i, pattern))
774                         res = TEST_FAILED;
775                 i += 4;
776                 if (check_addr(addr + i, ~pattern))
777                         res = TEST_FAILED;
778                 i += 4;
779                 if (progress(i)) {
780                         res = TEST_FAILED;
781                         goto end;
782                 }
783         }
784 end:
785         puts("\n");
786         return res;
787 }
788
789 /**********************************************************************
790  *
791  * Function:    pattern test
792  *
793  * Description: optimized loop for read/write pattern (array of 8 u32)
794  *
795  **********************************************************************/
796 #define PATTERN_SIZE    8
797 static enum test_result test_loop(const u32 *pattern, u32 *address,
798                                   const u32 bufsize)
799 {
800         int i;
801         int j;
802         enum test_result res = TEST_PASSED;
803         u32 offset, testsize, remaining;
804
805         offset = (u32)address;
806         remaining = bufsize;
807         while (remaining) {
808                 testsize = bufsize > 0x1000000 ? 0x1000000 : bufsize;
809
810                 __asm__("push {R0-R10}");
811                 __asm__("mov r0, %0" : : "r" (pattern));
812                 __asm__("mov r1, %0" : : "r" (offset));
813                 __asm__("mov r2, %0" : : "r" (testsize));
814                 __asm__("ldmia r0!, {R3-R10}");
815
816                 __asm__("loop2:");
817                 __asm__("stmia r1!, {R3-R10}");
818                 __asm__("stmia r1!, {R3-R10}");
819                 __asm__("stmia r1!, {R3-R10}");
820                 __asm__("stmia r1!, {R3-R10}");
821                 __asm__("subs r2, r2, #128");
822                 __asm__("bge loop2");
823                 __asm__("pop {R0-R10}");
824
825                 offset += testsize;
826                 remaining -= testsize;
827                 if (progress((u32)offset)) {
828                         res = TEST_FAILED;
829                         goto end;
830                 }
831         }
832
833         puts("\ncheck buffer");
834         for (i = 0; i < bufsize; i += PATTERN_SIZE * 4) {
835                 for (j = 0; j < PATTERN_SIZE; j++, address++)
836                         if (check_addr((u32)address, pattern[j])) {
837                                 res = TEST_FAILED;
838                                 goto end;
839                         }
840                 if (progress(i)) {
841                         res = TEST_FAILED;
842                         goto end;
843                 }
844         }
845
846 end:
847         puts("\n");
848         return res;
849 }
850
851 const u32 pattern_div1_x16[PATTERN_SIZE] = {
852         0x0000FFFF, 0x0000FFFF, 0x0000FFFF, 0x0000FFFF,
853         0x0000FFFF, 0x0000FFFF, 0x0000FFFF, 0x0000FFFF
854 };
855
856 const u32 pattern_div2_x16[PATTERN_SIZE] = {
857         0xFFFFFFFF, 0x00000000, 0xFFFFFFFF, 0x00000000,
858         0xFFFFFFFF, 0x00000000, 0xFFFFFFFF, 0x00000000
859 };
860
861 const u32 pattern_div4_x16[PATTERN_SIZE] = {
862         0xFFFFFFFF, 0xFFFFFFFF, 0x00000000, 0x00000000,
863         0xFFFFFFFF, 0xFFFFFFFF, 0x00000000, 0x00000000
864 };
865
866 const u32 pattern_div4_x32[PATTERN_SIZE] = {
867         0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
868         0x00000000, 0x00000000, 0x00000000, 0x00000000
869 };
870
871 const u32 pattern_mostly_zero_x16[PATTERN_SIZE] = {
872         0x00000000, 0x00000000, 0x00000000, 0x0000FFFF,
873         0x00000000, 0x00000000, 0x00000000, 0x00000000
874 };
875
876 const u32 pattern_mostly_zero_x32[PATTERN_SIZE] = {
877         0x00000000, 0x00000000, 0x00000000, 0xFFFFFFFF,
878         0x00000000, 0x00000000, 0x00000000, 0x00000000
879 };
880
881 const u32 pattern_mostly_one_x16[PATTERN_SIZE] = {
882         0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0000FFFF,
883         0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF
884 };
885
886 const u32 pattern_mostly_one_x32[PATTERN_SIZE] = {
887         0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x00000000,
888         0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF
889 };
890
891 #define NB_PATTERN      5
892 static enum test_result test_freq_pattern(struct stm32mp1_ddrctl *ctl,
893                                           struct stm32mp1_ddrphy *phy,
894                                           char *string, int argc, char *argv[])
895 {
896         const u32 * const patterns_x16[NB_PATTERN] = {
897                 pattern_div1_x16,
898                 pattern_div2_x16,
899                 pattern_div4_x16,
900                 pattern_mostly_zero_x16,
901                 pattern_mostly_one_x16,
902         };
903         const u32 * const patterns_x32[NB_PATTERN] = {
904                 pattern_div2_x16,
905                 pattern_div4_x16,
906                 pattern_div4_x32,
907                 pattern_mostly_zero_x32,
908                 pattern_mostly_one_x32
909         };
910         const char *patterns_comments[NB_PATTERN] = {
911                 "switching at frequency F/1",
912                 "switching at frequency F/2",
913                 "switching at frequency F/4",
914                 "mostly zero",
915                 "mostly one"
916         };
917
918         enum test_result res = TEST_PASSED, pattern_res;
919         int i, bus_width;
920         const u32 **patterns;
921         u32 bufsize;
922
923         if (get_bufsize(string, argc, argv, 0, &bufsize, 4 * 1024))
924                 return TEST_ERROR;
925
926         switch (readl(&ctl->mstr) & DDRCTRL_MSTR_DATA_BUS_WIDTH_MASK) {
927         case DDRCTRL_MSTR_DATA_BUS_WIDTH_HALF:
928         case DDRCTRL_MSTR_DATA_BUS_WIDTH_QUARTER:
929                 bus_width = 16;
930                 break;
931         default:
932                 bus_width = 32;
933                 break;
934         }
935
936         printf("running test pattern at 0x%08x length 0x%x width = %d\n",
937                STM32_DDR_BASE, bufsize, bus_width);
938
939         patterns =
940                 (const u32 **)(bus_width == 16 ? patterns_x16 : patterns_x32);
941
942         for (i = 0; i < NB_PATTERN; i++) {
943                 printf("test data pattern %s:", patterns_comments[i]);
944                 pattern_res = test_loop(patterns[i], (u32 *)STM32_DDR_BASE,
945                                         bufsize);
946                 if (pattern_res != TEST_PASSED) {
947                         printf("Failed\n");
948                         return pattern_res;
949                 }
950                 printf("Passed\n");
951         }
952
953         return res;
954 }
955
956 /**********************************************************************
957  *
958  * Function:    pattern test with size
959  *
960  * Description: loop for write pattern
961  *
962  **********************************************************************/
963
964 static enum test_result test_loop_size(const u32 *pattern, u32 size,
965                                        u32 *address,
966                                        const u32 bufsize)
967 {
968         int i, j;
969         enum test_result res = TEST_PASSED;
970         u32 *p = address;
971
972         for (i = 0; i < bufsize; i += size * 4) {
973                 for (j = 0; j < size ; j++, p++)
974                         *p = pattern[j];
975                 if (progress(i)) {
976                         res = TEST_FAILED;
977                         goto end;
978                 }
979         }
980
981         puts("\ncheck buffer");
982         p = address;
983         for (i = 0; i < bufsize; i += size * 4) {
984                 for (j = 0; j < size; j++, p++)
985                         if (check_addr((u32)p, pattern[j])) {
986                                 res = TEST_FAILED;
987                                 goto end;
988                         }
989                 if (progress(i)) {
990                         res = TEST_FAILED;
991                         goto end;
992                 }
993         }
994
995 end:
996         puts("\n");
997         return res;
998 }
999
1000 static enum test_result test_checkboard(struct stm32mp1_ddrctl *ctl,
1001                                         struct stm32mp1_ddrphy *phy,
1002                                         char *string, int argc, char *argv[])
1003 {
1004         enum test_result res = TEST_PASSED;
1005         u32 bufsize, nb_loop, loop = 0, addr;
1006         int i;
1007
1008         u32 checkboard[2] = {0x55555555, 0xAAAAAAAA};
1009
1010         if (get_bufsize(string, argc, argv, 0, &bufsize, 4 * 1024))
1011                 return TEST_ERROR;
1012         if (get_nb_loop(string, argc, argv, 1, &nb_loop, 1))
1013                 return TEST_ERROR;
1014         if (get_addr(string, argc, argv, 2, &addr))
1015                 return TEST_ERROR;
1016
1017         printf("running %d loops at 0x%08x length 0x%x\n",
1018                nb_loop, addr, bufsize);
1019         while (1) {
1020                 for (i = 0; i < 2; i++) {
1021                         res = test_loop_size(checkboard, 2, (u32 *)addr,
1022                                              bufsize);
1023                         if (res)
1024                                 return res;
1025                         checkboard[0] = ~checkboard[0];
1026                         checkboard[1] = ~checkboard[1];
1027                 }
1028                 if (test_loop_end(&loop, nb_loop, 1))
1029                         break;
1030         }
1031         sprintf(string, "no error for %d loops at 0x%08x length 0x%x",
1032                 loop, addr, bufsize);
1033
1034         return res;
1035 }
1036
1037 static enum test_result test_blockseq(struct stm32mp1_ddrctl *ctl,
1038                                       struct stm32mp1_ddrphy *phy,
1039                                       char *string, int argc, char *argv[])
1040 {
1041         enum test_result res = TEST_PASSED;
1042         u32 bufsize, nb_loop, loop = 0, addr, value;
1043         int i;
1044
1045         if (get_bufsize(string, argc, argv, 0, &bufsize, 4 * 1024))
1046                 return TEST_ERROR;
1047         if (get_nb_loop(string, argc, argv, 1, &nb_loop, 1))
1048                 return TEST_ERROR;
1049         if (get_addr(string, argc, argv, 2, &addr))
1050                 return TEST_ERROR;
1051
1052         printf("running %d loops at 0x%08x length 0x%x\n",
1053                nb_loop, addr, bufsize);
1054         while (1) {
1055                 for (i = 0; i < 256; i++) {
1056                         value = i | i << 8 | i << 16 | i << 24;
1057                         printf("pattern = %08x", value);
1058                         res = test_loop_size(&value, 1, (u32 *)addr, bufsize);
1059                         if (res != TEST_PASSED)
1060                                 return res;
1061                 }
1062                 if (test_loop_end(&loop, nb_loop, 1))
1063                         break;
1064         }
1065         sprintf(string, "no error for %d loops at 0x%08x length 0x%x",
1066                 loop, addr, bufsize);
1067
1068         return res;
1069 }
1070
1071 static enum test_result test_walkbit0(struct stm32mp1_ddrctl *ctl,
1072                                       struct stm32mp1_ddrphy *phy,
1073                                       char *string, int argc, char *argv[])
1074 {
1075         enum test_result res = TEST_PASSED;
1076         u32 bufsize, nb_loop, loop = 0, addr, value;
1077         int i;
1078
1079         if (get_bufsize(string, argc, argv, 0, &bufsize, 4 * 1024))
1080                 return TEST_ERROR;
1081         if (get_nb_loop(string, argc, argv, 1, &nb_loop, 1))
1082                 return TEST_ERROR;
1083         if (get_addr(string, argc, argv, 2, &addr))
1084                 return TEST_ERROR;
1085
1086         printf("running %d loops at 0x%08x length 0x%x\n",
1087                nb_loop, addr, bufsize);
1088         while (1) {
1089                 for (i = 0; i < 64; i++) {
1090                         if (i < 32)
1091                                 value = 1 << i;
1092                         else
1093                                 value = 1 << (63 - i);
1094
1095                         printf("pattern = %08x", value);
1096                         res = test_loop_size(&value, 1, (u32 *)addr, bufsize);
1097                         if (res != TEST_PASSED)
1098                                 return res;
1099                 }
1100                 if (test_loop_end(&loop, nb_loop, 1))
1101                         break;
1102         }
1103         sprintf(string, "no error for %d loops at 0x%08x length 0x%x",
1104                 loop, addr, bufsize);
1105
1106         return res;
1107 }
1108
1109 static enum test_result test_walkbit1(struct stm32mp1_ddrctl *ctl,
1110                                       struct stm32mp1_ddrphy *phy,
1111                                       char *string, int argc, char *argv[])
1112 {
1113         enum test_result res = TEST_PASSED;
1114         u32 bufsize, nb_loop, loop = 0, addr, value;
1115         int i;
1116
1117         if (get_bufsize(string, argc, argv, 0, &bufsize, 4 * 1024))
1118                 return TEST_ERROR;
1119         if (get_nb_loop(string, argc, argv, 1, &nb_loop, 1))
1120                 return TEST_ERROR;
1121         if (get_addr(string, argc, argv, 2, &addr))
1122                 return TEST_ERROR;
1123
1124         printf("running %d loops at 0x%08x length 0x%x\n",
1125                nb_loop, addr, bufsize);
1126         while (1) {
1127                 for (i = 0; i < 64; i++) {
1128                         if (i < 32)
1129                                 value = ~(1 << i);
1130                         else
1131                                 value = ~(1 << (63 - i));
1132
1133                         printf("pattern = %08x", value);
1134                         res = test_loop_size(&value, 1, (u32 *)addr, bufsize);
1135                         if (res != TEST_PASSED)
1136                                 return res;
1137                 }
1138                 if (test_loop_end(&loop, nb_loop, 1))
1139                         break;
1140         }
1141         sprintf(string, "no error for %d loops at 0x%08x length 0x%x",
1142                 loop, addr, bufsize);
1143
1144         return res;
1145 }
1146
1147 /*
1148  * try to catch bad bits which are dependent on the current values of
1149  * surrounding bits in either the same word32
1150  */
1151 static enum test_result test_bitspread(struct stm32mp1_ddrctl *ctl,
1152                                        struct stm32mp1_ddrphy *phy,
1153                                        char *string, int argc, char *argv[])
1154 {
1155         enum test_result res = TEST_PASSED;
1156         u32 bufsize, nb_loop, loop = 0, addr, bitspread[4];
1157         int i, j;
1158
1159         if (get_bufsize(string, argc, argv, 0, &bufsize, 4 * 1024))
1160                 return TEST_ERROR;
1161         if (get_nb_loop(string, argc, argv, 1, &nb_loop, 1))
1162                 return TEST_ERROR;
1163         if (get_addr(string, argc, argv, 2, &addr))
1164                 return TEST_ERROR;
1165
1166         printf("running %d loops at 0x%08x length 0x%x\n",
1167                nb_loop, addr, bufsize);
1168         while (1) {
1169                 for (i = 1; i < 32; i++) {
1170                         for (j = 0; j < i; j++) {
1171                                 if (i < 32)
1172                                         bitspread[0] = (1 << i) | (1 << j);
1173                                 else
1174                                         bitspread[0] = (1 << (63 - i)) |
1175                                                        (1 << (63 - j));
1176                                 bitspread[1] = bitspread[0];
1177                                 bitspread[2] = ~bitspread[0];
1178                                 bitspread[3] = ~bitspread[0];
1179                                 printf("pattern = %08x", bitspread[0]);
1180
1181                                 res = test_loop_size(bitspread, 4, (u32 *)addr,
1182                                                      bufsize);
1183                                 if (res != TEST_PASSED)
1184                                         return res;
1185                         }
1186                 }
1187                 if (test_loop_end(&loop, nb_loop, 1))
1188                         break;
1189         }
1190         sprintf(string, "no error for %d loops at 0x%08x length 0x%x",
1191                 loop, addr, bufsize);
1192
1193         return res;
1194 }
1195
1196 static enum test_result test_bitflip(struct stm32mp1_ddrctl *ctl,
1197                                      struct stm32mp1_ddrphy *phy,
1198                                      char *string, int argc, char *argv[])
1199 {
1200         enum test_result res = TEST_PASSED;
1201         u32 bufsize, nb_loop, loop = 0, addr;
1202         int i;
1203
1204         u32 bitflip[4];
1205
1206         if (get_bufsize(string, argc, argv, 0, &bufsize, 4 * 1024))
1207                 return TEST_ERROR;
1208         if (get_nb_loop(string, argc, argv, 1, &nb_loop, 1))
1209                 return TEST_ERROR;
1210         if (get_addr(string, argc, argv, 2, &addr))
1211                 return TEST_ERROR;
1212
1213         printf("running %d loops at 0x%08x length 0x%x\n",
1214                nb_loop, addr, bufsize);
1215         while (1) {
1216                 for (i = 0; i < 32; i++) {
1217                         bitflip[0] = 1 << i;
1218                         bitflip[1] = bitflip[0];
1219                         bitflip[2] = ~bitflip[0];
1220                         bitflip[3] = bitflip[2];
1221                         printf("pattern = %08x", bitflip[0]);
1222
1223                         res = test_loop_size(bitflip, 4, (u32 *)addr, bufsize);
1224                         if (res != TEST_PASSED)
1225                                 return res;
1226                 }
1227                 if (test_loop_end(&loop, nb_loop, 1))
1228                         break;
1229         }
1230         sprintf(string, "no error for %d loops at 0x%08x length 0x%x",
1231                 loop, addr, bufsize);
1232
1233         return res;
1234 }
1235
1236 /**********************************************************************
1237  *
1238  * Function: infinite read access to DDR
1239  *
1240  * Description: continuous read the same pattern at the same address
1241  *
1242  **********************************************************************/
1243 static enum test_result test_read(struct stm32mp1_ddrctl *ctl,
1244                                   struct stm32mp1_ddrphy *phy,
1245                                   char *string, int argc, char *argv[])
1246 {
1247         u32 *addr;
1248         u32 data;
1249         u32 loop = 0;
1250         int i, size = 1024 * 1024;
1251         bool random = false;
1252
1253         if (get_addr(string, argc, argv, 0, (u32 *)&addr))
1254                 return TEST_ERROR;
1255
1256         if (get_pattern(string, argc, argv, 1, &data, 0xA5A5AA55))
1257                 return TEST_ERROR;
1258
1259         if ((u32)addr == ADDR_INVALID) {
1260                 printf("running random\n");
1261                 random = true;
1262         } else {
1263                 printf("running at 0x%08x with pattern=0x%08x\n",
1264                        (u32)addr, data);
1265                 writel(data, addr);
1266         }
1267
1268         while (1) {
1269                 for (i = 0; i < size; i++) {
1270                         if (random)
1271                                 addr = (u32 *)(STM32_DDR_BASE +
1272                                        (rand() & (STM32_DDR_SIZE - 1) & ~0x3));
1273                         data = readl(addr);
1274                 }
1275                 if (test_loop_end(&loop, 0, 1))
1276                         break;
1277         }
1278         if (random)
1279                 sprintf(string, "%d loops random", loop);
1280         else
1281                 sprintf(string, "%d loops at 0x%x: %x", loop, (u32)addr, data);
1282
1283         return TEST_PASSED;
1284 }
1285
1286 /**********************************************************************
1287  *
1288  * Function: infinite write access to DDR
1289  *
1290  * Description: continuous write the same pattern at the same address
1291  *
1292  **********************************************************************/
1293 static enum test_result test_write(struct stm32mp1_ddrctl *ctl,
1294                                    struct stm32mp1_ddrphy *phy,
1295                                    char *string, int argc, char *argv[])
1296 {
1297         u32 *addr;
1298         u32 data;
1299         u32 loop = 0;
1300         int i, size = 1024 * 1024;
1301         bool random = false;
1302
1303         if (get_addr(string, argc, argv, 0, (u32 *)&addr))
1304                 return TEST_ERROR;
1305
1306         if (get_pattern(string, argc, argv, 1, &data, 0xA5A5AA55))
1307                 return TEST_ERROR;
1308
1309         if ((u32)addr == ADDR_INVALID) {
1310                 printf("running random\n");
1311                 random = true;
1312         } else {
1313                 printf("running at 0x%08x with pattern 0x%08x\n",
1314                        (u32)addr, data);
1315         }
1316
1317         while (1) {
1318                 for (i = 0; i < size; i++) {
1319                         if (random) {
1320                                 addr = (u32 *)(STM32_DDR_BASE +
1321                                        (rand() & (STM32_DDR_SIZE - 1) & ~0x3));
1322                                 data = rand();
1323                         }
1324                         writel(data, addr);
1325                 }
1326                 if (test_loop_end(&loop, 0, 1))
1327                         break;
1328         }
1329         if (random)
1330                 sprintf(string, "%d loops random", loop);
1331         else
1332                 sprintf(string, "%d loops at 0x%x: %x", loop, (u32)addr, data);
1333
1334         return TEST_PASSED;
1335 }
1336
1337 #define NB_TEST_INFINITE 2
1338 static enum test_result test_all(struct stm32mp1_ddrctl *ctl,
1339                                  struct stm32mp1_ddrphy *phy,
1340                                  char *string, int argc, char *argv[])
1341 {
1342         enum test_result res = TEST_PASSED, result;
1343         int i, nb_error = 0;
1344         u32 loop = 0, nb_loop;
1345
1346         if (get_nb_loop(string, argc, argv, 0, &nb_loop, 1))
1347                 return TEST_ERROR;
1348
1349         while (!nb_error) {
1350                 /* execute all the test except the lasts which are infinite */
1351                 for (i = 1; i < test_nb - NB_TEST_INFINITE; i++) {
1352                         printf("execute %d:%s\n", (int)i, test[i].name);
1353                         result = test[i].fct(ctl, phy, string, 0, NULL);
1354                         printf("result %d:%s = ", (int)i, test[i].name);
1355                         if (result != TEST_PASSED) {
1356                                 nb_error++;
1357                                 res = TEST_FAILED;
1358                                 puts("Failed");
1359                         } else {
1360                                 puts("Passed");
1361                         }
1362                         puts("\n\n");
1363                 }
1364                 printf("loop %d: %d/%d test failed\n\n\n",
1365                        loop + 1, nb_error, test_nb - NB_TEST_INFINITE);
1366                 if (test_loop_end(&loop, nb_loop, 1))
1367                         break;
1368         }
1369         if (res != TEST_PASSED) {
1370                 sprintf(string, "loop %d: %d/%d test failed", loop, nb_error,
1371                         test_nb - NB_TEST_INFINITE);
1372         } else {
1373                 sprintf(string, "loop %d: %d tests passed", loop,
1374                         test_nb - NB_TEST_INFINITE);
1375         }
1376         return res;
1377 }
1378
1379 /****************************************************************
1380  * TEST Description
1381  ****************************************************************/
1382
1383 const struct test_desc test[] = {
1384         {test_all, "All", "[loop]", "Execute all tests", 1 },
1385         {test_databus, "Simple DataBus", "[addr]",
1386          "Verifies each data line by walking 1 on fixed address",
1387          1
1388          },
1389         {databuswalk0, "DataBusWalking0", "[loop] [addr]",
1390          "Verifies each data bus signal can be driven low (32 word burst)",
1391          2
1392         },
1393         {databuswalk1, "DataBusWalking1", "[loop] [addr]",
1394          "Verifies each data bus signal can be driven high (32 word burst)",
1395          2
1396         },
1397         {test_addressbus, "AddressBus", "[size] [addr]",
1398          "Verifies each relevant bits of the address and checking for aliasing",
1399          2
1400          },
1401         {test_memdevice, "MemDevice", "[size] [addr]",
1402          "Test the integrity of a physical memory (test every storage bit in the region)",
1403          2
1404          },
1405         {test_sso, "SimultaneousSwitchingOutput", "[size] [addr] ",
1406          "Stress the data bus over an address range",
1407          2
1408         },
1409         {test_noise, "Noise", "[pattern] [addr]",
1410          "Verifies r/w while forcing switching of all data bus lines.",
1411          3
1412         },
1413         {test_noise_burst, "NoiseBurst", "[size] [pattern] [addr]",
1414          "burst transfers while forcing switching of the data bus lines",
1415          3
1416         },
1417         {test_random, "Random", "[size] [loop] [addr]",
1418          "Verifies r/w and memcopy(burst for pseudo random value.",
1419          3
1420         },
1421         {test_freq_pattern, "FrequencySelectivePattern", "[size]",
1422          "write & test patterns: Mostly Zero, Mostly One and F/n",
1423          1
1424         },
1425         {test_blockseq, "BlockSequential", "[size] [loop] [addr]",
1426          "test incremental pattern",
1427          3
1428         },
1429         {test_checkboard, "Checkerboard", "[size] [loop] [addr]",
1430          "test checker pattern",
1431          3
1432         },
1433         {test_bitspread, "BitSpread", "[size] [loop] [addr]",
1434          "test Bit Spread pattern",
1435          3
1436         },
1437         {test_bitflip, "BitFlip", "[size] [loop] [addr]",
1438          "test Bit Flip pattern",
1439          3
1440         },
1441         {test_walkbit0, "WalkingOnes", "[size] [loop] [addr]",
1442          "test Walking Ones pattern",
1443          3
1444         },
1445         {test_walkbit1, "WalkingZeroes", "[size] [loop] [addr]",
1446          "test Walking Zeroes pattern",
1447          3
1448         },
1449         /* need to the the 2 last one (infinite) : skipped for test all */
1450         {test_read, "infinite read", "[addr] [pattern]",
1451          "basic test : infinite read access (random: addr=0xFFFFFFFF)", 2},
1452         {test_write, "infinite write", "[addr] [pattern]",
1453          "basic test : infinite write access (random: addr=0xFFFFFFFF)", 2},
1454 };
1455
1456 const int test_nb = ARRAY_SIZE(test);