stm32mp1_tests.c 38 KB

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