diff options
Diffstat (limited to 'drivers/gpu/drm/i915/intel_crt.c')
| -rw-r--r-- | drivers/gpu/drm/i915/intel_crt.c | 36 | 
1 files changed, 33 insertions, 3 deletions
diff --git a/drivers/gpu/drm/i915/intel_crt.c b/drivers/gpu/drm/i915/intel_crt.c index 7ed4a41c396..23bdc8cd145 100644 --- a/drivers/gpu/drm/i915/intel_crt.c +++ b/drivers/gpu/drm/i915/intel_crt.c @@ -326,6 +326,36 @@ static bool intel_crt_detect_hotplug(struct drm_connector *connector)  	return ret;  } +static struct edid *intel_crt_get_edid(struct drm_connector *connector, +				struct i2c_adapter *i2c) +{ +	struct edid *edid; + +	edid = drm_get_edid(connector, i2c); + +	if (!edid && !intel_gmbus_is_forced_bit(i2c)) { +		DRM_DEBUG_KMS("CRT GMBUS EDID read failed, retry using GPIO bit-banging\n"); +		intel_gmbus_force_bit(i2c, true); +		edid = drm_get_edid(connector, i2c); +		intel_gmbus_force_bit(i2c, false); +	} + +	return edid; +} + +/* local version of intel_ddc_get_modes() to use intel_crt_get_edid() */ +static int intel_crt_ddc_get_modes(struct drm_connector *connector, +				struct i2c_adapter *adapter) +{ +	struct edid *edid; + +	edid = intel_crt_get_edid(connector, adapter); +	if (!edid) +		return 0; + +	return intel_connector_update_modes(connector, edid); +} +  static bool intel_crt_detect_ddc(struct drm_connector *connector)  {  	struct intel_crt *crt = intel_attached_crt(connector); @@ -336,7 +366,7 @@ static bool intel_crt_detect_ddc(struct drm_connector *connector)  	BUG_ON(crt->base.type != INTEL_OUTPUT_ANALOG);  	i2c = intel_gmbus_get_adapter(dev_priv, dev_priv->crt_ddc_pin); -	edid = drm_get_edid(connector, i2c); +	edid = intel_crt_get_edid(connector, i2c);  	if (edid) {  		bool is_digital = edid->input & DRM_EDID_INPUT_DIGITAL; @@ -544,13 +574,13 @@ static int intel_crt_get_modes(struct drm_connector *connector)  	struct i2c_adapter *i2c;  	i2c = intel_gmbus_get_adapter(dev_priv, dev_priv->crt_ddc_pin); -	ret = intel_ddc_get_modes(connector, i2c); +	ret = intel_crt_ddc_get_modes(connector, i2c);  	if (ret || !IS_G4X(dev))  		return ret;  	/* Try to probe digital port for output in DVI-I -> VGA mode. */  	i2c = intel_gmbus_get_adapter(dev_priv, GMBUS_PORT_DPB); -	return intel_ddc_get_modes(connector, i2c); +	return intel_crt_ddc_get_modes(connector, i2c);  }  static int intel_crt_set_property(struct drm_connector *connector,  |