diff mbox

[v2] drm/i915/dp: Send DPCD ON for MST before phy_up

Message ID 20180405203601.23242-1-lyude@redhat.com (mailing list archive)
State New, archived
Headers show

Commit Message

Lyude Paul April 5, 2018, 8:36 p.m. UTC
When doing a modeset where the sink is transitioning from D3 to D0 , it
would sometimes be possible for the initial power_up_phy() to start
timing out. This would only be observed in the last action before the
sink went into D3 mode was intel_dp_sink_dpms(DRM_MODE_DPMS_OFF). We
originally thought this might be an issue with us accidentally shutting
off the aux block when putting the sink into D3, but since the DP spec
mandates that sinks must wake up within 1ms while we have 100ms to
respond to an ESI irq, this didn't really add up. Turns out that the
problem is more subtle then that:

It turns out that the timeout is from us not enabling DPMS on the MST
hub before actually trying to initiate sideband communications. This
would cause the first sideband communication (power_up_phy()), to start
timing out because the sink wasn't ready to respond. Afterwards, we
would call intel_dp_sink_dpms(DRM_MODE_DPMS_ON) in
intel_ddi_pre_enable_dp(), which would actually result in waking up the
sink so that sideband requests would work again.

Since DPMS is what lets us actually bring the hub up into a state where
sideband communications become functional again, we just need to make
sure to enable DPMS on the display before attempting to perform sideband
communications.

Changes since v1:
- Remove comment above if (!intel_dp->is_mst) - vsryjala
- Move intel_dp_sink_dpms() for MST into intel_dp_post_disable_mst() to
  keep enable/disable paths symmetrical
- Improve commit message - dhnkrn

Signed-off-by: Lyude Paul <lyude@redhat.com>
Cc: Dhinakaran Pandiyan <dhinakaran.pandiyan@intel.com>
Cc: Ville Syrjälä <ville.syrjala@linux.intel.com>
Cc: Laura Abbott <labbott@redhat.com>
Cc: stable@vger.kernel.org
Fixes: ad260ab32a4d9 ("drm/i915/dp: Write to SET_POWER dpcd to enable MST hub.")
---
This email should hopefully actually be picked up by patchwork this
time, hooray!

 drivers/gpu/drm/i915/intel_ddi.c    | 6 ++++--
 drivers/gpu/drm/i915/intel_dp_mst.c | 2 ++
 2 files changed, 6 insertions(+), 2 deletions(-)

Comments

Lyude Paul April 5, 2018, 8:49 p.m. UTC | #1
Actually - ignore this patch, I'm going to do a v3 because i just noticed
there is something very silly and broken I just introduced into the disable
codepath

