1 // SPDX-License-Identifier: GPL-2.0
3 * (C) Copyright 2018 Rockchip Electronics Co., Ltd.
7 #include <debug_uart.h>
10 #include <asm/arch-rockchip/sdram.h>
11 #include <asm/arch-rockchip/sdram_common.h>
13 #ifdef CONFIG_RAM_ROCKCHIP_DEBUG
14 void sdram_print_dram_type(unsigned char dramtype)
33 printascii("Unknown Device");
38 void sdram_print_ddr_info(struct sdram_cap_info *cap_info,
39 struct sdram_base_params *base)
44 bg = (cap_info->dbw == 0) ? 2 : 1;
46 sdram_print_dram_type(base->dramtype);
49 printdec(base->ddr_freq);
53 printdec(8 << cap_info->bw);
55 printdec(cap_info->col);
57 printdec(0x1 << cap_info->bk);
58 if (base->dramtype == DDR4) {
62 printascii(" CS0 Row=");
63 printdec(cap_info->cs0_row);
64 if (cap_info->cs0_high16bit_row !=
67 printdec(cap_info->cs0_high16bit_row);
69 if (cap_info->rank > 1) {
70 printascii(" CS1 Row=");
71 printdec(cap_info->cs1_row);
72 if (cap_info->cs1_high16bit_row !=
75 printdec(cap_info->cs1_high16bit_row);
79 printdec(cap_info->rank);
80 printascii(" Die BW=");
81 printdec(8 << cap_info->dbw);
83 cap = sdram_get_cs_cap(cap_info, 3, base->dramtype);
84 if (cap_info->row_3_4)
92 void sdram_print_stride(unsigned int stride)
96 printf("128B stride\n");
103 printf("256B stride\n");
108 printf("512B stride\n");
111 printf("4K stride\n");
114 printf("32MB + 256B stride\n");
117 printf("no stride\n");
126 * note: it didn't consider about row_3_4
128 u64 sdram_get_cs_cap(struct sdram_cap_info *cap_info, u32 cs, u32 dram_type)
133 if (dram_type == DDR4)
134 /* DDR4 8bit dram BG = 2(4bank groups),
135 * 16bit dram BG = 1 (2 bank groups)
137 bg = (cap_info->dbw == 0) ? 2 : 1;
140 cap[0] = 1llu << (cap_info->bw + cap_info->col +
141 bg + cap_info->bk + cap_info->cs0_row);
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);
154 return (cap[0] + cap[1]);
158 void sdram_copy_to_reg(u32 *dest, const u32 *src, u32 n)
162 for (i = 0; i < n / sizeof(u32); i++) {
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)
173 *p_os_reg2 |= SYS_REG_ENC_DDRTYPE(base->dramtype);
174 *p_os_reg2 |= SYS_REG_ENC_NUM_CH(base->num_channels);
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);
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);
192 int sdram_detect_bw(struct sdram_cap_info *cap_info)
197 int sdram_detect_cs(struct sdram_cap_info *cap_info)
202 int sdram_detect_col(struct sdram_cap_info *cap_info,
205 void __iomem *test_addr;
207 u32 bw = cap_info->bw;
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))
219 printascii("col error\n");
228 int sdram_detect_bank(struct sdram_cap_info *cap_info,
229 u32 coltmp, u32 bktmp)
231 void __iomem *test_addr;
233 u32 bw = cap_info->bw;
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))
250 /* detect bg for ddr4 */
251 int sdram_detect_bg(struct sdram_cap_info *cap_info,
254 void __iomem *test_addr;
256 u32 bw = cap_info->bw;
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))
273 /* detect dbw for ddr3,lpddr2,lpddr3,lpddr4 */
274 int sdram_detect_dbw(struct sdram_cap_info *cap_info, u32 dram_type)
276 u32 row, col, bk, bw, cs_cap, cs;
277 u32 die_bw_0 = 0, die_bw_1 = 0;
279 if (dram_type == DDR3 || dram_type == LPDDR4) {
281 } else if (dram_type == LPDDR3 || dram_type == LPDDR2) {
282 row = cap_info->cs0_row;
287 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;
296 die_bw_0 = (col < 12) ? 2 : 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;
307 die_bw_0 = (col < 12) ? 2 : 1;
313 cap_info->dbw = (die_bw_0 > die_bw_1) ? die_bw_0 : die_bw_1;
319 int sdram_detect_row(struct sdram_cap_info *cap_info,
320 u32 coltmp, u32 bktmp, u32 rowtmp)
323 u32 bw = cap_info->bw;
324 void __iomem *test_addr;
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))
336 printascii("row error");
340 cap_info->cs0_row = row;
345 int sdram_detect_row_3_4(struct sdram_cap_info *cap_info,
346 u32 coltmp, u32 bktmp)
349 u32 bw = cap_info->bw;
350 u32 row = cap_info->cs0_row;
351 void __iomem *test_addr, *test_addr1;
353 test_addr = CONFIG_SYS_SDRAM_BASE;
354 test_addr1 = (void __iomem *)(CONFIG_SYS_SDRAM_BASE +
355 (0x3ul << (row + bktmp + coltmp + bw - 1ul - 1ul)));
357 writel(0, test_addr);
358 writel(PATTERN, test_addr1);
359 if ((readl(test_addr) == 0) && (readl(test_addr1) == PATTERN))
364 cap_info->row_3_4 = row_3_4;
369 int sdram_detect_high_row(struct sdram_cap_info *cap_info)
371 cap_info->cs0_high16bit_row = cap_info->cs0_row;
372 cap_info->cs1_high16bit_row = cap_info->cs1_row;
377 int sdram_detect_cs1_row(struct sdram_cap_info *cap_info, u32 dram_type)
379 void __iomem *test_addr;
380 u32 row = 0, bktmp, coltmp, bw;
384 if (cap_info->rank == 2) {
385 cs0_cap = sdram_get_cs_cap(cap_info, 0, dram_type);
387 if (dram_type == DDR4) {
388 if (cap_info->dbw == 0)
389 bktmp = cap_info->bk + 2;
391 bktmp = cap_info->bk + 1;
393 bktmp = cap_info->bk;
396 coltmp = cap_info->col;
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.
410 for (row = cap_info->cs0_row; row > 12; row--) {
411 test_addr = (void __iomem *)(CONFIG_SYS_SDRAM_BASE +
413 (1ul << (row + bktmp + coltmp + bw - 1ul)));
414 writel(0, CONFIG_SYS_SDRAM_BASE + cs0_cap);
415 writel(PATTERN, test_addr);
417 if (((readl(test_addr) & byte_mask) ==
418 (PATTERN & byte_mask)) &&
419 ((readl(CONFIG_SYS_SDRAM_BASE + cs0_cap) &
426 cap_info->cs1_row = row;