socfpga_gen5.c 6.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252
  1. /*
  2. * Copyright (C) 2012 Altera Corporation <www.altera.com>
  3. * All rights reserved.
  4. *
  5. * SPDX-License-Identifier: BSD-3-Clause
  6. */
  7. #include <common.h>
  8. #include <asm/io.h>
  9. #include <linux/errno.h>
  10. #include <asm/arch/fpga_manager.h>
  11. #include <asm/arch/reset_manager.h>
  12. #include <asm/arch/system_manager.h>
  13. DECLARE_GLOBAL_DATA_PTR;
  14. #define FPGA_TIMEOUT_CNT 0x1000000
  15. static struct socfpga_fpga_manager *fpgamgr_regs =
  16. (struct socfpga_fpga_manager *)SOCFPGA_FPGAMGRREGS_ADDRESS;
  17. static struct socfpga_system_manager *sysmgr_regs =
  18. (struct socfpga_system_manager *)SOCFPGA_SYSMGR_ADDRESS;
  19. /* Set CD ratio */
  20. static void fpgamgr_set_cd_ratio(unsigned long ratio)
  21. {
  22. clrsetbits_le32(&fpgamgr_regs->ctrl,
  23. 0x3 << FPGAMGRREGS_CTRL_CDRATIO_LSB,
  24. (ratio & 0x3) << FPGAMGRREGS_CTRL_CDRATIO_LSB);
  25. }
  26. /* Start the FPGA programming by initialize the FPGA Manager */
  27. static int fpgamgr_program_init(void)
  28. {
  29. unsigned long msel, i;
  30. /* Get the MSEL value */
  31. msel = readl(&fpgamgr_regs->stat);
  32. msel &= FPGAMGRREGS_STAT_MSEL_MASK;
  33. msel >>= FPGAMGRREGS_STAT_MSEL_LSB;
  34. /*
  35. * Set the cfg width
  36. * If MSEL[3] = 1, cfg width = 32 bit
  37. */
  38. if (msel & 0x8) {
  39. setbits_le32(&fpgamgr_regs->ctrl,
  40. FPGAMGRREGS_CTRL_CFGWDTH_MASK);
  41. /* To determine the CD ratio */
  42. /* MSEL[1:0] = 0, CD Ratio = 1 */
  43. if ((msel & 0x3) == 0x0)
  44. fpgamgr_set_cd_ratio(CDRATIO_x1);
  45. /* MSEL[1:0] = 1, CD Ratio = 4 */
  46. else if ((msel & 0x3) == 0x1)
  47. fpgamgr_set_cd_ratio(CDRATIO_x4);
  48. /* MSEL[1:0] = 2, CD Ratio = 8 */
  49. else if ((msel & 0x3) == 0x2)
  50. fpgamgr_set_cd_ratio(CDRATIO_x8);
  51. } else { /* MSEL[3] = 0 */
  52. clrbits_le32(&fpgamgr_regs->ctrl,
  53. FPGAMGRREGS_CTRL_CFGWDTH_MASK);
  54. /* To determine the CD ratio */
  55. /* MSEL[1:0] = 0, CD Ratio = 1 */
  56. if ((msel & 0x3) == 0x0)
  57. fpgamgr_set_cd_ratio(CDRATIO_x1);
  58. /* MSEL[1:0] = 1, CD Ratio = 2 */
  59. else if ((msel & 0x3) == 0x1)
  60. fpgamgr_set_cd_ratio(CDRATIO_x2);
  61. /* MSEL[1:0] = 2, CD Ratio = 4 */
  62. else if ((msel & 0x3) == 0x2)
  63. fpgamgr_set_cd_ratio(CDRATIO_x4);
  64. }
  65. /* To enable FPGA Manager configuration */
  66. clrbits_le32(&fpgamgr_regs->ctrl, FPGAMGRREGS_CTRL_NCE_MASK);
  67. /* To enable FPGA Manager drive over configuration line */
  68. setbits_le32(&fpgamgr_regs->ctrl, FPGAMGRREGS_CTRL_EN_MASK);
  69. /* Put FPGA into reset phase */
  70. setbits_le32(&fpgamgr_regs->ctrl, FPGAMGRREGS_CTRL_NCONFIGPULL_MASK);
  71. /* (1) wait until FPGA enter reset phase */
  72. for (i = 0; i < FPGA_TIMEOUT_CNT; i++) {
  73. if (fpgamgr_get_mode() == FPGAMGRREGS_MODE_RESETPHASE)
  74. break;
  75. }
  76. /* If not in reset state, return error */
  77. if (fpgamgr_get_mode() != FPGAMGRREGS_MODE_RESETPHASE) {
  78. puts("FPGA: Could not reset\n");
  79. return -1;
  80. }
  81. /* Release FPGA from reset phase */
  82. clrbits_le32(&fpgamgr_regs->ctrl, FPGAMGRREGS_CTRL_NCONFIGPULL_MASK);
  83. /* (2) wait until FPGA enter configuration phase */
  84. for (i = 0; i < FPGA_TIMEOUT_CNT; i++) {
  85. if (fpgamgr_get_mode() == FPGAMGRREGS_MODE_CFGPHASE)
  86. break;
  87. }
  88. /* If not in configuration state, return error */
  89. if (fpgamgr_get_mode() != FPGAMGRREGS_MODE_CFGPHASE) {
  90. puts("FPGA: Could not configure\n");
  91. return -2;
  92. }
  93. /* Clear all interrupts in CB Monitor */
  94. writel(0xFFF, &fpgamgr_regs->gpio_porta_eoi);
  95. /* Enable AXI configuration */
  96. setbits_le32(&fpgamgr_regs->ctrl, FPGAMGRREGS_CTRL_AXICFGEN_MASK);
  97. return 0;
  98. }
  99. /* Ensure the FPGA entering config done */
  100. static int fpgamgr_program_poll_cd(void)
  101. {
  102. const uint32_t mask = FPGAMGRREGS_MON_GPIO_EXT_PORTA_NS_MASK |
  103. FPGAMGRREGS_MON_GPIO_EXT_PORTA_CD_MASK;
  104. unsigned long reg, i;
  105. /* (3) wait until full config done */
  106. for (i = 0; i < FPGA_TIMEOUT_CNT; i++) {
  107. reg = readl(&fpgamgr_regs->gpio_ext_porta);
  108. /* Config error */
  109. if (!(reg & mask)) {
  110. printf("FPGA: Configuration error.\n");
  111. return -3;
  112. }
  113. /* Config done without error */
  114. if (reg & mask)
  115. break;
  116. }
  117. /* Timeout happened, return error */
  118. if (i == FPGA_TIMEOUT_CNT) {
  119. printf("FPGA: Timeout waiting for program.\n");
  120. return -4;
  121. }
  122. /* Disable AXI configuration */
  123. clrbits_le32(&fpgamgr_regs->ctrl, FPGAMGRREGS_CTRL_AXICFGEN_MASK);
  124. return 0;
  125. }
  126. /* Ensure the FPGA entering init phase */
  127. static int fpgamgr_program_poll_initphase(void)
  128. {
  129. unsigned long i;
  130. /* Additional clocks for the CB to enter initialization phase */
  131. if (fpgamgr_dclkcnt_set(0x4))
  132. return -5;
  133. /* (4) wait until FPGA enter init phase or user mode */
  134. for (i = 0; i < FPGA_TIMEOUT_CNT; i++) {
  135. if (fpgamgr_get_mode() == FPGAMGRREGS_MODE_INITPHASE)
  136. break;
  137. if (fpgamgr_get_mode() == FPGAMGRREGS_MODE_USERMODE)
  138. break;
  139. }
  140. /* If not in configuration state, return error */
  141. if (i == FPGA_TIMEOUT_CNT)
  142. return -6;
  143. return 0;
  144. }
  145. /* Ensure the FPGA entering user mode */
  146. static int fpgamgr_program_poll_usermode(void)
  147. {
  148. unsigned long i;
  149. /* Additional clocks for the CB to exit initialization phase */
  150. if (fpgamgr_dclkcnt_set(0x5000))
  151. return -7;
  152. /* (5) wait until FPGA enter user mode */
  153. for (i = 0; i < FPGA_TIMEOUT_CNT; i++) {
  154. if (fpgamgr_get_mode() == FPGAMGRREGS_MODE_USERMODE)
  155. break;
  156. }
  157. /* If not in configuration state, return error */
  158. if (i == FPGA_TIMEOUT_CNT)
  159. return -8;
  160. /* To release FPGA Manager drive over configuration line */
  161. clrbits_le32(&fpgamgr_regs->ctrl, FPGAMGRREGS_CTRL_EN_MASK);
  162. return 0;
  163. }
  164. /*
  165. * FPGA Manager to program the FPGA. This is the interface used by FPGA driver.
  166. * Return 0 for sucess, non-zero for error.
  167. */
  168. int socfpga_load(Altera_desc *desc, const void *rbf_data, size_t rbf_size)
  169. {
  170. unsigned long status;
  171. if ((uint32_t)rbf_data & 0x3) {
  172. puts("FPGA: Unaligned data, realign to 32bit boundary.\n");
  173. return -EINVAL;
  174. }
  175. /* Prior programming the FPGA, all bridges need to be shut off */
  176. /* Disable all signals from hps peripheral controller to fpga */
  177. writel(0, &sysmgr_regs->fpgaintfgrp_module);
  178. /* Disable all signals from FPGA to HPS SDRAM */
  179. #define SDR_CTRLGRP_FPGAPORTRST_ADDRESS 0x5080
  180. writel(0, SOCFPGA_SDR_ADDRESS + SDR_CTRLGRP_FPGAPORTRST_ADDRESS);
  181. /* Disable all axi bridge (hps2fpga, lwhps2fpga & fpga2hps) */
  182. socfpga_bridges_reset(1);
  183. /* Unmap the bridges from NIC-301 */
  184. writel(0x1, SOCFPGA_L3REGS_ADDRESS);
  185. /* Initialize the FPGA Manager */
  186. status = fpgamgr_program_init();
  187. if (status)
  188. return status;
  189. /* Write the RBF data to FPGA Manager */
  190. fpgamgr_program_write(rbf_data, rbf_size);
  191. /* Ensure the FPGA entering config done */
  192. status = fpgamgr_program_poll_cd();
  193. if (status)
  194. return status;
  195. /* Ensure the FPGA entering init phase */
  196. status = fpgamgr_program_poll_initphase();
  197. if (status)
  198. return status;
  199. /* Ensure the FPGA entering user mode */
  200. return fpgamgr_program_poll_usermode();
  201. }