cmd_ddr3.c 6.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249
  1. /*
  2. * Keystone2: DDR3 test commands
  3. *
  4. * (C) Copyright 2012-2014
  5. * Texas Instruments Incorporated, <www.ti.com>
  6. *
  7. * SPDX-License-Identifier: GPL-2.0+
  8. */
  9. #include <asm/arch/hardware.h>
  10. #include <asm/arch/ddr3.h>
  11. #include <common.h>
  12. #include <command.h>
  13. DECLARE_GLOBAL_DATA_PTR;
  14. #define DDR_MIN_ADDR CONFIG_SYS_SDRAM_BASE
  15. #define STACKSIZE (512 << 10) /* 512 KiB */
  16. #define DDR_REMAP_ADDR 0x80000000
  17. #define ECC_START_ADDR1 ((DDR_MIN_ADDR - DDR_REMAP_ADDR) >> 17)
  18. #define ECC_END_ADDR1 (((gd->start_addr_sp - DDR_REMAP_ADDR - \
  19. STACKSIZE) >> 17) - 2)
  20. #define DDR_TEST_BURST_SIZE 1024
  21. static int ddr_memory_test(u32 start_address, u32 end_address, int quick)
  22. {
  23. u32 index_start, value, index;
  24. index_start = start_address;
  25. while (1) {
  26. /* Write a pattern */
  27. for (index = index_start;
  28. index < index_start + DDR_TEST_BURST_SIZE;
  29. index += 4)
  30. __raw_writel(index, index);
  31. /* Read and check the pattern */
  32. for (index = index_start;
  33. index < index_start + DDR_TEST_BURST_SIZE;
  34. index += 4) {
  35. value = __raw_readl(index);
  36. if (value != index) {
  37. printf("ddr_memory_test: Failed at address index = 0x%x value = 0x%x *(index) = 0x%x\n",
  38. index, value, __raw_readl(index));
  39. return -1;
  40. }
  41. }
  42. index_start += DDR_TEST_BURST_SIZE;
  43. if (index_start >= end_address)
  44. break;
  45. if (quick)
  46. continue;
  47. /* Write a pattern for complementary values */
  48. for (index = index_start;
  49. index < index_start + DDR_TEST_BURST_SIZE;
  50. index += 4)
  51. __raw_writel((u32)~index, index);
  52. /* Read and check the pattern */
  53. for (index = index_start;
  54. index < index_start + DDR_TEST_BURST_SIZE;
  55. index += 4) {
  56. value = __raw_readl(index);
  57. if (value != ~index) {
  58. printf("ddr_memory_test: Failed at address index = 0x%x value = 0x%x *(index) = 0x%x\n",
  59. index, value, __raw_readl(index));
  60. return -1;
  61. }
  62. }
  63. index_start += DDR_TEST_BURST_SIZE;
  64. if (index_start >= end_address)
  65. break;
  66. /* Write a pattern */
  67. for (index = index_start;
  68. index < index_start + DDR_TEST_BURST_SIZE;
  69. index += 2)
  70. __raw_writew((u16)index, index);
  71. /* Read and check the pattern */
  72. for (index = index_start;
  73. index < index_start + DDR_TEST_BURST_SIZE;
  74. index += 2) {
  75. value = __raw_readw(index);
  76. if (value != (u16)index) {
  77. printf("ddr_memory_test: Failed at address index = 0x%x value = 0x%x *(index) = 0x%x\n",
  78. index, value, __raw_readw(index));
  79. return -1;
  80. }
  81. }
  82. index_start += DDR_TEST_BURST_SIZE;
  83. if (index_start >= end_address)
  84. break;
  85. /* Write a pattern */
  86. for (index = index_start;
  87. index < index_start + DDR_TEST_BURST_SIZE;
  88. index += 1)
  89. __raw_writeb((u8)index, index);
  90. /* Read and check the pattern */
  91. for (index = index_start;
  92. index < index_start + DDR_TEST_BURST_SIZE;
  93. index += 1) {
  94. value = __raw_readb(index);
  95. if (value != (u8)index) {
  96. printf("ddr_memory_test: Failed at address index = 0x%x value = 0x%x *(index) = 0x%x\n",
  97. index, value, __raw_readb(index));
  98. return -1;
  99. }
  100. }
  101. index_start += DDR_TEST_BURST_SIZE;
  102. if (index_start >= end_address)
  103. break;
  104. }
  105. puts("ddr memory test PASSED!\n");
  106. return 0;
  107. }
  108. static int ddr_memory_compare(u32 address1, u32 address2, u32 size)
  109. {
  110. u32 index, value, index2, value2;
  111. for (index = address1, index2 = address2;
  112. index < address1 + size;
  113. index += 4, index2 += 4) {
  114. value = __raw_readl(index);
  115. value2 = __raw_readl(index2);
  116. if (value != value2) {
  117. printf("ddr_memory_test: Compare failed at address = 0x%x value = 0x%x, address2 = 0x%x value2 = 0x%x\n",
  118. index, value, index2, value2);
  119. return -1;
  120. }
  121. }
  122. puts("ddr memory compare PASSED!\n");
  123. return 0;
  124. }
  125. static int ddr_memory_ecc_err(u32 base, u32 address, u32 ecc_err)
  126. {
  127. u32 value1, value2, value3;
  128. puts("Disabling DDR ECC ...\n");
  129. ddr3_disable_ecc(base);
  130. value1 = __raw_readl(address);
  131. value2 = value1 ^ ecc_err;
  132. __raw_writel(value2, address);
  133. value3 = __raw_readl(address);
  134. printf("ECC err test, addr 0x%x, read data 0x%x, wrote data 0x%x, err pattern: 0x%x, read after write data 0x%x\n",
  135. address, value1, value2, ecc_err, value3);
  136. __raw_writel(ECC_START_ADDR1 | (ECC_END_ADDR1 << 16),
  137. base + KS2_DDR3_ECC_ADDR_RANGE1_OFFSET);
  138. puts("Enabling DDR ECC ...\n");
  139. ddr3_enable_ecc(base, 1);
  140. value1 = __raw_readl(address);
  141. printf("ECC err test, addr 0x%x, read data 0x%x\n", address, value1);
  142. ddr3_check_ecc_int(base);
  143. return 0;
  144. }
  145. static int do_ddr_test(cmd_tbl_t *cmdtp,
  146. int flag, int argc, char * const argv[])
  147. {
  148. u32 start_addr, end_addr, size, ecc_err;
  149. if ((argc == 4) && (strncmp(argv[1], "ecc_err", 8) == 0)) {
  150. if (!ddr3_ecc_support_rmw(KS2_DDR3A_EMIF_CTRL_BASE)) {
  151. puts("ECC RMW isn't supported for this SOC\n");
  152. return 1;
  153. }
  154. start_addr = simple_strtoul(argv[2], NULL, 16);
  155. ecc_err = simple_strtoul(argv[3], NULL, 16);
  156. if ((start_addr < CONFIG_SYS_SDRAM_BASE) ||
  157. (start_addr > (CONFIG_SYS_SDRAM_BASE +
  158. CONFIG_MAX_RAM_BANK_SIZE - 1))) {
  159. puts("Invalid address!\n");
  160. return cmd_usage(cmdtp);
  161. }
  162. ddr_memory_ecc_err(KS2_DDR3A_EMIF_CTRL_BASE,
  163. start_addr, ecc_err);
  164. return 0;
  165. }
  166. if (!(((argc == 4) && (strncmp(argv[1], "test", 5) == 0)) ||
  167. ((argc == 5) && (strncmp(argv[1], "compare", 8) == 0))))
  168. return cmd_usage(cmdtp);
  169. start_addr = simple_strtoul(argv[2], NULL, 16);
  170. end_addr = simple_strtoul(argv[3], NULL, 16);
  171. if ((start_addr < CONFIG_SYS_SDRAM_BASE) ||
  172. (start_addr > (CONFIG_SYS_SDRAM_BASE +
  173. CONFIG_MAX_RAM_BANK_SIZE - 1)) ||
  174. (end_addr < CONFIG_SYS_SDRAM_BASE) ||
  175. (end_addr > (CONFIG_SYS_SDRAM_BASE +
  176. CONFIG_MAX_RAM_BANK_SIZE - 1)) || (start_addr >= end_addr)) {
  177. puts("Invalid start or end address!\n");
  178. return cmd_usage(cmdtp);
  179. }
  180. puts("Please wait ...\n");
  181. if (argc == 5) {
  182. size = simple_strtoul(argv[4], NULL, 16);
  183. ddr_memory_compare(start_addr, end_addr, size);
  184. } else {
  185. ddr_memory_test(start_addr, end_addr, 0);
  186. }
  187. return 0;
  188. }
  189. U_BOOT_CMD(ddr, 5, 1, do_ddr_test,
  190. "DDR3 test",
  191. "test <start_addr in hex> <end_addr in hex> - test DDR from start\n"
  192. " address to end address\n"
  193. "ddr compare <start_addr in hex> <end_addr in hex> <size in hex> -\n"
  194. " compare DDR data of (size) bytes from start address to end\n"
  195. " address\n"
  196. "ddr ecc_err <addr in hex> <bit_err in hex> - generate bit errors\n"
  197. " in DDR data at <addr>, the command will read a 32-bit data\n"
  198. " from <addr>, and write (data ^ bit_err) back to <addr>\n"
  199. );