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