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