mpddrc.c 6.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229
  1. // SPDX-License-Identifier: GPL-2.0+
  2. /*
  3. * Copyright (C) 2013 Atmel Corporation
  4. * Bo Shen <voice.shen@atmel.com>
  5. *
  6. * Copyright (C) 2015 Atmel Corporation
  7. * Wenyou Yang <wenyou.yang@atmel.com>
  8. */
  9. #include <common.h>
  10. #include <asm/io.h>
  11. #include <asm/arch/atmel_mpddrc.h>
  12. #define SAMA5D3_MPDDRC_VERSION 0x140
  13. static inline void atmel_mpddr_op(const struct atmel_mpddr *mpddr,
  14. int mode,
  15. u32 ram_address)
  16. {
  17. writel(mode, &mpddr->mr);
  18. writel(0, ram_address);
  19. }
  20. static int ddr2_decodtype_is_seq(const unsigned int base, u32 cr)
  21. {
  22. struct atmel_mpddr *mpddr = (struct atmel_mpddr *)base;
  23. u16 version = readl(&mpddr->version) & 0xffff;
  24. if ((version >= SAMA5D3_MPDDRC_VERSION) &&
  25. (cr & ATMEL_MPDDRC_CR_DECOD_INTERLEAVED))
  26. return 0;
  27. return 1;
  28. }
  29. int ddr2_init(const unsigned int base,
  30. const unsigned int ram_address,
  31. const struct atmel_mpddrc_config *mpddr_value)
  32. {
  33. const struct atmel_mpddr *mpddr = (struct atmel_mpddr *)base;
  34. u32 ba_off, cr;
  35. /* Compute bank offset according to NC in configuration register */
  36. ba_off = (mpddr_value->cr & ATMEL_MPDDRC_CR_NC_MASK) + 9;
  37. if (ddr2_decodtype_is_seq(base, mpddr_value->cr))
  38. ba_off += ((mpddr_value->cr & ATMEL_MPDDRC_CR_NR_MASK) >> 2) + 11;
  39. ba_off += (mpddr_value->md & ATMEL_MPDDRC_MD_DBW_MASK) ? 1 : 2;
  40. /* Program the memory device type into the memory device register */
  41. writel(mpddr_value->md, &mpddr->md);
  42. /* Program the configuration register */
  43. writel(mpddr_value->cr, &mpddr->cr);
  44. /* Program the timing register */
  45. writel(mpddr_value->tpr0, &mpddr->tpr0);
  46. writel(mpddr_value->tpr1, &mpddr->tpr1);
  47. writel(mpddr_value->tpr2, &mpddr->tpr2);
  48. /* Issue a NOP command */
  49. atmel_mpddr_op(mpddr, ATMEL_MPDDRC_MR_MODE_NOP_CMD, ram_address);
  50. /* A 200 us is provided to precede any signal toggle */
  51. udelay(200);
  52. /* Issue a NOP command */
  53. atmel_mpddr_op(mpddr, ATMEL_MPDDRC_MR_MODE_NOP_CMD, ram_address);
  54. /* Issue an all banks precharge command */
  55. atmel_mpddr_op(mpddr, ATMEL_MPDDRC_MR_MODE_PRCGALL_CMD, ram_address);
  56. /* Issue an extended mode register set(EMRS2) to choose operation */
  57. atmel_mpddr_op(mpddr, ATMEL_MPDDRC_MR_MODE_EXT_LMR_CMD,
  58. ram_address + (0x2 << ba_off));
  59. /* Issue an extended mode register set(EMRS3) to set EMSR to 0 */
  60. atmel_mpddr_op(mpddr, ATMEL_MPDDRC_MR_MODE_EXT_LMR_CMD,
  61. ram_address + (0x3 << ba_off));
  62. /*
  63. * Issue an extended mode register set(EMRS1) to enable DLL and
  64. * program D.I.C (output driver impedance control)
  65. */
  66. atmel_mpddr_op(mpddr, ATMEL_MPDDRC_MR_MODE_EXT_LMR_CMD,
  67. ram_address + (0x1 << ba_off));
  68. /* Enable DLL reset */
  69. cr = readl(&mpddr->cr);
  70. writel(cr | ATMEL_MPDDRC_CR_DLL_RESET_ENABLED, &mpddr->cr);
  71. /* A mode register set(MRS) cycle is issued to reset DLL */
  72. atmel_mpddr_op(mpddr, ATMEL_MPDDRC_MR_MODE_LMR_CMD, ram_address);
  73. /* Issue an all banks precharge command */
  74. atmel_mpddr_op(mpddr, ATMEL_MPDDRC_MR_MODE_PRCGALL_CMD, ram_address);
  75. /* Two auto-refresh (CBR) cycles are provided */
  76. atmel_mpddr_op(mpddr, ATMEL_MPDDRC_MR_MODE_RFSH_CMD, ram_address);
  77. atmel_mpddr_op(mpddr, ATMEL_MPDDRC_MR_MODE_RFSH_CMD, ram_address);
  78. /* Disable DLL reset */
  79. cr = readl(&mpddr->cr);
  80. writel(cr & (~ATMEL_MPDDRC_CR_DLL_RESET_ENABLED), &mpddr->cr);
  81. /* A mode register set (MRS) cycle is issued to disable DLL reset */
  82. atmel_mpddr_op(mpddr, ATMEL_MPDDRC_MR_MODE_LMR_CMD, ram_address);
  83. /* Set OCD calibration in default state */
  84. cr = readl(&mpddr->cr);
  85. writel(cr | ATMEL_MPDDRC_CR_OCD_DEFAULT, &mpddr->cr);
  86. /*
  87. * An extended mode register set (EMRS1) cycle is issued
  88. * to OCD default value
  89. */
  90. atmel_mpddr_op(mpddr, ATMEL_MPDDRC_MR_MODE_EXT_LMR_CMD,
  91. ram_address + (0x1 << ba_off));
  92. /* OCD calibration mode exit */
  93. cr = readl(&mpddr->cr);
  94. writel(cr & (~ATMEL_MPDDRC_CR_OCD_DEFAULT), &mpddr->cr);
  95. /*
  96. * An extended mode register set (EMRS1) cycle is issued
  97. * to enable OCD exit
  98. */
  99. atmel_mpddr_op(mpddr, ATMEL_MPDDRC_MR_MODE_EXT_LMR_CMD,
  100. ram_address + (0x1 << ba_off));
  101. /* A nornal mode command is provided */
  102. atmel_mpddr_op(mpddr, ATMEL_MPDDRC_MR_MODE_NORMAL_CMD, ram_address);
  103. /* Perform a write access to any DDR2-SDRAM address */
  104. writel(0, ram_address);
  105. /* Write the refresh rate */
  106. writel(mpddr_value->rtr, &mpddr->rtr);
  107. return 0;
  108. }
  109. int ddr3_init(const unsigned int base,
  110. const unsigned int ram_address,
  111. const struct atmel_mpddrc_config *mpddr_value)
  112. {
  113. struct atmel_mpddr *mpddr = (struct atmel_mpddr *)base;
  114. u32 ba_off;
  115. /* Compute bank offset according to NC in configuration register */
  116. ba_off = (mpddr_value->cr & ATMEL_MPDDRC_CR_NC_MASK) + 9;
  117. if (ddr2_decodtype_is_seq(base, mpddr_value->cr))
  118. ba_off += ((mpddr_value->cr &
  119. ATMEL_MPDDRC_CR_NR_MASK) >> 2) + 11;
  120. ba_off += (mpddr_value->md & ATMEL_MPDDRC_MD_DBW_MASK) ? 1 : 2;
  121. /* Program the memory device type */
  122. writel(mpddr_value->md, &mpddr->md);
  123. /*
  124. * Program features of the DDR3-SDRAM device and timing parameters
  125. */
  126. writel(mpddr_value->cr, &mpddr->cr);
  127. writel(mpddr_value->tpr0, &mpddr->tpr0);
  128. writel(mpddr_value->tpr1, &mpddr->tpr1);
  129. writel(mpddr_value->tpr2, &mpddr->tpr2);
  130. /* A NOP command is issued to the DDR3-SRAM */
  131. atmel_mpddr_op(mpddr, ATMEL_MPDDRC_MR_MODE_NOP_CMD, ram_address);
  132. /* A pause of at least 500us must be observed before a single toggle. */
  133. udelay(500);
  134. /* A NOP command is issued to the DDR3-SDRAM */
  135. atmel_mpddr_op(mpddr, ATMEL_MPDDRC_MR_MODE_NOP_CMD, ram_address);
  136. /*
  137. * An Extended Mode Register Set (EMRS2) cycle is issued to choose
  138. * between commercial or high temperature operations.
  139. */
  140. atmel_mpddr_op(mpddr, ATMEL_MPDDRC_MR_MODE_EXT_LMR_CMD,
  141. ram_address + (0x2 << ba_off));
  142. /*
  143. * Step 7: An Extended Mode Register Set (EMRS3) cycle is issued to set
  144. * the Extended Mode Register to 0.
  145. */
  146. atmel_mpddr_op(mpddr, ATMEL_MPDDRC_MR_MODE_EXT_LMR_CMD,
  147. ram_address + (0x3 << ba_off));
  148. /*
  149. * An Extended Mode Register Set (EMRS1) cycle is issued to disable and
  150. * to program O.D.S. (Output Driver Strength).
  151. */
  152. atmel_mpddr_op(mpddr, ATMEL_MPDDRC_MR_MODE_EXT_LMR_CMD,
  153. ram_address + (0x1 << ba_off));
  154. /*
  155. * Write a one to the DLL bit (enable DLL reset) in the MPDDRC
  156. * Configuration Register.
  157. */
  158. /* A Mode Register Set (MRS) cycle is issued to reset DLL. */
  159. atmel_mpddr_op(mpddr, ATMEL_MPDDRC_MR_MODE_LMR_CMD, ram_address);
  160. udelay(50);
  161. /*
  162. * A Calibration command (MRS) is issued to calibrate RTT and RON
  163. * values for the Process Voltage Temperature (PVT).
  164. */
  165. atmel_mpddr_op(mpddr, ATMEL_MPDDRC_MR_MODE_DEEP_CMD, ram_address);
  166. /* A Normal Mode command is provided. */
  167. atmel_mpddr_op(mpddr, ATMEL_MPDDRC_MR_MODE_NORMAL_CMD, ram_address);
  168. /* Perform a write access to any DDR3-SDRAM address. */
  169. writel(0, ram_address);
  170. /*
  171. * Write the refresh rate into the COUNT field in the MPDDRC
  172. * Refresh Timer Register (MPDDRC_RTR):
  173. */
  174. writel(mpddr_value->rtr, &mpddr->rtr);
  175. return 0;
  176. }