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 #define AST2600_SDRAMMC_FPGA
24 
25 /* in order to speed up DRAM init time, write pre-defined values to registers
26  * directly */
27 #define AST2600_SDRAMMC_MANUAL_CLK
28 
29 #ifdef AST2600_SDRAMMC_FPGA
30 /* mode register settings for FPGA are fixed */
31 #define DDR4_MR01_MODE		0x03010100
32 #define DDR4_MR23_MODE		0x00000000
33 #define DDR4_MR45_MODE		0x04C00000
34 #define DDR4_MR6_MODE		0x00000050
35 #define DDR4_TRFC		0x17263434
36 
37 /* FPGA need for an additional initialization procedure: search read window */
38 #define SEARCH_RDWIN_ANCHOR_0   (CONFIG_SYS_SDRAM_BASE + 0x0000)
39 #define SEARCH_RDWIN_ANCHOR_1   (CONFIG_SYS_SDRAM_BASE + 0x0004)
40 #define SEARCH_RDWIN_PTRN_0     0x12345678
41 #define SEARCH_RDWIN_PTRN_1     0xaabbccdd
42 #define SEARCH_RDWIN_PTRN_SUM   0xbcf02355
43 #else
44 /* mode register setting for real chip are derived from the model GDDR4-1600 */
45 #define DDR4_MR01_MODE		0x03010510
46 #define DDR4_MR23_MODE		0x00000000
47 #define DDR4_MR45_MODE		0x04000000
48 #define DDR4_MR6_MODE           0x00000400
49 #define DDR4_TRFC               0x467299f1
50 #endif  /* end of "#ifdef AST2600_SDRAMMC_FPGA" */
51 
52 #define SDRAM_SIZE_1KB		(1024U)
53 #define SDRAM_SIZE_1MB		(SDRAM_SIZE_1KB * SDRAM_SIZE_1KB)
54 #define SDRAM_MIN_SIZE		(256 * SDRAM_SIZE_1MB)
55 #define SDRAM_MAX_SIZE		(2048 * SDRAM_SIZE_1MB)
56 
57 /* register offset */
58 #define AST_SCU_CONFIG		0x004
59 #define AST_SCU_HANDSHAKE	0x100
60 #define AST_SCU_MPLL		0x220
61 #define AST_SCU_FPGA_PLL	0x400
62 #define AST_SCU_HW_STRAP	0x500
63 
64 /* bit-field of AST_SCU_HW_STRAP */
65 #define SCU_HWSTRAP_VGAMEM_SHIFT	2
66 #define SCU_HWSTRAP_VGAMEM_MASK		(3 << SCU_HWSTRAP_VGAMEM_SHIFT)
67 #define SCU_HWSTRAP_DDR3		(1 << 25)
68 
69 
70 /* bit-field of AST_SCU_HANDSHAKE */
71 #define SCU_SDRAM_INIT_READY_SHIFT	6
72 #define SCU_SDRAM_INIT_READY_MASK	(0x1 << SCU_SDRAM_INIT_READY_SHIFT)
73 #define SCU_SDRAM_INIT_BY_SOC_SHIFT	7
74 #define SCU_SDRAM_INIT_BY_SOC_MASK	(0x1 << SCU_SDRAM_INIT_BY_SOC_SHIFT)
75 
76 
77 /* bit-field of AST_SCU_MPLL */
78 #define SCU_MPLL_FREQ_MASK		0x007FFFFF	/* bit[22:0] */
79 #define SCU_MPLL_FREQ_400M		0x0008405F	/* 0x0038007F */
80 #define SCU_MPLL_FREQ_200M		0x0078007F
81 #define SCU_MPLL_FREQ_CFG		SCU_MPLL_FREQ_400M
82 
83 #define SCU_MPLL_TURN_OFF		BIT(23)
84 #define SCU_MPLL_BYPASS			BIT(24)
85 #define SCU_MPLL_RESET			BIT(25)
86 
87 DECLARE_GLOBAL_DATA_PTR;
88 
89 /*
90  * Bandwidth configuration parameters for different SDRAM requests.
91  * These are hardcoded settings taken from Aspeed SDK.
92  */
93 #ifdef AST2600_SDRAMMC_FPGA
94 static const u32 ddr4_ac_timing[4] = {0x030C0207, 0x04451133, 0x0E010200,
95                                       0x00000140};
96 
97 static const u32 ddr_max_grant_params[4] = {0x88888888, 0x88888888, 0x88888888,
98                                             0x88888888};
99 #else
100 static const u32 ddr4_ac_timing[4] = {0x040e0307, 0x0f4711f1, 0x0e060304,
101                                       0x00001240};
102 
103 static const u32 ddr_max_grant_params[4] = {0x44444444, 0x44444444, 0x44444444,
104                                             0x44444444};
105 #endif
106 
107 struct dram_info {
108 	struct ram_info info;
109 	struct clk ddr_clk;
110 	struct ast2600_sdrammc_regs *regs;
111 	void __iomem *scu;
112 	struct ast2600_ddr_phy *phy;
113 	void __iomem *phy_setting;
114 	void __iomem *phy_status;
115 	ulong clock_rate;
116 };
117 
118 static void ast2600_sdramphy_kick_training(struct dram_info *info)
119 {
120 #ifndef AST2600_SDRAMMC_FPGA
121         struct ast2600_sdrammc_regs *regs = info->regs;
122         u32 mask = SDRAM_PHYCTRL0_INIT | SDRAM_PHYCTRL0_PLL_LOCKED;
123         u32 data;
124 
125         writel(0, &regs->phy_ctrl[0]);
126         udelay(2);
127         writel(SDRAM_PHYCTRL0_NRST | SDRAM_PHYCTRL0_INIT, &regs->phy_ctrl[0]);
128 
129         /* wait for (PLL_LOCKED == 1) and (INIT == 0) */
130         do {
131                 data = readl(&regs->phy_ctrl[0]) & mask;
132         } while (SDRAM_PHYCTRL0_PLL_LOCKED != data);
133 #endif
134 }
135 
136 /**
137  * @brief	load DDR-PHY configurations table to the PHY registers
138  * @param[in]	p_tbl - pointer to the configuration table
139  * @param[in]	info - pointer to the DRAM info struct
140 */
141 static void ast2600_sdramphy_init(u32 *p_tbl, struct dram_info *info)
142 {
143 #ifndef AST2600_SDRAMMC_FPGA
144 	u32 reg_base = (u32)info->phy_setting;
145 	u32 addr = p_tbl[0];
146         u32 data;
147         int i = 1;
148 
149         debug("%s:reg base = 0x%08x, 1st addr = 0x%08x\n", __func__, reg_base,
150                addr);
151 
152         /* load PHY configuration table into PHY-setting registers */
153         while (1) {
154                 if (addr < reg_base) {
155                         debug("invalid DDR-PHY addr: 0x%08x\n", addr);
156                         break;
157                 }
158                 data = p_tbl[i++];
159 
160                 if (DDR_PHY_TBL_END == data) {
161                         break;
162                 } else if (DDR_PHY_TBL_CHG_ADDR == data) {
163                         addr = p_tbl[i++];
164                 } else {
165                         writel(data, addr);
166                         addr += 4;
167                 }
168         }
169 #endif
170 }
171 
172 static void ast2600_sdramphy_show_status(struct dram_info *info)
173 {
174 #ifndef AST2600_SDRAMMC_FPGA
175         u32 value;
176         u32 reg_base = (u32)info->phy_status;
177 
178         debug("%s:reg base = 0x%08x\n", __func__, reg_base);
179 
180         value = readl(reg_base + 0x00);
181         if (value & BIT(3)) {
182                 debug("initial PVT calibration fail\n");
183         }
184         if (value & BIT(5)) {
185                 debug("runtime calibration fail\n");
186         }
187 
188         value = readl(reg_base + 0x30);
189         debug("IO PU = 0x%02x\n", value & 0xff);
190         debug("IO PD = 0x%02x\n", (value >> 16) & 0xff);
191 
192         value = readl(reg_base + 0x88);
193         debug("PHY vref: 0x%02x_%02x\n", value & 0xff, (value >> 8) & 0xff);
194         value = readl(reg_base + 0x90);
195         debug("DDR vref: 0x%02x\n", value & 0x3f);
196 
197         value = readl(reg_base + 0x40);
198         debug("MLB Gate training result: 0x%04x_%04x\n", value & 0xffff,
199               (value >> 16) & 0xffff);
200         value = readl(reg_base + 0x50);
201         debug("MLB Gate pass window: 0x%04x_%04x\n", value & 0xffff,
202               (value >> 16) & 0xffff);
203         value = readl(reg_base + 0x60);
204         debug("Rising  edge Read Data Eye Training Result      = 0x%x_%x\n",
205               value & 0xff, (value >> 8) & 0xff);
206 
207         value = readl(reg_base + 0x68);
208         debug("Rising  edge Read Data Eye Training Pass Window = 0x%x_%x\n",
209               value & 0xff, (value >> 8) & 0xff);
210 
211         value = readl(reg_base + 0xC0);
212         debug("Falling edge Read Data Eye Training Result      = 0x%x_%x\n",
213               value & 0xff, (value >> 8) & 0xff);
214 
215         value = readl(reg_base + 0xC8);
216         debug("Falling edge Read Data Eye Training Pass Window = 0x%x_%x\n",
217               value & 0xff, (value >> 8) & 0xff);
218 
219         value = readl(reg_base + 0x74);
220         debug("Write Data Eye fine Training Result             = %X_%X\n",
221               value & 0xff, (value >> 8) & 0xff);
222 
223         value = readl(reg_base + 0x7C);
224         debug("Write Data Eye Training Pass Window             = 0x%x_%x\n",
225               value & 0xff, (value >> 8) & 0xff);
226 #endif
227 }
228 
229 /**
230  * @brief       SDRAM memory controller test mode with data-generation
231  * @param[in]   - info - pointer to the current dram_info
232  * @param[in]   - data_gen - data_gen index
233  * @param[in]	- mode - 0:single, 1:burst
234  * @return      - 0:success, others:fail
235 */
236 static int ast2600_sdrammc_dg_test(struct dram_info *info, u32 data_gen,
237                                    u32 mode)
238 {
239         u32 data;
240 	u32 mask;
241 	struct ast2600_sdrammc_regs *regs = info->regs;
242 
243         writel(0, &regs->ecc_test_ctrl);
244         data = (data_gen << SDRAM_TEST_GEN_MODE_SHIFT) | SDRAM_TEST_ERRSTOP |
245                SDRAM_TEST_EN;
246         if (mode) {
247                 data |=
248                     (SDRAM_TEST_ERRSTOP | SDRAM_TEST_EN | SDRAM_TEST_MODE_RW);
249         } else {
250                 data |= (SDRAM_TEST_ERRSTOP | SDRAM_TEST_EN |
251                          SDRAM_TEST_MODE_WO | SDRAM_TEST_TWO_MODES);
252         }
253         writel(data, &regs->ecc_test_ctrl);
254 
255 	mask = SDRAM_TEST_DONE | SDRAM_TEST_FAIL;
256         do {
257                 data = readl(&regs->ecc_test_ctrl) & mask;
258                 if (data & SDRAM_TEST_FAIL) {
259                         debug("%s %d fail\n", __func__, data_gen);
260                         return 1;
261                 }
262         } while (!data);
263 
264         writel(0x00000000, &regs->ecc_test_ctrl);
265         return 0;
266 }
267 
268 static int ast2600_sdrammc_cbr_test(struct dram_info *info, u32 pattern)
269 {
270         struct ast2600_sdrammc_regs *regs = info->regs;
271         int i;
272         int ret = 0;
273 
274         writel((0xff << SDRAM_TEST_LEN_SHIFT), &regs->test_addr);
275         writel(pattern, &regs->test_init_val);
276 
277         /* scan all data-generation mode */
278         for (i = 0; i < 8; i++) {
279                 if (0 == ast2600_sdrammc_dg_test(info, i, 0)) {
280                         debug("sdrammc calibration test fail: single data "
281                               "mode\n");
282                         ret = 1;
283                         break;
284                 }
285         }
286 
287         for (i = 0; i < 8; i++) {
288                 if (0 == ast2600_sdrammc_dg_test(info, i, 1)) {
289                         debug(
290                             "sdrammc calibration test fail: burst data mode\n");
291                         ret = 1;
292                         break;
293                 }
294         }
295 
296         writel(0, &regs->ecc_test_ctrl);
297         return ret;
298 }
299 
300 #define MC_TEST_PATTERN_N 8
301 static u32 as2600_sdrammc_test_pattern[MC_TEST_PATTERN_N] = {
302     0xcc33cc33, 0xff00ff00, 0xaa55aa55, 0x88778877,
303     0x92cc4d6e, 0x543d3cde, 0xf1e843c7, 0x7c61d253};
304 
305 static int ast2600_sdrammc_test(struct dram_info *info)
306 {
307         int i;
308         int ret;
309 
310         for (i = 0; i < MC_TEST_PATTERN_N; i++) {
311                 ret = ast2600_sdrammc_cbr_test(info,
312                                                as2600_sdrammc_test_pattern[i]);
313                 if (ret) {
314                         return ret;
315                 }
316                 debug("%s: pass %d\n", __func__, i);
317         }
318 
319         return ret;
320 }
321 
322 static size_t ast2600_sdrammc_get_vga_mem_size(struct dram_info *info)
323 {
324         u32 vga_hwconf;
325         size_t vga_mem_size_base = 8 * 1024 * 1024;
326 
327         vga_hwconf = readl(info->scu + AST_SCU_HW_STRAP) &
328                      SCU_HWSTRAP_VGAMEM_MASK >> SCU_HWSTRAP_VGAMEM_SHIFT;
329 
330         return vga_mem_size_base << vga_hwconf;
331 }
332 #ifdef AST2600_SDRAMMC_FPGA
333 static void ast2600_sdrammc_fpga_set_pll(struct dram_info *info)
334 {
335         u32 data;
336         u32 scu_base = (u32)info->scu;
337 
338         writel(0x00000303, scu_base + AST_SCU_FPGA_PLL);
339 
340         do {
341                 data = readl(scu_base + AST_SCU_CONFIG);
342         } while (!(data & 0x100));
343 
344         writel(0x00000103, scu_base + AST_SCU_FPGA_PLL);
345 }
346 
347 static int ast2600_sdrammc_search_read_window(struct dram_info *info)
348 {
349         u32 pll, pll_min, pll_max, dat1, offset;
350         u32 win = 0x03, gwin = 0, gwinsize = 0;
351         u32 phy_setting = (u32)info->phy_setting;
352 
353         writel(SEARCH_RDWIN_PTRN_0, SEARCH_RDWIN_ANCHOR_0);
354         writel(SEARCH_RDWIN_PTRN_1, SEARCH_RDWIN_ANCHOR_1);
355 
356         while (gwin == 0) {
357                 while (!(win & 0x80)) {
358                         debug("Window = 0x%X\n", win);
359                         writel(win, phy_setting + 0x0000);
360 
361                         dat1 = readl(SEARCH_RDWIN_ANCHOR_0);
362                         dat1 += readl(SEARCH_RDWIN_ANCHOR_1);
363                         while (dat1 == SEARCH_RDWIN_PTRN_SUM) {
364                                 ast2600_sdrammc_fpga_set_pll(info);
365                                 dat1 = readl(SEARCH_RDWIN_ANCHOR_0);
366                                 dat1 += readl(SEARCH_RDWIN_ANCHOR_1);
367                         }
368 
369                         pll_min = 0xfff;
370                         pll_max = 0x0;
371                         pll = 0;
372                         while (pll_max > 0 || pll < 256) {
373                                 ast2600_sdrammc_fpga_set_pll(info);
374                                 dat1 = readl(SEARCH_RDWIN_ANCHOR_0);
375                                 dat1 += readl(SEARCH_RDWIN_ANCHOR_1);
376                                 if (dat1 == SEARCH_RDWIN_PTRN_SUM) {
377                                         if (pll_min > pll) {
378                                                 pll_min = pll;
379                                         }
380                                         if (pll_max < pll) {
381                                                 pll_max = pll;
382                                         }
383                                         debug("%3d_(%3d:%3d)\n", pll, pll_min,
384                                                pll_max);
385                                 } else if (pll_max > 0) {
386                                         pll_min = pll_max - pll_min;
387                                         if (gwinsize < pll_min) {
388                                                 gwin = win;
389                                                 gwinsize = pll_min;
390                                         }
391                                         break;
392                                 }
393                                 pll += 1;
394                         }
395 
396                         if (gwin != 0 && pll_max == 0) {
397                                 break;
398                         }
399                         win = win << 1;
400                 }
401                 if (gwin == 0) {
402                         win = 0x7;
403                 }
404         }
405         debug("Set PLL Read Gating Window = %x\n", gwin);
406         writel(gwin, phy_setting + 0x0000);
407 
408         debug("PLL Read Window training\n");
409         pll_min = 0xfff;
410         pll_max = 0x0;
411 
412         debug("Search Window Start\n");
413         dat1 = readl(SEARCH_RDWIN_ANCHOR_0);
414         dat1 += readl(SEARCH_RDWIN_ANCHOR_1);
415         while (dat1 == SEARCH_RDWIN_PTRN_SUM) {
416                 ast2600_sdrammc_fpga_set_pll(info);
417                 dat1 = readl(SEARCH_RDWIN_ANCHOR_0);
418                 dat1 += readl(SEARCH_RDWIN_ANCHOR_1);
419         }
420 
421         debug("Search Window Margin\n");
422         pll = 0;
423         while (pll_max > 0 || pll < 256) {
424                 ast2600_sdrammc_fpga_set_pll(info);
425                 dat1 = readl(SEARCH_RDWIN_ANCHOR_0);
426                 dat1 += readl(SEARCH_RDWIN_ANCHOR_1);
427                 if (dat1 == SEARCH_RDWIN_PTRN_SUM) {
428                         if (pll_min > pll) {
429                                 pll_min = pll;
430                         }
431                         if (pll_max < pll) {
432                                 pll_max = pll;
433                         }
434                         debug("%3d_(%3d:%3d)\n", pll, pll_min, pll_max);
435                 } else if (pll_max > 0 && (pll_max - pll_min) > 20) {
436                         break;
437                 } else if (pll_max > 0) {
438                         pll_min = 0xfff;
439                         pll_max = 0x0;
440                 }
441                 pll += 1;
442         }
443         if (pll_min < pll_max) {
444                 debug("PLL Read window = %d\n", (pll_max - pll_min));
445                 offset = (pll_max - pll_min) >> 1;
446                 pll_min = 0xfff;
447                 pll = 0;
448                 while (pll < (pll_min + offset)) {
449                         ast2600_sdrammc_fpga_set_pll(info);
450                         dat1 = readl(SEARCH_RDWIN_ANCHOR_0);
451                         dat1 += readl(SEARCH_RDWIN_ANCHOR_1);
452                         if (dat1 == SEARCH_RDWIN_PTRN_SUM) {
453                                 if (pll_min > pll) {
454                                         pll_min = pll;
455                                 }
456                                 debug("%d\n", pll);
457                         } else {
458                                 pll_min = 0xfff;
459                                 pll_max = 0x0;
460                         }
461                         pll += 1;
462                 }
463                 return (1);
464         } else {
465                 debug("PLL Read window training fail\n");
466                 return (0);
467         }
468 }
469 #endif  /* end of "#ifdef AST2600_SDRAMMC_FPGA" */
470 
471 /*
472  * Find out RAM size and save it in dram_info
473  *
474  * The procedure is taken from Aspeed SDK
475  */
476 static void ast2600_sdrammc_calc_size(struct dram_info *info)
477 {
478 	/* The controller supports 256/512/1024/2048 MB ram */
479 	size_t ram_size = SDRAM_MIN_SIZE;
480 	const int write_test_offset = 0x100000;
481 	u32 test_pattern = 0xdeadbeef;
482 	u32 cap_param = SDRAM_CONF_CAP_2048M;
483 	u32 refresh_timing_param = DDR4_TRFC;
484 	const u32 write_addr_base = CONFIG_SYS_SDRAM_BASE + write_test_offset;
485 
486 	for (ram_size = SDRAM_MAX_SIZE; ram_size > SDRAM_MIN_SIZE;
487 	     ram_size >>= 1) {
488 		writel(test_pattern, write_addr_base + (ram_size >> 1));
489 		test_pattern = (test_pattern >> 4) | (test_pattern << 28);
490 	}
491 
492 	/* One last write to overwrite all wrapped values */
493 	writel(test_pattern, write_addr_base);
494 
495 	/* Reset the pattern and see which value was really written */
496 	test_pattern = 0xdeadbeef;
497 	for (ram_size = SDRAM_MAX_SIZE; ram_size > SDRAM_MIN_SIZE;
498 	     ram_size >>= 1) {
499 		if (readl(write_addr_base + (ram_size >> 1)) == test_pattern)
500 			break;
501 
502 		--cap_param;
503 		refresh_timing_param >>= 8;
504 		test_pattern = (test_pattern >> 4) | (test_pattern << 28);
505 	}
506 
507 	clrsetbits_le32(&info->regs->ac_timing[1],
508 			(SDRAM_AC_TRFC_MASK << SDRAM_AC_TRFC_SHIFT),
509 			((refresh_timing_param & SDRAM_AC_TRFC_MASK)
510 			 << SDRAM_AC_TRFC_SHIFT));
511 
512 	info->info.base = CONFIG_SYS_SDRAM_BASE;
513 	info->info.size = ram_size - ast2600_sdrammc_get_vga_mem_size(info);
514 	clrsetbits_le32(&info->regs->config,
515 			(SDRAM_CONF_CAP_MASK << SDRAM_CONF_CAP_SHIFT),
516 			((cap_param & SDRAM_CONF_CAP_MASK)
517 			 << SDRAM_CONF_CAP_SHIFT));
518 }
519 
520 static int ast2600_sdrammc_init_ddr4(struct dram_info *info)
521 {
522         const u32 power_ctrl = MCR34_CKE_EN | MCR34_AUTOPWRDN_EN |
523                                MCR34_MREQ_BYPASS_DIS | MCR34_RESETN_DIS |
524                                MCR34_ODT_EN | MCR34_ODT_AUTO_ON |
525                                (0x1 << MCR34_ODT_EXT_SHIFT);
526 
527 #ifdef CONFIG_DUALX8_RAM
528 	setbits_le32(&info->regs->config, SDRAM_CONF_DDR4 | SDRAM_CONF_DUALX8);
529 #else
530 	setbits_le32(&info->regs->config, SDRAM_CONF_DDR4);
531 #endif
532 
533         /* init SDRAM-PHY only on real chip */
534 	ast2600_sdramphy_init(ast2600_sdramphy_config, info);
535 	ast2600_sdramphy_kick_training(info);
536 
537         writel((MCR34_CKE_EN | MCR34_MREQI_DIS | MCR34_RESETN_DIS),
538                &info->regs->power_ctrl);
539         writel(SDRAM_RESET_DLL_ZQCL_EN, &info->regs->refresh_timing);
540 
541         writel(MCR30_SET_MR(3), &info->regs->mode_setting_control);
542         writel(MCR30_SET_MR(6), &info->regs->mode_setting_control);
543         writel(MCR30_SET_MR(5), &info->regs->mode_setting_control);
544         writel(MCR30_SET_MR(4), &info->regs->mode_setting_control);
545         writel(MCR30_SET_MR(2), &info->regs->mode_setting_control);
546         writel(MCR30_SET_MR(1), &info->regs->mode_setting_control);
547         writel(MCR30_SET_MR(0) | MCR30_RESET_DLL_DELAY_EN,
548                &info->regs->mode_setting_control);
549 
550 #ifdef AST2600_SDRAMMC_FPGA
551         writel(SDRAM_REFRESH_EN | SDRAM_RESET_DLL_ZQCL_EN |
552                    (0x5d << SDRAM_REFRESH_PERIOD_SHIFT),
553                &info->regs->refresh_timing);
554 #else
555         writel(SDRAM_REFRESH_EN | SDRAM_RESET_DLL_ZQCL_EN |
556                    (0x5f << SDRAM_REFRESH_PERIOD_SHIFT),
557                &info->regs->refresh_timing);
558 #endif
559 
560         /* wait self-refresh idle */
561         while (readl(&info->regs->power_ctrl) & MCR34_SELF_REFRESH_STATUS_MASK)
562                 ;
563 
564 #ifdef AST2600_SDRAMMC_FPGA
565         writel(SDRAM_REFRESH_EN | SDRAM_LOW_PRI_REFRESH_EN |
566                    SDRAM_REFRESH_ZQCS_EN |
567                    (0x5d << SDRAM_REFRESH_PERIOD_SHIFT) |
568                    (0x4000 << SDRAM_REFRESH_PERIOD_ZQCS_SHIFT),
569                &info->regs->refresh_timing);
570 #else
571         writel(SDRAM_REFRESH_EN | SDRAM_LOW_PRI_REFRESH_EN |
572                    SDRAM_REFRESH_ZQCS_EN |
573                    (0x5f << SDRAM_REFRESH_PERIOD_SHIFT) |
574                    (0x42aa << SDRAM_REFRESH_PERIOD_ZQCS_SHIFT),
575                &info->regs->refresh_timing);
576 #endif
577 
578         writel(power_ctrl, &info->regs->power_ctrl);
579 
580 #ifdef AST2600_SDRAMMC_FPGA
581         /* toggle Vref training */
582         setbits_le32(&info->regs->mr6_mode_setting, 0x80);
583         writel(MCR30_RESET_DLL_DELAY_EN | MCR30_SET_MR(6),
584                &info->regs->mode_setting_control);
585         clrbits_le32(&info->regs->mr6_mode_setting, 0x80);
586         writel(MCR30_RESET_DLL_DELAY_EN | MCR30_SET_MR(6),
587                &info->regs->mode_setting_control);
588 #endif
589 	return 0;
590 }
591 
592 static void ast2600_sdrammc_unlock(struct dram_info *info)
593 {
594 	writel(SDRAM_UNLOCK_KEY, &info->regs->protection_key);
595 	while (!readl(&info->regs->protection_key))
596 		;
597 }
598 
599 static void ast2600_sdrammc_lock(struct dram_info *info)
600 {
601 	writel(~SDRAM_UNLOCK_KEY, &info->regs->protection_key);
602 	while (readl(&info->regs->protection_key))
603 		;
604 }
605 
606 static void ast2600_sdrammc_common_init(struct ast2600_sdrammc_regs *regs)
607 {
608 	int i;
609 
610         writel(SDRAM_VIDEO_UNLOCK_KEY, &regs->gm_protection_key);
611         writel(MCR34_MREQI_DIS | MCR34_RESETN_DIS, &regs->power_ctrl);
612         writel(0x10 << MCR38_RW_MAX_GRANT_CNT_RQ_SHIFT,
613                &regs->arbitration_ctrl);
614         writel(0xFFFFFFFF, &regs->req_limit_mask);
615 
616         for (i = 0; i < ARRAY_SIZE(ddr_max_grant_params); ++i)
617                 writel(ddr_max_grant_params[i], &regs->max_grant_len[i]);
618 
619         writel(MCR50_RESET_ALL_INTR, &regs->intr_ctrl);
620 
621         /* FIXME: the sample code does NOT match the datasheet */
622         writel(0x7FFFFFF, &regs->ecc_range_ctrl);
623 
624         writel(0, &regs->ecc_test_ctrl);
625         writel(0, &regs->test_addr);
626         writel(0, &regs->test_fail_dq_bit);
627         writel(0, &regs->test_init_val);
628 
629         writel(0xFFFFFFFF, &regs->req_input_ctrl);
630         writel(0, &regs->req_high_pri_ctrl);
631 
632 #ifdef AST2600_SDRAMMC_FPGA
633         //writel(0xFF, 0x1e6e0100);
634 #endif
635         udelay(500);
636 
637 	/* set capacity to the max size */
638         clrsetbits_le32(&regs->config, SDRAM_CONF_CAP_MASK,
639                         SDRAM_CONF_CAP_2048M);
640 
641 	/* load controller setting */
642 	for (i = 0; i < ARRAY_SIZE(ddr4_ac_timing); ++i)
643 		writel(ddr4_ac_timing[i], &regs->ac_timing[i]);
644 
645 	writel(DDR4_MR01_MODE, &regs->mr01_mode_setting);
646 	writel(DDR4_MR23_MODE, &regs->mr23_mode_setting);
647 	writel(DDR4_MR45_MODE, &regs->mr45_mode_setting);
648 	writel(DDR4_MR6_MODE, &regs->mr6_mode_setting);
649 }
650 
651 static int ast2600_sdrammc_probe(struct udevice *dev)
652 {
653 	struct reset_ctl reset_ctl;
654 	struct dram_info *priv = (struct dram_info *)dev_get_priv(dev);
655 	struct ast2600_sdrammc_regs *regs = priv->regs;
656 	struct udevice *clk_dev;
657 	int ret = clk_get_by_index(dev, 0, &priv->ddr_clk);
658 	uint32_t reg;
659 
660 	if (ret) {
661 		debug("DDR:No CLK\n");
662 		return ret;
663 	}
664 
665 	/* find SCU base address from clock device */
666 	ret = uclass_get_device_by_driver(UCLASS_CLK, DM_GET_DRIVER(aspeed_scu),
667                                           &clk_dev);
668 	if (ret) {
669 		debug("clock device not defined\n");
670 		return ret;
671 	}
672 
673 	priv->scu = devfdt_get_addr_ptr(clk_dev);
674 	if (IS_ERR(priv->scu)) {
675 		debug("%s(): can't get SCU\n", __func__);
676 		return PTR_ERR(priv->scu);
677 	}
678 
679 	if (readl(priv->scu + AST_SCU_HANDSHAKE) & SCU_SDRAM_INIT_READY_MASK) {
680 		debug("%s(): DDR SDRAM had been initialized\n", __func__);
681 		ast2600_sdrammc_calc_size(priv);
682 		return 0;
683 	}
684 
685 #ifdef AST2600_SDRAMMC_MANUAL_CLK
686 	reg = readl(priv->scu + AST_SCU_MPLL);
687 	reg |= (SCU_MPLL_RESET | SCU_MPLL_TURN_OFF);
688 	writel(reg, priv->scu + AST_SCU_MPLL);
689 	reg &= ~(SCU_MPLL_RESET | SCU_MPLL_TURN_OFF| SCU_MPLL_FREQ_MASK);
690 	reg |= SCU_MPLL_FREQ_CFG;
691 	writel(reg, priv->scu + AST_SCU_MPLL);
692 #else
693 	clk_set_rate(&priv->ddr_clk, priv->clock_rate);
694 #endif
695 
696 #if 0
697 	/* FIXME: enable the following code if reset-driver is ready */
698 	ret = reset_get_by_index(dev, 0, &reset_ctl);
699 	if (ret) {
700 		debug("%s(): Failed to get reset signal\n", __func__);
701 		return ret;
702 	}
703 
704 	ret = reset_assert(&reset_ctl);
705 	if (ret) {
706 		debug("%s(): SDRAM reset failed: %u\n", __func__, ret);
707 		return ret;
708 	}
709 #endif
710 
711 	ast2600_sdrammc_unlock(priv);
712 	ast2600_sdrammc_common_init(regs);
713 
714 	if (readl(priv->scu + AST_SCU_HW_STRAP) & SCU_HWSTRAP_DDR3) {
715 		debug("Unsupported SDRAM type: DDR3\n");
716 		return -EINVAL;
717 	} else {
718 		ast2600_sdrammc_init_ddr4(priv);
719 	}
720 
721 #ifdef AST2600_SDRAMMC_FPGA
722         ast2600_sdrammc_search_read_window(priv);
723 #endif
724 
725 	ast2600_sdramphy_show_status(priv);
726 	ast2600_sdrammc_calc_size(priv);
727 #if 0
728 	ast2600_sdrammc_test(priv);
729 #endif
730 	clrbits_le32(&regs->intr_ctrl, MCR50_RESET_ALL_INTR);
731 	ast2600_sdrammc_lock(priv);
732 	return 0;
733 }
734 
735 static int ast2600_sdrammc_ofdata_to_platdata(struct udevice *dev)
736 {
737 	struct dram_info *priv = dev_get_priv(dev);
738 	int ret;
739 
740 	priv->regs = (void *)(uintptr_t)devfdt_get_addr_index(dev, 0);
741 	priv->phy_setting = (void *)(uintptr_t)devfdt_get_addr_index(dev, 1);
742 	priv->phy_status = (void *)(uintptr_t)devfdt_get_addr_index(dev, 2);
743 
744 	priv->clock_rate = fdtdec_get_int(gd->fdt_blob, dev_of_offset(dev),
745 					  "clock-frequency", 0);
746 	if (!priv->clock_rate) {
747 		debug("DDR Clock Rate not defined\n");
748 		return -EINVAL;
749 	}
750 
751 	return 0;
752 }
753 
754 static int ast2600_sdrammc_get_info(struct udevice *dev, struct ram_info *info)
755 {
756 	struct dram_info *priv = dev_get_priv(dev);
757 
758 	*info = priv->info;
759 
760 	return 0;
761 }
762 
763 static struct ram_ops ast2600_sdrammc_ops = {
764 	.get_info = ast2600_sdrammc_get_info,
765 };
766 
767 static const struct udevice_id ast2600_sdrammc_ids[] = {
768 	{ .compatible = "aspeed,ast2600-sdrammc" },
769 	{ }
770 };
771 
772 U_BOOT_DRIVER(sdrammc_ast2600) = {
773 	.name = "aspeed_ast2600_sdrammc",
774 	.id = UCLASS_RAM,
775 	.of_match = ast2600_sdrammc_ids,
776 	.ops = &ast2600_sdrammc_ops,
777 	.ofdata_to_platdata = ast2600_sdrammc_ofdata_to_platdata,
778 	.probe = ast2600_sdrammc_probe,
779 	.priv_auto_alloc_size = sizeof(struct dram_info),
780 };
781