xref: /rk3399_rockchip-uboot/drivers/ram/rockchip/sdram_common.c (revision 1a6462e18b332d3d7224ca63f04699cdae79be46)
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 int sdram_detect_bw(struct sdram_cap_info *cap_info)
182 {
183 	return 0;
184 }
185 
186 int sdram_detect_cs(struct sdram_cap_info *cap_info)
187 {
188 	return 0;
189 }
190 
191 int sdram_detect_col(struct sdram_cap_info *cap_info,
192 		     u32 coltmp)
193 {
194 	void __iomem *test_addr;
195 	u32 col;
196 	u32 bw = cap_info->bw;
197 
198 	for (col = coltmp; col >= 9; col -= 1) {
199 		writel(0, CONFIG_SYS_SDRAM_BASE);
200 		test_addr = (void __iomem *)(CONFIG_SYS_SDRAM_BASE +
201 				(1ul << (col + bw - 1ul)));
202 		writel(PATTERN, test_addr);
203 		if ((readl(test_addr) == PATTERN) &&
204 		    (readl(CONFIG_SYS_SDRAM_BASE) == 0))
205 			break;
206 	}
207 	if (col == 8) {
208 		printascii("col error\n");
209 		return -1;
210 	}
211 
212 	cap_info->col = col;
213 
214 	return 0;
215 }
216 
217 int sdram_detect_bank(struct sdram_cap_info *cap_info,
218 		      u32 coltmp, u32 bktmp)
219 {
220 	void __iomem *test_addr;
221 	u32 bk;
222 	u32 bw = cap_info->bw;
223 
224 	test_addr = (void __iomem *)(CONFIG_SYS_SDRAM_BASE +
225 			(1ul << (coltmp + bktmp + bw - 1ul)));
226 	writel(0, CONFIG_SYS_SDRAM_BASE);
227 	writel(PATTERN, test_addr);
228 	if ((readl(test_addr) == PATTERN) &&
229 	    (readl(CONFIG_SYS_SDRAM_BASE) == 0))
230 		bk = 3;
231 	else
232 		bk = 2;
233 
234 	cap_info->bk = bk;
235 
236 	return 0;
237 }
238 
239 /* detect bg for ddr4 */
240 int sdram_detect_bg(struct sdram_cap_info *cap_info,
241 		    u32 coltmp)
242 {
243 	void __iomem *test_addr;
244 	u32 dbw;
245 	u32 bw = cap_info->bw;
246 
247 	test_addr = (void __iomem *)(CONFIG_SYS_SDRAM_BASE +
248 			(1ul << (coltmp + bw + 1ul)));
249 	writel(0, CONFIG_SYS_SDRAM_BASE);
250 	writel(PATTERN, test_addr);
251 	if ((readl(test_addr) == PATTERN) &&
252 	    (readl(CONFIG_SYS_SDRAM_BASE) == 0))
253 		dbw = 0;
254 	else
255 		dbw = 1;
256 
257 	cap_info->dbw = dbw;
258 
259 	return 0;
260 }
261 
262 /* detect dbw for ddr3,lpddr2,lpddr3,lpddr4 */
263 int sdram_detect_dbw(struct sdram_cap_info *cap_info, u32 dram_type)
264 {
265 	u32 row, col, bk, bw, cs_cap, cs;
266 	u32 die_bw_0 = 0, die_bw_1 = 0;
267 
268 	if (dram_type == DDR3 || dram_type == LPDDR4) {
269 		cap_info->dbw = 1;
270 	} else if (dram_type == LPDDR3 || dram_type == LPDDR2) {
271 		row = cap_info->cs0_row;
272 		col = cap_info->col;
273 		bk = cap_info->bk;
274 		cs = cap_info->rank;
275 		bw = cap_info->bw;
276 		cs_cap = (1 << (row + col + bk + bw - 20));
277 		if (bw == 2) {
278 			if (cs_cap <= 0x2000000) /* 256Mb */
279 				die_bw_0 = (col < 9) ? 2 : 1;
280 			else if (cs_cap <= 0x10000000) /* 2Gb */
281 				die_bw_0 = (col < 10) ? 2 : 1;
282 			else if (cs_cap <= 0x40000000) /* 8Gb */
283 				die_bw_0 = (col < 11) ? 2 : 1;
284 			else
285 				die_bw_0 = (col < 12) ? 2 : 1;
286 			if (cs > 1) {
287 				row = cap_info->cs1_row;
288 				cs_cap = (1 << (row + col + bk + bw - 20));
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 			}
298 		} else {
299 			die_bw_1 = 1;
300 			die_bw_0 = 1;
301 		}
302 		cap_info->dbw = (die_bw_0 > die_bw_1) ? die_bw_0 : die_bw_1;
303 	}
304 
305 	return 0;
306 }
307 
308 int sdram_detect_row(struct sdram_cap_info *cap_info,
309 		     u32 coltmp, u32 bktmp, u32 rowtmp)
310 {
311 	u32 row;
312 	u32 bw = cap_info->bw;
313 	void __iomem *test_addr;
314 
315 	for (row = rowtmp; row > 12; row--) {
316 		writel(0, CONFIG_SYS_SDRAM_BASE);
317 		test_addr = (void __iomem *)(CONFIG_SYS_SDRAM_BASE +
318 				(1ul << (row + bktmp + coltmp + bw - 1ul)));
319 		writel(PATTERN, test_addr);
320 		if ((readl(test_addr) == PATTERN) &&
321 		    (readl(CONFIG_SYS_SDRAM_BASE) == 0))
322 			break;
323 	}
324 	if (row == 12) {
325 		printascii("row error");
326 		return -1;
327 	}
328 
329 	cap_info->cs0_row = row;
330 
331 	return 0;
332 }
333 
334 int sdram_detect_row_3_4(struct sdram_cap_info *cap_info,
335 			 u32 coltmp, u32 bktmp)
336 {
337 	u32 row_3_4;
338 	u32 bw = cap_info->bw;
339 	u32 row = cap_info->cs0_row;
340 	void __iomem *test_addr, *test_addr1;
341 
342 	test_addr = CONFIG_SYS_SDRAM_BASE;
343 	test_addr1 = (void __iomem *)(CONFIG_SYS_SDRAM_BASE +
344 			(0x3ul << (row + bktmp + coltmp + bw - 1ul - 1ul)));
345 
346 	writel(0, test_addr);
347 	writel(PATTERN, test_addr1);
348 	if ((readl(test_addr) == 0) && (readl(test_addr1) == PATTERN))
349 		row_3_4 = 0;
350 	else
351 		row_3_4 = 1;
352 
353 	cap_info->row_3_4 = row_3_4;
354 
355 	return 0;
356 }
357 
358 int sdram_detect_high_row(struct sdram_cap_info *cap_info)
359 {
360 	cap_info->cs0_high16bit_row = cap_info->cs0_row;
361 	cap_info->cs1_high16bit_row = cap_info->cs1_row;
362 
363 	return 0;
364 }
365 
366 int sdram_detect_cs1_row(struct sdram_cap_info *cap_info, u32 dram_type)
367 {
368 	void __iomem *test_addr;
369 	u32 row = 0, bktmp, coltmp, bw;
370 	ulong cs0_cap;
371 	u32 byte_mask;
372 
373 	if (cap_info->rank == 2) {
374 		cs0_cap = sdram_get_cs_cap(cap_info, 0, dram_type);
375 
376 		if (dram_type == DDR4) {
377 			if (cap_info->dbw == 0)
378 				bktmp = cap_info->bk + 2;
379 			else
380 				bktmp = cap_info->bk + 1;
381 		} else {
382 			bktmp = cap_info->bk;
383 		}
384 		bw = cap_info->bw;
385 		coltmp = cap_info->col;
386 
387 		/*
388 		 * because px30 support axi split,min bandwidth
389 		 * is 8bit. if cs0 is 32bit, cs1 may 32bit or 16bit
390 		 * so we check low 16bit data when detect cs1 row.
391 		 * if cs0 is 16bit/8bit, we check low 8bit data.
392 		 */
393 		if (bw == 2)
394 			byte_mask = 0xFFFF;
395 		else
396 			byte_mask = 0xFF;
397 
398 		/* detect cs1 row */
399 		for (row = cap_info->cs0_row; row > 12; row--) {
400 			test_addr = (void __iomem *)(CONFIG_SYS_SDRAM_BASE +
401 				    cs0_cap +
402 				    (1ul << (row + bktmp + coltmp + bw - 1ul)));
403 			writel(0, CONFIG_SYS_SDRAM_BASE + cs0_cap);
404 			writel(PATTERN, test_addr);
405 
406 			if (((readl(test_addr) & byte_mask) ==
407 			     (PATTERN & byte_mask)) &&
408 			    ((readl(CONFIG_SYS_SDRAM_BASE + cs0_cap) &
409 			      byte_mask) == 0)) {
410 				break;
411 			}
412 		}
413 	}
414 
415 	cap_info->cs1_row = row;
416 
417 	return 0;
418 }
419 
420