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