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