ddr_init.c 6.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267
  1. /*
  2. * Copyright 2018-2022 NXP
  3. *
  4. * SPDX-License-Identifier: BSD-3-Clause
  5. */
  6. #include <assert.h>
  7. #include <errno.h>
  8. #include <string.h>
  9. #include <common/debug.h>
  10. #include <ddr.h>
  11. #include <lib/utils.h>
  12. #include <errata.h>
  13. #include <platform_def.h>
  14. #ifdef CONFIG_STATIC_DDR
  15. const struct ddr_cfg_regs static_2100 = {
  16. .cs[0].config = U(0x80040322),
  17. .cs[0].bnds = U(0x1FF),
  18. .cs[1].config = U(0x80000322),
  19. .cs[1].bnds = U(0x1FF),
  20. .sdram_cfg[0] = U(0xE5004000),
  21. .sdram_cfg[1] = U(0x401151),
  22. .timing_cfg[0] = U(0xD1770018),
  23. .timing_cfg[1] = U(0xF2FC9245),
  24. .timing_cfg[2] = U(0x594197),
  25. .timing_cfg[3] = U(0x2101100),
  26. .timing_cfg[4] = U(0x220002),
  27. .timing_cfg[5] = U(0x5401400),
  28. .timing_cfg[7] = U(0x26600000),
  29. .timing_cfg[8] = U(0x5446A00),
  30. .dq_map[0] = U(0x32C57554),
  31. .dq_map[1] = U(0xD4BB0BD4),
  32. .dq_map[2] = U(0x2EC2F554),
  33. .dq_map[3] = U(0xD95D4001),
  34. .sdram_mode[0] = U(0x3010631),
  35. .sdram_mode[1] = U(0x100200),
  36. .sdram_mode[9] = U(0x8400000),
  37. .sdram_mode[8] = U(0x500),
  38. .sdram_mode[2] = U(0x10631),
  39. .sdram_mode[3] = U(0x100200),
  40. .sdram_mode[10] = U(0x400),
  41. .sdram_mode[11] = U(0x8400000),
  42. .sdram_mode[4] = U(0x10631),
  43. .sdram_mode[5] = U(0x100200),
  44. .sdram_mode[12] = U(0x400),
  45. .sdram_mode[13] = U(0x8400000),
  46. .sdram_mode[6] = U(0x10631),
  47. .sdram_mode[7] = U(0x100200),
  48. .sdram_mode[14] = U(0x400),
  49. .sdram_mode[15] = U(0x8400000),
  50. .interval = U(0x1FFE07FF),
  51. .zq_cntl = U(0x8A090705),
  52. .clk_cntl = U(0x2000000),
  53. .cdr[0] = U(0x80040000),
  54. .cdr[1] = U(0xC1),
  55. .wrlvl_cntl[0] = U(0x86750609),
  56. .wrlvl_cntl[1] = U(0xA0B0C0D),
  57. .wrlvl_cntl[2] = U(0xF10110E),
  58. };
  59. const struct ddr_cfg_regs static_1800 = {
  60. .cs[0].config = U(0x80040322),
  61. .cs[0].bnds = U(0x1FF),
  62. .cs[1].config = U(0x80000322),
  63. .cs[1].bnds = U(0x1FF),
  64. .sdram_cfg[0] = U(0xE5004000),
  65. .sdram_cfg[1] = U(0x401151),
  66. .timing_cfg[0] = U(0x91660018),
  67. .timing_cfg[1] = U(0xDDD82045),
  68. .timing_cfg[2] = U(0x512153),
  69. .timing_cfg[3] = U(0x10E1100),
  70. .timing_cfg[4] = U(0x220002),
  71. .timing_cfg[5] = U(0x4401400),
  72. .timing_cfg[7] = U(0x14400000),
  73. .timing_cfg[8] = U(0x3335900),
  74. .dq_map[0] = U(0x32C57554),
  75. .dq_map[1] = U(0xD4BB0BD4),
  76. .dq_map[2] = U(0x2EC2F554),
  77. .dq_map[3] = U(0xD95D4001),
  78. .sdram_mode[0] = U(0x3010421),
  79. .sdram_mode[1] = U(0x80200),
  80. .sdram_mode[9] = U(0x4400000),
  81. .sdram_mode[8] = U(0x500),
  82. .sdram_mode[2] = U(0x10421),
  83. .sdram_mode[3] = U(0x80200),
  84. .sdram_mode[10] = U(0x400),
  85. .sdram_mode[11] = U(0x4400000),
  86. .sdram_mode[4] = U(0x10421),
  87. .sdram_mode[5] = U(0x80200),
  88. .sdram_mode[12] = U(0x400),
  89. .sdram_mode[13] = U(0x4400000),
  90. .sdram_mode[6] = U(0x10421),
  91. .sdram_mode[7] = U(0x80200),
  92. .sdram_mode[14] = U(0x400),
  93. .sdram_mode[15] = U(0x4400000),
  94. .interval = U(0x1B6C06DB),
  95. .zq_cntl = U(0x8A090705),
  96. .clk_cntl = U(0x2000000),
  97. .cdr[0] = U(0x80040000),
  98. .cdr[1] = U(0xC1),
  99. .wrlvl_cntl[0] = U(0x86750607),
  100. .wrlvl_cntl[1] = U(0x8090A0B),
  101. .wrlvl_cntl[2] = U(0xD0E0F0C),
  102. };
  103. const struct ddr_cfg_regs static_1600 = {
  104. .cs[0].config = U(0x80040322),
  105. .cs[0].bnds = U(0x1FF),
  106. .cs[1].config = U(0x80000322),
  107. .cs[1].bnds = U(0x1FF),
  108. .sdram_cfg[0] = U(0xE5004000),
  109. .sdram_cfg[1] = U(0x401151),
  110. .sdram_cfg[2] = U(0x0),
  111. .timing_cfg[0] = U(0x91550018),
  112. .timing_cfg[1] = U(0xBAB48E44),
  113. .timing_cfg[2] = U(0x490111),
  114. .timing_cfg[3] = U(0x10C1000),
  115. .timing_cfg[4] = U(0x220002),
  116. .timing_cfg[5] = U(0x3401400),
  117. .timing_cfg[6] = U(0x0),
  118. .timing_cfg[7] = U(0x13300000),
  119. .timing_cfg[8] = U(0x1224800),
  120. .timing_cfg[9] = U(0x0),
  121. .dq_map[0] = U(0x32C57554),
  122. .dq_map[1] = U(0xD4BB0BD4),
  123. .dq_map[2] = U(0x2EC2F554),
  124. .dq_map[3] = U(0xD95D4001),
  125. .sdram_mode[0] = U(0x3010211),
  126. .sdram_mode[1] = U(0x0),
  127. .sdram_mode[9] = U(0x400000),
  128. .sdram_mode[8] = U(0x500),
  129. .sdram_mode[2] = U(0x10211),
  130. .sdram_mode[3] = U(0x0),
  131. .sdram_mode[10] = U(0x400),
  132. .sdram_mode[11] = U(0x400000),
  133. .sdram_mode[4] = U(0x10211),
  134. .sdram_mode[5] = U(0x0),
  135. .sdram_mode[12] = U(0x400),
  136. .sdram_mode[13] = U(0x400000),
  137. .sdram_mode[6] = U(0x10211),
  138. .sdram_mode[7] = U(0x0),
  139. .sdram_mode[14] = U(0x400),
  140. .sdram_mode[15] = U(0x400000),
  141. .interval = U(0x18600618),
  142. .zq_cntl = U(0x8A090705),
  143. .ddr_sr_cntr = U(0x0),
  144. .clk_cntl = U(0x2000000),
  145. .cdr[0] = U(0x80040000),
  146. .cdr[1] = U(0xC1),
  147. .wrlvl_cntl[0] = U(0x86750607),
  148. .wrlvl_cntl[1] = U(0x8090A0B),
  149. .wrlvl_cntl[2] = U(0xD0E0F0C),
  150. };
  151. struct static_table {
  152. unsigned long rate;
  153. const struct ddr_cfg_regs *regs;
  154. };
  155. const struct static_table table[] = {
  156. {1600, &static_1600},
  157. {1800, &static_1800},
  158. {2100, &static_2100},
  159. };
  160. long long board_static_ddr(struct ddr_info *priv)
  161. {
  162. const unsigned long clk = priv->clk / 1000000;
  163. long long size = 0;
  164. int i;
  165. for (i = 0; i < ARRAY_SIZE(table); i++) {
  166. if (table[i].rate >= clk) {
  167. break;
  168. }
  169. }
  170. if (i < ARRAY_SIZE(table)) {
  171. VERBOSE("Found static setting for rate %ld\n", table[i].rate);
  172. memcpy(&priv->ddr_reg, table[i].regs,
  173. sizeof(struct ddr_cfg_regs));
  174. size = 0x200000000UL;
  175. } else {
  176. ERROR("Not static settings for rate %ld\n", clk);
  177. }
  178. return size;
  179. }
  180. #else /* ifndef CONFIG_STATIC_DDR */
  181. static const struct rc_timing rce[] = {
  182. {U(1600), U(8), U(7)},
  183. {U(1867), U(8), U(7)},
  184. {U(2134), U(8), U(9)},
  185. {}
  186. };
  187. static const struct board_timing udimm[] = {
  188. {U(0x04), rce, U(0x01020304), U(0x06070805)},
  189. {U(0x1f), rce, U(0x01020304), U(0x06070805)},
  190. };
  191. int ddr_board_options(struct ddr_info *priv)
  192. {
  193. int ret;
  194. struct memctl_opt *popts = &priv->opt;
  195. if (popts->rdimm) {
  196. debug("RDIMM parameters not set.\n");
  197. return -EINVAL;
  198. }
  199. ret = cal_board_params(priv, udimm, ARRAY_SIZE(udimm));
  200. if (ret != 0) {
  201. return ret;
  202. }
  203. popts->wrlvl_override = U(1);
  204. popts->wrlvl_sample = U(0x0); /* 32 clocks */
  205. popts->cpo_sample = U(0x61);
  206. popts->ddr_cdr1 = DDR_CDR1_DHC_EN |
  207. DDR_CDR1_ODT(DDR_CDR_ODT_80ohm);
  208. popts->ddr_cdr2 = DDR_CDR2_ODT(DDR_CDR_ODT_80ohm) |
  209. DDR_CDR2_VREF_TRAIN_EN |
  210. DDR_CDR2_VREF_RANGE_2;
  211. popts->bstopre = U(0);
  212. return 0;
  213. }
  214. #endif /* ifdef CONFIG_STATIC_DDR */
  215. long long init_ddr(void)
  216. {
  217. int spd_addr[] = {NXP_SPD_EEPROM0};
  218. struct ddr_info info;
  219. struct sysinfo sys;
  220. long long dram_size;
  221. zeromem(&sys, sizeof(sys));
  222. if (get_clocks(&sys)) {
  223. ERROR("System clocks are not set\n");
  224. assert(0);
  225. }
  226. debug("platform clock %lu\n", sys.freq_platform);
  227. debug("DDR PLL1 %lu\n", sys.freq_ddr_pll0);
  228. debug("DDR PLL2 %lu\n", sys.freq_ddr_pll1);
  229. zeromem(&info, sizeof(struct ddr_info));
  230. info.num_ctlrs = U(1);
  231. info.dimm_on_ctlr = U(1);
  232. info.clk = get_ddr_freq(&sys, 0);
  233. info.spd_addr = spd_addr;
  234. info.ddr[0] = (void *)NXP_DDR_ADDR;
  235. dram_size = dram_init(&info);
  236. if (dram_size < 0) {
  237. ERROR("DDR init failed.\n");
  238. }
  239. #ifdef ERRATA_SOC_A008850
  240. erratum_a008850_post();
  241. #endif
  242. return dram_size;
  243. }