dram_retention.c 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224
  1. /*
  2. * Copyright 2018-2023 NXP
  3. *
  4. * SPDX-License-Identifier: BSD-3-Clause
  5. */
  6. #include <stdbool.h>
  7. #include <lib/mmio.h>
  8. #include <dram.h>
  9. #include <gpc_reg.h>
  10. #include <platform_def.h>
  11. #define SRC_DDR1_RCR (IMX_SRC_BASE + 0x1000)
  12. #define SRC_DDR2_RCR (IMX_SRC_BASE + 0x1004)
  13. #define CCM_SRC_CTRL_OFFSET (IMX_CCM_BASE + 0x800)
  14. #define CCM_CCGR_OFFSET (IMX_CCM_BASE + 0x4000)
  15. #define CCM_TARGET_ROOT_OFFSET (IMX_CCM_BASE + 0x8000)
  16. #define CCM_SRC_CTRL(n) (CCM_SRC_CTRL_OFFSET + 0x10 * (n))
  17. #define CCM_CCGR(n) (CCM_CCGR_OFFSET + 0x10 * (n))
  18. #define CCM_TARGET_ROOT(n) (CCM_TARGET_ROOT_OFFSET + 0x80 * (n))
  19. #define DBGCAM_EMPTY 0x36000000
  20. static void rank_setting_update(void)
  21. {
  22. uint32_t i, offset;
  23. uint32_t pstate_num = dram_info.num_fsp;
  24. /* only support maximum 3 setpoints */
  25. pstate_num = (pstate_num > MAX_FSP_NUM) ? MAX_FSP_NUM : pstate_num;
  26. for (i = 0U; i < pstate_num; i++) {
  27. offset = i ? (i + 1) * 0x1000 : 0U;
  28. mmio_write_32(DDRC_DRAMTMG2(0) + offset, dram_info.rank_setting[i][0]);
  29. if (dram_info.dram_type != DDRC_LPDDR4) {
  30. mmio_write_32(DDRC_DRAMTMG9(0) + offset, dram_info.rank_setting[i][1]);
  31. }
  32. #if !defined(PLAT_imx8mq)
  33. mmio_write_32(DDRC_RANKCTL(0) + offset,
  34. dram_info.rank_setting[i][2]);
  35. #endif
  36. }
  37. #if defined(PLAT_imx8mq)
  38. mmio_write_32(DDRC_RANKCTL(0), dram_info.rank_setting[0][2]);
  39. #endif
  40. }
  41. void dram_enter_retention(void)
  42. {
  43. /* Wait DBGCAM to be empty */
  44. while (mmio_read_32(DDRC_DBGCAM(0)) != DBGCAM_EMPTY) {
  45. ;
  46. }
  47. /* Block AXI ports from taking anymore transactions */
  48. mmio_write_32(DDRC_PCTRL_0(0), 0x0);
  49. /* Wait until all AXI ports are idle */
  50. while (mmio_read_32(DDRC_PSTAT(0)) & 0x10001) {
  51. ;
  52. }
  53. /* Enter self refresh */
  54. mmio_write_32(DDRC_PWRCTL(0), 0xaa);
  55. /* LPDDR4 & DDR4/DDR3L need to check different status */
  56. if (dram_info.dram_type == DDRC_LPDDR4) {
  57. while (0x223 != (mmio_read_32(DDRC_STAT(0)) & 0x33f)) {
  58. ;
  59. }
  60. } else {
  61. while (0x23 != (mmio_read_32(DDRC_STAT(0)) & 0x3f)) {
  62. ;
  63. }
  64. }
  65. mmio_write_32(DDRC_DFIMISC(0), 0x0);
  66. mmio_write_32(DDRC_SWCTL(0), 0x0);
  67. mmio_write_32(DDRC_DFIMISC(0), 0x1f00);
  68. mmio_write_32(DDRC_DFIMISC(0), 0x1f20);
  69. while (mmio_read_32(DDRC_DFISTAT(0)) & 0x1) {
  70. ;
  71. }
  72. mmio_write_32(DDRC_DFIMISC(0), 0x1f00);
  73. /* wait DFISTAT.dfi_init_complete to 1 */
  74. while (!(mmio_read_32(DDRC_DFISTAT(0)) & 0x1)) {
  75. ;
  76. }
  77. mmio_write_32(DDRC_SWCTL(0), 0x1);
  78. /* should check PhyInLP3 pub reg */
  79. dwc_ddrphy_apb_wr(0xd0000, 0x0);
  80. if (!(dwc_ddrphy_apb_rd(0x90028) & 0x1)) {
  81. INFO("PhyInLP3 = 1\n");
  82. }
  83. dwc_ddrphy_apb_wr(0xd0000, 0x1);
  84. /* pwrdnreqn_async adbm/adbs of ddr */
  85. mmio_clrbits_32(IMX_GPC_BASE + GPC_PU_PWRHSK, DDRMIX_ADB400_SYNC);
  86. while (mmio_read_32(IMX_GPC_BASE + GPC_PU_PWRHSK) & DDRMIX_ADB400_ACK)
  87. ;
  88. mmio_setbits_32(IMX_GPC_BASE + GPC_PU_PWRHSK, DDRMIX_ADB400_SYNC);
  89. /* remove PowerOk */
  90. mmio_write_32(SRC_DDR1_RCR, 0x8F000008);
  91. mmio_write_32(CCM_CCGR(5), 0);
  92. mmio_write_32(CCM_SRC_CTRL(15), 2);
  93. /* enable the phy iso */
  94. mmio_setbits_32(IMX_GPC_BASE + DDRMIX_PGC, 1);
  95. mmio_setbits_32(IMX_GPC_BASE + PU_PGC_DN_TRG, DDRMIX_PWR_REQ);
  96. VERBOSE("dram enter retention\n");
  97. }
  98. void dram_exit_retention(void)
  99. {
  100. VERBOSE("dram exit retention\n");
  101. /* assert all reset */
  102. #if defined(PLAT_imx8mq)
  103. mmio_write_32(SRC_DDR2_RCR, 0x8F000003);
  104. mmio_write_32(SRC_DDR1_RCR, 0x8F00000F);
  105. mmio_write_32(SRC_DDR2_RCR, 0x8F000000);
  106. #else
  107. mmio_write_32(SRC_DDR1_RCR, 0x8F00001F);
  108. mmio_write_32(SRC_DDR1_RCR, 0x8F00000F);
  109. #endif
  110. mmio_write_32(CCM_CCGR(5), 2);
  111. mmio_write_32(CCM_SRC_CTRL(15), 2);
  112. /* change the clock source of dram_apb_clk_root */
  113. mmio_write_32(CCM_TARGET_ROOT(65) + 0x8, (0x7 << 24) | (0x7 << 16));
  114. mmio_write_32(CCM_TARGET_ROOT(65) + 0x4, (0x4 << 24) | (0x3 << 16));
  115. /* disable iso */
  116. mmio_setbits_32(IMX_GPC_BASE + PU_PGC_UP_TRG, DDRMIX_PWR_REQ);
  117. mmio_write_32(SRC_DDR1_RCR, 0x8F000006);
  118. /* wait dram pll locked */
  119. while (!(mmio_read_32(DRAM_PLL_CTRL) & BIT(31))) {
  120. ;
  121. }
  122. /* ddrc re-init */
  123. dram_umctl2_init(dram_info.timing_info);
  124. /*
  125. * Skips the DRAM init routine and starts up in selfrefresh mode
  126. * Program INIT0.skip_dram_init = 2'b11
  127. */
  128. mmio_setbits_32(DDRC_INIT0(0), 0xc0000000);
  129. /* Keeps the controller in self-refresh mode */
  130. mmio_write_32(DDRC_PWRCTL(0), 0xaa);
  131. mmio_write_32(DDRC_DBG1(0), 0x0);
  132. mmio_write_32(SRC_DDR1_RCR, 0x8F000004);
  133. mmio_write_32(SRC_DDR1_RCR, 0x8F000000);
  134. /* before write Dynamic reg, sw_done should be 0 */
  135. mmio_write_32(DDRC_SWCTL(0), 0x0);
  136. #if !PLAT_imx8mn
  137. if (dram_info.dram_type == DDRC_LPDDR4) {
  138. mmio_write_32(DDRC_DDR_SS_GPR0, 0x01); /*LPDDR4 mode */
  139. }
  140. #endif /* !PLAT_imx8mn */
  141. mmio_write_32(DDRC_DFIMISC(0), 0x0);
  142. /* dram phy re-init */
  143. dram_phy_init(dram_info.timing_info);
  144. /* workaround for rank-to-rank issue */
  145. rank_setting_update();
  146. /* DWC_DDRPHYA_APBONLY0_MicroContMuxSel */
  147. dwc_ddrphy_apb_wr(0xd0000, 0x0);
  148. while (dwc_ddrphy_apb_rd(0x20097)) {
  149. ;
  150. }
  151. dwc_ddrphy_apb_wr(0xd0000, 0x1);
  152. /* before write Dynamic reg, sw_done should be 0 */
  153. mmio_write_32(DDRC_SWCTL(0), 0x0);
  154. mmio_write_32(DDRC_DFIMISC(0), 0x20);
  155. /* wait DFISTAT.dfi_init_complete to 1 */
  156. while (!(mmio_read_32(DDRC_DFISTAT(0)) & 0x1)) {
  157. ;
  158. }
  159. /* clear DFIMISC.dfi_init_start */
  160. mmio_write_32(DDRC_DFIMISC(0), 0x0);
  161. /* set DFIMISC.dfi_init_complete_en */
  162. mmio_write_32(DDRC_DFIMISC(0), 0x1);
  163. /* set SWCTL.sw_done to enable quasi-dynamic register programming */
  164. mmio_write_32(DDRC_SWCTL(0), 0x1);
  165. /* wait SWSTAT.sw_done_ack to 1 */
  166. while (!(mmio_read_32(DDRC_SWSTAT(0)) & 0x1)) {
  167. ;
  168. }
  169. mmio_write_32(DDRC_PWRCTL(0), 0x88);
  170. /* wait STAT to normal state */
  171. while (0x1 != (mmio_read_32(DDRC_STAT(0)) & 0x7)) {
  172. ;
  173. }
  174. mmio_write_32(DDRC_PCTRL_0(0), 0x1);
  175. /* dis_auto-refresh is set to 0 */
  176. mmio_write_32(DDRC_RFSHCTL3(0), 0x0);
  177. /* should check PhyInLP3 pub reg */
  178. dwc_ddrphy_apb_wr(0xd0000, 0x0);
  179. if (!(dwc_ddrphy_apb_rd(0x90028) & 0x1)) {
  180. VERBOSE("PHYInLP3 = 0\n");
  181. }
  182. dwc_ddrphy_apb_wr(0xd0000, 0x1);
  183. }