1 // SPDX-License-Identifier: GPL-2.0
2 /*
3  * Copyright (C) ASPEED Technology Inc.
4  *
5  */
6 
7 #include <common.h>
8 #include <clk.h>
9 #include <dm.h>
10 #include <errno.h>
11 #include <ram.h>
12 #include <regmap.h>
13 #include <reset.h>
14 #include <asm/io.h>
15 #include <asm/arch/scu_ast2600.h>
16 #include <asm/arch/sdram_ast2600.h>
17 #include <linux/err.h>
18 #include <linux/kernel.h>
19 #include <dt-bindings/clock/ast2600-clock.h>
20 #include "sdram_phy_ast2600.h"
21 
22 /* in order to speed up DRAM init time, write pre-defined values to registers
23  * directly */
24 #define AST2600_SDRAMMC_MANUAL_CLK
25 
26 /* register offset */
27 #define AST_SCU_FPGA_STATUS	0x004
28 #define AST_SCU_HANDSHAKE	0x100
29 #define AST_SCU_MPLL		0x220
30 #define AST_SCU_MPLL_EXT	0x224
31 #define AST_SCU_FPGA_PLL	0x400
32 #define AST_SCU_HW_STRAP	0x500
33 #define AST_SCU_EFUSE_DATA	0x594
34 
35 
36 /* bit-field of AST_SCU_HW_STRAP */
37 #define SCU_HWSTRAP_VGAMEM_SHIFT	13
38 #define SCU_HWSTRAP_VGAMEM_MASK		GENMASK(14, 13)
39 
40 /* bit-field of AST_SCU_EFUSE_DATA */
41 #define SCU_EFUSE_DATA_VGA_DIS_MASK	BIT(14)
42 
43 /* bit-field of AST_SCU_HANDSHAKE */
44 #define SCU_SDRAM_INIT_READY_MASK	BIT(6)
45 #define SCU_SDRAM_INIT_BY_SOC_MASK	BIT(7)
46 
47 /* bit-field of AST_SCU_MPLL */
48 #define SCU_MPLL_RESET			BIT(25)
49 #define SCU_MPLL_BYPASS			BIT(24)
50 #define SCU_MPLL_TURN_OFF		BIT(23)
51 #define SCU_MPLL_FREQ_MASK		GENMASK(22, 0)
52 
53 #define SCU_MPLL_FREQ_400M		0x0008405F
54 #define SCU_MPLL_EXT_400M		0x0000002F
55 //#define SCU_MPLL_FREQ_400M		0x0038007F
56 //#define SCU_MPLL_EXT_400M		0x0000003F
57 #define SCU_MPLL_FREQ_333M		0x00488299
58 #define SCU_MPLL_EXT_333M		0x0000014C
59 #define SCU_MPLL_FREQ_200M		0x0078007F
60 #define SCU_MPLL_EXT_200M		0x0000003F
61 #define SCU_MPLL_FREQ_100M		0x0078003F
62 #define SCU_MPLL_EXT_100M		0x0000001F
63 /* MPLL configuration */
64 #if defined(CONFIG_ASPEED_DDR4_1600)
65 #define SCU_MPLL_FREQ_CFG		SCU_MPLL_FREQ_400M
66 #define SCU_MPLL_EXT_CFG		SCU_MPLL_EXT_400M
67 #elif defined(CONFIG_ASPEED_DDR4_1333)
68 #define SCU_MPLL_FREQ_CFG		SCU_MPLL_FREQ_333M
69 #define SCU_MPLL_EXT_CFG		SCU_MPLL_EXT_333M
70 #elif defined(CONFIG_ASPEED_DDR4_800)
71 #define SCU_MPLL_FREQ_CFG		SCU_MPLL_FREQ_200M
72 #define SCU_MPLL_EXT_CFG		SCU_MPLL_EXT_200M
73 #elif defined(CONFIG_ASPEED_DDR4_400)
74 #define SCU_MPLL_FREQ_CFG		SCU_MPLL_FREQ_100M
75 #define SCU_MPLL_EXT_CFG		SCU_MPLL_EXT_100M
76 #else
77 #error "undefined DDR4 target rate\n"
78 #endif
79 
80 /* AC timing and SDRAM mode registers */
81 #if defined(CONFIG_FPGA_ASPEED) || defined(CONFIG_ASPEED_PALLADIUM)
82 /* mode register settings for FPGA are fixed */
83 #define DDR4_MR01_MODE		0x03010100
84 #define DDR4_MR23_MODE		0x00000000
85 #define DDR4_MR45_MODE		0x04C00000
86 #define DDR4_MR6_MODE		0x00000050
87 #define DDR4_TRFC_FPGA		0x17263434
88 
89 /* FPGA need for an additional initialization procedure: search read window */
90 #define SEARCH_RDWIN_ANCHOR_0   (CONFIG_SYS_SDRAM_BASE + 0x0000)
91 #define SEARCH_RDWIN_ANCHOR_1   (CONFIG_SYS_SDRAM_BASE + 0x0004)
92 #define SEARCH_RDWIN_PTRN_0     0x12345678
93 #define SEARCH_RDWIN_PTRN_1     0xaabbccdd
94 #define SEARCH_RDWIN_PTRN_SUM   0xbcf02355
95 #else
96 /* mode register setting for real chip are derived from the model GDDR4-1600 */
97 #define DDR4_MR01_MODE		0x03010510
98 #define DDR4_MR23_MODE		0x00000000
99 #define DDR4_MR45_MODE		0x04000000
100 #define DDR4_MR6_MODE           0x00000400
101 #define DDR4_TRFC_1600		0x467299f1
102 #define DDR4_TRFC_1333		0x3a5f80c9
103 #define DDR4_TRFC_800		0x23394c78
104 #define DDR4_TRFC_400		0x111c263c
105 #endif /* end of "#if defined(CONFIG_FPGA_ASPEED) ||                           \
106 	  defined(CONFIG_ASPEED_PALLADIUM)" */
107 
108 #if defined(CONFIG_FPGA_ASPEED) || defined(CONFIG_ASPEED_PALLADIUM)
109 #define DDR4_TRFC			DDR4_TRFC_FPGA
110 #else
111 /* real chip setting */
112 #if defined(CONFIG_ASPEED_DDR4_1600)
113 #define DDR4_TRFC			DDR4_TRFC_1600
114 #define DDR4_PHY_TRAIN_TRFC		0xc30
115 #elif defined(CONFIG_ASPEED_DDR4_1333)
116 #define DDR4_TRFC			DDR4_TRFC_1333
117 #define DDR4_PHY_TRAIN_TRFC		0xa25
118 #elif defined(CONFIG_ASPEED_DDR4_800)
119 #define DDR4_TRFC			DDR4_TRFC_800
120 #define DDR4_PHY_TRAIN_TRFC		0x618
121 #elif defined(CONFIG_ASPEED_DDR4_400)
122 #define DDR4_TRFC			DDR4_TRFC_400
123 #define DDR4_PHY_TRAIN_TRFC		0x30c
124 #else
125 #error "undefined tRFC setting"
126 #endif	/* end of "#if (SCU_MPLL_FREQ_CFG == SCU_MPLL_FREQ_400M)" */
127 #endif  /* end of "#if defined(CONFIG_FPGA_ASPEED) ||                          \
128 	   defined(CONFIG_ASPEED_PALLADIUM)" */
129 
130 /* supported SDRAM size */
131 #define SDRAM_SIZE_1KB		(1024U)
132 #define SDRAM_SIZE_1MB		(SDRAM_SIZE_1KB * SDRAM_SIZE_1KB)
133 #define SDRAM_MIN_SIZE		(256 * SDRAM_SIZE_1MB)
134 #define SDRAM_MAX_SIZE		(2048 * SDRAM_SIZE_1MB)
135 
136 
137 DECLARE_GLOBAL_DATA_PTR;
138 
139 /*
140  * Bandwidth configuration parameters for different SDRAM requests.
141  * These are hardcoded settings taken from Aspeed SDK.
142  */
143 #if defined(CONFIG_FPGA_ASPEED) || defined(CONFIG_ASPEED_PALLADIUM)
144 static const u32 ddr4_ac_timing[4] = {0x030C0207, 0x04451133, 0x0E010200,
145                                       0x00000140};
146 
147 static const u32 ddr_max_grant_params[4] = {0x88888888, 0x88888888, 0x88888888,
148                                             0x88888888};
149 #else
150 static const u32 ddr4_ac_timing[4] = {0x040e0307, 0x0f4711f1, 0x0e060304,
151                                       0x00001240};
152 
153 static const u32 ddr_max_grant_params[4] = {0x44444444, 0x44444444, 0x44444444,
154                                             0x44444444};
155 #endif
156 
157 struct dram_info {
158 	struct ram_info info;
159 	struct clk ddr_clk;
160 	struct ast2600_sdrammc_regs *regs;
161 	void __iomem *scu;
162 	struct ast2600_ddr_phy *phy;
163 	void __iomem *phy_setting;
164 	void __iomem *phy_status;
165 	ulong clock_rate;
166 };
167 
168 static void ast2600_sdramphy_kick_training(struct dram_info *info)
169 {
170 #if !defined(CONFIG_FPGA_ASPEED) && !defined(CONFIG_ASPEED_PALLADIUM)
171 	struct ast2600_sdrammc_regs *regs = info->regs;
172 	u32 volatile data;
173 
174 	writel(SDRAM_PHYCTRL0_NRST, &regs->phy_ctrl[0]);
175 	udelay(5);
176 	writel(SDRAM_PHYCTRL0_NRST | SDRAM_PHYCTRL0_INIT, &regs->phy_ctrl[0]);
177 	udelay(1000);
178 
179 	while (1) {
180 		data = readl(&regs->phy_ctrl[0]) & SDRAM_PHYCTRL0_INIT;
181 		if (~data) {
182 			break;
183 		}
184 	}
185 
186 #if 0
187 	while (1) {
188 		data = readl(0x1e6e0400) & BIT(1);
189 		if (data) {
190 			break;
191 		}
192 	}
193 #endif
194 #endif
195 }
196 
197 /**
198  * @brief	load DDR-PHY configurations table to the PHY registers
199  * @param[in]	p_tbl - pointer to the configuration table
200  * @param[in]	info - pointer to the DRAM info struct
201  *
202  * There are two sets of MRS (Mode Registers) configuration in ast2600 memory
203  * system: one is in the SDRAM MC (memory controller) which is used in run
204  * time, and the other is in the DDR-PHY IP which is used during DDR-PHY
205  * training.
206 */
207 static void ast2600_sdramphy_init(u32 *p_tbl, struct dram_info *info)
208 {
209 #if !defined(CONFIG_FPGA_ASPEED) && !defined(CONFIG_ASPEED_PALLADIUM)
210 	u32 reg_base = (u32)info->phy_setting;
211 	u32 addr = p_tbl[0];
212         u32 data;
213         int i = 1;
214 
215 	writel(0, &info->regs->phy_ctrl[0]);
216 	udelay(10);
217 	//writel(SDRAM_PHYCTRL0_NRST, &regs->phy_ctrl[0]);
218 
219 
220         /* load PHY configuration table into PHY-setting registers */
221         while (1) {
222                 if (addr < reg_base) {
223                         debug("invalid DDR-PHY addr: 0x%08x\n", addr);
224                         break;
225                 }
226                 data = p_tbl[i++];
227 
228                 if (DDR_PHY_TBL_END == data) {
229                         break;
230                 } else if (DDR_PHY_TBL_CHG_ADDR == data) {
231                         addr = p_tbl[i++];
232                 } else {
233                         writel(data, addr);
234                         addr += 4;
235                 }
236         }
237 
238 	data = readl(info->phy_setting + 0x84) & ~GENMASK(16, 0);
239 	data |= DDR4_PHY_TRAIN_TRFC;
240 	writel(data, info->phy_setting + 0x84);
241 #endif
242 }
243 
244 static int ast2600_sdramphy_check_status(struct dram_info *info)
245 {
246 #if !defined(CONFIG_FPGA_ASPEED) && !defined(CONFIG_ASPEED_PALLADIUM)
247         u32 value, tmp;
248         u32 reg_base = (u32)info->phy_status;
249 	int need_retrain = 0;
250 
251 	debug("\nSDRAM PHY training report:\n");
252 	/* training status */
253 	value = readl(reg_base + 0x00);
254 	debug("rO_DDRPHY_reg offset 0x00 = 0x%08x\n", value);
255 	if (value & BIT(3)) {
256 		debug("\tinitial PVT calibration fail\n");
257 	}
258 	if (value & BIT(5)) {
259 		debug("\truntime calibration fail\n");
260 	}
261 
262 	/* PU & PD */
263 	value = readl(reg_base + 0x30);
264 	debug("rO_DDRPHY_reg offset 0x30 = 0x%08x\n", value);
265         debug("  PU = 0x%02x\n", value & 0xff);
266         debug("  PD = 0x%02x\n", (value >> 16) & 0xff);
267 
268 	/* read eye window */
269         value = readl(reg_base + 0x68);
270 	if (0 == (value & GENMASK(7, 0))) {
271 		need_retrain = 1;
272 	}
273 
274 	debug("rO_DDRPHY_reg offset 0x68 = 0x%08x\n", value);
275 	debug("  rising edge of read data eye training pass window\n");
276 	tmp = (((value & GENMASK(7, 0)) >> 0) * 100) / 255;
277 	debug("    B0:%d%%\n", tmp);
278 	tmp = (((value & GENMASK(15, 8)) >> 8) * 100) / 255;
279         debug("    B1:%d%%\n", tmp);
280 
281 	value = readl(reg_base + 0xC8);
282 	debug("rO_DDRPHY_reg offset 0xC8 = 0x%08x\n", value);
283 	debug("  falling edge of read data eye training pass window\n");
284 	tmp = (((value & GENMASK(7, 0)) >> 0) * 100) / 255;
285 	debug("    B0:%d%%\n", tmp);
286 	tmp = (((value & GENMASK(15, 8)) >> 8) * 100) / 255;
287         debug("    B1:%d%%\n", tmp);
288 
289         /* write eye window */
290         value = readl(reg_base + 0x7c);
291 	if (0 == (value & GENMASK(7, 0))) {
292 		need_retrain = 1;
293 	}
294 
295 	debug("rO_DDRPHY_reg offset 0x7C = 0x%08x\n", value);
296 	debug("  rising edge of write data eye training pass window\n");
297 	tmp = (((value & GENMASK(7, 0)) >> 0) * 100) / 255;
298 	debug("    B0:%d%%\n", tmp);
299 	tmp = (((value & GENMASK(15, 8)) >> 8) * 100) / 255;
300         debug("    B1:%d%%\n", tmp);
301 
302 	/* read Vref training result */
303         value = readl(reg_base + 0x88);
304 	debug("rO_DDRPHY_reg offset 0x88 = 0x%08x\n", value);
305         debug("  read Vref training result\n");
306 	tmp = (((value & GENMASK(7, 0)) >> 0) * 100) / 127;
307 	debug("    B0:%d%%\n", tmp);
308 	tmp = (((value & GENMASK(15, 8)) >> 8) * 100) / 127;
309         debug("    B1:%d%%\n", tmp);
310 
311         /* write Vref training result */
312         value = readl(reg_base + 0x90);
313 	debug("rO_DDRPHY_reg offset 0x90 = 0x%08x\n", value);
314 #if 0
315 	tmp = (((value & GENMASK(5, 0)) >> 0) * 100) / 127;
316         debug("  write Vref training result = %d%%\n", tmp);
317 #endif
318 
319         /* gate train */
320 	value = readl(reg_base + 0x50);
321 	if ((0 == (value & GENMASK(15, 0))) ||
322 	    (0 == (value & GENMASK(31, 16)))) {
323 		need_retrain = 1;
324 	}
325 #if 0
326 	if (((value >> 24) & 0xff) < 3)
327 		need_retrain = 1;
328 	else
329 		need_retrain = 0;
330 #endif
331 	debug("rO_DDRPHY_reg offset 0x50 = 0x%08x\n", value);
332 #if 0
333 	debug("  gate training pass window\n");
334 	tmp = (((value & GENMASK(7, 0)) >> 0) * 100) / 255;
335 	debug("    module 0: %d.%03d\n", (value >> 8) & 0xff, tmp);
336         tmp = (((value & GENMASK(23, 16)) >> 0) * 100) / 255;
337 	debug("    module 1: %d.%03d\n", (value >> 24) & 0xff, tmp);
338 #endif
339 
340 	return need_retrain;
341 #else
342 	return 0;
343 #endif
344 }
345 #ifndef CONFIG_ASPEED_BYPASS_SELFTEST
346 #define MC_TEST_PATTERN_N 8
347 static u32 as2600_sdrammc_test_pattern[MC_TEST_PATTERN_N] = {
348     0xcc33cc33, 0xff00ff00, 0xaa55aa55, 0x88778877,
349     0x92cc4d6e, 0x543d3cde, 0xf1e843c7, 0x7c61d253};
350 
351 #define TIMEOUT_DRAM	5000000
352 int ast2600_sdrammc_dg_test(struct dram_info *info, unsigned int datagen, u32 mode)
353 {
354 	unsigned int data;
355 	unsigned int timeout = 0;
356 	struct ast2600_sdrammc_regs *regs = info->regs;
357 
358 	writel(0, &regs->ecc_test_ctrl);
359 	if (mode == 0) {
360 		writel(0x00000085 | (datagen << 3), &regs->ecc_test_ctrl);
361 	} else {
362 		writel(0x000000C1 | (datagen << 3), &regs->ecc_test_ctrl);
363 	}
364 
365 	do {
366 		data = readl(&regs->ecc_test_ctrl) & GENMASK(13, 12);
367 
368 		if (data & BIT(13))
369 			return (0);
370 
371 		if (++timeout > TIMEOUT_DRAM) {
372 			printf("Timeout!!\n");
373 			writel(0, &regs->ecc_test_ctrl);
374 
375 			return (0);
376 		}
377 	} while (!data);
378 
379 	writel(0, &regs->ecc_test_ctrl);
380 
381 	return (1);
382 }
383 
384 int ast2600_sdrammc_cbr_test(struct dram_info *info)
385 {
386 	struct ast2600_sdrammc_regs *regs = info->regs;
387 	u32 i;
388 
389 	clrsetbits_le32(&regs->test_addr, GENMASK(30, 4), 0x7ffff0);
390 
391 	/* single */
392 	for (i=0; i<8; i++) {
393   		if(!ast2600_sdrammc_dg_test(info, i, 0))   return(0);
394 	}
395 
396 	/* burst */
397 	for (i=0; i<8; i++) {
398   		if(!ast2600_sdrammc_dg_test(info, i, i))   return(0);
399 	}
400 
401 	return(1);
402 }
403 
404 static int ast2600_sdrammc_test(struct dram_info *info)
405 {
406 	struct ast2600_sdrammc_regs *regs = info->regs;
407 
408 	u32 pass_cnt = 0;
409 	u32 fail_cnt = 0;
410 	u32 target_cnt = 2;
411 	u32 test_cnt = 0;
412 	u32 pattern;
413 	u32 i = 0;
414 	bool finish = false;
415 
416 	debug("sdram mc test:\n");
417 	while (finish == false) {
418 		pattern = as2600_sdrammc_test_pattern[i++];
419 		i = i % MC_TEST_PATTERN_N;
420 		debug("  pattern = %08X : ",pattern);
421 		writel(pattern, &regs->test_init_val);
422 
423 		if (!ast2600_sdrammc_cbr_test(info)) {
424 			debug("fail\n");
425 			fail_cnt++;
426 		} else {
427 			debug("pass\n");
428 			pass_cnt++;
429 		}
430 
431 		if (++test_cnt == target_cnt) {
432 			finish = true;
433 		}
434 	}
435 	debug("statistics: pass/fail/total:%d/%d/%d\n", pass_cnt, fail_cnt,
436 	       target_cnt);
437 	return fail_cnt;
438 }
439 #endif
440 /**
441  * scu500[14:13]
442  * 	2b'00: VGA memory size = 16MB
443  * 	2b'01: VGA memory size = 16MB
444  * 	2b'10: VGA memory size = 32MB
445  * 	2b'11: VGA memory size = 64MB
446  *
447  * mcr04[3:2]
448  * 	2b'00: VGA memory size = 8MB
449  * 	2b'01: VGA memory size = 16MB
450  * 	2b'10: VGA memory size = 32MB
451  * 	2b'11: VGA memory size = 64MB
452 */
453 static size_t ast2600_sdrammc_get_vga_mem_size(struct dram_info *info)
454 {
455         u32 vga_hwconf;
456         size_t vga_mem_size_base = 8 * 1024 * 1024;
457 
458 	vga_hwconf =
459 	    (readl(info->scu + AST_SCU_HW_STRAP) & SCU_HWSTRAP_VGAMEM_MASK) >>
460 	    SCU_HWSTRAP_VGAMEM_SHIFT;
461 
462 	if (vga_hwconf == 0) {
463 		vga_hwconf = 1;
464 		writel(vga_hwconf << SCU_HWSTRAP_VGAMEM_SHIFT,
465 		       info->scu + AST_SCU_HW_STRAP);
466 	}
467 
468 	clrsetbits_le32(&info->regs->config, SDRAM_CONF_VGA_SIZE_MASK,
469 			((vga_hwconf << SDRAM_CONF_VGA_SIZE_SHIFT) &
470 			 SDRAM_CONF_VGA_SIZE_MASK));
471 
472 	/* no need to reserve VGA memory if efuse[VGA disable] is set */
473 	if (readl(info->scu + AST_SCU_EFUSE_DATA) & SCU_EFUSE_DATA_VGA_DIS_MASK)
474 		return 0;
475 
476 	return vga_mem_size_base << vga_hwconf;
477 }
478 #if defined(CONFIG_FPGA_ASPEED) || defined(CONFIG_ASPEED_PALLADIUM)
479 static void ast2600_sdrammc_fpga_set_pll(struct dram_info *info)
480 {
481         u32 data;
482         u32 scu_base = (u32)info->scu;
483 
484         writel(0x00000303, scu_base + AST_SCU_FPGA_PLL);
485 
486         do {
487                 data = readl(scu_base + AST_SCU_FPGA_STATUS);
488         } while (!(data & 0x100));
489 
490         writel(0x00000103, scu_base + AST_SCU_FPGA_PLL);
491 }
492 
493 static int ast2600_sdrammc_search_read_window(struct dram_info *info)
494 {
495         u32 pll, pll_min, pll_max, dat1, offset;
496         u32 win = 0x03, gwin = 0, gwinsize = 0;
497         u32 phy_setting = (u32)info->phy_setting;
498 
499 #ifdef CONFIG_ASPEED_PALLADIUM
500 	writel(0xc, phy_setting + 0x0000);
501 	return (1);
502 #endif
503         writel(SEARCH_RDWIN_PTRN_0, SEARCH_RDWIN_ANCHOR_0);
504         writel(SEARCH_RDWIN_PTRN_1, SEARCH_RDWIN_ANCHOR_1);
505 
506         while (gwin == 0) {
507                 while (!(win & 0x80)) {
508                         debug("Window = 0x%X\n", win);
509                         writel(win, phy_setting + 0x0000);
510 
511                         dat1 = readl(SEARCH_RDWIN_ANCHOR_0);
512                         dat1 += readl(SEARCH_RDWIN_ANCHOR_1);
513                         while (dat1 == SEARCH_RDWIN_PTRN_SUM) {
514                                 ast2600_sdrammc_fpga_set_pll(info);
515                                 dat1 = readl(SEARCH_RDWIN_ANCHOR_0);
516                                 dat1 += readl(SEARCH_RDWIN_ANCHOR_1);
517                         }
518 
519                         pll_min = 0xfff;
520                         pll_max = 0x0;
521                         pll = 0;
522                         while (pll_max > 0 || pll < 256) {
523                                 ast2600_sdrammc_fpga_set_pll(info);
524                                 dat1 = readl(SEARCH_RDWIN_ANCHOR_0);
525                                 dat1 += readl(SEARCH_RDWIN_ANCHOR_1);
526                                 if (dat1 == SEARCH_RDWIN_PTRN_SUM) {
527                                         if (pll_min > pll) {
528                                                 pll_min = pll;
529                                         }
530                                         if (pll_max < pll) {
531                                                 pll_max = pll;
532                                         }
533                                         debug("%3d_(%3d:%3d)\n", pll, pll_min,
534                                                pll_max);
535                                 } else if (pll_max > 0) {
536                                         pll_min = pll_max - pll_min;
537                                         if (gwinsize < pll_min) {
538                                                 gwin = win;
539                                                 gwinsize = pll_min;
540                                         }
541                                         break;
542                                 }
543                                 pll += 1;
544                         }
545 
546                         if (gwin != 0 && pll_max == 0) {
547                                 break;
548                         }
549                         win = win << 1;
550                 }
551                 if (gwin == 0) {
552                         win = 0x7;
553                 }
554         }
555         debug("Set PLL Read Gating Window = %x\n", gwin);
556         writel(gwin, phy_setting + 0x0000);
557 
558         debug("PLL Read Window training\n");
559         pll_min = 0xfff;
560         pll_max = 0x0;
561 
562         debug("Search Window Start\n");
563         dat1 = readl(SEARCH_RDWIN_ANCHOR_0);
564         dat1 += readl(SEARCH_RDWIN_ANCHOR_1);
565         while (dat1 == SEARCH_RDWIN_PTRN_SUM) {
566                 ast2600_sdrammc_fpga_set_pll(info);
567                 dat1 = readl(SEARCH_RDWIN_ANCHOR_0);
568                 dat1 += readl(SEARCH_RDWIN_ANCHOR_1);
569         }
570 
571         debug("Search Window Margin\n");
572         pll = 0;
573         while (pll_max > 0 || pll < 256) {
574                 ast2600_sdrammc_fpga_set_pll(info);
575                 dat1 = readl(SEARCH_RDWIN_ANCHOR_0);
576                 dat1 += readl(SEARCH_RDWIN_ANCHOR_1);
577                 if (dat1 == SEARCH_RDWIN_PTRN_SUM) {
578                         if (pll_min > pll) {
579                                 pll_min = pll;
580                         }
581                         if (pll_max < pll) {
582                                 pll_max = pll;
583                         }
584                         debug("%3d_(%3d:%3d)\n", pll, pll_min, pll_max);
585                 } else if (pll_max > 0 && (pll_max - pll_min) > 20) {
586                         break;
587                 } else if (pll_max > 0) {
588                         pll_min = 0xfff;
589                         pll_max = 0x0;
590                 }
591                 pll += 1;
592         }
593         if (pll_min < pll_max) {
594                 debug("PLL Read window = %d\n", (pll_max - pll_min));
595                 offset = (pll_max - pll_min) >> 1;
596                 pll_min = 0xfff;
597                 pll = 0;
598                 while (pll < (pll_min + offset)) {
599                         ast2600_sdrammc_fpga_set_pll(info);
600                         dat1 = readl(SEARCH_RDWIN_ANCHOR_0);
601                         dat1 += readl(SEARCH_RDWIN_ANCHOR_1);
602                         if (dat1 == SEARCH_RDWIN_PTRN_SUM) {
603                                 if (pll_min > pll) {
604                                         pll_min = pll;
605                                 }
606                                 debug("%d\n", pll);
607                         } else {
608                                 pll_min = 0xfff;
609                                 pll_max = 0x0;
610                         }
611                         pll += 1;
612                 }
613                 return (1);
614         } else {
615                 debug("PLL Read window training fail\n");
616                 return (0);
617         }
618 }
619 #endif /* end of "#if defined(CONFIG_FPGA_ASPEED) ||                           \
620 	  defined(CONFIG_ASPEED_PALLADIUM)" */
621 
622 /*
623  * Find out RAM size and save it in dram_info
624  *
625  * The procedure is taken from Aspeed SDK
626  */
627 static void ast2600_sdrammc_calc_size(struct dram_info *info)
628 {
629 	/* The controller supports 256/512/1024/2048 MB ram */
630 	size_t ram_size = SDRAM_MIN_SIZE;
631 	const int write_test_offset = 0x100000;
632 	u32 test_pattern = 0xdeadbeef;
633 	u32 cap_param = SDRAM_CONF_CAP_2048M;
634 	u32 refresh_timing_param = DDR4_TRFC;
635 	const u32 write_addr_base = CONFIG_SYS_SDRAM_BASE + write_test_offset;
636 
637 	for (ram_size = SDRAM_MAX_SIZE; ram_size > SDRAM_MIN_SIZE;
638 	     ram_size >>= 1) {
639 		writel(test_pattern, write_addr_base + (ram_size >> 1));
640 		test_pattern = (test_pattern >> 4) | (test_pattern << 28);
641 	}
642 
643 	/* One last write to overwrite all wrapped values */
644 	writel(test_pattern, write_addr_base);
645 
646 	/* Reset the pattern and see which value was really written */
647 	test_pattern = 0xdeadbeef;
648 	for (ram_size = SDRAM_MAX_SIZE; ram_size > SDRAM_MIN_SIZE;
649 	     ram_size >>= 1) {
650 		if (readl(write_addr_base + (ram_size >> 1)) == test_pattern)
651 			break;
652 
653 		--cap_param;
654 		refresh_timing_param >>= 8;
655 		test_pattern = (test_pattern >> 4) | (test_pattern << 28);
656 	}
657 
658 	clrsetbits_le32(&info->regs->ac_timing[1],
659 			(SDRAM_AC_TRFC_MASK << SDRAM_AC_TRFC_SHIFT),
660 			((refresh_timing_param & SDRAM_AC_TRFC_MASK)
661 			 << SDRAM_AC_TRFC_SHIFT));
662 
663 	info->info.base = CONFIG_SYS_SDRAM_BASE;
664 	info->info.size = ram_size - ast2600_sdrammc_get_vga_mem_size(info);
665 	clrsetbits_le32(
666 	    &info->regs->config, SDRAM_CONF_CAP_MASK,
667 	    ((cap_param << SDRAM_CONF_CAP_SHIFT) & SDRAM_CONF_CAP_MASK));
668 }
669 
670 static int ast2600_sdrammc_init_ddr4(struct dram_info *info)
671 {
672         const u32 power_ctrl = MCR34_CKE_EN | MCR34_AUTOPWRDN_EN |
673                                MCR34_MREQ_BYPASS_DIS | MCR34_RESETN_DIS |
674                                MCR34_ODT_EN | MCR34_ODT_AUTO_ON |
675                                (0x1 << MCR34_ODT_EXT_SHIFT);
676 
677         /* init SDRAM-PHY only on real chip */
678 	ast2600_sdramphy_init(ast2600_sdramphy_config, info);
679         writel((MCR34_CKE_EN | MCR34_MREQI_DIS | MCR34_RESETN_DIS),
680                &info->regs->power_ctrl);
681 	udelay(5);
682 	ast2600_sdramphy_kick_training(info);
683 	udelay(500);
684         writel(SDRAM_RESET_DLL_ZQCL_EN, &info->regs->refresh_timing);
685 
686         writel(MCR30_SET_MR(3), &info->regs->mode_setting_control);
687         writel(MCR30_SET_MR(6), &info->regs->mode_setting_control);
688         writel(MCR30_SET_MR(5), &info->regs->mode_setting_control);
689         writel(MCR30_SET_MR(4), &info->regs->mode_setting_control);
690         writel(MCR30_SET_MR(2), &info->regs->mode_setting_control);
691         writel(MCR30_SET_MR(1), &info->regs->mode_setting_control);
692         writel(MCR30_SET_MR(0) | MCR30_RESET_DLL_DELAY_EN,
693                &info->regs->mode_setting_control);
694 
695 #if defined(CONFIG_FPGA_ASPEED) || defined(CONFIG_ASPEED_PALLADIUM)
696 
697         writel(SDRAM_REFRESH_EN | SDRAM_RESET_DLL_ZQCL_EN |
698                    (0x5d << SDRAM_REFRESH_PERIOD_SHIFT),
699                &info->regs->refresh_timing);
700 #else
701         writel(SDRAM_REFRESH_EN | SDRAM_RESET_DLL_ZQCL_EN |
702                    (0x5f << SDRAM_REFRESH_PERIOD_SHIFT),
703                &info->regs->refresh_timing);
704 #endif
705 
706         /* wait self-refresh idle */
707         while (readl(&info->regs->power_ctrl) & MCR34_SELF_REFRESH_STATUS_MASK)
708                 ;
709 
710 #if defined(CONFIG_FPGA_ASPEED) || defined(CONFIG_ASPEED_PALLADIUM)
711         writel(SDRAM_REFRESH_EN | SDRAM_LOW_PRI_REFRESH_EN |
712                    SDRAM_REFRESH_ZQCS_EN |
713                    (0x5d << SDRAM_REFRESH_PERIOD_SHIFT) |
714                    (0x4000 << SDRAM_REFRESH_PERIOD_ZQCS_SHIFT),
715                &info->regs->refresh_timing);
716 #else
717         writel(SDRAM_REFRESH_EN | SDRAM_LOW_PRI_REFRESH_EN |
718                    SDRAM_REFRESH_ZQCS_EN |
719                    (0x5f << SDRAM_REFRESH_PERIOD_SHIFT) |
720                    (0x42aa << SDRAM_REFRESH_PERIOD_ZQCS_SHIFT),
721                &info->regs->refresh_timing);
722 #endif
723 
724         writel(power_ctrl, &info->regs->power_ctrl);
725 	udelay(500);
726 
727 #if defined(CONFIG_FPGA_ASPEED)
728         /* toggle Vref training */
729         setbits_le32(&info->regs->mr6_mode_setting, 0x80);
730         writel(MCR30_RESET_DLL_DELAY_EN | MCR30_SET_MR(6),
731                &info->regs->mode_setting_control);
732         clrbits_le32(&info->regs->mr6_mode_setting, 0x80);
733         writel(MCR30_RESET_DLL_DELAY_EN | MCR30_SET_MR(6),
734                &info->regs->mode_setting_control);
735 #endif
736 	return 0;
737 }
738 
739 static void ast2600_sdrammc_unlock(struct dram_info *info)
740 {
741 	writel(SDRAM_UNLOCK_KEY, &info->regs->protection_key);
742 	while (!readl(&info->regs->protection_key))
743 		;
744 }
745 
746 static void ast2600_sdrammc_lock(struct dram_info *info)
747 {
748 	writel(~SDRAM_UNLOCK_KEY, &info->regs->protection_key);
749 	while (readl(&info->regs->protection_key))
750 		;
751 }
752 
753 static void ast2600_sdrammc_common_init(struct ast2600_sdrammc_regs *regs)
754 {
755 	int i;
756 
757         writel(MCR34_MREQI_DIS | MCR34_RESETN_DIS, &regs->power_ctrl);
758         writel(SDRAM_VIDEO_UNLOCK_KEY, &regs->gm_protection_key);
759         writel(0x10 << MCR38_RW_MAX_GRANT_CNT_RQ_SHIFT,
760                &regs->arbitration_ctrl);
761         writel(0xFFBBFFF4, &regs->req_limit_mask);
762 
763 	for (i = 0; i < ARRAY_SIZE(ddr_max_grant_params); ++i)
764                 writel(ddr_max_grant_params[i], &regs->max_grant_len[i]);
765 
766         writel(MCR50_RESET_ALL_INTR, &regs->intr_ctrl);
767 
768         /* FIXME: the sample code does NOT match the datasheet */
769         writel(0x07FFFFFF, &regs->ecc_range_ctrl);
770 
771         writel(0, &regs->ecc_test_ctrl);
772         writel(0x80000001, &regs->test_addr);
773         writel(0, &regs->test_fail_dq_bit);
774         writel(0, &regs->test_init_val);
775 
776         writel(0xFFFFFFFF, &regs->req_input_ctrl);
777         writel(0, &regs->req_high_pri_ctrl);
778 
779         udelay(600);
780 
781 #ifdef CONFIG_ASPEED_DDR4_DUALX8
782 	writel(0x37, &regs->config);
783 #else
784 	writel(0x17, &regs->config);
785 #endif
786 
787 	/* load controller setting */
788 	for (i = 0; i < ARRAY_SIZE(ddr4_ac_timing); ++i)
789 		writel(ddr4_ac_timing[i], &regs->ac_timing[i]);
790 
791 	writel(DDR4_MR01_MODE, &regs->mr01_mode_setting);
792 	writel(DDR4_MR23_MODE, &regs->mr23_mode_setting);
793 	writel(DDR4_MR45_MODE, &regs->mr45_mode_setting);
794 	writel(DDR4_MR6_MODE, &regs->mr6_mode_setting);
795 }
796 /*
797  * Update size info according to the ECC HW setting
798  *
799  * Assume SDRAM has been initialized by SPL or the host.  To get the RAM size, we
800  * don't need to calculate the ECC size again but read from MCR04 and derive the
801  * size from its value.
802  */
803 static void ast2600_sdrammc_update_size(struct dram_info *info)
804 {
805 	struct ast2600_sdrammc_regs *regs = info->regs;
806 	size_t hw_size;
807 
808 	if (0 == (readl(&regs->config) & SDRAM_CONF_ECC_SETUP))
809 		return;
810 
811 	hw_size = readl(&regs->ecc_range_ctrl) & GENMASK(30, 20);
812 	hw_size += (1 << 20);
813 
814 	info->info.size = hw_size;
815 }
816 #ifdef CONFIG_ASPEED_ECC
817 static void ast2600_sdrammc_ecc_enable(struct dram_info *info)
818 {
819 	struct ast2600_sdrammc_regs *regs = info->regs;
820 	size_t conf_size;
821 	u32 reg;
822 
823 	conf_size = CONFIG_ASPEED_ECC_SIZE * SDRAM_SIZE_1MB;
824 	if (conf_size > info->info.size) {
825 		printf("warning: ECC configured %dMB but actual size is %dMB\n",
826 		       CONFIG_ASPEED_ECC_SIZE,
827 		       info->info.size / SDRAM_SIZE_1MB);
828 		conf_size = info->info.size;
829 	} else if (conf_size == 0) {
830 		conf_size = info->info.size;
831 	}
832 
833 	info->info.size = (((conf_size / 9) * 8) >> 20) << 20;
834 	writel(((info->info.size >> 20) - 1) << 20, &regs->ecc_range_ctrl);
835 	reg = readl(&regs->config) | SDRAM_CONF_ECC_SETUP;
836 	writel(reg, &regs->config);
837 
838 	writel(0, &regs->test_init_val);
839 	writel(0x80000001, &regs->test_addr);
840 	writel(0x221, &regs->ecc_test_ctrl);
841 	while (0 == (readl(&regs->ecc_test_ctrl) & BIT(12)))
842 		;
843 	writel(0, &regs->ecc_test_ctrl);
844 	writel(BIT(31), &regs->intr_ctrl);
845 	writel(0, &regs->intr_ctrl);
846 }
847 #endif
848 
849 static int ast2600_sdrammc_probe(struct udevice *dev)
850 {
851 	struct dram_info *priv = (struct dram_info *)dev_get_priv(dev);
852 	struct ast2600_sdrammc_regs *regs = priv->regs;
853 	struct udevice *clk_dev;
854 	int ret;
855 	volatile uint32_t reg;
856 
857 	/* find SCU base address from clock device */
858 	ret = uclass_get_device_by_driver(UCLASS_CLK, DM_GET_DRIVER(aspeed_scu),
859                                           &clk_dev);
860 	if (ret) {
861 		debug("clock device not defined\n");
862 		return ret;
863 	}
864 
865 	priv->scu = devfdt_get_addr_ptr(clk_dev);
866 	if (IS_ERR(priv->scu)) {
867 		debug("%s(): can't get SCU\n", __func__);
868 		return PTR_ERR(priv->scu);
869 	}
870 
871 	if (readl(priv->scu + AST_SCU_HANDSHAKE) & SCU_SDRAM_INIT_READY_MASK) {
872 		printf("already initialized, ");
873 		ast2600_sdrammc_calc_size(priv);
874 		ast2600_sdrammc_update_size(priv);
875 		return 0;
876 	}
877 
878 #ifdef AST2600_SDRAMMC_MANUAL_CLK
879 	reg = readl(priv->scu + AST_SCU_MPLL);
880 	reg &= ~(BIT(24) | GENMASK(22, 0));
881 	reg |= (BIT(25) | BIT(23) | SCU_MPLL_FREQ_CFG);
882 	writel(reg, priv->scu + AST_SCU_MPLL);
883         writel(SCU_MPLL_EXT_CFG, priv->scu + AST_SCU_MPLL_EXT);
884 	udelay(100);
885 	reg &= ~(BIT(25) | BIT(23));
886 	writel(reg, priv->scu + AST_SCU_MPLL);
887 	while(0 == (readl(priv->scu + AST_SCU_MPLL_EXT) & BIT(31)));
888 #else
889 	ret = clk_get_by_index(dev, 0, &priv->ddr_clk);
890 	if (ret) {
891 		debug("DDR:No CLK\n");
892 		return ret;
893 	}
894 	clk_set_rate(&priv->ddr_clk, priv->clock_rate);
895 #endif
896 
897 #if 0
898 	/* FIXME: enable the following code if reset-driver is ready */
899 	struct reset_ctl reset_ctl;
900 	ret = reset_get_by_index(dev, 0, &reset_ctl);
901 	if (ret) {
902 		debug("%s(): Failed to get reset signal\n", __func__);
903 		return ret;
904 	}
905 
906 	ret = reset_assert(&reset_ctl);
907 	if (ret) {
908 		debug("%s(): SDRAM reset failed: %u\n", __func__, ret);
909 		return ret;
910 	}
911 #endif
912 
913 	ast2600_sdrammc_unlock(priv);
914 	ast2600_sdrammc_common_init(regs);
915 L_ast2600_sdramphy_train:
916 	ast2600_sdrammc_init_ddr4(priv);
917 
918 #if defined(CONFIG_FPGA_ASPEED) || defined(CONFIG_ASPEED_PALLADIUM)
919         ast2600_sdrammc_search_read_window(priv);
920 #else
921 	/* make sure DDR-PHY is ready before access */
922 	do {
923 		reg = readl(priv->phy_status) & BIT(1);
924 	} while(reg == 0);
925 #endif
926 
927 	if (0 != ast2600_sdramphy_check_status(priv)) {
928 		printf("DDR4 PHY training fail, retrain\n");
929 		goto L_ast2600_sdramphy_train;
930 	}
931 
932 	ast2600_sdrammc_calc_size(priv);
933 
934 #ifndef CONFIG_ASPEED_BYPASS_SELFTEST
935         if (0 != ast2600_sdrammc_test(priv)) {
936 		printf("%s: DDR4 init fail\n", __func__);
937 		return -EINVAL;
938 	}
939 #endif
940 
941 #ifdef CONFIG_ASPEED_ECC
942 	ast2600_sdrammc_ecc_enable(priv);
943 #endif
944 
945 	writel(readl(priv->scu + AST_SCU_HANDSHAKE) | SCU_SDRAM_INIT_READY_MASK,
946 	       priv->scu + AST_SCU_HANDSHAKE);
947 
948 	clrbits_le32(&regs->intr_ctrl, MCR50_RESET_ALL_INTR);
949 	ast2600_sdrammc_lock(priv);
950 	return 0;
951 }
952 
953 static int ast2600_sdrammc_ofdata_to_platdata(struct udevice *dev)
954 {
955 	struct dram_info *priv = dev_get_priv(dev);
956 
957 	priv->regs = (void *)(uintptr_t)devfdt_get_addr_index(dev, 0);
958 	priv->phy_setting = (void *)(uintptr_t)devfdt_get_addr_index(dev, 1);
959 	priv->phy_status = (void *)(uintptr_t)devfdt_get_addr_index(dev, 2);
960 
961 	priv->clock_rate = fdtdec_get_int(gd->fdt_blob, dev_of_offset(dev),
962 					  "clock-frequency", 0);
963 	if (!priv->clock_rate) {
964 		debug("DDR Clock Rate not defined\n");
965 		return -EINVAL;
966 	}
967 
968 	return 0;
969 }
970 
971 static int ast2600_sdrammc_get_info(struct udevice *dev, struct ram_info *info)
972 {
973 	struct dram_info *priv = dev_get_priv(dev);
974 
975 	*info = priv->info;
976 
977 	return 0;
978 }
979 
980 static struct ram_ops ast2600_sdrammc_ops = {
981 	.get_info = ast2600_sdrammc_get_info,
982 };
983 
984 static const struct udevice_id ast2600_sdrammc_ids[] = {
985 	{ .compatible = "aspeed,ast2600-sdrammc" },
986 	{ }
987 };
988 
989 U_BOOT_DRIVER(sdrammc_ast2600) = {
990 	.name = "aspeed_ast2600_sdrammc",
991 	.id = UCLASS_RAM,
992 	.of_match = ast2600_sdrammc_ids,
993 	.ops = &ast2600_sdrammc_ops,
994 	.ofdata_to_platdata = ast2600_sdrammc_ofdata_to_platdata,
995 	.probe = ast2600_sdrammc_probe,
996 	.priv_auto_alloc_size = sizeof(struct dram_info),
997 };
998