1 // SPDX-License-Identifier: MIT
2 /*
3  * Copyright © 2019 Intel Corporation
4  */
5 
6 #include "i915_drv.h"
7 #include "i915_reg.h"
8 #include "intel_ddi.h"
9 #include "intel_de.h"
10 #include "intel_display.h"
11 #include "intel_display_power_map.h"
12 #include "intel_display_types.h"
13 #include "intel_dkl_phy_regs.h"
14 #include "intel_dp_mst.h"
15 #include "intel_mg_phy_regs.h"
16 #include "intel_tc.h"
17 
18 static const char *tc_port_mode_name(enum tc_port_mode mode)
19 {
20 	static const char * const names[] = {
21 		[TC_PORT_DISCONNECTED] = "disconnected",
22 		[TC_PORT_TBT_ALT] = "tbt-alt",
23 		[TC_PORT_DP_ALT] = "dp-alt",
24 		[TC_PORT_LEGACY] = "legacy",
25 	};
26 
27 	if (WARN_ON(mode >= ARRAY_SIZE(names)))
28 		mode = TC_PORT_DISCONNECTED;
29 
30 	return names[mode];
31 }
32 
33 static bool intel_tc_port_in_mode(struct intel_digital_port *dig_port,
34 				  enum tc_port_mode mode)
35 {
36 	struct drm_i915_private *i915 = to_i915(dig_port->base.base.dev);
37 	enum phy phy = intel_port_to_phy(i915, dig_port->base.port);
38 
39 	return intel_phy_is_tc(i915, phy) && dig_port->tc_mode == mode;
40 }
41 
42 bool intel_tc_port_in_tbt_alt_mode(struct intel_digital_port *dig_port)
43 {
44 	return intel_tc_port_in_mode(dig_port, TC_PORT_TBT_ALT);
45 }
46 
47 bool intel_tc_port_in_dp_alt_mode(struct intel_digital_port *dig_port)
48 {
49 	return intel_tc_port_in_mode(dig_port, TC_PORT_DP_ALT);
50 }
51 
52 bool intel_tc_port_in_legacy_mode(struct intel_digital_port *dig_port)
53 {
54 	return intel_tc_port_in_mode(dig_port, TC_PORT_LEGACY);
55 }
56 
57 bool intel_tc_cold_requires_aux_pw(struct intel_digital_port *dig_port)
58 {
59 	struct drm_i915_private *i915 = to_i915(dig_port->base.base.dev);
60 
61 	return (DISPLAY_VER(i915) == 11 && dig_port->tc_legacy_port) ||
62 		IS_ALDERLAKE_P(i915);
63 }
64 
65 static enum intel_display_power_domain
66 tc_cold_get_power_domain(struct intel_digital_port *dig_port, enum tc_port_mode mode)
67 {
68 	struct drm_i915_private *i915 = to_i915(dig_port->base.base.dev);
69 
70 	if (mode == TC_PORT_TBT_ALT || !intel_tc_cold_requires_aux_pw(dig_port))
71 		return POWER_DOMAIN_TC_COLD_OFF;
72 
73 	return intel_display_power_legacy_aux_domain(i915, dig_port->aux_ch);
74 }
75 
76 static intel_wakeref_t
77 tc_cold_block_in_mode(struct intel_digital_port *dig_port, enum tc_port_mode mode,
78 		      enum intel_display_power_domain *domain)
79 {
80 	struct drm_i915_private *i915 = to_i915(dig_port->base.base.dev);
81 
82 	*domain = tc_cold_get_power_domain(dig_port, mode);
83 
84 	return intel_display_power_get(i915, *domain);
85 }
86 
87 static intel_wakeref_t
88 tc_cold_block(struct intel_digital_port *dig_port, enum intel_display_power_domain *domain)
89 {
90 	return tc_cold_block_in_mode(dig_port, dig_port->tc_mode, domain);
91 }
92 
93 static void
94 tc_cold_unblock(struct intel_digital_port *dig_port, enum intel_display_power_domain domain,
95 		intel_wakeref_t wakeref)
96 {
97 	struct drm_i915_private *i915 = to_i915(dig_port->base.base.dev);
98 
99 	/*
100 	 * wakeref == -1, means some error happened saving save_depot_stack but
101 	 * power should still be put down and 0 is a invalid save_depot_stack
102 	 * id so can be used to skip it for non TC legacy ports.
103 	 */
104 	if (wakeref == 0)
105 		return;
106 
107 	intel_display_power_put(i915, domain, wakeref);
108 }
109 
110 static void
111 assert_tc_cold_blocked(struct intel_digital_port *dig_port)
112 {
113 	struct drm_i915_private *i915 = to_i915(dig_port->base.base.dev);
114 	bool enabled;
115 
116 	enabled = intel_display_power_is_enabled(i915,
117 						 tc_cold_get_power_domain(dig_port,
118 									  dig_port->tc_mode));
119 	drm_WARN_ON(&i915->drm, !enabled);
120 }
121 
122 static enum intel_display_power_domain
123 tc_port_power_domain(struct intel_digital_port *dig_port)
124 {
125 	struct drm_i915_private *i915 = to_i915(dig_port->base.base.dev);
126 	enum tc_port tc_port = intel_port_to_tc(i915, dig_port->base.port);
127 
128 	return POWER_DOMAIN_PORT_DDI_LANES_TC1 + tc_port - TC_PORT_1;
129 }
130 
131 static void
132 assert_tc_port_power_enabled(struct intel_digital_port *dig_port)
133 {
134 	struct drm_i915_private *i915 = to_i915(dig_port->base.base.dev);
135 
136 	drm_WARN_ON(&i915->drm,
137 		    !intel_display_power_is_enabled(i915, tc_port_power_domain(dig_port)));
138 }
139 
140 u32 intel_tc_port_get_lane_mask(struct intel_digital_port *dig_port)
141 {
142 	struct drm_i915_private *i915 = to_i915(dig_port->base.base.dev);
143 	u32 lane_mask;
144 
145 	lane_mask = intel_de_read(i915, PORT_TX_DFLEXDPSP(dig_port->tc_phy_fia));
146 
147 	drm_WARN_ON(&i915->drm, lane_mask == 0xffffffff);
148 	assert_tc_cold_blocked(dig_port);
149 
150 	lane_mask &= DP_LANE_ASSIGNMENT_MASK(dig_port->tc_phy_fia_idx);
151 	return lane_mask >> DP_LANE_ASSIGNMENT_SHIFT(dig_port->tc_phy_fia_idx);
152 }
153 
154 u32 intel_tc_port_get_pin_assignment_mask(struct intel_digital_port *dig_port)
155 {
156 	struct drm_i915_private *i915 = to_i915(dig_port->base.base.dev);
157 	u32 pin_mask;
158 
159 	pin_mask = intel_de_read(i915, PORT_TX_DFLEXPA1(dig_port->tc_phy_fia));
160 
161 	drm_WARN_ON(&i915->drm, pin_mask == 0xffffffff);
162 	assert_tc_cold_blocked(dig_port);
163 
164 	return (pin_mask & DP_PIN_ASSIGNMENT_MASK(dig_port->tc_phy_fia_idx)) >>
165 	       DP_PIN_ASSIGNMENT_SHIFT(dig_port->tc_phy_fia_idx);
166 }
167 
168 int intel_tc_port_fia_max_lane_count(struct intel_digital_port *dig_port)
169 {
170 	struct drm_i915_private *i915 = to_i915(dig_port->base.base.dev);
171 	intel_wakeref_t wakeref;
172 	u32 lane_mask;
173 
174 	if (dig_port->tc_mode != TC_PORT_DP_ALT)
175 		return 4;
176 
177 	assert_tc_cold_blocked(dig_port);
178 
179 	lane_mask = 0;
180 	with_intel_display_power(i915, POWER_DOMAIN_DISPLAY_CORE, wakeref)
181 		lane_mask = intel_tc_port_get_lane_mask(dig_port);
182 
183 	switch (lane_mask) {
184 	default:
185 		MISSING_CASE(lane_mask);
186 		fallthrough;
187 	case 0x1:
188 	case 0x2:
189 	case 0x4:
190 	case 0x8:
191 		return 1;
192 	case 0x3:
193 	case 0xc:
194 		return 2;
195 	case 0xf:
196 		return 4;
197 	}
198 }
199 
200 void intel_tc_port_set_fia_lane_count(struct intel_digital_port *dig_port,
201 				      int required_lanes)
202 {
203 	struct drm_i915_private *i915 = to_i915(dig_port->base.base.dev);
204 	bool lane_reversal = dig_port->saved_port_bits & DDI_BUF_PORT_REVERSAL;
205 	u32 val;
206 
207 	drm_WARN_ON(&i915->drm,
208 		    lane_reversal && dig_port->tc_mode != TC_PORT_LEGACY);
209 
210 	assert_tc_cold_blocked(dig_port);
211 
212 	val = intel_de_read(i915, PORT_TX_DFLEXDPMLE1(dig_port->tc_phy_fia));
213 	val &= ~DFLEXDPMLE1_DPMLETC_MASK(dig_port->tc_phy_fia_idx);
214 
215 	switch (required_lanes) {
216 	case 1:
217 		val |= lane_reversal ?
218 			DFLEXDPMLE1_DPMLETC_ML3(dig_port->tc_phy_fia_idx) :
219 			DFLEXDPMLE1_DPMLETC_ML0(dig_port->tc_phy_fia_idx);
220 		break;
221 	case 2:
222 		val |= lane_reversal ?
223 			DFLEXDPMLE1_DPMLETC_ML3_2(dig_port->tc_phy_fia_idx) :
224 			DFLEXDPMLE1_DPMLETC_ML1_0(dig_port->tc_phy_fia_idx);
225 		break;
226 	case 4:
227 		val |= DFLEXDPMLE1_DPMLETC_ML3_0(dig_port->tc_phy_fia_idx);
228 		break;
229 	default:
230 		MISSING_CASE(required_lanes);
231 	}
232 
233 	intel_de_write(i915, PORT_TX_DFLEXDPMLE1(dig_port->tc_phy_fia), val);
234 }
235 
236 static void tc_port_fixup_legacy_flag(struct intel_digital_port *dig_port,
237 				      u32 live_status_mask)
238 {
239 	struct drm_i915_private *i915 = to_i915(dig_port->base.base.dev);
240 	u32 valid_hpd_mask;
241 
242 	if (dig_port->tc_legacy_port)
243 		valid_hpd_mask = BIT(TC_PORT_LEGACY);
244 	else
245 		valid_hpd_mask = BIT(TC_PORT_DP_ALT) |
246 				 BIT(TC_PORT_TBT_ALT);
247 
248 	if (!(live_status_mask & ~valid_hpd_mask))
249 		return;
250 
251 	/* If live status mismatches the VBT flag, trust the live status. */
252 	drm_dbg_kms(&i915->drm,
253 		    "Port %s: live status %08x mismatches the legacy port flag %08x, fixing flag\n",
254 		    dig_port->tc_port_name, live_status_mask, valid_hpd_mask);
255 
256 	dig_port->tc_legacy_port = !dig_port->tc_legacy_port;
257 }
258 
259 static u32 icl_tc_port_live_status_mask(struct intel_digital_port *dig_port)
260 {
261 	struct drm_i915_private *i915 = to_i915(dig_port->base.base.dev);
262 	u32 isr_bit = i915->display.hotplug.pch_hpd[dig_port->base.hpd_pin];
263 	u32 mask = 0;
264 	u32 val;
265 
266 	val = intel_de_read(i915, PORT_TX_DFLEXDPSP(dig_port->tc_phy_fia));
267 
268 	if (val == 0xffffffff) {
269 		drm_dbg_kms(&i915->drm,
270 			    "Port %s: PHY in TCCOLD, nothing connected\n",
271 			    dig_port->tc_port_name);
272 		return mask;
273 	}
274 
275 	if (val & TC_LIVE_STATE_TBT(dig_port->tc_phy_fia_idx))
276 		mask |= BIT(TC_PORT_TBT_ALT);
277 	if (val & TC_LIVE_STATE_TC(dig_port->tc_phy_fia_idx))
278 		mask |= BIT(TC_PORT_DP_ALT);
279 
280 	if (intel_de_read(i915, SDEISR) & isr_bit)
281 		mask |= BIT(TC_PORT_LEGACY);
282 
283 	/* The sink can be connected only in a single mode. */
284 	if (!drm_WARN_ON_ONCE(&i915->drm, hweight32(mask) > 1))
285 		tc_port_fixup_legacy_flag(dig_port, mask);
286 
287 	return mask;
288 }
289 
290 static u32 adl_tc_port_live_status_mask(struct intel_digital_port *dig_port)
291 {
292 	struct drm_i915_private *i915 = to_i915(dig_port->base.base.dev);
293 	enum tc_port tc_port = intel_port_to_tc(i915, dig_port->base.port);
294 	u32 isr_bit = i915->display.hotplug.pch_hpd[dig_port->base.hpd_pin];
295 	u32 val, mask = 0;
296 
297 	/*
298 	 * On ADL-P HW/FW will wake from TCCOLD to complete the read access of
299 	 * registers in IOM. Note that this doesn't apply to PHY and FIA
300 	 * registers.
301 	 */
302 	val = intel_de_read(i915, TCSS_DDI_STATUS(tc_port));
303 	if (val & TCSS_DDI_STATUS_HPD_LIVE_STATUS_ALT)
304 		mask |= BIT(TC_PORT_DP_ALT);
305 	if (val & TCSS_DDI_STATUS_HPD_LIVE_STATUS_TBT)
306 		mask |= BIT(TC_PORT_TBT_ALT);
307 
308 	if (intel_de_read(i915, SDEISR) & isr_bit)
309 		mask |= BIT(TC_PORT_LEGACY);
310 
311 	/* The sink can be connected only in a single mode. */
312 	if (!drm_WARN_ON(&i915->drm, hweight32(mask) > 1))
313 		tc_port_fixup_legacy_flag(dig_port, mask);
314 
315 	return mask;
316 }
317 
318 static u32 tc_port_live_status_mask(struct intel_digital_port *dig_port)
319 {
320 	struct drm_i915_private *i915 = to_i915(dig_port->base.base.dev);
321 
322 	if (IS_ALDERLAKE_P(i915))
323 		return adl_tc_port_live_status_mask(dig_port);
324 
325 	return icl_tc_port_live_status_mask(dig_port);
326 }
327 
328 /*
329  * Return the PHY status complete flag indicating that display can acquire the
330  * PHY ownership. The IOM firmware sets this flag when a DP-alt or legacy sink
331  * is connected and it's ready to switch the ownership to display. The flag
332  * will be left cleared when a TBT-alt sink is connected, where the PHY is
333  * owned by the TBT subsystem and so switching the ownership to display is not
334  * required.
335  */
336 static bool icl_tc_phy_status_complete(struct intel_digital_port *dig_port)
337 {
338 	struct drm_i915_private *i915 = to_i915(dig_port->base.base.dev);
339 	u32 val;
340 
341 	val = intel_de_read(i915, PORT_TX_DFLEXDPPMS(dig_port->tc_phy_fia));
342 	if (val == 0xffffffff) {
343 		drm_dbg_kms(&i915->drm,
344 			    "Port %s: PHY in TCCOLD, assuming not complete\n",
345 			    dig_port->tc_port_name);
346 		return false;
347 	}
348 
349 	return val & DP_PHY_MODE_STATUS_COMPLETED(dig_port->tc_phy_fia_idx);
350 }
351 
352 /*
353  * Return the PHY status complete flag indicating that display can acquire the
354  * PHY ownership. The IOM firmware sets this flag when it's ready to switch
355  * the ownership to display, regardless of what sink is connected (TBT-alt,
356  * DP-alt, legacy or nothing). For TBT-alt sinks the PHY is owned by the TBT
357  * subsystem and so switching the ownership to display is not required.
358  */
359 static bool adl_tc_phy_status_complete(struct intel_digital_port *dig_port)
360 {
361 	struct drm_i915_private *i915 = to_i915(dig_port->base.base.dev);
362 	enum tc_port tc_port = intel_port_to_tc(i915, dig_port->base.port);
363 	u32 val;
364 
365 	val = intel_de_read(i915, TCSS_DDI_STATUS(tc_port));
366 	if (val == 0xffffffff) {
367 		drm_dbg_kms(&i915->drm,
368 			    "Port %s: PHY in TCCOLD, assuming not complete\n",
369 			    dig_port->tc_port_name);
370 		return false;
371 	}
372 
373 	return val & TCSS_DDI_STATUS_READY;
374 }
375 
376 static bool tc_phy_status_complete(struct intel_digital_port *dig_port)
377 {
378 	struct drm_i915_private *i915 = to_i915(dig_port->base.base.dev);
379 
380 	if (IS_ALDERLAKE_P(i915))
381 		return adl_tc_phy_status_complete(dig_port);
382 
383 	return icl_tc_phy_status_complete(dig_port);
384 }
385 
386 static bool icl_tc_phy_take_ownership(struct intel_digital_port *dig_port,
387 				      bool take)
388 {
389 	struct drm_i915_private *i915 = to_i915(dig_port->base.base.dev);
390 	u32 val;
391 
392 	val = intel_de_read(i915, PORT_TX_DFLEXDPCSSS(dig_port->tc_phy_fia));
393 	if (val == 0xffffffff) {
394 		drm_dbg_kms(&i915->drm,
395 			    "Port %s: PHY in TCCOLD, can't %s ownership\n",
396 			    dig_port->tc_port_name, take ? "take" : "release");
397 
398 		return false;
399 	}
400 
401 	val &= ~DP_PHY_MODE_STATUS_NOT_SAFE(dig_port->tc_phy_fia_idx);
402 	if (take)
403 		val |= DP_PHY_MODE_STATUS_NOT_SAFE(dig_port->tc_phy_fia_idx);
404 
405 	intel_de_write(i915, PORT_TX_DFLEXDPCSSS(dig_port->tc_phy_fia), val);
406 
407 	return true;
408 }
409 
410 static bool adl_tc_phy_take_ownership(struct intel_digital_port *dig_port,
411 				      bool take)
412 {
413 	struct drm_i915_private *i915 = to_i915(dig_port->base.base.dev);
414 	enum port port = dig_port->base.port;
415 
416 	intel_de_rmw(i915, DDI_BUF_CTL(port), DDI_BUF_CTL_TC_PHY_OWNERSHIP,
417 		     take ? DDI_BUF_CTL_TC_PHY_OWNERSHIP : 0);
418 
419 	return true;
420 }
421 
422 static bool tc_phy_take_ownership(struct intel_digital_port *dig_port, bool take)
423 {
424 	struct drm_i915_private *i915 = to_i915(dig_port->base.base.dev);
425 
426 	if (IS_ALDERLAKE_P(i915))
427 		return adl_tc_phy_take_ownership(dig_port, take);
428 
429 	return icl_tc_phy_take_ownership(dig_port, take);
430 }
431 
432 static bool icl_tc_phy_is_owned(struct intel_digital_port *dig_port)
433 {
434 	struct drm_i915_private *i915 = to_i915(dig_port->base.base.dev);
435 	u32 val;
436 
437 	val = intel_de_read(i915, PORT_TX_DFLEXDPCSSS(dig_port->tc_phy_fia));
438 	if (val == 0xffffffff) {
439 		drm_dbg_kms(&i915->drm,
440 			    "Port %s: PHY in TCCOLD, assume not owned\n",
441 			    dig_port->tc_port_name);
442 		return false;
443 	}
444 
445 	return val & DP_PHY_MODE_STATUS_NOT_SAFE(dig_port->tc_phy_fia_idx);
446 }
447 
448 static bool adl_tc_phy_is_owned(struct intel_digital_port *dig_port)
449 {
450 	struct drm_i915_private *i915 = to_i915(dig_port->base.base.dev);
451 	enum port port = dig_port->base.port;
452 	u32 val;
453 
454 	val = intel_de_read(i915, DDI_BUF_CTL(port));
455 	return val & DDI_BUF_CTL_TC_PHY_OWNERSHIP;
456 }
457 
458 static bool tc_phy_is_owned(struct intel_digital_port *dig_port)
459 {
460 	struct drm_i915_private *i915 = to_i915(dig_port->base.base.dev);
461 
462 	if (IS_ALDERLAKE_P(i915))
463 		return adl_tc_phy_is_owned(dig_port);
464 
465 	return icl_tc_phy_is_owned(dig_port);
466 }
467 
468 /*
469  * This function implements the first part of the Connect Flow described by our
470  * specification, Gen11 TypeC Programming chapter. The rest of the flow (reading
471  * lanes, EDID, etc) is done as needed in the typical places.
472  *
473  * Unlike the other ports, type-C ports are not available to use as soon as we
474  * get a hotplug. The type-C PHYs can be shared between multiple controllers:
475  * display, USB, etc. As a result, handshaking through FIA is required around
476  * connect and disconnect to cleanly transfer ownership with the controller and
477  * set the type-C power state.
478  */
479 static void icl_tc_phy_connect(struct intel_digital_port *dig_port,
480 			       int required_lanes)
481 {
482 	struct drm_i915_private *i915 = to_i915(dig_port->base.base.dev);
483 	u32 live_status_mask;
484 	int max_lanes;
485 
486 	if (!tc_phy_status_complete(dig_port) &&
487 	    !drm_WARN_ON(&i915->drm, dig_port->tc_legacy_port)) {
488 		drm_dbg_kms(&i915->drm, "Port %s: PHY not ready\n",
489 			    dig_port->tc_port_name);
490 		goto out_set_tbt_alt_mode;
491 	}
492 
493 	live_status_mask = tc_port_live_status_mask(dig_port);
494 	if (!(live_status_mask & (BIT(TC_PORT_DP_ALT) | BIT(TC_PORT_LEGACY))) &&
495 	    !dig_port->tc_legacy_port) {
496 		drm_dbg_kms(&i915->drm, "Port %s: PHY ownership not required (live status %02x)\n",
497 			    dig_port->tc_port_name, live_status_mask);
498 		goto out_set_tbt_alt_mode;
499 	}
500 
501 	if (!tc_phy_take_ownership(dig_port, true) &&
502 	    !drm_WARN_ON(&i915->drm, dig_port->tc_legacy_port))
503 		goto out_set_tbt_alt_mode;
504 
505 	max_lanes = intel_tc_port_fia_max_lane_count(dig_port);
506 	if (dig_port->tc_legacy_port) {
507 		drm_WARN_ON(&i915->drm, max_lanes != 4);
508 		dig_port->tc_mode = TC_PORT_LEGACY;
509 
510 		return;
511 	}
512 
513 	/*
514 	 * Now we have to re-check the live state, in case the port recently
515 	 * became disconnected. Not necessary for legacy mode.
516 	 */
517 	if (!(tc_port_live_status_mask(dig_port) & BIT(TC_PORT_DP_ALT))) {
518 		drm_dbg_kms(&i915->drm, "Port %s: PHY sudden disconnect\n",
519 			    dig_port->tc_port_name);
520 		goto out_release_phy;
521 	}
522 
523 	if (max_lanes < required_lanes) {
524 		drm_dbg_kms(&i915->drm,
525 			    "Port %s: PHY max lanes %d < required lanes %d\n",
526 			    dig_port->tc_port_name,
527 			    max_lanes, required_lanes);
528 		goto out_release_phy;
529 	}
530 
531 	dig_port->tc_mode = TC_PORT_DP_ALT;
532 
533 	return;
534 
535 out_release_phy:
536 	tc_phy_take_ownership(dig_port, false);
537 out_set_tbt_alt_mode:
538 	dig_port->tc_mode = TC_PORT_TBT_ALT;
539 }
540 
541 /*
542  * See the comment at the connect function. This implements the Disconnect
543  * Flow.
544  */
545 static void icl_tc_phy_disconnect(struct intel_digital_port *dig_port)
546 {
547 	switch (dig_port->tc_mode) {
548 	case TC_PORT_LEGACY:
549 	case TC_PORT_DP_ALT:
550 		tc_phy_take_ownership(dig_port, false);
551 		fallthrough;
552 	case TC_PORT_TBT_ALT:
553 		dig_port->tc_mode = TC_PORT_DISCONNECTED;
554 		fallthrough;
555 	case TC_PORT_DISCONNECTED:
556 		break;
557 	default:
558 		MISSING_CASE(dig_port->tc_mode);
559 	}
560 }
561 
562 static bool tc_phy_is_ready_and_owned(struct intel_digital_port *dig_port,
563 				      bool phy_is_ready, bool phy_is_owned)
564 {
565 	struct drm_i915_private *i915 = to_i915(dig_port->base.base.dev);
566 
567 	drm_WARN_ON(&i915->drm, phy_is_owned && !phy_is_ready);
568 
569 	return phy_is_ready && phy_is_owned;
570 }
571 
572 static bool tc_phy_is_connected(struct intel_digital_port *dig_port,
573 				enum icl_port_dpll_id port_pll_type)
574 {
575 	struct intel_encoder *encoder = &dig_port->base;
576 	struct drm_i915_private *i915 = to_i915(encoder->base.dev);
577 	bool phy_is_ready = tc_phy_status_complete(dig_port);
578 	bool phy_is_owned = tc_phy_is_owned(dig_port);
579 	bool is_connected;
580 
581 	if (tc_phy_is_ready_and_owned(dig_port, phy_is_ready, phy_is_owned))
582 		is_connected = port_pll_type == ICL_PORT_DPLL_MG_PHY;
583 	else
584 		is_connected = port_pll_type == ICL_PORT_DPLL_DEFAULT;
585 
586 	drm_dbg_kms(&i915->drm,
587 		    "Port %s: PHY connected: %s (ready: %s, owned: %s, pll_type: %s)\n",
588 		    dig_port->tc_port_name,
589 		    str_yes_no(is_connected),
590 		    str_yes_no(phy_is_ready),
591 		    str_yes_no(phy_is_owned),
592 		    port_pll_type == ICL_PORT_DPLL_DEFAULT ? "tbt" : "non-tbt");
593 
594 	return is_connected;
595 }
596 
597 static void tc_phy_wait_for_ready(struct intel_digital_port *dig_port)
598 {
599 	struct drm_i915_private *i915 = to_i915(dig_port->base.base.dev);
600 
601 	if (wait_for(tc_phy_status_complete(dig_port), 100))
602 		drm_err(&i915->drm, "Port %s: timeout waiting for PHY ready\n",
603 			dig_port->tc_port_name);
604 }
605 
606 static enum tc_port_mode
607 hpd_mask_to_tc_mode(u32 live_status_mask)
608 {
609 	if (live_status_mask)
610 		return fls(live_status_mask) - 1;
611 
612 	return TC_PORT_DISCONNECTED;
613 }
614 
615 static enum tc_port_mode
616 tc_phy_hpd_live_mode(struct intel_digital_port *dig_port)
617 {
618 	u32 live_status_mask = tc_port_live_status_mask(dig_port);
619 
620 	return hpd_mask_to_tc_mode(live_status_mask);
621 }
622 
623 static enum tc_port_mode
624 get_tc_mode_in_phy_owned_state(struct intel_digital_port *dig_port,
625 			       enum tc_port_mode live_mode)
626 {
627 	switch (live_mode) {
628 	case TC_PORT_LEGACY:
629 	case TC_PORT_DP_ALT:
630 		return live_mode;
631 	default:
632 		MISSING_CASE(live_mode);
633 		fallthrough;
634 	case TC_PORT_TBT_ALT:
635 	case TC_PORT_DISCONNECTED:
636 		if (dig_port->tc_legacy_port)
637 			return TC_PORT_LEGACY;
638 		else
639 			return TC_PORT_DP_ALT;
640 	}
641 }
642 
643 static enum tc_port_mode
644 get_tc_mode_in_phy_not_owned_state(struct intel_digital_port *dig_port,
645 				   enum tc_port_mode live_mode)
646 {
647 	switch (live_mode) {
648 	case TC_PORT_LEGACY:
649 		return TC_PORT_DISCONNECTED;
650 	case TC_PORT_DP_ALT:
651 	case TC_PORT_TBT_ALT:
652 		return TC_PORT_TBT_ALT;
653 	default:
654 		MISSING_CASE(live_mode);
655 		fallthrough;
656 	case TC_PORT_DISCONNECTED:
657 		if (dig_port->tc_legacy_port)
658 			return TC_PORT_DISCONNECTED;
659 		else
660 			return TC_PORT_TBT_ALT;
661 	}
662 }
663 
664 static enum tc_port_mode
665 intel_tc_port_get_current_mode(struct intel_digital_port *dig_port)
666 {
667 	struct drm_i915_private *i915 = to_i915(dig_port->base.base.dev);
668 	enum tc_port_mode live_mode = tc_phy_hpd_live_mode(dig_port);
669 	bool phy_is_ready;
670 	bool phy_is_owned;
671 	enum tc_port_mode mode;
672 
673 	/*
674 	 * For legacy ports the IOM firmware initializes the PHY during boot-up
675 	 * and system resume whether or not a sink is connected. Wait here for
676 	 * the initialization to get ready.
677 	 */
678 	if (dig_port->tc_legacy_port)
679 		tc_phy_wait_for_ready(dig_port);
680 
681 	phy_is_ready = tc_phy_status_complete(dig_port);
682 	phy_is_owned = tc_phy_is_owned(dig_port);
683 
684 	if (!tc_phy_is_ready_and_owned(dig_port, phy_is_ready, phy_is_owned)) {
685 		mode = get_tc_mode_in_phy_not_owned_state(dig_port, live_mode);
686 	} else {
687 		drm_WARN_ON(&i915->drm, live_mode == TC_PORT_TBT_ALT);
688 		mode = get_tc_mode_in_phy_owned_state(dig_port, live_mode);
689 	}
690 
691 	drm_dbg_kms(&i915->drm,
692 		    "Port %s: PHY mode: %s (ready: %s, owned: %s, HPD: %s)\n",
693 		    dig_port->tc_port_name,
694 		    tc_port_mode_name(mode),
695 		    str_yes_no(phy_is_ready),
696 		    str_yes_no(phy_is_owned),
697 		    tc_port_mode_name(live_mode));
698 
699 	return mode;
700 }
701 
702 static enum tc_port_mode default_tc_mode(struct intel_digital_port *dig_port)
703 {
704 	if (dig_port->tc_legacy_port)
705 		return TC_PORT_LEGACY;
706 
707 	return TC_PORT_TBT_ALT;
708 }
709 
710 static enum tc_port_mode
711 hpd_mask_to_target_mode(struct intel_digital_port *dig_port, u32 live_status_mask)
712 {
713 	enum tc_port_mode mode = hpd_mask_to_tc_mode(live_status_mask);
714 
715 	if (mode != TC_PORT_DISCONNECTED)
716 		return mode;
717 
718 	return default_tc_mode(dig_port);
719 }
720 
721 static enum tc_port_mode
722 intel_tc_port_get_target_mode(struct intel_digital_port *dig_port)
723 {
724 	u32 live_status_mask = tc_port_live_status_mask(dig_port);
725 
726 	return hpd_mask_to_target_mode(dig_port, live_status_mask);
727 }
728 
729 static void intel_tc_port_reset_mode(struct intel_digital_port *dig_port,
730 				     int required_lanes, bool force_disconnect)
731 {
732 	struct drm_i915_private *i915 = to_i915(dig_port->base.base.dev);
733 	enum tc_port_mode old_tc_mode = dig_port->tc_mode;
734 
735 	intel_display_power_flush_work(i915);
736 	if (!intel_tc_cold_requires_aux_pw(dig_port)) {
737 		enum intel_display_power_domain aux_domain;
738 		bool aux_powered;
739 
740 		aux_domain = intel_aux_power_domain(dig_port);
741 		aux_powered = intel_display_power_is_enabled(i915, aux_domain);
742 		drm_WARN_ON(&i915->drm, aux_powered);
743 	}
744 
745 	icl_tc_phy_disconnect(dig_port);
746 	if (!force_disconnect)
747 		icl_tc_phy_connect(dig_port, required_lanes);
748 
749 	drm_dbg_kms(&i915->drm, "Port %s: TC port mode reset (%s -> %s)\n",
750 		    dig_port->tc_port_name,
751 		    tc_port_mode_name(old_tc_mode),
752 		    tc_port_mode_name(dig_port->tc_mode));
753 }
754 
755 static bool intel_tc_port_needs_reset(struct intel_digital_port *dig_port)
756 {
757 	return intel_tc_port_get_target_mode(dig_port) != dig_port->tc_mode;
758 }
759 
760 static void intel_tc_port_update_mode(struct intel_digital_port *dig_port,
761 				      int required_lanes, bool force_disconnect)
762 {
763 	enum intel_display_power_domain domain;
764 	intel_wakeref_t wref;
765 	bool needs_reset = force_disconnect;
766 
767 	if (!needs_reset) {
768 		/* Get power domain required to check the hotplug live status. */
769 		wref = tc_cold_block(dig_port, &domain);
770 		needs_reset = intel_tc_port_needs_reset(dig_port);
771 		tc_cold_unblock(dig_port, domain, wref);
772 	}
773 
774 	if (!needs_reset)
775 		return;
776 
777 	/* Get power domain required for resetting the mode. */
778 	wref = tc_cold_block_in_mode(dig_port, TC_PORT_DISCONNECTED, &domain);
779 
780 	intel_tc_port_reset_mode(dig_port, required_lanes, force_disconnect);
781 
782 	/* Get power domain matching the new mode after reset. */
783 	tc_cold_unblock(dig_port, dig_port->tc_lock_power_domain,
784 			fetch_and_zero(&dig_port->tc_lock_wakeref));
785 	if (dig_port->tc_mode != TC_PORT_DISCONNECTED)
786 		dig_port->tc_lock_wakeref = tc_cold_block(dig_port,
787 							  &dig_port->tc_lock_power_domain);
788 
789 	tc_cold_unblock(dig_port, domain, wref);
790 }
791 
792 static void __intel_tc_port_get_link(struct intel_digital_port *dig_port)
793 {
794 	dig_port->tc_link_refcount++;
795 }
796 
797 static void __intel_tc_port_put_link(struct intel_digital_port *dig_port)
798 {
799 	dig_port->tc_link_refcount--;
800 }
801 
802 static bool tc_port_is_enabled(struct intel_digital_port *dig_port)
803 {
804 	struct drm_i915_private *i915 = to_i915(dig_port->base.base.dev);
805 
806 	assert_tc_port_power_enabled(dig_port);
807 
808 	return intel_de_read(i915, DDI_BUF_CTL(dig_port->base.port)) &
809 	       DDI_BUF_CTL_ENABLE;
810 }
811 
812 /**
813  * intel_tc_port_init_mode: Read out HW state and init the given port's TypeC mode
814  * @dig_port: digital port
815  *
816  * Read out the HW state and initialize the TypeC mode of @dig_port. The mode
817  * will be locked until intel_tc_port_sanitize_mode() is called.
818  */
819 void intel_tc_port_init_mode(struct intel_digital_port *dig_port)
820 {
821 	struct drm_i915_private *i915 = to_i915(dig_port->base.base.dev);
822 	intel_wakeref_t tc_cold_wref;
823 	enum intel_display_power_domain domain;
824 	bool update_mode = false;
825 
826 	mutex_lock(&dig_port->tc_lock);
827 
828 	drm_WARN_ON(&i915->drm, dig_port->tc_mode != TC_PORT_DISCONNECTED);
829 	drm_WARN_ON(&i915->drm, dig_port->tc_lock_wakeref);
830 	drm_WARN_ON(&i915->drm, dig_port->tc_link_refcount);
831 
832 	tc_cold_wref = tc_cold_block(dig_port, &domain);
833 
834 	dig_port->tc_mode = intel_tc_port_get_current_mode(dig_port);
835 	/*
836 	 * Save the initial mode for the state check in
837 	 * intel_tc_port_sanitize_mode().
838 	 */
839 	dig_port->tc_init_mode = dig_port->tc_mode;
840 	if (dig_port->tc_mode != TC_PORT_DISCONNECTED)
841 		dig_port->tc_lock_wakeref =
842 			tc_cold_block(dig_port, &dig_port->tc_lock_power_domain);
843 
844 	/*
845 	 * The PHY needs to be connected for AUX to work during HW readout and
846 	 * MST topology resume, but the PHY mode can only be changed if the
847 	 * port is disabled.
848 	 *
849 	 * An exception is the case where BIOS leaves the PHY incorrectly
850 	 * disconnected on an enabled legacy port. Work around that by
851 	 * connecting the PHY even though the port is enabled. This doesn't
852 	 * cause a problem as the PHY ownership state is ignored by the
853 	 * IOM/TCSS firmware (only display can own the PHY in that case).
854 	 */
855 	if (!tc_port_is_enabled(dig_port)) {
856 		update_mode = true;
857 	} else if (dig_port->tc_mode == TC_PORT_DISCONNECTED) {
858 		drm_WARN_ON(&i915->drm, !dig_port->tc_legacy_port);
859 		drm_err(&i915->drm,
860 			"Port %s: PHY disconnected on enabled port, connecting it\n",
861 			dig_port->tc_port_name);
862 		update_mode = true;
863 	}
864 
865 	if (update_mode)
866 		intel_tc_port_update_mode(dig_port, 1, false);
867 
868 	/* Prevent changing dig_port->tc_mode until intel_tc_port_sanitize_mode() is called. */
869 	__intel_tc_port_get_link(dig_port);
870 
871 	tc_cold_unblock(dig_port, domain, tc_cold_wref);
872 
873 	mutex_unlock(&dig_port->tc_lock);
874 }
875 
876 static bool tc_port_has_active_links(struct intel_digital_port *dig_port,
877 				     const struct intel_crtc_state *crtc_state)
878 {
879 	struct drm_i915_private *i915 = to_i915(dig_port->base.base.dev);
880 	enum icl_port_dpll_id pll_type = ICL_PORT_DPLL_DEFAULT;
881 	int active_links = 0;
882 
883 	if (dig_port->dp.is_mst) {
884 		/* TODO: get the PLL type for MST, once HW readout is done for it. */
885 		active_links = intel_dp_mst_encoder_active_links(dig_port);
886 	} else if (crtc_state && crtc_state->hw.active) {
887 		pll_type = intel_ddi_port_pll_type(&dig_port->base, crtc_state);
888 		active_links = 1;
889 	}
890 
891 	if (active_links && !tc_phy_is_connected(dig_port, pll_type))
892 		drm_err(&i915->drm,
893 			"Port %s: PHY disconnected with %d active link(s)\n",
894 			dig_port->tc_port_name, active_links);
895 
896 	return active_links;
897 }
898 
899 /**
900  * intel_tc_port_sanitize_mode: Sanitize the given port's TypeC mode
901  * @dig_port: digital port
902  * @crtc_state: atomic state of CRTC connected to @dig_port
903  *
904  * Sanitize @dig_port's TypeC mode wrt. the encoder's state right after driver
905  * loading and system resume:
906  * If the encoder is enabled keep the TypeC mode/PHY connected state locked until
907  * the encoder is disabled.
908  * If the encoder is disabled make sure the PHY is disconnected.
909  * @crtc_state is valid if @dig_port is enabled, NULL otherwise.
910  */
911 void intel_tc_port_sanitize_mode(struct intel_digital_port *dig_port,
912 				 const struct intel_crtc_state *crtc_state)
913 {
914 	struct drm_i915_private *i915 = to_i915(dig_port->base.base.dev);
915 
916 	mutex_lock(&dig_port->tc_lock);
917 
918 	drm_WARN_ON(&i915->drm, dig_port->tc_link_refcount != 1);
919 	if (!tc_port_has_active_links(dig_port, crtc_state)) {
920 		/*
921 		 * TBT-alt is the default mode in any case the PHY ownership is not
922 		 * held (regardless of the sink's connected live state), so
923 		 * we'll just switch to disconnected mode from it here without
924 		 * a note.
925 		 */
926 		if (dig_port->tc_init_mode != TC_PORT_TBT_ALT &&
927 		    dig_port->tc_init_mode != TC_PORT_DISCONNECTED)
928 			drm_dbg_kms(&i915->drm,
929 				    "Port %s: PHY left in %s mode on disabled port, disconnecting it\n",
930 				    dig_port->tc_port_name,
931 				    tc_port_mode_name(dig_port->tc_init_mode));
932 		icl_tc_phy_disconnect(dig_port);
933 		__intel_tc_port_put_link(dig_port);
934 
935 		tc_cold_unblock(dig_port, dig_port->tc_lock_power_domain,
936 				fetch_and_zero(&dig_port->tc_lock_wakeref));
937 	}
938 
939 	drm_dbg_kms(&i915->drm, "Port %s: sanitize mode (%s)\n",
940 		    dig_port->tc_port_name,
941 		    tc_port_mode_name(dig_port->tc_mode));
942 
943 	mutex_unlock(&dig_port->tc_lock);
944 }
945 
946 /*
947  * The type-C ports are different because even when they are connected, they may
948  * not be available/usable by the graphics driver: see the comment on
949  * icl_tc_phy_connect(). So in our driver instead of adding the additional
950  * concept of "usable" and make everything check for "connected and usable" we
951  * define a port as "connected" when it is not only connected, but also when it
952  * is usable by the rest of the driver. That maintains the old assumption that
953  * connected ports are usable, and avoids exposing to the users objects they
954  * can't really use.
955  */
956 bool intel_tc_port_connected_locked(struct intel_encoder *encoder)
957 {
958 	struct intel_digital_port *dig_port = enc_to_dig_port(encoder);
959 	struct drm_i915_private *i915 = to_i915(dig_port->base.base.dev);
960 
961 	drm_WARN_ON(&i915->drm, !intel_tc_port_ref_held(dig_port));
962 
963 	return tc_port_live_status_mask(dig_port) & BIT(dig_port->tc_mode);
964 }
965 
966 bool intel_tc_port_connected(struct intel_encoder *encoder)
967 {
968 	struct intel_digital_port *dig_port = enc_to_dig_port(encoder);
969 	bool is_connected;
970 
971 	intel_tc_port_lock(dig_port);
972 	is_connected = intel_tc_port_connected_locked(encoder);
973 	intel_tc_port_unlock(dig_port);
974 
975 	return is_connected;
976 }
977 
978 static void __intel_tc_port_lock(struct intel_digital_port *dig_port,
979 				 int required_lanes)
980 {
981 	struct drm_i915_private *i915 = to_i915(dig_port->base.base.dev);
982 
983 	mutex_lock(&dig_port->tc_lock);
984 
985 	cancel_delayed_work(&dig_port->tc_disconnect_phy_work);
986 
987 	if (!dig_port->tc_link_refcount)
988 		intel_tc_port_update_mode(dig_port, required_lanes,
989 					  false);
990 
991 	drm_WARN_ON(&i915->drm, dig_port->tc_mode == TC_PORT_DISCONNECTED);
992 	drm_WARN_ON(&i915->drm, dig_port->tc_mode != TC_PORT_TBT_ALT &&
993 				!tc_phy_is_owned(dig_port));
994 }
995 
996 void intel_tc_port_lock(struct intel_digital_port *dig_port)
997 {
998 	__intel_tc_port_lock(dig_port, 1);
999 }
1000 
1001 /**
1002  * intel_tc_port_disconnect_phy_work: disconnect TypeC PHY from display port
1003  * @dig_port: digital port
1004  *
1005  * Disconnect the given digital port from its TypeC PHY (handing back the
1006  * control of the PHY to the TypeC subsystem). This will happen in a delayed
1007  * manner after each aux transactions and modeset disables.
1008  */
1009 static void intel_tc_port_disconnect_phy_work(struct work_struct *work)
1010 {
1011 	struct intel_digital_port *dig_port =
1012 		container_of(work, struct intel_digital_port, tc_disconnect_phy_work.work);
1013 
1014 	mutex_lock(&dig_port->tc_lock);
1015 
1016 	if (!dig_port->tc_link_refcount)
1017 		intel_tc_port_update_mode(dig_port, 1, true);
1018 
1019 	mutex_unlock(&dig_port->tc_lock);
1020 }
1021 
1022 /**
1023  * intel_tc_port_flush_work: flush the work disconnecting the PHY
1024  * @dig_port: digital port
1025  *
1026  * Flush the delayed work disconnecting an idle PHY.
1027  */
1028 void intel_tc_port_flush_work(struct intel_digital_port *dig_port)
1029 {
1030 	flush_delayed_work(&dig_port->tc_disconnect_phy_work);
1031 }
1032 
1033 void intel_tc_port_unlock(struct intel_digital_port *dig_port)
1034 {
1035 	if (!dig_port->tc_link_refcount && dig_port->tc_mode != TC_PORT_DISCONNECTED)
1036 		queue_delayed_work(system_unbound_wq, &dig_port->tc_disconnect_phy_work,
1037 				   msecs_to_jiffies(1000));
1038 
1039 	mutex_unlock(&dig_port->tc_lock);
1040 }
1041 
1042 bool intel_tc_port_ref_held(struct intel_digital_port *dig_port)
1043 {
1044 	return mutex_is_locked(&dig_port->tc_lock) ||
1045 	       dig_port->tc_link_refcount;
1046 }
1047 
1048 void intel_tc_port_get_link(struct intel_digital_port *dig_port,
1049 			    int required_lanes)
1050 {
1051 	__intel_tc_port_lock(dig_port, required_lanes);
1052 	__intel_tc_port_get_link(dig_port);
1053 	intel_tc_port_unlock(dig_port);
1054 }
1055 
1056 void intel_tc_port_put_link(struct intel_digital_port *dig_port)
1057 {
1058 	intel_tc_port_lock(dig_port);
1059 	__intel_tc_port_put_link(dig_port);
1060 	intel_tc_port_unlock(dig_port);
1061 
1062 	/*
1063 	 * Disconnecting the PHY after the PHY's PLL gets disabled may
1064 	 * hang the system on ADL-P, so disconnect the PHY here synchronously.
1065 	 * TODO: remove this once the root cause of the ordering requirement
1066 	 * is found/fixed.
1067 	 */
1068 	intel_tc_port_flush_work(dig_port);
1069 }
1070 
1071 static bool
1072 tc_has_modular_fia(struct drm_i915_private *i915, struct intel_digital_port *dig_port)
1073 {
1074 	enum intel_display_power_domain domain;
1075 	intel_wakeref_t wakeref;
1076 	u32 val;
1077 
1078 	if (!INTEL_INFO(i915)->display.has_modular_fia)
1079 		return false;
1080 
1081 	mutex_lock(&dig_port->tc_lock);
1082 	wakeref = tc_cold_block(dig_port, &domain);
1083 	val = intel_de_read(i915, PORT_TX_DFLEXDPSP(FIA1));
1084 	tc_cold_unblock(dig_port, domain, wakeref);
1085 	mutex_unlock(&dig_port->tc_lock);
1086 
1087 	drm_WARN_ON(&i915->drm, val == 0xffffffff);
1088 
1089 	return val & MODULAR_FIA_MASK;
1090 }
1091 
1092 static void
1093 tc_port_load_fia_params(struct drm_i915_private *i915, struct intel_digital_port *dig_port)
1094 {
1095 	enum port port = dig_port->base.port;
1096 	enum tc_port tc_port = intel_port_to_tc(i915, port);
1097 
1098 	/*
1099 	 * Each Modular FIA instance houses 2 TC ports. In SOC that has more
1100 	 * than two TC ports, there are multiple instances of Modular FIA.
1101 	 */
1102 	if (tc_has_modular_fia(i915, dig_port)) {
1103 		dig_port->tc_phy_fia = tc_port / 2;
1104 		dig_port->tc_phy_fia_idx = tc_port % 2;
1105 	} else {
1106 		dig_port->tc_phy_fia = FIA1;
1107 		dig_port->tc_phy_fia_idx = tc_port;
1108 	}
1109 }
1110 
1111 void intel_tc_port_init(struct intel_digital_port *dig_port, bool is_legacy)
1112 {
1113 	struct drm_i915_private *i915 = to_i915(dig_port->base.base.dev);
1114 	enum port port = dig_port->base.port;
1115 	enum tc_port tc_port = intel_port_to_tc(i915, port);
1116 
1117 	if (drm_WARN_ON(&i915->drm, tc_port == TC_PORT_NONE))
1118 		return;
1119 
1120 	snprintf(dig_port->tc_port_name, sizeof(dig_port->tc_port_name),
1121 		 "%c/TC#%d", port_name(port), tc_port + 1);
1122 
1123 	mutex_init(&dig_port->tc_lock);
1124 	INIT_DELAYED_WORK(&dig_port->tc_disconnect_phy_work, intel_tc_port_disconnect_phy_work);
1125 	dig_port->tc_legacy_port = is_legacy;
1126 	dig_port->tc_mode = TC_PORT_DISCONNECTED;
1127 	dig_port->tc_link_refcount = 0;
1128 	tc_port_load_fia_params(i915, dig_port);
1129 
1130 	intel_tc_port_init_mode(dig_port);
1131 }
1132