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