ddr_init.c 8.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354
  1. /*
  2. * Copyright 2018-2021 NXP
  3. *
  4. * SPDX-License-Identifier: BSD-3-Clause
  5. *
  6. */
  7. #include <assert.h>
  8. #include <errno.h>
  9. #include <stdbool.h>
  10. #include <stdint.h>
  11. #include <stdio.h>
  12. #include <stdlib.h>
  13. #include <string.h>
  14. #include <common/debug.h>
  15. #include <ddr.h>
  16. #include <lib/utils.h>
  17. #include <load_img.h>
  18. #include "plat_common.h"
  19. #include <platform_def.h>
  20. #ifdef CONFIG_STATIC_DDR
  21. const struct ddr_cfg_regs static_3200 = {
  22. .cs[0].bnds = U(0x03FFU),
  23. .cs[1].bnds = U(0x03FF),
  24. .cs[0].config = U(0x80050422),
  25. .cs[1].config = U(0x80000422),
  26. .cs[2].bnds = U(0x00),
  27. .cs[3].bnds = U(0x00),
  28. .cs[2].config = U(0x00),
  29. .cs[3].config = U(0x00),
  30. .timing_cfg[0] = U(0xFFAA0018),
  31. .timing_cfg[1] = U(0x646A8844),
  32. .timing_cfg[2] = U(0x00058022),
  33. .timing_cfg[3] = U(0x13622100),
  34. .timing_cfg[4] = U(0x02),
  35. .timing_cfg[5] = U(0x07401400),
  36. .timing_cfg[7] = U(0x3BB00000),
  37. .timing_cfg[8] = U(0x0944AC00),
  38. .sdram_cfg[0] = U(0x65044008),
  39. .sdram_cfg[1] = U(0x00401011),
  40. .sdram_cfg[2] = U(0x00),
  41. .sdram_mode[0] = U(0x06010C50),
  42. .sdram_mode[1] = U(0x00280400),
  43. .sdram_mode[2] = U(0x00),
  44. .sdram_mode[3] = U(0x00),
  45. .sdram_mode[4] = U(0x00),
  46. .sdram_mode[5] = U(0x00),
  47. .sdram_mode[6] = U(0x00),
  48. .sdram_mode[7] = U(0x00),
  49. .sdram_mode[8] = U(0x0500),
  50. .sdram_mode[9] = U(0x10240000),
  51. .sdram_mode[10] = U(0x00),
  52. .sdram_mode[11] = U(0x00),
  53. .sdram_mode[12] = U(0x00),
  54. .sdram_mode[13] = U(0x00),
  55. .sdram_mode[14] = U(0x00),
  56. .sdram_mode[15] = U(0x00),
  57. .md_cntl = U(0x00),
  58. .interval = U(0x30C00000),
  59. .data_init = U(0xDEADBEEF),
  60. .init_addr = U(0x00),
  61. .zq_cntl = U(0x8A090705),
  62. .sdram_rcw[0] = U(0x00),
  63. .sdram_rcw[1] = U(0x00),
  64. .sdram_rcw[2] = U(0x00),
  65. .sdram_rcw[3] = U(0x00),
  66. .sdram_rcw[4] = U(0x00),
  67. .sdram_rcw[5] = U(0x00),
  68. .err_disable = U(0x00),
  69. .err_int_en = U(0x00),
  70. };
  71. const struct ddr_cfg_regs static_2900 = {
  72. .cs[0].bnds = U(0x03FF),
  73. .cs[1].bnds = U(0x03FF),
  74. .cs[0].config = U(0x80050422),
  75. .cs[1].config = U(0x80000422),
  76. .cs[2].bnds = U(0x00),
  77. .cs[3].bnds = U(0x00),
  78. .cs[2].config = U(0x00),
  79. .cs[3].config = U(0x00),
  80. .timing_cfg[0] = U(0xFF990018),
  81. .timing_cfg[1] = U(0x4F4A4844),
  82. .timing_cfg[2] = U(0x0005601F),
  83. .timing_cfg[3] = U(0x125F2100),
  84. .timing_cfg[4] = U(0x02),
  85. .timing_cfg[5] = U(0x07401400),
  86. .timing_cfg[7] = U(0x3AA00000),
  87. .timing_cfg[8] = U(0x09449B00),
  88. .sdram_cfg[0] = U(0x65044008),
  89. .sdram_cfg[1] = U(0x00401011),
  90. .sdram_cfg[2] = U(0x00),
  91. .sdram_mode[0] = U(0x06010C50),
  92. .sdram_mode[1] = U(0x00280400),
  93. .sdram_mode[2] = U(0x00),
  94. .sdram_mode[3] = U(0x00),
  95. .sdram_mode[4] = U(0x00),
  96. .sdram_mode[5] = U(0x00),
  97. .sdram_mode[6] = U(0x00),
  98. .sdram_mode[7] = U(0x00),
  99. .sdram_mode[8] = U(0x0500),
  100. .sdram_mode[9] = U(0x10240000),
  101. .sdram_mode[10] = U(0x00),
  102. .sdram_mode[11] = U(0x00),
  103. .sdram_mode[12] = U(0x00),
  104. .sdram_mode[13] = U(0x00),
  105. .sdram_mode[14] = U(0x00),
  106. .sdram_mode[15] = U(0x00),
  107. .md_cntl = U(0x00),
  108. .interval = U(0x2C2E0000),
  109. .data_init = U(0xDEADBEEF),
  110. .init_addr = U(0x00),
  111. .zq_cntl = U(0x8A090705),
  112. .sdram_rcw[0] = U(0x00),
  113. .sdram_rcw[1] = U(0x00),
  114. .sdram_rcw[2] = U(0x00),
  115. .sdram_rcw[3] = U(0x00),
  116. .sdram_rcw[4] = U(0x00),
  117. .sdram_rcw[5] = U(0x00),
  118. .err_disable = U(0x00),
  119. .err_int_en = U(0x00),
  120. };
  121. const struct ddr_cfg_regs static_2600 = {
  122. .cs[0].bnds = U(0x03FF),
  123. .cs[1].bnds = U(0x03FF),
  124. .cs[0].config = U(0x80050422),
  125. .cs[1].config = U(0x80000422),
  126. .cs[2].bnds = U(0x00),
  127. .cs[3].bnds = U(0x00),
  128. .cs[2].config = U(0x00),
  129. .cs[3].config = U(0x00),
  130. .timing_cfg[0] = U(0xFF880018),
  131. .timing_cfg[1] = U(0x2A24F444),
  132. .timing_cfg[2] = U(0x007141DC),
  133. .timing_cfg[3] = U(0x125B2100),
  134. .timing_cfg[4] = U(0x02),
  135. .timing_cfg[5] = U(0x06401400),
  136. .timing_cfg[7] = U(0x28800000),
  137. .timing_cfg[8] = U(0x07338A00),
  138. .sdram_cfg[0] = U(0x65044008),
  139. .sdram_cfg[1] = U(0x00401011),
  140. .sdram_cfg[2] = U(0x00),
  141. .sdram_mode[0] = U(0x06010A70),
  142. .sdram_mode[1] = U(0x00200400),
  143. .sdram_mode[2] = U(0x00),
  144. .sdram_mode[3] = U(0x00),
  145. .sdram_mode[4] = U(0x00),
  146. .sdram_mode[5] = U(0x00),
  147. .sdram_mode[6] = U(0x00),
  148. .sdram_mode[7] = U(0x00),
  149. .sdram_mode[8] = U(0x0500),
  150. .sdram_mode[9] = U(0x0C240000),
  151. .sdram_mode[10] = U(0x00),
  152. .sdram_mode[11] = U(0x00),
  153. .sdram_mode[12] = U(0x00),
  154. .sdram_mode[13] = U(0x00),
  155. .sdram_mode[14] = U(0x00),
  156. .sdram_mode[15] = U(0x00),
  157. .md_cntl = U(0x00),
  158. .interval = U(0x279C0000),
  159. .data_init = U(0xDEADBEEF),
  160. .init_addr = U(0x00),
  161. .zq_cntl = U(0x8A090705),
  162. .sdram_rcw[0] = U(0x00),
  163. .sdram_rcw[1] = U(0x00),
  164. .sdram_rcw[2] = U(0x00),
  165. .sdram_rcw[3] = U(0x00),
  166. .sdram_rcw[4] = U(0x00),
  167. .sdram_rcw[5] = U(0x00),
  168. .err_disable = U(0x00),
  169. .err_int_en = U(0x00),
  170. };
  171. const struct dimm_params static_dimm = {
  172. .rdimm = 0U,
  173. .primary_sdram_width = 64U,
  174. .ec_sdram_width = 8U,
  175. .n_ranks = 2U,
  176. .device_width = 8U,
  177. .mirrored_dimm = 1U,
  178. };
  179. /* Sample code using two UDIMM MT18ASF1G72AZ-2G6B1, on each DDR controller */
  180. unsigned long long board_static_ddr(struct ddr_info *priv)
  181. {
  182. memcpy(&priv->ddr_reg, &static_2900, sizeof(static_2900));
  183. memcpy(&priv->dimm, &static_dimm, sizeof(static_dimm));
  184. priv->conf.cs_on_dimm[0] = 0x3;
  185. ddr_board_options(priv);
  186. compute_ddr_phy(priv);
  187. return ULL(0x400000000);
  188. }
  189. #elif defined(CONFIG_DDR_NODIMM)
  190. /*
  191. * Sample code to bypass reading SPD. This is a sample, not recommended
  192. * for boards with slots. DDR model number: UDIMM MT18ASF1G72AZ-2G6B1.
  193. */
  194. struct dimm_params ddr_raw_timing = {
  195. .n_ranks = 2U,
  196. .rank_density = U(0x200000000),
  197. .capacity = U(0x400000000),
  198. .primary_sdram_width = 64U,
  199. .ec_sdram_width = 8U,
  200. .device_width = 8U,
  201. .die_density = U(0x5),
  202. .rdimm = 0U,
  203. .mirrored_dimm = 1U,
  204. .n_row_addr = 16U,
  205. .n_col_addr = 10U,
  206. .bank_addr_bits = 0U,
  207. .bank_group_bits = 2U,
  208. .edc_config = 2U,
  209. .burst_lengths_bitmask = U(0x0c),
  210. .tckmin_x_ps = 625,
  211. .tckmax_ps = 1600,
  212. .caslat_x = U(0x15FFFC00),
  213. .taa_ps = 13750,
  214. .trcd_ps = 13750,
  215. .trp_ps = 13750,
  216. .tras_ps = 32000,
  217. .trc_ps = 457500,
  218. .twr_ps = 15000,
  219. .trfc1_ps = 350000,
  220. .trfc2_ps = 260000,
  221. .trfc4_ps = 160000,
  222. .tfaw_ps = 21000,
  223. .trrds_ps = 2500,
  224. .trrdl_ps = 4900,
  225. .tccdl_ps = 5000,
  226. .refresh_rate_ps = 7800000U,
  227. };
  228. int ddr_get_ddr_params(struct dimm_params *pdimm,
  229. struct ddr_conf *conf)
  230. {
  231. static const char dimm_model[] = "Fixed DDR on board";
  232. conf->dimm_in_use[0] = 1; /* Modify accordingly */
  233. memcpy(pdimm, &ddr_raw_timing, sizeof(struct dimm_params));
  234. memcpy(pdimm->mpart, dimm_model, sizeof(dimm_model) - 1);
  235. /* valid DIMM mask, change accordingly, together with dimm_on_ctlr. */
  236. return 0x5;
  237. }
  238. #endif /* CONFIG_DDR_NODIMM */
  239. int ddr_board_options(struct ddr_info *priv)
  240. {
  241. struct memctl_opt *popts = &priv->opt;
  242. const struct ddr_conf *conf = &priv->conf;
  243. popts->vref_dimm = U(0x19); /* range 1, 83.4% */
  244. popts->rtt_override = 1U;
  245. popts->rtt_override_value = 0x5U; /* RTT being used as 60 ohm */
  246. popts->rtt_park = 120U;
  247. popts->otf_burst_chop_en = 0;
  248. popts->burst_length = DDR_BL8;
  249. popts->trwt_override = 1U;
  250. popts->bstopre = 0U; /* auto precharge */
  251. popts->addr_hash = 1;
  252. /* Set ODT impedance on PHY side */
  253. switch (conf->cs_on_dimm[1]) {
  254. case 0xc: /* Two slots dual rank */
  255. case 0x4: /* Two slots single rank, not valid for interleaving */
  256. popts->trwt = U(0xf);
  257. popts->twrt = U(0x7);
  258. popts->trrt = U(0x7);
  259. popts->twwt = U(0x7);
  260. popts->vref_phy = U(0x6B); /* 83.6% */
  261. popts->odt = 60U;
  262. popts->phy_tx_impedance = 28U;
  263. break;
  264. case 0: /* Ont slot used */
  265. default:
  266. popts->trwt = U(0x3);
  267. popts->twrt = U(0x3);
  268. popts->trrt = U(0x3);
  269. popts->twwt = U(0x3);
  270. popts->vref_phy = U(0x5D); /* 72% */
  271. popts->odt = 60U;
  272. popts->phy_tx_impedance = 28U;
  273. break;
  274. }
  275. return 0;
  276. }
  277. #ifdef NXP_WARM_BOOT
  278. long long init_ddr(uint32_t wrm_bt_flg)
  279. #else
  280. long long init_ddr(void)
  281. #endif
  282. {
  283. int spd_addr[] = { 0x51, 0x52, 0x53, 0x54 };
  284. struct ddr_info info;
  285. struct sysinfo sys;
  286. long long dram_size;
  287. zeromem(&sys, sizeof(sys));
  288. if (get_clocks(&sys) != 0) {
  289. ERROR("System clocks are not set\n");
  290. panic();
  291. }
  292. debug("platform clock %lu\n", sys.freq_platform);
  293. debug("DDR PLL1 %lu\n", sys.freq_ddr_pll0);
  294. debug("DDR PLL2 %lu\n", sys.freq_ddr_pll1);
  295. zeromem(&info, sizeof(info));
  296. /* Set two DDRC. Unused DDRC will be removed automatically. */
  297. info.num_ctlrs = NUM_OF_DDRC;
  298. info.spd_addr = spd_addr;
  299. info.ddr[0] = (void *)NXP_DDR_ADDR;
  300. info.ddr[1] = (void *)NXP_DDR2_ADDR;
  301. info.phy[0] = (void *)NXP_DDR_PHY1_ADDR;
  302. info.phy[1] = (void *)NXP_DDR_PHY2_ADDR;
  303. info.clk = get_ddr_freq(&sys, 0);
  304. info.img_loadr = load_img;
  305. info.phy_gen2_fw_img_buf = PHY_GEN2_FW_IMAGE_BUFFER;
  306. if (info.clk == 0) {
  307. info.clk = get_ddr_freq(&sys, 1);
  308. }
  309. info.dimm_on_ctlr = DDRC_NUM_DIMM;
  310. info.warm_boot_flag = DDR_WRM_BOOT_NT_SUPPORTED;
  311. #ifdef NXP_WARM_BOOT
  312. if (wrm_bt_flg != 0) {
  313. info.warm_boot_flag = DDR_WARM_BOOT;
  314. } else {
  315. info.warm_boot_flag = DDR_COLD_BOOT;
  316. }
  317. #endif
  318. dram_size = dram_init(&info
  319. #if defined(NXP_HAS_CCN504) || defined(NXP_HAS_CCN508)
  320. , NXP_CCN_HN_F_0_ADDR
  321. #endif
  322. );
  323. if (dram_size < 0) {
  324. ERROR("DDR init failed.\n");
  325. }
  326. return dram_size;
  327. }