cmd_ddr3.c 6.4 KB

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