File Index
Files and directories
Sign in
FILE

intel_cx0_phy.c

File preview with syntax highlighting.

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