23
23
#include "intel_modeset_lock.h"
24
24
#include "intel_tc.h"
25
25
26
+ #define DP_PIN_ASSIGNMENT_NONE 0x0
26
27
#define DP_PIN_ASSIGNMENT_C 0x3
27
28
#define DP_PIN_ASSIGNMENT_D 0x4
28
29
#define DP_PIN_ASSIGNMENT_E 0x5
@@ -66,6 +67,7 @@ struct intel_tc_port {
66
67
enum tc_port_mode init_mode ;
67
68
enum phy_fia phy_fia ;
68
69
u8 phy_fia_idx ;
70
+ u8 max_lane_count ;
69
71
};
70
72
71
73
static enum intel_display_power_domain
@@ -307,6 +309,8 @@ static int lnl_tc_port_get_max_lane_count(struct intel_digital_port *dig_port)
307
309
REG_FIELD_GET (TCSS_DDI_STATUS_PIN_ASSIGNMENT_MASK , val );
308
310
309
311
switch (pin_assignment ) {
312
+ case DP_PIN_ASSIGNMENT_NONE :
313
+ return 0 ;
310
314
default :
311
315
MISSING_CASE (pin_assignment );
312
316
fallthrough ;
@@ -365,12 +369,12 @@ static int intel_tc_port_get_max_lane_count(struct intel_digital_port *dig_port)
365
369
}
366
370
}
367
371
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 )
369
373
{
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 ;
372
376
373
- if (! intel_encoder_is_tc ( & dig_port -> base ) || tc -> mode != TC_PORT_DP_ALT )
377
+ if (tc -> mode != TC_PORT_DP_ALT )
374
378
return 4 ;
375
379
376
380
assert_tc_cold_blocked (tc );
@@ -384,6 +388,25 @@ int intel_tc_port_max_lane_count(struct intel_digital_port *dig_port)
384
388
return intel_tc_port_get_max_lane_count (dig_port );
385
389
}
386
390
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
+
387
410
void intel_tc_port_set_fia_lane_count (struct intel_digital_port * dig_port ,
388
411
int required_lanes )
389
412
{
@@ -596,9 +619,12 @@ static void icl_tc_phy_get_hw_state(struct intel_tc_port *tc)
596
619
tc_cold_wref = __tc_cold_block (tc , & domain );
597
620
598
621
tc -> mode = tc_phy_get_current_mode (tc );
599
- if (tc -> mode != TC_PORT_DISCONNECTED )
622
+ if (tc -> mode != TC_PORT_DISCONNECTED ) {
600
623
tc -> lock_wakeref = tc_cold_block (tc );
601
624
625
+ read_pin_configuration (tc );
626
+ }
627
+
602
628
__tc_cold_unblock (tc , domain , tc_cold_wref );
603
629
}
604
630
@@ -656,8 +682,11 @@ static bool icl_tc_phy_connect(struct intel_tc_port *tc,
656
682
657
683
tc -> lock_wakeref = tc_cold_block (tc );
658
684
659
- if (tc -> mode == TC_PORT_TBT_ALT )
685
+ if (tc -> mode == TC_PORT_TBT_ALT ) {
686
+ read_pin_configuration (tc );
687
+
660
688
return true;
689
+ }
661
690
662
691
if ((!tc_phy_is_ready (tc ) ||
663
692
!icl_tc_phy_take_ownership (tc , true)) &&
@@ -668,6 +697,7 @@ static bool icl_tc_phy_connect(struct intel_tc_port *tc,
668
697
goto out_unblock_tc_cold ;
669
698
}
670
699
700
+ read_pin_configuration (tc );
671
701
672
702
if (!tc_phy_verify_legacy_or_dp_alt_mode (tc , required_lanes ))
673
703
goto out_release_phy ;
@@ -858,9 +888,12 @@ static void adlp_tc_phy_get_hw_state(struct intel_tc_port *tc)
858
888
port_wakeref = intel_display_power_get (display , port_power_domain );
859
889
860
890
tc -> mode = tc_phy_get_current_mode (tc );
861
- if (tc -> mode != TC_PORT_DISCONNECTED )
891
+ if (tc -> mode != TC_PORT_DISCONNECTED ) {
862
892
tc -> lock_wakeref = tc_cold_block (tc );
863
893
894
+ read_pin_configuration (tc );
895
+ }
896
+
864
897
intel_display_power_put (display , port_power_domain , port_wakeref );
865
898
}
866
899
@@ -873,6 +906,9 @@ static bool adlp_tc_phy_connect(struct intel_tc_port *tc, int required_lanes)
873
906
874
907
if (tc -> mode == TC_PORT_TBT_ALT ) {
875
908
tc -> lock_wakeref = tc_cold_block (tc );
909
+
910
+ read_pin_configuration (tc );
911
+
876
912
return true;
877
913
}
878
914
@@ -894,6 +930,8 @@ static bool adlp_tc_phy_connect(struct intel_tc_port *tc, int required_lanes)
894
930
895
931
tc -> lock_wakeref = tc_cold_block (tc );
896
932
933
+ read_pin_configuration (tc );
934
+
897
935
if (!tc_phy_verify_legacy_or_dp_alt_mode (tc , required_lanes ))
898
936
goto out_unblock_tc_cold ;
899
937
@@ -1124,9 +1162,18 @@ static void xelpdp_tc_phy_get_hw_state(struct intel_tc_port *tc)
1124
1162
tc_cold_wref = __tc_cold_block (tc , & domain );
1125
1163
1126
1164
tc -> mode = tc_phy_get_current_mode (tc );
1127
- if (tc -> mode != TC_PORT_DISCONNECTED )
1165
+ if (tc -> mode != TC_PORT_DISCONNECTED ) {
1128
1166
tc -> lock_wakeref = tc_cold_block (tc );
1129
1167
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
+
1130
1177
drm_WARN_ON (display -> drm ,
1131
1178
(tc -> mode == TC_PORT_DP_ALT || tc -> mode == TC_PORT_LEGACY ) &&
1132
1179
!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)
1138
1185
{
1139
1186
tc -> lock_wakeref = tc_cold_block (tc );
1140
1187
1141
- if (tc -> mode == TC_PORT_TBT_ALT )
1188
+ if (tc -> mode == TC_PORT_TBT_ALT ) {
1189
+ read_pin_configuration (tc );
1190
+
1142
1191
return true;
1192
+ }
1143
1193
1144
1194
if (!xelpdp_tc_phy_enable_tcss_power (tc , true))
1145
1195
goto out_unblock_tccold ;
1146
1196
1147
1197
xelpdp_tc_phy_take_ownership (tc , true);
1148
1198
1199
+ read_pin_configuration (tc );
1200
+
1149
1201
if (!tc_phy_verify_legacy_or_dp_alt_mode (tc , required_lanes ))
1150
1202
goto out_release_phy ;
1151
1203
@@ -1226,14 +1278,19 @@ static void tc_phy_get_hw_state(struct intel_tc_port *tc)
1226
1278
tc -> phy_ops -> get_hw_state (tc );
1227
1279
}
1228
1280
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 )
1231
1284
{
1232
1285
struct intel_display * display = to_intel_display (tc -> dig_port );
1233
1286
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 );
1235
1289
1236
- return phy_is_ready && phy_is_owned ;
1290
+ return phy_is_ready && phy_is_owned ;
1291
+ } else {
1292
+ return phy_is_owned ;
1293
+ }
1237
1294
}
1238
1295
1239
1296
static 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,
1244
1301
bool phy_is_owned = tc_phy_is_owned (tc );
1245
1302
bool is_connected ;
1246
1303
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 ))
1248
1305
is_connected = port_pll_type == ICL_PORT_DPLL_MG_PHY ;
1249
1306
else
1250
1307
is_connected = port_pll_type == ICL_PORT_DPLL_DEFAULT ;
@@ -1352,7 +1409,7 @@ tc_phy_get_current_mode(struct intel_tc_port *tc)
1352
1409
phy_is_ready = tc_phy_is_ready (tc );
1353
1410
phy_is_owned = tc_phy_is_owned (tc );
1354
1411
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 )) {
1356
1413
mode = get_tc_mode_in_phy_not_owned_state (tc , live_mode );
1357
1414
} else {
1358
1415
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,
1441
1498
intel_display_power_flush_work (display );
1442
1499
if (!intel_tc_cold_requires_aux_pw (dig_port )) {
1443
1500
enum intel_display_power_domain aux_domain ;
1444
- bool aux_powered ;
1445
1501
1446
1502
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 );
1449
1506
}
1450
1507
1451
1508
tc_phy_disconnect (tc );
0 commit comments