fpga.c 8.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358
  1. /*
  2. * (C) Copyright 2002
  3. * Wolfgang Grandegger, DENX Software Engineering, wg@denx.de.
  4. *
  5. * See file CREDITS for list of people who contributed to this
  6. * project.
  7. *
  8. * This program is free software; you can redistribute it and/or
  9. * modify it under the terms of the GNU General Public License as
  10. * published by the Free Software Foundation; either version 2 of
  11. * the License, or (at your option) any later version.
  12. *
  13. * This program is distributed in the hope that it will be useful,
  14. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  15. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  16. * GNU General Public License for more details.
  17. *
  18. * You should have received a copy of the GNU General Public License
  19. * along with this program; if not, write to the Free Software
  20. * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
  21. * MA 02111-1307 USA
  22. */
  23. #include <common.h>
  24. #include <command.h>
  25. #include <linux/ctype.h>
  26. #include <common.h>
  27. #include <cmd_boot.h>
  28. #include <cmd_bsp.h>
  29. #include "fpga.h"
  30. int power_on_reset(void);
  31. /* . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */
  32. static int fpga_get_version(fpga_t* fpga, char* name)
  33. {
  34. char vname[12];
  35. /*
  36. * Net-list string format:
  37. * "vvvvvvvvddddddddn...".
  38. * Version Date Name
  39. * "0000000322042002PUMA" = PUMA version 3 from 22.04.2002.
  40. */
  41. if (strlen(name) < (16 + strlen(fpga->name)))
  42. goto failure;
  43. /* Check FPGA name */
  44. if (strcmp(&name[16], fpga->name) != 0)
  45. goto failure;
  46. /* Get version number */
  47. memcpy(vname, name, 8);
  48. vname[8] = '\0';
  49. return simple_strtoul(vname, NULL, 16);
  50. failure:
  51. printf("Image name %s is invalid\n", name);
  52. return -1;
  53. }
  54. /* . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */
  55. static fpga_t* fpga_get(char* fpga_name)
  56. {
  57. char name[FPGA_NAME_LEN];
  58. int i;
  59. if (strlen(fpga_name) >= FPGA_NAME_LEN)
  60. goto failure;
  61. for (i = 0; i < strlen(fpga_name); i++)
  62. name[i] = toupper(fpga_name[i]);
  63. name[i] = '\0';
  64. for (i = 0; i < fpga_count; i++) {
  65. if (strcmp(name, fpga_list[i].name) == 0)
  66. return &fpga_list[i];
  67. }
  68. failure:
  69. printf("FPGA: name %s is invalid\n", fpga_name);
  70. return NULL;
  71. }
  72. /* . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */
  73. static void fpga_status (fpga_t* fpga)
  74. {
  75. /* Check state */
  76. if (fpga_control(fpga, FPGA_DONE_IS_HIGH))
  77. printf ("%s is loaded (%08lx)\n",
  78. fpga->name, fpga_control(fpga, FPGA_GET_ID));
  79. else
  80. printf ("%s is NOT loaded\n", fpga->name);
  81. }
  82. /* . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */
  83. #define FPGA_RESET_TIMEOUT 100 /* = 10 ms */
  84. static int fpga_reset (fpga_t* fpga)
  85. {
  86. int i;
  87. /* Set PROG to low and wait til INIT goes low */
  88. fpga_control(fpga, FPGA_PROG_SET_LOW);
  89. for (i = 0; i < FPGA_RESET_TIMEOUT; i++) {
  90. udelay (100);
  91. if (!fpga_control(fpga, FPGA_INIT_IS_HIGH))
  92. break;
  93. }
  94. if (i == FPGA_RESET_TIMEOUT)
  95. goto failure;
  96. /* Set PROG to high and wait til INIT goes high */
  97. fpga_control(fpga, FPGA_PROG_SET_HIGH);
  98. for (i = 0; i < FPGA_RESET_TIMEOUT; i++) {
  99. udelay (100);
  100. if (fpga_control(fpga, FPGA_INIT_IS_HIGH))
  101. break;
  102. }
  103. if (i == FPGA_RESET_TIMEOUT)
  104. goto failure;
  105. return 0;
  106. failure:
  107. return 1;
  108. }
  109. /* . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */
  110. #define FPGA_LOAD_TIMEOUT 100 /* = 10 ms */
  111. static int fpga_load (fpga_t* fpga, ulong addr, int checkall)
  112. {
  113. volatile uchar *fpga_addr = (volatile uchar *)fpga->conf_base;
  114. image_header_t hdr;
  115. ulong len, checksum;
  116. uchar *data = (uchar *)&hdr;
  117. char *s, msg[32];
  118. int verify, i;
  119. /*
  120. * Check the image header and data of the net-list
  121. */
  122. memcpy (&hdr, (char *)addr, sizeof(image_header_t));
  123. if (hdr.ih_magic != IH_MAGIC) {
  124. strcpy (msg, "Bad Image Magic Number");
  125. goto failure;
  126. }
  127. len = sizeof(image_header_t);
  128. checksum = hdr.ih_hcrc;
  129. hdr.ih_hcrc = 0;
  130. if (crc32 (0, data, len) != checksum) {
  131. strcpy (msg, "Bad Image Header CRC");
  132. goto failure;
  133. }
  134. data = (uchar*)(addr + sizeof(image_header_t));
  135. len = hdr.ih_size;
  136. s = getenv ("verify");
  137. verify = (s && (*s == 'n')) ? 0 : 1;
  138. if (verify) {
  139. if (crc32 (0, data, len) != hdr.ih_dcrc) {
  140. strcpy (msg, "Bad Image Data CRC");
  141. goto failure;
  142. }
  143. }
  144. if (checkall && fpga_get_version(fpga, hdr.ih_name) < 0)
  145. return 1;
  146. /* align length */
  147. if (len & 1)
  148. ++len;
  149. /*
  150. * Reset FPGA and wait for completion
  151. */
  152. if (fpga_reset(fpga)) {
  153. strcpy (msg, "Reset Timeout");
  154. goto failure;
  155. }
  156. printf ("(%s)... ", hdr.ih_name);
  157. /*
  158. * Copy data to FPGA
  159. */
  160. fpga_control (fpga, FPGA_LOAD_MODE);
  161. while (len--) {
  162. *fpga_addr = *data++;
  163. }
  164. fpga_control (fpga, FPGA_READ_MODE);
  165. /*
  166. * Wait for completion and check error status if timeout
  167. */
  168. for (i = 0; i < FPGA_LOAD_TIMEOUT; i++) {
  169. udelay (100);
  170. if (fpga_control (fpga, FPGA_DONE_IS_HIGH))
  171. break;
  172. }
  173. if (i == FPGA_LOAD_TIMEOUT) {
  174. if (fpga_control(fpga, FPGA_INIT_IS_HIGH))
  175. strcpy(msg, "Invalid Size");
  176. else
  177. strcpy(msg, "CRC Error");
  178. goto failure;
  179. }
  180. printf("done\n");
  181. return 0;
  182. failure:
  183. printf("ERROR: %s\n", msg);
  184. return 1;
  185. }
  186. #if (CONFIG_COMMANDS & CFG_CMD_BSP)
  187. /* . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */
  188. int do_fpga (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
  189. {
  190. ulong addr = 0;
  191. int i;
  192. fpga_t* fpga;
  193. if (argc < 2)
  194. goto failure;
  195. if (strncmp(argv[1], "stat", 4) == 0) { /* status */
  196. if (argc == 2) {
  197. for (i = 0; i < fpga_count; i++) {
  198. fpga_status (&fpga_list[i]);
  199. }
  200. }
  201. else if (argc == 3) {
  202. if ((fpga = fpga_get(argv[2])) == 0)
  203. goto failure;
  204. fpga_status (fpga);
  205. }
  206. else
  207. goto failure;
  208. }
  209. else if (strcmp(argv[1],"load") == 0) { /* load */
  210. if (argc == 3 && fpga_count == 1) {
  211. fpga = &fpga_list[0];
  212. }
  213. else if (argc == 4) {
  214. if ((fpga = fpga_get(argv[2])) == 0)
  215. goto failure;
  216. }
  217. else
  218. goto failure;
  219. addr = simple_strtoul(argv[argc-1], NULL, 16);
  220. printf ("FPGA load %s: addr %08lx: ",
  221. fpga->name, addr);
  222. fpga_load (fpga, addr, 1);
  223. }
  224. else if (strncmp(argv[1], "rese", 4) == 0) { /* reset */
  225. if (argc == 2 && fpga_count == 1) {
  226. fpga = &fpga_list[0];
  227. }
  228. else if (argc == 3) {
  229. if ((fpga = fpga_get(argv[2])) == 0)
  230. goto failure;
  231. }
  232. else
  233. goto failure;
  234. printf ("FPGA reset %s: ", fpga->name);
  235. if (fpga_reset(fpga))
  236. printf ("ERROR: Timeout\n");
  237. else
  238. printf ("done\n");
  239. }
  240. else
  241. goto failure;
  242. return 0;
  243. failure:
  244. printf ("Usage:\n%s\n", cmdtp->usage);
  245. return 1;
  246. }
  247. #endif /* CONFIG_COMMANDS & CFG_CMD_BSP */
  248. /* . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */
  249. int fpga_init (void)
  250. {
  251. ulong addr;
  252. ulong new_id, old_id = 0;
  253. image_header_t *hdr;
  254. fpga_t* fpga;
  255. int do_load, i, j;
  256. char name[16], *s;
  257. /*
  258. * Port setup for FPGA control
  259. */
  260. for (i = 0; i < fpga_count; i++) {
  261. fpga_control(&fpga_list[i], FPGA_INIT_PORTS);
  262. }
  263. /*
  264. * Load FPGA(s): a new net-list is loaded if the FPGA is
  265. * empty, Power-on-Reset or the old one is not up-to-date
  266. */
  267. for (i = 0; i < fpga_count; i++) {
  268. fpga = &fpga_list[i];
  269. printf ("%s: ", fpga->name);
  270. for (j = 0; j < strlen(fpga->name); j++)
  271. name[j] = tolower(fpga->name[j]);
  272. name[j] = '\0';
  273. sprintf(name, "%s_addr", name);
  274. addr = 0;
  275. if ((s = getenv(name)) != NULL)
  276. addr = simple_strtoul(s, NULL, 16);
  277. if (!addr) {
  278. printf ("env. variable %s undefined\n", name);
  279. return 1;
  280. }
  281. hdr = (image_header_t *)addr;
  282. if ((new_id = fpga_get_version(fpga, hdr->ih_name)) == -1)
  283. return 1;
  284. do_load = 1;
  285. if (!power_on_reset() && fpga_control(fpga, FPGA_DONE_IS_HIGH)) {
  286. old_id = fpga_control(fpga, FPGA_GET_ID);
  287. if (new_id == old_id)
  288. do_load = 0;
  289. }
  290. if (do_load) {
  291. printf ("loading ");
  292. fpga_load (fpga, addr, 0);
  293. } else {
  294. printf ("loaded (%08lx)\n", old_id);
  295. }
  296. }
  297. return 0;
  298. }