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