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