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