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