summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/i830.h1
-rw-r--r--src/i830_driver.c59
-rw-r--r--src/i830_modes.c21
3 files changed, 55 insertions, 26 deletions
diff --git a/src/i830.h b/src/i830.h
index 6c153fa3..996e1446 100644
--- a/src/i830.h
+++ b/src/i830.h
@@ -428,6 +428,7 @@ extern DisplayModePtr i830GetModePool(ScrnInfoPtr pScrn, vbeInfoPtr pVbe,
VbeInfoBlock *vbe, int modeTypes);
extern void i830SetModeParameters(ScrnInfoPtr pScrn, vbeInfoPtr pVbe);
extern void i830PrintModes(ScrnInfoPtr pScrn);
+extern int I830GetBestRefresh(ScrnInfoPtr pScrn, int refresh);
/*
* 12288 is set as the maximum, chosen because it is enough for
diff --git a/src/i830_driver.c b/src/i830_driver.c
index 6acde944..f5417931 100644
--- a/src/i830_driver.c
+++ b/src/i830_driver.c
@@ -365,11 +365,14 @@ I830BIOSProbeDDC(ScrnInfoPtr pScrn, int index)
ConfiguredMonitor = vbeDoEDID(pVbe, NULL);
}
-/* Various extended video BIOS functions. */
-static const int refreshes[] = {
- 43, 56, 60, 70, 72, 75, 85, 100, 120
+/* Various extended video BIOS functions.
+ * 100 and 120Hz aren't really supported, they work but only get close
+ * to the requested refresh, and really not close enough.
+ * I've seen 100Hz come out at 104Hz, and 120Hz come out at 128Hz */
+const int i830refreshes[] = {
+ 43, 56, 60, 70, 72, 75, 85 /* 100, 120 */
};
-static const int nrefreshes = sizeof(refreshes) / sizeof(refreshes[0]);
+static const int nrefreshes = sizeof(i830refreshes) / sizeof(i830refreshes[0]);
static Bool
Check5fStatus(ScrnInfoPtr pScrn, int func, int ax)
@@ -400,7 +403,7 @@ BitToRefresh(int bits)
for (i = 0; i < nrefreshes; i++)
if (bits & (1 << i))
- return refreshes[i];
+ return i830refreshes[i];
return 0;
}
@@ -538,15 +541,39 @@ vbeDoPanelID(vbeInfoPtr pVbe)
I830InterpretPanelID(pVbe->pInt10->scrnIndex, PanelID_data);
}
+int
+I830GetBestRefresh(ScrnInfoPtr pScrn, int refresh)
+{
+ int i;
+
+ for (i = nrefreshes - 1; i >= 0; i--) {
+ /*
+ * Look for the highest value that the requested (refresh + 2) is
+ * greater than or equal to.
+ */
+ if (i830refreshes[i] <= (refresh + 2))
+ break;
+ }
+ /* i can be 0 if the requested refresh was higher than the max. */
+ if (i == 0) {
+ if (refresh >= i830refreshes[nrefreshes - 1])
+ i = nrefreshes - 1;
+ }
+
+ return i;
+}
static int
SetRefreshRate(ScrnInfoPtr pScrn, int mode, int refresh)
{
- int i;
vbeInfoPtr pVbe = I830PTR(pScrn)->pVbe;
+ int i = I830GetBestRefresh(pScrn, refresh);
DPRINTF(PFX, "SetRefreshRate: mode 0x%x, refresh: %d\n", mode, refresh);
+ DPRINTF(PFX, "Setting refresh rate to %dHz for mode 0x%02x\n",
+ i830refreshes[i], mode & 0xff);
+
/* Only 8-bit mode numbers are supported. */
if (mode & 0x100)
return 0;
@@ -555,25 +582,10 @@ SetRefreshRate(ScrnInfoPtr pScrn, int mode, int refresh)
pVbe->pInt10->ax = 0x5f05;
pVbe->pInt10->bx = mode & 0xff;
- for (i = nrefreshes - 1; i >= 0; i--) {
- /*
- * Look for the highest value that the requested (refresh + 2) is
- * greater than or equal to.
- */
- if (refreshes[i] <= (refresh + 2))
- break;
- }
- /* i can be 0 if the requested refresh was higher than the max. */
- if (i == 0) {
- if (refresh >= refreshes[nrefreshes - 1])
- i = nrefreshes - 1;
- }
- DPRINTF(PFX, "Setting refresh rate to %dHz for mode 0x%02x\n",
- refreshes[i], mode & 0xff);
pVbe->pInt10->cx = 1 << i;
xf86ExecX86int10_wrapper(pVbe->pInt10, pScrn);
if (Check5fStatus(pScrn, 0x5f05, pVbe->pInt10->ax))
- return refreshes[i];
+ return i830refreshes[i];
else
return 0;
}
@@ -2104,7 +2116,8 @@ I830BIOSPreInit(ScrnInfoPtr pScrn, int flags)
xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Clone Monitor Refresh Rate %d\n",
pI830->CloneRefresh);
}
- if (pI830->CloneRefresh < 60 || pI830->CloneRefresh > 120) {
+ /* See above i830refreshes on why 120Hz is commented out */
+ if (pI830->CloneRefresh < 60 || pI830->CloneRefresh > 85 /* 120 */) {
xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Bad Clone Refresh Rate\n");
PreInitCleanup(pScrn);
return FALSE;
diff --git a/src/i830_modes.c b/src/i830_modes.c
index 9b78866c..97ce45a5 100644
--- a/src/i830_modes.c
+++ b/src/i830_modes.c
@@ -60,8 +60,10 @@
#define C_PRIME (((C - J) * K/256.0) + J)
#define M_PRIME (K/256.0 * M)
+extern const int i830refreshes[];
+
static DisplayModePtr
-i830GetGTF (int h_pixels, int v_lines, float freq,
+I830GetGTF (int h_pixels, int v_lines, float freq,
int interlaced, int margins)
{
float h_pixels_rnd;
@@ -90,6 +92,7 @@ i830GetGTF (int h_pixels, int v_lines, float freq,
float h_sync;
float h_front_porch;
float v_odd_front_porch_lines;
+ char modename[20];
DisplayModePtr m;
m = xnfcalloc(sizeof(DisplayModeRec), 1);
@@ -341,6 +344,9 @@ i830GetGTF (int h_pixels, int v_lines, float freq,
m->HSync = h_freq;
m->VRefresh = freq;
+ sprintf(modename, "%dx%d", m->HDisplay,m->VDisplay);
+ m->name = xnfstrdup(modename);
+
return (m);
}
@@ -390,8 +396,16 @@ CheckMode(ScrnInfoPtr pScrn, vbeInfoPtr pVbe, VbeInfoBlock *vbe, int id,
vrefresh >= pScrn->monitor->vrefresh[i].lo; vrefresh -= 1.0f) {
if (vrefresh != (float)0.0f) {
- pMode = i830GetGTF(mode->XResolution, mode->YResolution,
- vrefresh, 0, 0);
+ float best_vrefresh;
+ int int_vrefresh;
+
+ /* Find the best refresh for the Intel chipsets */
+ int_vrefresh = I830GetBestRefresh(pScrn, (int)vrefresh);
+ best_vrefresh = (float)i830refreshes[int_vrefresh];
+
+ /* Now, grab the best mode from the available refresh */
+ pMode = I830GetGTF(mode->XResolution, mode->YResolution,
+ best_vrefresh, 0, 0);
pMode->type = M_T_BUILTIN;
@@ -649,6 +663,7 @@ i830SetModeParameters(ScrnInfoPtr pScrn, vbeInfoPtr pVbe)
data->mode |= (1 << 11);
data->block->RefreshRate = ((double)(data->block->PixelClock) /
(double)(pMode->HTotal * pMode->VTotal)) * 100;
+ data->block->RefreshRate = i830refreshes[I830GetBestRefresh(pScrn, data->block->RefreshRate / 100)] * 100;
#ifdef DEBUG
ErrorF("Video Modeline: ID: 0x%x Name: %s %i %i %i %i - "
" %i %i %i %i %.2f MHz Refresh: %.2f Hz\n",