aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/video/fbmon.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/video/fbmon.c')
-rw-r--r--drivers/video/fbmon.c48
1 files changed, 33 insertions, 15 deletions
diff --git a/drivers/video/fbmon.c b/drivers/video/fbmon.c
index 713226cdf3c6..fc7965b66775 100644
--- a/drivers/video/fbmon.c
+++ b/drivers/video/fbmon.c
@@ -538,25 +538,12 @@ static struct fb_videomode *fb_create_modedb(unsigned char *edid, int *dbsize)
538 538
539 *dbsize = 0; 539 *dbsize = 0;
540 540
541 DPRINTK(" Supported VESA Modes\n");
542 block = edid + ESTABLISHED_TIMING_1;
543 num += get_est_timing(block, &mode[num]);
544
545 DPRINTK(" Standard Timings\n");
546 block = edid + STD_TIMING_DESCRIPTIONS_START;
547 for (i = 0; i < STD_TIMING; i++, block += STD_TIMING_DESCRIPTION_SIZE)
548 num += get_std_timing(block, &mode[num]);
549
550 DPRINTK(" Detailed Timings\n"); 541 DPRINTK(" Detailed Timings\n");
551 block = edid + DETAILED_TIMING_DESCRIPTIONS_START; 542 block = edid + DETAILED_TIMING_DESCRIPTIONS_START;
552 for (i = 0; i < 4; i++, block+= DETAILED_TIMING_DESCRIPTION_SIZE) { 543 for (i = 0; i < 4; i++, block+= DETAILED_TIMING_DESCRIPTION_SIZE) {
553 int first = 1; 544 int first = 1;
554 545
555 if (block[0] == 0x00 && block[1] == 0x00) { 546 if (!(block[0] == 0x00 && block[1] == 0x00)) {
556 if (block[3] == 0xfa) {
557 num += get_dst_timing(block + 5, &mode[num]);
558 }
559 } else {
560 get_detailed_timing(block, &mode[num]); 547 get_detailed_timing(block, &mode[num]);
561 if (first) { 548 if (first) {
562 mode[num].flag |= FB_MODE_IS_FIRST; 549 mode[num].flag |= FB_MODE_IS_FIRST;
@@ -565,6 +552,21 @@ static struct fb_videomode *fb_create_modedb(unsigned char *edid, int *dbsize)
565 num++; 552 num++;
566 } 553 }
567 } 554 }
555
556 DPRINTK(" Supported VESA Modes\n");
557 block = edid + ESTABLISHED_TIMING_1;
558 num += get_est_timing(block, &mode[num]);
559
560 DPRINTK(" Standard Timings\n");
561 block = edid + STD_TIMING_DESCRIPTIONS_START;
562 for (i = 0; i < STD_TIMING; i++, block += STD_TIMING_DESCRIPTION_SIZE)
563 num += get_std_timing(block, &mode[num]);
564
565 block = edid + DETAILED_TIMING_DESCRIPTIONS_START;
566 for (i = 0; i < 4; i++, block+= DETAILED_TIMING_DESCRIPTION_SIZE) {
567 if (block[0] == 0x00 && block[1] == 0x00 && block[3] == 0xfa)
568 num += get_dst_timing(block + 5, &mode[num]);
569 }
568 570
569 /* Yikes, EDID data is totally useless */ 571 /* Yikes, EDID data is totally useless */
570 if (!num) { 572 if (!num) {
@@ -827,7 +829,7 @@ int fb_parse_edid(unsigned char *edid, struct fb_var_screeninfo *var)
827void fb_edid_to_monspecs(unsigned char *edid, struct fb_monspecs *specs) 829void fb_edid_to_monspecs(unsigned char *edid, struct fb_monspecs *specs)
828{ 830{
829 unsigned char *block; 831 unsigned char *block;
830 int i; 832 int i, found = 0;
831 833
832 if (edid == NULL) 834 if (edid == NULL)
833 return; 835 return;
@@ -869,6 +871,22 @@ void fb_edid_to_monspecs(unsigned char *edid, struct fb_monspecs *specs)
869 get_monspecs(edid, specs); 871 get_monspecs(edid, specs);
870 872
871 specs->modedb = fb_create_modedb(edid, &specs->modedb_len); 873 specs->modedb = fb_create_modedb(edid, &specs->modedb_len);
874
875 /*
876 * Workaround for buggy EDIDs that sets that the first
877 * detailed timing is preferred but has not detailed
878 * timing specified
879 */
880 for (i = 0; i < specs->modedb_len; i++) {
881 if (specs->modedb[i].flag & FB_MODE_IS_DETAILED) {
882 found = 1;
883 break;
884 }
885 }
886
887 if (!found)
888 specs->misc &= ~FB_MISC_1ST_DETAIL;
889
872 DPRINTK("========================================\n"); 890 DPRINTK("========================================\n");
873} 891}
874 892