Skip to content

Commit 68c3646

Browse files
ideakgregkh
authored andcommitted
drm/i915/icl+/tc: Cache the max lane count value
commit 5fd3523 upstream. 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 (cherry picked from commit 3e32438) Signed-off-by: Tvrtko Ursulin <tursulin@ursulin.net> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
1 parent 4059818 commit 68c3646

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
@@ -65,6 +65,7 @@ struct intel_tc_port {
6565
enum tc_port_mode init_mode;
6666
enum phy_fia phy_fia;
6767
u8 phy_fia_idx;
68+
u8 max_lane_count;
6869
};
6970

7071
static enum intel_display_power_domain
@@ -364,12 +365,12 @@ static int intel_tc_port_get_max_lane_count(struct intel_digital_port *dig_port)
364365
}
365366
}
366367

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

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

375376
assert_tc_cold_blocked(tc);
@@ -383,6 +384,21 @@ int intel_tc_port_max_lane_count(struct intel_digital_port *dig_port)
383384
return intel_tc_port_get_max_lane_count(dig_port);
384385
}
385386

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

597613
tc->mode = tc_phy_get_current_mode(tc);
598-
if (tc->mode != TC_PORT_DISCONNECTED)
614+
if (tc->mode != TC_PORT_DISCONNECTED) {
599615
tc->lock_wakeref = tc_cold_block(tc);
600616

617+
read_pin_configuration(tc);
618+
}
619+
601620
__tc_cold_unblock(tc, domain, tc_cold_wref);
602621
}
603622

@@ -655,8 +674,11 @@ static bool icl_tc_phy_connect(struct intel_tc_port *tc,
655674

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

658-
if (tc->mode == TC_PORT_TBT_ALT)
677+
if (tc->mode == TC_PORT_TBT_ALT) {
678+
read_pin_configuration(tc);
679+
659680
return true;
681+
}
660682

661683
if ((!tc_phy_is_ready(tc) ||
662684
!icl_tc_phy_take_ownership(tc, true)) &&
@@ -667,6 +689,7 @@ static bool icl_tc_phy_connect(struct intel_tc_port *tc,
667689
goto out_unblock_tc_cold;
668690
}
669691

692+
read_pin_configuration(tc);
670693

671694
if (!tc_phy_verify_legacy_or_dp_alt_mode(tc, required_lanes))
672695
goto out_release_phy;
@@ -857,9 +880,12 @@ static void adlp_tc_phy_get_hw_state(struct intel_tc_port *tc)
857880
port_wakeref = intel_display_power_get(display, port_power_domain);
858881

859882
tc->mode = tc_phy_get_current_mode(tc);
860-
if (tc->mode != TC_PORT_DISCONNECTED)
883+
if (tc->mode != TC_PORT_DISCONNECTED) {
861884
tc->lock_wakeref = tc_cold_block(tc);
862885

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

@@ -872,6 +898,9 @@ static bool adlp_tc_phy_connect(struct intel_tc_port *tc, int required_lanes)
872898

873899
if (tc->mode == TC_PORT_TBT_ALT) {
874900
tc->lock_wakeref = tc_cold_block(tc);
901+
902+
read_pin_configuration(tc);
903+
875904
return true;
876905
}
877906

@@ -893,6 +922,8 @@ static bool adlp_tc_phy_connect(struct intel_tc_port *tc, int required_lanes)
893922

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

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

@@ -1123,9 +1154,12 @@ static void xelpdp_tc_phy_get_hw_state(struct intel_tc_port *tc)
11231154
tc_cold_wref = __tc_cold_block(tc, &domain);
11241155

11251156
tc->mode = tc_phy_get_current_mode(tc);
1126-
if (tc->mode != TC_PORT_DISCONNECTED)
1157+
if (tc->mode != TC_PORT_DISCONNECTED) {
11271158
tc->lock_wakeref = tc_cold_block(tc);
11281159

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

1140-
if (tc->mode == TC_PORT_TBT_ALT)
1174+
if (tc->mode == TC_PORT_TBT_ALT) {
1175+
read_pin_configuration(tc);
1176+
11411177
return true;
1178+
}
11421179

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

11461183
xelpdp_tc_phy_take_ownership(tc, true);
11471184

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

0 commit comments

Comments
 (0)