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