ddr_init.c 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254
  1. // SPDX-License-Identifier: GPL-2.0
  2. /*
  3. * Copyright (C) 2020 MediaTek Inc.
  4. *
  5. * Author: Weijie Gao <weijie.gao@mediatek.com>
  6. */
  7. #include <common.h>
  8. #include <linux/bitops.h>
  9. #include <linux/delay.h>
  10. #include <linux/io.h>
  11. #include <linux/sizes.h>
  12. #include <mach/ddr.h>
  13. #include <mach/mc.h>
  14. #define DDR_BW_TEST_PAT 0xaa5555aa
  15. static const u32 sdr_size_cfg1[] = {
  16. [DRAM_8MB] = (1 << NUMROWS_S),
  17. [DRAM_16MB] = (1 << NUMROWS_S) | (1 << NUMCOLS_S),
  18. [DRAM_32MB] = (2 << NUMROWS_S) | (1 << NUMCOLS_S),
  19. [DRAM_64MB] = (2 << NUMROWS_S) | (2 << NUMCOLS_S),
  20. };
  21. static const u32 dram_size[] = {
  22. [DRAM_8MB] = SZ_8M,
  23. [DRAM_16MB] = SZ_16M,
  24. [DRAM_32MB] = SZ_32M,
  25. [DRAM_64MB] = SZ_64M,
  26. [DRAM_128MB] = SZ_128M,
  27. [DRAM_256MB] = SZ_256M,
  28. };
  29. static void dram_test_write(u32 addr, u32 val)
  30. {
  31. volatile ulong *target = (volatile ulong *)(KSEG1 + addr);
  32. sync();
  33. *target = val;
  34. sync();
  35. }
  36. static u32 dram_test_read(u32 addr)
  37. {
  38. volatile ulong *target = (volatile ulong *)(KSEG1 + addr);
  39. u32 val;
  40. sync();
  41. val = *target;
  42. sync();
  43. return val;
  44. }
  45. static int dram_addr_test_bit(u32 bit)
  46. {
  47. u32 val;
  48. dram_test_write(0, 0);
  49. dram_test_write(BIT(bit), DDR_BW_TEST_PAT);
  50. val = dram_test_read(0);
  51. if (val == DDR_BW_TEST_PAT)
  52. return 1;
  53. return 0;
  54. }
  55. static void mc_ddr_init(void __iomem *memc, const struct mc_ddr_cfg *cfg,
  56. u32 dq_dly, u32 dqs_dly, mc_reset_t mc_reset, u32 bw)
  57. {
  58. u32 val;
  59. mc_reset(1);
  60. __udelay(200);
  61. mc_reset(0);
  62. clrbits_32(memc + MEMCTL_SDRAM_CFG1_REG, RBC_MAPPING);
  63. writel(cfg->cfg2, memc + MEMCTL_DDR_CFG2_REG);
  64. writel(cfg->cfg3, memc + MEMCTL_DDR_CFG3_REG);
  65. writel(cfg->cfg4, memc + MEMCTL_DDR_CFG4_REG);
  66. writel(dq_dly, memc + MEMCTL_DDR_DQ_DLY_REG);
  67. writel(dqs_dly, memc + MEMCTL_DDR_DQS_DLY_REG);
  68. writel(cfg->cfg0, memc + MEMCTL_DDR_CFG0_REG);
  69. val = cfg->cfg1;
  70. if (bw) {
  71. val &= ~IND_SDRAM_WIDTH_M;
  72. val |= (bw << IND_SDRAM_WIDTH_S) & IND_SDRAM_WIDTH_M;
  73. }
  74. writel(val, memc + MEMCTL_DDR_CFG1_REG);
  75. clrsetbits_32(memc + MEMCTL_PWR_SAVE_CNT_REG, SR_TAR_CNT_M,
  76. 1 << SR_TAR_CNT_S);
  77. setbits_32(memc + MEMCTL_DDR_SELF_REFRESH_REG, SR_AUTO_EN);
  78. }
  79. void ddr1_init(struct mc_ddr_init_param *param)
  80. {
  81. enum mc_dram_size sz;
  82. u32 bw = 0;
  83. /* First initialization, determine bus width */
  84. mc_ddr_init(param->memc, &param->cfgs[DRAM_8MB], param->dq_dly,
  85. param->dqs_dly, param->mc_reset, IND_SDRAM_WIDTH_16BIT);
  86. /* Test bus width */
  87. dram_test_write(0, DDR_BW_TEST_PAT);
  88. if (dram_test_read(0) == DDR_BW_TEST_PAT)
  89. bw = IND_SDRAM_WIDTH_16BIT;
  90. else
  91. bw = IND_SDRAM_WIDTH_8BIT;
  92. /* Second initialization, determine DDR capacity */
  93. mc_ddr_init(param->memc, &param->cfgs[DRAM_128MB], param->dq_dly,
  94. param->dqs_dly, param->mc_reset, bw);
  95. if (dram_addr_test_bit(9)) {
  96. sz = DRAM_8MB;
  97. } else {
  98. if (dram_addr_test_bit(10)) {
  99. if (dram_addr_test_bit(23))
  100. sz = DRAM_16MB;
  101. else
  102. sz = DRAM_32MB;
  103. } else {
  104. if (dram_addr_test_bit(24))
  105. sz = DRAM_64MB;
  106. else
  107. sz = DRAM_128MB;
  108. }
  109. }
  110. /* Final initialization, with DDR calibration */
  111. mc_ddr_init(param->memc, &param->cfgs[sz], param->dq_dly,
  112. param->dqs_dly, param->mc_reset, bw);
  113. /* Return actual DDR configuration */
  114. param->memsize = dram_size[sz];
  115. param->bus_width = bw;
  116. }
  117. void ddr2_init(struct mc_ddr_init_param *param)
  118. {
  119. enum mc_dram_size sz;
  120. u32 bw = 0;
  121. /* First initialization, determine bus width */
  122. mc_ddr_init(param->memc, &param->cfgs[DRAM_32MB], param->dq_dly,
  123. param->dqs_dly, param->mc_reset, IND_SDRAM_WIDTH_16BIT);
  124. /* Test bus width */
  125. dram_test_write(0, DDR_BW_TEST_PAT);
  126. if (dram_test_read(0) == DDR_BW_TEST_PAT)
  127. bw = IND_SDRAM_WIDTH_16BIT;
  128. else
  129. bw = IND_SDRAM_WIDTH_8BIT;
  130. /* Second initialization, determine DDR capacity */
  131. mc_ddr_init(param->memc, &param->cfgs[DRAM_256MB], param->dq_dly,
  132. param->dqs_dly, param->mc_reset, bw);
  133. if (bw == IND_SDRAM_WIDTH_16BIT) {
  134. if (dram_addr_test_bit(10)) {
  135. sz = DRAM_32MB;
  136. } else {
  137. if (dram_addr_test_bit(24)) {
  138. if (dram_addr_test_bit(27))
  139. sz = DRAM_64MB;
  140. else
  141. sz = DRAM_128MB;
  142. } else {
  143. sz = DRAM_256MB;
  144. }
  145. }
  146. } else {
  147. if (dram_addr_test_bit(23)) {
  148. sz = DRAM_32MB;
  149. } else {
  150. if (dram_addr_test_bit(24)) {
  151. if (dram_addr_test_bit(27))
  152. sz = DRAM_64MB;
  153. else
  154. sz = DRAM_128MB;
  155. } else {
  156. sz = DRAM_256MB;
  157. }
  158. }
  159. }
  160. /* Final initialization, with DDR calibration */
  161. mc_ddr_init(param->memc, &param->cfgs[sz], param->dq_dly,
  162. param->dqs_dly, param->mc_reset, bw);
  163. /* Return actual DDR configuration */
  164. param->memsize = dram_size[sz];
  165. param->bus_width = bw;
  166. }
  167. static void mc_sdr_init(void __iomem *memc, mc_reset_t mc_reset, u32 cfg0,
  168. u32 cfg1)
  169. {
  170. mc_reset(1);
  171. __udelay(200);
  172. mc_reset(0);
  173. writel(cfg0, memc + MEMCTL_SDRAM_CFG0_REG);
  174. writel(cfg1, memc + MEMCTL_SDRAM_CFG1_REG);
  175. while (!(readl(memc + MEMCTL_SDRAM_CFG1_REG) & SDRAM_INIT_DONE))
  176. ;
  177. clrsetbits_32(memc + MEMCTL_PWR_SAVE_CNT_REG, SR_TAR_CNT_M,
  178. 1 << SR_TAR_CNT_S);
  179. setbits_32(memc + MEMCTL_DDR_SELF_REFRESH_REG, SR_AUTO_EN);
  180. }
  181. void sdr_init(struct mc_ddr_init_param *param)
  182. {
  183. enum mc_dram_size sz;
  184. u32 cfg1;
  185. cfg1 = param->sdr_cfg1 | SDRAM_INIT_START;
  186. cfg1 &= ~(NUMCOLS_M | NUMROWS_M);
  187. /* First initialization, determine SDR capacity */
  188. mc_sdr_init(param->memc, param->mc_reset, param->sdr_cfg0,
  189. cfg1 | sdr_size_cfg1[DRAM_64MB]);
  190. if (dram_addr_test_bit(9)) {
  191. sz = DRAM_8MB;
  192. } else {
  193. if (dram_addr_test_bit(10)) {
  194. if (dram_addr_test_bit(23))
  195. sz = DRAM_16MB;
  196. else
  197. sz = DRAM_32MB;
  198. } else {
  199. sz = DRAM_64MB;
  200. }
  201. }
  202. /* Final initialization */
  203. mc_sdr_init(param->memc, param->mc_reset, param->sdr_cfg0,
  204. cfg1 | sdr_size_cfg1[sz]);
  205. /* Return actual DDR configuration */
  206. param->memsize = dram_size[sz];
  207. }