All the mail mirrored from lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 1/2] drm/i915: Always perform link training when requested
@ 2016-05-13  6:23 Shubhangi Shrivastava
  2016-05-13  6:23 ` [PATCH 2/2] drm/i915: Lane count change detection Shubhangi Shrivastava
  2016-05-13  6:30 ` ✗ Ro.CI.BAT: failure for series starting with [1/2] drm/i915: Always perform link training when requested Patchwork
  0 siblings, 2 replies; 4+ messages in thread
From: Shubhangi Shrivastava @ 2016-05-13  6:23 UTC (permalink / raw
  To: intel-gfx; +Cc: Shubhangi Shrivastava

Short pulse can be generated for automated tests requesting
link training again, such scenarios we have to perform the
request irrespective of the current status of link. This
patch adds support for this request in DP encoder.

Signed-off-by: Sivakumar Thulasimani <sivakumar.thulasimani@intel.com>
Signed-off-by: Shubhangi Shrivastava <shubhangi.shrivastava@intel.com>
---
 drivers/gpu/drm/i915/intel_dp.c | 22 +++++++++++++---------
 1 file changed, 13 insertions(+), 9 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c
index 4c564ba..d5ed84f 100644
--- a/drivers/gpu/drm/i915/intel_dp.c
+++ b/drivers/gpu/drm/i915/intel_dp.c
@@ -3846,6 +3846,7 @@ intel_dp_check_link_status(struct intel_dp *intel_dp)
 	struct intel_encoder *intel_encoder = &dp_to_dig_port(intel_dp)->base;
 	struct drm_device *dev = intel_dp_to_dev(intel_dp);
 	u8 link_status[DP_LINK_STATUS_SIZE];
+	bool check_link = false;
 
 	WARN_ON(!drm_modeset_is_locked(&dev->mode_config.connection_mutex));
 
@@ -3854,17 +3855,20 @@ intel_dp_check_link_status(struct intel_dp *intel_dp)
 		return;
 	}
 
-	if (!intel_encoder->base.crtc)
-		return;
-
-	if (!to_intel_crtc(intel_encoder->base.crtc)->active)
-		return;
-
 	/* if link training is requested we should perform it always */
