aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm
diff options
context:
space:
mode:
authorZhao Yakui <yakui.zhao@intel.com>2009-06-22 03:31:26 -0400
committerEric Anholt <eric@anholt.net>2009-06-22 22:35:08 -0400
commitaa0261f230105b86409e29bbe851b09830d93d50 (patch)
tree43e27301b555f4f2305730eba9152cc95986d17b /drivers/gpu/drm
parent3fbe18d65d66054667aaee849bed74674bb50062 (diff)
drm/i915: Don't change the blank/sync width when calculating scaled modes
Also, use the border instead of border minus one. At the same time, make sure the horizontal border and hsync are even for the LVDS that works in dual-channel mode. So both horizontal border and hsync start are also changed to be even, even for the LVDS in single-channel mode. https://bugs.freedesktop.org/show_bug.cgi?id=20951 Signed-off-by: Zhao Yakui <yakui.zhao@intel.com> Signed-off-by: Eric Anholt <eric@anholt.net>
Diffstat (limited to 'drivers/gpu/drm')
-rw-r--r--drivers/gpu/drm/i915/intel_lvds.c91
1 files changed, 73 insertions, 18 deletions
diff --git a/drivers/gpu/drm/i915/intel_lvds.c b/drivers/gpu/drm/i915/intel_lvds.c
index f416ead71204..9564ca44a977 100644
--- a/drivers/gpu/drm/i915/intel_lvds.c
+++ b/drivers/gpu/drm/i915/intel_lvds.c
@@ -246,6 +246,9 @@ static bool intel_lvds_mode_fixup(struct drm_encoder *encoder,
246 bool border = 0; 246 bool border = 0;
247 int panel_ratio, desired_ratio, vert_scale, horiz_scale; 247 int panel_ratio, desired_ratio, vert_scale, horiz_scale;
248 int horiz_ratio, vert_ratio; 248 int horiz_ratio, vert_ratio;
249 u32 hsync_width, vsync_width;
250 u32 hblank_width, vblank_width;
251 u32 hsync_pos, vsync_pos;
249 252
250 /* Should never happen!! */ 253 /* Should never happen!! */
251 if (!IS_I965G(dev) && intel_crtc->pipe == 0) { 254 if (!IS_I965G(dev) && intel_crtc->pipe == 0) {
@@ -306,6 +309,14 @@ static bool intel_lvds_mode_fixup(struct drm_encoder *encoder,
306 pfit_control |= (intel_crtc->pipe << PFIT_PIPE_SHIFT) | 309 pfit_control |= (intel_crtc->pipe << PFIT_PIPE_SHIFT) |
307 PFIT_FILTER_FUZZY; 310 PFIT_FILTER_FUZZY;
308 311
312 hsync_width = adjusted_mode->crtc_hsync_end -
313 adjusted_mode->crtc_hsync_start;
314 vsync_width = adjusted_mode->crtc_vsync_end -
315 adjusted_mode->crtc_vsync_start;
316 hblank_width = adjusted_mode->crtc_hblank_end -
317 adjusted_mode->crtc_hblank_start;
318 vblank_width = adjusted_mode->crtc_vblank_end -
319 adjusted_mode->crtc_vblank_start;
309 /* 320 /*
310 * Deal with panel fitting options. Figure out how to stretch the 321 * Deal with panel fitting options. Figure out how to stretch the
311 * image based on its aspect ratio & the current panel fitting mode. 322 * image based on its aspect ratio & the current panel fitting mode.
@@ -339,23 +350,39 @@ static bool intel_lvds_mode_fixup(struct drm_encoder *encoder,
339 bottom_border++; 350 bottom_border++;
340 /* Set active & border values */ 351 /* Set active & border values */
341 adjusted_mode->crtc_hdisplay = mode->hdisplay; 352 adjusted_mode->crtc_hdisplay = mode->hdisplay;
353 /* Keep the boder be even */
354 if (right_border & 1)
355 right_border++;
356 /* use the border directly instead of border minuse one */
342 adjusted_mode->crtc_hblank_start = mode->hdisplay + 357 adjusted_mode->crtc_hblank_start = mode->hdisplay +
343 right_border - 1; 358 right_border;
344 adjusted_mode->crtc_hblank_end = adjusted_mode->crtc_htotal - 359 /* keep the blank width constant */
345 left_border - 1; 360 adjusted_mode->crtc_hblank_end =
361 adjusted_mode->crtc_hblank_start + hblank_width;
362 /* get the hsync pos relative to hblank start */
363 hsync_pos = (hblank_width - hsync_width) / 2;
364 /* keep the hsync pos be even */
365 if (hsync_pos & 1)
366 hsync_pos++;
346 adjusted_mode->crtc_hsync_start = 367 adjusted_mode->crtc_hsync_start =
347 adjusted_mode->crtc_hblank_start; 368 adjusted_mode->crtc_hblank_start + hsync_pos;
369 /* keep the hsync width constant */
348 adjusted_mode->crtc_hsync_end = 370 adjusted_mode->crtc_hsync_end =
349 adjusted_mode->crtc_hblank_end; 371 adjusted_mode->crtc_hsync_start + hsync_width;
350 adjusted_mode->crtc_vdisplay = mode->vdisplay; 372 adjusted_mode->crtc_vdisplay = mode->vdisplay;
373 /* use the border instead of border minus one */
351 adjusted_mode->crtc_vblank_start = mode->vdisplay + 374 adjusted_mode->crtc_vblank_start = mode->vdisplay +
352 bottom_border - 1; 375 bottom_border;
353 adjusted_mode->crtc_vblank_end = adjusted_mode->crtc_vtotal - 376 /* keep the vblank width constant */
354 top_border - 1; 377 adjusted_mode->crtc_vblank_end =
378 adjusted_mode->crtc_vblank_start + vblank_width;
379 /* get the vsync start postion relative to vblank start */
380 vsync_pos = (vblank_width - vsync_width) / 2;
355 adjusted_mode->crtc_vsync_start = 381 adjusted_mode->crtc_vsync_start =
356 adjusted_mode->crtc_vblank_start; 382 adjusted_mode->crtc_vblank_start + vsync_pos;
383 /* keep the vsync width constant */
357 adjusted_mode->crtc_vsync_end = 384 adjusted_mode->crtc_vsync_end =
358 adjusted_mode->crtc_vblank_end; 385 adjusted_mode->crtc_vblank_start + vsync_width;
359 border = 1; 386 border = 1;
360 break; 387 break;
361 case DRM_MODE_SCALE_ASPECT: 388 case DRM_MODE_SCALE_ASPECT:
@@ -400,15 +427,32 @@ static bool intel_lvds_mode_fixup(struct drm_encoder *encoder,
400 right_border = left_border; 427 right_border = left_border;
401 if (mode->hdisplay & 1) /* odd resolutions */ 428 if (mode->hdisplay & 1) /* odd resolutions */
402 right_border++; 429 right_border++;
430 /* keep the border be even */
431 if (right_border & 1)
432 right_border++;
403 adjusted_mode->crtc_hdisplay = scaled_width; 433 adjusted_mode->crtc_hdisplay = scaled_width;
434 /* use border instead of border minus one */
404 adjusted_mode->crtc_hblank_start = 435 adjusted_mode->crtc_hblank_start =
405 scaled_width + right_border - 1; 436 scaled_width + right_border;
437 /* keep the hblank width constant */
406 adjusted_mode->crtc_hblank_end = 438 adjusted_mode->crtc_hblank_end =
407 adjusted_mode->crtc_htotal - left_border - 1; 439 adjusted_mode->crtc_hblank_start +
440 hblank_width;
441 /*
442 * get the hsync start pos relative to
443 * hblank start
444 */
445 hsync_pos = (hblank_width - hsync_width) / 2;
446 /* keep the hsync_pos be even */
447 if (hsync_pos & 1)
448 hsync_pos++;
408 adjusted_mode->crtc_hsync_start = 449 adjusted_mode->crtc_hsync_start =
409 adjusted_mode->crtc_hblank_start; 450 adjusted_mode->crtc_hblank_start +
451 hsync_pos;
452 /* keept hsync width constant */
410 adjusted_mode->crtc_hsync_end = 453 adjusted_mode->crtc_hsync_end =
411 adjusted_mode->crtc_hblank_end; 454 adjusted_mode->crtc_hsync_start +
455 hsync_width;
412 border = 1; 456 border = 1;
413 } else if (panel_ratio < desired_ratio) { /* letter */ 457 } else if (panel_ratio < desired_ratio) { /* letter */
414 u32 scaled_height = mode->vdisplay * 458 u32 scaled_height = mode->vdisplay *
@@ -424,14 +468,25 @@ static bool intel_lvds_mode_fixup(struct drm_encoder *encoder,
424 if (mode->vdisplay & 1) 468 if (mode->vdisplay & 1)
425 bottom_border++; 469 bottom_border++;
426 adjusted_mode->crtc_vdisplay = scaled_height; 470 adjusted_mode->crtc_vdisplay = scaled_height;
471 /* use border instead of border minus one */
427 adjusted_mode->crtc_vblank_start = 472 adjusted_mode->crtc_vblank_start =
428 scaled_height + bottom_border - 1; 473 scaled_height + bottom_border;
474 /* keep the vblank width constant */
429 adjusted_mode->crtc_vblank_end = 475 adjusted_mode->crtc_vblank_end =
430 adjusted_mode->crtc_vtotal - top_border - 1; 476 adjusted_mode->crtc_vblank_start +
477 vblank_width;
478 /*
479 * get the vsync start pos relative to
480 * vblank start
481 */
482 vsync_pos = (vblank_width - vsync_width) / 2;
431 adjusted_mode->crtc_vsync_start = 483 adjusted_mode->crtc_vsync_start =
432 adjusted_mode->crtc_vblank_start; 484 adjusted_mode->crtc_vblank_start +
485 vsync_pos;
486 /* keep the vsync width constant */
433 adjusted_mode->crtc_vsync_end = 487 adjusted_mode->crtc_vsync_end =
434 adjusted_mode->crtc_vblank_end; 488 adjusted_mode->crtc_vsync_start +
489 vsync_width;
435 border = 1; 490 border = 1;
436 } else { 491 } else {
437 /* Aspects match, Let hw scale both directions */ 492 /* Aspects match, Let hw scale both directions */