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