aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/i915/intel_bios.c
diff options
context:
space:
mode:
authorZhao Yakui <yakui.zhao@intel.com>2009-11-19 22:24:17 -0500
committerEric Anholt <eric@anholt.net>2009-11-25 16:02:33 -0500
commitd1fcea6a529d22212b324f26cd660c85b289a026 (patch)
tree4b17d2172a1d05f4049386b9528c5d7c4bdc19cd /drivers/gpu/drm/i915/intel_bios.c
parent18f9ed12f8c977e25d65a16af8e8d73f72417ba1 (diff)
drm/i915: Check whether the LVDS downclock is found in VBT
Enumerate the LVDS panel timing info entry list in VBT to check whether the LVDS downclock is found. If found, the downclock is also used to switch dynamically between low and high frequency for LVDS. Signed-off-by: Zhao Yakui <yakui.zhao@intel.com> Acked-by: Jesse Barnes <jbarnes@virtuousgeek.org> Signed-off-by: Eric Anholt <eric@anholt.net>
Diffstat (limited to 'drivers/gpu/drm/i915/intel_bios.c')
-rw-r--r--drivers/gpu/drm/i915/intel_bios.c42
1 files changed, 42 insertions, 0 deletions
diff --git a/drivers/gpu/drm/i915/intel_bios.c b/drivers/gpu/drm/i915/intel_bios.c
index cbd911837b0..10806cd5e4d 100644
--- a/drivers/gpu/drm/i915/intel_bios.c
+++ b/drivers/gpu/drm/i915/intel_bios.c
@@ -114,6 +114,8 @@ parse_lfp_panel_data(struct drm_i915_private *dev_priv,
114 struct lvds_dvo_timing *dvo_timing; 114 struct lvds_dvo_timing *dvo_timing;
115 struct drm_display_mode *panel_fixed_mode; 115 struct drm_display_mode *panel_fixed_mode;
116 int lfp_data_size, dvo_timing_offset; 116 int lfp_data_size, dvo_timing_offset;
117 int i, temp_downclock;
118 struct drm_display_mode *temp_mode;
117 119
118 /* Defaults if we can't find VBT info */ 120 /* Defaults if we can't find VBT info */
119 dev_priv->lvds_dither = 0; 121 dev_priv->lvds_dither = 0;
@@ -162,6 +164,46 @@ parse_lfp_panel_data(struct drm_i915_private *dev_priv,
162 DRM_DEBUG_KMS("Found panel mode in BIOS VBT tables:\n"); 164 DRM_DEBUG_KMS("Found panel mode in BIOS VBT tables:\n");
163 drm_mode_debug_printmodeline(panel_fixed_mode); 165 drm_mode_debug_printmodeline(panel_fixed_mode);
164 166
167 temp_mode = kzalloc(sizeof(*temp_mode), GFP_KERNEL);
168 temp_downclock = panel_fixed_mode->clock;
169 /*
170 * enumerate the LVDS panel timing info entry in VBT to check whether
171 * the LVDS downclock is found.
172 */
173 for (i = 0; i < 16; i++) {
174 entry = (struct bdb_lvds_lfp_data_entry *)
175 ((uint8_t *)lvds_lfp_data->data + (lfp_data_size * i));
176 dvo_timing = (struct lvds_dvo_timing *)
177 ((unsigned char *)entry + dvo_timing_offset);
178
179 fill_detail_timing_data(temp_mode, dvo_timing);
180
181 if (temp_mode->hdisplay == panel_fixed_mode->hdisplay &&
182 temp_mode->hsync_start == panel_fixed_mode->hsync_start &&
183 temp_mode->hsync_end == panel_fixed_mode->hsync_end &&
184 temp_mode->htotal == panel_fixed_mode->htotal &&
185 temp_mode->vdisplay == panel_fixed_mode->vdisplay &&
186 temp_mode->vsync_start == panel_fixed_mode->vsync_start &&
187 temp_mode->vsync_end == panel_fixed_mode->vsync_end &&
188 temp_mode->vtotal == panel_fixed_mode->vtotal &&
189 temp_mode->clock < temp_downclock) {
190 /*
191 * downclock is already found. But we expect
192 * to find the lower downclock.
193 */
194 temp_downclock = temp_mode->clock;
195 }
196 /* clear it to zero */
197 memset(temp_mode, 0, sizeof(*temp_mode));
198 }
199 kfree(temp_mode);
200 if (temp_downclock < panel_fixed_mode->clock) {
201 dev_priv->lvds_downclock_avail = 1;
202 dev_priv->lvds_downclock = temp_downclock;
203 DRM_DEBUG_KMS("LVDS downclock is found in VBT. ",
204 "Normal Clock %dKHz, downclock %dKHz\n",
205 temp_downclock, panel_fixed_mode->clock);
206 }
165 return; 207 return;
166} 208}
167 209