1 // SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause
3 * Copyright (C) 2019, STMicroelectronics - All Rights Reserved
11 #include <linux/log2.h>
12 #include "stm32mp1_tests.h"
14 #define ADDR_INVALID 0xFFFFFFFF
16 DECLARE_GLOBAL_DATA_PTR;
18 static int get_bufsize(char *string, int argc, char *argv[], int arg_nb,
19 size_t *bufsize, size_t default_size)
24 if (strict_strtoul(argv[arg_nb], 0, &value) < 0) {
25 sprintf(string, "invalid %d parameter %s",
26 arg_nb, argv[arg_nb]);
29 if (value > STM32_DDR_SIZE || value == 0) {
30 sprintf(string, "invalid size %s", argv[arg_nb]);
34 sprintf(string, "unaligned size %s",
40 if (default_size != STM32_DDR_SIZE)
41 *bufsize = default_size;
43 *bufsize = get_ram_size((long *)STM32_DDR_BASE,
49 static int get_nb_loop(char *string, int argc, char *argv[], int arg_nb,
50 u32 *nb_loop, u32 default_nb_loop)
55 if (strict_strtoul(argv[arg_nb], 0, &value) < 0) {
56 sprintf(string, "invalid %d parameter %s",
57 arg_nb, argv[arg_nb]);
61 printf("WARNING: infinite loop requested\n");
64 *nb_loop = default_nb_loop;
70 static int get_addr(char *string, int argc, char *argv[], int arg_nb,
76 if (strict_strtoul(argv[arg_nb], 16, &value) < 0) {
77 sprintf(string, "invalid %d parameter %s",
78 arg_nb, argv[arg_nb]);
81 if (value < STM32_DDR_BASE) {
82 sprintf(string, "too low address %s", argv[arg_nb]);
85 if (value & 0x3 && value != ADDR_INVALID) {
86 sprintf(string, "unaligned address %s",
92 *addr = STM32_DDR_BASE;
98 static int get_pattern(char *string, int argc, char *argv[], int arg_nb,
99 u32 *pattern, u32 default_pattern)
104 if (strict_strtoul(argv[arg_nb], 16, &value) < 0) {
105 sprintf(string, "invalid %d parameter %s",
106 arg_nb, argv[arg_nb]);
111 *pattern = default_pattern;
117 static u32 check_addr(u32 addr, u32 value)
119 u32 data = readl(addr);
122 printf("0x%08x: 0x%08x <=> 0x%08x", addr, data, value);
124 printf("(2nd read: 0x%08x)", data);
126 printf("- read error");
128 printf("- write error");
135 static int progress(u32 offset)
137 if (!(offset & 0xFFFFFF)) {
140 printf("\ntest interrupted!\n");
147 static int test_loop_end(u32 *loop, u32 nb_loop, u32 progress)
150 if (nb_loop && *loop >= nb_loop)
152 if ((*loop) % progress)
154 /* allow to interrupt the test only for progress step */
156 printf("test interrupted!\n");
159 printf("loop #%d\n", *loop);
165 /**********************************************************************
167 * Function: memTestDataBus()
169 * Description: Test the data bus wiring in a memory region by
170 * performing a walking 1's test at a fixed address
171 * within that region. The address is selected
176 * Returns: 0 if the test succeeds.
177 * A non-zero result is the first pattern that failed.
179 **********************************************************************/
180 static u32 databus(u32 *address)
185 /* Perform a walking 1's test at the given address. */
186 for (pattern = 1; pattern != 0; pattern <<= 1) {
187 /* Write the test pattern. */
188 writel(pattern, address);
190 /* Read it back (immediately is okay for this test). */
191 read_value = readl(address);
192 debug("%x: %x <=> %x\n",
193 (u32)address, read_value, pattern);
195 if (read_value != pattern)
202 /**********************************************************************
204 * Function: memTestAddressBus()
206 * Description: Test the address bus wiring in a memory region by
207 * performing a walking 1's test on the relevant bits
208 * of the address and checking for aliasing. This test
209 * will find single-bit address failures such as stuck
210 * -high, stuck-low, and shorted pins. The base address
211 * and size of the region are selected by the caller.
213 * Notes: For best results, the selected base address should
214 * have enough LSB 0's to guarantee single address bit
215 * changes. For example, to test a 64-Kbyte region,
216 * select a base address on a 64-Kbyte boundary. Also,
217 * select the region size as a power-of-two--if at all
220 * Returns: NULL if the test succeeds.
221 * A non-zero result is the first address at which an
222 * aliasing problem was uncovered. By examining the
223 * contents of memory, it may be possible to gather
224 * additional information about the problem.
226 **********************************************************************/
227 static u32 *addressbus(u32 *address, u32 nb_bytes)
229 u32 mask = (nb_bytes / sizeof(u32) - 1);
234 u32 pattern = 0xAAAAAAAA;
235 u32 antipattern = 0x55555555;
237 /* Write the default pattern at each of the power-of-two offsets. */
238 for (offset = 1; (offset & mask) != 0; offset <<= 1)
239 writel(pattern, &address[offset]);
241 /* Check for address bits stuck high. */
243 writel(antipattern, &address[test_offset]);
245 for (offset = 1; (offset & mask) != 0; offset <<= 1) {
246 read_value = readl(&address[offset]);
247 debug("%x: %x <=> %x\n",
248 (u32)&address[offset], read_value, pattern);
249 if (read_value != pattern)
250 return &address[offset];
253 writel(pattern, &address[test_offset]);
255 /* Check for address bits stuck low or shorted. */
256 for (test_offset = 1; (test_offset & mask) != 0; test_offset <<= 1) {
257 writel(antipattern, &address[test_offset]);
258 if (readl(&address[0]) != pattern)
259 return &address[test_offset];
261 for (offset = 1; (offset & mask) != 0; offset <<= 1) {
262 if (readl(&address[offset]) != pattern &&
263 offset != test_offset)
264 return &address[test_offset];
266 writel(pattern, &address[test_offset]);
272 /**********************************************************************
274 * Function: memTestDevice()
276 * Description: Test the integrity of a physical memory device by
277 * performing an increment/decrement test over the
278 * entire region. In the process every storage bit
279 * in the device is tested as a zero and a one. The
280 * base address and the size of the region are
281 * selected by the caller.
285 * Returns: NULL if the test succeeds.
287 * A non-zero result is the first address at which an
288 * incorrect value was read back. By examining the
289 * contents of memory, it may be possible to gather
290 * additional information about the problem.
292 **********************************************************************/
293 static u32 *memdevice(u32 *address, u32 nb_bytes)
296 u32 nb_words = nb_bytes / sizeof(u32);
301 puts("Fill with pattern");
302 /* Fill memory with a known pattern. */
303 for (pattern = 1, offset = 0; offset < nb_words; pattern++, offset++) {
304 writel(pattern, &address[offset]);
305 if (progress(offset))
309 puts("\nCheck and invert pattern");
310 /* Check each location and invert it for the second pass. */
311 for (pattern = 1, offset = 0; offset < nb_words; pattern++, offset++) {
312 if (readl(&address[offset]) != pattern)
313 return &address[offset];
315 antipattern = ~pattern;
316 writel(antipattern, &address[offset]);
317 if (progress(offset))
321 puts("\nCheck inverted pattern");
322 /* Check each location for the inverted pattern and zero it. */
323 for (pattern = 1, offset = 0; offset < nb_words; pattern++, offset++) {
324 antipattern = ~pattern;
325 if (readl(&address[offset]) != antipattern)
326 return &address[offset];
327 if (progress(offset))
335 static enum test_result databuswalk0(struct stm32mp1_ddrctl *ctl,
336 struct stm32mp1_ddrphy *phy,
337 char *string, int argc, char *argv[])
340 u32 loop = 0, nb_loop;
345 if (get_nb_loop(string, argc, argv, 0, &nb_loop, 100))
347 if (get_addr(string, argc, argv, 1, &addr))
350 printf("running %d loops at 0x%x\n", nb_loop, addr);
352 for (i = 0; i < 32; i++)
353 writel(~(1 << i), addr + 4 * i);
354 for (i = 0; i < 32; i++) {
355 data = readl(addr + 4 * i);
356 if (~(1 << i) != data) {
358 debug("%x: error %x expected %x => error:%x\n",
359 addr + 4 * i, data, ~(1 << i), error);
362 if (test_loop_end(&loop, nb_loop, 1000))
364 for (i = 0; i < 32; i++)
365 writel(0, addr + 4 * i);
368 sprintf(string, "loop %d: error for bits 0x%x",
372 sprintf(string, "no error for %d loops", loop);
376 static enum test_result databuswalk1(struct stm32mp1_ddrctl *ctl,
377 struct stm32mp1_ddrphy *phy,
378 char *string, int argc, char *argv[])
381 u32 loop = 0, nb_loop;
386 if (get_nb_loop(string, argc, argv, 0, &nb_loop, 100))
388 if (get_addr(string, argc, argv, 1, &addr))
390 printf("running %d loops at 0x%x\n", nb_loop, addr);
392 for (i = 0; i < 32; i++)
393 writel(1 << i, addr + 4 * i);
394 for (i = 0; i < 32; i++) {
395 data = readl(addr + 4 * i);
396 if ((1 << i) != data) {
398 debug("%x: error %x expected %x => error:%x\n",
399 addr + 4 * i, data, (1 << i), error);
402 if (test_loop_end(&loop, nb_loop, 1000))
404 for (i = 0; i < 32; i++)
405 writel(0, addr + 4 * i);
408 sprintf(string, "loop %d: error for bits 0x%x",
412 sprintf(string, "no error for %d loops", loop);
416 static enum test_result test_databus(struct stm32mp1_ddrctl *ctl,
417 struct stm32mp1_ddrphy *phy,
418 char *string, int argc, char *argv[])
423 if (get_addr(string, argc, argv, 0, &addr))
425 error = databus((u32 *)addr);
427 sprintf(string, "0x%x: error for bits 0x%x",
431 sprintf(string, "address 0x%x", addr);
435 static enum test_result test_addressbus(struct stm32mp1_ddrctl *ctl,
436 struct stm32mp1_ddrphy *phy,
437 char *string, int argc, char *argv[])
443 if (get_bufsize(string, argc, argv, 0, &bufsize, 4 * 1024))
445 if (!is_power_of_2(bufsize)) {
446 sprintf(string, "size 0x%x is not a power of 2",
450 if (get_addr(string, argc, argv, 1, &addr))
453 error = (u32)addressbus((u32 *)addr, bufsize);
455 sprintf(string, "0x%x: error for address 0x%x",
459 sprintf(string, "address 0x%x, size 0x%x",
464 static enum test_result test_memdevice(struct stm32mp1_ddrctl *ctl,
465 struct stm32mp1_ddrphy *phy,
466 char *string, int argc, char *argv[])
472 if (get_bufsize(string, argc, argv, 0, &bufsize, 4 * 1024))
474 if (get_addr(string, argc, argv, 1, &addr))
476 error = (u32)memdevice((u32 *)addr, (unsigned long)bufsize);
478 sprintf(string, "0x%x: error for address 0x%x",
482 sprintf(string, "address 0x%x, size 0x%x",
487 /**********************************************************************
491 * Description: Test the Simultaneous Switching Output.
492 * Verifies succes sive reads and writes to the same memory word,
493 * holding one bit constant while toggling all other data bits
495 * => stress the data bus over an address range
497 * The CPU writes to each address in the given range.
498 * For each bit, first the CPU holds the bit at 1 while
499 * toggling the other bits, and then the CPU holds the bit at 0
500 * while toggling the other bits.
501 * After each write, the CPU reads the address that was written
502 * to verify that it contains the correct data
504 **********************************************************************/
505 static enum test_result test_sso(struct stm32mp1_ddrctl *ctl,
506 struct stm32mp1_ddrphy *phy,
507 char *string, int argc, char *argv[])
510 u32 addr, bufsize, remaining, offset;
514 if (get_bufsize(string, argc, argv, 0, &bufsize, 4))
516 if (get_addr(string, argc, argv, 1, &addr))
519 printf("running sso at 0x%x length 0x%x", addr, bufsize);
523 for (i = 0; i < 32; i++) {
525 for (j = 0; j < 6; j++) {
543 writel(data, offset);
544 error = check_addr(offset, data);
551 if (progress(offset << 7))
558 sprintf(string, "error for pattern 0x%x @0x%x",
562 sprintf(string, "no error for sso at 0x%x length 0x%x", addr, bufsize);
566 /**********************************************************************
570 * Description: Verifies r/w with pseudo-ramdom value on one region
571 * + write the region (individual access)
572 * + memcopy to the 2nd region (try to use burst)
573 * + verify the 2 regions
575 **********************************************************************/
576 static enum test_result test_random(struct stm32mp1_ddrctl *ctl,
577 struct stm32mp1_ddrphy *phy,
578 char *string, int argc, char *argv[])
580 u32 addr, offset, value = 0;
582 u32 loop = 0, nb_loop;
586 if (get_bufsize(string, argc, argv, 0, &bufsize, 8 * 1024))
588 if (get_nb_loop(string, argc, argv, 1, &nb_loop, 1))
590 if (get_addr(string, argc, argv, 2, &addr))
594 printf("running %d loops copy from 0x%x to 0x%x (buffer size=0x%x)\n",
595 nb_loop, addr, addr + bufsize, bufsize);
598 for (offset = 0; offset < bufsize; offset += 4)
599 writel(rand(), addr + offset);
601 memcpy((void *)addr + bufsize, (void *)addr, bufsize);
604 for (offset = 0; offset < 2 * bufsize; offset += 4) {
605 if (offset == bufsize)
608 error = check_addr(addr + offset, value);
611 if (progress(offset))
614 if (test_loop_end(&loop, nb_loop, 100))
621 "loop %d: error for address 0x%x: 0x%x expected 0x%x",
622 loop, offset, readl(offset), value);
625 sprintf(string, "no error for %d loops, size 0x%x",
630 /**********************************************************************
634 * Description: Verifies r/w while forcing switching of all data bus lines.
635 * optimised 4 iteration write/read/write/read cycles...
636 * for pattern and inversed pattern
638 **********************************************************************/
639 void do_noise(u32 addr, u32 pattern, u32 *result)
641 __asm__("push {R0-R11}");
642 __asm__("mov r0, %0" : : "r" (addr));
643 __asm__("mov r1, %0" : : "r" (pattern));
644 __asm__("mov r11, %0" : : "r" (result));
646 __asm__("mvn r2, r1");
648 __asm__("str r1, [r0]");
649 __asm__("ldr r3, [r0]");
650 __asm__("str r2, [r0]");
651 __asm__("ldr r4, [r0]");
653 __asm__("str r1, [r0]");
654 __asm__("ldr r5, [r0]");
655 __asm__("str r2, [r0]");
656 __asm__("ldr r6, [r0]");
658 __asm__("str r1, [r0]");
659 __asm__("ldr r7, [r0]");
660 __asm__("str r2, [r0]");
661 __asm__("ldr r8, [r0]");
663 __asm__("str r1, [r0]");
664 __asm__("ldr r9, [r0]");
665 __asm__("str r2, [r0]");
666 __asm__("ldr r10, [r0]");
668 __asm__("stmia R11!, {R3-R10}");
670 __asm__("pop {R0-R11}");
673 static enum test_result test_noise(struct stm32mp1_ddrctl *ctl,
674 struct stm32mp1_ddrphy *phy,
675 char *string, int argc, char *argv[])
680 enum test_result res = TEST_PASSED;
682 if (get_pattern(string, argc, argv, 0, &pattern, 0xFFFFFFFF))
684 if (get_addr(string, argc, argv, 1, &addr))
687 printf("running noise for 0x%x at 0x%x\n", pattern, addr);
689 do_noise(addr, pattern, result);
691 for (i = 0; i < 0x8;) {
692 if (check_addr((u32)&result[i++], pattern))
694 if (check_addr((u32)&result[i++], ~pattern))
701 /**********************************************************************
703 * Function: noise_burst
705 * Description: Verifies r/w while forcing switching of all data bus lines.
706 * optimised write loop witrh store multiple to use burst
707 * for pattern and inversed pattern
709 **********************************************************************/
710 void do_noise_burst(u32 addr, u32 pattern, size_t bufsize)
712 __asm__("push {R0-R9}");
713 __asm__("mov r0, %0" : : "r" (addr));
714 __asm__("mov r1, %0" : : "r" (pattern));
715 __asm__("mov r9, %0" : : "r" (bufsize));
717 __asm__("mvn r2, r1");
718 __asm__("mov r3, r1");
719 __asm__("mov r4, r2");
720 __asm__("mov r5, r1");
721 __asm__("mov r6, r2");
722 __asm__("mov r7, r1");
723 __asm__("mov r8, r2");
726 __asm__("stmia R0!, {R1-R8}");
727 __asm__("stmia R0!, {R1-R8}");
728 __asm__("stmia R0!, {R1-R8}");
729 __asm__("stmia R0!, {R1-R8}");
730 __asm__("subs r9, r9, #128");
731 __asm__("bge loop1");
732 __asm__("pop {R0-R9}");
735 /* chunk size enough to allow interruption with Ctrl-C*/
736 #define CHUNK_SIZE 0x8000000
737 static enum test_result test_noise_burst(struct stm32mp1_ddrctl *ctl,
738 struct stm32mp1_ddrphy *phy,
739 char *string, int argc, char *argv[])
741 u32 addr, offset, pattern;
742 size_t bufsize, remaining, size;
744 enum test_result res = TEST_PASSED;
746 if (get_bufsize(string, argc, argv, 0, &bufsize, 4 * 1024))
748 if (get_pattern(string, argc, argv, 1, &pattern, 0xFFFFFFFF))
750 if (get_addr(string, argc, argv, 2, &addr))
753 printf("running noise burst for 0x%x at 0x%x + 0x%x",
754 pattern, addr, bufsize);
760 if (remaining < size)
762 do_noise_burst(offset, pattern, size);
765 if (progress(offset)) {
770 puts("\ncheck buffer");
771 for (i = 0; i < bufsize;) {
772 if (check_addr(addr + i, pattern))
775 if (check_addr(addr + i, ~pattern))
788 /**********************************************************************
790 * Function: pattern test
792 * Description: optimized loop for read/write pattern (array of 8 u32)
794 **********************************************************************/
795 #define PATTERN_SIZE 8
796 static enum test_result test_loop(const u32 *pattern, u32 *address,
801 enum test_result res = TEST_PASSED;
802 u32 offset, testsize, remaining;
804 offset = (u32)address;
807 testsize = bufsize > 0x1000000 ? 0x1000000 : bufsize;
809 __asm__("push {R0-R10}");
810 __asm__("mov r0, %0" : : "r" (pattern));
811 __asm__("mov r1, %0" : : "r" (offset));
812 __asm__("mov r2, %0" : : "r" (testsize));
813 __asm__("ldmia r0!, {R3-R10}");
816 __asm__("stmia r1!, {R3-R10}");
817 __asm__("stmia r1!, {R3-R10}");
818 __asm__("stmia r1!, {R3-R10}");
819 __asm__("stmia r1!, {R3-R10}");
820 __asm__("subs r2, r2, #128");
821 __asm__("bge loop2");
822 __asm__("pop {R0-R10}");
825 remaining -= testsize;
826 if (progress((u32)offset)) {
832 puts("\ncheck buffer");
833 for (i = 0; i < bufsize; i += PATTERN_SIZE * 4) {
834 for (j = 0; j < PATTERN_SIZE; j++, address++)
835 if (check_addr((u32)address, pattern[j])) {
850 const u32 pattern_div1_x16[PATTERN_SIZE] = {
851 0x0000FFFF, 0x0000FFFF, 0x0000FFFF, 0x0000FFFF,
852 0x0000FFFF, 0x0000FFFF, 0x0000FFFF, 0x0000FFFF
855 const u32 pattern_div2_x16[PATTERN_SIZE] = {
856 0xFFFFFFFF, 0x00000000, 0xFFFFFFFF, 0x00000000,
857 0xFFFFFFFF, 0x00000000, 0xFFFFFFFF, 0x00000000
860 const u32 pattern_div4_x16[PATTERN_SIZE] = {
861 0xFFFFFFFF, 0xFFFFFFFF, 0x00000000, 0x00000000,
862 0xFFFFFFFF, 0xFFFFFFFF, 0x00000000, 0x00000000
865 const u32 pattern_div4_x32[PATTERN_SIZE] = {
866 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
867 0x00000000, 0x00000000, 0x00000000, 0x00000000
870 const u32 pattern_mostly_zero_x16[PATTERN_SIZE] = {
871 0x00000000, 0x00000000, 0x00000000, 0x0000FFFF,
872 0x00000000, 0x00000000, 0x00000000, 0x00000000
875 const u32 pattern_mostly_zero_x32[PATTERN_SIZE] = {
876 0x00000000, 0x00000000, 0x00000000, 0xFFFFFFFF,
877 0x00000000, 0x00000000, 0x00000000, 0x00000000
880 const u32 pattern_mostly_one_x16[PATTERN_SIZE] = {
881 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0000FFFF,
882 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF
885 const u32 pattern_mostly_one_x32[PATTERN_SIZE] = {
886 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x00000000,
887 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF
891 static enum test_result test_freq_pattern(struct stm32mp1_ddrctl *ctl,
892 struct stm32mp1_ddrphy *phy,
893 char *string, int argc, char *argv[])
895 const u32 * const patterns_x16[NB_PATTERN] = {
899 pattern_mostly_zero_x16,
900 pattern_mostly_one_x16,
902 const u32 * const patterns_x32[NB_PATTERN] = {
906 pattern_mostly_zero_x32,
907 pattern_mostly_one_x32
909 const char *patterns_comments[NB_PATTERN] = {
910 "switching at frequency F/1",
911 "switching at frequency F/2",
912 "switching at frequency F/4",
917 enum test_result res = TEST_PASSED, pattern_res;
919 const u32 **patterns;
922 if (get_bufsize(string, argc, argv, 0, &bufsize, 4 * 1024))
925 switch (readl(&ctl->mstr) & DDRCTRL_MSTR_DATA_BUS_WIDTH_MASK) {
926 case DDRCTRL_MSTR_DATA_BUS_WIDTH_HALF:
927 case DDRCTRL_MSTR_DATA_BUS_WIDTH_QUARTER:
935 printf("running test pattern at 0x%08x length 0x%x width = %d\n",
936 STM32_DDR_BASE, bufsize, bus_width);
939 (const u32 **)(bus_width == 16 ? patterns_x16 : patterns_x32);
941 for (i = 0; i < NB_PATTERN; i++) {
942 printf("test data pattern %s:", patterns_comments[i]);
943 pattern_res = test_loop(patterns[i], (u32 *)STM32_DDR_BASE,
945 if (pattern_res != TEST_PASSED) {
955 /**********************************************************************
957 * Function: pattern test with size
959 * Description: loop for write pattern
961 **********************************************************************/
963 static enum test_result test_loop_size(const u32 *pattern, u32 size,
968 enum test_result res = TEST_PASSED;
971 for (i = 0; i < bufsize; i += size * 4) {
972 for (j = 0; j < size ; j++, p++)
980 puts("\ncheck buffer");
982 for (i = 0; i < bufsize; i += size * 4) {
983 for (j = 0; j < size; j++, p++)
984 if (check_addr((u32)p, pattern[j])) {
999 static enum test_result test_checkboard(struct stm32mp1_ddrctl *ctl,
1000 struct stm32mp1_ddrphy *phy,
1001 char *string, int argc, char *argv[])
1003 enum test_result res = TEST_PASSED;
1004 u32 bufsize, nb_loop, loop = 0, addr;
1007 u32 checkboard[2] = {0x55555555, 0xAAAAAAAA};
1009 if (get_bufsize(string, argc, argv, 0, &bufsize, 4 * 1024))
1011 if (get_nb_loop(string, argc, argv, 1, &nb_loop, 1))
1013 if (get_addr(string, argc, argv, 2, &addr))
1016 printf("running %d loops at 0x%08x length 0x%x\n",
1017 nb_loop, addr, bufsize);
1019 for (i = 0; i < 2; i++) {
1020 res = test_loop_size(checkboard, 2, (u32 *)addr,
1024 checkboard[0] = ~checkboard[0];
1025 checkboard[1] = ~checkboard[1];
1027 if (test_loop_end(&loop, nb_loop, 1))
1030 sprintf(string, "no error for %d loops at 0x%08x length 0x%x",
1031 loop, addr, bufsize);
1036 static enum test_result test_blockseq(struct stm32mp1_ddrctl *ctl,
1037 struct stm32mp1_ddrphy *phy,
1038 char *string, int argc, char *argv[])
1040 enum test_result res = TEST_PASSED;
1041 u32 bufsize, nb_loop, loop = 0, addr, value;
1044 if (get_bufsize(string, argc, argv, 0, &bufsize, 4 * 1024))
1046 if (get_nb_loop(string, argc, argv, 1, &nb_loop, 1))
1048 if (get_addr(string, argc, argv, 2, &addr))
1051 printf("running %d loops at 0x%08x length 0x%x\n",
1052 nb_loop, addr, bufsize);
1054 for (i = 0; i < 256; i++) {
1055 value = i | i << 8 | i << 16 | i << 24;
1056 printf("pattern = %08x", value);
1057 res = test_loop_size(&value, 1, (u32 *)addr, bufsize);
1058 if (res != TEST_PASSED)
1061 if (test_loop_end(&loop, nb_loop, 1))
1064 sprintf(string, "no error for %d loops at 0x%08x length 0x%x",
1065 loop, addr, bufsize);
1070 static enum test_result test_walkbit0(struct stm32mp1_ddrctl *ctl,
1071 struct stm32mp1_ddrphy *phy,
1072 char *string, int argc, char *argv[])
1074 enum test_result res = TEST_PASSED;
1075 u32 bufsize, nb_loop, loop = 0, addr, value;
1078 if (get_bufsize(string, argc, argv, 0, &bufsize, 4 * 1024))
1080 if (get_nb_loop(string, argc, argv, 1, &nb_loop, 1))
1082 if (get_addr(string, argc, argv, 2, &addr))
1085 printf("running %d loops at 0x%08x length 0x%x\n",
1086 nb_loop, addr, bufsize);
1088 for (i = 0; i < 64; i++) {
1092 value = 1 << (63 - i);
1094 printf("pattern = %08x", value);
1095 res = test_loop_size(&value, 1, (u32 *)addr, bufsize);
1096 if (res != TEST_PASSED)
1099 if (test_loop_end(&loop, nb_loop, 1))
1102 sprintf(string, "no error for %d loops at 0x%08x length 0x%x",
1103 loop, addr, bufsize);
1108 static enum test_result test_walkbit1(struct stm32mp1_ddrctl *ctl,
1109 struct stm32mp1_ddrphy *phy,
1110 char *string, int argc, char *argv[])
1112 enum test_result res = TEST_PASSED;
1113 u32 bufsize, nb_loop, loop = 0, addr, value;
1116 if (get_bufsize(string, argc, argv, 0, &bufsize, 4 * 1024))
1118 if (get_nb_loop(string, argc, argv, 1, &nb_loop, 1))
1120 if (get_addr(string, argc, argv, 2, &addr))
1123 printf("running %d loops at 0x%08x length 0x%x\n",
1124 nb_loop, addr, bufsize);
1126 for (i = 0; i < 64; i++) {
1130 value = ~(1 << (63 - i));
1132 printf("pattern = %08x", value);
1133 res = test_loop_size(&value, 1, (u32 *)addr, bufsize);
1134 if (res != TEST_PASSED)
1137 if (test_loop_end(&loop, nb_loop, 1))
1140 sprintf(string, "no error for %d loops at 0x%08x length 0x%x",
1141 loop, addr, bufsize);
1147 * try to catch bad bits which are dependent on the current values of
1148 * surrounding bits in either the same word32
1150 static enum test_result test_bitspread(struct stm32mp1_ddrctl *ctl,
1151 struct stm32mp1_ddrphy *phy,
1152 char *string, int argc, char *argv[])
1154 enum test_result res = TEST_PASSED;
1155 u32 bufsize, nb_loop, loop = 0, addr, bitspread[4];
1158 if (get_bufsize(string, argc, argv, 0, &bufsize, 4 * 1024))
1160 if (get_nb_loop(string, argc, argv, 1, &nb_loop, 1))
1162 if (get_addr(string, argc, argv, 2, &addr))
1165 printf("running %d loops at 0x%08x length 0x%x\n",
1166 nb_loop, addr, bufsize);
1168 for (i = 1; i < 32; i++) {
1169 for (j = 0; j < i; j++) {
1171 bitspread[0] = (1 << i) | (1 << j);
1173 bitspread[0] = (1 << (63 - i)) |
1175 bitspread[1] = bitspread[0];
1176 bitspread[2] = ~bitspread[0];
1177 bitspread[3] = ~bitspread[0];
1178 printf("pattern = %08x", bitspread[0]);
1180 res = test_loop_size(bitspread, 4, (u32 *)addr,
1182 if (res != TEST_PASSED)
1186 if (test_loop_end(&loop, nb_loop, 1))
1189 sprintf(string, "no error for %d loops at 0x%08x length 0x%x",
1190 loop, addr, bufsize);
1195 static enum test_result test_bitflip(struct stm32mp1_ddrctl *ctl,
1196 struct stm32mp1_ddrphy *phy,
1197 char *string, int argc, char *argv[])
1199 enum test_result res = TEST_PASSED;
1200 u32 bufsize, nb_loop, loop = 0, addr;
1205 if (get_bufsize(string, argc, argv, 0, &bufsize, 4 * 1024))
1207 if (get_nb_loop(string, argc, argv, 1, &nb_loop, 1))
1209 if (get_addr(string, argc, argv, 2, &addr))
1212 printf("running %d loops at 0x%08x length 0x%x\n",
1213 nb_loop, addr, bufsize);
1215 for (i = 0; i < 32; i++) {
1216 bitflip[0] = 1 << i;
1217 bitflip[1] = bitflip[0];
1218 bitflip[2] = ~bitflip[0];
1219 bitflip[3] = bitflip[2];
1220 printf("pattern = %08x", bitflip[0]);
1222 res = test_loop_size(bitflip, 4, (u32 *)addr, bufsize);
1223 if (res != TEST_PASSED)
1226 if (test_loop_end(&loop, nb_loop, 1))
1229 sprintf(string, "no error for %d loops at 0x%08x length 0x%x",
1230 loop, addr, bufsize);
1235 /**********************************************************************
1237 * Function: infinite read access to DDR
1239 * Description: continuous read the same pattern at the same address
1241 **********************************************************************/
1242 static enum test_result test_read(struct stm32mp1_ddrctl *ctl,
1243 struct stm32mp1_ddrphy *phy,
1244 char *string, int argc, char *argv[])
1249 int i, size = 1024 * 1024;
1250 bool random = false;
1252 if (get_addr(string, argc, argv, 0, (u32 *)&addr))
1255 if (get_pattern(string, argc, argv, 1, &data, 0xA5A5AA55))
1258 if ((u32)addr == ADDR_INVALID) {
1259 printf("running random\n");
1262 printf("running at 0x%08x with pattern=0x%08x\n",
1268 for (i = 0; i < size; i++) {
1270 addr = (u32 *)(STM32_DDR_BASE +
1271 (rand() & (STM32_DDR_SIZE - 1) & ~0x3));
1274 if (test_loop_end(&loop, 0, 1))
1278 sprintf(string, "%d loops random", loop);
1280 sprintf(string, "%d loops at 0x%x: %x", loop, (u32)addr, data);
1285 /**********************************************************************
1287 * Function: infinite write access to DDR
1289 * Description: continuous write the same pattern at the same address
1291 **********************************************************************/
1292 static enum test_result test_write(struct stm32mp1_ddrctl *ctl,
1293 struct stm32mp1_ddrphy *phy,
1294 char *string, int argc, char *argv[])
1299 int i, size = 1024 * 1024;
1300 bool random = false;
1302 if (get_addr(string, argc, argv, 0, (u32 *)&addr))
1305 if (get_pattern(string, argc, argv, 1, &data, 0xA5A5AA55))
1308 if ((u32)addr == ADDR_INVALID) {
1309 printf("running random\n");
1312 printf("running at 0x%08x with pattern 0x%08x\n",
1317 for (i = 0; i < size; i++) {
1319 addr = (u32 *)(STM32_DDR_BASE +
1320 (rand() & (STM32_DDR_SIZE - 1) & ~0x3));
1325 if (test_loop_end(&loop, 0, 1))
1329 sprintf(string, "%d loops random", loop);
1331 sprintf(string, "%d loops at 0x%x: %x", loop, (u32)addr, data);
1336 #define NB_TEST_INFINITE 2
1337 static enum test_result test_all(struct stm32mp1_ddrctl *ctl,
1338 struct stm32mp1_ddrphy *phy,
1339 char *string, int argc, char *argv[])
1341 enum test_result res = TEST_PASSED, result;
1342 int i, nb_error = 0;
1343 u32 loop = 0, nb_loop;
1345 if (get_nb_loop(string, argc, argv, 0, &nb_loop, 1))
1349 /* execute all the test except the lasts which are infinite */
1350 for (i = 1; i < test_nb - NB_TEST_INFINITE; i++) {
1351 printf("execute %d:%s\n", (int)i, test[i].name);
1352 result = test[i].fct(ctl, phy, string, 0, NULL);
1353 printf("result %d:%s = ", (int)i, test[i].name);
1354 if (result != TEST_PASSED) {
1363 printf("loop %d: %d/%d test failed\n\n\n",
1364 loop + 1, nb_error, test_nb - NB_TEST_INFINITE);
1365 if (test_loop_end(&loop, nb_loop, 1))
1368 if (res != TEST_PASSED) {
1369 sprintf(string, "loop %d: %d/%d test failed", loop, nb_error,
1370 test_nb - NB_TEST_INFINITE);
1372 sprintf(string, "loop %d: %d tests passed", loop,
1373 test_nb - NB_TEST_INFINITE);
1378 /****************************************************************
1380 ****************************************************************/
1382 const struct test_desc test[] = {
1383 {test_all, "All", "[loop]", "Execute all tests", 1 },
1384 {test_databus, "Simple DataBus", "[addr]",
1385 "Verifies each data line by walking 1 on fixed address",
1388 {databuswalk0, "DataBusWalking0", "[loop] [addr]",
1389 "Verifies each data bus signal can be driven low (32 word burst)",
1392 {databuswalk1, "DataBusWalking1", "[loop] [addr]",
1393 "Verifies each data bus signal can be driven high (32 word burst)",
1396 {test_addressbus, "AddressBus", "[size] [addr]",
1397 "Verifies each relevant bits of the address and checking for aliasing",
1400 {test_memdevice, "MemDevice", "[size] [addr]",
1401 "Test the integrity of a physical memory (test every storage bit in the region)",
1404 {test_sso, "SimultaneousSwitchingOutput", "[size] [addr] ",
1405 "Stress the data bus over an address range",
1408 {test_noise, "Noise", "[pattern] [addr]",
1409 "Verifies r/w while forcing switching of all data bus lines.",
1412 {test_noise_burst, "NoiseBurst", "[size] [pattern] [addr]",
1413 "burst transfers while forcing switching of the data bus lines",
1416 {test_random, "Random", "[size] [loop] [addr]",
1417 "Verifies r/w and memcopy(burst for pseudo random value.",
1420 {test_freq_pattern, "FrequencySelectivePattern", "[size]",
1421 "write & test patterns: Mostly Zero, Mostly One and F/n",
1424 {test_blockseq, "BlockSequential", "[size] [loop] [addr]",
1425 "test incremental pattern",
1428 {test_checkboard, "Checkerboard", "[size] [loop] [addr]",
1429 "test checker pattern",
1432 {test_bitspread, "BitSpread", "[size] [loop] [addr]",
1433 "test Bit Spread pattern",
1436 {test_bitflip, "BitFlip", "[size] [loop] [addr]",
1437 "test Bit Flip pattern",
1440 {test_walkbit0, "WalkingOnes", "[size] [loop] [addr]",
1441 "test Walking Ones pattern",
1444 {test_walkbit1, "WalkingZeroes", "[size] [loop] [addr]",
1445 "test Walking Zeroes pattern",
1448 /* need to the the 2 last one (infinite) : skipped for test all */
1449 {test_read, "infinite read", "[addr] [pattern]",
1450 "basic test : infinite read access (random: addr=0xFFFFFFFF)", 2},
1451 {test_write, "infinite write", "[addr] [pattern]",
1452 "basic test : infinite write access (random: addr=0xFFFFFFFF)", 2},
1455 const int test_nb = ARRAY_SIZE(test);