Merge branch 'master' of git://git.freedesktop.org/git/xorg/xserver

This commit is contained in:
Kristian Høgsberg 2007-10-12 19:28:39 -04:00
commit 927757e102
9 changed files with 222 additions and 127 deletions

View File

@ -215,27 +215,10 @@ xf86AutoConfig(void)
{ {
const char **p; const char **p;
char buf[1024]; char buf[1024];
struct pci_device_iterator *iter;
struct pci_device * info = NULL;
const char *driver = NULL; const char *driver = NULL;
ConfigStatus ret; ConfigStatus ret;
/* Find the primary device, and get some information about it. */ driver = chooseVideoDriver();
iter = pci_slot_match_iterator_create(NULL);
while ((info = pci_device_next(iter)) != NULL) {
if (xf86IsPrimaryPci(info)) {
break;
}
}
pci_iterator_destroy(iter);
if (!info) {
ErrorF("Primary device is not PCI\n");
}
if (info)
driver = videoPtrToDriverName(info);
AppendToConfig(BUILTIN_MODULE_SECTION); AppendToConfig(BUILTIN_MODULE_SECTION);
AppendToConfig(BUILTIN_MONITOR_SECTION); AppendToConfig(BUILTIN_MONITOR_SECTION);
@ -301,15 +284,14 @@ xchomp(char *line)
len = strlen(line); len = strlen(line);
if (line[len - 1] == '\n' && len > 0) { if (line[len - 1] == '\n' && len > 0) {
line[len - 1] = '\0'; line[len - 1] = '\0';
return 0;
} }
return 0;
} }
GDevPtr GDevPtr
autoConfigDevice(GDevPtr preconf_device) autoConfigDevice(GDevPtr preconf_device)
{ {
GDevPtr ptr = NULL; GDevPtr ptr = NULL;
confScreenPtr scrn = NULL;
if (!xf86configptr) { if (!xf86configptr) {
return NULL; return NULL;
@ -347,41 +329,20 @@ autoConfigDevice(GDevPtr preconf_device)
return ptr; return ptr;
} }
char* static void
chooseVideoDriver(void) matchDriverFromFiles (char** matches, uint16_t match_vendor, uint16_t match_chip)
{ {
struct pci_device * info = NULL;
struct pci_device_iterator *iter;
DIR *idsdir; DIR *idsdir;
FILE *fp; FILE *fp;
struct dirent *direntry; struct dirent *direntry;
char *line = NULL; char *line = NULL;
char *chosen_driver = NULL;
size_t len; size_t len;
ssize_t read; ssize_t read;
char path_name[256], vendor_str[5], chip_str[5]; char path_name[256], vendor_str[5], chip_str[5];
uint16_t vendor, chip; uint16_t vendor, chip;
int i, j; int i, j;
char *matches[20]; /* If we have more than 20 drivers we're in trouble */
for (i=0 ; i<20 ; i++)
matches[i] = NULL;
/* Find the primary device, and get some information about it. */
iter = pci_slot_match_iterator_create(NULL);
while ((info = pci_device_next(iter)) != NULL) {
if (xf86IsPrimaryPci(info)) {
break;
}
}
pci_iterator_destroy(iter);
if (!info) {
ErrorF("Primary device is not PCI\n");
}
idsdir = opendir("/usr/share/xserver-xorg/pci"); idsdir = opendir("/usr/share/xserver-xorg/pci");
if (idsdir) { if (idsdir) {
direntry = readdir(idsdir); direntry = readdir(idsdir);
/* Read the directory */ /* Read the directory */
@ -423,8 +384,7 @@ chooseVideoDriver(void)
chip = (int)strtol(chip_str, NULL, 16); chip = (int)strtol(chip_str, NULL, 16);
} }
} }
if (vendor == info->vendor_id && if (vendor == match_vendor && chip == match_chip ) {
(chip == info->device_id || chip == -1)) {
i = 0; i = 0;
while (matches[i]) { while (matches[i]) {
i++; i++;
@ -457,6 +417,38 @@ chooseVideoDriver(void)
direntry = readdir(idsdir); direntry = readdir(idsdir);
} }
} }
end:
xfree(line);
closedir(idsdir);
}
char*
chooseVideoDriver(void)
{
struct pci_device * info = NULL;
struct pci_device_iterator *iter;
char *chosen_driver = NULL;
int i;
char *matches[20]; /* If we have more than 20 drivers we're in trouble */
for (i=0 ; i<20 ; i++)
matches[i] = NULL;
/* Find the primary device, and get some information about it. */
iter = pci_slot_match_iterator_create(NULL);
while ((info = pci_device_next(iter)) != NULL) {
if (xf86IsPrimaryPci(info)) {
break;
}
}
pci_iterator_destroy(iter);
if (!info) {
ErrorF("Primary device is not PCI\n");
}
matchDriverFromFiles(matches, info->vendor_id, info->device_id);
/* TODO Handle multiple drivers claiming to support the same PCI ID */ /* TODO Handle multiple drivers claiming to support the same PCI ID */
if (matches[0]) { if (matches[0]) {
@ -478,7 +470,6 @@ chooseVideoDriver(void)
xf86Msg(X_DEFAULT, "Matched %s for the autoconfigured driver\n", chosen_driver); xf86Msg(X_DEFAULT, "Matched %s for the autoconfigured driver\n", chosen_driver);
end:
i = 0; i = 0;
while (matches[i]) { while (matches[i]) {
if (matches[i] != chosen_driver) { if (matches[i] != chosen_driver) {
@ -486,8 +477,6 @@ chooseVideoDriver(void)
} }
i++; i++;
} }
xfree(line);
closedir(idsdir);
return chosen_driver; return chosen_driver;
} }

View File

@ -2134,8 +2134,12 @@ _X_EXPORT xf86MonPtr
xf86OutputGetEDID (xf86OutputPtr output, I2CBusPtr pDDCBus) xf86OutputGetEDID (xf86OutputPtr output, I2CBusPtr pDDCBus)
{ {
ScrnInfoPtr scrn = output->scrn; ScrnInfoPtr scrn = output->scrn;
xf86MonPtr mon;
return xf86DoEDID_DDC2 (scrn->scrnIndex, pDDCBus); mon = xf86DoEDID_DDC2 (scrn->scrnIndex, pDDCBus);
xf86DDCApplyQuirks (scrn->scrnIndex, pDDCBus);
return mon;
} }
static char *_xf86ConnectorNames[] = { "None", "VGA", "DVI-I", "DVI-D", static char *_xf86ConnectorNames[] = { "None", "VGA", "DVI-I", "DVI-D",

View File

@ -54,6 +54,16 @@ typedef enum {
DDC_QUIRK_PREFER_LARGE_60 = 1 << 0, DDC_QUIRK_PREFER_LARGE_60 = 1 << 0,
/* 135MHz clock is too high, drop a bit */ /* 135MHz clock is too high, drop a bit */
DDC_QUIRK_135_CLOCK_TOO_HIGH = 1 << 1, DDC_QUIRK_135_CLOCK_TOO_HIGH = 1 << 1,
/* Prefer the largest mode at 75 Hz */
DDC_QUIRK_PREFER_LARGE_75 = 1 << 2,
/* Convert detailed timing's horizontal from units of cm to mm */
DDC_QUIRK_DETAILED_H_IN_CM = 1 << 3,
/* Convert detailed timing's vertical from units of cm to mm */
DDC_QUIRK_DETAILED_V_IN_CM = 1 << 4,
/* Detailed timing descriptors have bogus size values, so just take the
* maximum size and use that.
*/
DDC_QUIRK_DETAILED_USE_MAXIMUM_SIZE = 1 << 5,
} ddc_quirk_t; } ddc_quirk_t;
static Bool quirk_prefer_large_60 (int scrnIndex, xf86MonPtr DDC) static Bool quirk_prefer_large_60 (int scrnIndex, xf86MonPtr DDC)
@ -81,6 +91,52 @@ static Bool quirk_prefer_large_60 (int scrnIndex, xf86MonPtr DDC)
return FALSE; return FALSE;
} }
static Bool quirk_prefer_large_75 (int scrnIndex, xf86MonPtr DDC)
{
/* Bug #11603: Funai Electronics PM36B */
if (memcmp (DDC->vendor.name, "FCM", 4) == 0 &&
DDC->vendor.prod_id == 13600)
return TRUE;
return FALSE;
}
static Bool quirk_detailed_h_in_cm (int scrnIndex, xf86MonPtr DDC)
{
/* Bug #10304: "LGPhilipsLCD LP154W01-A5" */
/* Bug #12784: "LGPhilipsLCD LP154W01-TLA2" */
if (memcmp (DDC->vendor.name, "LPL", 4) == 0 &&
DDC->vendor.prod_id == 0)
return TRUE;
/* Bug #11603: Funai Electronics PM36B */
if (memcmp (DDC->vendor.name, "FCM", 4) == 0 &&
DDC->vendor.prod_id == 13600)
return TRUE;
return FALSE;
}
static Bool quirk_detailed_v_in_cm (int scrnIndex, xf86MonPtr DDC)
{
/* Bug #11603: Funai Electronics PM36B */
if (memcmp (DDC->vendor.name, "FCM", 4) == 0 &&
DDC->vendor.prod_id == 13600)
return TRUE;
return FALSE;
}
static Bool quirk_detailed_use_maximum_size (int scrnIndex, xf86MonPtr DDC)
{
/* Bug #10304: LGPhilipsLCD LP154W01-A5 */
if (memcmp (DDC->vendor.name, "LPL", 4) == 0 &&
DDC->vendor.prod_id == 0)
return TRUE;
return FALSE;
}
static Bool quirk_135_clock_too_high (int scrnIndex, xf86MonPtr DDC) static Bool quirk_135_clock_too_high (int scrnIndex, xf86MonPtr DDC)
{ {
/* Envision Peripherals, Inc. EN-7100e. See bug #9550. */ /* Envision Peripherals, Inc. EN-7100e. See bug #9550. */
@ -106,6 +162,22 @@ static const ddc_quirk_map_t ddc_quirks[] = {
quirk_135_clock_too_high, DDC_QUIRK_135_CLOCK_TOO_HIGH, quirk_135_clock_too_high, DDC_QUIRK_135_CLOCK_TOO_HIGH,
"Recommended 135MHz pixel clock is too high" "Recommended 135MHz pixel clock is too high"
}, },
{
quirk_prefer_large_75, DDC_QUIRK_PREFER_LARGE_75,
"Detailed timing is not preferred, use largest mode at 75Hz"
},
{
quirk_detailed_h_in_cm, DDC_QUIRK_DETAILED_H_IN_CM,
"Detailed timings give horizontal size in cm."
},
{
quirk_detailed_v_in_cm, DDC_QUIRK_DETAILED_V_IN_CM,
"Detailed timings give vertical size in cm."
},
{
quirk_detailed_use_maximum_size, DDC_QUIRK_DETAILED_USE_MAXIMUM_SIZE,
"Detailed timings give sizes in cm."
},
{ {
NULL, DDC_QUIRK_NONE, NULL, DDC_QUIRK_NONE,
"No known quirks" "No known quirks"
@ -303,6 +375,98 @@ DDCGuessRangesFromModes(int scrnIndex, MonPtr Monitor, DisplayModePtr Modes)
} }
} }
static ddc_quirk_t
xf86DDCDetectQuirks(int scrnIndex, xf86MonPtr DDC, Bool verbose)
{
ddc_quirk_t quirks;
int i;
quirks = DDC_QUIRK_NONE;
for (i = 0; ddc_quirks[i].detect; i++) {
if (ddc_quirks[i].detect (scrnIndex, DDC)) {
if (verbose) {
xf86DrvMsg (scrnIndex, X_INFO, " EDID quirk: %s\n",
ddc_quirks[i].description);
}
quirks |= ddc_quirks[i].quirk;
}
}
return quirks;
}
/**
* Applies monitor-specific quirks to the decoded EDID information.
*
* Note that some quirks applying to the mode list are still implemented in
* xf86DDCGetModes.
*/
void
xf86DDCApplyQuirks(int scrnIndex, xf86MonPtr DDC)
{
ddc_quirk_t quirks = xf86DDCDetectQuirks (scrnIndex, DDC, FALSE);
int i;
for (i = 0; i < DET_TIMINGS; i++) {
struct detailed_monitor_section *det_mon = &DDC->det_mon[i];
if (det_mon->type != DT)
continue;
if (quirks & DDC_QUIRK_DETAILED_H_IN_CM)
det_mon->section.d_timings.h_size *= 10;
if (quirks & DDC_QUIRK_DETAILED_V_IN_CM)
det_mon->section.d_timings.v_size *= 10;
if (quirks & DDC_QUIRK_DETAILED_USE_MAXIMUM_SIZE) {
det_mon->section.d_timings.h_size = 10 * DDC->features.hsize;
det_mon->section.d_timings.v_size = 10 * DDC->features.vsize;
}
}
}
/**
* Walks the modes list, finding the mode with the largest area which is
* closest to the target refresh rate, and marks it as the only preferred mode.
*/
static void
xf86DDCSetPreferredRefresh(int scrnIndex, DisplayModePtr modes,
float target_refresh)
{
DisplayModePtr mode, best = modes;
for (mode = modes; mode; mode = mode->next)
{
mode->type &= ~M_T_PREFERRED;
if (mode == best) continue;
if (mode->HDisplay * mode->VDisplay >
best->HDisplay * best->VDisplay)
{
best = mode;
continue;
}
if (mode->HDisplay * mode->VDisplay ==
best->HDisplay * best->VDisplay)
{
double mode_refresh = xf86ModeVRefresh (mode);
double best_refresh = xf86ModeVRefresh (best);
double mode_dist = fabs(mode_refresh - target_refresh);
double best_dist = fabs(best_refresh - target_refresh);
if (mode_dist < best_dist)
{
best = mode;
continue;
}
}
}
if (best)
best->type |= M_T_PREFERRED;
}
_X_EXPORT DisplayModePtr _X_EXPORT DisplayModePtr
xf86DDCGetModes(int scrnIndex, xf86MonPtr DDC) xf86DDCGetModes(int scrnIndex, xf86MonPtr DDC)
{ {
@ -312,14 +476,8 @@ xf86DDCGetModes(int scrnIndex, xf86MonPtr DDC)
xf86DrvMsg (scrnIndex, X_INFO, "EDID vendor \"%s\", prod id %d\n", xf86DrvMsg (scrnIndex, X_INFO, "EDID vendor \"%s\", prod id %d\n",
DDC->vendor.name, DDC->vendor.prod_id); DDC->vendor.name, DDC->vendor.prod_id);
quirks = DDC_QUIRK_NONE;
for (i = 0; ddc_quirks[i].detect; i++) quirks = xf86DDCDetectQuirks(scrnIndex, DDC, TRUE);
if (ddc_quirks[i].detect (scrnIndex, DDC))
{
xf86DrvMsg (scrnIndex, X_INFO, " EDID quirk: %s\n",
ddc_quirks[i].description);
quirks |= ddc_quirks[i].quirk;
}
preferred = PREFERRED_TIMING_MODE(DDC->features.msc); preferred = PREFERRED_TIMING_MODE(DDC->features.msc);
if (quirks & DDC_QUIRK_PREFER_LARGE_60) if (quirks & DDC_QUIRK_PREFER_LARGE_60)
@ -357,32 +515,11 @@ xf86DDCGetModes(int scrnIndex, xf86MonPtr DDC)
Modes = xf86ModesAdd(Modes, Mode); Modes = xf86ModesAdd(Modes, Mode);
if (quirks & DDC_QUIRK_PREFER_LARGE_60) if (quirks & DDC_QUIRK_PREFER_LARGE_60)
{ xf86DDCSetPreferredRefresh(scrnIndex, Modes, 60);
DisplayModePtr best = Modes;
for (Mode = Modes; Mode; Mode = Mode->next) if (quirks & DDC_QUIRK_PREFER_LARGE_75)
{ xf86DDCSetPreferredRefresh(scrnIndex, Modes, 75);
if (Mode == best) continue;
if (Mode->HDisplay * Mode->VDisplay > best->HDisplay * best->VDisplay)
{
best = Mode;
continue;
}
if (Mode->HDisplay * Mode->VDisplay == best->HDisplay * best->VDisplay)
{
double mode_refresh = xf86ModeVRefresh (Mode);
double best_refresh = xf86ModeVRefresh (best);
double mode_dist = fabs(mode_refresh - 60.0);
double best_dist = fabs(best_refresh - 60.0);
if (mode_dist < best_dist)
{
best = Mode;
continue;
}
}
}
if (best)
best->type |= M_T_PREFERRED;
}
return Modes; return Modes;
} }

