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