fpga.c 8.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401
  1. /*
  2. * (C) Copyright 2002
  3. * Rich Ireland, Enterasys Networks, rireland@enterasys.com.
  4. * Keith Outwater, keith_outwater@mvis.com.
  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. */
  25. /*
  26. * Virtex2 FPGA configuration support for the GEN860T computer
  27. */
  28. #include <common.h>
  29. #include <virtex2.h>
  30. #include <command.h>
  31. #include "fpga.h"
  32. #if (CONFIG_FPGA)
  33. #if 0
  34. #define GEN860T_FPGA_DEBUG
  35. #endif
  36. #ifdef GEN860T_FPGA_DEBUG
  37. #define PRINTF(fmt,args...) printf (fmt ,##args)
  38. #else
  39. #define PRINTF(fmt,args...)
  40. #endif
  41. /*
  42. * Port bit numbers for the Selectmap controls
  43. */
  44. #define FPGA_INIT_BIT_NUM 22 /* PB22 */
  45. #define FPGA_RESET_BIT_NUM 11 /* PC11 */
  46. #define FPGA_DONE_BIT_NUM 16 /* PB16 */
  47. #define FPGA_PROGRAM_BIT_NUM 7 /* PA7 */
  48. /* Note that these are pointers to code that is in Flash. They will be
  49. * relocated at runtime.
  50. */
  51. Xilinx_Virtex2_Slave_SelectMap_fns fpga_fns = {
  52. fpga_pre_config_fn,
  53. fpga_pgm_fn,
  54. fpga_init_fn,
  55. fpga_err_fn,
  56. fpga_done_fn,
  57. fpga_clk_fn,
  58. fpga_cs_fn,
  59. fpga_wr_fn,
  60. fpga_read_data_fn,
  61. fpga_write_data_fn,
  62. fpga_busy_fn,
  63. fpga_abort_fn,
  64. fpga_post_config_fn
  65. };
  66. Xilinx_desc fpga[CONFIG_FPGA_COUNT] = {
  67. { Xilinx_Virtex2,
  68. slave_selectmap,
  69. XILINX_XC2V3000_SIZE,
  70. (void *)&fpga_fns,
  71. 0
  72. }
  73. };
  74. /*
  75. * Display FPGA revision information
  76. */
  77. void
  78. print_fpga_revision(void)
  79. {
  80. vu_long *rev_p = (vu_long *)0x60000008;
  81. printf("FPGA Revision 0x%.8lx"
  82. " (Date %.2lx/%.2lx/%.2lx, Status \"%.1lx\", Version %.3lu)\n",
  83. *rev_p,
  84. ((*rev_p >> 28) & 0xf),
  85. ((*rev_p >> 20) & 0xff),
  86. ((*rev_p >> 12) & 0xff),
  87. ((*rev_p >> 8) & 0xf),
  88. (*rev_p & 0xff));
  89. }
  90. /*
  91. * Perform a simple test of the FPGA to processor interface using the FPGA's
  92. * inverting bus test register. The great thing about doing a read/write
  93. * test on a register that inverts it's contents is that you avoid any
  94. * problems with bus charging.
  95. * Return 0 on failure, 1 on success.
  96. */
  97. int
  98. test_fpga_ibtr(void)
  99. {
  100. vu_long *ibtr_p = (vu_long *)0x60000010;
  101. vu_long readback;
  102. vu_long compare;
  103. int i;
  104. int j;
  105. int k;
  106. int pass = 1;
  107. static const ulong bitpattern[] = {
  108. 0xdeadbeef, /* magic ID pattern for debug */
  109. 0x00000001, /* single bit */
  110. 0x00000003, /* two adjacent bits */
  111. 0x00000007, /* three adjacent bits */
  112. 0x0000000F, /* four adjacent bits */
  113. 0x00000005, /* two non-adjacent bits */
  114. 0x00000015, /* three non-adjacent bits */
  115. 0x00000055, /* four non-adjacent bits */
  116. 0xaaaaaaaa, /* alternating 1/0 */
  117. };
  118. for (i = 0; i < 1024; i++) {
  119. for (j = 0; j < 31; j++) {
  120. for (k = 0; k < sizeof(bitpattern)/sizeof(bitpattern[0]); k++) {
  121. *ibtr_p = compare = (bitpattern[k] << j);
  122. readback = *ibtr_p;
  123. if (readback != ~compare) {
  124. printf("%s:%d: FPGA test fail: expected 0x%.8lx"
  125. " actual 0x%.8lx\n",
  126. __FUNCTION__, __LINE__, ~compare, readback);
  127. pass = 0;
  128. break;
  129. }
  130. }
  131. if (!pass) break;
  132. }
  133. if (!pass) break;
  134. }
  135. if (pass) {
  136. printf("FPGA inverting bus test passed\n");
  137. print_fpga_revision();
  138. }
  139. else {
  140. printf("** FPGA inverting bus test failed\n");
  141. }
  142. return pass;
  143. }
  144. /*
  145. * Set the active-low FPGA reset signal.
  146. */
  147. void
  148. fpga_reset(int assert)
  149. {
  150. volatile immap_t *immap = (immap_t *)CFG_IMMR;
  151. PRINTF("%s:%d: RESET ", __FUNCTION__, __LINE__);
  152. if (assert) {
  153. immap->im_ioport.iop_pcdat &= ~(0x8000 >> FPGA_RESET_BIT_NUM);
  154. PRINTF("asserted\n");
  155. }
  156. else {
  157. immap->im_ioport.iop_pcdat |= (0x8000 >> FPGA_RESET_BIT_NUM);
  158. PRINTF("deasserted\n");
  159. }
  160. }
  161. /*
  162. * Initialize the SelectMap interface. We assume that the mode and the
  163. * initial state of all of the port pins have already been set!
  164. */
  165. void
  166. fpga_selectmap_init(void)
  167. {
  168. PRINTF("%s:%d: Initialize SelectMap interface\n", __FUNCTION__, __LINE__);
  169. fpga_pgm_fn(FALSE, FALSE, 0); /* make sure program pin is inactive */
  170. }
  171. /*
  172. * Initialize the fpga. Return 1 on success, 0 on failure.
  173. */
  174. int
  175. gen860t_init_fpga(void)
  176. {
  177. DECLARE_GLOBAL_DATA_PTR;
  178. int i;
  179. PRINTF("%s:%d: Initialize FPGA interface (relocation offset = 0x%.8lx)\n",
  180. __FUNCTION__, __LINE__, gd->reloc_off);
  181. fpga_init(gd->reloc_off);
  182. fpga_selectmap_init();
  183. for(i=0; i < CONFIG_FPGA_COUNT; i++) {
  184. PRINTF("%s:%d: Adding fpga %d\n", __FUNCTION__, __LINE__, i);
  185. fpga_add(fpga_xilinx, &fpga[i]);
  186. }
  187. return 1;
  188. }
  189. /*
  190. * Set the FPGA's active-low SelectMap program line to the specified level
  191. */
  192. int
  193. fpga_pgm_fn(int assert, int flush, int cookie)
  194. {
  195. volatile immap_t *immap = (immap_t *)CFG_IMMR;
  196. PRINTF("%s:%d: FPGA PROGRAM ", __FUNCTION__, __LINE__);
  197. if (assert) {
  198. immap->im_ioport.iop_padat &= ~(0x8000 >> FPGA_PROGRAM_BIT_NUM);
  199. PRINTF("asserted\n");
  200. }
  201. else {
  202. immap->im_ioport.iop_padat |= (0x8000 >> FPGA_PROGRAM_BIT_NUM);
  203. PRINTF("deasserted\n");
  204. }
  205. return assert;
  206. }
  207. /*
  208. * Test the state of the active-low FPGA INIT line. Return 1 on INIT
  209. * asserted (low).
  210. */
  211. int
  212. fpga_init_fn(int cookie)
  213. {
  214. volatile immap_t *immap = (immap_t *)CFG_IMMR;
  215. PRINTF("%s:%d: INIT check... ", __FUNCTION__, __LINE__);
  216. if(immap->im_cpm.cp_pbdat & (0x80000000 >> FPGA_INIT_BIT_NUM)) {
  217. PRINTF("high\n");
  218. return 0;
  219. }
  220. else {
  221. PRINTF("low\n");
  222. return 1;
  223. }
  224. }
  225. /*
  226. * Test the state of the active-high FPGA DONE pin
  227. */
  228. int
  229. fpga_done_fn(int cookie)
  230. {
  231. volatile immap_t *immap = (immap_t *)CFG_IMMR;
  232. PRINTF("%s:%d: DONE check... ", __FUNCTION__, __LINE__);
  233. if (immap->im_cpm.cp_pbdat & (0x80000000 >> FPGA_DONE_BIT_NUM)) {
  234. PRINTF("high\n");
  235. return FPGA_SUCCESS;
  236. }
  237. else {
  238. PRINTF("low\n");
  239. return FPGA_FAIL;
  240. }
  241. }
  242. /*
  243. * Read FPGA SelectMap data.
  244. */
  245. int
  246. fpga_read_data_fn(unsigned char *data, int cookie)
  247. {
  248. vu_char *p = (vu_char *)SELECTMAP_BASE;
  249. *data = *p;
  250. #if 0
  251. PRINTF("%s: Read 0x%x into 0x%p\n", __FUNCTION__, (int)data, data);
  252. #endif
  253. return (int)data;
  254. }
  255. /*
  256. * Write data to the FPGA SelectMap port
  257. */
  258. int
  259. fpga_write_data_fn(unsigned char data, int flush, int cookie)
  260. {
  261. vu_char *p = (vu_char *)SELECTMAP_BASE;
  262. #if 0
  263. PRINTF("%s: Write Data 0x%x\n", __FUNCTION__, (int)data);
  264. #endif
  265. *p = data;
  266. return (int)data;
  267. }
  268. /*
  269. * Abort and FPGA operation
  270. */
  271. int
  272. fpga_abort_fn(int cookie)
  273. {
  274. PRINTF("%s:%d: FPGA program sequence aborted\n",
  275. __FUNCTION__, __LINE__);
  276. return FPGA_FAIL;
  277. }
  278. /*
  279. * FPGA pre-configuration function. Just make sure that
  280. * FPGA reset is asserted to keep the FPGA from starting up after
  281. * configuration.
  282. */
  283. int
  284. fpga_pre_config_fn(int cookie)
  285. {
  286. PRINTF("%s:%d: FPGA pre-configuration\n", __FUNCTION__, __LINE__);
  287. fpga_reset(TRUE);
  288. return 0;
  289. }
  290. /*
  291. * FPGA post configuration function. Blip the FPGA reset line and then see if
  292. * the FPGA appears to be running.
  293. */
  294. int
  295. fpga_post_config_fn(int cookie)
  296. {
  297. int rc;
  298. PRINTF("%s:%d: FPGA post configuration\n", __FUNCTION__, __LINE__);
  299. fpga_reset(TRUE);
  300. udelay(1000);
  301. fpga_reset(FALSE);
  302. udelay (1000);
  303. /*
  304. * Use the FPGA,s inverting bus test register to do a simple test of the
  305. * processor interface.
  306. */
  307. rc = test_fpga_ibtr();
  308. return rc;
  309. }
  310. /*
  311. * Clock, chip select and write signal assert functions and error check
  312. * and busy functions. These are only stubs because the GEN860T selectmap
  313. * interface handles sequencing of control signals automatically (it uses
  314. * a memory-mapped interface to the FPGA SelectMap port). The design of
  315. * the interface guarantees that the SelectMap port cannot be overrun so
  316. * no busy check is needed. A configuration error is signalled by INIT
  317. * going low during configuration, so there is no need for a separate error
  318. * function.
  319. */
  320. int
  321. fpga_clk_fn(int assert_clk, int flush, int cookie)
  322. {
  323. return assert_clk;
  324. }
  325. int
  326. fpga_cs_fn(int assert_cs, int flush, int cookie)
  327. {
  328. return assert_cs;
  329. }
  330. int
  331. fpga_wr_fn(int assert_write, int flush, int cookie)
  332. {
  333. return assert_write;
  334. }
  335. int
  336. fpga_err_fn(int cookie)
  337. {
  338. return 0;
  339. }
  340. int
  341. fpga_busy_fn(int cookie)
  342. {
  343. return 0;
  344. }
  345. #endif
  346. /* vim: set ts=4 tw=78 sw=4: */