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