system_m2sxxx.c 33 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005
  1. /*******************************************************************************
  2. * (c) Copyright 2012-2013 Microsemi SoC Products Group. All rights reserved.
  3. *
  4. * SmartFusion2 CMSIS system initialization.
  5. *
  6. * SVN $Revision: 7375 $
  7. * SVN $Date: 2015-05-01 14:57:40 +0100 (Fri, 01 May 2015) $
  8. */
  9. #include "m2sxxx.h"
  10. #if MSCC_NO_RELATIVE_PATHS
  11. #include "sys_config.h"
  12. #else
  13. #include "sys_config.h"
  14. #endif
  15. #include "sys_init_cfg_types.h"
  16. /*------------------------------------------------------------------------------
  17. Silicon revisions.
  18. */
  19. #define UNKNOWN_SILICON_REV 0
  20. #define M2S050_REV_A_SILICON 1
  21. #define M2S050_REV_B_SILICON 2
  22. /*------------------------------------------------------------------------------
  23. * CoreConfigP IP block version.
  24. */
  25. #define CORE_CONFIGP_V7_0 0x00070000u
  26. /*------------------------------------------------------------------------------
  27. *
  28. */
  29. void mscc_post_hw_cfg_init(void);
  30. /*------------------------------------------------------------------------------
  31. * CoreConfigP/CoreConfigP register bits
  32. */
  33. #define CONFIG_1_DONE 1u
  34. #define CONFIG_2_DONE 2u
  35. #define INIT_DONE_MASK 0x00000001u
  36. #define SDIF_RELEASED_MASK 0x00000002u
  37. /*------------------------------------------------------------------------------
  38. * System registers of interest.
  39. */
  40. /*
  41. * MSSDDR_FACC1_CR register masks:
  42. */
  43. #define DDR_CLK_EN_SHIFT 8u
  44. #define FACC_GLMUX_SEL_MASK 0x00001000u
  45. #define CONTROLLER_PLL_INIT_MASK 0x04000000u
  46. #define RCOSC_DIV2_MASK 0x00000004u
  47. /*
  48. * MSSDDR_PLL_STATUS register masks:
  49. */
  50. #define FAB_PLL_LOCK_MASK 0x00000001u
  51. #define MPLL_LOCK_MASK 0x00000002u
  52. /*
  53. * MSSDDR_PLL_STATUS_HIGH_CR register masks:
  54. */
  55. #define FACC_PLL_BYPASS_MASK 0x00000001u
  56. /*------------------------------------------------------------------------------
  57. * Standard CMSIS global variables.
  58. */
  59. uint32_t SystemCoreClock = MSS_SYS_M3_CLK_FREQ; /*!< System Clock Frequency (Core Clock) */
  60. /*------------------------------------------------------------------------------
  61. * SmartFusion2 specific clocks.
  62. */
  63. uint32_t g_FrequencyPCLK0 = MSS_SYS_APB_0_CLK_FREQ; /*!< Clock frequency of APB bus 0. */
  64. uint32_t g_FrequencyPCLK1 = MSS_SYS_APB_1_CLK_FREQ; /*!< Clock frequency of APB bus 1. */
  65. uint32_t g_FrequencyPCLK2 = MSS_SYS_APB_2_CLK_FREQ; /*!< Clock frequency of APB bus 2. */
  66. uint32_t g_FrequencyFIC0 = MSS_SYS_FIC_0_CLK_FREQ; /*!< Clock frequecny of FPGA fabric interface controller 1. */
  67. uint32_t g_FrequencyFIC1 = MSS_SYS_FIC_1_CLK_FREQ; /*!< Clock frequecny of FPGA fabric inteface controller 2. */
  68. uint32_t g_FrequencyFIC64 = MSS_SYS_FIC64_CLK_FREQ; /*!< Clock frequecny of 64-bit FPGA fabric interface controller. */
  69. /*------------------------------------------------------------------------------
  70. * System configuration tables generated by Libero.
  71. */
  72. #if MSS_SYS_MDDR_CONFIG_BY_CORTEX
  73. extern MDDR_TypeDef * const g_m2s_mddr_addr;
  74. extern const ddr_subsys_cfg_t g_m2s_mddr_subsys_config;
  75. #endif
  76. #if MSS_SYS_FDDR_CONFIG_BY_CORTEX
  77. extern FDDR_TypeDef * const g_m2s_fddr_addr;
  78. extern const ddr_subsys_cfg_t g_m2s_fddr_subsys_config;
  79. #endif
  80. #define MSS_SYS_SERDES_CONFIG_BY_CORTEX (MSS_SYS_SERDES_0_CONFIG_BY_CORTEX || MSS_SYS_SERDES_1_CONFIG_BY_CORTEX || MSS_SYS_SERDES_2_CONFIG_BY_CORTEX || MSS_SYS_SERDES_3_CONFIG_BY_CORTEX)
  81. #if MSS_SYS_SERDES_0_CONFIG_BY_CORTEX
  82. extern const cfg_addr_value_pair_t g_m2s_serdes_0_config[SERDES_0_CFG_NB_OF_PAIRS];
  83. #endif
  84. #if MSS_SYS_SERDES_1_CONFIG_BY_CORTEX
  85. extern const cfg_addr_value_pair_t g_m2s_serdes_1_config[SERDES_1_CFG_NB_OF_PAIRS];
  86. #endif
  87. #if MSS_SYS_SERDES_2_CONFIG_BY_CORTEX
  88. extern const cfg_addr_value_pair_t g_m2s_serdes_2_config[SERDES_2_CFG_NB_OF_PAIRS];
  89. #endif
  90. #if MSS_SYS_SERDES_3_CONFIG_BY_CORTEX
  91. extern const cfg_addr_value_pair_t g_m2s_serdes_3_config[SERDES_3_CFG_NB_OF_PAIRS];
  92. #endif
  93. #define MSS_SYS_CORESF2RESET_USED (MSS_SYS_MDDR_CONFIG_BY_CORTEX || MSS_SYS_FDDR_CONFIG_BY_CORTEX || MSS_SYS_SERDES_CONFIG_BY_CORTEX)
  94. /*==============================================================================
  95. * List of PCIe lanes on which PMA_READY must be polled. Allows only polling PMA
  96. * READY on the first lane of a PCIe link regardless of the number of lanes used
  97. * or whether lane reversal is used.
  98. */
  99. #if MSS_SYS_SERDES_CONFIG_BY_CORTEX
  100. #define CONFIG_REG_LANE_SEL_LANE_0 0x00000100U
  101. #define CONFIG_REG_LANE_SEL_LANE_1 0x00000200U
  102. #define CONFIG_REG_LANE_SEL_LANE_2 0x00000400U
  103. #define CONFIG_REG_LANE_SEL_LANE_3 0x00000800U
  104. #define CONFIG_REG_LANE_SEL_MASK (CONFIG_REG_LANE_SEL_LANE_0 | \
  105. CONFIG_REG_LANE_SEL_LANE_1 | \
  106. CONFIG_REG_LANE_SEL_LANE_2 | \
  107. CONFIG_REG_LANE_SEL_LANE_3)
  108. #define FIRST_PCIE_CTRL 1U
  109. #define SECOND_PCIE_CTRL 2U
  110. typedef struct pma_poll_info
  111. {
  112. SERDESIF_TypeDef * serdes;
  113. SERDES_TypeDef * const lane;
  114. uint16_t config_reg_lane_sel;
  115. uint16_t pcie_ctrl_id; /* distinguish between first and second PCIe controller on M2S090. */
  116. } pma_poll_info_t;
  117. /*------------------------------------------------------------------------------
  118. * SERDES0: list of PMA to poll as part of PCIe configuration. This list only
  119. * handles the first PCIe controller of SERDES0.
  120. */
  121. static const pma_poll_info_t g_serdes0_pcie_lane_cfg_lut[] =
  122. {
  123. #if defined(SERDESIF_0_PCIE_LANE_PMA_STATUS_LANE_0)
  124. {
  125. SERDES0, /* SERDESIF_TypeDef * serdes */
  126. &SERDES0->lane[0], /* SERDES_TypeDef * const lane */
  127. CONFIG_REG_LANE_SEL_LANE_0, /* uint16_t config_reg_lane_sel */
  128. FIRST_PCIE_CTRL /* uint16_t pcie_ctrl_id */
  129. },
  130. #endif
  131. #if defined(SERDESIF_0_PCIE_LANE_PMA_STATUS_LANE_1)
  132. {
  133. SERDES0, /* SERDESIF_TypeDef * serdes */
  134. &SERDES0->lane[1], /* SERDES_TypeDef * const lane */
  135. CONFIG_REG_LANE_SEL_LANE_1, /* uint16_t config_reg_lane_sel */
  136. FIRST_PCIE_CTRL /* uint16_t pcie_ctrl_id */
  137. },
  138. #endif
  139. #if defined(SERDESIF_0_PCIE_LANE_PMA_STATUS_LANE_2)
  140. {
  141. SERDES0, /* SERDESIF_TypeDef * serdes */
  142. &SERDES0->lane[2], /* SERDES_TypeDef * const lane */
  143. CONFIG_REG_LANE_SEL_LANE_2, /* uint16_t config_reg_lane_sel */
  144. FIRST_PCIE_CTRL /* uint16_t pcie_ctrl_id */
  145. },
  146. #endif
  147. #if defined(SERDESIF_0_PCIE_LANE_PMA_STATUS_LANE_3)
  148. {
  149. SERDES0, /* SERDESIF_TypeDef * serdes */
  150. &SERDES0->lane[3], /* SERDES_TypeDef * const lane */
  151. CONFIG_REG_LANE_SEL_LANE_3, /* uint16_t config_reg_lane_sel */
  152. FIRST_PCIE_CTRL /* uint16_t pcie_ctrl_id */
  153. },
  154. #endif
  155. {
  156. (SERDESIF_TypeDef *)0, /* SERDESIF_TypeDef * serdes */
  157. (SERDES_TypeDef *)0, /* SERDES_TypeDef * const lane */
  158. 0, /* uint16_t config_reg_lane_sel */
  159. 0 /* uint16_t pcie_ctrl_id */
  160. }
  161. };
  162. /*------------------------------------------------------------------------------
  163. * SERDES1: list of PMA to poll as part of PCIe configuration. This list handles
  164. * both SERDES1 first PCIe controller and the M2S090 SERDES0 second PCIe
  165. * controller.
  166. */
  167. static const pma_poll_info_t g_serdes1_pcie_lane_cfg_lut[] =
  168. {
  169. #if defined(SERDESIF_1_PCIE_LANE_PMA_STATUS_LANE_0)
  170. {
  171. SERDES1, /* SERDESIF_TypeDef * serdes */
  172. &SERDES1->lane[0], /* SERDES_TypeDef * const lane */
  173. CONFIG_REG_LANE_SEL_LANE_0, /* uint16_t config_reg_lane_sel */
  174. FIRST_PCIE_CTRL /* uint16_t pcie_ctrl_id */
  175. },
  176. #endif
  177. #if defined(SERDESIF_1_PCIE_LANE_PMA_STATUS_LANE_1)
  178. {
  179. SERDES1, /* SERDESIF_TypeDef * serdes */
  180. &SERDES1->lane[1], /* SERDES_TypeDef * const lane */
  181. CONFIG_REG_LANE_SEL_LANE_1, /* uint16_t config_reg_lane_sel */
  182. FIRST_PCIE_CTRL /* uint16_t pcie_ctrl_id */
  183. },
  184. #endif
  185. #if defined(SERDESIF_1_PCIE_LANE_PMA_STATUS_LANE_2)
  186. {
  187. SERDES1, /* SERDESIF_TypeDef * serdes */
  188. &SERDES1->lane[2], /* SERDES_TypeDef * const lane */
  189. CONFIG_REG_LANE_SEL_LANE_2, /* uint16_t config_reg_lane_sel */
  190. FIRST_PCIE_CTRL /* uint16_t pcie_ctrl_id */
  191. },
  192. #endif
  193. #if defined(SERDESIF_1_PCIE_LANE_PMA_STATUS_LANE_3)
  194. {
  195. SERDES1, /* SERDESIF_TypeDef * serdes */
  196. &SERDES1->lane[3], /* SERDES_TypeDef * const lane */
  197. CONFIG_REG_LANE_SEL_LANE_3, /* uint16_t config_reg_lane_sel */
  198. FIRST_PCIE_CTRL /* uint16_t pcie_ctrl_id */
  199. },
  200. #endif
  201. #if defined(SERDESIF_0_PCIE_1_LANE_PMA_STATUS_LANE_0)
  202. {
  203. SERDES0, /* SERDESIF_TypeDef * serdes */
  204. &SERDES0->lane[0], /* SERDES_TypeDef * const lane */
  205. CONFIG_REG_LANE_SEL_LANE_0, /* uint16_t config_reg_lane_sel */
  206. SECOND_PCIE_CTRL /* uint16_t pcie_ctrl_id */
  207. },
  208. #endif
  209. #if defined(SERDESIF_0_PCIE_1_LANE_PMA_STATUS_LANE_1)
  210. {
  211. SERDES0, /* SERDESIF_TypeDef * serdes */
  212. &SERDES0->lane[1], /* SERDES_TypeDef * const lane */
  213. CONFIG_REG_LANE_SEL_LANE_1, /* uint16_t config_reg_lane_sel */
  214. SECOND_PCIE_CTRL /* uint16_t pcie_ctrl_id */
  215. },
  216. #endif
  217. #if defined(SERDESIF_0_PCIE_1_LANE_PMA_STATUS_LANE_2)
  218. {
  219. SERDES0, /* SERDESIF_TypeDef * serdes */
  220. &SERDES0->lane[2], /* SERDES_TypeDef * const lane */
  221. CONFIG_REG_LANE_SEL_LANE_2, /* uint16_t config_reg_lane_sel */
  222. SECOND_PCIE_CTRL /* uint16_t pcie_ctrl_id */
  223. },
  224. #endif
  225. #if defined(SERDESIF_0_PCIE_1_LANE_PMA_STATUS_LANE_3)
  226. {
  227. SERDES0, /* SERDESIF_TypeDef * serdes */
  228. &SERDES0->lane[3], /* SERDES_TypeDef * const lane */
  229. CONFIG_REG_LANE_SEL_LANE_3, /* uint16_t config_reg_lane_sel */
  230. SECOND_PCIE_CTRL /* uint16_t pcie_ctrl_id */
  231. },
  232. #endif
  233. {
  234. (SERDESIF_TypeDef *)0, /* SERDESIF_TypeDef * serdes */
  235. (SERDES_TypeDef *)0, /* SERDES_TypeDef * const lane */
  236. 0, /* uint16_t config_reg_lane_sel */
  237. 0 /* uint16_t pcie_ctrl_id */
  238. }
  239. };
  240. /*------------------------------------------------------------------------------
  241. * SERDES2: list of PMA to poll as part of PCIe configuration.
  242. */
  243. static const pma_poll_info_t g_serdes2_pcie_lane_cfg_lut[] =
  244. {
  245. #if defined(SERDESIF_2_PCIE_LANE_PMA_STATUS_LANE_0)
  246. {
  247. SERDES2, /* SERDESIF_TypeDef * serdes */
  248. &SERDES2->lane[0], /* SERDES_TypeDef * const lane */
  249. CONFIG_REG_LANE_SEL_LANE_0, /* uint16_t config_reg_lane_sel */
  250. FIRST_PCIE_CTRL /* uint16_t pcie_ctrl_id */
  251. },
  252. #endif
  253. #if defined(SERDESIF_2_PCIE_LANE_PMA_STATUS_LANE_1)
  254. {
  255. SERDES2, /* SERDESIF_TypeDef * serdes */
  256. &SERDES2->lane[1], /* SERDES_TypeDef * const lane */
  257. CONFIG_REG_LANE_SEL_LANE_1, /* uint16_t config_reg_lane_sel */
  258. FIRST_PCIE_CTRL /* uint16_t pcie_ctrl_id */
  259. },
  260. #endif
  261. #if defined(SERDESIF_2_PCIE_LANE_PMA_STATUS_LANE_2)
  262. {
  263. SERDES2, /* SERDESIF_TypeDef * serdes */
  264. &SERDES2->lane[2], /* SERDES_TypeDef * const lane */
  265. CONFIG_REG_LANE_SEL_LANE_2, /* uint16_t config_reg_lane_sel */
  266. FIRST_PCIE_CTRL /* uint16_t pcie_ctrl_id */
  267. },
  268. #endif
  269. #if defined(SERDESIF_2_PCIE_LANE_PMA_STATUS_LANE_3)
  270. {
  271. SERDES2, /* SERDESIF_TypeDef * serdes */
  272. &SERDES2->lane[3], /* SERDES_TypeDef * const lane */
  273. CONFIG_REG_LANE_SEL_LANE_3, /* uint16_t config_reg_lane_sel */
  274. FIRST_PCIE_CTRL /* uint16_t pcie_ctrl_id */
  275. },
  276. #endif
  277. {
  278. (SERDESIF_TypeDef *)0, /* SERDESIF_TypeDef * serdes */
  279. (SERDES_TypeDef *)0, /* SERDES_TypeDef * const lane */
  280. 0, /* uint16_t config_reg_lane_sel */
  281. 0 /* uint16_t pcie_ctrl_id */
  282. }
  283. };
  284. /*------------------------------------------------------------------------------
  285. * SERDES3: list of PMA to poll as part of PCIe configuration.
  286. */
  287. static const pma_poll_info_t g_serdes3_pcie_lane_cfg_lut[] =
  288. {
  289. #if defined(SERDESIF_3_PCIE_LANE_PMA_STATUS_LANE_0)
  290. {
  291. SERDES3, /* SERDESIF_TypeDef * serdes */
  292. &SERDES3->lane[0], /* SERDES_TypeDef * const lane */
  293. CONFIG_REG_LANE_SEL_LANE_0, /* uint16_t config_reg_lane_sel */
  294. FIRST_PCIE_CTRL /* uint16_t pcie_ctrl_id */
  295. },
  296. #endif
  297. #if defined(SERDESIF_3_PCIE_LANE_PMA_STATUS_LANE_1)
  298. {
  299. SERDES3, /* SERDESIF_TypeDef * serdes */
  300. &SERDES3->lane[1], /* SERDES_TypeDef * const lane */
  301. CONFIG_REG_LANE_SEL_LANE_1, /* uint16_t config_reg_lane_sel */
  302. FIRST_PCIE_CTRL /* uint16_t pcie_ctrl_id */
  303. },
  304. #endif
  305. #if defined(SERDESIF_3_PCIE_LANE_PMA_STATUS_LANE_2)
  306. {
  307. SERDES3, /* SERDESIF_TypeDef * serdes */
  308. &SERDES3->lane[2], /* SERDES_TypeDef * const lane */
  309. CONFIG_REG_LANE_SEL_LANE_2, /* uint16_t config_reg_lane_sel */
  310. FIRST_PCIE_CTRL /* uint16_t pcie_ctrl_id */
  311. },
  312. #endif
  313. #if defined(SERDESIF_3_PCIE_LANE_PMA_STATUS_LANE_3)
  314. {
  315. SERDES3, /* SERDESIF_TypeDef * serdes */
  316. &SERDES3->lane[3], /* SERDES_TypeDef * const lane */
  317. CONFIG_REG_LANE_SEL_LANE_3, /* uint16_t config_reg_lane_sel */
  318. FIRST_PCIE_CTRL /* uint16_t pcie_ctrl_id */
  319. },
  320. #endif
  321. {
  322. (SERDESIF_TypeDef *)0, /* SERDESIF_TypeDef * serdes */
  323. (SERDES_TypeDef *)0, /* SERDES_TypeDef * const lane */
  324. 0, /* uint16_t config_reg_lane_sel */
  325. 0 /* uint16_t pcie_ctrl_id */
  326. }
  327. };
  328. /*------------------------------------------------------------------------------
  329. * Master lookup table for all SERDES PCIe configuration.
  330. */
  331. static const pma_poll_info_t * const g_pcie_lane_cfg_lut[] =
  332. {
  333. g_serdes0_pcie_lane_cfg_lut,
  334. g_serdes1_pcie_lane_cfg_lut,
  335. g_serdes2_pcie_lane_cfg_lut,
  336. g_serdes3_pcie_lane_cfg_lut
  337. };
  338. #endif
  339. /*------------------------------------------------------------------------------
  340. * Local functions:
  341. */
  342. static uint32_t get_silicon_revision(void);
  343. static void silicon_workarounds(void);
  344. static void m2s050_rev_a_workarounds(void);
  345. #if (MSS_SYS_FACC_INIT_BY_CORTEX == 1)
  346. static void complete_clock_config(void);
  347. #endif
  348. #if MSS_SYS_SERDES_CONFIG_BY_CORTEX
  349. static void configure_serdes_intf(void);
  350. static void configure_pcie_intf(void);
  351. static void configure_pcie_block
  352. (
  353. const cfg_addr_value_pair_t * p_addr_value_pair,
  354. uint32_t nb_of_cfg_pairs,
  355. uint32_t serdes_id
  356. );
  357. #endif
  358. #if (MSS_SYS_MDDR_CONFIG_BY_CORTEX || MSS_SYS_FDDR_CONFIG_BY_CORTEX)
  359. static void config_ddr_subsys
  360. (
  361. const ddr_subsys_cfg_t * p_ddr_subsys_cfg,
  362. DDRCore_TypeDef * p_ddr_subsys_regs
  363. );
  364. #endif
  365. #if MSS_SYS_SERDES_CONFIG_BY_CORTEX
  366. static void config_by_addr_value
  367. (
  368. const cfg_addr_value_pair_t * p_addr_value_pair,
  369. uint32_t nb_of_cfg_pairs
  370. );
  371. #endif
  372. static uint32_t get_rcosc_25_50mhz_frequency(void);
  373. static void set_clock_frequency_globals(uint32_t fclk);
  374. /***************************************************************************//**
  375. * See system_m2sxxx.h for details.
  376. */
  377. void SystemInit(void)
  378. {
  379. #if MSS_SYS_SERDES_CONFIG_BY_CORTEX
  380. uint32_t sdif_released;
  381. #endif
  382. #if MSS_SYS_CORESF2RESET_USED
  383. uint32_t init_done;
  384. #endif
  385. #if MSS_SYS_SERDES_CONFIG_BY_CORTEX
  386. uint32_t core_cfg_version;
  387. core_cfg_version = CORE_SF2_CFG->IP_VERSION_SR;
  388. #endif
  389. /*
  390. * Do not make use of global variables or make any asumptions regarding
  391. * memory content if modifying this function. The memory content has not been
  392. * initialised by the time this function is called by the start-up code.
  393. */
  394. #if (MSS_SYS_FACC_INIT_BY_CORTEX == 1)
  395. complete_clock_config();
  396. #endif
  397. silicon_workarounds();
  398. /*--------------------------------------------------------------------------
  399. * Set STKALIGN to ensure exception stacking starts on 8 bytes address
  400. * boundary. This ensures compliance with the "Procedure Call Standards for
  401. * the ARM Architecture" (AAPCS).
  402. */
  403. SCB->CCR |= SCB_CCR_STKALIGN_Msk;
  404. /*--------------------------------------------------------------------------
  405. * MDDR configuration
  406. */
  407. #if MSS_SYS_MDDR_CONFIG_BY_CORTEX
  408. if(0u == SYSREG->DDR_CR)
  409. {
  410. /*
  411. * We only configure the MDDR memory controller if MDDR is not remapped
  412. * to address 0x00000000. If MDDR is remapped to 0x00000000 then we are
  413. * probably executing this code from MDDR in a debugging session and
  414. * attempting to reconfigure the MDDR memory controller will cause the
  415. * Cortex-M3 to crash.
  416. */
  417. config_ddr_subsys(&g_m2s_mddr_subsys_config, &g_m2s_mddr_addr->core);
  418. }
  419. #endif
  420. /*--------------------------------------------------------------------------
  421. * FDDR configuration
  422. */
  423. #if MSS_SYS_FDDR_CONFIG_BY_CORTEX
  424. config_ddr_subsys(&g_m2s_fddr_subsys_config, &g_m2s_fddr_addr->core);
  425. #endif
  426. /*--------------------------------------------------------------------------
  427. * Call user defined configuration function.
  428. */
  429. mscc_post_hw_cfg_init();
  430. /*--------------------------------------------------------------------------
  431. * SERDES interfaces configuration.
  432. */
  433. #if MSS_SYS_SERDES_CONFIG_BY_CORTEX
  434. configure_serdes_intf();
  435. if(core_cfg_version >= CORE_CONFIGP_V7_0)
  436. {
  437. CORE_SF2_CFG->CONFIG_DONE = CONFIG_1_DONE;
  438. /* Poll for SDIF_RELEASED. */
  439. do
  440. {
  441. sdif_released = CORE_SF2_CFG->INIT_DONE & SDIF_RELEASED_MASK;
  442. } while (0u == sdif_released);
  443. }
  444. configure_pcie_intf();
  445. #endif
  446. /*--------------------------------------------------------------------------
  447. * Synchronize with CoreSF2Reset controlling resets from the fabric.
  448. */
  449. #if MSS_SYS_CORESF2RESET_USED
  450. /*
  451. * Negate FPGA_SOFTRESET to de-assert MSS_RESET_N_M2F in the fabric. We must
  452. * do this here because this signal is only deasserted by the System
  453. * Controller on a power-on reset. Other types of reset such as a watchdog
  454. * reset would result in the FPGA fabric being held in reset and getting
  455. * stuck waiting for the CoreSF2Config INIT_DONE to become asserted.
  456. */
  457. SYSREG->SOFT_RST_CR &= ~SYSREG_FPGA_SOFTRESET_MASK;
  458. /*
  459. * Signal to CoreSF2Reset that peripheral configuration registers have been
  460. * written.
  461. */
  462. CORE_SF2_CFG->CONFIG_DONE |= (CONFIG_1_DONE | CONFIG_2_DONE);
  463. /* Wait for INIT_DONE from CoreSF2Reset. */
  464. do
  465. {
  466. init_done = CORE_SF2_CFG->INIT_DONE & INIT_DONE_MASK;
  467. } while (0u == init_done);
  468. #endif
  469. }
  470. /***************************************************************************//**
  471. * SystemCoreClockUpdate()
  472. */
  473. #define RCOSC_25_50MHZ_CLK_SRC 0u
  474. #define CLK_XTAL_CLK_SRC 1u
  475. #define RCOSC_1_MHZ_CLK_SRC 2u
  476. #define CCC2ASCI_CLK_SRC 3u
  477. #define FACC_STANDBY_SHIFT 6u
  478. #define FACC_STANDBY_SEL_MASK 0x00000007u
  479. #define FREQ_32KHZ 32768u
  480. #define FREQ_1MHZ 1000000u
  481. #define FREQ_25MHZ 25000000u
  482. #define FREQ_50MHZ 50000000u
  483. void SystemCoreClockUpdate(void)
  484. {
  485. uint32_t controller_pll_init;
  486. uint32_t clk_src;
  487. controller_pll_init = SYSREG->MSSDDR_FACC1_CR & CONTROLLER_PLL_INIT_MASK;
  488. if(0u == controller_pll_init)
  489. {
  490. /* Normal operations. */
  491. uint32_t global_mux_sel;
  492. global_mux_sel = SYSREG->MSSDDR_FACC1_CR & FACC_GLMUX_SEL_MASK;
  493. if(0u == global_mux_sel)
  494. {
  495. /* MSS clocked from MSS PLL. Use Libero flow defines. */
  496. SystemCoreClock = MSS_SYS_M3_CLK_FREQ;
  497. g_FrequencyPCLK0 = MSS_SYS_APB_0_CLK_FREQ;
  498. g_FrequencyPCLK1 = MSS_SYS_APB_1_CLK_FREQ;
  499. g_FrequencyPCLK2 = MSS_SYS_APB_2_CLK_FREQ;
  500. g_FrequencyFIC0 = MSS_SYS_FIC_0_CLK_FREQ;
  501. g_FrequencyFIC1 = MSS_SYS_FIC_1_CLK_FREQ;
  502. g_FrequencyFIC64 = MSS_SYS_FIC64_CLK_FREQ;
  503. }
  504. else
  505. {
  506. /* MSS clocked from standby clock. */
  507. const uint8_t standby_clock_lut[8] = { RCOSC_25_50MHZ_CLK_SRC,
  508. CLK_XTAL_CLK_SRC,
  509. RCOSC_25_50MHZ_CLK_SRC,
  510. CLK_XTAL_CLK_SRC,
  511. RCOSC_1_MHZ_CLK_SRC,
  512. RCOSC_1_MHZ_CLK_SRC,
  513. CCC2ASCI_CLK_SRC,
  514. CCC2ASCI_CLK_SRC };
  515. uint32_t standby_sel;
  516. uint8_t clock_source;
  517. standby_sel = (SYSREG->MSSDDR_FACC2_CR >> FACC_STANDBY_SHIFT) & FACC_STANDBY_SEL_MASK;
  518. clock_source = standby_clock_lut[standby_sel];
  519. switch(clock_source)
  520. {
  521. case RCOSC_25_50MHZ_CLK_SRC:
  522. clk_src = get_rcosc_25_50mhz_frequency();
  523. set_clock_frequency_globals(clk_src);
  524. break;
  525. case CLK_XTAL_CLK_SRC:
  526. set_clock_frequency_globals(FREQ_32KHZ);
  527. break;
  528. case RCOSC_1_MHZ_CLK_SRC:
  529. set_clock_frequency_globals(FREQ_1MHZ);
  530. break;
  531. case CCC2ASCI_CLK_SRC:
  532. /* Fall through. */
  533. default:
  534. set_clock_frequency_globals(FREQ_1MHZ);
  535. break;
  536. }
  537. }
  538. }
  539. else
  540. {
  541. /* PLL initialization mode. Running from 25/50MHZ RC oscillator. */
  542. clk_src = get_rcosc_25_50mhz_frequency();
  543. set_clock_frequency_globals(clk_src);
  544. }
  545. }
  546. /***************************************************************************//**
  547. * Find out frequency generated by the 25_50mhz RC osciallator.
  548. */
  549. static uint32_t get_rcosc_25_50mhz_frequency(void)
  550. {
  551. uint32_t rcosc_div2;
  552. uint32_t rcosc_frequency;
  553. rcosc_div2 = SYSREG->MSSDDR_PLL_STATUS & RCOSC_DIV2_MASK;
  554. if(0u == rcosc_div2)
  555. {
  556. /* 25_50mhz oscillator is configured for 25 MHz operations. */
  557. rcosc_frequency = FREQ_25MHZ;
  558. }
  559. else
  560. {
  561. /* 25_50mhz oscillator is configured for 50 MHz operations. */
  562. rcosc_frequency = FREQ_50MHZ;
  563. }
  564. return rcosc_frequency;
  565. }
  566. /***************************************************************************//**
  567. Set the value of the clock frequency global variables based on the value of
  568. standby_clk passed as parameter.
  569. The following global variables are set by this function:
  570. - SystemCoreClock
  571. - g_FrequencyPCLK0
  572. - g_FrequencyPCLK1
  573. - g_FrequencyPCLK2
  574. - g_FrequencyFIC0
  575. - g_FrequencyFIC1
  576. - g_FrequencyFIC64
  577. */
  578. static void set_clock_frequency_globals(uint32_t standby_clk)
  579. {
  580. SystemCoreClock = standby_clk;
  581. g_FrequencyPCLK0 = standby_clk;
  582. g_FrequencyPCLK1 = standby_clk;
  583. g_FrequencyPCLK2 = MSS_SYS_APB_2_CLK_FREQ;
  584. g_FrequencyFIC0 = standby_clk;
  585. g_FrequencyFIC1 = standby_clk;
  586. g_FrequencyFIC64 = standby_clk;
  587. }
  588. /***************************************************************************//**
  589. * Write 16-bit configuration values into 32-bit word aligned registers.
  590. */
  591. #if (MSS_SYS_MDDR_CONFIG_BY_CORTEX || MSS_SYS_FDDR_CONFIG_BY_CORTEX)
  592. static void copy_cfg16_to_regs
  593. (
  594. volatile uint32_t * p_regs,
  595. const uint16_t * p_cfg,
  596. uint32_t nb_16bit_words
  597. )
  598. {
  599. uint32_t inc;
  600. for(inc = 0u; inc < nb_16bit_words; ++inc)
  601. {
  602. p_regs[inc] = p_cfg[inc];
  603. }
  604. }
  605. #endif
  606. /***************************************************************************//**
  607. * Configure peripheral using register address and register value pairs.
  608. */
  609. #if MSS_SYS_SERDES_CONFIG_BY_CORTEX
  610. static void config_by_addr_value
  611. (
  612. const cfg_addr_value_pair_t * p_addr_value_pair,
  613. uint32_t nb_of_cfg_pairs
  614. )
  615. {
  616. uint32_t inc;
  617. for(inc = 0u; inc < nb_of_cfg_pairs; ++inc)
  618. {
  619. *p_addr_value_pair[inc].p_reg = p_addr_value_pair[inc].value;
  620. }
  621. }
  622. #endif
  623. /***************************************************************************//**
  624. * DDR subsystem configuration.
  625. */
  626. #if (MSS_SYS_MDDR_CONFIG_BY_CORTEX || MSS_SYS_FDDR_CONFIG_BY_CORTEX)
  627. #define NB_OF_DDRC_REGS_TO_CONFIG 57u
  628. #define NB_OF_DDR_PHY_REGS_TO_CONFIG 65u
  629. static void config_ddr_subsys
  630. (
  631. const ddr_subsys_cfg_t * p_ddr_subsys_cfg,
  632. DDRCore_TypeDef * p_ddr_subsys_regs
  633. )
  634. {
  635. volatile uint32_t * p_regs;
  636. const uint16_t * p_cfg;
  637. /*--------------------------------------------------------------------------
  638. * Configure DDR controller part of the MDDR subsystem.
  639. */
  640. p_cfg = &p_ddr_subsys_cfg->ddrc.DYN_SOFT_RESET_CR;
  641. p_regs = &p_ddr_subsys_regs->ddrc.DYN_SOFT_RESET_CR;
  642. copy_cfg16_to_regs(p_regs, p_cfg, NB_OF_DDRC_REGS_TO_CONFIG);
  643. /*--------------------------------------------------------------------------
  644. * Configure DDR PHY.
  645. */
  646. p_cfg = &p_ddr_subsys_cfg->phy.LOOPBACK_TEST_CR;
  647. p_regs = &p_ddr_subsys_regs->phy.LOOPBACK_TEST_CR;
  648. copy_cfg16_to_regs(p_regs, p_cfg, NB_OF_DDR_PHY_REGS_TO_CONFIG);
  649. /*--------------------------------------------------------------------------
  650. * Configure DDR FIC.
  651. */
  652. p_ddr_subsys_regs->fic.NB_ADDR_CR = p_ddr_subsys_cfg->fic.NB_ADDR_CR;
  653. p_ddr_subsys_regs->fic.NBRWB_SIZE_CR = p_ddr_subsys_cfg->fic.NBRWB_SIZE_CR;
  654. p_ddr_subsys_regs->fic.WB_TIMEOUT_CR = p_ddr_subsys_cfg->fic.WB_TIMEOUT_CR;
  655. p_ddr_subsys_regs->fic.HPD_SW_RW_EN_CR = p_ddr_subsys_cfg->fic.HPD_SW_RW_EN_CR;
  656. p_ddr_subsys_regs->fic.HPD_SW_RW_INVAL_CR = p_ddr_subsys_cfg->fic.HPD_SW_RW_INVAL_CR;
  657. p_ddr_subsys_regs->fic.SW_WR_ERCLR_CR = p_ddr_subsys_cfg->fic.SW_WR_ERCLR_CR;
  658. p_ddr_subsys_regs->fic.ERR_INT_ENABLE_CR = p_ddr_subsys_cfg->fic.ERR_INT_ENABLE_CR;
  659. p_ddr_subsys_regs->fic.NUM_AHB_MASTERS_CR = p_ddr_subsys_cfg->fic.NUM_AHB_MASTERS_CR;
  660. p_ddr_subsys_regs->fic.LOCK_TIMEOUTVAL_CR[0] = p_ddr_subsys_cfg->fic.LOCK_TIMEOUTVAL_1_CR;
  661. p_ddr_subsys_regs->fic.LOCK_TIMEOUTVAL_CR[1] = p_ddr_subsys_cfg->fic.LOCK_TIMEOUTVAL_2_CR;
  662. p_ddr_subsys_regs->fic.LOCK_TIMEOUT_EN_CR = p_ddr_subsys_cfg->fic.LOCK_TIMEOUT_EN_CR;
  663. /*--------------------------------------------------------------------------
  664. * Enable DDR.
  665. */
  666. p_ddr_subsys_regs->ddrc.DYN_SOFT_RESET_CR = 0x01u;
  667. while(0x0000u == p_ddr_subsys_regs->ddrc.DDRC_SR)
  668. {
  669. ;
  670. }
  671. }
  672. #endif
  673. /***************************************************************************//**
  674. * Configure SERDES interfaces.
  675. */
  676. #if MSS_SYS_SERDES_CONFIG_BY_CORTEX
  677. static void configure_serdes_intf(void)
  678. {
  679. #if MSS_SYS_SERDES_0_CONFIG_BY_CORTEX
  680. config_by_addr_value(g_m2s_serdes_0_config, SERDES_0_CFG_NB_OF_PAIRS);
  681. #endif
  682. #if MSS_SYS_SERDES_1_CONFIG_BY_CORTEX
  683. config_by_addr_value(g_m2s_serdes_1_config, SERDES_1_CFG_NB_OF_PAIRS);
  684. #endif
  685. #if MSS_SYS_SERDES_2_CONFIG_BY_CORTEX
  686. config_by_addr_value(g_m2s_serdes_2_config, SERDES_2_CFG_NB_OF_PAIRS);
  687. #endif
  688. #if MSS_SYS_SERDES_3_CONFIG_BY_CORTEX
  689. config_by_addr_value(g_m2s_serdes_3_config, SERDES_3_CFG_NB_OF_PAIRS);
  690. #endif
  691. }
  692. /***************************************************************************//**
  693. * Configure PCIe interfaces.
  694. */
  695. static void configure_pcie_intf(void)
  696. {
  697. #if MSS_SYS_SERDES_0_CONFIG_BY_CORTEX
  698. configure_pcie_block(g_m2s_serdes_0_config, SERDES_0_CFG_NB_OF_PAIRS, 0u);
  699. #endif
  700. #if MSS_SYS_SERDES_1_CONFIG_BY_CORTEX
  701. configure_pcie_block(g_m2s_serdes_1_config, SERDES_1_CFG_NB_OF_PAIRS, 1u);
  702. #endif
  703. #if MSS_SYS_SERDES_2_CONFIG_BY_CORTEX
  704. configure_pcie_block(g_m2s_serdes_2_config, SERDES_2_CFG_NB_OF_PAIRS, 2u);
  705. #endif
  706. #if MSS_SYS_SERDES_3_CONFIG_BY_CORTEX
  707. configure_pcie_block(g_m2s_serdes_3_config, SERDES_3_CFG_NB_OF_PAIRS, 3u);
  708. #endif
  709. }
  710. /*------------------------------------------------------------------------------
  711. Configure one individual PCIe block.
  712. */
  713. static void configure_pcie_block
  714. (
  715. const cfg_addr_value_pair_t * p_addr_value_pair,
  716. uint32_t nb_of_cfg_pairs,
  717. uint32_t serdes_id
  718. )
  719. {
  720. uint32_t inc;
  721. const uint32_t PMA_READY_MASK = 0x00000080u;
  722. const uint32_t PCIE_CTRL_REG_LENGTH = 0x1000u;
  723. const uint32_t PCIE_CTLR_SOFTRESET_MASK = 0x00000001;
  724. const uint32_t PCIE2_CTLR_SOFTRESET_MASK = 0x00000040;
  725. SERDESIF_TypeDef * const serdes_lut[4] =
  726. {
  727. SERDES0, SERDES1, SERDES2, SERDES3
  728. };
  729. const uint32_t pcie_ctrl_top_addr_lut[4] =
  730. {
  731. SERDES0_CFG_BASE + PCIE_CTRL_REG_LENGTH,
  732. SERDES1_CFG_BASE + PCIE_CTRL_REG_LENGTH,
  733. SERDES2_CFG_BASE + PCIE_CTRL_REG_LENGTH,
  734. SERDES3_CFG_BASE + PCIE_CTRL_REG_LENGTH
  735. };
  736. /*
  737. * Poll for PMA_READY.
  738. */
  739. inc = 0U;
  740. while(g_pcie_lane_cfg_lut[serdes_id][inc].config_reg_lane_sel != 0)
  741. {
  742. uint32_t pma_ready;
  743. uint32_t config_phy_mode_1;
  744. /* select lane */
  745. config_phy_mode_1 = g_pcie_lane_cfg_lut[serdes_id][inc].serdes->sys_regs.CONFIG_PHY_MODE_1;
  746. config_phy_mode_1 &= ~CONFIG_REG_LANE_SEL_MASK;
  747. config_phy_mode_1 |= (uint32_t)g_pcie_lane_cfg_lut[serdes_id][inc].config_reg_lane_sel;
  748. g_pcie_lane_cfg_lut[serdes_id][inc].serdes->sys_regs.CONFIG_PHY_MODE_1 = config_phy_mode_1;
  749. /* Wait for PMA to become ready. */
  750. do
  751. {
  752. pma_ready = g_pcie_lane_cfg_lut[serdes_id][inc].lane->PMA_STATUS & PMA_READY_MASK;
  753. }
  754. while (0u == pma_ready);
  755. ++inc;
  756. }
  757. /*
  758. * Configure the PCIe controller registers.
  759. */
  760. for(inc = 0u; inc < nb_of_cfg_pairs; ++inc)
  761. {
  762. uint32_t reg_addr;
  763. reg_addr = (uint32_t)p_addr_value_pair[inc].p_reg;
  764. if(reg_addr < pcie_ctrl_top_addr_lut[serdes_id])
  765. {
  766. *p_addr_value_pair[inc].p_reg = p_addr_value_pair[inc].value;
  767. }
  768. }
  769. /*
  770. * Issue a soft-reset to the PCIe controller
  771. */
  772. inc = 0U;
  773. while(g_pcie_lane_cfg_lut[serdes_id][inc].config_reg_lane_sel != 0)
  774. {
  775. if(FIRST_PCIE_CTRL == g_pcie_lane_cfg_lut[serdes_id][inc].pcie_ctrl_id)
  776. {
  777. serdes_lut[serdes_id]->sys_regs.SERDESIF_SOFT_RESET &= ~PCIE_CTLR_SOFTRESET_MASK;
  778. serdes_lut[serdes_id]->sys_regs.SERDESIF_SOFT_RESET |= PCIE_CTLR_SOFTRESET_MASK;
  779. }
  780. else
  781. {
  782. serdes_lut[serdes_id]->sys_regs.SERDESIF_SOFT_RESET &= ~PCIE2_CTLR_SOFTRESET_MASK;
  783. serdes_lut[serdes_id]->sys_regs.SERDESIF_SOFT_RESET |= PCIE2_CTLR_SOFTRESET_MASK;
  784. }
  785. ++inc;
  786. }
  787. }
  788. #endif
  789. /*------------------------------------------------------------------------------
  790. Retrieve silicon revision from system registers.
  791. */
  792. static uint32_t get_silicon_revision(void)
  793. {
  794. uint32_t silicon_revision;
  795. uint32_t device_version;
  796. device_version = SYSREG->DEVICE_VERSION;
  797. switch(device_version)
  798. {
  799. case 0x0000F802:
  800. silicon_revision = M2S050_REV_A_SILICON;
  801. break;
  802. case 0x0001F802:
  803. silicon_revision = M2S050_REV_B_SILICON;
  804. break;
  805. default:
  806. silicon_revision = UNKNOWN_SILICON_REV;
  807. break;
  808. }
  809. return silicon_revision;
  810. }
  811. /*------------------------------------------------------------------------------
  812. Workarounds for various silicon versions.
  813. */
  814. static void silicon_workarounds(void)
  815. {
  816. uint32_t silicon_revision;
  817. silicon_revision = get_silicon_revision();
  818. switch(silicon_revision)
  819. {
  820. case M2S050_REV_A_SILICON:
  821. m2s050_rev_a_workarounds();
  822. break;
  823. case M2S050_REV_B_SILICON:
  824. /* Fall through. */
  825. case UNKNOWN_SILICON_REV:
  826. /* Fall through. */
  827. default:
  828. break;
  829. }
  830. }
  831. /*------------------------------------------------------------------------------
  832. Silicon workarounds for M2S050 rev A.
  833. */
  834. static void m2s050_rev_a_workarounds(void)
  835. {
  836. /*--------------------------------------------------------------------------
  837. * Work around a couple of silicon issues:
  838. */
  839. /* DDR_CLK_EN <- 1 */
  840. SYSREG->MSSDDR_FACC1_CR |= (uint32_t)1 << DDR_CLK_EN_SHIFT;
  841. /* CONTROLLER_PLL_INIT <- 0 */
  842. SYSREG->MSSDDR_FACC1_CR = SYSREG->MSSDDR_FACC1_CR & ~CONTROLLER_PLL_INIT_MASK;
  843. }
  844. /*------------------------------------------------------------------------------
  845. Complete clock configuration if requested by Libero.
  846. */
  847. #if (MSS_SYS_FACC_INIT_BY_CORTEX == 1)
  848. static void complete_clock_config(void)
  849. {
  850. uint32_t pll_locked;
  851. /* Wait for fabric PLL to lock. */
  852. do {
  853. pll_locked = SYSREG->MSSDDR_PLL_STATUS & FAB_PLL_LOCK_MASK;
  854. } while(!pll_locked);
  855. /* Negate MPLL bypass. */
  856. SYSREG->MSSDDR_PLL_STATUS_HIGH_CR &= ~FACC_PLL_BYPASS_MASK;
  857. /* Wait for MPLL to lock. */
  858. do {
  859. pll_locked = SYSREG->MSSDDR_PLL_STATUS & MPLL_LOCK_MASK;
  860. } while(!pll_locked);
  861. /* Switch FACC from standby to run mode. */
  862. SYSREG->MSSDDR_FACC1_CR &= ~FACC_GLMUX_SEL_MASK;
  863. /* Negate FPGA_SOFTRESET to de-assert MSS_RESET_N_M2F in the fabric */
  864. SYSREG->SOFT_RST_CR &= ~SYSREG_FPGA_SOFTRESET_MASK;
  865. }
  866. #endif