diff options
author | Alan Hourihane <alanh@fairlite.demon.co.uk> | 2006-07-27 15:28:42 +0100 |
---|---|---|
committer | Alan Hourihane <alanh@fairlite.demon.co.uk> | 2006-07-27 15:28:42 +0100 |
commit | ac3ad32f667b306e771617d784648f7111743f1a (patch) | |
tree | ee329699d3f40abc1b729287dc9051becf8c5a58 /src | |
parent | e786e2f9f3a4df31702736db6f68a44c9ebba546 (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.c | 4 | ||||
-rw-r--r-- | src/i830_driver.c | 72 | ||||
-rw-r--r-- | src/i830_modes.c | 98 |
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 |