brintos

brintos / linux-shallow public Read only

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