aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/i915/intel_crt.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gpu/drm/i915/intel_crt.c')
-rw-r--r--drivers/gpu/drm/i915/intel_crt.c36
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 bc5e2c97db61..80bf3112dc1f 100644
--- a/drivers/gpu/drm/i915/intel_crt.c
+++ b/drivers/gpu/drm/i915/intel_crt.c
@@ -328,6 +328,36 @@ static bool intel_crt_detect_hotplug(struct drm_connector *connector)
328 return ret; 328 return ret;
329} 329}
330 330
331static struct edid *intel_crt_get_edid(struct drm_connector *connector,
332 struct i2c_adapter *i2c)
333{
334 struct edid *edid;
335
336 edid = drm_get_edid(connector, i2c);
337
338 if (!edid && !intel_gmbus_is_forced_bit(i2c)) {
339 DRM_DEBUG_KMS("CRT GMBUS EDID read failed, retry using GPIO bit-banging\n");
340 intel_gmbus_force_bit(i2c, true);
341 edid = drm_get_edid(connector, i2c);
342 intel_gmbus_force_bit(i2c, false);
343 }
344
345 return edid;
346}
347
348/* local version of intel_ddc_get_modes() to use intel_crt_get_edid() */
349static int intel_crt_ddc_get_modes(struct drm_connector *connector,
350 struct i2c_adapter *adapter)
351{
352 struct edid *edid;
353
354 edid = intel_crt_get_edid(connector, adapter);
355 if (!edid)
356 return 0;
357
358 return intel_connector_update_modes(connector, edid);
359}
360
331static bool intel_crt_detect_ddc(struct drm_connector *connector) 361static bool intel_crt_detect_ddc(struct drm_connector *connector)
332{ 362{
333 struct intel_crt *crt = intel_attached_crt(connector); 363 struct intel_crt *crt = intel_attached_crt(connector);
@@ -338,7 +368,7 @@ static bool intel_crt_detect_ddc(struct drm_connector *connector)
338 BUG_ON(crt->base.type != INTEL_OUTPUT_ANALOG); 368 BUG_ON(crt->base.type != INTEL_OUTPUT_ANALOG);
339 369
340 i2c = intel_gmbus_get_adapter(dev_priv, dev_priv->crt_ddc_pin); 370 i2c = intel_gmbus_get_adapter(dev_priv, dev_priv->crt_ddc_pin);
341 edid = drm_get_edid(connector, i2c); 371 edid = intel_crt_get_edid(connector, i2c);
342 372
343 if (edid) { 373 if (edid) {
344 bool is_digital = edid->input & DRM_EDID_INPUT_DIGITAL; 374 bool is_digital = edid->input & DRM_EDID_INPUT_DIGITAL;
@@ -546,13 +576,13 @@ static int intel_crt_get_modes(struct drm_connector *connector)
546 struct i2c_adapter *i2c; 576 struct i2c_adapter *i2c;
547 577
548 i2c = intel_gmbus_get_adapter(dev_priv, dev_priv->crt_ddc_pin); 578 i2c = intel_gmbus_get_adapter(dev_priv, dev_priv->crt_ddc_pin);
549 ret = intel_ddc_get_modes(connector, i2c); 579 ret = intel_crt_ddc_get_modes(connector, i2c);
550 if (ret || !IS_G4X(dev)) 580 if (ret || !IS_G4X(dev))
551 return ret; 581 return ret;
552 582
553 /* Try to probe digital port for output in DVI-I -> VGA mode. */ 583 /* Try to probe digital port for output in DVI-I -> VGA mode. */
554 i2c = intel_gmbus_get_adapter(dev_priv, GMBUS_PORT_DPB); 584 i2c = intel_gmbus_get_adapter(dev_priv, GMBUS_PORT_DPB);
555 return intel_ddc_get_modes(connector, i2c); 585 return intel_crt_ddc_get_modes(connector, i2c);
556} 586}
557 587
558static int intel_crt_set_property(struct drm_connector *connector, 588static int intel_crt_set_property(struct drm_connector *connector,