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