1 // SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause
3 * Copyright (C) 2019, STMicroelectronics - All Rights Reserved
12 #include <linux/log2.h>
13 #include "stm32mp1_tests.h"
15 #define ADDR_INVALID 0xFFFFFFFF
17 DECLARE_GLOBAL_DATA_PTR;
19 static int get_bufsize(char *string, int argc, char *argv[], int arg_nb,
20 size_t *bufsize, size_t default_size, size_t min_size)
25 if (strict_strtoul(argv[arg_nb], 0, &value) < 0) {
26 sprintf(string, "invalid %d parameter %s",
27 arg_nb, argv[arg_nb]);
30 if (value > STM32_DDR_SIZE || value < min_size) {
31 sprintf(string, "invalid size %s (min=%d)",
32 argv[arg_nb], min_size);
35 if (value & (min_size - 1)) {
36 sprintf(string, "unaligned size %s (min=%d)",
37 argv[arg_nb], min_size);
42 if (default_size != STM32_DDR_SIZE)
43 *bufsize = default_size;
45 *bufsize = get_ram_size((long *)STM32_DDR_BASE,
51 static int get_nb_loop(char *string, int argc, char *argv[], int arg_nb,
52 u32 *nb_loop, u32 default_nb_loop)
57 if (strict_strtoul(argv[arg_nb], 0, &value) < 0) {
58 sprintf(string, "invalid %d parameter %s",
59 arg_nb, argv[arg_nb]);
63 printf("WARNING: infinite loop requested\n");
66 *nb_loop = default_nb_loop;
72 static int get_addr(char *string, int argc, char *argv[], int arg_nb,
78 if (strict_strtoul(argv[arg_nb], 16, &value) < 0) {
79 sprintf(string, "invalid %d parameter %s",
80 arg_nb, argv[arg_nb]);
83 if (value < STM32_DDR_BASE) {
84 sprintf(string, "too low address %s", argv[arg_nb]);
87 if (value & 0x3 && value != ADDR_INVALID) {
88 sprintf(string, "unaligned address %s",
94 *addr = STM32_DDR_BASE;
100 static int get_pattern(char *string, int argc, char *argv[], int arg_nb,
101 u32 *pattern, u32 default_pattern)
106 if (strict_strtoul(argv[arg_nb], 16, &value) < 0) {
107 sprintf(string, "invalid %d parameter %s",
108 arg_nb, argv[arg_nb]);
113 *pattern = default_pattern;
119 static u32 check_addr(u32 addr, u32 value)
121 u32 data = readl(addr);
124 printf("0x%08x: 0x%08x <=> 0x%08x", addr, data, value);
126 printf("(2nd read: 0x%08x)", data);
128 printf("- read error");
130 printf("- write error");
137 static int progress(u32 offset)
139 if (!(offset & 0xFFFFFF)) {
142 printf("\ntest interrupted!\n");
149 static int test_loop_end(u32 *loop, u32 nb_loop, u32 progress)
152 if (nb_loop && *loop >= nb_loop)
154 if ((*loop) % progress)
156 /* allow to interrupt the test only for progress step */
158 printf("test interrupted!\n");
161 printf("loop #%d\n", *loop);
167 /**********************************************************************
169 * Function: memTestDataBus()
171 * Description: Test the data bus wiring in a memory region by
172 * performing a walking 1's test at a fixed address
173 * within that region. The address is selected
178 * Returns: 0 if the test succeeds.
179 * A non-zero result is the first pattern that failed.
181 **********************************************************************/
182 static u32 databus(u32 *address)
187 /* Perform a walking 1's test at the given address. */
188 for (pattern = 1; pattern != 0; pattern <<= 1) {
189 /* Write the test pattern. */
190 writel(pattern, address);
192 /* Read it back (immediately is okay for this test). */
193 read_value = readl(address);
194 debug("%x: %x <=> %x\n",
195 (u32)address, read_value, pattern);
197 if (read_value != pattern)
204 /**********************************************************************
206 * Function: memTestAddressBus()
208 * Description: Test the address bus wiring in a memory region by
209 * performing a walking 1's test on the relevant bits
210 * of the address and checking for aliasing. This test
211 * will find single-bit address failures such as stuck
212 * -high, stuck-low, and shorted pins. The base address
213 * and size of the region are selected by the caller.
215 * Notes: For best results, the selected base address should
216 * have enough LSB 0's to guarantee single address bit
217 * changes. For example, to test a 64-Kbyte region,
218 * select a base address on a 64-Kbyte boundary. Also,
219 * select the region size as a power-of-two--if at all
222 * Returns: NULL if the test succeeds.
223 * A non-zero result is the first address at which an
224 * aliasing problem was uncovered. By examining the
225 * contents of memory, it may be possible to gather
226 * additional information about the problem.
228 **********************************************************************/
229 static u32 *addressbus(u32 *address, u32 nb_bytes)
231 u32 mask = (nb_bytes / sizeof(u32) - 1);
236 u32 pattern = 0xAAAAAAAA;
237 u32 antipattern = 0x55555555;
239 /* Write the default pattern at each of the power-of-two offsets. */
240 for (offset = 1; (offset & mask) != 0; offset <<= 1)
241 writel(pattern, &address[offset]);
243 /* Check for address bits stuck high. */
245 writel(antipattern, &address[test_offset]);
247 for (offset = 1; (offset & mask) != 0; offset <<= 1) {
248 read_value = readl(&address[offset]);
249 debug("%x: %x <=> %x\n",
250 (u32)&address[offset], read_value, pattern);
251 if (read_value != pattern)
252 return &address[offset];
255 writel(pattern, &address[test_offset]);
257 /* Check for address bits stuck low or shorted. */
258 for (test_offset = 1; (test_offset & mask) != 0; test_offset <<= 1) {
259 writel(antipattern, &address[test_offset]);
260 if (readl(&address[0]) != pattern)
261 return &address[test_offset];
263 for (offset = 1; (offset & mask) != 0; offset <<= 1) {
264 if (readl(&address[offset]) != pattern &&
265 offset != test_offset)
266 return &address[test_offset];
268 writel(pattern, &address[test_offset]);
274 /**********************************************************************
276 * Function: memTestDevice()
278 * Description: Test the integrity of a physical memory device by
279 * performing an increment/decrement test over the
280 * entire region. In the process every storage bit
281 * in the device is tested as a zero and a one. The
282 * base address and the size of the region are
283 * selected by the caller.
287 * Returns: NULL if the test succeeds.
289 * A non-zero result is the first address at which an
290 * incorrect value was read back. By examining the
291 * contents of memory, it may be possible to gather
292 * additional information about the problem.
294 **********************************************************************/
295 static u32 *memdevice(u32 *address, u32 nb_bytes)
298 u32 nb_words = nb_bytes / sizeof(u32);
303 puts("Fill with pattern");
304 /* Fill memory with a known pattern. */
305 for (pattern = 1, offset = 0; offset < nb_words; pattern++, offset++) {
306 writel(pattern, &address[offset]);
307 if (progress(offset))
311 puts("\nCheck and invert pattern");
312 /* Check each location and invert it for the second pass. */
313 for (pattern = 1, offset = 0; offset < nb_words; pattern++, offset++) {
314 if (readl(&address[offset]) != pattern)
315 return &address[offset];
317 antipattern = ~pattern;
318 writel(antipattern, &address[offset]);
319 if (progress(offset))
323 puts("\nCheck inverted pattern");
324 /* Check each location for the inverted pattern and zero it. */
325 for (pattern = 1, offset = 0; offset < nb_words; pattern++, offset++) {
326 antipattern = ~pattern;
327 if (readl(&address[offset]) != antipattern)
328 return &address[offset];
329 if (progress(offset))
337 static enum test_result databuswalk0(struct stm32mp1_ddrctl *ctl,
338 struct stm32mp1_ddrphy *phy,
339 char *string, int argc, char *argv[])
342 u32 loop = 0, nb_loop;
347 if (get_nb_loop(string, argc, argv, 0, &nb_loop, 100))
349 if (get_addr(string, argc, argv, 1, &addr))
352 printf("running %d loops at 0x%x\n", nb_loop, addr);
354 for (i = 0; i < 32; i++)
355 writel(~(1 << i), addr + 4 * i);
356 for (i = 0; i < 32; i++) {
357 data = readl(addr + 4 * i);
358 if (~(1 << i) != data) {
360 debug("%x: error %x expected %x => error:%x\n",
361 addr + 4 * i, data, ~(1 << i), error);
364 if (test_loop_end(&loop, nb_loop, 1000))
366 for (i = 0; i < 32; i++)
367 writel(0, addr + 4 * i);
370 sprintf(string, "loop %d: error for bits 0x%x",
374 sprintf(string, "no error for %d loops", loop);
378 static enum test_result databuswalk1(struct stm32mp1_ddrctl *ctl,
379 struct stm32mp1_ddrphy *phy,
380 char *string, int argc, char *argv[])
383 u32 loop = 0, nb_loop;
388 if (get_nb_loop(string, argc, argv, 0, &nb_loop, 100))
390 if (get_addr(string, argc, argv, 1, &addr))
392 printf("running %d loops at 0x%x\n", nb_loop, addr);
394 for (i = 0; i < 32; i++)
395 writel(1 << i, addr + 4 * i);
396 for (i = 0; i < 32; i++) {
397 data = readl(addr + 4 * i);
398 if ((1 << i) != data) {
400 debug("%x: error %x expected %x => error:%x\n",
401 addr + 4 * i, data, (1 << i), error);
404 if (test_loop_end(&loop, nb_loop, 1000))
406 for (i = 0; i < 32; i++)
407 writel(0, addr + 4 * i);
410 sprintf(string, "loop %d: error for bits 0x%x",
414 sprintf(string, "no error for %d loops", loop);
418 static enum test_result test_databus(struct stm32mp1_ddrctl *ctl,
419 struct stm32mp1_ddrphy *phy,
420 char *string, int argc, char *argv[])
425 if (get_addr(string, argc, argv, 0, &addr))
427 error = databus((u32 *)addr);
429 sprintf(string, "0x%x: error for bits 0x%x",
433 sprintf(string, "address 0x%x", addr);
437 static enum test_result test_addressbus(struct stm32mp1_ddrctl *ctl,
438 struct stm32mp1_ddrphy *phy,
439 char *string, int argc, char *argv[])
445 if (get_bufsize(string, argc, argv, 0, &bufsize, STM32_DDR_SIZE, 4))
447 if (!is_power_of_2(bufsize)) {
448 sprintf(string, "size 0x%x is not a power of 2",
452 if (get_addr(string, argc, argv, 1, &addr))
455 printf("running at 0x%08x length 0x%x\n", addr, bufsize);
456 error = (u32)addressbus((u32 *)addr, bufsize);
458 sprintf(string, "0x%x: error for address 0x%x",
462 sprintf(string, "address 0x%x, size 0x%x",
467 static enum test_result test_memdevice(struct stm32mp1_ddrctl *ctl,
468 struct stm32mp1_ddrphy *phy,
469 char *string, int argc, char *argv[])
475 if (get_bufsize(string, argc, argv, 0, &bufsize, 4 * 1024, 4))
477 if (get_addr(string, argc, argv, 1, &addr))
479 error = (u32)memdevice((u32 *)addr, (unsigned long)bufsize);
481 sprintf(string, "0x%x: error for address 0x%x",
485 sprintf(string, "address 0x%x, size 0x%x",
490 /**********************************************************************
494 * Description: Test the Simultaneous Switching Output.
495 * Verifies succes sive reads and writes to the same memory word,
496 * holding one bit constant while toggling all other data bits
498 * => stress the data bus over an address range
500 * The CPU writes to each address in the given range.
501 * For each bit, first the CPU holds the bit at 1 while
502 * toggling the other bits, and then the CPU holds the bit at 0
503 * while toggling the other bits.
504 * After each write, the CPU reads the address that was written
505 * to verify that it contains the correct data
507 **********************************************************************/
508 static enum test_result test_sso(struct stm32mp1_ddrctl *ctl,
509 struct stm32mp1_ddrphy *phy,
510 char *string, int argc, char *argv[])
513 u32 addr, bufsize, remaining, offset;
517 if (get_bufsize(string, argc, argv, 0, &bufsize, 4 * 1024, 4))
519 if (get_addr(string, argc, argv, 1, &addr))
522 printf("running sso at 0x%x length 0x%x", addr, bufsize);
526 for (i = 0; i < 32; i++) {
528 for (j = 0; j < 6; j++) {
546 writel(data, offset);
547 error = check_addr(offset, data);
554 if (progress(offset << 7))
561 sprintf(string, "error for pattern 0x%x @0x%x",
565 sprintf(string, "no error for sso at 0x%x length 0x%x", addr, bufsize);
569 /**********************************************************************
573 * Description: Verifies r/w with pseudo-ramdom value on one region
574 * + write the region (individual access)
575 * + memcopy to the 2nd region (try to use burst)
576 * + verify the 2 regions
578 **********************************************************************/
579 static enum test_result test_random(struct stm32mp1_ddrctl *ctl,
580 struct stm32mp1_ddrphy *phy,
581 char *string, int argc, char *argv[])
583 u32 addr, offset, value = 0;
585 u32 loop = 0, nb_loop;
589 if (get_bufsize(string, argc, argv, 0, &bufsize, 4 * 1024, 8))
591 if (get_nb_loop(string, argc, argv, 1, &nb_loop, 1))
593 if (get_addr(string, argc, argv, 2, &addr))
597 printf("running %d loops copy from 0x%x to 0x%x (buffer size=0x%x)\n",
598 nb_loop, addr, addr + bufsize, bufsize);
601 for (offset = 0; offset < bufsize; offset += 4)
602 writel(rand(), addr + offset);
604 memcpy((void *)addr + bufsize, (void *)addr, bufsize);
607 for (offset = 0; offset < 2 * bufsize; offset += 4) {
608 if (offset == bufsize)
611 error = check_addr(addr + offset, value);
614 if (progress(offset))
617 if (test_loop_end(&loop, nb_loop, 100))
624 "loop %d: error for address 0x%x: 0x%x expected 0x%x",
625 loop, offset, readl(offset), value);
628 sprintf(string, "no error for %d loops, size 0x%x",
633 /**********************************************************************
637 * Description: Verifies r/w while forcing switching of all data bus lines.
638 * optimised 4 iteration write/read/write/read cycles...
639 * for pattern and inversed pattern
641 **********************************************************************/
642 void do_noise(u32 addr, u32 pattern, u32 *result)
644 __asm__("push {R0-R11}");
645 __asm__("mov r0, %0" : : "r" (addr));
646 __asm__("mov r1, %0" : : "r" (pattern));
647 __asm__("mov r11, %0" : : "r" (result));
649 __asm__("mvn r2, r1");
651 __asm__("str r1, [r0]");
652 __asm__("ldr r3, [r0]");
653 __asm__("str r2, [r0]");
654 __asm__("ldr r4, [r0]");
656 __asm__("str r1, [r0]");
657 __asm__("ldr r5, [r0]");
658 __asm__("str r2, [r0]");
659 __asm__("ldr r6, [r0]");
661 __asm__("str r1, [r0]");
662 __asm__("ldr r7, [r0]");
663 __asm__("str r2, [r0]");
664 __asm__("ldr r8, [r0]");
666 __asm__("str r1, [r0]");
667 __asm__("ldr r9, [r0]");
668 __asm__("str r2, [r0]");
669 __asm__("ldr r10, [r0]");
671 __asm__("stmia R11!, {R3-R10}");
673 __asm__("pop {R0-R11}");
676 static enum test_result test_noise(struct stm32mp1_ddrctl *ctl,
677 struct stm32mp1_ddrphy *phy,
678 char *string, int argc, char *argv[])
683 enum test_result res = TEST_PASSED;
685 if (get_pattern(string, argc, argv, 0, &pattern, 0xFFFFFFFF))
687 if (get_addr(string, argc, argv, 1, &addr))
690 printf("running noise for 0x%x at 0x%x\n", pattern, addr);
692 do_noise(addr, pattern, result);
694 for (i = 0; i < 0x8;) {
695 if (check_addr((u32)&result[i++], pattern))
697 if (check_addr((u32)&result[i++], ~pattern))
704 /**********************************************************************
706 * Function: noise_burst
708 * Description: Verifies r/w while forcing switching of all data bus lines.
709 * optimised write loop witrh store multiple to use burst
710 * for pattern and inversed pattern
712 **********************************************************************/
713 void do_noise_burst(u32 addr, u32 pattern, size_t bufsize)
715 __asm__("push {R0-R9}");
716 __asm__("mov r0, %0" : : "r" (addr));
717 __asm__("mov r1, %0" : : "r" (pattern));
718 __asm__("mov r9, %0" : : "r" (bufsize));
720 __asm__("mvn r2, r1");
721 __asm__("mov r3, r1");
722 __asm__("mov r4, r2");
723 __asm__("mov r5, r1");
724 __asm__("mov r6, r2");
725 __asm__("mov r7, r1");
726 __asm__("mov r8, r2");
729 __asm__("stmia R0!, {R1-R8}");
730 __asm__("stmia R0!, {R1-R8}");
731 __asm__("stmia R0!, {R1-R8}");
732 __asm__("stmia R0!, {R1-R8}");
733 __asm__("subs r9, r9, #128");
734 __asm__("bge loop1");
735 __asm__("pop {R0-R9}");
738 /* chunk size enough to allow interruption with Ctrl-C*/
739 #define CHUNK_SIZE 0x8000000
740 static enum test_result test_noise_burst(struct stm32mp1_ddrctl *ctl,
741 struct stm32mp1_ddrphy *phy,
742 char *string, int argc, char *argv[])
744 u32 addr, offset, pattern;
745 size_t bufsize, remaining, size;
747 enum test_result res = TEST_PASSED;
749 if (get_bufsize(string, argc, argv, 0, &bufsize, 4 * 1024, 128))
751 if (get_pattern(string, argc, argv, 1, &pattern, 0xFFFFFFFF))
753 if (get_addr(string, argc, argv, 2, &addr))
756 printf("running noise burst for 0x%x at 0x%x + 0x%x",
757 pattern, addr, bufsize);
763 if (remaining < size)
765 do_noise_burst(offset, pattern, size);
768 if (progress(offset)) {
773 puts("\ncheck buffer");
774 for (i = 0; i < bufsize;) {
775 if (check_addr(addr + i, pattern))
778 if (check_addr(addr + i, ~pattern))
791 /**********************************************************************
793 * Function: pattern test
795 * Description: optimized loop for read/write pattern (array of 8 u32)
797 **********************************************************************/
798 #define PATTERN_SIZE 8
799 static enum test_result test_loop(const u32 *pattern, u32 *address,
804 enum test_result res = TEST_PASSED;
805 u32 offset, testsize, remaining;
807 offset = (u32)address;
810 testsize = bufsize > 0x1000000 ? 0x1000000 : bufsize;
812 __asm__("push {R0-R10}");
813 __asm__("mov r0, %0" : : "r" (pattern));
814 __asm__("mov r1, %0" : : "r" (offset));
815 __asm__("mov r2, %0" : : "r" (testsize));
816 __asm__("ldmia r0!, {R3-R10}");
819 __asm__("stmia r1!, {R3-R10}");
820 __asm__("stmia r1!, {R3-R10}");
821 __asm__("stmia r1!, {R3-R10}");
822 __asm__("stmia r1!, {R3-R10}");
823 __asm__("subs r2, r2, #128");
824 __asm__("bge loop2");
825 __asm__("pop {R0-R10}");
828 remaining -= testsize;
829 if (progress((u32)offset)) {
835 puts("\ncheck buffer");
836 for (i = 0; i < bufsize; i += PATTERN_SIZE * 4) {
837 for (j = 0; j < PATTERN_SIZE; j++, address++)
838 if (check_addr((u32)address, pattern[j])) {
853 const u32 pattern_div1_x16[PATTERN_SIZE] = {
854 0x0000FFFF, 0x0000FFFF, 0x0000FFFF, 0x0000FFFF,
855 0x0000FFFF, 0x0000FFFF, 0x0000FFFF, 0x0000FFFF
858 const u32 pattern_div2_x16[PATTERN_SIZE] = {
859 0xFFFFFFFF, 0x00000000, 0xFFFFFFFF, 0x00000000,
860 0xFFFFFFFF, 0x00000000, 0xFFFFFFFF, 0x00000000
863 const u32 pattern_div4_x16[PATTERN_SIZE] = {
864 0xFFFFFFFF, 0xFFFFFFFF, 0x00000000, 0x00000000,
865 0xFFFFFFFF, 0xFFFFFFFF, 0x00000000, 0x00000000
868 const u32 pattern_div4_x32[PATTERN_SIZE] = {
869 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
870 0x00000000, 0x00000000, 0x00000000, 0x00000000
873 const u32 pattern_mostly_zero_x16[PATTERN_SIZE] = {
874 0x00000000, 0x00000000, 0x00000000, 0x0000FFFF,
875 0x00000000, 0x00000000, 0x00000000, 0x00000000
878 const u32 pattern_mostly_zero_x32[PATTERN_SIZE] = {
879 0x00000000, 0x00000000, 0x00000000, 0xFFFFFFFF,
880 0x00000000, 0x00000000, 0x00000000, 0x00000000
883 const u32 pattern_mostly_one_x16[PATTERN_SIZE] = {
884 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0000FFFF,
885 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF
888 const u32 pattern_mostly_one_x32[PATTERN_SIZE] = {
889 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x00000000,
890 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF
894 static enum test_result test_freq_pattern(struct stm32mp1_ddrctl *ctl,
895 struct stm32mp1_ddrphy *phy,
896 char *string, int argc, char *argv[])
898 const u32 * const patterns_x16[NB_PATTERN] = {
902 pattern_mostly_zero_x16,
903 pattern_mostly_one_x16,
905 const u32 * const patterns_x32[NB_PATTERN] = {
909 pattern_mostly_zero_x32,
910 pattern_mostly_one_x32
912 const char *patterns_comments[NB_PATTERN] = {
913 "switching at frequency F/1",
914 "switching at frequency F/2",
915 "switching at frequency F/4",
920 enum test_result res = TEST_PASSED, pattern_res;
922 const u32 **patterns;
925 if (get_bufsize(string, argc, argv, 0, &bufsize, 4 * 1024, 128))
927 if (get_addr(string, argc, argv, 1, &addr))
930 switch (readl(&ctl->mstr) & DDRCTRL_MSTR_DATA_BUS_WIDTH_MASK) {
931 case DDRCTRL_MSTR_DATA_BUS_WIDTH_HALF:
932 case DDRCTRL_MSTR_DATA_BUS_WIDTH_QUARTER:
940 printf("running test pattern at 0x%08x length 0x%x width = %d\n",
941 addr, bufsize, bus_width);
944 (const u32 **)(bus_width == 16 ? patterns_x16 : patterns_x32);
946 for (i = 0; i < NB_PATTERN; i++) {
947 printf("test data pattern %s:", patterns_comments[i]);
948 pattern_res = test_loop(patterns[i], (u32 *)addr, bufsize);
949 if (pattern_res != TEST_PASSED) {
959 /**********************************************************************
961 * Function: pattern test with size
963 * Description: loop for write pattern
965 **********************************************************************/
967 static enum test_result test_loop_size(const u32 *pattern, u32 size,
972 enum test_result res = TEST_PASSED;
975 for (i = 0; i < bufsize; i += size * 4) {
976 for (j = 0; j < size ; j++, p++)
984 puts("\ncheck buffer");
986 for (i = 0; i < bufsize; i += size * 4) {
987 for (j = 0; j < size; j++, p++)
988 if (check_addr((u32)p, pattern[j])) {
1003 static enum test_result test_checkboard(struct stm32mp1_ddrctl *ctl,
1004 struct stm32mp1_ddrphy *phy,
1005 char *string, int argc, char *argv[])
1007 enum test_result res = TEST_PASSED;
1008 u32 bufsize, nb_loop, loop = 0, addr;
1011 u32 checkboard[2] = {0x55555555, 0xAAAAAAAA};
1013 if (get_bufsize(string, argc, argv, 0, &bufsize, 4 * 1024, 8))
1015 if (get_nb_loop(string, argc, argv, 1, &nb_loop, 1))
1017 if (get_addr(string, argc, argv, 2, &addr))
1020 printf("running %d loops at 0x%08x length 0x%x\n",
1021 nb_loop, addr, bufsize);
1023 for (i = 0; i < 2; i++) {
1024 res = test_loop_size(checkboard, 2, (u32 *)addr,
1028 checkboard[0] = ~checkboard[0];
1029 checkboard[1] = ~checkboard[1];
1031 if (test_loop_end(&loop, nb_loop, 1))
1034 sprintf(string, "no error for %d loops at 0x%08x length 0x%x",
1035 loop, addr, bufsize);
1040 static enum test_result test_blockseq(struct stm32mp1_ddrctl *ctl,
1041 struct stm32mp1_ddrphy *phy,
1042 char *string, int argc, char *argv[])
1044 enum test_result res = TEST_PASSED;
1045 u32 bufsize, nb_loop, loop = 0, addr, value;
1048 if (get_bufsize(string, argc, argv, 0, &bufsize, 4 * 1024, 4))
1050 if (get_nb_loop(string, argc, argv, 1, &nb_loop, 1))
1052 if (get_addr(string, argc, argv, 2, &addr))
1055 printf("running %d loops at 0x%08x length 0x%x\n",
1056 nb_loop, addr, bufsize);
1058 for (i = 0; i < 256; i++) {
1059 value = i | i << 8 | i << 16 | i << 24;
1060 printf("pattern = %08x", value);
1061 res = test_loop_size(&value, 1, (u32 *)addr, bufsize);
1062 if (res != TEST_PASSED)
1065 if (test_loop_end(&loop, nb_loop, 1))
1068 sprintf(string, "no error for %d loops at 0x%08x length 0x%x",
1069 loop, addr, bufsize);
1074 static enum test_result test_walkbit0(struct stm32mp1_ddrctl *ctl,
1075 struct stm32mp1_ddrphy *phy,
1076 char *string, int argc, char *argv[])
1078 enum test_result res = TEST_PASSED;
1079 u32 bufsize, nb_loop, loop = 0, addr, value;
1082 if (get_bufsize(string, argc, argv, 0, &bufsize, 4 * 1024, 4))
1084 if (get_nb_loop(string, argc, argv, 1, &nb_loop, 1))
1086 if (get_addr(string, argc, argv, 2, &addr))
1089 printf("running %d loops at 0x%08x length 0x%x\n",
1090 nb_loop, addr, bufsize);
1092 for (i = 0; i < 64; i++) {
1096 value = 1 << (63 - i);
1098 printf("pattern = %08x", value);
1099 res = test_loop_size(&value, 1, (u32 *)addr, bufsize);
1100 if (res != TEST_PASSED)
1103 if (test_loop_end(&loop, nb_loop, 1))
1106 sprintf(string, "no error for %d loops at 0x%08x length 0x%x",
1107 loop, addr, bufsize);
1112 static enum test_result test_walkbit1(struct stm32mp1_ddrctl *ctl,
1113 struct stm32mp1_ddrphy *phy,
1114 char *string, int argc, char *argv[])
1116 enum test_result res = TEST_PASSED;
1117 u32 bufsize, nb_loop, loop = 0, addr, value;
1120 if (get_bufsize(string, argc, argv, 0, &bufsize, 4 * 1024, 4))
1122 if (get_nb_loop(string, argc, argv, 1, &nb_loop, 1))
1124 if (get_addr(string, argc, argv, 2, &addr))
1127 printf("running %d loops at 0x%08x length 0x%x\n",
1128 nb_loop, addr, bufsize);
1130 for (i = 0; i < 64; i++) {
1134 value = ~(1 << (63 - i));
1136 printf("pattern = %08x", value);
1137 res = test_loop_size(&value, 1, (u32 *)addr, bufsize);
1138 if (res != TEST_PASSED)
1141 if (test_loop_end(&loop, nb_loop, 1))
1144 sprintf(string, "no error for %d loops at 0x%08x length 0x%x",
1145 loop, addr, bufsize);
1151 * try to catch bad bits which are dependent on the current values of
1152 * surrounding bits in either the same word32
1154 static enum test_result test_bitspread(struct stm32mp1_ddrctl *ctl,
1155 struct stm32mp1_ddrphy *phy,
1156 char *string, int argc, char *argv[])
1158 enum test_result res = TEST_PASSED;
1159 u32 bufsize, nb_loop, loop = 0, addr, bitspread[4];
1162 if (get_bufsize(string, argc, argv, 0, &bufsize, 4 * 1024, 32))
1164 if (get_nb_loop(string, argc, argv, 1, &nb_loop, 1))
1166 if (get_addr(string, argc, argv, 2, &addr))
1169 printf("running %d loops at 0x%08x length 0x%x\n",
1170 nb_loop, addr, bufsize);
1172 for (i = 1; i < 32; i++) {
1173 for (j = 0; j < i; j++) {
1175 bitspread[0] = (1 << i) | (1 << j);
1177 bitspread[0] = (1 << (63 - i)) |
1179 bitspread[1] = bitspread[0];
1180 bitspread[2] = ~bitspread[0];
1181 bitspread[3] = ~bitspread[0];
1182 printf("pattern = %08x", bitspread[0]);
1184 res = test_loop_size(bitspread, 4, (u32 *)addr,
1186 if (res != TEST_PASSED)
1190 if (test_loop_end(&loop, nb_loop, 1))
1193 sprintf(string, "no error for %d loops at 0x%08x length 0x%x",
1194 loop, addr, bufsize);
1199 static enum test_result test_bitflip(struct stm32mp1_ddrctl *ctl,
1200 struct stm32mp1_ddrphy *phy,
1201 char *string, int argc, char *argv[])
1203 enum test_result res = TEST_PASSED;
1204 u32 bufsize, nb_loop, loop = 0, addr;
1209 if (get_bufsize(string, argc, argv, 0, &bufsize, 4 * 1024, 32))
1211 if (get_nb_loop(string, argc, argv, 1, &nb_loop, 1))
1213 if (get_addr(string, argc, argv, 2, &addr))
1216 printf("running %d loops at 0x%08x length 0x%x\n",
1217 nb_loop, addr, bufsize);
1219 for (i = 0; i < 32; i++) {
1220 bitflip[0] = 1 << i;
1221 bitflip[1] = bitflip[0];
1222 bitflip[2] = ~bitflip[0];
1223 bitflip[3] = bitflip[2];
1224 printf("pattern = %08x", bitflip[0]);
1226 res = test_loop_size(bitflip, 4, (u32 *)addr, bufsize);
1227 if (res != TEST_PASSED)
1230 if (test_loop_end(&loop, nb_loop, 1))
1233 sprintf(string, "no error for %d loops at 0x%08x length 0x%x",
1234 loop, addr, bufsize);
1239 /**********************************************************************
1241 * Function: infinite read access to DDR
1243 * Description: continuous read the same pattern at the same address
1245 **********************************************************************/
1246 static enum test_result test_read(struct stm32mp1_ddrctl *ctl,
1247 struct stm32mp1_ddrphy *phy,
1248 char *string, int argc, char *argv[])
1253 int i, size = 1024 * 1024;
1254 bool random = false;
1256 if (get_addr(string, argc, argv, 0, (u32 *)&addr))
1259 if (get_pattern(string, argc, argv, 1, &data, 0xA5A5AA55))
1262 if ((u32)addr == ADDR_INVALID) {
1263 printf("running random\n");
1266 printf("running at 0x%08x with pattern=0x%08x\n",
1272 for (i = 0; i < size; i++) {
1274 addr = (u32 *)(STM32_DDR_BASE +
1275 (rand() & (STM32_DDR_SIZE - 1) & ~0x3));
1278 if (test_loop_end(&loop, 0, 1))
1282 sprintf(string, "%d loops random", loop);
1284 sprintf(string, "%d loops at 0x%x: %x", loop, (u32)addr, data);
1289 /**********************************************************************
1291 * Function: infinite write access to DDR
1293 * Description: continuous write the same pattern at the same address
1295 **********************************************************************/
1296 static enum test_result test_write(struct stm32mp1_ddrctl *ctl,
1297 struct stm32mp1_ddrphy *phy,
1298 char *string, int argc, char *argv[])
1303 int i, size = 1024 * 1024;
1304 bool random = false;
1306 if (get_addr(string, argc, argv, 0, (u32 *)&addr))
1309 if (get_pattern(string, argc, argv, 1, &data, 0xA5A5AA55))
1312 if ((u32)addr == ADDR_INVALID) {
1313 printf("running random\n");
1316 printf("running at 0x%08x with pattern 0x%08x\n",
1321 for (i = 0; i < size; i++) {
1323 addr = (u32 *)(STM32_DDR_BASE +
1324 (rand() & (STM32_DDR_SIZE - 1) & ~0x3));
1329 if (test_loop_end(&loop, 0, 1))
1333 sprintf(string, "%d loops random", loop);
1335 sprintf(string, "%d loops at 0x%x: %x", loop, (u32)addr, data);
1340 #define NB_TEST_INFINITE 2
1341 static enum test_result test_all(struct stm32mp1_ddrctl *ctl,
1342 struct stm32mp1_ddrphy *phy,
1343 char *string, int argc, char *argv[])
1345 enum test_result res = TEST_PASSED, result;
1346 int i, nb_error = 0;
1347 u32 loop = 0, nb_loop;
1349 if (get_nb_loop(string, argc, argv, 0, &nb_loop, 1))
1353 /* execute all the test except the lasts which are infinite */
1354 for (i = 1; i < test_nb - NB_TEST_INFINITE; i++) {
1355 printf("execute %d:%s\n", (int)i, test[i].name);
1356 result = test[i].fct(ctl, phy, string, 0, NULL);
1357 printf("result %d:%s = ", (int)i, test[i].name);
1358 if (result != TEST_PASSED) {
1367 printf("loop %d: %d/%d test failed\n\n\n",
1368 loop + 1, nb_error, test_nb - NB_TEST_INFINITE);
1369 if (test_loop_end(&loop, nb_loop, 1))
1372 if (res != TEST_PASSED) {
1373 sprintf(string, "loop %d: %d/%d test failed", loop, nb_error,
1374 test_nb - NB_TEST_INFINITE);
1376 sprintf(string, "loop %d: %d tests passed", loop,
1377 test_nb - NB_TEST_INFINITE);
1382 /****************************************************************
1384 ****************************************************************/
1386 const struct test_desc test[] = {
1387 {test_all, "All", "[loop]", "Execute all tests", 1 },
1388 {test_databus, "Simple DataBus", "[addr]",
1389 "Verifies each data line by walking 1 on fixed address",
1392 {databuswalk0, "DataBusWalking0", "[loop] [addr]",
1393 "Verifies each data bus signal can be driven low (32 word burst)",
1396 {databuswalk1, "DataBusWalking1", "[loop] [addr]",
1397 "Verifies each data bus signal can be driven high (32 word burst)",
1400 {test_addressbus, "AddressBus", "[size] [addr]",
1401 "Verifies each relevant bits of the address and checking for aliasing",
1404 {test_memdevice, "MemDevice", "[size] [addr]",
1405 "Test the integrity of a physical memory (test every storage bit in the region)",
1408 {test_sso, "SimultaneousSwitchingOutput", "[size] [addr] ",
1409 "Stress the data bus over an address range",
1412 {test_noise, "Noise", "[pattern] [addr]",
1413 "Verifies r/w while forcing switching of all data bus lines.",
1416 {test_noise_burst, "NoiseBurst", "[size] [pattern] [addr]",
1417 "burst transfers while forcing switching of the data bus lines",
1420 {test_random, "Random", "[size] [loop] [addr]",
1421 "Verifies r/w and memcopy(burst for pseudo random value.",
1424 {test_freq_pattern, "FrequencySelectivePattern", "[size] [addr]",
1425 "write & test patterns: Mostly Zero, Mostly One and F/n",
1428 {test_blockseq, "BlockSequential", "[size] [loop] [addr]",
1429 "test incremental pattern",
1432 {test_checkboard, "Checkerboard", "[size] [loop] [addr]",
1433 "test checker pattern",
1436 {test_bitspread, "BitSpread", "[size] [loop] [addr]",
1437 "test Bit Spread pattern",
1440 {test_bitflip, "BitFlip", "[size] [loop] [addr]",
1441 "test Bit Flip pattern",
1444 {test_walkbit0, "WalkingOnes", "[size] [loop] [addr]",
1445 "test Walking Ones pattern",
1448 {test_walkbit1, "WalkingZeroes", "[size] [loop] [addr]",
1449 "test Walking Zeroes pattern",
1452 /* need to the the 2 last one (infinite) : skipped for test all */
1453 {test_read, "infinite read", "[addr] [pattern]",
1454 "basic test : infinite read access (random: addr=0xFFFFFFFF)", 2},
1455 {test_write, "infinite write", "[addr] [pattern]",
1456 "basic test : infinite write access (random: addr=0xFFFFFFFF)", 2},
1459 const int test_nb = ARRAY_SIZE(test);