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