View File

@ -95,4 +95,7 @@ xf86GetMonitorModes (ScrnInfoPtr pScrn, XF86ConfMonitorPtr conf_monitor);
DisplayModePtr DisplayModePtr
xf86GetDefaultModes (Bool interlaceAllowed, Bool doubleScanAllowed); xf86GetDefaultModes (Bool interlaceAllowed, Bool doubleScanAllowed);
void
xf86DDCApplyQuirks(int scrnIndex, xf86MonPtr DDC);
#endif /* _XF86MODES_H_ */ #endif /* _XF86MODES_H_ */

View File

@ -186,8 +186,6 @@ else\
"The Inactive keyword must be followed by a Device name in quotes." "The Inactive keyword must be followed by a Device name in quotes."
#define UNDEFINED_SCREEN_MSG \ #define UNDEFINED_SCREEN_MSG \
"Undefined Screen \"%s\" referenced by ServerLayout \"%s\"." "Undefined Screen \"%s\" referenced by ServerLayout \"%s\"."
#define UNDEFINED_MONITOR_MSG \
"Undefined Monitor \"%s\" referenced by Screen \"%s\"."
#define UNDEFINED_MODES_MSG \ #define UNDEFINED_MODES_MSG \
"Undefined Modes Section \"%s\" referenced by Monitor \"%s\"." "Undefined Modes Section \"%s\" referenced by Monitor \"%s\"."
#define UNDEFINED_DEVICE_MSG \ #define UNDEFINED_DEVICE_MSG \
@ -204,8 +202,6 @@ else\
"This section must have an Identifier line." "This section must have an Identifier line."
#define ONLY_ONE_MSG \ #define ONLY_ONE_MSG \
"This section must have only one of either %s line." "This section must have only one of either %s line."
#define UNDEFINED_DRIVER_MSG \
"Device section \"%s\" must have a Driver line."
#define UNDEFINED_INPUTDRIVER_MSG \ #define UNDEFINED_INPUTDRIVER_MSG \
"InputDevice section \"%s\" must have a Driver line." "InputDevice section \"%s\" must have a Driver line."
#define INVALID_GAMMA_MSG \ #define INVALID_GAMMA_MSG \

