diff options
Diffstat (limited to 'drivers')
| -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 */ |
