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