1283 int numEdidModes; |
1280 int numEdidModes; |
1284 int numDtModes = 0; |
1281 int numDtModes = 0; |
1285 int numDtModelines = 0; |
1282 int numDtModelines = 0; |
1286 int numStdModes = 0; |
1283 int numStdModes = 0; |
1287 char **rmodeNames; |
1284 char **rmodeNames; |
1288 DisplayModePtr modePool; |
1285 float hmin = 1e6, hmax = 0.0, vmin = 1e6, vmax = 0.0; |
|
1286 int useBuiltin = FALSE; |
|
1287 float builtinHSync = 0.0; |
|
1288 float builtinVRfrsh = 0.0; |
1289 |
1289 |
1290 #ifdef DEBUG |
1290 #ifdef DEBUG |
1291 ErrorF("xf86ValidateModes(%p, %p, %p, %p,\n\t\t %p, %d, %d, %d, %d, %d, %d, %d, %d, 0x%x)\n", |
1291 ErrorF("xf86ValidateModes(%p, %p, %p, %p,\n\t\t %p, %d, %d, %d, %d, %d, %d, %d, %d, 0x%x)\n", |
1292 scrp, availModes, modeNames, clockRanges, |
1292 scrp, availModes, modeNames, clockRanges, |
1293 linePitches, minPitch, maxPitch, pitchInc, |
1293 linePitches, minPitch, maxPitch, pitchInc, |
1311 return -1; |
1311 return -1; |
1312 } |
1312 } |
1313 if ((virtualX > 0) != (virtualY > 0)) { |
1313 if ((virtualX > 0) != (virtualY > 0)) { |
1314 ErrorF("xf86ValidateModes: called with invalid virtual resolution\n"); |
1314 ErrorF("xf86ValidateModes: called with invalid virtual resolution\n"); |
1315 return -1; |
1315 return -1; |
1316 } |
|
1317 |
|
1318 /* |
|
1319 * If DDC is empty, try VBE DDC probing, since xf86DoEDID_DDC2 |
|
1320 * probing, which at least nv and ati drivers count on, sometimes |
|
1321 * fails for some CRT monitors |
|
1322 */ |
|
1323 #ifdef sun |
|
1324 #ifdef improve_for_nvidia_driver |
|
1325 /* |
|
1326 * With nvidia driver, EDID modes are added to availModes with type 0, |
|
1327 * reconstruct them. |
|
1328 */ |
|
1329 if (!strcmp (scrp->driverName, "nvidia")) { |
|
1330 for (p = availModes; p != NULL; p = p->next) |
|
1331 if (p->type == 0) { |
|
1332 dt_modes[numDtModelines] = *p; |
|
1333 dt_modes[numDtModelines].type = M_T_EDID; |
|
1334 dt_mode_names[numDtModes++] = xnfstrdup(p->name); |
|
1335 dt_mode_names[numDtModes] = NULL; |
|
1336 } |
|
1337 /* |
|
1338 * If monitor probing failed with nvidia driver, try the results from |
|
1339 * VBE probing |
|
1340 */ |
|
1341 } |
|
1342 if ((!scrp->monitor->DDC) && (strcmp (scrp->driverName, "nvidia") || |
|
1343 (!numDtModelines))) { |
|
1344 #else |
|
1345 if ((!scrp->monitor->DDC) && strcmp (scrp->driverName, "nvidia")) { |
|
1346 #endif |
|
1347 #else |
|
1348 if (!scrp->monitor->DDC) { |
|
1349 #endif |
|
1350 int entityIndex = scrp->entityList[0]; |
|
1351 |
|
1352 if ((xf86LoadSubModule(scrp, "vbe")) && xf86FallbackDDCProbe) |
|
1353 scrp->monitor->DDC = xf86FallbackDDCProbe (entityIndex, scrp); |
|
1354 } |
1316 } |
1355 |
1317 |
1356 /* |
1318 /* |
1357 * Probe monitor so that we can enforce/warn about its limits. |
1319 * Probe monitor so that we can enforce/warn about its limits. |
1358 * If one or more DS_RANGES descriptions are present, use the parameters |
1320 * If one or more DS_RANGES descriptions are present, use the parameters |
1555 vrefresh[numTimings].lo = vmin; |
1516 vrefresh[numTimings].lo = vmin; |
1556 vrefresh[numTimings].hi = vmax; |
1517 vrefresh[numTimings].hi = vmax; |
1557 numTimings++; |
1518 numTimings++; |
1558 } |
1519 } |
1559 } |
1520 } |
1560 |
1521 } else { |
1561 if (numTimings > 0) { |
1522 /* Check built-in modes */ |
|
1523 for (p = scrp->modePool; p != NULL; p = p->next) { |
|
1524 if (p->type == M_T_BUILTIN) { |
|
1525 std_mode_names[numStdModes++] = xnfstrdup(p->name); |
|
1526 std_mode_names[numStdModes] = NULL; |
|
1527 useBuiltin = TRUE; |
|
1528 if (ModeHSync(p) > builtinHSync) |
|
1529 builtinHSync = ModeHSync(p); |
|
1530 if ((float) ModeVRefresh(p) > builtinVRfrsh) |
|
1531 builtinVRfrsh = (float) ModeVRefresh(p); |
|
1532 } |
|
1533 } |
|
1534 if (numStdModes == 0) |
|
1535 for (p = scrp->monitor->Modes; p != NULL; p = p->next) { |
|
1536 if (p->type == M_T_BUILTIN) { |
|
1537 std_mode_names[numStdModes++] = xnfstrdup(p->name); |
|
1538 std_mode_names[numStdModes] = NULL; |
|
1539 useBuiltin = TRUE; |
|
1540 if (ModeHSync(p) > builtinHSync) |
|
1541 builtinHSync = ModeHSync(p); |
|
1542 if ((float) ModeVRefresh(p) > builtinVRfrsh) |
|
1543 builtinVRfrsh = (float) ModeVRefresh(p); |
|
1544 } |
|
1545 } |
|
1546 } |
|
1547 |
|
1548 if (numTimings > 0) { |
|
1549 MonPtr monitor = scrp->monitor; |
|
1550 int i, j; |
1562 |
1551 |
1563 #ifdef DEBUG |
1552 #ifdef DEBUG |
1564 for (i = 0; i < numTimings; i++) { |
1553 for (i = 0; i < numTimings; i++) { |
1565 ErrorF("DDC - Hsync %.1f-%.1f kHz - Vrefresh %.1f-%.1f Hz\n", |
1554 ErrorF("DDC - Hsync %.1f-%.1f kHz - Vrefresh %.1f-%.1f Hz\n", |
1566 hsync[i].lo, hsync[i].hi, |
1555 hsync[i].lo, hsync[i].hi, vrefresh[i].lo, vrefresh[i].hi); |
1567 vrefresh[i].lo, vrefresh[i].hi); |
1556 } |
1568 } |
|
1569 #endif |
1557 #endif |
1570 |
1558 |
1571 #define DDC_SYNC_TOLERANCE SYNC_TOLERANCE |
1559 #define DDC_SYNC_TOLERANCE SYNC_TOLERANCE |
1572 if (monitor->nHsync > 0) { |
1560 if (monitor->nHsync > 0) { |
1573 for (i = 0; i < monitor->nHsync; i++) { |
1561 for (i = 0; i < monitor->nHsync; i++) { |
1574 Bool good = FALSE; |
1562 Bool good = FALSE; |
1575 for (j = 0; j < numTimings; j++) { |
1563 for (j = 0; j < numTimings; j++) { |
1576 if ((1.0 - DDC_SYNC_TOLERANCE) * hsync[j].lo <= |
1564 if ((1.0 - DDC_SYNC_TOLERANCE) * hsync[j].lo <= |
1577 monitor->hsync[i].lo && |
1565 monitor->hsync[i].lo && |
1578 (1.0 + DDC_SYNC_TOLERANCE) * hsync[j].hi >= |
1566 (1.0 + DDC_SYNC_TOLERANCE) * hsync[j].hi >= |
1579 monitor->hsync[i].hi) { |
1567 monitor->hsync[i].hi) { |
1580 good = TRUE; |
1568 good = TRUE; |
1581 break; |
1569 break; |
1582 } |
|
1583 } |
1570 } |
1584 if (!good) { |
1571 } |
1585 xf86DrvMsg(scrp->scrnIndex, X_WARNING, |
1572 if (!good) { |
1586 "config file hsync range %g-%gkHz not within DDC " |
1573 xf86DrvMsg(scrp->scrnIndex, X_WARNING, |
1587 "hsync ranges.\n", |
1574 "config file hsync range %g-%gkHz not within DDC " |
1588 monitor->hsync[i].lo, monitor->hsync[i].hi); |
1575 "hsync ranges.\n", |
|
1576 monitor->hsync[i].lo, monitor->hsync[i].hi); |
|
1577 } |
|
1578 } |
|
1579 } |
|
1580 |
|
1581 if (monitor->nVrefresh > 0) { |
|
1582 for (i = 0; i < monitor->nVrefresh; i++) { |
|
1583 Bool good = FALSE; |
|
1584 for (j = 0; j < numTimings; j++) { |
|
1585 if ((1.0 - DDC_SYNC_TOLERANCE) * vrefresh[j].lo <= |
|
1586 monitor->vrefresh[0].lo && |
|
1587 (1.0 + DDC_SYNC_TOLERANCE) * vrefresh[j].hi >= |
|
1588 monitor->vrefresh[0].hi) { |
|
1589 good = TRUE; |
|
1590 break; |
1589 } |
1591 } |
|
1592 } |
|
1593 if (!good) { |
|
1594 xf86DrvMsg(scrp->scrnIndex, X_WARNING, |
|
1595 "config file vrefresh range %g-%gHz not within DDC " |
|
1596 "vrefresh ranges.\n", |
|
1597 monitor->vrefresh[i].lo, monitor->vrefresh[i].hi); |
1590 } |
1598 } |
1591 } |
1599 } |
1592 |
1600 } |
1593 if (monitor->nVrefresh > 0) { |
|
1594 for (i = 0; i < monitor->nVrefresh; i++) { |
|
1595 Bool good = FALSE; |
|
1596 for (j = 0; j < numTimings; j++) { |
|
1597 if ((1.0 - DDC_SYNC_TOLERANCE) * vrefresh[j].lo <= |
|
1598 monitor->vrefresh[0].lo && |
|
1599 (1.0 + DDC_SYNC_TOLERANCE) * vrefresh[j].hi >= |
|
1600 monitor->vrefresh[0].hi) { |
|
1601 good = TRUE; |
|
1602 break; |
|
1603 } |
|
1604 } |
|
1605 if (!good) { |
|
1606 xf86DrvMsg(scrp->scrnIndex, X_WARNING, |
|
1607 "config file vrefresh range %g-%gHz not within DDC " |
|
1608 "vrefresh ranges.\n", |
|
1609 monitor->vrefresh[i].lo, monitor->vrefresh[i].hi); |
|
1610 } |
|
1611 } |
|
1612 } |
|
1613 } |
|
1614 } |
1601 } |
1615 |
1602 |
1616 /* |
1603 /* |
1617 * If requested by the driver, allow missing hsync and/or vrefresh ranges |
1604 * If requested by the driver, allow missing hsync and/or vrefresh ranges |
1618 * in the monitor section. |
1605 * in the monitor section. |
1859 } else { |
1839 } else { |
1860 char *typestring; |
1840 char *typestring; |
1861 |
1841 |
1862 switch (p->type) { |
1842 switch (p->type) { |
1863 case M_T_BUILTIN: |
1843 case M_T_BUILTIN: |
1864 typestring = xnfstrdup("builtin"); |
1844 typestring = xnfstrdup("(B)"); |
1865 break; |
1845 break; |
1866 case M_T_USERDEF: |
1846 case M_T_USERDEF: |
1867 typestring = xnfstrdup("user"); |
1847 typestring = xnfstrdup("(U)"); |
1868 break; |
1848 break; |
1869 case M_T_EDID: |
1849 case M_T_EDID: |
1870 typestring = xnfstrdup("EDID"); |
1850 typestring = xnfstrdup("(E)"); |
1871 break; |
1851 break; |
1872 case M_T_DEFAULT: |
1852 case M_T_DEFAULT: |
1873 typestring = xnfstrdup("default"); |
1853 typestring = xnfstrdup("(D)"); |
1874 break; |
1854 break; |
1875 default: |
1855 default: |
1876 typestring = xnfstrdup(""); |
1856 typestring = xnfstrdup(""); |
1877 break; |
1857 break; |
1878 } |
1858 } |
1879 xf86DrvMsg(scrp->scrnIndex, X_INFO, |
1859 xf86DrvMsg(scrp->scrnIndex, X_INFO, |
1880 "Not including %s \"%s\" %.1fMHz (%s) in pool\n", typestring, |
1860 "Excluding %s \"%s\" %.1fMHz (%s)\n", typestring, |
1881 p->name, p->Clock/1000.0, xf86ModeStatusToString(status)); |
1861 p->name, p->Clock/1000.0, xf86ModeStatusToString(status)); |
1882 } |
1862 } |
1883 if (i < numDtModelines) |
1863 if (i < numDtModelines) |
1884 i++; |
1864 i++; |
1885 else |
1865 else |
1966 last = NULL; |
1946 last = NULL; |
1967 if (rmodeNames != NULL) { |
1947 if (rmodeNames != NULL) { |
1968 for (i = 0; rmodeNames[i] != NULL; i++) { |
1948 for (i = 0; rmodeNames[i] != NULL; i++) { |
1969 if (fallbackMode) |
1949 if (fallbackMode) |
1970 xf86DrvMsg(scrp->scrnIndex, X_INFO, |
1950 xf86DrvMsg(scrp->scrnIndex, X_INFO, |
1971 "Prepend Fallback mode name \"%s\" to validation list\n", |
1951 "Prepend Fallback mode name (F) \"%s\" to validation list\n", |
1972 rmodeNames[i]); |
1952 rmodeNames[i]); |
1973 else { |
1953 else { |
1974 if (userModes) |
1954 if (userModes) |
1975 xf86DrvMsg(scrp->scrnIndex, X_INFO, |
1955 xf86DrvMsg(scrp->scrnIndex, X_INFO, |
1976 "Prepend User mode name \"%s\" to validation list\n", |
1956 "Prepend User mode name (U) \"%s\" to validation list\n", |
1977 rmodeNames[i]); |
1957 rmodeNames[i]); |
1978 else |
1958 else |
1979 xf86DrvMsg(scrp->scrnIndex, X_INFO, |
1959 if (useBuiltin) |
1980 "Prepend EDID mode name \"%s\" to validation list\n", rmodeNames[i]); |
1960 xf86DrvMsg(scrp->scrnIndex, X_INFO, |
|
1961 "Prepend BUILTIN mode name (B) \"%s\" to validation list\n", |
|
1962 rmodeNames[i]); |
|
1963 else |
|
1964 xf86DrvMsg(scrp->scrnIndex, X_INFO, |
|
1965 "Prepend EDID mode name (E) \"%s\" to validation list\n", |
|
1966 rmodeNames[i]); |
1981 } |
1967 } |
1982 new = xnfcalloc(1, sizeof(DisplayModeRec)); |
1968 new = xnfcalloc(1, sizeof(DisplayModeRec)); |
1983 new->prev = last; |
1969 new->prev = last; |
1984 if (userModes) |
1970 if (userModes) |
1985 new->type = M_T_USERDEF; |
1971 new->type = M_T_USERDEF; |
1986 else { |
1972 else { |
1987 if (fallbackMode) |
1973 if (useBuiltin) |
1988 new->type = M_T_DEFAULT; |
1974 new->type = M_T_BUILTIN; |
1989 else |
1975 else { |
1990 new->type = M_T_EDID; |
1976 if (fallbackMode) |
|
1977 new->type = M_T_DEFAULT; |
|
1978 else |
|
1979 new->type = M_T_EDID; |
|
1980 } |
1991 } |
1981 } |
1992 new->name = xnfalloc(strlen(rmodeNames[i]) + 1); |
1982 new->name = xnfalloc(strlen(rmodeNames[i]) + 1); |
1993 strcpy(new->name, rmodeNames[i]); |
1983 strcpy(new->name, rmodeNames[i]); |
1994 if (new->prev) |
1984 if (new->prev) |
1995 new->prev->next = new; |
1985 new->prev->next = new; |
2256 for (p = scrp->modes; p != NULL; p = p->next) |
2246 for (p = scrp->modes; p != NULL; p = p->next) |
2257 if (p->status == MODE_OK) |
2247 if (p->status == MODE_OK) |
2258 break; |
2248 break; |
2259 if (p) { |
2249 if (p) { |
2260 xf86DrvMsg(scrp->scrnIndex, X_INFO, |
2250 xf86DrvMsg(scrp->scrnIndex, X_INFO, |
2261 "Valid mode on top of list : \"%s\" %.1f MHz %.1f kHz, %.1f Hz with --\n", |
2251 "Valid mode on top: \"%s\" %.1f MHz %.1f kHz, %.1f Hz with --\n", |
2262 p->name, p->Clock/1000.0, ModeHSync(p), ModeVRefresh(p)); |
2252 p->name, p->Clock/1000.0, ModeHSync(p), ModeVRefresh(p)); |
2263 PrintModeline(scrp->scrnIndex, p); |
2253 PrintModeline(scrp->scrnIndex, p); |
2264 } |
2254 } |
2265 |
2255 |
2266 /* Make the mode list into a circular list by joining up the ends */ |
2256 /* Make the mode list into a circular list by joining up the ends */ |
2444 if (mode->Flags & V_NCSYNC) add(&flags, "-csync"); |
2434 if (mode->Flags & V_NCSYNC) add(&flags, "-csync"); |
2445 #if 0 |
2435 #if 0 |
2446 if (mode->Flags & V_CLKDIV2) add(&flags, "vclk/2"); |
2436 if (mode->Flags & V_CLKDIV2) add(&flags, "vclk/2"); |
2447 #endif |
2437 #endif |
2448 xf86DrvMsgVerb(scrnIndex, X_INFO, 3, |
2438 xf86DrvMsgVerb(scrnIndex, X_INFO, 3, |
2449 "Modeline \"%s\" %6.2f %i %i %i %i %i %i %i %i%s\n", |
2439 "\"%s\" %6.2f %i %i %i %i %i %i %i %i%s\n", |
2450 mode->name, mode->Clock/1000., mode->HDisplay, |
2440 mode->name, mode->Clock/1000., mode->HDisplay, |
2451 mode->HSyncStart, mode->HSyncEnd, mode->HTotal, |
2441 mode->HSyncStart, mode->HSyncEnd, mode->HTotal, |
2452 mode->VDisplay, mode->VSyncStart, mode->VSyncEnd, |
2442 mode->VDisplay, mode->VSyncStart, mode->VSyncEnd, |
2453 mode->VTotal, flags); |
2443 mode->VTotal, flags); |
2454 xfree(flags); |
2444 xfree(flags); |