intel-xe.lists.freedesktop.org archive mirror
 help / color / mirror / Atom feed
From: Imre Deak <imre.deak@intel.com>
To: <intel-gfx@lists.freedesktop.org>, <intel-xe@lists.freedesktop.org>
Cc: <stable@vger.kernel.org>, Charlton Lin <charlton.lin@intel.com>,
	"Khaled Almahallawy" <khaled.almahallawy@intel.com>
Subject: [PATCH v2 02/19] drm/i915/icl+/tc: Cache the max lane count value
Date: Tue, 5 Aug 2025 12:33:48 +0300	[thread overview]
Message-ID: <20250805093349.679158-1-imre.deak@intel.com> (raw)
In-Reply-To: <20250805073700.642107-3-imre.deak@intel.com>

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>
Signed-off-by: Imre Deak <imre.deak@intel.com>
---
 drivers/gpu/drm/i915/display/intel_tc.c | 57 +++++++++++++++++++++----
 1 file changed, 48 insertions(+), 9 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/intel_tc.c b/drivers/gpu/drm/i915/display/intel_tc.c
index 73a08bd84a70a..b8453fc3ab688 100644
--- a/drivers/gpu/drm/i915/display/intel_tc.c
+++ b/drivers/gpu/drm/i915/display/intel_tc.c
@@ -66,6 +66,7 @@ struct intel_tc_port {
 	enum tc_port_mode init_mode;
 	enum phy_fia phy_fia;
 	u8 phy_fia_idx;
+	u8 max_lane_count;
 };
 
 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)
 	}
 }
 
-int intel_tc_port_max_lane_count(struct intel_digital_port *dig_port)
+static int get_max_lane_count(struct intel_tc_port *tc)
 {
-	struct intel_display *display = to_intel_display(dig_port);
-	struct intel_tc_port *tc = to_tc_port(dig_port);
+	struct intel_display *display = to_intel_display(tc->dig_port);
+	struct intel_digital_port *dig_port = tc->dig_port;
 
-	if (!intel_encoder_is_tc(&dig_port->base) || tc->mode != TC_PORT_DP_ALT)
+	if (tc->mode != TC_PORT_DP_ALT)
 		return 4;
 
 	assert_tc_cold_blocked(tc);
@@ -384,6 +385,21 @@ int intel_tc_port_max_lane_count(struct intel_digital_port *dig_port)
 	return intel_tc_port_get_max_lane_count(dig_port);
 }
 
+static void read_pin_configuration(struct intel_tc_port *tc)
+{
+	tc->max_lane_count = get_max_lane_count(tc);
+}
+
+int intel_tc_port_max_lane_count(struct intel_digital_port *dig_port)
+{
+	struct intel_tc_port *tc = to_tc_port(dig_port);
+
+	if (!intel_encoder_is_tc(&dig_port->base))
+		return 4;
+
+	return get_max_lane_count(tc);
+}
+
 void intel_tc_port_set_fia_lane_count(struct intel_digital_port *dig_port,
 				      int required_lanes)
 {
@@ -596,9 +612,12 @@ static void icl_tc_phy_get_hw_state(struct intel_tc_port *tc)
 	tc_cold_wref = __tc_cold_block(tc, &domain);
 
 	tc->mode = tc_phy_get_current_mode(tc);
-	if (tc->mode != TC_PORT_DISCONNECTED)
+	if (tc->mode != TC_PORT_DISCONNECTED) {
 		tc->lock_wakeref = tc_cold_block(tc);
 
+		read_pin_configuration(tc);
+	}
+
 	__tc_cold_unblock(tc, domain, tc_cold_wref);
 }
 
