diff --git a/hw/xfree86/common/Makefile.am b/hw/xfree86/common/Makefile.am index 6aa117448..bf3876ba2 100644 --- a/hw/xfree86/common/Makefile.am +++ b/hw/xfree86/common/Makefile.am @@ -41,7 +41,8 @@ nodist_libinit_a_SOURCES = xf86Build.h INCLUDES = $(XORG_INCS) -I$(srcdir)/../ddc -I$(srcdir)/../i2c \ -I$(srcdir)/../loader -I$(srcdir)/../rac -I$(srcdir)/../parser \ -I$(srcdir)/../vbe -I$(srcdir)/../int10 \ - -I$(srcdir)/../vgahw -I$(srcdir)/../dixmods/extmod + -I$(srcdir)/../vgahw -I$(srcdir)/../dixmods/extmod \ + -I$(srcdir)/../modes sdk_HEADERS = compiler.h fourcc.h xf86.h xf86Module.h xf86Opt.h \ xf86PciInfo.h xf86Priv.h xf86Privstr.h xf86Resources.h \ diff --git a/hw/xfree86/common/xf86Mode.c b/hw/xfree86/common/xf86Mode.c index c1b0a5fc9..24a431dc5 100644 --- a/hw/xfree86/common/xf86Mode.c +++ b/hw/xfree86/common/xf86Mode.c @@ -39,6 +39,7 @@ #endif #include +#include "xf86Modes.h" #include "os.h" #include "servermd.h" #include "mibank.h" @@ -705,16 +706,9 @@ xf86CheckModeForMonitor(DisplayModePtr mode, MonPtr monitor) * -- libv */ - /* Is the horizontal blanking a bit lowish? */ - if (((mode->HDisplay * 5 / 4) & ~0x07) > mode->HTotal) { - /* is this a cvt -r mode, and only a cvt -r mode? */ - if (((mode->HTotal - mode->HDisplay) == 160) && - ((mode->HSyncEnd - mode->HDisplay) == 80) && - ((mode->HSyncEnd - mode->HSyncStart) == 32) && - ((mode->VSyncStart - mode->VDisplay) == 3)) { - if (!monitor->reducedblanking && !(mode->type & M_T_DRIVER)) - return MODE_NO_REDUCED; - } + if (xf86ModeIsReduced(mode)) { + if (!monitor->reducedblanking && !(mode->type & M_T_DRIVER)) + return MODE_NO_REDUCED; } if ((monitor->maxPixClock) && (mode->Clock > monitor->maxPixClock)) diff --git a/hw/xfree86/modes/xf86EdidModes.c b/hw/xfree86/modes/xf86EdidModes.c index 3b23a0ed9..9465f663b 100644 --- a/hw/xfree86/modes/xf86EdidModes.c +++ b/hw/xfree86/modes/xf86EdidModes.c @@ -1,5 +1,6 @@ /* * Copyright 2006 Luc Verhaegen. + * Copyright 2008 Red Hat, Inc. * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), @@ -39,11 +40,33 @@ #include #include "property.h" #include "propertyst.h" -#include "xf86DDC.h" #include "xf86Crtc.h" #include #include +static Bool +xf86MonitorSupportsReducedBlanking(xf86MonPtr DDC) +{ + /* EDID 1.4 explicitly defines RB support */ + if (DDC->ver.revision >= 4) { + int i; + for (i = 0; i < DET_TIMINGS; i++) { + struct detailed_monitor_section *det_mon = &DDC->det_mon[i]; + if (det_mon->type == DS_RANGES) + if (det_mon->section.ranges.supported_blanking & CVT_REDUCED) + return TRUE; + } + + return FALSE; + } + + /* For anything older, assume digital means RB support. Boo. */ + if (DDC->features.input_type) + return TRUE; + + return FALSE; +} + /* * Quirks to work around broken EDID data from various monitors. */ @@ -400,16 +423,22 @@ ModeRefresh(DisplayModePtr mode) } /* - * XXX should try not to return RB modes to non-RB displays... + * If rb is not set, then we'll not consider reduced-blanking modes as + * part of the DMT pool. For the 'standard' EDID mode descriptor there's + * no way to specify whether the mode should be RB or not. */ static DisplayModePtr -FindDMTMode(int hsize, int vsize, int refresh) +FindDMTMode(int hsize, int vsize, int refresh, Bool rb) { int i; DisplayModePtr ret; for (i = 0; i < sizeof(DMTModes) / sizeof(DisplayModeRec); i++) { ret = &DMTModes[i]; + + if (!rb && xf86ModeIsReduced(ret)) + continue; + if (ret->HDisplay == hsize && ret->VDisplay == vsize && refresh == ModeRefresh(ret)) @@ -438,7 +467,7 @@ FindDMTMode(int hsize, int vsize, int refresh) */ static DisplayModePtr DDCModesFromStandardTiming(struct std_timings *timing, ddc_quirk_t quirks, - int timing_level) + int timing_level, Bool rb) { DisplayModePtr Modes = NULL, Mode = NULL; int i; @@ -446,10 +475,11 @@ DDCModesFromStandardTiming(struct std_timings *timing, ddc_quirk_t quirks, for (i = 0; i < STD_TIMINGS; i++) { if (timing[i].hsize && timing[i].vsize && timing[i].refresh) { Mode = FindDMTMode(timing[i].hsize, timing[i].vsize, - timing[i].refresh); + timing[i].refresh, rb); if (!Mode) { if (timing_level == LEVEL_CVT) + /* pass rb here too? */ Mode = xf86CVTMode(timing[i].hsize, timing[i].vsize, timing[i].refresh, FALSE, FALSE); else if (timing_level == LEVEL_GTF) @@ -734,7 +764,7 @@ xf86DDCGetModes(int scrnIndex, xf86MonPtr DDC) int i; DisplayModePtr Modes = NULL, Mode; ddc_quirk_t quirks; - Bool preferred; + Bool preferred, rb; int timing_level; xf86DrvMsg (scrnIndex, X_INFO, "EDID vendor \"%s\", prod id %d\n", @@ -750,6 +780,8 @@ xf86DDCGetModes(int scrnIndex, xf86MonPtr DDC) if (quirks & (DDC_QUIRK_PREFER_LARGE_60 | DDC_QUIRK_PREFER_LARGE_75)) preferred = FALSE; + rb = xf86MonitorSupportsReducedBlanking(DDC); + timing_level = MonitorStandardTimingLevel(DDC); for (i = 0; i < DET_TIMINGS; i++) { @@ -766,7 +798,7 @@ xf86DDCGetModes(int scrnIndex, xf86MonPtr DDC) break; case DS_STD_TIMINGS: Mode = DDCModesFromStandardTiming(det_mon->section.std_t, - quirks, timing_level); + quirks, timing_level, rb); Modes = xf86ModesAdd(Modes, Mode); break; #if XORG_VERSION_CURRENT < XORG_VERSION_NUMERIC(7,0,0,0,0) @@ -785,7 +817,7 @@ xf86DDCGetModes(int scrnIndex, xf86MonPtr DDC) Modes = xf86ModesAdd(Modes, Mode); /* Add standard timings */ - Mode = DDCModesFromStandardTiming(DDC->timings2, quirks, timing_level); + Mode = DDCModesFromStandardTiming(DDC->timings2, quirks, timing_level, rb); Modes = xf86ModesAdd(Modes, Mode); if (quirks & DDC_QUIRK_PREFER_LARGE_60) @@ -820,12 +852,7 @@ xf86DDCMonitorSet(int scrnIndex, MonPtr Monitor, xf86MonPtr DDC) Monitor->heightmm = 10 * DDC->features.vsize; } - /* - * If this is a digital display, then we can use reduced blanking. - * XXX This is a 1.3 heuristic. 1.4 explicitly defines rb support. - */ - if (DDC->features.input_type) - Monitor->reducedblanking = TRUE; + Monitor->reducedblanking = xf86MonitorSupportsReducedBlanking(DDC); Modes = xf86DDCGetModes(scrnIndex, DDC); diff --git a/hw/xfree86/modes/xf86Modes.c b/hw/xfree86/modes/xf86Modes.c index dd5ce6483..0fdfbdb85 100644 --- a/hw/xfree86/modes/xf86Modes.c +++ b/hw/xfree86/modes/xf86Modes.c @@ -518,6 +518,18 @@ xf86ValidateModesBandwidth(ScrnInfoPtr pScrn, DisplayModePtr modeList, } } +Bool +xf86ModeIsReduced(DisplayModePtr mode) +{ + if ((((mode->HDisplay * 5 / 4) & ~0x07) > mode->HTotal) && + ((mode->HTotal - mode->HDisplay) == 160) && + ((mode->HSyncEnd - mode->HDisplay) == 80) && + ((mode->HSyncEnd - mode->HSyncStart) == 32) && + ((mode->VSyncStart - mode->VDisplay) == 3)) + return TRUE; + return FALSE; +} + /** * Marks as bad any reduced-blanking modes. * diff --git a/hw/xfree86/modes/xf86Modes.h b/hw/xfree86/modes/xf86Modes.h index acdea65d8..af5987b24 100644 --- a/hw/xfree86/modes/xf86Modes.h +++ b/hw/xfree86/modes/xf86Modes.h @@ -64,6 +64,9 @@ DisplayModePtr xf86CVTMode(int HDisplay, int VDisplay, float VRefresh, Bool Reduced, Bool Interlaced); DisplayModePtr xf86GTFMode(int h_pixels, int v_lines, float freq, int interlaced, int margins); +Bool +xf86ModeIsReduced(DisplayModePtr mode); + void xf86ValidateModesFlags(ScrnInfoPtr pScrn, DisplayModePtr modeList, int flags);