Message ID | 1436874683-24090-4-git-send-email-sonika.jindal@intel.com (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
On ti, 2015-07-14 at 17:21 +0530, Sonika Jindal wrote: > Adding this for SKL onwards. > > 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) > > Signed-off-by: Sonika Jindal <sonika.jindal@intel.com> > --- > drivers/gpu/drm/i915/intel_dp.c | 4 ++-- > drivers/gpu/drm/i915/intel_drv.h | 2 ++ > drivers/gpu/drm/i915/intel_hdmi.c | 43 +++++++++++++++++++++++++++++++++---- > 3 files changed, 43 insertions(+), 6 deletions(-) > > diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c > index 4ebfc3a..7b54b9d 100644 > --- a/drivers/gpu/drm/i915/intel_dp.c > +++ b/drivers/gpu/drm/i915/intel_dp.c > @@ -4443,8 +4443,8 @@ ironlake_dp_detect(struct intel_dp *intel_dp) > return intel_dp_detect_dpcd(intel_dp); > } > > -static int g4x_digital_port_connected(struct drm_device *dev, > - struct intel_digital_port *intel_dig_port) > +int g4x_digital_port_connected(struct drm_device *dev, > + struct intel_digital_port *intel_dig_port) > { > struct drm_i915_private *dev_priv = dev->dev_private; > uint32_t bit; > diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h > index a47fbc3..30c8dd6 100644 > --- a/drivers/gpu/drm/i915/intel_drv.h > +++ b/drivers/gpu/drm/i915/intel_drv.h > @@ -1187,6 +1187,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); > +int g4x_digital_port_connected(struct drm_device *dev, > + struct intel_digital_port *intel_dig_port); > > /* intel_dp_mst.c */ > int intel_dp_mst_encoder_init(struct intel_digital_port *intel_dig_port, int conn_id); > diff --git a/drivers/gpu/drm/i915/intel_hdmi.c b/drivers/gpu/drm/i915/intel_hdmi.c > index c4b82ce..402be54 100644 > --- a/drivers/gpu/drm/i915/intel_hdmi.c > +++ b/drivers/gpu/drm/i915/intel_hdmi.c > @@ -1300,6 +1300,40 @@ intel_hdmi_unset_edid(struct drm_connector *connector) > to_intel_connector(connector)->detect_edid = NULL; > } > > +static bool bxt_port_connected(struct drm_i915_private *dev_priv, > + struct intel_digital_port *port) > +{ > + u32 temp = I915_READ(GEN8_DE_PORT_ISR); > + > + /* TODO: Add bxt A0/A1 wa related to hpd pin swap */ This doesn't seem to work on my BXT A1 RVP. For me GEN8_DE_PORT_ISR reads all 0 even while an HDMI monitor is plugged to port B. > + switch (port->port) { > + case PORT_B: > + return temp & BXT_DE_PORT_HP_DDIB; > + > + case PORT_C: > + return temp & BXT_DE_PORT_HP_DDIC; > + > + default: > + return false; > + > + } > +} > + > +static bool intel_hdmi_live_status(struct intel_digital_port *intel_dig_port) > +{ > + struct drm_device *dev = intel_dig_port->base.base.dev; > + struct drm_i915_private *dev_priv = to_i915(dev); > + > + if (IS_VALLEYVIEW(dev)) > + return g4x_digital_port_connected(dev, intel_dig_port); > + else if (IS_SKYLAKE(dev)) > + return ibx_digital_port_connected(dev_priv, intel_dig_port); > + else if (IS_BROXTON(dev)) > + return bxt_port_connected(dev_priv, intel_dig_port); > + > + return true; > +} > + > static bool > intel_hdmi_set_edid(struct drm_connector *connector) > { > @@ -1308,15 +1342,16 @@ intel_hdmi_set_edid(struct drm_connector *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 (intel_hdmi_live_status(hdmi_to_dig_port(intel_hdmi))) > + edid = drm_get_edid(connector, > + intel_gmbus_get_adapter(dev_priv, > + intel_hdmi->ddc_bus)); > > intel_display_power_put(dev_priv, power_domain); >
On 7/14/2015 7:59 PM, Imre Deak wrote: > On ti, 2015-07-14 at 17:21 +0530, Sonika Jindal wrote: >> Adding this for SKL onwards. >> >> 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) >> >> Signed-off-by: Sonika Jindal <sonika.jindal@intel.com> >> --- >> drivers/gpu/drm/i915/intel_dp.c | 4 ++-- >> drivers/gpu/drm/i915/intel_drv.h | 2 ++ >> drivers/gpu/drm/i915/intel_hdmi.c | 43 +++++++++++++++++++++++++++++++++---- >> 3 files changed, 43 insertions(+), 6 deletions(-) >> >> diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c >> index 4ebfc3a..7b54b9d 100644 >> --- a/drivers/gpu/drm/i915/intel_dp.c >> +++ b/drivers/gpu/drm/i915/intel_dp.c >> @@ -4443,8 +4443,8 @@ ironlake_dp_detect(struct intel_dp *intel_dp) >> return intel_dp_detect_dpcd(intel_dp); >> } >> >> -static int g4x_digital_port_connected(struct drm_device *dev, >> - struct intel_digital_port *intel_dig_port) >> +int g4x_digital_port_connected(struct drm_device *dev, >> + struct intel_digital_port *intel_dig_port) >> { >> struct drm_i915_private *dev_priv = dev->dev_private; >> uint32_t bit; >> diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h >> index a47fbc3..30c8dd6 100644 >> --- a/drivers/gpu/drm/i915/intel_drv.h >> +++ b/drivers/gpu/drm/i915/intel_drv.h >> @@ -1187,6 +1187,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); >> +int g4x_digital_port_connected(struct drm_device *dev, >> + struct intel_digital_port *intel_dig_port); >> >> /* intel_dp_mst.c */ >> int intel_dp_mst_encoder_init(struct intel_digital_port *intel_dig_port, int conn_id); >> diff --git a/drivers/gpu/drm/i915/intel_hdmi.c b/drivers/gpu/drm/i915/intel_hdmi.c >> index c4b82ce..402be54 100644 >> --- a/drivers/gpu/drm/i915/intel_hdmi.c >> +++ b/drivers/gpu/drm/i915/intel_hdmi.c >> @@ -1300,6 +1300,40 @@ intel_hdmi_unset_edid(struct drm_connector *connector) >> to_intel_connector(connector)->detect_edid = NULL; >> } >> >> +static bool bxt_port_connected(struct drm_i915_private *dev_priv, >> + struct intel_digital_port *port) >> +{ >> + u32 temp = I915_READ(GEN8_DE_PORT_ISR); >> + >> + /* TODO: Add bxt A0/A1 wa related to hpd pin swap */ > > This doesn't seem to work on my BXT A1 RVP. For me GEN8_DE_PORT_ISR > reads all 0 even while an HDMI monitor is plugged to port B. > This is really strange, I checked on atleast 3 different A1 boards and 3 different monitors (also on two different branches) and I see 0x44440 as 0x8 after the HPD swap patch when monitor is connected and it is 0 when no hdmi monitor is present. Do you think something to do with the board config? >> + switch (port->port) { >> + case PORT_B: >> + return temp & BXT_DE_PORT_HP_DDIB; >> + >> + case PORT_C: >> + return temp & BXT_DE_PORT_HP_DDIC; >> + >> + default: >> + return false; >> + >> + } >> +} >> + >> +static bool intel_hdmi_live_status(struct intel_digital_port *intel_dig_port) >> +{ >> + struct drm_device *dev = intel_dig_port->base.base.dev; >> + struct drm_i915_private *dev_priv = to_i915(dev); >> + >> + if (IS_VALLEYVIEW(dev)) >> + return g4x_digital_port_connected(dev, intel_dig_port); >> + else if (IS_SKYLAKE(dev)) >> + return ibx_digital_port_connected(dev_priv, intel_dig_port); >> + else if (IS_BROXTON(dev)) >> + return bxt_port_connected(dev_priv, intel_dig_port); >> + >> + return true; >> +} >> + >> static bool >> intel_hdmi_set_edid(struct drm_connector *connector) >> { >> @@ -1308,15 +1342,16 @@ intel_hdmi_set_edid(struct drm_connector *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 (intel_hdmi_live_status(hdmi_to_dig_port(intel_hdmi))) >> + edid = drm_get_edid(connector, >> + intel_gmbus_get_adapter(dev_priv, >> + intel_hdmi->ddc_bus)); >> >> intel_display_power_put(dev_priv, power_domain); >> > >
On Wed, 2015-07-15 at 09:25 +0530, Jindal, Sonika wrote: > > On 7/14/2015 7:59 PM, Imre Deak wrote: > > On ti, 2015-07-14 at 17:21 +0530, Sonika Jindal wrote: > >> Adding this for SKL onwards. > >> > >> 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) > >> > >> Signed-off-by: Sonika Jindal <sonika.jindal@intel.com> > >> --- > >> drivers/gpu/drm/i915/intel_dp.c | 4 ++-- > >> drivers/gpu/drm/i915/intel_drv.h | 2 ++ > >> drivers/gpu/drm/i915/intel_hdmi.c | 43 +++++++++++++++++++++++++++++++++---- > >> 3 files changed, 43 insertions(+), 6 deletions(-) > >> > >> diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c > >> index 4ebfc3a..7b54b9d 100644 > >> --- a/drivers/gpu/drm/i915/intel_dp.c > >> +++ b/drivers/gpu/drm/i915/intel_dp.c > >> @@ -4443,8 +4443,8 @@ ironlake_dp_detect(struct intel_dp *intel_dp) > >> return intel_dp_detect_dpcd(intel_dp); > >> } > >> > >> -static int g4x_digital_port_connected(struct drm_device *dev, > >> - struct intel_digital_port *intel_dig_port) > >> +int g4x_digital_port_connected(struct drm_device *dev, > >> + struct intel_digital_port *intel_dig_port) > >> { > >> struct drm_i915_private *dev_priv = dev->dev_private; > >> uint32_t bit; > >> diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h > >> index a47fbc3..30c8dd6 100644 > >> --- a/drivers/gpu/drm/i915/intel_drv.h > >> +++ b/drivers/gpu/drm/i915/intel_drv.h > >> @@ -1187,6 +1187,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); > >> +int g4x_digital_port_connected(struct drm_device *dev, > >> + struct intel_digital_port *intel_dig_port); > >> > >> /* intel_dp_mst.c */ > >> int intel_dp_mst_encoder_init(struct intel_digital_port *intel_dig_port, int conn_id); > >> diff --git a/drivers/gpu/drm/i915/intel_hdmi.c b/drivers/gpu/drm/i915/intel_hdmi.c > >> index c4b82ce..402be54 100644 > >> --- a/drivers/gpu/drm/i915/intel_hdmi.c > >> +++ b/drivers/gpu/drm/i915/intel_hdmi.c > >> @@ -1300,6 +1300,40 @@ intel_hdmi_unset_edid(struct drm_connector *connector) > >> to_intel_connector(connector)->detect_edid = NULL; > >> } > >> > >> +static bool bxt_port_connected(struct drm_i915_private *dev_priv, > >> + struct intel_digital_port *port) > >> +{ > >> + u32 temp = I915_READ(GEN8_DE_PORT_ISR); > >> + > >> + /* TODO: Add bxt A0/A1 wa related to hpd pin swap */ > > > > This doesn't seem to work on my BXT A1 RVP. For me GEN8_DE_PORT_ISR > > reads all 0 even while an HDMI monitor is plugged to port B. > > > This is really strange, I checked on atleast 3 different A1 boards and 3 > different monitors (also on two different branches) and I see 0x44440 as > 0x8 after the HPD swap patch when monitor is connected and it is 0 when > no hdmi monitor is present. > Do you think something to do with the board config? Upgrading my BIOS from version W25 to W29 has solved this issue, GEN8_DE_PORT_ISR bit 3 is set now correctly whenever the monitor is connected. My guess is that some GPIO/PIN configuration change done by the BIOS has fixed this, although I haven't found the reason by looking at the PAD_CFG register contents and BIOS release notes. > >> + switch (port->port) { > >> + case PORT_B: > >> + return temp & BXT_DE_PORT_HP_DDIB; > >> + > >> + case PORT_C: > >> + return temp & BXT_DE_PORT_HP_DDIC; > >> + > >> + default: > >> + return false; > >> + > >> + } > >> +} > >> + > >> +static bool intel_hdmi_live_status(struct intel_digital_port *intel_dig_port) > >> +{ > >> + struct drm_device *dev = intel_dig_port->base.base.dev; > >> + struct drm_i915_private *dev_priv = to_i915(dev); > >> + > >> + if (IS_VALLEYVIEW(dev)) > >> + return g4x_digital_port_connected(dev, intel_dig_port); > >> + else if (IS_SKYLAKE(dev)) > >> + return ibx_digital_port_connected(dev_priv, intel_dig_port); > >> + else if (IS_BROXTON(dev)) > >> + return bxt_port_connected(dev_priv, intel_dig_port); > >> + > >> + return true; > >> +} > >> + > >> static bool > >> intel_hdmi_set_edid(struct drm_connector *connector) > >> { > >> @@ -1308,15 +1342,16 @@ intel_hdmi_set_edid(struct drm_connector *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 (intel_hdmi_live_status(hdmi_to_dig_port(intel_hdmi))) > >> + edid = drm_get_edid(connector, > >> + intel_gmbus_get_adapter(dev_priv, > >> + intel_hdmi->ddc_bus)); > >> > >> intel_display_power_put(dev_priv, power_domain); > >> > > > >
On 7/14/2015 5:21 PM, Sonika Jindal wrote: > Adding this for SKL onwards. > > 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) > > Signed-off-by: Sonika Jindal <sonika.jindal@intel.com> > --- > drivers/gpu/drm/i915/intel_dp.c | 4 ++-- > drivers/gpu/drm/i915/intel_drv.h | 2 ++ > drivers/gpu/drm/i915/intel_hdmi.c | 43 +++++++++++++++++++++++++++++++++---- > 3 files changed, 43 insertions(+), 6 deletions(-) > > diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c > index 4ebfc3a..7b54b9d 100644 > --- a/drivers/gpu/drm/i915/intel_dp.c > +++ b/drivers/gpu/drm/i915/intel_dp.c > @@ -4443,8 +4443,8 @@ ironlake_dp_detect(struct intel_dp *intel_dp) > return intel_dp_detect_dpcd(intel_dp); > } > > -static int g4x_digital_port_connected(struct drm_device *dev, > - struct intel_digital_port *intel_dig_port) > +int g4x_digital_port_connected(struct drm_device *dev, > + struct intel_digital_port *intel_dig_port) > { > struct drm_i915_private *dev_priv = dev->dev_private; > uint32_t bit; > diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h > index a47fbc3..30c8dd6 100644 > --- a/drivers/gpu/drm/i915/intel_drv.h > +++ b/drivers/gpu/drm/i915/intel_drv.h > @@ -1187,6 +1187,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); > +int g4x_digital_port_connected(struct drm_device *dev, > + struct intel_digital_port *intel_dig_port); > > /* intel_dp_mst.c */ > int intel_dp_mst_encoder_init(struct intel_digital_port *intel_dig_port, int conn_id); > diff --git a/drivers/gpu/drm/i915/intel_hdmi.c b/drivers/gpu/drm/i915/intel_hdmi.c > index c4b82ce..402be54 100644 > --- a/drivers/gpu/drm/i915/intel_hdmi.c > +++ b/drivers/gpu/drm/i915/intel_hdmi.c > @@ -1300,6 +1300,40 @@ intel_hdmi_unset_edid(struct drm_connector *connector) > to_intel_connector(connector)->detect_edid = NULL; > } > > +static bool bxt_port_connected(struct drm_i915_private *dev_priv, > + struct intel_digital_port *port) > +{ > + u32 temp = I915_READ(GEN8_DE_PORT_ISR); > + > + /* TODO: Add bxt A0/A1 wa related to hpd pin swap */ > + switch (port->port) { why not pass the encoder and use its hpd_pin ? that will avoid the need to do A0/A1 related checks ? > + case PORT_B: > + return temp & BXT_DE_PORT_HP_DDIB; > + > + case PORT_C: > + return temp & BXT_DE_PORT_HP_DDIC; > + > + default: > + return false; > + > + } > +} > + > +static bool intel_hdmi_live_status(struct intel_digital_port *intel_dig_port) > +{ > + struct drm_device *dev = intel_dig_port->base.base.dev; > + struct drm_i915_private *dev_priv = to_i915(dev); > + > + if (IS_VALLEYVIEW(dev)) > + return g4x_digital_port_connected(dev, intel_dig_port); > + else if (IS_SKYLAKE(dev)) > + return ibx_digital_port_connected(dev_priv, intel_dig_port); > + else if (IS_BROXTON(dev)) > + return bxt_port_connected(dev_priv, intel_dig_port); > + > + return true; > +} > + > static bool > intel_hdmi_set_edid(struct drm_connector *connector) > { > @@ -1308,15 +1342,16 @@ intel_hdmi_set_edid(struct drm_connector *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 (intel_hdmi_live_status(hdmi_to_dig_port(intel_hdmi))) > + edid = drm_get_edid(connector, > + intel_gmbus_get_adapter(dev_priv, > + intel_hdmi->ddc_bus)); > > intel_display_power_put(dev_priv, power_domain); >
On 8/10/2015 11:14 AM, Sivakumar Thulasimani wrote: > > > On 7/14/2015 5:21 PM, Sonika Jindal wrote: >> Adding this for SKL onwards. >> >> 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) >> >> Signed-off-by: Sonika Jindal <sonika.jindal@intel.com> >> --- >> drivers/gpu/drm/i915/intel_dp.c | 4 ++-- >> drivers/gpu/drm/i915/intel_drv.h | 2 ++ >> drivers/gpu/drm/i915/intel_hdmi.c | 43 >> +++++++++++++++++++++++++++++++++---- >> 3 files changed, 43 insertions(+), 6 deletions(-) >> >> diff --git a/drivers/gpu/drm/i915/intel_dp.c >> b/drivers/gpu/drm/i915/intel_dp.c >> index 4ebfc3a..7b54b9d 100644 >> --- a/drivers/gpu/drm/i915/intel_dp.c >> +++ b/drivers/gpu/drm/i915/intel_dp.c >> @@ -4443,8 +4443,8 @@ ironlake_dp_detect(struct intel_dp *intel_dp) >> return intel_dp_detect_dpcd(intel_dp); >> } >> -static int g4x_digital_port_connected(struct drm_device *dev, >> - struct intel_digital_port *intel_dig_port) >> +int g4x_digital_port_connected(struct drm_device *dev, >> + struct intel_digital_port *intel_dig_port) >> { >> struct drm_i915_private *dev_priv = dev->dev_private; >> uint32_t bit; >> diff --git a/drivers/gpu/drm/i915/intel_drv.h >> b/drivers/gpu/drm/i915/intel_drv.h >> index a47fbc3..30c8dd6 100644 >> --- a/drivers/gpu/drm/i915/intel_drv.h >> +++ b/drivers/gpu/drm/i915/intel_drv.h >> @@ -1187,6 +1187,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); >> +int g4x_digital_port_connected(struct drm_device *dev, >> + struct intel_digital_port *intel_dig_port); >> /* intel_dp_mst.c */ >> int intel_dp_mst_encoder_init(struct intel_digital_port >> *intel_dig_port, int conn_id); >> diff --git a/drivers/gpu/drm/i915/intel_hdmi.c >> b/drivers/gpu/drm/i915/intel_hdmi.c >> index c4b82ce..402be54 100644 >> --- a/drivers/gpu/drm/i915/intel_hdmi.c >> +++ b/drivers/gpu/drm/i915/intel_hdmi.c >> @@ -1300,6 +1300,40 @@ intel_hdmi_unset_edid(struct drm_connector >> *connector) >> to_intel_connector(connector)->detect_edid = NULL; >> } >> +static bool bxt_port_connected(struct drm_i915_private *dev_priv, >> + struct intel_digital_port *port) >> +{ >> + u32 temp = I915_READ(GEN8_DE_PORT_ISR); >> + >> + /* TODO: Add bxt A0/A1 wa related to hpd pin swap */ >> + switch (port->port) { > why not pass the encoder and use its hpd_pin ? that will avoid the need > to do > A0/A1 related checks ? This was kept to make it inline with the other functions which does the same thing. But because of the work around i think it will make sense to try the way you suggest. >> + case PORT_B: >> + return temp & BXT_DE_PORT_HP_DDIB; >> + >> + case PORT_C: >> + return temp & BXT_DE_PORT_HP_DDIC; >> + >> + default: >> + return false; >> + >> + } >> +} >> + >> +static bool intel_hdmi_live_status(struct intel_digital_port >> *intel_dig_port) >> +{ >> + struct drm_device *dev = intel_dig_port->base.base.dev; >> + struct drm_i915_private *dev_priv = to_i915(dev); >> + >> + if (IS_VALLEYVIEW(dev)) >> + return g4x_digital_port_connected(dev, intel_dig_port); >> + else if (IS_SKYLAKE(dev)) >> + return ibx_digital_port_connected(dev_priv, intel_dig_port); >> + else if (IS_BROXTON(dev)) >> + return bxt_port_connected(dev_priv, intel_dig_port); >> + >> + return true; >> +} >> + >> static bool >> intel_hdmi_set_edid(struct drm_connector *connector) >> { >> @@ -1308,15 +1342,16 @@ intel_hdmi_set_edid(struct drm_connector >> *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 (intel_hdmi_live_status(hdmi_to_dig_port(intel_hdmi))) >> + edid = drm_get_edid(connector, >> + intel_gmbus_get_adapter(dev_priv, >> + intel_hdmi->ddc_bus)); >> intel_display_power_put(dev_priv, power_domain); >
diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c index 4ebfc3a..7b54b9d 100644 --- a/drivers/gpu/drm/i915/intel_dp.c +++ b/drivers/gpu/drm/i915/intel_dp.c @@ -4443,8 +4443,8 @@ ironlake_dp_detect(struct intel_dp *intel_dp) return intel_dp_detect_dpcd(intel_dp); } -static int g4x_digital_port_connected(struct drm_device *dev, - struct intel_digital_port *intel_dig_port) +int g4x_digital_port_connected(struct drm_device *dev, + struct intel_digital_port *intel_dig_port) { struct drm_i915_private *dev_priv = dev->dev_private; uint32_t bit; diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h index a47fbc3..30c8dd6 100644 --- a/drivers/gpu/drm/i915/intel_drv.h +++ b/drivers/gpu/drm/i915/intel_drv.h @@ -1187,6 +1187,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); +int g4x_digital_port_connected(struct drm_device *dev, + struct intel_digital_port *intel_dig_port); /* intel_dp_mst.c */ int intel_dp_mst_encoder_init(struct intel_digital_port *intel_dig_port, int conn_id); diff --git a/drivers/gpu/drm/i915/intel_hdmi.c b/drivers/gpu/drm/i915/intel_hdmi.c index c4b82ce..402be54 100644 --- a/drivers/gpu/drm/i915/intel_hdmi.c +++ b/drivers/gpu/drm/i915/intel_hdmi.c @@ -1300,6 +1300,40 @@ intel_hdmi_unset_edid(struct drm_connector *connector) to_intel_connector(connector)->detect_edid = NULL; } +static bool bxt_port_connected(struct drm_i915_private *dev_priv, + struct intel_digital_port *port) +{ + u32 temp = I915_READ(GEN8_DE_PORT_ISR); + + /* TODO: Add bxt A0/A1 wa related to hpd pin swap */ + switch (port->port) { + case PORT_B: + return temp & BXT_DE_PORT_HP_DDIB; + + case PORT_C: + return temp & BXT_DE_PORT_HP_DDIC; + + default: + return false; + + } +} + +static bool intel_hdmi_live_status(struct intel_digital_port *intel_dig_port) +{ + struct drm_device *dev = intel_dig_port->base.base.dev; + struct drm_i915_private *dev_priv = to_i915(dev); + + if (IS_VALLEYVIEW(dev)) + return g4x_digital_port_connected(dev, intel_dig_port); + else if (IS_SKYLAKE(dev)) + return ibx_digital_port_connected(dev_priv, intel_dig_port); + else if (IS_BROXTON(dev)) + return bxt_port_connected(dev_priv, intel_dig_port); + + return true; +} + static bool intel_hdmi_set_edid(struct drm_connector *connector) { @@ -1308,15 +1342,16 @@ intel_hdmi_set_edid(struct drm_connector *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 (intel_hdmi_live_status(hdmi_to_dig_port(intel_hdmi))) + edid = drm_get_edid(connector, + intel_gmbus_get_adapter(dev_priv, + intel_hdmi->ddc_bus)); intel_display_power_put(dev_priv, power_domain);
Adding this for SKL onwards. 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) Signed-off-by: Sonika Jindal <sonika.jindal@intel.com> --- drivers/gpu/drm/i915/intel_dp.c | 4 ++-- drivers/gpu/drm/i915/intel_drv.h | 2 ++ drivers/gpu/drm/i915/intel_hdmi.c | 43 +++++++++++++++++++++++++++++++++---- 3 files changed, 43 insertions(+), 6 deletions(-)