1 /* 2 * Copyright 2021 NXP 3 * SPDX-License-Identifier: BSD-3-Clause 4 * 5 */ 6 7 #include <errno.h> 8 #include <stdint.h> 9 #include <stdio.h> 10 #include <stdlib.h> 11 #include <string.h> 12 13 #include <common/debug.h> 14 #include "csr.h" 15 #include <ddr.h> 16 #include "ddr4fw.h" 17 #include <drivers/delay_timer.h> 18 #ifdef NXP_WARM_BOOT 19 #include <fspi_api.h> 20 #endif 21 #include "input.h" 22 #include <lib/mmio.h> 23 #include <lib/utils.h> 24 #include <lib/xlat_tables/xlat_tables_v2.h> 25 #ifdef DDR_PHY_DEBUG 26 #include "messages.h" 27 #endif 28 #ifdef NXP_WARM_BOOT 29 #include "phy.h" 30 #endif 31 #include "pie.h" 32 33 #define TIMEOUTDEFAULT 500 34 #define MAP_PHY_ADDR(pstate, n, instance, offset, c) \ 35 ((((pstate * n) + instance + c) << 12) + offset) 36 37 static uint32_t map_phy_addr_space(uint32_t addr) 38 { 39 /* 23 bit addressing */ 40 uint32_t pstate = (addr & U(0x700000)) >> 20U; /* bit 22:20 */ 41 uint32_t block_type = (addr & U(0x0f0000)) >> 16U; /* bit 19:16 */ 42 uint32_t instance = (addr & U(0x00f000)) >> 12U; /* bit 15:12 */ 43 uint32_t offset = (addr & U(0x000fff)); /* bit 11:0 */ 44 45 switch (block_type) { 46 case 0x0: /* 0x0 : ANIB */ 47 return MAP_PHY_ADDR(pstate, 12, instance, offset, 0); 48 case 0x1: /* 0x1 : DBYTE */ 49 return MAP_PHY_ADDR(pstate, 10, instance, offset, 0x30); 50 case 0x2: /* 0x2 : MASTER */ 51 return MAP_PHY_ADDR(pstate, 1, 0, offset, 0x58); 52 case 0x4: /* 0x4 : ACSM */ 53 return MAP_PHY_ADDR(pstate, 1, 0, offset, 0x5c); 54 case 0x5: /* 0x5 : μCTL Memory */ 55 return MAP_PHY_ADDR(pstate, 0, instance, offset, 0x60); 56 case 0x7: /* 0x7 : PPGC */ 57 return MAP_PHY_ADDR(pstate, 0, 0, offset, 0x68); 58 case 0x9: /* 0x9 : INITENG */ 59 return MAP_PHY_ADDR(pstate, 1, 0, offset, 0x69); 60 case 0xc: /* 0xC : DRTUB */ 61 return MAP_PHY_ADDR(pstate, 0, 0, offset, 0x6d); 62 case 0xd: /* 0xD : APB Only */ 63 return MAP_PHY_ADDR(pstate, 0, 0, offset, 0x6e); 64 default: 65 printf("ERR: Invalid block_type = 0x%x\n", block_type); 66 return 0; 67 } 68 } 69 70 static inline uint16_t *phy_io_addr(void *phy, uint32_t addr) 71 { 72 return phy + (map_phy_addr_space(addr) << 2); 73 } 74 75 static inline void phy_io_write16(uint16_t *phy, uint32_t addr, uint16_t data) 76 { 77 mmio_write_16((uintptr_t)phy_io_addr(phy, addr), data); 78 #ifdef DEBUG_PHY_IO 79 printf("0x%06x,0x%x\n", addr, data); 80 #endif 81 } 82 83 static inline uint16_t phy_io_read16(uint16_t *phy, uint32_t addr) 84 { 85 uint16_t reg = mmio_read_16((uintptr_t) phy_io_addr(phy, addr)); 86 87 #ifdef DEBUG_PHY_IO 88 printf("R: 0x%06x,0x%x\n", addr, reg); 89 #endif 90 91 return reg; 92 } 93 94 #ifdef NXP_APPLY_MAX_CDD 95 96 #define CDD_VAL_READ_ADDR (0x054012) 97 #define CDD_DATA_LEN (60) 98 99 static void read_phy_reg(uint16_t *phy, uint32_t addr, 100 uint16_t *buf, uint32_t len) 101 { 102 uint32_t i = 0U; 103 104 for (i = 0U; i < len/2; i++) { 105 buf[i] = phy_io_read16(phy, (addr + i)); 106 } 107 } 108 109 static uint32_t findrank(uint32_t cs_in_use) 110 { 111 uint32_t val = 0U; 112 113 switch (cs_in_use) { 114 case U(0xf): 115 val = 4U; 116 break; 117 case U(0x3): 118 val = 2U; 119 break; 120 case U(0x1): 121 val = 1U; 122 break; 123 default: 124 printf("Error - Invalid cs_in_use value\n"); 125 } 126 return val; 127 } 128 129 static uint8_t findmax(uint8_t *buf, uint32_t len) 130 { 131 uint8_t max = 0U; 132 uint32_t i = 0U; 133 134 for (i = 0U; i < len; i++) { 135 if (buf[i] > max) { 136 max = buf[i]; 137 } 138 } 139 140 return max; 141 } 142 143 static void get_cdd_val(uint16_t **phy_ptr, uint32_t rank, uint32_t freq, 144 uint32_t *tcfg0, uint32_t *tcfg4) 145 { 146 uint8_t cdd[CDD_DATA_LEN+4] = {0U}; 147 uint32_t i, val = 0U; 148 uint16_t *phy; 149 uint8_t buf[16] = {U(0x0)}; 150 uint8_t trr = 0U, tww = 0U, trw = 0U, twr = 0U; 151 uint8_t rrmax = 0U, wwmax = 0U, rwmax = 0U, wrmax = 0U; 152 uint8_t tmp = U(0x0); 153 uint8_t *c = NULL; 154 155 for (i = 0U; i < NUM_OF_DDRC; i++) { 156 157 phy = phy_ptr[i]; 158 if (phy == NULL) { 159 continue; 160 } 161 162 phy_io_write16(phy, t_apbonly | 163 csr_micro_cont_mux_sel_addr, U(0x0)); 164 165 read_phy_reg(phy, CDD_VAL_READ_ADDR, 166 (uint16_t *)&cdd, CDD_DATA_LEN); 167 168 phy_io_write16(phy, t_apbonly | 169 csr_micro_cont_mux_sel_addr, U(0x1)); 170 171 /* CDD values and address 172 * 173 * 0x054012 0x24 cdd[0] CDD[X][X] 174 * 0x054012 0x25 cdd[1] RR[3][2] 175 * 0x054013 0x26 cdd[2] RR[3][1] 176 * 0x054013 0x27 cdd[3] RR[3][0] 177 * 0x054014 0x28 cdd[4] RR[2][3] 178 * 0x054014 0x29 cdd[5] RR[2][1] 179 * 0x054015 0x2a cdd[6] RR[2][0] 180 * 0x054015 0x2b cdd[7] RR[1][3] 181 * 0x054016 0x2c cdd[8] RR[1][2] 182 * 0x054016 0x2d cdd[9] RR[1][0] 183 * 0x054017 0x2e cdd[10] RR[0][3] 184 * 0x054017 0x2f cdd[11] RR[0][2] 185 * 0x054018 0x30 cdd[12] RR[0][1] 186 187 * 0x054018 0x31 cdd[13] WW[3][2] 188 * 0x054019 0x32 cdd[14] WW[3][1] 189 * 0x054019 0x33 cdd[15] WW[3][0] 190 * 0x05401a 0x34 cdd[16] WW[2][3] 191 * 0x05401a 0x35 cdd[17] WW[2][1] 192 * 0x05401b 0x36 cdd[18] WW[2][0] 193 * 0x05401b 0x37 cdd[19] WW[1][3] 194 * 0x05401c 0x38 cdd[20] WW[1][2] 195 * 0x05401c 0x39 cdd[21] WW[1][0] 196 * 0x05401d 0x3a cdd[22] WW[0][3] 197 * 0x05401d 0x3b cdd[23] WW[0][2] 198 * 0x05401e 0x3c cdd[24] WW[0][1] 199 200 * 0x05401e 0x3d cdd[25] RW[3][3] 201 * 0x05401f 0x3e cdd[26] RW[3][2] 202 * 0x05401f 0x3f cdd[27] RW[3][1] 203 * 0x054020 0x40 cdd[28] RW[3][0] 204 * 0x054020 0x41 cdd[29] RW[2][3] 205 * 0x054021 0x42 cdd[30] RW[2][2] 206 * 0x054021 0x43 cdd[31] RW[2][1] 207 * 0x054022 0x44 cdd[32] RW[2][0] 208 * 0x054022 0x45 cdd[33] RW[1][3] 209 * 0x054023 0x46 cdd[34] RW[1][2] 210 * 0x054023 0x47 cdd[35] RW[1][1] 211 * 0x054024 0x48 cdd[36] RW[1][0] 212 * 0x054024 0x49 cdd[37] RW[0][3] 213 * 0x054025 0x4a cdd[38] RW[0][2] 214 * 0x054025 0x4b cdd[39] RW[0][1] 215 * 0x054026 0x4c cdd[40] RW[0][0] 216 217 * 0x054026 0x4d cdd[41] WR[3][3] 218 * 0x054027 0x4e cdd[42] WR[3][2] 219 * 0x054027 0x4f cdd[43] WR[3][1] 220 * 0x054028 0x50 cdd[44] WR[3][0] 221 * 0x054028 0x51 cdd[45] WR[2][3] 222 * 0x054029 0x52 cdd[46] WR[2][2] 223 * 0x054029 0x53 cdd[47] WR[2][1] 224 * 0x05402a 0x54 cdd[48] WR[2][0] 225 * 0x05402a 0x55 cdd[49] WR[1][3] 226 * 0x05402b 0x56 cdd[50] WR[1][2] 227 * 0x05402b 0x57 cdd[51] WR[1][1] 228 * 0x05402c 0x58 cdd[52] WR[1][0] 229 * 0x05402c 0x59 cdd[53] WR[0][3] 230 * 0x05402d 0x5a cdd[54] WR[0][2] 231 * 0x05402d 0x5b cdd[55] WR[0][1] 232 * 0x05402e 0x5c cdd[56] WR[0][0] 233 * 0x05402e 0x5d cdd[57] CDD[Y][Y] 234 */ 235 236 switch (rank) { 237 case 1U: 238 tmp = rwmax; 239 rwmax = cdd[40]; 240 if (tmp > rwmax) { 241 rwmax = tmp; 242 } 243 244 tmp = wrmax; 245 wrmax = cdd[56]; 246 if (tmp > wrmax) { 247 wrmax = tmp; 248 } 249 250 break; 251 252 case 2U: 253 buf[0] = cdd[12]; 254 buf[1] = cdd[9]; 255 tmp = rrmax; 256 rrmax = findmax(buf, 2U); 257 if (tmp > rrmax) { 258 rrmax = tmp; 259 } 260 261 buf[0] = cdd[24]; 262 buf[1] = cdd[21]; 263 tmp = wwmax; 264 wwmax = findmax(buf, 2U); 265 if (tmp > wwmax) { 266 wwmax = tmp; 267 } 268 269 buf[0] = cdd[40]; 270 buf[1] = cdd[39]; 271 buf[2] = cdd[36]; 272 buf[3] = cdd[35]; 273 tmp = rwmax; 274 rwmax = findmax(buf, 4U); 275 if (tmp > rwmax) { 276 rwmax = tmp; 277 } 278 279 buf[0] = cdd[56]; 280 buf[1] = cdd[55]; 281 buf[2] = cdd[52]; 282 buf[3] = cdd[51]; 283 tmp = wrmax; 284 wrmax = findmax(buf, 4U); 285 if (tmp > wrmax) { 286 wrmax = tmp; 287 } 288 289 break; 290 291 case 4U: 292 tmp = rrmax; 293 c = &cdd[1]; 294 rrmax = findmax(c, 12U); 295 if (tmp > rrmax) { 296 rrmax = tmp; 297 } 298 299 tmp = wwmax; 300 c = &cdd[13]; 301 wwmax = findmax(c, 12U); 302 if (tmp > wwmax) { 303 wwmax = tmp; 304 } 305 306 tmp = rwmax; 307 c = &cdd[25]; 308 rwmax = findmax(c, 16U); 309 if (tmp > rwmax) { 310 rwmax = tmp; 311 } 312 313 tmp = wrmax; 314 c = &cdd[41]; 315 wrmax = findmax(c, 16U); 316 if (tmp > wrmax) { 317 wrmax = tmp; 318 } 319 320 break; 321 322 } 323 } 324 325 rrmax += 3U; 326 wwmax += 4U; 327 328 if (wwmax > 7U) { 329 wwmax = 7U; 330 } 331 332 if (rrmax > 7U) { 333 rrmax = 7U; 334 } 335 336 if (wrmax > U(0xf)) { 337 wrmax = 0U; 338 } 339 340 if (rwmax > U(0x7)) { 341 rwmax = U(0x7); 342 } 343 344 val = *tcfg0; 345 tww = (val >> 24U) & U(0x3); 346 trr = (val >> 26U) & U(0x3); 347 twr = (val >> 28U) & U(0x3); 348 trw = (val >> 30U) & U(0x3); 349 350 val = *tcfg4; 351 tww = tww | (((val >> 8U) & U(0x1)) << 2U); 352 trr = trr | (((val >> 10U) & U(0x1)) << 2U); 353 twr = twr | (((val >> 12U) & U(0x1)) << 2U); 354 trw = trw | (((val >> 14U) & U(0x3)) << 2U); 355 356 if (trr > rrmax) { 357 rrmax = trr; 358 } 359 360 if (tww > wwmax) { 361 wwmax = tww; 362 } 363 364 if (trw > rwmax) { 365 rwmax = trw; 366 } 367 368 if (twr > wrmax) { 369 wrmax = twr; 370 } 371 372 debug("CDD rrmax %x wwmax %x rwmax %x wrmax %x\n", 373 rrmax, wwmax, rwmax, wrmax); 374 375 val = ((wwmax & U(0x3)) << 24U) 376 | ((rrmax & U(0x3)) << 26U) 377 | ((wrmax & U(0x3)) << 28U) 378 | ((rwmax & U(0x3)) << 30U); 379 380 *tcfg0 = (*tcfg0 & U(0x00FFFFFF)) | (val); 381 382 val = (((wwmax >> 2U) & U(0x1)) << 8U) 383 | (((rrmax >> 2U) & U(0x1)) << 10U) 384 | (((wrmax >> 2U) & U(0x1)) << 12U) 385 | (((rwmax >> 2U) & U(0x3)) << 14U); 386 387 *tcfg4 = (*tcfg4 & U(0xffff00ff)) | val; 388 } 389 #endif 390 391 #ifdef NXP_WARM_BOOT 392 int save_phy_training_values(uint16_t **phy_ptr, uint32_t address_to_store, 393 uint32_t num_of_phy, int train2d) 394 { 395 uint16_t *phy = NULL, value = 0x0; 396 uint32_t size = 1U, num_of_regs = 1U, phy_store = 0U; 397 int i = 0, j = 0, ret = -EINVAL; 398 399 ret = xspi_sector_erase(address_to_store, PHY_ERASE_SIZE); 400 if (ret != 0) { 401 return -EINVAL; 402 } 403 404 for (j = 0; j < num_of_phy; j++) { 405 /* Save training values of all PHYs */ 406 phy = phy_ptr[j]; 407 size = sizeof(training_1D_values); 408 num_of_regs = ARRAY_SIZE(training_1D_values); 409 410 /* Enable access to the internal CSRs */ 411 phy_io_write16(phy, t_apbonly | 412 csr_micro_cont_mux_sel_addr, 0x0); 413 /* Enable clocks in case they were disabled. */ 414 phy_io_write16(phy, t_drtub | 415 csr_ucclk_hclk_enables_addr, 0x3); 416 if (train2d != 0) { 417 /* Address to store training values is 418 * to be appended for next PHY 419 */ 420 phy_store = address_to_store + (j * 421 (sizeof(training_1D_values) + 422 sizeof(training_2D_values))); 423 } else { 424 phy_store = address_to_store + (j * 425 (sizeof(training_1D_values))); 426 } 427 debug("Saving 1D Training reg val at: %d\n", phy_store); 428 for (i = 0; i < num_of_regs; i++) { 429 value = phy_io_read16(phy, training_1D_values[i].addr); 430 #ifdef DEBUG_WARM_RESET 431 debug("%d. Reg: %x, value: %x PHY: %p\n", i, 432 training_1D_values[i].addr, value, 433 phy_io_addr(phy, 434 training_1D_values[i].addr)); 435 #endif 436 training_1D_values[i].data = value; 437 } 438 /* Storing 1D training values on flash */ 439 ret = xspi_write(phy_store, (void *)training_1D_values, size); 440 if (train2d != 0) { 441 phy_store = phy_store+size; 442 size = sizeof(training_2D_values); 443 num_of_regs = ARRAY_SIZE(training_2D_values); 444 debug("Saving 2D Training reg val at:%d\n", phy_store); 445 for (i = 0; i < num_of_regs; i++) { 446 value = phy_io_read16(phy, 447 training_2D_values[i].addr); 448 training_2D_values[i].data = value; 449 #ifdef DEBUG_WARM_RESET 450 debug("%d.2D addr:0x%x,val:0x%x,PHY:0x%p\n", 451 i, training_2D_values[i].addr, 452 value, phy_io_addr(phy, 453 training_2D_values[i].addr)); 454 #endif 455 } 456 /* Storing 2D training values on flash */ 457 ret = xspi_write(phy_store, training_2D_values, 458 size); 459 } 460 /* Disable clocks in case they were disabled. */ 461 phy_io_write16(phy, t_drtub | 462 csr_ucclk_hclk_enables_addr, 0x0); 463 /* Disable access to the internal CSRs */ 464 phy_io_write16(phy, t_apbonly | 465 csr_micro_cont_mux_sel_addr, 0x1); 466 } 467 if (ret != 0) { 468 return -EINVAL; 469 } 470 471 return 0; 472 } 473 474 int restore_phy_training_values(uint16_t **phy_ptr, uint32_t address_to_restore, 475 uint32_t num_of_phy, int train2d) 476 { 477 uint16_t *phy = NULL; 478 uint32_t size = 1U, num_of_regs = 1U, phy_store = 0U; 479 int i = 0, j = 0, ret = -EINVAL; 480 481 debug("Restoring Training register values\n"); 482 for (j = 0; j < num_of_phy; j++) { 483 phy = phy_ptr[j]; 484 size = sizeof(training_1D_values); 485 num_of_regs = ARRAY_SIZE(training_1D_values); 486 if (train2d != 0) { 487 /* The address to restore training values is 488 * to be appended for next PHY 489 */ 490 phy_store = address_to_restore + (j * 491 (sizeof(training_1D_values) + 492 sizeof(training_2D_values))); 493 } else { 494 phy_store = address_to_restore + (j * 495 (sizeof(training_1D_values))); 496 } 497 /* Enable access to the internal CSRs */ 498 phy_io_write16(phy, t_apbonly | 499 csr_micro_cont_mux_sel_addr, 0x0); 500 /* Enable clocks in case they were disabled. */ 501 phy_io_write16(phy, t_drtub | 502 csr_ucclk_hclk_enables_addr, 0x3); 503 504 /* Reading 1D training values from flash*/ 505 ret = xspi_read(phy_store, (uint32_t *)training_1D_values, 506 size); 507 debug("Restoring 1D Training reg val at:%08x\n", phy_store); 508 for (i = 0; i < num_of_regs; i++) { 509 phy_io_write16(phy, training_1D_values[i].addr, 510 training_1D_values[i].data); 511 #ifdef DEBUG_WARM_RESET 512 debug("%d. Reg: %x, value: %x PHY: %p\n", i, 513 training_1D_values[i].addr, 514 training_1D_values[i].data, 515 phy_io_addr(phy, 516 training_1D_values[i].addr)); 517 #endif 518 } 519 if (train2d != 0) { 520 phy_store = phy_store + size; 521 size = sizeof(training_2D_values); 522 num_of_regs = ARRAY_SIZE(training_2D_values); 523 /* Reading 2D training values from flash */ 524 ret = xspi_read(phy_store, 525 (uint32_t *)training_2D_values, size); 526 debug("Restoring 2D Training reg val at:%08x\n", 527 phy_store); 528 for (i = 0; i < num_of_regs; i++) { 529 phy_io_write16(phy, training_2D_values[i].addr, 530 training_2D_values[i].data); 531 #ifdef DEBUG_WARM_RESET 532 debug("%d. Reg: %x, value: %x PHY: %p\n", i, 533 training_2D_values[i].addr, 534 training_2D_values[i].data, 535 phy_io_addr(phy, 536 training_1D_values[i].addr)); 537 #endif 538 } 539 } 540 /* Disable clocks in case they were disabled. */ 541 phy_io_write16(phy, t_drtub | 542 csr_ucclk_hclk_enables_addr, 0x0); 543 /* Disable access to the internal CSRs */ 544 phy_io_write16(phy, t_apbonly | 545 csr_micro_cont_mux_sel_addr, 0x1); 546 } 547 if (ret != 0) { 548 return -EINVAL; 549 } 550 return 0; 551 } 552 #endif 553 554 static void load_pieimage(uint16_t *phy, 555 enum dimm_types dimm_type) 556 { 557 int i; 558 int size; 559 const struct pie *image = NULL; 560 561 switch (dimm_type) { 562 case UDIMM: 563 case SODIMM: 564 case NODIMM: 565 image = pie_udimm; 566 size = ARRAY_SIZE(pie_udimm); 567 break; 568 case RDIMM: 569 image = pie_rdimm; 570 size = ARRAY_SIZE(pie_rdimm); 571 break; 572 case LRDIMM: 573 image = pie_lrdimm; 574 size = ARRAY_SIZE(pie_lrdimm); 575 break; 576 default: 577 printf("Unsupported DIMM type\n"); 578 break; 579 } 580 581 if (image != NULL) { 582 for (i = 0; i < size; i++) 583 phy_io_write16(phy, image[i].addr, image[i].data); 584 } 585 } 586 587 static void prog_acsm_playback(uint16_t *phy, 588 const struct input *input, const void *msg) 589 { 590 int vec; 591 const struct ddr4r1d *msg_blk; 592 uint16_t acsmplayback[2][3]; 593 uint32_t f0rc0a; 594 uint32_t f0rc3x; 595 uint32_t f0rc5x; 596 597 if (input->basic.dimm_type != RDIMM) { 598 return; 599 } 600 601 msg_blk = msg; 602 f0rc0a = (msg_blk->f0rc0a_d0 & U(0xf)) | U(0xa0); 603 f0rc3x = (msg_blk->f0rc3x_d0 & U(0xff)) | U(0x300); 604 f0rc5x = (input->adv.phy_gen2_umctl_f0rc5x & U(0xff)) | U(0x500); 605 606 acsmplayback[0][0] = U(0x3ff) & f0rc0a; 607 acsmplayback[1][0] = (U(0x1c00) & f0rc0a) >> 10U; 608 acsmplayback[0][1] = U(0x3ff) & f0rc3x; 609 acsmplayback[1][1] = (U(0x1c00) & f0rc3x) >> 10U; 610 acsmplayback[0][2] = U(0x3ff) & f0rc5x; 611 acsmplayback[1][2] = (U(0x1c00) & f0rc5x) >> 10U; 612 for (vec = 0; vec < 3; vec++) { 613 phy_io_write16(phy, t_acsm | (csr_acsm_playback0x0_addr + 614 (vec << 1)), acsmplayback[0][vec]); 615 phy_io_write16(phy, t_acsm | (csr_acsm_playback1x0_addr + 616 (vec << 1)), acsmplayback[1][vec]); 617 } 618 } 619 620 static void prog_acsm_ctr(uint16_t *phy, 621 const struct input *input) 622 { 623 if (input->basic.dimm_type != RDIMM) { 624 return; 625 } 626 627 phy_io_write16(phy, t_acsm | csr_acsm_ctrl13_addr, 628 0xf << csr_acsm_cke_enb_lsb); 629 630 phy_io_write16(phy, t_acsm | csr_acsm_ctrl0_addr, 631 csr_acsm_par_mode_mask | csr_acsm_2t_mode_mask); 632 } 633 634 static void prog_cal_rate_run(uint16_t *phy, 635 const struct input *input) 636 { 637 int cal_rate; 638 int cal_interval; 639 int cal_once; 640 uint32_t addr; 641 642 cal_interval = input->adv.cal_interval; 643 cal_once = input->adv.cal_once; 644 cal_rate = 0x1 << csr_cal_run_lsb | 645 cal_once << csr_cal_once_lsb | 646 cal_interval << csr_cal_interval_lsb; 647 addr = t_master | csr_cal_rate_addr; 648 phy_io_write16(phy, addr, cal_rate); 649 } 650 651 static void prog_seq0bdly0(uint16_t *phy, 652 const struct input *input) 653 { 654 int ps_count[4]; 655 int frq; 656 uint32_t addr; 657 int lower_freq_opt = 0; 658 659 __unused const soc_info_t *soc_info; 660 661 frq = input->basic.frequency >> 1; 662 ps_count[0] = frq >> 3; /* 0.5 * frq / 4*/ 663 if (input->basic.frequency < 400) { 664 lower_freq_opt = (input->basic.dimm_type == RDIMM) ? 7 : 3; 665 } else if (input->basic.frequency < 533) { 666 lower_freq_opt = (input->basic.dimm_type == RDIMM) ? 14 : 11; 667 } 668 669 /* 1.0 * frq / 4 - lower_freq */ 670 ps_count[1] = (frq >> 2) - lower_freq_opt; 671 ps_count[2] = (frq << 1) + (frq >> 1); /* 10.0 * frq / 4 */ 672 673 #ifdef DDR_PLL_FIX 674 soc_info = get_soc_info(); 675 if (soc_info->maj_ver == 1) { 676 ps_count[0] = 0x520; /* seq0bdly0 */ 677 ps_count[1] = 0xa41; /* seq0bdly1 */ 678 ps_count[2] = 0x668a; /* seq0bdly2 */ 679 } 680 #endif 681 if (frq > 266) { 682 ps_count[3] = 44; 683 } else if (frq > 200) { 684 ps_count[3] = 33; 685 } else { 686 ps_count[3] = 16; 687 } 688 689 addr = t_master | csr_seq0bdly0_addr; 690 phy_io_write16(phy, addr, ps_count[0]); 691 692 debug("seq0bdly0 = 0x%x\n", phy_io_read16(phy, addr)); 693 694 addr = t_master | csr_seq0bdly1_addr; 695 phy_io_write16(phy, addr, ps_count[1]); 696 697 debug("seq0bdly1 = 0x%x\n", phy_io_read16(phy, addr)); 698 699 addr = t_master | csr_seq0bdly2_addr; 700 phy_io_write16(phy, addr, ps_count[2]); 701 702 debug("seq0bdly2 = 0x%x\n", phy_io_read16(phy, addr)); 703 704 addr = t_master | csr_seq0bdly3_addr; 705 phy_io_write16(phy, addr, ps_count[3]); 706 707 debug("seq0bdly3 = 0x%x\n", phy_io_read16(phy, addr)); 708 } 709 710 /* Only RDIMM requires msg_blk */ 711 static void i_load_pie(uint16_t **phy_ptr, 712 const struct input *input, 713 const void *msg) 714 { 715 int i; 716 uint16_t *phy; 717 718 for (i = 0; i < NUM_OF_DDRC; i++) { 719 phy = phy_ptr[i]; 720 if (phy == NULL) { 721 continue; 722 } 723 724 phy_io_write16(phy, 725 t_apbonly | csr_micro_cont_mux_sel_addr, 726 0U); 727 728 load_pieimage(phy, input->basic.dimm_type); 729 730 prog_seq0bdly0(phy, input); 731 phy_io_write16(phy, t_initeng | csr_seq0bdisable_flag0_addr, 732 U(0x0000)); 733 phy_io_write16(phy, t_initeng | csr_seq0bdisable_flag1_addr, 734 U(0x0173)); 735 phy_io_write16(phy, t_initeng | csr_seq0bdisable_flag2_addr, 736 U(0x0060)); 737 phy_io_write16(phy, t_initeng | csr_seq0bdisable_flag3_addr, 738 U(0x6110)); 739 phy_io_write16(phy, t_initeng | csr_seq0bdisable_flag4_addr, 740 U(0x2152)); 741 phy_io_write16(phy, t_initeng | csr_seq0bdisable_flag5_addr, 742 U(0xdfbd)); 743 phy_io_write16(phy, t_initeng | csr_seq0bdisable_flag6_addr, 744 input->basic.dimm_type == RDIMM && 745 input->adv.phy_gen2_umctl_opt == 1U ? 746 U(0x6000) : U(0xffff)); 747 phy_io_write16(phy, t_initeng | csr_seq0bdisable_flag7_addr, 748 U(0x6152)); 749 prog_acsm_playback(phy, input, msg); /* rdimm */ 750 prog_acsm_ctr(phy, input); /* rdimm */ 751 752 phy_io_write16(phy, t_master | csr_cal_zap_addr, U(0x1)); 753 prog_cal_rate_run(phy, input); 754 755 phy_io_write16(phy, t_drtub | csr_ucclk_hclk_enables_addr, 756 input->basic.dimm_type == RDIMM ? U(0x2) : 0U); 757 758 phy_io_write16(phy, t_apbonly | csr_micro_cont_mux_sel_addr, 1U); 759 } 760 } 761 762 static void phy_gen2_init_input(struct input *input) 763 { 764 int i; 765 766 input->adv.dram_byte_swap = 0; 767 input->adv.ext_cal_res_val = 0; 768 input->adv.tx_slew_rise_dq = 0xf; 769 input->adv.tx_slew_fall_dq = 0xf; 770 input->adv.tx_slew_rise_ac = 0xf; 771 input->adv.tx_slew_fall_ac = 0xf; 772 input->adv.mem_alert_en = 0; 773 input->adv.mem_alert_puimp = 5; 774 input->adv.mem_alert_vref_level = 0x29; 775 input->adv.mem_alert_sync_bypass = 0; 776 input->adv.cal_interval = 0x9; 777 input->adv.cal_once = 0; 778 input->adv.dis_dyn_adr_tri = 0; 779 input->adv.is2ttiming = 0; 780 input->adv.d4rx_preamble_length = 0; 781 input->adv.d4tx_preamble_length = 0; 782 783 for (i = 0; i < 7; i++) { 784 debug("mr[%d] = 0x%x\n", i, input->mr[i]); 785 } 786 787 debug("input->cs_d0 = 0x%x\n", input->cs_d0); 788 debug("input->cs_d1 = 0x%x\n", input->cs_d1); 789 debug("input->mirror = 0x%x\n", input->mirror); 790 debug("PHY ODT impedance = %d ohm\n", input->adv.odtimpedance); 791 debug("PHY DQ driver impedance = %d ohm\n", input->adv.tx_impedance); 792 debug("PHY Addr driver impedance = %d ohm\n", input->adv.atx_impedance); 793 794 for (i = 0; i < 4; i++) { 795 debug("odt[%d] = 0x%x\n", i, input->odt[i]); 796 } 797 798 if (input->basic.dimm_type == RDIMM) { 799 for (i = 0; i < 16; i++) { 800 debug("input->rcw[%d] = 0x%x\n", i, input->rcw[i]); 801 } 802 debug("input->rcw3x = 0x%x\n", input->rcw3x); 803 } 804 } 805 806 /* 807 * All protocols share the same base structure of message block. 808 * RDIMM and LRDIMM have more entries defined than UDIMM. 809 * Create message blocks for 1D and 2D training. 810 * Update len with message block size. 811 */ 812 static int phy_gen2_msg_init(void *msg_1d, 813 void *msg_2d, 814 const struct input *input) 815 { 816 struct ddr4u1d *msg_blk = msg_1d; 817 struct ddr4u2d *msg_blk_2d = msg_2d; 818 struct ddr4r1d *msg_blk_r; 819 struct ddr4lr1d *msg_blk_lr; 820 821 switch (input->basic.dimm_type) { 822 case UDIMM: 823 case SODIMM: 824 case NODIMM: 825 msg_blk->dram_type = U(0x2); 826 break; 827 case RDIMM: 828 msg_blk->dram_type = U(0x4); 829 break; 830 case LRDIMM: 831 msg_blk->dram_type = U(0x5); 832 break; 833 default: 834 ERROR("Unsupported DIMM type\n"); 835 return -EINVAL; 836 } 837 msg_blk->pstate = 0U; 838 839 /*Enable quickRd2D, a substage of read deskew, to 1D training.*/ 840 msg_blk->reserved00 = U(0x20); 841 842 /*Enable High-Effort WrDQ1D.*/ 843 msg_blk->reserved00 |= U(0x40); 844 845 /* Enable 1D extra effort training.*/ 846 msg_blk->reserved1c[3] = U(0x3); 847 848 if (input->basic.dimm_type == LRDIMM) { 849 msg_blk->sequence_ctrl = U(0x3f1f); 850 } else { 851 msg_blk->sequence_ctrl = U(0x031f); 852 } 853 msg_blk->phy_config_override = 0U; 854 #ifdef DDR_PHY_DEBUG 855 msg_blk->hdt_ctrl = U(0x5); 856 #else 857 msg_blk->hdt_ctrl = U(0xc9); 858 #endif 859 msg_blk->msg_misc = U(0x0); 860 msg_blk->dfimrlmargin = U(0x1); 861 msg_blk->phy_vref = input->vref ? input->vref : U(0x61); 862 msg_blk->cs_present = input->cs_d0 | input->cs_d1; 863 msg_blk->cs_present_d0 = input->cs_d0; 864 msg_blk->cs_present_d1 = input->cs_d1; 865 if (input->mirror != 0) { 866 msg_blk->addr_mirror = U(0x0a); /* odd CS are mirrored */ 867 } 868 msg_blk->share2dvref_result = 1U; 869 870 msg_blk->acsm_odt_ctrl0 = input->odt[0]; 871 msg_blk->acsm_odt_ctrl1 = input->odt[1]; 872 msg_blk->acsm_odt_ctrl2 = input->odt[2]; 873 msg_blk->acsm_odt_ctrl3 = input->odt[3]; 874 msg_blk->enabled_dqs = (input->basic.num_active_dbyte_dfi0 + 875 input->basic.num_active_dbyte_dfi1) * 8; 876 msg_blk->x16present = input->basic.dram_data_width == 0x10 ? 877 msg_blk->cs_present : 0; 878 msg_blk->d4misc = U(0x1); 879 msg_blk->cs_setup_gddec = U(0x1); 880 msg_blk->rtt_nom_wr_park0 = 0U; 881 msg_blk->rtt_nom_wr_park1 = 0U; 882 msg_blk->rtt_nom_wr_park2 = 0U; 883 msg_blk->rtt_nom_wr_park3 = 0U; 884 msg_blk->rtt_nom_wr_park4 = 0U; 885 msg_blk->rtt_nom_wr_park5 = 0U; 886 msg_blk->rtt_nom_wr_park6 = 0U; 887 msg_blk->rtt_nom_wr_park7 = 0U; 888 msg_blk->mr0 = input->mr[0]; 889 msg_blk->mr1 = input->mr[1]; 890 msg_blk->mr2 = input->mr[2]; 891 msg_blk->mr3 = input->mr[3]; 892 msg_blk->mr4 = input->mr[4]; 893 msg_blk->mr5 = input->mr[5]; 894 msg_blk->mr6 = input->mr[6]; 895 if ((msg_blk->mr4 & U(0x1c0)) != 0U) { 896 ERROR("Setting DRAM CAL mode is not supported\n"); 897 } 898 899 msg_blk->alt_cas_l = 0U; 900 msg_blk->alt_wcas_l = 0U; 901 902 msg_blk->dramfreq = input->basic.frequency * 2U; 903 msg_blk->pll_bypass_en = input->basic.pll_bypass; 904 msg_blk->dfi_freq_ratio = input->basic.dfi_freq_ratio == 0U ? 1U : 905 input->basic.dfi_freq_ratio == 1U ? 2U : 906 4U; 907 msg_blk->bpznres_val = input->adv.ext_cal_res_val; 908 msg_blk->disabled_dbyte = 0U; 909 910 debug("msg_blk->dram_type = 0x%x\n", msg_blk->dram_type); 911 debug("msg_blk->sequence_ctrl = 0x%x\n", msg_blk->sequence_ctrl); 912 debug("msg_blk->phy_cfg = 0x%x\n", msg_blk->phy_cfg); 913 debug("msg_blk->x16present = 0x%x\n", msg_blk->x16present); 914 debug("msg_blk->dramfreq = 0x%x\n", msg_blk->dramfreq); 915 debug("msg_blk->pll_bypass_en = 0x%x\n", msg_blk->pll_bypass_en); 916 debug("msg_blk->dfi_freq_ratio = 0x%x\n", msg_blk->dfi_freq_ratio); 917 debug("msg_blk->phy_odt_impedance = 0x%x\n", 918 msg_blk->phy_odt_impedance); 919 debug("msg_blk->phy_drv_impedance = 0x%x\n", 920 msg_blk->phy_drv_impedance); 921 debug("msg_blk->bpznres_val = 0x%x\n", msg_blk->bpznres_val); 922 debug("msg_blk->enabled_dqs = 0x%x\n", msg_blk->enabled_dqs); 923 debug("msg_blk->acsm_odt_ctrl0 = 0x%x\n", msg_blk->acsm_odt_ctrl0); 924 debug("msg_blk->acsm_odt_ctrl1 = 0x%x\n", msg_blk->acsm_odt_ctrl1); 925 debug("msg_blk->acsm_odt_ctrl2 = 0x%x\n", msg_blk->acsm_odt_ctrl2); 926 debug("msg_blk->acsm_odt_ctrl3 = 0x%x\n", msg_blk->acsm_odt_ctrl3); 927 928 /* RDIMM only */ 929 if (input->basic.dimm_type == RDIMM || 930 input->basic.dimm_type == LRDIMM) { 931 msg_blk_r = (struct ddr4r1d *)msg_blk; 932 if (msg_blk_r->cs_present_d0 != 0U) { 933 msg_blk_r->f0rc00_d0 = input->rcw[0]; 934 msg_blk_r->f0rc01_d0 = input->rcw[1]; 935 msg_blk_r->f0rc02_d0 = input->rcw[2]; 936 msg_blk_r->f0rc03_d0 = input->rcw[3]; 937 msg_blk_r->f0rc04_d0 = input->rcw[4]; 938 msg_blk_r->f0rc05_d0 = input->rcw[5]; 939 msg_blk_r->f0rc06_d0 = input->rcw[6]; 940 msg_blk_r->f0rc07_d0 = input->rcw[7]; 941 msg_blk_r->f0rc08_d0 = input->rcw[8]; 942 msg_blk_r->f0rc09_d0 = input->rcw[9]; 943 msg_blk_r->f0rc0a_d0 = input->rcw[10]; 944 msg_blk_r->f0rc0b_d0 = input->rcw[11]; 945 msg_blk_r->f0rc0c_d0 = input->rcw[12]; 946 msg_blk_r->f0rc0d_d0 = input->rcw[13]; 947 msg_blk_r->f0rc0e_d0 = input->rcw[14]; 948 msg_blk_r->f0rc0f_d0 = input->rcw[15]; 949 msg_blk_r->f0rc3x_d0 = input->rcw3x; 950 } 951 if (msg_blk_r->cs_present_d1 != 0) { 952 msg_blk_r->f0rc00_d1 = input->rcw[0]; 953 msg_blk_r->f0rc01_d1 = input->rcw[1]; 954 msg_blk_r->f0rc02_d1 = input->rcw[2]; 955 msg_blk_r->f0rc03_d1 = input->rcw[3]; 956 msg_blk_r->f0rc04_d1 = input->rcw[4]; 957 msg_blk_r->f0rc05_d1 = input->rcw[5]; 958 msg_blk_r->f0rc06_d1 = input->rcw[6]; 959 msg_blk_r->f0rc07_d1 = input->rcw[7]; 960 msg_blk_r->f0rc08_d1 = input->rcw[8]; 961 msg_blk_r->f0rc09_d1 = input->rcw[9]; 962 msg_blk_r->f0rc0a_d1 = input->rcw[10]; 963 msg_blk_r->f0rc0b_d1 = input->rcw[11]; 964 msg_blk_r->f0rc0c_d1 = input->rcw[12]; 965 msg_blk_r->f0rc0d_d1 = input->rcw[13]; 966 msg_blk_r->f0rc0e_d1 = input->rcw[14]; 967 msg_blk_r->f0rc0f_d1 = input->rcw[15]; 968 msg_blk_r->f0rc3x_d1 = input->rcw3x; 969 } 970 if (input->basic.dimm_type == LRDIMM) { 971 msg_blk_lr = (struct ddr4lr1d *)msg_blk; 972 msg_blk_lr->bc0a_d0 = msg_blk_lr->f0rc0a_d0; 973 msg_blk_lr->bc0a_d1 = msg_blk_lr->f0rc0a_d1; 974 msg_blk_lr->f0bc6x_d0 = msg_blk_lr->f0rc3x_d0; 975 msg_blk_lr->f0bc6x_d1 = msg_blk_lr->f0rc3x_d1; 976 } 977 } 978 979 /* below is different for 1D and 2D message block */ 980 if (input->basic.train2d != 0) { 981 memcpy(msg_blk_2d, msg_blk, sizeof(struct ddr4u1d)); 982 /*High-Effort WrDQ1D is applicable to 2D traning also*/ 983 msg_blk_2d->reserved00 |= U(0x40); 984 msg_blk_2d->sequence_ctrl = U(0x0061); 985 msg_blk_2d->rx2d_train_opt = 0U; 986 msg_blk_2d->tx2d_train_opt = 0U; 987 msg_blk_2d->share2dvref_result = 1U; 988 msg_blk_2d->delay_weight2d = U(0x20); 989 msg_blk_2d->voltage_weight2d = U(0x80); 990 debug("rx2d_train_opt %d, tx2d_train_opt %d\n", 991 msg_blk_2d->rx2d_train_opt, 992 msg_blk_2d->tx2d_train_opt); 993 } 994 995 msg_blk->phy_cfg = (((msg_blk->mr3 & U(0x8)) != 0U) || 996 ((msg_blk_2d->mr3 & 0x8) != 0U)) ? 0U 997 : input->adv.is2ttiming; 998 999 return 0; 1000 } 1001 1002 static void prog_tx_pre_drv_mode(uint16_t *phy, 1003 const struct input *input) 1004 { 1005 int lane, byte, b_addr, c_addr, p_addr; 1006 int tx_slew_rate, tx_pre_p, tx_pre_n; 1007 int tx_pre_drv_mode = 0x2; 1008 uint32_t addr; 1009 1010 /* Program TxPreDrvMode with 0x2 */ 1011 /* FIXME: TxPreDrvMode depends on DramType? */ 1012 tx_pre_p = input->adv.tx_slew_rise_dq; 1013 tx_pre_n = input->adv.tx_slew_fall_dq; 1014 tx_slew_rate = tx_pre_drv_mode << csr_tx_pre_drv_mode_lsb | 1015 tx_pre_p << csr_tx_pre_p_lsb | 1016 tx_pre_n << csr_tx_pre_n_lsb; 1017 p_addr = 0; 1018 for (byte = 0; byte < input->basic.num_dbyte; byte++) { 1019 c_addr = byte << 12; 1020 for (lane = 0; lane <= 1; lane++) { 1021 b_addr = lane << 8; 1022 addr = p_addr | t_dbyte | c_addr | b_addr | 1023 csr_tx_slew_rate_addr; 1024 phy_io_write16(phy, addr, tx_slew_rate); 1025 } 1026 } 1027 } 1028 1029 static void prog_atx_pre_drv_mode(uint16_t *phy, 1030 const struct input *input) 1031 { 1032 int anib, c_addr; 1033 int atx_slew_rate, atx_pre_p, atx_pre_n, atx_pre_drv_mode, 1034 ck_anib_inst[2]; 1035 uint32_t addr; 1036 1037 atx_pre_n = input->adv.tx_slew_fall_ac; 1038 atx_pre_p = input->adv.tx_slew_rise_ac; 1039 1040 if (input->basic.num_anib == 8) { 1041 ck_anib_inst[0] = 1; 1042 ck_anib_inst[1] = 1; 1043 } else if (input->basic.num_anib == 10 || input->basic.num_anib == 12 || 1044 input->basic.num_anib == 13) { 1045 ck_anib_inst[0] = 4; 1046 ck_anib_inst[1] = 5; 1047 } else { 1048 ERROR("Invalid number of aNIBs: %d\n", input->basic.num_anib); 1049 return; 1050 } 1051 1052 for (anib = 0; anib < input->basic.num_anib; anib++) { 1053 c_addr = anib << 12; 1054 if (anib == ck_anib_inst[0] || anib == ck_anib_inst[1]) { 1055 atx_pre_drv_mode = 0; 1056 } else { 1057 atx_pre_drv_mode = 3; 1058 } 1059 atx_slew_rate = atx_pre_drv_mode << csr_atx_pre_drv_mode_lsb | 1060 atx_pre_n << csr_atx_pre_n_lsb | 1061 atx_pre_p << csr_atx_pre_p_lsb; 1062 addr = t_anib | c_addr | csr_atx_slew_rate_addr; 1063 phy_io_write16(phy, addr, atx_slew_rate); 1064 } 1065 } 1066 1067 static void prog_enable_cs_multicast(uint16_t *phy, 1068 const struct input *input) 1069 { 1070 uint32_t addr = t_master | csr_enable_cs_multicast_addr; 1071 1072 if (input->basic.dimm_type != RDIMM && 1073 input->basic.dimm_type != LRDIMM) { 1074 return; 1075 } 1076 1077 phy_io_write16(phy, addr, input->adv.cast_cs_to_cid); 1078 } 1079 1080 static void prog_dfi_rd_data_cs_dest_map(uint16_t *phy, 1081 unsigned int ip_rev, 1082 const struct input *input, 1083 const struct ddr4lr1d *msg) 1084 { 1085 const struct ddr4lr1d *msg_blk; 1086 uint16_t dfi_xxdestm0 = 0U; 1087 uint16_t dfi_xxdestm1 = 0U; 1088 uint16_t dfi_xxdestm2 = 0U; 1089 uint16_t dfi_xxdestm3 = 0U; 1090 uint16_t dfi_rd_data_cs_dest_map; 1091 uint16_t dfi_wr_data_cs_dest_map; 1092 __unused const soc_info_t *soc_info; 1093 1094 #ifdef ERRATA_DDR_A011396 1095 /* Only apply to DDRC 5.05.00 */ 1096 soc_info = get_soc_info(NXP_DCFG_ADDR); 1097 if ((soc_info->maj_ver == 1U) && (ip_rev == U(0x50500))) { 1098 phy_io_write16(phy, 1099 t_master | csr_dfi_rd_data_cs_dest_map_addr, 1100 0U); 1101 return; 1102 } 1103 #endif 1104 1105 msg_blk = msg; 1106 1107 switch (input->basic.dimm_type) { 1108 case UDIMM: 1109 case SODIMM: 1110 case NODIMM: 1111 if ((msg_blk->msg_misc & U(0x40)) != 0U) { 1112 dfi_rd_data_cs_dest_map = U(0xa0); 1113 dfi_wr_data_cs_dest_map = U(0xa0); 1114 1115 phy_io_write16(phy, 1116 t_master | csr_dfi_rd_data_cs_dest_map_addr, 1117 dfi_rd_data_cs_dest_map); 1118 phy_io_write16(phy, 1119 t_master | csr_dfi_wr_data_cs_dest_map_addr, 1120 dfi_wr_data_cs_dest_map); 1121 } 1122 break; 1123 case LRDIMM: 1124 if (msg->cs_present_d1 != 0U) { 1125 dfi_xxdestm2 = 1U; 1126 dfi_xxdestm3 = 1U; 1127 } 1128 1129 dfi_rd_data_cs_dest_map = 1130 dfi_xxdestm0 << csr_dfi_rd_destm0_lsb | 1131 dfi_xxdestm1 << csr_dfi_rd_destm1_lsb | 1132 dfi_xxdestm2 << csr_dfi_rd_destm2_lsb | 1133 dfi_xxdestm3 << csr_dfi_rd_destm3_lsb; 1134 dfi_wr_data_cs_dest_map = 1135 dfi_xxdestm0 << csr_dfi_wr_destm0_lsb | 1136 dfi_xxdestm1 << csr_dfi_wr_destm1_lsb | 1137 dfi_xxdestm2 << csr_dfi_wr_destm2_lsb | 1138 dfi_xxdestm3 << csr_dfi_wr_destm3_lsb; 1139 phy_io_write16(phy, t_master | csr_dfi_rd_data_cs_dest_map_addr, 1140 dfi_rd_data_cs_dest_map); 1141 phy_io_write16(phy, t_master | csr_dfi_wr_data_cs_dest_map_addr, 1142 dfi_wr_data_cs_dest_map); 1143 1144 break; 1145 default: 1146 break; 1147 } 1148 } 1149 1150 static void prog_pll_ctrl(uint16_t *phy, 1151 const struct input *input) 1152 { 1153 uint32_t addr; 1154 int pll_ctrl1 = 0x21; /* 000100001b */ 1155 int pll_ctrl4 = 0x17f; /* 101111111b */ 1156 int pll_test_mode = 0x24; /* 00100100b */ 1157 1158 addr = t_master | csr_pll_ctrl1_addr; 1159 phy_io_write16(phy, addr, pll_ctrl1); 1160 1161 debug("pll_ctrl1 = 0x%x\n", phy_io_read16(phy, addr)); 1162 1163 addr = t_master | csr_pll_test_mode_addr; 1164 phy_io_write16(phy, addr, pll_test_mode); 1165 1166 debug("pll_test_mode = 0x%x\n", phy_io_read16(phy, addr)); 1167 1168 addr = t_master | csr_pll_ctrl4_addr; 1169 phy_io_write16(phy, addr, pll_ctrl4); 1170 1171 debug("pll_ctrl4 = 0x%x\n", phy_io_read16(phy, addr)); 1172 } 1173 1174 static void prog_pll_ctrl2(uint16_t *phy, 1175 const struct input *input) 1176 { 1177 int pll_ctrl2; 1178 uint32_t addr = t_master | csr_pll_ctrl2_addr; 1179 1180 if (input->basic.frequency / 2 < 235) { 1181 pll_ctrl2 = 0x7; 1182 } else if (input->basic.frequency / 2 < 313) { 1183 pll_ctrl2 = 0x6; 1184 } else if (input->basic.frequency / 2 < 469) { 1185 pll_ctrl2 = 0xb; 1186 } else if (input->basic.frequency / 2 < 625) { 1187 pll_ctrl2 = 0xa; 1188 } else if (input->basic.frequency / 2 < 938) { 1189 pll_ctrl2 = 0x19; 1190 } else if (input->basic.frequency / 2 < 1067) { 1191 pll_ctrl2 = 0x18; 1192 } else { 1193 pll_ctrl2 = 0x19; 1194 } 1195 1196 phy_io_write16(phy, addr, pll_ctrl2); 1197 1198 debug("pll_ctrl2 = 0x%x\n", phy_io_read16(phy, addr)); 1199 } 1200 1201 static void prog_dll_lck_param(uint16_t *phy, const struct input *input) 1202 { 1203 uint32_t addr = t_master | csr_dll_lockparam_addr; 1204 1205 phy_io_write16(phy, addr, U(0x212)); 1206 debug("dll_lck_param = 0x%x\n", phy_io_read16(phy, addr)); 1207 } 1208 1209 static void prog_dll_gain_ctl(uint16_t *phy, const struct input *input) 1210 { 1211 uint32_t addr = t_master | csr_dll_gain_ctl_addr; 1212 1213 phy_io_write16(phy, addr, U(0x61)); 1214 debug("dll_gain_ctl = 0x%x\n", phy_io_read16(phy, addr)); 1215 } 1216 1217 static void prog_pll_pwr_dn(uint16_t *phy, 1218 const struct input *input) 1219 { 1220 uint32_t addr; 1221 1222 addr = t_master | csr_pll_pwr_dn_addr; 1223 phy_io_write16(phy, addr, 0U); 1224 1225 debug("pll_pwrdn = 0x%x\n", phy_io_read16(phy, addr)); 1226 } 1227 1228 static void prog_ard_ptr_init_val(uint16_t *phy, 1229 const struct input *input) 1230 { 1231 int ard_ptr_init_val; 1232 uint32_t addr = t_master | csr_ard_ptr_init_val_addr; 1233 1234 if (input->basic.frequency >= 933) { 1235 ard_ptr_init_val = 0x2; 1236 } else { 1237 ard_ptr_init_val = 0x1; 1238 } 1239 1240 phy_io_write16(phy, addr, ard_ptr_init_val); 1241 } 1242 1243 static void prog_dqs_preamble_control(uint16_t *phy, 1244 const struct input *input) 1245 { 1246 int data; 1247 uint32_t addr = t_master | csr_dqs_preamble_control_addr; 1248 const int wdqsextension = 0; 1249 const int lp4sttc_pre_bridge_rx_en = 0; 1250 const int lp4postamble_ext = 0; 1251 const int lp4tgl_two_tck_tx_dqs_pre = 0; 1252 const int position_dfe_init = 2; 1253 const int dll_rx_preamble_mode = 1; 1254 int two_tck_tx_dqs_pre = input->adv.d4tx_preamble_length; 1255 int two_tck_rx_dqs_pre = input->adv.d4rx_preamble_length; 1256 1257 data = wdqsextension << csr_wdqsextension_lsb | 1258 lp4sttc_pre_bridge_rx_en << csr_lp4sttc_pre_bridge_rx_en_lsb | 1259 lp4postamble_ext << csr_lp4postamble_ext_lsb | 1260 lp4tgl_two_tck_tx_dqs_pre << csr_lp4tgl_two_tck_tx_dqs_pre_lsb | 1261 position_dfe_init << csr_position_dfe_init_lsb | 1262 two_tck_tx_dqs_pre << csr_two_tck_tx_dqs_pre_lsb | 1263 two_tck_rx_dqs_pre << csr_two_tck_rx_dqs_pre_lsb; 1264 phy_io_write16(phy, addr, data); 1265 1266 data = dll_rx_preamble_mode << csr_dll_rx_preamble_mode_lsb; 1267 addr = t_master | csr_dbyte_dll_mode_cntrl_addr; 1268 phy_io_write16(phy, addr, data); 1269 } 1270 1271 static void prog_proc_odt_time_ctl(uint16_t *phy, 1272 const struct input *input) 1273 { 1274 int proc_odt_time_ctl; 1275 uint32_t addr = t_master | csr_proc_odt_time_ctl_addr; 1276 1277 if (input->adv.wdqsext != 0) { 1278 proc_odt_time_ctl = 0x3; 1279 } else if (input->basic.frequency <= 933) { 1280 proc_odt_time_ctl = 0xa; 1281 } else if (input->basic.frequency <= 1200) { 1282 if (input->adv.d4rx_preamble_length == 1) { 1283 proc_odt_time_ctl = 0x2; 1284 } else { 1285 proc_odt_time_ctl = 0x6; 1286 } 1287 } else { 1288 if (input->adv.d4rx_preamble_length == 1) { 1289 proc_odt_time_ctl = 0x3; 1290 } else { 1291 proc_odt_time_ctl = 0x7; 1292 } 1293 } 1294 phy_io_write16(phy, addr, proc_odt_time_ctl); 1295 } 1296 1297 static const struct impedance_mapping map[] = { 1298 { 29, 0x3f }, 1299 { 31, 0x3e }, 1300 { 33, 0x3b }, 1301 { 36, 0x3a }, 1302 { 39, 0x39 }, 1303 { 42, 0x38 }, 1304 { 46, 0x1b }, 1305 { 51, 0x1a }, 1306 { 57, 0x19 }, 1307 { 64, 0x18 }, 1308 { 74, 0x0b }, 1309 { 88, 0x0a }, 1310 { 108, 0x09 }, 1311 { 140, 0x08 }, 1312 { 200, 0x03 }, 1313 { 360, 0x02 }, 1314 { 481, 0x01 }, 1315 {} 1316 }; 1317 1318 static int map_impedance(int strength) 1319 { 1320 const struct impedance_mapping *tbl = map; 1321 int val = 0; 1322 1323 if (strength == 0) { 1324 return 0; 1325 } 1326 1327 while (tbl->ohm != 0U) { 1328 if (strength < tbl->ohm) { 1329 val = tbl->code; 1330 break; 1331 } 1332 tbl++; 1333 } 1334 1335 return val; 1336 } 1337 1338 static int map_odtstren_p(int strength, int hard_macro_ver) 1339 { 1340 int val = -1; 1341 1342 if (hard_macro_ver == 4) { 1343 if (strength == 0) { 1344 val = 0; 1345 } else if (strength == 120) { 1346 val = 0x8; 1347 } else if (strength == 60) { 1348 val = 0x18; 1349 } else if (strength == 40) { 1350 val = 0x38; 1351 } else { 1352 printf("error: unsupported ODTStrenP %d\n", strength); 1353 } 1354 } else { 1355 val = map_impedance(strength); 1356 } 1357 1358 return val; 1359 } 1360 1361 static void prog_tx_odt_drv_stren(uint16_t *phy, 1362 const struct input *input) 1363 { 1364 int lane, byte, b_addr, c_addr; 1365 int tx_odt_drv_stren; 1366 int odtstren_p, odtstren_n; 1367 uint32_t addr; 1368 1369 odtstren_p = map_odtstren_p(input->adv.odtimpedance, 1370 input->basic.hard_macro_ver); 1371 if (odtstren_p < 0) { 1372 return; 1373 } 1374 1375 odtstren_n = 0; /* always high-z */ 1376 tx_odt_drv_stren = odtstren_n << csr_odtstren_n_lsb | odtstren_p; 1377 for (byte = 0; byte < input->basic.num_dbyte; byte++) { 1378 c_addr = byte << 12; 1379 for (lane = 0; lane <= 1; lane++) { 1380 b_addr = lane << 8; 1381 addr = t_dbyte | c_addr | b_addr | 1382 csr_tx_odt_drv_stren_addr; 1383 phy_io_write16(phy, addr, tx_odt_drv_stren); 1384 } 1385 } 1386 } 1387 1388 static int map_drvstren_fsdq_p(int strength, int hard_macro_ver) 1389 { 1390 int val = -1; 1391 1392 if (hard_macro_ver == 4) { 1393 if (strength == 0) { 1394 val = 0x07; 1395 } else if (strength == 120) { 1396 val = 0x0F; 1397 } else if (strength == 60) { 1398 val = 0x1F; 1399 } else if (strength == 40) { 1400 val = 0x3F; 1401 } else { 1402 printf("error: unsupported drv_stren_fSDq_p %d\n", 1403 strength); 1404 } 1405 } else { 1406 val = map_impedance(strength); 1407 } 1408 1409 return val; 1410 } 1411 1412 static int map_drvstren_fsdq_n(int strength, int hard_macro_ver) 1413 { 1414 int val = -1; 1415 1416 if (hard_macro_ver == 4) { 1417 if (strength == 0) { 1418 val = 0x00; 1419 } else if (strength == 120) { 1420 val = 0x08; 1421 } else if (strength == 60) { 1422 val = 0x18; 1423 } else if (strength == 40) { 1424 val = 0x38; 1425 } else { 1426 printf("error: unsupported drvStrenFSDqN %d\n", 1427 strength); 1428 } 1429 } else { 1430 val = map_impedance(strength); 1431 } 1432 1433 return val; 1434 } 1435 1436 static void prog_tx_impedance_ctrl1(uint16_t *phy, 1437 const struct input *input) 1438 { 1439 int lane, byte, b_addr, c_addr; 1440 int tx_impedance_ctrl1; 1441 int drv_stren_fsdq_p, drv_stren_fsdq_n; 1442 uint32_t addr; 1443 1444 drv_stren_fsdq_p = map_drvstren_fsdq_p(input->adv.tx_impedance, 1445 input->basic.hard_macro_ver); 1446 drv_stren_fsdq_n = map_drvstren_fsdq_n(input->adv.tx_impedance, 1447 input->basic.hard_macro_ver); 1448 tx_impedance_ctrl1 = drv_stren_fsdq_n << csr_drv_stren_fsdq_n_lsb | 1449 drv_stren_fsdq_p << csr_drv_stren_fsdq_p_lsb; 1450 1451 for (byte = 0; byte < input->basic.num_dbyte; byte++) { 1452 c_addr = byte << 12; 1453 for (lane = 0; lane <= 1; lane++) { 1454 b_addr = lane << 8; 1455 addr = t_dbyte | c_addr | b_addr | 1456 csr_tx_impedance_ctrl1_addr; 1457 phy_io_write16(phy, addr, tx_impedance_ctrl1); 1458 } 1459 } 1460 } 1461 1462 static int map_adrv_stren_p(int strength, int hard_macro_ver) 1463 { 1464 int val = -1; 1465 1466 if (hard_macro_ver == 4) { 1467 if (strength == 120) { 1468 val = 0x1c; 1469 } else if (strength == 60) { 1470 val = 0x1d; 1471 } else if (strength == 40) { 1472 val = 0x1f; 1473 } else { 1474 printf("error: unsupported aDrv_stren_p %d\n", 1475 strength); 1476 } 1477 } else { 1478 if (strength == 120) { 1479 val = 0x00; 1480 } else if (strength == 60) { 1481 val = 0x01; 1482 } else if (strength == 40) { 1483 val = 0x03; 1484 } else if (strength == 30) { 1485 val = 0x07; 1486 } else if (strength == 24) { 1487 val = 0x0f; 1488 } else if (strength == 20) { 1489 val = 0x1f; 1490 } else { 1491 printf("error: unsupported aDrv_stren_p %d\n", 1492 strength); 1493 } 1494 } 1495 1496 return val; 1497 } 1498 1499 static int map_adrv_stren_n(int strength, int hard_macro_ver) 1500 { 1501 int val = -1; 1502 1503 if (hard_macro_ver == 4) { 1504 if (strength == 120) { 1505 val = 0x00; 1506 } else if (strength == 60) { 1507 val = 0x01; 1508 } else if (strength == 40) { 1509 val = 0x03; 1510 } else { 1511 printf("Error: unsupported ADrvStrenP %d\n", strength); 1512 } 1513 } else { 1514 if (strength == 120) { 1515 val = 0x00; 1516 } else if (strength == 60) { 1517 val = 0x01; 1518 } else if (strength == 40) { 1519 val = 0x03; 1520 } else if (strength == 30) { 1521 val = 0x07; 1522 } else if (strength == 24) { 1523 val = 0x0f; 1524 } else if (strength == 20) { 1525 val = 0x1f; 1526 } else { 1527 printf("Error: unsupported ADrvStrenP %d\n", strength); 1528 } 1529 } 1530 1531 return val; 1532 } 1533 1534 static void prog_atx_impedance(uint16_t *phy, 1535 const struct input *input) 1536 { 1537 int anib, c_addr; 1538 int atx_impedance; 1539 int adrv_stren_p; 1540 int adrv_stren_n; 1541 uint32_t addr; 1542 1543 if (input->basic.hard_macro_ver == 4 && 1544 input->adv.atx_impedance == 20) { 1545 printf("Error:ATxImpedance has to be 40 for HardMacroVer 4\n"); 1546 return; 1547 } 1548 1549 adrv_stren_p = map_adrv_stren_p(input->adv.atx_impedance, 1550 input->basic.hard_macro_ver); 1551 adrv_stren_n = map_adrv_stren_n(input->adv.atx_impedance, 1552 input->basic.hard_macro_ver); 1553 atx_impedance = adrv_stren_n << csr_adrv_stren_n_lsb | 1554 adrv_stren_p << csr_adrv_stren_p_lsb; 1555 for (anib = 0; anib < input->basic.num_anib; anib++) { 1556 c_addr = anib << 12; 1557 addr = t_anib | c_addr | csr_atx_impedance_addr; 1558 phy_io_write16(phy, addr, atx_impedance); 1559 } 1560 } 1561 1562 static void prog_dfi_mode(uint16_t *phy, 1563 const struct input *input) 1564 { 1565 int dfi_mode; 1566 uint32_t addr; 1567 1568 if (input->basic.dfi1exists == 1) { 1569 dfi_mode = 0x5; /* DFI1 exists but disabled */ 1570 } else { 1571 dfi_mode = 0x1; /* DFI1 does not physically exists */ 1572 } 1573 addr = t_master | csr_dfi_mode_addr; 1574 phy_io_write16(phy, addr, dfi_mode); 1575 } 1576 1577 static void prog_acx4_anib_dis(uint16_t *phy, const struct input *input) 1578 { 1579 uint32_t addr; 1580 1581 addr = t_master | csr_acx4_anib_dis_addr; 1582 phy_io_write16(phy, addr, 0x0); 1583 debug("%s 0x%x\n", __func__, phy_io_read16(phy, addr)); 1584 } 1585 1586 static void prog_dfi_camode(uint16_t *phy, 1587 const struct input *input) 1588 { 1589 int dfi_camode = 2; 1590 uint32_t addr = t_master | csr_dfi_camode_addr; 1591 1592 phy_io_write16(phy, addr, dfi_camode); 1593 } 1594 1595 static void prog_cal_drv_str0(uint16_t *phy, 1596 const struct input *input) 1597 { 1598 int cal_drv_str0; 1599 int cal_drv_str_pd50; 1600 int cal_drv_str_pu50; 1601 uint32_t addr; 1602 1603 cal_drv_str_pu50 = input->adv.ext_cal_res_val; 1604 cal_drv_str_pd50 = cal_drv_str_pu50; 1605 cal_drv_str0 = cal_drv_str_pu50 << csr_cal_drv_str_pu50_lsb | 1606 cal_drv_str_pd50; 1607 addr = t_master | csr_cal_drv_str0_addr; 1608 phy_io_write16(phy, addr, cal_drv_str0); 1609 } 1610 1611 static void prog_cal_uclk_info(uint16_t *phy, 1612 const struct input *input) 1613 { 1614 int cal_uclk_ticks_per1u_s; 1615 uint32_t addr; 1616 1617 cal_uclk_ticks_per1u_s = input->basic.frequency >> 1; 1618 if (cal_uclk_ticks_per1u_s < 24) { 1619 cal_uclk_ticks_per1u_s = 24; 1620 } 1621 1622 addr = t_master | csr_cal_uclk_info_addr; 1623 phy_io_write16(phy, addr, cal_uclk_ticks_per1u_s); 1624 } 1625 1626 static void prog_cal_rate(uint16_t *phy, 1627 const struct input *input) 1628 { 1629 int cal_rate; 1630 int cal_interval; 1631 int cal_once; 1632 uint32_t addr; 1633 1634 cal_interval = input->adv.cal_interval; 1635 cal_once = input->adv.cal_once; 1636 cal_rate = cal_once << csr_cal_once_lsb | 1637 cal_interval << csr_cal_interval_lsb; 1638 addr = t_master | csr_cal_rate_addr; 1639 phy_io_write16(phy, addr, cal_rate); 1640 } 1641 1642 static void prog_vref_in_global(uint16_t *phy, 1643 const struct input *input, 1644 const struct ddr4u1d *msg) 1645 { 1646 int vref_in_global; 1647 int global_vref_in_dac = 0; 1648 int global_vref_in_sel = 0; 1649 uint32_t addr; 1650 1651 /* 1652 * phy_vref_prcnt = msg->phy_vref / 128.0 1653 * global_vref_in_dac = (phy_vref_prcnt - 0.345) / 0.005; 1654 */ 1655 global_vref_in_dac = (msg->phy_vref * 1000 - 345 * 128 + 320) / 1656 (5 * 128); 1657 1658 vref_in_global = global_vref_in_dac << csr_global_vref_in_dac_lsb | 1659 global_vref_in_sel; 1660 addr = t_master | csr_vref_in_global_addr; 1661 phy_io_write16(phy, addr, vref_in_global); 1662 } 1663 1664 static void prog_dq_dqs_rcv_cntrl(uint16_t *phy, 1665 const struct input *input) 1666 { 1667 int lane, byte, b_addr, c_addr; 1668 int dq_dqs_rcv_cntrl; 1669 int gain_curr_adj_defval = 0xb; 1670 int major_mode_dbyte = 3; 1671 int dfe_ctrl_defval = 0; 1672 int ext_vref_range_defval = 0; 1673 int sel_analog_vref = 1; 1674 uint32_t addr; 1675 1676 dq_dqs_rcv_cntrl = gain_curr_adj_defval << csr_gain_curr_adj_lsb | 1677 major_mode_dbyte << csr_major_mode_dbyte_lsb | 1678 dfe_ctrl_defval << csr_dfe_ctrl_lsb | 1679 ext_vref_range_defval << csr_ext_vref_range_lsb | 1680 sel_analog_vref << csr_sel_analog_vref_lsb; 1681 for (byte = 0; byte < input->basic.num_dbyte; byte++) { 1682 c_addr = byte << 12; 1683 for (lane = 0; lane <= 1; lane++) { 1684 b_addr = lane << 8; 1685 addr = t_dbyte | c_addr | b_addr | 1686 csr_dq_dqs_rcv_cntrl_addr; 1687 phy_io_write16(phy, addr, dq_dqs_rcv_cntrl); 1688 } 1689 } 1690 } 1691 1692 static void prog_mem_alert_control(uint16_t *phy, 1693 const struct input *input) 1694 { 1695 int mem_alert_control; 1696 int mem_alert_control2; 1697 int malertpu_en; 1698 int malertrx_en; 1699 int malertvref_level; 1700 int malertpu_stren; 1701 int malertsync_bypass; 1702 int malertdisable_val_defval = 1; 1703 uint32_t addr; 1704 1705 if (input->basic.dram_type == DDR4 && input->adv.mem_alert_en == 1) { 1706 malertpu_en = 1; 1707 malertrx_en = 1; 1708 malertpu_stren = input->adv.mem_alert_puimp; 1709 malertvref_level = input->adv.mem_alert_vref_level; 1710 malertsync_bypass = input->adv.mem_alert_sync_bypass; 1711 mem_alert_control = malertdisable_val_defval << 14 | 1712 malertrx_en << 13 | 1713 malertpu_en << 12 | 1714 malertpu_stren << 8 | 1715 malertvref_level; 1716 mem_alert_control2 = malertsync_bypass << 1717 csr_malertsync_bypass_lsb; 1718 addr = t_master | csr_mem_alert_control_addr; 1719 phy_io_write16(phy, addr, mem_alert_control); 1720 addr = t_master | csr_mem_alert_control2_addr; 1721 phy_io_write16(phy, addr, mem_alert_control2); 1722 } 1723 } 1724 1725 static void prog_dfi_freq_ratio(uint16_t *phy, 1726 const struct input *input) 1727 { 1728 int dfi_freq_ratio; 1729 uint32_t addr = t_master | csr_dfi_freq_ratio_addr; 1730 1731 dfi_freq_ratio = input->basic.dfi_freq_ratio; 1732 phy_io_write16(phy, addr, dfi_freq_ratio); 1733 } 1734 1735 static void prog_tristate_mode_ca(uint16_t *phy, 1736 const struct input *input) 1737 { 1738 int tristate_mode_ca; 1739 int dis_dyn_adr_tri; 1740 int ddr2tmode; 1741 int ck_dis_val_def = 1; 1742 uint32_t addr = t_master | csr_tristate_mode_ca_addr; 1743 1744 dis_dyn_adr_tri = input->adv.dis_dyn_adr_tri; 1745 ddr2tmode = input->adv.is2ttiming; 1746 tristate_mode_ca = ck_dis_val_def << csr_ck_dis_val_lsb | 1747 ddr2tmode << csr_ddr2tmode_lsb | 1748 dis_dyn_adr_tri << csr_dis_dyn_adr_tri_lsb; 1749 phy_io_write16(phy, addr, tristate_mode_ca); 1750 } 1751 1752 static void prog_dfi_xlat(uint16_t *phy, 1753 const struct input *input) 1754 { 1755 uint16_t loop_vector; 1756 int dfifreqxlat_dat; 1757 int pllbypass_dat; 1758 uint32_t addr; 1759 1760 /* fIXME: Shall unused P1, P2, P3 be bypassed? */ 1761 pllbypass_dat = input->basic.pll_bypass; /* only [0] is used */ 1762 for (loop_vector = 0; loop_vector < 8; loop_vector++) { 1763 if (loop_vector == 0) { 1764 dfifreqxlat_dat = pllbypass_dat + 0x5555; 1765 } else if (loop_vector == 7) { 1766 dfifreqxlat_dat = 0xf000; 1767 } else { 1768 dfifreqxlat_dat = 0x5555; 1769 } 1770 addr = t_master | (csr_dfi_freq_xlat0_addr + loop_vector); 1771 phy_io_write16(phy, addr, dfifreqxlat_dat); 1772 } 1773 } 1774 1775 static void prog_dbyte_misc_mode(uint16_t *phy, 1776 const struct input *input, 1777 const struct ddr4u1d *msg) 1778 { 1779 int dbyte_misc_mode; 1780 int dq_dqs_rcv_cntrl1; 1781 int dq_dqs_rcv_cntrl1_1; 1782 int byte, c_addr; 1783 uint32_t addr; 1784 1785 dbyte_misc_mode = 0x1 << csr_dbyte_disable_lsb; 1786 dq_dqs_rcv_cntrl1 = 0x1ff << csr_power_down_rcvr_lsb | 1787 0x1 << csr_power_down_rcvr_dqs_lsb | 1788 0x1 << csr_rx_pad_standby_en_lsb; 1789 dq_dqs_rcv_cntrl1_1 = (0x100 << csr_power_down_rcvr_lsb | 1790 csr_rx_pad_standby_en_mask); 1791 for (byte = 0; byte < input->basic.num_dbyte; byte++) { 1792 c_addr = byte << 12; 1793 if (byte <= input->basic.num_active_dbyte_dfi0 - 1) { 1794 /* disable RDBI lane if not used. */ 1795 if ((input->basic.dram_data_width != 4) && 1796 (((msg->mr5 >> 12) & 0x1) == 0)) { 1797 addr = t_dbyte 1798 | c_addr 1799 | csr_dq_dqs_rcv_cntrl1_addr; 1800 phy_io_write16(phy, addr, dq_dqs_rcv_cntrl1_1); 1801 } 1802 } else { 1803 addr = t_dbyte | c_addr | csr_dbyte_misc_mode_addr; 1804 phy_io_write16(phy, addr, dbyte_misc_mode); 1805 addr = t_dbyte | c_addr | csr_dq_dqs_rcv_cntrl1_addr; 1806 phy_io_write16(phy, addr, dq_dqs_rcv_cntrl1); 1807 } 1808 } 1809 } 1810 1811 static void prog_master_x4config(uint16_t *phy, 1812 const struct input *input) 1813 { 1814 int master_x4config; 1815 int x4tg; 1816 uint32_t addr = t_master | csr_master_x4config_addr; 1817 1818 x4tg = input->basic.dram_data_width == 4 ? 0xf : 0; 1819 master_x4config = x4tg << csr_x4tg_lsb; 1820 phy_io_write16(phy, addr, master_x4config); 1821 } 1822 1823 static void prog_dmipin_present(uint16_t *phy, 1824 const struct input *input, 1825 const struct ddr4u1d *msg) 1826 { 1827 int dmipin_present; 1828 uint32_t addr = t_master | csr_dmipin_present_addr; 1829 1830 dmipin_present = (msg->mr5 >> 12) & 0x1; 1831 phy_io_write16(phy, addr, dmipin_present); 1832 } 1833 1834 static void prog_dfi_phyupd(uint16_t *phy, 1835 const struct input *input) 1836 { 1837 int dfiphyupd_dat; 1838 uint32_t addr; 1839 1840 addr = t_master | (csr_dfiphyupd_addr); 1841 dfiphyupd_dat = phy_io_read16(phy, addr) & 1842 ~csr_dfiphyupd_threshold_mask; 1843 1844 phy_io_write16(phy, addr, dfiphyupd_dat); 1845 } 1846 1847 static void prog_cal_misc2(uint16_t *phy, 1848 const struct input *input) 1849 { 1850 int cal_misc2_dat, cal_drv_pdth_data, cal_offsets_dat; 1851 uint32_t addr; 1852 1853 addr = t_master | (csr_cal_misc2_addr); 1854 cal_misc2_dat = phy_io_read16(phy, addr) | 1855 (1 << csr_cal_misc2_err_dis); 1856 1857 phy_io_write16(phy, addr, cal_misc2_dat); 1858 1859 addr = t_master | (csr_cal_offsets_addr); 1860 1861 cal_drv_pdth_data = 0x9 << 6; 1862 cal_offsets_dat = (phy_io_read16(phy, addr) & ~csr_cal_drv_pdth_mask) 1863 | cal_drv_pdth_data; 1864 1865 phy_io_write16(phy, addr, cal_offsets_dat); 1866 } 1867 1868 static int c_init_phy_config(uint16_t **phy_ptr, 1869 unsigned int ip_rev, 1870 const struct input *input, 1871 const void *msg) 1872 { 1873 int i; 1874 uint16_t *phy; 1875 __unused const soc_info_t *soc_info; 1876 1877 for (i = 0; i < NUM_OF_DDRC; i++) { 1878 phy = phy_ptr[i]; 1879 if (phy == NULL) { 1880 continue; 1881 } 1882 1883 debug("Initialize PHY %d config\n", i); 1884 prog_dfi_phyupd(phy, input); 1885 prog_cal_misc2(phy, input); 1886 prog_tx_pre_drv_mode(phy, input); 1887 prog_atx_pre_drv_mode(phy, input); 1888 prog_enable_cs_multicast(phy, input); /* rdimm and lrdimm */ 1889 prog_dfi_rd_data_cs_dest_map(phy, ip_rev, input, msg); 1890 prog_pll_ctrl2(phy, input); 1891 #ifdef DDR_PLL_FIX 1892 soc_info = get_soc_info(); 1893 debug("SOC_SI_REV = %x\n", soc_info->maj_ver); 1894 if (soc_info->maj_ver == 1) { 1895 prog_pll_pwr_dn(phy, input); 1896 1897 /*Enable FFE aka TxEqualizationMode for rev1 SI*/ 1898 phy_io_write16(phy, 0x010048, 0x1); 1899 } 1900 #endif 1901 prog_ard_ptr_init_val(phy, input); 1902 prog_dqs_preamble_control(phy, input); 1903 prog_dll_lck_param(phy, input); 1904 prog_dll_gain_ctl(phy, input); 1905 prog_proc_odt_time_ctl(phy, input); 1906 prog_tx_odt_drv_stren(phy, input); 1907 prog_tx_impedance_ctrl1(phy, input); 1908 prog_atx_impedance(phy, input); 1909 prog_dfi_mode(phy, input); 1910 prog_dfi_camode(phy, input); 1911 prog_cal_drv_str0(phy, input); 1912 prog_cal_uclk_info(phy, input); 1913 prog_cal_rate(phy, input); 1914 prog_vref_in_global(phy, input, msg); 1915 prog_dq_dqs_rcv_cntrl(phy, input); 1916 prog_mem_alert_control(phy, input); 1917 prog_dfi_freq_ratio(phy, input); 1918 prog_tristate_mode_ca(phy, input); 1919 prog_dfi_xlat(phy, input); 1920 prog_dbyte_misc_mode(phy, input, msg); 1921 prog_master_x4config(phy, input); 1922 prog_dmipin_present(phy, input, msg); 1923 prog_acx4_anib_dis(phy, input); 1924 } 1925 1926 return 0; 1927 } 1928 1929 static uint32_t get_mail(uint16_t *phy, int stream) 1930 { 1931 int timeout; 1932 uint32_t mail = 0U; 1933 1934 timeout = TIMEOUTDEFAULT; 1935 while (((--timeout) != 0) && 1936 ((phy_io_read16(phy, t_apbonly | csr_uct_shadow_regs) 1937 & uct_write_prot_shadow_mask) != 0)) { 1938 mdelay(10); 1939 } 1940 if (timeout == 0) { 1941 ERROR("Timeout getting mail from PHY\n"); 1942 return 0xFFFF; 1943 } 1944 1945 mail = phy_io_read16(phy, t_apbonly | 1946 csr_uct_write_only_shadow); 1947 if (stream != 0) { 1948 mail |= phy_io_read16(phy, t_apbonly | 1949 csr_uct_dat_write_only_shadow) << 16; 1950 } 1951 1952 /* Ack */ 1953 phy_io_write16(phy, t_apbonly | csr_dct_write_prot, 0); 1954 1955 timeout = TIMEOUTDEFAULT; 1956 while (((--timeout) != 0) && 1957 ((phy_io_read16(phy, t_apbonly | csr_uct_shadow_regs) 1958 & uct_write_prot_shadow_mask) == 0)) { 1959 mdelay(1); 1960 } 1961 if (timeout == 0) { 1962 ERROR("Timeout ack PHY mail\n"); 1963 } 1964 1965 /* completed */ 1966 phy_io_write16(phy, t_apbonly | csr_dct_write_prot, 1U); 1967 1968 return mail; 1969 } 1970 1971 #ifdef DDR_PHY_DEBUG 1972 static const char *lookup_msg(uint32_t index, int train2d) 1973 { 1974 int i; 1975 int size; 1976 const struct phy_msg *messages; 1977 const char *ptr = NULL; 1978 1979 if (train2d != 0) { 1980 messages = messages_2d; 1981 size = ARRAY_SIZE(messages_2d); 1982 } else { 1983 messages = messages_1d; 1984 size = ARRAY_SIZE(messages_1d); 1985 } 1986 for (i = 0; i < size; i++) { 1987 if (messages[i].index == index) { 1988 ptr = messages[i].msg; 1989 break; 1990 } 1991 } 1992 1993 return ptr; 1994 } 1995 #endif 1996 1997 #define MAX_ARGS 32 1998 static void decode_stream_message(uint16_t *phy, int train2d) 1999 { 2000 uint32_t index __unused; 2001 2002 __unused const char *format; 2003 __unused uint32_t args[MAX_ARGS]; 2004 __unused int i; 2005 2006 #ifdef DDR_PHY_DEBUG 2007 index = get_mail(phy, 1); 2008 if ((index & 0xffff) > MAX_ARGS) { /* up to MAX_ARGS args so far */ 2009 printf("Program error in %s\n", __func__); 2010 } 2011 for (i = 0; i < (index & 0xffff) && i < MAX_ARGS; i++) { 2012 args[i] = get_mail(phy, 1); 2013 } 2014 2015 format = lookup_msg(index, train2d); 2016 if (format != NULL) { 2017 printf("0x%08x: ", index); 2018 printf(format, args[0], args[1], args[2], args[3], args[4], 2019 args[5], args[6], args[7], args[8], args[9], args[10], 2020 args[11], args[12], args[13], args[14], args[15], 2021 args[16], args[17], args[18], args[19], args[20], 2022 args[21], args[22], args[23], args[24], args[25], 2023 args[26], args[27], args[28], args[29], args[30], 2024 args[31]); 2025 } 2026 #endif 2027 } 2028 2029 static int wait_fw_done(uint16_t *phy, int train2d) 2030 { 2031 uint32_t mail = 0U; 2032 2033 while (mail == U(0x0)) { 2034 mail = get_mail(phy, 0); 2035 switch (mail) { 2036 case U(0x7): 2037 debug("%s Training completed\n", train2d ? "2D" : "1D"); 2038 break; 2039 case U(0xff): 2040 debug("%s Training failure\n", train2d ? "2D" : "1D"); 2041 break; 2042 case U(0x0): 2043 debug("End of initialization\n"); 2044 mail = 0U; 2045 break; 2046 case U(0x1): 2047 debug("End of fine write leveling\n"); 2048 mail = 0U; 2049 break; 2050 case U(0x2): 2051 debug("End of read enable training\n"); 2052 mail = 0U; 2053 break; 2054 case U(0x3): 2055 debug("End of read delay center optimization\n"); 2056 mail = 0U; 2057 break; 2058 case U(0x4): 2059 debug("End of write delay center optimization\n"); 2060 mail = 0U; 2061 break; 2062 case U(0x5): 2063 debug("End of 2D read delay/voltage center optimztn\n"); 2064 mail = 0U; 2065 break; 2066 case U(0x6): 2067 debug("End of 2D write delay/voltage center optmztn\n"); 2068 mail = 0U; 2069 break; 2070 case U(0x8): 2071 decode_stream_message(phy, train2d); 2072 mail = 0U; 2073 break; 2074 case U(0x9): 2075 debug("End of max read latency training\n"); 2076 mail = 0U; 2077 break; 2078 case U(0xa): 2079 debug("End of read dq deskew training\n"); 2080 mail = 0U; 2081 break; 2082 case U(0xc): 2083 debug("End of LRDIMM Specific training, including:\n"); 2084 debug("/tDWL, MREP, MRD and MWD\n"); 2085 mail = 0U; 2086 break; 2087 case U(0xd): 2088 debug("End of CA training\n"); 2089 mail = 0U; 2090 break; 2091 case U(0xfd): 2092 debug("End of MPR read delay center optimization\n"); 2093 mail = 0U; 2094 break; 2095 case U(0xfe): 2096 debug("End of Write leveling coarse delay\n"); 2097 mail = 0U; 2098 break; 2099 case U(0xffff): 2100 debug("Timed out\n"); 2101 break; 2102 default: 2103 mail = 0U; 2104 break; 2105 } 2106 } 2107 2108 if (mail == U(0x7)) { 2109 return 0; 2110 } else if (mail == U(0xff)) { 2111 return -EIO; 2112 } else if (mail == U(0xffff)) { 2113 return -ETIMEDOUT; 2114 } 2115 2116 debug("PHY_GEN2 FW: Unxpected mail = 0x%x\n", mail); 2117 2118 return -EINVAL; 2119 } 2120 2121 static int g_exec_fw(uint16_t **phy_ptr, int train2d, struct input *input) 2122 { 2123 int ret = -EINVAL; 2124 int i; 2125 uint16_t *phy; 2126 2127 for (i = 0; i < NUM_OF_DDRC; i++) { 2128 phy = phy_ptr[i]; 2129 if (phy == NULL) { 2130 continue; 2131 } 2132 debug("Applying PLL optimal settings\n"); 2133 prog_pll_ctrl2(phy, input); 2134 prog_pll_ctrl(phy, input); 2135 phy_io_write16(phy, 2136 t_apbonly | csr_micro_cont_mux_sel_addr, 2137 0x1); 2138 phy_io_write16(phy, 2139 t_apbonly | csr_micro_reset_addr, 2140 csr_reset_to_micro_mask | 2141 csr_stall_to_micro_mask); 2142 phy_io_write16(phy, 2143 t_apbonly | csr_micro_reset_addr, 2144 csr_stall_to_micro_mask); 2145 phy_io_write16(phy, 2146 t_apbonly | csr_micro_reset_addr, 2147 0); 2148 2149 ret = wait_fw_done(phy, train2d); 2150 if (ret == -ETIMEDOUT) { 2151 ERROR("Wait timed out: Firmware execution on PHY %d\n", 2152 i); 2153 } 2154 } 2155 return ret; 2156 } 2157 2158 static inline int send_fw(uint16_t *phy, 2159 uint32_t dst, 2160 uint16_t *img, 2161 uint32_t size) 2162 { 2163 uint32_t i; 2164 2165 if ((size % 2U) != 0U) { 2166 ERROR("Wrong image size 0x%x\n", size); 2167 return -EINVAL; 2168 } 2169 2170 for (i = 0U; i < size / 2; i++) { 2171 phy_io_write16(phy, dst + i, *(img + i)); 2172 } 2173 2174 return 0; 2175 } 2176 2177 static int load_fw(uint16_t **phy_ptr, 2178 struct input *input, 2179 int train2d, 2180 void *msg, 2181 size_t len, 2182 uintptr_t phy_gen2_fw_img_buf, 2183 int (*img_loadr)(unsigned int, uintptr_t *, uint32_t *), 2184 uint32_t warm_boot_flag) 2185 { 2186 uint32_t imem_id, dmem_id; 2187 uintptr_t image_buf; 2188 uint32_t size; 2189 int ret; 2190 int i; 2191 uint16_t *phy; 2192 2193 switch (input->basic.dimm_type) { 2194 case UDIMM: 2195 case SODIMM: 2196 case NODIMM: 2197 imem_id = train2d ? DDR_IMEM_UDIMM_2D_IMAGE_ID : 2198 DDR_IMEM_UDIMM_1D_IMAGE_ID; 2199 dmem_id = train2d ? DDR_DMEM_UDIMM_2D_IMAGE_ID : 2200 DDR_DMEM_UDIMM_1D_IMAGE_ID; 2201 break; 2202 case RDIMM: 2203 imem_id = train2d ? DDR_IMEM_RDIMM_2D_IMAGE_ID : 2204 DDR_IMEM_RDIMM_1D_IMAGE_ID; 2205 dmem_id = train2d ? DDR_DMEM_RDIMM_2D_IMAGE_ID : 2206 DDR_DMEM_RDIMM_1D_IMAGE_ID; 2207 break; 2208 default: 2209 ERROR("Unsupported DIMM type\n"); 2210 return -EINVAL; 2211 } 2212 2213 size = PHY_GEN2_MAX_IMAGE_SIZE; 2214 image_buf = (uintptr_t)phy_gen2_fw_img_buf; 2215 mmap_add_dynamic_region(phy_gen2_fw_img_buf, 2216 phy_gen2_fw_img_buf, 2217 PHY_GEN2_MAX_IMAGE_SIZE, 2218 MT_MEMORY | MT_RW | MT_SECURE); 2219 ret = img_loadr(imem_id, &image_buf, &size); 2220 if (ret != 0) { 2221 ERROR("Failed to load %d firmware.\n", imem_id); 2222 return ret; 2223 } 2224 debug("Loaded Imaged id %d of size %x at address %lx\n", 2225 imem_id, size, image_buf); 2226 2227 for (i = 0; i < NUM_OF_DDRC; i++) { 2228 phy = phy_ptr[i]; 2229 if (phy == NULL) { 2230 continue; 2231 } 2232 2233 if (warm_boot_flag != DDR_WARM_BOOT) { 2234 if (train2d == 0) { 2235 phy_io_write16(phy, t_master | 2236 csr_mem_reset_l_addr, 2237 csr_protect_mem_reset_mask); 2238 } 2239 } 2240 /* Enable access to the internal CSRs */ 2241 phy_io_write16(phy, t_apbonly | csr_micro_cont_mux_sel_addr, 0); 2242 2243 ret = send_fw(phy, PHY_GEN2_IMEM_ADDR, 2244 (uint16_t *)image_buf, size); 2245 if (ret != 0) { 2246 return ret; 2247 } 2248 } 2249 2250 size = PHY_GEN2_MAX_IMAGE_SIZE; 2251 image_buf = (uintptr_t)phy_gen2_fw_img_buf; 2252 ret = img_loadr(dmem_id, &image_buf, &size); 2253 if (ret != 0) { 2254 ERROR("Failed to load %d firmware.\n", dmem_id); 2255 return ret; 2256 } 2257 debug("Loaded Imaged id %d of size %x at address %lx\n", 2258 dmem_id, size, image_buf); 2259 image_buf += len; 2260 size -= len; 2261 2262 for (i = 0; i < NUM_OF_DDRC; i++) { 2263 phy = phy_ptr[i]; 2264 if (phy == NULL) { 2265 continue; 2266 } 2267 2268 ret = send_fw(phy, PHY_GEN2_DMEM_ADDR, msg, len); 2269 if (ret != 0) { 2270 return ret; 2271 } 2272 2273 ret = send_fw(phy, PHY_GEN2_DMEM_ADDR + len / 2, 2274 (uint16_t *)image_buf, size); 2275 if (ret != 0) { 2276 return ret; 2277 } 2278 } 2279 2280 return ret; 2281 } 2282 2283 static void parse_odt(const unsigned int val, 2284 const int read, 2285 const int i, 2286 const unsigned int cs_d0, 2287 const unsigned int cs_d1, 2288 unsigned int *odt) 2289 { 2290 int shift = read ? 4 : 0; 2291 int j; 2292 2293 if (i < 0 || i > 3) { 2294 printf("Error: invalid chip-select value\n"); 2295 } 2296 switch (val) { 2297 case DDR_ODT_CS: 2298 odt[i] |= (1 << i) << shift; 2299 break; 2300 case DDR_ODT_ALL_OTHER_CS: 2301 for (j = 0; j < DDRC_NUM_CS; j++) { 2302 if (i == j) { 2303 continue; 2304 } 2305 if (((cs_d0 | cs_d1) & (1 << j)) == 0) { 2306 continue; 2307 } 2308 odt[j] |= (1 << i) << shift; 2309 } 2310 break; 2311 case DDR_ODT_CS_AND_OTHER_DIMM: 2312 odt[i] |= (1 << i) << 4; 2313 /* fallthrough */ 2314 case DDR_ODT_OTHER_DIMM: 2315 for (j = 0; j < DDRC_NUM_CS; j++) { 2316 if ((((cs_d0 & (1 << i)) != 0) && 2317 ((cs_d1 & (1 << j)) != 0)) || 2318 (((cs_d1 & (1 << i)) != 0) && 2319 ((cs_d0 & (1 << j)) != 0))) { 2320 odt[j] |= (1 << i) << shift; 2321 } 2322 } 2323 break; 2324 case DDR_ODT_ALL: 2325 for (j = 0; j < DDRC_NUM_CS; j++) { 2326 if (((cs_d0 | cs_d1) & (1 << j)) == 0) { 2327 continue; 2328 } 2329 odt[j] |= (1 << i) << shift; 2330 } 2331 break; 2332 case DDR_ODT_SAME_DIMM: 2333 for (j = 0; j < DDRC_NUM_CS; j++) { 2334 if ((((cs_d0 & (1 << i)) != 0) && 2335 ((cs_d0 & (1 << j)) != 0)) || 2336 (((cs_d1 & (1 << i)) != 0) && 2337 ((cs_d1 & (1 << j)) != 0))) { 2338 odt[j] |= (1 << i) << shift; 2339 } 2340 } 2341 break; 2342 case DDR_ODT_OTHER_CS_ONSAMEDIMM: 2343 for (j = 0; j < DDRC_NUM_CS; j++) { 2344 if (i == j) { 2345 continue; 2346 } 2347 if ((((cs_d0 & (1 << i)) != 0) && 2348 ((cs_d0 & (1 << j)) != 0)) || 2349 (((cs_d1 & (1 << i)) != 0) && 2350 ((cs_d1 & (1 << j)) != 0))) { 2351 odt[j] |= (1 << i) << shift; 2352 } 2353 } 2354 break; 2355 case DDR_ODT_NEVER: 2356 break; 2357 default: 2358 break; 2359 } 2360 } 2361 2362 #ifdef DEBUG_DDR_INPUT_CONFIG 2363 char *dram_types_str[] = { 2364 "DDR4", 2365 "DDR3", 2366 "LDDDR4", 2367 "LPDDR3", 2368 "LPDDR2", 2369 "DDR5" 2370 }; 2371 2372 char *dimm_types_str[] = { 2373 "UDIMM", 2374 "SODIMM", 2375 "RDIMM", 2376 "LRDIMM", 2377 "NODIMM", 2378 }; 2379 2380 2381 static void print_jason_format(struct input *input, 2382 struct ddr4u1d *msg_1d, 2383 struct ddr4u2d *msg_2d) 2384 { 2385 2386 printf("\n{"); 2387 printf("\n \"dram_type\": \"%s\",", dram_types_str[input->basic.dram_type]); 2388 printf("\n \"dimm_type\": \"%s\",", dimm_types_str[input->basic.dimm_type]); 2389 printf("\n \"hard_macro_ver\": \"%d\",", input->basic.hard_macro_ver); 2390 printf("\n \"num_dbyte\": \"0x%04x\",", (unsigned int)input->basic.num_dbyte); 2391 printf("\n \"num_active_dbyte_dfi0\": \"0x%04x\",", (unsigned int)input->basic.num_active_dbyte_dfi0); 2392 printf("\n \"num_anib\": \"0x%04x\",", (unsigned int)input->basic.num_anib); 2393 printf("\n \"num_rank_dfi0\": \"0x%04x\",", (unsigned int)input->basic.num_rank_dfi0); 2394 printf("\n \"num_pstates\": \"0x%04x\",", (unsigned int)input->basic.num_pstates); 2395 printf("\n \"frequency\": \"%d\",", input->basic.frequency); 2396 printf("\n \"pll_bypass\": \"0x%04x\",", (unsigned int)input->basic.dfi_freq_ratio); 2397 printf("\n \"dfi_freq_ratio\": \"0x%04x\",", (unsigned int)input->basic.dfi_freq_ratio); 2398 printf("\n \"dfi1_exists\": \"0x%04x\",", (unsigned int)input->basic.dfi1exists); 2399 printf("\n \"dram_data_width\": \"0x%04x\",", (unsigned int)input->basic.dram_data_width); 2400 printf("\n \"dram_byte_swap\": \"0x%04x\",", (unsigned int)input->adv.dram_byte_swap); 2401 printf("\n \"ext_cal_res_val\": \"0x%04x\",", (unsigned int)input->adv.ext_cal_res_val); 2402 printf("\n \"tx_slew_rise_dq\": \"0x%04x\",", (unsigned int)input->adv.tx_slew_rise_dq); 2403 printf("\n \"tx_slew_fall_dq\": \"0x%04x\",", (unsigned int)input->adv.tx_slew_fall_dq); 2404 printf("\n \"tx_slew_rise_ac\": \"0x%04x\",", (unsigned int)input->adv.tx_slew_rise_ac); 2405 printf("\n \"tx_slew_fall_ac\": \"0x%04x\",", (unsigned int)input->adv.tx_slew_fall_ac); 2406 printf("\n \"odt_impedance\": \"%d\",", input->adv.odtimpedance); 2407 printf("\n \"tx_impedance\": \"%d\",", input->adv.tx_impedance); 2408 printf("\n \"atx_impedance\": \"%d\",", input->adv.atx_impedance); 2409 printf("\n \"mem_alert_en\": \"0x%04x\",", (unsigned int)input->adv.mem_alert_en); 2410 printf("\n \"mem_alert_pu_imp\": \"0x%04x\",", (unsigned int)input->adv.mem_alert_puimp); 2411 printf("\n \"mem_alert_vref_level\": \"0x%04x\",", (unsigned int)input->adv.mem_alert_vref_level); 2412 printf("\n \"mem_alert_sync_bypass\": \"0x%04x\",", (unsigned int)input->adv.mem_alert_sync_bypass); 2413 printf("\n \"cal_interval\": \"0x%04x\",", (unsigned int)input->adv.cal_interval); 2414 printf("\n \"cal_once\": \"0x%04x\",", (unsigned int)input->adv.cal_once); 2415 printf("\n \"dis_dyn_adr_tri\": \"0x%04x\",", (unsigned int)input->adv.dis_dyn_adr_tri); 2416 printf("\n \"is2t_timing\": \"0x%04x\",", (unsigned int)input->adv.is2ttiming); 2417 printf("\n \"d4rx_preabmle_length\": \"0x%04x\",", (unsigned int)input->adv.d4rx_preamble_length); 2418 printf("\n \"d4tx_preamble_length\": \"0x%04x\",", (unsigned int)input->adv.d4tx_preamble_length); 2419 printf("\n \"msg_misc\": \"0x%02x\",", (unsigned int)msg_1d->msg_misc); 2420 printf("\n \"reserved00\": \"0x%01x\",", (unsigned int)msg_1d->reserved00); 2421 printf("\n \"hdt_ctrl\": \"0x%02x\",", (unsigned int)msg_1d->hdt_ctrl); 2422 printf("\n \"cs_present\": \"0x%02x\",", (unsigned int)msg_1d->cs_present); 2423 printf("\n \"phy_vref\": \"0x%02x\",", (unsigned int)msg_1d->phy_vref); 2424 printf("\n \"dfi_mrl_margin\": \"0x%02x\",", (unsigned int)msg_1d->dfimrlmargin); 2425 printf("\n \"addr_mirror\": \"0x%02x\",", (unsigned int)msg_1d->addr_mirror); 2426 printf("\n \"wr_odt_pat_rank0\": \"0x%02x\",", (unsigned int)(msg_1d->acsm_odt_ctrl0 & 0x0f)); 2427 printf("\n \"wr_odt_pat_rank1\": \"0x%02x\",", (unsigned int)(msg_1d->acsm_odt_ctrl1 & 0x0f)); 2428 printf("\n \"wr_odt_pat_rank2\": \"0x%02x\",", (unsigned int)(msg_1d->acsm_odt_ctrl2 & 0x0f)); 2429 printf("\n \"wr_odt_pat_rank3\": \"0x%02x\",", (unsigned int)(msg_1d->acsm_odt_ctrl3 & 0x0f)); 2430 printf("\n \"rd_odt_pat_rank0\": \"0x%02x\",", (unsigned int)(msg_1d->acsm_odt_ctrl0 & 0xf0)); 2431 printf("\n \"rd_odt_pat_rank1\": \"0x%02x\",", (unsigned int)(msg_1d->acsm_odt_ctrl1 & 0xf0)); 2432 printf("\n \"rd_odt_pat_rank2\": \"0x%02x\",", (unsigned int)(msg_1d->acsm_odt_ctrl2 & 0xf0)); 2433 printf("\n \"rd_odt_pat_rank3\": \"0x%02x\",", (unsigned int)(msg_1d->acsm_odt_ctrl3 & 0xf0)); 2434 printf("\n \"d4_misc\": \"0x%01x\",", (unsigned int)msg_1d->d4misc); 2435 printf("\n \"share_2d_vref_results\": \"0x%01x\",", (unsigned int)msg_1d->share2dvref_result); 2436 printf("\n \"sequence_ctrl\": \"0x%04x\",", (unsigned int)msg_1d->sequence_ctrl); 2437 printf("\n \"mr0\": \"0x%04x\",", (unsigned int)msg_1d->mr0); 2438 printf("\n \"mr1\": \"0x%04x\",", (unsigned int)msg_1d->mr1); 2439 printf("\n \"mr2\": \"0x%04x\",", (unsigned int)msg_1d->mr2); 2440 printf("\n \"mr3\": \"0x%04x\",", (unsigned int)msg_1d->mr3); 2441 printf("\n \"mr4\": \"0x%04x\",", (unsigned int)msg_1d->mr4); 2442 printf("\n \"mr5\": \"0x%04x\",", (unsigned int)msg_1d->mr5); 2443 printf("\n \"mr6\": \"0x%04x\",", (unsigned int)msg_1d->mr6); 2444 printf("\n \"alt_cal_l\": \"0x%04x\",", (unsigned int)msg_1d->alt_cas_l); 2445 printf("\n \"alt_wcal_l\": \"0x%04x\",", (unsigned int)msg_1d->alt_wcas_l); 2446 printf("\n \"sequence_ctrl_2d\": \"0x%04x\",", (unsigned int)msg_2d->sequence_ctrl); 2447 printf("\n \"rtt_nom_wr_park0\": \"0x%01x\",", (unsigned int)msg_1d->rtt_nom_wr_park0); 2448 printf("\n \"rtt_nom_wr_park1\": \"0x%01x\",", (unsigned int)msg_1d->rtt_nom_wr_park1); 2449 printf("\n \"rtt_nom_wr_park2\": \"0x%01x\",", (unsigned int)msg_1d->rtt_nom_wr_park2); 2450 printf("\n \"rtt_nom_wr_park3\": \"0x%01x\",", (unsigned int)msg_1d->rtt_nom_wr_park3); 2451 printf("\n \"rtt_nom_wr_park4\": \"0x%01x\",", (unsigned int)msg_1d->rtt_nom_wr_park4); 2452 printf("\n \"rtt_nom_wr_park5\": \"0x%01x\",", (unsigned int)msg_1d->rtt_nom_wr_park5); 2453 printf("\n \"rtt_nom_wr_park6\": \"0x%01x\",", (unsigned int)msg_1d->rtt_nom_wr_park6); 2454 printf("\n \"rtt_nom_wr_park7\": \"0x%01x\"", (unsigned int)msg_1d->rtt_nom_wr_park7); 2455 printf("\n}"); 2456 printf("\n"); 2457 } 2458 #endif 2459 2460 int compute_ddr_phy(struct ddr_info *priv) 2461 { 2462 const unsigned long clk = priv->clk; 2463 const struct memctl_opt *popts = &priv->opt; 2464 const struct ddr_conf *conf = &priv->conf; 2465 const struct dimm_params *dimm_param = &priv->dimm; 2466 struct ddr_cfg_regs *regs = &priv->ddr_reg; 2467 int ret; 2468 static struct input input; 2469 static struct ddr4u1d msg_1d; 2470 static struct ddr4u2d msg_2d; 2471 unsigned int i; 2472 unsigned int odt_rd, odt_wr; 2473 __unused const soc_info_t *soc_info; 2474 #ifdef NXP_APPLY_MAX_CDD 2475 unsigned int tcfg0, tcfg4, rank; 2476 #endif 2477 2478 if (dimm_param == NULL) { 2479 ERROR("Empty DIMM parameters.\n"); 2480 return -EINVAL; 2481 } 2482 2483 zeromem(&input, sizeof(input)); 2484 zeromem(&msg_1d, sizeof(msg_1d)); 2485 zeromem(&msg_2d, sizeof(msg_2d)); 2486 2487 input.basic.dram_type = DDR4; 2488 /* FIXME: Add condition for LRDIMM */ 2489 input.basic.dimm_type = (dimm_param->rdimm != 0) ? RDIMM : UDIMM; 2490 input.basic.num_dbyte = dimm_param->primary_sdram_width / 8 + 2491 dimm_param->ec_sdram_width / 8; 2492 input.basic.num_active_dbyte_dfi0 = input.basic.num_dbyte; 2493 input.basic.num_rank_dfi0 = dimm_param->n_ranks; 2494 input.basic.dram_data_width = dimm_param->device_width; 2495 input.basic.hard_macro_ver = 0xa; 2496 input.basic.num_pstates = 1; 2497 input.basic.dfi_freq_ratio = 1; 2498 input.basic.num_anib = 0xc; 2499 input.basic.train2d = popts->skip2d ? 0 : 1; 2500 input.basic.frequency = (int) (clk / 2000000ul); 2501 debug("frequency = %dMHz\n", input.basic.frequency); 2502 input.cs_d0 = conf->cs_on_dimm[0]; 2503 #if DDRC_NUM_DIMM > 1 2504 input.cs_d1 = conf->cs_on_dimm[1]; 2505 #endif 2506 input.mirror = dimm_param->mirrored_dimm; 2507 input.mr[0] = regs->sdram_mode[0] & U(0xffff); 2508 input.mr[1] = regs->sdram_mode[0] >> 16U; 2509 input.mr[2] = regs->sdram_mode[1] >> 16U; 2510 input.mr[3] = regs->sdram_mode[1] & U(0xffff); 2511 input.mr[4] = regs->sdram_mode[8] >> 16U; 2512 input.mr[5] = regs->sdram_mode[8] & U(0xffff); 2513 input.mr[6] = regs->sdram_mode[9] >> 16U; 2514 input.vref = popts->vref_phy; 2515 debug("Vref_phy = %d percent\n", (input.vref * 100U) >> 7U); 2516 for (i = 0U; i < DDRC_NUM_CS; i++) { 2517 if ((regs->cs[i].config & SDRAM_CS_CONFIG_EN) == 0U) { 2518 continue; 2519 } 2520 odt_rd = (regs->cs[i].config >> 20U) & U(0x7); 2521 odt_wr = (regs->cs[i].config >> 16U) & U(0x7); 2522 parse_odt(odt_rd, true, i, input.cs_d0, input.cs_d1, 2523 input.odt); 2524 parse_odt(odt_wr, false, i, input.cs_d0, input.cs_d1, 2525 input.odt); 2526 } 2527 2528 /* Do not set sdram_cfg[RD_EN] or sdram_cfg2[RCW_EN] for RDIMM */ 2529 if (dimm_param->rdimm != 0U) { 2530 regs->sdram_cfg[0] &= ~(1 << 28U); 2531 regs->sdram_cfg[1] &= ~(1 << 2U); 2532 input.rcw[0] = (regs->sdram_rcw[0] >> 28U) & U(0xf); 2533 input.rcw[1] = (regs->sdram_rcw[0] >> 24U) & U(0xf); 2534 input.rcw[2] = (regs->sdram_rcw[0] >> 20U) & U(0xf); 2535 input.rcw[3] = (regs->sdram_rcw[0] >> 16U) & U(0xf); 2536 input.rcw[4] = (regs->sdram_rcw[0] >> 12U) & U(0xf); 2537 input.rcw[5] = (regs->sdram_rcw[0] >> 8U) & U(0xf); 2538 input.rcw[6] = (regs->sdram_rcw[0] >> 4U) & U(0xf); 2539 input.rcw[7] = (regs->sdram_rcw[0] >> 0U) & U(0xf); 2540 input.rcw[8] = (regs->sdram_rcw[1] >> 28U) & U(0xf); 2541 input.rcw[9] = (regs->sdram_rcw[1] >> 24U) & U(0xf); 2542 input.rcw[10] = (regs->sdram_rcw[1] >> 20U) & U(0xf); 2543 input.rcw[11] = (regs->sdram_rcw[1] >> 16U) & U(0xf); 2544 input.rcw[12] = (regs->sdram_rcw[1] >> 12U) & U(0xf); 2545 input.rcw[13] = (regs->sdram_rcw[1] >> 8U) & U(0xf); 2546 input.rcw[14] = (regs->sdram_rcw[1] >> 4U) & U(0xf); 2547 input.rcw[15] = (regs->sdram_rcw[1] >> 0U) & U(0xf); 2548 input.rcw3x = (regs->sdram_rcw[2] >> 8U) & U(0xff); 2549 } 2550 2551 input.adv.odtimpedance = popts->odt ? popts->odt : 60; 2552 input.adv.tx_impedance = popts->phy_tx_impedance ? 2553 popts->phy_tx_impedance : 28; 2554 input.adv.atx_impedance = popts->phy_atx_impedance ? 2555 popts->phy_atx_impedance : 30; 2556 2557 debug("Initializing input adv data structure\n"); 2558 phy_gen2_init_input(&input); 2559 2560 debug("Initializing message block\n"); 2561 ret = phy_gen2_msg_init(&msg_1d, &msg_2d, &input); 2562 if (ret != 0) { 2563 ERROR("Init msg failed (error code %d)\n", ret); 2564 return ret; 2565 } 2566 2567 ret = c_init_phy_config(priv->phy, priv->ip_rev, &input, &msg_1d); 2568 if (ret != 0) { 2569 ERROR("Init PHY failed (error code %d)\n", ret); 2570 return ret; 2571 } 2572 #ifdef NXP_WARM_BOOT 2573 debug("Warm boot flag value %0x\n", priv->warm_boot_flag); 2574 if (priv->warm_boot_flag == DDR_WARM_BOOT) { 2575 debug("Restoring the Phy training data\n"); 2576 // Restore the training data 2577 ret = restore_phy_training_values(priv->phy, 2578 PHY_TRAINING_REGS_ON_FLASH, 2579 priv->num_ctlrs, 2580 input.basic.train2d); 2581 if (ret != 0) { 2582 ERROR("Restoring of training data failed %d\n", ret); 2583 return ret; 2584 } 2585 } else { 2586 #endif 2587 2588 debug("Load 1D firmware\n"); 2589 ret = load_fw(priv->phy, &input, 0, &msg_1d, 2590 sizeof(struct ddr4u1d), priv->phy_gen2_fw_img_buf, 2591 priv->img_loadr, priv->warm_boot_flag); 2592 if (ret != 0) { 2593 ERROR("Loading firmware failed (error code %d)\n", ret); 2594 return ret; 2595 } 2596 2597 debug("Execute firmware\n"); 2598 ret = g_exec_fw(priv->phy, 0, &input); 2599 if (ret != 0) { 2600 ERROR("Execution FW failed (error code %d)\n", ret); 2601 } 2602 2603 #ifdef NXP_APPLY_MAX_CDD 2604 soc_info = get_soc_info(NXP_DCFG_ADDR); 2605 if (soc_info->maj_ver == 2) { 2606 tcfg0 = regs->timing_cfg[0]; 2607 tcfg4 = regs->timing_cfg[4]; 2608 rank = findrank(conf->cs_in_use); 2609 get_cdd_val(priv->phy, rank, input.basic.frequency, 2610 &tcfg0, &tcfg4); 2611 regs->timing_cfg[0] = tcfg0; 2612 regs->timing_cfg[4] = tcfg4; 2613 } 2614 #endif 2615 2616 if ((ret == 0) && (input.basic.train2d != 0)) { 2617 /* 2D training starts here */ 2618 debug("Load 2D firmware\n"); 2619 ret = load_fw(priv->phy, &input, 1, &msg_2d, 2620 sizeof(struct ddr4u2d), 2621 priv->phy_gen2_fw_img_buf, 2622 priv->img_loadr, 2623 priv->warm_boot_flag); 2624 if (ret != 0) { 2625 ERROR("Loading fw failed (err code %d)\n", ret); 2626 } else { 2627 debug("Execute 2D firmware\n"); 2628 ret = g_exec_fw(priv->phy, 1, &input); 2629 if (ret != 0) { 2630 ERROR("Execution FW failed (err %d)\n", 2631 ret); 2632 } 2633 } 2634 } 2635 #ifdef NXP_WARM_BOOT 2636 if (priv->warm_boot_flag != DDR_WRM_BOOT_NT_SUPPORTED && 2637 ret == 0) { 2638 debug("save the phy training data\n"); 2639 //Save training data TBD 2640 ret = save_phy_training_values(priv->phy, 2641 PHY_TRAINING_REGS_ON_FLASH, 2642 priv->num_ctlrs, 2643 input.basic.train2d); 2644 if (ret != 0) { 2645 ERROR("Saving training data failed."); 2646 ERROR("Warm boot will fail. Error=%d.\n", ret); 2647 } 2648 } 2649 } /* else */ 2650 #endif 2651 2652 if (ret == 0) { 2653 debug("Load PIE\n"); 2654 i_load_pie(priv->phy, &input, &msg_1d); 2655 2656 NOTICE("DDR4 %s with %d-rank %d-bit bus (x%d)\n", 2657 input.basic.dimm_type == RDIMM ? "RDIMM" : 2658 input.basic.dimm_type == LRDIMM ? "LRDIMM" : 2659 "UDIMM", 2660 dimm_param->n_ranks, 2661 dimm_param->primary_sdram_width, 2662 dimm_param->device_width); 2663 } 2664 #ifdef DEBUG_DDR_INPUT_CONFIG 2665 print_jason_format(&input, &msg_1d, &msg_2d); 2666 #endif 2667 2668 return ret; 2669 } 2670