fpga.c 7.6 KB

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