xref: /rk3399_ARM-atf/plat/imx/imx8m/ddr/dram_retention.c (revision 3330084979e4c1a39a92f0642000664c79a00dda)
1 /*
2  * Copyright 2018-2023 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 
28 static void rank_setting_update(void)
29 {
30 	uint32_t i, offset;
31 	uint32_t pstate_num = dram_info.num_fsp;
32 
33 	for (i = 0U; i < pstate_num; i++) {
34 		offset = i ? (i + 1) * 0x1000 : 0U;
35 		mmio_write_32(DDRC_DRAMTMG2(0) + offset, dram_info.rank_setting[i][0]);
36 		if (dram_info.dram_type != DDRC_LPDDR4) {
37 			mmio_write_32(DDRC_DRAMTMG9(0) + offset, dram_info.rank_setting[i][1]);
38 		}
39 
40 #if !defined(PLAT_imx8mq)
41 		mmio_write_32(DDRC_RANKCTL(0) + offset,
42 			dram_info.rank_setting[i][2]);
43 #endif
44 	}
45 #if defined(PLAT_imx8mq)
46 		mmio_write_32(DDRC_RANKCTL(0), dram_info.rank_setting[0][2]);
47 #endif
48 }
49 
50 void dram_enter_retention(void)
51 {
52 	/* Wait DBGCAM to be empty */
53 	while (mmio_read_32(DDRC_DBGCAM(0)) != DBGCAM_EMPTY) {
54 		;
55 	}
56 
57 	/* Block AXI ports from taking anymore transactions */
58 	mmio_write_32(DDRC_PCTRL_0(0), 0x0);
59 	/* Wait until all AXI ports are idle */
60 	while (mmio_read_32(DDRC_PSTAT(0)) & 0x10001) {
61 		;
62 	}
63 
64 	/* Enter self refresh */
65 	mmio_write_32(DDRC_PWRCTL(0), 0xaa);
66 
67 	/* LPDDR4 & DDR4/DDR3L need to check different status */
68 	if (dram_info.dram_type == DDRC_LPDDR4) {
69 		while (0x223 != (mmio_read_32(DDRC_STAT(0)) & 0x33f)) {
70 			;
71 		}
72 	} else {
73 		while (0x23 != (mmio_read_32(DDRC_STAT(0)) & 0x3f)) {
74 			;
75 		}
76 	}
77 
78 	mmio_write_32(DDRC_DFIMISC(0), 0x0);
79 	mmio_write_32(DDRC_SWCTL(0), 0x0);
80 	mmio_write_32(DDRC_DFIMISC(0), 0x1f00);
81 	mmio_write_32(DDRC_DFIMISC(0), 0x1f20);
82 
83 	while (mmio_read_32(DDRC_DFISTAT(0)) & 0x1) {
84 		;
85 	}
86 
87 	mmio_write_32(DDRC_DFIMISC(0), 0x1f00);
88 	/* wait DFISTAT.dfi_init_complete to 1 */
89 	while (!(mmio_read_32(DDRC_DFISTAT(0)) & 0x1)) {
90 		;
91 	}
92 
93 	mmio_write_32(DDRC_SWCTL(0), 0x1);
94 
95 	/* should check PhyInLP3 pub reg */
96 	dwc_ddrphy_apb_wr(0xd0000, 0x0);
97 	if (!(dwc_ddrphy_apb_rd(0x90028) & 0x1)) {
98 		INFO("PhyInLP3 = 1\n");
99 	}
100 	dwc_ddrphy_apb_wr(0xd0000, 0x1);
101 
102 #if defined(PLAT_imx8mq)
103 	/* pwrdnreqn_async adbm/adbs of ddr */
104 	mmio_clrbits_32(GPC_PU_PWRHSK, BIT(1));
105 	while (mmio_read_32(GPC_PU_PWRHSK) & BIT(18)) {
106 		;
107 	}
108 	mmio_setbits_32(GPC_PU_PWRHSK, BIT(1));
109 #else
110 	/* pwrdnreqn_async adbm/adbs of ddr */
111 	mmio_clrbits_32(GPC_PU_PWRHSK, BIT(2));
112 	while (mmio_read_32(GPC_PU_PWRHSK) & BIT(20)) {
113 		;
114 	}
115 	mmio_setbits_32(GPC_PU_PWRHSK, BIT(2));
116 #endif
117 	/* remove PowerOk */
118 	mmio_write_32(SRC_DDR1_RCR, 0x8F000008);
119 
120 	mmio_write_32(CCM_CCGR(5), 0);
121 	mmio_write_32(CCM_SRC_CTRL(15), 2);
122 
123 	/* enable the phy iso */
124 	mmio_setbits_32(IMX_GPC_BASE + 0xd40, 1);
125 	mmio_setbits_32(IMX_GPC_BASE + PU_PGC_DN_TRG, BIT(5));
126 
127 	VERBOSE("dram enter retention\n");
128 }
129 
130 void dram_exit_retention(void)
131 {
132 	VERBOSE("dram exit retention\n");
133 	/* assert all reset */
134 #if defined(PLAT_imx8mq)
135 	mmio_write_32(SRC_DDR2_RCR, 0x8F000003);
136 	mmio_write_32(SRC_DDR1_RCR, 0x8F00000F);
137 	mmio_write_32(SRC_DDR2_RCR, 0x8F000000);
138 #else
139 	mmio_write_32(SRC_DDR1_RCR, 0x8F00001F);
140 	mmio_write_32(SRC_DDR1_RCR, 0x8F00000F);
141 #endif
142 	mmio_write_32(CCM_CCGR(5), 2);
143 	mmio_write_32(CCM_SRC_CTRL(15), 2);
144 
145 	/* disable iso */
146 	mmio_setbits_32(IMX_GPC_BASE + PU_PGC_UP_TRG, BIT(5));
147 	mmio_write_32(SRC_DDR1_RCR, 0x8F000006);
148 
149 	/* wait dram pll locked */
150 	while (!(mmio_read_32(DRAM_PLL_CTRL) & BIT(31))) {
151 		;
152 	}
153 
154 	/* ddrc re-init */
155 	dram_umctl2_init(dram_info.timing_info);
156 
157 	/*
158 	 * Skips the DRAM init routine and starts up in selfrefresh mode
159 	 * Program INIT0.skip_dram_init = 2'b11
160 	 */
161 	mmio_setbits_32(DDRC_INIT0(0), 0xc0000000);
162 	/* Keeps the controller in self-refresh mode */
163 	mmio_write_32(DDRC_PWRCTL(0), 0xaa);
164 	mmio_write_32(DDRC_DBG1(0), 0x0);
165 	mmio_write_32(SRC_DDR1_RCR, 0x8F000004);
166 	mmio_write_32(SRC_DDR1_RCR, 0x8F000000);
167 
168 	/* before write Dynamic reg, sw_done should be 0 */
169 	mmio_write_32(DDRC_SWCTL(0), 0x0);
170 
171 #if !PLAT_imx8mn
172 	if (dram_info.dram_type == DDRC_LPDDR4) {
173 		mmio_write_32(DDRC_DDR_SS_GPR0, 0x01); /*LPDDR4 mode */
174 	}
175 #endif /* !PLAT_imx8mn */
176 
177 	mmio_write_32(DDRC_DFIMISC(0), 0x0);
178 
179 	/* dram phy re-init */
180 	dram_phy_init(dram_info.timing_info);
181 
182 	/* workaround for rank-to-rank issue */
183 	rank_setting_update();
184 
185 	/* DWC_DDRPHYA_APBONLY0_MicroContMuxSel */
186 	dwc_ddrphy_apb_wr(0xd0000, 0x0);
187 	while (dwc_ddrphy_apb_rd(0x20097)) {
188 		;
189 	}
190 	dwc_ddrphy_apb_wr(0xd0000, 0x1);
191 
192 	/* before write Dynamic reg, sw_done should be 0 */
193 	mmio_write_32(DDRC_SWCTL(0), 0x0);
194 	mmio_write_32(DDRC_DFIMISC(0), 0x20);
195 	/* wait DFISTAT.dfi_init_complete to 1 */
196 	while (!(mmio_read_32(DDRC_DFISTAT(0)) & 0x1)) {
197 		;
198 	}
199 
200 	/* clear DFIMISC.dfi_init_start */
201 	mmio_write_32(DDRC_DFIMISC(0), 0x0);
202 	/* set DFIMISC.dfi_init_complete_en */
203 	mmio_write_32(DDRC_DFIMISC(0), 0x1);
204 
205 	/* set SWCTL.sw_done to enable quasi-dynamic register programming */
206 	mmio_write_32(DDRC_SWCTL(0), 0x1);
207 	/* wait SWSTAT.sw_done_ack to 1 */
208 	while (!(mmio_read_32(DDRC_SWSTAT(0)) & 0x1)) {
209 		;
210 	}
211 
212 	mmio_write_32(DDRC_PWRCTL(0), 0x88);
213 	/* wait STAT to normal state */
214 	while (0x1 != (mmio_read_32(DDRC_STAT(0)) & 0x7)) {
215 		;
216 	}
217 
218 	mmio_write_32(DDRC_PCTRL_0(0), 0x1);
219 	 /* dis_auto-refresh is set to 0 */
220 	mmio_write_32(DDRC_RFSHCTL3(0), 0x0);
221 
222 	/* should check PhyInLP3 pub reg */
223 	dwc_ddrphy_apb_wr(0xd0000, 0x0);
224 	if (!(dwc_ddrphy_apb_rd(0x90028) & 0x1)) {
225 		VERBOSE("PHYInLP3 = 0\n");
226 	}
227 	dwc_ddrphy_apb_wr(0xd0000, 0x1);
228 }
229