As we may query the edid multiple times following a detect, record the EDID found during output discovery and reuse it. This is a separate issue from caching the output EDID across detection cycles. Signed-off-by: Chris Wilson <chris@xxxxxxxxxxxxxxxxxx> --- drivers/gpu/drm/i915/intel_hdmi.c | 68 ++++++++++++--------------------------- 1 file changed, 21 insertions(+), 47 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_hdmi.c b/drivers/gpu/drm/i915/intel_hdmi.c index 9169786..f765527 100644 --- a/drivers/gpu/drm/i915/intel_hdmi.c +++ b/drivers/gpu/drm/i915/intel_hdmi.c @@ -988,17 +988,17 @@ intel_hdmi_detect(struct drm_connector *connector, bool force) intel_gmbus_get_adapter(dev_priv, intel_hdmi->ddc_bus)); - if (edid) { - if (edid->input & DRM_EDID_INPUT_DIGITAL) { - status = connector_status_connected; - if (intel_hdmi->force_audio != HDMI_AUDIO_OFF_DVI) - intel_hdmi->has_hdmi_sink = - drm_detect_hdmi_monitor(edid); - intel_hdmi->has_audio = drm_detect_monitor_audio(edid); - intel_hdmi->rgb_quant_range_selectable = - drm_rgb_quant_range_selectable(edid); - } - kfree(edid); + kfree(to_intel_connector(connector)->detect_edid); + to_intel_connector(connector)->detect_edid = edid; + + if (edid && edid->input & DRM_EDID_INPUT_DIGITAL) { + status = connector_status_connected; + if (intel_hdmi->force_audio != HDMI_AUDIO_OFF_DVI) + intel_hdmi->has_hdmi_sink = + drm_detect_hdmi_monitor(edid); + intel_hdmi->has_audio = drm_detect_monitor_audio(edid); + intel_hdmi->rgb_quant_range_selectable = + drm_rgb_quant_range_selectable(edid); } if (status == connector_status_connected) { @@ -1015,51 +1015,24 @@ intel_hdmi_detect(struct drm_connector *connector, bool force) static int intel_hdmi_get_modes(struct drm_connector *connector) { - struct intel_encoder *intel_encoder = intel_attached_encoder(connector); - struct intel_hdmi *intel_hdmi = enc_to_intel_hdmi(&intel_encoder->base); - struct drm_i915_private *dev_priv = connector->dev->dev_private; - enum intel_display_power_domain power_domain; - int ret; - - /* We should parse the EDID data and find out if it's an HDMI sink so - * we can send audio to it. - */ - - power_domain = intel_display_port_power_domain(intel_encoder); - intel_display_power_get(dev_priv, power_domain); - - ret = intel_ddc_get_modes(connector, - intel_gmbus_get_adapter(dev_priv, - intel_hdmi->ddc_bus)); + struct edid *edid; - intel_display_power_put(dev_priv, power_domain); + edid = to_intel_connector(connector)->detect_edid; + if (edid == NULL) + return 0; - return ret; + return intel_connector_update_modes(connector, edid); } static bool intel_hdmi_detect_audio(struct drm_connector *connector) { - struct intel_encoder *intel_encoder = intel_attached_encoder(connector); - struct intel_hdmi *intel_hdmi = enc_to_intel_hdmi(&intel_encoder->base); - struct drm_i915_private *dev_priv = connector->dev->dev_private; - enum intel_display_power_domain power_domain; - struct edid *edid; bool has_audio = false; + struct edid *edid; - 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 (edid) { - if (edid->input & DRM_EDID_INPUT_DIGITAL) - has_audio = drm_detect_monitor_audio(edid); - kfree(edid); - } - - intel_display_power_put(dev_priv, power_domain); + edid = to_intel_connector(connector)->detect_edid; + if (edid && edid->input & DRM_EDID_INPUT_DIGITAL) + has_audio = drm_detect_monitor_audio(edid); return has_audio; } @@ -1479,6 +1452,7 @@ static void chv_hdmi_pre_enable(struct intel_encoder *encoder) static void intel_hdmi_destroy(struct drm_connector *connector) { + kfree(to_intel_connector(connector)->detect_edid); drm_connector_cleanup(connector); kfree(connector); } -- 1.9.1 _______________________________________________ Intel-gfx mailing list Intel-gfx@xxxxxxxxxxxxxxxxxxxxx http://lists.freedesktop.org/mailman/listinfo/intel-gfx