1 // SPDX-License-Identifier: GPL-2.0
2 /*
3  * Copyright (C) ASPEED Technology Inc.
4  */
5 #include <common.h>
6 #include <clk.h>
7 #include <dm.h>
8 #include <errno.h>
9 #include <ram.h>
10 #include <regmap.h>
11 #include <reset.h>
12 #include <asm/io.h>
13 #include <asm/arch/scu_ast2600.h>
14 #include <asm/arch/sdram_ast2600.h>
15 #include <asm/global_data.h>
16 #include <linux/err.h>
17 #include <linux/kernel.h>
18 #include <dt-bindings/clock/ast2600-clock.h>
19 
20 #define DDR_PHY_TBL_CHG_ADDR            0xaeeddeea
21 #define DDR_PHY_TBL_END                 0xaeededed
22 
23 #if defined(CONFIG_ASPEED_DDR4_800)
24 u32 ast2600_sdramphy_config[165] = {
25 	0x1e6e0100,	// start address
26 	0x00000000,	// phyr000
27 	0x0c002062,	// phyr004
28 	0x1a7a0063,	// phyr008
29 	0x5a7a0063,	// phyr00c
30 	0x1a7a0063,	// phyr010
31 	0x1a7a0063,	// phyr014
32 	0x20000000,	// phyr018
33 	0x20000000,	// phyr01c
34 	0x20000000,	// phyr020
35 	0x20000000,	// phyr024
36 	0x00000008,	// phyr028
37 	0x00000000,	// phyr02c
38 	0x00077600,	// phyr030
39 	0x00000000,	// phyr034
40 	0x00000000,	// phyr038
41 	0x20000000,	// phyr03c
42 	0x50506000,	// phyr040
43 	0x50505050,	// phyr044
44 	0x00002f07,	// phyr048
45 	0x00003080,	// phyr04c
46 	0x04000000,	// phyr050
47 	0x00000200,	// phyr054
48 	0x03140201,	// phyr058
49 	0x04800000,	// phyr05c
50 	0x0800044e,	// phyr060
51 	0x00000000,	// phyr064
52 	0x00180008,	// phyr068
53 	0x00e00400,	// phyr06c
54 	0x00140206,	// phyr070
55 	0x1d4c0000,	// phyr074
56 	0x493e0107,	// phyr078
57 	0x08060404,	// phyr07c
58 	0x90000a00,	// phyr080
59 	0x06420618,	// phyr084
60 	0x00001002,	// phyr088
61 	0x05701016,	// phyr08c
62 	0x10000000,	// phyr090
63 	0xaeeddeea,	// change address
64 	0x1e6e019c,	// new address
65 	0x20202020,	// phyr09c
66 	0x20202020,	// phyr0a0
67 	0x00002020,	// phyr0a4
68 	0x00002020,	// phyr0a8
69 	0x00000001,	// phyr0ac
70 	0xaeeddeea,	// change address
71 	0x1e6e01cc,	// new address
72 	0x01010101,	// phyr0cc
73 	0x01010101,	// phyr0d0
74 	0x80808080,	// phyr0d4
75 	0x80808080,	// phyr0d8
76 	0xaeeddeea,	// change address
77 	0x1e6e0288,	// new address
78 	0x80808080,	// phyr188
79 	0x80808080,	// phyr18c
80 	0x80808080,	// phyr190
81 	0x80808080,	// phyr194
82 	0xaeeddeea,	// change address
83 	0x1e6e02f8,	// new address
84 	0x90909090,	// phyr1f8
85 	0x88888888,	// phyr1fc
86 	0xaeeddeea,	// change address
87 	0x1e6e0300,	// new address
88 	0x00000000,	// phyr200
89 	0xaeeddeea,	// change address
90 	0x1e6e0194,	// new address
91 	0x80118260,	// phyr094
92 	0xaeeddeea,	// change address
93 	0x1e6e019c,	// new address
94 	0x20202020,	// phyr09c
95 	0x20202020,	// phyr0a0
96 	0x00002020,	// phyr0a4
97 	0x80000000,	// phyr0a8
98 	0x00000001,	// phyr0ac
99 	0xaeeddeea,	// change address
100 	0x1e6e0318,	// new address
101 	0x09222719,	// phyr218
102 	0x00aa4403,	// phyr21c
103 	0xaeeddeea,	// change address
104 	0x1e6e0198,	// new address
105 	0x08060000,	// phyr098
106 	0xaeeddeea,	// change address
107 	0x1e6e01b0,	// new address
108 	0x00000000,	// phyr0b0
109 	0x00000000,	// phyr0b4
110 	0x00000000,	// phyr0b8
111 	0x00000000,	// phyr0bc
112 	0x00000000,	// phyr0c0
113 	0x00000000,	// phyr0c4
114 	0x000aff2c,	// phyr0c8
115 	0xaeeddeea,	// change address
116 	0x1e6e01dc,	// new address
117 	0x00080000,	// phyr0dc
118 	0x00000000,	// phyr0e0
119 	0xaa55aa55,	// phyr0e4
120 	0x55aa55aa,	// phyr0e8
121 	0xaaaa5555,	// phyr0ec
122 	0x5555aaaa,	// phyr0f0
123 	0xaa55aa55,	// phyr0f4
124 	0x55aa55aa,	// phyr0f8
125 	0xaaaa5555,	// phyr0fc
126 	0x5555aaaa,	// phyr100
127 	0xaa55aa55,	// phyr104
128 	0x55aa55aa,	// phyr108
129 	0xaaaa5555,	// phyr10c
130 	0x5555aaaa,	// phyr110
131 	0xaa55aa55,	// phyr114
132 	0x55aa55aa,	// phyr118
133 	0xaaaa5555,	// phyr11c
134 	0x5555aaaa,	// phyr120
135 	0x20202020,	// phyr124
136 	0x20202020,	// phyr128
137 	0x20202020,	// phyr12c
138 	0x20202020,	// phyr130
139 	0x20202020,	// phyr134
140 	0x20202020,	// phyr138
141 	0x20202020,	// phyr13c
142 	0x20202020,	// phyr140
143 	0x20202020,	// phyr144
144 	0x20202020,	// phyr148
145 	0x20202020,	// phyr14c
146 	0x20202020,	// phyr150
147 	0x20202020,	// phyr154
148 	0x20202020,	// phyr158
149 	0x20202020,	// phyr15c
150 	0x20202020,	// phyr160
151 	0x20202020,	// phyr164
152 	0x20202020,	// phyr168
153 	0x20202020,	// phyr16c
154 	0x20202020,	// phyr170
155 	0xaeeddeea,	// change address
156 	0x1e6e0298,	// new address
157 	0x20200800,	// phyr198
158 	0x20202020,	// phyr19c
159 	0x20202020,	// phyr1a0
160 	0x20202020,	// phyr1a4
161 	0x20202020,	// phyr1a8
162 	0x20202020,	// phyr1ac
163 	0x20202020,	// phyr1b0
164 	0x20202020,	// phyr1b4
165 	0x20202020,	// phyr1b8
166 	0x20202020,	// phyr1bc
167 	0x20202020,	// phyr1c0
168 	0x20202020,	// phyr1c4
169 	0x20202020,	// phyr1c8
170 	0x20202020,	// phyr1cc
171 	0x20202020,	// phyr1d0
172 	0x20202020,	// phyr1d4
173 	0x20202020,	// phyr1d8
174 	0x20202020,	// phyr1dc
175 	0x20202020,	// phyr1e0
176 	0x20202020,	// phyr1e4
177 	0x00002020,	// phyr1e8
178 	0xaeeddeea,	// change address
179 	0x1e6e0304,	// new address
180 	0x00000800,	// phyr204
181 	0xaeeddeea,	// change address
182 	0x1e6e027c,	// new address
183 	0x4e400000,	// phyr17c
184 	0x59595959,	// phyr180
185 	0x40404040,	// phyr184
186 	0xaeeddeea,	// change address
187 	0x1e6e02f4,	// new address
188 	0x00000059,	// phyr1f4
189 	0xaeededed,	// end
190 };
191 #else
192 u32 ast2600_sdramphy_config[165] = {
193 	0x1e6e0100,	// start address
194 	0x00000000,	// phyr000
195 	0x0c002062,	// phyr004
196 	0x1a7a0063,	// phyr008
197 	0x5a7a0063,	// phyr00c
198 	0x1a7a0063,	// phyr010
199 	0x1a7a0063,	// phyr014
200 	0x20000000,	// phyr018
201 	0x20000000,	// phyr01c
202 	0x20000000,	// phyr020
203 	0x20000000,	// phyr024
204 	0x00000008,	// phyr028
205 	0x00000000,	// phyr02c
206 	0x00077600,	// phyr030
207 	0x00000000,	// phyr034
208 	0x00000000,	// phyr038
209 	0x20000000,	// phyr03c
210 	0x50506000,	// phyr040
211 	0x50505050,	// phyr044
212 	0x00002f07,	// phyr048
213 	0x00003080,	// phyr04c
214 	0x04000000,	// phyr050
215 	0x00000200,	// phyr054
216 	0x03140501,	// phyr058-rtt:40
217 	0x04800000,	// phyr05c
218 	0x0800044e,	// phyr060
219 	0x00000000,	// phyr064
220 	0x00180008,	// phyr068
221 	0x00e00400,	// phyr06c
222 	0x00140206,	// phyr070
223 	0x1d4c0000,	// phyr074
224 	0x493e0107,	// phyr078
225 	0x08060404,	// phyr07c
226 	0x90000a00,	// phyr080
227 	0x06420c30,	// phyr084
228 	0x00001002,	// phyr088
229 	0x05701016,	// phyr08c
230 	0x10000000,	// phyr090
231 	0xaeeddeea,	// change address
232 	0x1e6e019c,	// new address
233 	0x20202020,	// phyr09c
234 	0x20202020,	// phyr0a0
235 	0x00002020,	// phyr0a4
236 	0x00002020,	// phyr0a8
237 	0x00000001,	// phyr0ac
238 	0xaeeddeea,	// change address
239 	0x1e6e01cc,	// new address
240 	0x01010101,	// phyr0cc
241 	0x01010101,	// phyr0d0
242 	0x80808080,	// phyr0d4
243 	0x80808080,	// phyr0d8
244 	0xaeeddeea,	// change address
245 	0x1e6e0288,	// new address
246 	0x80808080,	// phyr188
247 	0x80808080,	// phyr18c
248 	0x80808080,	// phyr190
249 	0x80808080,	// phyr194
250 	0xaeeddeea,	// change address
251 	0x1e6e02f8,	// new address
252 	0x90909090,	// phyr1f8
253 	0x88888888,	// phyr1fc
254 	0xaeeddeea,	// change address
255 	0x1e6e0300,	// new address
256 	0x00000000,	// phyr200
257 	0xaeeddeea,	// change address
258 	0x1e6e0194,	// new address
259 	0x801112e0,	// phyr094 - bit12=1,15=0,- write window is ok
260 	0xaeeddeea,	// change address
261 	0x1e6e019c,	// new address
262 	0x20202020,	// phyr09c
263 	0x20202020,	// phyr0a0
264 	0x00002020,	// phyr0a4
265 	0x80000000,	// phyr0a8
266 	0x00000001,	// phyr0ac
267 	0xaeeddeea,	// change address
268 	0x1e6e0318,	// new address
269 	0x09222719,	// phyr218
270 	0x00aa4403,	// phyr21c
271 	0xaeeddeea,	// change address
272 	0x1e6e0198,	// new address
273 	0x08060000,	// phyr098
274 	0xaeeddeea,	// change address
275 	0x1e6e01b0,	// new address
276 	0x00000000,	// phyr0b0
277 	0x00000000,	// phyr0b4
278 	0x00000000,	// phyr0b8
279 	0x00000000,	// phyr0bc
280 	0x00000000,	// phyr0c0 - ori
281 	0x00000000,	// phyr0c4
282 	0x000aff2c,	// phyr0c8
283 	0xaeeddeea,	// change address
284 	0x1e6e01dc,	// new address
285 	0x00080000,	// phyr0dc
286 	0x00000000,	// phyr0e0
287 	0xaa55aa55,	// phyr0e4
288 	0x55aa55aa,	// phyr0e8
289 	0xaaaa5555,	// phyr0ec
290 	0x5555aaaa,	// phyr0f0
291 	0xaa55aa55,	// phyr0f4
292 	0x55aa55aa,	// phyr0f8
293 	0xaaaa5555,	// phyr0fc
294 	0x5555aaaa,	// phyr100
295 	0xaa55aa55,	// phyr104
296 	0x55aa55aa,	// phyr108
297 	0xaaaa5555,	// phyr10c
298 	0x5555aaaa,	// phyr110
299 	0xaa55aa55,	// phyr114
300 	0x55aa55aa,	// phyr118
301 	0xaaaa5555,	// phyr11c
302 	0x5555aaaa,	// phyr120
303 	0x20202020,	// phyr124
304 	0x20202020,	// phyr128
305 	0x20202020,	// phyr12c
306 	0x20202020,	// phyr130
307 	0x20202020,	// phyr134
308 	0x20202020,	// phyr138
309 	0x20202020,	// phyr13c
310 	0x20202020,	// phyr140
311 	0x20202020,	// phyr144
312 	0x20202020,	// phyr148
313 	0x20202020,	// phyr14c
314 	0x20202020,	// phyr150
315 	0x20202020,	// phyr154
316 	0x20202020,	// phyr158
317 	0x20202020,	// phyr15c
318 	0x20202020,	// phyr160
319 	0x20202020,	// phyr164
320 	0x20202020,	// phyr168
321 	0x20202020,	// phyr16c
322 	0x20202020,	// phyr170
323 	0xaeeddeea,	// change address
324 	0x1e6e0298,	// new address
325 	0x20200800,	// phyr198
326 	0x20202020,	// phyr19c
327 	0x20202020,	// phyr1a0
328 	0x20202020,	// phyr1a4
329 	0x20202020,	// phyr1a8
330 	0x20202020,	// phyr1ac
331 	0x20202020,	// phyr1b0
332 	0x20202020,	// phyr1b4
333 	0x20202020,	// phyr1b8
334 	0x20202020,	// phyr1bc
335 	0x20202020,	// phyr1c0
336 	0x20202020,	// phyr1c4
337 	0x20202020,	// phyr1c8
338 	0x20202020,	// phyr1cc
339 	0x20202020,	// phyr1d0
340 	0x20202020,	// phyr1d4
341 	0x20202020,	// phyr1d8
342 	0x20202020,	// phyr1dc
343 	0x20202020,	// phyr1e0
344 	0x20202020,	// phyr1e4
345 	0x00002020,	// phyr1e8
346 	0xaeeddeea,	// change address
347 	0x1e6e0304,	// new address
348 	0x00000800,	// phyr204
349 	0xaeeddeea,	// change address
350 	0x1e6e027c,	// new address
351 	0x4e400000,	// phyr17c
352 	0x59595959,	// phyr180
353 	0x40404040,	// phyr184
354 	0xaeeddeea,	// change address
355 	0x1e6e02f4,	// new address
356 	0x00000059,	// phyr1f4
357 	0xaeededed,	// end
358 };
359 #endif
360 
361 /* MPLL configuration */
362 #define SCU_MPLL_FREQ_400M	0x0008405F
363 #define SCU_MPLL_EXT_400M	0x0000002F
364 #define SCU_MPLL_FREQ_333M	0x00488299
365 #define SCU_MPLL_EXT_333M	0x0000014C
366 #define SCU_MPLL_FREQ_200M	0x0078007F
367 #define SCU_MPLL_EXT_200M	0x0000003F
368 #define SCU_MPLL_FREQ_100M	0x0078003F
369 #define SCU_MPLL_EXT_100M	0x0000001F
370 
371 #if defined(CONFIG_ASPEED_DDR4_1600)
372 #define SCU_MPLL_FREQ_CFG	SCU_MPLL_FREQ_400M
373 #define SCU_MPLL_EXT_CFG	SCU_MPLL_EXT_400M
374 #elif defined(CONFIG_ASPEED_DDR4_1333)
375 #define SCU_MPLL_FREQ_CFG	SCU_MPLL_FREQ_333M
376 #define SCU_MPLL_EXT_CFG	SCU_MPLL_EXT_333M
377 #elif defined(CONFIG_ASPEED_DDR4_800)
378 #define SCU_MPLL_FREQ_CFG	SCU_MPLL_FREQ_200M
379 #define SCU_MPLL_EXT_CFG	SCU_MPLL_EXT_200M
380 #elif defined(CONFIG_ASPEED_DDR4_400)
381 #define SCU_MPLL_FREQ_CFG	SCU_MPLL_FREQ_100M
382 #define SCU_MPLL_EXT_CFG	SCU_MPLL_EXT_100M
383 #else
384 #error "undefined DDR4 target rate\n"
385 #endif
386 
387 /*
388  * AC timing and SDRAM mode register setting
389  * for real chip are derived from the model GDDR4-1600
390  */
391 #define DDR4_MR01_MODE	0x03010510
392 #define DDR4_MR23_MODE	0x00000000
393 #define DDR4_MR45_MODE	0x04000000
394 #define DDR4_MR6_MODE	0x00000400
395 #define DDR4_TRFC_1600	0x467299f1
396 #define DDR4_TRFC_1333	0x3a5f80c9
397 #define DDR4_TRFC_800	0x23394c78
398 #define DDR4_TRFC_400	0x111c263c
399 
400 #if defined(CONFIG_ASPEED_DDR4_1600)
401 #define DDR4_TRFC		DDR4_TRFC_1600
402 #define DDR4_PHY_TRAIN_TRFC	0xc30
403 #elif defined(CONFIG_ASPEED_DDR4_1333)
404 #define DDR4_TRFC		DDR4_TRFC_1333
405 #define DDR4_PHY_TRAIN_TRFC	0xa25
406 #elif defined(CONFIG_ASPEED_DDR4_800)
407 #define DDR4_TRFC		DDR4_TRFC_800
408 #define DDR4_PHY_TRAIN_TRFC	0x618
409 #elif defined(CONFIG_ASPEED_DDR4_400)
410 #define DDR4_TRFC		DDR4_TRFC_400
411 #define DDR4_PHY_TRAIN_TRFC	0x30c
412 #else
413 #error "undefined tRFC setting"
414 #endif
415 
416 /* supported SDRAM size */
417 #define SDRAM_SIZE_1KB		(1024U)
418 #define SDRAM_SIZE_1MB		(SDRAM_SIZE_1KB * SDRAM_SIZE_1KB)
419 #define SDRAM_MIN_SIZE		(256 * SDRAM_SIZE_1MB)
420 #define SDRAM_MAX_SIZE		(2048 * SDRAM_SIZE_1MB)
421 
422 DECLARE_GLOBAL_DATA_PTR;
423 
424 static const u32 ddr4_ac_timing[4] = {
425 	0x040e0307, 0x0f4711f1, 0x0e060304, 0x00001240 };
426 static const u32 ddr_max_grant_params[4] = {
427 	0x44444444, 0x44444444, 0x44444444, 0x44444444 };
428 
429 struct dram_info {
430 	struct ram_info info;
431 	struct clk ddr_clk;
432 	struct ast2600_sdrammc_regs *regs;
433 	struct ast2600_scu *scu;
434 	struct ast2600_ddr_phy *phy;
435 	void __iomem *phy_setting;
436 	void __iomem *phy_status;
437 	ulong clock_rate;
438 };
439 
ast2600_sdramphy_kick_training(struct dram_info * info)440 static void ast2600_sdramphy_kick_training(struct dram_info *info)
441 {
442 	u32 data;
443 	struct ast2600_sdrammc_regs *regs = info->regs;
444 
445 	writel(SDRAM_PHYCTRL0_NRST, &regs->phy_ctrl[0]);
446 	udelay(5);
447 	writel(SDRAM_PHYCTRL0_NRST | SDRAM_PHYCTRL0_INIT, &regs->phy_ctrl[0]);
448 	udelay(1000);
449 
450 	while (1) {
451 		data = readl(&regs->phy_ctrl[0]) & SDRAM_PHYCTRL0_INIT;
452 		if (~data)
453 			break;
454 	}
455 }
456 
457 /**
458  * @brief	load DDR-PHY configurations table to the PHY registers
459  * @param[in]	p_tbl - pointer to the configuration table
460  * @param[in]	info - pointer to the DRAM info struct
461  *
462  * There are two sets of MRS (Mode Registers) configuration in ast2600 memory
463  * system: one is in the SDRAM MC (memory controller) which is used in run
464  * time, and the other is in the DDR-PHY IP which is used during DDR-PHY
465  * training.
466  */
ast2600_sdramphy_init(u32 * p_tbl,struct dram_info * info)467 static void ast2600_sdramphy_init(u32 *p_tbl, struct dram_info *info)
468 {
469 	u32 reg_base = (u32)info->phy_setting;
470 	u32 addr = p_tbl[0];
471 	u32 data;
472 	int i = 1;
473 
474 	writel(0, &info->regs->phy_ctrl[0]);
475 	udelay(10);
476 
477 	while (1) {
478 		if (addr < reg_base) {
479 			debug("invalid DDR-PHY addr: 0x%08x\n", addr);
480 			break;
481 		}
482 		data = p_tbl[i++];
483 
484 		if (data == DDR_PHY_TBL_END) {
485 			break;
486 		} else if (data == DDR_PHY_TBL_CHG_ADDR) {
487 			addr = p_tbl[i++];
488 		} else {
489 			writel(data, addr);
490 			addr += 4;
491 		}
492 	}
493 
494 	data = readl(info->phy_setting + 0x84) & ~GENMASK(16, 0);
495 	data |= DDR4_PHY_TRAIN_TRFC;
496 	writel(data, info->phy_setting + 0x84);
497 }
498 
ast2600_sdramphy_check_status(struct dram_info * info)499 static int ast2600_sdramphy_check_status(struct dram_info *info)
500 {
501 	u32 value, tmp;
502 	u32 reg_base = (u32)info->phy_status;
503 	int need_retrain = 0;
504 
505 	debug("\nSDRAM PHY training report:\n");
506 
507 	/* training status */
508 	value = readl(reg_base + 0x00);
509 	debug("rO_DDRPHY_reg offset 0x00 = 0x%08x\n", value);
510 
511 	if (value & BIT(3))
512 		debug("\tinitial PVT calibration fail\n");
513 
514 	if (value & BIT(5))
515 		debug("\truntime calibration fail\n");
516 
517 	/* PU & PD */
518 	value = readl(reg_base + 0x30);
519 	debug("rO_DDRPHY_reg offset 0x30 = 0x%08x\n", value);
520 	debug("  PU = 0x%02x\n", value & 0xff);
521 	debug("  PD = 0x%02x\n", (value >> 16) & 0xff);
522 
523 	/* read eye window */
524 	value = readl(reg_base + 0x68);
525 	if (0 == (value & GENMASK(7, 0)))
526 		need_retrain = 1;
527 
528 	debug("rO_DDRPHY_reg offset 0x68 = 0x%08x\n", value);
529 	debug("  rising edge of read data eye training pass window\n");
530 	tmp = (((value & GENMASK(7, 0)) >> 0) * 100) / 255;
531 	debug("    B0:%d%%\n", tmp);
532 	tmp = (((value & GENMASK(15, 8)) >> 8) * 100) / 255;
533 	debug("    B1:%d%%\n", tmp);
534 
535 	value = readl(reg_base + 0xC8);
536 	debug("rO_DDRPHY_reg offset 0xC8 = 0x%08x\n", value);
537 	debug("  falling edge of read data eye training pass window\n");
538 	tmp = (((value & GENMASK(7, 0)) >> 0) * 100) / 255;
539 	debug("    B0:%d%%\n", tmp);
540 	tmp = (((value & GENMASK(15, 8)) >> 8) * 100) / 255;
541 	debug("    B1:%d%%\n", tmp);
542 
543 	/* write eye window */
544 	value = readl(reg_base + 0x7c);
545 	if (0 == (value & GENMASK(7, 0)))
546 		need_retrain = 1;
547 
548 	debug("rO_DDRPHY_reg offset 0x7C = 0x%08x\n", value);
549 	debug("  rising edge of write data eye training pass window\n");
550 	tmp = (((value & GENMASK(7, 0)) >> 0) * 100) / 255;
551 	debug("    B0:%d%%\n", tmp);
552 	tmp = (((value & GENMASK(15, 8)) >> 8) * 100) / 255;
553 	debug("    B1:%d%%\n", tmp);
554 
555 	/* read Vref training result */
556 	value = readl(reg_base + 0x88);
557 	debug("rO_DDRPHY_reg offset 0x88 = 0x%08x\n", value);
558 	debug("  read Vref training result\n");
559 	tmp = (((value & GENMASK(7, 0)) >> 0) * 100) / 127;
560 	debug("    B0:%d%%\n", tmp);
561 	tmp = (((value & GENMASK(15, 8)) >> 8) * 100) / 127;
562 	debug("    B1:%d%%\n", tmp);
563 
564 	/* write Vref training result */
565 	value = readl(reg_base + 0x90);
566 	debug("rO_DDRPHY_reg offset 0x90 = 0x%08x\n", value);
567 
568 	/* gate train */
569 	value = readl(reg_base + 0x50);
570 	if ((0 == (value & GENMASK(15, 0))) ||
571 	    (0 == (value & GENMASK(31, 16)))) {
572 		need_retrain = 1;
573 	}
574 
575 	debug("rO_DDRPHY_reg offset 0x50 = 0x%08x\n", value);
576 
577 	return need_retrain;
578 }
579 
580 #ifndef CONFIG_ASPEED_BYPASS_SELFTEST
581 #define MC_TEST_PATTERN_N 8
582 static u32 as2600_sdrammc_test_pattern[MC_TEST_PATTERN_N] = {
583 	0xcc33cc33, 0xff00ff00, 0xaa55aa55, 0x88778877,
584 	0x92cc4d6e, 0x543d3cde, 0xf1e843c7, 0x7c61d253 };
585 
586 #define TIMEOUT_DRAM	5000000
ast2600_sdrammc_dg_test(struct dram_info * info,unsigned int datagen,u32 mode)587 int ast2600_sdrammc_dg_test(struct dram_info *info, unsigned int datagen, u32 mode)
588 {
589 	unsigned int data;
590 	unsigned int timeout = 0;
591 	struct ast2600_sdrammc_regs *regs = info->regs;
592 
593 	writel(0, &regs->ecc_test_ctrl);
594 
595 	if (mode == 0)
596 		writel(0x00000085 | (datagen << 3), &regs->ecc_test_ctrl);
597 	else
598 		writel(0x000000C1 | (datagen << 3), &regs->ecc_test_ctrl);
599 
600 	do {
601 		data = readl(&regs->ecc_test_ctrl) & GENMASK(13, 12);
602 
603 		if (data & BIT(13))
604 			return 0;
605 
606 		if (++timeout > TIMEOUT_DRAM) {
607 			debug("Timeout!!\n");
608 			writel(0, &regs->ecc_test_ctrl);
609 			return -1;
610 		}
611 	} while (!data);
612 
613 	writel(0, &regs->ecc_test_ctrl);
614 
615 	return 0;
616 }
617 
ast2600_sdrammc_cbr_test(struct dram_info * info)618 int ast2600_sdrammc_cbr_test(struct dram_info *info)
619 {
620 	u32 i;
621 	struct ast2600_sdrammc_regs *regs = info->regs;
622 
623 	clrsetbits_le32(&regs->test_addr, GENMASK(30, 4), 0x7ffff0);
624 
625 	/* single */
626 	for (i = 0; i < 8; i++)
627 		if (ast2600_sdrammc_dg_test(info, i, 0))
628 			return -1;
629 
630 	/* burst */
631 	for (i = 0; i < 8; i++)
632 		if (ast2600_sdrammc_dg_test(info, i, i))
633 			return -1;
634 
635 	return 0;
636 }
637 
ast2600_sdrammc_test(struct dram_info * info)638 static int ast2600_sdrammc_test(struct dram_info *info)
639 {
640 	struct ast2600_sdrammc_regs *regs = info->regs;
641 
642 	u32 pass_cnt = 0;
643 	u32 fail_cnt = 0;
644 	u32 target_cnt = 2;
645 	u32 test_cnt = 0;
646 	u32 pattern;
647 	u32 i = 0;
648 	bool finish = false;
649 
650 	debug("sdram mc test:\n");
651 	while (!finish) {
652 		pattern = as2600_sdrammc_test_pattern[i++];
653 		i = i % MC_TEST_PATTERN_N;
654 		debug("  pattern = %08X : ", pattern);
655 		writel(pattern, &regs->test_init_val);
656 
657 		if (ast2600_sdrammc_cbr_test(info)) {
658 			debug("fail\n");
659 			fail_cnt++;
660 		} else {
661 			debug("pass\n");
662 			pass_cnt++;
663 		}
664 
665 		if (++test_cnt == target_cnt)
666 			finish = true;
667 	}
668 	debug("statistics: pass/fail/total:%d/%d/%d\n", pass_cnt, fail_cnt,
669 	      target_cnt);
670 
671 	return fail_cnt;
672 }
673 #endif
674 
675 /*
676  * scu500[14:13]
677  *	2b'00: VGA memory size = 16MB
678  *	2b'01: VGA memory size = 16MB
679  *	2b'10: VGA memory size = 32MB
680  *	2b'11: VGA memory size = 64MB
681  *
682  * mcr04[3:2]
683  *	2b'00: VGA memory size = 8MB
684  *	2b'01: VGA memory size = 16MB
685  *	2b'10: VGA memory size = 32MB
686  *	2b'11: VGA memory size = 64MB
687  */
ast2600_sdrammc_get_vga_mem_size(struct dram_info * info)688 static size_t ast2600_sdrammc_get_vga_mem_size(struct dram_info *info)
689 {
690 	u32 vga_hwconf;
691 	size_t vga_mem_size_base = 8 * 1024 * 1024;
692 
693 	vga_hwconf =
694 		(readl(&info->scu->hwstrap1) & SCU_HWSTRAP1_VGA_MEM_MASK) >>
695 		 SCU_HWSTRAP1_VGA_MEM_SHIFT;
696 
697 	if (vga_hwconf == 0) {
698 		vga_hwconf = 1;
699 		writel(vga_hwconf << SCU_HWSTRAP1_VGA_MEM_SHIFT,
700 		       &info->scu->hwstrap1);
701 	}
702 
703 	clrsetbits_le32(&info->regs->config, SDRAM_CONF_VGA_SIZE_MASK,
704 			((vga_hwconf << SDRAM_CONF_VGA_SIZE_SHIFT) &
705 			 SDRAM_CONF_VGA_SIZE_MASK));
706 
707 	/* no need to reserve VGA memory if efuse[VGA disable] is set */
708 	if (readl(&info->scu->efuse) & SCU_EFUSE_DIS_VGA)
709 		return 0;
710 
711 	return vga_mem_size_base << vga_hwconf;
712 }
713 
714 /*
715  * Find out RAM size and save it in dram_info
716  *
717  * The procedure is taken from Aspeed SDK
718  */
ast2600_sdrammc_calc_size(struct dram_info * info)719 static void ast2600_sdrammc_calc_size(struct dram_info *info)
720 {
721 	/* The controller supports 256/512/1024/2048 MB ram */
722 	size_t ram_size = SDRAM_MIN_SIZE;
723 	const int write_test_offset = 0x100000;
724 	u32 test_pattern = 0xdeadbeef;
725 	u32 cap_param = SDRAM_CONF_CAP_2048M;
726 	u32 refresh_timing_param = DDR4_TRFC;
727 	const u32 write_addr_base = CONFIG_SYS_SDRAM_BASE + write_test_offset;
728 
729 	for (ram_size = SDRAM_MAX_SIZE; ram_size > SDRAM_MIN_SIZE;
730 	     ram_size >>= 1) {
731 		writel(test_pattern, write_addr_base + (ram_size >> 1));
732 		test_pattern = (test_pattern >> 4) | (test_pattern << 28);
733 	}
734 
735 	/* One last write to overwrite all wrapped values */
736 	writel(test_pattern, write_addr_base);
737 
738 	/* Reset the pattern and see which value was really written */
739 	test_pattern = 0xdeadbeef;
740 	for (ram_size = SDRAM_MAX_SIZE; ram_size > SDRAM_MIN_SIZE;
741 	     ram_size >>= 1) {
742 		if (readl(write_addr_base + (ram_size >> 1)) == test_pattern)
743 			break;
744 
745 		--cap_param;
746 		refresh_timing_param >>= 8;
747 		test_pattern = (test_pattern >> 4) | (test_pattern << 28);
748 	}
749 
750 	clrsetbits_le32(&info->regs->ac_timing[1],
751 			(SDRAM_AC_TRFC_MASK << SDRAM_AC_TRFC_SHIFT),
752 			((refresh_timing_param & SDRAM_AC_TRFC_MASK)
753 			 << SDRAM_AC_TRFC_SHIFT));
754 
755 	info->info.base = CONFIG_SYS_SDRAM_BASE;
756 	info->info.size = ram_size - ast2600_sdrammc_get_vga_mem_size(info);
757 
758 	clrsetbits_le32(&info->regs->config, SDRAM_CONF_CAP_MASK,
759 			((cap_param << SDRAM_CONF_CAP_SHIFT) & SDRAM_CONF_CAP_MASK));
760 }
761 
ast2600_sdrammc_init_ddr4(struct dram_info * info)762 static int ast2600_sdrammc_init_ddr4(struct dram_info *info)
763 {
764 	const u32 power_ctrl = MCR34_CKE_EN | MCR34_AUTOPWRDN_EN |
765 		MCR34_MREQ_BYPASS_DIS | MCR34_RESETN_DIS |
766 		MCR34_ODT_EN | MCR34_ODT_AUTO_ON |
767 		(0x1 << MCR34_ODT_EXT_SHIFT);
768 
769 	/* init SDRAM-PHY only on real chip */
770 	ast2600_sdramphy_init(ast2600_sdramphy_config, info);
771 	writel((MCR34_CKE_EN | MCR34_MREQI_DIS | MCR34_RESETN_DIS),
772 	       &info->regs->power_ctrl);
773 	udelay(5);
774 	ast2600_sdramphy_kick_training(info);
775 	udelay(500);
776 	writel(SDRAM_RESET_DLL_ZQCL_EN, &info->regs->refresh_timing);
777 
778 	writel(MCR30_SET_MR(3), &info->regs->mode_setting_control);
779 	writel(MCR30_SET_MR(6), &info->regs->mode_setting_control);
780 	writel(MCR30_SET_MR(5), &info->regs->mode_setting_control);
781 	writel(MCR30_SET_MR(4), &info->regs->mode_setting_control);
782 	writel(MCR30_SET_MR(2), &info->regs->mode_setting_control);
783 	writel(MCR30_SET_MR(1), &info->regs->mode_setting_control);
784 	writel(MCR30_SET_MR(0) | MCR30_RESET_DLL_DELAY_EN,
785 	       &info->regs->mode_setting_control);
786 
787 	writel(SDRAM_REFRESH_EN | SDRAM_RESET_DLL_ZQCL_EN |
788 	       (0x5f << SDRAM_REFRESH_PERIOD_SHIFT),
789 	       &info->regs->refresh_timing);
790 
791 	/* wait self-refresh idle */
792 	while (readl(&info->regs->power_ctrl) &
793 	       MCR34_SELF_REFRESH_STATUS_MASK)
794 		;
795 
796 	writel(SDRAM_REFRESH_EN | SDRAM_LOW_PRI_REFRESH_EN |
797 	       SDRAM_REFRESH_ZQCS_EN |
798 	       (0x5f << SDRAM_REFRESH_PERIOD_SHIFT) |
799 	       (0x42aa << SDRAM_REFRESH_PERIOD_ZQCS_SHIFT),
800 	       &info->regs->refresh_timing);
801 
802 	writel(power_ctrl, &info->regs->power_ctrl);
803 	udelay(500);
804 
805 	return 0;
806 }
807 
ast2600_sdrammc_unlock(struct dram_info * info)808 static void ast2600_sdrammc_unlock(struct dram_info *info)
809 {
810 	writel(SDRAM_UNLOCK_KEY, &info->regs->protection_key);
811 	while (!readl(&info->regs->protection_key))
812 		;
813 }
814 
ast2600_sdrammc_lock(struct dram_info * info)815 static void ast2600_sdrammc_lock(struct dram_info *info)
816 {
817 	writel(~SDRAM_UNLOCK_KEY, &info->regs->protection_key);
818 	while (readl(&info->regs->protection_key))
819 		;
820 }
821 
ast2600_sdrammc_common_init(struct ast2600_sdrammc_regs * regs)822 static void ast2600_sdrammc_common_init(struct ast2600_sdrammc_regs *regs)
823 {
824 	int i;
825 
826 	writel(MCR34_MREQI_DIS | MCR34_RESETN_DIS, &regs->power_ctrl);
827 	writel(SDRAM_VIDEO_UNLOCK_KEY, &regs->gm_protection_key);
828 	writel(0x10 << MCR38_RW_MAX_GRANT_CNT_RQ_SHIFT,
829 	       &regs->arbitration_ctrl);
830 	writel(0xFFBBFFF4, &regs->req_limit_mask);
831 
832 	for (i = 0; i < ARRAY_SIZE(ddr_max_grant_params); ++i)
833 		writel(ddr_max_grant_params[i], &regs->max_grant_len[i]);
834 
835 	writel(MCR50_RESET_ALL_INTR, &regs->intr_ctrl);
836 
837 	writel(0x07FFFFFF, &regs->ecc_range_ctrl);
838 
839 	writel(0, &regs->ecc_test_ctrl);
840 	writel(0x80000001, &regs->test_addr);
841 	writel(0, &regs->test_fail_dq_bit);
842 	writel(0, &regs->test_init_val);
843 
844 	writel(0xFFFFFFFF, &regs->req_input_ctrl);
845 	writel(0, &regs->req_high_pri_ctrl);
846 
847 	udelay(600);
848 
849 #ifdef CONFIG_ASPEED_DDR4_DUALX8
850 	writel(0x37, &regs->config);
851 #else
852 	writel(0x17, &regs->config);
853 #endif
854 
855 	/* load controller setting */
856 	for (i = 0; i < ARRAY_SIZE(ddr4_ac_timing); ++i)
857 		writel(ddr4_ac_timing[i], &regs->ac_timing[i]);
858 
859 	writel(DDR4_MR01_MODE, &regs->mr01_mode_setting);
860 	writel(DDR4_MR23_MODE, &regs->mr23_mode_setting);
861 	writel(DDR4_MR45_MODE, &regs->mr45_mode_setting);
862 	writel(DDR4_MR6_MODE, &regs->mr6_mode_setting);
863 }
864 
865 /*
866  * Update size info according to the ECC HW setting
867  *
868  * Assume SDRAM has been initialized by SPL or the host.  To get the RAM size, we
869  * don't need to calculate the ECC size again but read from MCR04 and derive the
870  * size from its value.
871  */
ast2600_sdrammc_update_size(struct dram_info * info)872 static void ast2600_sdrammc_update_size(struct dram_info *info)
873 {
874 	struct ast2600_sdrammc_regs *regs = info->regs;
875 	u32 conf = readl(&regs->config);
876 	u32 cap_param;
877 	size_t ram_size = SDRAM_MAX_SIZE;
878 	size_t hw_size;
879 
880 	cap_param = (conf & SDRAM_CONF_CAP_MASK) >> SDRAM_CONF_CAP_SHIFT;
881 	switch (cap_param) {
882 	case SDRAM_CONF_CAP_2048M:
883 		ram_size = 2048 * SDRAM_SIZE_1MB;
884 		break;
885 	case SDRAM_CONF_CAP_1024M:
886 		ram_size = 1024 * SDRAM_SIZE_1MB;
887 		break;
888 	case SDRAM_CONF_CAP_512M:
889 		ram_size = 512 * SDRAM_SIZE_1MB;
890 		break;
891 	case SDRAM_CONF_CAP_256M:
892 		ram_size = 256 * SDRAM_SIZE_1MB;
893 		break;
894 	}
895 
896 	info->info.base = CONFIG_SYS_SDRAM_BASE;
897 	info->info.size = ram_size - ast2600_sdrammc_get_vga_mem_size(info);
898 
899 	if (0 == (conf & SDRAM_CONF_ECC_SETUP))
900 		return;
901 
902 	hw_size = readl(&regs->ecc_range_ctrl) & SDRAM_ECC_RANGE_ADDR_MASK;
903 	hw_size += (1 << SDRAM_ECC_RANGE_ADDR_SHIFT);
904 
905 	info->info.size = hw_size;
906 }
907 
908 #ifdef CONFIG_ASPEED_ECC
ast2600_sdrammc_ecc_enable(struct dram_info * info)909 static void ast2600_sdrammc_ecc_enable(struct dram_info *info)
910 {
911 	struct ast2600_sdrammc_regs *regs = info->regs;
912 	size_t conf_size;
913 	u32 reg;
914 
915 	conf_size = CONFIG_ASPEED_ECC_SIZE * SDRAM_SIZE_1MB;
916 	if (conf_size > info->info.size) {
917 		printf("warning: ECC configured %dMB but actual size is %dMB\n",
918 		       CONFIG_ASPEED_ECC_SIZE,
919 		       info->info.size / SDRAM_SIZE_1MB);
920 		conf_size = info->info.size;
921 	} else if (conf_size == 0) {
922 		conf_size = info->info.size;
923 	}
924 
925 	info->info.size = (((conf_size / 9) * 8) >> 20) << 20;
926 	writel(((info->info.size >> 20) - 1) << 20, &regs->ecc_range_ctrl);
927 	reg = readl(&regs->config) | SDRAM_CONF_ECC_SETUP;
928 	writel(reg, &regs->config);
929 
930 	writel(0, &regs->test_init_val);
931 	writel(0x80000001, &regs->test_addr);
932 	writel(0x221, &regs->ecc_test_ctrl);
933 	while (0 == (readl(&regs->ecc_test_ctrl) & BIT(12)))
934 		;
935 	writel(0, &regs->ecc_test_ctrl);
936 	writel(BIT(31), &regs->intr_ctrl);
937 	writel(0, &regs->intr_ctrl);
938 }
939 #endif
940 
ast2600_sdrammc_probe(struct udevice * dev)941 static int ast2600_sdrammc_probe(struct udevice *dev)
942 {
943 	int ret;
944 	u32 reg;
945 	struct dram_info *priv = (struct dram_info *)dev_get_priv(dev);
946 	struct ast2600_sdrammc_regs *regs = priv->regs;
947 	struct udevice *clk_dev;
948 
949 	/* find SCU base address from clock device */
950 	ret = uclass_get_device_by_driver(UCLASS_CLK,
951 					  DM_DRIVER_GET(aspeed_ast2600_scu), &clk_dev);
952 	if (ret) {
953 		debug("clock device not defined\n");
954 		return ret;
955 	}
956 
957 	priv->scu = devfdt_get_addr_ptr(clk_dev);
958 	if (IS_ERR(priv->scu)) {
959 		debug("%s(): can't get SCU\n", __func__);
960 		return PTR_ERR(priv->scu);
961 	}
962 
963 	if (readl(&priv->scu->dram_hdshk) & SCU_DRAM_HDSHK_RDY) {
964 		printf("already initialized, ");
965 		ast2600_sdrammc_update_size(priv);
966 		return 0;
967 	}
968 
969 	reg = readl(&priv->scu->mpll);
970 	reg &= ~(SCU_PLL_BYPASS | SCU_PLL_DIV_MASK |
971 		 SCU_PLL_DENUM_MASK | SCU_PLL_NUM_MASK);
972 	reg |= (SCU_PLL_RST | SCU_PLL_OFF | SCU_MPLL_FREQ_CFG);
973 	writel(reg, &priv->scu->mpll);
974 	writel(SCU_MPLL_EXT_CFG, &priv->scu->mpll_ext);
975 	udelay(100);
976 	reg &= ~(SCU_PLL_RST | SCU_PLL_OFF);
977 	writel(reg, &priv->scu->mpll);
978 
979 	while ((readl(&priv->scu->mpll_ext) & BIT(31)) == 0)
980 		;
981 
982 	ast2600_sdrammc_unlock(priv);
983 	ast2600_sdrammc_common_init(regs);
984 L_ast2600_sdramphy_train:
985 	ast2600_sdrammc_init_ddr4(priv);
986 
987 	/* make sure DDR-PHY is ready before access */
988 	do {
989 		reg = readl(priv->phy_status) & BIT(1);
990 	} while (reg == 0);
991 
992 	if (ast2600_sdramphy_check_status(priv) != 0) {
993 		printf("DDR4 PHY training fail, retrain\n");
994 		goto L_ast2600_sdramphy_train;
995 	}
996 
997 	ast2600_sdrammc_calc_size(priv);
998 
999 #ifndef CONFIG_ASPEED_BYPASS_SELFTEST
1000 	if (ast2600_sdrammc_test(priv) != 0) {
1001 		printf("%s: DDR4 init fail\n", __func__);
1002 		return -EINVAL;
1003 	}
1004 #endif
1005 
1006 #ifdef CONFIG_ASPEED_ECC
1007 	ast2600_sdrammc_ecc_enable(priv);
1008 #endif
1009 
1010 	writel(readl(&priv->scu->dram_hdshk) | SCU_DRAM_HDSHK_RDY,
1011 	       &priv->scu->dram_hdshk);
1012 
1013 	clrbits_le32(&regs->intr_ctrl, MCR50_RESET_ALL_INTR);
1014 	ast2600_sdrammc_lock(priv);
1015 	return 0;
1016 }
1017 
ast2600_sdrammc_of_to_plat(struct udevice * dev)1018 static int ast2600_sdrammc_of_to_plat(struct udevice *dev)
1019 {
1020 	struct dram_info *priv = dev_get_priv(dev);
1021 
1022 	priv->regs = (void *)(uintptr_t)devfdt_get_addr_index(dev, 0);
1023 	priv->phy_setting = (void *)(uintptr_t)devfdt_get_addr_index(dev, 1);
1024 	priv->phy_status = (void *)(uintptr_t)devfdt_get_addr_index(dev, 2);
1025 
1026 	priv->clock_rate = fdtdec_get_int(gd->fdt_blob, dev_of_offset(dev),
1027 					  "clock-frequency", 0);
1028 	if (!priv->clock_rate) {
1029 		debug("DDR Clock Rate not defined\n");
1030 		return -EINVAL;
1031 	}
1032 
1033 	return 0;
1034 }
1035 
ast2600_sdrammc_get_info(struct udevice * dev,struct ram_info * info)1036 static int ast2600_sdrammc_get_info(struct udevice *dev, struct ram_info *info)
1037 {
1038 	struct dram_info *priv = dev_get_priv(dev);
1039 
1040 	*info = priv->info;
1041 
1042 	return 0;
1043 }
1044 
1045 static struct ram_ops ast2600_sdrammc_ops = {
1046 	.get_info = ast2600_sdrammc_get_info,
1047 };
1048 
1049 static const struct udevice_id ast2600_sdrammc_ids[] = {
1050 	{ .compatible = "aspeed,ast2600-sdrammc" },
1051 	{ }
1052 };
1053 
1054 U_BOOT_DRIVER(sdrammc_ast2600) = {
1055 	.name = "aspeed_ast2600_sdrammc",
1056 	.id = UCLASS_RAM,
1057 	.of_match = ast2600_sdrammc_ids,
1058 	.ops = &ast2600_sdrammc_ops,
1059 	.of_to_plat = ast2600_sdrammc_of_to_plat,
1060 	.probe = ast2600_sdrammc_probe,
1061 	.priv_auto = sizeof(struct dram_info),
1062 };
1063