ddr3.c 9.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339
  1. // SPDX-License-Identifier: GPL-2.0+
  2. /*
  3. * EMIF: DDR3 test commands
  4. *
  5. * Copyright (C) 2012-2017 Texas Instruments Incorporated, <www.ti.com>
  6. */
  7. #include <cpu_func.h>
  8. #include <asm/arch/hardware.h>
  9. #include <asm/cache.h>
  10. #include <asm/emif.h>
  11. #include <common.h>
  12. #include <command.h>
  13. DECLARE_GLOBAL_DATA_PTR;
  14. #ifdef CONFIG_ARCH_KEYSTONE
  15. #include <asm/arch/ddr3.h>
  16. #define DDR_MIN_ADDR CONFIG_SYS_SDRAM_BASE
  17. #define STACKSIZE (512 << 10) /* 512 KiB */
  18. #define DDR_REMAP_ADDR 0x80000000
  19. #define ECC_START_ADDR1 ((DDR_MIN_ADDR - DDR_REMAP_ADDR) >> 17)
  20. #define ECC_END_ADDR1 (((gd->start_addr_sp - DDR_REMAP_ADDR - \
  21. STACKSIZE) >> 17) - 2)
  22. #endif
  23. #define DDR_TEST_BURST_SIZE 1024
  24. static int ddr_memory_test(u32 start_address, u32 end_address, int quick)
  25. {
  26. u32 index_start, value, index;
  27. index_start = start_address;
  28. while (1) {
  29. /* Write a pattern */
  30. for (index = index_start;
  31. index < index_start + DDR_TEST_BURST_SIZE;
  32. index += 4)
  33. __raw_writel(index, index);
  34. /* Read and check the pattern */
  35. for (index = index_start;
  36. index < index_start + DDR_TEST_BURST_SIZE;
  37. index += 4) {
  38. value = __raw_readl(index);
  39. if (value != index) {
  40. printf("ddr_memory_test: Failed at address index = 0x%x value = 0x%x *(index) = 0x%x\n",
  41. index, value, __raw_readl(index));
  42. return -1;
  43. }
  44. }
  45. index_start += DDR_TEST_BURST_SIZE;
  46. if (index_start >= end_address)
  47. break;
  48. if (quick)
  49. continue;
  50. /* Write a pattern for complementary values */
  51. for (index = index_start;
  52. index < index_start + DDR_TEST_BURST_SIZE;
  53. index += 4)
  54. __raw_writel((u32)~index, index);
  55. /* Read and check the pattern */
  56. for (index = index_start;
  57. index < index_start + DDR_TEST_BURST_SIZE;
  58. index += 4) {
  59. value = __raw_readl(index);
  60. if (value != ~index) {
  61. printf("ddr_memory_test: Failed at address index = 0x%x value = 0x%x *(index) = 0x%x\n",
  62. index, value, __raw_readl(index));
  63. return -1;
  64. }
  65. }
  66. index_start += DDR_TEST_BURST_SIZE;
  67. if (index_start >= end_address)
  68. break;
  69. /* Write a pattern */
  70. for (index = index_start;
  71. index < index_start + DDR_TEST_BURST_SIZE;
  72. index += 2)
  73. __raw_writew((u16)index, index);
  74. /* Read and check the pattern */
  75. for (index = index_start;
  76. index < index_start + DDR_TEST_BURST_SIZE;
  77. index += 2) {
  78. value = __raw_readw(index);
  79. if (value != (u16)index) {
  80. printf("ddr_memory_test: Failed at address index = 0x%x value = 0x%x *(index) = 0x%x\n",
  81. index, value, __raw_readw(index));
  82. return -1;
  83. }
  84. }
  85. index_start += DDR_TEST_BURST_SIZE;
  86. if (index_start >= end_address)
  87. break;
  88. /* Write a pattern */
  89. for (index = index_start;
  90. index < index_start + DDR_TEST_BURST_SIZE;
  91. index += 1)
  92. __raw_writeb((u8)index, index);
  93. /* Read and check the pattern */
  94. for (index = index_start;
  95. index < index_start + DDR_TEST_BURST_SIZE;
  96. index += 1) {
  97. value = __raw_readb(index);
  98. if (value != (u8)index) {
  99. printf("ddr_memory_test: Failed at address index = 0x%x value = 0x%x *(index) = 0x%x\n",
  100. index, value, __raw_readb(index));
  101. return -1;
  102. }
  103. }
  104. index_start += DDR_TEST_BURST_SIZE;
  105. if (index_start >= end_address)
  106. break;
  107. }
  108. puts("ddr memory test PASSED!\n");
  109. return 0;
  110. }
  111. static int ddr_memory_compare(u32 address1, u32 address2, u32 size)
  112. {
  113. u32 index, value, index2, value2;
  114. for (index = address1, index2 = address2;
  115. index < address1 + size;
  116. index += 4, index2 += 4) {
  117. value = __raw_readl(index);
  118. value2 = __raw_readl(index2);
  119. if (value != value2) {
  120. printf("ddr_memory_test: Compare failed at address = 0x%x value = 0x%x, address2 = 0x%x value2 = 0x%x\n",
  121. index, value, index2, value2);
  122. return -1;
  123. }
  124. }
  125. puts("ddr memory compare PASSED!\n");
  126. return 0;
  127. }
  128. static void ddr_check_ecc_status(void)
  129. {
  130. struct emif_reg_struct *emif = (struct emif_reg_struct *)EMIF1_BASE;
  131. u32 err_1b = readl(&emif->emif_1b_ecc_err_cnt);
  132. u32 int_status = readl(&emif->emif_irqstatus_raw_sys);
  133. int ecc_test = 0;
  134. char *env;
  135. env = env_get("ecc_test");
  136. if (env)
  137. ecc_test = simple_strtol(env, NULL, 0);
  138. puts("ECC test Status:\n");
  139. if (int_status & EMIF_INT_WR_ECC_ERR_SYS_MASK)
  140. puts("\tECC test: DDR ECC write error interrupted\n");
  141. if (int_status & EMIF_INT_TWOBIT_ECC_ERR_SYS_MASK)
  142. if (!ecc_test)
  143. panic("\tECC test: DDR ECC 2-bit error interrupted");
  144. if (int_status & EMIF_INT_ONEBIT_ECC_ERR_SYS_MASK)
  145. puts("\tECC test: DDR ECC 1-bit error interrupted\n");
  146. if (err_1b)
  147. printf("\tECC test: 1-bit ECC err count: 0x%x\n", err_1b);
  148. }
  149. static int ddr_memory_ecc_err(u32 addr, u32 ecc_err)
  150. {
  151. struct emif_reg_struct *emif = (struct emif_reg_struct *)EMIF1_BASE;
  152. u32 ecc_ctrl = readl(&emif->emif_ecc_ctrl_reg);
  153. u32 val1, val2, val3;
  154. debug("Disabling D-Cache before ECC test\n");
  155. dcache_disable();
  156. invalidate_dcache_all();
  157. puts("Testing DDR ECC:\n");
  158. puts("\tECC test: Disabling DDR ECC ...\n");
  159. writel(0, &emif->emif_ecc_ctrl_reg);
  160. val1 = readl(addr);
  161. val2 = val1 ^ ecc_err;
  162. writel(val2, addr);
  163. val3 = readl(addr);
  164. #ifdef CONFIG_ARCH_KEYSTONE
  165. ecc_ctrl = ECC_START_ADDR1 | (ECC_END_ADDR1 << 16);
  166. writel(ecc_ctrl, EMIF1_BASE + KS2_DDR3_ECC_ADDR_RANGE1_OFFSET);
  167. ddr3_enable_ecc(EMIF1_BASE, 1);
  168. #else
  169. writel(ecc_ctrl, &emif->emif_ecc_ctrl_reg);
  170. #endif
  171. printf("\tECC test: addr 0x%x, read data 0x%x, written data 0x%x, err pattern: 0x%x, read after write data 0x%x\n",
  172. addr, val1, val2, ecc_err, val3);
  173. puts("\tECC test: Enabled DDR ECC ...\n");
  174. val1 = readl(addr);
  175. printf("\tECC test: addr 0x%x, read data 0x%x\n", addr, val1);
  176. ddr_check_ecc_status();
  177. debug("Enabling D-cache back after ECC test\n");
  178. enable_caches();
  179. return 0;
  180. }
  181. static int is_addr_valid(u32 addr)
  182. {
  183. struct emif_reg_struct *emif = (struct emif_reg_struct *)EMIF1_BASE;
  184. u32 start_addr, end_addr, range, ecc_ctrl;
  185. #ifdef CONFIG_ARCH_KEYSTONE
  186. ecc_ctrl = EMIF_ECC_REG_ECC_ADDR_RGN_1_EN_MASK;
  187. range = ECC_START_ADDR1 | (ECC_END_ADDR1 << 16);
  188. #else
  189. ecc_ctrl = readl(&emif->emif_ecc_ctrl_reg);
  190. range = readl(&emif->emif_ecc_address_range_1);
  191. #endif
  192. /* Check in ecc address range 1 */
  193. if (ecc_ctrl & EMIF_ECC_REG_ECC_ADDR_RGN_1_EN_MASK) {
  194. start_addr = ((range & EMIF_ECC_REG_ECC_START_ADDR_MASK) << 16)
  195. + CONFIG_SYS_SDRAM_BASE;
  196. end_addr = (range & EMIF_ECC_REG_ECC_END_ADDR_MASK) + 0xFFFF +
  197. CONFIG_SYS_SDRAM_BASE;
  198. if ((addr >= start_addr) && (addr <= end_addr))
  199. /* addr within ecc address range 1 */
  200. return 1;
  201. }
  202. /* Check in ecc address range 2 */
  203. if (ecc_ctrl & EMIF_ECC_REG_ECC_ADDR_RGN_2_EN_MASK) {
  204. range = readl(&emif->emif_ecc_address_range_2);
  205. start_addr = ((range & EMIF_ECC_REG_ECC_START_ADDR_MASK) << 16)
  206. + CONFIG_SYS_SDRAM_BASE;
  207. end_addr = (range & EMIF_ECC_REG_ECC_END_ADDR_MASK) + 0xFFFF +
  208. CONFIG_SYS_SDRAM_BASE;
  209. if ((addr >= start_addr) && (addr <= end_addr))
  210. /* addr within ecc address range 2 */
  211. return 1;
  212. }
  213. return 0;
  214. }
  215. static int is_ecc_enabled(void)
  216. {
  217. struct emif_reg_struct *emif = (struct emif_reg_struct *)EMIF1_BASE;
  218. u32 ecc_ctrl = readl(&emif->emif_ecc_ctrl_reg);
  219. return (ecc_ctrl & EMIF_ECC_CTRL_REG_ECC_EN_MASK) &&
  220. (ecc_ctrl & EMIF_ECC_REG_RMW_EN_MASK);
  221. }
  222. static int do_ddr_test(cmd_tbl_t *cmdtp,
  223. int flag, int argc, char * const argv[])
  224. {
  225. u32 start_addr, end_addr, size, ecc_err;
  226. if ((argc == 4) && (strncmp(argv[1], "ecc_err", 8) == 0)) {
  227. if (!is_ecc_enabled()) {
  228. puts("ECC not enabled. Please Enable ECC any try again\n");
  229. return CMD_RET_FAILURE;
  230. }
  231. start_addr = simple_strtoul(argv[2], NULL, 16);
  232. ecc_err = simple_strtoul(argv[3], NULL, 16);
  233. if (!is_addr_valid(start_addr)) {
  234. puts("Invalid address. Please enter ECC supported address!\n");
  235. return CMD_RET_FAILURE;
  236. }
  237. ddr_memory_ecc_err(start_addr, ecc_err);
  238. return 0;
  239. }
  240. if (!(((argc == 4) && (strncmp(argv[1], "test", 5) == 0)) ||
  241. ((argc == 5) && (strncmp(argv[1], "compare", 8) == 0))))
  242. return cmd_usage(cmdtp);
  243. start_addr = simple_strtoul(argv[2], NULL, 16);
  244. end_addr = simple_strtoul(argv[3], NULL, 16);
  245. if ((start_addr < CONFIG_SYS_SDRAM_BASE) ||
  246. (start_addr > (CONFIG_SYS_SDRAM_BASE +
  247. get_effective_memsize() - 1)) ||
  248. (end_addr < CONFIG_SYS_SDRAM_BASE) ||
  249. (end_addr > (CONFIG_SYS_SDRAM_BASE +
  250. get_effective_memsize() - 1)) || (start_addr >= end_addr)) {
  251. puts("Invalid start or end address!\n");
  252. return cmd_usage(cmdtp);
  253. }
  254. puts("Please wait ...\n");
  255. if (argc == 5) {
  256. size = simple_strtoul(argv[4], NULL, 16);
  257. ddr_memory_compare(start_addr, end_addr, size);
  258. } else {
  259. ddr_memory_test(start_addr, end_addr, 0);
  260. }
  261. return 0;
  262. }
  263. U_BOOT_CMD(ddr, 5, 1, do_ddr_test,
  264. "DDR3 test",
  265. "test <start_addr in hex> <end_addr in hex> - test DDR from start\n"
  266. " address to end address\n"
  267. "ddr compare <start_addr in hex> <end_addr in hex> <size in hex> -\n"
  268. " compare DDR data of (size) bytes from start address to end\n"
  269. " address\n"
  270. "ddr ecc_err <addr in hex> <bit_err in hex> - generate bit errors\n"
  271. " in DDR data at <addr>, the command will read a 32-bit data\n"
  272. " from <addr>, and write (data ^ bit_err) back to <addr>\n"
  273. );