xref: /rk3399_ARM-atf/plat/imx/imx8ulp/dram.c (revision 416c4433f0047a86165e450e60f93020c561151b)
1 /*
2  * Copyright 2021-2024 NXP
3  *
4  * SPDX-License-Identifier: BSD-3-Clause
5  */
6 
7 #include <assert.h>
8 #include <stdbool.h>
9 
10 #include <arch_helpers.h>
11 #include <bl31/interrupt_mgmt.h>
12 #include <common/runtime_svc.h>
13 #include <lib/mmio.h>
14 #include <lib/spinlock.h>
15 #include <plat/common/platform.h>
16 
17 #include <platform_def.h>
18 
19 #include <dram.h>
20 #include <upower_api.h>
21 
22 #define PHY_FREQ_SEL_INDEX(x)		((x) << 16)
23 #define PHY_FREQ_MULTICAST_EN(x)	((x) << 8)
24 #define DENALI_PHY_1537			U(0x5804)
25 
26 #define IMX_DDRC_BASE			U(0x2E060000)
27 #define SAVED_DRAM_DATA_BASE		U(0x20055000)
28 #define DENALI_CTL_144			0x240
29 #define LPI_WAKEUP_EN_SHIFT		U(8)
30 #define IMX_LPAV_SIM_BASE		0x2DA50000
31 #define LPDDR_CTRL			0x14
32 #define LPDDR_AUTO_LP_MODE_DISABLE	BIT(24)
33 #define SOC_LP_CMD_SHIFT		U(15)
34 #define LPDDR_CTRL2			0x18
35 
36 #define DENALI_CTL_00			U(0x0)
37 #define DENALI_CTL_23			U(0x5c)
38 #define DFIBUS_FREQ_INIT_SHIFT		U(24)
39 #define TSREF2PHYMSTR_SHIFT		U(8)
40 #define TSREF2PHYMSTR_MASK		GENMASK(13, 8)
41 
42 #define DENALI_CTL_24			U(0x60)
43 #define DENALI_CTL_25			U(0x64)
44 
45 #define DENALI_CTL_93			U(0x174)
46 #define PWRUP_SREFRESH_EXIT		BIT(0)
47 
48 #define DENALI_CTL_127				U(0x1fc)
49 #define PHYMSTR_TRAIN_AFTER_INIT_COMPLETE	BIT(16)
50 
51 #define DENALI_CTL_147			U(0x24c)
52 #define DENALI_CTL_153			U(0x264)
53 #define PCPCS_PD_EN			BIT(8)
54 
55 #define DENALI_CTL_249			U(0x3E4)
56 #define DENALI_CTL_266			U(0x428)
57 
58 #define DENALI_PHY_1547			U(0x582c)
59 #define PHY_LP4_BOOT_DISABLE		BIT(8)
60 
61 #define DENALI_PHY_1559			U(0x585c)
62 #define DENALI_PHY_1590			U(0x58D8)
63 
64 #define DENALI_PI_00			U(0x2000)
65 #define DENALI_PI_04			U(0x2010)
66 #define DENALI_PI_52			U(0x20D0)
67 #define DENALI_PI_26			U(0x2068)
68 #define DENALI_PI_33			U(0x2084)
69 #define DENALI_PI_65			U(0x2104)
70 #define DENALI_PI_77			U(0x2134)
71 #define DENALI_PI_134			U(0x2218)
72 #define DENALI_PI_131			U(0x220C)
73 #define DENALI_PI_132			U(0x2210)
74 #define DENALI_PI_134			U(0x2218)
75 #define DENALI_PI_137			U(0x2224)
76 #define DENALI_PI_174			U(0x22B8)
77 #define DENALI_PI_175			U(0x22BC)
78 #define DENALI_PI_181			U(0x22D4)
79 #define DENALI_PI_182			U(0x22D8)
80 #define DENALI_PI_191			U(0x22FC)
81 #define DENALI_PI_192			U(0x2300)
82 #define DENALI_PI_212			U(0x2350)
83 #define DENALI_PI_214			U(0x2358)
84 #define DENALI_PI_217			U(0x2364)
85 
86 #define LPDDR3_TYPE	U(0x7)
87 #define LPDDR4_TYPE	U(0xB)
88 
89 extern void upower_wait_resp(void);
90 
91 struct dram_cfg_param {
92 	uint32_t reg;
93 	uint32_t val;
94 };
95 
96 struct dram_timing_info {
97 	/* ddr controller config */
98 	struct dram_cfg_param *ctl_cfg;
99 	unsigned int ctl_cfg_num;
100 	/* pi config */
101 	struct dram_cfg_param *pi_cfg;
102 	unsigned int pi_cfg_num;
103 	/* phy freq1 config */
104 	struct dram_cfg_param *phy_f1_cfg;
105 	unsigned int phy_f1_cfg_num;
106 	/* phy freq2 config */
107 	struct dram_cfg_param *phy_f2_cfg;
108 	unsigned int phy_f2_cfg_num;
109 	/* initialized drate table */
110 	unsigned int fsp_table[3];
111 };
112 
113 #define CTL_NUM		U(680)
114 #define PI_NUM		U(298)
115 #define PHY_NUM		U(1654)
116 #define PHY_DIFF_NUM	U(49)
117 struct dram_cfg {
118 	uint32_t ctl_cfg[CTL_NUM];
119 	uint32_t pi_cfg[PI_NUM];
120 	uint32_t phy_full[PHY_NUM];
121 	uint32_t phy_diff[PHY_DIFF_NUM];
122 };
123 
124 struct dram_timing_info *info;
125 struct dram_cfg *dram_timing_cfg;
126 
127 /* mark if dram cfg is already saved */
128 static bool dram_cfg_saved;
129 static uint32_t dram_class;
130 
131 /* PHY register index for frequency diff */
132 uint32_t freq_specific_reg_array[PHY_DIFF_NUM] = {
133 90, 92, 93, 96, 97, 100, 101, 102, 103, 104, 114,
134 346, 348, 349, 352, 353, 356, 357, 358, 359, 360,
135 370, 602, 604, 605, 608, 609, 612, 613, 614, 615,
136 616, 626, 858, 860, 861, 864, 865, 868, 869, 870,
137 871, 872, 882, 1063, 1319, 1566, 1624, 1625
138 };
139 
140 /* lock used for DDR DVFS */
141 spinlock_t dfs_lock;
142 static volatile uint32_t core_count;
143 static volatile bool in_progress;
144 static volatile bool sys_dvfs;
145 static int num_fsp;
146 
147 static void ddr_init(void)
148 {
149 	unsigned int i;
150 
151 	/* restore the ddr ctl config */
152 	for (i = 0U; i < CTL_NUM; i++) {
153 		mmio_write_32(IMX_DDRC_BASE + i * 4, dram_timing_cfg->ctl_cfg[i]);
154 	}
155 
156 	/* load the PI registers */
157 	for (i = 0U; i < PI_NUM; i++) {
158 		mmio_write_32(IMX_DDRC_BASE + 0x2000 + i * 4, dram_timing_cfg->pi_cfg[i]);
159 	}
160 
161 
162 	 /* restore all PHY registers for all the fsp. */
163 	mmio_write_32(IMX_DDRC_BASE + DENALI_PHY_1537, 0x100);
164 	/* restore all the phy configs */
165 	for (i = 0U; i < PHY_NUM; i++) {
166 		/* skip the reserved registers space */
167 		if (i >= 121U && i <= 255U) {
168 			continue;
169 		}
170 		if (i >= 377U && i <= 511U) {
171 			continue;
172 		}
173 		if (i >= 633U && i <= 767U) {
174 			continue;
175 		}
176 		if (i >= 889U && i <= 1023U) {
177 			continue;
178 		}
179 		if (i >= 1065U && i <= 1279U) {
180 			continue;
181 		}
182 		if (i >= 1321U && i <= 1535U) {
183 			continue;
184 		}
185 		mmio_write_32(IMX_DDRC_BASE + 0x4000 + i * 4, dram_timing_cfg->phy_full[i]);
186 	}
187 
188 	if (dram_class == LPDDR4_TYPE) {
189 		/* restore only the diff. */
190 		mmio_write_32(IMX_DDRC_BASE + DENALI_PHY_1537, 0x0);
191 		for (i = 0U; i < PHY_DIFF_NUM; i++) {
192 			mmio_write_32(IMX_DDRC_BASE + 0x4000 + freq_specific_reg_array[i] * 4,
193 				      dram_timing_cfg->phy_diff[i]);
194 		}
195 	}
196 
197 	/* Re-enable MULTICAST mode */
198 	mmio_write_32(IMX_DDRC_BASE + DENALI_PHY_1537, PHY_FREQ_MULTICAST_EN(1));
199 }
200 
201 void dram_enter_retention(void)
202 {
203 	unsigned int i;
204 
205 	/* 1. config the PCC_LPDDR4[SSADO] to 2b'11 for ACK domain 0/1's STOP */
206 	mmio_setbits_32(IMX_PCC5_BASE + 0x108, 0x2 << 22);
207 
208 	/*
209 	 * 2. Make sure the DENALI_CTL_144[LPI_WAKEUP_EN[5:0]] has the bit
210 	 * LPI_WAKEUP_EN[3] = 1b'1. This enables the option 'self-refresh
211 	 * long with mem and ctlr clk gating or self-refresh  power-down
212 	 * long with mem and ctlr clk gating'
213 	 */
214 	mmio_setbits_32(IMX_DDRC_BASE + DENALI_CTL_144, BIT(3) << LPI_WAKEUP_EN_SHIFT);
215 
216 	/*
217 	 * 3a. Config SIM_LPAV LPDDR_CTRL[LPDDR_AUTO_LP_MODE_DISABLE] to 1b'0(enable
218 	 * the logic to automatic handles low power entry/exit. This is the recommended
219 	 * option over handling through software.
220 	 * 3b. Config the SIM_LPAV LPDDR_CTRL[SOC_LP_CMD] to 6b'101001(encoding for
221 	 * self_refresh with both DDR controller and DRAM clock gate. THis is mandatory
222 	 * since LPPDR logic will be power gated).
223 	 */
224 	mmio_clrbits_32(IMX_LPAV_SIM_BASE + LPDDR_CTRL, LPDDR_AUTO_LP_MODE_DISABLE);
225 	mmio_clrsetbits_32(IMX_LPAV_SIM_BASE + LPDDR_CTRL,
226 			   0x3f << SOC_LP_CMD_SHIFT, 0x29 << SOC_LP_CMD_SHIFT);
227 
228 	/* Save DDR Controller & PHY config.
229 	 * Set PHY_FREQ_SEL_MULTICAST_EN=0 & PHY_FREQ_SEL_INDEX=1. Read and store all
230 	 * the PHY registers for F2 into phy_f1_cfg, then read/store the diff between
231 	 * F1 & F2 into phy_f2_cfg.
232 	 */
233 	if (!dram_cfg_saved) {
234 		info = (struct dram_timing_info *)SAVED_DRAM_DATA_BASE;
235 		dram_timing_cfg = (struct dram_cfg *)(SAVED_DRAM_DATA_BASE +
236 					sizeof(struct dram_timing_info));
237 
238 		/* get the dram type */
239 		dram_class = mmio_read_32(IMX_DDRC_BASE + DENALI_CTL_00);
240 		dram_class = (dram_class >> 8) & 0xf;
241 
242 		/* save the ctl registers */
243 		for (i = 0U; i < CTL_NUM; i++) {
244 			dram_timing_cfg->ctl_cfg[i] = mmio_read_32(IMX_DDRC_BASE + i * 4);
245 		}
246 		dram_timing_cfg->ctl_cfg[0] = dram_timing_cfg->ctl_cfg[0] & 0xFFFFFFFE;
247 
248 		/* save the PI registers */
249 		for (i = 0U; i < PI_NUM; i++) {
250 			dram_timing_cfg->pi_cfg[i] = mmio_read_32(IMX_DDRC_BASE + 0x2000 + i * 4);
251 		}
252 		dram_timing_cfg->pi_cfg[0] = dram_timing_cfg->pi_cfg[0] & 0xFFFFFFFE;
253 
254 		/*
255 		 * Read and store all PHY registers. full array is a full
256 		 * copy for all the setpoint
257 		 */
258 		if (dram_class == LPDDR4_TYPE) {
259 			mmio_write_32(IMX_DDRC_BASE + DENALI_PHY_1537, 0x10000);
260 			for (i = 0U; i < PHY_NUM; i++) {
261 				/* Make sure MULTICASE is enabled */
262 				if (i == 1537U) {
263 					dram_timing_cfg->phy_full[i] = 0x100;
264 				} else {
265 					dram_timing_cfg->phy_full[i] = mmio_read_32(IMX_DDRC_BASE + 0x4000 + i * 4);
266 				}
267 			}
268 
269 			/*
270 			 * set PHY_FREQ_SEL_MULTICAST_EN=0 & PHY_FREQ_SEL_INDEX=0.
271 			 * Read and store only the diff.
272 			 */
273 			mmio_write_32(IMX_DDRC_BASE + DENALI_PHY_1537, 0x0);
274 			/* save only the frequency based diff config to save memory */
275 			for (i = 0U; i < PHY_DIFF_NUM; i++) {
276 				dram_timing_cfg->phy_diff[i] = mmio_read_32(IMX_DDRC_BASE + 0x4000 +
277 									    freq_specific_reg_array[i] * 4);
278 			}
279 		} else {
280 			/* LPDDR3, only f1 need to save */
281 			for (i = 0U; i < info->phy_f1_cfg_num; i++) {
282 				info->phy_f1_cfg[i].val = mmio_read_32(info->phy_f1_cfg[i].reg);
283 			}
284 		}
285 
286 		dram_cfg_saved = true;
287 	}
288 }
289 
290 void dram_exit_retention(void)
291 {
292 	uint32_t val;
293 
294 	/* 1. Config the LPAV PLL4 and DDR clock for the desired LPDDR operating frequency. */
295 	mmio_setbits_32(IMX_PCC5_BASE + 0x108, BIT(30));
296 
297 	/* 2. Write PCC5.PCC_LPDDR4[SWRST] to 1b'1 to release LPDDR from reset. */
298 	mmio_setbits_32(IMX_PCC5_BASE + 0x108, BIT(28));
299 
300 	/* 3. Reload the LPDDR CTL/PI/PHY register */
301 	ddr_init();
302 
303 	if (dram_class == LPDDR4_TYPE) {
304 		/* 4a. FIXME Set PHY_SET_DFI_INPUT_N parameters to 4'h1. LPDDR4 only */
305 		mmio_write_32(IMX_DDRC_BASE + DENALI_PHY_1559, 0x01010101);
306 
307 		/*
308 		 * 4b. CTL PWRUP_SREFRESH_EXIT=1'b0 for disabling self refresh exit
309 		 * from controller.
310 		 */
311 		/*
312 		 * 4c. PI_PWRUP_SELF_REF_EXIT=1, PI_MC_PWRUP_SELF_REF_EXIT=0 for enabling
313 		 * self refresh exit from PI
314 		 */
315 		/* 4c. PI_INT_LVL_EN=0 to skip Initialization trainings. */
316 		/*
317 		 * 4d. PI_WRLVL_EN_F0/1/2= PI_CALVL_EN_F0/1/2= PI_RDLVL_EN_F0/1/2=
318 		 * PI_RDLVL_GATE_EN_F0/1/2= PI_WDQLVL_EN_F0/1/2=0x2.
319 		 * Enable non initialization trainings.
320 		 */
321 		/* 4e. PI_PWRUP_SREFRESH_EXIT_CS=0xF */
322 		/* 4f. PI_DLL_RESET=0x1 */
323 		mmio_setbits_32(IMX_DDRC_BASE + DENALI_PI_137, 0x1);
324 		/* PI_PWRUP_SELF_REF_EXIT = 1 */
325 		mmio_setbits_32(IMX_DDRC_BASE + DENALI_PI_132, 0x01000000);
326 		/* PI_MC_PWRUP_SELF_REF_EXIT = 0 */
327 		mmio_clrbits_32(IMX_DDRC_BASE + DENALI_PI_132, BIT(16));
328 		/* PI_INT_LVL_EN = 0 */
329 		mmio_clrbits_32(IMX_DDRC_BASE + DENALI_PI_04, BIT(0));
330 		/* PI_WRLVL_EN_F0 = 3, PI_WRLVL_EN_F1 = 3 */
331 		mmio_setbits_32(IMX_DDRC_BASE + DENALI_PI_174, 0x03030000);
332 		/* PI_WRLVL_EN_F2 = 3 */
333 		mmio_setbits_32(IMX_DDRC_BASE + DENALI_PI_175, 0x03);
334 		/* PI_CALVL_EN_F0 = 3, PI_CALVL_EN_F1 = 3 */
335 		mmio_setbits_32(IMX_DDRC_BASE + DENALI_PI_191, 0x03030000);
336 		/* PI_CALVL_EN_F2 = 3 */
337 		mmio_setbits_32(IMX_DDRC_BASE + DENALI_PI_192, 0x03);
338 		/* PI_WDQLVL_EN_F0 = 3 */
339 		mmio_setbits_32(IMX_DDRC_BASE + DENALI_PI_212, 0x300);
340 		/* PI_WDQLVL_EN_F1 = 3 */
341 		mmio_setbits_32(IMX_DDRC_BASE + DENALI_PI_214, 0x03000000);
342 		/* PI_WDQLVL_EN_F2 = 3 */
343 		mmio_setbits_32(IMX_DDRC_BASE + DENALI_PI_217, 0x300);
344 		/* PI_EDLVL_EN_F0 = 3, PI_EDLVL_GATE_EN_F0 = 3 */
345 		mmio_setbits_32(IMX_DDRC_BASE + DENALI_PI_181, 0x03030000);
346 		/*
347 		 * PI_RDLVL_EN_F1 = 3, PI_RDLVL_GATE_EN_F1 = 3,
348 		 * PI_RDLVL_EN_F2 = 3, PI_RDLVL_GATE_EN_F2 = 3
349 		 */
350 		mmio_setbits_32(IMX_DDRC_BASE + DENALI_PI_182, 0x03030303);
351 		/* PI_PWRUP_SREFRESH_EXIT_CS = 0xF */
352 		mmio_setbits_32(IMX_DDRC_BASE + DENALI_PI_134, 0x000F0000);
353 	} else {
354 		/* PI_DLL_RESET=1 */
355 		mmio_setbits_32(IMX_DDRC_BASE + DENALI_PI_137, 0x1);
356 		/* PI_PWRUP_SELF_REF_EXIT=1 */
357 		mmio_setbits_32(IMX_DDRC_BASE + DENALI_PI_132, 0x01000000);
358 		/* PI_MC_PWRUP_SELF_REF_EXIT=0 */
359 		mmio_clrbits_32(IMX_DDRC_BASE + DENALI_PI_132, BIT(16));
360 		/* PI_INT_LVL_EN=0 */
361 		mmio_clrbits_32(IMX_DDRC_BASE + DENALI_PI_04, BIT(0));
362 		/* PI_WRLVL_EN_F0=3 */
363 		mmio_setbits_32(IMX_DDRC_BASE + DENALI_PI_174, 0x00030000);
364 		/* PI_CALVL_EN_F0=3 */
365 		mmio_setbits_32(IMX_DDRC_BASE + DENALI_PI_191, 0x00030000);
366 		/* PI_RDLVL_EN_F0=3,PI_RDLVL_GATE_EN_F0=3 */
367 		mmio_setbits_32(IMX_DDRC_BASE + DENALI_PI_181, 0x03030000);
368 		/* PI_PWRUP_SREFRESH_EXIT_CS=0xF */
369 		mmio_setbits_32(IMX_DDRC_BASE + DENALI_PI_134, 0x000F0000);
370 	}
371 
372 	mmio_write_32(IMX_DDRC_BASE + DENALI_CTL_144, 0x00002D00);
373 
374 	/* Force in-order AXI read data */
375 	mmio_write_32(IMX_DDRC_BASE + DENALI_CTL_144, 0x1);
376 
377 	/*
378 	 * Disable special R/W group switches so that R/W group placement
379 	 * is always at END of R/W group.
380 	 */
381 	mmio_write_32(IMX_DDRC_BASE + DENALI_CTL_249, 0x0);
382 
383 	/* Reduce time for IO pad calibration */
384 	mmio_write_32(IMX_DDRC_BASE + DENALI_PHY_1590, 0x01000000);
385 
386 	mmio_write_32(IMX_DDRC_BASE + DENALI_CTL_25, 0x00020100);
387 
388 	/* PD disable */
389 	mmio_write_32(IMX_DDRC_BASE + DENALI_CTL_153, 0x04040000);
390 	/*
391 	 * 5. Disable automatic LP entry and PCPCS modes LP_AUTO_ENTRY_EN
392 	 * to 1b'0, PCPCS_PD_EN to 1b'0
393 	 */
394 
395 	upwr_xcp_set_ddr_retention(APD_DOMAIN, 0, NULL);
396 	upower_wait_resp();
397 
398 	if (dram_class == LPDDR4_TYPE) {
399 		/* 7. Write PI START parameter to 1'b1 */
400 		mmio_write_32(IMX_DDRC_BASE + DENALI_PI_00, 0x00000b01);
401 
402 		/* 8. Write CTL START parameter to 1'b1 */
403 		mmio_write_32(IMX_DDRC_BASE + DENALI_CTL_00, 0x00000b01);
404 	} else {
405 		/* 7. Write PI START parameter to 1'b1 */
406 		mmio_write_32(IMX_DDRC_BASE + DENALI_PI_00, 0x00000701);
407 
408 		/* 8. Write CTL START parameter to 1'b1 */
409 		mmio_write_32(IMX_DDRC_BASE + DENALI_CTL_00, 0x00000701);
410 	}
411 
412 	/* 9. DENALI_CTL_266:  Wait for INT_STATUS_INIT=0x2 */
413 	do {
414 		val = (mmio_read_32(IMX_DDRC_BASE + DENALI_CTL_266) >> 8) & 0xFF;
415 	} while (val != 0x2);
416 
417 	/*
418 	 * 10. Run SW trainings by setting PI_CALVL_REQ,PI_WRLVL_REQ,PI_RDLVL_GATE_REQ,
419 	 * PI_RDLVL_REQ,PI_WDQLVL_REQ(NA for LPDDR3) in same order.
420 	 */
421 	if (dram_class == LPDDR4_TYPE) {
422 		mmio_setbits_32(IMX_DDRC_BASE + DENALI_PI_52, 0x10000); /* CALVL */
423 		mmio_setbits_32(IMX_DDRC_BASE + DENALI_PI_26, 0x100); /* WRLVL */
424 		mmio_setbits_32(IMX_DDRC_BASE + DENALI_PI_33, 0x10000); /* RDGATE */
425 		mmio_setbits_32(IMX_DDRC_BASE + DENALI_PI_33, 0x100); /* RDQLVL */
426 		mmio_setbits_32(IMX_DDRC_BASE + DENALI_PI_65, 0x10000); /* WDQLVL */
427 
428 		/* 11. Wait for trainings to get complete by polling PI_INT_STATUS */
429 		while ((mmio_read_32(IMX_DDRC_BASE + DENALI_PI_77) & 0x07E00000) != 0x07E00000) {
430 			;
431 		}
432 	} else {
433 		mmio_setbits_32(IMX_DDRC_BASE + DENALI_PI_52, 0x10000); /* CALVL */
434 		mmio_setbits_32(IMX_DDRC_BASE + DENALI_PI_26, 0x100); /* WRLVL */
435 		mmio_setbits_32(IMX_DDRC_BASE + DENALI_PI_33, 0x10000); /* RDGATE */
436 		mmio_setbits_32(IMX_DDRC_BASE + DENALI_PI_33, 0x100); /* RDQLVL */
437 		while ((mmio_read_32(IMX_DDRC_BASE + DENALI_PI_77) & 0x05E00000) != 0x05E00000) {
438 			;
439 		}
440 	}
441 }
442 
443 #define LPDDR_DONE       (0x1<<4)
444 #define SOC_FREQ_CHG_ACK (0x1<<6)
445 #define SOC_FREQ_CHG_REQ (0x1<<7)
446 #define LPI_WAKEUP_EN    (0x4<<8)
447 #define SOC_FREQ_REQ     (0x1<<11)
448 
449 #define LPDDR_EN_CLKGATE (0x1<<17)
450 
451 static void set_cgc2_ddrclk(uint8_t src, uint8_t div)
452 {
453 
454 	/* Wait until the reg is unlocked for writing */
455 	while (mmio_read_32(IMX_CGC2_BASE + 0x40) & BIT(31))
456 		;
457 
458 	mmio_write_32(IMX_CGC2_BASE + 0x40, (src << 28) | (div << 21));
459 	/* Wait for the clock switching done */
460 	while (!(mmio_read_32(IMX_CGC2_BASE + 0x40) & BIT(27)))
461 		;
462 }
463 static void set_ddr_clk(uint32_t ddr_freq)
464 {
465 	/* Disable DDR clock */
466 	mmio_clrbits_32(IMX_PCC5_BASE + 0x108, BIT(30));
467 	switch (ddr_freq) {
468 	/* boot frequency ? */
469 	case 48:
470 		set_cgc2_ddrclk(2, 0);
471 		break;
472 	/* default bypass frequency for fsp 1 */
473 	case 192:
474 		set_cgc2_ddrclk(0, 1);
475 		break;
476 	case 384:
477 		set_cgc2_ddrclk(0, 0);
478 		break;
479 	case 264:
480 		set_cgc2_ddrclk(4, 3);
481 		break;
482 	case 528:
483 		set_cgc2_ddrclk(4, 1);
484 		break;
485 	default:
486 		break;
487 	}
488 	/* Enable DDR clock */
489 	mmio_setbits_32(IMX_PCC5_BASE + 0x108, BIT(30));
490 
491 	/* Wait until the reg is unlocked for writing */
492 	while (mmio_read_32(IMX_CGC2_BASE + 0x40) & BIT(31)) {
493 		;
494 	}
495 }
496 
497 #define AVD_SIM_LPDDR_CTRL	(IMX_LPAV_SIM_BASE + 0x14)
498 #define AVD_SIM_LPDDR_CTRL2	(IMX_LPAV_SIM_BASE + 0x18)
499 #define MAX_FSP_NUM	U(3)
500 #define DDR_DFS_GET_FSP_COUNT	0x10
501 #define DDR_BYPASS_DRATE	U(400)
502 
503 extern int upower_pmic_i2c_write(uint32_t reg_addr, uint32_t reg_val);
504 
505 /* Normally, we only switch frequency between 1(bypass) and 2(highest) */
506 int lpddr4_dfs(uint32_t freq_index)
507 {
508 	uint32_t lpddr_ctrl, lpddr_ctrl2;
509 	uint32_t ddr_ctl_144;
510 
511 	/*
512 	 * Valid index: 0 to 2
513 	 * index 0: boot frequency
514 	 * index 1: bypass frequency
515 	 * index 2: highest frequency
516 	 */
517 	if (freq_index > 2U) {
518 		return -1;
519 	}
520 
521 	/*
522 	 * increase the voltage to 1.1V firstly before increase frequency
523 	 * and APD enter OD mode
524 	 */
525 	if (freq_index == 2U && sys_dvfs) {
526 		upower_pmic_i2c_write(0x22, 0x28);
527 	}
528 
529 	/* Enable LPI_WAKEUP_EN */
530 	ddr_ctl_144 = mmio_read_32(IMX_DDRC_BASE + DENALI_CTL_144);
531 	mmio_setbits_32(IMX_DDRC_BASE + DENALI_CTL_144, LPI_WAKEUP_EN);
532 
533 	/* put DRAM into long self-refresh & clock gating */
534 	lpddr_ctrl = mmio_read_32(AVD_SIM_LPDDR_CTRL);
535 	lpddr_ctrl = (lpddr_ctrl & ~((0x3f << 15) | (0x3 << 9))) | (0x28 << 15) | (freq_index << 9);
536 	mmio_write_32(AVD_SIM_LPDDR_CTRL, lpddr_ctrl);
537 
538 	/* Gating the clock */
539 	lpddr_ctrl2 = mmio_read_32(AVD_SIM_LPDDR_CTRL2);
540 	mmio_setbits_32(AVD_SIM_LPDDR_CTRL2, LPDDR_EN_CLKGATE);
541 
542 	/* Request frequency change */
543 	mmio_setbits_32(AVD_SIM_LPDDR_CTRL, SOC_FREQ_REQ);
544 
545 	do {
546 		lpddr_ctrl = mmio_read_32(AVD_SIM_LPDDR_CTRL);
547 		if (lpddr_ctrl & SOC_FREQ_CHG_REQ) {
548 			/* Bypass mode */
549 			if (info->fsp_table[freq_index] < DDR_BYPASS_DRATE) {
550 				/* Change to PLL bypass mode */
551 				mmio_write_32(IMX_LPAV_SIM_BASE, 0x1);
552 				/* change the ddr clock source & frequency */
553 				set_ddr_clk(info->fsp_table[freq_index]);
554 			} else {
555 				/* Change to PLL unbypass mode */
556 				mmio_write_32(IMX_LPAV_SIM_BASE, 0x0);
557 				/* change the ddr clock source & frequency */
558 				set_ddr_clk(info->fsp_table[freq_index] >> 1);
559 			}
560 
561 			mmio_clrsetbits_32(AVD_SIM_LPDDR_CTRL, SOC_FREQ_CHG_REQ, SOC_FREQ_CHG_ACK);
562 			continue;
563 		}
564 	} while ((lpddr_ctrl & LPDDR_DONE) != 0); /* several try? */
565 
566 	/* restore the original setting */
567 	mmio_write_32(IMX_DDRC_BASE + DENALI_CTL_144, ddr_ctl_144);
568 	mmio_write_32(AVD_SIM_LPDDR_CTRL2, lpddr_ctrl2);
569 
570 	/* Check the DFS result */
571 	lpddr_ctrl = mmio_read_32(AVD_SIM_LPDDR_CTRL) & 0xF;
572 	if (lpddr_ctrl != 0U) {
573 		/* Must be something wrong, return failure */
574 		return -1;
575 	}
576 
577 	/* decrease the BUCK3 voltage after frequency changed to lower
578 	 * and APD in ND_MODE
579 	 */
580 	if (freq_index == 1U && sys_dvfs) {
581 		upower_pmic_i2c_write(0x22, 0x20);
582 	}
583 
584 	/* DFS done successfully */
585 	return 0;
586 }
587 
588 /* for the non-primary core, waiting for DFS done */
589 static uint64_t waiting_dvfs(uint32_t id, uint32_t flags,
590 		void *handle, void *cookie)
591 {
592 	uint32_t irq;
593 
594 	irq = plat_ic_acknowledge_interrupt();
595 	if (irq < 1022U) {
596 		plat_ic_end_of_interrupt(irq);
597 	}
598 
599 	/* set the WFE done status */
600 	spin_lock(&dfs_lock);
601 	core_count++;
602 	dsb();
603 	spin_unlock(&dfs_lock);
604 
605 	while (in_progress) {
606 		wfe();
607 	}
608 
609 	return 0;
610 }
611 
612 int dram_dvfs_handler(uint32_t smc_fid, void *handle,
613 		u_register_t x1, u_register_t x2, u_register_t x3)
614 {
615 	unsigned int fsp_index = x1;
616 	uint32_t online_cpus = x2 - 1;
617 	uint64_t mpidr = read_mpidr_el1();
618 	unsigned int cpu_id = MPIDR_AFFLVL0_VAL(mpidr);
619 
620 	/* Get the number of FSPs */
621 	if (x1 == DDR_DFS_GET_FSP_COUNT) {
622 		SMC_RET2(handle, num_fsp, info->fsp_table[1]);
623 	}
624 
625 	/* start lpddr frequency scaling */
626 	in_progress = true;
627 	sys_dvfs = x3 ? true : false;
628 	dsb();
629 
630 	/* notify other core wait for scaling done */
631 	for (unsigned int i = 0; i < PLATFORM_CORE_COUNT; i++)
632 		/* Skip raise SGI for current CPU */
633 		if (i != cpu_id) {
634 			plat_ic_raise_el3_sgi(0x8, i);
635 		}
636 
637 	/* Make sure all the cpu in WFE */
638 	while (online_cpus != core_count) {
639 		;
640 	}
641 
642 	/* Flush the L1/L2 cache */
643 	dcsw_op_all(DCCSW);
644 
645 	lpddr4_dfs(fsp_index);
646 
647 	in_progress = false;
648 	core_count = 0;
649 	dsb();
650 	sev();
651 	isb();
652 
653 	SMC_RET1(handle, 0);
654 }
655 
656 void dram_init(void)
657 {
658 	uint32_t flags = 0;
659 	uint32_t rc;
660 	unsigned int i;
661 
662 	/* Register the EL3 handler for DDR DVFS */
663 	set_interrupt_rm_flag(flags, NON_SECURE);
664 	rc = register_interrupt_type_handler(INTR_TYPE_EL3, waiting_dvfs, flags);
665 	if (rc) {
666 		panic();
667 	}
668 
669 	info = (struct dram_timing_info *)SAVED_DRAM_DATA_BASE;
670 
671 	/* Get the num of the supported Fsp */
672 	for (i = 0; i < MAX_FSP_NUM; i++) {
673 		if (!info->fsp_table[i]) {
674 			break;
675 		}
676 	}
677 
678 	num_fsp = (i > MAX_FSP_NUM) ? MAX_FSP_NUM : i;
679 }
680