On Thu, 2018-04-05 at 16:36 -0400, Lyude Paul wrote:
> When doing a modeset where the sink is transitioning from D3 to D0 , it
> would sometimes be possible for the initial power_up_phy() to start
> timing out. This would only be observed in the last action before the
> sink went into D3 mode was intel_dp_sink_dpms(DRM_MODE_DPMS_OFF). We
> originally thought this might be an issue with us accidentally shutting
> off the aux block when putting the sink into D3, but since the DP spec
> mandates that sinks must wake up within 1ms while we have 100ms to
> respond to an ESI irq, this didn't really add up. Turns out that the
> problem is more subtle then that:
> 
> It turns out that the timeout is from us not enabling DPMS on the MST
> hub before actually trying to initiate sideband communications. This
> would cause the first sideband communication (power_up_phy()), to start
> timing out because the sink wasn't ready to respond. Afterwards, we
> would call intel_dp_sink_dpms(DRM_MODE_DPMS_ON) in
> intel_ddi_pre_enable_dp(), which would actually result in waking up the
> sink so that sideband requests would work again.
> 
> Since DPMS is what lets us actually bring the hub up into a state where
> sideband communications become functional again, we just need to make
> sure to enable DPMS on the display before attempting to perform sideband
> communications.
> 
> Changes since v1:
> - Remove comment above if (!intel_dp->is_mst) - vsryjala
> - Move intel_dp_sink_dpms() for MST into intel_dp_post_disable_mst() to
>   keep enable/disable paths symmetrical
> - Improve commit message - dhnkrn
> 
> Signed-off-by: Lyude Paul <lyude@redhat.com>
> Cc: Dhinakaran Pandiyan <dhinakaran.pandiyan@intel.com>
> Cc: Ville Syrjälä <ville.syrjala@linux.intel.com>
> Cc: Laura Abbott <labbott@redhat.com>
> Cc: stable@vger.kernel.org
> Fixes: ad260ab32a4d9 ("drm/i915/dp: Write to SET_POWER dpcd to enable MST
> hub.")
> ---
> This email should hopefully actually be picked up by patchwork this
> time, hooray!
> 
>  drivers/gpu/drm/i915/intel_ddi.c    | 6 ++++--
>  drivers/gpu/drm/i915/intel_dp_mst.c | 2 ++
>  2 files changed, 6 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/intel_ddi.c
> b/drivers/gpu/drm/i915/intel_ddi.c
> index a6672a9abd85..c0bf7419e1c1 100644
> --- a/drivers/gpu/drm/i915/intel_ddi.c
> +++ b/drivers/gpu/drm/i915/intel_ddi.c
> @@ -2324,7 +2324,8 @@ static void intel_ddi_pre_enable_dp(struct
> intel_encoder *encoder,
>  		intel_prepare_dp_ddi_buffers(encoder, crtc_state);
>  
>  	intel_ddi_init_dp_buf_reg(encoder);
> -	intel_dp_sink_dpms(intel_dp, DRM_MODE_DPMS_ON);
> +	if (!intel_dp->is_mst)
> +		intel_dp_sink_dpms(intel_dp, DRM_MODE_DPMS_ON);
>  	intel_dp_start_link_train(intel_dp);
>  	if (port != PORT_A || INTEL_GEN(dev_priv) >= 9)
>  		intel_dp_stop_link_train(intel_dp);
> @@ -2427,7 +2428,8 @@ static void intel_ddi_post_disable_dp(struct
> intel_encoder *encoder,
>  	 * Power down sink before disabling the port, otherwise we end
>  	 * up getting interrupts from the sink on detecting link loss.
>  	 */
> -	intel_dp_sink_dpms(intel_dp, DRM_MODE_DPMS_OFF);
> +	if (!intel_dp->is_mst)
> +		intel_dp_sink_dpms(intel_dp, DRM_MODE_DPMS_OFF);
>  
>  	intel_disable_ddi_buf(encoder);
>  
> diff --git a/drivers/gpu/drm/i915/intel_dp_mst.c
> b/drivers/gpu/drm/i915/intel_dp_mst.c
> index c3de0918ee13..2493bd1e0e59 100644
> --- a/drivers/gpu/drm/i915/intel_dp_mst.c
> +++ b/drivers/gpu/drm/i915/intel_dp_mst.c
> @@ -176,6 +176,7 @@ static void intel_mst_post_disable_dp(struct
> intel_encoder *encoder,
>  	 */
>  	drm_dp_send_power_updown_phy(&intel_dp->mst_mgr, connector->port,
>  				     false);
> +	intel_dp_sink_dpms(intel_dp, DRM_MODE_DPMS_OFF);
>  
>  	intel_dp->active_mst_links--;
>  
> @@ -223,6 +224,7 @@ static void intel_mst_pre_enable_dp(struct intel_encoder
> *encoder,
>  
>  	DRM_DEBUG_KMS("active links %d\n", intel_dp->active_mst_links);
>  
> +	intel_dp_sink_dpms(intel_dp, DRM_MODE_DPMS_ON);
>  	drm_dp_send_power_updown_phy(&intel_dp->mst_mgr, connector->port,
> true);
>  	if (intel_dp->active_mst_links == 0)
>  		intel_dig_port->base.pre_enable(&intel_dig_port->base,
Dhinakaran Pandiyan April 5, 2018, 8:51 p.m. UTC | #2
On Thu, 2018-04-05 at 16:36 -0400, Lyude Paul wrote:
> When doing a modeset where the sink is transitioning from D3 to D0 , it

> would sometimes be possible for the initial power_up_phy() to start

> timing out. This would only be observed in the last action before the

> sink went into D3 mode was intel_dp_sink_dpms(DRM_MODE_DPMS_OFF). We

> originally thought this might be an issue with us accidentally shutting

> off the aux block when putting the sink into D3, but since the DP spec

> mandates that sinks must wake up within 1ms while we have 100ms to

> respond to an ESI irq, this didn't really add up. Turns out that the

> problem is more subtle then that:

> 

> It turns out that the timeout is from us not enabling DPMS on the MST

> hub before actually trying to initiate sideband communications. This

> would cause the first sideband communication (power_up_phy()), to start

> timing out because the sink wasn't ready to respond. Afterwards, we

> would call intel_dp_sink_dpms(DRM_MODE_DPMS_ON) in

> intel_ddi_pre_enable_dp(), which would actually result in waking up the

> sink so that sideband requests would work again.

> 

> Since DPMS is what lets us actually bring the hub up into a state where

> sideband communications become functional again, we just need to make

> sure to enable DPMS on the display before attempting to perform sideband

> communications.

> 

> Changes since v1:

> - Remove comment above if (!intel_dp->is_mst) - vsryjala

> - Move intel_dp_sink_dpms() for MST into intel_dp_post_disable_mst() to

>   keep enable/disable paths symmetrical

> - Improve commit message - dhnkrn

> 

> Signed-off-by: Lyude Paul <lyude@redhat.com>

> Cc: Dhinakaran Pandiyan <dhinakaran.pandiyan@intel.com>

> Cc: Ville Syrjälä <ville.syrjala@linux.intel.com>

> Cc: Laura Abbott <labbott@redhat.com>

> Cc: stable@vger.kernel.org

> Fixes: ad260ab32a4d9 ("drm/i915/dp: Write to SET_POWER dpcd to enable MST hub.")

> ---

> This email should hopefully actually be picked up by patchwork this

> time, hooray!

> 

>  drivers/gpu/drm/i915/intel_ddi.c    | 6 ++++--

>  drivers/gpu/drm/i915/intel_dp_mst.c | 2 ++

>  2 files changed, 6 insertions(+), 2 deletions(-)

> 

> diff --git a/drivers/gpu/drm/i915/intel_ddi.c b/drivers/gpu/drm/i915/intel_ddi.c

> index a6672a9abd85..c0bf7419e1c1 100644

> --- a/drivers/gpu/drm/i915/intel_ddi.c

> +++ b/drivers/gpu/drm/i915/intel_ddi.c

> @@ -2324,7 +2324,8 @@ static void intel_ddi_pre_enable_dp(struct intel_encoder *encoder,

>  		intel_prepare_dp_ddi_buffers(encoder, crtc_state);

>  

>  	intel_ddi_init_dp_buf_reg(encoder);

> -	intel_dp_sink_dpms(intel_dp, DRM_MODE_DPMS_ON);

> +	if (!intel_dp->is_mst)

> +		intel_dp_sink_dpms(intel_dp, DRM_MODE_DPMS_ON);

>  	intel_dp_start_link_train(intel_dp);

>  	if (port != PORT_A || INTEL_GEN(dev_priv) >= 9)

>  		intel_dp_stop_link_train(intel_dp);

> @@ -2427,7 +2428,8 @@ static void intel_ddi_post_disable_dp(struct intel_encoder *encoder,

>  	 * Power down sink before disabling the port, otherwise we end

>  	 * up getting interrupts from the sink on detecting link loss.

>  	 */

> -	intel_dp_sink_dpms(intel_dp, DRM_MODE_DPMS_OFF);

> +	if (!intel_dp->is_mst)

> +		intel_dp_sink_dpms(intel_dp, DRM_MODE_DPMS_OFF);

>  

>  	intel_disable_ddi_buf(encoder);

>  

> diff --git a/drivers/gpu/drm/i915/intel_dp_mst.c b/drivers/gpu/drm/i915/intel_dp_mst.c

> index c3de0918ee13..2493bd1e0e59 100644

> --- a/drivers/gpu/drm/i915/intel_dp_mst.c

> +++ b/drivers/gpu/drm/i915/intel_dp_mst.c

> @@ -176,6 +176,7 @@ static void intel_mst_post_disable_dp(struct intel_encoder *encoder,

>  	 */

>  	drm_dp_send_power_updown_phy(&intel_dp->mst_mgr, connector->port,

>  				     false);

> +	intel_dp_sink_dpms(intel_dp, DRM_MODE_DPMS_OFF);


Needed only when _links goes from 1 -> 0
>  

>  	intel_dp->active_mst_links--;

>  

> @@ -223,6 +224,7 @@ static void intel_mst_pre_enable_dp(struct intel_encoder *encoder,

>  

>  	DRM_DEBUG_KMS("active links %d\n", intel_dp->active_mst_links);

>  

> +	intel_dp_sink_dpms(intel_dp, DRM_MODE_DPMS_ON);

Needed only when _links goes from 0 -> 1
>  	drm_dp_send_power_updown_phy(&intel_dp->mst_mgr, connector->port, true);

>  	if (intel_dp->active_mst_links == 0)

>  		intel_dig_port->base.pre_enable(&intel_dig_port->base,
Sasha Levin April 10, 2018, 1:49 p.m. UTC | #3
Hi,

[This is an automated email]

This commit has been processed because it contains a "Fixes:" tag,
fixing commit: .

The bot has also determined it's probably a bug fixing patch. (score: 98.1292)

The bot has tested the following trees: v4.16.1, v4.15.16, v4.14.33, v4.9.93, v4.4.127.

v4.16.1: Build OK!
v4.15.16: Build OK!
v4.14.33: Failed to apply! Possible dependencies:
    5ea2355a100a ("drm/i915/mst: Use MST sideband message transactions for dpms control")
    b1e314462bba ("drm/i915/dp: Write to SET_POWER dpcd to enable MST hub.")
    c5f93fcf2ee1 ("drm/i915: Disable infoframes when shutting down DDI HDMI")
    f45f3da7c4f6 ("drm/i915: Split intel_ddi_post_disable() into DP vs. HDMI variants")

v4.9.93: Failed to apply! Possible dependencies:
    5ea2355a100a ("drm/i915/mst: Use MST sideband message transactions for dpms control")
    b1e314462bba ("drm/i915/dp: Write to SET_POWER dpcd to enable MST hub.")
    c5f93fcf2ee1 ("drm/i915: Disable infoframes when shutting down DDI HDMI")
    f45f3da7c4f6 ("drm/i915: Split intel_ddi_post_disable() into DP vs. HDMI variants")

v4.4.127: Failed to apply! Possible dependencies:
    0552f7651bc2 ("drm/i915/mst: use reference counted connectors. (v3)")
    5ea2355a100a ("drm/i915/mst: Use MST sideband message transactions for dpms control")
    b1e314462bba ("drm/i915/dp: Write to SET_POWER dpcd to enable MST hub.")
    ba88d153526f ("drm/i915: Split intel_ddi_pre_enable() into DP and HDMI versions")
    c5f93fcf2ee1 ("drm/i915: Disable infoframes when shutting down DDI HDMI")
    f45f3da7c4f6 ("drm/i915: Split intel_ddi_post_disable() into DP vs. HDMI variants")


--
Thanks,
Sasha
diff mbox

Patch

diff --git a/drivers/gpu/drm/i915/intel_ddi.c b/drivers/gpu/drm/i915/intel_ddi.c
index a6672a9abd85..c0bf7419e1c1 100644
--- a/drivers/gpu/drm/i915/intel_ddi.c
+++ b/drivers/gpu/drm/i915/intel_ddi.c
@@ -2324,7 +2324,8 @@  static void intel_ddi_pre_enable_dp(struct intel_encoder *encoder,
 		intel_prepare_dp_ddi_buffers(encoder, crtc_state);
 
 	intel_ddi_init_dp_buf_reg(encoder);
-	intel_dp_sink_dpms(intel_dp, DRM_MODE_DPMS_ON);
+	if (!intel_dp->is_mst)
+		intel_dp_sink_dpms(intel_dp, DRM_MODE_DPMS_ON);
 	intel_dp_start_link_train(intel_dp);
 	if (port != PORT_A || INTEL_GEN(dev_priv) >= 9)
 		intel_dp_stop_link_train(intel_dp);
@@ -2427,7 +2428,8 @@  static void intel_ddi_post_disable_dp(struct intel_encoder *encoder,
 	 * Power down sink before disabling the port, otherwise we end
 	 * up getting interrupts from the sink on detecting link loss.
 	 */
-	intel_dp_sink_dpms(intel_dp, DRM_MODE_DPMS_OFF);
+	if (!intel_dp->is_mst)
+		intel_dp_sink_dpms(intel_dp, DRM_MODE_DPMS_OFF);
 
 	intel_disable_ddi_buf(encoder);
 
diff --git a/drivers/gpu/drm/i915/intel_dp_mst.c b/drivers/gpu/drm/i915/intel_dp_mst.c
index c3de0918ee13..2493bd1e0e59 100644
--- a/drivers/gpu/drm/i915/intel_dp_mst.c
+++ b/drivers/gpu/drm/i915/intel_dp_mst.c
@@ -176,6 +176,7 @@  static void intel_mst_post_disable_dp(struct intel_encoder *encoder,
 	 */
 	drm_dp_send_power_updown_phy(&intel_dp->mst_mgr, connector->port,
 				     false);
+	intel_dp_sink_dpms(intel_dp, DRM_MODE_DPMS_OFF);
 
 	intel_dp->active_mst_links--;
 
@@ -223,6 +224,7 @@  static void intel_mst_pre_enable_dp(struct intel_encoder *encoder,
 
 	DRM_DEBUG_KMS("active links %d\n", intel_dp->active_mst_links);
 
+	intel_dp_sink_dpms(intel_dp, DRM_MODE_DPMS_ON);
 	drm_dp_send_power_updown_phy(&intel_dp->mst_mgr, connector->port, true);
 	if (intel_dp->active_mst_links == 0)
 		intel_dig_port->base.pre_enable(&intel_dig_port->base,