Commit 5ea2355a authored by Dhinakaran Pandiyan's avatar Dhinakaran Pandiyan Committed by Jani Nikula

drm/i915/mst: Use MST sideband message transactions for dpms control

Use the POWER_DOWN_PHY and POWER_UP_PHY sideband message transactions to
set power states for downstream sinks. Apart from giving us the ability
to set power state for individual sinks, this fixes the below test for
me.

$ xrandr --display :0 --output DP-2-2-8 --off
$ xrandr --display :0 --output DP-2-2-1 --off
$ xrandr --display :0 --output DP-2-2-8 --auto #Black screen
$ xrandr --display :0 --output DP-2-2-1 --auto

v2: Modify and document the dpms and port disable order (Ville)
    Add comment explaining is_mst = !crtc_state equivalence(Ville, Maarten)

v3 by Jani: rebase

References: https://bugs.freedesktop.org/show_bug.cgi?id=90963
References: https://bugs.freedesktop.org/show_bug.cgi?id=88124
Cc: Ville Syrjälä <ville.syrjala@linux.intel.com>
Cc: Lyude <lyude@redhat.com>
Cc: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
Reviewed-by: default avatarLyude Paul <lyude@redhat.com>
Acked-by: default avatarMaarten Lankhorst <maarten.lankhorst@linux.intel.com>
Signed-off-by: default avatarDhinakaran Pandiyan <dhinakaran.pandiyan@intel.com>
Signed-off-by: default avatarJani Nikula <jani.nikula@intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20171003142211.860-1-jani.nikula@intel.com
parent ac14fbd4
...@@ -2162,6 +2162,7 @@ static void intel_ddi_pre_enable_dp(struct intel_encoder *encoder, ...@@ -2162,6 +2162,7 @@ static void intel_ddi_pre_enable_dp(struct intel_encoder *encoder,
intel_prepare_dp_ddi_buffers(encoder); intel_prepare_dp_ddi_buffers(encoder);
intel_ddi_init_dp_buf_reg(encoder); intel_ddi_init_dp_buf_reg(encoder);
if (!link_mst)
intel_dp_sink_dpms(intel_dp, DRM_MODE_DPMS_ON); intel_dp_sink_dpms(intel_dp, DRM_MODE_DPMS_ON);
intel_dp_start_link_train(intel_dp); intel_dp_start_link_train(intel_dp);
if (port != PORT_A || INTEL_GEN(dev_priv) >= 9) if (port != PORT_A || INTEL_GEN(dev_priv) >= 9)
...@@ -2236,11 +2237,20 @@ static void intel_ddi_post_disable(struct intel_encoder *intel_encoder, ...@@ -2236,11 +2237,20 @@ static void intel_ddi_post_disable(struct intel_encoder *intel_encoder,
uint32_t val; uint32_t val;
bool wait = false; bool wait = false;
/* old_crtc_state and old_conn_state are NULL when called from DP_MST */
if (type == INTEL_OUTPUT_DP || type == INTEL_OUTPUT_EDP) { if (type == INTEL_OUTPUT_DP || type == INTEL_OUTPUT_EDP) {
/*
* old_crtc_state and old_conn_state are NULL when called from
* DP_MST. The main connector associated with this port is never
* bound to a crtc for MST.
*/
bool is_mst = !old_crtc_state;
struct intel_dp *intel_dp = enc_to_intel_dp(encoder); struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
/*
* Power down sink before disabling the port, otherwise we end
* up getting interrupts from the sink on detecting link loss.
*/
if (!is_mst)
intel_dp_sink_dpms(intel_dp, DRM_MODE_DPMS_OFF); intel_dp_sink_dpms(intel_dp, DRM_MODE_DPMS_OFF);
} }
......
...@@ -162,14 +162,19 @@ static void intel_mst_post_disable_dp(struct intel_encoder *encoder, ...@@ -162,14 +162,19 @@ static void intel_mst_post_disable_dp(struct intel_encoder *encoder,
drm_dp_mst_deallocate_vcpi(&intel_dp->mst_mgr, connector->port); drm_dp_mst_deallocate_vcpi(&intel_dp->mst_mgr, connector->port);
/*
* Power down mst path before disabling the port, otherwise we end
* up getting interrupts from the sink upon detecting link loss.
*/
drm_dp_send_power_updown_phy(&intel_dp->mst_mgr, connector->port,
false);
intel_dp->active_mst_links--; intel_dp->active_mst_links--;
intel_mst->connector = NULL; intel_mst->connector = NULL;
if (intel_dp->active_mst_links == 0) { if (intel_dp->active_mst_links == 0) {
intel_dig_port->base.post_disable(&intel_dig_port->base, intel_dig_port->base.post_disable(&intel_dig_port->base,
NULL, NULL); NULL, NULL);
intel_dp_sink_dpms(intel_dp, DRM_MODE_DPMS_OFF);
} }
DRM_DEBUG_KMS("active links %d\n", intel_dp->active_mst_links); DRM_DEBUG_KMS("active links %d\n", intel_dp->active_mst_links);
} }
...@@ -196,6 +201,7 @@ static void intel_mst_pre_enable_dp(struct intel_encoder *encoder, ...@@ -196,6 +201,7 @@ static void intel_mst_pre_enable_dp(struct intel_encoder *encoder,
DRM_DEBUG_KMS("active links %d\n", intel_dp->active_mst_links); DRM_DEBUG_KMS("active links %d\n", intel_dp->active_mst_links);
drm_dp_send_power_updown_phy(&intel_dp->mst_mgr, connector->port, true);
if (intel_dp->active_mst_links == 0) if (intel_dp->active_mst_links == 0)
intel_dig_port->base.pre_enable(&intel_dig_port->base, intel_dig_port->base.pre_enable(&intel_dig_port->base,
pipe_config, NULL); pipe_config, NULL);
......
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