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