aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/i915/intel_lvds.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gpu/drm/i915/intel_lvds.c')
-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 */