xref: /rk3399_rockchip-uboot/drivers/ram/rockchip/sdram_common.c (revision c7de5349c9abcd4e28cc34f9eb02efdc19b877b3)
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 
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 
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 		printascii(" CS3 Row=");
84 		printdec(cap_info->cs3_row);
85 	}
86 	printascii(" CS=");
87 	printdec(cap_info->rank);
88 	printascii(" Die BW=");
89 	printdec(8 << cap_info->dbw);
90 
91 	cap = sdram_get_cs_cap(cap_info, 3, base->dramtype);
92 	if (cap_info->row_3_4)
93 		cap = cap * 3 / 4;
94 	else if (split)
95 		cap = cap / 2 + (split << 24) / 2;
96 
97 	printascii(" Size=");
98 	printdec(cap >> 20);
99 	printascii("MB\n");
100 }
101 
102 /*
103  * cs: 0:cs0
104  *	   1:cs1
105  *     else cs0+cs1
106  * note: it didn't consider about row_3_4
107  */
108 u64 sdram_get_cs_cap(struct sdram_cap_info *cap_info, u32 cs, u32 dram_type)
109 {
110 	u32 bg;
111 	u64 cap[4];
112 
113 	if (dram_type == DDR4)
114 		/* DDR4 8bit dram BG = 2(4bank groups),
115 		 * 16bit dram BG = 1 (2 bank groups)
116 		 */
117 		bg = (cap_info->dbw == 0) ? 2 : 1;
118 	else
119 		bg = 0;
120 	cap[0] = 1llu << (cap_info->bw + cap_info->col +
121 		bg + cap_info->bk + cap_info->cs0_row);
122 
123 	if (cap_info->rank >= 2)
124 		cap[1] = 1llu << (cap_info->bw + cap_info->col +
125 			bg + cap_info->bk + cap_info->cs1_row);
126 	else
127 		cap[1] = 0;
128 
129 	if (cap_info->rank == 4) {
130 		cap[2] = 1llu << (cap_info->bw + cap_info->col +
131 			bg + cap_info->bk + cap_info->cs2_row);
132 		cap[3] = 1llu << (cap_info->bw + cap_info->col +
133 			bg + cap_info->bk + cap_info->cs3_row);
134 	} else {
135 		cap[2] = 0;
136 		cap[3] = 0;
137 	}
138 	if (cs == 0)
139 		return cap[0];
140 	else if (cs == 1)
141 		return cap[1];
142 	else
143 		return (cap[0] + cap[1] + cap[2] + cap[3]);
144 }
145 
146 /* n: Unit bytes */
147 void sdram_copy_to_reg(u32 *dest, const u32 *src, u32 n)
148 {
149 	int i;
150 
151 	for (i = 0; i < n / sizeof(u32); i++) {
152 		writel(*src, dest);
153 		src++;
154 		dest++;
155 	}
156 }
157 
158 void sdram_org_config(struct sdram_cap_info *cap_info,
159 		      struct sdram_base_params *base,
160 		      u32 *p_os_reg2, u32 *p_os_reg3, u32 channel)
161 {
162 	*p_os_reg2 |= SYS_REG_ENC_DDRTYPE(base->dramtype);
163 	*p_os_reg2 |= SYS_REG_ENC_NUM_CH(base->num_channels);
164 
165 	*p_os_reg2 |= SYS_REG_ENC_ROW_3_4(cap_info->row_3_4, channel);
166 	*p_os_reg2 |= SYS_REG_ENC_CHINFO(channel);
167 	*p_os_reg2 |= SYS_REG_ENC_RANK(cap_info->rank, channel);
168 	*p_os_reg2 |= SYS_REG_ENC_COL(cap_info->col, channel);
169 	*p_os_reg2 |= SYS_REG_ENC_BK(cap_info->bk, channel);
170 	*p_os_reg2 |= SYS_REG_ENC_BW(cap_info->bw, channel);
171 	*p_os_reg2 |= SYS_REG_ENC_DBW(cap_info->dbw, channel);
172 
173 	SYS_REG_ENC_CS0_ROW(cap_info->cs0_row, *p_os_reg2, *p_os_reg3, channel);
174 	if (cap_info->cs1_row)
175 		SYS_REG_ENC_CS1_ROW(cap_info->cs1_row, *p_os_reg2,
176 				    *p_os_reg3, channel);
177 	*p_os_reg3 |= SYS_REG_ENC_CS1_COL(cap_info->col, channel);
178 	*p_os_reg3 |= SYS_REG_ENC_VERSION(DDR_SYS_REG_VERSION);
179 }
180 
181 void sdram_org_config_v3(struct sdram_cap_info *cap_info,
182 			 struct sdram_base_params *base,
183 			 u32 *p_os_reg2, u32 *p_os_reg3, u32 channel)
184 {
185 	SYS_REG_ENC_DDRTYPE_V3(base->dramtype, *p_os_reg2, *p_os_reg3);
186 
187 	*p_os_reg2 |= SYS_REG_ENC_NUM_CH_V3((base->num_channels > 2) ?
188 					    2 : base->num_channels);
189 
190 	*p_os_reg2 |= SYS_REG_ENC_ROW_3_4_V3(cap_info->row_3_4, channel);
191 	*p_os_reg2 |= SYS_REG_ENC_CHINFO_V3((channel >= 2) ? channel - 2 : channel);
192 	if (channel == 0 || channel == 2)
193 		SYS_REG_ENC_CH0_2_RANK_V3(cap_info->rank,
194 					  *p_os_reg2, *p_os_reg3);
195 	else
196 		*p_os_reg2 |= SYS_REG_ENC_CH1_3_RANK(cap_info->rank);
197 
198 	*p_os_reg2 |= SYS_REG_ENC_COL_V3(cap_info->col, channel);
199 	*p_os_reg2 |= SYS_REG_ENC_BK_V3(cap_info->bk, channel);
200 	*p_os_reg2 |= SYS_REG_ENC_BW_V3(cap_info->bw, channel);
201 	*p_os_reg2 |= SYS_REG_ENC_DBW_V3(cap_info->dbw, channel);
202 
203 	SYS_REG_ENC_CS0_ROW_V3(cap_info->cs0_row, *p_os_reg2, *p_os_reg3, channel);
204 	if (cap_info->cs1_row)
205 		SYS_REG_ENC_CS1_ROW_V3(cap_info->cs1_row, *p_os_reg2,
206 				       *p_os_reg3, channel);
207 	if ((channel == 0 || channel == 2) && cap_info->rank > 2) {
208 		if (cap_info->cs2_row == cap_info->cs0_row)
209 			*p_os_reg3 |= SYS_REG_ENC_CS2_DELTA_ROW_V3(0);
210 		else
211 			*p_os_reg3 |= SYS_REG_ENC_CS2_DELTA_ROW_V3(1);
212 
213 		if (cap_info->cs3_row == cap_info->cs0_row)
214 			*p_os_reg3 |= SYS_REG_ENC_CS3_DELTA_ROW_V3(0);
215 		else
216 			*p_os_reg3 |= SYS_REG_ENC_CS3_DELTA_ROW_V3(1);
217 	}
218 
219 	*p_os_reg3 |= SYS_REG_ENC_CS1_COL_V3(cap_info->col, channel);
220 	*p_os_reg3 |= SYS_REG_ENC_VERSION(DDR_SYS_REG_VERSION_3);
221 }
222 
223 int sdram_detect_bw(struct sdram_cap_info *cap_info)
224 {
225 	return 0;
226 }
227 
228 int sdram_detect_cs(struct sdram_cap_info *cap_info)
229 {
230 	return 0;
231 }
232 
233 int sdram_detect_col(struct sdram_cap_info *cap_info,
234 		     u32 coltmp)
235 {
236 	void __iomem *test_addr;
237 	u32 col;
238 	u32 bw = cap_info->bw;
239 
240 	for (col = coltmp; col >= 9; col -= 1) {
241 		writel(0, CONFIG_SYS_SDRAM_BASE);
242 		test_addr = (void __iomem *)(CONFIG_SYS_SDRAM_BASE +
243 				(1ul << (col + bw - 1ul)));
244 		writel(PATTERN, test_addr);
245 		if ((readl(test_addr) == PATTERN) &&
246 		    (readl(CONFIG_SYS_SDRAM_BASE) == 0))
247 			break;
248 	}
249 	if (col == 8) {
250 		printascii("col error\n");
251 		return -1;
252 	}
253 
254 	cap_info->col = col;
255 
256 	return 0;
257 }
258 
259 int sdram_detect_bank(struct sdram_cap_info *cap_info,
260 		      u32 coltmp, u32 bktmp)
261 {
262 	void __iomem *test_addr;
263 	u32 bk;
264 	u32 bw = cap_info->bw;
265 
266 	test_addr = (void __iomem *)(CONFIG_SYS_SDRAM_BASE +
267 			(1ul << (coltmp + bktmp + bw - 1ul)));
268 	writel(0, CONFIG_SYS_SDRAM_BASE);
269 	writel(PATTERN, test_addr);
270 	if ((readl(test_addr) == PATTERN) &&
271 	    (readl(CONFIG_SYS_SDRAM_BASE) == 0))
272 		bk = 3;
273 	else
274 		bk = 2;
275 
276 	cap_info->bk = bk;
277 
278 	return 0;
279 }
280 
281 /* detect bg for ddr4 */
282 int sdram_detect_bg(struct sdram_cap_info *cap_info,
283 		    u32 coltmp)
284 {
285 	void __iomem *test_addr;
286 	u32 dbw;
287 	u32 bw = cap_info->bw;
288 
289 	test_addr = (void __iomem *)(CONFIG_SYS_SDRAM_BASE +
290 			(1ul << (coltmp + bw + 1ul)));
291 	writel(0, CONFIG_SYS_SDRAM_BASE);
292 	writel(PATTERN, test_addr);
293 	if ((readl(test_addr) == PATTERN) &&
294 	    (readl(CONFIG_SYS_SDRAM_BASE) == 0))
295 		dbw = 0;
296 	else
297 		dbw = 1;
298 
299 	cap_info->dbw = dbw;
300 
301 	return 0;
302 }
303 
304 /* detect dbw for ddr3,lpddr2,lpddr3,lpddr4 */
305 int sdram_detect_dbw(struct sdram_cap_info *cap_info, u32 dram_type)
306 {
307 	u32 row, col, bk, bw, cs_cap, cs;
308 	u32 die_bw_0 = 0, die_bw_1 = 0;
309 
310 	if (dram_type == DDR3) {
311 		if (cap_info->bw == 0)
312 			cap_info->dbw = 0;
313 		else
314 			cap_info->dbw = 1;
315 	} else if (dram_type == LPDDR4) {
316 		cap_info->dbw = 1;
317 	} else if (dram_type == LPDDR3 || dram_type == LPDDR2) {
318 		row = cap_info->cs0_row;
319 		col = cap_info->col;
320 		bk = cap_info->bk;
321 		cs = cap_info->rank;
322 		bw = cap_info->bw;
323 		cs_cap = (1 << (row + col + bk + bw - 20));
324 		if (bw == 2) {
325 			if (cs_cap <= 0x2000000) /* 256Mb */
326 				die_bw_0 = (col < 9) ? 2 : 1;
327 			else if (cs_cap <= 0x10000000) /* 2Gb */
328 				die_bw_0 = (col < 10) ? 2 : 1;
329 			else if (cs_cap <= 0x40000000) /* 8Gb */
330 				die_bw_0 = (col < 11) ? 2 : 1;
331 			else
332 				die_bw_0 = (col < 12) ? 2 : 1;
333 			if (cs > 1) {
334 				row = cap_info->cs1_row;
335 				cs_cap = (1 << (row + col + bk + bw - 20));
336 				if (cs_cap <= 0x2000000) /* 256Mb */
337 					die_bw_0 = (col < 9) ? 2 : 1;
338 				else if (cs_cap <= 0x10000000) /* 2Gb */
339 					die_bw_0 = (col < 10) ? 2 : 1;
340 				else if (cs_cap <= 0x40000000) /* 8Gb */
341 					die_bw_0 = (col < 11) ? 2 : 1;
342 				else
343 					die_bw_0 = (col < 12) ? 2 : 1;
344 			}
345 		} else {
346 			die_bw_1 = 1;
347 			die_bw_0 = 1;
348 		}
349 		cap_info->dbw = (die_bw_0 > die_bw_1) ? die_bw_0 : die_bw_1;
350 	}
351 
352 	return 0;
353 }
354 
355 int sdram_detect_row(struct sdram_cap_info *cap_info,
356 		     u32 coltmp, u32 bktmp, u32 rowtmp)
357 {
358 	u32 row;
359 	u32 bw = cap_info->bw;
360 	void __iomem *test_addr;
361 
362 	for (row = rowtmp; row > 12; row--) {
363 		writel(0, CONFIG_SYS_SDRAM_BASE);
364 		test_addr = (void __iomem *)(CONFIG_SYS_SDRAM_BASE +
365 				(1ul << (row + bktmp + coltmp + bw - 1ul)));
366 		writel(PATTERN, test_addr);
367 		if ((readl(test_addr) == PATTERN) &&
368 		    (readl(CONFIG_SYS_SDRAM_BASE) == 0))
369 			break;
370 	}
371 	if (row == 12) {
372 		printascii("row error");
373 		return -1;
374 	}
375 
376 	cap_info->cs0_row = row;
377 
378 	return 0;
379 }
380 
381 int sdram_detect_row_3_4(struct sdram_cap_info *cap_info,
382 			 u32 coltmp, u32 bktmp)
383 {
384 	u32 row_3_4;
385 	u32 bw = cap_info->bw;
386 	u32 row = cap_info->cs0_row;
387 	void __iomem *test_addr, *test_addr1;
388 
389 	test_addr = CONFIG_SYS_SDRAM_BASE;
390 	test_addr1 = (void __iomem *)(CONFIG_SYS_SDRAM_BASE +
391 			(0x3ul << (row + bktmp + coltmp + bw - 1ul - 1ul)));
392 
393 	writel(0, test_addr);
394 	writel(PATTERN, test_addr1);
395 	if ((readl(test_addr) == 0) && (readl(test_addr1) == PATTERN))
396 		row_3_4 = 0;
397 	else
398 		row_3_4 = 1;
399 
400 	cap_info->row_3_4 = row_3_4;
401 
402 	return 0;
403 }
404 
405 int sdram_detect_high_row(struct sdram_cap_info *cap_info)
406 {
407 	cap_info->cs0_high16bit_row = cap_info->cs0_row;
408 	cap_info->cs1_high16bit_row = cap_info->cs1_row;
409 
410 	return 0;
411 }
412 
413 int sdram_detect_cs1_row(struct sdram_cap_info *cap_info, u32 dram_type)
414 {
415 	void __iomem *test_addr;
416 	u32 row = 0, bktmp, coltmp, bw;
417 	ulong cs0_cap;
418 	u32 byte_mask;
419 
420 	if (cap_info->rank == 2) {
421 		cs0_cap = sdram_get_cs_cap(cap_info, 0, dram_type);
422 
423 		if (dram_type == DDR4) {
424 			if (cap_info->dbw == 0)
425 				bktmp = cap_info->bk + 2;
426 			else
427 				bktmp = cap_info->bk + 1;
428 		} else {
429 			bktmp = cap_info->bk;
430 		}
431 		bw = cap_info->bw;
432 		coltmp = cap_info->col;
433 
434 		/*
435 		 * because px30 support axi split,min bandwidth
436 		 * is 8bit. if cs0 is 32bit, cs1 may 32bit or 16bit
437 		 * so we check low 16bit data when detect cs1 row.
438 		 * if cs0 is 16bit/8bit, we check low 8bit data.
439 		 */
440 		if (bw == 2)
441 			byte_mask = 0xFFFF;
442 		else
443 			byte_mask = 0xFF;
444 
445 		/* detect cs1 row */
446 		for (row = cap_info->cs0_row; row > 12; row--) {
447 			test_addr = (void __iomem *)(CONFIG_SYS_SDRAM_BASE +
448 				    cs0_cap +
449 				    (1ul << (row + bktmp + coltmp + bw - 1ul)));
450 			writel(0, CONFIG_SYS_SDRAM_BASE + cs0_cap);
451 			writel(PATTERN, test_addr);
452 
453 			if (((readl(test_addr) & byte_mask) ==
454 			     (PATTERN & byte_mask)) &&
455 			    ((readl(CONFIG_SYS_SDRAM_BASE + cs0_cap) &
456 			      byte_mask) == 0)) {
457 				break;
458 			}
459 		}
460 	}
461 
462 	cap_info->cs1_row = row;
463 
464 	return 0;
465 }
466 
467