From 475666d4f80f148a091fa20257fe2381223d3c62 Mon Sep 17 00:00:00 2001 From: "Antonino A. Daplas" Date: Mon, 7 Nov 2005 01:00:46 -0800 Subject: [PATCH] fbdev: Workaround for buggy EDID blocks Some EDID blocks set the flag "prefer first detailed timing" without providing any detailed timing at all. Clear this flag if the block does not provide detailed timings. Signed-off-by: Antonino Daplas Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/video/fbmon.c | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) (limited to 'drivers/video/fbmon.c') diff --git a/drivers/video/fbmon.c b/drivers/video/fbmon.c index 713226cdf3c6..442a52d10913 100644 --- a/drivers/video/fbmon.c +++ b/drivers/video/fbmon.c @@ -827,7 +827,7 @@ int fb_parse_edid(unsigned char *edid, struct fb_var_screeninfo *var) void fb_edid_to_monspecs(unsigned char *edid, struct fb_monspecs *specs) { unsigned char *block; - int i; + int i, found = 0; if (edid == NULL) return; @@ -869,6 +869,22 @@ void fb_edid_to_monspecs(unsigned char *edid, struct fb_monspecs *specs) get_monspecs(edid, specs); specs->modedb = fb_create_modedb(edid, &specs->modedb_len); + + /* + * Workaround for buggy EDIDs that sets that the first + * detailed timing is preferred but has not detailed + * timing specified + */ + for (i = 0; i < specs->modedb_len; i++) { + if (specs->modedb[i].flag & FB_MODE_IS_DETAILED) { + found = 1; + break; + } + } + + if (!found) + specs->misc &= ~FB_MISC_1ST_DETAIL; + DPRINTK("========================================\n"); } -- cgit v1.2.1 From 14c8102ffc9d08aa86fb08ed4bdb005768650e44 Mon Sep 17 00:00:00 2001 From: "Antonino A. Daplas" Date: Mon, 7 Nov 2005 01:00:53 -0800 Subject: [PATCH] fbdev: Rearrange mode database entries Rearrange mode database entries such that preferred timings are entered first, and less preferred timings are entered last. (Detailed, VESA, established/standard). Signed-off-by: Antonino Daplas Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/video/fbmon.c | 30 ++++++++++++++++-------------- 1 file changed, 16 insertions(+), 14 deletions(-) (limited to 'drivers/video/fbmon.c') diff --git a/drivers/video/fbmon.c b/drivers/video/fbmon.c index 442a52d10913..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) *dbsize = 0; - DPRINTK(" Supported VESA Modes\n"); - block = edid + ESTABLISHED_TIMING_1; - num += get_est_timing(block, &mode[num]); - - DPRINTK(" Standard Timings\n"); - block = edid + STD_TIMING_DESCRIPTIONS_START; - for (i = 0; i < STD_TIMING; i++, block += STD_TIMING_DESCRIPTION_SIZE) - num += get_std_timing(block, &mode[num]); - DPRINTK(" Detailed Timings\n"); block = edid + DETAILED_TIMING_DESCRIPTIONS_START; for (i = 0; i < 4; i++, block+= DETAILED_TIMING_DESCRIPTION_SIZE) { int first = 1; - if (block[0] == 0x00 && block[1] == 0x00) { - if (block[3] == 0xfa) { - num += get_dst_timing(block + 5, &mode[num]); - } - } else { + if (!(block[0] == 0x00 && block[1] == 0x00)) { get_detailed_timing(block, &mode[num]); if (first) { mode[num].flag |= FB_MODE_IS_FIRST; @@ -565,6 +552,21 @@ static struct fb_videomode *fb_create_modedb(unsigned char *edid, int *dbsize) num++; } } + + DPRINTK(" Supported VESA Modes\n"); + block = edid + ESTABLISHED_TIMING_1; + num += get_est_timing(block, &mode[num]); + + DPRINTK(" Standard Timings\n"); + block = edid + STD_TIMING_DESCRIPTIONS_START; + for (i = 0; i < STD_TIMING; i++, block += STD_TIMING_DESCRIPTION_SIZE) + num += get_std_timing(block, &mode[num]); + + block = edid + DETAILED_TIMING_DESCRIPTIONS_START; + for (i = 0; i < 4; i++, block+= DETAILED_TIMING_DESCRIPTION_SIZE) { + if (block[0] == 0x00 && block[1] == 0x00 && block[3] == 0xfa) + num += get_dst_timing(block + 5, &mode[num]); + } /* Yikes, EDID data is totally useless */ if (!num) { -- cgit v1.2.1