summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChris Wilson <chris@chris-wilson.co.uk>2010-08-08 14:28:23 +0100
committerEric Anholt <eric@anholt.net>2010-08-09 14:11:28 -0700
commit8545423a912cf500009cbadfae57f706cf2b28e8 (patch)
treea1b3adb16dbc824ef9b09f2ec2ec1198a4e11d51
parentaa40d6bbb9cf88f3fb296a57e046a52e9a68ab72 (diff)
drm/i915/sdvo: Only set is_lvds if we have a valid fixed mode.
If we have failed to ascertain the fixed mode for the LVDS panel, then trust the pixel clock ranges reported for the connection when determing valid modes. This makes intel_sdvo_mode_valid() consistent with intel_lvds_mode_valid() which is also a no-op is there is no fixed mode defined. (Since the mode is both validated by SDVO and LVDS, why are checking against an LVDS fixed mode in SDVO...) By only defining is_lvds to be true when we actually have an LVDS output with a fixed mode, we avoid various potential NULL deferences where the assumption is made that all LVDS outputs have a fixed mode. References: Bug 29449 - [Q35] failure to read EDID/vbios for LVDS, no mode => no output https://bugs.freedesktop.org/show_bug.cgi?id=29449 The primary failure in this bug is not finding the EDID and determining the correct fixed panel mode. However, this patch should fix the secondary issue of not enabling any of the standard modes for the panel either. Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk> Signed-off-by: Eric Anholt <eric@anholt.net>
-rw-r--r--drivers/gpu/drm/i915/intel_sdvo.c10
1 files changed, 3 insertions, 7 deletions
diff --git a/drivers/gpu/drm/i915/intel_sdvo.c b/drivers/gpu/drm/i915/intel_sdvo.c
index 69cf7241c3e..5c765bb0845 100644
--- a/drivers/gpu/drm/i915/intel_sdvo.c
+++ b/drivers/gpu/drm/i915/intel_sdvo.c
@@ -1274,10 +1274,7 @@ static int intel_sdvo_mode_valid(struct drm_connector *connector,
if (intel_sdvo->pixel_clock_max < mode->clock)
return MODE_CLOCK_HIGH;
- if (intel_sdvo->is_lvds == true) {
- if (intel_sdvo->sdvo_lvds_fixed_mode == NULL)
- return MODE_PANEL;
-
+ if (intel_sdvo->is_lvds) {
if (mode->hdisplay > intel_sdvo->sdvo_lvds_fixed_mode->hdisplay)
return MODE_PANEL;
@@ -1534,7 +1531,7 @@ static enum drm_connector_status intel_sdvo_detect(struct drm_connector *connect
intel_sdvo->base.needs_tv_clock = true;
}
if (response & SDVO_LVDS_MASK)
- intel_sdvo->is_lvds = true;
+ intel_sdvo->is_lvds = intel_sdvo->sdvo_lvds_fixed_mode != NULL;
}
return ret;
@@ -1697,6 +1694,7 @@ end:
if (newmode->type & DRM_MODE_TYPE_PREFERRED) {
intel_sdvo->sdvo_lvds_fixed_mode =
drm_mode_duplicate(connector->dev, newmode);
+ intel_sdvo->is_lvds = true;
break;
}
}
@@ -2190,8 +2188,6 @@ intel_sdvo_lvds_init(struct intel_sdvo *intel_sdvo, int device)
encoder->encoder_type = DRM_MODE_ENCODER_LVDS;
connector->connector_type = DRM_MODE_CONNECTOR_LVDS;
- intel_sdvo->is_lvds = true;
-
if (device == 0) {
intel_sdvo->controlled_output |= SDVO_OUTPUT_LVDS0;
intel_sdvo_connector->output_flag = SDVO_OUTPUT_LVDS0;