drm/i915/mtl: Add C10 phy programming for HDMI
[platform/kernel/linux-starfive.git] / drivers / gpu / drm / i915 / display / intel_cx0_phy.c
1 // SPDX-License-Identifier: MIT
2 /*
3  * Copyright © 2023 Intel Corporation
4  */
5
6 #include "i915_reg.h"
7 #include "intel_cx0_phy.h"
8 #include "intel_cx0_phy_regs.h"
9 #include "intel_ddi.h"
10 #include "intel_ddi_buf_trans.h"
11 #include "intel_de.h"
12 #include "intel_display_types.h"
13 #include "intel_dp.h"
14 #include "intel_panel.h"
15 #include "intel_psr.h"
16 #include "intel_tc.h"
17
18 #define MB_WRITE_COMMITTED      true
19 #define MB_WRITE_UNCOMMITTED    false
20
21 #define for_each_cx0_lane_in_mask(__lane_mask, __lane) \
22         for ((__lane) = 0; (__lane) < 2; (__lane)++) \
23                 for_each_if((__lane_mask) & BIT(__lane))
24
25 #define INTEL_CX0_LANE0         BIT(0)
26 #define INTEL_CX0_LANE1         BIT(1)
27 #define INTEL_CX0_BOTH_LANES    (INTEL_CX0_LANE1 | INTEL_CX0_LANE0)
28
29 bool intel_is_c10phy(struct drm_i915_private *i915, enum phy phy)
30 {
31         if (IS_METEORLAKE(i915) && (phy < PHY_C))
32                 return true;
33
34         return false;
35 }
36
37 static int lane_mask_to_lane(u8 lane_mask)
38 {
39         if (WARN_ON((lane_mask & ~INTEL_CX0_BOTH_LANES) ||
40                     hweight8(lane_mask) != 1))
41                 return 0;
42
43         return ilog2(lane_mask);
44 }
45
46 static void
47 assert_dc_off(struct drm_i915_private *i915)
48 {
49         bool enabled;
50
51         enabled = intel_display_power_is_enabled(i915, POWER_DOMAIN_DC_OFF);
52         drm_WARN_ON(&i915->drm, !enabled);
53 }
54
55 /*
56  * Prepare HW for CX0 phy transactions.
57  *
58  * It is required that PSR and DC5/6 are disabled before any CX0 message
59  * bus transaction is executed.
60  */
61 static intel_wakeref_t intel_cx0_phy_transaction_begin(struct intel_encoder *encoder)
62 {
63         struct drm_i915_private *i915 = to_i915(encoder->base.dev);
64         struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
65
66         intel_psr_pause(intel_dp);
67         return intel_display_power_get(i915, POWER_DOMAIN_DC_OFF);
68 }
69
70 static void intel_cx0_phy_transaction_end(struct intel_encoder *encoder, intel_wakeref_t wakeref)
71 {
72         struct drm_i915_private *i915 = to_i915(encoder->base.dev);
73         struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
74
75         intel_psr_resume(intel_dp);
76         intel_display_power_put(i915, POWER_DOMAIN_DC_OFF, wakeref);
77 }
78
79 static void intel_clear_response_ready_flag(struct drm_i915_private *i915,
80                                             enum port port, int lane)
81 {
82         intel_de_rmw(i915, XELPDP_PORT_P2M_MSGBUS_STATUS(port, lane),
83                      0, XELPDP_PORT_P2M_RESPONSE_READY | XELPDP_PORT_P2M_ERROR_SET);
84 }
85
86 static void intel_cx0_bus_reset(struct drm_i915_private *i915, enum port port, int lane)
87 {
88         enum phy phy = intel_port_to_phy(i915, port);
89
90         intel_de_write(i915, XELPDP_PORT_M2P_MSGBUS_CTL(port, lane),
91                        XELPDP_PORT_M2P_TRANSACTION_RESET);
92
93         if (intel_de_wait_for_clear(i915, XELPDP_PORT_M2P_MSGBUS_CTL(port, lane),
94                                     XELPDP_PORT_M2P_TRANSACTION_RESET,
95                                     XELPDP_MSGBUS_TIMEOUT_SLOW)) {
96                 drm_err_once(&i915->drm, "Failed to bring PHY %c to idle.\n", phy_name(phy));
97                 return;
98         }
99
100         intel_clear_response_ready_flag(i915, port, lane);
101 }
102
103 static int intel_cx0_wait_for_ack(struct drm_i915_private *i915, enum port port,
104                                   int command, int lane, u32 *val)
105 {
106         enum phy phy = intel_port_to_phy(i915, port);
107
108         if (__intel_de_wait_for_register(i915,
109                                          XELPDP_PORT_P2M_MSGBUS_STATUS(port, lane),
110                                          XELPDP_PORT_P2M_RESPONSE_READY,
111                                          XELPDP_PORT_P2M_RESPONSE_READY,
112                                          XELPDP_MSGBUS_TIMEOUT_FAST_US,
113                                          XELPDP_MSGBUS_TIMEOUT_SLOW, val)) {
114                 drm_dbg_kms(&i915->drm, "PHY %c Timeout waiting for message ACK. Status: 0x%x\n",
115                             phy_name(phy), *val);
116                 return -ETIMEDOUT;
117         }
118
119         if (*val & XELPDP_PORT_P2M_ERROR_SET) {
120                 drm_dbg_kms(&i915->drm, "PHY %c Error occurred during %s command. Status: 0x%x\n", phy_name(phy),
121                             command == XELPDP_PORT_P2M_COMMAND_READ_ACK ? "read" : "write", *val);
122                 intel_cx0_bus_reset(i915, port, lane);
123                 return -EINVAL;
124         }
125
126         if (REG_FIELD_GET(XELPDP_PORT_P2M_COMMAND_TYPE_MASK, *val) != command) {
127                 drm_dbg_kms(&i915->drm, "PHY %c Not a %s response. MSGBUS Status: 0x%x.\n", phy_name(phy),
128                             command == XELPDP_PORT_P2M_COMMAND_READ_ACK ? "read" : "write", *val);
129                 intel_cx0_bus_reset(i915, port, lane);
130                 return -EINVAL;
131         }
132
133         return 0;
134 }
135
136 static int __intel_cx0_read_once(struct drm_i915_private *i915, enum port port,
137                                  int lane, u16 addr)
138 {
139         enum phy phy = intel_port_to_phy(i915, port);
140         int ack;
141         u32 val;
142
143         if (intel_de_wait_for_clear(i915, XELPDP_PORT_M2P_MSGBUS_CTL(port, lane),
144                                     XELPDP_PORT_M2P_TRANSACTION_PENDING,
145                                     XELPDP_MSGBUS_TIMEOUT_SLOW)) {
146                 drm_dbg_kms(&i915->drm,
147                             "PHY %c Timeout waiting for previous transaction to complete. Reset the bus and retry.\n", phy_name(phy));
148                 intel_cx0_bus_reset(i915, port, lane);
149                 return -ETIMEDOUT;
150         }
151
152         intel_de_write(i915, XELPDP_PORT_M2P_MSGBUS_CTL(port, lane),
153                        XELPDP_PORT_M2P_TRANSACTION_PENDING |
154                        XELPDP_PORT_M2P_COMMAND_READ |
155                        XELPDP_PORT_M2P_ADDRESS(addr));
156
157         ack = intel_cx0_wait_for_ack(i915, port, XELPDP_PORT_P2M_COMMAND_READ_ACK, lane, &val);
158         if (ack < 0) {
159                 intel_cx0_bus_reset(i915, port, lane);
160                 return ack;
161         }
162
163         intel_clear_response_ready_flag(i915, port, lane);
164
165         return REG_FIELD_GET(XELPDP_PORT_P2M_DATA_MASK, val);
166 }
167
168 static u8 __intel_cx0_read(struct drm_i915_private *i915, enum port port,
169                            int lane, u16 addr)
170 {
171         enum phy phy = intel_port_to_phy(i915, port);
172         int i, status;
173
174         assert_dc_off(i915);
175
176         /* 3 tries is assumed to be enough to read successfully */
177         for (i = 0; i < 3; i++) {
178                 status = __intel_cx0_read_once(i915, port, lane, addr);
179
180                 if (status >= 0)
181                         return status;
182         }
183
184         drm_err_once(&i915->drm, "PHY %c Read %04x failed after %d retries.\n",
185                      phy_name(phy), addr, i);
186
187         return 0;
188 }
189
190 static u8 intel_cx0_read(struct drm_i915_private *i915, enum port port,
191                          u8 lane_mask, u16 addr)
192 {
193         int lane = lane_mask_to_lane(lane_mask);
194
195         return __intel_cx0_read(i915, port, lane, addr);
196 }
197
198 static int __intel_cx0_write_once(struct drm_i915_private *i915, enum port port,
199                                   int lane, u16 addr, u8 data, bool committed)
200 {
201         enum phy phy = intel_port_to_phy(i915, port);
202         u32 val;
203
204         if (intel_de_wait_for_clear(i915, XELPDP_PORT_M2P_MSGBUS_CTL(port, lane),
205                                     XELPDP_PORT_M2P_TRANSACTION_PENDING,
206                                     XELPDP_MSGBUS_TIMEOUT_SLOW)) {
207                 drm_dbg_kms(&i915->drm,
208                             "PHY %c Timeout waiting for previous transaction to complete. Resetting the bus.\n", phy_name(phy));
209                 intel_cx0_bus_reset(i915, port, lane);
210                 return -ETIMEDOUT;
211         }
212
213         intel_de_write(i915, XELPDP_PORT_M2P_MSGBUS_CTL(port, lane),
214                        XELPDP_PORT_M2P_TRANSACTION_PENDING |
215                        (committed ? XELPDP_PORT_M2P_COMMAND_WRITE_COMMITTED :
216                                     XELPDP_PORT_M2P_COMMAND_WRITE_UNCOMMITTED) |
217                        XELPDP_PORT_M2P_DATA(data) |
218                        XELPDP_PORT_M2P_ADDRESS(addr));
219
220         if (intel_de_wait_for_clear(i915, XELPDP_PORT_M2P_MSGBUS_CTL(port, lane),
221                                     XELPDP_PORT_M2P_TRANSACTION_PENDING,
222                                     XELPDP_MSGBUS_TIMEOUT_SLOW)) {
223                 drm_dbg_kms(&i915->drm,
224                             "PHY %c Timeout waiting for write to complete. Resetting the bus.\n", phy_name(phy));
225                 intel_cx0_bus_reset(i915, port, lane);
226                 return -ETIMEDOUT;
227         }
228
229         if (committed) {
230                 if (intel_cx0_wait_for_ack(i915, port, XELPDP_PORT_P2M_COMMAND_WRITE_ACK, lane, &val) < 0) {
231                         intel_cx0_bus_reset(i915, port, lane);
232                         return -EINVAL;
233                 }
234         } else if ((intel_de_read(i915, XELPDP_PORT_P2M_MSGBUS_STATUS(port, lane)) &
235                     XELPDP_PORT_P2M_ERROR_SET)) {
236                 drm_dbg_kms(&i915->drm,
237                             "PHY %c Error occurred during write command.\n", phy_name(phy));
238                 intel_cx0_bus_reset(i915, port, lane);
239                 return -EINVAL;
240         }
241
242         intel_clear_response_ready_flag(i915, port, lane);
243
244         return 0;
245 }
246
247 static void __intel_cx0_write(struct drm_i915_private *i915, enum port port,
248                               int lane, u16 addr, u8 data, bool committed)
249 {
250         enum phy phy = intel_port_to_phy(i915, port);
251         int i, status;
252
253         assert_dc_off(i915);
254
255         /* 3 tries is assumed to be enough to write successfully */
256         for (i = 0; i < 3; i++) {
257                 status = __intel_cx0_write_once(i915, port, lane, addr, data, committed);
258
259                 if (status == 0)
260                         return;
261         }
262
263         drm_err_once(&i915->drm,
264                      "PHY %c Write %04x failed after %d retries.\n", phy_name(phy), addr, i);
265 }
266
267 static void intel_cx0_write(struct drm_i915_private *i915, enum port port,
268                             u8 lane_mask, u16 addr, u8 data, bool committed)
269 {
270         int lane;
271
272         for_each_cx0_lane_in_mask(lane_mask, lane)
273                 __intel_cx0_write(i915, port, lane, addr, data, committed);
274 }
275
276 static void __intel_cx0_rmw(struct drm_i915_private *i915, enum port port,
277                             int lane, u16 addr, u8 clear, u8 set, bool committed)
278 {
279         u8 old, val;
280
281         old = __intel_cx0_read(i915, port, lane, addr);
282         val = (old & ~clear) | set;
283
284         if (val != old)
285                 __intel_cx0_write(i915, port, lane, addr, val, committed);
286 }
287
288 static void intel_cx0_rmw(struct drm_i915_private *i915, enum port port,
289                           u8 lane_mask, u16 addr, u8 clear, u8 set, bool committed)
290 {
291         u8 lane;
292
293         for_each_cx0_lane_in_mask(lane_mask, lane)
294                 __intel_cx0_rmw(i915, port, lane, addr, clear, set, committed);
295 }
296
297 static u8 intel_c10_get_tx_vboost_lvl(const struct intel_crtc_state *crtc_state)
298 {
299         if (intel_crtc_has_dp_encoder(crtc_state)) {
300                 if (!intel_crtc_has_type(crtc_state, INTEL_OUTPUT_EDP) &&
301                     (crtc_state->port_clock == 540000 ||
302                      crtc_state->port_clock == 810000))
303                         return 5;
304                 else
305                         return 4;
306         } else {
307                 return 5;
308         }
309 }
310
311 static u8 intel_c10_get_tx_term_ctl(const struct intel_crtc_state *crtc_state)
312 {
313         if (intel_crtc_has_dp_encoder(crtc_state)) {
314                 if (!intel_crtc_has_type(crtc_state, INTEL_OUTPUT_EDP) &&
315                     (crtc_state->port_clock == 540000 ||
316                      crtc_state->port_clock == 810000))
317                         return 5;
318                 else
319                         return 2;
320         } else {
321                 return 6;
322         }
323 }
324
325 void intel_cx0_phy_set_signal_levels(struct intel_encoder *encoder,
326                                      const struct intel_crtc_state *crtc_state)
327 {
328         struct drm_i915_private *i915 = to_i915(encoder->base.dev);
329         const struct intel_ddi_buf_trans *trans;
330         enum phy phy = intel_port_to_phy(i915, encoder->port);
331         intel_wakeref_t wakeref;
332         int n_entries, ln;
333
334         wakeref = intel_cx0_phy_transaction_begin(encoder);
335
336         trans = encoder->get_buf_trans(encoder, crtc_state, &n_entries);
337         if (drm_WARN_ON_ONCE(&i915->drm, !trans)) {
338                 intel_cx0_phy_transaction_end(encoder, wakeref);
339                 return;
340         }
341
342         if (intel_is_c10phy(i915, phy)) {
343                 intel_cx0_rmw(i915, encoder->port, INTEL_CX0_BOTH_LANES, PHY_C10_VDR_CONTROL(1),
344                               0, C10_VDR_CTRL_MSGBUS_ACCESS, MB_WRITE_COMMITTED);
345                 intel_cx0_rmw(i915, encoder->port, INTEL_CX0_BOTH_LANES, PHY_C10_VDR_CMN(3),
346                               C10_CMN3_TXVBOOST_MASK,
347                               C10_CMN3_TXVBOOST(intel_c10_get_tx_vboost_lvl(crtc_state)),
348                               MB_WRITE_UNCOMMITTED);
349                 intel_cx0_rmw(i915, encoder->port, INTEL_CX0_BOTH_LANES, PHY_C10_VDR_TX(1),
350                               C10_TX1_TERMCTL_MASK,
351                               C10_TX1_TERMCTL(intel_c10_get_tx_term_ctl(crtc_state)),
352                               MB_WRITE_COMMITTED);
353         }
354
355         for (ln = 0; ln < crtc_state->lane_count; ln++) {
356                 int level = intel_ddi_level(encoder, crtc_state, ln);
357                 int lane, tx;
358
359                 lane = ln / 2;
360                 tx = ln % 2;
361
362                 intel_cx0_rmw(i915, encoder->port, BIT(lane), PHY_CX0_VDROVRD_CTL(lane, tx, 0),
363                               C10_PHY_OVRD_LEVEL_MASK,
364                               C10_PHY_OVRD_LEVEL(trans->entries[level].snps.pre_cursor),
365                               MB_WRITE_COMMITTED);
366                 intel_cx0_rmw(i915, encoder->port, BIT(lane), PHY_CX0_VDROVRD_CTL(lane, tx, 1),
367                               C10_PHY_OVRD_LEVEL_MASK,
368                               C10_PHY_OVRD_LEVEL(trans->entries[level].snps.vswing),
369                               MB_WRITE_COMMITTED);
370                 intel_cx0_rmw(i915, encoder->port, BIT(lane), PHY_CX0_VDROVRD_CTL(lane, tx, 2),
371                               C10_PHY_OVRD_LEVEL_MASK,
372                               C10_PHY_OVRD_LEVEL(trans->entries[level].snps.post_cursor),
373                               MB_WRITE_COMMITTED);
374         }
375
376         /* Write Override enables in 0xD71 */
377         intel_cx0_rmw(i915, encoder->port, INTEL_CX0_BOTH_LANES, PHY_C10_VDR_OVRD,
378                       0, PHY_C10_VDR_OVRD_TX1 | PHY_C10_VDR_OVRD_TX2,
379                       MB_WRITE_COMMITTED);
380
381         if (intel_is_c10phy(i915, phy))
382                 intel_cx0_rmw(i915, encoder->port, INTEL_CX0_BOTH_LANES, PHY_C10_VDR_CONTROL(1),
383                               0, C10_VDR_CTRL_UPDATE_CFG, MB_WRITE_COMMITTED);
384
385         intel_cx0_phy_transaction_end(encoder, wakeref);
386 }
387
388 /*
389  * Basic DP link rates with 38.4 MHz reference clock.
390  * Note: The tables below are with SSC. In non-ssc
391  * registers 0xC04 to 0xC08(pll[4] to pll[8]) will be
392  * programmed 0.
393  */
394
395 static const struct intel_c10pll_state mtl_c10_dp_rbr = {
396         .clock = 162000,
397         .tx = 0x10,
398         .cmn = 0x21,
399         .pll[0] = 0xB4,
400         .pll[1] = 0,
401         .pll[2] = 0x30,
402         .pll[3] = 0x1,
403         .pll[4] = 0x26,
404         .pll[5] = 0x0C,
405         .pll[6] = 0x98,
406         .pll[7] = 0x46,
407         .pll[8] = 0x1,
408         .pll[9] = 0x1,
409         .pll[10] = 0,
410         .pll[11] = 0,
411         .pll[12] = 0xC0,
412         .pll[13] = 0,
413         .pll[14] = 0,
414         .pll[15] = 0x2,
415         .pll[16] = 0x84,
416         .pll[17] = 0x4F,
417         .pll[18] = 0xE5,
418         .pll[19] = 0x23,
419 };
420
421 static const struct intel_c10pll_state mtl_c10_edp_r216 = {
422         .clock = 216000,
423         .tx = 0x10,
424         .cmn = 0x21,
425         .pll[0] = 0x4,
426         .pll[1] = 0,
427         .pll[2] = 0xA2,
428         .pll[3] = 0x1,
429         .pll[4] = 0x33,
430         .pll[5] = 0x10,
431         .pll[6] = 0x75,
432         .pll[7] = 0xB3,
433         .pll[8] = 0x1,
434         .pll[9] = 0x1,
435         .pll[10] = 0,
436         .pll[11] = 0,
437         .pll[12] = 0,
438         .pll[13] = 0,
439         .pll[14] = 0,
440         .pll[15] = 0x2,
441         .pll[16] = 0x85,
442         .pll[17] = 0x0F,
443         .pll[18] = 0xE6,
444         .pll[19] = 0x23,
445 };
446
447 static const struct intel_c10pll_state mtl_c10_edp_r243 = {
448         .clock = 243000,
449         .tx = 0x10,
450         .cmn = 0x21,
451         .pll[0] = 0x34,
452         .pll[1] = 0,
453         .pll[2] = 0xDA,
454         .pll[3] = 0x1,
455         .pll[4] = 0x39,
456         .pll[5] = 0x12,
457         .pll[6] = 0xE3,
458         .pll[7] = 0xE9,
459         .pll[8] = 0x1,
460         .pll[9] = 0x1,
461         .pll[10] = 0,
462         .pll[11] = 0,
463         .pll[12] = 0x20,
464         .pll[13] = 0,
465         .pll[14] = 0,
466         .pll[15] = 0x2,
467         .pll[16] = 0x85,
468         .pll[17] = 0x8F,
469         .pll[18] = 0xE6,
470         .pll[19] = 0x23,
471 };
472
473 static const struct intel_c10pll_state mtl_c10_dp_hbr1 = {
474         .clock = 270000,
475         .tx = 0x10,
476         .cmn = 0x21,
477         .pll[0] = 0xF4,
478         .pll[1] = 0,
479         .pll[2] = 0xF8,
480         .pll[3] = 0x0,
481         .pll[4] = 0x20,
482         .pll[5] = 0x0A,
483         .pll[6] = 0x29,
484         .pll[7] = 0x10,
485         .pll[8] = 0x1,   /* Verify */
486         .pll[9] = 0x1,
487         .pll[10] = 0,
488         .pll[11] = 0,
489         .pll[12] = 0xA0,
490         .pll[13] = 0,
491         .pll[14] = 0,
492         .pll[15] = 0x1,
493         .pll[16] = 0x84,
494         .pll[17] = 0x4F,
495         .pll[18] = 0xE5,
496         .pll[19] = 0x23,
497 };
498
499 static const struct intel_c10pll_state mtl_c10_edp_r324 = {
500         .clock = 324000,
501         .tx = 0x10,
502         .cmn = 0x21,
503         .pll[0] = 0xB4,
504         .pll[1] = 0,
505         .pll[2] = 0x30,
506         .pll[3] = 0x1,
507         .pll[4] = 0x26,
508         .pll[5] = 0x0C,
509         .pll[6] = 0x98,
510         .pll[7] = 0x46,
511         .pll[8] = 0x1,
512         .pll[9] = 0x1,
513         .pll[10] = 0,
514         .pll[11] = 0,
515         .pll[12] = 0xC0,
516         .pll[13] = 0,
517         .pll[14] = 0,
518         .pll[15] = 0x1,
519         .pll[16] = 0x85,
520         .pll[17] = 0x4F,
521         .pll[18] = 0xE6,
522         .pll[19] = 0x23,
523 };
524
525 static const struct intel_c10pll_state mtl_c10_edp_r432 = {
526         .clock = 432000,
527         .tx = 0x10,
528         .cmn = 0x21,
529         .pll[0] = 0x4,
530         .pll[1] = 0,
531         .pll[2] = 0xA2,
532         .pll[3] = 0x1,
533         .pll[4] = 0x33,
534         .pll[5] = 0x10,
535         .pll[6] = 0x75,
536         .pll[7] = 0xB3,
537         .pll[8] = 0x1,
538         .pll[9] = 0x1,
539         .pll[10] = 0,
540         .pll[11] = 0,
541         .pll[12] = 0,
542         .pll[13] = 0,
543         .pll[14] = 0,
544         .pll[15] = 0x1,
545         .pll[16] = 0x85,
546         .pll[17] = 0x0F,
547         .pll[18] = 0xE6,
548         .pll[19] = 0x23,
549 };
550
551 static const struct intel_c10pll_state mtl_c10_dp_hbr2 = {
552         .clock = 540000,
553         .tx = 0x10,
554         .cmn = 0x21,
555         .pll[0] = 0xF4,
556         .pll[1] = 0,
557         .pll[2] = 0xF8,
558         .pll[3] = 0,
559         .pll[4] = 0x20,
560         .pll[5] = 0x0A,
561         .pll[6] = 0x29,
562         .pll[7] = 0x10,
563         .pll[8] = 0x1,
564         .pll[9] = 0x1,
565         .pll[10] = 0,
566         .pll[11] = 0,
567         .pll[12] = 0xA0,
568         .pll[13] = 0,
569         .pll[14] = 0,
570         .pll[15] = 0,
571         .pll[16] = 0x84,
572         .pll[17] = 0x4F,
573         .pll[18] = 0xE5,
574         .pll[19] = 0x23,
575 };
576
577 static const struct intel_c10pll_state mtl_c10_edp_r675 = {
578         .clock = 675000,
579         .tx = 0x10,
580         .cmn = 0x21,
581         .pll[0] = 0xB4,
582         .pll[1] = 0,
583         .pll[2] = 0x3E,
584         .pll[3] = 0x1,
585         .pll[4] = 0xA8,
586         .pll[5] = 0x0C,
587         .pll[6] = 0x33,
588         .pll[7] = 0x54,
589         .pll[8] = 0x1,
590         .pll[9] = 0x1,
591         .pll[10] = 0,
592         .pll[11] = 0,
593         .pll[12] = 0xC8,
594         .pll[13] = 0,
595         .pll[14] = 0,
596         .pll[15] = 0,
597         .pll[16] = 0x85,
598         .pll[17] = 0x8F,
599         .pll[18] = 0xE6,
600         .pll[19] = 0x23,
601 };
602
603 static const struct intel_c10pll_state mtl_c10_dp_hbr3 = {
604         .clock = 810000,
605         .tx = 0x10,
606         .cmn = 0x21,
607         .pll[0] = 0x34,
608         .pll[1] = 0,
609         .pll[2] = 0x84,
610         .pll[3] = 0x1,
611         .pll[4] = 0x30,
612         .pll[5] = 0x0F,
613         .pll[6] = 0x3D,
614         .pll[7] = 0x98,
615         .pll[8] = 0x1,
616         .pll[9] = 0x1,
617         .pll[10] = 0,
618         .pll[11] = 0,
619         .pll[12] = 0xF0,
620         .pll[13] = 0,
621         .pll[14] = 0,
622         .pll[15] = 0,
623         .pll[16] = 0x84,
624         .pll[17] = 0x0F,
625         .pll[18] = 0xE5,
626         .pll[19] = 0x23,
627 };
628
629 static const struct intel_c10pll_state * const mtl_c10_dp_tables[] = {
630         &mtl_c10_dp_rbr,
631         &mtl_c10_dp_hbr1,
632         &mtl_c10_dp_hbr2,
633         &mtl_c10_dp_hbr3,
634         NULL,
635 };
636
637 static const struct intel_c10pll_state * const mtl_c10_edp_tables[] = {
638         &mtl_c10_dp_rbr,
639         &mtl_c10_edp_r216,
640         &mtl_c10_edp_r243,
641         &mtl_c10_dp_hbr1,
642         &mtl_c10_edp_r324,
643         &mtl_c10_edp_r432,
644         &mtl_c10_dp_hbr2,
645         &mtl_c10_edp_r675,
646         &mtl_c10_dp_hbr3,
647         NULL,
648 };
649
650 /*
651  * HDMI link rates with 38.4 MHz reference clock.
652  */
653
654 static const struct intel_c10pll_state mtl_c10_hdmi_25_2 = {
655         .clock = 25200,
656         .tx = 0x10,
657         .cmn = 0x1,
658         .pll[0] = 0x4,
659         .pll[1] = 0,
660         .pll[2] = 0xB2,
661         .pll[3] = 0,
662         .pll[4] = 0,
663         .pll[5] = 0,
664         .pll[6] = 0,
665         .pll[7] = 0,
666         .pll[8] = 0x20,
667         .pll[9] = 0x1,
668         .pll[10] = 0,
669         .pll[11] = 0,
670         .pll[12] = 0,
671         .pll[13] = 0,
672         .pll[14] = 0,
673         .pll[15] = 0xD,
674         .pll[16] = 0x6,
675         .pll[17] = 0x8F,
676         .pll[18] = 0x84,
677         .pll[19] = 0x23,
678 };
679
680 static const struct intel_c10pll_state mtl_c10_hdmi_27_0 = {
681         .clock = 27000,
682         .tx = 0x10,
683         .cmn = 0x1,
684         .pll[0] = 0x34,
685         .pll[1] = 0,
686         .pll[2] = 0xC0,
687         .pll[3] = 0,
688         .pll[4] = 0,
689         .pll[5] = 0,
690         .pll[6] = 0,
691         .pll[7] = 0,
692         .pll[8] = 0x20,
693         .pll[9] = 0x1,
694         .pll[10] = 0,
695         .pll[11] = 0,
696         .pll[12] = 0x80,
697         .pll[13] = 0,
698         .pll[14] = 0,
699         .pll[15] = 0xD,
700         .pll[16] = 0x6,
701         .pll[17] = 0xCF,
702         .pll[18] = 0x84,
703         .pll[19] = 0x23,
704 };
705
706 static const struct intel_c10pll_state mtl_c10_hdmi_74_25 = {
707         .clock = 74250,
708         .tx = 0x10,
709         .cmn = 0x1,
710         .pll[0] = 0xF4,
711         .pll[1] = 0,
712         .pll[2] = 0x7A,
713         .pll[3] = 0,
714         .pll[4] = 0,
715         .pll[5] = 0,
716         .pll[6] = 0,
717         .pll[7] = 0,
718         .pll[8] = 0x20,
719         .pll[9] = 0x1,
720         .pll[10] = 0,
721         .pll[11] = 0,
722         .pll[12] = 0x58,
723         .pll[13] = 0,
724         .pll[14] = 0,
725         .pll[15] = 0xB,
726         .pll[16] = 0x6,
727         .pll[17] = 0xF,
728         .pll[18] = 0x85,
729         .pll[19] = 0x23,
730 };
731
732 static const struct intel_c10pll_state mtl_c10_hdmi_148_5 = {
733         .clock = 148500,
734         .tx = 0x10,
735         .cmn = 0x1,
736         .pll[0] = 0xF4,
737         .pll[1] = 0,
738         .pll[2] = 0x7A,
739         .pll[3] = 0,
740         .pll[4] = 0,
741         .pll[5] = 0,
742         .pll[6] = 0,
743         .pll[7] = 0,
744         .pll[8] = 0x20,
745         .pll[9] = 0x1,
746         .pll[10] = 0,
747         .pll[11] = 0,
748         .pll[12] = 0x58,
749         .pll[13] = 0,
750         .pll[14] = 0,
751         .pll[15] = 0xA,
752         .pll[16] = 0x6,
753         .pll[17] = 0xF,
754         .pll[18] = 0x85,
755         .pll[19] = 0x23,
756 };
757
758 static const struct intel_c10pll_state mtl_c10_hdmi_594 = {
759         .clock = 594000,
760         .tx = 0x10,
761         .cmn = 0x1,
762         .pll[0] = 0xF4,
763         .pll[1] = 0,
764         .pll[2] = 0x7A,
765         .pll[3] = 0,
766         .pll[4] = 0,
767         .pll[5] = 0,
768         .pll[6] = 0,
769         .pll[7] = 0,
770         .pll[8] = 0x20,
771         .pll[9] = 0x1,
772         .pll[10] = 0,
773         .pll[11] = 0,
774         .pll[12] = 0x58,
775         .pll[13] = 0,
776         .pll[14] = 0,
777         .pll[15] = 0x8,
778         .pll[16] = 0x6,
779         .pll[17] = 0xF,
780         .pll[18] = 0x85,
781         .pll[19] = 0x23,
782 };
783
784 /* Precomputed C10 HDMI PLL tables */
785 static const struct intel_c10pll_state mtl_c10_hdmi_27027 = {
786         .clock = 27027,
787         .tx = 0x10,
788         .cmn = 0x1,
789         .pll[0] = 0x34, .pll[1] = 0x00, .pll[2] = 0xC0, .pll[3] = 0x00, .pll[4] = 0x00,
790         .pll[5] = 0x00, .pll[6] = 0x00, .pll[7] = 0x00, .pll[8] = 0x20, .pll[9] = 0xFF,
791         .pll[10] = 0xFF, .pll[11] = 0xCC, .pll[12] = 0x9C, .pll[13] = 0xCB, .pll[14] = 0xCC,
792         .pll[15] = 0x0D, .pll[16] = 0x08, .pll[17] = 0x8F, .pll[18] = 0x84, .pll[19] = 0x23,
793 };
794
795 static const struct intel_c10pll_state mtl_c10_hdmi_28320 = {
796         .clock = 28320,
797         .tx = 0x10,
798         .cmn = 0x1,
799         .pll[0] = 0x04, .pll[1] = 0x00, .pll[2] = 0xCC, .pll[3] = 0x00, .pll[4] = 0x00,
800         .pll[5] = 0x00, .pll[6] = 0x00, .pll[7] = 0x00, .pll[8] = 0x20, .pll[9] = 0xFF,
801         .pll[10] = 0xFF, .pll[11] = 0x00, .pll[12] = 0x00, .pll[13] = 0x00, .pll[14] = 0x00,
802         .pll[15] = 0x0D, .pll[16] = 0x08, .pll[17] = 0x8F, .pll[18] = 0x84, .pll[19] = 0x23,
803 };
804
805 static const struct intel_c10pll_state mtl_c10_hdmi_30240 = {
806         .clock = 30240,
807         .tx = 0x10,
808         .cmn = 0x1,
809         .pll[0] = 0x04, .pll[1] = 0x00, .pll[2] = 0xDC, .pll[3] = 0x00, .pll[4] = 0x00,
810         .pll[5] = 0x00, .pll[6] = 0x00, .pll[7] = 0x00, .pll[8] = 0x20, .pll[9] = 0xFF,
811         .pll[10] = 0xFF, .pll[11] = 0x00, .pll[12] = 0x00, .pll[13] = 0x00, .pll[14] = 0x00,
812         .pll[15] = 0x0D, .pll[16] = 0x08, .pll[17] = 0xCF, .pll[18] = 0x84, .pll[19] = 0x23,
813 };
814
815 static const struct intel_c10pll_state mtl_c10_hdmi_31500 = {
816         .clock = 31500,
817         .tx = 0x10,
818         .cmn = 0x1,
819         .pll[0] = 0xF4, .pll[1] = 0x00, .pll[2] = 0x62, .pll[3] = 0x00, .pll[4] = 0x00,
820         .pll[5] = 0x00, .pll[6] = 0x00, .pll[7] = 0x00, .pll[8] = 0x20, .pll[9] = 0xFF,
821         .pll[10] = 0xFF, .pll[11] = 0x00, .pll[12] = 0xA0, .pll[13] = 0x00, .pll[14] = 0x00,
822         .pll[15] = 0x0C, .pll[16] = 0x09, .pll[17] = 0x8F, .pll[18] = 0x84, .pll[19] = 0x23,
823 };
824
825 static const struct intel_c10pll_state mtl_c10_hdmi_36000 = {
826         .clock = 36000,
827         .tx = 0x10,
828         .cmn = 0x1,
829         .pll[0] = 0xC4, .pll[1] = 0x00, .pll[2] = 0x76, .pll[3] = 0x00, .pll[4] = 0x00,
830         .pll[5] = 0x00, .pll[6] = 0x00, .pll[7] = 0x00, .pll[8] = 0x20, .pll[9] = 0xFF,
831         .pll[10] = 0xFF, .pll[11] = 0x00, .pll[12] = 0x00, .pll[13] = 0x00, .pll[14] = 0x00,
832         .pll[15] = 0x0C, .pll[16] = 0x08, .pll[17] = 0x8F, .pll[18] = 0x84, .pll[19] = 0x23,
833 };
834
835 static const struct intel_c10pll_state mtl_c10_hdmi_40000 = {
836         .clock = 40000,
837         .tx = 0x10,
838         .cmn = 0x1,
839         .pll[0] = 0xB4, .pll[1] = 0x00, .pll[2] = 0x86, .pll[3] = 0x00, .pll[4] = 0x00,
840         .pll[5] = 0x00, .pll[6] = 0x00, .pll[7] = 0x00, .pll[8] = 0x20, .pll[9] = 0xFF,
841         .pll[10] = 0xFF, .pll[11] = 0x55, .pll[12] = 0x55, .pll[13] = 0x55, .pll[14] = 0x55,
842         .pll[15] = 0x0C, .pll[16] = 0x08, .pll[17] = 0x8F, .pll[18] = 0x84, .pll[19] = 0x23,
843 };
844
845 static const struct intel_c10pll_state mtl_c10_hdmi_49500 = {
846         .clock = 49500,
847         .tx = 0x10,
848         .cmn = 0x1,
849         .pll[0] = 0x74, .pll[1] = 0x00, .pll[2] = 0xAE, .pll[3] = 0x00, .pll[4] = 0x00,
850         .pll[5] = 0x00, .pll[6] = 0x00, .pll[7] = 0x00, .pll[8] = 0x20, .pll[9] = 0xFF,
851         .pll[10] = 0xFF, .pll[11] = 0x00, .pll[12] = 0x20, .pll[13] = 0x00, .pll[14] = 0x00,
852         .pll[15] = 0x0C, .pll[16] = 0x08, .pll[17] = 0xCF, .pll[18] = 0x84, .pll[19] = 0x23,
853 };
854
855 static const struct intel_c10pll_state mtl_c10_hdmi_50000 = {
856         .clock = 50000,
857         .tx = 0x10,
858         .cmn = 0x1,
859         .pll[0] = 0x74, .pll[1] = 0x00, .pll[2] = 0xB0, .pll[3] = 0x00, .pll[4] = 0x00,
860         .pll[5] = 0x00, .pll[6] = 0x00, .pll[7] = 0x00, .pll[8] = 0x20, .pll[9] = 0xFF,
861         .pll[10] = 0xFF, .pll[11] = 0xAA, .pll[12] = 0x2A, .pll[13] = 0xA9, .pll[14] = 0xAA,
862         .pll[15] = 0x0C, .pll[16] = 0x08, .pll[17] = 0xCF, .pll[18] = 0x84, .pll[19] = 0x23,
863 };
864
865 static const struct intel_c10pll_state mtl_c10_hdmi_57284 = {
866         .clock = 57284,
867         .tx = 0x10,
868         .cmn = 0x1,
869         .pll[0] = 0x34, .pll[1] = 0x00, .pll[2] = 0xCE, .pll[3] = 0x00, .pll[4] = 0x00,
870         .pll[5] = 0x00, .pll[6] = 0x00, .pll[7] = 0x00, .pll[8] = 0x20, .pll[9] = 0xFF,
871         .pll[10] = 0xFF, .pll[11] = 0x77, .pll[12] = 0x57, .pll[13] = 0x77, .pll[14] = 0x77,
872         .pll[15] = 0x0C, .pll[16] = 0x08, .pll[17] = 0x8F, .pll[18] = 0x84, .pll[19] = 0x23,
873 };
874
875 static const struct intel_c10pll_state mtl_c10_hdmi_58000 = {
876         .clock = 58000,
877         .tx = 0x10,
878         .cmn = 0x1,
879         .pll[0] = 0x34, .pll[1] = 0x00, .pll[2] = 0xD0, .pll[3] = 0x00, .pll[4] = 0x00,
880         .pll[5] = 0x00, .pll[6] = 0x00, .pll[7] = 0x00, .pll[8] = 0x20, .pll[9] = 0xFF,
881         .pll[10] = 0xFF, .pll[11] = 0x55, .pll[12] = 0xD5, .pll[13] = 0x55, .pll[14] = 0x55,
882         .pll[15] = 0x0C, .pll[16] = 0x08, .pll[17] = 0xCF, .pll[18] = 0x84, .pll[19] = 0x23,
883 };
884
885 static const struct intel_c10pll_state mtl_c10_hdmi_65000 = {
886         .clock = 65000,
887         .tx = 0x10,
888         .cmn = 0x1,
889         .pll[0] = 0xF4, .pll[1] = 0x00, .pll[2] = 0x66, .pll[3] = 0x00, .pll[4] = 0x00,
890         .pll[5] = 0x00, .pll[6] = 0x00, .pll[7] = 0x00, .pll[8] = 0x20, .pll[9] = 0xFF,
891         .pll[10] = 0xFF, .pll[11] = 0x55, .pll[12] = 0xB5, .pll[13] = 0x55, .pll[14] = 0x55,
892         .pll[15] = 0x0B, .pll[16] = 0x09, .pll[17] = 0xCF, .pll[18] = 0x84, .pll[19] = 0x23,
893 };
894
895 static const struct intel_c10pll_state mtl_c10_hdmi_71000 = {
896         .clock = 71000,
897         .tx = 0x10,
898         .cmn = 0x1,
899         .pll[0] = 0xF4, .pll[1] = 0x00, .pll[2] = 0x72, .pll[3] = 0x00, .pll[4] = 0x00,
900         .pll[5] = 0x00, .pll[6] = 0x00, .pll[7] = 0x00, .pll[8] = 0x20, .pll[9] = 0xFF,
901         .pll[10] = 0xFF, .pll[11] = 0x55, .pll[12] = 0xF5, .pll[13] = 0x55, .pll[14] = 0x55,
902         .pll[15] = 0x0B, .pll[16] = 0x08, .pll[17] = 0x8F, .pll[18] = 0x84, .pll[19] = 0x23,
903 };
904
905 static const struct intel_c10pll_state mtl_c10_hdmi_74176 = {
906         .clock = 74176,
907         .tx = 0x10,
908         .cmn = 0x1,
909         .pll[0] = 0xF4, .pll[1] = 0x00, .pll[2] = 0x7A, .pll[3] = 0x00, .pll[4] = 0x00,
910         .pll[5] = 0x00, .pll[6] = 0x00, .pll[7] = 0x00, .pll[8] = 0x20, .pll[9] = 0xFF,
911         .pll[10] = 0xFF, .pll[11] = 0x44, .pll[12] = 0x44, .pll[13] = 0x44, .pll[14] = 0x44,
912         .pll[15] = 0x0B, .pll[16] = 0x08, .pll[17] = 0x8F, .pll[18] = 0x84, .pll[19] = 0x23,
913 };
914
915 static const struct intel_c10pll_state mtl_c10_hdmi_75000 = {
916         .clock = 75000,
917         .tx = 0x10,
918         .cmn = 0x1,
919         .pll[0] = 0xF4, .pll[1] = 0x00, .pll[2] = 0x7C, .pll[3] = 0x00, .pll[4] = 0x00,
920         .pll[5] = 0x00, .pll[6] = 0x00, .pll[7] = 0x00, .pll[8] = 0x20, .pll[9] = 0xFF,
921         .pll[10] = 0xFF, .pll[11] = 0x00, .pll[12] = 0x20, .pll[13] = 0x00, .pll[14] = 0x00,
922         .pll[15] = 0x0B, .pll[16] = 0x08, .pll[17] = 0xCF, .pll[18] = 0x84, .pll[19] = 0x23,
923 };
924
925 static const struct intel_c10pll_state mtl_c10_hdmi_78750 = {
926         .clock = 78750,
927         .tx = 0x10,
928         .cmn = 0x1,
929         .pll[0] = 0xB4, .pll[1] = 0x00, .pll[2] = 0x84, .pll[3] = 0x00, .pll[4] = 0x00,
930         .pll[5] = 0x00, .pll[6] = 0x00, .pll[7] = 0x00, .pll[8] = 0x20, .pll[9] = 0xFF,
931         .pll[10] = 0xFF, .pll[11] = 0x00, .pll[12] = 0x08, .pll[13] = 0x00, .pll[14] = 0x00,
932         .pll[15] = 0x0B, .pll[16] = 0x08, .pll[17] = 0x8F, .pll[18] = 0x84, .pll[19] = 0x23,
933 };
934
935 static const struct intel_c10pll_state mtl_c10_hdmi_85500 = {
936         .clock = 85500,
937         .tx = 0x10,
938         .cmn = 0x1,
939         .pll[0] = 0xB4, .pll[1] = 0x00, .pll[2] = 0x92, .pll[3] = 0x00, .pll[4] = 0x00,
940         .pll[5] = 0x00, .pll[6] = 0x00, .pll[7] = 0x00, .pll[8] = 0x20, .pll[9] = 0xFF,
941         .pll[10] = 0xFF, .pll[11] = 0x00, .pll[12] = 0x10, .pll[13] = 0x00, .pll[14] = 0x00,
942         .pll[15] = 0x0B, .pll[16] = 0x08, .pll[17] = 0xCF, .pll[18] = 0x84, .pll[19] = 0x23,
943 };
944
945 static const struct intel_c10pll_state mtl_c10_hdmi_88750 = {
946         .clock = 88750,
947         .tx = 0x10,
948         .cmn = 0x1,
949         .pll[0] = 0x74, .pll[1] = 0x00, .pll[2] = 0x98, .pll[3] = 0x00, .pll[4] = 0x00,
950         .pll[5] = 0x00, .pll[6] = 0x00, .pll[7] = 0x00, .pll[8] = 0x20, .pll[9] = 0xFF,
951         .pll[10] = 0xFF, .pll[11] = 0xAA, .pll[12] = 0x72, .pll[13] = 0xA9, .pll[14] = 0xAA,
952         .pll[15] = 0x0B, .pll[16] = 0x09, .pll[17] = 0xCF, .pll[18] = 0x84, .pll[19] = 0x23,
953 };
954
955 static const struct intel_c10pll_state mtl_c10_hdmi_106500 = {
956         .clock = 106500,
957         .tx = 0x10,
958         .cmn = 0x1,
959         .pll[0] = 0x34, .pll[1] = 0x00, .pll[2] = 0xBC, .pll[3] = 0x00, .pll[4] = 0x00,
960         .pll[5] = 0x00, .pll[6] = 0x00, .pll[7] = 0x00, .pll[8] = 0x20, .pll[9] = 0xFF,
961         .pll[10] = 0xFF, .pll[11] = 0x00, .pll[12] = 0xF0, .pll[13] = 0x00, .pll[14] = 0x00,
962         .pll[15] = 0x0B, .pll[16] = 0x08, .pll[17] = 0x8F, .pll[18] = 0x84, .pll[19] = 0x23,
963 };
964
965 static const struct intel_c10pll_state mtl_c10_hdmi_108000 = {
966         .clock = 108000,
967         .tx = 0x10,
968         .cmn = 0x1,
969         .pll[0] = 0x34, .pll[1] = 0x00, .pll[2] = 0xC0, .pll[3] = 0x00, .pll[4] = 0x00,
970         .pll[5] = 0x00, .pll[6] = 0x00, .pll[7] = 0x00, .pll[8] = 0x20, .pll[9] = 0xFF,
971         .pll[10] = 0xFF, .pll[11] = 0x00, .pll[12] = 0x80, .pll[13] = 0x00, .pll[14] = 0x00,
972         .pll[15] = 0x0B, .pll[16] = 0x08, .pll[17] = 0x8F, .pll[18] = 0x84, .pll[19] = 0x23,
973 };
974
975 static const struct intel_c10pll_state mtl_c10_hdmi_115500 = {
976         .clock = 115500,
977         .tx = 0x10,
978         .cmn = 0x1,
979         .pll[0] = 0x34, .pll[1] = 0x00, .pll[2] = 0xD0, .pll[3] = 0x00, .pll[4] = 0x00,
980         .pll[5] = 0x00, .pll[6] = 0x00, .pll[7] = 0x00, .pll[8] = 0x20, .pll[9] = 0xFF,
981         .pll[10] = 0xFF, .pll[11] = 0x00, .pll[12] = 0x50, .pll[13] = 0x00, .pll[14] = 0x00,
982         .pll[15] = 0x0B, .pll[16] = 0x08, .pll[17] = 0xCF, .pll[18] = 0x84, .pll[19] = 0x23,
983 };
984
985 static const struct intel_c10pll_state mtl_c10_hdmi_119000 = {
986         .clock = 119000,
987         .tx = 0x10,
988         .cmn = 0x1,
989         .pll[0] = 0x34, .pll[1] = 0x00, .pll[2] = 0xD6, .pll[3] = 0x00, .pll[4] = 0x00,
990         .pll[5] = 0x00, .pll[6] = 0x00, .pll[7] = 0x00, .pll[8] = 0x20, .pll[9] = 0xFF,
991         .pll[10] = 0xFF, .pll[11] = 0x55, .pll[12] = 0xF5, .pll[13] = 0x55, .pll[14] = 0x55,
992         .pll[15] = 0x0B, .pll[16] = 0x08, .pll[17] = 0xCF, .pll[18] = 0x84, .pll[19] = 0x23,
993 };
994
995 static const struct intel_c10pll_state mtl_c10_hdmi_135000 = {
996         .clock = 135000,
997         .tx = 0x10,
998         .cmn = 0x1,
999         .pll[0] = 0xF4, .pll[1] = 0x00, .pll[2] = 0x6C, .pll[3] = 0x00, .pll[4] = 0x00,
1000         .pll[5] = 0x00, .pll[6] = 0x00, .pll[7] = 0x00, .pll[8] = 0x20, .pll[9] = 0xFF,
1001         .pll[10] = 0xFF, .pll[11] = 0x00, .pll[12] = 0x50, .pll[13] = 0x00, .pll[14] = 0x00,
1002         .pll[15] = 0x0A, .pll[16] = 0x09, .pll[17] = 0xCF, .pll[18] = 0x84, .pll[19] = 0x23,
1003 };
1004
1005 static const struct intel_c10pll_state mtl_c10_hdmi_138500 = {
1006         .clock = 138500,
1007         .tx = 0x10,
1008         .cmn = 0x1,
1009         .pll[0] = 0xF4, .pll[1] = 0x00, .pll[2] = 0x70, .pll[3] = 0x00, .pll[4] = 0x00,
1010         .pll[5] = 0x00, .pll[6] = 0x00, .pll[7] = 0x00, .pll[8] = 0x20, .pll[9] = 0xFF,
1011         .pll[10] = 0xFF, .pll[11] = 0xAA, .pll[12] = 0x22, .pll[13] = 0xA9, .pll[14] = 0xAA,
1012         .pll[15] = 0x0A, .pll[16] = 0x08, .pll[17] = 0x8F, .pll[18] = 0x84, .pll[19] = 0x23,
1013 };
1014
1015 static const struct intel_c10pll_state mtl_c10_hdmi_147160 = {
1016         .clock = 147160,
1017         .tx = 0x10,
1018         .cmn = 0x1,
1019         .pll[0] = 0xF4, .pll[1] = 0x00, .pll[2] = 0x78, .pll[3] = 0x00, .pll[4] = 0x00,
1020         .pll[5] = 0x00, .pll[6] = 0x00, .pll[7] = 0x00, .pll[8] = 0x20, .pll[9] = 0xFF,
1021         .pll[10] = 0xFF, .pll[11] = 0x55, .pll[12] = 0xA5, .pll[13] = 0x55, .pll[14] = 0x55,
1022         .pll[15] = 0x0A, .pll[16] = 0x08, .pll[17] = 0x8F, .pll[18] = 0x84, .pll[19] = 0x23,
1023 };
1024
1025 static const struct intel_c10pll_state mtl_c10_hdmi_148352 = {
1026         .clock = 148352,
1027         .tx = 0x10,
1028         .cmn = 0x1,
1029         .pll[0] = 0xF4, .pll[1] = 0x00, .pll[2] = 0x7A, .pll[3] = 0x00, .pll[4] = 0x00,
1030         .pll[5] = 0x00, .pll[6] = 0x00, .pll[7] = 0x00, .pll[8] = 0x20, .pll[9] = 0xFF,
1031         .pll[10] = 0xFF, .pll[11] = 0x44, .pll[12] = 0x44, .pll[13] = 0x44, .pll[14] = 0x44,
1032         .pll[15] = 0x0A, .pll[16] = 0x08, .pll[17] = 0x8F, .pll[18] = 0x84, .pll[19] = 0x23,
1033 };
1034
1035 static const struct intel_c10pll_state mtl_c10_hdmi_154000 = {
1036         .clock = 154000,
1037         .tx = 0x10,
1038         .cmn = 0x1,
1039         .pll[0] = 0xB4, .pll[1] = 0x00, .pll[2] = 0x80, .pll[3] = 0x00, .pll[4] = 0x00,
1040         .pll[5] = 0x00, .pll[6] = 0x00, .pll[7] = 0x00, .pll[8] = 0x20, .pll[9] = 0xFF,
1041         .pll[10] = 0xFF, .pll[11] = 0x55, .pll[12] = 0x35, .pll[13] = 0x55, .pll[14] = 0x55,
1042         .pll[15] = 0x0A, .pll[16] = 0x08, .pll[17] = 0x8F, .pll[18] = 0x84, .pll[19] = 0x23,
1043 };
1044
1045 static const struct intel_c10pll_state mtl_c10_hdmi_162000 = {
1046         .clock = 162000,
1047         .tx = 0x10,
1048         .cmn = 0x1,
1049         .pll[0] = 0xB4, .pll[1] = 0x00, .pll[2] = 0x88, .pll[3] = 0x00, .pll[4] = 0x00,
1050         .pll[5] = 0x00, .pll[6] = 0x00, .pll[7] = 0x00, .pll[8] = 0x20, .pll[9] = 0xFF,
1051         .pll[10] = 0xFF, .pll[11] = 0x00, .pll[12] = 0x60, .pll[13] = 0x00, .pll[14] = 0x00,
1052         .pll[15] = 0x0A, .pll[16] = 0x08, .pll[17] = 0x8F, .pll[18] = 0x84, .pll[19] = 0x23,
1053 };
1054
1055 static const struct intel_c10pll_state mtl_c10_hdmi_167000 = {
1056         .clock = 167000,
1057         .tx = 0x10,
1058         .cmn = 0x1,
1059         .pll[0] = 0xB4, .pll[1] = 0x00, .pll[2] = 0x8C, .pll[3] = 0x00, .pll[4] = 0x00,
1060         .pll[5] = 0x00, .pll[6] = 0x00, .pll[7] = 0x00, .pll[8] = 0x20, .pll[9] = 0xFF,
1061         .pll[10] = 0xFF, .pll[11] = 0xAA, .pll[12] = 0xFA, .pll[13] = 0xA9, .pll[14] = 0xAA,
1062         .pll[15] = 0x0A, .pll[16] = 0x08, .pll[17] = 0x8F, .pll[18] = 0x84, .pll[19] = 0x23,
1063 };
1064
1065 static const struct intel_c10pll_state mtl_c10_hdmi_197802 = {
1066         .clock = 197802,
1067         .tx = 0x10,
1068         .cmn = 0x1,
1069         .pll[0] = 0x74, .pll[1] = 0x00, .pll[2] = 0xAE, .pll[3] = 0x00, .pll[4] = 0x00,
1070         .pll[5] = 0x00, .pll[6] = 0x00, .pll[7] = 0x00, .pll[8] = 0x20, .pll[9] = 0xFF,
1071         .pll[10] = 0xFF, .pll[11] = 0x99, .pll[12] = 0x05, .pll[13] = 0x98, .pll[14] = 0x99,
1072         .pll[15] = 0x0A, .pll[16] = 0x08, .pll[17] = 0xCF, .pll[18] = 0x84, .pll[19] = 0x23,
1073 };
1074
1075 static const struct intel_c10pll_state mtl_c10_hdmi_198000 = {
1076         .clock = 198000,
1077         .tx = 0x10,
1078         .cmn = 0x1,
1079         .pll[0] = 0x74, .pll[1] = 0x00, .pll[2] = 0xAE, .pll[3] = 0x00, .pll[4] = 0x00,
1080         .pll[5] = 0x00, .pll[6] = 0x00, .pll[7] = 0x00, .pll[8] = 0x20, .pll[9] = 0xFF,
1081         .pll[10] = 0xFF, .pll[11] = 0x00, .pll[12] = 0x20, .pll[13] = 0x00, .pll[14] = 0x00,
1082         .pll[15] = 0x0A, .pll[16] = 0x08, .pll[17] = 0xCF, .pll[18] = 0x84, .pll[19] = 0x23,
1083 };
1084
1085 static const struct intel_c10pll_state mtl_c10_hdmi_209800 = {
1086         .clock = 209800,
1087         .tx = 0x10,
1088         .cmn = 0x1,
1089         .pll[0] = 0x34, .pll[1] = 0x00, .pll[2] = 0xBA, .pll[3] = 0x00, .pll[4] = 0x00,
1090         .pll[5] = 0x00, .pll[6] = 0x00, .pll[7] = 0x00, .pll[8] = 0x20, .pll[9] = 0xFF,
1091         .pll[10] = 0xFF, .pll[11] = 0x55, .pll[12] = 0x45, .pll[13] = 0x55, .pll[14] = 0x55,
1092         .pll[15] = 0x0A, .pll[16] = 0x08, .pll[17] = 0x8F, .pll[18] = 0x84, .pll[19] = 0x23,
1093 };
1094
1095 static const struct intel_c10pll_state mtl_c10_hdmi_241500 = {
1096         .clock = 241500,
1097         .tx = 0x10,
1098         .cmn = 0x1,
1099         .pll[0] = 0x34, .pll[1] = 0x00, .pll[2] = 0xDA, .pll[3] = 0x00, .pll[4] = 0x00,
1100         .pll[5] = 0x00, .pll[6] = 0x00, .pll[7] = 0x00, .pll[8] = 0x20, .pll[9] = 0xFF,
1101         .pll[10] = 0xFF, .pll[11] = 0x00, .pll[12] = 0xC8, .pll[13] = 0x00, .pll[14] = 0x00,
1102         .pll[15] = 0x0A, .pll[16] = 0x08, .pll[17] = 0xCF, .pll[18] = 0x84, .pll[19] = 0x23,
1103 };
1104
1105 static const struct intel_c10pll_state mtl_c10_hdmi_262750 = {
1106         .clock = 262750,
1107         .tx = 0x10,
1108         .cmn = 0x1,
1109         .pll[0] = 0xF4, .pll[1] = 0x00, .pll[2] = 0x68, .pll[3] = 0x00, .pll[4] = 0x00,
1110         .pll[5] = 0x00, .pll[6] = 0x00, .pll[7] = 0x00, .pll[8] = 0x20, .pll[9] = 0xFF,
1111         .pll[10] = 0xFF, .pll[11] = 0xAA, .pll[12] = 0x6C, .pll[13] = 0xA9, .pll[14] = 0xAA,
1112         .pll[15] = 0x09, .pll[16] = 0x09, .pll[17] = 0xCF, .pll[18] = 0x84, .pll[19] = 0x23,
1113 };
1114
1115 static const struct intel_c10pll_state mtl_c10_hdmi_268500 = {
1116         .clock = 268500,
1117         .tx = 0x10,
1118         .cmn = 0x1,
1119         .pll[0] = 0xF4, .pll[1] = 0x00, .pll[2] = 0x6A, .pll[3] = 0x00, .pll[4] = 0x00,
1120         .pll[5] = 0x00, .pll[6] = 0x00, .pll[7] = 0x00, .pll[8] = 0x20, .pll[9] = 0xFF,
1121         .pll[10] = 0xFF, .pll[11] = 0x00, .pll[12] = 0xEC, .pll[13] = 0x00, .pll[14] = 0x00,
1122         .pll[15] = 0x09, .pll[16] = 0x09, .pll[17] = 0xCF, .pll[18] = 0x84, .pll[19] = 0x23,
1123 };
1124
1125 static const struct intel_c10pll_state mtl_c10_hdmi_296703 = {
1126         .clock = 296703,
1127         .tx = 0x10,
1128         .cmn = 0x1,
1129         .pll[0] = 0xF4, .pll[1] = 0x00, .pll[2] = 0x7A, .pll[3] = 0x00, .pll[4] = 0x00,
1130         .pll[5] = 0x00, .pll[6] = 0x00, .pll[7] = 0x00, .pll[8] = 0x20, .pll[9] = 0xFF,
1131         .pll[10] = 0xFF, .pll[11] = 0x33, .pll[12] = 0x44, .pll[13] = 0x33, .pll[14] = 0x33,
1132         .pll[15] = 0x09, .pll[16] = 0x08, .pll[17] = 0x8F, .pll[18] = 0x84, .pll[19] = 0x23,
1133 };
1134
1135 static const struct intel_c10pll_state mtl_c10_hdmi_297000 = {
1136         .clock = 297000,
1137         .tx = 0x10,
1138         .cmn = 0x1,
1139         .pll[0] = 0xF4, .pll[1] = 0x00, .pll[2] = 0x7A, .pll[3] = 0x00, .pll[4] = 0x00,
1140         .pll[5] = 0x00, .pll[6] = 0x00, .pll[7] = 0x00, .pll[8] = 0x20, .pll[9] = 0xFF,
1141         .pll[10] = 0xFF, .pll[11] = 0x00, .pll[12] = 0x58, .pll[13] = 0x00, .pll[14] = 0x00,
1142         .pll[15] = 0x09, .pll[16] = 0x08, .pll[17] = 0x8F, .pll[18] = 0x84, .pll[19] = 0x23,
1143 };
1144
1145 static const struct intel_c10pll_state mtl_c10_hdmi_319750 = {
1146         .clock = 319750,
1147         .tx = 0x10,
1148         .cmn = 0x1,
1149         .pll[0] = 0xB4, .pll[1] = 0x00, .pll[2] = 0x86, .pll[3] = 0x00, .pll[4] = 0x00,
1150         .pll[5] = 0x00, .pll[6] = 0x00, .pll[7] = 0x00, .pll[8] = 0x20, .pll[9] = 0xFF,
1151         .pll[10] = 0xFF, .pll[11] = 0xAA, .pll[12] = 0x44, .pll[13] = 0xA9, .pll[14] = 0xAA,
1152         .pll[15] = 0x09, .pll[16] = 0x08, .pll[17] = 0x8F, .pll[18] = 0x84, .pll[19] = 0x23,
1153 };
1154
1155 static const struct intel_c10pll_state mtl_c10_hdmi_497750 = {
1156         .clock = 497750,
1157         .tx = 0x10,
1158         .cmn = 0x1,
1159         .pll[0] = 0x34, .pll[1] = 0x00, .pll[2] = 0xE2, .pll[3] = 0x00, .pll[4] = 0x00,
1160         .pll[5] = 0x00, .pll[6] = 0x00, .pll[7] = 0x00, .pll[8] = 0x20, .pll[9] = 0xFF,
1161         .pll[10] = 0xFF, .pll[11] = 0x55, .pll[12] = 0x9F, .pll[13] = 0x55, .pll[14] = 0x55,
1162         .pll[15] = 0x09, .pll[16] = 0x08, .pll[17] = 0xCF, .pll[18] = 0x84, .pll[19] = 0x23,
1163 };
1164
1165 static const struct intel_c10pll_state mtl_c10_hdmi_592000 = {
1166         .clock = 592000,
1167         .tx = 0x10,
1168         .cmn = 0x1,
1169         .pll[0] = 0xF4, .pll[1] = 0x00, .pll[2] = 0x7A, .pll[3] = 0x00, .pll[4] = 0x00,
1170         .pll[5] = 0x00, .pll[6] = 0x00, .pll[7] = 0x00, .pll[8] = 0x20, .pll[9] = 0xFF,
1171         .pll[10] = 0xFF, .pll[11] = 0x55, .pll[12] = 0x15, .pll[13] = 0x55, .pll[14] = 0x55,
1172         .pll[15] = 0x08, .pll[16] = 0x08, .pll[17] = 0x8F, .pll[18] = 0x84, .pll[19] = 0x23,
1173 };
1174
1175 static const struct intel_c10pll_state mtl_c10_hdmi_593407 = {
1176         .clock = 593407,
1177         .tx = 0x10,
1178         .cmn = 0x1,
1179         .pll[0] = 0xF4, .pll[1] = 0x00, .pll[2] = 0x7A, .pll[3] = 0x00, .pll[4] = 0x00,
1180         .pll[5] = 0x00, .pll[6] = 0x00, .pll[7] = 0x00, .pll[8] = 0x20, .pll[9] = 0xFF,
1181         .pll[10] = 0xFF, .pll[11] = 0x3B, .pll[12] = 0x44, .pll[13] = 0xBA, .pll[14] = 0xBB,
1182         .pll[15] = 0x08, .pll[16] = 0x08, .pll[17] = 0x8F, .pll[18] = 0x84, .pll[19] = 0x23,
1183 };
1184
1185 static const struct intel_c10pll_state * const mtl_c10_hdmi_tables[] = {
1186         &mtl_c10_hdmi_25_2, /* Consolidated Table */
1187         &mtl_c10_hdmi_27_0, /* Consolidated Table */
1188         &mtl_c10_hdmi_27027,
1189         &mtl_c10_hdmi_28320,
1190         &mtl_c10_hdmi_30240,
1191         &mtl_c10_hdmi_31500,
1192         &mtl_c10_hdmi_36000,
1193         &mtl_c10_hdmi_40000,
1194         &mtl_c10_hdmi_49500,
1195         &mtl_c10_hdmi_50000,
1196         &mtl_c10_hdmi_57284,
1197         &mtl_c10_hdmi_58000,
1198         &mtl_c10_hdmi_65000,
1199         &mtl_c10_hdmi_71000,
1200         &mtl_c10_hdmi_74176,
1201         &mtl_c10_hdmi_74_25, /* Consolidated Table */
1202         &mtl_c10_hdmi_75000,
1203         &mtl_c10_hdmi_78750,
1204         &mtl_c10_hdmi_85500,
1205         &mtl_c10_hdmi_88750,
1206         &mtl_c10_hdmi_106500,
1207         &mtl_c10_hdmi_108000,
1208         &mtl_c10_hdmi_115500,
1209         &mtl_c10_hdmi_119000,
1210         &mtl_c10_hdmi_135000,
1211         &mtl_c10_hdmi_138500,
1212         &mtl_c10_hdmi_147160,
1213         &mtl_c10_hdmi_148352,
1214         &mtl_c10_hdmi_148_5, /* Consolidated Table */
1215         &mtl_c10_hdmi_154000,
1216         &mtl_c10_hdmi_162000,
1217         &mtl_c10_hdmi_167000,
1218         &mtl_c10_hdmi_197802,
1219         &mtl_c10_hdmi_198000,
1220         &mtl_c10_hdmi_209800,
1221         &mtl_c10_hdmi_241500,
1222         &mtl_c10_hdmi_262750,
1223         &mtl_c10_hdmi_268500,
1224         &mtl_c10_hdmi_296703,
1225         &mtl_c10_hdmi_297000,
1226         &mtl_c10_hdmi_319750,
1227         &mtl_c10_hdmi_497750,
1228         &mtl_c10_hdmi_592000,
1229         &mtl_c10_hdmi_593407,
1230         &mtl_c10_hdmi_594, /* Consolidated Table */
1231         NULL,
1232 };
1233
1234 int intel_c10_phy_check_hdmi_link_rate(int clock)
1235 {
1236         const struct intel_c10pll_state * const *tables = mtl_c10_hdmi_tables;
1237         int i;
1238
1239         for (i = 0; tables[i]; i++) {
1240                 if (clock == tables[i]->clock)
1241                         return MODE_OK;
1242         }
1243
1244         return MODE_CLOCK_RANGE;
1245 }
1246
1247 static const struct intel_c10pll_state * const *
1248 intel_c10pll_tables_get(struct intel_crtc_state *crtc_state,
1249                         struct intel_encoder *encoder)
1250 {
1251         if (intel_crtc_has_dp_encoder(crtc_state)) {
1252                 if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_EDP))
1253                         return mtl_c10_edp_tables;
1254                 else
1255                         return mtl_c10_dp_tables;
1256         } else if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_HDMI)) {
1257                 return mtl_c10_hdmi_tables;
1258         }
1259
1260         MISSING_CASE(encoder->type);
1261         return NULL;
1262 }
1263
1264 static void intel_c10pll_update_pll(struct intel_crtc_state *crtc_state,
1265                                     struct intel_encoder *encoder)
1266 {
1267         struct drm_i915_private *i915 = to_i915(encoder->base.dev);
1268         struct intel_cx0pll_state *pll_state = &crtc_state->cx0pll_state;
1269         int i;
1270
1271         if (intel_crtc_has_dp_encoder(crtc_state)) {
1272                 if (intel_panel_use_ssc(i915)) {
1273                         struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
1274
1275                         pll_state->ssc_enabled =
1276                                 (intel_dp->dpcd[DP_MAX_DOWNSPREAD] & DP_MAX_DOWNSPREAD_0_5);
1277                 }
1278         }
1279
1280         if (pll_state->ssc_enabled)
1281                 return;
1282
1283         drm_WARN_ON(&i915->drm, ARRAY_SIZE(pll_state->c10.pll) < 9);
1284         for (i = 4; i < 9; i++)
1285                 pll_state->c10.pll[i] = 0;
1286 }
1287
1288 static int intel_c10pll_calc_state(struct intel_crtc_state *crtc_state,
1289                                    struct intel_encoder *encoder)
1290 {
1291         const struct intel_c10pll_state * const *tables;
1292         int i;
1293
1294         tables = intel_c10pll_tables_get(crtc_state, encoder);
1295         if (!tables)
1296                 return -EINVAL;
1297
1298         for (i = 0; tables[i]; i++) {
1299                 if (crtc_state->port_clock == tables[i]->clock) {
1300                         crtc_state->cx0pll_state.c10 = *tables[i];
1301                         intel_c10pll_update_pll(crtc_state, encoder);
1302
1303                         return 0;
1304                 }
1305         }
1306
1307         return -EINVAL;
1308 }
1309
1310 int intel_cx0pll_calc_state(struct intel_crtc_state *crtc_state,
1311                             struct intel_encoder *encoder)
1312 {
1313         struct drm_i915_private *i915 = to_i915(encoder->base.dev);
1314         enum phy phy = intel_port_to_phy(i915, encoder->port);
1315
1316         drm_WARN_ON(&i915->drm, !intel_is_c10phy(i915, phy));
1317
1318         return intel_c10pll_calc_state(crtc_state, encoder);
1319 }
1320
1321 void intel_c10pll_readout_hw_state(struct intel_encoder *encoder,
1322                                    struct intel_c10pll_state *pll_state)
1323 {
1324         struct drm_i915_private *i915 = to_i915(encoder->base.dev);
1325         u8 lane = INTEL_CX0_LANE0;
1326         intel_wakeref_t wakeref;
1327         int i;
1328
1329         wakeref = intel_cx0_phy_transaction_begin(encoder);
1330
1331         /*
1332          * According to C10 VDR Register programming Sequence we need
1333          * to do this to read PHY internal registers from MsgBus.
1334          */
1335         intel_cx0_rmw(i915, encoder->port, lane, PHY_C10_VDR_CONTROL(1),
1336                       0, C10_VDR_CTRL_MSGBUS_ACCESS,
1337                       MB_WRITE_COMMITTED);
1338
1339         for (i = 0; i < ARRAY_SIZE(pll_state->pll); i++)
1340                 pll_state->pll[i] = intel_cx0_read(i915, encoder->port, lane,
1341                                                    PHY_C10_VDR_PLL(i));
1342
1343         pll_state->cmn = intel_cx0_read(i915, encoder->port, lane, PHY_C10_VDR_CMN(0));
1344         pll_state->tx = intel_cx0_read(i915, encoder->port, lane, PHY_C10_VDR_TX(0));
1345
1346         intel_cx0_phy_transaction_end(encoder, wakeref);
1347 }
1348
1349 static void intel_c10_pll_program(struct drm_i915_private *i915,
1350                                   const struct intel_crtc_state *crtc_state,
1351                                   struct intel_encoder *encoder)
1352 {
1353         const struct intel_c10pll_state *pll_state = &crtc_state->cx0pll_state.c10;
1354         int i;
1355
1356         intel_cx0_rmw(i915, encoder->port, INTEL_CX0_BOTH_LANES, PHY_C10_VDR_CONTROL(1),
1357                       0, C10_VDR_CTRL_MSGBUS_ACCESS,
1358                       MB_WRITE_COMMITTED);
1359
1360         /* Custom width needs to be programmed to 0 for both the phy lanes */
1361         intel_cx0_rmw(i915, encoder->port, INTEL_CX0_BOTH_LANES, PHY_C10_VDR_CUSTOM_WIDTH,
1362                       C10_VDR_CUSTOM_WIDTH_MASK, C10_VDR_CUSTOM_WIDTH_8_10,
1363                       MB_WRITE_COMMITTED);
1364         intel_cx0_rmw(i915, encoder->port, INTEL_CX0_BOTH_LANES, PHY_C10_VDR_CONTROL(1),
1365                       0, C10_VDR_CTRL_UPDATE_CFG,
1366                       MB_WRITE_COMMITTED);
1367
1368         /* Program the pll values only for the master lane */
1369         for (i = 0; i < ARRAY_SIZE(pll_state->pll); i++)
1370                 intel_cx0_write(i915, encoder->port, INTEL_CX0_LANE0, PHY_C10_VDR_PLL(i),
1371                                 pll_state->pll[i],
1372                                 (i % 4) ? MB_WRITE_UNCOMMITTED : MB_WRITE_COMMITTED);
1373
1374         intel_cx0_write(i915, encoder->port, INTEL_CX0_LANE0, PHY_C10_VDR_CMN(0), pll_state->cmn, MB_WRITE_COMMITTED);
1375         intel_cx0_write(i915, encoder->port, INTEL_CX0_LANE0, PHY_C10_VDR_TX(0), pll_state->tx, MB_WRITE_COMMITTED);
1376
1377         intel_cx0_rmw(i915, encoder->port, INTEL_CX0_LANE0, PHY_C10_VDR_CONTROL(1),
1378                       0, C10_VDR_CTRL_MASTER_LANE | C10_VDR_CTRL_UPDATE_CFG,
1379                       MB_WRITE_COMMITTED);
1380 }
1381
1382 void intel_c10pll_dump_hw_state(struct drm_i915_private *i915,
1383                                 const struct intel_c10pll_state *hw_state)
1384 {
1385         bool fracen;
1386         int i;
1387         unsigned int frac_quot = 0, frac_rem = 0, frac_den = 1;
1388         unsigned int multiplier, tx_clk_div;
1389
1390         fracen = hw_state->pll[0] & C10_PLL0_FRACEN;
1391         drm_dbg_kms(&i915->drm, "c10pll_hw_state: fracen: %s, ",
1392                     str_yes_no(fracen));
1393
1394         if (fracen) {
1395                 frac_quot = hw_state->pll[12] << 8 | hw_state->pll[11];
1396                 frac_rem =  hw_state->pll[14] << 8 | hw_state->pll[13];
1397                 frac_den =  hw_state->pll[10] << 8 | hw_state->pll[9];
1398                 drm_dbg_kms(&i915->drm, "quot: %u, rem: %u, den: %u,\n",
1399                             frac_quot, frac_rem, frac_den);
1400         }
1401
1402         multiplier = (REG_FIELD_GET8(C10_PLL3_MULTIPLIERH_MASK, hw_state->pll[3]) << 8 |
1403                       hw_state->pll[2]) / 2 + 16;
1404         tx_clk_div = REG_FIELD_GET8(C10_PLL15_TXCLKDIV_MASK, hw_state->pll[15]);
1405         drm_dbg_kms(&i915->drm,
1406                     "multiplier: %u, tx_clk_div: %u.\n", multiplier, tx_clk_div);
1407
1408         drm_dbg_kms(&i915->drm, "c10pll_rawhw_state:");
1409         drm_dbg_kms(&i915->drm, "tx: 0x%x, cmn: 0x%x\n", hw_state->tx, hw_state->cmn);
1410
1411         BUILD_BUG_ON(ARRAY_SIZE(hw_state->pll) % 4);
1412         for (i = 0; i < ARRAY_SIZE(hw_state->pll); i = i + 4)
1413                 drm_dbg_kms(&i915->drm, "pll[%d] = 0x%x, pll[%d] = 0x%x, pll[%d] = 0x%x, pll[%d] = 0x%x\n",
1414                             i, hw_state->pll[i], i + 1, hw_state->pll[i + 1],
1415                             i + 2, hw_state->pll[i + 2], i + 3, hw_state->pll[i + 3]);
1416 }
1417
1418 int intel_c10pll_calc_port_clock(struct intel_encoder *encoder,
1419                                  const struct intel_c10pll_state *pll_state)
1420 {
1421         unsigned int frac_quot = 0, frac_rem = 0, frac_den = 1;
1422         unsigned int multiplier, tx_clk_div, hdmi_div, refclk = 38400;
1423         int tmpclk = 0;
1424
1425         if (pll_state->pll[0] & C10_PLL0_FRACEN) {
1426                 frac_quot = pll_state->pll[12] << 8 | pll_state->pll[11];
1427                 frac_rem =  pll_state->pll[14] << 8 | pll_state->pll[13];
1428                 frac_den =  pll_state->pll[10] << 8 | pll_state->pll[9];
1429         }
1430
1431         multiplier = (REG_FIELD_GET8(C10_PLL3_MULTIPLIERH_MASK, pll_state->pll[3]) << 8 |
1432                       pll_state->pll[2]) / 2 + 16;
1433
1434         tx_clk_div = REG_FIELD_GET8(C10_PLL15_TXCLKDIV_MASK, pll_state->pll[15]);
1435         hdmi_div = REG_FIELD_GET8(C10_PLL15_HDMIDIV_MASK, pll_state->pll[15]);
1436
1437         tmpclk = DIV_ROUND_CLOSEST_ULL(mul_u32_u32(refclk, (multiplier << 16) + frac_quot) +
1438                                      DIV_ROUND_CLOSEST(refclk * frac_rem, frac_den),
1439                                      10 << (tx_clk_div + 16));
1440         tmpclk *= (hdmi_div ? 2 : 1);
1441
1442         return tmpclk;
1443 }
1444
1445 static void intel_program_port_clock_ctl(struct intel_encoder *encoder,
1446                                          const struct intel_crtc_state *crtc_state,
1447                                          bool lane_reversal)
1448 {
1449         struct drm_i915_private *i915 = to_i915(encoder->base.dev);
1450         u32 val = 0;
1451
1452         intel_de_rmw(i915, XELPDP_PORT_BUF_CTL1(encoder->port), XELPDP_PORT_REVERSAL,
1453                      lane_reversal ? XELPDP_PORT_REVERSAL : 0);
1454
1455         if (lane_reversal)
1456                 val |= XELPDP_LANE1_PHY_CLOCK_SELECT;
1457
1458         val |= XELPDP_FORWARD_CLOCK_UNGATE;
1459         val |= XELPDP_DDI_CLOCK_SELECT(XELPDP_DDI_CLOCK_SELECT_MAXPCLK);
1460
1461         /* TODO: HDMI FRL */
1462         /* TODO: DP2.0 10G and 20G rates enable MPLLA*/
1463         val |= crtc_state->cx0pll_state.ssc_enabled ? XELPDP_SSC_ENABLE_PLLB : 0;
1464
1465         intel_de_rmw(i915, XELPDP_PORT_CLOCK_CTL(encoder->port),
1466                      XELPDP_LANE1_PHY_CLOCK_SELECT | XELPDP_FORWARD_CLOCK_UNGATE |
1467                      XELPDP_DDI_CLOCK_SELECT_MASK | XELPDP_SSC_ENABLE_PLLB, val);
1468 }
1469
1470 static u32 intel_cx0_get_powerdown_update(u8 lane_mask)
1471 {
1472         u32 val = 0;
1473         int lane = 0;
1474
1475         for_each_cx0_lane_in_mask(lane_mask, lane)
1476                 val |= XELPDP_LANE_POWERDOWN_UPDATE(lane);
1477
1478         return val;
1479 }
1480
1481 static u32 intel_cx0_get_powerdown_state(u8 lane_mask, u8 state)
1482 {
1483         u32 val = 0;
1484         int lane = 0;
1485
1486         for_each_cx0_lane_in_mask(lane_mask, lane)
1487                 val |= XELPDP_LANE_POWERDOWN_NEW_STATE(lane, state);
1488
1489         return val;
1490 }
1491
1492 static void intel_cx0_powerdown_change_sequence(struct drm_i915_private *i915,
1493                                                 enum port port,
1494                                                 u8 lane_mask, u8 state)
1495 {
1496         enum phy phy = intel_port_to_phy(i915, port);
1497         int lane;
1498
1499         intel_de_rmw(i915, XELPDP_PORT_BUF_CTL2(port),
1500                      intel_cx0_get_powerdown_state(INTEL_CX0_BOTH_LANES, XELPDP_LANE_POWERDOWN_NEW_STATE_MASK),
1501                      intel_cx0_get_powerdown_state(lane_mask, state));
1502
1503         /* Wait for pending transactions.*/
1504         for_each_cx0_lane_in_mask(lane_mask, lane)
1505                 if (intel_de_wait_for_clear(i915, XELPDP_PORT_M2P_MSGBUS_CTL(port, lane),
1506                                             XELPDP_PORT_M2P_TRANSACTION_PENDING,
1507                                             XELPDP_MSGBUS_TIMEOUT_SLOW)) {
1508                         drm_dbg_kms(&i915->drm,
1509                                     "PHY %c Timeout waiting for previous transaction to complete. Reset the bus.\n",
1510                                     phy_name(phy));
1511                         intel_cx0_bus_reset(i915, port, lane);
1512                 }
1513
1514         intel_de_rmw(i915, XELPDP_PORT_BUF_CTL2(port),
1515                      intel_cx0_get_powerdown_update(INTEL_CX0_BOTH_LANES),
1516                      intel_cx0_get_powerdown_update(lane_mask));
1517
1518         /* Update Timeout Value */
1519         if (__intel_de_wait_for_register(i915, XELPDP_PORT_BUF_CTL2(port),
1520                                          intel_cx0_get_powerdown_update(lane_mask), 0,
1521                                          XELPDP_PORT_POWERDOWN_UPDATE_TIMEOUT_US, 0, NULL))
1522                 drm_warn(&i915->drm, "PHY %c failed to bring out of Lane reset after %dus.\n",
1523                          phy_name(phy), XELPDP_PORT_RESET_START_TIMEOUT_US);
1524 }
1525
1526 static void intel_cx0_setup_powerdown(struct drm_i915_private *i915, enum port port)
1527 {
1528         intel_de_rmw(i915, XELPDP_PORT_BUF_CTL2(port),
1529                      XELPDP_POWER_STATE_READY_MASK,
1530                      XELPDP_POWER_STATE_READY(CX0_P2_STATE_READY));
1531         intel_de_rmw(i915, XELPDP_PORT_BUF_CTL3(port),
1532                      XELPDP_POWER_STATE_ACTIVE_MASK |
1533                      XELPDP_PLL_LANE_STAGGERING_DELAY_MASK,
1534                      XELPDP_POWER_STATE_ACTIVE(CX0_P0_STATE_ACTIVE) |
1535                      XELPDP_PLL_LANE_STAGGERING_DELAY(0));
1536 }
1537
1538 static u32 intel_cx0_get_pclk_refclk_request(u8 lane_mask)
1539 {
1540         u32 val = 0;
1541         int lane = 0;
1542
1543         for_each_cx0_lane_in_mask(lane_mask, lane)
1544                 val |= XELPDP_LANE_PCLK_REFCLK_REQUEST(lane);
1545
1546         return val;
1547 }
1548
1549 static u32 intel_cx0_get_pclk_refclk_ack(u8 lane_mask)
1550 {
1551         u32 val = 0;
1552         int lane = 0;
1553
1554         for_each_cx0_lane_in_mask(lane_mask, lane)
1555                 val |= XELPDP_LANE_PCLK_REFCLK_ACK(lane);
1556
1557         return val;
1558 }
1559
1560 /* FIXME: Some Type-C cases need not reset both the lanes. Handle those cases. */
1561 static void intel_cx0_phy_lane_reset(struct drm_i915_private *i915, enum port port,
1562                                      bool lane_reversal)
1563 {
1564         enum phy phy = intel_port_to_phy(i915, port);
1565         u8 lane_mask = lane_reversal ? INTEL_CX0_LANE1 :
1566                                   INTEL_CX0_LANE0;
1567
1568         if (__intel_de_wait_for_register(i915, XELPDP_PORT_BUF_CTL1(port),
1569                                          XELPDP_PORT_BUF_SOC_PHY_READY,
1570                                          XELPDP_PORT_BUF_SOC_PHY_READY,
1571                                          XELPDP_PORT_BUF_SOC_READY_TIMEOUT_US, 0, NULL))
1572                 drm_warn(&i915->drm, "PHY %c failed to bring out of SOC reset after %dus.\n",
1573                          phy_name(phy), XELPDP_PORT_BUF_SOC_READY_TIMEOUT_US);
1574
1575         intel_de_rmw(i915, XELPDP_PORT_BUF_CTL2(port),
1576                      XELPDP_LANE_PIPE_RESET(0) | XELPDP_LANE_PIPE_RESET(1),
1577                      XELPDP_LANE_PIPE_RESET(0) | XELPDP_LANE_PIPE_RESET(1));
1578
1579         if (__intel_de_wait_for_register(i915, XELPDP_PORT_BUF_CTL2(port),
1580                                          XELPDP_LANE_PHY_CURRENT_STATUS(0) |
1581                                          XELPDP_LANE_PHY_CURRENT_STATUS(1),
1582                                          XELPDP_LANE_PHY_CURRENT_STATUS(0) |
1583                                          XELPDP_LANE_PHY_CURRENT_STATUS(1),
1584                                          XELPDP_PORT_RESET_START_TIMEOUT_US, 0, NULL))
1585                 drm_warn(&i915->drm, "PHY %c failed to bring out of Lane reset after %dus.\n",
1586                          phy_name(phy), XELPDP_PORT_RESET_START_TIMEOUT_US);
1587
1588         intel_de_rmw(i915, XELPDP_PORT_CLOCK_CTL(port),
1589                      intel_cx0_get_pclk_refclk_request(INTEL_CX0_BOTH_LANES),
1590                      intel_cx0_get_pclk_refclk_request(lane_mask));
1591
1592         if (__intel_de_wait_for_register(i915, XELPDP_PORT_CLOCK_CTL(port),
1593                                          intel_cx0_get_pclk_refclk_ack(INTEL_CX0_BOTH_LANES),
1594                                          intel_cx0_get_pclk_refclk_ack(lane_mask),
1595                                          XELPDP_REFCLK_ENABLE_TIMEOUT_US, 0, NULL))
1596                 drm_warn(&i915->drm, "PHY %c failed to request refclk after %dus.\n",
1597                          phy_name(phy), XELPDP_REFCLK_ENABLE_TIMEOUT_US);
1598
1599         intel_cx0_powerdown_change_sequence(i915, port, INTEL_CX0_BOTH_LANES,
1600                                             CX0_P2_STATE_RESET);
1601         intel_cx0_setup_powerdown(i915, port);
1602
1603         intel_de_rmw(i915, XELPDP_PORT_BUF_CTL2(port),
1604                      XELPDP_LANE_PIPE_RESET(0) | XELPDP_LANE_PIPE_RESET(1),
1605                      0);
1606
1607         if (intel_de_wait_for_clear(i915, XELPDP_PORT_BUF_CTL2(port),
1608                                     XELPDP_LANE_PHY_CURRENT_STATUS(0) |
1609                                     XELPDP_LANE_PHY_CURRENT_STATUS(1),
1610                                     XELPDP_PORT_RESET_END_TIMEOUT))
1611                 drm_warn(&i915->drm, "PHY %c failed to bring out of Lane reset after %dms.\n",
1612                          phy_name(phy), XELPDP_PORT_RESET_END_TIMEOUT);
1613 }
1614
1615 static void intel_c10_program_phy_lane(struct drm_i915_private *i915,
1616                                        struct intel_encoder *encoder, int lane_count,
1617                                        bool lane_reversal)
1618 {
1619         u8 l0t1, l0t2, l1t1, l1t2;
1620         bool dp_alt_mode = intel_tc_port_in_dp_alt_mode(enc_to_dig_port(encoder));
1621         enum port port = encoder->port;
1622
1623         intel_cx0_rmw(i915, port, INTEL_CX0_BOTH_LANES, PHY_C10_VDR_CONTROL(1),
1624                       0, C10_VDR_CTRL_MSGBUS_ACCESS,
1625                       MB_WRITE_COMMITTED);
1626
1627         /* TODO: DP-alt MFD case where only one PHY lane should be programmed. */
1628         l0t1 = intel_cx0_read(i915, port, INTEL_CX0_LANE0, PHY_CX0_TX_CONTROL(1, 2));
1629         l0t2 = intel_cx0_read(i915, port, INTEL_CX0_LANE0, PHY_CX0_TX_CONTROL(2, 2));
1630         l1t1 = intel_cx0_read(i915, port, INTEL_CX0_LANE1, PHY_CX0_TX_CONTROL(1, 2));
1631         l1t2 = intel_cx0_read(i915, port, INTEL_CX0_LANE1, PHY_CX0_TX_CONTROL(2, 2));
1632
1633         l0t1 |= CONTROL2_DISABLE_SINGLE_TX;
1634         l0t2 |= CONTROL2_DISABLE_SINGLE_TX;
1635         l1t1 |= CONTROL2_DISABLE_SINGLE_TX;
1636         l1t2 |= CONTROL2_DISABLE_SINGLE_TX;
1637
1638         if (lane_reversal) {
1639                 switch (lane_count) {
1640                 case 4:
1641                         l0t1 &= ~CONTROL2_DISABLE_SINGLE_TX;
1642                         fallthrough;
1643                 case 3:
1644                         l0t2 &= ~CONTROL2_DISABLE_SINGLE_TX;
1645                         fallthrough;
1646                 case 2:
1647                         l1t1 &= ~CONTROL2_DISABLE_SINGLE_TX;
1648                         fallthrough;
1649                 case 1:
1650                         l1t2 &= ~CONTROL2_DISABLE_SINGLE_TX;
1651                         break;
1652                 default:
1653                         MISSING_CASE(lane_count);
1654                 }
1655         } else {
1656                 switch (lane_count) {
1657                 case 4:
1658                         l1t2 &= ~CONTROL2_DISABLE_SINGLE_TX;
1659                         fallthrough;
1660                 case 3:
1661                         l1t1 &= ~CONTROL2_DISABLE_SINGLE_TX;
1662                         fallthrough;
1663                 case 2:
1664                         l0t2 &= ~CONTROL2_DISABLE_SINGLE_TX;
1665                         l0t1 &= ~CONTROL2_DISABLE_SINGLE_TX;
1666                         break;
1667                 case 1:
1668                         if (dp_alt_mode)
1669                                 l0t2 &= ~CONTROL2_DISABLE_SINGLE_TX;
1670                         else
1671                                 l0t1 &= ~CONTROL2_DISABLE_SINGLE_TX;
1672                         break;
1673                 default:
1674                         MISSING_CASE(lane_count);
1675                 }
1676         }
1677
1678         /* disable MLs */
1679         intel_cx0_write(i915, port, INTEL_CX0_LANE0, PHY_CX0_TX_CONTROL(1, 2),
1680                         l0t1, MB_WRITE_COMMITTED);
1681         intel_cx0_write(i915, port, INTEL_CX0_LANE0, PHY_CX0_TX_CONTROL(2, 2),
1682                         l0t2, MB_WRITE_COMMITTED);
1683         intel_cx0_write(i915, port, INTEL_CX0_LANE1, PHY_CX0_TX_CONTROL(1, 2),
1684                         l1t1, MB_WRITE_COMMITTED);
1685         intel_cx0_write(i915, port, INTEL_CX0_LANE1, PHY_CX0_TX_CONTROL(2, 2),
1686                         l1t2, MB_WRITE_COMMITTED);
1687
1688         intel_cx0_rmw(i915, port, INTEL_CX0_BOTH_LANES, PHY_C10_VDR_CONTROL(1),
1689                       0, C10_VDR_CTRL_UPDATE_CFG,
1690                       MB_WRITE_COMMITTED);
1691 }
1692
1693 static u32 intel_cx0_get_pclk_pll_request(u8 lane_mask)
1694 {
1695         u32 val = 0;
1696         int lane = 0;
1697
1698         for_each_cx0_lane_in_mask(lane_mask, lane)
1699                 val |= XELPDP_LANE_PCLK_PLL_REQUEST(lane);
1700
1701         return val;
1702 }
1703
1704 static u32 intel_cx0_get_pclk_pll_ack(u8 lane_mask)
1705 {
1706         u32 val = 0;
1707         int lane = 0;
1708
1709         for_each_cx0_lane_in_mask(lane_mask, lane)
1710                 val |= XELPDP_LANE_PCLK_PLL_ACK(lane);
1711
1712         return val;
1713 }
1714
1715 static void intel_c10pll_enable(struct intel_encoder *encoder,
1716                                 const struct intel_crtc_state *crtc_state)
1717 {
1718         struct drm_i915_private *i915 = to_i915(encoder->base.dev);
1719         enum phy phy = intel_port_to_phy(i915, encoder->port);
1720         struct intel_digital_port *dig_port = enc_to_dig_port(encoder);
1721         bool lane_reversal = dig_port->saved_port_bits & DDI_BUF_PORT_REVERSAL;
1722         u8 maxpclk_lane = lane_reversal ? INTEL_CX0_LANE1 :
1723                                           INTEL_CX0_LANE0;
1724
1725         /*
1726          * 1. Program PORT_CLOCK_CTL REGISTER to configure
1727          * clock muxes, gating and SSC
1728          */
1729         intel_program_port_clock_ctl(encoder, crtc_state, lane_reversal);
1730
1731         /* 2. Bring PHY out of reset. */
1732         intel_cx0_phy_lane_reset(i915, encoder->port, lane_reversal);
1733
1734         /*
1735          * 3. Change Phy power state to Ready.
1736          * TODO: For DP alt mode use only one lane.
1737          */
1738         intel_cx0_powerdown_change_sequence(i915, encoder->port, INTEL_CX0_BOTH_LANES,
1739                                             CX0_P2_STATE_READY);
1740
1741         /* 4. Program PHY internal PLL internal registers. */
1742         intel_c10_pll_program(i915, crtc_state, encoder);
1743
1744         /*
1745          * 5. Program the enabled and disabled owned PHY lane
1746          * transmitters over message bus
1747          */
1748         intel_c10_program_phy_lane(i915, encoder, crtc_state->lane_count, lane_reversal);
1749
1750         /*
1751          * 6. Follow the Display Voltage Frequency Switching - Sequence
1752          * Before Frequency Change. We handle this step in bxt_set_cdclk().
1753          */
1754
1755         /*
1756          * 7. Program DDI_CLK_VALFREQ to match intended DDI
1757          * clock frequency.
1758          */
1759         intel_de_write(i915, DDI_CLK_VALFREQ(encoder->port),
1760                        crtc_state->port_clock);
1761
1762         /*
1763          * 8. Set PORT_CLOCK_CTL register PCLK PLL Request
1764          * LN<Lane for maxPCLK> to "1" to enable PLL.
1765          */
1766         intel_de_rmw(i915, XELPDP_PORT_CLOCK_CTL(encoder->port),
1767                      intel_cx0_get_pclk_pll_request(INTEL_CX0_BOTH_LANES),
1768                      intel_cx0_get_pclk_pll_request(maxpclk_lane));
1769
1770         /* 9. Poll on PORT_CLOCK_CTL PCLK PLL Ack LN<Lane for maxPCLK> == "1". */
1771         if (__intel_de_wait_for_register(i915, XELPDP_PORT_CLOCK_CTL(encoder->port),
1772                                          intel_cx0_get_pclk_pll_ack(INTEL_CX0_BOTH_LANES),
1773                                          intel_cx0_get_pclk_pll_ack(maxpclk_lane),
1774                                          XELPDP_PCLK_PLL_ENABLE_TIMEOUT_US, 0, NULL))
1775                 drm_warn(&i915->drm, "Port %c PLL not locked after %dus.\n",
1776                          phy_name(phy), XELPDP_PCLK_PLL_ENABLE_TIMEOUT_US);
1777
1778         /*
1779          * 10. Follow the Display Voltage Frequency Switching Sequence After
1780          * Frequency Change. We handle this step in bxt_set_cdclk().
1781          */
1782 }
1783
1784 void intel_cx0pll_enable(struct intel_encoder *encoder,
1785                          const struct intel_crtc_state *crtc_state)
1786 {
1787         struct drm_i915_private *i915 = to_i915(encoder->base.dev);
1788         enum phy phy = intel_port_to_phy(i915, encoder->port);
1789         intel_wakeref_t wakeref;
1790
1791         wakeref = intel_cx0_phy_transaction_begin(encoder);
1792
1793         drm_WARN_ON(&i915->drm, !intel_is_c10phy(i915, phy));
1794         intel_c10pll_enable(encoder, crtc_state);
1795
1796         /* TODO: enable TBT-ALT mode */
1797         intel_cx0_phy_transaction_end(encoder, wakeref);
1798 }
1799
1800 static void intel_c10pll_disable(struct intel_encoder *encoder)
1801 {
1802         struct drm_i915_private *i915 = to_i915(encoder->base.dev);
1803         enum phy phy = intel_port_to_phy(i915, encoder->port);
1804
1805         /* 1. Change owned PHY lane power to Disable state. */
1806         intel_cx0_powerdown_change_sequence(i915, encoder->port, INTEL_CX0_BOTH_LANES,
1807                                             CX0_P2PG_STATE_DISABLE);
1808
1809         /*
1810          * 2. Follow the Display Voltage Frequency Switching Sequence Before
1811          * Frequency Change. We handle this step in bxt_set_cdclk().
1812          */
1813
1814         /*
1815          * 3. Set PORT_CLOCK_CTL register PCLK PLL Request LN<Lane for maxPCLK>
1816          * to "0" to disable PLL.
1817          */
1818         intel_de_rmw(i915, XELPDP_PORT_CLOCK_CTL(encoder->port),
1819                      intel_cx0_get_pclk_pll_request(INTEL_CX0_BOTH_LANES) |
1820                      intel_cx0_get_pclk_refclk_request(INTEL_CX0_BOTH_LANES), 0);
1821
1822         /* 4. Program DDI_CLK_VALFREQ to 0. */
1823         intel_de_write(i915, DDI_CLK_VALFREQ(encoder->port), 0);
1824
1825         /*
1826          * 5. Poll on PORT_CLOCK_CTL PCLK PLL Ack LN<Lane for maxPCLK**> == "0".
1827          */
1828         if (__intel_de_wait_for_register(i915, XELPDP_PORT_CLOCK_CTL(encoder->port),
1829                                          intel_cx0_get_pclk_pll_ack(INTEL_CX0_BOTH_LANES) |
1830                                          intel_cx0_get_pclk_refclk_ack(INTEL_CX0_BOTH_LANES), 0,
1831                                          XELPDP_PCLK_PLL_DISABLE_TIMEOUT_US, 0, NULL))
1832                 drm_warn(&i915->drm, "Port %c PLL not unlocked after %dus.\n",
1833                          phy_name(phy), XELPDP_PCLK_PLL_DISABLE_TIMEOUT_US);
1834
1835         /*
1836          * 6. Follow the Display Voltage Frequency Switching Sequence After
1837          * Frequency Change. We handle this step in bxt_set_cdclk().
1838          */
1839
1840         /* 7. Program PORT_CLOCK_CTL register to disable and gate clocks. */
1841         intel_de_rmw(i915, XELPDP_PORT_CLOCK_CTL(encoder->port),
1842                      XELPDP_DDI_CLOCK_SELECT_MASK, 0);
1843         intel_de_rmw(i915, XELPDP_PORT_CLOCK_CTL(encoder->port),
1844                      XELPDP_FORWARD_CLOCK_UNGATE, 0);
1845 }
1846
1847 void intel_cx0pll_disable(struct intel_encoder *encoder)
1848 {
1849         struct drm_i915_private *i915 = to_i915(encoder->base.dev);
1850         enum phy phy = intel_port_to_phy(i915, encoder->port);
1851         intel_wakeref_t wakeref;
1852
1853         wakeref = intel_cx0_phy_transaction_begin(encoder);
1854
1855         drm_WARN_ON(&i915->drm, !intel_is_c10phy(i915, phy));
1856         intel_c10pll_disable(encoder);
1857         intel_cx0_phy_transaction_end(encoder, wakeref);
1858 }
1859
1860 void intel_c10pll_state_verify(struct intel_atomic_state *state,
1861                                struct intel_crtc_state *new_crtc_state)
1862 {
1863         struct drm_i915_private *i915 = to_i915(state->base.dev);
1864         struct intel_c10pll_state mpllb_hw_state = { 0 };
1865         struct intel_c10pll_state *mpllb_sw_state = &new_crtc_state->cx0pll_state.c10;
1866         struct intel_crtc *crtc = to_intel_crtc(new_crtc_state->uapi.crtc);
1867         struct intel_encoder *encoder;
1868         enum phy phy;
1869         int i;
1870
1871         if (DISPLAY_VER(i915) < 14)
1872                 return;
1873
1874         if (!new_crtc_state->hw.active)
1875                 return;
1876
1877         encoder = intel_get_crtc_new_encoder(state, new_crtc_state);
1878         phy = intel_port_to_phy(i915, encoder->port);
1879
1880         if (!intel_is_c10phy(i915, phy))
1881                 return;
1882
1883         intel_c10pll_readout_hw_state(encoder, &mpllb_hw_state);
1884
1885         for (i = 0; i < ARRAY_SIZE(mpllb_sw_state->pll); i++) {
1886                 u8 expected = mpllb_sw_state->pll[i];
1887
1888                 I915_STATE_WARN(mpllb_hw_state.pll[i] != expected,
1889                                 "[CRTC:%d:%s] mismatch in C10MPLLB: Register[%d] (expected 0x%02x, found 0x%02x)",
1890                                 crtc->base.base.id, crtc->base.name,
1891                                 i, expected, mpllb_hw_state.pll[i]);
1892         }
1893
1894         I915_STATE_WARN(mpllb_hw_state.tx != mpllb_sw_state->tx,
1895                         "[CRTC:%d:%s] mismatch in C10MPLLB: Register TX0 (expected 0x%02x, found 0x%02x)",
1896                         crtc->base.base.id, crtc->base.name,
1897                         mpllb_sw_state->tx, mpllb_hw_state.tx);
1898
1899         I915_STATE_WARN(mpllb_hw_state.cmn != mpllb_sw_state->cmn,
1900                         "[CRTC:%d:%s] mismatch in C10MPLLB: Register CMN0 (expected 0x%02x, found 0x%02x)",
1901                         crtc->base.base.id, crtc->base.name,
1902                         mpllb_sw_state->cmn, mpllb_hw_state.cmn);
1903 }