fpga.c 9.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409
  1. /*
  2. * (C) Copyright 2006
  3. * Wolfgang Wegner, ASTRO Strobel Kommunikationssysteme GmbH,
  4. * w.wegner@astro-kom.de
  5. *
  6. * based on the files by
  7. * Heiko Schocher, DENX Software Engineering, hs@denx.de
  8. * and
  9. * Rich Ireland, Enterasys Networks, rireland@enterasys.com.
  10. * Keith Outwater, keith_outwater@mvis.com.
  11. *
  12. * SPDX-License-Identifier: GPL-2.0+
  13. */
  14. /* Altera/Xilinx FPGA configuration support for the ASTRO "URMEL" board */
  15. #include <common.h>
  16. #include <watchdog.h>
  17. #include <altera.h>
  18. #include <ACEX1K.h>
  19. #include <spartan3.h>
  20. #include <command.h>
  21. #include <asm/immap_5329.h>
  22. #include <asm/io.h>
  23. #include "fpga.h"
  24. DECLARE_GLOBAL_DATA_PTR;
  25. int altera_pre_fn(int cookie)
  26. {
  27. gpio_t *gpiop = (gpio_t *)MMAP_GPIO;
  28. unsigned char tmp_char;
  29. unsigned short tmp_short;
  30. /* first, set the required pins to GPIO function */
  31. /* PAR_T0IN -> GPIO */
  32. tmp_char = readb(&gpiop->par_timer);
  33. tmp_char &= 0xfc;
  34. writeb(tmp_char, &gpiop->par_timer);
  35. /* all QSPI pins -> GPIO */
  36. writew(0x0000, &gpiop->par_qspi);
  37. /* U0RTS, U0CTS -> GPIO */
  38. tmp_short = __raw_readw(&gpiop->par_uart);
  39. tmp_short &= 0xfff3;
  40. __raw_writew(tmp_short, &gpiop->par_uart);
  41. /* all PWM pins -> GPIO */
  42. writeb(0x00, &gpiop->par_pwm);
  43. /* next, set data direction registers */
  44. writeb(0x01, &gpiop->pddr_timer);
  45. writeb(0x25, &gpiop->pddr_qspi);
  46. writeb(0x0c, &gpiop->pddr_uart);
  47. writeb(0x04, &gpiop->pddr_pwm);
  48. /* ensure other SPI peripherals are deselected */
  49. writeb(0x08, &gpiop->ppd_uart);
  50. writeb(0x38, &gpiop->ppd_qspi);
  51. /* CONFIG = 0 STATUS = 0 -> FPGA in reset state */
  52. writeb(0xFB, &gpiop->pclrr_uart);
  53. /* enable Altera configuration by clearing QSPI_CS2 and DT0IN */
  54. writeb(0xFE, &gpiop->pclrr_timer);
  55. writeb(0xDF, &gpiop->pclrr_qspi);
  56. return FPGA_SUCCESS;
  57. }
  58. /* Set the state of CONFIG Pin */
  59. int altera_config_fn(int assert_config, int flush, int cookie)
  60. {
  61. gpio_t *gpiop = (gpio_t *)MMAP_GPIO;
  62. if (assert_config)
  63. writeb(0x04, &gpiop->ppd_uart);
  64. else
  65. writeb(0xFB, &gpiop->pclrr_uart);
  66. return FPGA_SUCCESS;
  67. }
  68. /* Returns the state of STATUS Pin */
  69. int altera_status_fn(int cookie)
  70. {
  71. gpio_t *gpiop = (gpio_t *)MMAP_GPIO;
  72. if (readb(&gpiop->ppd_pwm) & 0x08)
  73. return FPGA_FAIL;
  74. return FPGA_SUCCESS;
  75. }
  76. /* Returns the state of CONF_DONE Pin */
  77. int altera_done_fn(int cookie)
  78. {
  79. gpio_t *gpiop = (gpio_t *)MMAP_GPIO;
  80. if (readb(&gpiop->ppd_pwm) & 0x20)
  81. return FPGA_FAIL;
  82. return FPGA_SUCCESS;
  83. }
  84. /*
  85. * writes the complete buffer to the FPGA
  86. * writing the complete buffer in one function is much faster,
  87. * then calling it for every bit
  88. */
  89. int altera_write_fn(const void *buf, size_t len, int flush, int cookie)
  90. {
  91. size_t bytecount = 0;
  92. gpio_t *gpiop = (gpio_t *)MMAP_GPIO;
  93. unsigned char *data = (unsigned char *)buf;
  94. unsigned char val = 0;
  95. int i;
  96. int len_40 = len / 40;
  97. while (bytecount < len) {
  98. val = data[bytecount++];
  99. i = 8;
  100. do {
  101. writeb(0xFB, &gpiop->pclrr_qspi);
  102. if (val & 0x01)
  103. writeb(0x01, &gpiop->ppd_qspi);
  104. else
  105. writeb(0xFE, &gpiop->pclrr_qspi);
  106. writeb(0x04, &gpiop->ppd_qspi);
  107. val >>= 1;
  108. i--;
  109. } while (i > 0);
  110. if (bytecount % len_40 == 0) {
  111. #if defined(CONFIG_HW_WATCHDOG) || defined(CONFIG_WATCHDOG)
  112. WATCHDOG_RESET();
  113. #endif
  114. #ifdef CONFIG_SYS_FPGA_PROG_FEEDBACK
  115. putc('.'); /* let them know we are alive */
  116. #endif
  117. #ifdef CONFIG_SYS_FPGA_CHECK_CTRLC
  118. if (ctrlc())
  119. return FPGA_FAIL;
  120. #endif
  121. }
  122. }
  123. return FPGA_SUCCESS;
  124. }
  125. /* called, when programming is aborted */
  126. int altera_abort_fn(int cookie)
  127. {
  128. gpio_t *gpiop = (gpio_t *)MMAP_GPIO;
  129. writeb(0x20, &gpiop->ppd_qspi);
  130. writeb(0x08, &gpiop->ppd_uart);
  131. return FPGA_SUCCESS;
  132. }
  133. /* called, when programming was succesful */
  134. int altera_post_fn(int cookie)
  135. {
  136. return altera_abort_fn(cookie);
  137. }
  138. /*
  139. * Note that these are pointers to code that is in Flash. They will be
  140. * relocated at runtime.
  141. * FIXME: relocation not yet working for coldfire, see below!
  142. */
  143. Altera_CYC2_Passive_Serial_fns altera_fns = {
  144. altera_pre_fn,
  145. altera_config_fn,
  146. altera_status_fn,
  147. altera_done_fn,
  148. altera_write_fn,
  149. altera_abort_fn,
  150. altera_post_fn
  151. };
  152. Altera_desc altera_fpga[CONFIG_FPGA_COUNT] = {
  153. {Altera_CYC2,
  154. passive_serial,
  155. 85903,
  156. (void *)&altera_fns,
  157. NULL,
  158. 0}
  159. };
  160. /* Initialize the fpga. Return 1 on success, 0 on failure. */
  161. int astro5373l_altera_load(void)
  162. {
  163. int i;
  164. for (i = 0; i < CONFIG_FPGA_COUNT; i++) {
  165. /*
  166. * I did not yet manage to get relocation work properly,
  167. * so set stuff here instead of static initialisation:
  168. */
  169. altera_fns.pre = altera_pre_fn;
  170. altera_fns.config = altera_config_fn;
  171. altera_fns.status = altera_status_fn;
  172. altera_fns.done = altera_done_fn;
  173. altera_fns.write = altera_write_fn;
  174. altera_fns.abort = altera_abort_fn;
  175. altera_fns.post = altera_post_fn;
  176. altera_fpga[i].iface_fns = (void *)&altera_fns;
  177. fpga_add(fpga_altera, &altera_fpga[i]);
  178. }
  179. return 1;
  180. }
  181. /* Set the FPGA's PROG_B line to the specified level */
  182. int xilinx_pgm_config_fn(int assert, int flush, int cookie)
  183. {
  184. gpio_t *gpiop = (gpio_t *)MMAP_GPIO;
  185. if (assert)
  186. writeb(0xFB, &gpiop->pclrr_uart);
  187. else
  188. writeb(0x04, &gpiop->ppd_uart);
  189. return assert;
  190. }
  191. /*
  192. * Test the state of the active-low FPGA INIT line. Return 1 on INIT
  193. * asserted (low).
  194. */
  195. int xilinx_init_config_fn(int cookie)
  196. {
  197. gpio_t *gpiop = (gpio_t *)MMAP_GPIO;
  198. return (readb(&gpiop->ppd_pwm) & 0x08) == 0;
  199. }
  200. /* Test the state of the active-high FPGA DONE pin */
  201. int xilinx_done_config_fn(int cookie)
  202. {
  203. gpio_t *gpiop = (gpio_t *)MMAP_GPIO;
  204. return (readb(&gpiop->ppd_pwm) & 0x20) >> 5;
  205. }
  206. /* Abort an FPGA operation */
  207. int xilinx_abort_config_fn(int cookie)
  208. {
  209. gpio_t *gpiop = (gpio_t *)MMAP_GPIO;
  210. /* ensure all SPI peripherals and FPGAs are deselected */
  211. writeb(0x08, &gpiop->ppd_uart);
  212. writeb(0x01, &gpiop->ppd_timer);
  213. writeb(0x38, &gpiop->ppd_qspi);
  214. return FPGA_FAIL;
  215. }
  216. /*
  217. * FPGA pre-configuration function. Just make sure that
  218. * FPGA reset is asserted to keep the FPGA from starting up after
  219. * configuration.
  220. */
  221. int xilinx_pre_config_fn(int cookie)
  222. {
  223. gpio_t *gpiop = (gpio_t *)MMAP_GPIO;
  224. unsigned char tmp_char;
  225. unsigned short tmp_short;
  226. /* first, set the required pins to GPIO function */
  227. /* PAR_T0IN -> GPIO */
  228. tmp_char = readb(&gpiop->par_timer);
  229. tmp_char &= 0xfc;
  230. writeb(tmp_char, &gpiop->par_timer);
  231. /* all QSPI pins -> GPIO */
  232. writew(0x0000, &gpiop->par_qspi);
  233. /* U0RTS, U0CTS -> GPIO */
  234. tmp_short = __raw_readw(&gpiop->par_uart);
  235. tmp_short &= 0xfff3;
  236. __raw_writew(tmp_short, &gpiop->par_uart);
  237. /* all PWM pins -> GPIO */
  238. writeb(0x00, &gpiop->par_pwm);
  239. /* next, set data direction registers */
  240. writeb(0x01, &gpiop->pddr_timer);
  241. writeb(0x25, &gpiop->pddr_qspi);
  242. writeb(0x0c, &gpiop->pddr_uart);
  243. writeb(0x04, &gpiop->pddr_pwm);
  244. /* ensure other SPI peripherals are deselected */
  245. writeb(0x08, &gpiop->ppd_uart);
  246. writeb(0x38, &gpiop->ppd_qspi);
  247. writeb(0x01, &gpiop->ppd_timer);
  248. /* CONFIG = 0, STATUS = 0 -> FPGA in reset state */
  249. writeb(0xFB, &gpiop->pclrr_uart);
  250. /* enable Xilinx configuration by clearing QSPI_CS2 and U0CTS */
  251. writeb(0xF7, &gpiop->pclrr_uart);
  252. writeb(0xDF, &gpiop->pclrr_qspi);
  253. return 0;
  254. }
  255. /*
  256. * FPGA post configuration function. Should perform a test if FPGA is running.
  257. */
  258. int xilinx_post_config_fn(int cookie)
  259. {
  260. int rc = 0;
  261. /*
  262. * no test yet
  263. */
  264. return rc;
  265. }
  266. int xilinx_clk_config_fn(int assert_clk, int flush, int cookie)
  267. {
  268. gpio_t *gpiop = (gpio_t *)MMAP_GPIO;
  269. if (assert_clk)
  270. writeb(0x04, &gpiop->ppd_qspi);
  271. else
  272. writeb(0xFB, &gpiop->pclrr_qspi);
  273. return assert_clk;
  274. }
  275. int xilinx_wr_config_fn(int assert_write, int flush, int cookie)
  276. {
  277. gpio_t *gpiop = (gpio_t *)MMAP_GPIO;
  278. if (assert_write)
  279. writeb(0x01, &gpiop->ppd_qspi);
  280. else
  281. writeb(0xFE, &gpiop->pclrr_qspi);
  282. return assert_write;
  283. }
  284. int xilinx_fastwr_config_fn(void *buf, size_t len, int flush, int cookie)
  285. {
  286. size_t bytecount = 0;
  287. gpio_t *gpiop = (gpio_t *)MMAP_GPIO;
  288. unsigned char *data = (unsigned char *)buf;
  289. unsigned char val = 0;
  290. int i;
  291. int len_40 = len / 40;
  292. for (bytecount = 0; bytecount < len; bytecount++) {
  293. val = *(data++);
  294. for (i = 8; i > 0; i--) {
  295. writeb(0xFB, &gpiop->pclrr_qspi);
  296. if (val & 0x80)
  297. writeb(0x01, &gpiop->ppd_qspi);
  298. else
  299. writeb(0xFE, &gpiop->pclrr_qspi);
  300. writeb(0x04, &gpiop->ppd_qspi);
  301. val <<= 1;
  302. }
  303. if (bytecount % len_40 == 0) {
  304. #if defined(CONFIG_HW_WATCHDOG) || defined(CONFIG_WATCHDOG)
  305. WATCHDOG_RESET();
  306. #endif
  307. #ifdef CONFIG_SYS_FPGA_PROG_FEEDBACK
  308. putc('.'); /* let them know we are alive */
  309. #endif
  310. #ifdef CONFIG_SYS_FPGA_CHECK_CTRLC
  311. if (ctrlc())
  312. return FPGA_FAIL;
  313. #endif
  314. }
  315. }
  316. return FPGA_SUCCESS;
  317. }
  318. /*
  319. * Note that these are pointers to code that is in Flash. They will be
  320. * relocated at runtime.
  321. * FIXME: relocation not yet working for coldfire, see below!
  322. */
  323. xilinx_spartan3_slave_serial_fns xilinx_fns = {
  324. xilinx_pre_config_fn,
  325. xilinx_pgm_config_fn,
  326. xilinx_clk_config_fn,
  327. xilinx_init_config_fn,
  328. xilinx_done_config_fn,
  329. xilinx_wr_config_fn,
  330. 0,
  331. xilinx_fastwr_config_fn
  332. };
  333. xilinx_desc xilinx_fpga[CONFIG_FPGA_COUNT] = {
  334. {xilinx_spartan3,
  335. slave_serial,
  336. XILINX_XC3S4000_SIZE,
  337. (void *)&xilinx_fns,
  338. 0,
  339. &spartan3_op}
  340. };
  341. /* Initialize the fpga. Return 1 on success, 0 on failure. */
  342. int astro5373l_xilinx_load(void)
  343. {
  344. int i;
  345. fpga_init();
  346. for (i = 0; i < CONFIG_FPGA_COUNT; i++) {
  347. /*
  348. * I did not yet manage to get relocation work properly,
  349. * so set stuff here instead of static initialisation:
  350. */
  351. xilinx_fns.pre = xilinx_pre_config_fn;
  352. xilinx_fns.pgm = xilinx_pgm_config_fn;
  353. xilinx_fns.clk = xilinx_clk_config_fn;
  354. xilinx_fns.init = xilinx_init_config_fn;
  355. xilinx_fns.done = xilinx_done_config_fn;
  356. xilinx_fns.wr = xilinx_wr_config_fn;
  357. xilinx_fns.bwr = xilinx_fastwr_config_fn;
  358. xilinx_fpga[i].iface_fns = (void *)&xilinx_fns;
  359. fpga_add(fpga_xilinx, &xilinx_fpga[i]);
  360. }
  361. return 1;
  362. }