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