diff mbox

[6/8] drm/i915/dp: clear DP encoder CRTC if the receiver disappears

Message ID 1309558978-4704-7-git-send-email-jbarnes@virtuousgeek.org (mailing list archive)
State New, archived
Headers show

Commit Message

Jesse Barnes July 1, 2011, 10:22 p.m. UTC
If the receiver goes away, drop any associated CRTC.  This will force a
full mode set on any subsequent setcrtc call, which is what we need if
the receiver is gone and the link is down.

Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
---
 drivers/gpu/drm/i915/intel_dp.c |   10 ++++++++--
 1 files changed, 8 insertions(+), 2 deletions(-)

Comments

Keith Packard July 1, 2011, 11:48 p.m. UTC | #1
On Fri,  1 Jul 2011 15:22:56 -0700, Jesse Barnes <jbarnes@virtuousgeek.org> wrote:

> If the receiver goes away, drop any associated CRTC.  This will force a
> full mode set on any subsequent setcrtc call, which is what we need if
> the receiver is gone and the link is down.

This doesn't look like a good solution to me -- we're smashing the
connection between the DP output and the selected CRTC. If you plug the
cable back in, won't this mess things up when we try to retrain again?
Jesse Barnes July 1, 2011, 11:59 p.m. UTC | #2
On Fri, 01 Jul 2011 16:48:27 -0700
Keith Packard <keithp@keithp.com> wrote:

> On Fri,  1 Jul 2011 15:22:56 -0700, Jesse Barnes <jbarnes@virtuousgeek.org> wrote:
> 
> > If the receiver goes away, drop any associated CRTC.  This will force a
> > full mode set on any subsequent setcrtc call, which is what we need if
> > the receiver is gone and the link is down.
> 
> This doesn't look like a good solution to me -- we're smashing the
> connection between the DP output and the selected CRTC. If you plug the
> cable back in, won't this mess things up when we try to retrain again?

That depends on what behavior we want.  With the previous fixes, if you
unplug, we'll get a hotplug event, fail to detect a link, and tear down
the receiver.  With the old code you'd get bad behavior unless you had
hit a DPMS path earlier.

A subsequent hotplug will be ignored as far as link training goes, since
we don't have a receiver configured.

In both cases, we'll emit hotplug events to userspace, which is free to
react (or not) however it wants.

So I think we'd need to leave the receiver_configured bit set even if
the hot plug re-train failed, and just try it again on the next hot
plug (assuming we want to preserve user configs across hot plug
events and not just let userspace handle the hotplug events).
Keith Packard July 2, 2011, 12:31 a.m. UTC | #3
On Fri, 1 Jul 2011 16:59:48 -0700, Jesse Barnes <jbarnes@virtuousgeek.org> wrote:

> That depends on what behavior we want.  With the previous fixes, if you
> unplug, we'll get a hotplug event, fail to detect a link, and tear down
> the receiver.  With the old code you'd get bad behavior unless you had
> hit a DPMS path earlier.

Yeah, the old code was clearly wrong; this looks like something that
needs fixing, I just don't know what the right fix is.

> A subsequent hotplug will be ignored as far as link training goes, since
> we don't have a receiver configured.

Do we need separate variables for 'should be configured' and 'actually is
configured' then? We need to know if there is a configuration we should
be selecting, and then we need to know whether the display is actually
using that configuration.

> In both cases, we'll emit hotplug events to userspace, which is free to
> react (or not) however it wants.

Let's assume (for now) that user space doesn't do anything. That seems
like a good first step to get right; we should assume that if user space
sets some mode then it should work correctly.

> So I think we'd need to leave the receiver_configured bit set even if
> the hot plug re-train failed, and just try it again on the next hot
> plug (assuming we want to preserve user configs across hot plug
> events and not just let userspace handle the hotplug events).

I don't think we want to lose the user config -- in the absence of any
user-driven changes, we want to reset the mode exactly as it was when
the monitor is plugged back in.
diff mbox

Patch

diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c
index f41aec3..d7a8d24 100644
--- a/drivers/gpu/drm/i915/intel_dp.c
+++ b/drivers/gpu/drm/i915/intel_dp.c
@@ -1533,7 +1533,7 @@  intel_dp_check_link_status(struct intel_dp *intel_dp)
 
 	if (!intel_dp_get_link_status(intel_dp)) {
 		intel_dp_link_down(intel_dp);
-		return;
+		goto out_gone;
 	}
 
 	/* Try to read receiver status if the link appears to be up */
@@ -1542,13 +1542,19 @@  intel_dp_check_link_status(struct intel_dp *intel_dp)
 				       sizeof (intel_dp->dpcd));
 	if (ret != sizeof(intel_dp->dpcd)) {
 		intel_dp_link_down(intel_dp);
-		return;
+		goto out_gone;
 	}
 
 	if (!intel_channel_eq_ok(intel_dp)) {
 		intel_dp_start_link_train(intel_dp);
 		intel_dp_complete_link_train(intel_dp);
 	}
+
+	return;
+
+out_gone:
+	DRM_DEBUG_DRIVER("sink gone, clearing crtc for DP\n");
+	intel_dp->base.base.crtc = NULL;
 }
 
 static enum drm_connector_status