blob: 6bc51572b2f1a563e43995040eb22894b186d7b1 [file] [log] [blame]
Kever Yangb5497b52019-11-15 11:04:37 +08001// 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-rockchip/sdram.h>
11#include <asm/arch-rockchip/sdram_common.h>
12
Kever Yang8e005542019-11-15 11:04:38 +080013#ifdef CONFIG_RAM_ROCKCHIP_DEBUG
14void sdram_print_dram_type(unsigned char dramtype)
15{
16 switch (dramtype) {
17 case DDR3:
18 printascii("DDR3");
19 break;
20 case DDR4:
21 printascii("DDR4");
22 break;
23 case LPDDR2:
24 printascii("LPDDR2");
25 break;
26 case LPDDR3:
27 printascii("LPDDR3");
28 break;
29 case LPDDR4:
30 printascii("LPDDR4");
31 break;
32 default:
33 printascii("Unknown Device");
34 break;
35 }
36}
37
38void sdram_print_ddr_info(struct sdram_cap_info *cap_info,
39 struct sdram_base_params *base)
40{
41 u64 cap;
42 u32 bg;
43
44 bg = (cap_info->dbw == 0) ? 2 : 1;
45
46 sdram_print_dram_type(base->dramtype);
47
48 printascii(", ");
49 printdec(base->ddr_freq);
50 printascii("MHz\n");
51
52 printascii("BW=");
53 printdec(8 << cap_info->bw);
54 printascii(" Col=");
55 printdec(cap_info->col);
56 printascii(" Bk=");
57 printdec(0x1 << cap_info->bk);
58 if (base->dramtype == DDR4) {
59 printascii(" BG=");
60 printdec(1 << bg);
61 }
62 printascii(" CS0 Row=");
63 printdec(cap_info->cs0_row);
64 if (cap_info->cs0_high16bit_row !=
65 cap_info->cs0_row) {
66 printascii("/");
67 printdec(cap_info->cs0_high16bit_row);
68 }
69 if (cap_info->rank > 1) {
70 printascii(" CS1 Row=");
71 printdec(cap_info->cs1_row);
72 if (cap_info->cs1_high16bit_row !=
73 cap_info->cs1_row) {
74 printascii("/");
75 printdec(cap_info->cs1_high16bit_row);
76 }
77 }
78 printascii(" CS=");
79 printdec(cap_info->rank);
80 printascii(" Die BW=");
81 printdec(8 << cap_info->dbw);
82
83 cap = sdram_get_cs_cap(cap_info, 3, base->dramtype);
84 if (cap_info->row_3_4)
85 cap = cap * 3 / 4;
86
87 printascii(" Size=");
88 printdec(cap >> 20);
89 printascii("MB\n");
90}
91
92void sdram_print_stride(unsigned int stride)
93{
94 switch (stride) {
95 case 0xc:
96 printf("128B stride\n");
97 break;
98 case 5:
99 case 9:
100 case 0xd:
101 case 0x11:
102 case 0x19:
103 printf("256B stride\n");
104 break;
105 case 0xa:
106 case 0xe:
107 case 0x12:
108 printf("512B stride\n");
109 break;
110 case 0xf:
111 printf("4K stride\n");
112 break;
113 case 0x1f:
114 printf("32MB + 256B stride\n");
115 break;
116 default:
117 printf("no stride\n");
118 }
119}
120#endif
121
122/*
123 * cs: 0:cs0
124 * 1:cs1
125 * else cs0+cs1
126 * note: it didn't consider about row_3_4
127 */
128u64 sdram_get_cs_cap(struct sdram_cap_info *cap_info, u32 cs, u32 dram_type)
129{
130 u32 bg;
131 u64 cap[2];
132
133 if (dram_type == DDR4)
134 /* DDR4 8bit dram BG = 2(4bank groups),
135 * 16bit dram BG = 1 (2 bank groups)
136 */
137 bg = (cap_info->dbw == 0) ? 2 : 1;
138 else
139 bg = 0;
140 cap[0] = 1llu << (cap_info->bw + cap_info->col +
141 bg + cap_info->bk + cap_info->cs0_row);
142
143 if (cap_info->rank == 2)
144 cap[1] = 1llu << (cap_info->bw + cap_info->col +
145 bg + cap_info->bk + cap_info->cs1_row);
146 else
147 cap[1] = 0;
148
149 if (cs == 0)
150 return cap[0];
151 else if (cs == 1)
152 return cap[1];
153 else
154 return (cap[0] + cap[1]);
155}
156
Kever Yangb5497b52019-11-15 11:04:37 +0800157/* n: Unit bytes */
158void sdram_copy_to_reg(u32 *dest, const u32 *src, u32 n)
159{
160 int i;
161
162 for (i = 0; i < n / sizeof(u32); i++) {
163 writel(*src, dest);
164 src++;
165 dest++;
166 }
167}
168
169void sdram_org_config(struct sdram_cap_info *cap_info,
170 struct sdram_base_params *base,
171 u32 *p_os_reg2, u32 *p_os_reg3, u32 channel)
172{
173 *p_os_reg2 |= SYS_REG_ENC_DDRTYPE(base->dramtype);
174 *p_os_reg2 |= SYS_REG_ENC_NUM_CH(base->num_channels);
175
176 *p_os_reg2 |= SYS_REG_ENC_ROW_3_4(cap_info->row_3_4, channel);
177 *p_os_reg2 |= SYS_REG_ENC_CHINFO(channel);
178 *p_os_reg2 |= SYS_REG_ENC_RANK(cap_info->rank, channel);
179 *p_os_reg2 |= SYS_REG_ENC_COL(cap_info->col, channel);
180 *p_os_reg2 |= SYS_REG_ENC_BK(cap_info->bk, channel);
181 *p_os_reg2 |= SYS_REG_ENC_BW(cap_info->bw, channel);
182 *p_os_reg2 |= SYS_REG_ENC_DBW(cap_info->dbw, channel);
183
184 SYS_REG_ENC_CS0_ROW(cap_info->cs0_row, *p_os_reg2, *p_os_reg3, channel);
185 if (cap_info->cs1_row)
186 SYS_REG_ENC_CS1_ROW(cap_info->cs1_row, *p_os_reg2,
187 *p_os_reg3, channel);
188 *p_os_reg3 |= SYS_REG_ENC_CS1_COL(cap_info->col, channel);
189 *p_os_reg3 |= SYS_REG_ENC_VERSION(DDR_SYS_REG_VERSION);
190}
191
192int sdram_detect_bw(struct sdram_cap_info *cap_info)
193{
194 return 0;
195}
196
197int sdram_detect_cs(struct sdram_cap_info *cap_info)
198{
199 return 0;
200}
201
202int sdram_detect_col(struct sdram_cap_info *cap_info,
203 u32 coltmp)
204{
205 void __iomem *test_addr;
206 u32 col;
207 u32 bw = cap_info->bw;
208
209 for (col = coltmp; col >= 9; col -= 1) {
210 writel(0, CONFIG_SYS_SDRAM_BASE);
211 test_addr = (void __iomem *)(CONFIG_SYS_SDRAM_BASE +
212 (1ul << (col + bw - 1ul)));
213 writel(PATTERN, test_addr);
214 if ((readl(test_addr) == PATTERN) &&
215 (readl(CONFIG_SYS_SDRAM_BASE) == 0))
216 break;
217 }
218 if (col == 8) {
219 printascii("col error\n");
220 return -1;
221 }
222
223 cap_info->col = col;
224
225 return 0;
226}
227
228int sdram_detect_bank(struct sdram_cap_info *cap_info,
229 u32 coltmp, u32 bktmp)
230{
231 void __iomem *test_addr;
232 u32 bk;
233 u32 bw = cap_info->bw;
234
235 test_addr = (void __iomem *)(CONFIG_SYS_SDRAM_BASE +
236 (1ul << (coltmp + bktmp + bw - 1ul)));
237 writel(0, CONFIG_SYS_SDRAM_BASE);
238 writel(PATTERN, test_addr);
239 if ((readl(test_addr) == PATTERN) &&
240 (readl(CONFIG_SYS_SDRAM_BASE) == 0))
241 bk = 3;
242 else
243 bk = 2;
244
245 cap_info->bk = bk;
246
247 return 0;
248}
249
250/* detect bg for ddr4 */
251int sdram_detect_bg(struct sdram_cap_info *cap_info,
252 u32 coltmp)
253{
254 void __iomem *test_addr;
255 u32 dbw;
256 u32 bw = cap_info->bw;
257
258 test_addr = (void __iomem *)(CONFIG_SYS_SDRAM_BASE +
259 (1ul << (coltmp + bw + 1ul)));
260 writel(0, CONFIG_SYS_SDRAM_BASE);
261 writel(PATTERN, test_addr);
262 if ((readl(test_addr) == PATTERN) &&
263 (readl(CONFIG_SYS_SDRAM_BASE) == 0))
264 dbw = 0;
265 else
266 dbw = 1;
267
268 cap_info->dbw = dbw;
269
270 return 0;
271}
272
273/* detect dbw for ddr3,lpddr2,lpddr3,lpddr4 */
274int sdram_detect_dbw(struct sdram_cap_info *cap_info, u32 dram_type)
275{
276 u32 row, col, bk, bw, cs_cap, cs;
277 u32 die_bw_0 = 0, die_bw_1 = 0;
278
279 if (dram_type == DDR3 || dram_type == LPDDR4) {
280 cap_info->dbw = 1;
281 } else if (dram_type == LPDDR3 || dram_type == LPDDR2) {
282 row = cap_info->cs0_row;
283 col = cap_info->col;
284 bk = cap_info->bk;
285 cs = cap_info->rank;
286 bw = cap_info->bw;
287 cs_cap = (1 << (row + col + bk + bw - 20));
288 if (bw == 2) {
289 if (cs_cap <= 0x2000000) /* 256Mb */
290 die_bw_0 = (col < 9) ? 2 : 1;
291 else if (cs_cap <= 0x10000000) /* 2Gb */
292 die_bw_0 = (col < 10) ? 2 : 1;
293 else if (cs_cap <= 0x40000000) /* 8Gb */
294 die_bw_0 = (col < 11) ? 2 : 1;
295 else
296 die_bw_0 = (col < 12) ? 2 : 1;
297 if (cs > 1) {
298 row = cap_info->cs1_row;
299 cs_cap = (1 << (row + col + bk + bw - 20));
300 if (cs_cap <= 0x2000000) /* 256Mb */
301 die_bw_0 = (col < 9) ? 2 : 1;
302 else if (cs_cap <= 0x10000000) /* 2Gb */
303 die_bw_0 = (col < 10) ? 2 : 1;
304 else if (cs_cap <= 0x40000000) /* 8Gb */
305 die_bw_0 = (col < 11) ? 2 : 1;
306 else
307 die_bw_0 = (col < 12) ? 2 : 1;
308 }
309 } else {
310 die_bw_1 = 1;
311 die_bw_0 = 1;
312 }
313 cap_info->dbw = (die_bw_0 > die_bw_1) ? die_bw_0 : die_bw_1;
314 }
315
316 return 0;
317}
318
319int sdram_detect_row(struct sdram_cap_info *cap_info,
320 u32 coltmp, u32 bktmp, u32 rowtmp)
321{
322 u32 row;
323 u32 bw = cap_info->bw;
324 void __iomem *test_addr;
325
326 for (row = rowtmp; row > 12; row--) {
327 writel(0, CONFIG_SYS_SDRAM_BASE);
328 test_addr = (void __iomem *)(CONFIG_SYS_SDRAM_BASE +
329 (1ul << (row + bktmp + coltmp + bw - 1ul)));
330 writel(PATTERN, test_addr);
331 if ((readl(test_addr) == PATTERN) &&
332 (readl(CONFIG_SYS_SDRAM_BASE) == 0))
333 break;
334 }
335 if (row == 12) {
336 printascii("row error");
337 return -1;
338 }
339
340 cap_info->cs0_row = row;
341
342 return 0;
343}
344
345int sdram_detect_row_3_4(struct sdram_cap_info *cap_info,
346 u32 coltmp, u32 bktmp)
347{
348 u32 row_3_4;
349 u32 bw = cap_info->bw;
350 u32 row = cap_info->cs0_row;
351 void __iomem *test_addr, *test_addr1;
352
353 test_addr = CONFIG_SYS_SDRAM_BASE;
354 test_addr1 = (void __iomem *)(CONFIG_SYS_SDRAM_BASE +
355 (0x3ul << (row + bktmp + coltmp + bw - 1ul - 1ul)));
356
357 writel(0, test_addr);
358 writel(PATTERN, test_addr1);
359 if ((readl(test_addr) == 0) && (readl(test_addr1) == PATTERN))
360 row_3_4 = 0;
361 else
362 row_3_4 = 1;
363
364 cap_info->row_3_4 = row_3_4;
365
366 return 0;
367}
368
369int sdram_detect_high_row(struct sdram_cap_info *cap_info)
370{
371 cap_info->cs0_high16bit_row = cap_info->cs0_row;
372 cap_info->cs1_high16bit_row = cap_info->cs1_row;
373
374 return 0;
375}
376
377int sdram_detect_cs1_row(struct sdram_cap_info *cap_info, u32 dram_type)
378{
379 void __iomem *test_addr;
380 u32 row = 0, bktmp, coltmp, bw;
381 ulong cs0_cap;
382 u32 byte_mask;
383
384 if (cap_info->rank == 2) {
385 cs0_cap = sdram_get_cs_cap(cap_info, 0, dram_type);
386
387 if (dram_type == DDR4) {
388 if (cap_info->dbw == 0)
389 bktmp = cap_info->bk + 2;
390 else
391 bktmp = cap_info->bk + 1;
392 } else {
393 bktmp = cap_info->bk;
394 }
395 bw = cap_info->bw;
396 coltmp = cap_info->col;
397
398 /*
399 * because px30 support axi split,min bandwidth
400 * is 8bit. if cs0 is 32bit, cs1 may 32bit or 16bit
401 * so we check low 16bit data when detect cs1 row.
402 * if cs0 is 16bit/8bit, we check low 8bit data.
403 */
404 if (bw == 2)
405 byte_mask = 0xFFFF;
406 else
407 byte_mask = 0xFF;
408
409 /* detect cs1 row */
410 for (row = cap_info->cs0_row; row > 12; row--) {
411 test_addr = (void __iomem *)(CONFIG_SYS_SDRAM_BASE +
412 cs0_cap +
413 (1ul << (row + bktmp + coltmp + bw - 1ul)));
414 writel(0, CONFIG_SYS_SDRAM_BASE + cs0_cap);
415 writel(PATTERN, test_addr);
416
417 if (((readl(test_addr) & byte_mask) ==
418 (PATTERN & byte_mask)) &&
419 ((readl(CONFIG_SYS_SDRAM_BASE + cs0_cap) &
420 byte_mask) == 0)) {
421 break;
422 }
423 }
424 }
425
426 cap_info->cs1_row = row;
427
428 return 0;
429}