aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/video/modedb.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/video/modedb.c')
-rw-r--r--drivers/video/modedb.c62
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 }
537done: 567done:
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