1 // SPDX-License-Identifier: GPL-2.0
2 /*
3 * (C) Copyright 2018 Rockchip Electronics Co., Ltd.
4 */
5
6 #include <common.h>
7 #include <debug_uart.h>
8 #include <ram.h>
9 #include <asm/io.h>
10 #include <asm/arch/sdram.h>
11 #include <asm/arch/sdram_common.h>
12
sdram_print_dram_type(unsigned char dramtype)13 void sdram_print_dram_type(unsigned char dramtype)
14 {
15 switch (dramtype) {
16 case DDR3:
17 printascii("DDR3");
18 break;
19 case DDR4:
20 printascii("DDR4");
21 break;
22 case LPDDR2:
23 printascii("LPDDR2");
24 break;
25 case LPDDR3:
26 printascii("LPDDR3");
27 break;
28 case LPDDR4:
29 printascii("LPDDR4");
30 break;
31 case LPDDR4X:
32 printascii("LPDDR4X");
33 break;
34 default:
35 printascii("Unknown Device");
36 break;
37 }
38 }
39
sdram_print_ddr_info(struct sdram_cap_info * cap_info,struct sdram_base_params * base,u32 split)40 void sdram_print_ddr_info(struct sdram_cap_info *cap_info,
41 struct sdram_base_params *base, u32 split)
42 {
43 u64 cap;
44 u32 bg;
45
46 bg = (cap_info->dbw == 0) ? 2 : 1;
47
48 sdram_print_dram_type(base->dramtype);
49
50 printascii(", ");
51 printdec(base->ddr_freq);
52 printascii("MHz\n");
53
54 printascii("BW=");
55 printdec(8 << cap_info->bw);
56 printascii(" Col=");
57 printdec(cap_info->col);
58 printascii(" Bk=");
59 printdec(0x1 << cap_info->bk);
60 if (base->dramtype == DDR4) {
61 printascii(" BG=");
62 printdec(1 << bg);
63 }
64 printascii(" CS0 Row=");
65 printdec(cap_info->cs0_row);
66 if (cap_info->cs0_high16bit_row !=
67 cap_info->cs0_row) {
68 printascii("/");
69 printdec(cap_info->cs0_high16bit_row);
70 }
71 if (cap_info->rank > 1) {
72 printascii(" CS1 Row=");
73 printdec(cap_info->cs1_row);
74 if (cap_info->cs1_high16bit_row !=
75 cap_info->cs1_row) {
76 printascii("/");
77 printdec(cap_info->cs1_high16bit_row);
78 }
79 }
80 if (cap_info->rank > 2) {
81 printascii(" CS2 Row=");
82 printdec(cap_info->cs2_row);
83 if (cap_info->cs2_high16bit_row !=
84 cap_info->cs2_row) {
85 printascii("/");
86 printdec(cap_info->cs2_high16bit_row);
87 }
88 printascii(" CS3 Row=");
89 printdec(cap_info->cs3_row);
90 if (cap_info->cs3_high16bit_row !=
91 cap_info->cs3_row) {
92 printascii("/");
93 printdec(cap_info->cs3_high16bit_row);
94 }
95 }
96 printascii(" CS=");
97 printdec(cap_info->rank);
98 printascii(" Die BW=");
99 printdec(8 << cap_info->dbw);
100
101 cap = sdram_get_cs_cap(cap_info, 3, base->dramtype);
102 if (cap_info->row_3_4)
103 cap = cap * 3 / 4;
104 else if (split)
105 cap = cap / 2 + (split << 24) / 2;
106
107 printascii(" Size=");
108 printdec(cap >> 20);
109 printascii("MB\n");
110 }
111
112 /*
113 * cs: 0:cs0
114 * 1:cs1
115 * else cs0+cs1
116 * note: it didn't consider about row_3_4
117 */
sdram_get_cs_cap(struct sdram_cap_info * cap_info,u32 cs,u32 dram_type)118 u64 sdram_get_cs_cap(struct sdram_cap_info *cap_info, u32 cs, u32 dram_type)
119 {
120 u32 bg;
121 u64 cap[4];
122
123 if (dram_type == DDR4)
124 /* DDR4 8bit dram BG = 2(4bank groups),
125 * 16bit dram BG = 1 (2 bank groups)
126 */
127 bg = (cap_info->dbw == 0) ? 2 : 1;
128 else
129 bg = 0;
130 cap[0] = 1llu << (cap_info->bw + cap_info->col +
131 bg + cap_info->bk + cap_info->cs0_row);
132
133 if (cap_info->rank >= 2)
134 cap[1] = 1llu << (cap_info->bw + cap_info->col +
135 bg + cap_info->bk + cap_info->cs1_row);
136 else
137 cap[1] = 0;
138
139 if (cap_info->rank == 4) {
140 cap[2] = 1llu << (cap_info->bw + cap_info->col +
141 bg + cap_info->bk + cap_info->cs2_row);
142 cap[3] = 1llu << (cap_info->bw + cap_info->col +
143 bg + cap_info->bk + cap_info->cs3_row);
144 } else {
145 cap[2] = 0;
146 cap[3] = 0;
147 }
148 if (cs == 0)
149 return cap[0];
150 else if (cs == 1)
151 return cap[1];
152 else
153 return (cap[0] + cap[1] + cap[2] + cap[3]);
154 }
155
156 /* n: Unit bytes */
sdram_copy_to_reg(u32 * dest,const u32 * src,u32 n)157 void sdram_copy_to_reg(u32 *dest, const u32 *src, u32 n)
158 {
159 int i;
160
161 for (i = 0; i < n / sizeof(u32); i++) {
162 writel(*src, dest);
163 src++;
164 dest++;
165 }
166 }
167
sdram_org_config(struct sdram_cap_info * cap_info,struct sdram_base_params * base,u32 * p_os_reg2,u32 * p_os_reg3,u32 channel)168 void sdram_org_config(struct sdram_cap_info *cap_info,
169 struct sdram_base_params *base,
170 u32 *p_os_reg2, u32 *p_os_reg3, u32 channel)
171 {
172 *p_os_reg2 |= SYS_REG_ENC_DDRTYPE(base->dramtype);
173 *p_os_reg2 |= SYS_REG_ENC_NUM_CH(base->num_channels);
174
175 *p_os_reg2 |= SYS_REG_ENC_ROW_3_4(cap_info->row_3_4, channel);
176 *p_os_reg2 |= SYS_REG_ENC_CHINFO(channel);
177 *p_os_reg2 |= SYS_REG_ENC_RANK(cap_info->rank, channel);
178 *p_os_reg2 |= SYS_REG_ENC_COL(cap_info->col, channel);
179 *p_os_reg2 |= SYS_REG_ENC_BK(cap_info->bk, channel);
180 *p_os_reg2 |= SYS_REG_ENC_BW(cap_info->bw, channel);
181 *p_os_reg2 |= SYS_REG_ENC_DBW(cap_info->dbw, channel);
182
183 SYS_REG_ENC_CS0_ROW(cap_info->cs0_row, *p_os_reg2, *p_os_reg3, channel);
184 if (cap_info->cs1_row)
185 SYS_REG_ENC_CS1_ROW(cap_info->cs1_row, *p_os_reg2,
186 *p_os_reg3, channel);
187 *p_os_reg3 |= SYS_REG_ENC_CS1_COL(cap_info->col, channel);
188 *p_os_reg3 |= SYS_REG_ENC_VERSION(DDR_SYS_REG_VERSION);
189 }
190
sdram_org_config_v3(struct sdram_cap_info * cap_info,struct sdram_base_params * base,u32 * p_os_reg2,u32 * p_os_reg3,u32 channel)191 void sdram_org_config_v3(struct sdram_cap_info *cap_info,
192 struct sdram_base_params *base,
193 u32 *p_os_reg2, u32 *p_os_reg3, u32 channel)
194 {
195 SYS_REG_ENC_DDRTYPE_V3(base->dramtype, *p_os_reg2, *p_os_reg3);
196
197 *p_os_reg2 |= SYS_REG_ENC_NUM_CH_V3((base->num_channels > 2) ?
198 2 : base->num_channels);
199
200 *p_os_reg2 |= SYS_REG_ENC_ROW_3_4_V3(cap_info->row_3_4, channel);
201 *p_os_reg2 |= SYS_REG_ENC_CHINFO_V3((channel >= 2) ? channel - 2 : channel);
202 if (channel == 0 || channel == 2)
203 SYS_REG_ENC_CH0_2_RANK_V3(cap_info->rank,
204 *p_os_reg2, *p_os_reg3);
205 else
206 *p_os_reg2 |= SYS_REG_ENC_CH1_3_RANK(cap_info->rank);
207
208 *p_os_reg2 |= SYS_REG_ENC_COL_V3(cap_info->col, channel);
209 *p_os_reg2 |= SYS_REG_ENC_BK_V3(cap_info->bk, channel);
210 *p_os_reg2 |= SYS_REG_ENC_BW_V3(cap_info->bw, channel);
211 *p_os_reg2 |= SYS_REG_ENC_DBW_V3(cap_info->dbw, channel);
212
213 SYS_REG_ENC_CS0_ROW_V3(cap_info->cs0_row, *p_os_reg2, *p_os_reg3, channel);
214 if (cap_info->cs1_row)
215 SYS_REG_ENC_CS1_ROW_V3(cap_info->cs1_row, *p_os_reg2,
216 *p_os_reg3, channel);
217 if ((channel == 0 || channel == 2) && cap_info->rank > 2) {
218 if (cap_info->cs2_row == cap_info->cs0_row)
219 *p_os_reg3 |= SYS_REG_ENC_CS2_DELTA_ROW_V3(0);
220 else
221 *p_os_reg3 |= SYS_REG_ENC_CS2_DELTA_ROW_V3(1);
222
223 if (cap_info->cs3_row == cap_info->cs0_row)
224 *p_os_reg3 |= SYS_REG_ENC_CS3_DELTA_ROW_V3(0);
225 else
226 *p_os_reg3 |= SYS_REG_ENC_CS3_DELTA_ROW_V3(1);
227 }
228
229 *p_os_reg3 |= SYS_REG_ENC_CS1_COL_V3(cap_info->col, channel);
230 *p_os_reg3 |= SYS_REG_ENC_VERSION(DDR_SYS_REG_VERSION_3);
231 }
232
sdram_detect_bw(struct sdram_cap_info * cap_info)233 int sdram_detect_bw(struct sdram_cap_info *cap_info)
234 {
235 return 0;
236 }
237
sdram_detect_cs(struct sdram_cap_info * cap_info)238 int sdram_detect_cs(struct sdram_cap_info *cap_info)
239 {
240 return 0;
241 }
242
sdram_detect_col(struct sdram_cap_info * cap_info,u32 coltmp)243 int sdram_detect_col(struct sdram_cap_info *cap_info,
244 u32 coltmp)
245 {
246 void __iomem *test_addr;
247 u32 col;
248 u32 bw = cap_info->bw;
249
250 for (col = coltmp; col >= 9; col -= 1) {
251 writel(0, CONFIG_SYS_SDRAM_BASE);
252 test_addr = (void __iomem *)(CONFIG_SYS_SDRAM_BASE +
253 (1ul << (col + bw - 1ul)));
254 writel(PATTERN, test_addr);
255 if ((readl(test_addr) == PATTERN) &&
256 (readl(CONFIG_SYS_SDRAM_BASE) == 0))
257 break;
258 }
259 if (col == 8) {
260 printascii("col error\n");
261 return -1;
262 }
263
264 cap_info->col = col;
265
266 return 0;
267 }
268
sdram_detect_bank(struct sdram_cap_info * cap_info,u32 coltmp,u32 bktmp)269 int sdram_detect_bank(struct sdram_cap_info *cap_info,
270 u32 coltmp, u32 bktmp)
271 {
272 void __iomem *test_addr;
273 u32 bk;
274 u32 bw = cap_info->bw;
275
276 test_addr = (void __iomem *)(CONFIG_SYS_SDRAM_BASE +
277 (1ul << (coltmp + bktmp + bw - 1ul)));
278 writel(0, CONFIG_SYS_SDRAM_BASE);
279 writel(PATTERN, test_addr);
280 if ((readl(test_addr) == PATTERN) &&
281 (readl(CONFIG_SYS_SDRAM_BASE) == 0))
282 bk = 3;
283 else
284 bk = 2;
285
286 cap_info->bk = bk;
287
288 return 0;
289 }
290
291 /* detect bg for ddr4 */
sdram_detect_bg(struct sdram_cap_info * cap_info,u32 coltmp)292 int sdram_detect_bg(struct sdram_cap_info *cap_info,
293 u32 coltmp)
294 {
295 void __iomem *test_addr;
296 u32 dbw;
297 u32 bw = cap_info->bw;
298
299 test_addr = (void __iomem *)(CONFIG_SYS_SDRAM_BASE +
300 (1ul << (coltmp + bw + 1ul)));
301 writel(0, CONFIG_SYS_SDRAM_BASE);
302 writel(PATTERN, test_addr);
303 if ((readl(test_addr) == PATTERN) &&
304 (readl(CONFIG_SYS_SDRAM_BASE) == 0))
305 dbw = 0;
306 else
307 dbw = 1;
308
309 cap_info->dbw = dbw;
310
311 return 0;
312 }
313
314 /* detect dbw for ddr3,lpddr2,lpddr3,lpddr4 */
sdram_detect_dbw(struct sdram_cap_info * cap_info,u32 dram_type)315 int sdram_detect_dbw(struct sdram_cap_info *cap_info, u32 dram_type)
316 {
317 u32 row, col, bk, bw, cs_cap, cs;
318 u32 die_bw_0 = 0, die_bw_1 = 0;
319
320 if (dram_type == DDR3) {
321 if (cap_info->bw == 0)
322 cap_info->dbw = 0;
323 else
324 cap_info->dbw = 1;
325 } else if (dram_type == LPDDR4) {
326 cap_info->dbw = 1;
327 } else if (dram_type == LPDDR3 || dram_type == LPDDR2) {
328 row = cap_info->cs0_row;
329 col = cap_info->col;
330 bk = cap_info->bk;
331 cs = cap_info->rank;
332 bw = cap_info->bw;
333 cs_cap = (1 << (row + col + bk + bw - 20));
334 if (bw == 2) {
335 if (cs_cap <= 0x20) /* 256Mb */
336 die_bw_0 = (col < 9) ? 2 : 1;
337 else if (cs_cap <= 0x100) /* 2Gb */
338 die_bw_0 = (col < 10) ? 2 : 1;
339 else if (cs_cap <= 0x400) /* 8Gb */
340 die_bw_0 = (col < 11) ? 2 : 1;
341 else
342 die_bw_0 = (col < 12) ? 2 : 1;
343 if (cs > 1) {
344 row = cap_info->cs1_row;
345 cs_cap = (1 << (row + col + bk + bw - 20));
346 if (cs_cap <= 0x20) /* 256Mb */
347 die_bw_0 = (col < 9) ? 2 : 1;
348 else if (cs_cap <= 0x100) /* 2Gb */
349 die_bw_0 = (col < 10) ? 2 : 1;
350 else if (cs_cap <= 0x400) /* 8Gb */
351 die_bw_0 = (col < 11) ? 2 : 1;
352 else
353 die_bw_0 = (col < 12) ? 2 : 1;
354 }
355 } else {
356 die_bw_1 = 1;
357 die_bw_0 = 1;
358 }
359 cap_info->dbw = (die_bw_0 > die_bw_1) ? die_bw_0 : die_bw_1;
360 }
361
362 return 0;
363 }
364
sdram_detect_row(struct sdram_cap_info * cap_info,u32 coltmp,u32 bktmp,u32 rowtmp)365 int sdram_detect_row(struct sdram_cap_info *cap_info,
366 u32 coltmp, u32 bktmp, u32 rowtmp)
367 {
368 u32 row;
369 u32 bw = cap_info->bw;
370 void __iomem *test_addr;
371
372 for (row = rowtmp; row > 12; row--) {
373 writel(0, CONFIG_SYS_SDRAM_BASE);
374 test_addr = (void __iomem *)(CONFIG_SYS_SDRAM_BASE +
375 (1ul << (row + bktmp + coltmp + bw - 1ul)));
376 writel(PATTERN, test_addr);
377 if ((readl(test_addr) == PATTERN) &&
378 (readl(CONFIG_SYS_SDRAM_BASE) == 0))
379 break;
380 }
381 if (row == 12) {
382 printascii("row error");
383 return -1;
384 }
385
386 cap_info->cs0_row = row;
387
388 return 0;
389 }
390
sdram_detect_row_3_4(struct sdram_cap_info * cap_info,u32 coltmp,u32 bktmp)391 int sdram_detect_row_3_4(struct sdram_cap_info *cap_info,
392 u32 coltmp, u32 bktmp)
393 {
394 u32 row_3_4;
395 u32 bw = cap_info->bw;
396 u32 row = cap_info->cs0_row;
397 void __iomem *test_addr, *test_addr1;
398
399 test_addr = CONFIG_SYS_SDRAM_BASE;
400 test_addr1 = (void __iomem *)(CONFIG_SYS_SDRAM_BASE +
401 (0x3ul << (row + bktmp + coltmp + bw - 1ul - 1ul)));
402
403 writel(0, test_addr);
404 writel(PATTERN, test_addr1);
405 if ((readl(test_addr) == 0) && (readl(test_addr1) == PATTERN))
406 row_3_4 = 0;
407 else
408 row_3_4 = 1;
409
410 cap_info->row_3_4 = row_3_4;
411
412 return 0;
413 }
414
sdram_detect_high_row(struct sdram_cap_info * cap_info,u32 dramtype)415 int sdram_detect_high_row(struct sdram_cap_info *cap_info, u32 dramtype)
416 {
417 unsigned long base_addr;
418 u32 cs0_high_row, cs1_high_row, cs;
419 u64 cap = 0, cs0_cap = 0;
420 u32 i;
421 void __iomem *test_addr, *test_addr1;
422 #ifdef CONFIG_ROCKCHIP_RK3568
423 u32 cs2_high_row, cs3_high_row;
424 #endif
425
426 cs = cap_info->rank;
427 /* 8bit bandwidth no enable axi split*/
428 if (!cap_info->bw) {
429 cs0_high_row = cap_info->cs0_row;
430 cs1_high_row = cap_info->cs1_row;
431 #ifdef CONFIG_ROCKCHIP_RK3568
432 if (cs > 2) {
433 cs2_high_row = cap_info->cs2_row;
434 cs3_high_row = cap_info->cs3_row;
435 }
436 #endif
437 goto out;
438 }
439 #ifdef CONFIG_ROCKCHIP_RK3568
440 if (cs > 2) {
441 cs0_high_row = cap_info->cs0_row;
442 cs1_high_row = cap_info->cs1_row;
443 cs2_high_row = cap_info->cs2_row;
444 cs3_high_row = cap_info->cs3_row;
445
446 goto out;
447 }
448 #endif
449
450 cs0_cap = sdram_get_cs_cap(cap_info, 0, dramtype);
451 if (cs == 2) {
452 base_addr = CONFIG_SYS_SDRAM_BASE + cs0_cap;
453 cap = sdram_get_cs_cap(cap_info, 1, dramtype);
454 } else {
455 base_addr = CONFIG_SYS_SDRAM_BASE;
456 cap = cs0_cap;
457 }
458 /* detect full bandwidth size */
459 for (i = 0; i < 4; i++) {
460 test_addr = (void __iomem *)base_addr;
461 test_addr1 = (void __iomem *)(base_addr +
462 (unsigned long)(cap / (1ul << (i + 1))));
463 writel(0x0, test_addr);
464 writel(PATTERN, test_addr1);
465 if ((readl(test_addr) == 0x0) &&
466 (readl(test_addr1) == PATTERN))
467 break;
468 }
469 if (i == 4 && cs == 1) {
470 printascii("can't support this cap\n");
471 return -1;
472 }
473
474 if (cs == 2) {
475 cs0_high_row = cap_info->cs0_row;
476 if (i == 4)
477 cs1_high_row = 0;
478 else
479 cs1_high_row = cap_info->cs1_row - i;
480 } else {
481 cs0_high_row = cap_info->cs0_row - i;
482 cs1_high_row = 0;
483 }
484
485 out:
486 cap_info->cs0_high16bit_row = cs0_high_row;
487 cap_info->cs1_high16bit_row = cs1_high_row;
488 #ifdef CONFIG_ROCKCHIP_RK3568
489 if (cs > 2) {
490 cap_info->cs2_high16bit_row = cs2_high_row;
491 cap_info->cs3_high16bit_row = cs3_high_row;
492 }
493 #endif
494
495 return 0;
496 }
497
sdram_detect_cs1_row(struct sdram_cap_info * cap_info,u32 dram_type)498 int sdram_detect_cs1_row(struct sdram_cap_info *cap_info, u32 dram_type)
499 {
500 void __iomem *test_addr;
501 u32 row = 0, bktmp, coltmp, bw;
502 ulong cs0_cap;
503 u32 byte_mask;
504
505 if (cap_info->rank == 2) {
506 cs0_cap = sdram_get_cs_cap(cap_info, 0, dram_type);
507
508 if (dram_type == DDR4) {
509 if (cap_info->dbw == 0)
510 bktmp = cap_info->bk + 2;
511 else
512 bktmp = cap_info->bk + 1;
513 } else {
514 bktmp = cap_info->bk;
515 }
516 bw = cap_info->bw;
517 coltmp = cap_info->col;
518
519 /*
520 * because px30 support axi split,min bandwidth
521 * is 8bit. if cs0 is 32bit, cs1 may 32bit or 16bit
522 * so we check low 16bit data when detect cs1 row.
523 * if cs0 is 16bit/8bit, we check low 8bit data.
524 */
525 if (bw == 2)
526 byte_mask = 0xFFFF;
527 else
528 byte_mask = 0xFF;
529
530 /* detect cs1 row */
531 for (row = cap_info->cs0_row; row > 12; row--) {
532 test_addr = (void __iomem *)(CONFIG_SYS_SDRAM_BASE +
533 cs0_cap +
534 (1ul << (row + bktmp + coltmp + bw - 1ul)));
535 writel(0, CONFIG_SYS_SDRAM_BASE + cs0_cap);
536 writel(PATTERN, test_addr);
537
538 if (((readl(test_addr) & byte_mask) ==
539 (PATTERN & byte_mask)) &&
540 ((readl(CONFIG_SYS_SDRAM_BASE + cs0_cap) &
541 byte_mask) == 0)) {
542 break;
543 }
544 }
545 }
546
547 cap_info->cs1_row = row;
548
549 return 0;
550 }
551
552