Skip to content

Commit 3e32438

Browse files
committed
drm/i915/icl+/tc: Cache the max lane count value
The PHY's pin assignment value in the TCSS_DDI_STATUS register - as set by the HW/FW based on the connected DP-alt sink's TypeC/PD pin assignment negotiation - gets cleared by the HW/FW on LNL+ as soon as the sink gets disconnected, even if the PHY ownership got acquired already by the driver (and hence the PHY itself is still connected and used by the display). This is similar to how the PHY Ready flag gets cleared on LNL+ in the same register. To be able to query the max lane count value on LNL+ - which is based on the above pin assignment - at all times even after the sink gets disconnected, the max lane count must be determined and cached during the PHY's HW readout and connect sequences. Do that here, leaving the actual use of the cached value to a follow-up change. v2: Don't read out the pin configuration if the PHY is disconnected. Cc: stable@vger.kernel.org # v6.8+ Reported-by: Charlton Lin <charlton.lin@intel.com> Tested-by: Khaled Almahallawy <khaled.almahallawy@intel.com> Reviewed-by: Mika Kahola <mika.kahola@intel.com> Signed-off-by: Imre Deak <imre.deak@intel.com> Link: https://lore.kernel.org/r/20250811080152.906216-3-imre.deak@intel.com
1 parent 89f4b19 commit 3e32438

File tree

1 file changed

+48
-9
lines changed

1 file changed

+48
-9
lines changed

drivers/gpu/drm/i915/display/intel_tc.c

Lines changed: 48 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,7 @@ struct intel_tc_port {
6666
enum tc_port_mode init_mode;
6767
enum phy_fia phy_fia;
6868
u8 phy_fia_idx;
69+
u8 max_lane_count;
6970
};
7071

7172
static enum intel_display_power_domain
@@ -365,12 +366,12 @@ static int intel_tc_port_get_max_lane_count(struct intel_digital_port *dig_port)
365366
}
366367
}
367368

368-
int intel_tc_port_max_lane_count(struct intel_digital_port *dig_port)
369+
static int get_max_lane_count(struct intel_tc_port *tc)
369370
{
370-
struct intel_display *display = to_intel_display(dig_port);
371-
struct intel_tc_port *tc = to_tc_port(dig_port);
371+
struct intel_display *display = to_intel_display(tc->dig_port);
372+
struct intel_digital_port *dig_port = tc->dig_port;
372373

373-
if (!intel_encoder_is_tc(&dig_port->base) || tc->mode != TC_PORT_DP_ALT)
374+
if (tc->mode != TC_PORT_DP_ALT)
374375
return 4;
375376

376377
assert_tc_cold_blocked(tc);
@@ -384,6 +385,21 @@ int intel_tc_port_max_lane_count(struct intel_digital_port *dig_port)
384385
return intel_tc_port_get_max_lane_count(dig_port);
385386
}
386387

388+
static void read_pin_configuration(struct intel_tc_port *tc)
389+
{
390+
tc->max_lane_count = get_max_lane_count(tc);
391+
}
392+
393+
int intel_tc_port_max_lane_count(struct intel_digital_port *dig_port)
394+
{
395+
struct intel_tc_port *tc = to_tc_port(dig_port);
396+
397+
if (!intel_encoder_is_tc(&dig_port->base))
398+
return 4;
399+
400+
return get_max_lane_count(tc);
401+
}
402+
387403
void intel_tc_port_set_fia_lane_count(struct intel_digital_port *dig_port,
388404
int required_lanes)
389405
{
@@ -596,9 +612,12 @@ static void icl_tc_phy_get_hw_state(struct intel_tc_port *tc)
596612
tc_cold_wref = __tc_cold_block(tc, &domain);
597613

598614
tc->mode = tc_phy_get_current_mode(tc);
599-
if (tc->mode != TC_PORT_DISCONNECTED)
615+
if (tc->mode != TC_PORT_DISCONNECTED) {
600616
tc->lock_wakeref = tc_cold_block(tc);
601617

618+
read_pin_configuration(tc);
619+
}
620+
602621
__tc_cold_unblock(tc, domain, tc_cold_wref);
603622
}
604623

