mpc8360emds.c 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574
  1. /*
  2. * Copyright (C) 2006 Freescale Semiconductor, Inc.
  3. *
  4. * Dave Liu <daveliu@freescale.com>
  5. * based on board/mpc8349emds/mpc8349emds.c
  6. *
  7. * See file CREDITS for list of people who contributed to this
  8. * project.
  9. *
  10. * This program is free software; you can redistribute it and/or
  11. * modify it under the terms of the GNU General Public License as
  12. * published by the Free Software Foundation; either version 2 of
  13. * the License, or (at your option) any later version.
  14. */
  15. #include <common.h>
  16. #include <ioports.h>
  17. #include <mpc83xx.h>
  18. #include <i2c.h>
  19. #include <spd.h>
  20. #include <miiphy.h>
  21. #include <command.h>
  22. #if defined(CONFIG_PCI)
  23. #include <pci.h>
  24. #endif
  25. #if defined(CONFIG_SPD_EEPROM)
  26. #include <spd_sdram.h>
  27. #else
  28. #include <asm/mmu.h>
  29. #endif
  30. int board_early_init_f(void)
  31. {
  32. volatile u8 *bcsr = (volatile u8 *)CFG_BCSR;
  33. /* Enable flash write */
  34. bcsr[0xa] &= ~0x04;
  35. return 0;
  36. }
  37. #if defined(CONFIG_DDR_ECC) && !defined(CONFIG_ECC_INIT_VIA_DDRC)
  38. extern void ddr_enable_ecc(unsigned int dram_size);
  39. #endif
  40. int fixed_sdram(void);
  41. void sdram_init(void);
  42. long int initdram(int board_type)
  43. {
  44. volatile immap_t *im = (immap_t *) CFG_IMMRBAR;
  45. u32 msize = 0;
  46. if ((im->sysconf.immrbar & IMMRBAR_BASE_ADDR) != (u32) im)
  47. return -1;
  48. /* DDR SDRAM - Main SODIMM */
  49. im->sysconf.ddrlaw[0].bar = CFG_DDR_BASE & LAWBAR_BAR;
  50. #if defined(CONFIG_SPD_EEPROM)
  51. msize = spd_sdram();
  52. #else
  53. msize = fixed_sdram();
  54. #endif
  55. #if defined(CONFIG_DDR_ECC) && !defined(CONFIG_ECC_INIT_VIA_DDRC)
  56. /*
  57. * Initialize DDR ECC byte
  58. */
  59. ddr_enable_ecc(msize * 1024 * 1024);
  60. #endif
  61. /*
  62. * Initialize SDRAM if it is on local bus.
  63. */
  64. sdram_init();
  65. puts(" DDR RAM: ");
  66. /* return total bus SDRAM size(bytes) -- DDR */
  67. return (msize * 1024 * 1024);
  68. }
  69. #if !defined(CONFIG_SPD_EEPROM)
  70. /*************************************************************************
  71. * fixed sdram init -- doesn't use serial presence detect.
  72. ************************************************************************/
  73. int fixed_sdram(void)
  74. {
  75. volatile immap_t *im = (immap_t *) CFG_IMMRBAR;
  76. u32 msize = 0;
  77. u32 ddr_size;
  78. u32 ddr_size_log2;
  79. msize = CFG_DDR_SIZE;
  80. for (ddr_size = msize << 20, ddr_size_log2 = 0;
  81. (ddr_size > 1); ddr_size = ddr_size >> 1, ddr_size_log2++) {
  82. if (ddr_size & 1) {
  83. return -1;
  84. }
  85. }
  86. im->sysconf.ddrlaw[0].ar =
  87. LAWAR_EN | ((ddr_size_log2 - 1) & LAWAR_SIZE);
  88. #if (CFG_DDR_SIZE != 256)
  89. #warning Currenly any ddr size other than 256 is not supported
  90. #endif
  91. im->ddr.csbnds[0].csbnds = 0x00000007;
  92. im->ddr.csbnds[1].csbnds = 0x0008000f;
  93. im->ddr.cs_config[0] = CFG_DDR_CONFIG;
  94. im->ddr.cs_config[1] = CFG_DDR_CONFIG;
  95. im->ddr.timing_cfg_1 = CFG_DDR_TIMING_1;
  96. im->ddr.timing_cfg_2 = CFG_DDR_TIMING_2;
  97. im->ddr.sdram_cfg = CFG_DDR_CONTROL;
  98. im->ddr.sdram_mode = CFG_DDR_MODE;
  99. im->ddr.sdram_interval = CFG_DDR_INTERVAL;
  100. udelay(200);
  101. im->ddr.sdram_cfg |= SDRAM_CFG_MEM_EN;
  102. return msize;
  103. }
  104. #endif /*!CFG_SPD_EEPROM */
  105. int checkboard(void)
  106. {
  107. puts("Board: Freescale MPC8360EMDS\n");
  108. return 0;
  109. }
  110. /*
  111. * if MPC8360EMDS is soldered with SDRAM
  112. */
  113. #if defined(CFG_BR2_PRELIM) \
  114. && defined(CFG_OR2_PRELIM) \
  115. && defined(CFG_LBLAWBAR2_PRELIM) \
  116. && defined(CFG_LBLAWAR2_PRELIM)
  117. /*
  118. * Initialize SDRAM memory on the Local Bus.
  119. */
  120. void sdram_init(void)
  121. {
  122. volatile immap_t *immap = (immap_t *) CFG_IMMRBAR;
  123. volatile lbus83xx_t *lbc = &immap->lbus;
  124. uint *sdram_addr = (uint *) CFG_LBC_SDRAM_BASE;
  125. puts("\n SDRAM on Local Bus: ");
  126. print_size(CFG_LBC_SDRAM_SIZE * 1024 * 1024, "\n");
  127. /*
  128. * Setup SDRAM Base and Option Registers, already done in cpu_init.c
  129. */
  130. /*setup mtrpt, lsrt and lbcr for LB bus */
  131. lbc->lbcr = CFG_LBC_LBCR;
  132. lbc->mrtpr = CFG_LBC_MRTPR;
  133. lbc->lsrt = CFG_LBC_LSRT;
  134. asm("sync");
  135. /*
  136. * Configure the SDRAM controller Machine Mode Register.
  137. */
  138. lbc->lsdmr = CFG_LBC_LSDMR_5; /* Normal Operation */
  139. lbc->lsdmr = CFG_LBC_LSDMR_1; /* Precharge All Banks */
  140. asm("sync");
  141. *sdram_addr = 0xff;
  142. udelay(100);
  143. /*
  144. * We need do 8 times auto refresh operation.
  145. */
  146. lbc->lsdmr = CFG_LBC_LSDMR_2;
  147. asm("sync");
  148. *sdram_addr = 0xff; /* 1 times */
  149. udelay(100);
  150. *sdram_addr = 0xff; /* 2 times */
  151. udelay(100);
  152. *sdram_addr = 0xff; /* 3 times */
  153. udelay(100);
  154. *sdram_addr = 0xff; /* 4 times */
  155. udelay(100);
  156. *sdram_addr = 0xff; /* 5 times */
  157. udelay(100);
  158. *sdram_addr = 0xff; /* 6 times */
  159. udelay(100);
  160. *sdram_addr = 0xff; /* 7 times */
  161. udelay(100);
  162. *sdram_addr = 0xff; /* 8 times */
  163. udelay(100);
  164. /* Mode register write operation */
  165. lbc->lsdmr = CFG_LBC_LSDMR_4;
  166. asm("sync");
  167. *(sdram_addr + 0xcc) = 0xff;
  168. udelay(100);
  169. /* Normal operation */
  170. lbc->lsdmr = CFG_LBC_LSDMR_5 | 0x40000000;
  171. asm("sync");
  172. *sdram_addr = 0xff;
  173. udelay(100);
  174. }
  175. #else
  176. void sdram_init(void)
  177. {
  178. puts("SDRAM on Local Bus is NOT available!\n");
  179. }
  180. #endif
  181. #if defined(CONFIG_DDR_ECC) && defined(CONFIG_DDR_ECC_CMD)
  182. /*
  183. * ECC user commands
  184. */
  185. void ecc_print_status(void)
  186. {
  187. volatile immap_t *immap = (immap_t *) CFG_IMMRBAR;
  188. volatile ddr83xx_t *ddr = &immap->ddr;
  189. printf("\nECC mode: %s\n\n",
  190. (ddr->sdram_cfg & SDRAM_CFG_ECC_EN) ? "ON" : "OFF");
  191. /* Interrupts */
  192. printf("Memory Error Interrupt Enable:\n");
  193. printf(" Multiple-Bit Error Interrupt Enable: %d\n",
  194. (ddr->err_int_en & ECC_ERR_INT_EN_MBEE) ? 1 : 0);
  195. printf(" Single-Bit Error Interrupt Enable: %d\n",
  196. (ddr->err_int_en & ECC_ERR_INT_EN_SBEE) ? 1 : 0);
  197. printf(" Memory Select Error Interrupt Enable: %d\n\n",
  198. (ddr->err_int_en & ECC_ERR_INT_EN_MSEE) ? 1 : 0);
  199. /* Error disable */
  200. printf("Memory Error Disable:\n");
  201. printf(" Multiple-Bit Error Disable: %d\n",
  202. (ddr->err_disable & ECC_ERROR_DISABLE_MBED) ? 1 : 0);
  203. printf(" Sinle-Bit Error Disable: %d\n",
  204. (ddr->err_disable & ECC_ERROR_DISABLE_SBED) ? 1 : 0);
  205. printf(" Memory Select Error Disable: %d\n\n",
  206. (ddr->err_disable & ECC_ERROR_DISABLE_MSED) ? 1 : 0);
  207. /* Error injection */
  208. printf("Memory Data Path Error Injection Mask High/Low: %08lx %08lx\n",
  209. ddr->data_err_inject_hi, ddr->data_err_inject_lo);
  210. printf("Memory Data Path Error Injection Mask ECC:\n");
  211. printf(" ECC Mirror Byte: %d\n",
  212. (ddr->ecc_err_inject & ECC_ERR_INJECT_EMB) ? 1 : 0);
  213. printf(" ECC Injection Enable: %d\n",
  214. (ddr->ecc_err_inject & ECC_ERR_INJECT_EIEN) ? 1 : 0);
  215. printf(" ECC Error Injection Mask: 0x%02x\n\n",
  216. ddr->ecc_err_inject & ECC_ERR_INJECT_EEIM);
  217. /* SBE counter/threshold */
  218. printf("Memory Single-Bit Error Management (0..255):\n");
  219. printf(" Single-Bit Error Threshold: %d\n",
  220. (ddr->err_sbe & ECC_ERROR_MAN_SBET) >> ECC_ERROR_MAN_SBET_SHIFT);
  221. printf(" Single-Bit Error Counter: %d\n\n",
  222. (ddr->err_sbe & ECC_ERROR_MAN_SBEC) >> ECC_ERROR_MAN_SBEC_SHIFT);
  223. /* Error detect */
  224. printf("Memory Error Detect:\n");
  225. printf(" Multiple Memory Errors: %d\n",
  226. (ddr->err_detect & ECC_ERROR_DETECT_MME) ? 1 : 0);
  227. printf(" Multiple-Bit Error: %d\n",
  228. (ddr->err_detect & ECC_ERROR_DETECT_MBE) ? 1 : 0);
  229. printf(" Single-Bit Error: %d\n",
  230. (ddr->err_detect & ECC_ERROR_DETECT_SBE) ? 1 : 0);
  231. printf(" Memory Select Error: %d\n\n",
  232. (ddr->err_detect & ECC_ERROR_DETECT_MSE) ? 1 : 0);
  233. /* Capture data */
  234. printf("Memory Error Address Capture: 0x%08lx\n", ddr->capture_address);
  235. printf("Memory Data Path Read Capture High/Low: %08lx %08lx\n",
  236. ddr->capture_data_hi, ddr->capture_data_lo);
  237. printf("Memory Data Path Read Capture ECC: 0x%02x\n\n",
  238. ddr->capture_ecc & CAPTURE_ECC_ECE);
  239. printf("Memory Error Attributes Capture:\n");
  240. printf(" Data Beat Number: %d\n",
  241. (ddr->capture_attributes & ECC_CAPT_ATTR_BNUM) >>
  242. ECC_CAPT_ATTR_BNUM_SHIFT);
  243. printf(" Transaction Size: %d\n",
  244. (ddr->capture_attributes & ECC_CAPT_ATTR_TSIZ) >>
  245. ECC_CAPT_ATTR_TSIZ_SHIFT);
  246. printf(" Transaction Source: %d\n",
  247. (ddr->capture_attributes & ECC_CAPT_ATTR_TSRC) >>
  248. ECC_CAPT_ATTR_TSRC_SHIFT);
  249. printf(" Transaction Type: %d\n",
  250. (ddr->capture_attributes & ECC_CAPT_ATTR_TTYP) >>
  251. ECC_CAPT_ATTR_TTYP_SHIFT);
  252. printf(" Error Information Valid: %d\n\n",
  253. ddr->capture_attributes & ECC_CAPT_ATTR_VLD);
  254. }
  255. int do_ecc(cmd_tbl_t * cmdtp, int flag, int argc, char *argv[])
  256. {
  257. volatile immap_t *immap = (immap_t *) CFG_IMMRBAR;
  258. volatile ddr83xx_t *ddr = &immap->ddr;
  259. volatile u32 val;
  260. u64 *addr;
  261. u32 count;
  262. register u64 *i;
  263. u32 ret[2];
  264. u32 pattern[2];
  265. u32 writeback[2];
  266. /* The pattern is written into memory to generate error */
  267. pattern[0] = 0xfedcba98UL;
  268. pattern[1] = 0x76543210UL;
  269. /* After injecting error, re-initialize the memory with the value */
  270. writeback[0] = 0x01234567UL;
  271. writeback[1] = 0x89abcdefUL;
  272. if (argc > 4) {
  273. printf("Usage:\n%s\n", cmdtp->usage);
  274. return 1;
  275. }
  276. if (argc == 2) {
  277. if (strcmp(argv[1], "status") == 0) {
  278. ecc_print_status();
  279. return 0;
  280. } else if (strcmp(argv[1], "captureclear") == 0) {
  281. ddr->capture_address = 0;
  282. ddr->capture_data_hi = 0;
  283. ddr->capture_data_lo = 0;
  284. ddr->capture_ecc = 0;
  285. ddr->capture_attributes = 0;
  286. return 0;
  287. }
  288. }
  289. if (argc == 3) {
  290. if (strcmp(argv[1], "sbecnt") == 0) {
  291. val = simple_strtoul(argv[2], NULL, 10);
  292. if (val > 255) {
  293. printf("Incorrect Counter value, "
  294. "should be 0..255\n");
  295. return 1;
  296. }
  297. val = (val << ECC_ERROR_MAN_SBEC_SHIFT);
  298. val |= (ddr->err_sbe & ECC_ERROR_MAN_SBET);
  299. ddr->err_sbe = val;
  300. return 0;
  301. } else if (strcmp(argv[1], "sbethr") == 0) {
  302. val = simple_strtoul(argv[2], NULL, 10);
  303. if (val > 255) {
  304. printf("Incorrect Counter value, "
  305. "should be 0..255\n");
  306. return 1;
  307. }
  308. val = (val << ECC_ERROR_MAN_SBET_SHIFT);
  309. val |= (ddr->err_sbe & ECC_ERROR_MAN_SBEC);
  310. ddr->err_sbe = val;
  311. return 0;
  312. } else if (strcmp(argv[1], "errdisable") == 0) {
  313. val = ddr->err_disable;
  314. if (strcmp(argv[2], "+sbe") == 0) {
  315. val |= ECC_ERROR_DISABLE_SBED;
  316. } else if (strcmp(argv[2], "+mbe") == 0) {
  317. val |= ECC_ERROR_DISABLE_MBED;
  318. } else if (strcmp(argv[2], "+mse") == 0) {
  319. val |= ECC_ERROR_DISABLE_MSED;
  320. } else if (strcmp(argv[2], "+all") == 0) {
  321. val |= (ECC_ERROR_DISABLE_SBED |
  322. ECC_ERROR_DISABLE_MBED |
  323. ECC_ERROR_DISABLE_MSED);
  324. } else if (strcmp(argv[2], "-sbe") == 0) {
  325. val &= ~ECC_ERROR_DISABLE_SBED;
  326. } else if (strcmp(argv[2], "-mbe") == 0) {
  327. val &= ~ECC_ERROR_DISABLE_MBED;
  328. } else if (strcmp(argv[2], "-mse") == 0) {
  329. val &= ~ECC_ERROR_DISABLE_MSED;
  330. } else if (strcmp(argv[2], "-all") == 0) {
  331. val &= ~(ECC_ERROR_DISABLE_SBED |
  332. ECC_ERROR_DISABLE_MBED |
  333. ECC_ERROR_DISABLE_MSED);
  334. } else {
  335. printf("Incorrect err_disable field\n");
  336. return 1;
  337. }
  338. ddr->err_disable = val;
  339. __asm__ __volatile__("sync");
  340. __asm__ __volatile__("isync");
  341. return 0;
  342. } else if (strcmp(argv[1], "errdetectclr") == 0) {
  343. val = ddr->err_detect;
  344. if (strcmp(argv[2], "mme") == 0) {
  345. val |= ECC_ERROR_DETECT_MME;
  346. } else if (strcmp(argv[2], "sbe") == 0) {
  347. val |= ECC_ERROR_DETECT_SBE;
  348. } else if (strcmp(argv[2], "mbe") == 0) {
  349. val |= ECC_ERROR_DETECT_MBE;
  350. } else if (strcmp(argv[2], "mse") == 0) {
  351. val |= ECC_ERROR_DETECT_MSE;
  352. } else if (strcmp(argv[2], "all") == 0) {
  353. val |= (ECC_ERROR_DETECT_MME |
  354. ECC_ERROR_DETECT_MBE |
  355. ECC_ERROR_DETECT_SBE |
  356. ECC_ERROR_DETECT_MSE);
  357. } else {
  358. printf("Incorrect err_detect field\n");
  359. return 1;
  360. }
  361. ddr->err_detect = val;
  362. return 0;
  363. } else if (strcmp(argv[1], "injectdatahi") == 0) {
  364. val = simple_strtoul(argv[2], NULL, 16);
  365. ddr->data_err_inject_hi = val;
  366. return 0;
  367. } else if (strcmp(argv[1], "injectdatalo") == 0) {
  368. val = simple_strtoul(argv[2], NULL, 16);
  369. ddr->data_err_inject_lo = val;
  370. return 0;
  371. } else if (strcmp(argv[1], "injectecc") == 0) {
  372. val = simple_strtoul(argv[2], NULL, 16);
  373. if (val > 0xff) {
  374. printf("Incorrect ECC inject mask, "
  375. "should be 0x00..0xff\n");
  376. return 1;
  377. }
  378. val |= (ddr->ecc_err_inject & ~ECC_ERR_INJECT_EEIM);
  379. ddr->ecc_err_inject = val;
  380. return 0;
  381. } else if (strcmp(argv[1], "inject") == 0) {
  382. val = ddr->ecc_err_inject;
  383. if (strcmp(argv[2], "en") == 0)
  384. val |= ECC_ERR_INJECT_EIEN;
  385. else if (strcmp(argv[2], "dis") == 0)
  386. val &= ~ECC_ERR_INJECT_EIEN;
  387. else
  388. printf("Incorrect command\n");
  389. ddr->ecc_err_inject = val;
  390. __asm__ __volatile__("sync");
  391. __asm__ __volatile__("isync");
  392. return 0;
  393. } else if (strcmp(argv[1], "mirror") == 0) {
  394. val = ddr->ecc_err_inject;
  395. if (strcmp(argv[2], "en") == 0)
  396. val |= ECC_ERR_INJECT_EMB;
  397. else if (strcmp(argv[2], "dis") == 0)
  398. val &= ~ECC_ERR_INJECT_EMB;
  399. else
  400. printf("Incorrect command\n");
  401. ddr->ecc_err_inject = val;
  402. return 0;
  403. }
  404. }
  405. if (argc == 4) {
  406. if (strcmp(argv[1], "testdw") == 0) {
  407. addr = (u64 *) simple_strtoul(argv[2], NULL, 16);
  408. count = simple_strtoul(argv[3], NULL, 16);
  409. if ((u32) addr % 8) {
  410. printf("Address not alligned on "
  411. "double word boundary\n");
  412. return 1;
  413. }
  414. disable_interrupts();
  415. for (i = addr; i < addr + count; i++) {
  416. /* enable injects */
  417. ddr->ecc_err_inject |= ECC_ERR_INJECT_EIEN;
  418. __asm__ __volatile__("sync");
  419. __asm__ __volatile__("isync");
  420. /* write memory location injecting errors */
  421. ppcDWstore((u32 *) i, pattern);
  422. /* disable injects */
  423. ddr->ecc_err_inject &= ~ECC_ERR_INJECT_EIEN;
  424. __asm__ __volatile__("sync");
  425. __asm__ __volatile__("isync");
  426. /* read data, this generates ECC error */
  427. ppcDWload((u32 *) i, ret);
  428. /* re-initialize memory, double word write the location again,
  429. * generates new ECC code this time */
  430. ppcDWstore((u32 *) i, writeback);
  431. }
  432. enable_interrupts();
  433. return 0;
  434. }
  435. if (strcmp(argv[1], "testword") == 0) {
  436. addr = (u64 *) simple_strtoul(argv[2], NULL, 16);
  437. count = simple_strtoul(argv[3], NULL, 16);
  438. if ((u32) addr % 8) {
  439. printf("Address not alligned on "
  440. "double word boundary\n");
  441. return 1;
  442. }
  443. disable_interrupts();
  444. for (i = addr; i < addr + count; i++) {
  445. /* enable injects */
  446. ddr->ecc_err_inject |= ECC_ERR_INJECT_EIEN;
  447. __asm__ __volatile__("sync");
  448. __asm__ __volatile__("isync");
  449. /* write memory location injecting errors */
  450. *(u32 *) i = 0xfedcba98UL;
  451. __asm__ __volatile__("sync");
  452. /* sub double word write,
  453. * bus will read-modify-write,
  454. * generates ECC error */
  455. *((u32 *) i + 1) = 0x76543210UL;
  456. __asm__ __volatile__("sync");
  457. /* disable injects */
  458. ddr->ecc_err_inject &= ~ECC_ERR_INJECT_EIEN;
  459. __asm__ __volatile__("sync");
  460. __asm__ __volatile__("isync");
  461. /* re-initialize memory,
  462. * double word write the location again,
  463. * generates new ECC code this time */
  464. ppcDWstore((u32 *) i, writeback);
  465. }
  466. enable_interrupts();
  467. return 0;
  468. }
  469. }
  470. printf("Usage:\n%s\n", cmdtp->usage);
  471. return 1;
  472. }
  473. U_BOOT_CMD(ecc, 4, 0, do_ecc,
  474. "ecc - support for DDR ECC features\n",
  475. "status - print out status info\n"
  476. "ecc captureclear - clear capture regs data\n"
  477. "ecc sbecnt <val> - set Single-Bit Error counter\n"
  478. "ecc sbethr <val> - set Single-Bit Threshold\n"
  479. "ecc errdisable <flag> - clear/set disable Memory Error Disable, flag:\n"
  480. " [-|+]sbe - Single-Bit Error\n"
  481. " [-|+]mbe - Multiple-Bit Error\n"
  482. " [-|+]mse - Memory Select Error\n"
  483. " [-|+]all - all errors\n"
  484. "ecc errdetectclr <flag> - clear Memory Error Detect, flag:\n"
  485. " mme - Multiple Memory Errors\n"
  486. " sbe - Single-Bit Error\n"
  487. " mbe - Multiple-Bit Error\n"
  488. " mse - Memory Select Error\n"
  489. " all - all errors\n"
  490. "ecc injectdatahi <hi> - set Memory Data Path Error Injection Mask High\n"
  491. "ecc injectdatalo <lo> - set Memory Data Path Error Injection Mask Low\n"
  492. "ecc injectecc <ecc> - set ECC Error Injection Mask\n"
  493. "ecc inject <en|dis> - enable/disable error injection\n"
  494. "ecc mirror <en|dis> - enable/disable mirror byte\n"
  495. "ecc testdw <addr> <cnt> - test mem region with double word access:\n"
  496. " - enables injects\n"
  497. " - writes pattern injecting errors with double word access\n"
  498. " - disables injects\n"
  499. " - reads pattern back with double word access, generates error\n"
  500. " - re-inits memory\n"
  501. "ecc testword <addr> <cnt> - test mem region with word access:\n"
  502. " - enables injects\n"
  503. " - writes pattern injecting errors with word access\n"
  504. " - writes pattern with word access, generates error\n"
  505. " - disables injects\n" " - re-inits memory");
  506. #endif /* if defined(CONFIG_DDR_ECC) && defined(CONFIG_DDR_ECC_CMD) */