From: Imre Deak <imre.deak@intel.com>
To: stable@vger.kernel.org, Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Cc: intel-gfx@lists.freedesktop.org
Subject: [Intel-gfx] [PATCH 1/1] drm/i915/tc: Fix system resume MST mode restore for DP-alt sinks
Date: Mon, 10 Jul 2023 17:13:59 +0300 [thread overview]
Message-ID: <20230710141359.754365-2-imre.deak@intel.com> (raw)
In-Reply-To: <20230710141359.754365-1-imre.deak@intel.com>
commit 06f66261a1567d66b9d35c87393b6edfbea4c8f8 upstream.
At least restoring the MST topology during system resume needs to use
AUX before the display HW readout->sanitization sequence is complete,
but on TC ports the PHY may be in the wrong mode for this, resulting in
the AUX transfers to fail.
The initial TC port mode is kept fixed as BIOS left it for the above HW
readout sequence (to prevent changing the mode on an enabled port). If
the port is disabled this initial mode is TBT - as in any case the PHY
ownership is not held - even if a DP-alt sink is connected. Thus, the
AUX transfers during this time will use TBT mode instead of the expected
DP-alt mode and so time out.
Fix the above by connecting the PHY during port initialization if the
port is disabled, which will switch to the expected mode (DP-alt in the
above case).
As the encoder/pipe HW state isn't read-out yet at this point, check if
the port is enabled based on the DDI_BUF enabled flag. Save the read-out
initial mode, so intel_tc_port_sanitize_mode() can check this wrt. the
read-out encoder HW state.
Signed-off-by: Imre Deak <imre.deak@intel.com>
Reviewed-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20230316131724.359612-5-imre.deak@intel.com
[For stable include intel_de.h for intel_de_read() (Imre)]
References: https://gitlab.freedesktop.org/drm/intel/-/issues/4306#note_1832688
Cc: <stable@vger.kernel.org> # 6.1.x: a82796a2e332: Fix TypeC mode initialization
Cc: <stable@vger.kernel.org> # 6.1.x: 67165722c27c: Fix TC port link ref init
---
.../drm/i915/display/intel_display_types.h | 1 +
drivers/gpu/drm/i915/display/intel_tc.c | 51 +++++++++++++++++--
2 files changed, 48 insertions(+), 4 deletions(-)
diff --git a/drivers/gpu/drm/i915/display/intel_display_types.h b/drivers/gpu/drm/i915/display/intel_display_types.h
index 63b7105e818a6..a8bf91a21cb24 100644
--- a/drivers/gpu/drm/i915/display/intel_display_types.h
+++ b/drivers/gpu/drm/i915/display/intel_display_types.h
@@ -1763,6 +1763,7 @@ struct intel_digital_port {
bool tc_legacy_port:1;
char tc_port_name[8];
enum tc_port_mode tc_mode;
+ enum tc_port_mode tc_init_mode;
enum phy_fia tc_phy_fia;
u8 tc_phy_fia_idx;
diff --git a/drivers/gpu/drm/i915/display/intel_tc.c b/drivers/gpu/drm/i915/display/intel_tc.c
index f50c92ca0dff8..bda77828dc95f 100644
--- a/drivers/gpu/drm/i915/display/intel_tc.c
+++ b/drivers/gpu/drm/i915/display/intel_tc.c
@@ -5,6 +5,7 @@
#include "i915_drv.h"
#include "i915_reg.h"
+#include "intel_de.h"
#include "intel_display.h"
#include "intel_display_power_map.h"
#include "intel_display_types.h"
@@ -116,6 +117,24 @@ assert_tc_cold_blocked(struct intel_digital_port *dig_port)
drm_WARN_ON(&i915->drm, !enabled);
}
+static enum intel_display_power_domain
+tc_port_power_domain(struct intel_digital_port *dig_port)
+{
+ struct drm_i915_private *i915 = to_i915(dig_port->base.base.dev);
+ enum tc_port tc_port = intel_port_to_tc(i915, dig_port->base.port);
+
+ return POWER_DOMAIN_PORT_DDI_LANES_TC1 + tc_port - TC_PORT_1;
+}
+
+static void
+assert_tc_port_power_enabled(struct intel_digital_port *dig_port)
+{
+ struct drm_i915_private *i915 = to_i915(dig_port->base.base.dev);
+
+ drm_WARN_ON(&i915->drm,
+ !intel_display_power_is_enabled(i915, tc_port_power_domain(dig_port)));
+}
+
u32 intel_tc_port_get_lane_mask(struct intel_digital_port *dig_port)
{
struct drm_i915_private *i915 = to_i915(dig_port->base.base.dev);
@@ -693,6 +712,16 @@ static void __intel_tc_port_put_link(struct intel_digital_port *dig_port)
dig_port->tc_link_refcount--;
}
+static bool tc_port_is_enabled(struct intel_digital_port *dig_port)
+{
+ struct drm_i915_private *i915 = to_i915(dig_port->base.base.dev);
+
+ assert_tc_port_power_enabled(dig_port);
+
+ return intel_de_read(i915, DDI_BUF_CTL(dig_port->base.port)) &
+ DDI_BUF_CTL_ENABLE;
+}
+
/**
* intel_tc_port_init_mode: Read out HW state and init the given port's TypeC mode
* @dig_port: digital port
@@ -715,10 +744,24 @@ void intel_tc_port_init_mode(struct intel_digital_port *dig_port)
tc_cold_wref = tc_cold_block(dig_port, &domain);
dig_port->tc_mode = intel_tc_port_get_current_mode(dig_port);
- /* Prevent changing dig_port->tc_mode until intel_tc_port_sanitize_mode() is called. */
- __intel_tc_port_get_link(dig_port);
+ /*
+ * Save the initial mode for the state check in
+ * intel_tc_port_sanitize_mode().
+ */
+ dig_port->tc_init_mode = dig_port->tc_mode;
dig_port->tc_lock_wakeref = tc_cold_block(dig_port, &dig_port->tc_lock_power_domain);
+ /*
+ * The PHY needs to be connected for AUX to work during HW readout and
+ * MST topology resume, but the PHY mode can only be changed if the
+ * port is disabled.
+ */
+ if (!tc_port_is_enabled(dig_port))
+ intel_tc_port_update_mode(dig_port, 1, false);
+
+ /* Prevent changing dig_port->tc_mode until intel_tc_port_sanitize_mode() is called. */
+ __intel_tc_port_get_link(dig_port);
+
tc_cold_unblock(dig_port, domain, tc_cold_wref);
drm_dbg_kms(&i915->drm, "Port %s: init mode (%s)\n",
@@ -764,11 +807,11 @@ void intel_tc_port_sanitize_mode(struct intel_digital_port *dig_port)
* we'll just switch to disconnected mode from it here without
* a note.
*/
- if (dig_port->tc_mode != TC_PORT_TBT_ALT)
+ if (dig_port->tc_init_mode != TC_PORT_TBT_ALT)
drm_dbg_kms(&i915->drm,
"Port %s: PHY left in %s mode on disabled port, disconnecting it\n",
dig_port->tc_port_name,
- tc_port_mode_name(dig_port->tc_mode));
+ tc_port_mode_name(dig_port->tc_init_mode));
icl_tc_phy_disconnect(dig_port);
__intel_tc_port_put_link(dig_port);
--
2.37.2
next prev parent reply other threads:[~2023-07-10 14:14 UTC|newest]
Thread overview: 4+ messages / expand[flat|nested] mbox.gz Atom feed top
2023-07-10 14:13 [Intel-gfx] [PATCH 0/1] v6.1 stable backport request Imre Deak
2023-07-10 14:13 ` Imre Deak [this message]
2023-07-10 16:38 ` [Intel-gfx] ✗ Fi.CI.BUILD: failure for " Patchwork
2023-07-16 15:07 ` [Intel-gfx] [PATCH 0/1] " Greg Kroah-Hartman
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=20230710141359.754365-2-imre.deak@intel.com \
--to=imre.deak@intel.com \
--cc=gregkh@linuxfoundation.org \
--cc=intel-gfx@lists.freedesktop.org \
--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