drm/i915: Override SDVO panel type in VBT
authorChris Wilson <chris@chris-wilson.co.uk>
Sat, 29 Jan 2011 16:50:25 +0000 (16:50 +0000)
committerChris Wilson <chris@chris-wilson.co.uk>
Tue, 1 Feb 2011 08:48:36 +0000 (08:48 +0000)
Judging by comments in the BIOS, if the SDVO LVDS option h40 is enabled,
then we are supposed to query the real panel type via Int15. We don't do
this and so for the Sony Vaio VGC-JS210J which has otherwise default
values, we choose the wrong mode.

This patch adds a driver option, i915.vbt_sdvo_panel_type, which can be
used to override the value in the VBT.

Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=33691
Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
drivers/gpu/drm/i915/i915_drv.c
drivers/gpu/drm/i915/i915_drv.h
drivers/gpu/drm/i915/intel_bios.c

index 211de8e572003d7737dd28854d1a5ca9529f775b..db13d4d460424ee0859a1ef471166a4d66f49d53 100644 (file)
@@ -52,6 +52,9 @@ module_param_named(lvds_downclock, i915_lvds_downclock, int, 0400);
 unsigned int i915_panel_use_ssc = 1;
 module_param_named(lvds_use_ssc, i915_panel_use_ssc, int, 0600);
 
+int i915_vbt_sdvo_panel_type = -1;
+module_param_named(vbt_sdvo_panel_type, i915_vbt_sdvo_panel_type, int, 0600);
+
 static bool i915_try_reset = true;
 module_param_named(reset, i915_try_reset, bool, 0600);
 
index 6e1cfa42f42124bc39a0303cfae203dcd3fc9457..fb5979774c09134dd9a7dd2738e49e42e4374edd 100644 (file)
@@ -962,6 +962,7 @@ extern unsigned int i915_fbpercrtc;
 extern unsigned int i915_powersave;
 extern unsigned int i915_lvds_downclock;
 extern unsigned int i915_panel_use_ssc;
+extern int i915_vbt_sdvo_panel_type;
 
 extern int i915_suspend(struct drm_device *dev, pm_message_t state);
 extern int i915_resume(struct drm_device *dev);
index 35c3b1442ba9de9bc382f739c891a598738da53c..48a0f03b60c31f6b4a0a6809dfa1fb992830a11a 100644 (file)
@@ -226,29 +226,35 @@ static void
 parse_sdvo_panel_data(struct drm_i915_private *dev_priv,
                      struct bdb_header *bdb)
 {
-       struct bdb_sdvo_lvds_options *sdvo_lvds_options;
        struct lvds_dvo_timing *dvo_timing;
        struct drm_display_mode *panel_fixed_mode;
+       int index;
 
-       sdvo_lvds_options = find_section(bdb, BDB_SDVO_LVDS_OPTIONS);
-       if (!sdvo_lvds_options)
-               return;
+       index = i915_vbt_sdvo_panel_type;
+       if (index == -1) {
+               struct bdb_sdvo_lvds_options *sdvo_lvds_options;
+
+               sdvo_lvds_options = find_section(bdb, BDB_SDVO_LVDS_OPTIONS);
+               if (!sdvo_lvds_options)
+                       return;
+
+               index = sdvo_lvds_options->panel_type;
+       }
 
        dvo_timing = find_section(bdb, BDB_SDVO_PANEL_DTDS);
        if (!dvo_timing)
                return;
 
        panel_fixed_mode = kzalloc(sizeof(*panel_fixed_mode), GFP_KERNEL);
-
        if (!panel_fixed_mode)
                return;
 
-       fill_detail_timing_data(panel_fixed_mode,
-                       dvo_timing + sdvo_lvds_options->panel_type);
+       fill_detail_timing_data(panel_fixed_mode, dvo_timing + index);
 
        dev_priv->sdvo_lvds_vbt_mode = panel_fixed_mode;
 
-       return;
+       DRM_DEBUG_KMS("Found SDVO panel mode in BIOS VBT tables:\n");
+       drm_mode_debug_printmodeline(panel_fixed_mode);
 }
 
 static int intel_bios_ssc_frequency(struct drm_device *dev,