View File

@ -357,26 +357,6 @@ xf86freeDeviceList (XF86ConfDevicePtr ptr)
} }
} }
int
xf86validateDevice (XF86ConfigPtr p)
{
XF86ConfDevicePtr device = p->conf_device_lst;
if (!device) {
xf86validationError ("At least one Device section is required.");
return (FALSE);
}
while (device) {
if (!device->dev_driver) {
xf86validationError (UNDEFINED_DRIVER_MSG, device->dev_identifier);
return (FALSE);
}
device = device->list.next;
}
return (TRUE);
}
XF86ConfDevicePtr XF86ConfDevicePtr
xf86findDevice (const char *ident, XF86ConfDevicePtr p) xf86findDevice (const char *ident, XF86ConfDevicePtr p)
{ {

View File

@ -498,12 +498,6 @@ xf86validateScreen (XF86ConfigPtr p)
XF86ConfDevicePtr device; XF86ConfDevicePtr device;
XF86ConfAdaptorLinkPtr adaptor; XF86ConfAdaptorLinkPtr adaptor;
if (!screen)
{
xf86validationError ("At least one Screen section is required.");
return (FALSE);
}
while (screen) while (screen)
{ {
if (screen->scrn_obso_driver && !screen->scrn_identifier) if (screen->scrn_obso_driver && !screen->scrn_identifier)
@ -512,13 +506,7 @@ xf86validateScreen (XF86ConfigPtr p)
monitor = xf86findMonitor (screen->scrn_monitor_str, p->conf_monitor_lst); monitor = xf86findMonitor (screen->scrn_monitor_str, p->conf_monitor_lst);
if (screen->scrn_monitor_str) if (screen->scrn_monitor_str)
{ {
if (!monitor) if (monitor)
{
xf86validationError (UNDEFINED_MONITOR_MSG,
screen->scrn_monitor_str, screen->scrn_identifier);
return (FALSE);
}
else
{ {
screen->scrn_monitor = monitor; screen->scrn_monitor = monitor;
if (!xf86validateMonitor(p, screen)) if (!xf86validateMonitor(p, screen))

View File

@ -80,10 +80,8 @@ static xf86ConfigSymTabRec TopLevelTab[] =
static int static int
xf86validateConfig (XF86ConfigPtr p) xf86validateConfig (XF86ConfigPtr p)
{ {
/*if (!xf86validateDevice (p)) if (!xf86validateScreen (p))
return FALSE;*/ return FALSE;
/*if (!xf86validateScreen (p))
return FALSE;*/
if (!xf86validateInput (p)) if (!xf86validateInput (p))
return FALSE; return FALSE;
if (!xf86validateLayout (p)) if (!xf86validateLayout (p))

View File

@ -8,6 +8,6 @@ sdkdir=@sdkdir@
Name: xorg-server Name: xorg-server
Description: Modular X.Org X Server Description: Modular X.Org X Server
Version: @PACKAGE_VERSION@ Version: @PACKAGE_VERSION@
Requires.private: pixman-1 Requires: pixman-1
Cflags: -I${sdkdir} Cflags: -I${sdkdir}
Libs: -L${libdir} Libs: -L${libdir}