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