ddr_init.c 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194
  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/io.h>
  10. #include <linux/sizes.h>
  11. #include <mach/ddr.h>
  12. #include <mach/mc.h>
  13. #define DDR_BW_TEST_PAT 0xaa5555aa
  14. static const u32 dram_size[] = {
  15. [DRAM_8MB] = SZ_8M,
  16. [DRAM_16MB] = SZ_16M,
  17. [DRAM_32MB] = SZ_32M,
  18. [DRAM_64MB] = SZ_64M,
  19. [DRAM_128MB] = SZ_128M,
  20. [DRAM_256MB] = SZ_256M,
  21. };
  22. static void dram_test_write(u32 addr, u32 val)
  23. {
  24. volatile ulong *target = (volatile ulong *)(KSEG1 + addr);
  25. sync();
  26. *target = val;
  27. sync();
  28. }
  29. static u32 dram_test_read(u32 addr)
  30. {
  31. volatile ulong *target = (volatile ulong *)(KSEG1 + addr);
  32. u32 val;
  33. sync();
  34. val = *target;
  35. sync();
  36. return val;
  37. }
  38. static int dram_addr_test_bit(u32 bit)
  39. {
  40. u32 val;
  41. dram_test_write(0, 0);
  42. dram_test_write(BIT(bit), DDR_BW_TEST_PAT);
  43. val = dram_test_read(0);
  44. if (val == DDR_BW_TEST_PAT)
  45. return 1;
  46. return 0;
  47. }
  48. static void mc_ddr_init(void __iomem *memc, const struct mc_ddr_cfg *cfg,
  49. u32 dq_dly, u32 dqs_dly, mc_reset_t mc_reset, u32 bw)
  50. {
  51. u32 val;
  52. mc_reset(1);
  53. __udelay(200);
  54. mc_reset(0);
  55. clrbits_32(memc + MEMCTL_SDRAM_CFG1_REG, RBC_MAPPING);
  56. writel(cfg->cfg2, memc + MEMCTL_DDR_CFG2_REG);
  57. writel(cfg->cfg3, memc + MEMCTL_DDR_CFG3_REG);
  58. writel(cfg->cfg4, memc + MEMCTL_DDR_CFG4_REG);
  59. writel(dq_dly, memc + MEMCTL_DDR_DQ_DLY_REG);
  60. writel(dqs_dly, memc + MEMCTL_DDR_DQS_DLY_REG);
  61. writel(cfg->cfg0, memc + MEMCTL_DDR_CFG0_REG);
  62. val = cfg->cfg1;
  63. if (bw) {
  64. val &= ~IND_SDRAM_WIDTH_M;
  65. val |= (bw << IND_SDRAM_WIDTH_S) & IND_SDRAM_WIDTH_M;
  66. }
  67. writel(val, memc + MEMCTL_DDR_CFG1_REG);
  68. clrsetbits_32(memc + MEMCTL_PWR_SAVE_CNT_REG, SR_TAR_CNT_M,
  69. 1 << SR_TAR_CNT_S);
  70. setbits_32(memc + MEMCTL_DDR_SELF_REFRESH_REG, SR_AUTO_EN);
  71. }
  72. void ddr1_init(struct mc_ddr_init_param *param)
  73. {
  74. enum mc_dram_size sz;
  75. u32 bw = 0;
  76. /* First initialization, determine bus width */
  77. mc_ddr_init(param->memc, &param->cfgs[DRAM_8MB], param->dq_dly,
  78. param->dqs_dly, param->mc_reset, IND_SDRAM_WIDTH_16BIT);
  79. /* Test bus width */
  80. dram_test_write(0, DDR_BW_TEST_PAT);
  81. if (dram_test_read(0) == DDR_BW_TEST_PAT)
  82. bw = IND_SDRAM_WIDTH_16BIT;
  83. else
  84. bw = IND_SDRAM_WIDTH_8BIT;
  85. /* Second initialization, determine DDR capacity */
  86. mc_ddr_init(param->memc, &param->cfgs[DRAM_128MB], param->dq_dly,
  87. param->dqs_dly, param->mc_reset, bw);
  88. if (dram_addr_test_bit(9)) {
  89. sz = DRAM_8MB;
  90. } else {
  91. if (dram_addr_test_bit(10)) {
  92. if (dram_addr_test_bit(23))
  93. sz = DRAM_16MB;
  94. else
  95. sz = DRAM_32MB;
  96. } else {
  97. if (dram_addr_test_bit(24))
  98. sz = DRAM_64MB;
  99. else
  100. sz = DRAM_128MB;
  101. }
  102. }
  103. /* Final initialization, with DDR calibration */
  104. mc_ddr_init(param->memc, &param->cfgs[sz], param->dq_dly,
  105. param->dqs_dly, param->mc_reset, bw);
  106. /* Return actual DDR configuration */
  107. param->memsize = dram_size[sz];
  108. param->bus_width = bw;
  109. }
  110. void ddr2_init(struct mc_ddr_init_param *param)
  111. {
  112. enum mc_dram_size sz;
  113. u32 bw = 0;
  114. /* First initialization, determine bus width */
  115. mc_ddr_init(param->memc, &param->cfgs[DRAM_32MB], param->dq_dly,
  116. param->dqs_dly, param->mc_reset, IND_SDRAM_WIDTH_16BIT);
  117. /* Test bus width */
  118. dram_test_write(0, DDR_BW_TEST_PAT);
  119. if (dram_test_read(0) == DDR_BW_TEST_PAT)
  120. bw = IND_SDRAM_WIDTH_16BIT;
  121. else
  122. bw = IND_SDRAM_WIDTH_8BIT;
  123. /* Second initialization, determine DDR capacity */
  124. mc_ddr_init(param->memc, &param->cfgs[DRAM_256MB], param->dq_dly,
  125. param->dqs_dly, param->mc_reset, bw);
  126. if (bw == IND_SDRAM_WIDTH_16BIT) {
  127. if (dram_addr_test_bit(10)) {
  128. sz = DRAM_32MB;
  129. } else {
  130. if (dram_addr_test_bit(24)) {
  131. if (dram_addr_test_bit(27))
  132. sz = DRAM_64MB;
  133. else
  134. sz = DRAM_128MB;
  135. } else {
  136. sz = DRAM_256MB;
  137. }
  138. }
  139. } else {
  140. if (dram_addr_test_bit(23)) {
  141. sz = DRAM_32MB;
  142. } else {
  143. if (dram_addr_test_bit(24)) {
  144. if (dram_addr_test_bit(27))
  145. sz = DRAM_64MB;
  146. else
  147. sz = DRAM_128MB;
  148. } else {
  149. sz = DRAM_256MB;
  150. }
  151. }
  152. }
  153. /* Final initialization, with DDR calibration */
  154. mc_ddr_init(param->memc, &param->cfgs[sz], param->dq_dly,
  155. param->dqs_dly, param->mc_reset, bw);
  156. /* Return actual DDR configuration */
  157. param->memsize = dram_size[sz];
  158. param->bus_width = bw;
  159. }