summaryrefslogtreecommitdiff
path: root/drivers/gpu/drm/i915/display/intel_tc.c
diff options
context:
space:
mode:
authorImre Deak <imre.deak@intel.com>2019-06-28 17:36:26 +0300
committerImre Deak <imre.deak@intel.com>2019-07-01 14:50:29 +0300
commit8c10e2262663951ab4d43d4f74e282566c04e00c (patch)
treeaf9b259aed348a2d9493caadd5099fed8a8382f2 /drivers/gpu/drm/i915/display/intel_tc.c
parent32691b58d157584b18faabf25cce755c1e31c370 (diff)
drm/i915: Keep the TypeC port mode fixed for detect/AUX transfers
We must keep the TypeC port mode fixed for the duration of the connector detection and each AUX transfers. Add a new TypeC lock holding it around these two sequences. For consistency also hold the lock during the port mode sanitization. Whenever resetting the port mode (only during the detection for now) the port's AUX power domain must be disabled already. Flush the async power domain disabling work to ensure this. A follow-up patch will make the port mode changing more robust by postponing the change for active ports. v2: - Fix checkpatch issue: missing annotation for tc_lock. Cc: José Roberto de Souza <jose.souza@intel.com> Cc: Rodrigo Vivi <rodrigo.vivi@intel.com> Cc: Paulo Zanoni <paulo.r.zanoni@intel.com> Cc: Ville Syrjälä <ville.syrjala@linux.intel.com> 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/20190628143635.22066-15-imre.deak@intel.com
Diffstat (limited to 'drivers/gpu/drm/i915/display/intel_tc.c')
-rw-r--r--drivers/gpu/drm/i915/display/intel_tc.c30
1 files changed, 29 insertions, 1 deletions
diff --git a/drivers/gpu/drm/i915/display/intel_tc.c b/drivers/gpu/drm/i915/display/intel_tc.c
index 78340115b994..18a599a71bd3 100644
--- a/drivers/gpu/drm/i915/display/intel_tc.c
+++ b/drivers/gpu/drm/i915/display/intel_tc.c
@@ -312,8 +312,11 @@ intel_tc_port_get_target_mode(struct intel_digital_port *dig_port)
static void intel_tc_port_reset_mode(struct intel_digital_port *dig_port)
{
+ struct drm_i915_private *dev_priv = to_i915(dig_port->base.base.dev);
enum tc_port_mode old_tc_mode = dig_port->tc_mode;
+ intel_display_power_flush_work(dev_priv);
+
icl_tc_phy_disconnect(dig_port);
icl_tc_phy_connect(dig_port);
@@ -328,6 +331,8 @@ void intel_tc_port_sanitize(struct intel_digital_port *dig_port)
struct intel_encoder *encoder = &dig_port->base;
int active_links = 0;
+ mutex_lock(&dig_port->tc_lock);
+
dig_port->tc_mode = intel_tc_port_get_current_mode(dig_port);
if (dig_port->dp.is_mst)
active_links = intel_dp_mst_encoder_active_links(dig_port);
@@ -348,6 +353,8 @@ out:
DRM_DEBUG_KMS("Port %s: sanitize mode (%s)\n",
dig_port->tc_port_name,
tc_port_mode_name(dig_port->tc_mode));
+
+ mutex_unlock(&dig_port->tc_lock);
}
static bool intel_tc_port_needs_reset(struct intel_digital_port *dig_port)
@@ -367,10 +374,30 @@ static bool intel_tc_port_needs_reset(struct intel_digital_port *dig_port)
*/
bool intel_tc_port_connected(struct intel_digital_port *dig_port)
{
+ bool is_connected;
+
+ mutex_lock(&dig_port->tc_lock);
+
if (intel_tc_port_needs_reset(dig_port))
intel_tc_port_reset_mode(dig_port);
- return tc_port_live_status_mask(dig_port) & BIT(dig_port->tc_mode);
+ is_connected = tc_port_live_status_mask(dig_port) &
+ BIT(dig_port->tc_mode);
+
+ mutex_unlock(&dig_port->tc_lock);
+
+ return is_connected;
+}
+
+void intel_tc_port_lock(struct intel_digital_port *dig_port)
+{
+ mutex_lock(&dig_port->tc_lock);
+ /* TODO: reset the TypeC port mode if needed */
+}
+
+void intel_tc_port_unlock(struct intel_digital_port *dig_port)
+{
+ mutex_unlock(&dig_port->tc_lock);
}
void intel_tc_port_init(struct intel_digital_port *dig_port, bool is_legacy)
@@ -385,5 +412,6 @@ void intel_tc_port_init(struct intel_digital_port *dig_port, bool is_legacy)
snprintf(dig_port->tc_port_name, sizeof(dig_port->tc_port_name),
"%c/TC#%d", port_name(port), tc_port + 1);
+ mutex_init(&dig_port->tc_lock);
dig_port->tc_legacy_port = is_legacy;
}