-	if ((intel_dp->compliance_test_type == DP_TEST_LINK_TRAINING) ||
-	    (!drm_dp_channel_eq_ok(link_status, intel_dp->lane_count))) {
-		DRM_DEBUG_KMS("%s: channel EQ not ok, retraining\n",
+	if (intel_dp->compliance_test_type == DP_TEST_LINK_TRAINING) {
+		DRM_DEBUG_KMS("%s: Link training requested, retraining\n",
 			      intel_encoder->base.name);
+		check_link = true;
+	} else if (((to_intel_crtc(intel_encoder->base.crtc)->active) &&
+		  (intel_encoder->base.crtc)) &&
+		  (!drm_dp_channel_eq_ok(link_status, intel_dp->lane_count))) {
+			DRM_DEBUG_KMS("%s: channel EQ not ok, retraining\n",
+				      intel_encoder->base.name);
+			check_link = true;
+	}
+
+	if (check_link) {
 		intel_dp_start_link_train(intel_dp);
 		intel_dp_stop_link_train(intel_dp);
 	}
-- 
2.6.1

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply related	[flat|nested] 4+ messages in thread

* [PATCH 2/2] drm/i915: Lane count change detection
  2016-05-13  6:23 [PATCH 1/2] drm/i915: Always perform link training when requested Shubhangi Shrivastava
@ 2016-05-13  6:23 ` Shubhangi Shrivastava
  2016-05-17 10:17   ` Daniel Vetter
  2016-05-13  6:30 ` ✗ Ro.CI.BAT: failure for series starting with [1/2] drm/i915: Always perform link training when requested Patchwork
  1 sibling, 1 reply; 4+ messages in thread
From: Shubhangi Shrivastava @ 2016-05-13  6:23 UTC (permalink / raw
  To: intel-gfx; +Cc: Shubhangi Shrivastava

DP panel can issue short pulse interrupts during which it can
modify the number of lanes supported by it. This will result in
change in capabilities of the display and limit the max
resoultion possible on it. This should be informed to the
user mode as well since HWC will issue the modeset assuming
old capabilities.

This patch detects lane count change and simulates a detatch
and attach, so to the user mode or anyone else tracking the
display it will appear as unplug and replug of different
display.

v2: moved queuing of delayed thread to intel_dp where we
set simulate_disconnect_connect flag. There is a chance
for short pulse to be hit even before long pulse detection
is complete, in such a scenario the delayed thread won't
be queued resulting in flag never getting cleared.
Since we set the flag and queue it immediately we can be
sure that the flag will be cleared.

Signed-off-by: Sivakumar Thulasimani <sivakumar.thulasimani@intel.com>
Signed-off-by: Shubhangi Shrivastava <shubhangi.shrivastava@intel.com>
---
 drivers/gpu/drm/i915/i915_drv.h      |  1 +
 drivers/gpu/drm/i915/i915_irq.c      |  2 ++
 drivers/gpu/drm/i915/intel_dp.c      | 47 ++++++++++++++++++++++++++++++---
 drivers/gpu/drm/i915/intel_drv.h     |  4 +++
 drivers/gpu/drm/i915/intel_hotplug.c | 50 ++++++++++++++++++++++++++++++++++++
 5 files changed, 100 insertions(+), 4 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index 7a0b513..30d3636 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -280,6 +280,7 @@ struct i915_hotplug {
 	u32 long_port_mask;
 	u32 short_port_mask;
 	struct work_struct dig_port_work;
+	struct delayed_work simulate_work;
 
 	/*
 	 * if we get a HPD irq from DP and a HPD irq from non-DP
diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c
index f0d9414..74fe755 100644
--- a/drivers/gpu/drm/i915/i915_irq.c
+++ b/drivers/gpu/drm/i915/i915_irq.c
@@ -4572,6 +4572,8 @@ void intel_irq_init(struct drm_i915_private *dev_priv)
 
 	INIT_WORK(&dev_priv->rps.work, gen6_pm_rps_work);
 	INIT_WORK(&dev_priv->l3_parity.error_work, ivybridge_parity_work);
+	INIT_DELAYED_WORK(&dev_priv->hotplug.simulate_work,
+			  intel_hpd_simulate_reconnect_work);
 
 	/* Let's track the enabled rps events */
 	if (IS_VALLEYVIEW(dev_priv))
diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c
index d5ed84f..ebd525e 100644
--- a/drivers/gpu/drm/i915/intel_dp.c
+++ b/drivers/gpu/drm/i915/intel_dp.c
@@ -3783,6 +3783,26 @@ update_status:
 	}
 }
 
+static void intel_dp_update_simulate_detach_info(struct intel_dp *intel_dp)
+{
+	struct intel_connector *intel_connector = intel_dp->attached_connector;
+	struct drm_device *dev = intel_dp_to_dev(intel_dp);
+	struct drm_i915_private *dev_priv = dev->dev_private;
+
+	/*
+	 * Queue thread only if it is not already done.
+	 * The flag is cleared inside the callback function
+	 * hence we can be sure that there is no race condition
+	 * under which it may remain set.
+	 */
+	if (!intel_connector->simulate_disconnect_connect) {
+		intel_connector->simulate_disconnect_connect = true;
+		DRM_DEBUG_KMS("Queue simulate work func\n");
+		mod_delayed_work(system_wq, &dev_priv->hotplug.simulate_work,
+				 msecs_to_jiffies(100));
+	}
+}
+
 static int
 intel_dp_check_mst_status(struct intel_dp *intel_dp)
 {
@@ -3893,6 +3913,7 @@ intel_dp_short_pulse(struct intel_dp *intel_dp)
 	struct drm_device *dev = intel_dp_to_dev(intel_dp);
 	u8 sink_irq_vector;
 	u8 old_sink_count = intel_dp->sink_count;
+	u8 old_lane_count = intel_dp->dpcd[DP_MAX_LANE_COUNT];
 	bool ret;
 
 	/*
@@ -3924,6 +3945,20 @@ intel_dp_short_pulse(struct intel_dp *intel_dp)
 			sink_irq_vector &= ~DP_AUTOMATED_TEST_REQUEST;
 		}
 
+		/*
+		 * If lane count has changed, we need to inform
+		 * user mode of new capablities, this is done by setting
+		 * our flag to do a fake disconnect and connect so it
+		 * will appear to the user mode that a new panel is
+		 * connected and will use the new capabilties of the
+		 * panel
+		 */
+		if (old_lane_count != intel_dp->dpcd[DP_MAX_LANE_COUNT]) {
+			DRM_DEBUG_KMS("Lane count changed\n");
+			intel_dp_update_simulate_detach_info(intel_dp);
+			return false;
+		}
+
 		if (sink_irq_vector & (DP_CP_IRQ | DP_SINK_SPECIFIC_IRQ))
 			DRM_DEBUG_DRIVER("CP or sink specific irq unhandled\n");
 
@@ -4213,13 +4248,17 @@ intel_dp_long_pulse(struct intel_connector *intel_connector)
 	intel_display_power_get(to_i915(dev), power_domain);
 
 	/* Can't disconnect eDP, but you can close the lid... */
-	if (is_edp(intel_dp))
+	if (is_edp(intel_dp)) {
 		status = edp_detect(intel_dp);
-	else if (intel_digital_port_connected(to_i915(dev),
-					      dp_to_dig_port(intel_dp)))
+	} else if (intel_connector->simulate_disconnect_connect) {
+		DRM_DEBUG_KMS("Simulating disconnect\n");
+		status = connector_status_disconnected;
+	} else if (intel_digital_port_connected(to_i915(dev),
+					      dp_to_dig_port(intel_dp))) {
 		status = intel_dp_detect_dpcd(intel_dp);
-	else
+	} else {
 		status = connector_status_disconnected;
+	}
 
 	if (status != connector_status_connected) {
 		intel_dp->compliance_test_active = 0;
diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
index 8daadc5..995f0da 100644
--- a/drivers/gpu/drm/i915/intel_drv.h
+++ b/drivers/gpu/drm/i915/intel_drv.h
@@ -257,6 +257,8 @@ struct intel_connector {
 	struct edid *edid;
 	struct edid *detect_edid;
 
+	bool simulate_disconnect_connect;
+
 	/* since POLL and HPD connectors may use the same HPD line keep the native
 	   state of connector->polled in case hotplug storm detection changes it */
 	u8 polled;
@@ -1420,6 +1422,8 @@ bool intel_hdmi_compute_config(struct intel_encoder *encoder,
 			       struct intel_crtc_state *pipe_config);
 void intel_dp_dual_mode_set_tmds_output(struct intel_hdmi *hdmi, bool enable);
 
+/* intel_hotplug.c */
+void intel_hpd_simulate_reconnect_work(struct work_struct *work);
 
 /* intel_lvds.c */
 void intel_lvds_init(struct drm_device *dev);
diff --git a/drivers/gpu/drm/i915/intel_hotplug.c b/drivers/gpu/drm/i915/intel_hotplug.c
index 38eeca7..7e346d7 100644
--- a/drivers/gpu/drm/i915/intel_hotplug.c
+++ b/drivers/gpu/drm/i915/intel_hotplug.c
@@ -247,6 +247,55 @@ static bool intel_hpd_irq_event(struct drm_device *dev,
 	return true;
 }
 
+/*
+ * This function is the second half of logic to perform fake
+ * disconnect-connect. The first half was the connector setting
+ * a flag, returning status as disconnected and queing this function.
+ *
+ * This function uses simulate_disconnect_connect flag to identify the
+ * connector that should be detected again. Since this is executed after
+ * a delay if the panel is still plugged in it will be reported as
+ * connected to user mode
+ */
+void intel_hpd_simulate_reconnect_work(struct work_struct *work)
+{
+	struct drm_i915_private *dev_priv =
+		container_of(work, struct drm_i915_private,
+			     hotplug.simulate_work.work);
+	struct drm_device *dev = dev_priv->dev;
+	struct intel_encoder *intel_encoder;
+	struct intel_connector *intel_connector;
+	struct drm_connector *connector;
+	struct drm_mode_config *mode_config = &dev->mode_config;
+	enum port port;
+
+	DRM_DEBUG_KMS("\n");
+	mutex_lock(&mode_config->mutex);
+
+	list_for_each_entry(connector, &mode_config->connector_list, head) {
+		intel_connector = to_intel_connector(connector);
+		if (!intel_connector->simulate_disconnect_connect)
+			continue;
+
+		intel_connector->simulate_disconnect_connect = false;
+
+		if (!intel_connector->encoder)
+			continue;
+
+		intel_encoder = intel_connector->encoder;
+
+		port = intel_ddi_get_encoder_port(intel_encoder);
+
+		spin_lock_irq(&dev_priv->irq_lock);
+		dev_priv->hotplug.long_port_mask |= (1<<port);
+		spin_unlock_irq(&dev_priv->irq_lock);
+	}
+
+	mutex_unlock(&mode_config->mutex);
+
+	queue_work(dev_priv->hotplug.dp_wq, &dev_priv->hotplug.dig_port_work);
+}
+
 static void i915_digport_work_func(struct work_struct *work)
 {
 	struct drm_i915_private *dev_priv =
@@ -509,4 +558,5 @@ void intel_hpd_cancel_work(struct drm_i915_private *dev_priv)
 	cancel_work_sync(&dev_priv->hotplug.dig_port_work);
 	cancel_work_sync(&dev_priv->hotplug.hotplug_work);
 	cancel_delayed_work_sync(&dev_priv->hotplug.reenable_work);
+	cancel_delayed_work_sync(&dev_priv->hotplug.simulate_work);
 }
-- 
2.6.1

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply related	[flat|nested] 4+ messages in thread

* ✗ Ro.CI.BAT: failure for series starting with [1/2] drm/i915: Always perform link training when requested
  2016-05-13  6:23 [PATCH 1/2] drm/i915: Always perform link training when requested Shubhangi Shrivastava
  2016-05-13  6:23 ` [PATCH 2/2] drm/i915: Lane count change detection Shubhangi Shrivastava
@ 2016-05-13  6:30 ` Patchwork
  1 sibling, 0 replies; 4+ messages in thread
From: Patchwork @ 2016-05-13  6:30 UTC (permalink / raw
  To: Shubhangi Shrivastava; +Cc: intel-gfx

== Series Details ==

Series: series starting with [1/2] drm/i915: Always perform link training when requested
URL   : https://patchwork.freedesktop.org/series/7121/
State : failure

== Summary ==

Applying: drm/i915: Always perform link training when requested
Applying: drm/i915: Lane count change detection
Patch failed at 0002 drm/i915: Lane count change detection
The copy of the patch that failed is found in: .git/rebase-apply/patch
When you have resolved this problem, run "git am --continue".
If you prefer to skip this patch, run "git am --skip" instead.
To restore the original branch and stop patching, run "git am --abort".

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: [PATCH 2/2] drm/i915: Lane count change detection
  2016-05-13  6:23 ` [PATCH 2/2] drm/i915: Lane count change detection Shubhangi Shrivastava
@ 2016-05-17 10:17   ` Daniel Vetter
  0 siblings, 0 replies; 4+ messages in thread
From: Daniel Vetter @ 2016-05-17 10:17 UTC (permalink / raw
  To: Shubhangi Shrivastava; +Cc: intel-gfx

On Fri, May 13, 2016 at 11:53:43AM +0530, Shubhangi Shrivastava wrote:
> DP panel can issue short pulse interrupts during which it can
> modify the number of lanes supported by it. This will result in
> change in capabilities of the display and limit the max
> resoultion possible on it. This should be informed to the
> user mode as well since HWC will issue the modeset assuming
> old capabilities.
> 
> This patch detects lane count change and simulates a detatch
> and attach, so to the user mode or anyone else tracking the
> display it will appear as unplug and replug of different
> display.
> 
> v2: moved queuing of delayed thread to intel_dp where we
> set simulate_disconnect_connect flag. There is a chance
> for short pulse to be hit even before long pulse detection
> is complete, in such a scenario the delayed thread won't
> be queued resulting in flag never getting cleared.
> Since we set the flag and queue it immediately we can be
> sure that the flag will be cleared.
> 
> Signed-off-by: Sivakumar Thulasimani <sivakumar.thulasimani@intel.com>
> Signed-off-by: Shubhangi Shrivastava <shubhangi.shrivastava@intel.com>

This is nonsense, just send a uevent to userspace, and make sure that we
re-validate all the modes. Userspace is supposed to ask for updated mode
lists after every uevent, and then reset a suitable mode.

If hwc can't do that, then we're not going to add a horrible hack to the
kernel of temporarily unplugging something, since fundamentally that's
just duct-tape and still racy.

Note that right now we don't have support to generate uevents for when the
connector status hasn't changed. But we need that in a lot of other cases
too. I think the simplest option is to add a sink_lifetime counter
to drm_connector, and a helper to increment that, e.g.
drm_connector_sink_change().

Then we could call that from our probe/hotplug hooks every time something
relevant changes (different sink dongle, different number of lanes,
different edid). And the top-level probe helpers could also check for any
changes in the sink_lifetime instead of just connect/disconnect. I think
it'd be good if we also wire this up for edid changes, in the core
function which updates the edid blob.

Cheers, Daniel

> ---
>  drivers/gpu/drm/i915/i915_drv.h      |  1 +
>  drivers/gpu/drm/i915/i915_irq.c      |  2 ++
>  drivers/gpu/drm/i915/intel_dp.c      | 47 ++++++++++++++++++++++++++++++---
>  drivers/gpu/drm/i915/intel_drv.h     |  4 +++
>  drivers/gpu/drm/i915/intel_hotplug.c | 50 ++++++++++++++++++++++++++++++++++++
>  5 files changed, 100 insertions(+), 4 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
> index 7a0b513..30d3636 100644
> --- a/drivers/gpu/drm/i915/i915_drv.h
> +++ b/drivers/gpu/drm/i915/i915_drv.h
> @@ -280,6 +280,7 @@ struct i915_hotplug {
>  	u32 long_port_mask;
>  	u32 short_port_mask;
>  	struct work_struct dig_port_work;
> +	struct delayed_work simulate_work;
>  
>  	/*
>  	 * if we get a HPD irq from DP and a HPD irq from non-DP
> diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c
> index f0d9414..74fe755 100644
> --- a/drivers/gpu/drm/i915/i915_irq.c
> +++ b/drivers/gpu/drm/i915/i915_irq.c
> @@ -4572,6 +4572,8 @@ void intel_irq_init(struct drm_i915_private *dev_priv)
>  
>  	INIT_WORK(&dev_priv->rps.work, gen6_pm_rps_work);
>  	INIT_WORK(&dev_priv->l3_parity.error_work, ivybridge_parity_work);
> +	INIT_DELAYED_WORK(&dev_priv->hotplug.simulate_work,
> +			  intel_hpd_simulate_reconnect_work);
>  
>  	/* Let's track the enabled rps events */
>  	if (IS_VALLEYVIEW(dev_priv))
> diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c
> index d5ed84f..ebd525e 100644
> --- a/drivers/gpu/drm/i915/intel_dp.c
> +++ b/drivers/gpu/drm/i915/intel_dp.c
> @@ -3783,6 +3783,26 @@ update_status:
>  	}
>  }
>  
> +static void intel_dp_update_simulate_detach_info(struct intel_dp *intel_dp)
> +{
> +	struct intel_connector *intel_connector = intel_dp->attached_connector;
> +	struct drm_device *dev = intel_dp_to_dev(intel_dp);
> +	struct drm_i915_private *dev_priv = dev->dev_private;
> +
> +	/*
> +	 * Queue thread only if it is not already done.
> +	 * The flag is cleared inside the callback function
> +	 * hence we can be sure that there is no race condition
> +	 * under which it may remain set.
> +	 */
> +	if (!intel_connector->simulate_disconnect_connect) {
> +		intel_connector->simulate_disconnect_connect = true;
> +		DRM_DEBUG_KMS("Queue simulate work func\n");
> +		mod_delayed_work(system_wq, &dev_priv->hotplug.simulate_work,
> +				 msecs_to_jiffies(100));
> +	}
> +}
> +
>  static int
>  intel_dp_check_mst_status(struct intel_dp *intel_dp)
>  {
> @@ -3893,6 +3913,7 @@ intel_dp_short_pulse(struct intel_dp *intel_dp)
>  	struct drm_device *dev = intel_dp_to_dev(intel_dp);
>  	u8 sink_irq_vector;
>  	u8 old_sink_count = intel_dp->sink_count;
> +	u8 old_lane_count = intel_dp->dpcd[DP_MAX_LANE_COUNT];
>  	bool ret;
>  
>  	/*
> @@ -3924,6 +3945,20 @@ intel_dp_short_pulse(struct intel_dp *intel_dp)
>  			sink_irq_vector &= ~DP_AUTOMATED_TEST_REQUEST;
>  		}
>  
> +		/*
> +		 * If lane count has changed, we need to inform
> +		 * user mode of new capablities, this is done by setting
> +		 * our flag to do a fake disconnect and connect so it
> +		 * will appear to the user mode that a new panel is
> +		 * connected and will use the new capabilties of the
> +		 * panel
> +		 */
> +		if (old_lane_count != intel_dp->dpcd[DP_MAX_LANE_COUNT]) {
> +			DRM_DEBUG_KMS("Lane count changed\n");
> +			intel_dp_update_simulate_detach_info(intel_dp);
> +			return false;
> +		}
> +
>  		if (sink_irq_vector & (DP_CP_IRQ | DP_SINK_SPECIFIC_IRQ))
>  			DRM_DEBUG_DRIVER("CP or sink specific irq unhandled\n");
>  
> @@ -4213,13 +4248,17 @@ intel_dp_long_pulse(struct intel_connector *intel_connector)
>  	intel_display_power_get(to_i915(dev), power_domain);
>  
>  	/* Can't disconnect eDP, but you can close the lid... */
> -	if (is_edp(intel_dp))
> +	if (is_edp(intel_dp)) {
>  		status = edp_detect(intel_dp);
> -	else if (intel_digital_port_connected(to_i915(dev),
> -					      dp_to_dig_port(intel_dp)))
> +	} else if (intel_connector->simulate_disconnect_connect) {
> +		DRM_DEBUG_KMS("Simulating disconnect\n");
> +		status = connector_status_disconnected;
> +	} else if (intel_digital_port_connected(to_i915(dev),
> +					      dp_to_dig_port(intel_dp))) {
>  		status = intel_dp_detect_dpcd(intel_dp);
> -	else
> +	} else {
>  		status = connector_status_disconnected;
> +	}
>  
>  	if (status != connector_status_connected) {
>  		intel_dp->compliance_test_active = 0;
> diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
> index 8daadc5..995f0da 100644
> --- a/drivers/gpu/drm/i915/intel_drv.h
> +++ b/drivers/gpu/drm/i915/intel_drv.h
> @@ -257,6 +257,8 @@ struct intel_connector {
>  	struct edid *edid;
>  	struct edid *detect_edid;
>  
> +	bool simulate_disconnect_connect;
> +
>  	/* since POLL and HPD connectors may use the same HPD line keep the native
>  	   state of connector->polled in case hotplug storm detection changes it */
>  	u8 polled;
> @@ -1420,6 +1422,8 @@ bool intel_hdmi_compute_config(struct intel_encoder *encoder,
>  			       struct intel_crtc_state *pipe_config);
>  void intel_dp_dual_mode_set_tmds_output(struct intel_hdmi *hdmi, bool enable);
>  
> +/* intel_hotplug.c */
> +void intel_hpd_simulate_reconnect_work(struct work_struct *work);
>  
>  /* intel_lvds.c */
>  void intel_lvds_init(struct drm_device *dev);
> diff --git a/drivers/gpu/drm/i915/intel_hotplug.c b/drivers/gpu/drm/i915/intel_hotplug.c
> index 38eeca7..7e346d7 100644
> --- a/drivers/gpu/drm/i915/intel_hotplug.c
> +++ b/drivers/gpu/drm/i915/intel_hotplug.c
> @@ -247,6 +247,55 @@ static bool intel_hpd_irq_event(struct drm_device *dev,
>  	return true;
>  }
>  
> +/*
> + * This function is the second half of logic to perform fake
> + * disconnect-connect. The first half was the connector setting
> + * a flag, returning status as disconnected and queing this function.
> + *
> + * This function uses simulate_disconnect_connect flag to identify the
> + * connector that should be detected again. Since this is executed after
> + * a delay if the panel is still plugged in it will be reported as
> + * connected to user mode
> + */
> +void intel_hpd_simulate_reconnect_work(struct work_struct *work)
> +{
> +	struct drm_i915_private *dev_priv =
> +		container_of(work, struct drm_i915_private,
> +			     hotplug.simulate_work.work);
> +	struct drm_device *dev = dev_priv->dev;
> +	struct intel_encoder *intel_encoder;
> +	struct intel_connector *intel_connector;
> +	struct drm_connector *connector;
> +	struct drm_mode_config *mode_config = &dev->mode_config;
> +	enum port port;
> +
> +	DRM_DEBUG_KMS("\n");
> +	mutex_lock(&mode_config->mutex);
> +
> +	list_for_each_entry(connector, &mode_config->connector_list, head) {
> +		intel_connector = to_intel_connector(connector);
> +		if (!intel_connector->simulate_disconnect_connect)
> +			continue;
> +
> +		intel_connector->simulate_disconnect_connect = false;
> +
> +		if (!intel_connector->encoder)
> +			continue;
> +
> +		intel_encoder = intel_connector->encoder;
> +
> +		port = intel_ddi_get_encoder_port(intel_encoder);
> +
> +		spin_lock_irq(&dev_priv->irq_lock);
> +		dev_priv->hotplug.long_port_mask |= (1<<port);
> +		spin_unlock_irq(&dev_priv->irq_lock);
> +	}
> +
> +	mutex_unlock(&mode_config->mutex);
> +
> +	queue_work(dev_priv->hotplug.dp_wq, &dev_priv->hotplug.dig_port_work);
> +}
> +
>  static void i915_digport_work_func(struct work_struct *work)
>  {
>  	struct drm_i915_private *dev_priv =
> @@ -509,4 +558,5 @@ void intel_hpd_cancel_work(struct drm_i915_private *dev_priv)
>  	cancel_work_sync(&dev_priv->hotplug.dig_port_work);
>  	cancel_work_sync(&dev_priv->hotplug.hotplug_work);
>  	cancel_delayed_work_sync(&dev_priv->hotplug.reenable_work);
> +	cancel_delayed_work_sync(&dev_priv->hotplug.simulate_work);
>  }
> -- 
> 2.6.1
> 
> _______________________________________________
> Intel-gfx mailing list
> Intel-gfx@lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/intel-gfx

-- 
Daniel Vetter
Software Engineer, Intel Corporation
http://blog.ffwll.ch
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2016-05-17 10:17 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2016-05-13  6:23 [PATCH 1/2] drm/i915: Always perform link training when requested Shubhangi Shrivastava
2016-05-13  6:23 ` [PATCH 2/2] drm/i915: Lane count change detection Shubhangi Shrivastava
2016-05-17 10:17   ` Daniel Vetter
2016-05-13  6:30 ` ✗ Ro.CI.BAT: failure for series starting with [1/2] drm/i915: Always perform link training when requested Patchwork

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.