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.
This commit is contained in:
parent
e8cd77e14d
commit
8c8c4fdf34
|
@ -41,7 +41,8 @@ nodist_libinit_a_SOURCES = xf86Build.h
|
||||||
INCLUDES = $(XORG_INCS) -I$(srcdir)/../ddc -I$(srcdir)/../i2c \
|
INCLUDES = $(XORG_INCS) -I$(srcdir)/../ddc -I$(srcdir)/../i2c \
|
||||||
-I$(srcdir)/../loader -I$(srcdir)/../rac -I$(srcdir)/../parser \
|
-I$(srcdir)/../loader -I$(srcdir)/../rac -I$(srcdir)/../parser \
|
||||||
-I$(srcdir)/../vbe -I$(srcdir)/../int10 \
|
-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 \
|
sdk_HEADERS = compiler.h fourcc.h xf86.h xf86Module.h xf86Opt.h \
|
||||||
xf86PciInfo.h xf86Priv.h xf86Privstr.h xf86Resources.h \
|
xf86PciInfo.h xf86Priv.h xf86Privstr.h xf86Resources.h \
|
||||||
|
|
|
@ -39,6 +39,7 @@
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include <X11/X.h>
|
#include <X11/X.h>
|
||||||
|
#include "xf86Modes.h"
|
||||||
#include "os.h"
|
#include "os.h"
|
||||||
#include "servermd.h"
|
#include "servermd.h"
|
||||||
#include "mibank.h"
|
#include "mibank.h"
|
||||||
|
@ -705,16 +706,9 @@ xf86CheckModeForMonitor(DisplayModePtr mode, MonPtr monitor)
|
||||||
* -- libv
|
* -- libv
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* Is the horizontal blanking a bit lowish? */
|
if (xf86ModeIsReduced(mode)) {
|
||||||
if (((mode->HDisplay * 5 / 4) & ~0x07) > mode->HTotal) {
|
if (!monitor->reducedblanking && !(mode->type & M_T_DRIVER))
|
||||||
/* is this a cvt -r mode, and only a cvt -r mode? */
|
return MODE_NO_REDUCED;
|
||||||
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 ((monitor->maxPixClock) && (mode->Clock > monitor->maxPixClock))
|
if ((monitor->maxPixClock) && (mode->Clock > monitor->maxPixClock))
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
/*
|
/*
|
||||||
* Copyright 2006 Luc Verhaegen.
|
* Copyright 2006 Luc Verhaegen.
|
||||||
|
* Copyright 2008 Red Hat, Inc.
|
||||||
*
|
*
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||||
* copy of this software and associated documentation files (the "Software"),
|
* copy of this software and associated documentation files (the "Software"),
|
||||||
|
@ -39,11 +40,33 @@
|
||||||
#include <X11/Xatom.h>
|
#include <X11/Xatom.h>
|
||||||
#include "property.h"
|
#include "property.h"
|
||||||
#include "propertyst.h"
|
#include "propertyst.h"
|
||||||
#include "xf86DDC.h"
|
|
||||||
#include "xf86Crtc.h"
|
#include "xf86Crtc.h"
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <math.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.
|
* 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
|
static DisplayModePtr
|
||||||
FindDMTMode(int hsize, int vsize, int refresh)
|
FindDMTMode(int hsize, int vsize, int refresh, Bool rb)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
DisplayModePtr ret;
|
DisplayModePtr ret;
|
||||||
|
|
||||||
for (i = 0; i < sizeof(DMTModes) / sizeof(DisplayModeRec); i++) {
|
for (i = 0; i < sizeof(DMTModes) / sizeof(DisplayModeRec); i++) {
|
||||||
ret = &DMTModes[i];
|
ret = &DMTModes[i];
|
||||||
|
|
||||||
|
if (!rb && xf86ModeIsReduced(ret))
|
||||||
|
continue;
|
||||||
|
|
||||||
if (ret->HDisplay == hsize &&
|
if (ret->HDisplay == hsize &&
|
||||||
ret->VDisplay == vsize &&
|
ret->VDisplay == vsize &&
|
||||||
refresh == ModeRefresh(ret))
|
refresh == ModeRefresh(ret))
|
||||||
|
@ -438,7 +467,7 @@ FindDMTMode(int hsize, int vsize, int refresh)
|
||||||
*/
|
*/
|
||||||
static DisplayModePtr
|
static DisplayModePtr
|
||||||
DDCModesFromStandardTiming(struct std_timings *timing, ddc_quirk_t quirks,
|
DDCModesFromStandardTiming(struct std_timings *timing, ddc_quirk_t quirks,
|
||||||
int timing_level)
|
int timing_level, Bool rb)
|
||||||
{
|
{
|
||||||
DisplayModePtr Modes = NULL, Mode = NULL;
|
DisplayModePtr Modes = NULL, Mode = NULL;
|
||||||
int i;
|
int i;
|
||||||
|
@ -446,10 +475,11 @@ DDCModesFromStandardTiming(struct std_timings *timing, ddc_quirk_t quirks,
|
||||||
for (i = 0; i < STD_TIMINGS; i++) {
|
for (i = 0; i < STD_TIMINGS; i++) {
|
||||||
if (timing[i].hsize && timing[i].vsize && timing[i].refresh) {
|
if (timing[i].hsize && timing[i].vsize && timing[i].refresh) {
|
||||||
Mode = FindDMTMode(timing[i].hsize, timing[i].vsize,
|
Mode = FindDMTMode(timing[i].hsize, timing[i].vsize,
|
||||||
timing[i].refresh);
|
timing[i].refresh, rb);
|
||||||
|
|
||||||
if (!Mode) {
|
if (!Mode) {
|
||||||
if (timing_level == LEVEL_CVT)
|
if (timing_level == LEVEL_CVT)
|
||||||
|
/* pass rb here too? */
|
||||||
Mode = xf86CVTMode(timing[i].hsize, timing[i].vsize,
|
Mode = xf86CVTMode(timing[i].hsize, timing[i].vsize,
|
||||||
timing[i].refresh, FALSE, FALSE);
|
timing[i].refresh, FALSE, FALSE);
|
||||||
else if (timing_level == LEVEL_GTF)
|
else if (timing_level == LEVEL_GTF)
|
||||||
|
@ -734,7 +764,7 @@ xf86DDCGetModes(int scrnIndex, xf86MonPtr DDC)
|
||||||
int i;
|
int i;
|
||||||
DisplayModePtr Modes = NULL, Mode;
|
DisplayModePtr Modes = NULL, Mode;
|
||||||
ddc_quirk_t quirks;
|
ddc_quirk_t quirks;
|
||||||
Bool preferred;
|
Bool preferred, rb;
|
||||||
int timing_level;
|
int timing_level;
|
||||||
|
|
||||||
xf86DrvMsg (scrnIndex, X_INFO, "EDID vendor \"%s\", prod id %d\n",
|
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))
|
if (quirks & (DDC_QUIRK_PREFER_LARGE_60 | DDC_QUIRK_PREFER_LARGE_75))
|
||||||
preferred = FALSE;
|
preferred = FALSE;
|
||||||
|
|
||||||
|
rb = xf86MonitorSupportsReducedBlanking(DDC);
|
||||||
|
|
||||||
timing_level = MonitorStandardTimingLevel(DDC);
|
timing_level = MonitorStandardTimingLevel(DDC);
|
||||||
|
|
||||||
for (i = 0; i < DET_TIMINGS; i++) {
|
for (i = 0; i < DET_TIMINGS; i++) {
|
||||||
|
@ -766,7 +798,7 @@ xf86DDCGetModes(int scrnIndex, xf86MonPtr DDC)
|
||||||
break;
|
break;
|
||||||
case DS_STD_TIMINGS:
|
case DS_STD_TIMINGS:
|
||||||
Mode = DDCModesFromStandardTiming(det_mon->section.std_t,
|
Mode = DDCModesFromStandardTiming(det_mon->section.std_t,
|
||||||
quirks, timing_level);
|
quirks, timing_level, rb);
|
||||||
Modes = xf86ModesAdd(Modes, Mode);
|
Modes = xf86ModesAdd(Modes, Mode);
|
||||||
break;
|
break;
|
||||||
#if XORG_VERSION_CURRENT < XORG_VERSION_NUMERIC(7,0,0,0,0)
|
#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);
|
Modes = xf86ModesAdd(Modes, Mode);
|
||||||
|
|
||||||
/* Add standard timings */
|
/* Add standard timings */
|
||||||
Mode = DDCModesFromStandardTiming(DDC->timings2, quirks, timing_level);
|
Mode = DDCModesFromStandardTiming(DDC->timings2, quirks, timing_level, rb);
|
||||||
Modes = xf86ModesAdd(Modes, Mode);
|
Modes = xf86ModesAdd(Modes, Mode);
|
||||||
|
|
||||||
if (quirks & DDC_QUIRK_PREFER_LARGE_60)
|
if (quirks & DDC_QUIRK_PREFER_LARGE_60)
|
||||||
|
@ -820,12 +852,7 @@ xf86DDCMonitorSet(int scrnIndex, MonPtr Monitor, xf86MonPtr DDC)
|
||||||
Monitor->heightmm = 10 * DDC->features.vsize;
|
Monitor->heightmm = 10 * DDC->features.vsize;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
Monitor->reducedblanking = xf86MonitorSupportsReducedBlanking(DDC);
|
||||||
* 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;
|
|
||||||
|
|
||||||
Modes = xf86DDCGetModes(scrnIndex, DDC);
|
Modes = xf86DDCGetModes(scrnIndex, DDC);
|
||||||
|
|
||||||
|
|
|
@ -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.
|
* Marks as bad any reduced-blanking modes.
|
||||||
*
|
*
|
||||||
|
|
|
@ -64,6 +64,9 @@ DisplayModePtr xf86CVTMode(int HDisplay, int VDisplay, float VRefresh,
|
||||||
Bool Reduced, Bool Interlaced);
|
Bool Reduced, Bool Interlaced);
|
||||||
DisplayModePtr xf86GTFMode(int h_pixels, int v_lines, float freq, int interlaced, int margins);
|
DisplayModePtr xf86GTFMode(int h_pixels, int v_lines, float freq, int interlaced, int margins);
|
||||||
|
|
||||||
|
Bool
|
||||||
|
xf86ModeIsReduced(DisplayModePtr mode);
|
||||||
|
|
||||||
void
|
void
|
||||||
xf86ValidateModesFlags(ScrnInfoPtr pScrn, DisplayModePtr modeList,
|
xf86ValidateModesFlags(ScrnInfoPtr pScrn, DisplayModePtr modeList,
|
||||||
int flags);
|
int flags);
|
||||||
|
|
Loading…
Reference in New Issue