@@ -656,8 +675,11 @@ static bool icl_tc_phy_connect(struct intel_tc_port *tc,
 
 	tc->lock_wakeref = tc_cold_block(tc);
 
-	if (tc->mode == TC_PORT_TBT_ALT)
+	if (tc->mode == TC_PORT_TBT_ALT) {
+		read_pin_configuration(tc);
+
 		return true;
+	}
 
 	if ((!tc_phy_is_ready(tc) ||
 	     !icl_tc_phy_take_ownership(tc, true)) &&
@@ -668,6 +690,7 @@ static bool icl_tc_phy_connect(struct intel_tc_port *tc,
 		goto out_unblock_tc_cold;
 	}
 
+	read_pin_configuration(tc);
 
 	if (!tc_phy_verify_legacy_or_dp_alt_mode(tc, required_lanes))
 		goto out_release_phy;
@@ -858,9 +881,12 @@ static void adlp_tc_phy_get_hw_state(struct intel_tc_port *tc)
 	port_wakeref = intel_display_power_get(display, port_power_domain);
 
 	tc->mode = tc_phy_get_current_mode(tc);
-	if (tc->mode != TC_PORT_DISCONNECTED)
+	if (tc->mode != TC_PORT_DISCONNECTED) {
 		tc->lock_wakeref = tc_cold_block(tc);
 
+		read_pin_configuration(tc);
+	}
+
 	intel_display_power_put(display, port_power_domain, port_wakeref);
 }
 
@@ -873,6 +899,9 @@ static bool adlp_tc_phy_connect(struct intel_tc_port *tc, int required_lanes)
 
 	if (tc->mode == TC_PORT_TBT_ALT) {
 		tc->lock_wakeref = tc_cold_block(tc);
+
+		read_pin_configuration(tc);
+
 		return true;
 	}
 
@@ -894,6 +923,8 @@ static bool adlp_tc_phy_connect(struct intel_tc_port *tc, int required_lanes)
 
 	tc->lock_wakeref = tc_cold_block(tc);
 
+	read_pin_configuration(tc);
+
 	if (!tc_phy_verify_legacy_or_dp_alt_mode(tc, required_lanes))
 		goto out_unblock_tc_cold;
 
@@ -1124,9 +1155,12 @@ static void xelpdp_tc_phy_get_hw_state(struct intel_tc_port *tc)
 	tc_cold_wref = __tc_cold_block(tc, &domain);
 
 	tc->mode = tc_phy_get_current_mode(tc);
-	if (tc->mode != TC_PORT_DISCONNECTED)
+	if (tc->mode != TC_PORT_DISCONNECTED) {
 		tc->lock_wakeref = tc_cold_block(tc);
 
+		read_pin_configuration(tc);
+	}
+
 	drm_WARN_ON(display->drm,
 		    (tc->mode == TC_PORT_DP_ALT || tc->mode == TC_PORT_LEGACY) &&
 		    !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)
 {
 	tc->lock_wakeref = tc_cold_block(tc);
 
-	if (tc->mode == TC_PORT_TBT_ALT)
+	if (tc->mode == TC_PORT_TBT_ALT) {
+		read_pin_configuration(tc);
+
 		return true;
+	}
 
 	if (!xelpdp_tc_phy_enable_tcss_power(tc, true))
 		goto out_unblock_tccold;
 
 	xelpdp_tc_phy_take_ownership(tc, true);
 
+	read_pin_configuration(tc);
+
 	if (!tc_phy_verify_legacy_or_dp_alt_mode(tc, required_lanes))
 		goto out_release_phy;
 
-- 
2.49.1


  reply	other threads:[~2025-08-05  9:35 UTC|newest]

Thread overview: 65+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2025-08-05  7:36 [PATCH 00/19] drm/i915/tc: Fix enabled/disconnected DP-alt sink handling Imre Deak
2025-08-05  7:36 ` [PATCH 01/19] drm/i915/lnl+/tc: Fix handling of an enabled/disconnected dp-alt sink Imre Deak
2025-08-07  7:06   ` Kahola, Mika
2025-08-07 10:59   ` Luca Coelho
2025-08-07 11:38     ` Imre Deak
2025-08-07 12:19       ` Jani Nikula
2025-08-07 12:32         ` Imre Deak
2025-08-07 12:50           ` Imre Deak
2025-08-07 13:05             ` Jani Nikula
2025-08-07 13:24               ` Imre Deak
2025-08-07 14:10             ` Luca Coelho
2025-08-05  7:36 ` [PATCH 02/19] drm/i915/icl+/tc: Cache the max lane count value Imre Deak
2025-08-05  9:33   ` Imre Deak [this message]
2025-08-07  8:07     ` [PATCH v2 " Kahola, Mika
2025-08-05  7:36 ` [PATCH 03/19] drm/i915/lnl+/tc: Fix max lane count HW readout Imre Deak
2025-08-05  9:33   ` [PATCH v2 " Imre Deak
2025-08-07  8:36     ` Kahola, Mika
2025-08-05  7:36 ` [PATCH 04/19] drm/i915/lnl+/tc: Use the cached max lane count value Imre Deak
2025-08-07  8:49   ` Kahola, Mika
2025-08-05  7:36 ` [PATCH 05/19] drm/i915/icl+/tc: Convert AUX powered WARN to a debug message Imre Deak
2025-08-07 12:29   ` Kahola, Mika
2025-08-05  7:36 ` [PATCH 06/19] drm/i915/tc: Use the cached max lane count value Imre Deak
2025-08-06 12:02   ` Kahola, Mika
2025-08-05  7:36 ` [PATCH 07/19] drm/i915/tc: Move getting the power domain before reading DFLEX registers Imre Deak
2025-08-06 12:56   ` Kahola, Mika
2025-08-05  7:36 ` [PATCH 08/19] drm/i915/tc: Move asserting the power state after reading TCSS_DDI_STATUS Imre Deak
2025-08-06 13:22   ` Kahola, Mika
2025-08-05  7:36 ` [PATCH 09/19] drm/i915/tc: Add an enum for the TypeC pin assignment Imre Deak
2025-08-07 12:39   ` Kahola, Mika
2025-08-05  7:36 ` [PATCH 10/19] drm/i915/tc: Pass pin assignment value around using the pin assignment enum Imre Deak
2025-08-07 12:56   ` Kahola, Mika
2025-08-05  7:36 ` [PATCH 11/19] drm/i915/tc: Handle pin assignment NONE on all platforms Imre Deak
2025-08-07 12:57   ` Kahola, Mika
2025-08-05  7:36 ` [PATCH 12/19] drm/i915/tc: Validate the pin assignment " Imre Deak
2025-08-07 13:08   ` Kahola, Mika
2025-08-05  7:36 ` [PATCH 13/19] drm/i915/tc: Unify the way to get " Imre Deak
2025-08-08  6:44   ` Kahola, Mika
2025-08-05  7:36 ` [PATCH 14/19] drm/i915/tc: Unify the way to get the max lane count value on MTL+ Imre Deak
2025-08-08  7:32   ` Kahola, Mika
2025-08-05  7:36 ` [PATCH 15/19] drm/i915/tc: Handle non-TC encoders when getting the pin assignment Imre Deak
2025-08-08  7:45   ` Kahola, Mika
2025-08-05  7:36 ` [PATCH 16/19] drm/i915/tc: Pass intel_tc_port to internal lane mask/count helpers Imre Deak
2025-08-08  8:25   ` Kahola, Mika
2025-08-05  7:36 ` [PATCH 17/19] dmc/i915/tc: Report pin assignment NONE in TBT-alt mode Imre Deak
2025-08-08  8:26   ` Kahola, Mika
2025-08-05  7:36 ` [PATCH 18/19] drm/i915/tc: Cache the pin assignment value Imre Deak
2025-08-08  8:27   ` Kahola, Mika
2025-08-05  7:37 ` [PATCH 19/19] drm/i915/tc: Debug print the pin assignment and max lane count Imre Deak
2025-08-08  8:28   ` Kahola, Mika
2025-08-05  7:46 ` ✗ CI.checkpatch: warning for drm/i915/tc: Fix enabled/disconnected DP-alt sink handling Patchwork
2025-08-05  7:47 ` ✓ CI.KUnit: success " Patchwork
2025-08-05  8:02 ` ✗ CI.checksparse: warning " Patchwork
2025-08-05  8:49 ` ✗ Xe.CI.BAT: failure " Patchwork
2025-08-05 10:08 ` ✓ Xe.CI.Full: success " Patchwork
2025-08-05 11:41 ` ✗ CI.checkpatch: warning for drm/i915/tc: Fix enabled/disconnected DP-alt sink handling (rev3) Patchwork
2025-08-05 11:42 ` ✓ CI.KUnit: success " Patchwork
2025-08-05 11:57 ` ✗ CI.checksparse: warning " Patchwork
2025-08-05 13:02 ` ✓ Xe.CI.BAT: success " Patchwork
2025-08-05 15:31 ` ✓ Xe.CI.Full: " Patchwork
2025-08-06 11:44 ` [PATCH 00/19] drm/i915/tc: Fix enabled/disconnected DP-alt sink handling Luca Coelho
2025-08-06 11:54   ` Imre Deak
2025-08-06 12:54     ` Luca Coelho
2025-08-06 13:12       ` Imre Deak
2025-08-06 13:16         ` Luca Coelho
     [not found] ` <175439829105.213103.3969215907569188087@1538d3639d33>
2025-08-13 12:43   ` ✗ i915.CI.Full: failure for drm/i915/tc: Fix enabled/disconnected DP-alt sink handling (rev3) Imre Deak

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20250805093349.679158-1-imre.deak@intel.com \
    --to=imre.deak@intel.com \
    --cc=charlton.lin@intel.com \
    --cc=intel-gfx@lists.freedesktop.org \
    --cc=intel-xe@lists.freedesktop.org \
    --cc=khaled.almahallawy@intel.com \
    --cc=stable@vger.kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).