aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/video/fbmon.c28
1 files changed, 24 insertions, 4 deletions
diff --git a/drivers/video/fbmon.c b/drivers/video/fbmon.c
index fbbcb7156a34..87b0224d2347 100644
--- a/drivers/video/fbmon.c
+++ b/drivers/video/fbmon.c
@@ -605,6 +605,7 @@ static int fb_get_monitor_limits(unsigned char *edid, struct fb_monspecs *specs)
605 block = edid + DETAILED_TIMING_DESCRIPTIONS_START; 605 block = edid + DETAILED_TIMING_DESCRIPTIONS_START;
606 606
607 DPRINTK(" Monitor Operating Limits: "); 607 DPRINTK(" Monitor Operating Limits: ");
608
608 for (i = 0; i < 4; i++, block += DETAILED_TIMING_DESCRIPTION_SIZE) { 609 for (i = 0; i < 4; i++, block += DETAILED_TIMING_DESCRIPTION_SIZE) {
609 if (edid_is_limits_block(block)) { 610 if (edid_is_limits_block(block)) {
610 specs->hfmin = H_MIN_RATE * 1000; 611 specs->hfmin = H_MIN_RATE * 1000;
@@ -618,11 +619,12 @@ static int fb_get_monitor_limits(unsigned char *edid, struct fb_monspecs *specs)
618 break; 619 break;
619 } 620 }
620 } 621 }
621 622
622 /* estimate monitor limits based on modes supported */ 623 /* estimate monitor limits based on modes supported */
623 if (retval) { 624 if (retval) {
624 struct fb_videomode *modes; 625 struct fb_videomode *modes, *mode;
625 int num_modes, i, hz, hscan, pixclock; 626 int num_modes, i, hz, hscan, pixclock;
627 int vtotal, htotal;
626 628
627 modes = fb_create_modedb(edid, &num_modes); 629 modes = fb_create_modedb(edid, &num_modes);
628 if (!modes) { 630 if (!modes) {
@@ -632,20 +634,38 @@ static int fb_get_monitor_limits(unsigned char *edid, struct fb_monspecs *specs)
632 634
633 retval = 0; 635 retval = 0;
634 for (i = 0; i < num_modes; i++) { 636 for (i = 0; i < num_modes; i++) {
635 hz = modes[i].refresh; 637 mode = &modes[i];
636 pixclock = PICOS2KHZ(modes[i].pixclock) * 1000; 638 pixclock = PICOS2KHZ(modes[i].pixclock) * 1000;
637 hscan = (modes[i].yres * 105 * hz + 5000)/100; 639 htotal = mode->xres + mode->right_margin + mode->hsync_len
640 + mode->left_margin;
641 vtotal = mode->yres + mode->lower_margin + mode->vsync_len
642 + mode->upper_margin;
643
644 if (mode->vmode & FB_VMODE_INTERLACED)
645 vtotal /= 2;
646
647 if (mode->vmode & FB_VMODE_DOUBLE)
648 vtotal *= 2;
649
650 hscan = (pixclock + htotal / 2) / htotal;
651 hscan = (hscan + 500) / 1000 * 1000;
652 hz = (hscan + vtotal / 2) / vtotal;
638 653
639 if (specs->dclkmax == 0 || specs->dclkmax < pixclock) 654 if (specs->dclkmax == 0 || specs->dclkmax < pixclock)
640 specs->dclkmax = pixclock; 655 specs->dclkmax = pixclock;
656
641 if (specs->dclkmin == 0 || specs->dclkmin > pixclock) 657 if (specs->dclkmin == 0 || specs->dclkmin > pixclock)
642 specs->dclkmin = pixclock; 658 specs->dclkmin = pixclock;
659
643 if (specs->hfmax == 0 || specs->hfmax < hscan) 660 if (specs->hfmax == 0 || specs->hfmax < hscan)
644 specs->hfmax = hscan; 661 specs->hfmax = hscan;
662
645 if (specs->hfmin == 0 || specs->hfmin > hscan) 663 if (specs->hfmin == 0 || specs->hfmin > hscan)
646 specs->hfmin = hscan; 664 specs->hfmin = hscan;
665
647 if (specs->vfmax == 0 || specs->vfmax < hz) 666 if (specs->vfmax == 0 || specs->vfmax < hz)
648 specs->vfmax = hz; 667 specs->vfmax = hz;
668
649 if (specs->vfmin == 0 || specs->vfmin > hz) 669 if (specs->vfmin == 0 || specs->vfmin > hz)
650 specs->vfmin = hz; 670 specs->vfmin = hz;
651 } 671 }