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