diff options
Diffstat (limited to 'drivers/gpu/drm/i915/intel_lvds.c')
-rw-r--r-- | drivers/gpu/drm/i915/intel_lvds.c | 91 |
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 */ |