summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAdam Jackson <ajax@redhat.com>2008-07-21 16:39:43 -0400
committerAdam Jackson <ajax@redhat.com>2008-07-21 16:49:17 -0400
commit8c8c4fdf34bfc9d54ebea99fb0af14cad167b4a0 (patch)
tree11145925843b26a8edd3e72a5ec9b4b2d4999798
parente8cd77e14d3fa40e5cf1174acaf925362b2e0a11 (diff)
EDID: Various reduced blanking fixes.
- Use a single common function to compute reducedness. - Call it from both the old-school and new-school mode validation paths. - Define monitor reduced-blanking support in accord with EDID 1.4. - Attempt to filter RB DMT modes away from the "standard" EDID pool if the monitor doesn't claim RB support.
-rw-r--r--hw/xfree86/common/Makefile.am3
-rw-r--r--hw/xfree86/common/xf86Mode.c14
-rw-r--r--hw/xfree86/modes/xf86EdidModes.c55
-rw-r--r--hw/xfree86/modes/xf86Modes.c12
-rw-r--r--hw/xfree86/modes/xf86Modes.h3
5 files changed, 62 insertions, 25 deletions
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 <X11/X.h>
+#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 <X11/Xatom.h>
#include "property.h"
#include "propertyst.h"
-#include "xf86DDC.h"
#include "xf86Crtc.h"
#include <string.h>
#include <math.h>
+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);