summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlan Hourihane <alanh@fairlite.demon.co.uk>2005-03-03 18:01:51 +0000
committerAlan Hourihane <alanh@fairlite.demon.co.uk>2005-03-03 18:01:51 +0000
commit49dcbacf7fa7f29d18c18eec7e2f99e859bf4c7e (patch)
tree733133fabd6cdec4dfe45c32a1e251b5e9e2601c
parent7eaf88d00d7539fde68422ae6566f23993aa2633 (diff)
Limit the maximum refresh rate to 85Hz and remove the bogus
100Hz and 120Hz settings as they don't match close enough and are really unsupported.
-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",