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