1 // SPDX-License-Identifier: MIT 2 /* 3 * Copyright © 2023 Intel Corporation 4 */ 5 6 #include <linux/log2.h> 7 #include <linux/math64.h> 8 9 #include <drm/drm_print.h> 10 11 #include "intel_alpm.h" 12 #include "intel_cmtg.h" 13 #include "intel_cx0_phy.h" 14 #include "intel_cx0_phy_regs.h" 15 #include "intel_display_regs.h" 16 #include "intel_ddi.h" 17 #include "intel_ddi_buf_trans.h" 18 #include "intel_de.h" 19 #include "intel_display_types.h" 20 #include "intel_display_utils.h" 21 #include "intel_dp.h" 22 #include "intel_dpll.h" 23 #include "intel_hdmi.h" 24 #include "intel_lt_phy.h" 25 #include "intel_panel.h" 26 #include "intel_psr.h" 27 #include "intel_snps_hdmi_pll.h" 28 #include "intel_tc.h" 29 30 #define for_each_cx0_lane_in_mask(__lane_mask, __lane) \ 31 for ((__lane) = 0; (__lane) < 2; (__lane)++) \ 32 for_each_if((__lane_mask) & BIT(__lane)) 33 34 #define INTEL_CX0_LANE0 BIT(0) 35 #define INTEL_CX0_LANE1 BIT(1) 36 #define INTEL_CX0_BOTH_LANES (INTEL_CX0_LANE1 | INTEL_CX0_LANE0) 37 38 bool intel_encoder_is_c10phy(struct intel_encoder *encoder) 39 { 40 struct intel_display *display = to_intel_display(encoder); 41 enum phy phy = intel_encoder_to_phy(encoder); 42 43 if (display->platform.pantherlake) { 44 if (display->platform.pantherlake_wildcatlake) 45 return phy <= PHY_B; 46 else 47 return phy == PHY_A; 48 } 49 50 if ((display->platform.lunarlake || display->platform.meteorlake) && phy < PHY_C) 51 return true; 52 53 return false; 54 } 55 56 static int lane_mask_to_lane(u8 lane_mask) 57 { 58 if (WARN_ON((lane_mask & ~INTEL_CX0_BOTH_LANES) || 59 hweight8(lane_mask) != 1)) 60 return 0; 61 62 return ilog2(lane_mask); 63 } 64 65 static u8 intel_cx0_get_owned_lane_mask(struct intel_encoder *encoder) 66 { 67 struct intel_digital_port *dig_port = enc_to_dig_port(encoder); 68 69 if (!intel_tc_port_in_dp_alt_mode(dig_port)) 70 return INTEL_CX0_BOTH_LANES; 71 72 /* 73 * In DP-alt with pin assignment D, only PHY lane 0 is owned 74 * by display and lane 1 is owned by USB. 75 */ 76 return intel_tc_port_max_lane_count(dig_port) > 2 77 ? INTEL_CX0_BOTH_LANES : INTEL_CX0_LANE0; 78 } 79 80 static void 81 assert_dc_off(struct intel_display *display) 82 { 83 bool enabled; 84 85 enabled = intel_display_power_is_enabled(display, POWER_DOMAIN_DC_OFF); 86 drm_WARN_ON(display->drm, !enabled); 87 } 88 89 static void intel_cx0_program_msgbus_timer(struct intel_encoder *encoder) 90 { 91 struct intel_display *display = to_intel_display(encoder); 92 int lane; 93 94 for_each_cx0_lane_in_mask(INTEL_CX0_BOTH_LANES, lane) 95 intel_de_rmw(display, 96 XELPDP_PORT_MSGBUS_TIMER(display, encoder->port, lane), 97 XELPDP_PORT_MSGBUS_TIMER_VAL_MASK, 98 XELPDP_PORT_MSGBUS_TIMER_VAL); 99 } 100 101 /* 102 * Prepare HW for CX0 phy transactions. 103 * 104 * It is required that PSR and DC5/6 are disabled before any CX0 message 105 * bus transaction is executed. 106 * 107 * We also do the msgbus timer programming here to ensure that the timer 108 * is already programmed before any access to the msgbus. 109 */ 110 static struct ref_tracker *intel_cx0_phy_transaction_begin(struct intel_encoder *encoder) 111 { 112 struct intel_display *display = to_intel_display(encoder); 113 struct intel_dp *intel_dp = enc_to_intel_dp(encoder); 114 struct ref_tracker *wakeref; 115 116 intel_psr_pause(intel_dp); 117 wakeref = intel_display_power_get(display, POWER_DOMAIN_DC_OFF); 118 intel_cx0_program_msgbus_timer(encoder); 119 120 return wakeref; 121 } 122 123 static void intel_cx0_phy_transaction_end(struct intel_encoder *encoder, struct ref_tracker *wakeref) 124 { 125 struct intel_display *display = to_intel_display(encoder); 126 struct intel_dp *intel_dp = enc_to_intel_dp(encoder); 127 128 intel_psr_resume(intel_dp); 129 intel_display_power_put(display, POWER_DOMAIN_DC_OFF, wakeref); 130 } 131 132 void intel_cx0_clear_response_ready_flag(struct intel_encoder *encoder, 133 int lane) 134 { 135 struct intel_display *display = to_intel_display(encoder); 136 137 intel_de_rmw(display, 138 XELPDP_PORT_P2M_MSGBUS_STATUS(display, encoder->port, lane), 139 0, XELPDP_PORT_P2M_RESPONSE_READY | XELPDP_PORT_P2M_ERROR_SET); 140 } 141 142 void intel_cx0_bus_reset(struct intel_encoder *encoder, int lane) 143 { 144 struct intel_display *display = to_intel_display(encoder); 145 enum port port = encoder->port; 146 enum phy phy = intel_encoder_to_phy(encoder); 147 148 intel_de_write(display, XELPDP_PORT_M2P_MSGBUS_CTL(display, port, lane), 149 XELPDP_PORT_M2P_TRANSACTION_RESET); 150 151 if (intel_de_wait_for_clear_ms(display, XELPDP_PORT_M2P_MSGBUS_CTL(display, port, lane), 152 XELPDP_PORT_M2P_TRANSACTION_RESET, 153 XELPDP_MSGBUS_TIMEOUT_MS)) { 154 drm_err_once(display->drm, 155 "Failed to bring PHY %c to idle.\n", 156 phy_name(phy)); 157 return; 158 } 159 160 intel_cx0_clear_response_ready_flag(encoder, lane); 161 } 162 163 int intel_cx0_wait_for_ack(struct intel_encoder *encoder, 164 int command, int lane, u32 *val) 165 { 166 struct intel_display *display = to_intel_display(encoder); 167 enum port port = encoder->port; 168 enum phy phy = intel_encoder_to_phy(encoder); 169 170 if (intel_de_wait_ms(display, XELPDP_PORT_P2M_MSGBUS_STATUS(display, port, lane), 171 XELPDP_PORT_P2M_RESPONSE_READY, 172 XELPDP_PORT_P2M_RESPONSE_READY, 173 XELPDP_MSGBUS_TIMEOUT_MS, val)) { 174 drm_dbg_kms(display->drm, 175 "PHY %c Timeout waiting for message ACK. Status: 0x%x\n", 176 phy_name(phy), *val); 177 178 if (!(intel_de_read(display, XELPDP_PORT_MSGBUS_TIMER(display, port, lane)) & 179 XELPDP_PORT_MSGBUS_TIMER_TIMED_OUT)) 180 drm_dbg_kms(display->drm, 181 "PHY %c Hardware did not detect a timeout\n", 182 phy_name(phy)); 183 184 intel_cx0_bus_reset(encoder, lane); 185 return -ETIMEDOUT; 186 } 187 188 if (*val & XELPDP_PORT_P2M_ERROR_SET) { 189 drm_dbg_kms(display->drm, 190 "PHY %c Error occurred during %s command. Status: 0x%x\n", 191 phy_name(phy), 192 command == XELPDP_PORT_P2M_COMMAND_READ_ACK ? "read" : "write", *val); 193 intel_cx0_bus_reset(encoder, lane); 194 return -EINVAL; 195 } 196 197 if (REG_FIELD_GET(XELPDP_PORT_P2M_COMMAND_TYPE_MASK, *val) != command) { 198 drm_dbg_kms(display->drm, 199 "PHY %c Not a %s response. MSGBUS Status: 0x%x.\n", 200 phy_name(phy), 201 command == XELPDP_PORT_P2M_COMMAND_READ_ACK ? "read" : "write", *val); 202 intel_cx0_bus_reset(encoder, lane); 203 return -EINVAL; 204 } 205 206 return 0; 207 } 208 209 static int __intel_cx0_read_once(struct intel_encoder *encoder, 210 int lane, u16 addr) 211 { 212 struct intel_display *display = to_intel_display(encoder); 213 enum port port = encoder->port; 214 enum phy phy = intel_encoder_to_phy(encoder); 215 int ack; 216 u32 val; 217 218 if (intel_de_wait_for_clear_ms(display, XELPDP_PORT_M2P_MSGBUS_CTL(display, port, lane), 219 XELPDP_PORT_M2P_TRANSACTION_PENDING, 220 XELPDP_MSGBUS_TIMEOUT_MS)) { 221 drm_dbg_kms(display->drm, 222 "PHY %c Timeout waiting for previous transaction to complete. Reset the bus and retry.\n", phy_name(phy)); 223 intel_cx0_bus_reset(encoder, lane); 224 return -ETIMEDOUT; 225 } 226 227 intel_cx0_clear_response_ready_flag(encoder, lane); 228 229 intel_de_write(display, XELPDP_PORT_M2P_MSGBUS_CTL(display, port, lane), 230 XELPDP_PORT_M2P_TRANSACTION_PENDING | 231 XELPDP_PORT_M2P_COMMAND_READ | 232 XELPDP_PORT_M2P_ADDRESS(addr)); 233 234 ack = intel_cx0_wait_for_ack(encoder, XELPDP_PORT_P2M_COMMAND_READ_ACK, lane, &val); 235 if (ack < 0) 236 return ack; 237 238 intel_cx0_clear_response_ready_flag(encoder, lane); 239 240 /* 241 * FIXME: Workaround to let HW to settle 242 * down and let the message bus to end up 243 * in a known state 244 */ 245 if (DISPLAY_VER(display) < 30) 246 intel_cx0_bus_reset(encoder, lane); 247 248 return REG_FIELD_GET(XELPDP_PORT_P2M_DATA_MASK, val); 249 } 250 251 static u8 __intel_cx0_read(struct intel_encoder *encoder, 252 int lane, u16 addr) 253 { 254 struct intel_display *display = to_intel_display(encoder); 255 enum phy phy = intel_encoder_to_phy(encoder); 256 int i, status; 257 258 assert_dc_off(display); 259 260 /* 3 tries is assumed to be enough to read successfully */ 261 for (i = 0; i < 3; i++) { 262 status = __intel_cx0_read_once(encoder, lane, addr); 263 264 if (status >= 0) 265 return status; 266 } 267 268 drm_err_once(display->drm, 269 "PHY %c Read %04x failed after %d retries.\n", 270 phy_name(phy), addr, i); 271 272 return 0; 273 } 274 275 u8 intel_cx0_read(struct intel_encoder *encoder, u8 lane_mask, u16 addr) 276 { 277 int lane = lane_mask_to_lane(lane_mask); 278 279 return __intel_cx0_read(encoder, lane, addr); 280 } 281 282 static int __intel_cx0_write_once(struct intel_encoder *encoder, 283 int lane, u16 addr, u8 data, bool committed) 284 { 285 struct intel_display *display = to_intel_display(encoder); 286 enum port port = encoder->port; 287 enum phy phy = intel_encoder_to_phy(encoder); 288 int ack; 289 u32 val; 290 291 if (intel_de_wait_for_clear_ms(display, XELPDP_PORT_M2P_MSGBUS_CTL(display, port, lane), 292 XELPDP_PORT_M2P_TRANSACTION_PENDING, 293 XELPDP_MSGBUS_TIMEOUT_MS)) { 294 drm_dbg_kms(display->drm, 295 "PHY %c Timeout waiting for previous transaction to complete. Resetting the bus.\n", phy_name(phy)); 296 intel_cx0_bus_reset(encoder, lane); 297 return -ETIMEDOUT; 298 } 299 300 intel_cx0_clear_response_ready_flag(encoder, lane); 301 302 intel_de_write(display, XELPDP_PORT_M2P_MSGBUS_CTL(display, port, lane), 303 XELPDP_PORT_M2P_TRANSACTION_PENDING | 304 (committed ? XELPDP_PORT_M2P_COMMAND_WRITE_COMMITTED : 305 XELPDP_PORT_M2P_COMMAND_WRITE_UNCOMMITTED) | 306 XELPDP_PORT_M2P_DATA(data) | 307 XELPDP_PORT_M2P_ADDRESS(addr)); 308 309 if (intel_de_wait_for_clear_ms(display, XELPDP_PORT_M2P_MSGBUS_CTL(display, port, lane), 310 XELPDP_PORT_M2P_TRANSACTION_PENDING, 311 XELPDP_MSGBUS_TIMEOUT_MS)) { 312 drm_dbg_kms(display->drm, 313 "PHY %c Timeout waiting for write to complete. Resetting the bus.\n", phy_name(phy)); 314 intel_cx0_bus_reset(encoder, lane); 315 return -ETIMEDOUT; 316 } 317 318 if (committed) { 319 ack = intel_cx0_wait_for_ack(encoder, XELPDP_PORT_P2M_COMMAND_WRITE_ACK, lane, &val); 320 if (ack < 0) 321 return ack; 322 } else if ((intel_de_read(display, XELPDP_PORT_P2M_MSGBUS_STATUS(display, port, lane)) & 323 XELPDP_PORT_P2M_ERROR_SET)) { 324 drm_dbg_kms(display->drm, 325 "PHY %c Error occurred during write command.\n", phy_name(phy)); 326 intel_cx0_bus_reset(encoder, lane); 327 return -EINVAL; 328 } 329 330 intel_cx0_clear_response_ready_flag(encoder, lane); 331 332 /* 333 * FIXME: Workaround to let HW to settle 334 * down and let the message bus to end up 335 * in a known state 336 */ 337 if (DISPLAY_VER(display) < 30) 338 intel_cx0_bus_reset(encoder, lane); 339 340 return 0; 341 } 342 343 static void __intel_cx0_write(struct intel_encoder *encoder, 344 int lane, u16 addr, u8 data, bool committed) 345 { 346 struct intel_display *display = to_intel_display(encoder); 347 enum phy phy = intel_encoder_to_phy(encoder); 348 int i, status; 349 350 assert_dc_off(display); 351 352 /* 3 tries is assumed to be enough to write successfully */ 353 for (i = 0; i < 3; i++) { 354 status = __intel_cx0_write_once(encoder, lane, addr, data, committed); 355 356 if (status == 0) 357 return; 358 } 359 360 drm_err_once(display->drm, 361 "PHY %c Write %04x failed after %d retries.\n", phy_name(phy), addr, i); 362 } 363 364 void intel_cx0_write(struct intel_encoder *encoder, 365 u8 lane_mask, u16 addr, u8 data, bool committed) 366 { 367 int lane; 368 369 for_each_cx0_lane_in_mask(lane_mask, lane) 370 __intel_cx0_write(encoder, lane, addr, data, committed); 371 } 372 373 static void intel_c20_sram_write(struct intel_encoder *encoder, 374 int lane, u16 addr, u16 data) 375 { 376 struct intel_display *display = to_intel_display(encoder); 377 378 assert_dc_off(display); 379 380 intel_cx0_write(encoder, lane, PHY_C20_WR_ADDRESS_H, addr >> 8, 0); 381 intel_cx0_write(encoder, lane, PHY_C20_WR_ADDRESS_L, addr & 0xff, 0); 382 383 intel_cx0_write(encoder, lane, PHY_C20_WR_DATA_H, data >> 8, 0); 384 intel_cx0_write(encoder, lane, PHY_C20_WR_DATA_L, data & 0xff, 1); 385 } 386 387 static u16 intel_c20_sram_read(struct intel_encoder *encoder, 388 int lane, u16 addr) 389 { 390 struct intel_display *display = to_intel_display(encoder); 391 u16 val; 392 393 assert_dc_off(display); 394 395 intel_cx0_write(encoder, lane, PHY_C20_RD_ADDRESS_H, addr >> 8, 0); 396 intel_cx0_write(encoder, lane, PHY_C20_RD_ADDRESS_L, addr & 0xff, 1); 397 398 val = intel_cx0_read(encoder, lane, PHY_C20_RD_DATA_H); 399 val <<= 8; 400 val |= intel_cx0_read(encoder, lane, PHY_C20_RD_DATA_L); 401 402 return val; 403 } 404 405 static void __intel_cx0_rmw(struct intel_encoder *encoder, 406 int lane, u16 addr, u8 clear, u8 set, bool committed) 407 { 408 u8 old, val; 409 410 old = __intel_cx0_read(encoder, lane, addr); 411 val = (old & ~clear) | set; 412 413 if (val != old) 414 __intel_cx0_write(encoder, lane, addr, val, committed); 415 } 416 417 void intel_cx0_rmw(struct intel_encoder *encoder, 418 u8 lane_mask, u16 addr, u8 clear, u8 set, bool committed) 419 { 420 u8 lane; 421 422 for_each_cx0_lane_in_mask(lane_mask, lane) 423 __intel_cx0_rmw(encoder, lane, addr, clear, set, committed); 424 } 425 426 static u8 intel_c10_get_tx_vboost_lvl(const struct intel_crtc_state *crtc_state) 427 { 428 if (intel_crtc_has_dp_encoder(crtc_state)) { 429 if (!intel_crtc_has_type(crtc_state, INTEL_OUTPUT_EDP) && 430 (crtc_state->port_clock == 540000 || 431 crtc_state->port_clock == 810000)) 432 return 5; 433 else 434 return 4; 435 } else { 436 return 5; 437 } 438 } 439 440 static u8 intel_c10_get_tx_term_ctl(const struct intel_crtc_state *crtc_state) 441 { 442 if (intel_crtc_has_dp_encoder(crtc_state)) { 443 if (!intel_crtc_has_type(crtc_state, INTEL_OUTPUT_EDP) && 444 (crtc_state->port_clock == 540000 || 445 crtc_state->port_clock == 810000)) 446 return 5; 447 else 448 return 2; 449 } else { 450 return 6; 451 } 452 } 453 454 static void intel_c10_msgbus_access_begin(struct intel_encoder *encoder, 455 u8 lane_mask) 456 { 457 if (!intel_encoder_is_c10phy(encoder)) 458 return; 459 460 intel_cx0_rmw(encoder, lane_mask, PHY_C10_VDR_CONTROL(1), 461 0, C10_VDR_CTRL_MSGBUS_ACCESS, MB_WRITE_COMMITTED); 462 } 463 464 static void intel_c10_msgbus_access_commit(struct intel_encoder *encoder, 465 u8 lane_mask, bool master_lane) 466 { 467 u8 val = C10_VDR_CTRL_UPDATE_CFG; 468 469 if (!intel_encoder_is_c10phy(encoder)) 470 return; 471 472 if (master_lane) 473 val |= C10_VDR_CTRL_MASTER_LANE; 474 475 intel_cx0_rmw(encoder, lane_mask, PHY_C10_VDR_CONTROL(1), 476 0, val, MB_WRITE_COMMITTED); 477 } 478 479 void intel_cx0_phy_set_signal_levels(struct intel_encoder *encoder, 480 const struct intel_crtc_state *crtc_state) 481 { 482 struct intel_display *display = to_intel_display(encoder); 483 const struct intel_ddi_buf_trans *trans; 484 u8 owned_lane_mask; 485 struct ref_tracker *wakeref; 486 int n_entries, ln; 487 struct intel_digital_port *dig_port = enc_to_dig_port(encoder); 488 489 if (intel_tc_port_in_tbt_alt_mode(dig_port)) 490 return; 491 492 owned_lane_mask = intel_cx0_get_owned_lane_mask(encoder); 493 494 wakeref = intel_cx0_phy_transaction_begin(encoder); 495 496 trans = intel_ddi_buf_trans_get(encoder, crtc_state, &n_entries); 497 if (drm_WARN_ON_ONCE(display->drm, !trans)) { 498 intel_cx0_phy_transaction_end(encoder, wakeref); 499 return; 500 } 501 502 intel_c10_msgbus_access_begin(encoder, owned_lane_mask); 503 504 if (intel_encoder_is_c10phy(encoder)) { 505 intel_cx0_rmw(encoder, owned_lane_mask, PHY_C10_VDR_CMN(3), 506 C10_CMN3_TXVBOOST_MASK, 507 C10_CMN3_TXVBOOST(intel_c10_get_tx_vboost_lvl(crtc_state)), 508 MB_WRITE_UNCOMMITTED); 509 intel_cx0_rmw(encoder, owned_lane_mask, PHY_C10_VDR_TX(1), 510 C10_TX1_TERMCTL_MASK, 511 C10_TX1_TERMCTL(intel_c10_get_tx_term_ctl(crtc_state)), 512 MB_WRITE_COMMITTED); 513 } 514 515 for (ln = 0; ln < crtc_state->lane_count; ln++) { 516 int level = intel_ddi_level(encoder, crtc_state, ln); 517 int lane = ln / 2; 518 int tx = ln % 2; 519 u8 lane_mask = lane == 0 ? INTEL_CX0_LANE0 : INTEL_CX0_LANE1; 520 521 if (!(lane_mask & owned_lane_mask)) 522 continue; 523 524 intel_cx0_rmw(encoder, lane_mask, PHY_CX0_VDROVRD_CTL(lane, tx, 0), 525 C10_PHY_OVRD_LEVEL_MASK, 526 C10_PHY_OVRD_LEVEL(trans->entries[level].snps.pre_cursor), 527 MB_WRITE_COMMITTED); 528 intel_cx0_rmw(encoder, lane_mask, PHY_CX0_VDROVRD_CTL(lane, tx, 1), 529 C10_PHY_OVRD_LEVEL_MASK, 530 C10_PHY_OVRD_LEVEL(trans->entries[level].snps.vswing), 531 MB_WRITE_COMMITTED); 532 intel_cx0_rmw(encoder, lane_mask, PHY_CX0_VDROVRD_CTL(lane, tx, 2), 533 C10_PHY_OVRD_LEVEL_MASK, 534 C10_PHY_OVRD_LEVEL(trans->entries[level].snps.post_cursor), 535 MB_WRITE_COMMITTED); 536 } 537 538 /* Write Override enables in 0xD71 */ 539 intel_cx0_rmw(encoder, owned_lane_mask, PHY_C10_VDR_OVRD, 540 0, PHY_C10_VDR_OVRD_TX1 | PHY_C10_VDR_OVRD_TX2, 541 MB_WRITE_COMMITTED); 542 543 intel_c10_msgbus_access_commit(encoder, owned_lane_mask, false); 544 545 intel_cx0_phy_transaction_end(encoder, wakeref); 546 } 547 548 /* 549 * Basic DP link rates with 38.4 MHz reference clock. 550 * Note: The tables below are with SSC. In non-ssc 551 * registers 0xC04 to 0xC08(pll[4] to pll[8]) will be 552 * programmed 0. 553 */ 554 555 static const struct intel_c10pll_state mtl_c10_dp_rbr = { 556 .tx = 0x10, 557 .cmn = 0x21, 558 .pll[0] = 0xB4, 559 .pll[1] = 0, 560 .pll[2] = 0x30, 561 .pll[3] = 0x1, 562 .pll[4] = 0x26, 563 .pll[5] = 0x0C, 564 .pll[6] = 0x98, 565 .pll[7] = 0x46, 566 .pll[8] = 0x1, 567 .pll[9] = 0x1, 568 .pll[10] = 0, 569 .pll[11] = 0, 570 .pll[12] = 0xC0, 571 .pll[13] = 0, 572 .pll[14] = 0, 573 .pll[15] = 0x2, 574 .pll[16] = 0x84, 575 .pll[17] = 0x4F, 576 .pll[18] = 0xE5, 577 .pll[19] = 0x23, 578 }; 579 580 static const struct intel_c10pll_state mtl_c10_edp_r216 = { 581 .tx = 0x10, 582 .cmn = 0x21, 583 .pll[0] = 0x4, 584 .pll[1] = 0, 585 .pll[2] = 0xA2, 586 .pll[3] = 0x1, 587 .pll[4] = 0x33, 588 .pll[5] = 0x10, 589 .pll[6] = 0x75, 590 .pll[7] = 0xB3, 591 .pll[8] = 0x1, 592 .pll[9] = 0x1, 593 .pll[10] = 0, 594 .pll[11] = 0, 595 .pll[12] = 0, 596 .pll[13] = 0, 597 .pll[14] = 0, 598 .pll[15] = 0x2, 599 .pll[16] = 0x85, 600 .pll[17] = 0x0F, 601 .pll[18] = 0xE6, 602 .pll[19] = 0x23, 603 }; 604 605 static const struct intel_c10pll_state mtl_c10_edp_r243 = { 606 .tx = 0x10, 607 .cmn = 0x21, 608 .pll[0] = 0x34, 609 .pll[1] = 0, 610 .pll[2] = 0xDA, 611 .pll[3] = 0x1, 612 .pll[4] = 0x39, 613 .pll[5] = 0x12, 614 .pll[6] = 0xE3, 615 .pll[7] = 0xE9, 616 .pll[8] = 0x1, 617 .pll[9] = 0x1, 618 .pll[10] = 0, 619 .pll[11] = 0, 620 .pll[12] = 0x20, 621 .pll[13] = 0, 622 .pll[14] = 0, 623 .pll[15] = 0x2, 624 .pll[16] = 0x85, 625 .pll[17] = 0x8F, 626 .pll[18] = 0xE6, 627 .pll[19] = 0x23, 628 }; 629 630 static const struct intel_c10pll_state mtl_c10_dp_hbr1 = { 631 .tx = 0x10, 632 .cmn = 0x21, 633 .pll[0] = 0xF4, 634 .pll[1] = 0, 635 .pll[2] = 0xF8, 636 .pll[3] = 0x0, 637 .pll[4] = 0x20, 638 .pll[5] = 0x0A, 639 .pll[6] = 0x29, 640 .pll[7] = 0x10, 641 .pll[8] = 0x1, /* Verify */ 642 .pll[9] = 0x1, 643 .pll[10] = 0, 644 .pll[11] = 0, 645 .pll[12] = 0xA0, 646 .pll[13] = 0, 647 .pll[14] = 0, 648 .pll[15] = 0x1, 649 .pll[16] = 0x84, 650 .pll[17] = 0x4F, 651 .pll[18] = 0xE5, 652 .pll[19] = 0x23, 653 }; 654 655 static const struct intel_c10pll_state mtl_c10_edp_r324 = { 656 .tx = 0x10, 657 .cmn = 0x21, 658 .pll[0] = 0xB4, 659 .pll[1] = 0, 660 .pll[2] = 0x30, 661 .pll[3] = 0x1, 662 .pll[4] = 0x26, 663 .pll[5] = 0x0C, 664 .pll[6] = 0x98, 665 .pll[7] = 0x46, 666 .pll[8] = 0x1, 667 .pll[9] = 0x1, 668 .pll[10] = 0, 669 .pll[11] = 0, 670 .pll[12] = 0xC0, 671 .pll[13] = 0, 672 .pll[14] = 0, 673 .pll[15] = 0x1, 674 .pll[16] = 0x85, 675 .pll[17] = 0x4F, 676 .pll[18] = 0xE6, 677 .pll[19] = 0x23, 678 }; 679 680 static const struct intel_c10pll_state mtl_c10_edp_r432 = { 681 .tx = 0x10, 682 .cmn = 0x21, 683 .pll[0] = 0x4, 684 .pll[1] = 0, 685 .pll[2] = 0xA2, 686 .pll[3] = 0x1, 687 .pll[4] = 0x33, 688 .pll[5] = 0x10, 689 .pll[6] = 0x75, 690 .pll[7] = 0xB3, 691 .pll[8] = 0x1, 692 .pll[9] = 0x1, 693 .pll[10] = 0, 694 .pll[11] = 0, 695 .pll[12] = 0, 696 .pll[13] = 0, 697 .pll[14] = 0, 698 .pll[15] = 0x1, 699 .pll[16] = 0x85, 700 .pll[17] = 0x0F, 701 .pll[18] = 0xE6, 702 .pll[19] = 0x23, 703 }; 704 705 static const struct intel_c10pll_state mtl_c10_dp_hbr2 = { 706 .tx = 0x10, 707 .cmn = 0x21, 708 .pll[0] = 0xF4, 709 .pll[1] = 0, 710 .pll[2] = 0xF8, 711 .pll[3] = 0, 712 .pll[4] = 0x20, 713 .pll[5] = 0x0A, 714 .pll[6] = 0x29, 715 .pll[7] = 0x10, 716 .pll[8] = 0x1, 717 .pll[9] = 0x1, 718 .pll[10] = 0, 719 .pll[11] = 0, 720 .pll[12] = 0xA0, 721 .pll[13] = 0, 722 .pll[14] = 0, 723 .pll[15] = 0, 724 .pll[16] = 0x84, 725 .pll[17] = 0x4F, 726 .pll[18] = 0xE5, 727 .pll[19] = 0x23, 728 }; 729 730 static const struct intel_c10pll_state mtl_c10_edp_r675 = { 731 .tx = 0x10, 732 .cmn = 0x21, 733 .pll[0] = 0xB4, 734 .pll[1] = 0, 735 .pll[2] = 0x3E, 736 .pll[3] = 0x1, 737 .pll[4] = 0xA8, 738 .pll[5] = 0x0C, 739 .pll[6] = 0x33, 740 .pll[7] = 0x54, 741 .pll[8] = 0x1, 742 .pll[9] = 0x1, 743 .pll[10] = 0, 744 .pll[11] = 0, 745 .pll[12] = 0xC8, 746 .pll[13] = 0, 747 .pll[14] = 0, 748 .pll[15] = 0, 749 .pll[16] = 0x85, 750 .pll[17] = 0x8F, 751 .pll[18] = 0xE6, 752 .pll[19] = 0x23, 753 }; 754 755 static const struct intel_c10pll_state mtl_c10_dp_hbr3 = { 756 .tx = 0x10, 757 .cmn = 0x21, 758 .pll[0] = 0x34, 759 .pll[1] = 0, 760 .pll[2] = 0x84, 761 .pll[3] = 0x1, 762 .pll[4] = 0x30, 763 .pll[5] = 0x0F, 764 .pll[6] = 0x3D, 765 .pll[7] = 0x98, 766 .pll[8] = 0x1, 767 .pll[9] = 0x1, 768 .pll[10] = 0, 769 .pll[11] = 0, 770 .pll[12] = 0xF0, 771 .pll[13] = 0, 772 .pll[14] = 0, 773 .pll[15] = 0, 774 .pll[16] = 0x84, 775 .pll[17] = 0x0F, 776 .pll[18] = 0xE5, 777 .pll[19] = 0x23, 778 }; 779 780 struct intel_cx0pll_params { 781 const char *name; 782 bool is_c10; 783 bool is_hdmi; 784 int clock_rate; 785 union { 786 const struct intel_c10pll_state *c10; 787 const struct intel_c20pll_state *c20; 788 }; 789 }; 790 791 #define __C10PLL_PARAMS(__is_hdmi, __clock_rate, __state) { \ 792 .name = __stringify(__state), \ 793 .is_c10 = true, \ 794 .is_hdmi = __is_hdmi, \ 795 .clock_rate = __clock_rate, \ 796 .c10 = &__state, \ 797 } 798 799 #define __C20PLL_PARAMS(__is_hdmi, __clock_rate, __state) { \ 800 .name = __stringify(__state), \ 801 .is_c10 = false, \ 802 .is_hdmi = __is_hdmi, \ 803 .clock_rate = __clock_rate, \ 804 .c20 = &__state, \ 805 } 806 807 #define C10PLL_HDMI_PARAMS(__clock_rate, __state) __C10PLL_PARAMS(true, __clock_rate, __state) 808 #define C10PLL_DP_PARAMS(__clock_rate, __state) __C10PLL_PARAMS(false, __clock_rate, __state) 809 810 #define C20PLL_HDMI_PARAMS(__clock_rate, __state) __C20PLL_PARAMS(true, __clock_rate, __state) 811 #define C20PLL_DP_PARAMS(__clock_rate, __state) __C20PLL_PARAMS(false, __clock_rate, __state) 812 813 static const struct intel_cx0pll_params mtl_c10_dp_tables[] = { 814 C10PLL_DP_PARAMS(162000, mtl_c10_dp_rbr), 815 C10PLL_DP_PARAMS(270000, mtl_c10_dp_hbr1), 816 C10PLL_DP_PARAMS(540000, mtl_c10_dp_hbr2), 817 C10PLL_DP_PARAMS(810000, mtl_c10_dp_hbr3), 818 {} 819 }; 820 821 static const struct intel_cx0pll_params mtl_c10_edp_tables[] = { 822 C10PLL_DP_PARAMS(162000, mtl_c10_dp_rbr), 823 C10PLL_DP_PARAMS(216000, mtl_c10_edp_r216), 824 C10PLL_DP_PARAMS(243000, mtl_c10_edp_r243), 825 C10PLL_DP_PARAMS(270000, mtl_c10_dp_hbr1), 826 C10PLL_DP_PARAMS(324000, mtl_c10_edp_r324), 827 C10PLL_DP_PARAMS(432000, mtl_c10_edp_r432), 828 C10PLL_DP_PARAMS(540000, mtl_c10_dp_hbr2), 829 C10PLL_DP_PARAMS(675000, mtl_c10_edp_r675), 830 C10PLL_DP_PARAMS(810000, mtl_c10_dp_hbr3), 831 {} 832 }; 833 834 /* C20 basic DP 1.4 tables */ 835 static const struct intel_c20pll_state mtl_c20_dp_rbr = { 836 .tx = { 0xbe88, /* tx cfg0 */ 837 0x5800, /* tx cfg1 */ 838 0x0000, /* tx cfg2 */ 839 }, 840 .cmn = {0x0500, /* cmn cfg0*/ 841 0x0005, /* cmn cfg1 */ 842 0x0000, /* cmn cfg2 */ 843 0x0000, /* cmn cfg3 */ 844 }, 845 .mpllb = { 0x50a8, /* mpllb cfg0 */ 846 0x2120, /* mpllb cfg1 */ 847 0xcd9a, /* mpllb cfg2 */ 848 0xbfc1, /* mpllb cfg3 */ 849 0x5ab8, /* mpllb cfg4 */ 850 0x4c34, /* mpllb cfg5 */ 851 0x2000, /* mpllb cfg6 */ 852 0x0001, /* mpllb cfg7 */ 853 0x6000, /* mpllb cfg8 */ 854 0x0000, /* mpllb cfg9 */ 855 0x0000, /* mpllb cfg10 */ 856 }, 857 }; 858 859 static const struct intel_c20pll_state mtl_c20_dp_hbr1 = { 860 .tx = { 0xbe88, /* tx cfg0 */ 861 0x4800, /* tx cfg1 */ 862 0x0000, /* tx cfg2 */ 863 }, 864 .cmn = {0x0500, /* cmn cfg0*/ 865 0x0005, /* cmn cfg1 */ 866 0x0000, /* cmn cfg2 */ 867 0x0000, /* cmn cfg3 */ 868 }, 869 .mpllb = { 0x308c, /* mpllb cfg0 */ 870 0x2110, /* mpllb cfg1 */ 871 0xcc9c, /* mpllb cfg2 */ 872 0xbfc1, /* mpllb cfg3 */ 873 0x4b9a, /* mpllb cfg4 */ 874 0x3f81, /* mpllb cfg5 */ 875 0x2000, /* mpllb cfg6 */ 876 0x0001, /* mpllb cfg7 */ 877 0x5000, /* mpllb cfg8 */ 878 0x0000, /* mpllb cfg9 */ 879 0x0000, /* mpllb cfg10 */ 880 }, 881 }; 882 883 static const struct intel_c20pll_state mtl_c20_dp_hbr2 = { 884 .tx = { 0xbe88, /* tx cfg0 */ 885 0x4800, /* tx cfg1 */ 886 0x0000, /* tx cfg2 */ 887 }, 888 .cmn = {0x0500, /* cmn cfg0*/ 889 0x0005, /* cmn cfg1 */ 890 0x0000, /* cmn cfg2 */ 891 0x0000, /* cmn cfg3 */ 892 }, 893 .mpllb = { 0x108c, /* mpllb cfg0 */ 894 0x2108, /* mpllb cfg1 */ 895 0xcc9c, /* mpllb cfg2 */ 896 0xbfc1, /* mpllb cfg3 */ 897 0x4b9a, /* mpllb cfg4 */ 898 0x3f81, /* mpllb cfg5 */ 899 0x2000, /* mpllb cfg6 */ 900 0x0001, /* mpllb cfg7 */ 901 0x5000, /* mpllb cfg8 */ 902 0x0000, /* mpllb cfg9 */ 903 0x0000, /* mpllb cfg10 */ 904 }, 905 }; 906 907 static const struct intel_c20pll_state mtl_c20_dp_hbr3 = { 908 .tx = { 0xbe88, /* tx cfg0 */ 909 0x4800, /* tx cfg1 */ 910 0x0000, /* tx cfg2 */ 911 }, 912 .cmn = {0x0500, /* cmn cfg0*/ 913 0x0005, /* cmn cfg1 */ 914 0x0000, /* cmn cfg2 */ 915 0x0000, /* cmn cfg3 */ 916 }, 917 .mpllb = { 0x10d2, /* mpllb cfg0 */ 918 0x2108, /* mpllb cfg1 */ 919 0x8d98, /* mpllb cfg2 */ 920 0xbfc1, /* mpllb cfg3 */ 921 0x7166, /* mpllb cfg4 */ 922 0x5f42, /* mpllb cfg5 */ 923 0x2000, /* mpllb cfg6 */ 924 0x0001, /* mpllb cfg7 */ 925 0x7800, /* mpllb cfg8 */ 926 0x0000, /* mpllb cfg9 */ 927 0x0000, /* mpllb cfg10 */ 928 }, 929 }; 930 931 /* C20 basic DP 2.0 tables */ 932 static const struct intel_c20pll_state mtl_c20_dp_uhbr10 = { 933 .tx = { 0xbe21, /* tx cfg0 */ 934 0xe800, /* tx cfg1 */ 935 0x0000, /* tx cfg2 */ 936 }, 937 .cmn = {0x0700, /* cmn cfg0*/ 938 0x0005, /* cmn cfg1 */ 939 0x0000, /* cmn cfg2 */ 940 0x0000, /* cmn cfg3 */ 941 }, 942 .mplla = { 0x3104, /* mplla cfg0 */ 943 0xd105, /* mplla cfg1 */ 944 0xc025, /* mplla cfg2 */ 945 0xc025, /* mplla cfg3 */ 946 0x8c00, /* mplla cfg4 */ 947 0x759a, /* mplla cfg5 */ 948 0x4000, /* mplla cfg6 */ 949 0x0003, /* mplla cfg7 */ 950 0x3555, /* mplla cfg8 */ 951 0x0001, /* mplla cfg9 */ 952 }, 953 }; 954 955 static const struct intel_c20pll_state mtl_c20_dp_uhbr13_5 = { 956 .tx = { 0xbea0, /* tx cfg0 */ 957 0x4800, /* tx cfg1 */ 958 0x0000, /* tx cfg2 */ 959 }, 960 .cmn = {0x0500, /* cmn cfg0*/ 961 0x0005, /* cmn cfg1 */ 962 0x0000, /* cmn cfg2 */ 963 0x0000, /* cmn cfg3 */ 964 }, 965 .mpllb = { 0x015f, /* mpllb cfg0 */ 966 0x2205, /* mpllb cfg1 */ 967 0x1b17, /* mpllb cfg2 */ 968 0xffc1, /* mpllb cfg3 */ 969 0xe100, /* mpllb cfg4 */ 970 0xbd00, /* mpllb cfg5 */ 971 0x2000, /* mpllb cfg6 */ 972 0x0001, /* mpllb cfg7 */ 973 0x4800, /* mpllb cfg8 */ 974 0x0000, /* mpllb cfg9 */ 975 0x0000, /* mpllb cfg10 */ 976 }, 977 }; 978 979 static const struct intel_c20pll_state mtl_c20_dp_uhbr20 = { 980 .tx = { 0xbe20, /* tx cfg0 */ 981 0x4800, /* tx cfg1 */ 982 0x0000, /* tx cfg2 */ 983 }, 984 .cmn = {0x0500, /* cmn cfg0*/ 985 0x0005, /* cmn cfg1 */ 986 0x0000, /* cmn cfg2 */ 987 0x0000, /* cmn cfg3 */ 988 }, 989 .mplla = { 0x3104, /* mplla cfg0 */ 990 0xd105, /* mplla cfg1 */ 991 0x9217, /* mplla cfg2 */ 992 0x9217, /* mplla cfg3 */ 993 0x8c00, /* mplla cfg4 */ 994 0x759a, /* mplla cfg5 */ 995 0x4000, /* mplla cfg6 */ 996 0x0003, /* mplla cfg7 */ 997 0x3555, /* mplla cfg8 */ 998 0x0001, /* mplla cfg9 */ 999 }, 1000 }; 1001 1002 static const struct intel_cx0pll_params mtl_c20_dp_tables[] = { 1003 C20PLL_DP_PARAMS(162000, mtl_c20_dp_rbr), 1004 C20PLL_DP_PARAMS(270000, mtl_c20_dp_hbr1), 1005 C20PLL_DP_PARAMS(540000, mtl_c20_dp_hbr2), 1006 C20PLL_DP_PARAMS(810000, mtl_c20_dp_hbr3), 1007 C20PLL_DP_PARAMS(1000000, mtl_c20_dp_uhbr10), 1008 C20PLL_DP_PARAMS(1350000, mtl_c20_dp_uhbr13_5), 1009 C20PLL_DP_PARAMS(2000000, mtl_c20_dp_uhbr20), 1010 {} 1011 }; 1012 1013 /* 1014 * eDP link rates with 38.4 MHz reference clock. 1015 */ 1016 1017 static const struct intel_c20pll_state xe2hpd_c20_edp_r216 = { 1018 .tx = { 0xbe88, 1019 0x4800, 1020 0x0000, 1021 }, 1022 .cmn = { 0x0500, 1023 0x0005, 1024 0x0000, 1025 0x0000, 1026 }, 1027 .mpllb = { 0x50e1, 1028 0x2120, 1029 0x8e18, 1030 0xbfc1, 1031 0x9000, 1032 0x78f6, 1033 0x0000, 1034 0x0000, 1035 0x0000, 1036 0x0000, 1037 0x0000, 1038 }, 1039 }; 1040 1041 static const struct intel_c20pll_state xe2hpd_c20_edp_r243 = { 1042 .tx = { 0xbe88, 1043 0x4800, 1044 0x0000, 1045 }, 1046 .cmn = { 0x0500, 1047 0x0005, 1048 0x0000, 1049 0x0000, 1050 }, 1051 .mpllb = { 0x50fd, 1052 0x2120, 1053 0x8f18, 1054 0xbfc1, 1055 0xa200, 1056 0x8814, 1057 0x2000, 1058 0x0001, 1059 0x1000, 1060 0x0000, 1061 0x0000, 1062 }, 1063 }; 1064 1065 static const struct intel_c20pll_state xe2hpd_c20_edp_r324 = { 1066 .tx = { 0xbe88, 1067 0x4800, 1068 0x0000, 1069 }, 1070 .cmn = { 0x0500, 1071 0x0005, 1072 0x0000, 1073 0x0000, 1074 }, 1075 .mpllb = { 0x30a8, 1076 0x2110, 1077 0xcd9a, 1078 0xbfc1, 1079 0x6c00, 1080 0x5ab8, 1081 0x2000, 1082 0x0001, 1083 0x6000, 1084 0x0000, 1085 0x0000, 1086 }, 1087 }; 1088 1089 static const struct intel_c20pll_state xe2hpd_c20_edp_r432 = { 1090 .tx = { 0xbe88, 1091 0x4800, 1092 0x0000, 1093 }, 1094 .cmn = { 0x0500, 1095 0x0005, 1096 0x0000, 1097 0x0000, 1098 }, 1099 .mpllb = { 0x30e1, 1100 0x2110, 1101 0x8e18, 1102 0xbfc1, 1103 0x9000, 1104 0x78f6, 1105 0x0000, 1106 0x0000, 1107 0x0000, 1108 0x0000, 1109 0x0000, 1110 }, 1111 }; 1112 1113 static const struct intel_c20pll_state xe2hpd_c20_edp_r675 = { 1114 .tx = { 0xbe88, 1115 0x4800, 1116 0x0000, 1117 }, 1118 .cmn = { 0x0500, 1119 0x0005, 1120 0x0000, 1121 0x0000, 1122 }, 1123 .mpllb = { 0x10af, 1124 0x2108, 1125 0xce1a, 1126 0xbfc1, 1127 0x7080, 1128 0x5e80, 1129 0x2000, 1130 0x0001, 1131 0x6400, 1132 0x0000, 1133 0x0000, 1134 }, 1135 }; 1136 1137 static const struct intel_cx0pll_params xe2hpd_c20_edp_tables[] = { 1138 C20PLL_DP_PARAMS(162000, mtl_c20_dp_rbr), 1139 C20PLL_DP_PARAMS(216000, xe2hpd_c20_edp_r216), 1140 C20PLL_DP_PARAMS(243000, xe2hpd_c20_edp_r243), 1141 C20PLL_DP_PARAMS(270000, mtl_c20_dp_hbr1), 1142 C20PLL_DP_PARAMS(324000, xe2hpd_c20_edp_r324), 1143 C20PLL_DP_PARAMS(432000, xe2hpd_c20_edp_r432), 1144 C20PLL_DP_PARAMS(540000, mtl_c20_dp_hbr2), 1145 C20PLL_DP_PARAMS(675000, xe2hpd_c20_edp_r675), 1146 C20PLL_DP_PARAMS(810000, mtl_c20_dp_hbr3), 1147 {} 1148 }; 1149 1150 static const struct intel_c20pll_state xe2hpd_c20_dp_uhbr13_5 = { 1151 .tx = { 0xbea0, /* tx cfg0 */ 1152 0x4800, /* tx cfg1 */ 1153 0x0000, /* tx cfg2 */ 1154 }, 1155 .cmn = {0x0500, /* cmn cfg0*/ 1156 0x0005, /* cmn cfg1 */ 1157 0x0000, /* cmn cfg2 */ 1158 0x0000, /* cmn cfg3 */ 1159 }, 1160 .mpllb = { 0x015f, /* mpllb cfg0 */ 1161 0x2205, /* mpllb cfg1 */ 1162 0x1b17, /* mpllb cfg2 */ 1163 0xffc1, /* mpllb cfg3 */ 1164 0xbd00, /* mpllb cfg4 */ 1165 0x9ec3, /* mpllb cfg5 */ 1166 0x2000, /* mpllb cfg6 */ 1167 0x0001, /* mpllb cfg7 */ 1168 0x4800, /* mpllb cfg8 */ 1169 0x0000, /* mpllb cfg9 */ 1170 0x0000, /* mpllb cfg10 */ 1171 }, 1172 }; 1173 1174 static const struct intel_cx0pll_params xe2hpd_c20_dp_tables[] = { 1175 C20PLL_DP_PARAMS(162000, mtl_c20_dp_rbr), 1176 C20PLL_DP_PARAMS(270000, mtl_c20_dp_hbr1), 1177 C20PLL_DP_PARAMS(540000, mtl_c20_dp_hbr2), 1178 C20PLL_DP_PARAMS(810000, mtl_c20_dp_hbr3), 1179 C20PLL_DP_PARAMS(1000000, mtl_c20_dp_uhbr10), 1180 C20PLL_DP_PARAMS(1350000, xe2hpd_c20_dp_uhbr13_5), 1181 {} 1182 }; 1183 1184 static const struct intel_cx0pll_params xe3lpd_c20_dp_edp_tables[] = { 1185 C20PLL_DP_PARAMS(162000, mtl_c20_dp_rbr), 1186 C20PLL_DP_PARAMS(216000, xe2hpd_c20_edp_r216), 1187 C20PLL_DP_PARAMS(243000, xe2hpd_c20_edp_r243), 1188 C20PLL_DP_PARAMS(270000, mtl_c20_dp_hbr1), 1189 C20PLL_DP_PARAMS(324000, xe2hpd_c20_edp_r324), 1190 C20PLL_DP_PARAMS(432000, xe2hpd_c20_edp_r432), 1191 C20PLL_DP_PARAMS(540000, mtl_c20_dp_hbr2), 1192 C20PLL_DP_PARAMS(675000, xe2hpd_c20_edp_r675), 1193 C20PLL_DP_PARAMS(810000, mtl_c20_dp_hbr3), 1194 C20PLL_DP_PARAMS(1000000, mtl_c20_dp_uhbr10), 1195 C20PLL_DP_PARAMS(1350000, xe2hpd_c20_dp_uhbr13_5), 1196 C20PLL_DP_PARAMS(2000000, mtl_c20_dp_uhbr20), 1197 {} 1198 }; 1199 1200 /* 1201 * HDMI link rates with 38.4 MHz reference clock. 1202 */ 1203 1204 static const struct intel_c10pll_state mtl_c10_hdmi_25_2 = { 1205 .tx = 0x10, 1206 .cmn = 0x1, 1207 .pll[0] = 0x4, 1208 .pll[1] = 0, 1209 .pll[2] = 0xB2, 1210 .pll[3] = 0, 1211 .pll[4] = 0, 1212 .pll[5] = 0, 1213 .pll[6] = 0, 1214 .pll[7] = 0, 1215 .pll[8] = 0x20, 1216 .pll[9] = 0x1, 1217 .pll[10] = 0, 1218 .pll[11] = 0, 1219 .pll[12] = 0, 1220 .pll[13] = 0, 1221 .pll[14] = 0, 1222 .pll[15] = 0xD, 1223 .pll[16] = 0x6, 1224 .pll[17] = 0x8F, 1225 .pll[18] = 0x84, 1226 .pll[19] = 0x23, 1227 }; 1228 1229 static const struct intel_c10pll_state mtl_c10_hdmi_27_0 = { 1230 .tx = 0x10, 1231 .cmn = 0x1, 1232 .pll[0] = 0x34, 1233 .pll[1] = 0, 1234 .pll[2] = 0xC0, 1235 .pll[3] = 0, 1236 .pll[4] = 0, 1237 .pll[5] = 0, 1238 .pll[6] = 0, 1239 .pll[7] = 0, 1240 .pll[8] = 0x20, 1241 .pll[9] = 0x1, 1242 .pll[10] = 0, 1243 .pll[11] = 0, 1244 .pll[12] = 0x80, 1245 .pll[13] = 0, 1246 .pll[14] = 0, 1247 .pll[15] = 0xD, 1248 .pll[16] = 0x6, 1249 .pll[17] = 0xCF, 1250 .pll[18] = 0x84, 1251 .pll[19] = 0x23, 1252 }; 1253 1254 static const struct intel_c10pll_state mtl_c10_hdmi_74_25 = { 1255 .tx = 0x10, 1256 .cmn = 0x1, 1257 .pll[0] = 0xF4, 1258 .pll[1] = 0, 1259 .pll[2] = 0x7A, 1260 .pll[3] = 0, 1261 .pll[4] = 0, 1262 .pll[5] = 0, 1263 .pll[6] = 0, 1264 .pll[7] = 0, 1265 .pll[8] = 0x20, 1266 .pll[9] = 0x1, 1267 .pll[10] = 0, 1268 .pll[11] = 0, 1269 .pll[12] = 0x58, 1270 .pll[13] = 0, 1271 .pll[14] = 0, 1272 .pll[15] = 0xB, 1273 .pll[16] = 0x6, 1274 .pll[17] = 0xF, 1275 .pll[18] = 0x85, 1276 .pll[19] = 0x23, 1277 }; 1278 1279 static const struct intel_c10pll_state mtl_c10_hdmi_148_5 = { 1280 .tx = 0x10, 1281 .cmn = 0x1, 1282 .pll[0] = 0xF4, 1283 .pll[1] = 0, 1284 .pll[2] = 0x7A, 1285 .pll[3] = 0, 1286 .pll[4] = 0, 1287 .pll[5] = 0, 1288 .pll[6] = 0, 1289 .pll[7] = 0, 1290 .pll[8] = 0x20, 1291 .pll[9] = 0x1, 1292 .pll[10] = 0, 1293 .pll[11] = 0, 1294 .pll[12] = 0x58, 1295 .pll[13] = 0, 1296 .pll[14] = 0, 1297 .pll[15] = 0xA, 1298 .pll[16] = 0x6, 1299 .pll[17] = 0xF, 1300 .pll[18] = 0x85, 1301 .pll[19] = 0x23, 1302 }; 1303 1304 static const struct intel_c10pll_state mtl_c10_hdmi_594 = { 1305 .tx = 0x10, 1306 .cmn = 0x1, 1307 .pll[0] = 0xF4, 1308 .pll[1] = 0, 1309 .pll[2] = 0x7A, 1310 .pll[3] = 0, 1311 .pll[4] = 0, 1312 .pll[5] = 0, 1313 .pll[6] = 0, 1314 .pll[7] = 0, 1315 .pll[8] = 0x20, 1316 .pll[9] = 0x1, 1317 .pll[10] = 0, 1318 .pll[11] = 0, 1319 .pll[12] = 0x58, 1320 .pll[13] = 0, 1321 .pll[14] = 0, 1322 .pll[15] = 0x8, 1323 .pll[16] = 0x6, 1324 .pll[17] = 0xF, 1325 .pll[18] = 0x85, 1326 .pll[19] = 0x23, 1327 }; 1328 1329 /* Precomputed C10 HDMI PLL tables */ 1330 static const struct intel_c10pll_state mtl_c10_hdmi_27027 = { 1331 .tx = 0x10, 1332 .cmn = 0x1, 1333 .pll[0] = 0x34, .pll[1] = 0x00, .pll[2] = 0xC0, .pll[3] = 0x00, .pll[4] = 0x00, 1334 .pll[5] = 0x00, .pll[6] = 0x00, .pll[7] = 0x00, .pll[8] = 0x20, .pll[9] = 0xFF, 1335 .pll[10] = 0xFF, .pll[11] = 0xCC, .pll[12] = 0x9C, .pll[13] = 0xCB, .pll[14] = 0xCC, 1336 .pll[15] = 0x0D, .pll[16] = 0x08, .pll[17] = 0x8F, .pll[18] = 0x84, .pll[19] = 0x23, 1337 }; 1338 1339 static const struct intel_c10pll_state mtl_c10_hdmi_28320 = { 1340 .tx = 0x10, 1341 .cmn = 0x1, 1342 .pll[0] = 0x04, .pll[1] = 0x00, .pll[2] = 0xCC, .pll[3] = 0x00, .pll[4] = 0x00, 1343 .pll[5] = 0x00, .pll[6] = 0x00, .pll[7] = 0x00, .pll[8] = 0x20, .pll[9] = 0xFF, 1344 .pll[10] = 0xFF, .pll[11] = 0x00, .pll[12] = 0x00, .pll[13] = 0x00, .pll[14] = 0x00, 1345 .pll[15] = 0x0D, .pll[16] = 0x08, .pll[17] = 0x8F, .pll[18] = 0x84, .pll[19] = 0x23, 1346 }; 1347 1348 static const struct intel_c10pll_state mtl_c10_hdmi_30240 = { 1349 .tx = 0x10, 1350 .cmn = 0x1, 1351 .pll[0] = 0x04, .pll[1] = 0x00, .pll[2] = 0xDC, .pll[3] = 0x00, .pll[4] = 0x00, 1352 .pll[5] = 0x00, .pll[6] = 0x00, .pll[7] = 0x00, .pll[8] = 0x20, .pll[9] = 0xFF, 1353 .pll[10] = 0xFF, .pll[11] = 0x00, .pll[12] = 0x00, .pll[13] = 0x00, .pll[14] = 0x00, 1354 .pll[15] = 0x0D, .pll[16] = 0x08, .pll[17] = 0xCF, .pll[18] = 0x84, .pll[19] = 0x23, 1355 }; 1356 1357 static const struct intel_c10pll_state mtl_c10_hdmi_31500 = { 1358 .tx = 0x10, 1359 .cmn = 0x1, 1360 .pll[0] = 0xF4, .pll[1] = 0x00, .pll[2] = 0x62, .pll[3] = 0x00, .pll[4] = 0x00, 1361 .pll[5] = 0x00, .pll[6] = 0x00, .pll[7] = 0x00, .pll[8] = 0x20, .pll[9] = 0xFF, 1362 .pll[10] = 0xFF, .pll[11] = 0x00, .pll[12] = 0xA0, .pll[13] = 0x00, .pll[14] = 0x00, 1363 .pll[15] = 0x0C, .pll[16] = 0x09, .pll[17] = 0x8F, .pll[18] = 0x84, .pll[19] = 0x23, 1364 }; 1365 1366 static const struct intel_c10pll_state mtl_c10_hdmi_36000 = { 1367 .tx = 0x10, 1368 .cmn = 0x1, 1369 .pll[0] = 0xC4, .pll[1] = 0x00, .pll[2] = 0x76, .pll[3] = 0x00, .pll[4] = 0x00, 1370 .pll[5] = 0x00, .pll[6] = 0x00, .pll[7] = 0x00, .pll[8] = 0x20, .pll[9] = 0xFF, 1371 .pll[10] = 0xFF, .pll[11] = 0x00, .pll[12] = 0x00, .pll[13] = 0x00, .pll[14] = 0x00, 1372 .pll[15] = 0x0C, .pll[16] = 0x08, .pll[17] = 0x8F, .pll[18] = 0x84, .pll[19] = 0x23, 1373 }; 1374 1375 static const struct intel_c10pll_state mtl_c10_hdmi_40000 = { 1376 .tx = 0x10, 1377 .cmn = 0x1, 1378 .pll[0] = 0xB4, .pll[1] = 0x00, .pll[2] = 0x86, .pll[3] = 0x00, .pll[4] = 0x00, 1379 .pll[5] = 0x00, .pll[6] = 0x00, .pll[7] = 0x00, .pll[8] = 0x20, .pll[9] = 0xFF, 1380 .pll[10] = 0xFF, .pll[11] = 0x55, .pll[12] = 0x55, .pll[13] = 0x55, .pll[14] = 0x55, 1381 .pll[15] = 0x0C, .pll[16] = 0x08, .pll[17] = 0x8F, .pll[18] = 0x84, .pll[19] = 0x23, 1382 }; 1383 1384 static const struct intel_c10pll_state mtl_c10_hdmi_49500 = { 1385 .tx = 0x10, 1386 .cmn = 0x1, 1387 .pll[0] = 0x74, .pll[1] = 0x00, .pll[2] = 0xAE, .pll[3] = 0x00, .pll[4] = 0x00, 1388 .pll[5] = 0x00, .pll[6] = 0x00, .pll[7] = 0x00, .pll[8] = 0x20, .pll[9] = 0xFF, 1389 .pll[10] = 0xFF, .pll[11] = 0x00, .pll[12] = 0x20, .pll[13] = 0x00, .pll[14] = 0x00, 1390 .pll[15] = 0x0C, .pll[16] = 0x08, .pll[17] = 0xCF, .pll[18] = 0x84, .pll[19] = 0x23, 1391 }; 1392 1393 static const struct intel_c10pll_state mtl_c10_hdmi_50000 = { 1394 .tx = 0x10, 1395 .cmn = 0x1, 1396 .pll[0] = 0x74, .pll[1] = 0x00, .pll[2] = 0xB0, .pll[3] = 0x00, .pll[4] = 0x00, 1397 .pll[5] = 0x00, .pll[6] = 0x00, .pll[7] = 0x00, .pll[8] = 0x20, .pll[9] = 0xFF, 1398 .pll[10] = 0xFF, .pll[11] = 0xAA, .pll[12] = 0x2A, .pll[13] = 0xA9, .pll[14] = 0xAA, 1399 .pll[15] = 0x0C, .pll[16] = 0x08, .pll[17] = 0xCF, .pll[18] = 0x84, .pll[19] = 0x23, 1400 }; 1401 1402 static const struct intel_c10pll_state mtl_c10_hdmi_57284 = { 1403 .tx = 0x10, 1404 .cmn = 0x1, 1405 .pll[0] = 0x34, .pll[1] = 0x00, .pll[2] = 0xCE, .pll[3] = 0x00, .pll[4] = 0x00, 1406 .pll[5] = 0x00, .pll[6] = 0x00, .pll[7] = 0x00, .pll[8] = 0x20, .pll[9] = 0xFF, 1407 .pll[10] = 0xFF, .pll[11] = 0x77, .pll[12] = 0x57, .pll[13] = 0x77, .pll[14] = 0x77, 1408 .pll[15] = 0x0C, .pll[16] = 0x08, .pll[17] = 0x8F, .pll[18] = 0x84, .pll[19] = 0x23, 1409 }; 1410 1411 static const struct intel_c10pll_state mtl_c10_hdmi_58000 = { 1412 .tx = 0x10, 1413 .cmn = 0x1, 1414 .pll[0] = 0x34, .pll[1] = 0x00, .pll[2] = 0xD0, .pll[3] = 0x00, .pll[4] = 0x00, 1415 .pll[5] = 0x00, .pll[6] = 0x00, .pll[7] = 0x00, .pll[8] = 0x20, .pll[9] = 0xFF, 1416 .pll[10] = 0xFF, .pll[11] = 0x55, .pll[12] = 0xD5, .pll[13] = 0x55, .pll[14] = 0x55, 1417 .pll[15] = 0x0C, .pll[16] = 0x08, .pll[17] = 0xCF, .pll[18] = 0x84, .pll[19] = 0x23, 1418 }; 1419 1420 static const struct intel_c10pll_state mtl_c10_hdmi_65000 = { 1421 .tx = 0x10, 1422 .cmn = 0x1, 1423 .pll[0] = 0xF4, .pll[1] = 0x00, .pll[2] = 0x66, .pll[3] = 0x00, .pll[4] = 0x00, 1424 .pll[5] = 0x00, .pll[6] = 0x00, .pll[7] = 0x00, .pll[8] = 0x20, .pll[9] = 0xFF, 1425 .pll[10] = 0xFF, .pll[11] = 0x55, .pll[12] = 0xB5, .pll[13] = 0x55, .pll[14] = 0x55, 1426 .pll[15] = 0x0B, .pll[16] = 0x09, .pll[17] = 0xCF, .pll[18] = 0x84, .pll[19] = 0x23, 1427 }; 1428 1429 static const struct intel_c10pll_state mtl_c10_hdmi_71000 = { 1430 .tx = 0x10, 1431 .cmn = 0x1, 1432 .pll[0] = 0xF4, .pll[1] = 0x00, .pll[2] = 0x72, .pll[3] = 0x00, .pll[4] = 0x00, 1433 .pll[5] = 0x00, .pll[6] = 0x00, .pll[7] = 0x00, .pll[8] = 0x20, .pll[9] = 0xFF, 1434 .pll[10] = 0xFF, .pll[11] = 0x55, .pll[12] = 0xF5, .pll[13] = 0x55, .pll[14] = 0x55, 1435 .pll[15] = 0x0B, .pll[16] = 0x08, .pll[17] = 0x8F, .pll[18] = 0x84, .pll[19] = 0x23, 1436 }; 1437 1438 static const struct intel_c10pll_state mtl_c10_hdmi_74176 = { 1439 .tx = 0x10, 1440 .cmn = 0x1, 1441 .pll[0] = 0xF4, .pll[1] = 0x00, .pll[2] = 0x7A, .pll[3] = 0x00, .pll[4] = 0x00, 1442 .pll[5] = 0x00, .pll[6] = 0x00, .pll[7] = 0x00, .pll[8] = 0x20, .pll[9] = 0xFF, 1443 .pll[10] = 0xFF, .pll[11] = 0x44, .pll[12] = 0x44, .pll[13] = 0x44, .pll[14] = 0x44, 1444 .pll[15] = 0x0B, .pll[16] = 0x08, .pll[17] = 0x8F, .pll[18] = 0x84, .pll[19] = 0x23, 1445 }; 1446 1447 static const struct intel_c10pll_state mtl_c10_hdmi_75000 = { 1448 .tx = 0x10, 1449 .cmn = 0x1, 1450 .pll[0] = 0xF4, .pll[1] = 0x00, .pll[2] = 0x7C, .pll[3] = 0x00, .pll[4] = 0x00, 1451 .pll[5] = 0x00, .pll[6] = 0x00, .pll[7] = 0x00, .pll[8] = 0x20, .pll[9] = 0xFF, 1452 .pll[10] = 0xFF, .pll[11] = 0x00, .pll[12] = 0x20, .pll[13] = 0x00, .pll[14] = 0x00, 1453 .pll[15] = 0x0B, .pll[16] = 0x08, .pll[17] = 0xCF, .pll[18] = 0x84, .pll[19] = 0x23, 1454 }; 1455 1456 static const struct intel_c10pll_state mtl_c10_hdmi_78750 = { 1457 .tx = 0x10, 1458 .cmn = 0x1, 1459 .pll[0] = 0xB4, .pll[1] = 0x00, .pll[2] = 0x84, .pll[3] = 0x00, .pll[4] = 0x00, 1460 .pll[5] = 0x00, .pll[6] = 0x00, .pll[7] = 0x00, .pll[8] = 0x20, .pll[9] = 0xFF, 1461 .pll[10] = 0xFF, .pll[11] = 0x00, .pll[12] = 0x08, .pll[13] = 0x00, .pll[14] = 0x00, 1462 .pll[15] = 0x0B, .pll[16] = 0x08, .pll[17] = 0x8F, .pll[18] = 0x84, .pll[19] = 0x23, 1463 }; 1464 1465 static const struct intel_c10pll_state mtl_c10_hdmi_85500 = { 1466 .tx = 0x10, 1467 .cmn = 0x1, 1468 .pll[0] = 0xB4, .pll[1] = 0x00, .pll[2] = 0x92, .pll[3] = 0x00, .pll[4] = 0x00, 1469 .pll[5] = 0x00, .pll[6] = 0x00, .pll[7] = 0x00, .pll[8] = 0x20, .pll[9] = 0xFF, 1470 .pll[10] = 0xFF, .pll[11] = 0x00, .pll[12] = 0x10, .pll[13] = 0x00, .pll[14] = 0x00, 1471 .pll[15] = 0x0B, .pll[16] = 0x08, .pll[17] = 0xCF, .pll[18] = 0x84, .pll[19] = 0x23, 1472 }; 1473 1474 static const struct intel_c10pll_state mtl_c10_hdmi_88750 = { 1475 .tx = 0x10, 1476 .cmn = 0x1, 1477 .pll[0] = 0x74, .pll[1] = 0x00, .pll[2] = 0x98, .pll[3] = 0x00, .pll[4] = 0x00, 1478 .pll[5] = 0x00, .pll[6] = 0x00, .pll[7] = 0x00, .pll[8] = 0x20, .pll[9] = 0xFF, 1479 .pll[10] = 0xFF, .pll[11] = 0xAA, .pll[12] = 0x72, .pll[13] = 0xA9, .pll[14] = 0xAA, 1480 .pll[15] = 0x0B, .pll[16] = 0x09, .pll[17] = 0xCF, .pll[18] = 0x84, .pll[19] = 0x23, 1481 }; 1482 1483 static const struct intel_c10pll_state mtl_c10_hdmi_106500 = { 1484 .tx = 0x10, 1485 .cmn = 0x1, 1486 .pll[0] = 0x34, .pll[1] = 0x00, .pll[2] = 0xBC, .pll[3] = 0x00, .pll[4] = 0x00, 1487 .pll[5] = 0x00, .pll[6] = 0x00, .pll[7] = 0x00, .pll[8] = 0x20, .pll[9] = 0xFF, 1488 .pll[10] = 0xFF, .pll[11] = 0x00, .pll[12] = 0xF0, .pll[13] = 0x00, .pll[14] = 0x00, 1489 .pll[15] = 0x0B, .pll[16] = 0x08, .pll[17] = 0x8F, .pll[18] = 0x84, .pll[19] = 0x23, 1490 }; 1491 1492 static const struct intel_c10pll_state mtl_c10_hdmi_108000 = { 1493 .tx = 0x10, 1494 .cmn = 0x1, 1495 .pll[0] = 0x34, .pll[1] = 0x00, .pll[2] = 0xC0, .pll[3] = 0x00, .pll[4] = 0x00, 1496 .pll[5] = 0x00, .pll[6] = 0x00, .pll[7] = 0x00, .pll[8] = 0x20, .pll[9] = 0xFF, 1497 .pll[10] = 0xFF, .pll[11] = 0x00, .pll[12] = 0x80, .pll[13] = 0x00, .pll[14] = 0x00, 1498 .pll[15] = 0x0B, .pll[16] = 0x08, .pll[17] = 0x8F, .pll[18] = 0x84, .pll[19] = 0x23, 1499 }; 1500 1501 static const struct intel_c10pll_state mtl_c10_hdmi_115500 = { 1502 .tx = 0x10, 1503 .cmn = 0x1, 1504 .pll[0] = 0x34, .pll[1] = 0x00, .pll[2] = 0xD0, .pll[3] = 0x00, .pll[4] = 0x00, 1505 .pll[5] = 0x00, .pll[6] = 0x00, .pll[7] = 0x00, .pll[8] = 0x20, .pll[9] = 0xFF, 1506 .pll[10] = 0xFF, .pll[11] = 0x00, .pll[12] = 0x50, .pll[13] = 0x00, .pll[14] = 0x00, 1507 .pll[15] = 0x0B, .pll[16] = 0x08, .pll[17] = 0xCF, .pll[18] = 0x84, .pll[19] = 0x23, 1508 }; 1509 1510 static const struct intel_c10pll_state mtl_c10_hdmi_119000 = { 1511 .tx = 0x10, 1512 .cmn = 0x1, 1513 .pll[0] = 0x34, .pll[1] = 0x00, .pll[2] = 0xD6, .pll[3] = 0x00, .pll[4] = 0x00, 1514 .pll[5] = 0x00, .pll[6] = 0x00, .pll[7] = 0x00, .pll[8] = 0x20, .pll[9] = 0xFF, 1515 .pll[10] = 0xFF, .pll[11] = 0x55, .pll[12] = 0xF5, .pll[13] = 0x55, .pll[14] = 0x55, 1516 .pll[15] = 0x0B, .pll[16] = 0x08, .pll[17] = 0xCF, .pll[18] = 0x84, .pll[19] = 0x23, 1517 }; 1518 1519 static const struct intel_c10pll_state mtl_c10_hdmi_135000 = { 1520 .tx = 0x10, 1521 .cmn = 0x1, 1522 .pll[0] = 0xF4, .pll[1] = 0x00, .pll[2] = 0x6C, .pll[3] = 0x00, .pll[4] = 0x00, 1523 .pll[5] = 0x00, .pll[6] = 0x00, .pll[7] = 0x00, .pll[8] = 0x20, .pll[9] = 0xFF, 1524 .pll[10] = 0xFF, .pll[11] = 0x00, .pll[12] = 0x50, .pll[13] = 0x00, .pll[14] = 0x00, 1525 .pll[15] = 0x0A, .pll[16] = 0x09, .pll[17] = 0xCF, .pll[18] = 0x84, .pll[19] = 0x23, 1526 }; 1527 1528 static const struct intel_c10pll_state mtl_c10_hdmi_138500 = { 1529 .tx = 0x10, 1530 .cmn = 0x1, 1531 .pll[0] = 0xF4, .pll[1] = 0x00, .pll[2] = 0x70, .pll[3] = 0x00, .pll[4] = 0x00, 1532 .pll[5] = 0x00, .pll[6] = 0x00, .pll[7] = 0x00, .pll[8] = 0x20, .pll[9] = 0xFF, 1533 .pll[10] = 0xFF, .pll[11] = 0xAA, .pll[12] = 0x22, .pll[13] = 0xA9, .pll[14] = 0xAA, 1534 .pll[15] = 0x0A, .pll[16] = 0x08, .pll[17] = 0x8F, .pll[18] = 0x84, .pll[19] = 0x23, 1535 }; 1536 1537 static const struct intel_c10pll_state mtl_c10_hdmi_147160 = { 1538 .tx = 0x10, 1539 .cmn = 0x1, 1540 .pll[0] = 0xF4, .pll[1] = 0x00, .pll[2] = 0x78, .pll[3] = 0x00, .pll[4] = 0x00, 1541 .pll[5] = 0x00, .pll[6] = 0x00, .pll[7] = 0x00, .pll[8] = 0x20, .pll[9] = 0xFF, 1542 .pll[10] = 0xFF, .pll[11] = 0x55, .pll[12] = 0xA5, .pll[13] = 0x55, .pll[14] = 0x55, 1543 .pll[15] = 0x0A, .pll[16] = 0x08, .pll[17] = 0x8F, .pll[18] = 0x84, .pll[19] = 0x23, 1544 }; 1545 1546 static const struct intel_c10pll_state mtl_c10_hdmi_148352 = { 1547 .tx = 0x10, 1548 .cmn = 0x1, 1549 .pll[0] = 0xF4, .pll[1] = 0x00, .pll[2] = 0x7A, .pll[3] = 0x00, .pll[4] = 0x00, 1550 .pll[5] = 0x00, .pll[6] = 0x00, .pll[7] = 0x00, .pll[8] = 0x20, .pll[9] = 0xFF, 1551 .pll[10] = 0xFF, .pll[11] = 0x44, .pll[12] = 0x44, .pll[13] = 0x44, .pll[14] = 0x44, 1552 .pll[15] = 0x0A, .pll[16] = 0x08, .pll[17] = 0x8F, .pll[18] = 0x84, .pll[19] = 0x23, 1553 }; 1554 1555 static const struct intel_c10pll_state mtl_c10_hdmi_154000 = { 1556 .tx = 0x10, 1557 .cmn = 0x1, 1558 .pll[0] = 0xB4, .pll[1] = 0x00, .pll[2] = 0x80, .pll[3] = 0x00, .pll[4] = 0x00, 1559 .pll[5] = 0x00, .pll[6] = 0x00, .pll[7] = 0x00, .pll[8] = 0x20, .pll[9] = 0xFF, 1560 .pll[10] = 0xFF, .pll[11] = 0x55, .pll[12] = 0x35, .pll[13] = 0x55, .pll[14] = 0x55, 1561 .pll[15] = 0x0A, .pll[16] = 0x08, .pll[17] = 0x8F, .pll[18] = 0x84, .pll[19] = 0x23, 1562 }; 1563 1564 static const struct intel_c10pll_state mtl_c10_hdmi_162000 = { 1565 .tx = 0x10, 1566 .cmn = 0x1, 1567 .pll[0] = 0xB4, .pll[1] = 0x00, .pll[2] = 0x88, .pll[3] = 0x00, .pll[4] = 0x00, 1568 .pll[5] = 0x00, .pll[6] = 0x00, .pll[7] = 0x00, .pll[8] = 0x20, .pll[9] = 0xFF, 1569 .pll[10] = 0xFF, .pll[11] = 0x00, .pll[12] = 0x60, .pll[13] = 0x00, .pll[14] = 0x00, 1570 .pll[15] = 0x0A, .pll[16] = 0x08, .pll[17] = 0x8F, .pll[18] = 0x84, .pll[19] = 0x23, 1571 }; 1572 1573 static const struct intel_c10pll_state mtl_c10_hdmi_167000 = { 1574 .tx = 0x10, 1575 .cmn = 0x1, 1576 .pll[0] = 0xB4, .pll[1] = 0x00, .pll[2] = 0x8C, .pll[3] = 0x00, .pll[4] = 0x00, 1577 .pll[5] = 0x00, .pll[6] = 0x00, .pll[7] = 0x00, .pll[8] = 0x20, .pll[9] = 0xFF, 1578 .pll[10] = 0xFF, .pll[11] = 0xAA, .pll[12] = 0xFA, .pll[13] = 0xA9, .pll[14] = 0xAA, 1579 .pll[15] = 0x0A, .pll[16] = 0x08, .pll[17] = 0x8F, .pll[18] = 0x84, .pll[19] = 0x23, 1580 }; 1581 1582 static const struct intel_c10pll_state mtl_c10_hdmi_197802 = { 1583 .tx = 0x10, 1584 .cmn = 0x1, 1585 .pll[0] = 0x74, .pll[1] = 0x00, .pll[2] = 0xAE, .pll[3] = 0x00, .pll[4] = 0x00, 1586 .pll[5] = 0x00, .pll[6] = 0x00, .pll[7] = 0x00, .pll[8] = 0x20, .pll[9] = 0xFF, 1587 .pll[10] = 0xFF, .pll[11] = 0x99, .pll[12] = 0x05, .pll[13] = 0x98, .pll[14] = 0x99, 1588 .pll[15] = 0x0A, .pll[16] = 0x08, .pll[17] = 0xCF, .pll[18] = 0x84, .pll[19] = 0x23, 1589 }; 1590 1591 static const struct intel_c10pll_state mtl_c10_hdmi_198000 = { 1592 .tx = 0x10, 1593 .cmn = 0x1, 1594 .pll[0] = 0x74, .pll[1] = 0x00, .pll[2] = 0xAE, .pll[3] = 0x00, .pll[4] = 0x00, 1595 .pll[5] = 0x00, .pll[6] = 0x00, .pll[7] = 0x00, .pll[8] = 0x20, .pll[9] = 0xFF, 1596 .pll[10] = 0xFF, .pll[11] = 0x00, .pll[12] = 0x20, .pll[13] = 0x00, .pll[14] = 0x00, 1597 .pll[15] = 0x0A, .pll[16] = 0x08, .pll[17] = 0xCF, .pll[18] = 0x84, .pll[19] = 0x23, 1598 }; 1599 1600 static const struct intel_c10pll_state mtl_c10_hdmi_209800 = { 1601 .tx = 0x10, 1602 .cmn = 0x1, 1603 .pll[0] = 0x34, .pll[1] = 0x00, .pll[2] = 0xBA, .pll[3] = 0x00, .pll[4] = 0x00, 1604 .pll[5] = 0x00, .pll[6] = 0x00, .pll[7] = 0x00, .pll[8] = 0x20, .pll[9] = 0xFF, 1605 .pll[10] = 0xFF, .pll[11] = 0x55, .pll[12] = 0x45, .pll[13] = 0x55, .pll[14] = 0x55, 1606 .pll[15] = 0x0A, .pll[16] = 0x08, .pll[17] = 0x8F, .pll[18] = 0x84, .pll[19] = 0x23, 1607 }; 1608 1609 static const struct intel_c10pll_state mtl_c10_hdmi_241500 = { 1610 .tx = 0x10, 1611 .cmn = 0x1, 1612 .pll[0] = 0x34, .pll[1] = 0x00, .pll[2] = 0xDA, .pll[3] = 0x00, .pll[4] = 0x00, 1613 .pll[5] = 0x00, .pll[6] = 0x00, .pll[7] = 0x00, .pll[8] = 0x20, .pll[9] = 0xFF, 1614 .pll[10] = 0xFF, .pll[11] = 0x00, .pll[12] = 0xC8, .pll[13] = 0x00, .pll[14] = 0x00, 1615 .pll[15] = 0x0A, .pll[16] = 0x08, .pll[17] = 0xCF, .pll[18] = 0x84, .pll[19] = 0x23, 1616 }; 1617 1618 static const struct intel_c10pll_state mtl_c10_hdmi_262750 = { 1619 .tx = 0x10, 1620 .cmn = 0x1, 1621 .pll[0] = 0xF4, .pll[1] = 0x00, .pll[2] = 0x68, .pll[3] = 0x00, .pll[4] = 0x00, 1622 .pll[5] = 0x00, .pll[6] = 0x00, .pll[7] = 0x00, .pll[8] = 0x20, .pll[9] = 0xFF, 1623 .pll[10] = 0xFF, .pll[11] = 0xAA, .pll[12] = 0x6C, .pll[13] = 0xA9, .pll[14] = 0xAA, 1624 .pll[15] = 0x09, .pll[16] = 0x09, .pll[17] = 0xCF, .pll[18] = 0x84, .pll[19] = 0x23, 1625 }; 1626 1627 static const struct intel_c10pll_state mtl_c10_hdmi_268500 = { 1628 .tx = 0x10, 1629 .cmn = 0x1, 1630 .pll[0] = 0xF4, .pll[1] = 0x00, .pll[2] = 0x6A, .pll[3] = 0x00, .pll[4] = 0x00, 1631 .pll[5] = 0x00, .pll[6] = 0x00, .pll[7] = 0x00, .pll[8] = 0x20, .pll[9] = 0xFF, 1632 .pll[10] = 0xFF, .pll[11] = 0x00, .pll[12] = 0xEC, .pll[13] = 0x00, .pll[14] = 0x00, 1633 .pll[15] = 0x09, .pll[16] = 0x09, .pll[17] = 0xCF, .pll[18] = 0x84, .pll[19] = 0x23, 1634 }; 1635 1636 static const struct intel_c10pll_state mtl_c10_hdmi_296703 = { 1637 .tx = 0x10, 1638 .cmn = 0x1, 1639 .pll[0] = 0xF4, .pll[1] = 0x00, .pll[2] = 0x7A, .pll[3] = 0x00, .pll[4] = 0x00, 1640 .pll[5] = 0x00, .pll[6] = 0x00, .pll[7] = 0x00, .pll[8] = 0x20, .pll[9] = 0xFF, 1641 .pll[10] = 0xFF, .pll[11] = 0x33, .pll[12] = 0x44, .pll[13] = 0x33, .pll[14] = 0x33, 1642 .pll[15] = 0x09, .pll[16] = 0x08, .pll[17] = 0x8F, .pll[18] = 0x84, .pll[19] = 0x23, 1643 }; 1644 1645 static const struct intel_c10pll_state mtl_c10_hdmi_297000 = { 1646 .tx = 0x10, 1647 .cmn = 0x1, 1648 .pll[0] = 0xF4, .pll[1] = 0x00, .pll[2] = 0x7A, .pll[3] = 0x00, .pll[4] = 0x00, 1649 .pll[5] = 0x00, .pll[6] = 0x00, .pll[7] = 0x00, .pll[8] = 0x20, .pll[9] = 0xFF, 1650 .pll[10] = 0xFF, .pll[11] = 0x00, .pll[12] = 0x58, .pll[13] = 0x00, .pll[14] = 0x00, 1651 .pll[15] = 0x09, .pll[16] = 0x08, .pll[17] = 0x8F, .pll[18] = 0x84, .pll[19] = 0x23, 1652 }; 1653 1654 static const struct intel_c10pll_state mtl_c10_hdmi_319750 = { 1655 .tx = 0x10, 1656 .cmn = 0x1, 1657 .pll[0] = 0xB4, .pll[1] = 0x00, .pll[2] = 0x86, .pll[3] = 0x00, .pll[4] = 0x00, 1658 .pll[5] = 0x00, .pll[6] = 0x00, .pll[7] = 0x00, .pll[8] = 0x20, .pll[9] = 0xFF, 1659 .pll[10] = 0xFF, .pll[11] = 0xAA, .pll[12] = 0x44, .pll[13] = 0xA9, .pll[14] = 0xAA, 1660 .pll[15] = 0x09, .pll[16] = 0x08, .pll[17] = 0x8F, .pll[18] = 0x84, .pll[19] = 0x23, 1661 }; 1662 1663 static const struct intel_c10pll_state mtl_c10_hdmi_497750 = { 1664 .tx = 0x10, 1665 .cmn = 0x1, 1666 .pll[0] = 0x34, .pll[1] = 0x00, .pll[2] = 0xE2, .pll[3] = 0x00, .pll[4] = 0x00, 1667 .pll[5] = 0x00, .pll[6] = 0x00, .pll[7] = 0x00, .pll[8] = 0x20, .pll[9] = 0xFF, 1668 .pll[10] = 0xFF, .pll[11] = 0x55, .pll[12] = 0x9F, .pll[13] = 0x55, .pll[14] = 0x55, 1669 .pll[15] = 0x09, .pll[16] = 0x08, .pll[17] = 0xCF, .pll[18] = 0x84, .pll[19] = 0x23, 1670 }; 1671 1672 static const struct intel_c10pll_state mtl_c10_hdmi_592000 = { 1673 .tx = 0x10, 1674 .cmn = 0x1, 1675 .pll[0] = 0xF4, .pll[1] = 0x00, .pll[2] = 0x7A, .pll[3] = 0x00, .pll[4] = 0x00, 1676 .pll[5] = 0x00, .pll[6] = 0x00, .pll[7] = 0x00, .pll[8] = 0x20, .pll[9] = 0xFF, 1677 .pll[10] = 0xFF, .pll[11] = 0x55, .pll[12] = 0x15, .pll[13] = 0x55, .pll[14] = 0x55, 1678 .pll[15] = 0x08, .pll[16] = 0x08, .pll[17] = 0x8F, .pll[18] = 0x84, .pll[19] = 0x23, 1679 }; 1680 1681 static const struct intel_c10pll_state mtl_c10_hdmi_593407 = { 1682 .tx = 0x10, 1683 .cmn = 0x1, 1684 .pll[0] = 0xF4, .pll[1] = 0x00, .pll[2] = 0x7A, .pll[3] = 0x00, .pll[4] = 0x00, 1685 .pll[5] = 0x00, .pll[6] = 0x00, .pll[7] = 0x00, .pll[8] = 0x20, .pll[9] = 0xFF, 1686 .pll[10] = 0xFF, .pll[11] = 0x3B, .pll[12] = 0x44, .pll[13] = 0xBA, .pll[14] = 0xBB, 1687 .pll[15] = 0x08, .pll[16] = 0x08, .pll[17] = 0x8F, .pll[18] = 0x84, .pll[19] = 0x23, 1688 }; 1689 1690 static const struct intel_cx0pll_params mtl_c10_hdmi_tables[] = { 1691 C10PLL_HDMI_PARAMS(25200, mtl_c10_hdmi_25_2), /* Consolidated Table */ 1692 C10PLL_HDMI_PARAMS(27000, mtl_c10_hdmi_27_0), /* Consolidated Table */ 1693 C10PLL_HDMI_PARAMS(27027, mtl_c10_hdmi_27027), 1694 C10PLL_HDMI_PARAMS(28320, mtl_c10_hdmi_28320), 1695 C10PLL_HDMI_PARAMS(30240, mtl_c10_hdmi_30240), 1696 C10PLL_HDMI_PARAMS(31500, mtl_c10_hdmi_31500), 1697 C10PLL_HDMI_PARAMS(36000, mtl_c10_hdmi_36000), 1698 C10PLL_HDMI_PARAMS(40000, mtl_c10_hdmi_40000), 1699 C10PLL_HDMI_PARAMS(49500, mtl_c10_hdmi_49500), 1700 C10PLL_HDMI_PARAMS(50000, mtl_c10_hdmi_50000), 1701 C10PLL_HDMI_PARAMS(57284, mtl_c10_hdmi_57284), 1702 C10PLL_HDMI_PARAMS(58000, mtl_c10_hdmi_58000), 1703 C10PLL_HDMI_PARAMS(65000, mtl_c10_hdmi_65000), 1704 C10PLL_HDMI_PARAMS(71000, mtl_c10_hdmi_71000), 1705 C10PLL_HDMI_PARAMS(74176, mtl_c10_hdmi_74176), 1706 C10PLL_HDMI_PARAMS(74250, mtl_c10_hdmi_74_25), /* Consolidated Table */ 1707 C10PLL_HDMI_PARAMS(75000, mtl_c10_hdmi_75000), 1708 C10PLL_HDMI_PARAMS(78750, mtl_c10_hdmi_78750), 1709 C10PLL_HDMI_PARAMS(85500, mtl_c10_hdmi_85500), 1710 C10PLL_HDMI_PARAMS(88750, mtl_c10_hdmi_88750), 1711 C10PLL_HDMI_PARAMS(106500, mtl_c10_hdmi_106500), 1712 C10PLL_HDMI_PARAMS(108000, mtl_c10_hdmi_108000), 1713 C10PLL_HDMI_PARAMS(115500, mtl_c10_hdmi_115500), 1714 C10PLL_HDMI_PARAMS(119000, mtl_c10_hdmi_119000), 1715 C10PLL_HDMI_PARAMS(135000, mtl_c10_hdmi_135000), 1716 C10PLL_HDMI_PARAMS(138500, mtl_c10_hdmi_138500), 1717 C10PLL_HDMI_PARAMS(147160, mtl_c10_hdmi_147160), 1718 C10PLL_HDMI_PARAMS(148352, mtl_c10_hdmi_148352), 1719 C10PLL_HDMI_PARAMS(148500, mtl_c10_hdmi_148_5), /* Consolidated Table */ 1720 C10PLL_HDMI_PARAMS(154000, mtl_c10_hdmi_154000), 1721 C10PLL_HDMI_PARAMS(162000, mtl_c10_hdmi_162000), 1722 C10PLL_HDMI_PARAMS(167000, mtl_c10_hdmi_167000), 1723 C10PLL_HDMI_PARAMS(197802, mtl_c10_hdmi_197802), 1724 C10PLL_HDMI_PARAMS(198000, mtl_c10_hdmi_198000), 1725 C10PLL_HDMI_PARAMS(209800, mtl_c10_hdmi_209800), 1726 C10PLL_HDMI_PARAMS(241500, mtl_c10_hdmi_241500), 1727 C10PLL_HDMI_PARAMS(262750, mtl_c10_hdmi_262750), 1728 C10PLL_HDMI_PARAMS(268500, mtl_c10_hdmi_268500), 1729 C10PLL_HDMI_PARAMS(296703, mtl_c10_hdmi_296703), 1730 C10PLL_HDMI_PARAMS(297000, mtl_c10_hdmi_297000), 1731 C10PLL_HDMI_PARAMS(319750, mtl_c10_hdmi_319750), 1732 C10PLL_HDMI_PARAMS(497750, mtl_c10_hdmi_497750), 1733 C10PLL_HDMI_PARAMS(592000, mtl_c10_hdmi_592000), 1734 C10PLL_HDMI_PARAMS(593407, mtl_c10_hdmi_593407), 1735 C10PLL_HDMI_PARAMS(594000, mtl_c10_hdmi_594), /* Consolidated Table */ 1736 {} 1737 }; 1738 1739 static const struct intel_c20pll_state mtl_c20_hdmi_27_0 = { 1740 .tx = { 0xbe88, /* tx cfg0 */ 1741 0x9800, /* tx cfg1 */ 1742 0x0000, /* tx cfg2 */ 1743 }, 1744 .cmn = { 0x0500, /* cmn cfg0*/ 1745 0x0005, /* cmn cfg1 */ 1746 0x0000, /* cmn cfg2 */ 1747 0x0000, /* cmn cfg3 */ 1748 }, 1749 .mpllb = { 0xa0e0, /* mpllb cfg0 */ 1750 0x7d80, /* mpllb cfg1 */ 1751 0x0906, /* mpllb cfg2 */ 1752 0xbe40, /* mpllb cfg3 */ 1753 0x0000, /* mpllb cfg4 */ 1754 0x0000, /* mpllb cfg5 */ 1755 0x2200, /* mpllb cfg6 */ 1756 0x0001, /* mpllb cfg7 */ 1757 0x8000, /* mpllb cfg8 */ 1758 0x0000, /* mpllb cfg9 */ 1759 0x0001, /* mpllb cfg10 */ 1760 }, 1761 }; 1762 1763 static const struct intel_c20pll_state mtl_c20_hdmi_74_25 = { 1764 .tx = { 0xbe88, /* tx cfg0 */ 1765 0x9800, /* tx cfg1 */ 1766 0x0000, /* tx cfg2 */ 1767 }, 1768 .cmn = { 0x0500, /* cmn cfg0*/ 1769 0x0005, /* cmn cfg1 */ 1770 0x0000, /* cmn cfg2 */ 1771 0x0000, /* cmn cfg3 */ 1772 }, 1773 .mpllb = { 0x609a, /* mpllb cfg0 */ 1774 0x7d40, /* mpllb cfg1 */ 1775 0xca06, /* mpllb cfg2 */ 1776 0xbe40, /* mpllb cfg3 */ 1777 0x0000, /* mpllb cfg4 */ 1778 0x0000, /* mpllb cfg5 */ 1779 0x2200, /* mpllb cfg6 */ 1780 0x0001, /* mpllb cfg7 */ 1781 0x5800, /* mpllb cfg8 */ 1782 0x0000, /* mpllb cfg9 */ 1783 0x0001, /* mpllb cfg10 */ 1784 }, 1785 }; 1786 1787 static const struct intel_c20pll_state mtl_c20_hdmi_148_5 = { 1788 .tx = { 0xbe88, /* tx cfg0 */ 1789 0x9800, /* tx cfg1 */ 1790 0x0000, /* tx cfg2 */ 1791 }, 1792 .cmn = { 0x0500, /* cmn cfg0*/ 1793 0x0005, /* cmn cfg1 */ 1794 0x0000, /* cmn cfg2 */ 1795 0x0000, /* cmn cfg3 */ 1796 }, 1797 .mpllb = { 0x409a, /* mpllb cfg0 */ 1798 0x7d20, /* mpllb cfg1 */ 1799 0xca06, /* mpllb cfg2 */ 1800 0xbe40, /* mpllb cfg3 */ 1801 0x0000, /* mpllb cfg4 */ 1802 0x0000, /* mpllb cfg5 */ 1803 0x2200, /* mpllb cfg6 */ 1804 0x0001, /* mpllb cfg7 */ 1805 0x5800, /* mpllb cfg8 */ 1806 0x0000, /* mpllb cfg9 */ 1807 0x0001, /* mpllb cfg10 */ 1808 }, 1809 }; 1810 1811 static const struct intel_c20pll_state mtl_c20_hdmi_594 = { 1812 .tx = { 0xbe88, /* tx cfg0 */ 1813 0x9800, /* tx cfg1 */ 1814 0x0000, /* tx cfg2 */ 1815 }, 1816 .cmn = { 0x0500, /* cmn cfg0*/ 1817 0x0005, /* cmn cfg1 */ 1818 0x0000, /* cmn cfg2 */ 1819 0x0000, /* cmn cfg3 */ 1820 }, 1821 .mpllb = { 0x009a, /* mpllb cfg0 */ 1822 0x7d08, /* mpllb cfg1 */ 1823 0xca06, /* mpllb cfg2 */ 1824 0xbe40, /* mpllb cfg3 */ 1825 0x0000, /* mpllb cfg4 */ 1826 0x0000, /* mpllb cfg5 */ 1827 0x2200, /* mpllb cfg6 */ 1828 0x0001, /* mpllb cfg7 */ 1829 0x5800, /* mpllb cfg8 */ 1830 0x0000, /* mpllb cfg9 */ 1831 0x0001, /* mpllb cfg10 */ 1832 }, 1833 }; 1834 1835 static const struct intel_c20pll_state mtl_c20_hdmi_300 = { 1836 .tx = { 0xbe98, /* tx cfg0 */ 1837 0x8800, /* tx cfg1 */ 1838 0x0000, /* tx cfg2 */ 1839 }, 1840 .cmn = { 0x0500, /* cmn cfg0*/ 1841 0x0005, /* cmn cfg1 */ 1842 0x0000, /* cmn cfg2 */ 1843 0x0000, /* cmn cfg3 */ 1844 }, 1845 .mpllb = { 0x309c, /* mpllb cfg0 */ 1846 0x2110, /* mpllb cfg1 */ 1847 0xca06, /* mpllb cfg2 */ 1848 0xbe40, /* mpllb cfg3 */ 1849 0x0000, /* mpllb cfg4 */ 1850 0x0000, /* mpllb cfg5 */ 1851 0x2200, /* mpllb cfg6 */ 1852 0x0001, /* mpllb cfg7 */ 1853 0x2000, /* mpllb cfg8 */ 1854 0x0000, /* mpllb cfg9 */ 1855 0x0004, /* mpllb cfg10 */ 1856 }, 1857 }; 1858 1859 static const struct intel_c20pll_state mtl_c20_hdmi_600 = { 1860 .tx = { 0xbe98, /* tx cfg0 */ 1861 0x8800, /* tx cfg1 */ 1862 0x0000, /* tx cfg2 */ 1863 }, 1864 .cmn = { 0x0500, /* cmn cfg0*/ 1865 0x0005, /* cmn cfg1 */ 1866 0x0000, /* cmn cfg2 */ 1867 0x0000, /* cmn cfg3 */ 1868 }, 1869 .mpllb = { 0x109c, /* mpllb cfg0 */ 1870 0x2108, /* mpllb cfg1 */ 1871 0xca06, /* mpllb cfg2 */ 1872 0xbe40, /* mpllb cfg3 */ 1873 0x0000, /* mpllb cfg4 */ 1874 0x0000, /* mpllb cfg5 */ 1875 0x2200, /* mpllb cfg6 */ 1876 0x0001, /* mpllb cfg7 */ 1877 0x2000, /* mpllb cfg8 */ 1878 0x0000, /* mpllb cfg9 */ 1879 0x0004, /* mpllb cfg10 */ 1880 }, 1881 }; 1882 1883 static const struct intel_c20pll_state mtl_c20_hdmi_800 = { 1884 .tx = { 0xbe98, /* tx cfg0 */ 1885 0x8800, /* tx cfg1 */ 1886 0x0000, /* tx cfg2 */ 1887 }, 1888 .cmn = { 0x0500, /* cmn cfg0*/ 1889 0x0005, /* cmn cfg1 */ 1890 0x0000, /* cmn cfg2 */ 1891 0x0000, /* cmn cfg3 */ 1892 }, 1893 .mpllb = { 0x10d0, /* mpllb cfg0 */ 1894 0x2108, /* mpllb cfg1 */ 1895 0x4a06, /* mpllb cfg2 */ 1896 0xbe40, /* mpllb cfg3 */ 1897 0x0000, /* mpllb cfg4 */ 1898 0x0000, /* mpllb cfg5 */ 1899 0x2200, /* mpllb cfg6 */ 1900 0x0003, /* mpllb cfg7 */ 1901 0x2aaa, /* mpllb cfg8 */ 1902 0x0002, /* mpllb cfg9 */ 1903 0x0004, /* mpllb cfg10 */ 1904 }, 1905 }; 1906 1907 static const struct intel_c20pll_state mtl_c20_hdmi_1000 = { 1908 .tx = { 0xbe98, /* tx cfg0 */ 1909 0x8800, /* tx cfg1 */ 1910 0x0000, /* tx cfg2 */ 1911 }, 1912 .cmn = { 0x0500, /* cmn cfg0*/ 1913 0x0005, /* cmn cfg1 */ 1914 0x0000, /* cmn cfg2 */ 1915 0x0000, /* cmn cfg3 */ 1916 }, 1917 .mpllb = { 0x1104, /* mpllb cfg0 */ 1918 0x2108, /* mpllb cfg1 */ 1919 0x0a06, /* mpllb cfg2 */ 1920 0xbe40, /* mpllb cfg3 */ 1921 0x0000, /* mpllb cfg4 */ 1922 0x0000, /* mpllb cfg5 */ 1923 0x2200, /* mpllb cfg6 */ 1924 0x0003, /* mpllb cfg7 */ 1925 0x3555, /* mpllb cfg8 */ 1926 0x0001, /* mpllb cfg9 */ 1927 0x0004, /* mpllb cfg10 */ 1928 }, 1929 }; 1930 1931 static const struct intel_c20pll_state mtl_c20_hdmi_1200 = { 1932 .tx = { 0xbe98, /* tx cfg0 */ 1933 0x8800, /* tx cfg1 */ 1934 0x0000, /* tx cfg2 */ 1935 }, 1936 .cmn = { 0x0500, /* cmn cfg0*/ 1937 0x0005, /* cmn cfg1 */ 1938 0x0000, /* cmn cfg2 */ 1939 0x0000, /* cmn cfg3 */ 1940 }, 1941 .mpllb = { 0x1138, /* mpllb cfg0 */ 1942 0x2108, /* mpllb cfg1 */ 1943 0x5486, /* mpllb cfg2 */ 1944 0xfe40, /* mpllb cfg3 */ 1945 0x0000, /* mpllb cfg4 */ 1946 0x0000, /* mpllb cfg5 */ 1947 0x2200, /* mpllb cfg6 */ 1948 0x0001, /* mpllb cfg7 */ 1949 0x4000, /* mpllb cfg8 */ 1950 0x0000, /* mpllb cfg9 */ 1951 0x0004, /* mpllb cfg10 */ 1952 }, 1953 }; 1954 1955 static const struct intel_cx0pll_params mtl_c20_hdmi_tables[] = { 1956 C20PLL_HDMI_PARAMS(27000, mtl_c20_hdmi_27_0), 1957 C20PLL_HDMI_PARAMS(74250, mtl_c20_hdmi_74_25), 1958 C20PLL_HDMI_PARAMS(148500, mtl_c20_hdmi_148_5), 1959 C20PLL_HDMI_PARAMS(594000, mtl_c20_hdmi_594), 1960 C20PLL_HDMI_PARAMS(300000, mtl_c20_hdmi_300), 1961 C20PLL_HDMI_PARAMS(600000, mtl_c20_hdmi_600), 1962 C20PLL_HDMI_PARAMS(800000, mtl_c20_hdmi_800), 1963 C20PLL_HDMI_PARAMS(1000000, mtl_c20_hdmi_1000), 1964 C20PLL_HDMI_PARAMS(1200000, mtl_c20_hdmi_1200), 1965 {} 1966 }; 1967 1968 static const struct intel_cx0pll_params * 1969 intel_c10pll_tables_get(const struct intel_crtc_state *crtc_state, 1970 struct intel_encoder *encoder) 1971 { 1972 if (intel_crtc_has_dp_encoder(crtc_state)) { 1973 if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_EDP)) 1974 return mtl_c10_edp_tables; 1975 else 1976 return mtl_c10_dp_tables; 1977 } else if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_HDMI)) { 1978 return mtl_c10_hdmi_tables; 1979 } 1980 1981 MISSING_CASE(encoder->type); 1982 return NULL; 1983 } 1984 1985 static void intel_cx0pll_update_ssc(struct intel_encoder *encoder, 1986 struct intel_cx0pll_state *pll_state, bool is_dp) 1987 { 1988 struct intel_display *display = to_intel_display(encoder); 1989 1990 if (is_dp) { 1991 if (intel_panel_use_ssc(display)) { 1992 struct intel_dp *intel_dp = enc_to_intel_dp(encoder); 1993 pll_state->ssc_enabled = 1994 (intel_dp->dpcd[DP_MAX_DOWNSPREAD] & DP_MAX_DOWNSPREAD_0_5); 1995 } 1996 } 1997 } 1998 1999 #define C10_PLL_SSC_REG_START_IDX 4 2000 #define C10_PLL_SSC_REG_COUNT 5 2001 2002 static bool intel_c10pll_ssc_enabled(const struct intel_c10pll_state *pll_state) 2003 { 2004 return memchr_inv(&pll_state->pll[C10_PLL_SSC_REG_START_IDX], 2005 0, sizeof(pll_state->pll[0]) * C10_PLL_SSC_REG_COUNT); 2006 } 2007 2008 static void intel_c10pll_update_pll(struct intel_encoder *encoder, 2009 struct intel_cx0pll_state *pll_state) 2010 { 2011 struct intel_display *display = to_intel_display(encoder); 2012 int i; 2013 2014 if (pll_state->ssc_enabled) 2015 return; 2016 2017 drm_WARN_ON(display->drm, ARRAY_SIZE(pll_state->c10.pll) < 2018 C10_PLL_SSC_REG_START_IDX + C10_PLL_SSC_REG_COUNT); 2019 for (i = C10_PLL_SSC_REG_START_IDX; 2020 i < C10_PLL_SSC_REG_START_IDX + C10_PLL_SSC_REG_COUNT; 2021 i++) 2022 pll_state->c10.pll[i] = 0; 2023 } 2024 2025 static bool c10pll_state_is_dp(const struct intel_c10pll_state *pll_state) 2026 { 2027 return !REG_FIELD_GET8(C10_PLL15_HDMIDIV_MASK, pll_state->pll[15]); 2028 } 2029 2030 static bool c20pll_state_is_dp(const struct intel_c20pll_state *pll_state) 2031 { 2032 return pll_state->vdr.serdes_rate & PHY_C20_IS_DP; 2033 } 2034 2035 static bool cx0pll_state_is_dp(const struct intel_cx0pll_state *pll_state) 2036 { 2037 if (pll_state->use_c10) 2038 return c10pll_state_is_dp(&pll_state->c10); 2039 2040 return c20pll_state_is_dp(&pll_state->c20); 2041 } 2042 2043 static int intel_c10pll_calc_port_clock(const struct intel_c10pll_state *pll_state) 2044 { 2045 unsigned int frac_quot = 0, frac_rem = 0, frac_den = 1; 2046 unsigned int multiplier, tx_clk_div, hdmi_div, refclk = 38400; 2047 int tmpclk = 0; 2048 2049 if (pll_state->pll[0] & C10_PLL0_FRACEN) { 2050 frac_quot = pll_state->pll[12] << 8 | pll_state->pll[11]; 2051 frac_rem = pll_state->pll[14] << 8 | pll_state->pll[13]; 2052 frac_den = pll_state->pll[10] << 8 | pll_state->pll[9]; 2053 } 2054 2055 multiplier = (REG_FIELD_GET8(C10_PLL3_MULTIPLIERH_MASK, pll_state->pll[3]) << 8 | 2056 pll_state->pll[2]) / 2 + 16; 2057 2058 tx_clk_div = REG_FIELD_GET8(C10_PLL15_TXCLKDIV_MASK, pll_state->pll[15]); 2059 hdmi_div = REG_FIELD_GET8(C10_PLL15_HDMIDIV_MASK, pll_state->pll[15]); 2060 2061 tmpclk = DIV_ROUND_CLOSEST_ULL(mul_u32_u32(refclk, (multiplier << 16) + frac_quot) + 2062 DIV_ROUND_CLOSEST(refclk * frac_rem, frac_den), 2063 10 << (tx_clk_div + 16)); 2064 tmpclk *= (hdmi_div ? 2 : 1); 2065 2066 return tmpclk; 2067 } 2068 2069 static bool intel_c20phy_use_mpllb(const struct intel_c20pll_state *state) 2070 { 2071 return state->tx[0] & C20_PHY_USE_MPLLB; 2072 } 2073 2074 static int intel_c20pll_calc_port_clock(const struct intel_c20pll_state *pll_state) 2075 { 2076 unsigned int frac, frac_en, frac_quot, frac_rem, frac_den; 2077 unsigned int multiplier, refclk = 38400; 2078 unsigned int tx_clk_div; 2079 unsigned int ref_clk_mpllb_div; 2080 unsigned int fb_clk_div4_en; 2081 unsigned int ref, vco; 2082 unsigned int tx_rate_mult; 2083 unsigned int tx_rate = REG_FIELD_GET(C20_PHY_TX_RATE, pll_state->tx[0]); 2084 2085 if (intel_c20phy_use_mpllb(pll_state)) { 2086 tx_rate_mult = 1; 2087 frac_en = REG_FIELD_GET(C20_MPLLB_FRACEN, pll_state->mpllb[6]); 2088 frac_quot = pll_state->mpllb[8]; 2089 frac_rem = pll_state->mpllb[9]; 2090 frac_den = pll_state->mpllb[7]; 2091 multiplier = REG_FIELD_GET(C20_MULTIPLIER_MASK, pll_state->mpllb[0]); 2092 tx_clk_div = REG_FIELD_GET(C20_MPLLB_TX_CLK_DIV_MASK, pll_state->mpllb[0]); 2093 ref_clk_mpllb_div = REG_FIELD_GET(C20_REF_CLK_MPLLB_DIV_MASK, pll_state->mpllb[6]); 2094 fb_clk_div4_en = 0; 2095 } else { 2096 tx_rate_mult = 2; 2097 frac_en = REG_FIELD_GET(C20_MPLLA_FRACEN, pll_state->mplla[6]); 2098 frac_quot = pll_state->mplla[8]; 2099 frac_rem = pll_state->mplla[9]; 2100 frac_den = pll_state->mplla[7]; 2101 multiplier = REG_FIELD_GET(C20_MULTIPLIER_MASK, pll_state->mplla[0]); 2102 tx_clk_div = REG_FIELD_GET(C20_MPLLA_TX_CLK_DIV_MASK, pll_state->mplla[1]); 2103 ref_clk_mpllb_div = REG_FIELD_GET(C20_REF_CLK_MPLLB_DIV_MASK, pll_state->mplla[6]); 2104 fb_clk_div4_en = REG_FIELD_GET(C20_FB_CLK_DIV4_EN, pll_state->mplla[0]); 2105 } 2106 2107 if (frac_en) 2108 frac = frac_quot + DIV_ROUND_CLOSEST(frac_rem, frac_den); 2109 else 2110 frac = 0; 2111 2112 ref = DIV_ROUND_CLOSEST(refclk * (1 << (1 + fb_clk_div4_en)), 1 << ref_clk_mpllb_div); 2113 vco = DIV_ROUND_CLOSEST_ULL(mul_u32_u32(ref, (multiplier << (17 - 2)) + frac) >> 17, 10); 2114 2115 return vco << tx_rate_mult >> tx_clk_div >> tx_rate; 2116 } 2117 2118 /* 2119 * TODO: Convert the following to align with intel_c20pll_find_table() and 2120 * intel_c20pll_calc_state_from_table(). 2121 */ 2122 static int intel_c10pll_calc_state_from_table(struct intel_encoder *encoder, 2123 const struct intel_cx0pll_params *tables, 2124 bool is_dp, int port_clock, int lane_count, 2125 struct intel_cx0pll_state *pll_state) 2126 { 2127 struct intel_display *display = to_intel_display(encoder); 2128 int i; 2129 2130 for (i = 0; tables[i].name; i++) { 2131 int clock = intel_c10pll_calc_port_clock(tables[i].c10); 2132 2133 drm_WARN_ON(display->drm, !intel_dpll_clock_matches(clock, tables[i].clock_rate)); 2134 if (intel_dpll_clock_matches(port_clock, clock)) { 2135 pll_state->c10 = *tables[i].c10; 2136 intel_cx0pll_update_ssc(encoder, pll_state, is_dp); 2137 intel_c10pll_update_pll(encoder, pll_state); 2138 2139 pll_state->use_c10 = true; 2140 pll_state->lane_count = lane_count; 2141 2142 drm_WARN_ON(display->drm, is_dp != c10pll_state_is_dp(&pll_state->c10)); 2143 2144 return 0; 2145 } 2146 } 2147 2148 return -EINVAL; 2149 } 2150 2151 static int intel_c10pll_calc_state(const struct intel_crtc_state *crtc_state, 2152 struct intel_encoder *encoder, 2153 struct intel_dpll_hw_state *hw_state) 2154 { 2155 struct intel_display *display = to_intel_display(encoder); 2156 bool is_dp = intel_crtc_has_dp_encoder(crtc_state); 2157 const struct intel_cx0pll_params *tables; 2158 int err; 2159 2160 tables = intel_c10pll_tables_get(crtc_state, encoder); 2161 if (!tables) 2162 return -EINVAL; 2163 2164 err = intel_c10pll_calc_state_from_table(encoder, tables, is_dp, 2165 crtc_state->port_clock, crtc_state->lane_count, 2166 &hw_state->cx0pll); 2167 2168 if (err == 0 || !intel_crtc_has_type(crtc_state, INTEL_OUTPUT_HDMI)) 2169 return err; 2170 2171 /* For HDMI PLLs try SNPS PHY algorithm, if there are no precomputed tables */ 2172 intel_snps_hdmi_pll_compute_c10pll(&hw_state->cx0pll.c10, 2173 crtc_state->port_clock); 2174 intel_c10pll_update_pll(encoder, &hw_state->cx0pll); 2175 2176 hw_state->cx0pll.use_c10 = true; 2177 hw_state->cx0pll.lane_count = crtc_state->lane_count; 2178 2179 drm_WARN_ON(display->drm, is_dp != c10pll_state_is_dp(&hw_state->cx0pll.c10)); 2180 2181 return 0; 2182 } 2183 2184 int intel_readout_lane_count(struct intel_encoder *encoder, int lane0, int lane1) 2185 { 2186 struct intel_display *display = to_intel_display(encoder); 2187 u8 enabled_tx_lane_count = 0; 2188 int max_tx_lane_count = 4; 2189 bool lane_reversal; 2190 int tx_lane; 2191 2192 lane_reversal = intel_de_read(display, XELPDP_PORT_BUF_CTL1(display, encoder->port)) & 2193 XELPDP_PORT_REVERSAL; 2194 2195 /* 2196 * TODO: also check inactive TX lanes in all PHY lanes owned by the 2197 * display. For now checking only those PHY lane(s) which are owned 2198 * based on the active TX lane count (i.e. 2199 * 1,2 active TX lanes -> PHY lane#0 2200 * 3,4 active TX lanes -> PHY lane#0 and PHY lane#1). 2201 * 2202 * In case of lane reversal for 1, 2 active TX lanes, only PHY 2203 * lane#1 is used. This is only possible in TypeC legacy mode or if 2204 * the port is connected to a non-TC PHY. In both of these cases both 2205 * PHY lane#0 and #1 are owned by display, so check all 4 TX lanes in 2206 * both PHY lanes in those cases. 2207 */ 2208 if (!lane_reversal) 2209 max_tx_lane_count = DDI_PORT_WIDTH_GET(intel_de_read(display, 2210 DDI_BUF_CTL(encoder->port))); 2211 2212 if (!drm_WARN_ON(display->drm, max_tx_lane_count == 0)) 2213 max_tx_lane_count = round_up(max_tx_lane_count, 2); 2214 2215 for (tx_lane = 0; tx_lane < max_tx_lane_count; tx_lane++) { 2216 u8 phy_lane_mask = tx_lane < 2 ? lane0 : lane1; 2217 int tx = tx_lane % 2 + 1; 2218 u8 val; 2219 2220 val = intel_cx0_read(encoder, phy_lane_mask, PHY_CX0_TX_CONTROL(tx, 2)); 2221 if (!(val & CONTROL2_DISABLE_SINGLE_TX)) 2222 enabled_tx_lane_count++; 2223 } 2224 2225 return enabled_tx_lane_count; 2226 } 2227 2228 static bool readout_ssc_state(struct intel_encoder *encoder, bool is_mpll_b) 2229 { 2230 struct intel_display *display = to_intel_display(encoder); 2231 2232 return intel_de_read(display, XELPDP_PORT_CLOCK_CTL(display, encoder->port)) & 2233 (is_mpll_b ? XELPDP_SSC_ENABLE_PLLB : XELPDP_SSC_ENABLE_PLLA); 2234 } 2235 2236 static void intel_c10pll_readout_hw_state(struct intel_encoder *encoder, 2237 struct intel_cx0pll_state *cx0pll_state) 2238 { 2239 struct intel_c10pll_state *pll_state = &cx0pll_state->c10; 2240 struct intel_display *display = to_intel_display(encoder); 2241 enum phy phy = intel_encoder_to_phy(encoder); 2242 u8 lane = INTEL_CX0_LANE0; 2243 struct ref_tracker *wakeref; 2244 int i; 2245 2246 cx0pll_state->use_c10 = true; 2247 2248 wakeref = intel_cx0_phy_transaction_begin(encoder); 2249 2250 /* 2251 * According to C10 VDR Register programming Sequence we need 2252 * to do this to read PHY internal registers from MsgBus. 2253 */ 2254 intel_c10_msgbus_access_begin(encoder, lane); 2255 2256 cx0pll_state->lane_count = intel_readout_lane_count(encoder, INTEL_CX0_LANE0, 2257 INTEL_CX0_LANE1); 2258 2259 for (i = 0; i < ARRAY_SIZE(pll_state->pll); i++) 2260 pll_state->pll[i] = intel_cx0_read(encoder, lane, PHY_C10_VDR_PLL(i)); 2261 2262 pll_state->cmn = intel_cx0_read(encoder, lane, PHY_C10_VDR_CMN(0)); 2263 pll_state->tx = intel_cx0_read(encoder, lane, PHY_C10_VDR_TX(0)); 2264 2265 intel_cx0_phy_transaction_end(encoder, wakeref); 2266 2267 cx0pll_state->ssc_enabled = readout_ssc_state(encoder, true); 2268 2269 if (cx0pll_state->ssc_enabled != intel_c10pll_ssc_enabled(pll_state)) 2270 drm_dbg_kms(display->drm, 2271 "PHY %c: SSC state mismatch: port SSC is %s, PLL SSC is %s\n", 2272 phy_name(phy), 2273 str_enabled_disabled(cx0pll_state->ssc_enabled), 2274 str_enabled_disabled(intel_c10pll_ssc_enabled(pll_state))); 2275 } 2276 2277 static void intel_c10_pll_program(struct intel_display *display, 2278 struct intel_encoder *encoder, 2279 const struct intel_c10pll_state *pll_state) 2280 { 2281 int i; 2282 2283 intel_c10_msgbus_access_begin(encoder, INTEL_CX0_BOTH_LANES); 2284 2285 /* Program the pll values only for the master lane */ 2286 for (i = 0; i < ARRAY_SIZE(pll_state->pll); i++) 2287 intel_cx0_write(encoder, INTEL_CX0_LANE0, PHY_C10_VDR_PLL(i), 2288 pll_state->pll[i], 2289 (i % 4) ? MB_WRITE_UNCOMMITTED : MB_WRITE_COMMITTED); 2290 2291 intel_cx0_write(encoder, INTEL_CX0_LANE0, PHY_C10_VDR_CMN(0), pll_state->cmn, MB_WRITE_COMMITTED); 2292 intel_cx0_write(encoder, INTEL_CX0_LANE0, PHY_C10_VDR_TX(0), pll_state->tx, MB_WRITE_COMMITTED); 2293 2294 /* Custom width needs to be programmed to 0 for both the phy lanes */ 2295 intel_cx0_rmw(encoder, INTEL_CX0_BOTH_LANES, PHY_C10_VDR_CUSTOM_WIDTH, 2296 C10_VDR_CUSTOM_WIDTH_MASK, C10_VDR_CUSTOM_WIDTH_8_10, 2297 MB_WRITE_COMMITTED); 2298 2299 intel_c10_msgbus_access_commit(encoder, INTEL_CX0_LANE0, true); 2300 } 2301 2302 static void intel_c10pll_dump_hw_state(struct drm_printer *p, 2303 const struct intel_c10pll_state *hw_state) 2304 { 2305 bool fracen; 2306 int i; 2307 unsigned int frac_quot = 0, frac_rem = 0, frac_den = 1; 2308 unsigned int multiplier, tx_clk_div; 2309 2310 fracen = hw_state->pll[0] & C10_PLL0_FRACEN; 2311 drm_printf(p, "c10pll_hw_state: fracen: %s, ", str_yes_no(fracen)); 2312 2313 if (fracen) { 2314 frac_quot = hw_state->pll[12] << 8 | hw_state->pll[11]; 2315 frac_rem = hw_state->pll[14] << 8 | hw_state->pll[13]; 2316 frac_den = hw_state->pll[10] << 8 | hw_state->pll[9]; 2317 drm_printf(p, "quot: %u, rem: %u, den: %u,\n", 2318 frac_quot, frac_rem, frac_den); 2319 } 2320 2321 multiplier = (REG_FIELD_GET8(C10_PLL3_MULTIPLIERH_MASK, hw_state->pll[3]) << 8 | 2322 hw_state->pll[2]) / 2 + 16; 2323 tx_clk_div = REG_FIELD_GET8(C10_PLL15_TXCLKDIV_MASK, hw_state->pll[15]); 2324 drm_printf(p, 2325 "multiplier: %u, tx_clk_div: %u.\n", multiplier, tx_clk_div); 2326 2327 drm_printf(p, "c10pll_rawhw_state:"); 2328 drm_printf(p, "tx: 0x%x, cmn: 0x%x\n", hw_state->tx, hw_state->cmn); 2329 2330 BUILD_BUG_ON(ARRAY_SIZE(hw_state->pll) % 4); 2331 for (i = 0; i < ARRAY_SIZE(hw_state->pll); i = i + 4) 2332 drm_printf(p, 2333 "pll[%d] = 0x%x, pll[%d] = 0x%x, pll[%d] = 0x%x, pll[%d] = 0x%x\n", 2334 i, hw_state->pll[i], i + 1, hw_state->pll[i + 1], 2335 i + 2, hw_state->pll[i + 2], i + 3, hw_state->pll[i + 3]); 2336 } 2337 2338 /* 2339 * Some ARLs SoCs have the same drm PCI IDs, so need a helper to differentiate based 2340 * on the host bridge device ID to get the correct txx_mics value. 2341 */ 2342 static bool is_arrowlake_s_by_host_bridge(void) 2343 { 2344 struct pci_dev *pdev = NULL; 2345 u16 host_bridge_pci_dev_id; 2346 2347 while ((pdev = pci_get_class(PCI_CLASS_BRIDGE_HOST << 8, pdev))) 2348 host_bridge_pci_dev_id = pdev->device; 2349 2350 return pdev && IS_ARROWLAKE_S_BY_HOST_BRIDGE_ID(host_bridge_pci_dev_id); 2351 } 2352 2353 static u16 intel_c20_hdmi_tmds_tx_cgf_1(struct intel_display *display) 2354 { 2355 u16 tx_misc; 2356 u16 tx_dcc_cal_dac_ctrl_range = 8; 2357 u16 tx_term_ctrl = 2; 2358 2359 if (DISPLAY_VER(display) >= 20) { 2360 tx_misc = 5; 2361 tx_term_ctrl = 4; 2362 } else if (display->platform.battlemage) { 2363 tx_misc = 0; 2364 } else if (display->platform.meteorlake_u || 2365 is_arrowlake_s_by_host_bridge()) { 2366 tx_misc = 3; 2367 } else { 2368 tx_misc = 7; 2369 } 2370 2371 return (C20_PHY_TX_MISC(tx_misc) | 2372 C20_PHY_TX_DCC_CAL_RANGE(tx_dcc_cal_dac_ctrl_range) | 2373 C20_PHY_TX_DCC_BYPASS | C20_PHY_TX_TERM_CTL(tx_term_ctrl)); 2374 } 2375 2376 static int intel_c20_compute_hdmi_tmds_pll(struct intel_display *display, 2377 int port_clock, 2378 struct intel_c20pll_state *pll_state) 2379 { 2380 u64 datarate; 2381 u64 mpll_tx_clk_div; 2382 u64 vco_freq_shift; 2383 u64 vco_freq; 2384 u64 multiplier; 2385 u64 mpll_multiplier; 2386 u64 mpll_fracn_quot; 2387 u64 mpll_fracn_rem; 2388 u8 mpllb_ana_freq_vco; 2389 u8 mpll_div_multiplier; 2390 2391 if (port_clock < 25175 || port_clock > 600000) 2392 return -EINVAL; 2393 2394 datarate = ((u64)port_clock * 1000) * 10; 2395 mpll_tx_clk_div = ilog2(div64_u64((u64)CLOCK_9999MHZ, (u64)datarate)); 2396 vco_freq_shift = ilog2(div64_u64((u64)CLOCK_4999MHZ * (u64)256, (u64)datarate)); 2397 vco_freq = (datarate << vco_freq_shift) >> 8; 2398 multiplier = div64_u64((vco_freq << 28), (REFCLK_38_4_MHZ >> 4)); 2399 mpll_multiplier = 2 * (multiplier >> 32); 2400 2401 mpll_fracn_quot = (multiplier >> 16) & 0xFFFF; 2402 mpll_fracn_rem = multiplier & 0xFFFF; 2403 2404 mpll_div_multiplier = min_t(u8, div64_u64((vco_freq * 16 + (datarate >> 1)), 2405 datarate), 255); 2406 2407 if (vco_freq <= DATARATE_3000000000) 2408 mpllb_ana_freq_vco = MPLLB_ANA_FREQ_VCO_3; 2409 else if (vco_freq <= DATARATE_3500000000) 2410 mpllb_ana_freq_vco = MPLLB_ANA_FREQ_VCO_2; 2411 else if (vco_freq <= DATARATE_4000000000) 2412 mpllb_ana_freq_vco = MPLLB_ANA_FREQ_VCO_1; 2413 else 2414 mpllb_ana_freq_vco = MPLLB_ANA_FREQ_VCO_0; 2415 2416 pll_state->tx[0] = 0xbe88; 2417 pll_state->tx[1] = intel_c20_hdmi_tmds_tx_cgf_1(display); 2418 pll_state->tx[2] = 0x0000; 2419 pll_state->cmn[0] = 0x0500; 2420 pll_state->cmn[1] = 0x0005; 2421 pll_state->cmn[2] = 0x0000; 2422 pll_state->cmn[3] = 0x0000; 2423 pll_state->mpllb[0] = (MPLL_TX_CLK_DIV(mpll_tx_clk_div) | 2424 MPLL_MULTIPLIER(mpll_multiplier)); 2425 pll_state->mpllb[1] = (CAL_DAC_CODE(CAL_DAC_CODE_31) | 2426 WORD_CLK_DIV | 2427 MPLL_DIV_MULTIPLIER(mpll_div_multiplier)); 2428 pll_state->mpllb[2] = (MPLLB_ANA_FREQ_VCO(mpllb_ana_freq_vco) | 2429 CP_PROP(CP_PROP_20) | 2430 CP_INT(CP_INT_6)); 2431 pll_state->mpllb[3] = (V2I(V2I_2) | 2432 CP_PROP_GS(CP_PROP_GS_30) | 2433 CP_INT_GS(CP_INT_GS_28)); 2434 pll_state->mpllb[4] = 0x0000; 2435 pll_state->mpllb[5] = 0x0000; 2436 pll_state->mpllb[6] = (C20_MPLLB_FRACEN | SSC_UP_SPREAD); 2437 pll_state->mpllb[7] = MPLL_FRACN_DEN; 2438 pll_state->mpllb[8] = mpll_fracn_quot; 2439 pll_state->mpllb[9] = mpll_fracn_rem; 2440 pll_state->mpllb[10] = HDMI_DIV(HDMI_DIV_1); 2441 2442 return 0; 2443 } 2444 2445 static const struct intel_cx0pll_params * 2446 intel_c20_pll_tables_get(const struct intel_crtc_state *crtc_state, 2447 struct intel_encoder *encoder) 2448 { 2449 struct intel_display *display = to_intel_display(crtc_state); 2450 2451 if (intel_crtc_has_dp_encoder(crtc_state)) { 2452 if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_EDP)) { 2453 if (DISPLAY_RUNTIME_INFO(display)->edp_typec_support) 2454 return xe3lpd_c20_dp_edp_tables; 2455 if (DISPLAY_VERx100(display) == 1401) 2456 return xe2hpd_c20_edp_tables; 2457 } 2458 2459 if (DISPLAY_VER(display) >= 30) 2460 return xe3lpd_c20_dp_edp_tables; 2461 else if (DISPLAY_VERx100(display) == 1401) 2462 return xe2hpd_c20_dp_tables; 2463 else 2464 return mtl_c20_dp_tables; 2465 2466 } else if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_HDMI)) { 2467 return mtl_c20_hdmi_tables; 2468 } 2469 2470 MISSING_CASE(encoder->type); 2471 return NULL; 2472 } 2473 2474 static u8 intel_c20_get_dp_rate(u32 clock) 2475 { 2476 switch (clock) { 2477 case 162000: /* 1.62 Gbps DP1.4 */ 2478 return 0; 2479 case 270000: /* 2.7 Gbps DP1.4 */ 2480 return 1; 2481 case 540000: /* 5.4 Gbps DP 1.4 */ 2482 return 2; 2483 case 810000: /* 8.1 Gbps DP1.4 */ 2484 return 3; 2485 case 216000: /* 2.16 Gbps eDP */ 2486 return 4; 2487 case 243000: /* 2.43 Gbps eDP */ 2488 return 5; 2489 case 324000: /* 3.24 Gbps eDP */ 2490 return 6; 2491 case 432000: /* 4.32 Gbps eDP */ 2492 return 7; 2493 case 1000000: /* 10 Gbps DP2.0 */ 2494 return 8; 2495 case 1350000: /* 13.5 Gbps DP2.0 */ 2496 return 9; 2497 case 2000000: /* 20 Gbps DP2.0 */ 2498 return 10; 2499 case 648000: /* 6.48 Gbps eDP*/ 2500 return 11; 2501 case 675000: /* 6.75 Gbps eDP*/ 2502 return 12; 2503 default: 2504 MISSING_CASE(clock); 2505 return 0; 2506 } 2507 } 2508 2509 static u8 intel_c20_get_hdmi_rate(u32 clock) 2510 { 2511 if (clock >= 25175 && clock <= 600000) 2512 return 0; 2513 2514 switch (clock) { 2515 case 300000: /* 3 Gbps */ 2516 case 600000: /* 6 Gbps */ 2517 case 1200000: /* 12 Gbps */ 2518 return 1; 2519 case 800000: /* 8 Gbps */ 2520 return 2; 2521 case 1000000: /* 10 Gbps */ 2522 return 3; 2523 default: 2524 MISSING_CASE(clock); 2525 return 0; 2526 } 2527 } 2528 2529 static bool is_dp2(u32 clock) 2530 { 2531 /* DP2.0 clock rates */ 2532 if (clock == 1000000 || clock == 1350000 || clock == 2000000) 2533 return true; 2534 2535 return false; 2536 } 2537 2538 static int intel_get_c20_custom_width(u32 clock, bool dp) 2539 { 2540 if (dp && is_dp2(clock)) 2541 return 2; 2542 else if (intel_hdmi_is_frl(clock)) 2543 return 1; 2544 else 2545 return 0; 2546 } 2547 2548 static void intel_c20_calc_vdr_params(struct intel_c20pll_vdr_state *vdr, bool is_dp, 2549 int port_clock) 2550 { 2551 vdr->custom_width = intel_get_c20_custom_width(port_clock, is_dp); 2552 2553 vdr->serdes_rate = 0; 2554 vdr->hdmi_rate = 0; 2555 2556 if (is_dp) { 2557 vdr->serdes_rate = PHY_C20_IS_DP | 2558 PHY_C20_DP_RATE(intel_c20_get_dp_rate(port_clock)); 2559 } else { 2560 if (intel_hdmi_is_frl(port_clock)) 2561 vdr->serdes_rate = PHY_C20_IS_HDMI_FRL; 2562 2563 vdr->hdmi_rate = intel_c20_get_hdmi_rate(port_clock); 2564 } 2565 } 2566 2567 #define PHY_C20_SERDES_RATE_MASK (PHY_C20_IS_DP | PHY_C20_DP_RATE_MASK | PHY_C20_IS_HDMI_FRL) 2568 2569 static void intel_c20_readout_vdr_params(struct intel_encoder *encoder, 2570 struct intel_c20pll_vdr_state *vdr, bool *cntx) 2571 { 2572 u8 serdes; 2573 2574 serdes = intel_cx0_read(encoder, INTEL_CX0_LANE0, PHY_C20_VDR_CUSTOM_SERDES_RATE); 2575 *cntx = serdes & PHY_C20_CONTEXT_TOGGLE; 2576 2577 vdr->custom_width = intel_cx0_read(encoder, INTEL_CX0_LANE0, PHY_C20_VDR_CUSTOM_WIDTH) & 2578 PHY_C20_CUSTOM_WIDTH_MASK; 2579 2580 vdr->serdes_rate = serdes & PHY_C20_SERDES_RATE_MASK; 2581 if (!(vdr->serdes_rate & PHY_C20_IS_DP)) 2582 vdr->hdmi_rate = intel_cx0_read(encoder, INTEL_CX0_LANE0, PHY_C20_VDR_HDMI_RATE) & 2583 PHY_C20_HDMI_RATE_MASK; 2584 else 2585 vdr->hdmi_rate = 0; 2586 } 2587 2588 static void intel_c20_program_vdr_params(struct intel_encoder *encoder, 2589 const struct intel_c20pll_vdr_state *vdr, 2590 u8 owned_lane_mask) 2591 { 2592 struct intel_display *display = to_intel_display(encoder); 2593 2594 drm_WARN_ON(display->drm, vdr->custom_width & ~PHY_C20_CUSTOM_WIDTH_MASK); 2595 intel_cx0_rmw(encoder, owned_lane_mask, PHY_C20_VDR_CUSTOM_WIDTH, 2596 PHY_C20_CUSTOM_WIDTH_MASK, vdr->custom_width, 2597 MB_WRITE_COMMITTED); 2598 2599 drm_WARN_ON(display->drm, vdr->serdes_rate & ~PHY_C20_SERDES_RATE_MASK); 2600 intel_cx0_rmw(encoder, owned_lane_mask, PHY_C20_VDR_CUSTOM_SERDES_RATE, 2601 PHY_C20_SERDES_RATE_MASK, vdr->serdes_rate, 2602 MB_WRITE_COMMITTED); 2603 2604 if (vdr->serdes_rate & PHY_C20_IS_DP) 2605 return; 2606 2607 drm_WARN_ON(display->drm, vdr->hdmi_rate & ~PHY_C20_HDMI_RATE_MASK); 2608 intel_cx0_rmw(encoder, INTEL_CX0_BOTH_LANES, PHY_C20_VDR_HDMI_RATE, 2609 PHY_C20_HDMI_RATE_MASK, vdr->hdmi_rate, 2610 MB_WRITE_COMMITTED); 2611 } 2612 2613 static const struct intel_cx0pll_params * 2614 intel_c20_pll_find_table(const struct intel_crtc_state *crtc_state, 2615 struct intel_encoder *encoder) 2616 { 2617 struct intel_display *display = to_intel_display(crtc_state); 2618 const struct intel_cx0pll_params *tables; 2619 int i; 2620 2621 tables = intel_c20_pll_tables_get(crtc_state, encoder); 2622 if (!tables) 2623 return NULL; 2624 2625 for (i = 0; tables[i].name; i++) { 2626 int clock = intel_c20pll_calc_port_clock(tables[i].c20); 2627 2628 drm_WARN_ON(display->drm, !intel_dpll_clock_matches(clock, tables[i].clock_rate)); 2629 if (intel_dpll_clock_matches(crtc_state->port_clock, clock)) 2630 return &tables[i]; 2631 } 2632 2633 return NULL; 2634 } 2635 2636 static int intel_c20pll_calc_state_from_table(const struct intel_crtc_state *crtc_state, 2637 struct intel_encoder *encoder, 2638 struct intel_cx0pll_state *pll_state) 2639 { 2640 const struct intel_cx0pll_params *table; 2641 2642 table = intel_c20_pll_find_table(crtc_state, encoder); 2643 if (!table) 2644 return -EINVAL; 2645 2646 pll_state->c20 = *table->c20; 2647 2648 intel_cx0pll_update_ssc(encoder, pll_state, intel_crtc_has_dp_encoder(crtc_state)); 2649 2650 return 0; 2651 } 2652 2653 static int intel_c20pll_calc_state(const struct intel_crtc_state *crtc_state, 2654 struct intel_encoder *encoder, 2655 struct intel_dpll_hw_state *hw_state) 2656 { 2657 struct intel_display *display = to_intel_display(encoder); 2658 bool is_dp = intel_crtc_has_dp_encoder(crtc_state); 2659 int err = -ENOENT; 2660 2661 hw_state->cx0pll.use_c10 = false; 2662 hw_state->cx0pll.lane_count = crtc_state->lane_count; 2663 2664 /* 2665 * Try the ideal C20 HDMI tables before computing them, since the calculated 2666 * values, although correct, may not be optimal. 2667 */ 2668 if (err) 2669 err = intel_c20pll_calc_state_from_table(crtc_state, encoder, 2670 &hw_state->cx0pll); 2671 2672 /* TODO: Update SSC state for HDMI as well */ 2673 if (!is_dp && err) 2674 err = intel_c20_compute_hdmi_tmds_pll(display, crtc_state->port_clock, 2675 &hw_state->cx0pll.c20); 2676 2677 if (err) 2678 return err; 2679 2680 intel_c20_calc_vdr_params(&hw_state->cx0pll.c20.vdr, 2681 is_dp, crtc_state->port_clock); 2682 2683 drm_WARN_ON(display->drm, is_dp != c20pll_state_is_dp(&hw_state->cx0pll.c20)); 2684 2685 return 0; 2686 } 2687 2688 int intel_cx0pll_calc_state(const struct intel_crtc_state *crtc_state, 2689 struct intel_encoder *encoder, 2690 struct intel_dpll_hw_state *hw_state) 2691 { 2692 memset(hw_state, 0, sizeof(*hw_state)); 2693 2694 if (intel_encoder_is_c10phy(encoder)) 2695 return intel_c10pll_calc_state(crtc_state, encoder, hw_state); 2696 return intel_c20pll_calc_state(crtc_state, encoder, hw_state); 2697 } 2698 2699 static void intel_c20pll_readout_hw_state(struct intel_encoder *encoder, 2700 struct intel_cx0pll_state *cx0pll_state) 2701 { 2702 struct intel_c20pll_state *pll_state = &cx0pll_state->c20; 2703 struct intel_display *display = to_intel_display(encoder); 2704 bool cntx; 2705 struct ref_tracker *wakeref; 2706 int i; 2707 2708 cx0pll_state->use_c10 = false; 2709 2710 wakeref = intel_cx0_phy_transaction_begin(encoder); 2711 2712 cx0pll_state->lane_count = intel_readout_lane_count(encoder, INTEL_CX0_LANE0, 2713 INTEL_CX0_LANE1); 2714 2715 /* 1. Read VDR params and current context selection */ 2716 intel_c20_readout_vdr_params(encoder, &pll_state->vdr, &cntx); 2717 2718 /* Read Tx configuration */ 2719 for (i = 0; i < ARRAY_SIZE(pll_state->tx); i++) { 2720 if (cntx) 2721 pll_state->tx[i] = intel_c20_sram_read(encoder, 2722 INTEL_CX0_LANE0, 2723 PHY_C20_B_TX_CNTX_CFG(display, i)); 2724 else 2725 pll_state->tx[i] = intel_c20_sram_read(encoder, 2726 INTEL_CX0_LANE0, 2727 PHY_C20_A_TX_CNTX_CFG(display, i)); 2728 } 2729 2730 /* Read common configuration */ 2731 for (i = 0; i < ARRAY_SIZE(pll_state->cmn); i++) { 2732 if (cntx) 2733 pll_state->cmn[i] = intel_c20_sram_read(encoder, 2734 INTEL_CX0_LANE0, 2735 PHY_C20_B_CMN_CNTX_CFG(display, i)); 2736 else 2737 pll_state->cmn[i] = intel_c20_sram_read(encoder, 2738 INTEL_CX0_LANE0, 2739 PHY_C20_A_CMN_CNTX_CFG(display, i)); 2740 } 2741 2742 if (intel_c20phy_use_mpllb(pll_state)) { 2743 /* MPLLB configuration */ 2744 for (i = 0; i < ARRAY_SIZE(pll_state->mpllb); i++) { 2745 if (cntx) 2746 pll_state->mpllb[i] = intel_c20_sram_read(encoder, 2747 INTEL_CX0_LANE0, 2748 PHY_C20_B_MPLLB_CNTX_CFG(display, i)); 2749 else 2750 pll_state->mpllb[i] = intel_c20_sram_read(encoder, 2751 INTEL_CX0_LANE0, 2752 PHY_C20_A_MPLLB_CNTX_CFG(display, i)); 2753 } 2754 } else { 2755 /* MPLLA configuration */ 2756 for (i = 0; i < ARRAY_SIZE(pll_state->mplla); i++) { 2757 if (cntx) 2758 pll_state->mplla[i] = intel_c20_sram_read(encoder, 2759 INTEL_CX0_LANE0, 2760 PHY_C20_B_MPLLA_CNTX_CFG(display, i)); 2761 else 2762 pll_state->mplla[i] = intel_c20_sram_read(encoder, 2763 INTEL_CX0_LANE0, 2764 PHY_C20_A_MPLLA_CNTX_CFG(display, i)); 2765 } 2766 } 2767 2768 intel_cx0_phy_transaction_end(encoder, wakeref); 2769 2770 cx0pll_state->ssc_enabled = readout_ssc_state(encoder, intel_c20phy_use_mpllb(pll_state)); 2771 } 2772 2773 static void intel_c20pll_dump_hw_state(struct drm_printer *p, 2774 const struct intel_c20pll_state *hw_state) 2775 { 2776 int i; 2777 2778 drm_printf(p, "c20pll_hw_state:\n"); 2779 drm_printf(p, 2780 "tx[0] = 0x%.4x, tx[1] = 0x%.4x, tx[2] = 0x%.4x\n", 2781 hw_state->tx[0], hw_state->tx[1], hw_state->tx[2]); 2782 drm_printf(p, 2783 "cmn[0] = 0x%.4x, cmn[1] = 0x%.4x, cmn[2] = 0x%.4x, cmn[3] = 0x%.4x\n", 2784 hw_state->cmn[0], hw_state->cmn[1], hw_state->cmn[2], hw_state->cmn[3]); 2785 2786 if (intel_c20phy_use_mpllb(hw_state)) { 2787 for (i = 0; i < ARRAY_SIZE(hw_state->mpllb); i++) 2788 drm_printf(p, "mpllb[%d] = 0x%.4x\n", i, hw_state->mpllb[i]); 2789 } else { 2790 for (i = 0; i < ARRAY_SIZE(hw_state->mplla); i++) 2791 drm_printf(p, "mplla[%d] = 0x%.4x\n", i, hw_state->mplla[i]); 2792 2793 /* For full coverage, also print the additional PLL B entry. */ 2794 BUILD_BUG_ON(ARRAY_SIZE(hw_state->mplla) + 1 != ARRAY_SIZE(hw_state->mpllb)); 2795 drm_printf(p, "mpllb[%d] = 0x%.4x\n", i, hw_state->mpllb[i]); 2796 } 2797 2798 drm_printf(p, 2799 "vdr: custom width: 0x%02x, serdes rate: 0x%02x, hdmi rate: 0x%02x\n", 2800 hw_state->vdr.custom_width, hw_state->vdr.serdes_rate, hw_state->vdr.hdmi_rate); 2801 } 2802 2803 void intel_cx0pll_dump_hw_state(struct drm_printer *p, 2804 const struct intel_cx0pll_state *hw_state) 2805 { 2806 drm_printf(p, 2807 "cx0pll_hw_state: lane_count: %d, ssc_enabled: %s, use_c10: %s, tbt_mode: %s\n", 2808 hw_state->lane_count, str_yes_no(hw_state->ssc_enabled), 2809 str_yes_no(hw_state->use_c10), str_yes_no(hw_state->tbt_mode)); 2810 2811 if (hw_state->use_c10) 2812 intel_c10pll_dump_hw_state(p, &hw_state->c10); 2813 else 2814 intel_c20pll_dump_hw_state(p, &hw_state->c20); 2815 } 2816 2817 static bool intel_c20_protocol_switch_valid(struct intel_encoder *encoder) 2818 { 2819 struct intel_digital_port *intel_dig_port = enc_to_dig_port(encoder); 2820 2821 /* banks should not be cleared for DPALT/USB4/TBT modes */ 2822 /* TODO: optimize re-calibration in legacy mode */ 2823 return intel_tc_port_in_legacy_mode(intel_dig_port); 2824 } 2825 2826 static void intel_c20_pll_program(struct intel_display *display, 2827 struct intel_encoder *encoder, 2828 const struct intel_c20pll_state *pll_state) 2829 { 2830 u8 owned_lane_mask = intel_cx0_get_owned_lane_mask(encoder); 2831 bool cntx; 2832 int i; 2833 2834 /* 1. Read current context selection */ 2835 cntx = intel_cx0_read(encoder, INTEL_CX0_LANE0, PHY_C20_VDR_CUSTOM_SERDES_RATE) & 2836 PHY_C20_CONTEXT_TOGGLE; 2837 2838 /* 2839 * 2. If there is a protocol switch from HDMI to DP or vice versa, clear 2840 * the lane #0 MPLLB CAL_DONE_BANK DP2.0 10G and 20G rates enable MPLLA. 2841 * Protocol switch is only applicable for MPLLA 2842 */ 2843 if (intel_c20_protocol_switch_valid(encoder)) { 2844 for (i = 0; i < 4; i++) 2845 intel_c20_sram_write(encoder, INTEL_CX0_LANE0, RAWLANEAONX_DIG_TX_MPLLB_CAL_DONE_BANK(i), 0); 2846 usleep_range(4000, 4100); 2847 } 2848 2849 /* 3. Write SRAM configuration context. If A in use, write configuration to B context */ 2850 /* 3.1 Tx configuration */ 2851 for (i = 0; i < ARRAY_SIZE(pll_state->tx); i++) { 2852 if (cntx) 2853 intel_c20_sram_write(encoder, INTEL_CX0_LANE0, 2854 PHY_C20_A_TX_CNTX_CFG(display, i), 2855 pll_state->tx[i]); 2856 else 2857 intel_c20_sram_write(encoder, INTEL_CX0_LANE0, 2858 PHY_C20_B_TX_CNTX_CFG(display, i), 2859 pll_state->tx[i]); 2860 } 2861 2862 /* 3.2 common configuration */ 2863 for (i = 0; i < ARRAY_SIZE(pll_state->cmn); i++) { 2864 if (cntx) 2865 intel_c20_sram_write(encoder, INTEL_CX0_LANE0, 2866 PHY_C20_A_CMN_CNTX_CFG(display, i), 2867 pll_state->cmn[i]); 2868 else 2869 intel_c20_sram_write(encoder, INTEL_CX0_LANE0, 2870 PHY_C20_B_CMN_CNTX_CFG(display, i), 2871 pll_state->cmn[i]); 2872 } 2873 2874 /* 3.3 mpllb or mplla configuration */ 2875 if (intel_c20phy_use_mpllb(pll_state)) { 2876 for (i = 0; i < ARRAY_SIZE(pll_state->mpllb); i++) { 2877 if (cntx) 2878 intel_c20_sram_write(encoder, INTEL_CX0_LANE0, 2879 PHY_C20_A_MPLLB_CNTX_CFG(display, i), 2880 pll_state->mpllb[i]); 2881 else 2882 intel_c20_sram_write(encoder, INTEL_CX0_LANE0, 2883 PHY_C20_B_MPLLB_CNTX_CFG(display, i), 2884 pll_state->mpllb[i]); 2885 } 2886 } else { 2887 for (i = 0; i < ARRAY_SIZE(pll_state->mplla); i++) { 2888 if (cntx) 2889 intel_c20_sram_write(encoder, INTEL_CX0_LANE0, 2890 PHY_C20_A_MPLLA_CNTX_CFG(display, i), 2891 pll_state->mplla[i]); 2892 else 2893 intel_c20_sram_write(encoder, INTEL_CX0_LANE0, 2894 PHY_C20_B_MPLLA_CNTX_CFG(display, i), 2895 pll_state->mplla[i]); 2896 } 2897 } 2898 2899 /* 2900 * 4. Program custom width to match the link protocol. 2901 * 5. For DP or 6. For HDMI 2902 */ 2903 intel_c20_program_vdr_params(encoder, &pll_state->vdr, owned_lane_mask); 2904 2905 /* 2906 * 7. Write Vendor specific registers to toggle context setting to load 2907 * the updated programming toggle context bit 2908 */ 2909 intel_cx0_rmw(encoder, owned_lane_mask, PHY_C20_VDR_CUSTOM_SERDES_RATE, 2910 PHY_C20_CONTEXT_TOGGLE, cntx ? 0 : PHY_C20_CONTEXT_TOGGLE, 2911 MB_WRITE_COMMITTED); 2912 } 2913 2914 static bool is_mplla_clock_rate(int clock) 2915 { 2916 return intel_dpll_clock_matches(clock, 1000000) || 2917 intel_dpll_clock_matches(clock, 2000000); 2918 } 2919 2920 static void intel_program_port_clock_ctl(struct intel_encoder *encoder, 2921 const struct intel_cx0pll_state *pll_state, 2922 int port_clock, 2923 bool lane_reversal) 2924 { 2925 struct intel_display *display = to_intel_display(encoder); 2926 bool is_dp = cx0pll_state_is_dp(pll_state); 2927 u32 val = 0; 2928 2929 intel_de_rmw(display, XELPDP_PORT_BUF_CTL1(display, encoder->port), 2930 XELPDP_PORT_REVERSAL, 2931 lane_reversal ? XELPDP_PORT_REVERSAL : 0); 2932 2933 if (lane_reversal) 2934 val |= XELPDP_LANE1_PHY_CLOCK_SELECT; 2935 2936 val |= XELPDP_FORWARD_CLOCK_UNGATE; 2937 2938 if (!is_dp && intel_hdmi_is_frl(port_clock)) 2939 val |= XELPDP_DDI_CLOCK_SELECT_PREP(display, XELPDP_DDI_CLOCK_SELECT_DIV18CLK); 2940 else 2941 val |= XELPDP_DDI_CLOCK_SELECT_PREP(display, XELPDP_DDI_CLOCK_SELECT_MAXPCLK); 2942 2943 /* TODO: HDMI FRL */ 2944 /* DP2.0 10G and 20G rates enable MPLLA*/ 2945 if (is_mplla_clock_rate(port_clock)) 2946 val |= pll_state->ssc_enabled ? XELPDP_SSC_ENABLE_PLLA : 0; 2947 else 2948 val |= pll_state->ssc_enabled ? XELPDP_SSC_ENABLE_PLLB : 0; 2949 2950 intel_de_rmw(display, XELPDP_PORT_CLOCK_CTL(display, encoder->port), 2951 XELPDP_LANE1_PHY_CLOCK_SELECT | XELPDP_FORWARD_CLOCK_UNGATE | 2952 XELPDP_DDI_CLOCK_SELECT_MASK(display) | XELPDP_SSC_ENABLE_PLLA | 2953 XELPDP_SSC_ENABLE_PLLB, val); 2954 } 2955 2956 static u32 intel_cx0_get_powerdown_update(u8 lane_mask) 2957 { 2958 u32 val = 0; 2959 int lane = 0; 2960 2961 for_each_cx0_lane_in_mask(lane_mask, lane) 2962 val |= XELPDP_LANE_POWERDOWN_UPDATE(lane); 2963 2964 return val; 2965 } 2966 2967 static u32 intel_cx0_get_powerdown_state(u8 lane_mask, u8 state) 2968 { 2969 u32 val = 0; 2970 int lane = 0; 2971 2972 for_each_cx0_lane_in_mask(lane_mask, lane) 2973 val |= XELPDP_LANE_POWERDOWN_NEW_STATE(lane, state); 2974 2975 return val; 2976 } 2977 2978 void intel_cx0_powerdown_change_sequence(struct intel_encoder *encoder, 2979 u8 lane_mask, u8 state) 2980 { 2981 struct intel_display *display = to_intel_display(encoder); 2982 enum port port = encoder->port; 2983 enum phy phy = intel_encoder_to_phy(encoder); 2984 intel_reg_t buf_ctl2_reg = XELPDP_PORT_BUF_CTL2(display, port); 2985 int lane; 2986 2987 intel_de_rmw(display, buf_ctl2_reg, 2988 intel_cx0_get_powerdown_state(INTEL_CX0_BOTH_LANES, XELPDP_LANE_POWERDOWN_NEW_STATE_MASK), 2989 intel_cx0_get_powerdown_state(lane_mask, state)); 2990 2991 /* Wait for pending transactions.*/ 2992 for_each_cx0_lane_in_mask(lane_mask, lane) 2993 if (intel_de_wait_for_clear_ms(display, XELPDP_PORT_M2P_MSGBUS_CTL(display, port, lane), 2994 XELPDP_PORT_M2P_TRANSACTION_PENDING, 2995 XELPDP_MSGBUS_TIMEOUT_MS)) { 2996 drm_dbg_kms(display->drm, 2997 "PHY %c Timeout waiting for previous transaction to complete. Reset the bus.\n", 2998 phy_name(phy)); 2999 intel_cx0_bus_reset(encoder, lane); 3000 } 3001 3002 intel_de_rmw(display, buf_ctl2_reg, 3003 intel_cx0_get_powerdown_update(INTEL_CX0_BOTH_LANES), 3004 intel_cx0_get_powerdown_update(lane_mask)); 3005 3006 /* Update Timeout Value */ 3007 if (intel_de_wait_for_clear_ms(display, buf_ctl2_reg, 3008 intel_cx0_get_powerdown_update(lane_mask), 3009 XELPDP_PORT_POWERDOWN_UPDATE_TIMEOUT_MS)) 3010 drm_warn(display->drm, 3011 "PHY %c failed to change powerdown state\n", 3012 phy_name(phy)); 3013 } 3014 3015 void intel_cx0_setup_powerdown(struct intel_encoder *encoder) 3016 { 3017 struct intel_display *display = to_intel_display(encoder); 3018 enum port port = encoder->port; 3019 3020 intel_de_rmw(display, XELPDP_PORT_BUF_CTL2(display, port), 3021 XELPDP_POWER_STATE_READY_MASK, 3022 XELPDP_POWER_STATE_READY(XELPDP_P2_STATE_READY)); 3023 intel_de_rmw(display, XELPDP_PORT_BUF_CTL3(display, port), 3024 XELPDP_POWER_STATE_ACTIVE_MASK | 3025 XELPDP_PLL_LANE_STAGGERING_DELAY_MASK, 3026 XELPDP_POWER_STATE_ACTIVE(XELPDP_P0_STATE_ACTIVE) | 3027 XELPDP_PLL_LANE_STAGGERING_DELAY(0)); 3028 } 3029 3030 static u32 intel_cx0_get_pclk_refclk_request(u8 lane_mask) 3031 { 3032 u32 val = 0; 3033 int lane = 0; 3034 3035 for_each_cx0_lane_in_mask(lane_mask, lane) 3036 val |= XELPDP_LANE_PCLK_REFCLK_REQUEST(lane); 3037 3038 return val; 3039 } 3040 3041 static u32 intel_cx0_get_pclk_refclk_ack(u8 lane_mask) 3042 { 3043 u32 val = 0; 3044 int lane = 0; 3045 3046 for_each_cx0_lane_in_mask(lane_mask, lane) 3047 val |= XELPDP_LANE_PCLK_REFCLK_ACK(lane); 3048 3049 return val; 3050 } 3051 3052 static void intel_cx0_phy_lane_reset(struct intel_encoder *encoder, 3053 bool lane_reversal) 3054 { 3055 struct intel_display *display = to_intel_display(encoder); 3056 enum port port = encoder->port; 3057 enum phy phy = intel_encoder_to_phy(encoder); 3058 u8 owned_lane_mask = intel_cx0_get_owned_lane_mask(encoder); 3059 u8 lane_mask = lane_reversal ? INTEL_CX0_LANE1 : INTEL_CX0_LANE0; 3060 u32 lane_pipe_reset = owned_lane_mask == INTEL_CX0_BOTH_LANES 3061 ? XELPDP_LANE_PIPE_RESET(0) | XELPDP_LANE_PIPE_RESET(1) 3062 : XELPDP_LANE_PIPE_RESET(0); 3063 u32 lane_phy_current_status = owned_lane_mask == INTEL_CX0_BOTH_LANES 3064 ? (XELPDP_LANE_PHY_CURRENT_STATUS(0) | 3065 XELPDP_LANE_PHY_CURRENT_STATUS(1)) 3066 : XELPDP_LANE_PHY_CURRENT_STATUS(0); 3067 3068 if (intel_de_wait_for_set_us(display, XELPDP_PORT_BUF_CTL1(display, port), 3069 XELPDP_PORT_BUF_SOC_PHY_READY, 3070 XELPDP_PORT_BUF_SOC_READY_TIMEOUT_US)) 3071 drm_warn(display->drm, 3072 "PHY %c failed to bring out of SOC reset\n", 3073 phy_name(phy)); 3074 3075 intel_de_rmw(display, XELPDP_PORT_BUF_CTL2(display, port), lane_pipe_reset, 3076 lane_pipe_reset); 3077 3078 if (intel_de_wait_for_set_us(display, XELPDP_PORT_BUF_CTL2(display, port), 3079 lane_phy_current_status, 3080 XELPDP_PORT_RESET_START_TIMEOUT_US)) 3081 drm_warn(display->drm, 3082 "PHY %c failed to bring out of lane reset\n", 3083 phy_name(phy)); 3084 3085 intel_de_rmw(display, XELPDP_PORT_CLOCK_CTL(display, port), 3086 intel_cx0_get_pclk_refclk_request(owned_lane_mask), 3087 intel_cx0_get_pclk_refclk_request(lane_mask)); 3088 3089 if (intel_de_wait_us(display, XELPDP_PORT_CLOCK_CTL(display, port), 3090 intel_cx0_get_pclk_refclk_ack(owned_lane_mask), 3091 intel_cx0_get_pclk_refclk_ack(lane_mask), 3092 XELPDP_REFCLK_ENABLE_TIMEOUT_US, NULL)) 3093 drm_warn(display->drm, 3094 "PHY %c failed to request refclk\n", 3095 phy_name(phy)); 3096 3097 intel_cx0_powerdown_change_sequence(encoder, INTEL_CX0_BOTH_LANES, 3098 XELPDP_P2_STATE_RESET); 3099 intel_cx0_setup_powerdown(encoder); 3100 3101 intel_de_rmw(display, XELPDP_PORT_BUF_CTL2(display, port), lane_pipe_reset, 0); 3102 3103 if (intel_de_wait_for_clear_ms(display, XELPDP_PORT_BUF_CTL2(display, port), 3104 lane_phy_current_status, 3105 XELPDP_PORT_RESET_END_TIMEOUT_MS)) 3106 drm_warn(display->drm, 3107 "PHY %c failed to bring out of lane reset\n", 3108 phy_name(phy)); 3109 } 3110 3111 static void intel_cx0_program_phy_lane(struct intel_encoder *encoder, int lane_count, 3112 bool lane_reversal) 3113 { 3114 int i; 3115 u8 disables; 3116 bool dp_alt_mode = intel_tc_port_in_dp_alt_mode(enc_to_dig_port(encoder)); 3117 u8 owned_lane_mask = intel_cx0_get_owned_lane_mask(encoder); 3118 3119 intel_c10_msgbus_access_begin(encoder, owned_lane_mask); 3120 3121 if (lane_reversal) 3122 disables = REG_GENMASK8(3, 0) >> lane_count; 3123 else 3124 disables = REG_GENMASK8(3, 0) << lane_count; 3125 3126 if (dp_alt_mode && lane_count == 1) { 3127 disables &= ~REG_GENMASK8(1, 0); 3128 disables |= REG_FIELD_PREP8(REG_GENMASK8(1, 0), 0x1); 3129 } 3130 3131 for (i = 0; i < 4; i++) { 3132 int tx = i % 2 + 1; 3133 u8 lane_mask = i < 2 ? INTEL_CX0_LANE0 : INTEL_CX0_LANE1; 3134 3135 if (!(owned_lane_mask & lane_mask)) 3136 continue; 3137 3138 intel_cx0_rmw(encoder, lane_mask, PHY_CX0_TX_CONTROL(tx, 2), 3139 CONTROL2_DISABLE_SINGLE_TX, 3140 disables & BIT(i) ? CONTROL2_DISABLE_SINGLE_TX : 0, 3141 MB_WRITE_COMMITTED); 3142 } 3143 3144 intel_c10_msgbus_access_commit(encoder, owned_lane_mask, false); 3145 } 3146 3147 static u32 intel_cx0_get_pclk_pll_request(u8 lane_mask) 3148 { 3149 u32 val = 0; 3150 int lane = 0; 3151 3152 for_each_cx0_lane_in_mask(lane_mask, lane) 3153 val |= XELPDP_LANE_PCLK_PLL_REQUEST(lane); 3154 3155 return val; 3156 } 3157 3158 static u32 intel_cx0_get_pclk_pll_ack(u8 lane_mask) 3159 { 3160 u32 val = 0; 3161 int lane = 0; 3162 3163 for_each_cx0_lane_in_mask(lane_mask, lane) 3164 val |= XELPDP_LANE_PCLK_PLL_ACK(lane); 3165 3166 return val; 3167 } 3168 3169 static void intel_cx0pll_enable(struct intel_encoder *encoder, 3170 const struct intel_cx0pll_state *pll_state) 3171 { 3172 struct intel_display *display = to_intel_display(encoder); 3173 enum phy phy = intel_encoder_to_phy(encoder); 3174 struct intel_digital_port *dig_port = enc_to_dig_port(encoder); 3175 bool lane_reversal = dig_port->lane_reversal; 3176 u8 maxpclk_lane = lane_reversal ? INTEL_CX0_LANE1 : 3177 INTEL_CX0_LANE0; 3178 struct ref_tracker *wakeref = intel_cx0_phy_transaction_begin(encoder); 3179 int port_clock; 3180 3181 if (pll_state->use_c10) 3182 port_clock = intel_c10pll_calc_port_clock(&pll_state->c10); 3183 else 3184 port_clock = intel_c20pll_calc_port_clock(&pll_state->c20); 3185 3186 /* 3187 * Lane reversal is never used in DP-alt mode, in that case the 3188 * corresponding lane swapping (based on the TypeC cable flip state 3189 * for instance) is handled automatically by the HW via a TCSS mux. 3190 */ 3191 drm_WARN_ON(display->drm, lane_reversal && intel_tc_port_in_dp_alt_mode(dig_port)); 3192 3193 /* 3194 * 1. Program PORT_CLOCK_CTL REGISTER to configure 3195 * clock muxes, gating and SSC 3196 */ 3197 intel_program_port_clock_ctl(encoder, pll_state, port_clock, lane_reversal); 3198 3199 /* 2. Bring PHY out of reset. */ 3200 intel_cx0_phy_lane_reset(encoder, lane_reversal); 3201 3202 /* 3203 * 3. Change Phy power state to Ready. 3204 * TODO: For DP alt mode use only one lane. 3205 */ 3206 intel_cx0_powerdown_change_sequence(encoder, INTEL_CX0_BOTH_LANES, 3207 XELPDP_P2_STATE_READY); 3208 3209 /* 3210 * 4. Program PORT_MSGBUS_TIMER register's Message Bus Timer field to 0xA000. 3211 * (This is done inside intel_cx0_phy_transaction_begin(), since we would need 3212 * the right timer thresholds for readouts too.) 3213 */ 3214 3215 /* 5. Program PHY internal PLL internal registers. */ 3216 if (intel_encoder_is_c10phy(encoder)) 3217 intel_c10_pll_program(display, encoder, &pll_state->c10); 3218 else 3219 intel_c20_pll_program(display, encoder, &pll_state->c20); 3220 3221 /* 3222 * 6. Program the enabled and disabled owned PHY lane 3223 * transmitters over message bus 3224 */ 3225 intel_cx0_program_phy_lane(encoder, pll_state->lane_count, lane_reversal); 3226 3227 /* 3228 * 7. Follow the Display Voltage Frequency Switching - Sequence 3229 * Before Frequency Change. We handle this step in bxt_set_cdclk(). 3230 */ 3231 3232 /* 3233 * 8. Program DDI_CLK_VALFREQ to match intended DDI 3234 * clock frequency. 3235 */ 3236 intel_de_write(display, DDI_CLK_VALFREQ(encoder->port), port_clock); 3237 3238 /* 3239 * 9. Set PORT_CLOCK_CTL register PCLK PLL Request 3240 * LN<Lane for maxPCLK> to "1" to enable PLL. 3241 */ 3242 intel_de_rmw(display, XELPDP_PORT_CLOCK_CTL(display, encoder->port), 3243 intel_cx0_get_pclk_pll_request(INTEL_CX0_BOTH_LANES), 3244 intel_cx0_get_pclk_pll_request(maxpclk_lane)); 3245 3246 /* 10. Poll on PORT_CLOCK_CTL PCLK PLL Ack LN<Lane for maxPCLK> == "1". */ 3247 if (intel_de_wait_us(display, XELPDP_PORT_CLOCK_CTL(display, encoder->port), 3248 intel_cx0_get_pclk_pll_ack(INTEL_CX0_BOTH_LANES), 3249 intel_cx0_get_pclk_pll_ack(maxpclk_lane), 3250 XELPDP_PCLK_PLL_ENABLE_TIMEOUT_US, NULL)) 3251 drm_warn(display->drm, "Port %c PLL not locked\n", 3252 phy_name(phy)); 3253 3254 /* 3255 * 11. Follow the Display Voltage Frequency Switching Sequence After 3256 * Frequency Change. We handle this step in bxt_set_cdclk(). 3257 */ 3258 3259 /* 3260 * 12. Toggle powerdown if HDMI is enabled on C10 PHY. 3261 * 3262 * Wa_13013502646: 3263 * Fixes: HDMI lane to lane skew violations on C10 display PHYs. 3264 * Workaround: Toggle powerdown value by setting first to P0 and then to P2, for both 3265 * PHY lanes. 3266 */ 3267 if (!cx0pll_state_is_dp(pll_state) && pll_state->use_c10) { 3268 intel_cx0_powerdown_change_sequence(encoder, INTEL_CX0_BOTH_LANES, 3269 XELPDP_P0_STATE_ACTIVE); 3270 intel_cx0_powerdown_change_sequence(encoder, INTEL_CX0_BOTH_LANES, 3271 XELPDP_P2_STATE_READY); 3272 } 3273 3274 intel_cx0_phy_transaction_end(encoder, wakeref); 3275 } 3276 3277 void intel_mtl_tbt_pll_calc_state(struct intel_dpll_hw_state *hw_state) 3278 { 3279 memset(hw_state, 0, sizeof(*hw_state)); 3280 3281 hw_state->cx0pll.tbt_mode = true; 3282 } 3283 3284 bool intel_mtl_tbt_pll_readout_hw_state(struct intel_display *display, 3285 struct intel_dpll *pll, 3286 struct intel_dpll_hw_state *hw_state) 3287 { 3288 memset(hw_state, 0, sizeof(*hw_state)); 3289 3290 hw_state->cx0pll.tbt_mode = true; 3291 3292 return true; 3293 } 3294 3295 int intel_mtl_tbt_calc_port_clock(struct intel_encoder *encoder) 3296 { 3297 struct intel_display *display = to_intel_display(encoder); 3298 u32 clock, val; 3299 3300 val = intel_de_read(display, XELPDP_PORT_CLOCK_CTL(display, encoder->port)); 3301 3302 clock = XELPDP_DDI_CLOCK_SELECT_GET(display, val); 3303 3304 drm_WARN_ON(display->drm, !(val & XELPDP_FORWARD_CLOCK_UNGATE)); 3305 drm_WARN_ON(display->drm, !(val & XELPDP_TBT_CLOCK_REQUEST)); 3306 drm_WARN_ON(display->drm, !(val & XELPDP_TBT_CLOCK_ACK)); 3307 3308 switch (clock) { 3309 case XELPDP_DDI_CLOCK_SELECT_TBT_162: 3310 return 162000; 3311 case XELPDP_DDI_CLOCK_SELECT_TBT_270: 3312 return 270000; 3313 case XELPDP_DDI_CLOCK_SELECT_TBT_540: 3314 return 540000; 3315 case XELPDP_DDI_CLOCK_SELECT_TBT_810: 3316 return 810000; 3317 case XELPDP_DDI_CLOCK_SELECT_TBT_312_5: 3318 return 1000000; 3319 case XELPDP_DDI_CLOCK_SELECT_TBT_625: 3320 return 2000000; 3321 default: 3322 MISSING_CASE(clock); 3323 return 162000; 3324 } 3325 } 3326 3327 static int intel_mtl_tbt_clock_select(struct intel_display *display, 3328 int clock) 3329 { 3330 switch (clock) { 3331 case 162000: 3332 return XELPDP_DDI_CLOCK_SELECT_TBT_162; 3333 case 270000: 3334 return XELPDP_DDI_CLOCK_SELECT_TBT_270; 3335 case 540000: 3336 return XELPDP_DDI_CLOCK_SELECT_TBT_540; 3337 case 810000: 3338 return XELPDP_DDI_CLOCK_SELECT_TBT_810; 3339 case 1000000: 3340 if (DISPLAY_VER(display) < 30) { 3341 drm_WARN_ON(display->drm, "UHBR10 not supported for the platform\n"); 3342 return XELPDP_DDI_CLOCK_SELECT_TBT_162; 3343 } 3344 return XELPDP_DDI_CLOCK_SELECT_TBT_312_5; 3345 case 2000000: 3346 if (DISPLAY_VER(display) < 30) { 3347 drm_WARN_ON(display->drm, "UHBR20 not supported for the platform\n"); 3348 return XELPDP_DDI_CLOCK_SELECT_TBT_162; 3349 } 3350 return XELPDP_DDI_CLOCK_SELECT_TBT_625; 3351 default: 3352 MISSING_CASE(clock); 3353 return XELPDP_DDI_CLOCK_SELECT_TBT_162; 3354 } 3355 } 3356 3357 void intel_mtl_tbt_pll_enable_clock(struct intel_encoder *encoder, int port_clock) 3358 { 3359 struct intel_display *display = to_intel_display(encoder); 3360 enum phy phy = intel_encoder_to_phy(encoder); 3361 u32 val = 0; 3362 u32 mask; 3363 3364 /* 3365 * 1. Program PORT_CLOCK_CTL REGISTER to configure 3366 * clock muxes, gating and SSC 3367 */ 3368 3369 mask = XELPDP_DDI_CLOCK_SELECT_MASK(display); 3370 val |= XELPDP_DDI_CLOCK_SELECT_PREP(display, 3371 intel_mtl_tbt_clock_select(display, port_clock)); 3372 3373 mask |= XELPDP_FORWARD_CLOCK_UNGATE; 3374 val |= XELPDP_FORWARD_CLOCK_UNGATE; 3375 3376 intel_de_rmw(display, XELPDP_PORT_CLOCK_CTL(display, encoder->port), 3377 mask, val); 3378 3379 /* 2. Read back PORT_CLOCK_CTL REGISTER */ 3380 val = intel_de_read(display, XELPDP_PORT_CLOCK_CTL(display, encoder->port)); 3381 3382 /* 3383 * 3. Follow the Display Voltage Frequency Switching - Sequence 3384 * Before Frequency Change. We handle this step in bxt_set_cdclk(). 3385 */ 3386 3387 /* 3388 * 4. Set PORT_CLOCK_CTL register TBT CLOCK Request to "1" to enable PLL. 3389 */ 3390 val |= XELPDP_TBT_CLOCK_REQUEST; 3391 intel_de_write(display, XELPDP_PORT_CLOCK_CTL(display, encoder->port), val); 3392 3393 /* 5. Poll on PORT_CLOCK_CTL TBT CLOCK Ack == "1". */ 3394 if (intel_de_wait_for_set_us(display, XELPDP_PORT_CLOCK_CTL(display, encoder->port), 3395 XELPDP_TBT_CLOCK_ACK, 100)) 3396 drm_warn(display->drm, "[ENCODER:%d:%s][%c] PHY PLL not locked\n", 3397 encoder->base.base.id, encoder->base.name, phy_name(phy)); 3398 3399 /* 3400 * 6. Follow the Display Voltage Frequency Switching Sequence After 3401 * Frequency Change. We handle this step in bxt_set_cdclk(). 3402 */ 3403 3404 /* 3405 * 7. Program DDI_CLK_VALFREQ to match intended DDI 3406 * clock frequency. 3407 */ 3408 intel_de_write(display, DDI_CLK_VALFREQ(encoder->port), 3409 port_clock); 3410 } 3411 3412 void intel_mtl_pll_enable(struct intel_encoder *encoder, 3413 struct intel_dpll *pll, 3414 const struct intel_dpll_hw_state *dpll_hw_state) 3415 { 3416 intel_cx0pll_enable(encoder, &dpll_hw_state->cx0pll); 3417 } 3418 3419 void intel_mtl_pll_enable_clock(struct intel_encoder *encoder, 3420 const struct intel_crtc_state *crtc_state) 3421 { 3422 struct intel_display *display = to_intel_display(encoder); 3423 struct intel_digital_port *dig_port = enc_to_dig_port(encoder); 3424 3425 if (intel_tc_port_in_tbt_alt_mode(dig_port)) 3426 intel_mtl_tbt_pll_enable_clock(encoder, crtc_state->port_clock); 3427 3428 /* 3429 * CMTG can be enabled only when the transcoder and port are compatible 3430 * (transcoder A with port A, transcoder B with port B). 3431 */ 3432 if (HAS_LT_PHY(display) && 3433 ((crtc_state->cpu_transcoder == TRANSCODER_A && encoder->port == PORT_A) || 3434 (crtc_state->cpu_transcoder == TRANSCODER_B && encoder->port == PORT_B))) 3435 intel_cmtg_set_clk_select(crtc_state); 3436 } 3437 3438 /* 3439 * According to HAS we need to enable MAC Transmitting LFPS in the "PHY Common 3440 * Control 0" PIPE register in case of AUX Less ALPM is going to be used. This 3441 * function is doing that and is called by link retrain sequence. 3442 */ 3443 void intel_lnl_mac_transmit_lfps(struct intel_encoder *encoder, 3444 const struct intel_crtc_state *crtc_state) 3445 { 3446 struct intel_display *display = to_intel_display(encoder); 3447 struct ref_tracker *wakeref; 3448 int i; 3449 u8 owned_lane_mask; 3450 3451 if (DISPLAY_VER(display) < 20 || 3452 !intel_alpm_is_alpm_aux_less(enc_to_intel_dp(encoder), crtc_state)) 3453 return; 3454 3455 owned_lane_mask = intel_cx0_get_owned_lane_mask(encoder); 3456 3457 wakeref = intel_cx0_phy_transaction_begin(encoder); 3458 3459 intel_c10_msgbus_access_begin(encoder, owned_lane_mask); 3460 3461 for (i = 0; i < 4; i++) { 3462 int tx = i % 2 + 1; 3463 u8 lane_mask = i < 2 ? INTEL_CX0_LANE0 : INTEL_CX0_LANE1; 3464 3465 if (!(owned_lane_mask & lane_mask)) 3466 continue; 3467 3468 intel_cx0_rmw(encoder, lane_mask, PHY_CMN1_CONTROL(tx, 0), 3469 CONTROL0_MAC_TRANSMIT_LFPS, 3470 CONTROL0_MAC_TRANSMIT_LFPS, MB_WRITE_COMMITTED); 3471 } 3472 3473 intel_cx0_phy_transaction_end(encoder, wakeref); 3474 } 3475 3476 static u8 cx0_power_control_disable_val(struct intel_encoder *encoder) 3477 { 3478 struct intel_display *display = to_intel_display(encoder); 3479 3480 if (intel_encoder_is_c10phy(encoder)) 3481 return XELPDP_P2PG_STATE_DISABLE; 3482 3483 if ((display->platform.battlemage && encoder->port == PORT_A) || 3484 (DISPLAY_VER(display) >= 30 && encoder->type == INTEL_OUTPUT_EDP)) 3485 return XELPDP_P2PG_STATE_DISABLE; 3486 3487 return XELPDP_P4PG_STATE_DISABLE; 3488 } 3489 3490 static void intel_cx0pll_disable(struct intel_encoder *encoder) 3491 { 3492 struct intel_display *display = to_intel_display(encoder); 3493 enum phy phy = intel_encoder_to_phy(encoder); 3494 struct ref_tracker *wakeref = intel_cx0_phy_transaction_begin(encoder); 3495 3496 /* 1. Change owned PHY lane power to Disable state. */ 3497 intel_cx0_powerdown_change_sequence(encoder, INTEL_CX0_BOTH_LANES, 3498 cx0_power_control_disable_val(encoder)); 3499 3500 /* 3501 * 2. Follow the Display Voltage Frequency Switching Sequence Before 3502 * Frequency Change. We handle this step in bxt_set_cdclk(). 3503 */ 3504 3505 /* 3506 * 3. Set PORT_CLOCK_CTL register PCLK PLL Request LN<Lane for maxPCLK> 3507 * to "0" to disable PLL. 3508 */ 3509 intel_de_rmw(display, XELPDP_PORT_CLOCK_CTL(display, encoder->port), 3510 intel_cx0_get_pclk_pll_request(INTEL_CX0_BOTH_LANES) | 3511 intel_cx0_get_pclk_refclk_request(INTEL_CX0_BOTH_LANES), 0); 3512 3513 /* 4. Program DDI_CLK_VALFREQ to 0. */ 3514 intel_de_write(display, DDI_CLK_VALFREQ(encoder->port), 0); 3515 3516 /* 3517 * 5. Poll on PORT_CLOCK_CTL PCLK PLL Ack LN<Lane for maxPCLK**> == "0". 3518 */ 3519 if (intel_de_wait_for_clear_us(display, XELPDP_PORT_CLOCK_CTL(display, encoder->port), 3520 intel_cx0_get_pclk_pll_ack(INTEL_CX0_BOTH_LANES) | 3521 intel_cx0_get_pclk_refclk_ack(INTEL_CX0_BOTH_LANES), 3522 XELPDP_PCLK_PLL_DISABLE_TIMEOUT_US)) 3523 drm_warn(display->drm, "Port %c PLL not unlocked\n", 3524 phy_name(phy)); 3525 3526 /* 3527 * 6. Follow the Display Voltage Frequency Switching Sequence After 3528 * Frequency Change. We handle this step in bxt_set_cdclk(). 3529 */ 3530 3531 /* 7. Program PORT_CLOCK_CTL register to disable and gate clocks. */ 3532 intel_de_rmw(display, XELPDP_PORT_CLOCK_CTL(display, encoder->port), 3533 XELPDP_DDI_CLOCK_SELECT_MASK(display), 0); 3534 intel_de_rmw(display, XELPDP_PORT_CLOCK_CTL(display, encoder->port), 3535 XELPDP_FORWARD_CLOCK_UNGATE, 0); 3536 3537 intel_cx0_phy_transaction_end(encoder, wakeref); 3538 } 3539 3540 static bool intel_cx0_pll_is_enabled(struct intel_encoder *encoder) 3541 { 3542 struct intel_display *display = to_intel_display(encoder); 3543 struct intel_digital_port *dig_port = enc_to_dig_port(encoder); 3544 u8 lane = dig_port->lane_reversal ? INTEL_CX0_LANE1 : INTEL_CX0_LANE0; 3545 3546 return intel_de_read(display, XELPDP_PORT_CLOCK_CTL(display, encoder->port)) & 3547 intel_cx0_get_pclk_pll_request(lane); 3548 } 3549 3550 void intel_mtl_tbt_pll_disable_clock(struct intel_encoder *encoder) 3551 { 3552 struct intel_display *display = to_intel_display(encoder); 3553 enum phy phy = intel_encoder_to_phy(encoder); 3554 3555 /* 3556 * 1. Follow the Display Voltage Frequency Switching Sequence Before 3557 * Frequency Change. We handle this step in bxt_set_cdclk(). 3558 */ 3559 3560 /* 3561 * 2. Set PORT_CLOCK_CTL register TBT CLOCK Request to "0" to disable PLL. 3562 */ 3563 intel_de_rmw(display, XELPDP_PORT_CLOCK_CTL(display, encoder->port), 3564 XELPDP_TBT_CLOCK_REQUEST, 0); 3565 3566 /* 3. Poll on PORT_CLOCK_CTL TBT CLOCK Ack == "0". */ 3567 if (intel_de_wait_for_clear_us(display, XELPDP_PORT_CLOCK_CTL(display, encoder->port), 3568 XELPDP_TBT_CLOCK_ACK, 10)) 3569 drm_warn(display->drm, "[ENCODER:%d:%s][%c] PHY PLL not unlocked\n", 3570 encoder->base.base.id, encoder->base.name, phy_name(phy)); 3571 3572 /* 3573 * 4. Follow the Display Voltage Frequency Switching Sequence After 3574 * Frequency Change. We handle this step in bxt_set_cdclk(). 3575 */ 3576 3577 /* 3578 * 5. Program PORT CLOCK CTRL register to disable and gate clocks 3579 */ 3580 intel_de_rmw(display, XELPDP_PORT_CLOCK_CTL(display, encoder->port), 3581 XELPDP_DDI_CLOCK_SELECT_MASK(display) | 3582 XELPDP_FORWARD_CLOCK_UNGATE, 0); 3583 3584 /* 6. Program DDI_CLK_VALFREQ to 0. */ 3585 intel_de_write(display, DDI_CLK_VALFREQ(encoder->port), 0); 3586 } 3587 3588 void intel_mtl_pll_disable(struct intel_encoder *encoder) 3589 { 3590 intel_cx0pll_disable(encoder); 3591 } 3592 3593 void intel_mtl_pll_disable_clock(struct intel_encoder *encoder) 3594 { 3595 struct intel_digital_port *dig_port = enc_to_dig_port(encoder); 3596 3597 if (intel_tc_port_in_tbt_alt_mode(dig_port)) 3598 intel_mtl_tbt_pll_disable_clock(encoder); 3599 } 3600 3601 enum icl_port_dpll_id 3602 intel_mtl_port_pll_type(struct intel_encoder *encoder, 3603 const struct intel_crtc_state *crtc_state) 3604 { 3605 struct intel_display *display = to_intel_display(encoder); 3606 u32 val, clock; 3607 3608 /* 3609 * TODO: Determine the PLL type from the SW state, once MTL PLL 3610 * handling is done via the standard shared DPLL framework. 3611 */ 3612 val = intel_de_read(display, XELPDP_PORT_CLOCK_CTL(display, encoder->port)); 3613 clock = XELPDP_DDI_CLOCK_SELECT_GET(display, val); 3614 3615 if (clock == XELPDP_DDI_CLOCK_SELECT_MAXPCLK || 3616 clock == XELPDP_DDI_CLOCK_SELECT_DIV18CLK) 3617 return ICL_PORT_DPLL_MG_PHY; 3618 else 3619 return ICL_PORT_DPLL_DEFAULT; 3620 } 3621 3622 bool intel_cx0pll_readout_hw_state(struct intel_encoder *encoder, 3623 struct intel_cx0pll_state *pll_state) 3624 { 3625 memset(pll_state, 0, sizeof(*pll_state)); 3626 3627 if (!intel_cx0_pll_is_enabled(encoder)) 3628 return false; 3629 3630 if (intel_encoder_is_c10phy(encoder)) 3631 intel_c10pll_readout_hw_state(encoder, pll_state); 3632 else 3633 intel_c20pll_readout_hw_state(encoder, pll_state); 3634 3635 return true; 3636 } 3637 3638 static bool mtl_compare_hw_state_c10(const struct intel_c10pll_state *a, 3639 const struct intel_c10pll_state *b) 3640 { 3641 if (a->tx != b->tx) 3642 return false; 3643 3644 if (a->cmn != b->cmn) 3645 return false; 3646 3647 if (memcmp(&a->pll, &b->pll, sizeof(a->pll)) != 0) 3648 return false; 3649 3650 return true; 3651 } 3652 3653 static bool mtl_compare_hw_state_c20(const struct intel_c20pll_state *a, 3654 const struct intel_c20pll_state *b) 3655 { 3656 if (memcmp(&a->tx, &b->tx, sizeof(a->tx)) != 0) 3657 return false; 3658 3659 if (memcmp(&a->cmn, &b->cmn, sizeof(a->cmn)) != 0) 3660 return false; 3661 3662 if (a->tx[0] & C20_PHY_USE_MPLLB) { 3663 if (memcmp(&a->mpllb, &b->mpllb, sizeof(a->mpllb)) != 0) 3664 return false; 3665 } else { 3666 if (memcmp(&a->mplla, &b->mplla, sizeof(a->mplla)) != 0) 3667 return false; 3668 } 3669 3670 return true; 3671 } 3672 3673 bool intel_cx0pll_compare_hw_state(const struct intel_cx0pll_state *a, 3674 const struct intel_cx0pll_state *b) 3675 { 3676 if (a->tbt_mode || b->tbt_mode) 3677 return true; 3678 3679 if (a->use_c10 != b->use_c10) 3680 return false; 3681 3682 if (a->use_c10) 3683 return mtl_compare_hw_state_c10(&a->c10, 3684 &b->c10); 3685 else 3686 return mtl_compare_hw_state_c20(&a->c20, 3687 &b->c20); 3688 } 3689 3690 int intel_cx0pll_calc_port_clock(struct intel_encoder *encoder, 3691 const struct intel_cx0pll_state *pll_state) 3692 { 3693 if (intel_encoder_is_c10phy(encoder)) 3694 return intel_c10pll_calc_port_clock(&pll_state->c10); 3695 3696 return intel_c20pll_calc_port_clock(&pll_state->c20); 3697 } 3698 3699 /* 3700 * WA 14022081154 3701 * The dedicated display PHYs reset to a power state that blocks S0ix, increasing idle 3702 * system power. After a system reset (cold boot, S3/4/5, warm reset) if a dedicated 3703 * PHY is not being brought up shortly, use these steps to move the PHY to the lowest 3704 * power state to save power. For PTL the workaround is needed only for port A. Port B 3705 * is not connected. 3706 * 3707 * 1. Follow the PLL Enable Sequence, using any valid frequency such as DP 1.62 GHz. 3708 * This brings lanes out of reset and enables the PLL to allow powerdown to be moved 3709 * to the Disable state. 3710 * 2. Follow PLL Disable Sequence. This moves powerdown to the Disable state and disables the PLL. 3711 */ 3712 void intel_cx0_pll_power_save_wa(struct intel_display *display) 3713 { 3714 struct intel_encoder *encoder; 3715 3716 if (DISPLAY_VER(display) != 30) 3717 return; 3718 3719 for_each_intel_encoder(display->drm, encoder) { 3720 struct intel_cx0pll_state pll_state = {}; 3721 int port_clock = 162000; 3722 int lane_count = 4; 3723 3724 if (!intel_encoder_is_dig_port(encoder)) 3725 continue; 3726 3727 if (!intel_encoder_is_c10phy(encoder)) 3728 continue; 3729 3730 if (intel_cx0_pll_is_enabled(encoder)) 3731 continue; 3732 3733 if (intel_c10pll_calc_state_from_table(encoder, 3734 mtl_c10_edp_tables, 3735 true, port_clock, lane_count, 3736 &pll_state) < 0) { 3737 drm_WARN_ON(display->drm, 3738 "Unable to calc C10 state from the tables\n"); 3739 continue; 3740 } 3741 3742 drm_dbg_kms(display->drm, 3743 "[ENCODER:%d:%s] Applying power saving workaround on disabled PLL\n", 3744 encoder->base.base.id, encoder->base.name); 3745 3746 intel_cx0pll_enable(encoder, &pll_state); 3747 intel_cx0pll_disable(encoder); 3748 } 3749 } 3750 3751 static void intel_c10pll_verify_clock(struct intel_display *display, 3752 int precomputed_clock, 3753 const char *pll_state_name, 3754 const struct intel_c10pll_state *pll_state, 3755 bool is_precomputed_state) 3756 { 3757 struct drm_printer p; 3758 int clock; 3759 3760 clock = intel_c10pll_calc_port_clock(pll_state); 3761 3762 if (intel_dpll_clock_matches(clock, precomputed_clock)) 3763 return; 3764 3765 drm_warn(display->drm, 3766 "PLL state %s (%s): clock difference too high: computed %d, pre-computed %d\n", 3767 pll_state_name, 3768 is_precomputed_state ? "precomputed" : "computed", 3769 clock, precomputed_clock); 3770 3771 if (!drm_debug_enabled(DRM_UT_KMS)) 3772 return; 3773 3774 p = drm_dbg_printer(display->drm, DRM_UT_KMS, NULL); 3775 3776 drm_printf(&p, "PLL state %s (%s):\n", 3777 pll_state_name, 3778 is_precomputed_state ? "precomputed" : "computed"); 3779 intel_c10pll_dump_hw_state(&p, pll_state); 3780 } 3781 3782 static void intel_c10pll_verify_params(struct intel_display *display, 3783 const struct intel_cx0pll_params *pll_params) 3784 { 3785 struct intel_c10pll_state pll_state; 3786 3787 intel_c10pll_verify_clock(display, pll_params->clock_rate, pll_params->name, pll_params->c10, true); 3788 3789 if (!pll_params->is_hdmi) 3790 return; 3791 3792 intel_snps_hdmi_pll_compute_c10pll(&pll_state, pll_params->clock_rate); 3793 3794 intel_c10pll_verify_clock(display, pll_params->clock_rate, pll_params->name, &pll_state, false); 3795 } 3796 3797 static void intel_c20pll_verify_clock(struct intel_display *display, 3798 int precomputed_clock, 3799 const char *pll_state_name, 3800 const struct intel_c20pll_state *pll_state, 3801 bool is_precomputed_state) 3802 { 3803 struct drm_printer p; 3804 int clock; 3805 3806 clock = intel_c20pll_calc_port_clock(pll_state); 3807 3808 if (intel_dpll_clock_matches(clock, precomputed_clock)) 3809 return; 3810 3811 drm_warn(display->drm, 3812 "PLL state %s (%s): clock difference too high: computed %d, pre-computed %d\n", 3813 pll_state_name, 3814 is_precomputed_state ? "precomputed" : "computed", 3815 clock, precomputed_clock); 3816 3817 if (!drm_debug_enabled(DRM_UT_KMS)) 3818 return; 3819 3820 p = drm_dbg_printer(display->drm, DRM_UT_KMS, NULL); 3821 3822 drm_printf(&p, "PLL state %s (%s):\n", 3823 pll_state_name, 3824 is_precomputed_state ? "precomputed" : "computed"); 3825 intel_c20pll_dump_hw_state(&p, pll_state); 3826 } 3827 3828 static void intel_c20pll_verify_params(struct intel_display *display, 3829 const struct intel_cx0pll_params *pll_params) 3830 { 3831 struct intel_c20pll_state pll_state; 3832 3833 intel_c20pll_verify_clock(display, pll_params->clock_rate, pll_params->name, pll_params->c20, true); 3834 3835 if (!pll_params->is_hdmi) 3836 return; 3837 3838 if (intel_c20_compute_hdmi_tmds_pll(display, pll_params->clock_rate, &pll_state) != 0) 3839 return; 3840 3841 intel_c20pll_verify_clock(display, pll_params->clock_rate, pll_params->name, &pll_state, false); 3842 } 3843 3844 static void intel_cx0pll_verify_tables(struct intel_display *display, 3845 const struct intel_cx0pll_params *tables) 3846 { 3847 int i; 3848 3849 for (i = 0; tables[i].name; i++) { 3850 if (tables[i].is_c10) 3851 intel_c10pll_verify_params(display, &tables[i]); 3852 else 3853 intel_c20pll_verify_params(display, &tables[i]); 3854 } 3855 } 3856 3857 void intel_cx0pll_verify_plls(struct intel_display *display) 3858 { 3859 /* C10 */ 3860 intel_cx0pll_verify_tables(display, mtl_c10_edp_tables); 3861 intel_cx0pll_verify_tables(display, mtl_c10_dp_tables); 3862 intel_cx0pll_verify_tables(display, mtl_c10_hdmi_tables); 3863 3864 /* C20 */ 3865 intel_cx0pll_verify_tables(display, xe2hpd_c20_edp_tables); 3866 intel_cx0pll_verify_tables(display, mtl_c20_dp_tables); 3867 intel_cx0pll_verify_tables(display, xe2hpd_c20_dp_tables); 3868 intel_cx0pll_verify_tables(display, xe3lpd_c20_dp_edp_tables); 3869 intel_cx0pll_verify_tables(display, mtl_c20_hdmi_tables); 3870 } 3871