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