diff options
-rw-r--r-- | drivers/video/fbmon.c | 28 |
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 | } |