@@ -656,8 +675,11 @@ static bool icl_tc_phy_connect(struct intel_tc_port *tc,
656675

657676
tc->lock_wakeref = tc_cold_block(tc);
658677

659-
if (tc->mode == TC_PORT_TBT_ALT)
678+
if (tc->mode == TC_PORT_TBT_ALT) {
679+
read_pin_configuration(tc);
680+
660681
return true;
682+
}
661683

662684
if ((!tc_phy_is_ready(tc) ||
663685
!icl_tc_phy_take_ownership(tc, true)) &&
@@ -668,6 +690,7 @@ static bool icl_tc_phy_connect(struct intel_tc_port *tc,
668690
goto out_unblock_tc_cold;
669691
}
670692

693+
read_pin_configuration(tc);
671694

672695
if (!tc_phy_verify_legacy_or_dp_alt_mode(tc, required_lanes))
673696
goto out_release_phy;
@@ -858,9 +881,12 @@ static void adlp_tc_phy_get_hw_state(struct intel_tc_port *tc)
858881
port_wakeref = intel_display_power_get(display, port_power_domain);
859882

860883
tc->mode = tc_phy_get_current_mode(tc);
861-
if (tc->mode != TC_PORT_DISCONNECTED)
884+
if (tc->mode != TC_PORT_DISCONNECTED) {
862885
tc->lock_wakeref = tc_cold_block(tc);
863886

887+
read_pin_configuration(tc);
888+
}
889+
864890
intel_display_power_put(display, port_power_domain, port_wakeref);
865891
}
866892

@@ -873,6 +899,9 @@ static bool adlp_tc_phy_connect(struct intel_tc_port *tc, int required_lanes)
873899

874900
if (tc->mode == TC_PORT_TBT_ALT) {
875901
tc->lock_wakeref = tc_cold_block(tc);
902+
903+
read_pin_configuration(tc);
904+
876905
return true;
877906
}
878907

@@ -894,6 +923,8 @@ static bool adlp_tc_phy_connect(struct intel_tc_port *tc, int required_lanes)
894923

895924
tc->lock_wakeref = tc_cold_block(tc);
896925

926+
read_pin_configuration(tc);
927+
897928
if (!tc_phy_verify_legacy_or_dp_alt_mode(tc, required_lanes))
898929
goto out_unblock_tc_cold;
899930

@@ -1124,9 +1155,12 @@ static void xelpdp_tc_phy_get_hw_state(struct intel_tc_port *tc)
11241155
tc_cold_wref = __tc_cold_block(tc, &domain);
11251156

11261157
tc->mode = tc_phy_get_current_mode(tc);
1127-
if (tc->mode != TC_PORT_DISCONNECTED)
1158+
if (tc->mode != TC_PORT_DISCONNECTED) {
11281159
tc->lock_wakeref = tc_cold_block(tc);
11291160

1161+
read_pin_configuration(tc);
1162+
}
1163+
11301164
drm_WARN_ON(display->drm,
11311165
(tc->mode == TC_PORT_DP_ALT || tc->mode == TC_PORT_LEGACY) &&
11321166
!xelpdp_tc_phy_tcss_power_is_enabled(tc));
@@ -1138,14 +1172,19 @@ static bool xelpdp_tc_phy_connect(struct intel_tc_port *tc, int required_lanes)
11381172
{
11391173
tc->lock_wakeref = tc_cold_block(tc);
11401174

1141-
if (tc->mode == TC_PORT_TBT_ALT)
1175+
if (tc->mode == TC_PORT_TBT_ALT) {
1176+
read_pin_configuration(tc);
1177+
11421178
return true;
1179+
}
11431180

11441181
if (!xelpdp_tc_phy_enable_tcss_power(tc, true))
11451182
goto out_unblock_tccold;
11461183

11471184
xelpdp_tc_phy_take_ownership(tc, true);
11481185

1186+
read_pin_configuration(tc);
1187+
11491188
if (!tc_phy_verify_legacy_or_dp_alt_mode(tc, required_lanes))
11501189
goto out_release_phy;
11511190

0 commit comments

Comments
 (0)