Skip to content

Commit b1d43e6

Browse files
committed
drm/i915/dp: Flush modeset commits during connector detection
Make sure that a DP connector detection doesn't happen in parallel with an ongoing modeset on the connector. The reasons for this are: - Besides reading the capabilities, EDID etc. the detection may change the state of the sink (via the AUX bus), for instance by setting the LTTPR mode or the source OUI (the latter introduced by an upcoming patch). It's better to avoid such changes affecting an onging modeset in any way. - During a modeset's link training any access to DPCD registers, besides the registers used for link training should be avoided, at least in the LTTPR non-transparent and transparent link training modes. Such asynchronous accesses - besides connector detection - can also happen via the AUX device node for instance, for those a parallel modeset will have to be avoided in a similar way to the change in this patch. (A topic for a follow-up change.) - The source OUI written to an eDP sink is valid only while the panel power is enabled. A modeset on eDP will enable/disable the panel power synchronously; this should be prevented in the middle of the connector detection, to ensure a consistent sink state (which depends on the source OUI) for the whole duration of detection. The panel power could still get disabled during detection after an idle period (1 sec), this will be prevented by the next patch. v2: (Ville) - s/wait_for_crtc_hw_done/wait_for_connector_hw_done - Get drm_device using an intel_display instead of drm_i915_private ptr. Reviewed-by: Ville Syrjälä <[email protected]> Signed-off-by: Imre Deak <[email protected]> Link: https://patchwork.freedesktop.org/patch/msgid/[email protected]
1 parent 5eb2e78 commit b1d43e6

File tree

3 files changed

+26
-4
lines changed

3 files changed

+26
-4
lines changed

drivers/gpu/drm/i915/display/intel_dp.c

Lines changed: 23 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5039,6 +5039,21 @@ bool intel_dp_has_connector(struct intel_dp *intel_dp,
50395039
return false;
50405040
}
50415041

5042+
static void wait_for_connector_hw_done(const struct drm_connector_state *conn_state)
5043+
{
5044+
struct intel_connector *connector = to_intel_connector(conn_state->connector);
5045+
struct intel_display *display = to_intel_display(connector);
5046+
5047+
drm_modeset_lock_assert_held(&display->drm->mode_config.connection_mutex);
5048+
5049+
if (!conn_state->commit)
5050+
return;
5051+
5052+
drm_WARN_ON(display->drm,
5053+
!wait_for_completion_timeout(&conn_state->commit->hw_done,
5054+
msecs_to_jiffies(5000)));
5055+
}
5056+
50425057
int intel_dp_get_active_pipes(struct intel_dp *intel_dp,
50435058
struct drm_modeset_acquire_ctx *ctx,
50445059
u8 *pipe_mask)
@@ -5075,10 +5090,7 @@ int intel_dp_get_active_pipes(struct intel_dp *intel_dp,
50755090
if (!crtc_state->hw.active)
50765091
continue;
50775092

5078-
if (conn_state->commit)
5079-
drm_WARN_ON(&i915->drm,
5080-
!wait_for_completion_timeout(&conn_state->commit->hw_done,
5081-
msecs_to_jiffies(5000)));
5093+
wait_for_connector_hw_done(conn_state);
50825094

50835095
*pipe_mask |= BIT(crtc->pipe);
50845096
}
@@ -5087,6 +5099,11 @@ int intel_dp_get_active_pipes(struct intel_dp *intel_dp,
50875099
return ret;
50885100
}
50895101

5102+
void intel_dp_flush_connector_commits(struct intel_connector *connector)
5103+
{
5104+
wait_for_connector_hw_done(connector->base.state);
5105+
}
5106+
50905107
static bool intel_dp_is_connected(struct intel_dp *intel_dp)
50915108
{
50925109
struct intel_connector *connector = intel_dp->attached_connector;
@@ -5600,6 +5617,8 @@ intel_dp_detect(struct drm_connector *connector,
56005617
if (!intel_display_driver_check_access(dev_priv))
56015618
return connector->status;
56025619

5620+
intel_dp_flush_connector_commits(intel_connector);
5621+
56035622
/* Can't disconnect eDP */
56045623
if (intel_dp_is_edp(intel_dp))
56055624
status = edp_detect(intel_dp);

drivers/gpu/drm/i915/display/intel_dp.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,7 @@ void intel_dp_set_link_params(struct intel_dp *intel_dp,
5454
int intel_dp_get_active_pipes(struct intel_dp *intel_dp,
5555
struct drm_modeset_acquire_ctx *ctx,
5656
u8 *pipe_mask);
57+
void intel_dp_flush_connector_commits(struct intel_connector *connector);
5758
void intel_dp_link_check(struct intel_encoder *encoder);
5859
void intel_dp_check_link_state(struct intel_dp *intel_dp);
5960
void intel_dp_set_power(struct intel_dp *intel_dp, u8 mode);

drivers/gpu/drm/i915/display/intel_dp_mst.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1573,6 +1573,8 @@ intel_dp_mst_detect(struct drm_connector *connector,
15731573
if (!intel_display_driver_check_access(i915))
15741574
return connector->status;
15751575

1576+
intel_dp_flush_connector_commits(intel_connector);
1577+
15761578
return drm_dp_mst_detect_port(connector, ctx, &intel_dp->mst_mgr,
15771579
intel_connector->port);
15781580
}

0 commit comments

Comments
 (0)