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