1 // SPDX-License-Identifier: GPL-2.0 2 /* 3 * Copyright (C) Marvell International Ltd. and its affiliates 4 */ 5 6 #include <common.h> 7 #include <spl.h> 8 #include <asm/io.h> 9 #include <asm/arch/cpu.h> 10 #include <asm/arch/soc.h> 11 12 #include "ddr3_init.h" 13 14 /* List of allowed frequency listed in order of enum hws_ddr_freq */ 15 u32 freq_val[DDR_FREQ_LIMIT] = { 16 0, /*DDR_FREQ_LOW_FREQ */ 17 400, /*DDR_FREQ_400, */ 18 533, /*DDR_FREQ_533, */ 19 666, /*DDR_FREQ_667, */ 20 800, /*DDR_FREQ_800, */ 21 933, /*DDR_FREQ_933, */ 22 1066, /*DDR_FREQ_1066, */ 23 311, /*DDR_FREQ_311, */ 24 333, /*DDR_FREQ_333, */ 25 467, /*DDR_FREQ_467, */ 26 850, /*DDR_FREQ_850, */ 27 600, /*DDR_FREQ_600 */ 28 300, /*DDR_FREQ_300 */ 29 900, /*DDR_FREQ_900 */ 30 360, /*DDR_FREQ_360 */ 31 1000 /*DDR_FREQ_1000 */ 32 }; 33 34 /* Table for CL values per frequency for each speed bin index */ 35 struct cl_val_per_freq cas_latency_table[] = { 36 /* 37 * 400M 667M 933M 311M 467M 600M 360 38 * 100M 533M 800M 1066M 333M 850M 900 39 * 1000 (the order is 100, 400, 533 etc.) 40 */ 41 /* DDR3-800D */ 42 { {6, 5, 0, 0, 0, 0, 0, 5, 5, 0, 0, 0, 5, 0, 5, 0} }, 43 /* DDR3-800E */ 44 { {6, 6, 0, 0, 0, 0, 0, 6, 6, 0, 0, 0, 6, 0, 6, 0} }, 45 /* DDR3-1066E */ 46 { {6, 5, 6, 0, 0, 0, 0, 5, 5, 6, 0, 0, 5, 0, 5, 0} }, 47 /* DDR3-1066F */ 48 { {6, 6, 7, 0, 0, 0, 0, 6, 6, 7, 0, 0, 6, 0, 6, 0} }, 49 /* DDR3-1066G */ 50 { {6, 6, 8, 0, 0, 0, 0, 6, 6, 8, 0, 0, 6, 0, 6, 0} }, 51 /* DDR3-1333F* */ 52 { {6, 5, 6, 7, 0, 0, 0, 5, 5, 6, 0, 7, 5, 0, 5, 0} }, 53 /* DDR3-1333G */ 54 { {6, 5, 7, 8, 0, 0, 0, 5, 5, 7, 0, 8, 5, 0, 5, 0} }, 55 /* DDR3-1333H */ 56 { {6, 6, 8, 9, 0, 0, 0, 6, 6, 8, 0, 9, 6, 0, 6, 0} }, 57 /* DDR3-1333J* */ 58 { {6, 6, 8, 10, 0, 0, 0, 6, 6, 8, 0, 10, 6, 0, 6, 0} 59 /* DDR3-1600G* */}, 60 { {6, 5, 6, 7, 8, 0, 0, 5, 5, 6, 0, 7, 5, 0, 5, 0} }, 61 /* DDR3-1600H */ 62 { {6, 5, 6, 8, 9, 0, 0, 5, 5, 6, 0, 8, 5, 0, 5, 0} }, 63 /* DDR3-1600J */ 64 { {6, 5, 7, 9, 10, 0, 0, 5, 5, 7, 0, 9, 5, 0, 5, 0} }, 65 /* DDR3-1600K */ 66 { {6, 6, 8, 10, 11, 0, 0, 6, 6, 8, 0, 10, 6, 0, 6, 0 } }, 67 /* DDR3-1866J* */ 68 { {6, 5, 6, 8, 9, 11, 0, 5, 5, 6, 11, 8, 5, 0, 5, 0} }, 69 /* DDR3-1866K */ 70 { {6, 5, 7, 8, 10, 11, 0, 5, 5, 7, 11, 8, 5, 11, 5, 11} }, 71 /* DDR3-1866L */ 72 { {6, 6, 7, 9, 11, 12, 0, 6, 6, 7, 12, 9, 6, 12, 6, 12} }, 73 /* DDR3-1866M* */ 74 { {6, 6, 8, 10, 11, 13, 0, 6, 6, 8, 13, 10, 6, 13, 6, 13} }, 75 /* DDR3-2133K* */ 76 { {6, 5, 6, 7, 9, 10, 11, 5, 5, 6, 10, 7, 5, 11, 5, 11} }, 77 /* DDR3-2133L */ 78 { {6, 5, 6, 8, 9, 11, 12, 5, 5, 6, 11, 8, 5, 12, 5, 12} }, 79 /* DDR3-2133M */ 80 { {6, 5, 7, 9, 10, 12, 13, 5, 5, 7, 12, 9, 5, 13, 5, 13} }, 81 /* DDR3-2133N* */ 82 { {6, 6, 7, 9, 11, 13, 14, 6, 6, 7, 13, 9, 6, 14, 6, 14} }, 83 /* DDR3-1333H-ext */ 84 { {6, 6, 7, 9, 0, 0, 0, 6, 6, 7, 0, 9, 6, 0, 6, 0} }, 85 /* DDR3-1600K-ext */ 86 { {6, 6, 7, 9, 11, 0, 0, 6, 6, 7, 0, 9, 6, 0, 6, 0} }, 87 /* DDR3-1866M-ext */ 88 { {6, 6, 7, 9, 11, 13, 0, 6, 6, 7, 13, 9, 6, 13, 6, 13} }, 89 }; 90 91 /* Table for CWL values per speedbin index */ 92 struct cl_val_per_freq cas_write_latency_table[] = { 93 /* 94 * 400M 667M 933M 311M 467M 600M 360 95 * 100M 533M 800M 1066M 333M 850M 900 96 * (the order is 100, 400, 533 etc.) 97 */ 98 /* DDR3-800D */ 99 { {5, 5, 0, 0, 0, 0, 0, 5, 5, 0, 0, 0, 5, 0, 5, 0} }, 100 /* DDR3-800E */ 101 { {5, 5, 0, 0, 0, 0, 0, 5, 5, 0, 0, 0, 5, 0, 5, 0} }, 102 /* DDR3-1066E */ 103 { {5, 5, 6, 0, 0, 0, 0, 5, 5, 6, 0, 7, 5, 0, 5, 0} }, 104 /* DDR3-1066F */ 105 { {5, 5, 6, 0, 0, 0, 0, 5, 5, 6, 0, 7, 5, 0, 5, 0} }, 106 /* DDR3-1066G */ 107 { {5, 5, 6, 0, 0, 0, 0, 5, 5, 6, 0, 7, 5, 0, 5, 0} }, 108 /* DDR3-1333F* */ 109 { {5, 5, 6, 7, 0, 0, 0, 5, 5, 6, 0, 7, 5, 0, 5, 0} }, 110 /* DDR3-1333G */ 111 { {5, 5, 6, 7, 0, 0, 0, 5, 5, 6, 0, 7, 5, 0, 5, 0} }, 112 /* DDR3-1333H */ 113 { {5, 5, 6, 7, 0, 0, 0, 5, 5, 6, 0, 7, 5, 0, 5, 0} }, 114 /* DDR3-1333J* */ 115 { {5, 5, 6, 7, 0, 0, 0, 5, 5, 6, 0, 7, 5, 0, 5, 0} }, 116 /* DDR3-1600G* */ 117 { {5, 5, 6, 7, 8, 0, 0, 5, 5, 6, 0, 7, 5, 0, 5, 0} }, 118 /* DDR3-1600H */ 119 { {5, 5, 6, 7, 8, 0, 0, 5, 5, 6, 0, 7, 5, 0, 5, 0} }, 120 /* DDR3-1600J */ 121 { {5, 5, 6, 7, 8, 0, 0, 5, 5, 6, 0, 7, 5, 0, 5, 0} }, 122 /* DDR3-1600K */ 123 { {5, 5, 6, 7, 8, 0, 0, 5, 5, 6, 0, 7, 5, 0, 5, 0} }, 124 /* DDR3-1866J* */ 125 { {5, 5, 6, 7, 8, 9, 0, 5, 5, 6, 9, 7, 5, 0, 5, 0} }, 126 /* DDR3-1866K */ 127 { {5, 5, 6, 7, 8, 9, 0, 5, 5, 6, 9, 7, 5, 0, 5, 0} }, 128 /* DDR3-1866L */ 129 { {5, 5, 6, 7, 8, 9, 0, 5, 5, 6, 9, 7, 5, 9, 5, 9} }, 130 /* DDR3-1866M* */ 131 { {5, 5, 6, 7, 8, 9, 0, 5, 5, 6, 9, 7, 5, 9, 5, 9} }, 132 /* DDR3-2133K* */ 133 { {5, 5, 6, 7, 8, 9, 10, 5, 5, 6, 9, 7, 5, 9, 5, 10} }, 134 /* DDR3-2133L */ 135 { {5, 5, 6, 7, 8, 9, 10, 5, 5, 6, 9, 7, 5, 9, 5, 10} }, 136 /* DDR3-2133M */ 137 { {5, 5, 6, 7, 8, 9, 10, 5, 5, 6, 9, 7, 5, 9, 5, 10} }, 138 /* DDR3-2133N* */ 139 { {5, 5, 6, 7, 8, 9, 10, 5, 5, 6, 9, 7, 5, 9, 5, 10} }, 140 /* DDR3-1333H-ext */ 141 { {5, 5, 6, 7, 0, 0, 0, 5, 5, 6, 0, 7, 5, 0, 5, 0} }, 142 /* DDR3-1600K-ext */ 143 { {5, 5, 6, 7, 8, 0, 0, 5, 5, 6, 0, 7, 5, 0, 5, 0} }, 144 /* DDR3-1866M-ext */ 145 { {5, 5, 6, 7, 8, 9, 0, 5, 5, 6, 9, 7, 5, 9, 5, 9} }, 146 }; 147 148 u8 twr_mask_table[] = { 149 10, 150 10, 151 10, 152 10, 153 10, 154 1, /*5*/ 155 2, /*6*/ 156 3, /*7*/ 157 4, /*8*/ 158 10, 159 5, /*10*/ 160 10, 161 6, /*12*/ 162 10, 163 7, /*14*/ 164 10, 165 0 /*16*/ 166 }; 167 168 u8 cl_mask_table[] = { 169 0, 170 0, 171 0, 172 0, 173 0, 174 0x2, 175 0x4, 176 0x6, 177 0x8, 178 0xa, 179 0xc, 180 0xe, 181 0x1, 182 0x3, 183 0x5, 184 0x5 185 }; 186 187 u8 cwl_mask_table[] = { 188 0, 189 0, 190 0, 191 0, 192 0, 193 0, 194 0x1, 195 0x2, 196 0x3, 197 0x4, 198 0x5, 199 0x6, 200 0x7, 201 0x8, 202 0x9, 203 0x9 204 }; 205 206 /* RFC values (in ns) */ 207 u16 rfc_table[] = { 208 90, /* 512M */ 209 110, /* 1G */ 210 160, /* 2G */ 211 260, /* 4G */ 212 350 /* 8G */ 213 }; 214 215 u32 speed_bin_table_t_rc[] = { 216 50000, 217 52500, 218 48750, 219 50625, 220 52500, 221 46500, 222 48000, 223 49500, 224 51000, 225 45000, 226 46250, 227 47500, 228 48750, 229 44700, 230 45770, 231 46840, 232 47910, 233 43285, 234 44220, 235 45155, 236 46900 237 }; 238 239 u32 speed_bin_table_t_rcd_t_rp[] = { 240 12500, 241 15000, 242 11250, 243 13125, 244 15000, 245 10500, 246 12000, 247 13500, 248 15000, 249 10000, 250 11250, 251 12500, 252 13750, 253 10700, 254 11770, 255 12840, 256 13910, 257 10285, 258 11022, 259 12155, 260 13090, 261 }; 262 263 enum { 264 PATTERN_KILLER_PATTERN_TABLE_MAP_ROLE_AGGRESSOR = 0, 265 PATTERN_KILLER_PATTERN_TABLE_MAP_ROLE_VICTIM 266 }; 267 268 static u8 pattern_killer_pattern_table_map[KILLER_PATTERN_LENGTH * 2][2] = { 269 /*Aggressor / Victim */ 270 {1, 0}, 271 {0, 0}, 272 {1, 0}, 273 {1, 1}, 274 {0, 1}, 275 {0, 1}, 276 {1, 0}, 277 {0, 1}, 278 {1, 0}, 279 {0, 1}, 280 {1, 0}, 281 {1, 0}, 282 {0, 1}, 283 {1, 0}, 284 {0, 1}, 285 {0, 0}, 286 {1, 1}, 287 {0, 0}, 288 {1, 1}, 289 {0, 0}, 290 {1, 1}, 291 {0, 0}, 292 {1, 1}, 293 {1, 0}, 294 {0, 0}, 295 {1, 1}, 296 {0, 0}, 297 {1, 1}, 298 {0, 0}, 299 {0, 0}, 300 {0, 0}, 301 {0, 1}, 302 {0, 1}, 303 {1, 1}, 304 {0, 0}, 305 {0, 0}, 306 {1, 1}, 307 {1, 1}, 308 {0, 0}, 309 {1, 1}, 310 {0, 0}, 311 {1, 1}, 312 {1, 1}, 313 {0, 0}, 314 {0, 0}, 315 {1, 1}, 316 {0, 0}, 317 {1, 1}, 318 {0, 1}, 319 {0, 0}, 320 {0, 1}, 321 {0, 1}, 322 {0, 0}, 323 {1, 1}, 324 {1, 1}, 325 {1, 0}, 326 {1, 0}, 327 {1, 1}, 328 {1, 1}, 329 {1, 1}, 330 {1, 1}, 331 {1, 1}, 332 {1, 1}, 333 {1, 1} 334 }; 335 336 static u8 pattern_vref_pattern_table_map[] = { 337 /* 1 means 0xffffffff, 0 is 0x0 */ 338 0xb8, 339 0x52, 340 0x55, 341 0x8a, 342 0x33, 343 0xa6, 344 0x6d, 345 0xfe 346 }; 347 348 /* Return speed Bin value for selected index and t* element */ 349 u32 speed_bin_table(u8 index, enum speed_bin_table_elements element) 350 { 351 u32 result = 0; 352 353 switch (element) { 354 case SPEED_BIN_TRCD: 355 case SPEED_BIN_TRP: 356 result = speed_bin_table_t_rcd_t_rp[index]; 357 break; 358 case SPEED_BIN_TRAS: 359 if (index < 6) 360 result = 37500; 361 else if (index < 10) 362 result = 36000; 363 else if (index < 14) 364 result = 35000; 365 else if (index < 18) 366 result = 34000; 367 else 368 result = 33000; 369 break; 370 case SPEED_BIN_TRC: 371 result = speed_bin_table_t_rc[index]; 372 break; 373 case SPEED_BIN_TRRD1K: 374 if (index < 3) 375 result = 10000; 376 else if (index < 6) 377 result = 7005; 378 else if (index < 14) 379 result = 6000; 380 else 381 result = 5000; 382 break; 383 case SPEED_BIN_TRRD2K: 384 if (index < 6) 385 result = 10000; 386 else if (index < 14) 387 result = 7005; 388 else 389 result = 6000; 390 break; 391 case SPEED_BIN_TPD: 392 if (index < 3) 393 result = 7500; 394 else if (index < 10) 395 result = 5625; 396 else 397 result = 5000; 398 break; 399 case SPEED_BIN_TFAW1K: 400 if (index < 3) 401 result = 40000; 402 else if (index < 6) 403 result = 37500; 404 else if (index < 14) 405 result = 30000; 406 else if (index < 18) 407 result = 27000; 408 else 409 result = 25000; 410 break; 411 case SPEED_BIN_TFAW2K: 412 if (index < 6) 413 result = 50000; 414 else if (index < 10) 415 result = 45000; 416 else if (index < 14) 417 result = 40000; 418 else 419 result = 35000; 420 break; 421 case SPEED_BIN_TWTR: 422 result = 7500; 423 break; 424 case SPEED_BIN_TRTP: 425 result = 7500; 426 break; 427 case SPEED_BIN_TWR: 428 result = 15000; 429 break; 430 case SPEED_BIN_TMOD: 431 result = 15000; 432 break; 433 case SPEED_BIN_TXPDLL: 434 result = 24000; 435 break; 436 default: 437 break; 438 } 439 440 return result; 441 } 442 443 static inline u32 pattern_table_get_killer_word(u8 dqs, u8 index) 444 { 445 u8 i, byte = 0; 446 u8 role; 447 448 for (i = 0; i < 8; i++) { 449 role = (i == dqs) ? 450 (PATTERN_KILLER_PATTERN_TABLE_MAP_ROLE_AGGRESSOR) : 451 (PATTERN_KILLER_PATTERN_TABLE_MAP_ROLE_VICTIM); 452 byte |= pattern_killer_pattern_table_map[index][role] << i; 453 } 454 455 return byte | (byte << 8) | (byte << 16) | (byte << 24); 456 } 457 458 static inline u32 pattern_table_get_killer_word16(u8 dqs, u8 index) 459 { 460 u8 i, byte0 = 0, byte1 = 0; 461 u8 role; 462 463 for (i = 0; i < 8; i++) { 464 role = (i == dqs) ? 465 (PATTERN_KILLER_PATTERN_TABLE_MAP_ROLE_AGGRESSOR) : 466 (PATTERN_KILLER_PATTERN_TABLE_MAP_ROLE_VICTIM); 467 byte0 |= pattern_killer_pattern_table_map[index * 2][role] << i; 468 } 469 470 for (i = 0; i < 8; i++) { 471 role = (i == dqs) ? 472 (PATTERN_KILLER_PATTERN_TABLE_MAP_ROLE_AGGRESSOR) : 473 (PATTERN_KILLER_PATTERN_TABLE_MAP_ROLE_VICTIM); 474 byte1 |= pattern_killer_pattern_table_map 475 [index * 2 + 1][role] << i; 476 } 477 478 return byte0 | (byte0 << 8) | (byte1 << 16) | (byte1 << 24); 479 } 480 481 static inline u32 pattern_table_get_sso_word(u8 sso, u8 index) 482 { 483 u8 step = sso + 1; 484 485 if (0 == ((index / step) & 1)) 486 return 0x0; 487 else 488 return 0xffffffff; 489 } 490 491 static inline u32 pattern_table_get_vref_word(u8 index) 492 { 493 if (0 == ((pattern_vref_pattern_table_map[index / 8] >> 494 (index % 8)) & 1)) 495 return 0x0; 496 else 497 return 0xffffffff; 498 } 499 500 static inline u32 pattern_table_get_vref_word16(u8 index) 501 { 502 if (0 == pattern_killer_pattern_table_map 503 [PATTERN_KILLER_PATTERN_TABLE_MAP_ROLE_VICTIM][index * 2] && 504 0 == pattern_killer_pattern_table_map 505 [PATTERN_KILLER_PATTERN_TABLE_MAP_ROLE_VICTIM][index * 2 + 1]) 506 return 0x00000000; 507 else if (1 == pattern_killer_pattern_table_map 508 [PATTERN_KILLER_PATTERN_TABLE_MAP_ROLE_VICTIM][index * 2] && 509 0 == pattern_killer_pattern_table_map 510 [PATTERN_KILLER_PATTERN_TABLE_MAP_ROLE_VICTIM][index * 2 + 1]) 511 return 0xffff0000; 512 else if (0 == pattern_killer_pattern_table_map 513 [PATTERN_KILLER_PATTERN_TABLE_MAP_ROLE_VICTIM][index * 2] && 514 1 == pattern_killer_pattern_table_map 515 [PATTERN_KILLER_PATTERN_TABLE_MAP_ROLE_VICTIM][index * 2 + 1]) 516 return 0x0000ffff; 517 else 518 return 0xffffffff; 519 } 520 521 static inline u32 pattern_table_get_static_pbs_word(u8 index) 522 { 523 u16 temp; 524 525 temp = ((0x00ff << (index / 3)) & 0xff00) >> 8; 526 527 return temp | (temp << 8) | (temp << 16) | (temp << 24); 528 } 529 530 inline u32 pattern_table_get_word(u32 dev_num, enum hws_pattern type, u8 index) 531 { 532 u32 pattern; 533 struct hws_topology_map *tm = ddr3_get_topology_map(); 534 535 if (DDR3_IS_16BIT_DRAM_MODE(tm->bus_act_mask) == 0) { 536 /* 32bit patterns */ 537 switch (type) { 538 case PATTERN_PBS1: 539 case PATTERN_PBS2: 540 if (index == 0 || index == 2 || index == 5 || 541 index == 7) 542 pattern = PATTERN_55; 543 else 544 pattern = PATTERN_AA; 545 break; 546 case PATTERN_PBS3: 547 if (0 == (index & 1)) 548 pattern = PATTERN_55; 549 else 550 pattern = PATTERN_AA; 551 break; 552 case PATTERN_RL: 553 if (index < 6) 554 pattern = PATTERN_00; 555 else 556 pattern = PATTERN_80; 557 break; 558 case PATTERN_STATIC_PBS: 559 pattern = pattern_table_get_static_pbs_word(index); 560 break; 561 case PATTERN_KILLER_DQ0: 562 case PATTERN_KILLER_DQ1: 563 case PATTERN_KILLER_DQ2: 564 case PATTERN_KILLER_DQ3: 565 case PATTERN_KILLER_DQ4: 566 case PATTERN_KILLER_DQ5: 567 case PATTERN_KILLER_DQ6: 568 case PATTERN_KILLER_DQ7: 569 pattern = pattern_table_get_killer_word( 570 (u8)(type - PATTERN_KILLER_DQ0), index); 571 break; 572 case PATTERN_RL2: 573 if (index < 6) 574 pattern = PATTERN_00; 575 else 576 pattern = PATTERN_01; 577 break; 578 case PATTERN_TEST: 579 if (index > 1 && index < 6) 580 pattern = PATTERN_20; 581 else 582 pattern = PATTERN_00; 583 break; 584 case PATTERN_FULL_SSO0: 585 case PATTERN_FULL_SSO1: 586 case PATTERN_FULL_SSO2: 587 case PATTERN_FULL_SSO3: 588 pattern = pattern_table_get_sso_word( 589 (u8)(type - PATTERN_FULL_SSO0), index); 590 break; 591 case PATTERN_VREF: 592 pattern = pattern_table_get_vref_word(index); 593 break; 594 default: 595 pattern = 0; 596 break; 597 } 598 } else { 599 /* 16bit patterns */ 600 switch (type) { 601 case PATTERN_PBS1: 602 case PATTERN_PBS2: 603 case PATTERN_PBS3: 604 pattern = PATTERN_55AA; 605 break; 606 case PATTERN_RL: 607 if (index < 3) 608 pattern = PATTERN_00; 609 else 610 pattern = PATTERN_80; 611 break; 612 case PATTERN_STATIC_PBS: 613 pattern = PATTERN_00FF; 614 break; 615 case PATTERN_KILLER_DQ0: 616 case PATTERN_KILLER_DQ1: 617 case PATTERN_KILLER_DQ2: 618 case PATTERN_KILLER_DQ3: 619 case PATTERN_KILLER_DQ4: 620 case PATTERN_KILLER_DQ5: 621 case PATTERN_KILLER_DQ6: 622 case PATTERN_KILLER_DQ7: 623 pattern = pattern_table_get_killer_word16( 624 (u8)(type - PATTERN_KILLER_DQ0), index); 625 break; 626 case PATTERN_RL2: 627 if (index < 3) 628 pattern = PATTERN_00; 629 else 630 pattern = PATTERN_01; 631 break; 632 case PATTERN_TEST: 633 pattern = PATTERN_0080; 634 break; 635 case PATTERN_FULL_SSO0: 636 pattern = 0x0000ffff; 637 break; 638 case PATTERN_FULL_SSO1: 639 case PATTERN_FULL_SSO2: 640 case PATTERN_FULL_SSO3: 641 pattern = pattern_table_get_sso_word( 642 (u8)(type - PATTERN_FULL_SSO1), index); 643 break; 644 case PATTERN_VREF: 645 pattern = pattern_table_get_vref_word16(index); 646 break; 647 default: 648 pattern = 0; 649 break; 650 } 651 } 652 653 return pattern; 654 } 655