fpga_config.c 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253
  1. // SPDX-License-Identifier: GPL-2.0+
  2. /*
  3. * (C) Copyright 2012
  4. * Valentin Lontgchamp, Keymile AG, valentin.longchamp@keymile.com
  5. */
  6. #include <common.h>
  7. #include <i2c.h>
  8. #include <linux/delay.h>
  9. #include <linux/errno.h>
  10. /* GPIO Pin from kirkwood connected to PROGRAM_B pin of the xilinx FPGA */
  11. #define KM_XLX_PROGRAM_B_PIN 39
  12. #define BOCO_ADDR 0x10
  13. #define ID_REG 0x00
  14. #define BOCO2_ID 0x5b
  15. static int check_boco2(void)
  16. {
  17. int ret;
  18. u8 id;
  19. ret = i2c_read(BOCO_ADDR, ID_REG, 1, &id, 1);
  20. if (ret) {
  21. printf("%s: error reading the BOCO id !!\n", __func__);
  22. return ret;
  23. }
  24. return (id == BOCO2_ID);
  25. }
  26. static int boco_clear_bits(u8 reg, u8 flags)
  27. {
  28. int ret;
  29. u8 regval;
  30. /* give access to the EEPROM from FPGA */
  31. ret = i2c_read(BOCO_ADDR, reg, 1, &regval, 1);
  32. if (ret) {
  33. printf("%s: error reading the BOCO @%#x !!\n",
  34. __func__, reg);
  35. return ret;
  36. }
  37. regval &= ~flags;
  38. ret = i2c_write(BOCO_ADDR, reg, 1, &regval, 1);
  39. if (ret) {
  40. printf("%s: error writing the BOCO @%#x !!\n",
  41. __func__, reg);
  42. return ret;
  43. }
  44. return 0;
  45. }
  46. static int boco_set_bits(u8 reg, u8 flags)
  47. {
  48. int ret;
  49. u8 regval;
  50. /* give access to the EEPROM from FPGA */
  51. ret = i2c_read(BOCO_ADDR, reg, 1, &regval, 1);
  52. if (ret) {
  53. printf("%s: error reading the BOCO @%#x !!\n",
  54. __func__, reg);
  55. return ret;
  56. }
  57. regval |= flags;
  58. ret = i2c_write(BOCO_ADDR, reg, 1, &regval, 1);
  59. if (ret) {
  60. printf("%s: error writing the BOCO @%#x !!\n",
  61. __func__, reg);
  62. return ret;
  63. }
  64. return 0;
  65. }
  66. #define SPI_REG 0x06
  67. #define CFG_EEPROM 0x02
  68. #define FPGA_PROG 0x04
  69. #define FPGA_INIT_B 0x10
  70. #define FPGA_DONE 0x20
  71. #ifndef CONFIG_KM_FPGA_FORCE_CONFIG
  72. static int fpga_done(void)
  73. {
  74. int ret = 0;
  75. u8 regval;
  76. /* this is only supported with the boco2 design */
  77. if (!check_boco2())
  78. return 0;
  79. ret = i2c_read(BOCO_ADDR, SPI_REG, 1, &regval, 1);
  80. if (ret) {
  81. printf("%s: error reading the BOCO @%#x !!\n",
  82. __func__, SPI_REG);
  83. return 0;
  84. }
  85. return regval & FPGA_DONE ? 1 : 0;
  86. }
  87. #endif /* CONFIG_KM_FPGA_FORCE_CONFIG */
  88. static int skip;
  89. int trigger_fpga_config(void)
  90. {
  91. int ret = 0;
  92. skip = 0;
  93. #ifndef CONFIG_KM_FPGA_FORCE_CONFIG
  94. /* if the FPGA is already configured, we do not want to
  95. * reconfigure it */
  96. skip = 0;
  97. if (fpga_done()) {
  98. printf("PCIe FPGA config: skipped\n");
  99. skip = 1;
  100. return 0;
  101. }
  102. #endif /* CONFIG_KM_FPGA_FORCE_CONFIG */
  103. if (check_boco2()) {
  104. /* we have a BOCO2, this has to be triggered here */
  105. /* make sure the FPGA_can access the EEPROM */
  106. ret = boco_clear_bits(SPI_REG, CFG_EEPROM);
  107. if (ret)
  108. return ret;
  109. /* trigger the config start */
  110. ret = boco_clear_bits(SPI_REG, FPGA_PROG | FPGA_INIT_B);
  111. if (ret)
  112. return ret;
  113. /* small delay for the pulse */
  114. udelay(10);
  115. /* up signal for pulse end */
  116. ret = boco_set_bits(SPI_REG, FPGA_PROG);
  117. if (ret)
  118. return ret;
  119. /* finally, raise INIT_B to remove the config delay */
  120. ret = boco_set_bits(SPI_REG, FPGA_INIT_B);
  121. if (ret)
  122. return ret;
  123. } else {
  124. /* we do it the old way, with the gpio pin */
  125. kw_gpio_set_valid(KM_XLX_PROGRAM_B_PIN, 1);
  126. kw_gpio_direction_output(KM_XLX_PROGRAM_B_PIN, 0);
  127. /* small delay for the pulse */
  128. udelay(10);
  129. kw_gpio_direction_input(KM_XLX_PROGRAM_B_PIN);
  130. }
  131. return 0;
  132. }
  133. int wait_for_fpga_config(void)
  134. {
  135. int ret = 0;
  136. u8 spictrl;
  137. u32 timeout = 20000;
  138. if (skip)
  139. return 0;
  140. if (!check_boco2()) {
  141. /* we do not have BOCO2, this is not really used */
  142. return 0;
  143. }
  144. printf("PCIe FPGA config:");
  145. do {
  146. ret = i2c_read(BOCO_ADDR, SPI_REG, 1, &spictrl, 1);
  147. if (ret) {
  148. printf("%s: error reading the BOCO spictrl !!\n",
  149. __func__);
  150. return ret;
  151. }
  152. if (timeout-- == 0) {
  153. printf(" FPGA_DONE timeout\n");
  154. return -EFAULT;
  155. }
  156. udelay(10);
  157. } while (!(spictrl & FPGA_DONE));
  158. printf(" done\n");
  159. return 0;
  160. }
  161. #if defined(CONFIG_KM_FPGA_NO_RESET)
  162. int fpga_reset(void)
  163. {
  164. /* no dedicated reset pin for FPGA */
  165. return 0;
  166. }
  167. #else
  168. #define PRST1 0x4
  169. #define PCIE_RST 0x10
  170. #define TRAFFIC_RST 0x04
  171. int fpga_reset(void)
  172. {
  173. int ret = 0;
  174. u8 resets;
  175. if (!check_boco2()) {
  176. /* we do not have BOCO2, this is not really used */
  177. return 0;
  178. }
  179. /* if we have skipped, we only want to reset the PCIe part */
  180. resets = skip ? PCIE_RST : PCIE_RST | TRAFFIC_RST;
  181. ret = boco_clear_bits(PRST1, resets);
  182. if (ret)
  183. return ret;
  184. /* small delay for the pulse */
  185. udelay(10);
  186. ret = boco_set_bits(PRST1, resets);
  187. if (ret)
  188. return ret;
  189. return 0;
  190. }
  191. #endif
  192. /* the FPGA was configured, we configure the BOCO2 so that the EEPROM
  193. * is available from the Bobcat SPI bus */
  194. int toggle_eeprom_spi_bus(void)
  195. {
  196. int ret = 0;
  197. if (!check_boco2()) {
  198. /* we do not have BOCO2, this is not really used */
  199. return 0;
  200. }
  201. ret = boco_set_bits(SPI_REG, CFG_EEPROM);
  202. if (ret)
  203. return ret;
  204. return 0;
  205. }