prbs.c 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642
  1. // SPDX-License-Identifier: GPL-2.0-only
  2. /*
  3. * Copyright(C) 2021 Alibaba Communications Inc.
  4. * Author: David Li <liyong.li@alibaba-inc.com>
  5. */
  6. /*
  7. * PRBS test pattern
  8. *
  9. */
  10. #include <common.h>
  11. #include <console.h>
  12. #include <bootretry.h>
  13. #include <cli.h>
  14. #include <command.h>
  15. #include <console.h>
  16. #include <hash.h>
  17. #include <mapmem.h>
  18. #include <watchdog.h>
  19. #include <asm/io.h>
  20. #include <linux/compiler.h>
  21. #include <asm/asm.h>
  22. #include <asm/csr.h>
  23. #include <stdio.h>
  24. #include <stdint.h>
  25. #include <stdlib.h>
  26. #include "queue.h"
  27. //#define DEBUG
  28. #ifdef DEBUG
  29. #define CHECK_RESULT
  30. #endif
  31. #ifdef CHECK_RESULT
  32. static bool checked = true;
  33. #else
  34. static bool checked = false;
  35. #endif
  36. #define FIXED_RANGE 0x100000 // write fixed range for prbs_31 only
  37. #define BYTE_PER_CACHELINE 64
  38. #define BIT_PER_BYTE 8
  39. #define TIMER_FREQ (3*1000*1000)
  40. #define TIMER_TICK_MS (TIMER_FREQ/1000)
  41. u64 t_begin;
  42. u64 t_end;
  43. extern void flush_dcache_range(unsigned long start, unsigned long end);
  44. extern void invalidate_dcache_range(unsigned long start, unsigned long end);
  45. extern void invalid_dcache_range(unsigned long start, unsigned long end);
  46. extern unsigned long get_ddr_density(void);
  47. extern int riscv_get_time(u64 *time);
  48. struct PRBS_ELE {
  49. char *name;
  50. char *init_value;
  51. unsigned int init_cnt;
  52. char *expression;
  53. unsigned int exp_cnt;
  54. };
  55. char prbs7_init_value[] = {1,1,1,1,1,0,1};
  56. char prbs7_exp[] = {7,3};
  57. struct PRBS_ELE prbs7 = {
  58. "prbs_7",
  59. prbs7_init_value,
  60. 7,
  61. prbs7_exp,
  62. 2
  63. };
  64. char prbs15_init_value[] = {1,1,1,1,1,0,1,0,1,1,0,1,1,1,0};
  65. char prbs15_exp[] = {15,1};
  66. struct PRBS_ELE prbs15 = {
  67. "prbs_15",
  68. prbs15_init_value,
  69. 15,
  70. prbs15_exp,
  71. 2
  72. };
  73. char prbs23_init_value[] = {1,1,1,1,1,0,1,0,1,1,0,1,1,1,0,0,1,0,1,1,1,0,1};
  74. char prbs23_exp[] = {23,5};
  75. struct PRBS_ELE prbs23 = {
  76. "prbs_23",
  77. prbs23_init_value,
  78. 23,
  79. prbs23_exp,
  80. 2
  81. };
  82. char prbs31_init_value[] = {1,1,1,1,1,0,1,0,1,1,0,1,1,1,0,0,1,0,1,1,1,0,1,0,0,0,1,0,0,1,1};
  83. char prbs31_exp[] = {31,3};
  84. struct PRBS_ELE prbs31 = {
  85. "prbs_31",
  86. prbs31_init_value,
  87. 31,
  88. prbs31_exp,
  89. 2
  90. };
  91. unsigned int _generate_prbs_pos(unsigned int pos, unsigned int bit_value) {
  92. unsigned int pat = 0;
  93. int i;
  94. for(i=0; i<sizeof(pat)*BIT_PER_BYTE; i++)
  95. {
  96. pat |= bit_value << i;
  97. }
  98. return pat;
  99. }
  100. unsigned int _generate_prbs_neg(unsigned int pos, unsigned int bit_value) {
  101. unsigned int pat = 0;
  102. pat = bit_value;
  103. // reverse bit
  104. if((bit_value & (1 << pos)) == 0) {
  105. pat |= (unsigned int)0x1 << pos;
  106. }
  107. else {
  108. pat &= ~(bit_value & (1 << pos));
  109. }
  110. return pat;
  111. }
  112. unsigned int _generate_prbs_neg_all(unsigned int pos, unsigned int bit_value) {
  113. unsigned int pat = 0;
  114. int i;
  115. for(i=0; i<sizeof(pat)*BIT_PER_BYTE; i++)
  116. {
  117. pat |= bit_value << i;
  118. }
  119. pat = ~pat;
  120. return pat;
  121. }
  122. #define BYTE_PER_INTERLEAVE 512
  123. #ifdef CONFIG_DDR_CHBIT_256B
  124. //#define DDR_PHY0_ONLY
  125. #define DDR_PHY1_ONLY
  126. #define MULTIPLY 2
  127. #else
  128. #define MULTIPLY 1
  129. #endif
  130. int prbs_test(struct PRBS_ELE *prbs, unsigned int *buf, int pos, bool random_dq, bool need_check) {
  131. unsigned int i,j,k;
  132. unsigned int pattern;
  133. unsigned int bit_value;
  134. char *init_value = prbs->init_value;
  135. char *exp = prbs->expression;
  136. unsigned int init_cnt = prbs->init_cnt;
  137. unsigned int bit_len = (1 << init_cnt) -1;
  138. unsigned int exp_cnt = prbs->exp_cnt;
  139. unsigned int *p1;
  140. unsigned int tmp;
  141. unsigned int dq_cnt = 32;
  142. bool fixed_range = false;
  143. ulong ddr_density = get_ddr_density();
  144. printf("prbs name: %s\n", prbs->name);
  145. printf("prbs bit_len: %d\n", bit_len);
  146. printf("prbs init_cnt: %d\n", init_cnt);
  147. printf("prbs exp_cnt: %d\n", exp_cnt);
  148. if (strcmp(prbs->name, "prbs_31") == 0)
  149. fixed_range = true; // not enough space for prbs_31 incr range mode
  150. //Queue* queue = NULL;
  151. Queue* (queue[dq_cnt]);
  152. for (i = 0; i < dq_cnt; i++) {
  153. queue[i] = Queue_Init(OnQueueIncreasedEvent);
  154. if (queue[i] == NULL) {
  155. printf("ERROR: fail to Queue_Init queue[%d]\n", i);
  156. return -1;
  157. }
  158. }
  159. // fill queue with init_value
  160. for (i = 0; i < init_cnt; i++) {
  161. printf("prbs init_value[%d]: %d\n", init_cnt-i-1, init_value[init_cnt-i-1]);
  162. for (j = 0; j < dq_cnt; j++) {
  163. if ((j == pos) || (!random_dq)) {
  164. if (Queue_AddToHead(queue[j], init_value[init_cnt-i-1]) == -1)
  165. printf("fail to Queue_AddToHead queue[%d], vect[%d]\n", j, i);
  166. }
  167. else {
  168. //ulong tmp = rand_ul() % 2;
  169. u64 tmp;
  170. riscv_get_time(&tmp);
  171. tmp = tmp % 2;
  172. if (Queue_AddToHead(queue[j], (tmp==0)?0:1) == -1)
  173. printf("fail to Queue_AddToHead queue[%d], vect[%d]\n", j, i);
  174. }
  175. }
  176. }
  177. for (i = 0; i < dq_cnt; i++) {
  178. printf("prbs queue_value[%d]: [", i);
  179. for (j = 0; j < init_cnt; j++) {
  180. char data = Queue_QueryAt(queue[i], j);
  181. printf(" %d,", data);
  182. }
  183. printf("]\n");
  184. }
  185. //prbs31 sequence write
  186. p1 = buf;
  187. u64 bit_cnt = 0;
  188. for (i = 0; i < bit_len; i++) {
  189. bit_cnt++;
  190. if (fixed_range && ((bit_cnt % FIXED_RANGE) == 0))
  191. p1 = buf; // reset ptr to beginning
  192. else if ((bit_cnt % (ddr_density/4/2)) == 0)
  193. p1 = buf; // reset ptr to beginning
  194. bit_value = 0;
  195. for (j = 0; j < dq_cnt; j++) {
  196. unsigned int sum = 0;
  197. for (k = 0; k < exp_cnt; k++) {
  198. char data = Queue_QueryAt(queue[j], exp[k]-1);
  199. sum += data;
  200. }
  201. sum = sum % 2;
  202. Queue_AddToHead(queue[j], sum);
  203. bit_value |= Queue_GetFromTail(queue[j]) << j;
  204. }
  205. pattern = bit_value;
  206. //pattern = _generate_prbs_pos(pos, bit_value);
  207. #ifdef DEBUG
  208. printf("bit[%d]: val<0x%x>, addr<0x%lx>, write pos pattern: 0x%x\n", bit_len-i-1, bit_value, (ulong)p1, pattern);
  209. #endif
  210. *p1++ = pattern;
  211. // flush cache after write
  212. if(((ulong)p1 - (ulong)buf) % BYTE_PER_CACHELINE == 0)
  213. {
  214. flush_dcache_range((ulong)p1-BYTE_PER_CACHELINE, (ulong)p1-1);
  215. #ifdef DEBUG
  216. printf("flush cache start<0x%lx>, end<0x%lx>\n", (ulong)p1-BYTE_PER_CACHELINE, (ulong)p1-1);
  217. #endif
  218. }
  219. #if defined(DDR_PHY0_ONLY) || defined(DDR_PHY1_ONLY)
  220. if(((ulong)p1 - (ulong)buf) % (BYTE_PER_INTERLEAVE/2) == 0)
  221. {
  222. // jump to next PHY1's interleave space
  223. p1+=BYTE_PER_INTERLEAVE/2/sizeof(pattern);
  224. }
  225. #endif
  226. }
  227. for (i = 0; i < bit_len; i++) {
  228. bit_cnt++;
  229. if (fixed_range && ((bit_cnt % FIXED_RANGE) == 0))
  230. p1 = buf; // reset ptr to beginning
  231. else if ((bit_cnt % (ddr_density/4/2)) == 0)
  232. p1 = buf; // reset ptr to beginning
  233. bit_value = 0;
  234. for (j = 0; j < dq_cnt; j++) {
  235. unsigned int sum = 0;
  236. for (k = 0; k < exp_cnt; k++) {
  237. char data = Queue_QueryAt(queue[j], exp[k]-1);
  238. sum += data;
  239. }
  240. sum = sum % 2;
  241. Queue_AddToHead(queue[j], sum);
  242. bit_value |= Queue_GetFromTail(queue[j]) << j;
  243. }
  244. pattern = _generate_prbs_neg(pos, bit_value);
  245. #ifdef DEBUG
  246. printf("bit[%d]: val<0x%x>, addr<0x%lx>, write neg pattern: 0x%x\n", bit_len-i-1, bit_value, (ulong)p1, pattern);
  247. #endif
  248. *p1++ = pattern;
  249. // flush cache after write
  250. if(((ulong)p1 - (ulong)buf) % BYTE_PER_CACHELINE == 0)
  251. {
  252. flush_dcache_range((ulong)p1-BYTE_PER_CACHELINE, (ulong)p1-1);
  253. #ifdef DEBUG
  254. printf("flush cache start<0x%lx>, end<0x%lx>\n", (ulong)p1-BYTE_PER_CACHELINE, (ulong)p1-1);
  255. #endif
  256. }
  257. #if defined(DDR_PHY0_ONLY) || defined(DDR_PHY1_ONLY)
  258. if(((ulong)p1 - (ulong)buf) % (BYTE_PER_INTERLEAVE/2) == 0)
  259. {
  260. // jump to next PHY1's interleave space
  261. p1+=BYTE_PER_INTERLEAVE/2/sizeof(pattern);
  262. }
  263. #endif
  264. }
  265. if((ulong)p1 % BYTE_PER_CACHELINE != 0)
  266. {
  267. flush_dcache_range((ulong)p1&(~(BYTE_PER_CACHELINE-1)), (ulong)p1-1);
  268. #ifdef DEBUG
  269. printf("flush cache start<0x%lx>, end<0x%lx>\n", (ulong)p1&(~(BYTE_PER_CACHELINE-1)), (ulong)p1-1);
  270. #endif
  271. }
  272. if (!need_check)
  273. goto ret;
  274. // compare result
  275. // invalid cache before read
  276. mdelay(100);
  277. invalid_dcache_range((ulong)buf, (ulong)buf+(bit_len*4*2*2));
  278. p1 = buf;
  279. bit_cnt = 0;
  280. for (i = 0; i < bit_len; i++) {
  281. bit_cnt++;
  282. if (fixed_range && ((bit_cnt % FIXED_RANGE) == 0))
  283. p1 = buf; // reset ptr to beginning
  284. else if ((bit_cnt % (ddr_density/4/2)) == 0)
  285. p1 = buf; // reset ptr to beginning
  286. bit_value = 0;
  287. for (j = 0; j < dq_cnt; j++) {
  288. unsigned int sum = 0;
  289. for (k = 0; k < exp_cnt; k++) {
  290. char data = Queue_QueryAt(queue[j], exp[k]-1);
  291. sum += data;
  292. }
  293. sum = sum % 2;
  294. Queue_AddToHead(queue[j], sum);
  295. bit_value |= Queue_GetFromTail(queue[j]) << j;
  296. }
  297. pattern = bit_value;
  298. //pattern = _generate_prbs_pos(pos, bit_value);
  299. tmp = *p1;
  300. if (tmp != pattern) {
  301. printf("prbs test failure at addr<0x%lx>, expect<0x%x>, actual<0x%x>\n", (ulong)p1, pattern, tmp);
  302. }
  303. p1++;
  304. #if defined(DDR_PHY0_ONLY) || defined(DDR_PHY1_ONLY)
  305. if(((ulong)p1 - (ulong)buf) % (BYTE_PER_INTERLEAVE/2) == 0)
  306. {
  307. // jump to next PHY1's interleave space
  308. p1+=BYTE_PER_INTERLEAVE/2/sizeof(pattern);
  309. }
  310. #endif
  311. }
  312. for (i = 0; i < bit_len; i++) {
  313. bit_cnt++;
  314. if (fixed_range && ((bit_cnt % FIXED_RANGE) == 0))
  315. p1 = buf; // reset ptr to beginning
  316. else if ((bit_cnt % (ddr_density/4/2)) == 0)
  317. p1 = buf; // reset ptr to beginning
  318. bit_value = 0;
  319. for (j = 0; j < dq_cnt; j++) {
  320. unsigned int sum = 0;
  321. for (k = 0; k < exp_cnt; k++) {
  322. char data = Queue_QueryAt(queue[j], exp[k]-1);
  323. sum += data;
  324. }
  325. sum = sum % 2;
  326. Queue_AddToHead(queue[j], sum);
  327. bit_value |= Queue_GetFromTail(queue[j]) << j;
  328. }
  329. pattern = _generate_prbs_neg(pos, bit_value);
  330. tmp = *p1;
  331. if (tmp != pattern) {
  332. printf("prbs test failure at addr<0x%lx>, expect<0x%x>, actual<0x%x>\n", (ulong)p1, pattern, tmp);
  333. }
  334. p1++;
  335. #if defined(DDR_PHY0_ONLY) || defined(DDR_PHY1_ONLY)
  336. if(((ulong)p1 - (ulong)buf) % (BYTE_PER_INTERLEAVE/2) == 0)
  337. {
  338. // jump to next PHY1's interleave space
  339. p1+=BYTE_PER_INTERLEAVE/2/sizeof(pattern);
  340. }
  341. #endif
  342. }
  343. ret:
  344. for (i = 0; i < dq_cnt; i++)
  345. Queue_Free(queue[i], true);
  346. return 0;
  347. }
  348. static int do_prbs7_sequence_test(cmd_tbl_t *cmdtp, int flag, int argc,
  349. char * const argv[])
  350. {
  351. int ret = 0;
  352. unsigned int *buf, *p1;
  353. ulong addr = 0;
  354. ulong pos = 0;
  355. ulong iter = 1;
  356. ulong random_dq = 1;
  357. ulong i;
  358. ulong range = (1 << 7) *4 *2 *MULTIPLY; // occupys 4byte per bit, positive & negative, PHY0 & PHY1 space
  359. if (argc != 4 && argc != 5) {
  360. printf("should be 4 input parameters!!!");
  361. return CMD_RET_USAGE;
  362. }
  363. if (strict_strtoul(argv[1], 16, &addr) < 0)
  364. return CMD_RET_USAGE;
  365. if (strict_strtoul(argv[2], 16, &pos) < 0)
  366. return CMD_RET_USAGE;
  367. if (strict_strtoul(argv[3], 16, &iter) < 0)
  368. return CMD_RET_USAGE;
  369. if ((argc > 4) && strict_strtoul(argv[4], 16, &random_dq) < 0)
  370. return CMD_RET_USAGE;
  371. if ((addr < CONFIG_SYS_MEMTEST_START) || (addr > CONFIG_SYS_MEMTEST_END)) {
  372. printf("Refusing to do invalid region test 0x%lx\n", addr);
  373. //return -1;
  374. }
  375. if (pos >= 32) {
  376. printf("Refusing to do invalid bit position %ld\n", pos);
  377. return -1;
  378. }
  379. addr = addr & (~(BYTE_PER_INTERLEAVE - 1)); //addr align with ddr interleave(cacheline)
  380. #if defined(CONFIG_DDR_CHBIT_256B) && defined(DDR_PHY1_ONLY)
  381. addr += BYTE_PER_INTERLEAVE/2; // only access PHY1
  382. #endif
  383. printf("PRBS7 test: addr=0x%lx, pos=%d, iter=%d\n",
  384. addr, (int)pos, (int)iter);
  385. buf = map_sysmem(addr, range);
  386. p1 = buf;
  387. //clear buf and assure all buf allocated into cache entry
  388. for(i = 0; i < range; i+=4) {
  389. *p1++ = 0;
  390. }
  391. mdelay(100);
  392. for(i=0; i<iter; i++)
  393. {
  394. printf("prbs7 test itration<%ld>\n", i);
  395. riscv_get_time(&t_begin);
  396. prbs_test(&prbs7, buf, (int)pos, (random_dq!=0), checked);
  397. riscv_get_time(&t_end);
  398. printf("it spends %lld ms to do prbs7 sequence\n", (t_end - t_begin)/TIMER_TICK_MS);
  399. }
  400. return ret;
  401. }
  402. static int do_prbs15_sequence_test(cmd_tbl_t *cmdtp, int flag, int argc,
  403. char * const argv[])
  404. {
  405. int ret = 0;
  406. unsigned int *buf, *p1;
  407. ulong addr = 0;
  408. ulong pos = 0;
  409. ulong iter = 1;
  410. ulong random_dq = 1;
  411. ulong i;
  412. ulong range = (1 << 15) *4 *2 *MULTIPLY; // occupys 4byte per bit, positive & negative, PHY0 & PHY1 space
  413. if (argc != 4 && argc != 5) {
  414. printf("should be 4 input parameters!!!");
  415. return CMD_RET_USAGE;
  416. }
  417. if (strict_strtoul(argv[1], 16, &addr) < 0)
  418. return CMD_RET_USAGE;
  419. if (strict_strtoul(argv[2], 16, &pos) < 0)
  420. return CMD_RET_USAGE;
  421. if (strict_strtoul(argv[3], 16, &iter) < 0)
  422. return CMD_RET_USAGE;
  423. if ((argc > 4) && strict_strtoul(argv[4], 16, &random_dq) < 0)
  424. return CMD_RET_USAGE;
  425. if ((addr < CONFIG_SYS_MEMTEST_START) || (addr > CONFIG_SYS_MEMTEST_END)) {
  426. printf("Refusing to do invalid region test 0x%lx\n", addr);
  427. //return -1;
  428. }
  429. if (pos >= 32) {
  430. printf("Refusing to do invalid bit position %ld\n", pos);
  431. return -1;
  432. }
  433. addr = addr & (~(BYTE_PER_INTERLEAVE - 1)); //addr align with ddr interleave(cacheline)
  434. #if defined(CONFIG_DDR_CHBIT_256B) && defined(DDR_PHY1_ONLY)
  435. addr += BYTE_PER_INTERLEAVE/2; // only access PHY1
  436. #endif
  437. printf("PRBS15 test: addr=0x%lx, pos=%d, iter=%d\n",
  438. addr, (int)pos, (int)iter);
  439. buf = map_sysmem(addr, range);
  440. p1 = buf;
  441. //clear buf and assure all buf allocated into cache entry
  442. for(i = 0; i < range; i+=4) {
  443. *p1++ = 0;
  444. }
  445. mdelay(100);
  446. for(i=0; i<iter; i++)
  447. {
  448. printf("prbs15 test itration<%ld>\n", i);
  449. riscv_get_time(&t_begin);
  450. prbs_test(&prbs15, buf, (int)pos, (random_dq!=0), checked);
  451. riscv_get_time(&t_end);
  452. printf("it spends %lld ms to do prbs15 sequence\n", (t_end - t_begin)/TIMER_TICK_MS);
  453. }
  454. return ret;
  455. }
  456. static int do_prbs23_sequence_test(cmd_tbl_t *cmdtp, int flag, int argc,
  457. char * const argv[])
  458. {
  459. int ret = 0;
  460. unsigned int *buf, *p1;
  461. ulong addr = 0;
  462. ulong pos = 0;
  463. ulong iter = 1;
  464. ulong random_dq = 1;
  465. ulong i;
  466. ulong range = (1 << 23) *4 *2 *MULTIPLY; // occupys 4byte per bit, positive & negative, PHY0 & PHY1 space
  467. if (argc != 4 && argc != 5) {
  468. printf("should be 4 input parameters!!!");
  469. return CMD_RET_USAGE;
  470. }
  471. if (strict_strtoul(argv[1], 16, &addr) < 0)
  472. return CMD_RET_USAGE;
  473. if (strict_strtoul(argv[2], 16, &pos) < 0)
  474. return CMD_RET_USAGE;
  475. if (strict_strtoul(argv[3], 16, &iter) < 0)
  476. return CMD_RET_USAGE;
  477. if ((argc > 4) && strict_strtoul(argv[4], 16, &random_dq) < 0)
  478. return CMD_RET_USAGE;
  479. if ((addr < CONFIG_SYS_MEMTEST_START) || (addr > CONFIG_SYS_MEMTEST_END)) {
  480. printf("Refusing to do invalid region test 0x%lx\n", addr);
  481. //return -1;
  482. }
  483. if (pos >= 32) {
  484. printf("Refusing to do invalid bit position %ld\n", pos);
  485. return -1;
  486. }
  487. addr = addr & (~(BYTE_PER_INTERLEAVE - 1)); //addr align with ddr interleave(cacheline)
  488. #if defined(CONFIG_DDR_CHBIT_256B) && defined(DDR_PHY1_ONLY)
  489. addr += BYTE_PER_INTERLEAVE/2; // only access PHY1
  490. #endif
  491. printf("PRBS23 test: addr=0x%lx, pos=%d, iter=%d\n",
  492. addr, (int)pos, (int)iter);
  493. buf = map_sysmem(addr, range);
  494. p1 = buf;
  495. //clear buf and assure all buf allocated into cache entry
  496. for(i = 0; i < range; i+=4) {
  497. *p1++ = 0;
  498. }
  499. mdelay(100);
  500. for(i=0; i<iter; i++)
  501. {
  502. printf("prbs23 test itration<%ld>\n", i);
  503. riscv_get_time(&t_begin);
  504. prbs_test(&prbs23, buf, (int)pos, (random_dq!=0), checked);
  505. riscv_get_time(&t_end);
  506. printf("it spends %lld ms to do prbs23 sequence\n", (t_end - t_begin)/TIMER_TICK_MS);
  507. }
  508. return ret;
  509. }
  510. static int do_prbs31_sequence_test(cmd_tbl_t *cmdtp, int flag, int argc,
  511. char * const argv[])
  512. {
  513. int ret = 0;
  514. unsigned int *buf, *p1;
  515. ulong addr = 0;
  516. ulong pos = 0;
  517. ulong iter = 1;
  518. ulong random_dq = 1;
  519. ulong i;
  520. ulong ddr_density = get_ddr_density();
  521. ulong range = (ulong)(1 << 31) *4; // occupys 4byte per bit, positive & negative, PHY0 & PHY1 space
  522. // too large to store prbs31 patterns in DDR space, mmap 4GB and wrap write is allowed
  523. if (range > ddr_density)
  524. range = ddr_density;
  525. range = FIXED_RANGE; // FIXED_RANGE for prbs_31
  526. if (argc != 4 && argc != 5) {
  527. printf("should be 4 input parameters!!!");
  528. return CMD_RET_USAGE;
  529. }
  530. if (strict_strtoul(argv[1], 16, &addr) < 0)
  531. return CMD_RET_USAGE;
  532. if (strict_strtoul(argv[2], 16, &pos) < 0)
  533. return CMD_RET_USAGE;
  534. if (strict_strtoul(argv[3], 16, &iter) < 0)
  535. return CMD_RET_USAGE;
  536. if ((argc > 4) && strict_strtoul(argv[4], 16, &random_dq) < 0)
  537. return CMD_RET_USAGE;
  538. if ((addr < CONFIG_SYS_MEMTEST_START) || (addr > CONFIG_SYS_MEMTEST_END)) {
  539. printf("Refusing to do invalid region test 0x%lx\n", addr);
  540. //return -1;
  541. }
  542. if (pos >= 32) {
  543. printf("Refusing to do invalid bit position %ld\n", pos);
  544. return -1;
  545. }
  546. addr = addr & (~(BYTE_PER_INTERLEAVE - 1)); //addr align with ddr interleave(cacheline)
  547. #if defined(CONFIG_DDR_CHBIT_256B) && defined(DDR_PHY1_ONLY)
  548. addr += BYTE_PER_INTERLEAVE/2; // only access PHY1
  549. #endif
  550. printf("PRBS31 test: addr=0x%lx, pos=%d, iter=%d\n",
  551. addr, (int)pos, (int)iter);
  552. buf = map_sysmem(addr, range);
  553. p1 = buf;
  554. //clear buf and assure all buf allocated into cache entry
  555. for(i = 0; i < range; i+=4) {
  556. *p1++ = 0;
  557. }
  558. mdelay(100);
  559. for(i=0; i<iter; i++)
  560. {
  561. printf("prbs31 test itration<%ld>\n", i);
  562. riscv_get_time(&t_begin);
  563. prbs_test(&prbs31, buf, (int)pos, (random_dq!=0), false); // too large to check result
  564. riscv_get_time(&t_end);
  565. printf("it spends %lld ms to do prbs31 sequence\n", (t_end - t_begin)/TIMER_TICK_MS);
  566. }
  567. return ret;
  568. }
  569. U_BOOT_CMD(
  570. prbs_7, 5, 1, do_prbs7_sequence_test,
  571. "PRBS_7 sequence test",
  572. "[addr bit [iterations [is_random_dq]]]"
  573. );
  574. U_BOOT_CMD(
  575. prbs_15, 5, 1, do_prbs15_sequence_test,
  576. "PRBS_15 sequence test",
  577. "[addr bit [iterations [is_random_dq]]]"
  578. );
  579. U_BOOT_CMD(
  580. prbs_23, 5, 1, do_prbs23_sequence_test,
  581. "PRBS_23 sequence test",
  582. "[addr bit [iterations [is_random_dq]]]"
  583. );
  584. U_BOOT_CMD(
  585. prbs_31, 5, 1, do_prbs31_sequence_test,
  586. "PRBS_31 sequence test",
  587. "[addr bit [iterations [is_random_dq]]]"
  588. );