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