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)
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 == 0) {
31 sprintf(string, "invalid size %s", argv[arg_nb]);
35 sprintf(string, "unaligned size %s",
41 if (default_size != STM32_DDR_SIZE)
42 *bufsize = default_size;
44 *bufsize = get_ram_size((long *)STM32_DDR_BASE,
50 static int get_nb_loop(char *string, int argc, char *argv[], int arg_nb,
51 u32 *nb_loop, u32 default_nb_loop)
56 if (strict_strtoul(argv[arg_nb], 0, &value) < 0) {
57 sprintf(string, "invalid %d parameter %s",
58 arg_nb, argv[arg_nb]);
62 printf("WARNING: infinite loop requested\n");
65 *nb_loop = default_nb_loop;
71 static int get_addr(char *string, int argc, char *argv[], int 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]);
82 if (value < STM32_DDR_BASE) {
83 sprintf(string, "too low address %s", argv[arg_nb]);
86 if (value & 0x3 && value != ADDR_INVALID) {
87 sprintf(string, "unaligned address %s",
93 *addr = STM32_DDR_BASE;
99 static int get_pattern(char *string, int argc, char *argv[], int arg_nb,
100 u32 *pattern, u32 default_pattern)
105 if (strict_strtoul(argv[arg_nb], 16, &value) < 0) {
106 sprintf(string, "invalid %d parameter %s",
107 arg_nb, argv[arg_nb]);
112 *pattern = default_pattern;
118 static u32 check_addr(u32 addr, u32 value)
120 u32 data = readl(addr);
123 printf("0x%08x: 0x%08x <=> 0x%08x", addr, data, value);
125 printf("(2nd read: 0x%08x)", data);
127 printf("- read error");
129 printf("- write error");
136 static int progress(u32 offset)
138 if (!(offset & 0xFFFFFF)) {
141 printf("\ntest interrupted!\n");
148 static int test_loop_end(u32 *loop, u32 nb_loop, u32 progress)
151 if (nb_loop && *loop >= nb_loop)
153 if ((*loop) % progress)
155 /* allow to interrupt the test only for progress step */
157 printf("test interrupted!\n");
160 printf("loop #%d\n", *loop);
166 /**********************************************************************
168 * Function: memTestDataBus()
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
177 * Returns: 0 if the test succeeds.
178 * A non-zero result is the first pattern that failed.
180 **********************************************************************/
181 static u32 databus(u32 *address)
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);
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);
196 if (read_value != pattern)
203 /**********************************************************************
205 * Function: memTestAddressBus()
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.
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
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.
227 **********************************************************************/
228 static u32 *addressbus(u32 *address, u32 nb_bytes)
230 u32 mask = (nb_bytes / sizeof(u32) - 1);
235 u32 pattern = 0xAAAAAAAA;
236 u32 antipattern = 0x55555555;
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]);
242 /* Check for address bits stuck high. */
244 writel(antipattern, &address[test_offset]);
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];
254 writel(pattern, &address[test_offset]);
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];
262 for (offset = 1; (offset & mask) != 0; offset <<= 1) {
263 if (readl(&address[offset]) != pattern &&
264 offset != test_offset)
265 return &address[test_offset];
267 writel(pattern, &address[test_offset]);
273 /**********************************************************************
275 * Function: memTestDevice()
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.
286 * Returns: NULL if the test succeeds.
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.
293 **********************************************************************/
294 static u32 *memdevice(u32 *address, u32 nb_bytes)
297 u32 nb_words = nb_bytes / sizeof(u32);
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))
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];
316 antipattern = ~pattern;
317 writel(antipattern, &address[offset]);
318 if (progress(offset))
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))
336 static enum test_result databuswalk0(struct stm32mp1_ddrctl *ctl,
337 struct stm32mp1_ddrphy *phy,
338 char *string, int argc, char *argv[])
341 u32 loop = 0, nb_loop;
346 if (get_nb_loop(string, argc, argv, 0, &nb_loop, 100))
348 if (get_addr(string, argc, argv, 1, &addr))
351 printf("running %d loops at 0x%x\n", nb_loop, addr);
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) {
359 debug("%x: error %x expected %x => error:%x\n",
360 addr + 4 * i, data, ~(1 << i), error);
363 if (test_loop_end(&loop, nb_loop, 1000))
365 for (i = 0; i < 32; i++)
366 writel(0, addr + 4 * i);
369 sprintf(string, "loop %d: error for bits 0x%x",
373 sprintf(string, "no error for %d loops", loop);
377 static enum test_result databuswalk1(struct stm32mp1_ddrctl *ctl,
378 struct stm32mp1_ddrphy *phy,
379 char *string, int argc, char *argv[])
382 u32 loop = 0, nb_loop;
387 if (get_nb_loop(string, argc, argv, 0, &nb_loop, 100))
389 if (get_addr(string, argc, argv, 1, &addr))
391 printf("running %d loops at 0x%x\n", nb_loop, addr);
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) {
399 debug("%x: error %x expected %x => error:%x\n",
400 addr + 4 * i, data, (1 << i), error);
403 if (test_loop_end(&loop, nb_loop, 1000))
405 for (i = 0; i < 32; i++)
406 writel(0, addr + 4 * i);
409 sprintf(string, "loop %d: error for bits 0x%x",
413 sprintf(string, "no error for %d loops", loop);
417 static enum test_result test_databus(struct stm32mp1_ddrctl *ctl,
418 struct stm32mp1_ddrphy *phy,
419 char *string, int argc, char *argv[])
424 if (get_addr(string, argc, argv, 0, &addr))
426 error = databus((u32 *)addr);
428 sprintf(string, "0x%x: error for bits 0x%x",
432 sprintf(string, "address 0x%x", addr);
436 static enum test_result test_addressbus(struct stm32mp1_ddrctl *ctl,
437 struct stm32mp1_ddrphy *phy,
438 char *string, int argc, char *argv[])
444 if (get_bufsize(string, argc, argv, 0, &bufsize, 4 * 1024))
446 if (!is_power_of_2(bufsize)) {
447 sprintf(string, "size 0x%x is not a power of 2",
451 if (get_addr(string, argc, argv, 1, &addr))
454 error = (u32)addressbus((u32 *)addr, bufsize);
456 sprintf(string, "0x%x: error for address 0x%x",
460 sprintf(string, "address 0x%x, size 0x%x",
465 static enum test_result test_memdevice(struct stm32mp1_ddrctl *ctl,
466 struct stm32mp1_ddrphy *phy,
467 char *string, int argc, char *argv[])
473 if (get_bufsize(string, argc, argv, 0, &bufsize, 4 * 1024))
475 if (get_addr(string, argc, argv, 1, &addr))
477 error = (u32)memdevice((u32 *)addr, (unsigned long)bufsize);
479 sprintf(string, "0x%x: error for address 0x%x",
483 sprintf(string, "address 0x%x, size 0x%x",
488 /**********************************************************************
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
496 * => stress the data bus over an address range
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
505 **********************************************************************/
506 static enum test_result test_sso(struct stm32mp1_ddrctl *ctl,
507 struct stm32mp1_ddrphy *phy,
508 char *string, int argc, char *argv[])
511 u32 addr, bufsize, remaining, offset;
515 if (get_bufsize(string, argc, argv, 0, &bufsize, 4))
517 if (get_addr(string, argc, argv, 1, &addr))
520 printf("running sso at 0x%x length 0x%x", addr, bufsize);
524 for (i = 0; i < 32; i++) {
526 for (j = 0; j < 6; j++) {
544 writel(data, offset);
545 error = check_addr(offset, data);
552 if (progress(offset << 7))
559 sprintf(string, "error for pattern 0x%x @0x%x",
563 sprintf(string, "no error for sso at 0x%x length 0x%x", addr, bufsize);
567 /**********************************************************************
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
576 **********************************************************************/
577 static enum test_result test_random(struct stm32mp1_ddrctl *ctl,
578 struct stm32mp1_ddrphy *phy,
579 char *string, int argc, char *argv[])
581 u32 addr, offset, value = 0;
583 u32 loop = 0, nb_loop;
587 if (get_bufsize(string, argc, argv, 0, &bufsize, 8 * 1024))
589 if (get_nb_loop(string, argc, argv, 1, &nb_loop, 1))
591 if (get_addr(string, argc, argv, 2, &addr))
595 printf("running %d loops copy from 0x%x to 0x%x (buffer size=0x%x)\n",
596 nb_loop, addr, addr + bufsize, bufsize);
599 for (offset = 0; offset < bufsize; offset += 4)
600 writel(rand(), addr + offset);
602 memcpy((void *)addr + bufsize, (void *)addr, bufsize);
605 for (offset = 0; offset < 2 * bufsize; offset += 4) {
606 if (offset == bufsize)
609 error = check_addr(addr + offset, value);
612 if (progress(offset))
615 if (test_loop_end(&loop, nb_loop, 100))
622 "loop %d: error for address 0x%x: 0x%x expected 0x%x",
623 loop, offset, readl(offset), value);
626 sprintf(string, "no error for %d loops, size 0x%x",
631 /**********************************************************************
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
639 **********************************************************************/
640 void do_noise(u32 addr, u32 pattern, u32 *result)
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));
647 __asm__("mvn r2, r1");
649 __asm__("str r1, [r0]");
650 __asm__("ldr r3, [r0]");
651 __asm__("str r2, [r0]");
652 __asm__("ldr r4, [r0]");
654 __asm__("str r1, [r0]");
655 __asm__("ldr r5, [r0]");
656 __asm__("str r2, [r0]");
657 __asm__("ldr r6, [r0]");
659 __asm__("str r1, [r0]");
660 __asm__("ldr r7, [r0]");
661 __asm__("str r2, [r0]");
662 __asm__("ldr r8, [r0]");
664 __asm__("str r1, [r0]");
665 __asm__("ldr r9, [r0]");
666 __asm__("str r2, [r0]");
667 __asm__("ldr r10, [r0]");
669 __asm__("stmia R11!, {R3-R10}");
671 __asm__("pop {R0-R11}");
674 static enum test_result test_noise(struct stm32mp1_ddrctl *ctl,
675 struct stm32mp1_ddrphy *phy,
676 char *string, int argc, char *argv[])
681 enum test_result res = TEST_PASSED;
683 if (get_pattern(string, argc, argv, 0, &pattern, 0xFFFFFFFF))
685 if (get_addr(string, argc, argv, 1, &addr))
688 printf("running noise for 0x%x at 0x%x\n", pattern, addr);
690 do_noise(addr, pattern, result);
692 for (i = 0; i < 0x8;) {
693 if (check_addr((u32)&result[i++], pattern))
695 if (check_addr((u32)&result[i++], ~pattern))
702 /**********************************************************************
704 * Function: noise_burst
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
710 **********************************************************************/
711 void do_noise_burst(u32 addr, u32 pattern, size_t bufsize)
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));
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");
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}");
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[])
742 u32 addr, offset, pattern;
743 size_t bufsize, remaining, size;
745 enum test_result res = TEST_PASSED;
747 if (get_bufsize(string, argc, argv, 0, &bufsize, 4 * 1024))
749 if (get_pattern(string, argc, argv, 1, &pattern, 0xFFFFFFFF))
751 if (get_addr(string, argc, argv, 2, &addr))
754 printf("running noise burst for 0x%x at 0x%x + 0x%x",
755 pattern, addr, bufsize);
761 if (remaining < size)
763 do_noise_burst(offset, pattern, size);
766 if (progress(offset)) {
771 puts("\ncheck buffer");
772 for (i = 0; i < bufsize;) {
773 if (check_addr(addr + i, pattern))
776 if (check_addr(addr + i, ~pattern))
789 /**********************************************************************
791 * Function: pattern test
793 * Description: optimized loop for read/write pattern (array of 8 u32)
795 **********************************************************************/
796 #define PATTERN_SIZE 8
797 static enum test_result test_loop(const u32 *pattern, u32 *address,
802 enum test_result res = TEST_PASSED;
803 u32 offset, testsize, remaining;
805 offset = (u32)address;
808 testsize = bufsize > 0x1000000 ? 0x1000000 : bufsize;
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}");
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}");
826 remaining -= testsize;
827 if (progress((u32)offset)) {
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])) {
851 const u32 pattern_div1_x16[PATTERN_SIZE] = {
852 0x0000FFFF, 0x0000FFFF, 0x0000FFFF, 0x0000FFFF,
853 0x0000FFFF, 0x0000FFFF, 0x0000FFFF, 0x0000FFFF
856 const u32 pattern_div2_x16[PATTERN_SIZE] = {
857 0xFFFFFFFF, 0x00000000, 0xFFFFFFFF, 0x00000000,
858 0xFFFFFFFF, 0x00000000, 0xFFFFFFFF, 0x00000000
861 const u32 pattern_div4_x16[PATTERN_SIZE] = {
862 0xFFFFFFFF, 0xFFFFFFFF, 0x00000000, 0x00000000,
863 0xFFFFFFFF, 0xFFFFFFFF, 0x00000000, 0x00000000
866 const u32 pattern_div4_x32[PATTERN_SIZE] = {
867 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
868 0x00000000, 0x00000000, 0x00000000, 0x00000000
871 const u32 pattern_mostly_zero_x16[PATTERN_SIZE] = {
872 0x00000000, 0x00000000, 0x00000000, 0x0000FFFF,
873 0x00000000, 0x00000000, 0x00000000, 0x00000000
876 const u32 pattern_mostly_zero_x32[PATTERN_SIZE] = {
877 0x00000000, 0x00000000, 0x00000000, 0xFFFFFFFF,
878 0x00000000, 0x00000000, 0x00000000, 0x00000000
881 const u32 pattern_mostly_one_x16[PATTERN_SIZE] = {
882 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0000FFFF,
883 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF
886 const u32 pattern_mostly_one_x32[PATTERN_SIZE] = {
887 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x00000000,
888 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF
892 static enum test_result test_freq_pattern(struct stm32mp1_ddrctl *ctl,
893 struct stm32mp1_ddrphy *phy,
894 char *string, int argc, char *argv[])
896 const u32 * const patterns_x16[NB_PATTERN] = {
900 pattern_mostly_zero_x16,
901 pattern_mostly_one_x16,
903 const u32 * const patterns_x32[NB_PATTERN] = {
907 pattern_mostly_zero_x32,
908 pattern_mostly_one_x32
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",
918 enum test_result res = TEST_PASSED, pattern_res;
920 const u32 **patterns;
923 if (get_bufsize(string, argc, argv, 0, &bufsize, 4 * 1024))
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:
936 printf("running test pattern at 0x%08x length 0x%x width = %d\n",
937 STM32_DDR_BASE, bufsize, bus_width);
940 (const u32 **)(bus_width == 16 ? patterns_x16 : patterns_x32);
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,
946 if (pattern_res != TEST_PASSED) {
956 /**********************************************************************
958 * Function: pattern test with size
960 * Description: loop for write pattern
962 **********************************************************************/
964 static enum test_result test_loop_size(const u32 *pattern, u32 size,
969 enum test_result res = TEST_PASSED;
972 for (i = 0; i < bufsize; i += size * 4) {
973 for (j = 0; j < size ; j++, p++)
981 puts("\ncheck buffer");
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])) {
1000 static enum test_result test_checkboard(struct stm32mp1_ddrctl *ctl,
1001 struct stm32mp1_ddrphy *phy,
1002 char *string, int argc, char *argv[])
1004 enum test_result res = TEST_PASSED;
1005 u32 bufsize, nb_loop, loop = 0, addr;
1008 u32 checkboard[2] = {0x55555555, 0xAAAAAAAA};
1010 if (get_bufsize(string, argc, argv, 0, &bufsize, 4 * 1024))
1012 if (get_nb_loop(string, argc, argv, 1, &nb_loop, 1))
1014 if (get_addr(string, argc, argv, 2, &addr))
1017 printf("running %d loops at 0x%08x length 0x%x\n",
1018 nb_loop, addr, bufsize);
1020 for (i = 0; i < 2; i++) {
1021 res = test_loop_size(checkboard, 2, (u32 *)addr,
1025 checkboard[0] = ~checkboard[0];
1026 checkboard[1] = ~checkboard[1];
1028 if (test_loop_end(&loop, nb_loop, 1))
1031 sprintf(string, "no error for %d loops at 0x%08x length 0x%x",
1032 loop, addr, bufsize);
1037 static enum test_result test_blockseq(struct stm32mp1_ddrctl *ctl,
1038 struct stm32mp1_ddrphy *phy,
1039 char *string, int argc, char *argv[])
1041 enum test_result res = TEST_PASSED;
1042 u32 bufsize, nb_loop, loop = 0, addr, value;
1045 if (get_bufsize(string, argc, argv, 0, &bufsize, 4 * 1024))
1047 if (get_nb_loop(string, argc, argv, 1, &nb_loop, 1))
1049 if (get_addr(string, argc, argv, 2, &addr))
1052 printf("running %d loops at 0x%08x length 0x%x\n",
1053 nb_loop, addr, bufsize);
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)
1062 if (test_loop_end(&loop, nb_loop, 1))
1065 sprintf(string, "no error for %d loops at 0x%08x length 0x%x",
1066 loop, addr, bufsize);
1071 static enum test_result test_walkbit0(struct stm32mp1_ddrctl *ctl,
1072 struct stm32mp1_ddrphy *phy,
1073 char *string, int argc, char *argv[])
1075 enum test_result res = TEST_PASSED;
1076 u32 bufsize, nb_loop, loop = 0, addr, value;
1079 if (get_bufsize(string, argc, argv, 0, &bufsize, 4 * 1024))
1081 if (get_nb_loop(string, argc, argv, 1, &nb_loop, 1))
1083 if (get_addr(string, argc, argv, 2, &addr))
1086 printf("running %d loops at 0x%08x length 0x%x\n",
1087 nb_loop, addr, bufsize);
1089 for (i = 0; i < 64; i++) {
1093 value = 1 << (63 - i);
1095 printf("pattern = %08x", value);
1096 res = test_loop_size(&value, 1, (u32 *)addr, bufsize);
1097 if (res != TEST_PASSED)
1100 if (test_loop_end(&loop, nb_loop, 1))
1103 sprintf(string, "no error for %d loops at 0x%08x length 0x%x",
1104 loop, addr, bufsize);
1109 static enum test_result test_walkbit1(struct stm32mp1_ddrctl *ctl,
1110 struct stm32mp1_ddrphy *phy,
1111 char *string, int argc, char *argv[])
1113 enum test_result res = TEST_PASSED;
1114 u32 bufsize, nb_loop, loop = 0, addr, value;
1117 if (get_bufsize(string, argc, argv, 0, &bufsize, 4 * 1024))
1119 if (get_nb_loop(string, argc, argv, 1, &nb_loop, 1))
1121 if (get_addr(string, argc, argv, 2, &addr))
1124 printf("running %d loops at 0x%08x length 0x%x\n",
1125 nb_loop, addr, bufsize);
1127 for (i = 0; i < 64; i++) {
1131 value = ~(1 << (63 - i));
1133 printf("pattern = %08x", value);
1134 res = test_loop_size(&value, 1, (u32 *)addr, bufsize);
1135 if (res != TEST_PASSED)
1138 if (test_loop_end(&loop, nb_loop, 1))
1141 sprintf(string, "no error for %d loops at 0x%08x length 0x%x",
1142 loop, addr, bufsize);
1148 * try to catch bad bits which are dependent on the current values of
1149 * surrounding bits in either the same word32
1151 static enum test_result test_bitspread(struct stm32mp1_ddrctl *ctl,
1152 struct stm32mp1_ddrphy *phy,
1153 char *string, int argc, char *argv[])
1155 enum test_result res = TEST_PASSED;
1156 u32 bufsize, nb_loop, loop = 0, addr, bitspread[4];
1159 if (get_bufsize(string, argc, argv, 0, &bufsize, 4 * 1024))
1161 if (get_nb_loop(string, argc, argv, 1, &nb_loop, 1))
1163 if (get_addr(string, argc, argv, 2, &addr))
1166 printf("running %d loops at 0x%08x length 0x%x\n",
1167 nb_loop, addr, bufsize);
1169 for (i = 1; i < 32; i++) {
1170 for (j = 0; j < i; j++) {
1172 bitspread[0] = (1 << i) | (1 << j);
1174 bitspread[0] = (1 << (63 - i)) |
1176 bitspread[1] = bitspread[0];
1177 bitspread[2] = ~bitspread[0];
1178 bitspread[3] = ~bitspread[0];
1179 printf("pattern = %08x", bitspread[0]);
1181 res = test_loop_size(bitspread, 4, (u32 *)addr,
1183 if (res != TEST_PASSED)
1187 if (test_loop_end(&loop, nb_loop, 1))
1190 sprintf(string, "no error for %d loops at 0x%08x length 0x%x",
1191 loop, addr, bufsize);
1196 static enum test_result test_bitflip(struct stm32mp1_ddrctl *ctl,
1197 struct stm32mp1_ddrphy *phy,
1198 char *string, int argc, char *argv[])
1200 enum test_result res = TEST_PASSED;
1201 u32 bufsize, nb_loop, loop = 0, addr;
1206 if (get_bufsize(string, argc, argv, 0, &bufsize, 4 * 1024))
1208 if (get_nb_loop(string, argc, argv, 1, &nb_loop, 1))
1210 if (get_addr(string, argc, argv, 2, &addr))
1213 printf("running %d loops at 0x%08x length 0x%x\n",
1214 nb_loop, addr, bufsize);
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]);
1223 res = test_loop_size(bitflip, 4, (u32 *)addr, bufsize);
1224 if (res != TEST_PASSED)
1227 if (test_loop_end(&loop, nb_loop, 1))
1230 sprintf(string, "no error for %d loops at 0x%08x length 0x%x",
1231 loop, addr, bufsize);
1236 /**********************************************************************
1238 * Function: infinite read access to DDR
1240 * Description: continuous read the same pattern at the same address
1242 **********************************************************************/
1243 static enum test_result test_read(struct stm32mp1_ddrctl *ctl,
1244 struct stm32mp1_ddrphy *phy,
1245 char *string, int argc, char *argv[])
1250 int i, size = 1024 * 1024;
1251 bool random = false;
1253 if (get_addr(string, argc, argv, 0, (u32 *)&addr))
1256 if (get_pattern(string, argc, argv, 1, &data, 0xA5A5AA55))
1259 if ((u32)addr == ADDR_INVALID) {
1260 printf("running random\n");
1263 printf("running at 0x%08x with pattern=0x%08x\n",
1269 for (i = 0; i < size; i++) {
1271 addr = (u32 *)(STM32_DDR_BASE +
1272 (rand() & (STM32_DDR_SIZE - 1) & ~0x3));
1275 if (test_loop_end(&loop, 0, 1))
1279 sprintf(string, "%d loops random", loop);
1281 sprintf(string, "%d loops at 0x%x: %x", loop, (u32)addr, data);
1286 /**********************************************************************
1288 * Function: infinite write access to DDR
1290 * Description: continuous write the same pattern at the same address
1292 **********************************************************************/
1293 static enum test_result test_write(struct stm32mp1_ddrctl *ctl,
1294 struct stm32mp1_ddrphy *phy,
1295 char *string, int argc, char *argv[])
1300 int i, size = 1024 * 1024;
1301 bool random = false;
1303 if (get_addr(string, argc, argv, 0, (u32 *)&addr))
1306 if (get_pattern(string, argc, argv, 1, &data, 0xA5A5AA55))
1309 if ((u32)addr == ADDR_INVALID) {
1310 printf("running random\n");
1313 printf("running at 0x%08x with pattern 0x%08x\n",
1318 for (i = 0; i < size; i++) {
1320 addr = (u32 *)(STM32_DDR_BASE +
1321 (rand() & (STM32_DDR_SIZE - 1) & ~0x3));
1326 if (test_loop_end(&loop, 0, 1))
1330 sprintf(string, "%d loops random", loop);
1332 sprintf(string, "%d loops at 0x%x: %x", loop, (u32)addr, data);
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[])
1342 enum test_result res = TEST_PASSED, result;
1343 int i, nb_error = 0;
1344 u32 loop = 0, nb_loop;
1346 if (get_nb_loop(string, argc, argv, 0, &nb_loop, 1))
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) {
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))
1369 if (res != TEST_PASSED) {
1370 sprintf(string, "loop %d: %d/%d test failed", loop, nb_error,
1371 test_nb - NB_TEST_INFINITE);
1373 sprintf(string, "loop %d: %d tests passed", loop,
1374 test_nb - NB_TEST_INFINITE);
1379 /****************************************************************
1381 ****************************************************************/
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",
1389 {databuswalk0, "DataBusWalking0", "[loop] [addr]",
1390 "Verifies each data bus signal can be driven low (32 word burst)",
1393 {databuswalk1, "DataBusWalking1", "[loop] [addr]",
1394 "Verifies each data bus signal can be driven high (32 word burst)",
1397 {test_addressbus, "AddressBus", "[size] [addr]",
1398 "Verifies each relevant bits of the address and checking for aliasing",
1401 {test_memdevice, "MemDevice", "[size] [addr]",
1402 "Test the integrity of a physical memory (test every storage bit in the region)",
1405 {test_sso, "SimultaneousSwitchingOutput", "[size] [addr] ",
1406 "Stress the data bus over an address range",
1409 {test_noise, "Noise", "[pattern] [addr]",
1410 "Verifies r/w while forcing switching of all data bus lines.",
1413 {test_noise_burst, "NoiseBurst", "[size] [pattern] [addr]",
1414 "burst transfers while forcing switching of the data bus lines",
1417 {test_random, "Random", "[size] [loop] [addr]",
1418 "Verifies r/w and memcopy(burst for pseudo random value.",
1421 {test_freq_pattern, "FrequencySelectivePattern", "[size]",
1422 "write & test patterns: Mostly Zero, Mostly One and F/n",
1425 {test_blockseq, "BlockSequential", "[size] [loop] [addr]",
1426 "test incremental pattern",
1429 {test_checkboard, "Checkerboard", "[size] [loop] [addr]",
1430 "test checker pattern",
1433 {test_bitspread, "BitSpread", "[size] [loop] [addr]",
1434 "test Bit Spread pattern",
1437 {test_bitflip, "BitFlip", "[size] [loop] [addr]",
1438 "test Bit Flip pattern",
1441 {test_walkbit0, "WalkingOnes", "[size] [loop] [addr]",
1442 "test Walking Ones pattern",
1445 {test_walkbit1, "WalkingZeroes", "[size] [loop] [addr]",
1446 "test Walking Zeroes pattern",
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},
1456 const int test_nb = ARRAY_SIZE(test);