fpga.c 6.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344
  1. /*
  2. * (C) Copyright 2008 Dmitry Rakhchev, EmCraft Systems, rda@emcraft.com
  3. *
  4. * Developed for DENX Software Engineering GmbH
  5. *
  6. * SPDX-License-Identifier: GPL-2.0+
  7. */
  8. #include <common.h>
  9. /* This test performs testing of FPGA SCRATCH register,
  10. * gets FPGA version and run get_ram_size() on FPGA memory
  11. */
  12. #include <post.h>
  13. #include <watchdog.h>
  14. #include <asm/io.h>
  15. DECLARE_GLOBAL_DATA_PTR;
  16. #define FPGA_SCRATCH_REG 0xC4000050
  17. #define FPGA_VERSION_REG 0xC4000040
  18. #define FPGA_RAM_START 0xC4200000
  19. #define FPGA_RAM_END 0xC4203FFF
  20. #define FPGA_STAT 0xC400000C
  21. #define FPGA_BUFFER 0x00800000
  22. #define FPGA_RAM_SIZE (FPGA_RAM_END - FPGA_RAM_START + 1)
  23. #if CONFIG_POST & CONFIG_SYS_POST_BSPEC3
  24. const static unsigned long pattern[] = {
  25. 0xffffffff,
  26. 0xaaaaaaaa,
  27. 0xcccccccc,
  28. 0xf0f0f0f0,
  29. 0xff00ff00,
  30. 0xffff0000,
  31. 0x0000ffff,
  32. 0x00ff00ff,
  33. 0x0f0f0f0f,
  34. 0x33333333,
  35. 0x55555555,
  36. 0x00000000,
  37. };
  38. const static unsigned long otherpattern = 0x01234567;
  39. static int one_scratch_test(uint value)
  40. {
  41. uint read_value;
  42. int ret = 0;
  43. out_be32((void *)FPGA_SCRATCH_REG, value);
  44. /* read other location (protect against data lines capacity) */
  45. ret = in_be16((void *)FPGA_VERSION_REG);
  46. /* verify test pattern */
  47. read_value = in_be32((void *)FPGA_SCRATCH_REG);
  48. if (read_value != value) {
  49. post_log("FPGA SCRATCH test failed write %08X, read %08X\n",
  50. value, read_value);
  51. ret = -1;
  52. }
  53. return ret;
  54. }
  55. static int fpga_post_test1(ulong *start, ulong size, ulong val)
  56. {
  57. int ret = 0;
  58. ulong i = 0;
  59. ulong *mem = start;
  60. ulong readback;
  61. for (i = 0; i < size / sizeof(ulong); i++) {
  62. mem[i] = val;
  63. if (i % 1024 == 0)
  64. WATCHDOG_RESET();
  65. }
  66. for (i = 0; i < size / sizeof(ulong); i++) {
  67. readback = mem[i];
  68. if (readback != val) {
  69. post_log("FPGA Memory error at %08x, "
  70. "wrote %08x, read %08x !\n",
  71. mem + i, val, readback);
  72. ret = -1;
  73. break;
  74. }
  75. if (i % 1024 == 0)
  76. WATCHDOG_RESET();
  77. }
  78. return ret;
  79. }
  80. static int fpga_post_test2(ulong *start, ulong size)
  81. {
  82. int ret = 0;
  83. ulong i = 0;
  84. ulong *mem = start;
  85. ulong readback;
  86. for (i = 0; i < size / sizeof(ulong); i++) {
  87. mem[i] = 1 << (i % 32);
  88. if (i % 1024 == 0)
  89. WATCHDOG_RESET();
  90. }
  91. for (i = 0; i < size / sizeof(ulong); i++) {
  92. readback = mem[i];
  93. if (readback != 1 << (i % 32)) {
  94. post_log("FPGA Memory error at %08x, "
  95. "wrote %08x, read %08x !\n",
  96. mem + i, 1 << (i % 32), readback);
  97. ret = -1;
  98. break;
  99. }
  100. if (i % 1024 == 0)
  101. WATCHDOG_RESET();
  102. }
  103. return ret;
  104. }
  105. static int fpga_post_test3(ulong *start, ulong size)
  106. {
  107. int ret = 0;
  108. ulong i = 0;
  109. ulong *mem = start;
  110. ulong readback;
  111. for (i = 0; i < size / sizeof(ulong); i++) {
  112. mem[i] = i;
  113. if (i % 1024 == 0)
  114. WATCHDOG_RESET();
  115. }
  116. for (i = 0; i < size / sizeof(ulong); i++) {
  117. readback = mem[i];
  118. if (readback != i) {
  119. post_log("FPGA Memory error at %08x, "
  120. "wrote %08x, read %08x !\n",
  121. mem + i, i, readback);
  122. ret = -1;
  123. break;
  124. }
  125. if (i % 1024 == 0)
  126. WATCHDOG_RESET();
  127. }
  128. return ret;
  129. }
  130. static int fpga_post_test4(ulong *start, ulong size)
  131. {
  132. int ret = 0;
  133. ulong i = 0;
  134. ulong *mem = start;
  135. ulong readback;
  136. for (i = 0; i < size / sizeof(ulong); i++) {
  137. mem[i] = ~i;
  138. if (i % 1024 == 0)
  139. WATCHDOG_RESET();
  140. }
  141. for (i = 0; i < size / sizeof(ulong); i++) {
  142. readback = mem[i];
  143. if (readback != ~i) {
  144. post_log("FPGA Memory error at %08x, "
  145. "wrote %08x, read %08x !\n",
  146. mem + i, ~i, readback);
  147. ret = -1;
  148. break;
  149. }
  150. if (i % 1024 == 0)
  151. WATCHDOG_RESET();
  152. }
  153. return ret;
  154. }
  155. /* FPGA Memory-pattern-test */
  156. static int fpga_mem_test(void)
  157. {
  158. int ret = 0;
  159. ulong* start = (ulong *)FPGA_RAM_START;
  160. ulong size = FPGA_RAM_SIZE;
  161. if (ret == 0)
  162. ret = fpga_post_test1(start, size, 0x00000000);
  163. if (ret == 0)
  164. ret = fpga_post_test1(start, size, 0xffffffff);
  165. if (ret == 0)
  166. ret = fpga_post_test1(start, size, 0x55555555);
  167. if (ret == 0)
  168. ret = fpga_post_test1(start, size, 0xaaaaaaaa);
  169. WATCHDOG_RESET();
  170. if (ret == 0)
  171. ret = fpga_post_test2(start, size);
  172. if (ret == 0)
  173. ret = fpga_post_test3(start, size);
  174. if (ret == 0)
  175. ret = fpga_post_test4(start, size);
  176. return ret;
  177. }
  178. /* Verify FPGA addresslines */
  179. static int fpga_post_addrline(ulong *address, ulong *base, ulong size)
  180. {
  181. unsigned long *target;
  182. unsigned long *end;
  183. unsigned long readback;
  184. unsigned long xor;
  185. int ret = 0;
  186. end = (ulong *)((ulong)base + size);
  187. xor = 0;
  188. for (xor = sizeof(ulong); xor > 0; xor <<= 1) {
  189. target = (ulong*)((ulong)address ^ xor);
  190. if ((target >= base) && (target < end)) {
  191. *address = ~*target;
  192. readback = *target;
  193. if (readback == *address) {
  194. post_log("Memory (address line) error at %08x"
  195. "XOR value %08x !\n",
  196. address, target, xor);
  197. ret = -1;
  198. break;
  199. }
  200. }
  201. }
  202. return ret;
  203. }
  204. /* Verify FPGA addresslines */
  205. static int fpga_post_dataline(ulong *address)
  206. {
  207. unsigned long temp32 = 0;
  208. int i = 0;
  209. int ret = 0;
  210. for (i = 0; i < ARRAY_SIZE(pattern); i++) {
  211. *address = pattern[i];
  212. /*
  213. * Put a different pattern on the data lines: otherwise they
  214. * may float long enough to read back what we wrote.
  215. */
  216. *(address + 1) = otherpattern;
  217. temp32 = *address;
  218. if (temp32 != pattern[i]){
  219. post_log("Memory (date line) error at %08x, "
  220. "wrote %08x, read %08x !\n",
  221. address, pattern[i], temp32);
  222. ret = 1;
  223. }
  224. }
  225. return ret;
  226. }
  227. /* Verify FPGA, get version & memory size */
  228. int fpga_post_test(int flags)
  229. {
  230. uint old_value;
  231. uint version;
  232. uint read_value;
  233. int ret = 0;
  234. post_log("\n");
  235. old_value = in_be32((void *)FPGA_SCRATCH_REG);
  236. if (one_scratch_test(0x55555555))
  237. ret = 1;
  238. if (one_scratch_test(0xAAAAAAAA))
  239. ret = 1;
  240. out_be32((void *)FPGA_SCRATCH_REG, old_value);
  241. version = in_be32((void *)FPGA_VERSION_REG);
  242. post_log("FPGA version %u.%u\n",
  243. (version >> 8) & 0xFF, version & 0xFF);
  244. /* Enable write to FPGA RAM */
  245. out_be32((void *)FPGA_STAT, in_be32((void *)FPGA_STAT) | 0x1000);
  246. /* get RAM size */
  247. read_value = get_ram_size((void *)CONFIG_SYS_FPGA_BASE_1, FPGA_RAM_SIZE);
  248. post_log("FPGA RAM size %d bytes\n", read_value);
  249. WATCHDOG_RESET();
  250. /* copy fpga memory to DDR2 RAM*/
  251. memcpy((void *)FPGA_BUFFER,(void *)FPGA_RAM_START, FPGA_RAM_SIZE);
  252. WATCHDOG_RESET();
  253. /* Test datalines */
  254. if (fpga_post_dataline((ulong *)FPGA_RAM_START)) {
  255. ret = 1;
  256. goto out;
  257. }
  258. WATCHDOG_RESET();
  259. /* Test addresslines */
  260. if (fpga_post_addrline((ulong *)FPGA_RAM_START,
  261. (ulong *)FPGA_RAM_START, FPGA_RAM_SIZE)) {
  262. ret = 1;
  263. goto out;
  264. }
  265. WATCHDOG_RESET();
  266. if (fpga_post_addrline((ulong *)FPGA_RAM_END - sizeof(long),
  267. (ulong *)FPGA_RAM_START, FPGA_RAM_SIZE)) {
  268. ret = 1;
  269. goto out;
  270. }
  271. WATCHDOG_RESET();
  272. /* Memory Pattern Test */
  273. if (fpga_mem_test()) {
  274. ret = 1;
  275. goto out;
  276. }
  277. WATCHDOG_RESET();
  278. /* restore memory */
  279. memcpy((void *)FPGA_RAM_START,(void *)FPGA_BUFFER, FPGA_RAM_SIZE);
  280. WATCHDOG_RESET();
  281. out:
  282. /* Disable write to RAM */
  283. out_be32((void *)FPGA_STAT, in_be32((void *)FPGA_STAT) & 0xEFFF);
  284. return ret;
  285. }
  286. #endif /* CONFIG_POST & CONFIG_SYS_POST_BSPEC3 */