mpc8349emds.c 17 KB

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