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