ddr3.c 9.0 KB

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