summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorAlan Hourihane <alanh@fairlite.demon.co.uk>2006-07-27 15:28:42 +0100
committerAlan Hourihane <alanh@fairlite.demon.co.uk>2006-07-27 15:28:42 +0100
commitac3ad32f667b306e771617d784648f7111743f1a (patch)
treeee329699d3f40abc1b729287dc9051becf8c5a58 /src
parente786e2f9f3a4df31702736db6f68a44c9ebba546 (diff)
Calculate allowable refresh rates on the private
mode data for each independent screen in mergedfb. Lots of other fixes too.
Diffstat (limited to 'src')
-rw-r--r--src/i830_cursor.c4
-rw-r--r--src/i830_driver.c72
-rw-r--r--src/i830_modes.c98
3 files changed, 128 insertions, 46 deletions
diff --git a/src/i830_cursor.c b/src/i830_cursor.c
index 3786120d..1d7808b6 100644
--- a/src/i830_cursor.c
+++ b/src/i830_cursor.c
@@ -432,8 +432,8 @@ I830SetCursorPositionMerged(ScrnInfoPtr pScrn, int x, int y)
temp2 |= ((x2 & CURSOR_POS_MASK) << CURSOR_X_SHIFT);
temp2 |= ((y2 & CURSOR_POS_MASK) << CURSOR_Y_SHIFT);
- OUTREG(CURSOR_A_POSITION, temp2);
- OUTREG(CURSOR_B_POSITION, temp);
+ OUTREG(CURSOR_A_POSITION, temp);
+ OUTREG(CURSOR_B_POSITION, temp2);
if (pI830->cursorOn) {
if (hide)
diff --git a/src/i830_driver.c b/src/i830_driver.c
index eb851312..d32efa31 100644
--- a/src/i830_driver.c
+++ b/src/i830_driver.c
@@ -742,9 +742,6 @@ I830GenerateModeListFromLargestModes(ScrnInfoPtr pScrn,
* common mode for First and Second (if available). Additionally, and
* regardless if the above, we produce a clone mode consisting of
* the largest common mode (if available) in order to use DGA.
- * - Clone: If the (global) SecondPosition is Clone, we use the
- * largest common mode if available, otherwise the first two modes
- * in each list.
*/
switch(pos) {
@@ -1222,7 +1219,7 @@ I830MergedPointerMoved(int scrnIndex, int x, int y)
pScrn2->frameY1 = pScrn2->frameY0 + CDMPTR.Second->VDisplay - 1;
/* No need to update pScrn1->frame?1, done above */
- if (!pI830->pipe == 0) {
+ if (pI830->pipe == 0) {
OUTREG(DSPABASE, pI830->FrontBuffer.Start + ((pI830->FirstframeY0 * pScrn1->displayWidth + pI830->FirstframeX0) * pI830->cpp));
OUTREG(DSPBBASE, pI830->FrontBuffer.Start + ((pScrn2->frameY0 * pScrn1->displayWidth + pScrn2->frameX0) * pI830->cpp));
} else {
@@ -5150,8 +5147,7 @@ I830BIOSPreInit(ScrnInfoPtr pScrn, int flags)
}
if (pI830->MergedFB) {
- DisplayModePtr old_modes;
- DisplayModePtr cur_mode;
+ DisplayModePtr old_modes, cur_mode;
xf86PruneDriverModes(pI830->pScrn_2);
@@ -5915,12 +5911,18 @@ I830VESASetVBEMode(ScrnInfoPtr pScrn, int mode, VbeCRTCInfoBlock * block)
else
Mon = pI830->MonType2;
+
/* Now recheck refresh operations we can use */
pI830->useExtendedRefresh = FALSE;
pI830->vesa->useDefaultRefresh = FALSE;
- if (Mon != PIPE_CRT)
+ if (Mon != PIPE_CRT) {
+ xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
+ "A non-CRT device is attached to pipe %c.\n"
+ "\tNo refresh rate overrides will be attempted.\n",
+ PIPE_NAME(pI830->pipe));
pI830->vesa->useDefaultRefresh = TRUE;
+ }
mode |= 1 << 11;
if (pI830->vesa->useDefaultRefresh)
@@ -6011,13 +6013,24 @@ I830VESASetMode(ScrnInfoPtr pScrn, DisplayModePtr pMode)
}else {
I830ModePrivatePtr s = (I830ModePrivatePtr)mp->merged.Second->Private;
I830ModePrivatePtr f = (I830ModePrivatePtr)mp->merged.First->Private;
+ int pipe = pI830->pipe; /* save current pipe */
+
SetBIOSPipe(pScrn, !pI830->pipe);
- if (I830VESASetVBEMode(pScrn, (f->vbeData.mode | 1<<15 | 1<<14), f->vbeData.block) == FALSE) {
+
+ pI830->pipe = !pI830->pipe;
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Setting mode on Pipe %s.\n", pI830->pipe ? "B" : "A");
+
+ if (I830VESASetVBEMode(pScrn, (s->vbeData.mode | 1<<15 | 1<<14), s->vbeData.block) == FALSE) {
xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Set VBE Mode failed!\n");
return FALSE;
}
+
+ pI830->pipe = pipe; /* restore current pipe */
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Setting mode on Pipe %s.\n", pI830->pipe ? "B" : "A");
+
SetPipeAccess(pScrn);
- if (I830VESASetVBEMode(pScrn, (s->vbeData.mode | 1<<15 | 1<<14), s->vbeData.block) == FALSE) {
+
+ if (I830VESASetVBEMode(pScrn, (f->vbeData.mode | 1<<15 | 1<<14), f->vbeData.block) == FALSE) {
xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Set VBE Mode failed!\n");
return FALSE;
}
@@ -7170,7 +7183,7 @@ I830BIOSAdjustFrame(int scrnIndex, int x, int y, int flags)
if (pI830->MergedFB) {
I830AdjustFrameMerged(scrnIndex, x, y, flags);
- if (!pI830->pipe == 0) {
+ if (pI830->pipe == 0) {
OUTREG(DSPABASE, pI830->FrontBuffer.Start + ((pI830->FirstframeY0 * pScrn->displayWidth + pI830->FirstframeX0) * pI830->cpp));
OUTREG(DSPBBASE, pI830->FrontBuffer.Start + ((pI830->pScrn_2->frameY0 * pScrn->displayWidth + pI830->pScrn_2->frameX0) * pI830->cpp));
} else {
@@ -7344,21 +7357,29 @@ I830DetectMonitorChange(ScrnInfoPtr pScrn)
/* Re-read EDID */
pDDCModule = xf86LoadSubModule(pScrn, "ddc");
+
+ if (pI830->MergedFB) {
+ SetBIOSPipe(pScrn, !pI830->pipe);
+ monitor = vbeDoEDID(pI830->pVbe, pDDCModule);
+ if ((pI830->pScrn_2->monitor->DDC = monitor) != NULL) {
+ xf86PrintEDID(monitor);
+ xf86SetDDCproperties(pScrn, monitor);
+ }
+ SetPipeAccess(pScrn);
+ }
+
monitor = vbeDoEDID(pI830->pVbe, pDDCModule);
xf86UnloadSubModule(pDDCModule);
if ((pScrn->monitor->DDC = monitor) != NULL) {
xf86PrintEDID(monitor);
xf86SetDDCproperties(pScrn, monitor);
- } else
- /* No DDC, so get out of here, and continue to use the current settings */
- return FALSE;
+ }
- if (!(DDCclock = I830UseDDC(pScrn)))
- return FALSE;
+ DDCclock = I830UseDDC(pScrn);
+ /* Check if DDC exists on the second head, if not don't abort. */
if (pI830->MergedFB)
- if (!(DDCclock2 = I830UseDDC(pScrn)))
- return FALSE;
+ DDCclock2 = I830UseDDC(pI830->pScrn_2);
/* Revalidate the modes */
@@ -7378,7 +7399,7 @@ I830DetectMonitorChange(ScrnInfoPtr pScrn)
return FALSE;
}
- if (pI830->MergedFB) {
+ if (pI830->MergedFB && DDCclock2 > 0) {
SetBIOSPipe(pScrn, !pI830->pipe);
xf86DrvMsg(pScrn->scrnIndex, X_INFO,
"Retrieving mode pool for second head.\n");
@@ -7394,7 +7415,7 @@ I830DetectMonitorChange(ScrnInfoPtr pScrn)
}
VBESetModeNames(pScrn->modePool);
- if (pI830->MergedFB)
+ if (pI830->MergedFB && DDCclock2 > 0)
VBESetModeNames(pI830->pScrn_2->modePool);
if (pScrn->videoRam > (pI830->vbeInfo->TotalMemory * 64))
@@ -7409,7 +7430,7 @@ I830DetectMonitorChange(ScrnInfoPtr pScrn)
pScrn->display->virtualY,
memsize, LOOKUP_BEST_REFRESH);
- if (pI830->MergedFB) {
+ if (pI830->MergedFB && DDCclock2 > 0) {
VBEValidateModes(pI830->pScrn_2, pI830->pScrn_2->monitor->Modes,
pI830->pScrn_2->display->modes, NULL,
NULL, 0, MAX_DISPLAY_PITCH, 1,
@@ -7450,7 +7471,7 @@ I830DetectMonitorChange(ScrnInfoPtr pScrn)
}
/* Only use this if we've got DDC available */
- if (DDCclock2 > 0) {
+ if (pI830->MergedFB && DDCclock2 > 0) {
p = pI830->pScrn_2->modes;
if (p == NULL)
return FALSE;
@@ -7484,10 +7505,7 @@ I830DetectMonitorChange(ScrnInfoPtr pScrn)
xf86PruneDriverModes(pScrn);
- if (pI830->MergedFB) {
- DisplayModePtr old_modes;
- DisplayModePtr cur_mode;
-
+ if (pI830->MergedFB && DDCclock2 > 0) {
xf86PruneDriverModes(pI830->pScrn_2);
if (pI830->pScrn_2->modes == NULL) {
@@ -7495,6 +7513,10 @@ I830DetectMonitorChange(ScrnInfoPtr pScrn)
PreInitCleanup(pScrn);
return FALSE;
}
+ }
+
+ if (pI830->MergedFB) {
+ DisplayModePtr old_modes, cur_mode;
old_modes = pScrn->modes;
cur_mode = pScrn->currentMode;
diff --git a/src/i830_modes.c b/src/i830_modes.c
index 7d71396c..7d145198 100644
--- a/src/i830_modes.c
+++ b/src/i830_modes.c
@@ -674,23 +674,31 @@ I830GetModePool(ScrnInfoPtr pScrn, vbeInfoPtr pVbe, VbeInfoBlock *vbe)
void
I830SetModeParameters(ScrnInfoPtr pScrn, vbeInfoPtr pVbe)
{
- DisplayModePtr pMode;
+ I830Ptr pI830 = I830PTR(pScrn);
+ DisplayModePtr pMode = pScrn->modes;
+ DisplayModePtr ppMode = pScrn->modes;
I830ModePrivatePtr mp = NULL;
- pMode = pScrn->modes;
do {
int clock;
+
+ mp = (I830ModePrivatePtr) pMode->Private;
+ if (pI830->MergedFB) {
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO, "%s\n", pScrn->monitor->id);
+ ppMode = (DisplayModePtr) mp->merged.First;
+ mp = (I830ModePrivatePtr) mp->merged.First->Private;
+ }
mp->vbeData.block = xcalloc(sizeof(VbeCRTCInfoBlock), 1);
- mp->vbeData.block->HorizontalTotal = pMode->HTotal;
- mp->vbeData.block->HorizontalSyncStart = pMode->HSyncStart;
- mp->vbeData.block->HorizontalSyncEnd = pMode->HSyncEnd;
- mp->vbeData.block->VerticalTotal = pMode->VTotal;
- mp->vbeData.block->VerticalSyncStart = pMode->VSyncStart;
- mp->vbeData.block->VerticalSyncEnd = pMode->VSyncEnd;
- mp->vbeData.block->Flags = ((pMode->Flags & V_NHSYNC) ? CRTC_NHSYNC : 0) |
- ((pMode->Flags & V_NVSYNC) ? CRTC_NVSYNC : 0);
- mp->vbeData.block->PixelClock = pMode->Clock * 1000;
+ mp->vbeData.block->HorizontalTotal = ppMode->HTotal;
+ mp->vbeData.block->HorizontalSyncStart = ppMode->HSyncStart;
+ mp->vbeData.block->HorizontalSyncEnd = ppMode->HSyncEnd;
+ mp->vbeData.block->VerticalTotal = ppMode->VTotal;
+ mp->vbeData.block->VerticalSyncStart = ppMode->VSyncStart;
+ mp->vbeData.block->VerticalSyncEnd = ppMode->VSyncEnd;
+ mp->vbeData.block->Flags = ((ppMode->Flags & V_NHSYNC) ? CRTC_NHSYNC : 0) |
+ ((ppMode->Flags & V_NVSYNC) ? CRTC_NVSYNC : 0);
+ mp->vbeData.block->PixelClock = ppMode->Clock * 1000;
/* XXX May not have this. */
clock = VBEGetPixelClock(pVbe, mp->vbeData.mode, mp->vbeData.block->PixelClock);
if (clock)
@@ -701,26 +709,78 @@ I830SetModeParameters(ScrnInfoPtr pScrn, vbeInfoPtr pVbe)
(double)clock / 1000000.0);
#endif
mp->vbeData.mode |= (1 << 11);
- if (pMode->VRefresh != 0) {
- mp->vbeData.block->RefreshRate = pMode->VRefresh * 100;
+ if (ppMode->VRefresh != 0) {
+ mp->vbeData.block->RefreshRate = ppMode->VRefresh * 100;
} else {
mp->vbeData.block->RefreshRate = (int)(((double)(mp->vbeData.block->PixelClock)/
- (double)(pMode->HTotal * pMode->VTotal)) * 100);
+ (double)(ppMode->HTotal * ppMode->VTotal)) * 100);
}
xf86DrvMsg(pScrn->scrnIndex, X_INFO,
"Attempting to use %2.2fHz refresh for mode \"%s\" (%x)\n",
- (float)(((double)(mp->vbeData.block->PixelClock) / (double)(pMode->HTotal * pMode->VTotal))), pMode->name, mp->vbeData.mode);
+ (float)(((double)(mp->vbeData.block->PixelClock) / (double)(ppMode->HTotal * ppMode->VTotal))), ppMode->name, mp->vbeData.mode);
#ifdef DEBUG
ErrorF("Video Modeline: ID: 0x%x Name: %s %i %i %i %i - "
" %i %i %i %i %.2f MHz Refresh: %.2f Hz\n",
- mp->vbeData.mode, pMode->name, pMode->HDisplay, pMode->HSyncStart,
- pMode->HSyncEnd, pMode->HTotal, pMode->VDisplay,
- pMode->VSyncStart,pMode->VSyncEnd,pMode->VTotal,
+ mp->vbeData.mode, ppMode->name, ppMode->HDisplay, ppMode->HSyncStart,
+ ppMode->HSyncEnd, ppMode->HTotal, ppMode->VDisplay,
+ ppMode->VSyncStart,ppMode->VSyncEnd,ppMode->VTotal,
(double)mp->vbeData.block->PixelClock/1000000.0,
(double)mp->vbeData.block->RefreshRate/100);
#endif
- pMode = pMode->next;
+ pMode = ppMode = pMode->next;
} while (pMode != pScrn->modes);
+
+ if (pI830->MergedFB) {
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO, "%s\n", pI830->pScrn_2->monitor->id);
+ pMode = pScrn->modes;
+ do {
+ int clock;
+
+ mp = (I830ModePrivatePtr) pMode->Private;
+ ppMode = (DisplayModePtr) mp->merged.Second;
+ mp = (I830ModePrivatePtr) mp->merged.Second->Private;
+
+ mp->vbeData.block = xcalloc(sizeof(VbeCRTCInfoBlock), 1);
+ mp->vbeData.block->HorizontalTotal = ppMode->HTotal;
+ mp->vbeData.block->HorizontalSyncStart = ppMode->HSyncStart;
+ mp->vbeData.block->HorizontalSyncEnd = ppMode->HSyncEnd;
+ mp->vbeData.block->VerticalTotal = ppMode->VTotal;
+ mp->vbeData.block->VerticalSyncStart = ppMode->VSyncStart;
+ mp->vbeData.block->VerticalSyncEnd = ppMode->VSyncEnd;
+ mp->vbeData.block->Flags = ((ppMode->Flags & V_NHSYNC) ? CRTC_NHSYNC : 0) |
+ ((ppMode->Flags & V_NVSYNC) ? CRTC_NVSYNC : 0);
+ mp->vbeData.block->PixelClock = ppMode->Clock * 1000;
+ /* XXX May not have this. */
+ clock = VBEGetPixelClock(pVbe, mp->vbeData.mode, mp->vbeData.block->PixelClock);
+ if (clock)
+ mp->vbeData.block->PixelClock = clock;
+#ifdef DEBUG
+ ErrorF("Setting clock %.2fMHz, closest is %.2fMHz\n",
+ (double)mp->vbeData.block->PixelClock / 1000000.0,
+ (double)clock / 1000000.0);
+#endif
+ mp->vbeData.mode |= (1 << 11);
+ if (ppMode->VRefresh != 0) {
+ mp->vbeData.block->RefreshRate = ppMode->VRefresh * 100;
+ } else {
+ mp->vbeData.block->RefreshRate = (int)(((double)(mp->vbeData.block->PixelClock)/
+ (double)(ppMode->HTotal * ppMode->VTotal)) * 100);
+ }
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+ "Attempting to use %2.2fHz refresh for mode \"%s\" (%x)\n",
+ (float)(((double)(mp->vbeData.block->PixelClock) / (double)(ppMode->HTotal * ppMode->VTotal))), ppMode->name, mp->vbeData.mode);
+#ifdef DEBUG
+ ErrorF("Video Modeline: ID: 0x%x Name: %s %i %i %i %i - "
+ " %i %i %i %i %.2f MHz Refresh: %.2f Hz\n",
+ mp->vbeData.mode, ppMode->name, ppMode->HDisplay, ppMode->HSyncStart,
+ ppMode->HSyncEnd, ppMode->HTotal, ppMode->VDisplay,
+ ppMode->VSyncStart,ppMode->VSyncEnd,ppMode->VTotal,
+ (double)mp->vbeData.block->PixelClock/1000000.0,
+ (double)mp->vbeData.block->RefreshRate/100);
+#endif
+ pMode = ppMode = pMode->next;
+ } while (pMode != pScrn->modes);
+ }
}
void