stm32mp1_tests.c 38 KB

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