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