fpga.c 8.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446
  1. /*
  2. * (C) Copyright 2007
  3. * Matthias Fuchs, esd gmbh, matthias.fuchs@esd-electronics.com.
  4. *
  5. * SPDX-License-Identifier: GPL-2.0+
  6. */
  7. #include <common.h>
  8. #include <asm/io.h>
  9. #include <spartan2.h>
  10. #include <spartan3.h>
  11. #include <command.h>
  12. #include "fpga.h"
  13. #include "pmc440.h"
  14. DECLARE_GLOBAL_DATA_PTR;
  15. #if defined(CONFIG_FPGA)
  16. #define USE_SP_CODE
  17. #ifdef USE_SP_CODE
  18. xilinx_spartan3_slave_parallel_fns pmc440_fpga_fns = {
  19. fpga_pre_config_fn,
  20. fpga_pgm_fn,
  21. fpga_init_fn,
  22. NULL, /* err */
  23. fpga_done_fn,
  24. fpga_clk_fn,
  25. fpga_cs_fn,
  26. fpga_wr_fn,
  27. NULL, /* rdata */
  28. fpga_wdata_fn,
  29. fpga_busy_fn,
  30. fpga_abort_fn,
  31. fpga_post_config_fn,
  32. };
  33. #else
  34. xilinx_spartan3_slave_serial_fns pmc440_fpga_fns = {
  35. fpga_pre_config_fn,
  36. fpga_pgm_fn,
  37. fpga_clk_fn,
  38. fpga_init_fn,
  39. fpga_done_fn,
  40. fpga_wr_fn,
  41. fpga_post_config_fn,
  42. };
  43. #endif
  44. xilinx_spartan2_slave_serial_fns ngcc_fpga_fns = {
  45. ngcc_fpga_pre_config_fn,
  46. ngcc_fpga_pgm_fn,
  47. ngcc_fpga_clk_fn,
  48. ngcc_fpga_init_fn,
  49. ngcc_fpga_done_fn,
  50. ngcc_fpga_wr_fn,
  51. ngcc_fpga_post_config_fn
  52. };
  53. xilinx_desc fpga[CONFIG_FPGA_COUNT] = {
  54. XILINX_XC3S1200E_DESC(
  55. #ifdef USE_SP_CODE
  56. slave_parallel,
  57. #else
  58. slave_serial,
  59. #endif
  60. (void *)&pmc440_fpga_fns,
  61. 0),
  62. XILINX_XC2S200_DESC(
  63. slave_serial,
  64. (void *)&ngcc_fpga_fns,
  65. 0)
  66. };
  67. /*
  68. * Set the active-low FPGA reset signal.
  69. */
  70. void fpga_reset(int assert)
  71. {
  72. debug("%s:%d: RESET ", __FUNCTION__, __LINE__);
  73. if (assert) {
  74. out_be32((void*)GPIO1_OR, in_be32((void*)GPIO1_OR) & ~GPIO1_FPGA_DATA);
  75. debug("asserted\n");
  76. } else {
  77. out_be32((void*)GPIO1_OR, in_be32((void*)GPIO1_OR) | GPIO1_FPGA_DATA);
  78. debug("deasserted\n");
  79. }
  80. }
  81. /*
  82. * Initialize the SelectMap interface. We assume that the mode and the
  83. * initial state of all of the port pins have already been set!
  84. */
  85. void fpga_serialslave_init(void)
  86. {
  87. debug("%s:%d: Initialize serial slave interface\n", __FUNCTION__,
  88. __LINE__);
  89. fpga_pgm_fn(false, false, 0); /* make sure program pin is inactive */
  90. }
  91. /*
  92. * Set the FPGA's active-low SelectMap program line to the specified level
  93. */
  94. int fpga_pgm_fn(int assert, int flush, int cookie)
  95. {
  96. debug("%s:%d: FPGA PROGRAM ",
  97. __FUNCTION__, __LINE__);
  98. if (assert) {
  99. out_be32((void*)GPIO1_OR, in_be32((void*)GPIO1_OR) & ~GPIO1_FPGA_PRG);
  100. debug("asserted\n");
  101. } else {
  102. out_be32((void*)GPIO1_OR, in_be32((void*)GPIO1_OR) | GPIO1_FPGA_PRG);
  103. debug("deasserted\n");
  104. }
  105. return assert;
  106. }
  107. /*
  108. * Test the state of the active-low FPGA INIT line. Return 1 on INIT
  109. * asserted (low).
  110. */
  111. int fpga_init_fn(int cookie)
  112. {
  113. if (in_be32((void*)GPIO1_IR) & GPIO1_FPGA_INIT)
  114. return 0;
  115. else
  116. return 1;
  117. }
  118. #ifdef USE_SP_CODE
  119. int fpga_abort_fn(int cookie)
  120. {
  121. return 0;
  122. }
  123. int fpga_cs_fn(int assert_cs, int flush, int cookie)
  124. {
  125. return assert_cs;
  126. }
  127. int fpga_busy_fn(int cookie)
  128. {
  129. return 1;
  130. }
  131. #endif
  132. /*
  133. * Test the state of the active-high FPGA DONE pin
  134. */
  135. int fpga_done_fn(int cookie)
  136. {
  137. if (in_be32((void*)GPIO1_IR) & GPIO1_FPGA_DONE)
  138. return 1;
  139. else
  140. return 0;
  141. }
  142. /*
  143. * FPGA pre-configuration function. Just make sure that
  144. * FPGA reset is asserted to keep the FPGA from starting up after
  145. * configuration.
  146. */
  147. int fpga_pre_config_fn(int cookie)
  148. {
  149. debug("%s:%d: FPGA pre-configuration\n", __FUNCTION__, __LINE__);
  150. fpga_reset(true);
  151. /* release init# */
  152. out_be32((void*)GPIO0_OR, in_be32((void*)GPIO0_OR) | GPIO0_FPGA_FORCEINIT);
  153. /* disable PLD IOs */
  154. out_be32((void*)GPIO1_OR, in_be32((void*)GPIO1_OR) | GPIO1_IOEN_N);
  155. return 0;
  156. }
  157. /*
  158. * FPGA post configuration function. Blip the FPGA reset line and then see if
  159. * the FPGA appears to be running.
  160. */
  161. int fpga_post_config_fn(int cookie)
  162. {
  163. pmc440_fpga_t *fpga = (pmc440_fpga_t *)FPGA_BA;
  164. int rc=0;
  165. char *s;
  166. debug("%s:%d: FPGA post configuration\n", __FUNCTION__, __LINE__);
  167. /* enable PLD0..7 pins */
  168. out_be32((void*)GPIO1_OR, in_be32((void*)GPIO1_OR) & ~GPIO1_IOEN_N);
  169. fpga_reset(true);
  170. udelay (100);
  171. fpga_reset(false);
  172. udelay (100);
  173. FPGA_OUT32(&fpga->status, (gd->board_type << STATUS_HWREV_SHIFT) & STATUS_HWREV_MASK);
  174. /* NGCC/CANDES only: enable ledlink */
  175. if ((s = getenv("bd_type")) &&
  176. ((!strcmp(s, "ngcc")) || (!strcmp(s, "candes"))))
  177. FPGA_SETBITS(&fpga->ctrla, 0x29f8c000);
  178. return rc;
  179. }
  180. int fpga_clk_fn(int assert_clk, int flush, int cookie)
  181. {
  182. if (assert_clk)
  183. out_be32((void*)GPIO1_OR, in_be32((void*)GPIO1_OR) | GPIO1_FPGA_CLK);
  184. else
  185. out_be32((void*)GPIO1_OR, in_be32((void*)GPIO1_OR) & ~GPIO1_FPGA_CLK);
  186. return assert_clk;
  187. }
  188. int fpga_wr_fn(int assert_write, int flush, int cookie)
  189. {
  190. if (assert_write)
  191. out_be32((void*)GPIO1_OR, in_be32((void*)GPIO1_OR) | GPIO1_FPGA_DATA);
  192. else
  193. out_be32((void*)GPIO1_OR, in_be32((void*)GPIO1_OR) & ~GPIO1_FPGA_DATA);
  194. return assert_write;
  195. }
  196. #ifdef USE_SP_CODE
  197. int fpga_wdata_fn(uchar data, int flush, int cookie)
  198. {
  199. uchar val = data;
  200. ulong or = in_be32((void*)GPIO1_OR);
  201. int i = 7;
  202. do {
  203. /* Write data */
  204. if (val & 0x80)
  205. or = (or & ~GPIO1_FPGA_CLK) | GPIO1_FPGA_DATA;
  206. else
  207. or = or & ~(GPIO1_FPGA_CLK | GPIO1_FPGA_DATA);
  208. out_be32((void*)GPIO1_OR, or);
  209. /* Assert the clock */
  210. or |= GPIO1_FPGA_CLK;
  211. out_be32((void*)GPIO1_OR, or);
  212. val <<= 1;
  213. i --;
  214. } while (i > 0);
  215. /* Write last data bit (the 8th clock comes from the sp_load() code */
  216. if (val & 0x80)
  217. or = (or & ~GPIO1_FPGA_CLK) | GPIO1_FPGA_DATA;
  218. else
  219. or = or & ~(GPIO1_FPGA_CLK | GPIO1_FPGA_DATA);
  220. out_be32((void*)GPIO1_OR, or);
  221. return 0;
  222. }
  223. #endif
  224. #define NGCC_FPGA_PRG CLOCK_EN
  225. #define NGCC_FPGA_DATA RESET_OUT
  226. #define NGCC_FPGA_DONE CLOCK_IN
  227. #define NGCC_FPGA_INIT IRIGB_R_IN
  228. #define NGCC_FPGA_CLK CLOCK_OUT
  229. void ngcc_fpga_serialslave_init(void)
  230. {
  231. debug("%s:%d: Initialize serial slave interface\n",
  232. __FUNCTION__, __LINE__);
  233. /* make sure program pin is inactive */
  234. ngcc_fpga_pgm_fn(false, false, 0);
  235. }
  236. /*
  237. * Set the active-low FPGA reset signal.
  238. */
  239. void ngcc_fpga_reset(int assert)
  240. {
  241. debug("%s:%d: RESET ", __FUNCTION__, __LINE__);
  242. if (assert) {
  243. FPGA_CLRBITS(NGCC_CTRL_BASE, NGCC_CTRL_FPGARST_N);
  244. debug("asserted\n");
  245. } else {
  246. FPGA_SETBITS(NGCC_CTRL_BASE, NGCC_CTRL_FPGARST_N);
  247. debug("deasserted\n");
  248. }
  249. }
  250. /*
  251. * Set the FPGA's active-low SelectMap program line to the specified level
  252. */
  253. int ngcc_fpga_pgm_fn(int assert, int flush, int cookie)
  254. {
  255. pmc440_fpga_t *fpga = (pmc440_fpga_t *)FPGA_BA;
  256. debug("%s:%d: FPGA PROGRAM ", __FUNCTION__, __LINE__);
  257. if (assert) {
  258. FPGA_CLRBITS(&fpga->ctrla, NGCC_FPGA_PRG);
  259. debug("asserted\n");
  260. } else {
  261. FPGA_SETBITS(&fpga->ctrla, NGCC_FPGA_PRG);
  262. debug("deasserted\n");
  263. }
  264. return assert;
  265. }
  266. /*
  267. * Test the state of the active-low FPGA INIT line. Return 1 on INIT
  268. * asserted (low).
  269. */
  270. int ngcc_fpga_init_fn(int cookie)
  271. {
  272. pmc440_fpga_t *fpga = (pmc440_fpga_t *)FPGA_BA;
  273. debug("%s:%d: INIT check... ", __FUNCTION__, __LINE__);
  274. if (FPGA_IN32(&fpga->status) & NGCC_FPGA_INIT) {
  275. debug("high\n");
  276. return 0;
  277. } else {
  278. debug("low\n");
  279. return 1;
  280. }
  281. }
  282. /*
  283. * Test the state of the active-high FPGA DONE pin
  284. */
  285. int ngcc_fpga_done_fn(int cookie)
  286. {
  287. pmc440_fpga_t *fpga = (pmc440_fpga_t *)FPGA_BA;
  288. debug("%s:%d: DONE check... ", __FUNCTION__, __LINE__);
  289. if (FPGA_IN32(&fpga->status) & NGCC_FPGA_DONE) {
  290. debug("DONE high\n");
  291. return 1;
  292. } else {
  293. debug("low\n");
  294. return 0;
  295. }
  296. }
  297. /*
  298. * FPGA pre-configuration function.
  299. */
  300. int ngcc_fpga_pre_config_fn(int cookie)
  301. {
  302. pmc440_fpga_t *fpga = (pmc440_fpga_t *)FPGA_BA;
  303. debug("%s:%d: FPGA pre-configuration\n", __FUNCTION__, __LINE__);
  304. ngcc_fpga_reset(true);
  305. FPGA_CLRBITS(&fpga->ctrla, 0xfffffe00);
  306. ngcc_fpga_reset(true);
  307. return 0;
  308. }
  309. /*
  310. * FPGA post configuration function. Blip the FPGA reset line and then see if
  311. * the FPGA appears to be running.
  312. */
  313. int ngcc_fpga_post_config_fn(int cookie)
  314. {
  315. pmc440_fpga_t *fpga = (pmc440_fpga_t *)FPGA_BA;
  316. debug("%s:%d: NGCC FPGA post configuration\n", __FUNCTION__, __LINE__);
  317. udelay (100);
  318. ngcc_fpga_reset(false);
  319. FPGA_SETBITS(&fpga->ctrla, 0x29f8c000);
  320. return 0;
  321. }
  322. int ngcc_fpga_clk_fn(int assert_clk, int flush, int cookie)
  323. {
  324. pmc440_fpga_t *fpga = (pmc440_fpga_t *)FPGA_BA;
  325. if (assert_clk)
  326. FPGA_SETBITS(&fpga->ctrla, NGCC_FPGA_CLK);
  327. else
  328. FPGA_CLRBITS(&fpga->ctrla, NGCC_FPGA_CLK);
  329. return assert_clk;
  330. }
  331. int ngcc_fpga_wr_fn(int assert_write, int flush, int cookie)
  332. {
  333. pmc440_fpga_t *fpga = (pmc440_fpga_t *)FPGA_BA;
  334. if (assert_write)
  335. FPGA_SETBITS(&fpga->ctrla, NGCC_FPGA_DATA);
  336. else
  337. FPGA_CLRBITS(&fpga->ctrla, NGCC_FPGA_DATA);
  338. return assert_write;
  339. }
  340. /*
  341. * Initialize the fpga. Return 1 on success, 0 on failure.
  342. */
  343. int pmc440_init_fpga(void)
  344. {
  345. char *s;
  346. debug("%s:%d: Initialize FPGA interface\n",
  347. __FUNCTION__, __LINE__);
  348. fpga_init();
  349. fpga_serialslave_init ();
  350. debug("%s:%d: Adding fpga 0\n", __FUNCTION__, __LINE__);
  351. fpga_add (fpga_xilinx, &fpga[0]);
  352. /* NGCC only */
  353. if ((s = getenv("bd_type")) && !strcmp(s, "ngcc")) {
  354. ngcc_fpga_serialslave_init ();
  355. debug("%s:%d: Adding fpga 1\n", __FUNCTION__, __LINE__);
  356. fpga_add (fpga_xilinx, &fpga[1]);
  357. }
  358. return 0;
  359. }
  360. #endif /* CONFIG_FPGA */