2323#include "intel_modeset_lock.h"
2424#include "intel_tc.h"
2525
26+ #define DP_PIN_ASSIGNMENT_NONE 0x0
2627#define DP_PIN_ASSIGNMENT_C 0x3
2728#define DP_PIN_ASSIGNMENT_D 0x4
2829#define DP_PIN_ASSIGNMENT_E 0x5
@@ -66,6 +67,7 @@ struct intel_tc_port {
6667 enum tc_port_mode init_mode ;
6768 enum phy_fia phy_fia ;
6869 u8 phy_fia_idx ;
70+ u8 max_lane_count ;
6971};
7072
7173static enum intel_display_power_domain
@@ -307,6 +309,8 @@ static int lnl_tc_port_get_max_lane_count(struct intel_digital_port *dig_port)
307309 REG_FIELD_GET (TCSS_DDI_STATUS_PIN_ASSIGNMENT_MASK , val );
308310
309311 switch (pin_assignment ) {
312+ case DP_PIN_ASSIGNMENT_NONE :
313+ return 0 ;
310314 default :
311315 MISSING_CASE (pin_assignment );
312316 fallthrough ;
@@ -365,12 +369,12 @@ static int intel_tc_port_get_max_lane_count(struct intel_digital_port *dig_port)
365369 }
366370}
367371
368- int intel_tc_port_max_lane_count (struct intel_digital_port * dig_port )
372+ static int get_max_lane_count (struct intel_tc_port * tc )
369373{
370- struct intel_display * display = to_intel_display (dig_port );
371- struct intel_tc_port * tc = to_tc_port ( dig_port ) ;
374+ struct intel_display * display = to_intel_display (tc -> dig_port );
375+ struct intel_digital_port * dig_port = tc -> dig_port ;
372376
373- if (! intel_encoder_is_tc ( & dig_port -> base ) || tc -> mode != TC_PORT_DP_ALT )
377+ if (tc -> mode != TC_PORT_DP_ALT )
374378 return 4 ;
375379
376380 assert_tc_cold_blocked (tc );
@@ -384,6 +388,25 @@ int intel_tc_port_max_lane_count(struct intel_digital_port *dig_port)
384388 return intel_tc_port_get_max_lane_count (dig_port );
385389}
386390
391+ static void read_pin_configuration (struct intel_tc_port * tc )
392+ {
393+ tc -> max_lane_count = get_max_lane_count (tc );
394+ }
395+
396+ int intel_tc_port_max_lane_count (struct intel_digital_port * dig_port )
397+ {
398+ struct intel_display * display = to_intel_display (dig_port );
399+ struct intel_tc_port * tc = to_tc_port (dig_port );
400+
401+ if (!intel_encoder_is_tc (& dig_port -> base ))
402+ return 4 ;
403+
404+ if (DISPLAY_VER (display ) < 20 )
405+ return get_max_lane_count (tc );
406+
407+ return tc -> max_lane_count ;
408+ }
409+
387410void intel_tc_port_set_fia_lane_count (struct intel_digital_port * dig_port ,
388411 int required_lanes )
389412{
@@ -596,9 +619,12 @@ static void icl_tc_phy_get_hw_state(struct intel_tc_port *tc)
596619 tc_cold_wref = __tc_cold_block (tc , & domain );
597620
598621 tc -> mode = tc_phy_get_current_mode (tc );
599- if (tc -> mode != TC_PORT_DISCONNECTED )
622+ if (tc -> mode != TC_PORT_DISCONNECTED ) {
600623 tc -> lock_wakeref = tc_cold_block (tc );
601624
625+ read_pin_configuration (tc );
626+ }
627+
602628 __tc_cold_unblock (tc , domain , tc_cold_wref );
603629}
604630
@@ -656,8 +682,11 @@ static bool icl_tc_phy_connect(struct intel_tc_port *tc,
656682
657683 tc -> lock_wakeref = tc_cold_block (tc );
658684
659- if (tc -> mode == TC_PORT_TBT_ALT )
685+ if (tc -> mode == TC_PORT_TBT_ALT ) {
686+ read_pin_configuration (tc );
687+
660688 return true;
689+ }
661690
662691 if ((!tc_phy_is_ready (tc ) ||
663692 !icl_tc_phy_take_ownership (tc , true)) &&
@@ -668,6 +697,7 @@ static bool icl_tc_phy_connect(struct intel_tc_port *tc,
668697 goto out_unblock_tc_cold ;
669698 }
670699
700+ read_pin_configuration (tc );
671701
672702 if (!tc_phy_verify_legacy_or_dp_alt_mode (tc , required_lanes ))
673703 goto out_release_phy ;
@@ -858,9 +888,12 @@ static void adlp_tc_phy_get_hw_state(struct intel_tc_port *tc)
858888 port_wakeref = intel_display_power_get (display , port_power_domain );
859889
860890 tc -> mode = tc_phy_get_current_mode (tc );
861- if (tc -> mode != TC_PORT_DISCONNECTED )
891+ if (tc -> mode != TC_PORT_DISCONNECTED ) {
862892 tc -> lock_wakeref = tc_cold_block (tc );
863893
894+ read_pin_configuration (tc );
895+ }
896+
864897 intel_display_power_put (display , port_power_domain , port_wakeref );
865898}
866899
@@ -873,6 +906,9 @@ static bool adlp_tc_phy_connect(struct intel_tc_port *tc, int required_lanes)
873906
874907 if (tc -> mode == TC_PORT_TBT_ALT ) {
875908 tc -> lock_wakeref = tc_cold_block (tc );
909+
910+ read_pin_configuration (tc );
911+
876912 return true;
877913 }
878914
@@ -894,6 +930,8 @@ static bool adlp_tc_phy_connect(struct intel_tc_port *tc, int required_lanes)
894930
895931 tc -> lock_wakeref = tc_cold_block (tc );
896932
933+ read_pin_configuration (tc );
934+
897935 if (!tc_phy_verify_legacy_or_dp_alt_mode (tc , required_lanes ))
898936 goto out_unblock_tc_cold ;
899937
@@ -1124,9 +1162,18 @@ static void xelpdp_tc_phy_get_hw_state(struct intel_tc_port *tc)
11241162 tc_cold_wref = __tc_cold_block (tc , & domain );
11251163
11261164 tc -> mode = tc_phy_get_current_mode (tc );
1127- if (tc -> mode != TC_PORT_DISCONNECTED )
1165+ if (tc -> mode != TC_PORT_DISCONNECTED ) {
11281166 tc -> lock_wakeref = tc_cold_block (tc );
11291167
1168+ read_pin_configuration (tc );
1169+ /*
1170+ * Set a valid lane count value for a DP-alt sink which got
1171+ * disconnected. The driver can only disable the output on this PHY.
1172+ */
1173+ if (tc -> max_lane_count == 0 )
1174+ tc -> max_lane_count = 4 ;
1175+ }
1176+
11301177 drm_WARN_ON (display -> drm ,
11311178 (tc -> mode == TC_PORT_DP_ALT || tc -> mode == TC_PORT_LEGACY ) &&
11321179 !xelpdp_tc_phy_tcss_power_is_enabled (tc ));
@@ -1138,14 +1185,19 @@ static bool xelpdp_tc_phy_connect(struct intel_tc_port *tc, int required_lanes)
11381185{
11391186 tc -> lock_wakeref = tc_cold_block (tc );
11401187
1141- if (tc -> mode == TC_PORT_TBT_ALT )
1188+ if (tc -> mode == TC_PORT_TBT_ALT ) {
1189+ read_pin_configuration (tc );
1190+
11421191 return true;
1192+ }
11431193
11441194 if (!xelpdp_tc_phy_enable_tcss_power (tc , true))
11451195 goto out_unblock_tccold ;
11461196
11471197 xelpdp_tc_phy_take_ownership (tc , true);
11481198
1199+ read_pin_configuration (tc );
1200+
11491201 if (!tc_phy_verify_legacy_or_dp_alt_mode (tc , required_lanes ))
11501202 goto out_release_phy ;
11511203
@@ -1226,14 +1278,19 @@ static void tc_phy_get_hw_state(struct intel_tc_port *tc)
12261278 tc -> phy_ops -> get_hw_state (tc );
12271279}
12281280
1229- static bool tc_phy_is_ready_and_owned (struct intel_tc_port * tc ,
1230- bool phy_is_ready , bool phy_is_owned )
1281+ /* Is the PHY owned by display i.e. is it in legacy or DP-alt mode? */
1282+ static bool tc_phy_owned_by_display (struct intel_tc_port * tc ,
1283+ bool phy_is_ready , bool phy_is_owned )
12311284{
12321285 struct intel_display * display = to_intel_display (tc -> dig_port );
12331286
1234- drm_WARN_ON (display -> drm , phy_is_owned && !phy_is_ready );
1287+ if (DISPLAY_VER (display ) < 20 ) {
1288+ drm_WARN_ON (display -> drm , phy_is_owned && !phy_is_ready );
12351289
1236- return phy_is_ready && phy_is_owned ;
1290+ return phy_is_ready && phy_is_owned ;
1291+ } else {
1292+ return phy_is_owned ;
1293+ }
12371294}
12381295
12391296static bool tc_phy_is_connected (struct intel_tc_port * tc ,
@@ -1244,7 +1301,7 @@ static bool tc_phy_is_connected(struct intel_tc_port *tc,
12441301 bool phy_is_owned = tc_phy_is_owned (tc );
12451302 bool is_connected ;
12461303
1247- if (tc_phy_is_ready_and_owned (tc , phy_is_ready , phy_is_owned ))
1304+ if (tc_phy_owned_by_display (tc , phy_is_ready , phy_is_owned ))
12481305 is_connected = port_pll_type == ICL_PORT_DPLL_MG_PHY ;
12491306 else
12501307 is_connected = port_pll_type == ICL_PORT_DPLL_DEFAULT ;
@@ -1352,7 +1409,7 @@ tc_phy_get_current_mode(struct intel_tc_port *tc)
13521409 phy_is_ready = tc_phy_is_ready (tc );
13531410 phy_is_owned = tc_phy_is_owned (tc );
13541411
1355- if (!tc_phy_is_ready_and_owned (tc , phy_is_ready , phy_is_owned )) {
1412+ if (!tc_phy_owned_by_display (tc , phy_is_ready , phy_is_owned )) {
13561413 mode = get_tc_mode_in_phy_not_owned_state (tc , live_mode );
13571414 } else {
13581415 drm_WARN_ON (display -> drm , live_mode == TC_PORT_TBT_ALT );
@@ -1441,11 +1498,11 @@ static void intel_tc_port_reset_mode(struct intel_tc_port *tc,
14411498 intel_display_power_flush_work (display );
14421499 if (!intel_tc_cold_requires_aux_pw (dig_port )) {
14431500 enum intel_display_power_domain aux_domain ;
1444- bool aux_powered ;
14451501
14461502 aux_domain = intel_aux_power_domain (dig_port );
1447- aux_powered = intel_display_power_is_enabled (display , aux_domain );
1448- drm_WARN_ON (display -> drm , aux_powered );
1503+ if (intel_display_power_is_enabled (display , aux_domain ))
1504+ drm_dbg_kms (display -> drm , "Port %s: AUX unexpectedly powered\n" ,
1505+ tc -> port_name );
14491506 }
14501507
14511508 tc_phy_disconnect (tc );
0 commit comments