diff options
Diffstat (limited to 'drivers/video/modedb.c')
-rw-r--r-- | drivers/video/modedb.c | 62 |
1 files changed, 60 insertions, 2 deletions
diff --git a/drivers/video/modedb.c b/drivers/video/modedb.c index 3edc9f49344b..47516c44a390 100644 --- a/drivers/video/modedb.c +++ b/drivers/video/modedb.c | |||
@@ -456,12 +456,22 @@ static int fb_try_mode(struct fb_var_screeninfo *var, struct fb_info *info, | |||
456 | * | 456 | * |
457 | * Valid mode specifiers for @mode_option: | 457 | * Valid mode specifiers for @mode_option: |
458 | * | 458 | * |
459 | * <xres>x<yres>[-<bpp>][@<refresh>] or | 459 | * <xres>x<yres>[M][R][-<bpp>][@<refresh>][i][m] or |
460 | * <name>[-<bpp>][@<refresh>] | 460 | * <name>[-<bpp>][@<refresh>] |
461 | * | 461 | * |
462 | * with <xres>, <yres>, <bpp> and <refresh> decimal numbers and | 462 | * with <xres>, <yres>, <bpp> and <refresh> decimal numbers and |
463 | * <name> a string. | 463 | * <name> a string. |
464 | * | 464 | * |
465 | * If 'M' is present after yres (and before refresh/bpp if present), | ||
466 | * the function will compute the timings using VESA(tm) Coordinated | ||
467 | * Video Timings (CVT). If 'R' is present after 'M', will compute with | ||
468 | * reduced blanking (for flatpanels). If 'i' is present, compute | ||
469 | * interlaced mode. If 'm' is present, add margins equal to 1.8% | ||
470 | * of xres rounded down to 8 pixels, and 1.8% of yres. The char | ||
471 | * 'i' and 'm' must be after 'M' and 'R'. Example: | ||
472 | * | ||
473 | * 1024x768MR-8@60m - Reduced blank with margins at 60Hz. | ||
474 | * | ||
465 | * NOTE: The passed struct @var is _not_ cleared! This allows you | 475 | * NOTE: The passed struct @var is _not_ cleared! This allows you |
466 | * to supply values for e.g. the grayscale and accel_flags fields. | 476 | * to supply values for e.g. the grayscale and accel_flags fields. |
467 | * | 477 | * |
@@ -495,7 +505,7 @@ int fb_find_mode(struct fb_var_screeninfo *var, | |||
495 | unsigned int namelen = strlen(name); | 505 | unsigned int namelen = strlen(name); |
496 | int res_specified = 0, bpp_specified = 0, refresh_specified = 0; | 506 | int res_specified = 0, bpp_specified = 0, refresh_specified = 0; |
497 | unsigned int xres = 0, yres = 0, bpp = default_bpp, refresh = 0; | 507 | unsigned int xres = 0, yres = 0, bpp = default_bpp, refresh = 0; |
498 | int yres_specified = 0; | 508 | int yres_specified = 0, cvt = 0, rb = 0, interlace = 0, margins = 0; |
499 | u32 best, diff; | 509 | u32 best, diff; |
500 | 510 | ||
501 | for (i = namelen-1; i >= 0; i--) { | 511 | for (i = namelen-1; i >= 0; i--) { |
@@ -506,6 +516,8 @@ int fb_find_mode(struct fb_var_screeninfo *var, | |||
506 | !yres_specified) { | 516 | !yres_specified) { |
507 | refresh = my_atoi(&name[i+1]); | 517 | refresh = my_atoi(&name[i+1]); |
508 | refresh_specified = 1; | 518 | refresh_specified = 1; |
519 | if (cvt || rb) | ||
520 | cvt = 0; | ||
509 | } else | 521 | } else |
510 | goto done; | 522 | goto done; |
511 | break; | 523 | break; |
@@ -514,6 +526,8 @@ int fb_find_mode(struct fb_var_screeninfo *var, | |||
514 | if (!bpp_specified && !yres_specified) { | 526 | if (!bpp_specified && !yres_specified) { |
515 | bpp = my_atoi(&name[i+1]); | 527 | bpp = my_atoi(&name[i+1]); |
516 | bpp_specified = 1; | 528 | bpp_specified = 1; |
529 | if (cvt || rb) | ||
530 | cvt = 0; | ||
517 | } else | 531 | } else |
518 | goto done; | 532 | goto done; |
519 | break; | 533 | break; |
@@ -526,6 +540,22 @@ int fb_find_mode(struct fb_var_screeninfo *var, | |||
526 | break; | 540 | break; |
527 | case '0'...'9': | 541 | case '0'...'9': |
528 | break; | 542 | break; |
543 | case 'M': | ||
544 | if (!yres_specified) | ||
545 | cvt = 1; | ||
546 | break; | ||
547 | case 'R': | ||
548 | if (!cvt) | ||
549 | rb = 1; | ||
550 | break; | ||
551 | case 'm': | ||
552 | if (!cvt) | ||
553 | margins = 1; | ||
554 | break; | ||
555 | case 'i': | ||
556 | if (!cvt) | ||
557 | interlace = 1; | ||
558 | break; | ||
529 | default: | 559 | default: |
530 | goto done; | 560 | goto done; |
531 | } | 561 | } |
@@ -535,6 +565,34 @@ int fb_find_mode(struct fb_var_screeninfo *var, | |||
535 | res_specified = 1; | 565 | res_specified = 1; |
536 | } | 566 | } |
537 | done: | 567 | done: |
568 | if (cvt) { | ||
569 | struct fb_videomode cvt_mode; | ||
570 | int ret; | ||
571 | |||
572 | DPRINTK("CVT mode %dx%d@%dHz%s%s%s\n", xres, yres, | ||
573 | (refresh) ? refresh : 60, (rb) ? " reduced blanking" : | ||
574 | "", (margins) ? " with margins" : "", (interlace) ? | ||
575 | " interlaced" : ""); | ||
576 | |||
577 | cvt_mode.xres = xres; | ||
578 | cvt_mode.yres = yres; | ||
579 | cvt_mode.refresh = (refresh) ? refresh : 60; | ||
580 | |||
581 | if (interlace) | ||
582 | cvt_mode.vmode |= FB_VMODE_INTERLACED; | ||
583 | else | ||
584 | cvt_mode.vmode &= ~FB_VMODE_INTERLACED; | ||
585 | |||
586 | ret = fb_find_mode_cvt(&cvt_mode, margins, rb); | ||
587 | |||
588 | if (!ret && !fb_try_mode(var, info, &cvt_mode, bpp)) { | ||
589 | DPRINTK("modedb CVT: CVT mode ok\n"); | ||
590 | return 1; | ||
591 | } | ||
592 | |||
593 | DPRINTK("CVT mode invalid, getting mode from database\n"); | ||
594 | } | ||
595 | |||
538 | DPRINTK("Trying specified video mode%s %ix%i\n", | 596 | DPRINTK("Trying specified video mode%s %ix%i\n", |
539 | refresh_specified ? "" : " (ignoring refresh rate)", xres, yres); | 597 | refresh_specified ? "" : " (ignoring refresh rate)", xres, yres); |
540 | 598 | ||