Commit 2ded9e27 authored by ling.ma@intel.com's avatar ling.ma@intel.com Committed by Eric Anholt

drm/i915: hdmi detection according by reading edid

According to investigations from windows team ,hw team,
and our test results on all 4x platofrms available
(gm45, g45b, q45, g45a, g45c, g41a, and g41), we find
currently Hot plug live status and Hot plug interrupt
detection are not reliable, sometime the results from
the two approaches are contradicts. So we chose edid
detection for hdmi output.
Signed-off-by: default avatarMa Ling <ling.ma@intel.com>
Reviewed-by: default avatarIan Romanick <ian.d.romanick@intel.com>
Signed-off-by: default avatarEric Anholt <eric@anholt.net>
parent 2a2430f4
...@@ -130,16 +130,17 @@ static bool intel_hdmi_mode_fixup(struct drm_encoder *encoder, ...@@ -130,16 +130,17 @@ static bool intel_hdmi_mode_fixup(struct drm_encoder *encoder,
} }
static enum drm_connector_status static enum drm_connector_status
intel_hdmi_edid_detect(struct drm_connector *connector) intel_hdmi_detect(struct drm_connector *connector)
{ {
struct intel_output *intel_output = to_intel_output(connector); struct intel_output *intel_output = to_intel_output(connector);
struct intel_hdmi_priv *hdmi_priv = intel_output->dev_priv; struct intel_hdmi_priv *hdmi_priv = intel_output->dev_priv;
struct edid *edid = NULL; struct edid *edid = NULL;
enum drm_connector_status status = connector_status_disconnected; enum drm_connector_status status = connector_status_disconnected;
hdmi_priv->has_hdmi_sink = false;
edid = drm_get_edid(&intel_output->base, edid = drm_get_edid(&intel_output->base,
intel_output->ddc_bus); intel_output->ddc_bus);
hdmi_priv->has_hdmi_sink = false;
if (edid) { if (edid) {
if (edid->input & DRM_EDID_INPUT_DIGITAL) { if (edid->input & DRM_EDID_INPUT_DIGITAL) {
status = connector_status_connected; status = connector_status_connected;
...@@ -148,65 +149,8 @@ intel_hdmi_edid_detect(struct drm_connector *connector) ...@@ -148,65 +149,8 @@ intel_hdmi_edid_detect(struct drm_connector *connector)
intel_output->base.display_info.raw_edid = NULL; intel_output->base.display_info.raw_edid = NULL;
kfree(edid); kfree(edid);
} }
return status;
}
static enum drm_connector_status
igdng_hdmi_detect(struct drm_connector *connector)
{
struct intel_output *intel_output = to_intel_output(connector);
struct intel_hdmi_priv *hdmi_priv = intel_output->dev_priv;
/* FIXME hotplug detect */
hdmi_priv->has_hdmi_sink = false;
return intel_hdmi_edid_detect(connector);
}
static enum drm_connector_status return status;
intel_hdmi_detect(struct drm_connector *connector)
{
struct drm_device *dev = connector->dev;
struct drm_i915_private *dev_priv = dev->dev_private;
struct intel_output *intel_output = to_intel_output(connector);
struct intel_hdmi_priv *hdmi_priv = intel_output->dev_priv;
u32 temp, bit;
if (IS_IGDNG(dev))
return igdng_hdmi_detect(connector);
temp = I915_READ(PORT_HOTPLUG_EN);
switch (hdmi_priv->sdvox_reg) {
case SDVOB:
temp |= HDMIB_HOTPLUG_INT_EN;
break;
case SDVOC:
temp |= HDMIC_HOTPLUG_INT_EN;
break;
default:
return connector_status_unknown;
}
I915_WRITE(PORT_HOTPLUG_EN, temp);
POSTING_READ(PORT_HOTPLUG_EN);
switch (hdmi_priv->sdvox_reg) {
case SDVOB:
bit = HDMIB_HOTPLUG_INT_STATUS;
break;
case SDVOC:
bit = HDMIC_HOTPLUG_INT_STATUS;
break;
default:
return connector_status_unknown;
}
if ((I915_READ(PORT_HOTPLUG_STAT) & bit) != 0)
return intel_hdmi_edid_detect(connector);
else
return connector_status_disconnected;
} }
static int intel_hdmi_get_modes(struct drm_connector *connector) static int intel_hdmi_get_modes(struct drm_connector *connector)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment