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