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