Commit 8e8289a0 authored by Imre Deak's avatar Imre Deak

drm/i915/tc: Avoid using legacy AUX PW in TBT mode

For the ADL-P TBT mode the spec doesn't require blocking TC-cold by
using the legacy AUX power domain. To avoid the timeouts that this would
cause during PHY disconnect/reconnect sequences (which will be more
frequent after a follow-up change) use the TC_COLD_OFF power domain in
TBT mode on all platforms. On TGL this power domain blocks TC-cold via a
PUNIT command, while on other platforms the domain just takes a runtime
PM reference.

If the HPD live status indicates that the port mode needs to be reset
- for instance after switching from TBT to a DP-alt sink - still take
the AUX domain, since the IOM firmware handshake requires this.

v2: Rebased on v2 of the previous patch.

Cc: José Roberto de Souza <jose.souza@intel.com>
Signed-off-by: default avatarImre Deak <imre.deak@intel.com>
Reviewed-by: default avatarJosé Roberto de Souza <jose.souza@intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20210929132833.2253961-5-imre.deak@intel.com
parent d0bc6770
......@@ -59,10 +59,10 @@ bool intel_tc_cold_requires_aux_pw(struct intel_digital_port *dig_port)
static enum intel_display_power_domain
tc_cold_get_power_domain(struct intel_digital_port *dig_port, enum tc_port_mode mode)
{
if (intel_tc_cold_requires_aux_pw(dig_port))
return intel_legacy_aux_to_power_domain(dig_port->aux_ch);
else
if (mode == TC_PORT_TBT_ALT || !intel_tc_cold_requires_aux_pw(dig_port))
return POWER_DOMAIN_TC_COLD_OFF;
return intel_legacy_aux_to_power_domain(dig_port->aux_ch);
}
static intel_wakeref_t
......@@ -645,6 +645,36 @@ static void intel_tc_port_reset_mode(struct intel_digital_port *dig_port,
tc_port_mode_name(dig_port->tc_mode));
}
static bool intel_tc_port_needs_reset(struct intel_digital_port *dig_port)
{
return intel_tc_port_get_target_mode(dig_port) != dig_port->tc_mode;
}
static void intel_tc_port_update_mode(struct intel_digital_port *dig_port,
int required_lanes, bool force_disconnect)
{
enum intel_display_power_domain domain;
intel_wakeref_t wref;
bool needs_reset = force_disconnect;
if (!needs_reset) {
/* Get power domain required to check the hotplug live status. */
wref = tc_cold_block(dig_port, &domain);
needs_reset = intel_tc_port_needs_reset(dig_port);
tc_cold_unblock(dig_port, domain, wref);
}
if (!needs_reset)
return;
/* Get power domain required for resetting the mode. */
wref = tc_cold_block_in_mode(dig_port, TC_PORT_DISCONNECTED, &domain);
intel_tc_port_reset_mode(dig_port, required_lanes, force_disconnect);
tc_cold_unblock(dig_port, domain, wref);
}
static void
intel_tc_port_link_init_refcount(struct intel_digital_port *dig_port,
int refcount)
......@@ -691,11 +721,6 @@ void intel_tc_port_sanitize(struct intel_digital_port *dig_port)
mutex_unlock(&dig_port->tc_lock);
}
static bool intel_tc_port_needs_reset(struct intel_digital_port *dig_port)
{
return intel_tc_port_get_target_mode(dig_port) != dig_port->tc_mode;
}
/*
* The type-C ports are different because even when they are connected, they may
* not be available/usable by the graphics driver: see the comment on
......@@ -735,19 +760,11 @@ static void __intel_tc_port_lock(struct intel_digital_port *dig_port,
mutex_lock(&dig_port->tc_lock);
if (!dig_port->tc_link_refcount) {
enum intel_display_power_domain domain;
intel_wakeref_t tc_cold_wref;
tc_cold_wref = tc_cold_block(dig_port, &domain);
if (force_disconnect || intel_tc_port_needs_reset(dig_port))
intel_tc_port_reset_mode(dig_port, required_lanes,
if (!dig_port->tc_link_refcount)
intel_tc_port_update_mode(dig_port, required_lanes,
force_disconnect);
tc_cold_unblock(dig_port, domain, tc_cold_wref);
}
drm_WARN_ON(&i915->drm, dig_port->tc_lock_wakeref);
dig_port->tc_lock_wakeref = wakeref;
}
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment