Message ID | 1442290460-22109-1-git-send-email-sonika.jindal@intel.com (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
On Tue, Sep 15, 2015 at 09:44:20AM +0530, Sonika Jindal wrote: > The Bspec is very clear that Live status must be checked about before > trying to read EDID over DDC channel. This patch makes sure that HDMI > EDID is read only when live status is up. > > The live status doesn't seem to perform very consistent across various > platforms when tested with different monitors. The reason behind that is > some monitors are late to provide right voltage to set live_status up. > So, after getting the interrupt, for a small duration, live status reg > fluctuates, and then settles down showing the correct staus. > > This is explained here in, in a rough way: > HPD line ________________ > |\ T1 = Monitor Hotplug causing IRQ > | \______________________________________ > | | > | | > | | T2 = Live status is stable > | | _____________________________________ > | | /| > Live status _____________|_|/ | > | | | > | | | > | | | > T0 T1 T2 > > (Between T1 and T2 Live status fluctuates or can be even low, depending on > the monitor) > > After several experiments, we have concluded that a max delay > of 30ms is enough to allow the live status to settle down with > most of the monitors. This total delay of 30ms has been split into > a resolution of 3 retries of 10ms each, for the better cases. > > This delay is kept at 30ms, keeping in consideration that, HDCP compliance > expect the HPD handler to respond a plug out in 100ms, by disabling port. > > v2: Adding checks for VLV/CHV as well. Reusing old ibx and g4x functions > to check digital port status. Adding a separate function to get bxt live > status (Daniel) > v3: Using intel_encoder->hpd_pin to check the live status (Siva) > Moving the live status read to intel_hdmi_probe and passing parameter > to read/not to read the edid. (me) > v4: > * Added live status check for all platforms using > intel_digital_port_connected. > * Rebased on top of Jani's DP cleanup series > * Some monitors take time in setting the live status. So retry for few > times if this is a connect HPD > v5: Removed extra "drm/i915" from commit message. Adding Shashank's sob > which was missed. > v6: Drop the (!detect_edid && !live_status check) check because for DDI > ports which are enumerated as hdmi as well as DP, we don't have a > mechanism to differentiate between DP and hdmi inside the encoder's > hot_plug. This leads to call to the hdmi's hot_plug hook for DP as well > as hdmi which leads to issues during unplug because of the above check. > v7: Make intel_digital_port_connected global in this patch, some > reformatting of while loop, adding a print when live status is not > up. (Rodrigo) > v8: Rebase it on nightly which involved skipping the hot_plug hook for now > and letting the live_status check happen in detect until the hpd handling > part is finalized (Daniel) > > Signed-off-by: Shashank Sharma <shashank.sharma@intel.com> > Signed-off-by: Sonika Jindal <sonika.jindal@intel.com> > Reviewed-by: Rodrigo Vivi <rodrigo.vivi@intel.com> Queued for -next, thanks for the patch. -Daniel > --- > drivers/gpu/drm/i915/intel_dp.c | 2 +- > drivers/gpu/drm/i915/intel_drv.h | 2 ++ > drivers/gpu/drm/i915/intel_hdmi.c | 28 +++++++++++++++++++++------- > 3 files changed, 24 insertions(+), 8 deletions(-) > > diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c > index a687250..a6e22dd 100644 > --- a/drivers/gpu/drm/i915/intel_dp.c > +++ b/drivers/gpu/drm/i915/intel_dp.c > @@ -4670,7 +4670,7 @@ static bool bxt_digital_port_connected(struct drm_i915_private *dev_priv, > * > * Return %true if @port is connected, %false otherwise. > */ > -static bool intel_digital_port_connected(struct drm_i915_private *dev_priv, > +bool intel_digital_port_connected(struct drm_i915_private *dev_priv, > struct intel_digital_port *port) > { > if (HAS_PCH_IBX(dev_priv)) > diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h > index 08ba362..1e01350 100644 > --- a/drivers/gpu/drm/i915/intel_drv.h > +++ b/drivers/gpu/drm/i915/intel_drv.h > @@ -1210,6 +1210,8 @@ void intel_edp_drrs_disable(struct intel_dp *intel_dp); > void intel_edp_drrs_invalidate(struct drm_device *dev, > unsigned frontbuffer_bits); > void intel_edp_drrs_flush(struct drm_device *dev, unsigned frontbuffer_bits); > +bool intel_digital_port_connected(struct drm_i915_private *dev_priv, > + struct intel_digital_port *port); > void hsw_dp_set_ddi_pll_sel(struct intel_crtc_state *pipe_config); > > /* intel_dp_mst.c */ > diff --git a/drivers/gpu/drm/i915/intel_hdmi.c b/drivers/gpu/drm/i915/intel_hdmi.c > index e978c59..bb33c66 100644 > --- a/drivers/gpu/drm/i915/intel_hdmi.c > +++ b/drivers/gpu/drm/i915/intel_hdmi.c > @@ -1329,22 +1329,23 @@ intel_hdmi_unset_edid(struct drm_connector *connector) > } > > static bool > -intel_hdmi_set_edid(struct drm_connector *connector) > +intel_hdmi_set_edid(struct drm_connector *connector, bool force) > { > struct drm_i915_private *dev_priv = to_i915(connector->dev); > struct intel_hdmi *intel_hdmi = intel_attached_hdmi(connector); > struct intel_encoder *intel_encoder = > &hdmi_to_dig_port(intel_hdmi)->base; > enum intel_display_power_domain power_domain; > - struct edid *edid; > + struct edid *edid = NULL; > bool connected = false; > > power_domain = intel_display_port_power_domain(intel_encoder); > intel_display_power_get(dev_priv, power_domain); > > - edid = drm_get_edid(connector, > - intel_gmbus_get_adapter(dev_priv, > - intel_hdmi->ddc_bus)); > + if (force) > + edid = drm_get_edid(connector, > + intel_gmbus_get_adapter(dev_priv, > + intel_hdmi->ddc_bus)); > > intel_display_power_put(dev_priv, power_domain); > > @@ -1372,13 +1373,26 @@ static enum drm_connector_status > intel_hdmi_detect(struct drm_connector *connector, bool force) > { > enum drm_connector_status status; > + struct intel_hdmi *intel_hdmi = intel_attached_hdmi(connector); > + struct drm_i915_private *dev_priv = to_i915(connector->dev); > + bool live_status = false; > + unsigned int retry = 3; > > DRM_DEBUG_KMS("[CONNECTOR:%d:%s]\n", > connector->base.id, connector->name); > > + while (!live_status && --retry) { > + live_status = intel_digital_port_connected(dev_priv, > + hdmi_to_dig_port(intel_hdmi)); > + mdelay(10); > + } > + > + if (!live_status) > + DRM_DEBUG_KMS("Live status not up!"); > + > intel_hdmi_unset_edid(connector); > > - if (intel_hdmi_set_edid(connector)) { > + if (intel_hdmi_set_edid(connector, live_status)) { > struct intel_hdmi *intel_hdmi = intel_attached_hdmi(connector); > > hdmi_to_dig_port(intel_hdmi)->base.type = INTEL_OUTPUT_HDMI; > @@ -1402,7 +1416,7 @@ intel_hdmi_force(struct drm_connector *connector) > if (connector->status != connector_status_connected) > return; > > - intel_hdmi_set_edid(connector); > + intel_hdmi_set_edid(connector, true); > hdmi_to_dig_port(intel_hdmi)->base.type = INTEL_OUTPUT_HDMI; > } > > -- > 1.7.10.4 > > _______________________________________________ > Intel-gfx mailing list > Intel-gfx@lists.freedesktop.org > http://lists.freedesktop.org/mailman/listinfo/intel-gfx
On Tue, Sep 15, 2015 at 09:44:20AM +0530, Sonika Jindal wrote: > The Bspec is very clear that Live status must be checked about before > trying to read EDID over DDC channel. This patch makes sure that HDMI > EDID is read only when live status is up. > > The live status doesn't seem to perform very consistent across various > platforms when tested with different monitors. The reason behind that is > some monitors are late to provide right voltage to set live_status up. > So, after getting the interrupt, for a small duration, live status reg > fluctuates, and then settles down showing the correct staus. > > This is explained here in, in a rough way: > HPD line ________________ > |\ T1 = Monitor Hotplug causing IRQ > | \______________________________________ > | | > | | > | | T2 = Live status is stable > | | _____________________________________ > | | /| > Live status _____________|_|/ | > | | | > | | | > | | | > T0 T1 T2 > > (Between T1 and T2 Live status fluctuates or can be even low, depending on > the monitor) > > After several experiments, we have concluded that a max delay > of 30ms is enough to allow the live status to settle down with > most of the monitors. This total delay of 30ms has been split into > a resolution of 3 retries of 10ms each, for the better cases. > > This delay is kept at 30ms, keeping in consideration that, HDCP compliance > expect the HPD handler to respond a plug out in 100ms, by disabling port. This is a regression-fest. Revert with stable@? -Chris
+Shashank Shashank was planning to give a patch to bypass live status checks for older platforms. Regards, Sonika -----Original Message----- From: Chris Wilson [mailto:chris@chris-wilson.co.uk] Sent: Wednesday, March 9, 2016 2:34 AM To: Jindal, Sonika <sonika.jindal@intel.com> Cc: intel-gfx@lists.freedesktop.org Subject: Re: [Intel-gfx] [PATCH] drm/i915: Check live status before reading edid On Tue, Sep 15, 2015 at 09:44:20AM +0530, Sonika Jindal wrote: > The Bspec is very clear that Live status must be checked about before > trying to read EDID over DDC channel. This patch makes sure that HDMI > EDID is read only when live status is up. > > The live status doesn't seem to perform very consistent across various > platforms when tested with different monitors. The reason behind that > is some monitors are late to provide right voltage to set live_status up. > So, after getting the interrupt, for a small duration, live status reg > fluctuates, and then settles down showing the correct staus. > > This is explained here in, in a rough way: > HPD line ________________ > |\ T1 = Monitor Hotplug causing IRQ > | \______________________________________ > | | > | | > | | T2 = Live status is stable > | | _____________________________________ > | | /| > Live status _____________|_|/ | > | | | > | | | > | | | > T0 T1 T2 > > (Between T1 and T2 Live status fluctuates or can be even low, > depending on the monitor) > > After several experiments, we have concluded that a max delay of 30ms > is enough to allow the live status to settle down with most of the > monitors. This total delay of 30ms has been split into a resolution of > 3 retries of 10ms each, for the better cases. > > This delay is kept at 30ms, keeping in consideration that, HDCP > compliance expect the HPD handler to respond a plug out in 100ms, by disabling port. This is a regression-fest. Revert with stable@? -Chris -- Chris Wilson, Intel Open Source Technology Centre
We are procuring the DVI-single-link cable, as we don't have one with us. Sonika tested the Dual link cable, and that was working well. We can do two things here: - Add the gen check, which will allow the live_status check only for VLV and + platforms, others will go as it is. - Wait for some more time, get the cable and try to rep and fix the issue. Regards Shashank -----Original Message----- From: Jindal, Sonika Sent: Wednesday, March 09, 2016 11:23 AM To: Chris Wilson; Sharma, Shashank Cc: intel-gfx@lists.freedesktop.org Subject: RE: [Intel-gfx] [PATCH] drm/i915: Check live status before reading edid +Shashank Shashank was planning to give a patch to bypass live status checks for older platforms. Regards, Sonika -----Original Message----- From: Chris Wilson [mailto:chris@chris-wilson.co.uk] Sent: Wednesday, March 9, 2016 2:34 AM To: Jindal, Sonika <sonika.jindal@intel.com> Cc: intel-gfx@lists.freedesktop.org Subject: Re: [Intel-gfx] [PATCH] drm/i915: Check live status before reading edid On Tue, Sep 15, 2015 at 09:44:20AM +0530, Sonika Jindal wrote: > The Bspec is very clear that Live status must be checked about before > trying to read EDID over DDC channel. This patch makes sure that HDMI > EDID is read only when live status is up. > > The live status doesn't seem to perform very consistent across various > platforms when tested with different monitors. The reason behind that > is some monitors are late to provide right voltage to set live_status up. > So, after getting the interrupt, for a small duration, live status reg > fluctuates, and then settles down showing the correct staus. > > This is explained here in, in a rough way: > HPD line ________________ > |\ T1 = Monitor Hotplug causing IRQ > | \______________________________________ > | | > | | > | | T2 = Live status is stable > | | _____________________________________ > | | /| > Live status _____________|_|/ | > | | | > | | | > | | | > T0 T1 T2 > > (Between T1 and T2 Live status fluctuates or can be even low, > depending on the monitor) > > After several experiments, we have concluded that a max delay of 30ms > is enough to allow the live status to settle down with most of the > monitors. This total delay of 30ms has been split into a resolution of > 3 retries of 10ms each, for the better cases. > > This delay is kept at 30ms, keeping in consideration that, HDCP > compliance expect the HPD handler to respond a plug out in 100ms, by disabling port. This is a regression-fest. Revert with stable@? -Chris -- Chris Wilson, Intel Open Source Technology Centre
Hi all, I have sent one patch with live_status check restricted to gen7 and +, for this regression. drm/i915: Restrict usage of live status check Please help in review. Regards Shashank -----Original Message----- From: Sharma, Shashank Sent: Wednesday, March 09, 2016 11:25 AM To: Jindal, Sonika; Chris Wilson Cc: intel-gfx@lists.freedesktop.org; Mukherjee, Indranil Subject: RE: [Intel-gfx] [PATCH] drm/i915: Check live status before reading edid We are procuring the DVI-single-link cable, as we don't have one with us. Sonika tested the Dual link cable, and that was working well. We can do two things here: - Add the gen check, which will allow the live_status check only for VLV and + platforms, others will go as it is. - Wait for some more time, get the cable and try to rep and fix the issue. Regards Shashank -----Original Message----- From: Jindal, Sonika Sent: Wednesday, March 09, 2016 11:23 AM To: Chris Wilson; Sharma, Shashank Cc: intel-gfx@lists.freedesktop.org Subject: RE: [Intel-gfx] [PATCH] drm/i915: Check live status before reading edid +Shashank Shashank was planning to give a patch to bypass live status checks for older platforms. Regards, Sonika -----Original Message----- From: Chris Wilson [mailto:chris@chris-wilson.co.uk] Sent: Wednesday, March 9, 2016 2:34 AM To: Jindal, Sonika <sonika.jindal@intel.com> Cc: intel-gfx@lists.freedesktop.org Subject: Re: [Intel-gfx] [PATCH] drm/i915: Check live status before reading edid On Tue, Sep 15, 2015 at 09:44:20AM +0530, Sonika Jindal wrote: > The Bspec is very clear that Live status must be checked about before > trying to read EDID over DDC channel. This patch makes sure that HDMI > EDID is read only when live status is up. > > The live status doesn't seem to perform very consistent across various > platforms when tested with different monitors. The reason behind that > is some monitors are late to provide right voltage to set live_status up. > So, after getting the interrupt, for a small duration, live status reg > fluctuates, and then settles down showing the correct staus. > > This is explained here in, in a rough way: > HPD line ________________ > |\ T1 = Monitor Hotplug causing IRQ > | \______________________________________ > | | > | | > | | T2 = Live status is stable > | | _____________________________________ > | | /| > Live status _____________|_|/ | > | | | > | | | > | | | > T0 T1 T2 > > (Between T1 and T2 Live status fluctuates or can be even low, > depending on the monitor) > > After several experiments, we have concluded that a max delay of 30ms > is enough to allow the live status to settle down with most of the > monitors. This total delay of 30ms has been split into a resolution of > 3 retries of 10ms each, for the better cases. > > This delay is kept at 30ms, keeping in consideration that, HDCP > compliance expect the HPD handler to respond a plug out in 100ms, by disabling port. This is a regression-fest. Revert with stable@? -Chris -- Chris Wilson, Intel Open Source Technology Centre
diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c index a687250..a6e22dd 100644 --- a/drivers/gpu/drm/i915/intel_dp.c +++ b/drivers/gpu/drm/i915/intel_dp.c @@ -4670,7 +4670,7 @@ static bool bxt_digital_port_connected(struct drm_i915_private *dev_priv, * * Return %true if @port is connected, %false otherwise. */ -static bool intel_digital_port_connected(struct drm_i915_private *dev_priv, +bool intel_digital_port_connected(struct drm_i915_private *dev_priv, struct intel_digital_port *port) { if (HAS_PCH_IBX(dev_priv)) diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h index 08ba362..1e01350 100644 --- a/drivers/gpu/drm/i915/intel_drv.h +++ b/drivers/gpu/drm/i915/intel_drv.h @@ -1210,6 +1210,8 @@ void intel_edp_drrs_disable(struct intel_dp *intel_dp); void intel_edp_drrs_invalidate(struct drm_device *dev, unsigned frontbuffer_bits); void intel_edp_drrs_flush(struct drm_device *dev, unsigned frontbuffer_bits); +bool intel_digital_port_connected(struct drm_i915_private *dev_priv, + struct intel_digital_port *port); void hsw_dp_set_ddi_pll_sel(struct intel_crtc_state *pipe_config); /* intel_dp_mst.c */ diff --git a/drivers/gpu/drm/i915/intel_hdmi.c b/drivers/gpu/drm/i915/intel_hdmi.c index e978c59..bb33c66 100644 --- a/drivers/gpu/drm/i915/intel_hdmi.c +++ b/drivers/gpu/drm/i915/intel_hdmi.c @@ -1329,22 +1329,23 @@ intel_hdmi_unset_edid(struct drm_connector *connector) } static bool -intel_hdmi_set_edid(struct drm_connector *connector) +intel_hdmi_set_edid(struct drm_connector *connector, bool force) { struct drm_i915_private *dev_priv = to_i915(connector->dev); struct intel_hdmi *intel_hdmi = intel_attached_hdmi(connector); struct intel_encoder *intel_encoder = &hdmi_to_dig_port(intel_hdmi)->base; enum intel_display_power_domain power_domain; - struct edid *edid; + struct edid *edid = NULL; bool connected = false; power_domain = intel_display_port_power_domain(intel_encoder); intel_display_power_get(dev_priv, power_domain); - edid = drm_get_edid(connector, - intel_gmbus_get_adapter(dev_priv, - intel_hdmi->ddc_bus)); + if (force) + edid = drm_get_edid(connector, + intel_gmbus_get_adapter(dev_priv, + intel_hdmi->ddc_bus)); intel_display_power_put(dev_priv, power_domain); @@ -1372,13 +1373,26 @@ static enum drm_connector_status intel_hdmi_detect(struct drm_connector *connector, bool force) { enum drm_connector_status status; + struct intel_hdmi *intel_hdmi = intel_attached_hdmi(connector); + struct drm_i915_private *dev_priv = to_i915(connector->dev); + bool live_status = false; + unsigned int retry = 3; DRM_DEBUG_KMS("[CONNECTOR:%d:%s]\n", connector->base.id, connector->name); + while (!live_status && --retry) { + live_status = intel_digital_port_connected(dev_priv, + hdmi_to_dig_port(intel_hdmi)); + mdelay(10); + } + + if (!live_status) + DRM_DEBUG_KMS("Live status not up!"); + intel_hdmi_unset_edid(connector); - if (intel_hdmi_set_edid(connector)) { + if (intel_hdmi_set_edid(connector, live_status)) { struct intel_hdmi *intel_hdmi = intel_attached_hdmi(connector); hdmi_to_dig_port(intel_hdmi)->base.type = INTEL_OUTPUT_HDMI; @@ -1402,7 +1416,7 @@ intel_hdmi_force(struct drm_connector *connector) if (connector->status != connector_status_connected) return; - intel_hdmi_set_edid(connector); + intel_hdmi_set_edid(connector, true); hdmi_to_dig_port(intel_hdmi)->base.type = INTEL_OUTPUT_HDMI; }