socfpga_gen5.c 6.4 KB

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