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