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