diff options
author | Eric Anholt <eric@anholt.net> | 2007-03-04 21:49:00 -0800 |
---|---|---|
committer | Eric Anholt <eric@anholt.net> | 2007-03-04 22:06:32 -0800 |
commit | 015027034e970f1e3bb6ab239f7e0119235e404f (patch) | |
tree | 2bcbec130928ea27fdbc2eebcb2d60c66b785b13 /src/i830_driver.c | |
parent | 9a5106401a65c90df32cb71987fca7126dc22e81 (diff) | |
parent | bc20b54c34088356a277beaebcc90bb4a7063e19 (diff) |
Merge branch 'modesetting'
Conflicts:
configure.ac
src/i830_driver.c
src/i830_modes.c
src/i830_video.c
Diffstat (limited to 'src/i830_driver.c')
-rw-r--r-- | src/i830_driver.c | 8078 |
1 files changed, 1129 insertions, 6949 deletions
diff --git a/src/i830_driver.c b/src/i830_driver.c index f7c700a7..ac4e38c1 100644 --- a/src/i830_driver.c +++ b/src/i830_driver.c @@ -169,6 +169,7 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. #include <stdio.h> #include <unistd.h> #include <stdlib.h> +#include <stdio.h> #include "xf86.h" #include "xf86_OSproc.h" @@ -190,10 +191,9 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. #include "vbe.h" #include "shadow.h" #include "i830.h" - -#ifdef HAS_MTRR_SUPPORT -#include <asm/mtrr.h> -#endif +#include "i830_display.h" +#include "i830_debug.h" +#include "i830_bios.h" #ifdef XF86DRI #include "dri.h" @@ -201,12 +201,24 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. #include <errno.h> #endif +#ifdef I830_USE_EXA +const char *I830exaSymbols[] = { + "exaGetVersion", + "exaDriverInit", + "exaDriverFini", + "exaOffscreenAlloc", + "exaOffscreenFree", + "exaWaitSync", + NULL +}; +#endif + #define BIT(x) (1 << (x)) #define MAX(a,b) ((a) > (b) ? (a) : (b)) #define NB_OF(x) (sizeof (x) / sizeof (*x)) /* *INDENT-OFF* */ -static SymTabRec I830BIOSChipsets[] = { +static SymTabRec I830Chipsets[] = { {PCI_CHIP_I830_M, "i830"}, {PCI_CHIP_845_G, "845G"}, {PCI_CHIP_I855_GM, "852GM/855GM"}, @@ -223,7 +235,7 @@ static SymTabRec I830BIOSChipsets[] = { {-1, NULL} }; -static PciChipsets I830BIOSPciChipsets[] = { +static PciChipsets I830PciChipsets[] = { {PCI_CHIP_I830_M, PCI_CHIP_I830_M, RES_SHARED_VGA}, {PCI_CHIP_845_G, PCI_CHIP_845_G, RES_SHARED_VGA}, {PCI_CHIP_I855_GM, PCI_CHIP_I855_GM, RES_SHARED_VGA}, @@ -247,6 +259,9 @@ static PciChipsets I830BIOSPciChipsets[] = { */ typedef enum { +#if defined(I830_USE_XAA) && defined(I830_USE_EXA) + OPTION_ACCELMETHOD, +#endif OPTION_NOACCEL, OPTION_SW_CURSOR, OPTION_CACHE_LINES, @@ -255,30 +270,16 @@ typedef enum { OPTION_XVIDEO, OPTION_VIDEO_KEY, OPTION_COLOR_KEY, - OPTION_VBE_RESTORE, - OPTION_DISPLAY_INFO, - OPTION_DEVICE_PRESENCE, - OPTION_MONITOR_LAYOUT, - OPTION_CLONE, - OPTION_CLONE_REFRESH, OPTION_CHECKDEVICES, - OPTION_FIXEDPIPE, - OPTION_ROTATE, OPTION_LINEARALLOC, - OPTION_MERGEDFB, - OPTION_METAMODES, - OPTION_SECONDHSYNC, - OPTION_SECONDVREFRESH, - OPTION_SECONDPOSITION, - OPTION_SECONDISSCRN0, - OPTION_MERGEDFBNONRECT, - OPTION_MERGEDFBMOUSER, - OPTION_INTELXINERAMA, OPTION_INTELTEXPOOL, OPTION_INTELMMSIZE } I830Opts; -static OptionInfoRec I830BIOSOptions[] = { +static OptionInfoRec I830Options[] = { +#if defined(I830_USE_XAA) && defined(I830_USE_EXA) + {OPTION_ACCELMETHOD, "AccelMethod", OPTV_ANYSTR, {0}, FALSE}, +#endif {OPTION_NOACCEL, "NoAccel", OPTV_BOOLEAN, {0}, FALSE}, {OPTION_SW_CURSOR, "SWcursor", OPTV_BOOLEAN, {0}, FALSE}, {OPTION_CACHE_LINES, "CacheLines", OPTV_INTEGER, {0}, FALSE}, @@ -287,63 +288,33 @@ static OptionInfoRec I830BIOSOptions[] = { {OPTION_XVIDEO, "XVideo", OPTV_BOOLEAN, {0}, TRUE}, {OPTION_COLOR_KEY, "ColorKey", OPTV_INTEGER, {0}, FALSE}, {OPTION_VIDEO_KEY, "VideoKey", OPTV_INTEGER, {0}, FALSE}, - {OPTION_VBE_RESTORE, "VBERestore", OPTV_BOOLEAN, {0}, FALSE}, - {OPTION_DISPLAY_INFO,"DisplayInfo", OPTV_BOOLEAN, {0}, FALSE}, - {OPTION_DEVICE_PRESENCE,"DevicePresence",OPTV_BOOLEAN,{0}, FALSE}, - {OPTION_MONITOR_LAYOUT, "MonitorLayout", OPTV_ANYSTR,{0}, FALSE}, - {OPTION_CLONE, "Clone", OPTV_BOOLEAN, {0}, FALSE}, - {OPTION_CLONE_REFRESH,"CloneRefresh",OPTV_INTEGER, {0}, FALSE}, {OPTION_CHECKDEVICES, "CheckDevices",OPTV_BOOLEAN, {0}, FALSE}, - {OPTION_FIXEDPIPE, "FixedPipe", OPTV_ANYSTR, {0}, FALSE}, - {OPTION_ROTATE, "Rotate", OPTV_ANYSTR, {0}, FALSE}, {OPTION_LINEARALLOC, "LinearAlloc", OPTV_INTEGER, {0}, FALSE}, - {OPTION_MERGEDFB, "MergedFB", OPTV_BOOLEAN, {0}, FALSE}, - {OPTION_METAMODES, "MetaModes", OPTV_STRING, {0}, FALSE}, - {OPTION_SECONDHSYNC, "SecondMonitorHorizSync",OPTV_STRING, {0}, FALSE }, - {OPTION_SECONDVREFRESH,"SecondMonitorVertRefresh",OPTV_STRING,{0}, FALSE }, - {OPTION_SECONDPOSITION,"SecondPosition",OPTV_STRING, {0}, FALSE }, - {OPTION_SECONDISSCRN0,"MergedXineramaSecondIsScreen0", OPTV_BOOLEAN, {0}, FALSE }, - {OPTION_MERGEDFBNONRECT,"MergedNonRectangular",OPTV_BOOLEAN, {0}, FALSE}, - {OPTION_MERGEDFBMOUSER,"MergedMouseRestriction",OPTV_BOOLEAN, {0}, FALSE}, - {OPTION_INTELXINERAMA,"MergedXinerama",OPTV_BOOLEAN, {0}, TRUE}, {OPTION_INTELTEXPOOL,"Legacy3D", OPTV_BOOLEAN, {0}, FALSE}, {OPTION_INTELMMSIZE, "AperTexSize", OPTV_INTEGER, {0}, FALSE}, {-1, NULL, OPTV_NONE, {0}, FALSE} }; /* *INDENT-ON* */ -static void I830DisplayPowerManagementSet(ScrnInfoPtr pScrn, - int PowerManagementMode, int flags); -static void I830AdjustFrame(int scrnIndex, int x, int y, int flags); -static Bool I830BIOSCloseScreen(int scrnIndex, ScreenPtr pScreen); -static Bool I830BIOSSaveScreen(ScreenPtr pScreen, int unblack); -static Bool I830BIOSEnterVT(int scrnIndex, int flags); -static Bool I830VESASetVBEMode(ScrnInfoPtr pScrn, int mode, - VbeCRTCInfoBlock *block); -static CARD32 I830CheckDevicesTimer(OsTimerPtr timer, CARD32 now, pointer arg); -static Bool SetPipeAccess(ScrnInfoPtr pScrn); - -extern int I830EntityIndex; - -static Bool I830noPanoramiXExtension = TRUE; -static int I830XineramaNumScreens = 0; -static I830XineramaData *I830XineramadataPtr = NULL; -static int I830XineramaGeneration; +const char *i830_output_type_names[] = { + "Unused", + "Analog", + "DVO", + "SDVO", + "LVDS", + "TVOUT", +}; -static int I830ProcXineramaQueryVersion(ClientPtr client); -static int I830ProcXineramaGetState(ClientPtr client); -static int I830ProcXineramaGetScreenCount(ClientPtr client); -static int I830ProcXineramaGetScreenSize(ClientPtr client); -static int I830ProcXineramaIsActive(ClientPtr client); -static int I830ProcXineramaQueryScreens(ClientPtr client); -static int I830SProcXineramaDispatch(ClientPtr client); +static void i830AdjustFrame(int scrnIndex, int x, int y, int flags); +static Bool I830CloseScreen(int scrnIndex, ScreenPtr pScreen); +static Bool I830EnterVT(int scrnIndex, int flags); +static CARD32 I830CheckDevicesTimer(OsTimerPtr timer, CARD32 now, pointer arg); +static Bool SaveHWState(ScrnInfoPtr pScrn); +static Bool RestoreHWState(ScrnInfoPtr pScrn); /* temporary */ extern void xf86SetCursor(ScreenPtr pScreen, CursorPtr pCurs, int x, int y); -static const char *SecondMonitorName = "MergedFBMonitor"; - - #ifdef I830DEBUG void I830DPRINTF_stub(const char *filename, int line, const char *function, @@ -368,37 +339,34 @@ I830DPRINTF_stub(const char *filename, int line, const char *function, } #endif /* #ifdef I830DEBUG */ -/* XXX Check if this is still needed. */ +/* Export I830 options to i830 driver where necessary */ const OptionInfoRec * -I830BIOSAvailableOptions(int chipid, int busid) +I830AvailableOptions(int chipid, int busid) { int i; - for (i = 0; I830BIOSPciChipsets[i].PCIid > 0; i++) { - if (chipid == I830BIOSPciChipsets[i].PCIid) - return I830BIOSOptions; + for (i = 0; I830PciChipsets[i].PCIid > 0; i++) { + if (chipid == I830PciChipsets[i].PCIid) + return I830Options; } return NULL; } static Bool -I830BIOSGetRec(ScrnInfoPtr pScrn) +I830GetRec(ScrnInfoPtr pScrn) { I830Ptr pI830; if (pScrn->driverPrivate) return TRUE; pI830 = pScrn->driverPrivate = xnfcalloc(sizeof(I830Rec), 1); - pI830->vesa = xnfcalloc(sizeof(VESARec), 1); return TRUE; } static void -I830BIOSFreeRec(ScrnInfoPtr pScrn) +I830FreeRec(ScrnInfoPtr pScrn) { I830Ptr pI830; - VESAPtr pVesa; - DisplayModePtr mode; if (!pScrn) return; @@ -406,1680 +374,13 @@ I830BIOSFreeRec(ScrnInfoPtr pScrn) return; pI830 = I830PTR(pScrn); - mode = pScrn->modes; - - if (mode) { - do { - if (mode->Private) { - I830ModePrivatePtr mp = (I830ModePrivatePtr) mode->Private; - - xfree(mp); - mode->Private = NULL; - } - mode = mode->next; - } while (mode && mode != pScrn->modes); - } - - if (I830IsPrimary(pScrn)) { - if (pI830->vbeInfo) - VBEFreeVBEInfo(pI830->vbeInfo); - if (pI830->pVbe) - vbeFree(pI830->pVbe); - } - - pVesa = pI830->vesa; - if (pVesa->savedPal) - xfree(pVesa->savedPal); - xfree(pVesa); xfree(pScrn->driverPrivate); pScrn->driverPrivate = NULL; } -static Bool -InRegion(int x, int y, region r) -{ - return (r.x0 <= x) && (x <= r.x1) && (r.y0 <= y) && (y <= r.y1); -} - -static int -I830StrToRanges(range *r, char *s, int max) -{ - float num = 0.0; - int rangenum = 0; - Bool gotdash = FALSE; - Bool nextdash = FALSE; - char *strnum = NULL; - do { - switch(*s) { - case '0': - case '1': - case '2': - case '3': - case '4': - case '5': - case '6': - case '7': - case '8': - case '9': - case '.': - if(strnum == NULL) { - strnum = s; - gotdash = nextdash; - nextdash = FALSE; - } - break; - case '-': - case ' ': - case 0: - if(strnum == NULL) break; - sscanf(strnum, "%f", &num); - strnum = NULL; - if(gotdash) { - r[rangenum - 1].hi = num; - } else { - r[rangenum].lo = num; - r[rangenum].hi = num; - rangenum++; - } - if(*s == '-') nextdash = (rangenum != 0); - else if(rangenum >= max) return rangenum; - break; - default: - return 0; - } - - } while(*(s++) != 0); - - return rangenum; -} - -/* Calculate the vertical refresh rate from a mode */ -static float -I830CalcVRate(DisplayModePtr mode) -{ - float hsync, refresh = 0; - - if(mode->HSync > 0.0) - hsync = mode->HSync; - else if(mode->HTotal > 0) - hsync = (float)mode->Clock / (float)mode->HTotal; - else - hsync = 0.0; - - if(mode->VTotal > 0) - refresh = hsync * 1000.0 / mode->VTotal; - - if(mode->Flags & V_INTERLACE) - refresh *= 2.0; - - if(mode->Flags & V_DBLSCAN) - refresh /= 2.0; - - if(mode->VScan > 1) - refresh /= mode->VScan; - - if(mode->VRefresh > 0.0) - refresh = mode->VRefresh; - - if(hsync == 0.0 || refresh == 0.0) return 0.0; - - return refresh; -} - -/* Copy and link two modes (i, j) for mergedfb mode - * (Code base taken from mga driver) - * - * - Copy mode i, merge j to copy of i, link the result to dest - * - Link i and j in private record. - * - If dest is NULL, return value is copy of i linked to itself. - * - For mergedfb auto-config, we only check the dimension - * against virtualX/Y, if they were user-provided. - * - No special treatment required for CRTxxOffs. - * - Provide fake dotclock in order to distinguish between similar - * looking MetaModes (for RandR and VidMode extensions) - * - Set unique VRefresh of dest mode for RandR - */ -static DisplayModePtr -I830CopyModeNLink(ScrnInfoPtr pScrn, DisplayModePtr dest, - DisplayModePtr i, DisplayModePtr j, - int pos) -{ - DisplayModePtr mode; - int dx = 0,dy = 0; - - if(!((mode = xalloc(sizeof(DisplayModeRec))))) return dest; - memcpy(mode, i, sizeof(DisplayModeRec)); - if(!((mode->Private = xalloc(sizeof(I830ModePrivateRec))))) { - xfree(mode); - return dest; - } - ((I830ModePrivatePtr)mode->Private)->merged.First = i; - ((I830ModePrivatePtr)mode->Private)->merged.Second = j; - ((I830ModePrivatePtr)mode->Private)->merged.SecondPosition = pos; - if (((I830ModePrivatePtr)i->Private)->vbeData.mode > 0x30) { - ((I830ModePrivatePtr)mode->Private)->vbeData.mode = ((I830ModePrivatePtr)i->Private)->vbeData.mode; - ((I830ModePrivatePtr)mode->Private)->vbeData.data = ((I830ModePrivatePtr)i->Private)->vbeData.data; - } else { - ((I830ModePrivatePtr)mode->Private)->vbeData.mode = ((I830ModePrivatePtr)j->Private)->vbeData.mode; - ((I830ModePrivatePtr)mode->Private)->vbeData.data = ((I830ModePrivatePtr)j->Private)->vbeData.data; - } - mode->PrivSize = sizeof(I830ModePrivateRec); - - switch(pos) { - case PosLeftOf: - case PosRightOf: - if(!(pScrn->display->virtualX)) { - dx = i->HDisplay + j->HDisplay; - } else { - dx = min(pScrn->virtualX, i->HDisplay + j->HDisplay); - } - dx -= mode->HDisplay; - if(!(pScrn->display->virtualY)) { - dy = max(i->VDisplay, j->VDisplay); - } else { - dy = min(pScrn->virtualY, max(i->VDisplay, j->VDisplay)); - } - dy -= mode->VDisplay; - break; - case PosAbove: - case PosBelow: - if(!(pScrn->display->virtualY)) { - dy = i->VDisplay + j->VDisplay; - } else { - dy = min(pScrn->virtualY, i->VDisplay + j->VDisplay); - } - dy -= mode->VDisplay; - if(!(pScrn->display->virtualX)) { - dx = max(i->HDisplay, j->HDisplay); - } else { - dx = min(pScrn->virtualX, max(i->HDisplay, j->HDisplay)); - } - dx -= mode->HDisplay; - break; - } - mode->HDisplay += dx; - mode->HSyncStart += dx; - mode->HSyncEnd += dx; - mode->HTotal += dx; - mode->VDisplay += dy; - mode->VSyncStart += dy; - mode->VSyncEnd += dy; - mode->VTotal += dy; - - mode->type = M_T_DEFAULT; - - /* Set up as user defined (ie fake that the mode has been named in the - * Modes-list in the screen section; corrects cycling with CTRL-ALT-[-+] - * when source mode has not been listed there.) - */ - mode->type |= M_T_USERDEF; - - /* Set the VRefresh field (in order to make RandR use it for the rates). We - * simply set this to the refresh rate for the First mode (since Second will - * mostly be LCD or TV anyway). - */ - mode->VRefresh = I830CalcVRate(i); - - if( ((mode->HDisplay * ((pScrn->bitsPerPixel + 7) / 8) * mode->VDisplay) > (pScrn->videoRam * 1024)) || - (mode->HDisplay > 4088) || - (mode->VDisplay > 4096) ) { - - xf86DrvMsg(pScrn->scrnIndex, X_ERROR, - "Skipped \"%s\" (%dx%d), not enough video RAM or beyond hardware specs\n", - mode->name, mode->HDisplay, mode->VDisplay); - xfree(mode->Private); - xfree(mode); - - return dest; - } - - /* Now see if the resulting mode would be discarded as a "size" by the - * RandR extension, and increase its clock by 1000 in case it does. - */ - if(dest) { - DisplayModePtr t = dest; - do { - if((t->HDisplay == mode->HDisplay) && - (t->VDisplay == mode->VDisplay) && - ((int)(t->VRefresh + .5) == (int)(mode->VRefresh + .5))) { - mode->VRefresh += 1000.0; - } - t = t->next; - } while((t) && (t != dest)); - } - - /* Provide a fake but unique DotClock in order to trick the vidmode - * extension to allow selecting among a number of modes whose merged result - * looks identical but consists of different modes for First and Second - */ - mode->Clock = (int)(mode->VRefresh * 1000.0); - - xf86DrvMsg(pScrn->scrnIndex, X_INFO, - "Merged \"%s\" (%dx%d) and \"%s\" (%dx%d) to %dx%d (%d)\n", - i->name, i->HDisplay, i->VDisplay, j->name, j->HDisplay, j->VDisplay, - mode->HDisplay, mode->VDisplay, (int)mode->VRefresh); - - mode->next = mode; - mode->prev = mode; - - if(dest) { - mode->next = dest->next; /* Insert node after "dest" */ - dest->next->prev = mode; - mode->prev = dest; - dest->next = mode; - } - - return mode; -} - -/* Helper function to find a mode from a given name - * (Code base taken from mga driver) - */ -static DisplayModePtr -I830GetModeFromName(char* str, DisplayModePtr i) -{ - DisplayModePtr c = i; - if(!i) return NULL; - do { - if(strcmp(str, c->name) == 0) return c; - c = c->next; - } while(c != i); - return NULL; -} - -static DisplayModePtr -I830FindWidestTallestMode(DisplayModePtr i, Bool tallest) -{ - DisplayModePtr c = i, d = NULL; - int max = 0; - if(!i) return NULL; - do { - if(tallest) { - if(c->VDisplay > max) { - max = c->VDisplay; - d = c; - } - } else { - if(c->HDisplay > max) { - max = c->HDisplay; - d = c; - } - } - c = c->next; - } while(c != i); - return d; -} - -static void -I830FindWidestTallestCommonMode(DisplayModePtr i, DisplayModePtr j, Bool tallest, - DisplayModePtr *a, DisplayModePtr *b) -{ - DisplayModePtr c = i, d; - int max = 0; - Bool foundone; - - (*a) = (*b) = NULL; - - if(!i || !j) return; - - do { - d = j; - foundone = FALSE; - do { - if( (c->HDisplay == d->HDisplay) && - (c->VDisplay == d->VDisplay) ) { - foundone = TRUE; - break; - } - d = d->next; - } while(d != j); - if(foundone) { - if(tallest) { - if(c->VDisplay > max) { - max = c->VDisplay; - (*a) = c; - (*b) = d; - } - } else { - if(c->HDisplay > max) { - max = c->HDisplay; - (*a) = c; - (*b) = d; - } - } - } - c = c->next; - } while(c != i); -} - -static DisplayModePtr -I830GenerateModeListFromLargestModes(ScrnInfoPtr pScrn, - DisplayModePtr i, DisplayModePtr j, - int pos) -{ - I830Ptr pI830 = I830PTR(pScrn); - DisplayModePtr mode1 = NULL; - DisplayModePtr mode2 = NULL; - DisplayModePtr mode3 = NULL; - DisplayModePtr mode4 = NULL; - DisplayModePtr result = NULL; - - /* Now build a default list of MetaModes. - * - Non-clone: If the user enabled NonRectangular, we use the - * largest mode for each First and Second. If not, we use the largest - * 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. - */ - - switch(pos) { - case PosLeftOf: - case PosRightOf: - mode1 = I830FindWidestTallestMode(i, FALSE); - mode2 = I830FindWidestTallestMode(j, FALSE); - I830FindWidestTallestCommonMode(i, j, FALSE, &mode3, &mode4); - break; - case PosAbove: - case PosBelow: - mode1 = I830FindWidestTallestMode(i, TRUE); - mode2 = I830FindWidestTallestMode(j, TRUE); - I830FindWidestTallestCommonMode(i, j, TRUE, &mode3, &mode4); - break; - } - - if(mode3 && mode4 && !pI830->NonRect) { - mode1 = mode3; - mode2 = mode2; - } - - if(mode1 && mode2) { - result = I830CopyModeNLink(pScrn, result, mode1, mode2, pos); - } - - return result; -} - -/* Generate the merged-fb mode modelist - * (Taken from mga driver) - */ -static DisplayModePtr -I830GenerateModeListFromMetaModes(ScrnInfoPtr pScrn, char* str, - DisplayModePtr i, DisplayModePtr j, - int pos) -{ - char* strmode = str; - char modename[256]; - Bool gotdash = FALSE; - char gotsep = 0; - int p; - DisplayModePtr mode1 = NULL; - DisplayModePtr mode2 = NULL; - DisplayModePtr result = NULL; - int myslen; - - do { - switch(*str) { - case 0: - case '-': - case '+': - case ' ': - case ',': - case ';': - if(strmode != str) { - - myslen = str - strmode; - if(myslen > 255) myslen = 255; - strncpy(modename, strmode, myslen); - modename[myslen] = 0; - - if(gotdash) { - if(mode1 == NULL) { - xf86DrvMsg(pScrn->scrnIndex, X_ERROR, - "Error parsing MetaModes parameter\n"); - return NULL; - } - mode2 = I830GetModeFromName(modename, j); - if(!mode2) { - xf86DrvMsg(pScrn->scrnIndex, X_WARNING, - "Mode \"%s\" is not a supported mode for Second\n", modename); - xf86DrvMsg(pScrn->scrnIndex, X_WARNING, - "\t(Skipping metamode \"%s%c%s\")\n", mode1->name, gotsep, modename); - mode1 = NULL; - gotsep = 0; - } - } else { - mode1 = I830GetModeFromName(modename, i); - if(!mode1) { - char* tmps = str; - xf86DrvMsg(pScrn->scrnIndex, X_WARNING, - "Mode \"%s\" is not a supported mode for First\n", modename); - while(*tmps == ' ' || *tmps == ';') tmps++; - /* skip the next mode */ - if(*tmps == '-' || *tmps == '+' || *tmps == ',') { - tmps++; - /* skip spaces */ - while(*tmps == ' ' || *tmps == ';') tmps++; - /* skip modename */ - while(*tmps && *tmps != ' ' && *tmps != ';' && *tmps != '-' && *tmps != '+' && *tmps != ',') tmps++; - myslen = tmps - strmode; - if(myslen > 255) myslen = 255; - strncpy(modename,strmode,myslen); - modename[myslen] = 0; - str = tmps - 1; - } - xf86DrvMsg(pScrn->scrnIndex, X_WARNING, - "\t(Skipping metamode \"%s\")\n", modename); - mode1 = NULL; - gotsep = 0; - } - } - gotdash = FALSE; - } - strmode = str + 1; - gotdash |= (*str == '-' || *str == '+' || *str == ','); - if (*str == '-' || *str == '+' || *str == ',') - gotsep = *str; - - if(*str != 0) break; - /* Fall through otherwise */ - - default: - if(!gotdash && mode1) { - p = pos ; - if(!mode2) { - xf86DrvMsg(pScrn->scrnIndex, X_WARNING, - "Mode \"%s\" is not a supported mode for Second\n", mode1->name); - xf86DrvMsg(pScrn->scrnIndex, X_WARNING, - "\t(Skipping metamode \"%s\")\n", modename); - mode1 = NULL; - } else { - result = I830CopyModeNLink(pScrn, result, mode1, mode2, p); - mode1 = NULL; - mode2 = NULL; - } - gotsep = 0; - } - break; - - } - - } while(*(str++) != 0); - - return result; -} - -static DisplayModePtr -I830GenerateModeList(ScrnInfoPtr pScrn, char* str, - DisplayModePtr i, DisplayModePtr j, - int pos) -{ - I830Ptr pI830 = I830PTR(pScrn); - - if(str != NULL) { - return(I830GenerateModeListFromMetaModes(pScrn, str, i, j, pos)); - } else { - xf86DrvMsg(pScrn->scrnIndex, X_INFO, - "No MetaModes given, linking %s modes by default\n", - (pI830->NonRect ? - (((pos == PosLeftOf) || (pos == PosRightOf)) ? "widest" : "tallest") - : - (((pos == PosLeftOf) || (pos == PosRightOf)) ? "widest common" : "tallest common")) ); - return(I830GenerateModeListFromLargestModes(pScrn, i, j, pos)); - } -} - -static void -I830RecalcDefaultVirtualSize(ScrnInfoPtr pScrn) -{ - I830Ptr pI830 = I830PTR(pScrn); - DisplayModePtr mode, bmode; - int maxh, maxv; - static const char *str = "MergedFB: Virtual %s %d\n"; - static const char *errstr = "Virtual %s to small for given SecondPosition offset\n"; - - mode = bmode = pScrn->modes; - maxh = maxv = 0; - do { - if(mode->HDisplay > maxh) maxh = mode->HDisplay; - if(mode->VDisplay > maxv) maxv = mode->VDisplay; - mode = mode->next; - } while(mode != bmode); - - maxh += pI830->FirstXOffs + pI830->SecondXOffs; - maxv += pI830->FirstYOffs + pI830->SecondYOffs; - - if(!(pScrn->display->virtualX)) { - if(maxh > 4088) { - xf86DrvMsg(pScrn->scrnIndex, X_ERROR, - "Virtual width with SecondPosition offset beyond hardware specs\n"); - pI830->FirstXOffs = pI830->SecondXOffs = 0; - maxh -= (pI830->FirstXOffs + pI830->SecondXOffs); - } - pScrn->virtualX = maxh; - pScrn->displayWidth = maxh; - xf86DrvMsg(pScrn->scrnIndex, X_PROBED, str, "width", maxh); - } else { - if(maxh < pScrn->display->virtualX) { - xf86DrvMsg(pScrn->scrnIndex, X_ERROR, errstr, "width"); - pI830->FirstXOffs = pI830->SecondXOffs = 0; - } - } - - if(!(pScrn->display->virtualY)) { - pScrn->virtualY = maxv; - xf86DrvMsg(pScrn->scrnIndex, X_PROBED, str, "height", maxv); - } else { - if(maxv < pScrn->display->virtualY) { - xf86DrvMsg(pScrn->scrnIndex, X_ERROR, errstr, "height"); - pI830->FirstYOffs = pI830->SecondYOffs = 0; - } - } -} - -#define SDMPTR(x) ((I830ModePrivatePtr)x->currentMode->Private)->merged -#define CDMPTR ((I830ModePrivatePtr)pI830->currentMode->Private)->merged - -#define BOUND(test,low,hi) \ - { \ - if((test) < (low)) (test) = (low); \ - if((test) > (hi)) (test) = (hi); \ - } - -#define REBOUND(low,hi,test) \ - { \ - if((test) < (low)) { \ - (hi) += (test)-(low); \ - (low) = (test); \ - } \ - if((test) > (hi)) { \ - (low) += (test)-(hi); \ - (hi) = (test); \ - } \ - } - - -static void -I830MergedPointerMoved(int scrnIndex, int x, int y) -{ - ScrnInfoPtr pScrn1 = xf86Screens[scrnIndex]; - I830Ptr pI830 = I830PTR(pScrn1); - ScrnInfoPtr pScrn2 = pI830->pScrn_2; - region out, in1, in2, f2, f1; - int deltax, deltay; - int temp1, temp2; - int old1x0, old1y0, old2x0, old2y0; - int FirstXOffs = 0, FirstYOffs = 0, SecondXOffs = 0, SecondYOffs = 0; - int HVirt = pScrn1->virtualX; - int VVirt = pScrn1->virtualY; - int sigstate; - Bool doit = FALSE, HaveNonRect = FALSE, HaveOffsRegions = FALSE; - int pos = ((I830MergedDisplayModePtr)pI830->currentMode->Private)->SecondPosition; - - if(pI830->DGAactive) { - return; - /* DGA: There is no cursor and no panning while DGA is active. */ - } else { - FirstXOffs = pI830->FirstXOffs; - FirstYOffs = pI830->FirstYOffs; - SecondXOffs = pI830->SecondXOffs; - SecondYOffs = pI830->SecondYOffs; - HaveNonRect = pI830->HaveNonRect; - HaveOffsRegions = pI830->HaveOffsRegions; - } - - /* Check if the pointer is inside our dead areas */ - if((pI830->MouseRestrictions) && !I830noPanoramiXExtension) { - if(HaveNonRect) { - if(InRegion(x, y, pI830->NonRectDead)) { - switch(pos) { - case PosLeftOf: - case PosRightOf: y = pI830->NonRectDead.y0 - 1; - doit = TRUE; - break; - case PosAbove: - case PosBelow: x = pI830->NonRectDead.x0 - 1; - doit = TRUE; - default: break; - } - } - } - if(HaveOffsRegions) { - if(InRegion(x, y, pI830->OffDead1)) { - switch(pos) { - case PosLeftOf: - case PosRightOf: y = pI830->OffDead1.y1; - doit = TRUE; - break; - case PosAbove: - case PosBelow: x = pI830->OffDead1.x1; - doit = TRUE; - default: break; - } - } else if(InRegion(x, y, pI830->OffDead2)) { - switch(pos) { - case PosLeftOf: - case PosRightOf: y = pI830->OffDead2.y0 - 1; - doit = TRUE; - break; - case PosAbove: - case PosBelow: x = pI830->OffDead2.x0 - 1; - doit = TRUE; - default: break; - } - } - } - if(doit) { - UpdateCurrentTime(); - sigstate = xf86BlockSIGIO(); - miPointerAbsoluteCursor(x, y, currentTime.milliseconds); - xf86UnblockSIGIO(sigstate); - return; - } - } - - f1.x0 = old1x0 = pI830->FirstframeX0; - f1.x1 = pI830->FirstframeX1; - f1.y0 = old1y0 = pI830->FirstframeY0; - f1.y1 = pI830->FirstframeY1; - f2.x0 = old2x0 = pScrn2->frameX0; - f2.x1 = pScrn2->frameX1; - f2.y0 = old2y0 = pScrn2->frameY0; - f2.y1 = pScrn2->frameY1; - - /* Define the outer region. Crossing this causes all frames to move */ - out.x0 = pScrn1->frameX0; - out.x1 = pScrn1->frameX1; - out.y0 = pScrn1->frameY0; - out.y1 = pScrn1->frameY1; - - /* - * Define the inner sliding window. Being outsize both frames but - * inside the outer clipping window will slide corresponding frame - */ - in1 = out; - in2 = out; - switch(pos) { - case PosLeftOf: - in1.x0 = f1.x0; - in2.x1 = f2.x1; - break; - case PosRightOf: - in1.x1 = f1.x1; - in2.x0 = f2.x0; - break; - case PosBelow: - in1.y1 = f1.y1; - in2.y0 = f2.y0; - break; - case PosAbove: - in1.y0 = f1.y0; - in2.y1 = f2.y1; - break; - } - - deltay = 0; - deltax = 0; - - if(InRegion(x, y, out)) { /* inside outer region */ - - if(InRegion(x, y, in1) && !InRegion(x, y, f1)) { - REBOUND(f1.x0, f1.x1, x); - REBOUND(f1.y0, f1.y1, y); - deltax = 1; - } - if(InRegion(x, y, in2) && !InRegion(x, y, f2)) { - REBOUND(f2.x0, f2.x1, x); - REBOUND(f2.y0, f2.y1, y); - deltax = 1; - } - - } else { /* outside outer region */ - - if(out.x0 > x) { - deltax = x - out.x0; - } - if(out.x1 < x) { - deltax = x - out.x1; - } - if(deltax) { - pScrn1->frameX0 += deltax; - pScrn1->frameX1 += deltax; - f1.x0 += deltax; - f1.x1 += deltax; - f2.x0 += deltax; - f2.x1 += deltax; - } - - if(out.y0 > y) { - deltay = y - out.y0; - } - if(out.y1 < y) { - deltay = y - out.y1; - } - if(deltay) { - pScrn1->frameY0 += deltay; - pScrn1->frameY1 += deltay; - f1.y0 += deltay; - f1.y1 += deltay; - f2.y0 += deltay; - f2.y1 += deltay; - } - - switch(pos) { - case PosLeftOf: - if(x >= f1.x0) { REBOUND(f1.y0, f1.y1, y); } - if(x <= f2.x1) { REBOUND(f2.y0, f2.y1, y); } - break; - case PosRightOf: - if(x <= f1.x1) { REBOUND(f1.y0, f1.y1, y); } - if(x >= f2.x0) { REBOUND(f2.y0, f2.y1, y); } - break; - case PosBelow: - if(y <= f1.y1) { REBOUND(f1.x0, f1.x1, x); } - if(y >= f2.y0) { REBOUND(f2.x0, f2.x1, x); } - break; - case PosAbove: - if(y >= f1.y0) { REBOUND(f1.x0, f1.x1, x); } - if(y <= f2.y1) { REBOUND(f2.x0, f2.x1, x); } - break; - } - - } - - if(deltax || deltay) { - pI830->FirstframeX0 = f1.x0; - pI830->FirstframeY0 = f1.y0; - pScrn2->frameX0 = f2.x0; - pScrn2->frameY0 = f2.y0; - - switch(pos) { - case PosLeftOf: - case PosRightOf: - if(FirstYOffs || SecondYOffs || HaveNonRect) { - if(pI830->FirstframeY0 != old1y0) { - if(pI830->FirstframeY0 < FirstYOffs) - pI830->FirstframeY0 = FirstYOffs; - - temp1 = pI830->FirstframeY0 + CDMPTR.First->VDisplay; - temp2 = min((VVirt - SecondYOffs), (FirstYOffs + pI830->MBXNR1YMAX)); - if(temp1 > temp2) - pI830->FirstframeY0 -= (temp1 - temp2); - } - if(pScrn2->frameY0 != old2y0) { - if(pScrn2->frameY0 < SecondYOffs) - pScrn2->frameY0 = SecondYOffs; - - temp1 = pScrn2->frameY0 + CDMPTR.Second->VDisplay; - temp2 = min((VVirt - FirstYOffs), (SecondYOffs + pI830->MBXNR2YMAX)); - if(temp1 > temp2) - pScrn2->frameY0 -= (temp1 - temp2); - } - } - break; - case PosBelow: - case PosAbove: - if(FirstXOffs || SecondXOffs || HaveNonRect) { - if(pI830->FirstframeX0 != old1x0) { - if(pI830->FirstframeX0 < FirstXOffs) - pI830->FirstframeX0 = FirstXOffs; - - temp1 = pI830->FirstframeX0 + CDMPTR.First->HDisplay; - temp2 = min((HVirt - SecondXOffs), (FirstXOffs + pI830->MBXNR1XMAX)); - if(temp1 > temp2) - pI830->FirstframeX0 -= (temp1 - temp2); - } - if(pScrn2->frameX0 != old2x0) { - if(pScrn2->frameX0 < SecondXOffs) - pScrn2->frameX0 = SecondXOffs; - - temp1 = pScrn2->frameX0 + CDMPTR.Second->HDisplay; - temp2 = min((HVirt - FirstXOffs), (SecondXOffs + pI830->MBXNR2XMAX)); - if(temp1 > temp2) - pScrn2->frameX0 -= (temp1 - temp2); - } - } - break; - } - - pI830->FirstframeX1 = pI830->FirstframeX0 + CDMPTR.First->HDisplay - 1; - pI830->FirstframeY1 = pI830->FirstframeY0 + CDMPTR.First->VDisplay - 1; - pScrn2->frameX1 = pScrn2->frameX0 + CDMPTR.Second->HDisplay - 1; - pScrn2->frameY1 = pScrn2->frameY0 + CDMPTR.Second->VDisplay - 1; - - /* No need to update pScrn1->frame?1, done above */ - 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 { - OUTREG(DSPBBASE, pI830->FrontBuffer.Start + ((pI830->FirstframeY0 * pScrn1->displayWidth + pI830->FirstframeX0) * pI830->cpp)); - OUTREG(DSPABASE, pI830->FrontBuffer.Start + ((pScrn2->frameY0 * pScrn1->displayWidth + pScrn2->frameX0) * pI830->cpp)); - } - } -} - -static void -I830AdjustFrameMerged(int scrnIndex, int x, int y, int flags) -{ - ScrnInfoPtr pScrn1 = xf86Screens[scrnIndex]; - I830Ptr pI830 = I830PTR(pScrn1); - ScrnInfoPtr pScrn2 = pI830->pScrn_2; - int HTotal = pI830->currentMode->HDisplay; - int VTotal = pI830->currentMode->VDisplay; - int HMax = HTotal; - int VMax = VTotal; - int HVirt = pScrn1->virtualX; - int VVirt = pScrn1->virtualY; - int x1 = x, x2 = x; - int y1 = y, y2 = y; - int FirstXOffs = 0, FirstYOffs = 0, SecondXOffs = 0, SecondYOffs = 0; - int MBXNR1XMAX = 65536, MBXNR1YMAX = 65536, MBXNR2XMAX = 65536, MBXNR2YMAX = 65536; - - if(pI830->DGAactive) { - HVirt = pScrn1->displayWidth; - VVirt = pScrn1->virtualY; - } else { - FirstXOffs = pI830->FirstXOffs; - FirstYOffs = pI830->FirstYOffs; - SecondXOffs = pI830->SecondXOffs; - SecondYOffs = pI830->SecondYOffs; - MBXNR1XMAX = pI830->MBXNR1XMAX; - MBXNR1YMAX = pI830->MBXNR1YMAX; - MBXNR2XMAX = pI830->MBXNR2XMAX; - MBXNR2YMAX = pI830->MBXNR2YMAX; - } - - BOUND(x, 0, HVirt - HTotal); - BOUND(y, 0, VVirt - VTotal); - BOUND(x1, FirstXOffs, min(HVirt, MBXNR1XMAX + FirstXOffs) - min(HTotal, MBXNR1XMAX) - SecondXOffs); - BOUND(y1, FirstYOffs, min(VVirt, MBXNR1YMAX + FirstYOffs) - min(VTotal, MBXNR1YMAX) - SecondYOffs); - BOUND(x2, SecondXOffs, min(HVirt, MBXNR2XMAX + SecondXOffs) - min(HTotal, MBXNR2XMAX) - FirstXOffs); - BOUND(y2, SecondYOffs, min(VVirt, MBXNR2YMAX + SecondYOffs) - min(VTotal, MBXNR2YMAX) - FirstYOffs); - - switch(SDMPTR(pScrn1).SecondPosition) { - case PosLeftOf: - pScrn2->frameX0 = x2; - BOUND(pScrn2->frameY0, y2, y2 + min(VMax, MBXNR2YMAX) - CDMPTR.Second->VDisplay); - pI830->FirstframeX0 = x1 + CDMPTR.Second->HDisplay; - BOUND(pI830->FirstframeY0, y1, y1 + min(VMax, MBXNR1YMAX) - CDMPTR.First->VDisplay); - break; - case PosRightOf: - pI830->FirstframeX0 = x1; - BOUND(pI830->FirstframeY0, y1, y1 + min(VMax, MBXNR1YMAX) - CDMPTR.First->VDisplay); - pScrn2->frameX0 = x2 + CDMPTR.First->HDisplay; - BOUND(pScrn2->frameY0, y2, y2 + min(VMax, MBXNR2YMAX) - CDMPTR.Second->VDisplay); - break; - case PosAbove: - BOUND(pScrn2->frameX0, x2, x2 + min(HMax, MBXNR2XMAX) - CDMPTR.Second->HDisplay); - pScrn2->frameY0 = y2; - BOUND(pI830->FirstframeX0, x1, x1 + min(HMax, MBXNR1XMAX) - CDMPTR.First->HDisplay); - pI830->FirstframeY0 = y1 + CDMPTR.Second->VDisplay; - break; - case PosBelow: - BOUND(pI830->FirstframeX0, x1, x1 + min(HMax, MBXNR1XMAX) - CDMPTR.First->HDisplay); - pI830->FirstframeY0 = y1; - BOUND(pScrn2->frameX0, x2, x2 + min(HMax, MBXNR2XMAX) - CDMPTR.Second->HDisplay); - pScrn2->frameY0 = y2 + CDMPTR.First->VDisplay; - break; - } - - BOUND(pI830->FirstframeX0, 0, HVirt - CDMPTR.First->HDisplay); - BOUND(pI830->FirstframeY0, 0, VVirt - CDMPTR.First->VDisplay); - BOUND(pScrn2->frameX0, 0, HVirt - CDMPTR.Second->HDisplay); - BOUND(pScrn2->frameY0, 0, VVirt - CDMPTR.Second->VDisplay); - - pScrn1->frameX0 = x; - pScrn1->frameY0 = y; - - pI830->FirstframeX1 = pI830->FirstframeX0 + CDMPTR.First->HDisplay - 1; - pI830->FirstframeY1 = pI830->FirstframeY0 + CDMPTR.First->VDisplay - 1; - pScrn2->frameX1 = pScrn2->frameX0 + CDMPTR.Second->HDisplay - 1; - pScrn2->frameY1 = pScrn2->frameY0 + CDMPTR.Second->VDisplay - 1; - - pScrn1->frameX1 = pScrn1->frameX0 + pI830->currentMode->HDisplay - 1; - pScrn1->frameY1 = pScrn1->frameY0 + pI830->currentMode->VDisplay - 1; - pScrn1->frameX1 += FirstXOffs + SecondXOffs; - pScrn1->frameY1 += FirstYOffs + SecondYOffs; -} - -/* Pseudo-Xinerama extension for MergedFB mode */ -static void -I830UpdateXineramaScreenInfo(ScrnInfoPtr pScrn1) -{ - I830Ptr pI830 = I830PTR(pScrn1); - int scrnnum1 = 0, scrnnum2 = 1; - int x1=0, x2=0, y1=0, y2=0, h1=0, h2=0, w1=0, w2=0; - int realvirtX, realvirtY; - DisplayModePtr currentMode, firstMode; - Bool infochanged = FALSE; - Bool usenonrect = pI830->NonRect; - const char *rectxine = "\t... setting up rectangular Xinerama layout\n"; -#ifdef XF86DRI - drmI830Sarea *sarea = NULL; - - if (pI830->directRenderingEnabled) { - sarea = (drmI830Sarea *) DRIGetSAREAPrivate(pScrn1->pScreen); - } -#endif - - pI830->MBXNR1XMAX = pI830->MBXNR1YMAX = pI830->MBXNR2XMAX = pI830->MBXNR2YMAX = 65536; - pI830->HaveNonRect = pI830->HaveOffsRegions = FALSE; - - if(!pI830->MergedFB) { -#ifdef XF86DRI - if (pI830->directRenderingEnabled) { - sarea->pipeA_x = sarea->pipeA_y = sarea->pipeB_x = sarea->pipeB_y = 0; - - if (pI830->planeEnabled[0]) { - sarea->pipeA_w = pScrn1->virtualX; - sarea->pipeA_h = pScrn1->virtualY; - } else { - sarea->pipeA_w = 0; - sarea->pipeA_h = 0; - } - - if (pI830->planeEnabled[1]) { - sarea->pipeB_w = pScrn1->virtualX; - sarea->pipeB_h = pScrn1->virtualY; - } else { - sarea->pipeB_w = 0; - sarea->pipeB_h = 0; - } - } -#endif - - return; - } - - if (I830noPanoramiXExtension || !I830XineramadataPtr) { -#ifdef XF86DRI - if (!pI830->directRenderingEnabled) -#endif - return; - } - - if(pI830->SecondIsScrn0) { - scrnnum1 = 1; - scrnnum2 = 0; - } - - /* Attention: Usage of RandR may lead to virtual X and Y dimensions - * actually smaller than our MetaModes. To avoid this, we calculate - * the max* fields here (and not somewhere else, like in CopyNLink) - * - * *** Note: RandR is disabled if one of CRTxxOffs is non-zero. - */ - - /* "Real" virtual: Virtual without the Offset */ - realvirtX = pScrn1->virtualX - pI830->FirstXOffs - pI830->SecondXOffs; - realvirtY = pScrn1->virtualY - pI830->FirstYOffs - pI830->SecondYOffs; - - if((pI830->I830XineramaVX != pScrn1->virtualX) || (pI830->I830XineramaVY != pScrn1->virtualY)) { - - if(!(pScrn1->modes)) return; - - pI830->maxFirst_X1 = pI830->maxFirst_X2 = 0; - pI830->maxFirst_Y1 = pI830->maxFirst_Y2 = 0; - pI830->maxSecond_X1 = pI830->maxSecond_X2 = 0; - pI830->maxSecond_Y1 = pI830->maxSecond_Y2 = 0; - - currentMode = firstMode = pScrn1->modes; - - do { - - DisplayModePtr p = currentMode->next; - DisplayModePtr i = ((I830ModePrivatePtr)currentMode->Private)->merged.First; - DisplayModePtr j = ((I830ModePrivatePtr)currentMode->Private)->merged.Second; - - if((currentMode->HDisplay <= realvirtX) && (currentMode->VDisplay <= realvirtY) && - (i->HDisplay <= realvirtX) && (j->HDisplay <= realvirtX) && - (i->VDisplay <= realvirtY) && (j->VDisplay <= realvirtY)) { - - if(pI830->maxFirst_X1 == i->HDisplay) { - if(pI830->maxFirst_X2 < j->HDisplay) { - pI830->maxFirst_X2 = j->HDisplay; /* Widest Second mode displayed with widest CRT1 mode */ - } - } else if(pI830->maxFirst_X1 < i->HDisplay) { - pI830->maxFirst_X1 = i->HDisplay; /* Widest CRT1 mode */ - pI830->maxFirst_X2 = j->HDisplay; - } - if(pI830->maxSecond_X2 == j->HDisplay) { - if(pI830->maxSecond_X1 < i->HDisplay) { - pI830->maxSecond_X1 = i->HDisplay; /* Widest First mode displayed with widest Second mode */ - } - } else if(pI830->maxSecond_X2 < j->HDisplay) { - pI830->maxSecond_X2 = j->HDisplay; /* Widest Second mode */ - pI830->maxSecond_X1 = i->HDisplay; - } - if(pI830->maxFirst_Y1 == i->VDisplay) { /* Same as above, but tallest instead of widest */ - if(pI830->maxFirst_Y2 < j->VDisplay) { - pI830->maxFirst_Y2 = j->VDisplay; - } - } else if(pI830->maxFirst_Y1 < i->VDisplay) { - pI830->maxFirst_Y1 = i->VDisplay; - pI830->maxFirst_Y2 = j->VDisplay; - } - if(pI830->maxSecond_Y2 == j->VDisplay) { - if(pI830->maxSecond_Y1 < i->VDisplay) { - pI830->maxSecond_Y1 = i->VDisplay; - } - } else if(pI830->maxSecond_Y2 < j->VDisplay) { - pI830->maxSecond_Y2 = j->VDisplay; - pI830->maxSecond_Y1 = i->VDisplay; - } - } - currentMode = p; - - } while((currentMode) && (currentMode != firstMode)); - - pI830->I830XineramaVX = pScrn1->virtualX; - pI830->I830XineramaVY = pScrn1->virtualY; - infochanged = TRUE; - - } - - if((usenonrect) && pI830->maxFirst_X1) { - switch(pI830->SecondPosition) { - case PosLeftOf: - case PosRightOf: - if((pI830->maxFirst_Y1 != realvirtY) && (pI830->maxSecond_Y2 != realvirtY)) { - usenonrect = FALSE; - } - break; - case PosAbove: - case PosBelow: - if((pI830->maxFirst_X1 != realvirtX) && (pI830->maxSecond_X2 != realvirtX)) { - usenonrect = FALSE; - } - break; - } - if(infochanged && !usenonrect) { - xf86DrvMsg(pScrn1->scrnIndex, X_INFO, - "Virtual screen size does not match maximum display modes...\n"); - xf86DrvMsg(pScrn1->scrnIndex, X_INFO, rectxine); - - } - } else if(infochanged && usenonrect) { - usenonrect = FALSE; - xf86DrvMsg(pScrn1->scrnIndex, X_INFO, - "Only clone modes available for this virtual screen size...\n"); - xf86DrvMsg(pScrn1->scrnIndex, X_INFO, rectxine); - } - - if(pI830->maxFirst_X1) { /* Means we have at least one non-clone mode */ - switch(pI830->SecondPosition) { - case PosLeftOf: - x1 = min(pI830->maxFirst_X2, pScrn1->virtualX - pI830->maxFirst_X1); - if(x1 < 0) x1 = 0; - y1 = pI830->FirstYOffs; - w1 = pScrn1->virtualX - x1; - h1 = realvirtY; - if((usenonrect) && (pI830->maxFirst_Y1 != realvirtY)) { - h1 = pI830->MBXNR1YMAX = pI830->maxFirst_Y1; - pI830->NonRectDead.x0 = x1; - pI830->NonRectDead.x1 = x1 + w1 - 1; - pI830->NonRectDead.y0 = y1 + h1; - pI830->NonRectDead.y1 = pScrn1->virtualY - 1; - pI830->HaveNonRect = TRUE; - } - x2 = 0; - y2 = pI830->SecondYOffs; - w2 = max(pI830->maxSecond_X2, pScrn1->virtualX - pI830->maxSecond_X1); - if(w2 > pScrn1->virtualX) w2 = pScrn1->virtualX; - h2 = realvirtY; - if((usenonrect) && (pI830->maxSecond_Y2 != realvirtY)) { - h2 = pI830->MBXNR2YMAX = pI830->maxSecond_Y2; - pI830->NonRectDead.x0 = x2; - pI830->NonRectDead.x1 = x2 + w2 - 1; - pI830->NonRectDead.y0 = y2 + h2; - pI830->NonRectDead.y1 = pScrn1->virtualY - 1; - pI830->HaveNonRect = TRUE; - } - break; - case PosRightOf: - x1 = 0; - y1 = pI830->FirstYOffs; - w1 = max(pI830->maxFirst_X1, pScrn1->virtualX - pI830->maxFirst_X2); - if(w1 > pScrn1->virtualX) w1 = pScrn1->virtualX; - h1 = realvirtY; - if((usenonrect) && (pI830->maxFirst_Y1 != realvirtY)) { - h1 = pI830->MBXNR1YMAX = pI830->maxFirst_Y1; - pI830->NonRectDead.x0 = x1; - pI830->NonRectDead.x1 = x1 + w1 - 1; - pI830->NonRectDead.y0 = y1 + h1; - pI830->NonRectDead.y1 = pScrn1->virtualY - 1; - pI830->HaveNonRect = TRUE; - } - x2 = min(pI830->maxSecond_X1, pScrn1->virtualX - pI830->maxSecond_X2); - if(x2 < 0) x2 = 0; - y2 = pI830->SecondYOffs; - w2 = pScrn1->virtualX - x2; - h2 = realvirtY; - if((usenonrect) && (pI830->maxSecond_Y2 != realvirtY)) { - h2 = pI830->MBXNR2YMAX = pI830->maxSecond_Y2; - pI830->NonRectDead.x0 = x2; - pI830->NonRectDead.x1 = x2 + w2 - 1; - pI830->NonRectDead.y0 = y2 + h2; - pI830->NonRectDead.y1 = pScrn1->virtualY - 1; - pI830->HaveNonRect = TRUE; - } - break; - case PosAbove: - x1 = pI830->FirstXOffs; - y1 = min(pI830->maxFirst_Y2, pScrn1->virtualY - pI830->maxFirst_Y1); - if(y1 < 0) y1 = 0; - w1 = realvirtX; - h1 = pScrn1->virtualY - y1; - if((usenonrect) && (pI830->maxFirst_X1 != realvirtX)) { - w1 = pI830->MBXNR1XMAX = pI830->maxFirst_X1; - pI830->NonRectDead.x0 = x1 + w1; - pI830->NonRectDead.x1 = pScrn1->virtualX - 1; - pI830->NonRectDead.y0 = y1; - pI830->NonRectDead.y1 = y1 + h1 - 1; - pI830->HaveNonRect = TRUE; - } - x2 = pI830->SecondXOffs; - y2 = 0; - w2 = realvirtX; - h2 = max(pI830->maxSecond_Y2, pScrn1->virtualY - pI830->maxSecond_Y1); - if(h2 > pScrn1->virtualY) h2 = pScrn1->virtualY; - if((usenonrect) && (pI830->maxSecond_X2 != realvirtX)) { - w2 = pI830->MBXNR2XMAX = pI830->maxSecond_X2; - pI830->NonRectDead.x0 = x2 + w2; - pI830->NonRectDead.x1 = pScrn1->virtualX - 1; - pI830->NonRectDead.y0 = y2; - pI830->NonRectDead.y1 = y2 + h2 - 1; - pI830->HaveNonRect = TRUE; - } - break; - case PosBelow: - x1 = pI830->FirstXOffs; - y1 = 0; - w1 = realvirtX; - h1 = max(pI830->maxFirst_Y1, pScrn1->virtualY - pI830->maxFirst_Y2); - if(h1 > pScrn1->virtualY) h1 = pScrn1->virtualY; - if((usenonrect) && (pI830->maxFirst_X1 != realvirtX)) { - w1 = pI830->MBXNR1XMAX = pI830->maxFirst_X1; - pI830->NonRectDead.x0 = x1 + w1; - pI830->NonRectDead.x1 = pScrn1->virtualX - 1; - pI830->NonRectDead.y0 = y1; - pI830->NonRectDead.y1 = y1 + h1 - 1; - pI830->HaveNonRect = TRUE; - } - x2 = pI830->SecondXOffs; - y2 = min(pI830->maxSecond_Y1, pScrn1->virtualY - pI830->maxSecond_Y2); - if(y2 < 0) y2 = 0; - w2 = realvirtX; - h2 = pScrn1->virtualY - y2; - if((usenonrect) && (pI830->maxSecond_X2 != realvirtX)) { - w2 = pI830->MBXNR2XMAX = pI830->maxSecond_X2; - pI830->NonRectDead.x0 = x2 + w2; - pI830->NonRectDead.x1 = pScrn1->virtualX - 1; - pI830->NonRectDead.y0 = y2; - pI830->NonRectDead.y1 = y2 + h2 - 1; - pI830->HaveNonRect = TRUE; - } - default: - break; - } - - switch(pI830->SecondPosition) { - case PosLeftOf: - case PosRightOf: - if(pI830->FirstYOffs) { - pI830->OffDead1.x0 = x1; - pI830->OffDead1.x1 = x1 + w1 - 1; - pI830->OffDead1.y0 = 0; - pI830->OffDead1.y1 = y1 - 1; - pI830->OffDead2.x0 = x2; - pI830->OffDead2.x1 = x2 + w2 - 1; - pI830->OffDead2.y0 = y2 + h2; - pI830->OffDead2.y1 = pScrn1->virtualY - 1; - pI830->HaveOffsRegions = TRUE; - } else if(pI830->SecondYOffs) { - pI830->OffDead1.x0 = x2; - pI830->OffDead1.x1 = x2 + w2 - 1; - pI830->OffDead1.y0 = 0; - pI830->OffDead1.y1 = y2 - 1; - pI830->OffDead2.x0 = x1; - pI830->OffDead2.x1 = x1 + w1 - 1; - pI830->OffDead2.y0 = y1 + h1; - pI830->OffDead2.y1 = pScrn1->virtualY - 1; - pI830->HaveOffsRegions = TRUE; - } - break; - case PosAbove: - case PosBelow: - if(pI830->FirstXOffs) { - pI830->OffDead1.x0 = x2 + w2; - pI830->OffDead1.x1 = pScrn1->virtualX - 1; - pI830->OffDead1.y0 = y2; - pI830->OffDead1.y1 = y2 + h2 - 1; - pI830->OffDead2.x0 = 0; - pI830->OffDead2.x1 = x1 - 1; - pI830->OffDead2.y0 = y1; - pI830->OffDead2.y1 = y1 + h1 - 1; - pI830->HaveOffsRegions = TRUE; - } else if(pI830->SecondXOffs) { - pI830->OffDead1.x0 = x1 + w1; - pI830->OffDead1.x1 = pScrn1->virtualX - 1; - pI830->OffDead1.y0 = y1; - pI830->OffDead1.y1 = y1 + h1 - 1; - pI830->OffDead2.x0 = 0; - pI830->OffDead2.x1 = x2 - 1; - pI830->OffDead2.y0 = y2; - pI830->OffDead2.y1 = y2 + h2 - 1; - pI830->HaveOffsRegions = TRUE; - } - default: - break; - } - - } - -#ifdef XF86DRI - if (pI830->directRenderingEnabled) { - sarea->pipeA_x = x1; - sarea->pipeA_y = y1; - sarea->pipeA_w = w1; - sarea->pipeA_h = h1; - sarea->pipeB_x = x2; - sarea->pipeB_y = y2; - sarea->pipeB_w = w2; - sarea->pipeB_h = h2; - } -#endif - - if (I830XineramadataPtr && !I830noPanoramiXExtension) { - I830XineramadataPtr[scrnnum1].x = x1; - I830XineramadataPtr[scrnnum1].y = y1; - I830XineramadataPtr[scrnnum1].width = w1; - I830XineramadataPtr[scrnnum1].height = h1; - I830XineramadataPtr[scrnnum2].x = x2; - I830XineramadataPtr[scrnnum2].y = y2; - I830XineramadataPtr[scrnnum2].width = w2; - I830XineramadataPtr[scrnnum2].height = h2; - } else - return; - - if(infochanged) { - xf86DrvMsg(pScrn1->scrnIndex, X_INFO, - "Pseudo-Xinerama: First (Screen %d) (%d,%d)-(%d,%d)\n", - scrnnum1, x1, y1, w1+x1-1, h1+y1-1); - xf86DrvMsg(pScrn1->scrnIndex, X_INFO, - "Pseudo-Xinerama: Second (Screen %d) (%d,%d)-(%d,%d)\n", - scrnnum2, x2, y2, w2+x2-1, h2+y2-1); - if(pI830->HaveNonRect) { - xf86DrvMsg(pScrn1->scrnIndex, X_INFO, - "Pseudo-Xinerama: Inaccessible area (%d,%d)-(%d,%d)\n", - pI830->NonRectDead.x0, pI830->NonRectDead.y0, - pI830->NonRectDead.x1, pI830->NonRectDead.y1); - } - if(pI830->HaveOffsRegions) { - xf86DrvMsg(pScrn1->scrnIndex, X_INFO, - "Pseudo-Xinerama: Inaccessible offset area (%d,%d)-(%d,%d)\n", - pI830->OffDead1.x0, pI830->OffDead1.y0, - pI830->OffDead1.x1, pI830->OffDead1.y1); - xf86DrvMsg(pScrn1->scrnIndex, X_INFO, - "Pseudo-Xinerama: Inaccessible offset area (%d,%d)-(%d,%d)\n", - pI830->OffDead2.x0, pI830->OffDead2.y0, - pI830->OffDead2.x1, pI830->OffDead2.y1); - } - if(pI830->HaveNonRect || pI830->HaveOffsRegions) { - xf86DrvMsg(pScrn1->scrnIndex, X_INFO, - "Mouse restriction for inaccessible areas is %s\n", - pI830->MouseRestrictions ? "enabled" : "disabled"); - } - } -} - -/* Proc */ - -int -I830ProcXineramaQueryVersion(ClientPtr client) -{ - xPanoramiXQueryVersionReply rep; - register int n; - - REQUEST_SIZE_MATCH(xPanoramiXQueryVersionReq); - rep.type = X_Reply; - rep.length = 0; - rep.sequenceNumber = client->sequence; - rep.majorVersion = 1; - rep.minorVersion = 0; - if(client->swapped) { - swaps(&rep.sequenceNumber, n); - swapl(&rep.length, n); - swaps(&rep.majorVersion, n); - swaps(&rep.minorVersion, n); - } - WriteToClient(client, sizeof(xPanoramiXQueryVersionReply), (char *)&rep); - return (client->noClientException); -} - -int -I830ProcXineramaGetState(ClientPtr client) -{ - REQUEST(xPanoramiXGetStateReq); - WindowPtr pWin; - xPanoramiXGetStateReply rep; - register int n; - - REQUEST_SIZE_MATCH(xPanoramiXGetStateReq); - pWin = LookupWindow(stuff->window, client); - if(!pWin) return BadWindow; - - rep.type = X_Reply; - rep.length = 0; - rep.sequenceNumber = client->sequence; - rep.state = !I830noPanoramiXExtension; - if(client->swapped) { - swaps (&rep.sequenceNumber, n); - swapl (&rep.length, n); - swaps (&rep.state, n); - } - WriteToClient(client, sizeof(xPanoramiXGetStateReply), (char *)&rep); - return client->noClientException; -} - -int -I830ProcXineramaGetScreenCount(ClientPtr client) -{ - REQUEST(xPanoramiXGetScreenCountReq); - WindowPtr pWin; - xPanoramiXGetScreenCountReply rep; - register int n; - - REQUEST_SIZE_MATCH(xPanoramiXGetScreenCountReq); - pWin = LookupWindow(stuff->window, client); - if(!pWin) return BadWindow; - - rep.type = X_Reply; - rep.length = 0; - rep.sequenceNumber = client->sequence; - rep.ScreenCount = I830XineramaNumScreens; - if(client->swapped) { - swaps(&rep.sequenceNumber, n); - swapl(&rep.length, n); - swaps(&rep.ScreenCount, n); - } - WriteToClient(client, sizeof(xPanoramiXGetScreenCountReply), (char *)&rep); - return client->noClientException; -} - -int -I830ProcXineramaGetScreenSize(ClientPtr client) -{ - REQUEST(xPanoramiXGetScreenSizeReq); - WindowPtr pWin; - xPanoramiXGetScreenSizeReply rep; - register int n; - - REQUEST_SIZE_MATCH(xPanoramiXGetScreenSizeReq); - pWin = LookupWindow (stuff->window, client); - if(!pWin) return BadWindow; - - rep.type = X_Reply; - rep.length = 0; - rep.sequenceNumber = client->sequence; - rep.width = I830XineramadataPtr[stuff->screen].width; - rep.height = I830XineramadataPtr[stuff->screen].height; - if(client->swapped) { - swaps(&rep.sequenceNumber, n); - swapl(&rep.length, n); - swaps(&rep.width, n); - swaps(&rep.height, n); - } - WriteToClient(client, sizeof(xPanoramiXGetScreenSizeReply), (char *)&rep); - return client->noClientException; -} - -int -I830ProcXineramaIsActive(ClientPtr client) -{ - xXineramaIsActiveReply rep; - - REQUEST_SIZE_MATCH(xXineramaIsActiveReq); - - rep.type = X_Reply; - rep.length = 0; - rep.sequenceNumber = client->sequence; - rep.state = !I830noPanoramiXExtension; - if(client->swapped) { - register int n; - swaps(&rep.sequenceNumber, n); - swapl(&rep.length, n); - swapl(&rep.state, n); - } - WriteToClient(client, sizeof(xXineramaIsActiveReply), (char *) &rep); - return client->noClientException; -} - -int -I830ProcXineramaQueryScreens(ClientPtr client) -{ - xXineramaQueryScreensReply rep; - - REQUEST_SIZE_MATCH(xXineramaQueryScreensReq); - - rep.type = X_Reply; - rep.sequenceNumber = client->sequence; - rep.number = (I830noPanoramiXExtension) ? 0 : I830XineramaNumScreens; - rep.length = rep.number * sz_XineramaScreenInfo >> 2; - if(client->swapped) { - register int n; - swaps(&rep.sequenceNumber, n); - swapl(&rep.length, n); - swapl(&rep.number, n); - } - WriteToClient(client, sizeof(xXineramaQueryScreensReply), (char *)&rep); - - if(!I830noPanoramiXExtension) { - xXineramaScreenInfo scratch; - int i; - - for(i = 0; i < I830XineramaNumScreens; i++) { - scratch.x_org = I830XineramadataPtr[i].x; - scratch.y_org = I830XineramadataPtr[i].y; - scratch.width = I830XineramadataPtr[i].width; - scratch.height = I830XineramadataPtr[i].height; - if(client->swapped) { - register int n; - swaps(&scratch.x_org, n); - swaps(&scratch.y_org, n); - swaps(&scratch.width, n); - swaps(&scratch.height, n); - } - WriteToClient(client, sz_XineramaScreenInfo, (char *)&scratch); - } - } - - return client->noClientException; -} - -static int -I830ProcXineramaDispatch(ClientPtr client) -{ - REQUEST(xReq); - switch (stuff->data) { - case X_PanoramiXQueryVersion: - return I830ProcXineramaQueryVersion(client); - case X_PanoramiXGetState: - return I830ProcXineramaGetState(client); - case X_PanoramiXGetScreenCount: - return I830ProcXineramaGetScreenCount(client); - case X_PanoramiXGetScreenSize: - return I830ProcXineramaGetScreenSize(client); - case X_XineramaIsActive: - return I830ProcXineramaIsActive(client); - case X_XineramaQueryScreens: - return I830ProcXineramaQueryScreens(client); - } - return BadRequest; -} - -/* SProc */ - -static int -I830SProcXineramaQueryVersion (ClientPtr client) -{ - REQUEST(xPanoramiXQueryVersionReq); - register int n; - swaps(&stuff->length,n); - REQUEST_SIZE_MATCH (xPanoramiXQueryVersionReq); - return I830ProcXineramaQueryVersion(client); -} - -static int -I830SProcXineramaGetState(ClientPtr client) -{ - REQUEST(xPanoramiXGetStateReq); - register int n; - swaps (&stuff->length, n); - REQUEST_SIZE_MATCH(xPanoramiXGetStateReq); - return I830ProcXineramaGetState(client); -} - -static int -I830SProcXineramaGetScreenCount(ClientPtr client) -{ - REQUEST(xPanoramiXGetScreenCountReq); - register int n; - swaps (&stuff->length, n); - REQUEST_SIZE_MATCH(xPanoramiXGetScreenCountReq); - return I830ProcXineramaGetScreenCount(client); -} - -static int -I830SProcXineramaGetScreenSize(ClientPtr client) -{ - REQUEST(xPanoramiXGetScreenSizeReq); - register int n; - swaps (&stuff->length, n); - REQUEST_SIZE_MATCH(xPanoramiXGetScreenSizeReq); - return I830ProcXineramaGetScreenSize(client); -} - -static int -I830SProcXineramaIsActive(ClientPtr client) -{ - REQUEST(xXineramaIsActiveReq); - register int n; - swaps (&stuff->length, n); - REQUEST_SIZE_MATCH(xXineramaIsActiveReq); - return I830ProcXineramaIsActive(client); -} - -static int -I830SProcXineramaQueryScreens(ClientPtr client) -{ - REQUEST(xXineramaQueryScreensReq); - register int n; - swaps (&stuff->length, n); - REQUEST_SIZE_MATCH(xXineramaQueryScreensReq); - return I830ProcXineramaQueryScreens(client); -} - -int -I830SProcXineramaDispatch(ClientPtr client) -{ - REQUEST(xReq); - switch (stuff->data) { - case X_PanoramiXQueryVersion: - return I830SProcXineramaQueryVersion(client); - case X_PanoramiXGetState: - return I830SProcXineramaGetState(client); - case X_PanoramiXGetScreenCount: - return I830SProcXineramaGetScreenCount(client); - case X_PanoramiXGetScreenSize: - return I830SProcXineramaGetScreenSize(client); - case X_XineramaIsActive: - return I830SProcXineramaIsActive(client); - case X_XineramaQueryScreens: - return I830SProcXineramaQueryScreens(client); - } - return BadRequest; -} - -static void -I830XineramaResetProc(ExtensionEntry* extEntry) -{ - /* Called by CloseDownExtensions() */ - if(I830XineramadataPtr) { - Xfree(I830XineramadataPtr); - I830XineramadataPtr = NULL; - } -} - -static void -I830XineramaExtensionInit(ScrnInfoPtr pScrn) -{ - I830Ptr pI830 = I830PTR(pScrn); - Bool success = FALSE; - - if(!(I830XineramadataPtr)) { - - if(!pI830->MergedFB) { - I830noPanoramiXExtension = TRUE; - pI830->MouseRestrictions = FALSE; - return; - } - -#ifdef PANORAMIX - if(!noPanoramiXExtension) { - xf86DrvMsg(pScrn->scrnIndex, X_INFO, - "Xinerama active, not initializing Intel Pseudo-Xinerama\n"); - I830noPanoramiXExtension = TRUE; - pI830->MouseRestrictions = FALSE; - return; - } -#endif - - if(I830noPanoramiXExtension) { - xf86DrvMsg(pScrn->scrnIndex, X_INFO, - "Intel Pseudo-Xinerama disabled\n"); - pI830->MouseRestrictions = FALSE; - return; - } - - I830XineramaNumScreens = 2; - - while(I830XineramaGeneration != serverGeneration) { - - pI830->XineramaExtEntry = AddExtension(PANORAMIX_PROTOCOL_NAME, 0,0, - I830ProcXineramaDispatch, - I830SProcXineramaDispatch, - I830XineramaResetProc, - StandardMinorOpcode); - - if(!pI830->XineramaExtEntry) break; - - if(!(I830XineramadataPtr = (I830XineramaData *) - xcalloc(I830XineramaNumScreens, sizeof(I830XineramaData)))) break; - - I830XineramaGeneration = serverGeneration; - success = TRUE; - } - - if(!success) { - xf86DrvMsg(pScrn->scrnIndex, X_WARNING, - "Failed to initialize Intel Pseudo-Xinerama extension\n"); - I830noPanoramiXExtension = TRUE; - pI830->MouseRestrictions = FALSE; - return; - } - - xf86DrvMsg(pScrn->scrnIndex, X_INFO, - "Intel Pseudo-Xinerama extension initialized\n"); - - pI830->I830XineramaVX = 0; - pI830->I830XineramaVY = 0; - - } -} - static void -I830BIOSProbeDDC(ScrnInfoPtr pScrn, int index) +I830ProbeDDC(ScrnInfoPtr pScrn, int index) { vbeInfoPtr pVbe; @@ -2089,1036 +390,50 @@ I830BIOSProbeDDC(ScrnInfoPtr pScrn, int index) ConfiguredMonitor = vbeDoEDID(pVbe, NULL); } -/* 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(i830refreshes) / sizeof(i830refreshes[0]); - -static Bool -Check5fStatus(ScrnInfoPtr pScrn, int func, int ax) -{ - if (ax == 0x005f) - return TRUE; - else if (ax == 0x015f) { - xf86DrvMsg(pScrn->scrnIndex, X_WARNING, - "Extended BIOS function 0x%04x failed.\n", func); - return FALSE; - } else if ((ax & 0xff) != 0x5f) { - xf86DrvMsg(pScrn->scrnIndex, X_WARNING, - "Extended BIOS function 0x%04x not supported.\n", func); - return FALSE; - } else { - xf86DrvMsg(pScrn->scrnIndex, X_WARNING, - "Extended BIOS function 0x%04x returns 0x%04x.\n", - func, ax & 0xffff); - return FALSE; - } -} - static int -GetToggleList(ScrnInfoPtr pScrn, int toggle) -{ - vbeInfoPtr pVbe = I830PTR(pScrn)->pVbe; - - DPRINTF(PFX, "GetToggleList\n"); - - pVbe->pInt10->num = 0x10; - pVbe->pInt10->ax = 0x5f64; - pVbe->pInt10->bx = 0x500; - - pVbe->pInt10->bx |= toggle; - - xf86ExecX86int10_wrapper(pVbe->pInt10, pScrn); - if (Check5fStatus(pScrn, 0x5f64, pVbe->pInt10->ax)) { - xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Toggle (%d) 0x%x\n", toggle, pVbe->pInt10->cx); - return pVbe->pInt10->cx & 0xffff; - } - - return 0; -} - -static int -GetNextDisplayDeviceList(ScrnInfoPtr pScrn, int toggle) +I830DetectMemory(ScrnInfoPtr pScrn) { - vbeInfoPtr pVbe = I830PTR(pScrn)->pVbe; - int devices = 0; - int pipe = 0; - int i; - - DPRINTF(PFX, "GetNextDisplayDeviceList\n"); - - pVbe->pInt10->num = 0x10; - pVbe->pInt10->ax = 0x5f64; - pVbe->pInt10->bx = 0xA00; - pVbe->pInt10->bx |= toggle; - pVbe->pInt10->es = SEG_ADDR(pVbe->real_mode_base); - pVbe->pInt10->di = SEG_OFF(pVbe->real_mode_base); - - xf86ExecX86int10_wrapper(pVbe->pInt10, pScrn); - if (!Check5fStatus(pScrn, 0x5f64, pVbe->pInt10->ax)) - return 0; - - for (i=0; i<(pVbe->pInt10->cx & 0xff); i++) { - CARD32 VODA = (CARD32)((CARD32*)pVbe->memory)[i]; - - xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Next ACPI _DGS [%d] 0x%lx\n", - i, VODA); - - /* Check if it's a custom Video Output Device Attribute */ - if (!(VODA & 0x80000000)) - continue; - - pipe = (VODA & 0x000000F0) >> 4; - - if (pipe != 0 && pipe != 1) { - pipe = 0; + I830Ptr pI830 = I830PTR(pScrn); + PCITAG bridge; + CARD16 gmch_ctrl; + int memsize = 0, gtt_size; + int range; #if 0 - ErrorF("PIPE %d\n",pipe); + VbeInfoBlock *vbeInfo; #endif - } - - switch ((VODA & 0x00000F00) >> 8) { - case 0x0: - case 0x1: /* CRT */ - devices |= PIPE_CRT << (pipe == 1 ? 8 : 0); - break; - case 0x2: /* TV/HDTV */ - devices |= PIPE_TV << (pipe == 1 ? 8 : 0); - break; - case 0x3: /* DFP */ - devices |= PIPE_DFP << (pipe == 1 ? 8 : 0); - break; - case 0x4: /* LFP */ - devices |= PIPE_LFP << (pipe == 1 ? 8 : 0); - break; - } - } - - xf86DrvMsg(pScrn->scrnIndex, X_INFO, "ACPI Toggle devices 0x%x\n", devices); - - return devices; -} - -static int -GetAttachableDisplayDeviceList(ScrnInfoPtr pScrn) -{ - vbeInfoPtr pVbe = I830PTR(pScrn)->pVbe; - int i; - - DPRINTF(PFX, "GetAttachableDisplayDeviceList\n"); - - pVbe->pInt10->num = 0x10; - pVbe->pInt10->ax = 0x5f64; - pVbe->pInt10->bx = 0x900; - pVbe->pInt10->es = SEG_ADDR(pVbe->real_mode_base); - pVbe->pInt10->di = SEG_OFF(pVbe->real_mode_base); - - xf86ExecX86int10_wrapper(pVbe->pInt10, pScrn); - if (!Check5fStatus(pScrn, 0x5f64, pVbe->pInt10->ax)) - return 0; - - for (i=0; i<(pVbe->pInt10->cx & 0xff); i++) - xf86DrvMsg(pScrn->scrnIndex, X_INFO, - "Attachable device 0x%lx.\n", ((CARD32*)pVbe->memory)[i]); - - return pVbe->pInt10->cx & 0xffff; -} - -static int -BitToRefresh(int bits) -{ - int i; - - for (i = 0; i < nrefreshes; i++) - if (bits & (1 << i)) - return i830refreshes[i]; - return 0; -} - -static int -GetRefreshRate(ScrnInfoPtr pScrn, int mode, int *availRefresh) -{ - vbeInfoPtr pVbe = I830PTR(pScrn)->pVbe; - DPRINTF(PFX, "GetRefreshRate\n"); - - /* Only 8-bit mode numbers are supported. */ - if (mode & 0x100) - return 0; - - pVbe->pInt10->num = 0x10; - pVbe->pInt10->ax = 0x5f05; - pVbe->pInt10->bx = (mode & 0xff) | 0x100; - - xf86ExecX86int10_wrapper(pVbe->pInt10, pScrn); - if (Check5fStatus(pScrn, 0x5f05, pVbe->pInt10->ax)) { - if (availRefresh) - *availRefresh = pVbe->pInt10->bx; - return BitToRefresh(pVbe->pInt10->cx); - } else - return 0; -} - -struct panelid { - short hsize; - short vsize; - short fptype; - char redbpp; - char greenbpp; - char bluebpp; - char reservedbpp; - int rsvdoffscrnmemsize; - int rsvdoffscrnmemptr; - char reserved[14]; -}; - -static void -I830InterpretPanelID(int scrnIndex, unsigned char *tmp) -{ - ScrnInfoPtr pScrn = xf86Screens[scrnIndex]; - struct panelid *block = (struct panelid *)tmp; - -#define PANEL_DEFAULT_HZ 60 - - xf86DrvMsg(pScrn->scrnIndex, X_INFO, - "PanelID returned panel resolution : %dx%d\n", - block->hsize, block->vsize); - - /* If we get bogus values from this, don't accept it */ - if (block->hsize == 0 || block->vsize == 0) { - xf86DrvMsg(pScrn->scrnIndex, X_INFO, - "Bad Panel resolution - ignoring panelID\n"); - - return; - } - - /* If we have monitor timings then don't overwrite them */ - if (pScrn->monitor->nHsync > 0 && - pScrn->monitor->nVrefresh > 0) - return; - - /* With panels, we're always assuming a refresh of 60Hz */ - - pScrn->monitor->nHsync = 1; - pScrn->monitor->nVrefresh = 1; - - /* Give a little tolerance for the selected panel */ - pScrn->monitor->hsync[0].lo = (float)((PANEL_DEFAULT_HZ/1.05)*block->vsize)/1000; - pScrn->monitor->hsync[0].hi = (float)((PANEL_DEFAULT_HZ/0.95)*block->vsize)/1000; - pScrn->monitor->vrefresh[0].lo = (float)PANEL_DEFAULT_HZ; - pScrn->monitor->vrefresh[0].hi = (float)PANEL_DEFAULT_HZ; -} - -/* This should probably go into the VBE layer */ -static unsigned char * -vbeReadPanelID(vbeInfoPtr pVbe) -{ - int RealOff = pVbe->real_mode_base; - pointer page = pVbe->memory; - unsigned char *tmp = NULL; - int screen = pVbe->pInt10->scrnIndex; - - pVbe->pInt10->ax = 0x4F11; - pVbe->pInt10->bx = 0x01; - pVbe->pInt10->cx = 0; - pVbe->pInt10->dx = 0; - pVbe->pInt10->es = SEG_ADDR(RealOff); - pVbe->pInt10->di = SEG_OFF(RealOff); - pVbe->pInt10->num = 0x10; - - xf86ExecX86int10(pVbe->pInt10); - - if ((pVbe->pInt10->ax & 0xff) != 0x4f) { - xf86DrvMsgVerb(screen,X_INFO,3,"VESA VBE PanelID invalid\n"); - goto error; - } - switch (pVbe->pInt10->ax & 0xff00) { - case 0x0: - xf86DrvMsgVerb(screen,X_INFO,3,"VESA VBE PanelID read successfully\n"); - tmp = (unsigned char *)xnfalloc(32); - memcpy(tmp,page,32); - break; - case 0x100: - xf86DrvMsgVerb(screen,X_INFO,3,"VESA VBE PanelID read failed\n"); - break; - default: - xf86DrvMsgVerb(screen,X_INFO,3,"VESA VBE PanelID unknown failure %i\n", - pVbe->pInt10->ax & 0xff00); - break; - } - - error: - return tmp; -} - -static void -vbeDoPanelID(vbeInfoPtr pVbe) -{ - unsigned char *PanelID_data; - - if (!pVbe) return; - - PanelID_data = vbeReadPanelID(pVbe); - - if (!PanelID_data) - return; - - I830InterpretPanelID(pVbe->pInt10->scrnIndex, PanelID_data); -} - -int -I830GetBestRefresh(ScrnInfoPtr pScrn, int refresh) -{ - int i; + bridge = pciTag(0, 0, 0); /* This is always the host bridge */ + gmch_ctrl = pciReadWord(bridge, I830_GMCH_CTRL); - for (i = nrefreshes - 1; i >= 0; i--) { - /* - * Look for the highest value that the requested (refresh + 2) is - * greater than or equal to. + if (IS_I965G(pI830)) { + /* The 965 may have a GTT that is actually larger than is necessary + * to cover the aperture, so check the hardware's reporting of the + * GTT size. */ - if (i830refreshes[i] <= (refresh + 2)) + switch (INREG(PGETBL_CTL) & PGETBL_SIZE_MASK) { + case PGETBL_SIZE_512KB: + gtt_size = 512; 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) -{ - 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; - - pVbe->pInt10->num = 0x10; - pVbe->pInt10->ax = 0x5f05; - pVbe->pInt10->bx = mode & 0xff; - - pVbe->pInt10->cx = 1 << i; - xf86ExecX86int10_wrapper(pVbe->pInt10, pScrn); - if (Check5fStatus(pScrn, 0x5f05, pVbe->pInt10->ax)) - return i830refreshes[i]; - else - return 0; -} - -#if 0 -static Bool -SetPowerStatus(ScrnInfoPtr pScrn, int mode) -{ - vbeInfoPtr pVbe = I830PTR(pScrn)->pVbe; - - pVbe->pInt10->num = 0x10; - pVbe->pInt10->ax = 0x5f64; - pVbe->pInt10->bx = 0x0800 | mode; - pVbe->pInt10->cx = 0x0000; - - xf86ExecX86int10_wrapper(pVbe->pInt10, pScrn); - if (Check5fStatus(pScrn, 0x5f64, pVbe->pInt10->ax)) - return TRUE; - - return FALSE; -} -#endif - -static Bool -GetModeSupport(ScrnInfoPtr pScrn, int modePipeA, int modePipeB, - int devicesPipeA, int devicesPipeB, int *maxBandwidth, - int *bandwidthPipeA, int *bandwidthPipeB) -{ - vbeInfoPtr pVbe = I830PTR(pScrn)->pVbe; - - DPRINTF(PFX, "GetModeSupport: modes 0x%x, 0x%x, devices: 0x%x, 0x%x\n", - modePipeA, modePipeB, devicesPipeA, devicesPipeB); - - /* Only 8-bit mode numbers are supported. */ - if ((modePipeA & 0x100) || (modePipeB & 0x100)) - return FALSE; - - pVbe->pInt10->num = 0x10; - pVbe->pInt10->ax = 0x5f28; - pVbe->pInt10->bx = (modePipeA & 0xff) | ((modePipeB & 0xff) << 8); - if ((devicesPipeA & 0x80) || (devicesPipeB & 0x80)) - pVbe->pInt10->cx = 0x8000; - else - pVbe->pInt10->cx = (devicesPipeA & 0xff) | ((devicesPipeB & 0xff) << 8); - - xf86ExecX86int10_wrapper(pVbe->pInt10, pScrn); - if (Check5fStatus(pScrn, 0x5f28, pVbe->pInt10->ax)) { - if (maxBandwidth) - *maxBandwidth = pVbe->pInt10->cx; - if (bandwidthPipeA) - *bandwidthPipeA = pVbe->pInt10->dx & 0xffff; - /* XXX For XFree86 4.2.0 and earlier, ->dx is truncated to 16 bits. */ - if (bandwidthPipeB) - *bandwidthPipeB = (pVbe->pInt10->dx >> 16) & 0xffff; - return TRUE; - } else - return FALSE; -} - -#if 0 -static int -GetLFPCompMode(ScrnInfoPtr pScrn) -{ - vbeInfoPtr pVbe = I830PTR(pScrn)->pVbe; - - DPRINTF(PFX, "GetLFPCompMode\n"); - - pVbe->pInt10->num = 0x10; - pVbe->pInt10->ax = 0x5f61; - pVbe->pInt10->bx = 0x100; - - xf86ExecX86int10_wrapper(pVbe->pInt10, pScrn); - if (Check5fStatus(pScrn, 0x5f61, pVbe->pInt10->ax)) - return pVbe->pInt10->cx & 0xffff; - else - return -1; -} - -static Bool -SetLFPCompMode(ScrnInfoPtr pScrn, int compMode) -{ - vbeInfoPtr pVbe = I830PTR(pScrn)->pVbe; - - DPRINTF(PFX, "SetLFPCompMode: compMode %d\n", compMode); - - pVbe->pInt10->num = 0x10; - pVbe->pInt10->ax = 0x5f61; - pVbe->pInt10->bx = 0; - pVbe->pInt10->cx = compMode; - - xf86ExecX86int10_wrapper(pVbe->pInt10, pScrn); - return Check5fStatus(pScrn, 0x5f61, pVbe->pInt10->ax); -} -#endif - -static int -GetDisplayDevices(ScrnInfoPtr pScrn) -{ - I830Ptr pI830 = I830PTR(pScrn); - vbeInfoPtr pVbe = pI830->pVbe; - - DPRINTF(PFX, "GetDisplayDevices\n"); - -#if 0 - { - CARD32 temp; - ErrorF("ADPA is 0x%08x\n", INREG(ADPA)); - ErrorF("DVOA is 0x%08x\n", INREG(DVOA)); - ErrorF("DVOB is 0x%08x\n", INREG(DVOB)); - ErrorF("DVOC is 0x%08x\n", INREG(DVOC)); - ErrorF("LVDS is 0x%08x\n", INREG(LVDS)); - temp = INREG(DVOA_SRCDIM); - ErrorF("DVOA_SRCDIM is 0x%08x (%d x %d)\n", temp, - (temp >> 12) & 0xfff, temp & 0xfff); - temp = INREG(DVOB_SRCDIM); - ErrorF("DVOB_SRCDIM is 0x%08x (%d x %d)\n", temp, - (temp >> 12) & 0xfff, temp & 0xfff); - temp = INREG(DVOC_SRCDIM); - ErrorF("DVOC_SRCDIM is 0x%08x (%d x %d)\n", temp, - (temp >> 12) & 0xfff, temp & 0xfff); - ErrorF("SWF0 is 0x%08x\n", INREG(SWF0)); - ErrorF("SWF4 is 0x%08x\n", INREG(SWF4)); - } -#endif - - pVbe->pInt10->num = 0x10; - pVbe->pInt10->ax = 0x5f64; - pVbe->pInt10->bx = 0x100; - - xf86ExecX86int10_wrapper(pVbe->pInt10, pScrn); - if (Check5fStatus(pScrn, 0x5f64, pVbe->pInt10->ax)) { - return pVbe->pInt10->cx & 0xffff; - } else { - if (pI830->PciInfo->chipType == PCI_CHIP_E7221_G) /* FIXED CONFIG */ - return PIPE_CRT; - else - return -1; - } -} - -static int -GetBIOSPipe(ScrnInfoPtr pScrn) -{ - I830Ptr pI830 = I830PTR(pScrn); - vbeInfoPtr pVbe = pI830->pVbe; - int pipe; - - DPRINTF(PFX, "GetBIOSPipe:\n"); - - /* single pipe machines should always return Pipe A */ - if (pI830->availablePipes == 1) return 0; - - pVbe->pInt10->num = 0x10; - pVbe->pInt10->ax = 0x5f1c; - pVbe->pInt10->bx = 0x100; - - xf86ExecX86int10_wrapper(pVbe->pInt10, pScrn); - if (Check5fStatus(pScrn, 0x5f1c, pVbe->pInt10->ax)) { - if (pI830->newPipeSwitch) { - pipe = ((pVbe->pInt10->bx & 0x0001)); - } else { - pipe = ((pVbe->pInt10->cx & 0x0100) >> 8); + case PGETBL_SIZE_256KB: + gtt_size = 256; + break; + case PGETBL_SIZE_128KB: + gtt_size = 128; + break; + default: + FatalError("Unknown GTT size value: %08x\n", (int)INREG(PGETBL_CTL)); } - return pipe; - } - - /* failed, assume pipe A */ - return 0; -} - -static Bool -SetBIOSPipe(ScrnInfoPtr pScrn, int pipe) -{ - I830Ptr pI830 = I830PTR(pScrn); - vbeInfoPtr pVbe = pI830->pVbe; - - DPRINTF(PFX, "SetBIOSPipe: pipe 0x%x\n", pipe); - - /* single pipe machines should always return TRUE */ - if (pI830->availablePipes == 1) return TRUE; - - pVbe->pInt10->num = 0x10; - pVbe->pInt10->ax = 0x5f1c; - if (pI830->newPipeSwitch) { - pVbe->pInt10->bx = pipe; - pVbe->pInt10->cx = 0; } else { - pVbe->pInt10->bx = 0x0; - pVbe->pInt10->cx = pipe << 8; + /* Older chipsets only had GTT appropriately sized for the aperture. */ + gtt_size = pI830->FbMapSize / (1024*1024); } - xf86ExecX86int10_wrapper(pVbe->pInt10, pScrn); - if (Check5fStatus(pScrn, 0x5f1c, pVbe->pInt10->ax)) { - return TRUE; - } - - return FALSE; -} - -static Bool -SetPipeAccess(ScrnInfoPtr pScrn) -{ - I830Ptr pI830 = I830PTR(pScrn); - - /* Don't try messing with the pipe, unless we're dual head */ - if (xf86IsEntityShared(pScrn->entityList[0]) || pI830->Clone || pI830->MergedFB || pI830->origPipe != pI830->pipe) { - if (!SetBIOSPipe(pScrn, pI830->pipe)) - return FALSE; - } - - return TRUE; -} + xf86DrvMsg(pScrn->scrnIndex, X_INFO, "detected %d kB GTT.\n", gtt_size); -static Bool -I830Set640x480(ScrnInfoPtr pScrn) -{ - I830Ptr pI830 = I830PTR(pScrn); - int m; - - /* 640x480 8bpp */ - m = 0x30 | (1 << 15) | (1 << 14); - if (VBESetVBEMode(pI830->pVbe, m, NULL)) - return TRUE; - - /* if the first failed, let's try the next - usually 800x600 */ - m = 0x32 | (1 << 15) | (1 << 14); - - if (VBESetVBEMode(pI830->pVbe, m, NULL)) - return TRUE; - - return FALSE; -} - -/* This is needed for SetDisplayDevices to work correctly on I915G. - * Enable for all chipsets now as it has no bad side effects, apart - * from slightly longer startup time. - */ -#define I915G_WORKAROUND - -static Bool -SetDisplayDevices(ScrnInfoPtr pScrn, int devices) -{ - I830Ptr pI830 = I830PTR(pScrn); - vbeInfoPtr pVbe = pI830->pVbe; - CARD32 temp; - int singlepipe = 0; -#ifdef I915G_WORKAROUND - int getmode1; - Bool setmode = FALSE; -#endif - - DPRINTF(PFX, "SetDisplayDevices: devices 0x%x\n", devices); - - if (!pI830->specifiedMonitor) - return TRUE; - -#ifdef I915G_WORKAROUND - if (pI830->preinit) - setmode = TRUE; - if (pI830->leaving) - setmode = FALSE; - if (pI830->closing) - setmode = FALSE; - - if (setmode) { - VBEGetVBEMode(pVbe, &getmode1); - I830Set640x480(pScrn); - } -#endif - - pVbe->pInt10->num = 0x10; - pVbe->pInt10->ax = 0x5f64; - pVbe->pInt10->bx = 0x1; - pVbe->pInt10->cx = devices; - - xf86ExecX86int10_wrapper(pVbe->pInt10, pScrn); - if (Check5fStatus(pScrn, 0x5f64, pVbe->pInt10->ax)) { -#ifdef I915G_WORKAROUND - if (setmode) { - VBESetVBEMode(pI830->pVbe, getmode1 | 1<<15, NULL); - } -#endif - pI830->pipeEnabled[0] = (devices & 0xff) ? TRUE : FALSE; - pI830->pipeEnabled[1] = (devices & 0xff00) ? TRUE : FALSE; - - return TRUE; - } - -#ifdef I915G_WORKAROUND - if (setmode) - VBESetVBEMode(pI830->pVbe, getmode1 | 1<<15, NULL); -#endif - - if (devices & 0xff) { - pVbe->pInt10->num = 0x10; - pVbe->pInt10->ax = 0x5f64; - pVbe->pInt10->bx = 0x1; - pVbe->pInt10->cx = devices & 0xff; - - xf86ExecX86int10_wrapper(pVbe->pInt10, pScrn); - if (Check5fStatus(pScrn, 0x5f64, pVbe->pInt10->ax)) { - xf86DrvMsg(pScrn->scrnIndex, X_WARNING, - "Successfully set display devices to 0x%x.\n",devices & 0xff); - singlepipe = devices & 0xff00; /* set alternate */ - } else { - xf86DrvMsg(pScrn->scrnIndex, X_WARNING, - "Failed to set display devices to 0x%x.\n",devices & 0xff); - singlepipe = devices; - } - } else - singlepipe = devices; - - if (singlepipe == devices && devices & 0xff00) { - pVbe->pInt10->num = 0x10; - pVbe->pInt10->ax = 0x5f64; - pVbe->pInt10->bx = 0x1; - pVbe->pInt10->cx = devices & 0xff00; - - xf86ExecX86int10_wrapper(pVbe->pInt10, pScrn); - if (Check5fStatus(pScrn, 0x5f64, pVbe->pInt10->ax)) { - xf86DrvMsg(pScrn->scrnIndex, X_WARNING, - "Successfully set display devices to 0x%x.\n",devices & 0xff00); - singlepipe = devices & 0xff; /* set alternate */ - } else { - xf86DrvMsg(pScrn->scrnIndex, X_WARNING, - "Failed to set display devices to 0x%x.\n",devices & 0xff00); - singlepipe = devices; - } - } - - /* LVDS doesn't exist on these */ - if (IS_I830(pI830) || IS_845G(pI830) || IS_I865G(pI830) || IS_I915G(pI830) || IS_I945G(pI830) || IS_I965G(pI830)) - singlepipe &= ~(PIPE_LFP | (PIPE_LFP<<8)); - - if (pI830->availablePipes == 1) - singlepipe &= 0xFF; - - /* Disable LVDS */ - if (singlepipe & PIPE_LFP) { - /* LFP on PipeA is unlikely! */ - OUTREG(0x61200, INREG(0x61200) & ~0x80000000); - OUTREG(0x61204, INREG(0x61204) & ~0x00000001); - while ((INREG(0x61200) & 0x80000000) || (INREG(0x61204) & 1)); - /* Fix up LVDS */ - OUTREG(LVDS, (INREG(LVDS) & ~1<<30) | 0x80000300); - /* Enable LVDS */ - OUTREG(0x61200, INREG(0x61200) | 0x80000000); - OUTREG(0x61204, INREG(0x61204) | 0x00000001); - while (!(INREG(0x61200) & 0x80000000) && !(INREG(0x61204) & 1)); - xf86DrvMsg(pScrn->scrnIndex, X_WARNING, - "Enabling LVDS directly. Pipe A.\n"); - } else - if (singlepipe & (PIPE_LFP << 8)) { - OUTREG(0x61200, INREG(0x61200) & ~0x80000000); - OUTREG(0x61204, INREG(0x61204) & ~0x00000001); - while ((INREG(0x61200) & 0x80000000) || (INREG(0x61204) & 1)); - /* Fix up LVDS */ - OUTREG(LVDS, (INREG(LVDS) | 1<<30) | 0x80000300); - /* Enable LVDS */ - OUTREG(0x61200, INREG(0x61200) | 0x80000000); - OUTREG(0x61204, INREG(0x61204) | 0x00000001); - while (!(INREG(0x61200) & 0x80000000) && !(INREG(0x61204) & 1)); - xf86DrvMsg(pScrn->scrnIndex, X_WARNING, - "Enabling LVDS directly. Pipe B.\n"); - } - else if (!(IS_I830(pI830) || IS_845G(pI830) || IS_I865G(pI830))) { - if (!(devices & (PIPE_LFP | PIPE_LFP<<8))) { - OUTREG(0x61200, INREG(0x61200) & ~0x80000000); - OUTREG(0x61204, INREG(0x61204) & ~0x00000001); - while ((INREG(0x61200) & 0x80000000) || (INREG(0x61204) & 1)); - /* Fix up LVDS */ - OUTREG(LVDS, (INREG(LVDS) | 1<<30) & ~0x80000300); - xf86DrvMsg(pScrn->scrnIndex, X_WARNING, - "Disabling LVDS directly.\n"); - } - } - - /* Now try to program the registers directly if the BIOS failed. */ - temp = INREG(ADPA); - temp &= ~(ADPA_DAC_ENABLE | ADPA_PIPE_SELECT_MASK); - temp &= ~(ADPA_VSYNC_CNTL_DISABLE | ADPA_HSYNC_CNTL_DISABLE); - /* Turn on ADPA */ - if (singlepipe & PIPE_CRT) { - xf86DrvMsg(pScrn->scrnIndex, X_WARNING, - "Enabling ADPA directly. Pipe A.\n"); - temp |= ADPA_DAC_ENABLE | ADPA_PIPE_A_SELECT; - OUTREG(ADPA, temp); - } else - if (singlepipe & (PIPE_CRT << 8)) { - xf86DrvMsg(pScrn->scrnIndex, X_WARNING, - "Enabling ADPA directly. Pipe B.\n"); - temp |= ADPA_DAC_ENABLE | ADPA_PIPE_B_SELECT; - OUTREG(ADPA, temp); - } - else { - if (!(devices & (PIPE_CRT | PIPE_CRT<<8))) { - xf86DrvMsg(pScrn->scrnIndex, X_WARNING, - "Disabling ADPA directly.\n"); - temp |= ADPA_VSYNC_CNTL_DISABLE | ADPA_HSYNC_CNTL_DISABLE; - OUTREG(ADPA, temp); - } - } - - xf86DrvMsg(pScrn->scrnIndex, X_WARNING,"Writing config directly to SWF0.\n"); - temp = INREG(SWF0); - OUTREG(SWF0, (temp & ~(0xffff)) | (devices & 0xffff)); - - if (GetDisplayDevices(pScrn) != devices) { - xf86DrvMsg(pScrn->scrnIndex, X_WARNING, - "SetDisplayDevices failed with devices 0x%x instead of 0x%x\n", - GetDisplayDevices(pScrn), devices); - return FALSE; - } - - pI830->pipeEnabled[0] = (devices & 0xff) ? TRUE : FALSE; - pI830->pipeEnabled[1] = (devices & 0xff00) ? TRUE : FALSE; - - return TRUE; -} - -static Bool -GetBIOSVersion(ScrnInfoPtr pScrn, unsigned int *version) -{ - vbeInfoPtr pVbe = I830PTR(pScrn)->pVbe; - - DPRINTF(PFX, "GetBIOSVersion\n"); - - pVbe->pInt10->num = 0x10; - pVbe->pInt10->ax = 0x5f01; - - xf86ExecX86int10_wrapper(pVbe->pInt10, pScrn); - if (Check5fStatus(pScrn, 0x5f01, pVbe->pInt10->ax)) { - *version = pVbe->pInt10->bx; - return TRUE; - } - - *version = 0; - return FALSE; -} - -static Bool -GetDevicePresence(ScrnInfoPtr pScrn, Bool *required, int *attached, - int *encoderPresent) -{ - vbeInfoPtr pVbe = I830PTR(pScrn)->pVbe; - - DPRINTF(PFX, "GetDevicePresence\n"); - - pVbe->pInt10->num = 0x10; - pVbe->pInt10->ax = 0x5f64; - pVbe->pInt10->bx = 0x200; - - xf86ExecX86int10_wrapper(pVbe->pInt10, pScrn); - if (Check5fStatus(pScrn, 0x5f64, pVbe->pInt10->ax)) { - if (required) - *required = ((pVbe->pInt10->bx & 0x1) == 0); - if (attached) - *attached = (pVbe->pInt10->cx >> 8) & 0xff; - if (encoderPresent) - *encoderPresent = pVbe->pInt10->cx & 0xff; - return TRUE; - } else - return FALSE; -} - -static Bool -GetDisplayInfo(ScrnInfoPtr pScrn, int device, Bool *attached, Bool *present, - short *x, short *y) -{ - vbeInfoPtr pVbe = I830PTR(pScrn)->pVbe; - - DPRINTF(PFX, "GetDisplayInfo: device: 0x%x\n", device); - - switch (device & 0xff) { - case PIPE_CRT: - case PIPE_TV: - case PIPE_DFP: - case PIPE_LFP: - case PIPE_CRT2: - case PIPE_TV2: - case PIPE_DFP2: - case PIPE_LFP2: - break; - default: - xf86DrvMsg(pScrn->scrnIndex, X_ERROR, - "GetDisplayInfo: invalid device: 0x%x\n", device & 0xff); - return FALSE; - } - - pVbe->pInt10->num = 0x10; - pVbe->pInt10->ax = 0x5f64; - pVbe->pInt10->bx = 0x300; - pVbe->pInt10->cx = device & 0xff; - - xf86ExecX86int10_wrapper(pVbe->pInt10, pScrn); - if (Check5fStatus(pScrn, 0x5f64, pVbe->pInt10->ax)) { - if (attached) - *attached = ((pVbe->pInt10->bx & 0x2) != 0); - if (present) - *present = ((pVbe->pInt10->bx & 0x1) != 0); - if (pVbe->pInt10->cx != (device & 0xff)) { - if (y) { - *y = pVbe->pInt10->cx & 0xffff; - } - if (x) { - *x = (pVbe->pInt10->cx >> 16) & 0xffff; - } - } - return TRUE; - } else - return FALSE; -} - -/* - * Returns a string matching the device corresponding to the first bit set - * in "device". savedDevice is then set to device with that bit cleared. - * Subsequent calls with device == -1 will use savedDevice. - */ - -static const char *displayDevices[] = { - "CRT", - "TV", - "DFP (digital flat panel)", - "LFP (local flat panel)", - "Second (second CRT)", - "TV2 (second TV)", - "DFP2 (second digital flat panel)", - "LFP2 (second local flat panel)", - NULL -}; - -static const char * -DeviceToString(int device) -{ - static int savedDevice = -1; - int bit = 0; - const char *name; - - if (device == -1) { - device = savedDevice; - bit = 0; - } - - if (device == -1) - return NULL; - - while (displayDevices[bit]) { - if (device & (1 << bit)) { - name = displayDevices[bit]; - savedDevice = device & ~(1 << bit); - bit++; - return name; - } - bit++; - } - return NULL; -} - -static void -PrintDisplayDeviceInfo(ScrnInfoPtr pScrn) -{ - I830Ptr pI830 = I830PTR(pScrn); - int pipe, n; - int displays; - - DPRINTF(PFX, "PrintDisplayDeviceInfo\n"); - - displays = pI830->operatingDevices; - if (displays == -1) { - xf86DrvMsg(pScrn->scrnIndex, X_INFO, - "No active display devices.\n"); - return; - } - - /* Check for active devices connected to each display pipe. */ - for (n = 0; n < pI830->availablePipes; n++) { - pipe = ((displays >> PIPE_SHIFT(n)) & PIPE_ACTIVE_MASK); - if (pipe) { - const char *name; - - xf86DrvMsg(pScrn->scrnIndex, X_INFO, - "Currently active displays on Pipe %c:\n", PIPE_NAME(n)); - name = DeviceToString(pipe); - do { - xf86DrvMsg(pScrn->scrnIndex, X_INFO, "\t%s\n", name); - name = DeviceToString(-1); - } while (name); - - } else { - xf86DrvMsg(pScrn->scrnIndex, X_INFO, - "No active displays on Pipe %c.\n", PIPE_NAME(n)); - } - - if (pI830->pipeDisplaySize[n].x2 != 0) { - xf86DrvMsg(pScrn->scrnIndex, X_INFO, - "Lowest common panel size for pipe %c is %d x %d\n", - PIPE_NAME(n), pI830->pipeDisplaySize[n].x2, - pI830->pipeDisplaySize[n].y2); - } else if (pI830->pipeEnabled[n] && pipe & ~PIPE_CRT_ACTIVE) { - xf86DrvMsg(pScrn->scrnIndex, X_INFO, - "No display size information available for pipe %c.\n", - PIPE_NAME(n)); - } - } -} - -static void -GetPipeSizes(ScrnInfoPtr pScrn) -{ - I830Ptr pI830 = I830PTR(pScrn); - int pipe, n; - DisplayType i; - - DPRINTF(PFX, "GetPipeSizes\n"); - - - for (n = 0; n < pI830->availablePipes; n++) { - pipe = (pI830->operatingDevices >> PIPE_SHIFT(n)) & PIPE_ACTIVE_MASK; - pI830->pipeDisplaySize[n].x1 = pI830->pipeDisplaySize[n].y1 = 0; - pI830->pipeDisplaySize[n].x2 = pI830->pipeDisplaySize[n].y2 = 4096; - for (i = 0; i < NumDisplayTypes; i++) { - if (pipe & (1 << i) & PIPE_SIZED_DISP_MASK) { - if (pI830->displaySize[i].x2 != 0) { - xf86DrvMsg(pScrn->scrnIndex, X_INFO, - "Size of device %s is %d x %d\n", - displayDevices[i], - pI830->displaySize[i].x2, - pI830->displaySize[i].y2); - if (pI830->displaySize[i].x2 < pI830->pipeDisplaySize[n].x2) - pI830->pipeDisplaySize[n].x2 = pI830->displaySize[i].x2; - if (pI830->displaySize[i].y2 < pI830->pipeDisplaySize[n].y2) - pI830->pipeDisplaySize[n].y2 = pI830->displaySize[i].y2; - } - } - } - - if (pI830->pipeDisplaySize[n].x2 == 4096) - pI830->pipeDisplaySize[n].x2 = 0; - if (pI830->pipeDisplaySize[n].y2 == 4096) - pI830->pipeDisplaySize[n].y2 = 0; - } -} - -static Bool -I830DetectDisplayDevice(ScrnInfoPtr pScrn) -{ - I830Ptr pI830 = I830PTR(pScrn); - int pipe, n; - DisplayType i; - - /* This seems to lockup some Dell BIOS'. So it's on option to turn on */ - if (pI830->displayInfo) { - xf86DrvMsg(pScrn->scrnIndex, X_INFO, - "Broken BIOSes cause the system to hang here.\n" - "\t If you encounter this problem please add \n" - "\t\t Option \"DisplayInfo\" \"FALSE\"\n" - "\t to the Device section of your XF86Config file.\n"); - for (i = 0; i < NumDisplayTypes; i++) { - if (GetDisplayInfo(pScrn, 1 << i, &pI830->displayAttached[i], - &pI830->displayPresent[i], - &pI830->displaySize[i].x2, - &pI830->displaySize[i].y2)) { - xf86DrvMsg(pScrn->scrnIndex, X_INFO, - "Display Info: %s: attached: %s, present: %s, size: " - "(%d,%d)\n", displayDevices[i], - BOOLTOSTRING(pI830->displayAttached[i]), - BOOLTOSTRING(pI830->displayPresent[i]), - pI830->displaySize[i].x2, pI830->displaySize[i].y2); - } - } - } - - /* Check for active devices connected to each display pipe. */ - for (n = 0; n < pI830->availablePipes; n++) { - pipe = ((pI830->operatingDevices >> PIPE_SHIFT(n)) & PIPE_ACTIVE_MASK); - if (pipe) - pI830->pipeEnabled[n] = TRUE; - else - pI830->pipeEnabled[n] = FALSE; - } - - GetPipeSizes(pScrn); - - return TRUE; -} - -static int -I830DetectMemory(ScrnInfoPtr pScrn) -{ - I830Ptr pI830 = I830PTR(pScrn); - PCITAG bridge; - CARD16 gmch_ctrl; - int memsize = 0; - int range; - - bridge = pciTag(0, 0, 0); /* This is always the host bridge */ - gmch_ctrl = pciReadWord(bridge, I830_GMCH_CTRL); - - /* We need to reduce the stolen size, by the GTT and the popup. - * The GTT varying according the the FbMapSize and the popup is 4KB. */ - if (IS_I965G(pI830)) - range = 512 + 4; /* Fixed 512KB size for i965 */ - else - range = (pI830->FbMapSize / MB(1)) + 4; + /* The stolen memory has the GTT at the top, and the 4KB popup below that. + * Everything else can be freely used by the graphics driver. + */ + range = gtt_size + 4; if (IS_I85X(pI830) || IS_I865G(pI830) || IS_I9XX(pI830)) { switch (gmch_ctrl & I830_GMCH_GMS_MASK) { @@ -3176,6 +491,7 @@ I830DetectMemory(ScrnInfoPtr pScrn) } else { xf86DrvMsg(pScrn->scrnIndex, X_INFO, "no video memory detected.\n"); } + return memsize; } @@ -3218,7 +534,7 @@ I830MapMem(ScrnInfoPtr pScrn) return FALSE; if (I830IsPrimary(pScrn)) - pI830->LpRing->virtual_start = pI830->FbBase + pI830->LpRing->mem.Start; + pI830->LpRing->virtual_start = pI830->FbBase + pI830->LpRing->mem->offset; return TRUE; } @@ -3245,542 +561,187 @@ I830UnmapMem(ScrnInfoPtr pScrn) return TRUE; } -#ifndef HAVE_GET_PUT_BIOSMEMSIZE -#define HAVE_GET_PUT_BIOSMEMSIZE 1 -#endif - -#if HAVE_GET_PUT_BIOSMEMSIZE -/* - * Tell the BIOS how much video memory is available. The BIOS call used - * here won't always be available. - */ -static Bool -PutBIOSMemSize(ScrnInfoPtr pScrn, int memSize) +static void +I830LoadPalette(ScrnInfoPtr pScrn, int numColors, int *indices, + LOCO * colors, VisualPtr pVisual) { - vbeInfoPtr pVbe = I830PTR(pScrn)->pVbe; + xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn); + int i,j, index; + int p; + CARD16 lut_r[256], lut_g[256], lut_b[256]; - DPRINTF(PFX, "PutBIOSMemSize: %d kB\n", memSize / 1024); + DPRINTF(PFX, "I830LoadPalette: numColors: %d\n", numColors); - pVbe->pInt10->num = 0x10; - pVbe->pInt10->ax = 0x5f11; - pVbe->pInt10->bx = 0; - pVbe->pInt10->cx = memSize / GTT_PAGE_SIZE; + for(p = 0; p < xf86_config->num_crtc; p++) { + xf86CrtcPtr crtc = xf86_config->crtc[p]; + I830CrtcPrivatePtr intel_crtc = crtc->driver_private; - xf86ExecX86int10_wrapper(pVbe->pInt10, pScrn); - return Check5fStatus(pScrn, 0x5f11, pVbe->pInt10->ax); -} + /* Initialize to the old lookup table values. */ + for (i = 0; i < 256; i++) { + lut_r[i] = intel_crtc->lut_r[i] << 8; + lut_g[i] = intel_crtc->lut_g[i] << 8; + lut_b[i] = intel_crtc->lut_b[i] << 8; + } -/* - * This reports what the previous VBEGetVBEInfo() found. Be sure to call - * VBEGetVBEInfo() after changing the BIOS memory size view. If - * a separate BIOS call is added for this, it can be put here. Only - * return a valid value if the funtionality for PutBIOSMemSize() - * is available. - */ -static int -GetBIOSMemSize(ScrnInfoPtr pScrn) -{ - I830Ptr pI830 = I830PTR(pScrn); - int memSize = KB(pI830->vbeInfo->TotalMemory * 64); + switch(pScrn->depth) { + case 15: + for (i = 0; i < numColors; i++) { + index = indices[i]; + for (j = 0; j < 8; j++) { + lut_r[index * 8 + j] = colors[index].red << 8; + lut_g[index * 8 + j] = colors[index].green << 8; + lut_b[index * 8 + j] = colors[index].blue << 8; + } + } + break; + case 16: + for (i = 0; i < numColors; i++) { + index = indices[i]; + + if (i <= 31) { + for (j = 0; j < 8; j++) { + lut_r[index * 8 + j] = colors[index].red << 8; + lut_b[index * 8 + j] = colors[index].blue << 8; + } + } - DPRINTF(PFX, "GetBIOSMemSize\n"); + for (j = 0; j < 4; j++) { + lut_g[index * 4 + j] = colors[index].green << 8; + } + } + break; + default: + for (i = 0; i < numColors; i++) { + index = indices[i]; + lut_r[index] = colors[index].red << 8; + lut_g[index] = colors[index].green << 8; + lut_b[index] = colors[index].blue << 8; + } + break; + } - if (PutBIOSMemSize(pScrn, memSize)) - return memSize; - else - return -1; -} + /* Make the change through RandR */ +#ifdef RANDR_12_INTERFACE + RRCrtcGammaSet(crtc->randr_crtc, lut_r, lut_g, lut_b); +#else + crtc->funcs->gamma_set(crtc, lut_r, lut_g, lut_b, 256); #endif + } +} -/* - * These three functions allow the video BIOS's view of the available video - * memory to be changed. This is currently implemented only for the 830 - * and 845G, which can do this via a BIOS scratch register that holds the - * BIOS's view of the (pre-reserved) memory size. If another mechanism - * is available in the future, it can be plugged in here. - * - * The mapping used for the 830/845G scratch register's low 4 bits is: - * - * 320k => 0 - * 832k => 1 - * 8000k => 8 +int +i830_output_clones (ScrnInfoPtr pScrn, int type_mask) +{ + xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR (pScrn); + int o; + int index_mask = 0; + + for (o = 0; o < config->num_output; o++) + { + xf86OutputPtr output = config->output[o]; + I830OutputPrivatePtr intel_output = output->driver_private; + if (type_mask & (1 << intel_output->type)) + index_mask |= (1 << o); + } + return index_mask; +} + +/** + * Set up the outputs according to what type of chip we are. * - * The "unusual" values are the 512k, 1M, 8M pre-reserved memory, less - * overhead, rounded down to the BIOS-reported 64k granularity. + * Some outputs may not initialize, due to allocation failure or because a + * controller chip isn't found. */ - -static Bool -SaveBIOSMemSize(ScrnInfoPtr pScrn) +static void +I830SetupOutputs(ScrnInfoPtr pScrn) { - I830Ptr pI830 = I830PTR(pScrn); + xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR (pScrn); + I830Ptr pI830 = I830PTR(pScrn); + int o; - DPRINTF(PFX, "SaveBIOSMemSize\n"); - - if (!I830IsPrimary(pScrn)) - return FALSE; + /* everyone has at least a single analog output */ + i830_crt_init(pScrn); - pI830->useSWF1 = FALSE; - -#if HAVE_GET_PUT_BIOSMEMSIZE - if ((pI830->saveBIOSMemSize = GetBIOSMemSize(pScrn)) != -1) - return TRUE; -#endif - - if (IS_I830(pI830) || IS_845G(pI830)) { - pI830->useSWF1 = TRUE; - pI830->saveSWF1 = INREG(SWF1) & 0x0f; + /* Set up integrated LVDS */ + if (IS_MOBILE(pI830) && !IS_I830(pI830)) + i830_lvds_init(pScrn); + if (IS_I9XX(pI830)) { + i830_sdvo_init(pScrn, SDVOB); + i830_sdvo_init(pScrn, SDVOC); + } else { + i830_dvo_init(pScrn); + } + if (IS_I9XX(pI830) && !IS_I915G(pI830)) + i830_tv_init(pScrn); + + for (o = 0; o < config->num_output; o++) + { + xf86OutputPtr output = config->output[o]; + I830OutputPrivatePtr intel_output = output->driver_private; + int crtc_mask = 0, clone_mask = 0; + /* - * This is for sample purposes only. pI830->saveBIOSMemSize isn't used - * when pI830->useSWF1 is TRUE. + * Valid crtcs */ - switch (pI830->saveSWF1) { - case 0: - pI830->saveBIOSMemSize = KB(320); + switch (intel_output->type) { + case I830_OUTPUT_DVO: + case I830_OUTPUT_SDVO: + crtc_mask = ((1 << 0)| + (1 << 1)); + clone_mask = ((1 << I830_OUTPUT_ANALOG) | + (1 << I830_OUTPUT_DVO) | + (1 << I830_OUTPUT_SDVO)); break; - case 1: - pI830->saveBIOSMemSize = KB(832); + case I830_OUTPUT_ANALOG: + crtc_mask = ((1 << 0)); + clone_mask = ((1 << I830_OUTPUT_ANALOG) | + (1 << I830_OUTPUT_DVO) | + (1 << I830_OUTPUT_SDVO)); break; - case 8: - pI830->saveBIOSMemSize = KB(8000); + case I830_OUTPUT_LVDS: + crtc_mask = (1 << 1); + clone_mask = (1 << I830_OUTPUT_LVDS); break; - default: - pI830->saveBIOSMemSize = 0; + case I830_OUTPUT_TVOUT: + crtc_mask = ((1 << 0) | + (1 << 1)); + clone_mask = (1 << I830_OUTPUT_TVOUT); break; } - return TRUE; + output->possible_crtcs = crtc_mask; + output->possible_clones = i830_output_clones (pScrn, clone_mask); } - return FALSE; } -/* - * TweakMemorySize() tweaks the BIOS image to set the correct size. - * Original implementation by Christian Zietz in a stand-alone tool. +/** + * Setup the CRTCs */ -static CARD32 -TweakMemorySize(ScrnInfoPtr pScrn, CARD32 newsize, Bool preinit) -{ -#define SIZE 0x10000 -#define _855_IDOFFSET (-23) -#define _845_IDOFFSET (-19) - - const char *MAGICstring = "Total time for VGA POST:"; - const int len = strlen(MAGICstring); - I830Ptr pI830 = I830PTR(pScrn); - volatile char *position; - char *biosAddr; - CARD32 oldsize; - CARD32 oldpermission; - CARD32 ret = 0; - int i,j = 0; - int reg = (IS_845G(pI830) || IS_I865G(pI830)) ? _845_DRAM_RW_CONTROL - : _855_DRAM_RW_CONTROL; - - PCITAG tag =pciTag(0,0,0); - - if (!I830IsPrimary(pScrn)) - return 0; - if(!pI830->PciInfo - || !(IS_845G(pI830) || IS_I85X(pI830) || IS_I865G(pI830))) - return 0; - if (!pI830->pVbe) - return 0; - - biosAddr = xf86int10Addr(pI830->pVbe->pInt10, - pI830->pVbe->pInt10->BIOSseg << 4); - - if (!pI830->BIOSMemSizeLoc) { - if (!preinit) - return 0; - - /* Search for MAGIC string */ - for (i = 0; i < SIZE; i++) { - if (biosAddr[i] == MAGICstring[j]) { - if (++j == len) - break; - } else { - i -= j; - j = 0; - } - } - if (j < len) return 0; - - pI830->BIOSMemSizeLoc = (i - j + 1 + (IS_845G(pI830) - ? _845_IDOFFSET : _855_IDOFFSET)); - } - - position = biosAddr + pI830->BIOSMemSizeLoc; - oldsize = *(CARD32 *)position; - - ret = oldsize - 0x21000; - - /* verify that register really contains current size */ - if (preinit && ((ret >> 16) != pI830->vbeInfo->TotalMemory)) - return 0; - - oldpermission = pciReadLong(tag, reg); - pciWriteLong(tag, reg, DRAM_WRITE | (oldpermission & 0xffff)); - - *(CARD32 *)position = newsize + 0x21000; - - if (preinit) { - /* reinitialize VBE for new size */ - if (I830IsPrimary(pScrn)) { - VBEFreeVBEInfo(pI830->vbeInfo); - vbeFree(pI830->pVbe); - pI830->pVbe = VBEInit(NULL, pI830->pEnt->index); - pI830->vbeInfo = VBEGetVBEInfo(pI830->pVbe); - } else { - I830Ptr pI8301 = I830PTR(pI830->entityPrivate->pScrn_1); - pI830->pVbe = pI8301->pVbe; - pI830->vbeInfo = pI8301->vbeInfo; - } - - /* verify that change was successful */ - if (pI830->vbeInfo->TotalMemory != (newsize >> 16)){ - ret = 0; - *(CARD32 *)position = oldsize; - } else { - pI830->BIOSMemorySize = KB(pI830->vbeInfo->TotalMemory * 64); - xf86DrvMsg(pScrn->scrnIndex, X_INFO, - "Tweak BIOS image to %d kB VideoRAM\n", - (int)(pI830->BIOSMemorySize / 1024)); - } - } - - pciWriteLong(tag, reg, oldpermission); - - return ret; -} - -static void -RestoreBIOSMemSize(ScrnInfoPtr pScrn) -{ - I830Ptr pI830 = I830PTR(pScrn); - CARD32 swf1; - - DPRINTF(PFX, "RestoreBIOSMemSize\n"); - - if (!I830IsPrimary(pScrn)) - return; - - if (TweakMemorySize(pScrn, pI830->saveBIOSMemSize,FALSE)) - return; - - if (!pI830->overrideBIOSMemSize) - return; - -#if HAVE_GET_PUT_BIOSMEMSIZE - if (!pI830->useSWF1) { - PutBIOSMemSize(pScrn, pI830->saveBIOSMemSize); - return; - } -#endif - - if ((IS_I830(pI830) || IS_845G(pI830)) && pI830->useSWF1) { - swf1 = INREG(SWF1); - swf1 &= ~0x0f; - swf1 |= (pI830->saveSWF1 & 0x0f); - OUTREG(SWF1, swf1); - } -} - -static void -SetBIOSMemSize(ScrnInfoPtr pScrn, int newSize) +static void +I830PreInitDDC(ScrnInfoPtr pScrn) { I830Ptr pI830 = I830PTR(pScrn); - unsigned long swf1; - Bool mapped; - - DPRINTF(PFX, "SetBIOSMemSize: %d kB\n", newSize / 1024); - if (!pI830->overrideBIOSMemSize) - return; - -#if HAVE_GET_PUT_BIOSMEMSIZE - if (!pI830->useSWF1) { - PutBIOSMemSize(pScrn, newSize); - return; - } -#endif - - if ((IS_I830(pI830) || IS_845G(pI830)) && pI830->useSWF1) { - unsigned long newSWF1; - - /* Need MMIO access here. */ - mapped = (pI830->MMIOBase != NULL); - if (!mapped) - I830MapMMIO(pScrn); - - if (newSize <= KB(832)) - newSWF1 = 1; - else - newSWF1 = 8; - - swf1 = INREG(SWF1); - xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Before: SWF1 is 0x%08lx\n", swf1); - swf1 &= ~0x0f; - swf1 |= (newSWF1 & 0x0f); - xf86DrvMsg(pScrn->scrnIndex, X_INFO, "After: SWF1 is 0x%08lx\n", swf1); - OUTREG(SWF1, swf1); - if (!mapped) - I830UnmapMMIO(pScrn); - } -} - -static CARD32 val8[256]; - -static void -I830LoadPalette(ScrnInfoPtr pScrn, int numColors, int *indices, - LOCO * colors, VisualPtr pVisual) -{ - I830Ptr pI830; - int i,j, index; - unsigned char r, g, b; - CARD32 val, temp; - int palreg; - int dspreg, dspbase, dspsurf; - - DPRINTF(PFX, "I830LoadPalette: numColors: %d\n", numColors); - pI830 = I830PTR(pScrn); - - if (pI830->Clone || pI830->MergedFB) { - if (!pI830->pipe == 0) { - palreg = PALETTE_A; - dspreg = DSPACNTR; - dspbase = DSPABASE; - } else { - palreg = PALETTE_B; - dspreg = DSPBCNTR; - dspbase = DSPBBASE; - } - - /* To ensure gamma is enabled we need to turn off and on the plane */ - temp = INREG(dspreg); - OUTREG(dspreg, temp & ~(1<<31)); - OUTREG(dspbase, INREG(dspbase)); - OUTREG(dspreg, temp | DISPPLANE_GAMMA_ENABLE); - OUTREG(dspbase, INREG(dspbase)); - - /* It seems that an initial read is needed. */ - temp = INREG(palreg); - - switch(pScrn->depth) { - case 15: - for (i = 0; i < numColors; i++) { - index = indices[i]; - r = colors[index].red; - g = colors[index].green; - b = colors[index].blue; - val = (r << 16) | (g << 8) | b; - for (j = 0; j < 8; j++) { - OUTREG(palreg + index * 32 + (j * 4), val); - } - } - break; - case 16: - for (i = 0; i < numColors; i++) { - index = indices[i]; - r = colors[index / 2].red; - g = colors[index].green; - b = colors[index / 2].blue; - - val = (r << 16) | (g << 8) | b; - OUTREG(palreg + index * 16, val); - OUTREG(palreg + index * 16 + 4, val); - OUTREG(palreg + index * 16 + 8, val); - OUTREG(palreg + index * 16 + 12, val); - - if (index <= 31) { - r = colors[index].red; - g = colors[(index * 2) + 1].green; - b = colors[index].blue; - - val = (r << 16) | (g << 8) | b; - OUTREG(palreg + index * 32, val); - OUTREG(palreg + index * 32 + 4, val); - OUTREG(palreg + index * 32 + 8, val); - OUTREG(palreg + index * 32 + 12, val); - } - } - break; - default: - for(i = 0; i < numColors; i++) { - index = indices[i]; - r = colors[index].red; - g = colors[index].green; - b = colors[index].blue; - val = (r << 16) | (g << 8) | b; - OUTREG(palreg + index * 4, val); - } - break; - } - } - - if (pI830->pipe == 0) { - palreg = PALETTE_A; - dspreg = DSPACNTR; - dspbase = DSPABASE; - dspsurf = DSPASURF; + if (!xf86LoadSubModule(pScrn, "ddc")) { + pI830->ddc2 = FALSE; } else { - palreg = PALETTE_B; - dspreg = DSPBCNTR; - dspbase = DSPBBASE; - dspsurf = DSPBSURF; + xf86LoaderReqSymLists(I810ddcSymbols, NULL); + pI830->ddc2 = TRUE; } - /* To ensure gamma is enabled we need to turn off and on the plane */ - temp = INREG(dspreg); - OUTREG(dspreg, temp & ~(1<<31)); - OUTREG(dspbase, INREG(dspbase)); - OUTREG(dspreg, temp | DISPPLANE_GAMMA_ENABLE); - OUTREG(dspbase, INREG(dspbase)); - if (IS_I965G(pI830)) - OUTREG(dspsurf, INREG(dspsurf)); + /* DDC can use I2C bus */ + /* Load I2C if we have the code to use it */ + if (pI830->ddc2) { + if (xf86LoadSubModule(pScrn, "i2c")) { + xf86LoaderReqSymLists(I810i2cSymbols, NULL); - /* It seems that an initial read is needed. */ - temp = INREG(palreg); - - switch(pScrn->depth) { - case 15: - for (i = 0; i < numColors; i++) { - index = indices[i]; - r = colors[index].red; - g = colors[index].green; - b = colors[index].blue; - val = (r << 16) | (g << 8) | b; - for (j = 0; j < 8; j++) { - OUTREG(palreg + index * 32 + (j * 4), val); - } - } - break; - case 16: - for (i = 0; i < numColors; i++) { - index = indices[i]; - r = colors[index / 2].red; - g = colors[index].green; - b = colors[index / 2].blue; - - val = (r << 16) | (g << 8) | b; - OUTREG(palreg + index * 16, val); - OUTREG(palreg + index * 16 + 4, val); - OUTREG(palreg + index * 16 + 8, val); - OUTREG(palreg + index * 16 + 12, val); - - if (index <= 31) { - r = colors[index].red; - g = colors[(index * 2) + 1].green; - b = colors[index].blue; - - val = (r << 16) | (g << 8) | b; - OUTREG(palreg + index * 32, val); - OUTREG(palreg + index * 32 + 4, val); - OUTREG(palreg + index * 32 + 8, val); - OUTREG(palreg + index * 32 + 12, val); - } - } - break; - default: -#if 1 - /* Dual head 8bpp modes seem to squish the primary's cmap - reload */ - if (I830IsPrimary(pScrn) && xf86IsEntityShared(pScrn->entityList[0]) && - pScrn->depth == 8) { - for(i = 0; i < numColors; i++) { - index = indices[i]; - r = colors[index].red; - g = colors[index].green; - b = colors[index].blue; - val8[index] = (r << 16) | (g << 8) | b; - } - } -#endif - for(i = 0; i < numColors; i++) { - index = indices[i]; - r = colors[index].red; - g = colors[index].green; - b = colors[index].blue; - val = (r << 16) | (g << 8) | b; - OUTREG(palreg + index * 4, val); -#if 1 - /* Dual head 8bpp modes seem to squish the primary's cmap - reload */ - if (!I830IsPrimary(pScrn) && xf86IsEntityShared(pScrn->entityList[0]) && - pScrn->depth == 8) { - if (palreg == PALETTE_A) - OUTREG(PALETTE_B + index * 4, val8[index]); - else - OUTREG(PALETTE_A + index * 4, val8[index]); - } -#endif - } - break; - } -} - -static int -I830UseDDC(ScrnInfoPtr pScrn) -{ - xf86MonPtr DDC = (xf86MonPtr)(pScrn->monitor->DDC); - struct detailed_monitor_section* detMon; - struct monitor_ranges *mon_range = NULL; - int i; - - if (!DDC) return 0; - - /* Now change the hsync/vrefresh values of the current monitor to - * match those of DDC */ - for (i = 0; i < 4; i++) { - detMon = &DDC->det_mon[i]; - if(detMon->type == DS_RANGES) - mon_range = &detMon->section.ranges; - } - - if (!mon_range || mon_range->min_h == 0 || mon_range->max_h == 0 || - mon_range->min_v == 0 || mon_range->max_v == 0) - return 0; /* bad ddc */ - - xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Using detected DDC timings\n"); - xf86DrvMsg(pScrn->scrnIndex, X_INFO, "\tHorizSync %d-%d\n", - mon_range->min_h, mon_range->max_h); - xf86DrvMsg(pScrn->scrnIndex, X_INFO, "\tVertRefresh %d-%d\n", - mon_range->min_v, mon_range->max_v); -#define DDC_SYNC_TOLERANCE SYNC_TOLERANCE - if (pScrn->monitor->nHsync > 0) { - for (i = 0; i < pScrn->monitor->nHsync; i++) { - if ((1.0 - DDC_SYNC_TOLERANCE) * mon_range->min_h > - pScrn->monitor->hsync[i].lo || - (1.0 + DDC_SYNC_TOLERANCE) * mon_range->max_h < - pScrn->monitor->hsync[i].hi) { - xf86DrvMsg(pScrn->scrnIndex, X_WARNING, - "config file hsync range %g-%gkHz not within DDC " - "hsync range %d-%dkHz\n", - pScrn->monitor->hsync[i].lo, pScrn->monitor->hsync[i].hi, - mon_range->min_h, mon_range->max_h); - } - pScrn->monitor->hsync[i].lo = mon_range->min_h; - pScrn->monitor->hsync[i].hi = mon_range->max_h; - } - } - - if (pScrn->monitor->nVrefresh > 0) { - for (i=0; i<pScrn->monitor->nVrefresh; i++) { - if ((1.0 - DDC_SYNC_TOLERANCE) * mon_range->min_v > - pScrn->monitor->vrefresh[i].lo || - (1.0 + DDC_SYNC_TOLERANCE) * mon_range->max_v < - pScrn->monitor->vrefresh[i].hi) { - xf86DrvMsg(pScrn->scrnIndex, X_WARNING, - "config file vrefresh range %g-%gHz not within DDC " - "vrefresh range %d-%dHz\n", - pScrn->monitor->vrefresh[i].lo, pScrn->monitor->vrefresh[i].hi, - mon_range->min_v, mon_range->max_v); - } - pScrn->monitor->vrefresh[i].lo = mon_range->min_v; - pScrn->monitor->vrefresh[i].hi = mon_range->max_v; + pI830->ddc2 = TRUE; + } else { + pI830->ddc2 = FALSE; } } - - return mon_range->max_clock; } static void @@ -3789,39 +750,19 @@ PreInitCleanup(ScrnInfoPtr pScrn) I830Ptr pI830 = I830PTR(pScrn); if (I830IsPrimary(pScrn)) { - SetPipeAccess(pScrn); - - pI830->entityPrivate->pScrn_1 = NULL; - if (pI830->LpRing) - xfree(pI830->LpRing); - pI830->LpRing = NULL; - if (pI830->CursorMem) - xfree(pI830->CursorMem); - pI830->CursorMem = NULL; - if (pI830->CursorMemARGB) - xfree(pI830->CursorMemARGB); - pI830->CursorMemARGB = NULL; - if (pI830->OverlayMem) - xfree(pI830->OverlayMem); - pI830->OverlayMem = NULL; - if (pI830->overlayOn) - xfree(pI830->overlayOn); - pI830->overlayOn = NULL; - if (pI830->used3D) - xfree(pI830->used3D); - pI830->used3D = NULL; + if (pI830->entityPrivate) + pI830->entityPrivate->pScrn_1 = NULL; } else { if (pI830->entityPrivate) pI830->entityPrivate->pScrn_2 = NULL; } - RestoreBIOSMemSize(pScrn); if (pI830->swfSaved) { OUTREG(SWF0, pI830->saveSWF0); OUTREG(SWF4, pI830->saveSWF4); } if (pI830->MMIOBase) I830UnmapMMIO(pScrn); - I830BIOSFreeRec(pScrn); + I830FreeRec(pScrn); } Bool @@ -3837,53 +778,68 @@ I830IsPrimary(ScrnInfoPtr pScrn) return TRUE; } -#ifdef XF86DRI -static void -I830ReduceMMSize(ScrnInfoPtr pScrn, unsigned long newSize, - const char *reason) +static Bool +i830_xf86crtc_resize (ScrnInfoPtr scrn, int width, int height) +{ + scrn->virtualX = width; + scrn->virtualY = height; + return TRUE; +} + +static const xf86CrtcConfigFuncsRec i830_xf86crtc_config_funcs = { + i830_xf86crtc_resize +}; + +#define HOTKEY_BIOS_SWITCH 0 +#define HOTKEY_DRIVER_NOTIFY 1 + +/** + * Controls the BIOS's behavior on hotkey switch. + * + * If the mode is HOTKEY_BIOS_SWITCH, the BIOS will be set to do a mode switch + * on its own and update the state in the scratch register. + * If the mode is HOTKEY_DRIVER_NOTIFY, the BIOS won't do a mode switch and + * will just update the state to represent what it would have been switched to. + */ +static void +i830SetHotkeyControl(ScrnInfoPtr pScrn, int mode) { I830Ptr pI830 = I830PTR(pScrn); + CARD8 gr18; - newSize = ROUND_DOWN_TO(newSize, GTT_PAGE_SIZE); - if (newSize / GTT_PAGE_SIZE > I830_MM_MINPAGES) { - pI830->mmSize = newSize / 1024; - xf86DrvMsg(pScrn->scrnIndex, X_WARNING, - "DRM memory manager aperture size is reduced to %d kiB\n" - "\t%s\n", pI830->mmSize, reason); - } else { - xf86DrvMsg(pScrn->scrnIndex, X_WARNING, - "DRM memory manager will be disabled\n\t%s\n", reason); - pI830->mmSize = 0; - } + gr18 = pI830->readControl(pI830, GRX, 0x18); + if (mode == HOTKEY_BIOS_SWITCH) + gr18 &= ~HOTKEY_VBIOS_SWITCH_BLOCK; + else + gr18 |= HOTKEY_VBIOS_SWITCH_BLOCK; + pI830->writeControl(pI830, GRX, 0x18, gr18); } -#endif - +/** + * This is called per zaphod head (so usually just once) to do initialization + * before the Screen is created. + * + * This code generally covers probing, module loading, option handling + * card mapping, and RandR setup. + */ static Bool -I830BIOSPreInit(ScrnInfoPtr pScrn, int flags) +I830PreInit(ScrnInfoPtr pScrn, int flags) { + xf86CrtcConfigPtr xf86_config; vgaHWPtr hwp; I830Ptr pI830; MessageType from = X_PROBED; rgb defaultWeight = { 0, 0, 0 }; EntityInfoPtr pEnt; I830EntPtr pI830Ent = NULL; - int mem, memsize; int flags24; - int defmon = 0; - int i, n; - int DDCclock = 0, DDCclock2 = 0; + int i; char *s; - DisplayModePtr p, pMon; - xf86MonPtr monitor = NULL; - pointer pDDCModule = NULL, pVBEModule = NULL; - Bool enable; + pointer pVBEModule = NULL; const char *chipname; - unsigned int ver; - char v[5]; -#ifdef XF86DRI - unsigned long savedMMSize; -#endif + Bool enable; + int num_pipe; + int max_width, max_height; if (pScrn->numEntities != 1) return FALSE; @@ -3901,7 +857,7 @@ I830BIOSPreInit(ScrnInfoPtr pScrn, int flags) pEnt = xf86GetEntityInfo(pScrn->entityList[0]); if (flags & PROBE_DETECT) { - I830BIOSProbeDDC(pScrn, pEnt->index); + I830ProbeDDC(pScrn, pEnt->index); return TRUE; } @@ -3915,14 +871,14 @@ I830BIOSPreInit(ScrnInfoPtr pScrn, int flags) return FALSE; /* Allocate driverPrivate */ - if (!I830BIOSGetRec(pScrn)) + if (!I830GetRec(pScrn)) return FALSE; pI830 = I830PTR(pScrn); pI830->SaveGeneration = -1; pI830->pEnt = pEnt; - pI830->displayWidth = 640; /* default it */ + pScrn->displayWidth = 640; /* default it */ if (pI830->pEnt->location.type != BUS_PCI) return FALSE; @@ -4004,25 +960,14 @@ I830BIOSPreInit(ScrnInfoPtr pScrn, int flags) /* Process the options */ xf86CollectOptions(pScrn, NULL); - if (!(pI830->Options = xalloc(sizeof(I830BIOSOptions)))) + if (!(pI830->Options = xalloc(sizeof(I830Options)))) return FALSE; - memcpy(pI830->Options, I830BIOSOptions, sizeof(I830BIOSOptions)); + memcpy(pI830->Options, I830Options, sizeof(I830Options)); xf86ProcessOptions(pScrn->scrnIndex, pScrn->options, pI830->Options); /* We have to use PIO to probe, because we haven't mapped yet. */ I830SetPIOAccess(pI830); - /* Initialize VBE record */ - if (I830IsPrimary(pScrn)) { - if ((pI830->pVbe = VBEInit(NULL, pI830->pEnt->index)) == NULL) { - xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "VBE initialization failed.\n"); - return FALSE; - } - } else { - I830Ptr pI8301 = I830PTR(pI830->entityPrivate->pScrn_1); - pI830->pVbe = pI8301->pVbe; - } - switch (pI830->PciInfo->chipType) { case PCI_CHIP_I830_M: chipname = "830M"; @@ -4089,19 +1034,12 @@ I830BIOSPreInit(ScrnInfoPtr pScrn, int flags) xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Integrated Graphics Chipset: Intel(R) %s\n", chipname); - if (I830IsPrimary(pScrn)) { - pI830->vbeInfo = VBEGetVBEInfo(pI830->pVbe); - } else { - I830Ptr pI8301 = I830PTR(pI830->entityPrivate->pScrn_1); - pI830->vbeInfo = pI8301->vbeInfo; - } - /* Set the Chipset and ChipRev, allowing config file entries to override. */ if (pI830->pEnt->device->chipset && *pI830->pEnt->device->chipset) { pScrn->chipset = pI830->pEnt->device->chipset; from = X_CONFIG; } else if (pI830->pEnt->device->chipID >= 0) { - pScrn->chipset = (char *)xf86TokenToString(I830BIOSChipsets, + pScrn->chipset = (char *)xf86TokenToString(I830Chipsets, pI830->pEnt->device->chipID); from = X_CONFIG; xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "ChipID override: 0x%04X\n", @@ -4109,7 +1047,7 @@ I830BIOSPreInit(ScrnInfoPtr pScrn, int flags) pI830->PciInfo->chipType = pI830->pEnt->device->chipID; } else { from = X_PROBED; - pScrn->chipset = (char *)xf86TokenToString(I830BIOSChipsets, + pScrn->chipset = (char *)xf86TokenToString(I830Chipsets, pI830->PciInfo->chipType); } @@ -4164,9 +1102,29 @@ I830BIOSPreInit(ScrnInfoPtr pScrn, int flags) xf86DrvMsg(pScrn->scrnIndex, from, "IO registers at addr 0x%lX\n", (unsigned long)pI830->MMIOAddr); + /* Allocate an xf86CrtcConfig */ + xf86CrtcConfigInit (pScrn, &i830_xf86crtc_config_funcs); + xf86_config = XF86_CRTC_CONFIG_PTR(pScrn); + + /* See i830_exa.c comments for why we limit the framebuffer size like this. + */ + if (IS_I965G(pI830)) { + max_width = 8192; + max_height = 8192; + } else { + max_width = 2048; + max_height = 2048; + } + xf86CrtcSetSizeRange (pScrn, 320, 200, max_width, max_height); + /* Some of the probing needs MMIO access, so map it here. */ I830MapMMIO(pScrn); + xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Hardware state on X startup:\n"); + i830DumpRegs (pScrn); + + i830TakeRegSnapshot(pScrn); + #if 1 pI830->saveSWF0 = INREG(SWF0); pI830->saveSWF4 = INREG(SWF4); @@ -4193,75 +1151,63 @@ I830BIOSPreInit(ScrnInfoPtr pScrn, int flags) } } else { if (IS_I9XX(pI830)) { - if (pI830->PciInfo->memBase[2] & 0x08000000) - pI830->FbMapSize = 0x8000000; /* 128MB aperture */ - else - pI830->FbMapSize = 0x10000000; /* 256MB aperture */ - - if (pI830->PciInfo->chipType == PCI_CHIP_E7221_G) - pI830->FbMapSize = 0x8000000; /* 128MB aperture */ - } else - /* 128MB aperture for later chips */ + pI830->FbMapSize = 1UL << pciGetBaseSize(pI830->PciTag, 2, TRUE, + NULL); + } else { + /* 128MB aperture for later i8xx series. */ pI830->FbMapSize = 0x8000000; + } } if (pI830->PciInfo->chipType == PCI_CHIP_E7221_G) - pI830->availablePipes = 1; + num_pipe = 1; else if (IS_MOBILE(pI830) || IS_I9XX(pI830)) - pI830->availablePipes = 2; + num_pipe = 2; else - pI830->availablePipes = 1; + num_pipe = 1; xf86DrvMsg(pScrn->scrnIndex, X_INFO, "%d display pipe%s available.\n", - pI830->availablePipes, pI830->availablePipes > 1 ? "s" : ""); - - /* - * Get the pre-allocated (stolen) memory size. - */ - pI830->StolenMemory.Size = I830DetectMemory(pScrn); - pI830->StolenMemory.Start = 0; - pI830->StolenMemory.End = pI830->StolenMemory.Size; - - /* Sanity check: compare with what the BIOS thinks. */ - if (pI830->vbeInfo->TotalMemory != pI830->StolenMemory.Size / 1024 / 64) { - xf86DrvMsg(pScrn->scrnIndex, X_WARNING, - "Detected stolen memory (%ld kB) doesn't match what the BIOS" - " reports (%d kB)\n", - ROUND_DOWN_TO(pI830->StolenMemory.Size / 1024, 64), - pI830->vbeInfo->TotalMemory * 64); - } + num_pipe, num_pipe > 1 ? "s" : ""); - /* Find the maximum amount of agpgart memory available. */ - if (I830IsPrimary(pScrn)) { - mem = I830CheckAvailableMemory(pScrn); - pI830->StolenOnly = FALSE; - } else { - /* videoRam isn't used on the second head, but faked */ - mem = pI830->entityPrivate->pScrn_1->videoRam; - pI830->StolenOnly = TRUE; + if (xf86ReturnOptValBool(pI830->Options, OPTION_NOACCEL, FALSE)) { + pI830->noAccel = TRUE; } - if (mem <= 0) { - if (pI830->StolenMemory.Size <= 0) { - /* Shouldn't happen. */ - xf86DrvMsg(pScrn->scrnIndex, X_ERROR, - "/dev/agpgart is either not available, or no memory " - "is available\nfor allocation, " - "and no pre-allocated memory is available.\n"); - PreInitCleanup(pScrn); - return FALSE; - } - xf86DrvMsg(pScrn->scrnIndex, X_WARNING, - "/dev/agpgart is either not available, or no memory " - "is available\nfor allocation. " - "Using pre-allocated memory only.\n"); - mem = 0; - pI830->StolenOnly = TRUE; + /* + * The ugliness below: + * If either XAA or EXA (exclusive) is compiled in, default to it. + * + * If both are compiled in, and the user didn't specify noAccel, use the + * config option AccelMethod to determine which to use, defaulting to XAA + * if none is specified, or if the string was unrecognized. + * + * All this *could* go away if we removed XAA support from this driver, + * for example. :) + */ + if (!pI830->noAccel) { +#if (defined(I830_USE_EXA) && defined(I830_USE_XAA)) || !defined(I830_USE_EXA) + pI830->useEXA = FALSE; +#else + pI830->useEXA = TRUE; +#endif +#if defined(I830_USE_XAA) && defined(I830_USE_EXA) + int from = X_DEFAULT; + if ((s = (char *)xf86GetOptValString(pI830->Options, + OPTION_ACCELMETHOD))) { + if (!xf86NameCmp(s, "EXA")) { + from = X_CONFIG; + pI830->useEXA = TRUE; + } + else if (!xf86NameCmp(s, "XAA")) { + from = X_CONFIG; + pI830->useEXA = FALSE; + } + } +#endif + xf86DrvMsg(pScrn->scrnIndex, from, "Using %s for acceleration\n", + pI830->useEXA ? "EXA" : "XAA"); } - if (xf86ReturnOptValBool(pI830->Options, OPTION_NOACCEL, FALSE)) { - pI830->noAccel = TRUE; - } if (xf86ReturnOptValBool(pI830->Options, OPTION_SW_CURSOR, FALSE)) { pI830->SWCursor = TRUE; } @@ -4286,8 +1232,11 @@ I830BIOSPreInit(ScrnInfoPtr pScrn, int flags) if (!pI830->directRenderingDisabled) { Bool tmp = FALSE; - if (IS_I965G(pI830)) - pI830->mmModeFlags |= I830_KERNEL_TEX; + pI830->mmModeFlags |= I830_KERNEL_TEX; +#ifdef XF86DRI_MM + if (!IS_I965G(pI830)) + pI830->mmModeFlags |= I830_KERNEL_MM; +#endif from = X_PROBED; if (xf86GetOptValBool(pI830->Options, @@ -4299,14 +1248,12 @@ I830BIOSPreInit(ScrnInfoPtr pScrn, int flags) pI830->mmModeFlags &= ~I830_KERNEL_TEX; } } - if (from == X_CONFIG || - (pI830->mmModeFlags & I830_KERNEL_TEX)) { - xf86DrvMsg(pScrn->scrnIndex, from, - "Will %stry to allocate texture pool " - "for old Mesa 3D driver.\n", - (pI830->mmModeFlags & I830_KERNEL_TEX) ? - "" : "not "); - } + xf86DrvMsg(pScrn->scrnIndex, from, + "Will %stry to allocate texture pool " + "for old Mesa 3D driver.\n", + (pI830->mmModeFlags & I830_KERNEL_TEX) ? + "" : "not "); + pI830->mmSize = I830_MM_MAXSIZE; from = X_INFO; if (xf86GetOptValInteger(pI830->Options, OPTION_INTELMMSIZE, @@ -4323,181 +1270,46 @@ I830BIOSPreInit(ScrnInfoPtr pScrn, int flags) #endif pI830->LinearAlloc = 0; - if (xf86GetOptValInteger(pI830->Options, OPTION_LINEARALLOC, + if (xf86GetOptValULong(pI830->Options, OPTION_LINEARALLOC, &(pI830->LinearAlloc))) { - if (pI830->LinearAlloc > 0) - xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Allocating %dKbytes of memory\n", - pI830->LinearAlloc); - else + if (pI830->LinearAlloc < 0) pI830->LinearAlloc = 0; } - pI830->fixedPipe = -1; - if ((s = xf86GetOptValString(pI830->Options, OPTION_FIXEDPIPE)) && - I830IsPrimary(pScrn)) { - - if (strstr(s, "A") || strstr(s, "a") || strstr(s, "0")) - pI830->fixedPipe = 0; - else if (strstr(s, "B") || strstr(s, "b") || strstr(s, "1")) - pI830->fixedPipe = 1; - } - - pI830->MergedFB = - xf86ReturnOptValBool(pI830->Options, OPTION_MERGEDFB, FALSE); - - pI830->IntelXinerama = - xf86ReturnOptValBool(pI830->Options, OPTION_INTELXINERAMA, TRUE); - - pI830->MonType1 = PIPE_NONE; - pI830->MonType2 = PIPE_NONE; - pI830->specifiedMonitor = FALSE; - - if ((s = xf86GetOptValString(pI830->Options, OPTION_MONITOR_LAYOUT)) && - I830IsPrimary(pScrn)) { - char *Mon1; - char *Mon2; - char *sub; - - Mon1 = strtok(s, ","); - Mon2 = strtok(NULL, ","); - - if (Mon1) { - sub = strtok(Mon1, "+"); - do { - if (strcmp(sub, "NONE") == 0) - pI830->MonType1 |= PIPE_NONE; - else if (strcmp(sub, "CRT") == 0) - pI830->MonType1 |= PIPE_CRT; - else if (strcmp(sub, "TV") == 0) - pI830->MonType1 |= PIPE_TV; - else if (strcmp(sub, "DFP") == 0) - pI830->MonType1 |= PIPE_DFP; - else if (strcmp(sub, "LFP") == 0) - pI830->MonType1 |= PIPE_LFP; - else if (strcmp(sub, "Second") == 0) - pI830->MonType1 |= PIPE_CRT2; - else if (strcmp(sub, "TV2") == 0) - pI830->MonType1 |= PIPE_TV2; - else if (strcmp(sub, "DFP2") == 0) - pI830->MonType1 |= PIPE_DFP2; - else if (strcmp(sub, "LFP2") == 0) - pI830->MonType1 |= PIPE_LFP2; - else - xf86DrvMsg(pScrn->scrnIndex, X_WARNING, - "Invalid Monitor type specified for Pipe A\n"); - - sub = strtok(NULL, "+"); - } while (sub); - } - - if (Mon2) { - sub = strtok(Mon2, "+"); - do { - if (strcmp(sub, "NONE") == 0) - pI830->MonType2 |= PIPE_NONE; - else if (strcmp(sub, "CRT") == 0) - pI830->MonType2 |= PIPE_CRT; - else if (strcmp(sub, "TV") == 0) - pI830->MonType2 |= PIPE_TV; - else if (strcmp(sub, "DFP") == 0) - pI830->MonType2 |= PIPE_DFP; - else if (strcmp(sub, "LFP") == 0) - pI830->MonType2 |= PIPE_LFP; - else if (strcmp(sub, "Second") == 0) - pI830->MonType2 |= PIPE_CRT2; - else if (strcmp(sub, "TV2") == 0) - pI830->MonType2 |= PIPE_TV2; - else if (strcmp(sub, "DFP2") == 0) - pI830->MonType2 |= PIPE_DFP2; - else if (strcmp(sub, "LFP2") == 0) - pI830->MonType2 |= PIPE_LFP2; - else - xf86DrvMsg(pScrn->scrnIndex, X_WARNING, - "Invalid Monitor type specified for Pipe B\n"); - - sub = strtok(NULL, "+"); - } while (sub); - } - - if (pI830->availablePipes == 1 && pI830->MonType2 != PIPE_NONE) { - xf86DrvMsg(pScrn->scrnIndex, X_ERROR, - "Monitor 2 cannot be specified on single pipe devices\n"); - return FALSE; - } - - if (pI830->MonType1 == PIPE_NONE && pI830->MonType2 == PIPE_NONE) { - xf86DrvMsg(pScrn->scrnIndex, X_ERROR, - "Monitor 1 and 2 cannot be type NONE\n"); - return FALSE; - } - - pI830->specifiedMonitor = TRUE; + I830PreInitDDC(pScrn); + for (i = 0; i < num_pipe; i++) { + i830_crtc_init(pScrn, i); } + I830SetupOutputs(pScrn); - if (!pI830->MergedFB && - xf86ReturnOptValBool(pI830->Options, OPTION_CLONE, FALSE)) { - if (pI830->availablePipes == 1) { - xf86DrvMsg(pScrn->scrnIndex, X_ERROR, - "Can't enable Clone Mode because this is a single pipe device\n"); - PreInitCleanup(pScrn); - return FALSE; - } - if (pI830->entityPrivate) { - xf86DrvMsg(pScrn->scrnIndex, X_ERROR, - "Can't enable Clone Mode because second head is configured\n"); - PreInitCleanup(pScrn); - return FALSE; - } - xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Enabling Clone Mode\n"); - pI830->Clone = TRUE; - } + SaveHWState(pScrn); + /* Do an initial detection of the outputs while none are configured on yet. + * This will give us some likely legitimate response for later if both + * pipes are already allocated and we're asked to do a detect. + */ + for (i = 0; i < xf86_config->num_output; i++) + { + xf86OutputPtr output = xf86_config->output[i]; - pI830->CloneRefresh = 60; /* default to 60Hz */ - if (xf86GetOptValInteger(pI830->Options, OPTION_CLONE_REFRESH, - &(pI830->CloneRefresh))) { - xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Clone Monitor Refresh Rate %d\n", - pI830->CloneRefresh); + output->status = (*output->funcs->detect) (output); } - /* 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"); + if (!xf86InitialConfiguration (pScrn, FALSE)) + { + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "No valid modes.\n"); + RestoreHWState(pScrn); PreInitCleanup(pScrn); return FALSE; } + RestoreHWState(pScrn); - if ((pI830->entityPrivate && I830IsPrimary(pScrn)) || pI830->Clone || - pI830->MergedFB) { - if ((!xf86GetOptValString(pI830->Options, OPTION_MONITOR_LAYOUT))) { - xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "You must have a MonitorLayout " - "defined for use in a DualHead, Clone or MergedFB setup.\n"); - PreInitCleanup(pScrn); - return FALSE; - } - - if (pI830->MonType1 == PIPE_NONE || pI830->MonType2 == PIPE_NONE) { - xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Monitor 1 or Monitor 2 " - "cannot be type NONE in DualHead, Clone or MergedFB setup.\n"); - PreInitCleanup(pScrn); - return FALSE; - } - } - + /* XXX This should go away, replaced by xf86Crtc.c support for it */ pI830->rotation = RR_Rotate_0; - if ((s = xf86GetOptValString(pI830->Options, OPTION_ROTATE))) { - pI830->InitialRotation = 0; - if(!xf86NameCmp(s, "CW") || !xf86NameCmp(s, "270")) - pI830->InitialRotation = 270; - if(!xf86NameCmp(s, "CCW") || !xf86NameCmp(s, "90")) - pI830->InitialRotation = 90; - if(!xf86NameCmp(s, "180")) - pI830->InitialRotation = 180; - } /* * Let's setup the mobile systems to check the lid status */ - if (IS_MOBILE(pI830) && !pI830->MergedFB) { + if (IS_MOBILE(pI830)) { pI830->checkDevices = TRUE; if (!xf86ReturnOptValBool(pI830->Options, OPTION_CHECKDEVICES, TRUE)) { @@ -4515,164 +1327,7 @@ I830BIOSPreInit(ScrnInfoPtr pScrn, int flags) } else pI830->checkDevices = FALSE; - /* - * The "VideoRam" config file parameter specifies the total amount of - * memory that will be used/allocated. When agpgart support isn't - * available (StolenOnly == TRUE), this is limited to the amount of - * pre-allocated ("stolen") memory. - */ - - /* - * Default to I830_DEFAULT_VIDEOMEM_2D (8192KB) for 2D-only, - * or I830_DEFAULT_VIDEOMEM_3D (32768KB) for 3D. If the stolen memory - * amount is higher, default to it rounded up to the nearest MB. This - * guarantees that by default there will be at least some run-time - * space for things that need a physical address. - * But, we double the amounts when dual head is enabled, and therefore - * for 2D-only we use 16384KB, and 3D we use 65536KB. The VideoRAM - * for the second head is never used, as the primary head does the - * allocation. - */ - if (!pI830->pEnt->device->videoRam) { - from = X_DEFAULT; -#ifdef XF86DRI - if (!pI830->directRenderingDisabled) - pScrn->videoRam = I830_DEFAULT_VIDEOMEM_3D; - else -#endif - pScrn->videoRam = I830_DEFAULT_VIDEOMEM_2D; - - if (xf86IsEntityShared(pScrn->entityList[0])) { - if (I830IsPrimary(pScrn)) - pScrn->videoRam += I830_DEFAULT_VIDEOMEM_2D; - else - pScrn->videoRam = I830_MAXIMUM_VBIOS_MEM; - } - - if (pI830->StolenMemory.Size / 1024 > pScrn->videoRam) - pScrn->videoRam = ROUND_TO(pI830->StolenMemory.Size / 1024, 1024); - } else { - from = X_CONFIG; - pScrn->videoRam = pI830->pEnt->device->videoRam; - } - - /* Make sure it's on a page boundary */ - if (pScrn->videoRam & (GTT_PAGE_SIZE - 1)) { - xf86DrvMsg(pScrn->scrnIndex, X_WARNING, - "VideoRAM reduced to %d kByte " - "(page aligned - was %d)\n", pScrn->videoRam & ~(GTT_PAGE_SIZE - 1), pScrn->videoRam); - pScrn->videoRam &= ~(GTT_PAGE_SIZE - 1); - } - - DPRINTF(PFX, - "Available memory: %dk\n" - "Requested memory: %dk\n", mem, pScrn->videoRam); - - - if (mem + (pI830->StolenMemory.Size / 1024) < pScrn->videoRam) { - pScrn->videoRam = mem + (pI830->StolenMemory.Size / 1024); - from = X_PROBED; - if (mem + (pI830->StolenMemory.Size / 1024) < - pI830->pEnt->device->videoRam) { - xf86DrvMsg(pScrn->scrnIndex, X_WARNING, - "VideoRAM reduced to %d kByte " - "(limited to available sysmem)\n", pScrn->videoRam); - } - } - - if (pScrn->videoRam > pI830->FbMapSize / 1024) { - pScrn->videoRam = pI830->FbMapSize / 1024; - if (pI830->FbMapSize / 1024 < pI830->pEnt->device->videoRam) - xf86DrvMsg(pScrn->scrnIndex, X_WARNING, - "VideoRam reduced to %d kByte (limited to aperture size)\n", - pScrn->videoRam); - } - - if (mem > 0) { - /* - * If the reserved (BIOS accessible) memory is less than the desired - * amount, try to increase it. So far this is only implemented for - * the 845G and 830, but those details are handled in SetBIOSMemSize(). - * - * The BIOS-accessible amount is only important for setting video - * modes. The maximum amount we try to set is limited to what would - * be enough for 1920x1440 with a 2048 pitch. - * - * If ALLOCATE_ALL_BIOSMEM is enabled in i830_memory.c, all of the - * BIOS-aware memory will get allocated. If it isn't then it may - * not be, and in that case there is an assumption that the video - * BIOS won't attempt to access memory beyond what is needed for - * modes that are actually used. ALLOCATE_ALL_BIOSMEM is enabled by - * default. - */ - - /* Try to keep HW cursor and Overlay amounts separate from this. */ - int reserve = (HWCURSOR_SIZE + HWCURSOR_SIZE_ARGB + OVERLAY_SIZE) / 1024; - - if (pScrn->videoRam - reserve >= I830_MAXIMUM_VBIOS_MEM) - pI830->newBIOSMemSize = KB(I830_MAXIMUM_VBIOS_MEM); - else - pI830->newBIOSMemSize = - KB(ROUND_DOWN_TO(pScrn->videoRam - reserve, 64)); - if (pI830->vbeInfo->TotalMemory * 64 < pI830->newBIOSMemSize / 1024) { - - xf86DrvMsg(pScrn->scrnIndex, X_INFO, - "Will attempt to tell the BIOS that there is " - "%d kB VideoRAM\n", pI830->newBIOSMemSize / 1024); - if (SaveBIOSMemSize(pScrn)) { - pI830->overrideBIOSMemSize = TRUE; - SetBIOSMemSize(pScrn, pI830->newBIOSMemSize); - - if (I830IsPrimary(pScrn)) { - VBEFreeVBEInfo(pI830->vbeInfo); - vbeFree(pI830->pVbe); - pI830->pVbe = VBEInit(NULL, pI830->pEnt->index); - pI830->vbeInfo = VBEGetVBEInfo(pI830->pVbe); - } else { - I830Ptr pI8301 = I830PTR(pI830->entityPrivate->pScrn_1); - pI830->pVbe = pI8301->pVbe; - pI830->vbeInfo = pI8301->vbeInfo; - } - - pI830->BIOSMemorySize = KB(pI830->vbeInfo->TotalMemory * 64); - xf86DrvMsg(pScrn->scrnIndex, X_INFO, - "BIOS now sees %ld kB VideoRAM\n", - pI830->BIOSMemorySize / 1024); - } else if ((pI830->saveBIOSMemSize - = TweakMemorySize(pScrn, pI830->newBIOSMemSize,TRUE)) != 0) - pI830->overrideBIOSMemSize = TRUE; - else { - xf86DrvMsg(pScrn->scrnIndex, X_INFO, - "BIOS view of memory size can't be changed " - "(this is not an error).\n"); - } - } - } - - xf86DrvMsg(pScrn->scrnIndex, X_PROBED, - "Pre-allocated VideoRAM: %ld kByte\n", - pI830->StolenMemory.Size / 1024); - xf86DrvMsg(pScrn->scrnIndex, from, "VideoRAM: %d kByte\n", - pScrn->videoRam); - - pI830->TotalVideoRam = KB(pScrn->videoRam); - - /* - * If the requested videoRam amount is less than the stolen memory size, - * reduce the stolen memory size accordingly. - */ - if (pI830->StolenMemory.Size > pI830->TotalVideoRam) { - pI830->StolenMemory.Size = pI830->TotalVideoRam; - pI830->StolenMemory.End = pI830->TotalVideoRam; - } - - if (xf86GetOptValInteger(pI830->Options, OPTION_CACHE_LINES, - &(pI830->CacheLines))) { - xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Requested %d cache lines\n", - pI830->CacheLines); - } else { - pI830->CacheLines = -1; - } + pI830->stolen_size = I830DetectMemory(pScrn); pI830->XvDisabled = !xf86ReturnOptValBool(pI830->Options, OPTION_XVIDEO, TRUE); @@ -4705,101 +1360,6 @@ I830BIOSPreInit(ScrnInfoPtr pScrn, int flags) } #endif - if (pI830->MergedFB) { - pI830->pScrn_2 = xalloc(sizeof(ScrnInfoRec)); - - if(!pI830->pScrn_2) { - xf86DrvMsg(pScrn->scrnIndex, X_WARNING, "Failed to allocate memory for MergedFB mode. Disabling.\n"); - pI830->MergedFB = FALSE; - } else { - memcpy(pI830->pScrn_2, pScrn, sizeof(ScrnInfoRec)); - } - if((s = (char *)xf86GetOptValString(pI830->Options, OPTION_SECONDPOSITION))) { - int result; - int ival; - Bool valid = FALSE; - char *tempstr = xalloc(strlen(s) + 1); - result = sscanf(s, "%s %d", tempstr, &ival); - if(result >= 1) { - if(!xf86NameCmp(tempstr,"LeftOf")) { - pI830->SecondPosition = PosLeftOf; - valid = TRUE; - if(result == 2) { - if(ival < 0) pI830->FirstYOffs = -ival; - else pI830->SecondYOffs = ival; - } - pI830->SecondIsScrn0 = TRUE; - } else if(!xf86NameCmp(tempstr,"RightOf")) { - pI830->SecondPosition = PosRightOf; - valid = TRUE; - if(result == 2) { - if(ival < 0) pI830->FirstYOffs = -ival; - else pI830->SecondYOffs = ival; - } - pI830->SecondIsScrn0 = FALSE; - } else if(!xf86NameCmp(tempstr,"Above")) { - pI830->SecondPosition = PosAbove; - valid = TRUE; - if(result == 2) { - if(ival < 0) pI830->FirstXOffs = -ival; - else pI830->SecondXOffs = ival; - } - pI830->SecondIsScrn0 = FALSE; - } else if(!xf86NameCmp(tempstr,"Below")) { - pI830->SecondPosition = PosBelow; - valid = TRUE; - if(result == 2) { - if(ival < 0) pI830->FirstXOffs = -ival; - else pI830->SecondXOffs = ival; - } - pI830->SecondIsScrn0 = TRUE; - } - } - if(!valid) { - xf86DrvMsg(pScrn->scrnIndex, X_INFO, - "Valid parameters are: \"RightOf\", \"LeftOf\", \"Above\" or \"Below\"\n"); - } - xfree(tempstr); - } - - /* If OPTION_SECONDISSCRN0 is true then swap screens */ - if(xf86GetOptValBool(pI830->Options, OPTION_SECONDISSCRN0, TRUE)) { - if (pI830->SecondIsScrn0) - pI830->SecondIsScrn0 = FALSE; - else - pI830->SecondIsScrn0 = TRUE; - } - - /* Set pI830->NonRect according to OPTION_MERGEDFBNONRECT */ - if(xf86GetOptValBool(pI830->Options, OPTION_MERGEDFBNONRECT, TRUE)) - pI830->NonRect = TRUE; - else - pI830->NonRect = FALSE; - - /* Set pI830->MouseRestrictions according to OPTION_MERGEDFBMOUSER */ - if(xf86GetOptValBool(pI830->Options, OPTION_MERGEDFBMOUSER, TRUE)) - pI830->MouseRestrictions = TRUE; - else - pI830->MouseRestrictions = FALSE; - - if((s = (char *)xf86GetOptValString(pI830->Options, OPTION_METAMODES))) { - pI830->MetaModes = xalloc(strlen(s) + 1); - if(pI830->MetaModes) - memcpy(pI830->MetaModes, s, strlen(s) + 1); - } - if((s = (char *)xf86GetOptValString(pI830->Options, OPTION_SECONDHSYNC))) { - pI830->SecondHSync = xalloc(strlen(s) + 1); - if(pI830->SecondHSync) - memcpy(pI830->SecondHSync, s, strlen(s) + 1); - } - if((s = (char *)xf86GetOptValString(pI830->Options, OPTION_SECONDVREFRESH))) { - pI830->SecondVRefresh = xalloc(strlen(s) + 1); - if(pI830->SecondVRefresh) - memcpy(pI830->SecondVRefresh, s, strlen(s) + 1); - } - } - - /* * If the driver can do gamma correction, it should call xf86SetGamma() here. */ @@ -4813,184 +1373,6 @@ I830BIOSPreInit(ScrnInfoPtr pScrn, int flags) } } - GetBIOSVersion(pScrn, &ver); - - v[0] = (ver & 0xff000000) >> 24; - v[1] = (ver & 0x00ff0000) >> 16; - v[2] = (ver & 0x0000ff00) >> 8; - v[3] = (ver & 0x000000ff) >> 0; - v[4] = 0; - - pI830->bios_version = atoi(v); - - xf86DrvMsg(pScrn->scrnIndex, X_INFO, "BIOS Build: %d\n",pI830->bios_version); - - if (IS_I9XX(pI830)) - pI830->newPipeSwitch = TRUE; - else - if (pI830->availablePipes == 2 && pI830->bios_version >= 3062) { - /* BIOS build 3062 changed the pipe switching functionality */ - pI830->newPipeSwitch = TRUE; - xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Using new Pipe switch code\n"); - } else - pI830->newPipeSwitch = FALSE; - - pI830->devicePresence = FALSE; - from = X_DEFAULT; - if (xf86ReturnOptValBool(pI830->Options, OPTION_DEVICE_PRESENCE, FALSE)) { - pI830->devicePresence = TRUE; - from = X_CONFIG; - } - xf86DrvMsg(pScrn->scrnIndex, from, "Device Presence: %s.\n", - pI830->devicePresence ? "enabled" : "disabled"); - - /* This performs an active detect of the currently attached monitors - * or, at least it's meant to..... alas it doesn't seem to always work. - */ - if (pI830->devicePresence) { - int req, att, enc; - GetDevicePresence(pScrn, &req, &att, &enc); - for (i = 0; i < NumDisplayTypes; i++) { - xf86DrvMsg(pScrn->scrnIndex, X_INFO, - "Display Presence: %s: attached: %s, encoder: %s\n", - displayDevices[i], - BOOLTOSTRING(((1<<i) & att)>>i), - BOOLTOSTRING(((1<<i) & enc)>>i)); - } - } - - /* Save old configuration of detected devices */ - pI830->savedDevices = GetDisplayDevices(pScrn); - - if (I830IsPrimary(pScrn)) { - pI830->pipe = pI830->origPipe = GetBIOSPipe(pScrn); - - /* Override */ - if (pI830->fixedPipe != -1) { - if (xf86IsEntityShared(pScrn->entityList[0]) || pI830->Clone || - pI830->MergedFB) { - pI830->pipe = pI830->fixedPipe; - xf86DrvMsg(pScrn->scrnIndex, X_INFO, - "Fixed Pipe setting primary to pipe %s.\n", - pI830->fixedPipe ? "B" : "A"); - } - } - - /* If the monitors aren't setup, read from the current config */ - if (pI830->MonType1 == PIPE_NONE && pI830->MonType2 == PIPE_NONE) { - pI830->MonType1 = pI830->savedDevices & 0xff; - pI830->MonType2 = (pI830->savedDevices & 0xff00) >> 8; - } else { - /* Here, we've switched pipes from our primary */ - if (pI830->MonType1 == PIPE_NONE && pI830->pipe == 0) - pI830->pipe = 1; - if (pI830->MonType2 == PIPE_NONE && pI830->pipe == 1) - pI830->pipe = 0; - } - - pI830->operatingDevices = (pI830->MonType2 << 8) | pI830->MonType1; - - if (!xf86IsEntityShared(pScrn->entityList[0]) && !pI830->Clone && - !pI830->MergedFB) { - /* If we're not dual head, clone or mergedfb, turn off the - * second head if monitorlayout is also specified. - */ - - if (pI830->pipe == 0) - pI830->operatingDevices = pI830->MonType1; - else - pI830->operatingDevices = pI830->MonType2 << 8; - } - - if (pI830->pipe != pI830->origPipe) - xf86DrvMsg(pScrn->scrnIndex, X_WARNING, - "Primary Pipe has been switched from original pipe (%s to %s)\n", - pI830->origPipe ? "B" : "A", pI830->pipe ? "B" : "A"); - } else { - I830Ptr pI8301 = I830PTR(pI830->entityPrivate->pScrn_1); - pI830->operatingDevices = pI8301->operatingDevices; - pI830->pipe = !pI8301->pipe; - pI830->MonType1 = pI8301->MonType1; - pI830->MonType2 = pI8301->MonType2; - } - - /* Buggy BIOS 3066 is known to cause this, so turn this off */ - if (pI830->bios_version == 3066) { - pI830->displayInfo = FALSE; - xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Detected Broken Video BIOS, turning off displayInfo.\n"); - } else - pI830->displayInfo = TRUE; - from = X_DEFAULT; - if (!xf86ReturnOptValBool(pI830->Options, OPTION_DISPLAY_INFO, TRUE)) { - pI830->displayInfo = FALSE; - from = X_CONFIG; - } - if (xf86ReturnOptValBool(pI830->Options, OPTION_DISPLAY_INFO, FALSE)) { - pI830->displayInfo = TRUE; - from = X_CONFIG; - } - xf86DrvMsg(pScrn->scrnIndex, from, "Display Info: %s.\n", - pI830->displayInfo ? "enabled" : "disabled"); - - if (!I830DetectDisplayDevice(pScrn)) { - xf86DrvMsg(pScrn->scrnIndex, X_ERROR, - "Couldn't detect display devices.\n"); - PreInitCleanup(pScrn); - return FALSE; - } - - if (I830IsPrimary(pScrn)) { - if (!SetDisplayDevices(pScrn, pI830->operatingDevices)) { - xf86DrvMsg(pScrn->scrnIndex, X_ERROR, - "Failed to switch to monitor configuration (0x%x)\n", - pI830->operatingDevices); - xf86DrvMsg(pScrn->scrnIndex, X_ERROR, - "Please check the devices specified in your MonitorLayout\n"); - xf86DrvMsg(pScrn->scrnIndex, X_ERROR, - "is configured correctly.\n"); - PreInitCleanup(pScrn); - return FALSE; - } - } - - PrintDisplayDeviceInfo(pScrn); - - if (xf86IsEntityShared(pScrn->entityList[0])) { - if (!I830IsPrimary(pScrn)) { - /* This could be made to work with a little more fiddling */ - pI830->directRenderingDisabled = TRUE; - - xf86DrvMsg(pScrn->scrnIndex, from, "Secondary head is using Pipe %s\n", - pI830->pipe ? "B" : "A"); - } else { - xf86DrvMsg(pScrn->scrnIndex, from, "Primary head is using Pipe %s\n", - pI830->pipe ? "B" : "A"); - } - } else { - xf86DrvMsg(pScrn->scrnIndex, from, "Display is using Pipe %s\n", - pI830->pipe ? "B" : "A"); - } - - /* Alloc our pointers for the primary head */ - if (I830IsPrimary(pScrn)) { - pI830->LpRing = xalloc(sizeof(I830RingBuffer)); - pI830->CursorMem = xalloc(sizeof(I830MemRange)); - pI830->CursorMemARGB = xalloc(sizeof(I830MemRange)); - pI830->OverlayMem = xalloc(sizeof(I830MemRange)); - pI830->overlayOn = xalloc(sizeof(Bool)); - pI830->used3D = xalloc(sizeof(int)); - if (!pI830->LpRing || !pI830->CursorMem || !pI830->CursorMemARGB || - !pI830->OverlayMem || !pI830->overlayOn || !pI830->used3D) { - xf86DrvMsg(pScrn->scrnIndex, X_ERROR, - "Could not allocate primary data structures.\n"); - PreInitCleanup(pScrn); - return FALSE; - } - *pI830->overlayOn = FALSE; - if (pI830->entityPrivate) - pI830->entityPrivate->XvInUse = -1; - } - /* Check if the HW cursor needs physical address. */ if (IS_MOBILE(pI830) || IS_I9XX(pI830)) pI830->CursorNeedsPhysical = TRUE; @@ -5000,9 +1382,6 @@ I830BIOSPreInit(ScrnInfoPtr pScrn, int flags) if (IS_I965G(pI830)) pI830->CursorNeedsPhysical = FALSE; - /* Force ring buffer to be in low memory for all chipsets */ - pI830->NeedRingBufferLow = TRUE; - /* * XXX If we knew the pre-initialised GTT format for certain, we could * probably figure out the physical address even in the StolenOnly case. @@ -5021,602 +1400,25 @@ I830BIOSPreInit(ScrnInfoPtr pScrn, int flags) pI830->SWCursor = TRUE; } - /* - * Reduce the maximum videoram available for video modes by the ring buffer, - * minimum scratch space and HW cursor amounts. - */ - if (!pI830->SWCursor) { - pScrn->videoRam -= (HWCURSOR_SIZE / 1024); - pScrn->videoRam -= (HWCURSOR_SIZE_ARGB / 1024); - } - if (!pI830->XvDisabled) - pScrn->videoRam -= (OVERLAY_SIZE / 1024); - if (!pI830->noAccel) { - pScrn->videoRam -= (PRIMARY_RINGBUFFER_SIZE / 1024); - pScrn->videoRam -= (MIN_SCRATCH_BUFFER_SIZE / 1024); - } - - xf86DrvMsg(pScrn->scrnIndex, X_PROBED, - "Maximum frambuffer space: %d kByte\n", pScrn->videoRam); - - SetPipeAccess(pScrn); - - /* Check we have an LFP connected, before trying to - * read PanelID information. */ - if ( (pI830->pipe == 1 && pI830->operatingDevices & (PIPE_LFP << 8)) || - (pI830->pipe == 0 && pI830->operatingDevices & PIPE_LFP) ) - vbeDoPanelID(pI830->pVbe); - - pDDCModule = xf86LoadSubModule(pScrn, "ddc"); - - monitor = vbeDoEDID(pI830->pVbe, pDDCModule); - - if ((pScrn->monitor->DDC = monitor) != NULL) { - xf86PrintEDID(monitor); - xf86SetDDCproperties(pScrn, monitor); - } - - if(pI830->MergedFB) { - pI830->pScrn_2->monitor = xalloc(sizeof(MonRec)); - if(pI830->pScrn_2->monitor) { - DisplayModePtr tempm = NULL, currentm = NULL, newm = NULL; - memcpy(pI830->pScrn_2->monitor, pScrn->monitor, sizeof(MonRec)); - pI830->pScrn_2->monitor->DDC = NULL; - pI830->pScrn_2->monitor->Modes = NULL; - pI830->pScrn_2->monitor->id = (char *)SecondMonitorName; - tempm = pScrn->monitor->Modes; - while(tempm) { - if(!(newm = xalloc(sizeof(DisplayModeRec)))) break; - memcpy(newm, tempm, sizeof(DisplayModeRec)); - if(!(newm->name = xalloc(strlen(tempm->name) + 1))) { - xfree(newm); - break; - } - strcpy(newm->name, tempm->name); - if(!pI830->pScrn_2->monitor->Modes) - pI830->pScrn_2->monitor->Modes = newm; - if(currentm) { - currentm->next = newm; - newm->prev = currentm; - } - currentm = newm; - tempm = tempm->next; - } - if(pI830->SecondHSync) { - pI830->pScrn_2->monitor->nHsync = - I830StrToRanges(pI830->pScrn_2->monitor->hsync, pI830->SecondHSync, MAX_HSYNC); - } - if(pI830->SecondVRefresh) { - pI830->pScrn_2->monitor->nVrefresh = - I830StrToRanges(pI830->pScrn_2->monitor->vrefresh, pI830->SecondVRefresh, MAX_VREFRESH); - } - SetBIOSPipe(pScrn, !pI830->pipe); - pI830->pVbe->ddc = DDC_UNCHECKED; - xf86DrvMsg(pScrn->scrnIndex, X_INFO, - "Probing DDC data for second head\n"); - if((monitor = vbeDoEDID(pI830->pVbe, pDDCModule))) { - xf86PrintEDID(monitor); - xf86SetDDCproperties(pI830->pScrn_2, monitor); - pI830->pScrn_2->monitor->DDC = monitor; - /* use DDC data if no ranges in config file */ - if(!pI830->SecondHSync) { - pI830->pScrn_2->monitor->nHsync = 0; - } - if(!pI830->SecondVRefresh) { - pI830->pScrn_2->monitor->nVrefresh = 0; - } - } - SetPipeAccess(pScrn); - } else { - xf86DrvMsg(pScrn->scrnIndex, X_ERROR, - "Failed to allocate memory for second monitor.\n"); - if(pI830->pScrn_2) - xfree(pI830->pScrn_2); - pI830->pScrn_2 = NULL; - pI830->MergedFB = FALSE; - } - } - - xf86UnloadSubModule(pDDCModule); - - /* XXX Move this to a header. */ -#define VIDEO_BIOS_SCRATCH 0x18 - -#if 1 - /* - * XXX This should be in ScreenInit/EnterVT. PreInit should not leave the - * state changed. - */ - /* Enable hot keys by writing the proper value to GR18 */ + if (!xf86RandR12PreInit (pScrn)) { - CARD8 gr18; - - gr18 = pI830->readControl(pI830, GRX, VIDEO_BIOS_SCRATCH); - gr18 &= ~0x80; /* - * Clear Hot key bit so that Video - * BIOS performs the hot key - * servicing - */ - pI830->writeControl(pI830, GRX, VIDEO_BIOS_SCRATCH, gr18); - } -#endif - - pI830->useExtendedRefresh = FALSE; - - if (xf86IsEntityShared(pScrn->entityList[0]) || pI830->Clone || - pI830->MergedFB) { - int pipe = - (pI830->operatingDevices >> PIPE_SHIFT(pI830->pipe)) & PIPE_ACTIVE_MASK; - if (pipe & ~PIPE_CRT_ACTIVE) { - 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; - } - /* - * Some desktop platforms might not have 0x5f05, so useExtendedRefresh - * would need to be set to FALSE for those cases. - */ - if (!pI830->vesa->useDefaultRefresh) - pI830->useExtendedRefresh = TRUE; - } else { - for (i = 0; i < pI830->availablePipes; i++) { - int pipe = - (pI830->operatingDevices >> PIPE_SHIFT(i)) & PIPE_ACTIVE_MASK; - if (pipe & ~PIPE_CRT_ACTIVE) { - 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(i)); - pI830->vesa->useDefaultRefresh = TRUE; - } - /* - * Some desktop platforms might not have 0x5f05, so useExtendedRefresh - * would need to be set to FALSE for those cases. - */ - if (!pI830->vesa->useDefaultRefresh) - pI830->useExtendedRefresh = TRUE; - } - } - - if (pI830->useExtendedRefresh && !pI830->vesa->useDefaultRefresh) { - xf86DrvMsg(pScrn->scrnIndex, X_INFO, - "Will use BIOS call 0x5f05 to set refresh rates for CRTs.\n"); - } - - /* - * Limit videoram available for mode selection to what the video - * BIOS can see. - */ - if (pScrn->videoRam > (pI830->vbeInfo->TotalMemory * 64)) - memsize = pI830->vbeInfo->TotalMemory * 64; - else - memsize = pScrn->videoRam; - xf86DrvMsg(pScrn->scrnIndex, X_PROBED, - "Maximum space available for video modes: %d kByte\n", memsize); - - /* By now, we should have had some monitor settings, but if not, we - * need to setup some defaults. These are used in common/xf86Modes.c - * so we'll use them here for GetModePool, and that's all. - * We unset them after the call, so we can report 'defaults' as being - * used through the common layer. - */ -#define DEFAULT_HSYNC_LO 28 -#define DEFAULT_HSYNC_HI 33 -#define DEFAULT_VREFRESH_LO 43 -#define DEFAULT_VREFRESH_HI 72 - - if (pScrn->monitor->nHsync == 0) { - pScrn->monitor->hsync[0].lo = DEFAULT_HSYNC_LO; - pScrn->monitor->hsync[0].hi = DEFAULT_HSYNC_HI; - pScrn->monitor->nHsync = 1; - defmon |= 1; - } - - if (pScrn->monitor->nVrefresh == 0) { - pScrn->monitor->vrefresh[0].lo = DEFAULT_VREFRESH_LO; - pScrn->monitor->vrefresh[0].hi = DEFAULT_VREFRESH_HI; - pScrn->monitor->nVrefresh = 1; - defmon |= 2; - } - - DDCclock = I830UseDDC(pScrn); - - if (pI830->MergedFB) - DDCclock2 = I830UseDDC(pI830->pScrn_2); - - /* - * Note: VBE modes (> 0x7f) won't work with Intel's extended BIOS - * functions. - */ - pScrn->modePool = I830GetModePool(pScrn, pI830->pVbe, pI830->vbeInfo); - - if (!pScrn->modePool) { - xf86DrvMsg(pScrn->scrnIndex, X_ERROR, - "No Video BIOS modes for chosen depth.\n"); - PreInitCleanup(pScrn); - return FALSE; - } - - if (pI830->MergedFB) { - SetBIOSPipe(pScrn, !pI830->pipe); - xf86DrvMsg(pScrn->scrnIndex, X_INFO, - "Retrieving mode pool for second head.\n"); - pI830->pScrn_2->modePool = I830GetModePool(pI830->pScrn_2, pI830->pVbe, pI830->vbeInfo); - - if (!pI830->pScrn_2->modePool) { - xf86DrvMsg(pScrn->scrnIndex, X_ERROR, - "No Video BIOS modes for chosen depth.\n"); - PreInitCleanup(pScrn); - return FALSE; - } - SetPipeAccess(pScrn); - } - - /* This may look a little weird, but to notify that we're using the - * default hsync/vrefresh we need to unset what we just set ..... - */ - if (defmon & 1) { - pScrn->monitor->hsync[0].lo = 0; - pScrn->monitor->hsync[0].hi = 0; - pScrn->monitor->nHsync = 0; - } - - if (defmon & 2) { - pScrn->monitor->vrefresh[0].lo = 0; - pScrn->monitor->vrefresh[0].hi = 0; - pScrn->monitor->nVrefresh = 0; - } - - SetPipeAccess(pScrn); - VBESetModeNames(pScrn->modePool); - if (pI830->MergedFB) - VBESetModeNames(pI830->pScrn_2->modePool); - - - /* - * XXX DDC information: There's code in xf86ValidateModes - * (VBEValidateModes) to set monitor defaults based on DDC information - * where available. If we need something that does better than this, - * there's code in vesa/vesa.c. - */ - - /* XXX Need to get relevant modes and virtual parameters. */ - /* Do the mode validation without regard to special scanline pitches. */ - SetPipeAccess(pScrn); - n = VBEValidateModes(pScrn, NULL, pScrn->display->modes, NULL, - NULL, 0, MAX_DISPLAY_PITCH, 1, - 0, MAX_DISPLAY_HEIGHT, - pScrn->display->virtualX, - pScrn->display->virtualY, - memsize, LOOKUP_BEST_REFRESH); - if (n <= 0) { - xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "No valid modes.\n"); + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "RandR initialization failure\n"); PreInitCleanup(pScrn); return FALSE; - } - - if (pI830->MergedFB) { - n = VBEValidateModes(pI830->pScrn_2, NULL, pI830->pScrn_2->display->modes, NULL, - NULL, 0, MAX_DISPLAY_PITCH, 1, - 0, MAX_DISPLAY_HEIGHT, - pScrn->display->virtualX, - pScrn->display->virtualY, - memsize, LOOKUP_BEST_REFRESH); - if (n <= 0) { - xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "No valid modes.\n"); - PreInitCleanup(pScrn); - return FALSE; - } - } - - /* Only use this if we've got DDC available */ - if (DDCclock > 0) { - p = pScrn->modes; - if (p == NULL) - return FALSE; - do { - int Clock = 100000000; /* incredible value */ - - if (p->status == MODE_OK) { - for (pMon = pScrn->monitor->Modes; pMon != NULL; pMon = pMon->next) { - if ((pMon->HDisplay != p->HDisplay) || - (pMon->VDisplay != p->VDisplay) || - (pMon->Flags & (V_INTERLACE | V_DBLSCAN | V_CLKDIV2))) - continue; - - /* Find lowest supported Clock for this resolution */ - if (Clock > pMon->Clock) - Clock = pMon->Clock; - } - - if (Clock != 100000000 && DDCclock < 2550 && Clock / 1000.0 > DDCclock) { - ErrorF("(%s,%s) mode clock %gMHz exceeds DDC maximum %dMHz\n", - p->name, pScrn->monitor->id, - Clock/1000.0, DDCclock); - p->status = MODE_BAD; - } - } - p = p->next; - } while (p != NULL && p != pScrn->modes); - } - - /* Only use this if we've got DDC available */ - if (DDCclock2 > 0) { - p = pI830->pScrn_2->modes; - if (p == NULL) - return FALSE; - do { - int Clock = 100000000; /* incredible value */ - - if (p->status == MODE_OK) { - for (pMon = pI830->pScrn_2->monitor->Modes; pMon != NULL; pMon = pMon->next) { - if ((pMon->HDisplay != p->HDisplay) || - (pMon->VDisplay != p->VDisplay) || - (pMon->Flags & (V_INTERLACE | V_DBLSCAN | V_CLKDIV2))) - continue; - - /* Find lowest supported Clock for this resolution */ - if (Clock > pMon->Clock) - Clock = pMon->Clock; - } - - if (Clock != 100000000 && DDCclock2 < 2550 && Clock / 1000.0 > DDCclock2) { - ErrorF("(%s,%s) mode clock %gMHz exceeds DDC maximum %dMHz\n", - p->name, pI830->pScrn_2->monitor->id, - Clock/1000.0, DDCclock2); - p->status = MODE_BAD; - } - } - p = p->next; - } while (p != NULL && p != pI830->pScrn_2->modes); - } - - xf86PruneDriverModes(pScrn); + } if (pScrn->modes == NULL) { xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "No modes.\n"); PreInitCleanup(pScrn); return FALSE; } - - if (pI830->MergedFB) { - DisplayModePtr old_modes, cur_mode; - - xf86PruneDriverModes(pI830->pScrn_2); - - if (pI830->pScrn_2->modes == NULL) { - xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "No modes.\n"); - PreInitCleanup(pScrn); - return FALSE; - } - - old_modes = pScrn->modes; - cur_mode = pScrn->currentMode; - - xf86DrvMsg(pScrn->scrnIndex, X_INFO, "MergedFB: Generating mode list\n"); - - pScrn->modes = I830GenerateModeList(pScrn, pI830->MetaModes, - old_modes, pI830->pScrn_2->modes, - pI830->SecondPosition); - - if(!pScrn->modes) { - xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "No modes. Disabling MergedFB.\n"); - pScrn->modes = old_modes; - pScrn->currentMode = cur_mode; - pI830->MergedFB = FALSE; - } - } - - /* Now we check the VESA BIOS's displayWidth and reset if necessary */ - p = pScrn->modes; - do { - I830ModePrivatePtr mp = (I830ModePrivatePtr) p->Private; - VbeModeInfoBlock *modeInfo; - - /* Get BytesPerScanline so we can reset displayWidth */ - if ((modeInfo = VBEGetModeInfo(pI830->pVbe, mp->vbeData.mode))) { - if (pScrn->displayWidth < modeInfo->BytesPerScanline / pI830->cpp) { - xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Correcting stride (%d -> %d)\n", pScrn->displayWidth, modeInfo->BytesPerScanline); - pScrn->displayWidth = modeInfo->BytesPerScanline / pI830->cpp; - } - } - p = p->next; - } while (p != NULL && p != pScrn->modes); - pScrn->currentMode = pScrn->modes; - if (pI830->MergedFB) { - /* If no virtual dimension was given by the user, - * calculate a sane one now. Adapts pScrn->virtualX, - * pScrn->virtualY and pScrn->displayWidth. - */ - I830RecalcDefaultVirtualSize(pScrn); - - pScrn->modes = pScrn->modes->next; /* We get the last from GenerateModeList(), skip to first */ - pScrn->currentMode = pScrn->modes; - pI830->currentMode = pScrn->currentMode; - } - -#ifndef USE_PITCHES -#define USE_PITCHES 1 -#endif - pI830->disableTiling = FALSE; - - /* - * If DRI is potentially usable, check if there is enough memory available - * for it, and if there's also enough to allow tiling to be enabled. - */ - -#if defined(XF86DRI) - if (!I830CheckDRIAvailable(pScrn)) { - pI830->directRenderingDisabled = TRUE; - pI830->mmSize = 0; - } else if (pScrn->videoRam > pI830->FbMapSize / 1024 - pI830->mmSize) { - I830ReduceMMSize(pScrn, pI830->FbMapSize - KB(pScrn->videoRam), - "to make room for video memory"); - } - - if (I830IsPrimary(pScrn) && !pI830->directRenderingDisabled) { - int savedDisplayWidth = pScrn->displayWidth; - int memNeeded = 0; - /* Good pitches to allow tiling. Don't care about pitches < 1024. */ - static const int pitches[] = { -/* - 128 * 2, - 128 * 4, -*/ - 128 * 8, - 128 * 16, - 128 * 32, - 128 * 64, - 0 - }; - -#ifdef I830_XV - /* - * Set this so that the overlay allocation is factored in when - * appropriate. - */ - pI830->XvEnabled = !pI830->XvDisabled; -#endif - - for (i = 0; pitches[i] != 0; i++) { -#if USE_PITCHES - if (pitches[i] >= pScrn->displayWidth) { - pScrn->displayWidth = pitches[i]; - break; - } -#else - if (pitches[i] == pScrn->displayWidth) - break; -#endif - } - - /* - * If the displayWidth is a tilable pitch, test if there's enough - * memory available to enable tiling. - */ - savedMMSize = pI830->mmSize; - if (pScrn->displayWidth == pitches[i]) { - retry_dryrun: - I830ResetAllocations(pScrn, 0); - if (I830Allocate2DMemory(pScrn, ALLOCATE_DRY_RUN | ALLOC_INITIAL) && - I830Allocate3DMemory(pScrn, ALLOCATE_DRY_RUN)) { - memNeeded = I830GetExcessMemoryAllocations(pScrn); - if (memNeeded > 0 || pI830->MemoryAperture.Size < 0) { - if (memNeeded > 0) { - xf86DrvMsg(pScrn->scrnIndex, X_INFO, - "%d kBytes additional video memory is " - "required to\n\tenable tiling mode for DRI.\n", - (memNeeded + 1023) / 1024); - } - if (pI830->MemoryAperture.Size < 0) { - if (KB(pI830->mmSize) > I830_MM_MINPAGES * GTT_PAGE_SIZE) { - I830ReduceMMSize(pScrn, I830_MM_MINPAGES * GTT_PAGE_SIZE, - "to make room in AGP aperture for tiling."); - goto retry_dryrun; - } - - xf86DrvMsg(pScrn->scrnIndex, X_WARNING, - "Allocation with DRI tiling enabled would " - "exceed the\n" - "\tmemory aperture size (%ld kB) by %ld kB.\n" - "\tReduce VideoRam amount to avoid this!\n", - pI830->FbMapSize / 1024, - -pI830->MemoryAperture.Size / 1024); - } - pScrn->displayWidth = savedDisplayWidth; - pI830->allowPageFlip = FALSE; - } else if (pScrn->displayWidth != savedDisplayWidth) { - xf86DrvMsg(pScrn->scrnIndex, X_INFO, - "Increasing the scanline pitch to allow tiling mode " - "(%d -> %d).\n", - savedDisplayWidth, pScrn->displayWidth); - } - } else { - memNeeded = 0; - xf86DrvMsg(pScrn->scrnIndex, X_WARNING, - "Unexpected dry run allocation failure (1).\n"); - } - } - if (memNeeded > 0 || pI830->MemoryAperture.Size < 0) { - /* - * Tiling can't be enabled. Check if there's enough memory for DRI - * without tiling. - */ - pI830->mmSize = savedMMSize; - pI830->disableTiling = TRUE; - retry_dryrun2: - I830ResetAllocations(pScrn, 0); - if (I830Allocate2DMemory(pScrn, ALLOCATE_DRY_RUN | ALLOC_INITIAL) && - I830Allocate3DMemory(pScrn, ALLOCATE_DRY_RUN | ALLOC_NO_TILING)) { - memNeeded = I830GetExcessMemoryAllocations(pScrn); - if (memNeeded > 0 || pI830->MemoryAperture.Size < 0) { - if (memNeeded > 0) { - xf86DrvMsg(pScrn->scrnIndex, X_INFO, - "%d kBytes additional video memory is required " - "to enable DRI.\n", - (memNeeded + 1023) / 1024); - } - if (pI830->MemoryAperture.Size < 0) { - if (KB(pI830->mmSize) > I830_MM_MINPAGES * GTT_PAGE_SIZE) { - I830ReduceMMSize(pScrn, I830_MM_MINPAGES * GTT_PAGE_SIZE, - "to save AGP aperture space for video memory."); - goto retry_dryrun2; - } - xf86DrvMsg(pScrn->scrnIndex, X_WARNING, - "Allocation with DRI enabled would " - "exceed the\n" - "\tmemory aperture size (%ld kB) by %ld kB.\n" - "\tReduce VideoRam amount to avoid this!\n", - pI830->FbMapSize / 1024, - -pI830->MemoryAperture.Size / 1024); - } - pI830->mmSize = 0; - pI830->directRenderingDisabled = TRUE; - xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Disabling DRI.\n"); - } - } else { - xf86DrvMsg(pScrn->scrnIndex, X_WARNING, - "Unexpected dry run allocation failure (2).\n"); - } - } - } else -#endif - pI830->disableTiling = TRUE; /* no DRI - so disableTiling */ - - if (pScrn->displayWidth >= 4096) { - xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Cannot support > 1024x768 in leftof/rightof configurations. disabling DRI.\n"); - pI830->directRenderingDisabled = TRUE; - } - - if (pScrn->virtualY > 2048) { + if (!IS_I965G(pI830) && pScrn->virtualY > 2048) { xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Cannot support > 2048 vertical lines. disabling acceleration.\n"); pI830->noAccel = TRUE; } - pI830->displayWidth = pScrn->displayWidth; - - SetPipeAccess(pScrn); - I830PrintModes(pScrn); - - if (!pI830->vesa->useDefaultRefresh) { - /* - * This sets the parameters for the VBE modes according to the best - * usable parameters from the Monitor sections modes (usually the - * default VESA modes), allowing for better than default refresh rates. - * This only works for VBE 3.0 and later. Also, we only do this - * if there are no non-CRT devices attached. - */ - SetPipeAccess(pScrn); - I830SetModeParameters(pScrn, pI830->pVbe); - } - - /* PreInit shouldn't leave any state changes, so restore this. */ - RestoreBIOSMemSize(pScrn); - /* Don't need MMIO access anymore. */ if (pI830->swfSaved) { OUTREG(SWF0, pI830->saveSWF0); @@ -5634,14 +1436,33 @@ I830BIOSPreInit(ScrnInfoPtr pScrn, int flags) xf86LoaderReqSymLists(I810fbSymbols, NULL); - if (!pI830->noAccel) { +#ifdef I830_USE_XAA + if (!pI830->noAccel && !pI830->useEXA) { if (!xf86LoadSubModule(pScrn, "xaa")) { PreInitCleanup(pScrn); return FALSE; } xf86LoaderReqSymLists(I810xaaSymbols, NULL); } +#endif + +#ifdef I830_USE_EXA + if (!pI830->noAccel && pI830->useEXA) { + XF86ModReqInfo req; + int errmaj, errmin; + memset(&req, 0, sizeof(req)); + req.majorversion = 2; + req.minorversion = 0; + if (!LoadSubModule(pScrn->module, "exa", NULL, NULL, NULL, &req, + &errmaj, &errmin)) { + LoaderErrorMsg(NULL, "exa", errmaj, errmin); + PreInitCleanup(pScrn); + return FALSE; + } + xf86LoaderReqSymLists(I830exaSymbols, NULL); + } +#endif if (!pI830->SWCursor) { if (!xf86LoadSubModule(pScrn, "ramdac")) { PreInitCleanup(pScrn); @@ -5650,6 +1471,8 @@ I830BIOSPreInit(ScrnInfoPtr pScrn, int flags) xf86LoaderReqSymLists(I810ramdacSymbols, NULL); } + i830CompareRegsToSnapshot(pScrn, "After PreInit"); + I830UnmapMMIO(pScrn); /* We won't be using the VGA access after the probe. */ @@ -5659,23 +1482,11 @@ I830BIOSPreInit(ScrnInfoPtr pScrn, int flags) #if 0 if (I830IsPrimary(pScrn)) { - VBEFreeVBEInfo(pI830->vbeInfo); vbeFree(pI830->pVbe); } - pI830->vbeInfo = NULL; pI830->pVbe = NULL; #endif - /* Use the VBE mode restore workaround by default. */ - pI830->vbeRestoreWorkaround = TRUE; - from = X_DEFAULT; - if (xf86ReturnOptValBool(pI830->Options, OPTION_VBE_RESTORE, FALSE)) { - pI830->vbeRestoreWorkaround = FALSE; - from = X_CONFIG; - } - xf86DrvMsg(pScrn->scrnIndex, from, "VBE Restore workaround: %s.\n", - pI830->vbeRestoreWorkaround ? "enabled" : "disabled"); - #if defined(XF86DRI) /* Load the dri module if requested. */ if (xf86ReturnOptValBool(pI830->Options, OPTION_DRI, FALSE) && @@ -5715,61 +1526,6 @@ I830BIOSPreInit(ScrnInfoPtr pScrn, int flags) } /* - * As the name says. Check that the initial state is reasonable. - * If any unrecoverable problems are found, bail out here. - */ -static Bool -CheckInheritedState(ScrnInfoPtr pScrn) -{ - I830Ptr pI830 = I830PTR(pScrn); - int errors = 0, fatal = 0; - unsigned long temp, head, tail; - - if (!I830IsPrimary(pScrn)) return TRUE; - - /* Check first for page table errors */ - temp = INREG(PGE_ERR); - if (temp != 0) { - xf86DrvMsg(pScrn->scrnIndex, X_WARNING, "PGTBL_ER is 0x%08lx\n", temp); - errors++; - } - temp = INREG(PGETBL_CTL); - if (!(temp & 1)) { - xf86DrvMsg(pScrn->scrnIndex, X_WARNING, - "PGTBL_CTL (0x%08lx) indicates GTT is disabled\n", temp); - errors++; - } - temp = INREG(LP_RING + RING_LEN); - if (temp & 1) { - xf86DrvMsg(pScrn->scrnIndex, X_WARNING, - "PRB0_CTL (0x%08lx) indicates ring buffer enabled\n", temp); - errors++; - } - head = INREG(LP_RING + RING_HEAD); - tail = INREG(LP_RING + RING_TAIL); - if ((tail & I830_TAIL_MASK) != (head & I830_HEAD_MASK)) { - xf86DrvMsg(pScrn->scrnIndex, X_WARNING, - "PRB0_HEAD (0x%08lx) and PRB0_TAIL (0x%08lx) indicate " - "ring buffer not flushed\n", head, tail); - errors++; - } - -#if 0 - if (errors) { - if (IS_I965G(pI830)) - I965PrintErrorState(pScrn); - else - I830PrintErrorState(pScrn); - } -#endif - - if (fatal) - FatalError("CheckInheritedState: can't recover from the above\n"); - - return (errors != 0); -} - -/* * Reset registers that it doesn't make sense to save/restore to a sane state. * This is basically the ring buffer and fence registers. Restoring these * doesn't make sense without restoring GTT mappings. This is something that @@ -5799,16 +1555,25 @@ ResetState(ScrnInfoPtr pScrn, Bool flush) for (i = 0; i < FENCE_NR; i++) OUTREG(FENCE + i * 4, 0); } - /* Flush the ring buffer (if enabled), then disable it. */ - if (pI830->AccelInfoRec != NULL && flush) { - temp = INREG(LP_RING + RING_LEN); - if (temp & 1) { - I830RefreshRing(pScrn); - I830Sync(pScrn); - DO_RING_IDLE(); - } - } + /* God this is ugly */ +#define flush_ring() do { \ + temp = INREG(LP_RING + RING_LEN); \ + if (temp & 1) { \ + I830RefreshRing(pScrn); \ + I830Sync(pScrn); \ + DO_RING_IDLE(); \ + } \ + } while(0) +#ifdef I830_USE_XAA + if (!pI830->useEXA && flush && pI830->AccelInfoRec) + flush_ring(); +#endif +#ifdef I830_USE_XAA + if (pI830->useEXA && flush && pI830->EXADriverPtr) + flush_ring(); +#endif + OUTREG(LP_RING + RING_LEN, 0); OUTREG(LP_RING + RING_HEAD, 0); OUTREG(LP_RING + RING_TAIL, 0); @@ -5830,18 +1595,18 @@ SetFenceRegs(ScrnInfoPtr pScrn) if (IS_I965G(pI830)) { for (i = 0; i < FENCE_NEW_NR; i++) { - OUTREG(FENCE_NEW + i * 8, pI830->ModeReg.Fence[i]); - OUTREG(FENCE_NEW + 4 + i * 8, pI830->ModeReg.Fence[i+FENCE_NEW_NR]); + OUTREG(FENCE_NEW + i * 8, pI830->fence[i]); + OUTREG(FENCE_NEW + 4 + i * 8, pI830->fence[i+FENCE_NEW_NR]); if (I810_DEBUG & DEBUG_VERBOSE_VGA) { - ErrorF("Fence Start Register : %x\n", pI830->ModeReg.Fence[i]); - ErrorF("Fence End Register : %x\n", pI830->ModeReg.Fence[i+FENCE_NEW_NR]); + ErrorF("Fence Start Register : %x\n", pI830->fence[i]); + ErrorF("Fence End Register : %x\n", pI830->fence[i+FENCE_NEW_NR]); } } } else { for (i = 0; i < FENCE_NR; i++) { - OUTREG(FENCE + i * 4, pI830->ModeReg.Fence[i]); + OUTREG(FENCE + i * 4, pI830->fence[i]); if (I810_DEBUG & DEBUG_VERBOSE_VGA) - ErrorF("Fence Register : %x\n", pI830->ModeReg.Fence[i]); + ErrorF("Fence Register : %x\n", pI830->fence[i]); } } } @@ -5866,25 +1631,22 @@ SetRingRegs(ScrnInfoPtr pScrn) OUTREG(LP_RING + RING_TAIL, 0); OUTREG(LP_RING + RING_HEAD, 0); - if ((long)(pI830->LpRing->mem.Start & I830_RING_START_MASK) != - pI830->LpRing->mem.Start) { - xf86DrvMsg(pScrn->scrnIndex, X_ERROR, - "I830SetRingRegs: Ring buffer start (%lx) violates its " - "mask (%x)\n", pI830->LpRing->mem.Start, I830_RING_START_MASK); - } + assert((pI830->LpRing->mem->offset & I830_RING_START_MASK) == + pI830->LpRing->mem->offset); + /* Don't care about the old value. Reserved bits must be zero anyway. */ - itemp = pI830->LpRing->mem.Start & I830_RING_START_MASK; + itemp = pI830->LpRing->mem->offset; OUTREG(LP_RING + RING_START, itemp); - if (((pI830->LpRing->mem.Size - 4096) & I830_RING_NR_PAGES) != - pI830->LpRing->mem.Size - 4096) { + if (((pI830->LpRing->mem->size - 4096) & I830_RING_NR_PAGES) != + pI830->LpRing->mem->size - 4096) { xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "I830SetRingRegs: Ring buffer size - 4096 (%lx) violates its " - "mask (%x)\n", pI830->LpRing->mem.Size - 4096, + "mask (%x)\n", pI830->LpRing->mem->size - 4096, I830_RING_NR_PAGES); } /* Don't care about the old value. Reserved bits must be zero anyway. */ - itemp = (pI830->LpRing->mem.Size - 4096) & I830_RING_NR_PAGES; + itemp = (pI830->LpRing->mem->size - 4096) & I830_RING_NR_PAGES; itemp |= (RING_NO_REPORT | RING_VALID); OUTREG(LP_RING + RING_LEN, itemp); I830RefreshRing(pScrn); @@ -5911,80 +1673,88 @@ SetHWOperatingState(ScrnInfoPtr pScrn) static Bool SaveHWState(ScrnInfoPtr pScrn) { + xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn); I830Ptr pI830 = I830PTR(pScrn); - vbeInfoPtr pVbe = pI830->pVbe; vgaHWPtr hwp = VGAHWPTR(pScrn); vgaRegPtr vgaReg = &hwp->SavedReg; - VbeModeInfoBlock *modeInfo; - VESAPtr pVesa; - - DPRINTF(PFX, "SaveHWState\n"); + int i; - if (I830IsPrimary(pScrn) && pI830->pipe != pI830->origPipe) - SetBIOSPipe(pScrn, pI830->origPipe); - else - SetPipeAccess(pScrn); - - pVesa = pI830->vesa; - - /* Make sure we save at least this information in case of failure. */ - VBEGetVBEMode(pVbe, &pVesa->stateMode); - pVesa->stateRefresh = GetRefreshRate(pScrn, pVesa->stateMode, NULL); - modeInfo = VBEGetModeInfo(pVbe, pVesa->stateMode); - pVesa->savedScanlinePitch = 0; - if (modeInfo) { - if (VBE_MODE_GRAPHICS(modeInfo)) { - VBEGetLogicalScanline(pVbe, &pVesa->savedScanlinePitch, NULL, NULL); + /* Save video mode information for native mode-setting. */ + pI830->saveDSPACNTR = INREG(DSPACNTR); + pI830->savePIPEACONF = INREG(PIPEACONF); + pI830->savePIPEASRC = INREG(PIPEASRC); + pI830->saveFPA0 = INREG(FPA0); + pI830->saveFPA1 = INREG(FPA1); + pI830->saveDPLL_A = INREG(DPLL_A); + if (IS_I965G(pI830)) + pI830->saveDPLL_A_MD = INREG(DPLL_A_MD); + pI830->saveHTOTAL_A = INREG(HTOTAL_A); + pI830->saveHBLANK_A = INREG(HBLANK_A); + pI830->saveHSYNC_A = INREG(HSYNC_A); + pI830->saveVTOTAL_A = INREG(VTOTAL_A); + pI830->saveVBLANK_A = INREG(VBLANK_A); + pI830->saveVSYNC_A = INREG(VSYNC_A); + pI830->saveDSPASTRIDE = INREG(DSPASTRIDE); + pI830->saveDSPASIZE = INREG(DSPASIZE); + pI830->saveDSPAPOS = INREG(DSPAPOS); + pI830->saveDSPABASE = INREG(DSPABASE); + + for(i= 0; i < 256; i++) { + pI830->savePaletteA[i] = INREG(PALETTE_A + (i << 2)); + } + + if(xf86_config->num_crtc == 2) { + pI830->savePIPEBCONF = INREG(PIPEBCONF); + pI830->savePIPEBSRC = INREG(PIPEBSRC); + pI830->saveDSPBCNTR = INREG(DSPBCNTR); + pI830->saveFPB0 = INREG(FPB0); + pI830->saveFPB1 = INREG(FPB1); + pI830->saveDPLL_B = INREG(DPLL_B); + if (IS_I965G(pI830)) + pI830->saveDPLL_B_MD = INREG(DPLL_B_MD); + pI830->saveHTOTAL_B = INREG(HTOTAL_B); + pI830->saveHBLANK_B = INREG(HBLANK_B); + pI830->saveHSYNC_B = INREG(HSYNC_B); + pI830->saveVTOTAL_B = INREG(VTOTAL_B); + pI830->saveVBLANK_B = INREG(VBLANK_B); + pI830->saveVSYNC_B = INREG(VSYNC_B); + pI830->saveDSPBSTRIDE = INREG(DSPBSTRIDE); + pI830->saveDSPBSIZE = INREG(DSPBSIZE); + pI830->saveDSPBPOS = INREG(DSPBPOS); + pI830->saveDSPBBASE = INREG(DSPBBASE); + for(i= 0; i < 256; i++) { + pI830->savePaletteB[i] = INREG(PALETTE_B + (i << 2)); } - VBEFreeModeInfo(modeInfo); } - vgaHWUnlock(hwp); - vgaHWSave(pScrn, vgaReg, VGA_SR_FONTS); - - pVesa = pI830->vesa; - if (IS_I965G(pI830)) { - pI830->savedAsurf = INREG(DSPASURF); - pI830->savedBsurf = INREG(DSPBSURF); + pI830->saveDSPASURF = INREG(DSPASURF); + pI830->saveDSPBSURF = INREG(DSPBSURF); } - /* - * This save/restore method doesn't work for 845G BIOS, or for some - * other platforms. Enable it in all cases. - */ - /* - * KW: This may have been because of the behaviour I've found on my - * board: The 'save' command actually modifies the interrupt - * registers, turning off the irq & breaking the kernel module - * behaviour. - */ - if (!pI830->vbeRestoreWorkaround) { - CARD16 imr = INREG16(IMR); - CARD16 ier = INREG16(IER); - CARD16 hwstam = INREG16(HWSTAM); - - if (!VBESaveRestore(pVbe, MODE_SAVE, &pVesa->state, &pVesa->stateSize, - &pVesa->statePage)) { - xf86DrvMsg(pScrn->scrnIndex, X_ERROR, - "SaveHWState: VBESaveRestore(MODE_SAVE) failed.\n"); - return FALSE; - } + pI830->saveVCLK_DIVISOR_VGA0 = INREG(VCLK_DIVISOR_VGA0); + pI830->saveVCLK_DIVISOR_VGA1 = INREG(VCLK_DIVISOR_VGA1); + pI830->saveVCLK_POST_DIV = INREG(VCLK_POST_DIV); + pI830->saveVGACNTRL = INREG(VGACNTRL); - OUTREG16(IMR, imr); - OUTREG16(IER, ier); - OUTREG16(HWSTAM, hwstam); + for(i = 0; i < 7; i++) { + pI830->saveSWF[i] = INREG(SWF0 + (i << 2)); + pI830->saveSWF[i+7] = INREG(SWF00 + (i << 2)); } + pI830->saveSWF[14] = INREG(SWF30); + pI830->saveSWF[15] = INREG(SWF31); + pI830->saveSWF[16] = INREG(SWF32); - pVesa->savedPal = VBESetGetPaletteData(pVbe, FALSE, 0, 256, - NULL, FALSE, FALSE); - if (!pVesa->savedPal) { - xf86DrvMsg(pScrn->scrnIndex, X_ERROR, - "SaveHWState: VBESetGetPaletteData(GET) failed.\n"); - return FALSE; + pI830->savePFIT_CONTROL = INREG(PFIT_CONTROL); + + for (i = 0; i < xf86_config->num_output; i++) { + xf86OutputPtr output = xf86_config->output[i]; + if (output->funcs->save) + (*output->funcs->save) (output); } - VBEGetDisplayStart(pVbe, &pVesa->x, &pVesa->y); + vgaHWUnlock(hwp); + vgaHWSave(pScrn, vgaReg, VGA_SR_FONTS); return TRUE; } @@ -5992,717 +1762,141 @@ SaveHWState(ScrnInfoPtr pScrn) static Bool RestoreHWState(ScrnInfoPtr pScrn) { + xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn); I830Ptr pI830 = I830PTR(pScrn); - vbeInfoPtr pVbe = pI830->pVbe; vgaHWPtr hwp = VGAHWPTR(pScrn); vgaRegPtr vgaReg = &hwp->SavedReg; - VESAPtr pVesa; - Bool restored = FALSE; + int i; DPRINTF(PFX, "RestoreHWState\n"); - if (I830IsPrimary(pScrn) && pI830->pipe != pI830->origPipe) - SetBIOSPipe(pScrn, pI830->origPipe); - else - SetPipeAccess(pScrn); - - pVesa = pI830->vesa; - - /* - * Workaround for text mode restoration with some flat panels. - * Temporarily program a 640x480 mode before switching back to - * text mode. - */ - if (pVesa->useDefaultRefresh) - I830Set640x480(pScrn); - - if (pVesa->state && pVesa->stateSize) { - CARD16 imr = INREG16(IMR); - CARD16 ier = INREG16(IER); - CARD16 hwstam = INREG16(HWSTAM); - - /* Make a copy of the state. Don't rely on it not being touched. */ - if (!pVesa->pstate) { - pVesa->pstate = xalloc(pVesa->stateSize); - if (pVesa->pstate) - memcpy(pVesa->pstate, pVesa->state, pVesa->stateSize); - } - restored = VBESaveRestore(pVbe, MODE_RESTORE, &pVesa->state, - &pVesa->stateSize, &pVesa->statePage); - if (!restored) { - xf86DrvMsg(pScrn->scrnIndex, X_WARNING, - "RestoreHWState: VBESaveRestore failed.\n"); - } - /* Copy back */ - if (pVesa->pstate) - memcpy(pVesa->state, pVesa->pstate, pVesa->stateSize); - - OUTREG16(IMR, imr); - OUTREG16(IER, ier); - OUTREG16(HWSTAM, hwstam); - } - /* If that failed, restore the original mode. */ - if (!restored) { - xf86DrvMsg(pScrn->scrnIndex, X_WARNING, - "Setting the original video mode instead of restoring\n\t" - "the saved state\n"); - I830VESASetVBEMode(pScrn, pVesa->stateMode, NULL); - if (!pVesa->useDefaultRefresh && pI830->useExtendedRefresh) { - SetRefreshRate(pScrn, pVesa->stateMode, pVesa->stateRefresh); - } - } - if (pVesa->savedScanlinePitch) - VBESetLogicalScanline(pVbe, pVesa->savedScanlinePitch); - - if (pVesa->savedPal) - VBESetGetPaletteData(pVbe, TRUE, 0, 256, pVesa->savedPal, FALSE, TRUE); - - VBESetDisplayStart(pVbe, pVesa->x, pVesa->y, TRUE); - - if (IS_I965G(pI830)) { - OUTREG(DSPASURF, pI830->savedAsurf); - OUTREG(DSPBSURF, pI830->savedBsurf); - } - - vgaHWRestore(pScrn, vgaReg, VGA_SR_FONTS); - vgaHWLock(hwp); - - return TRUE; -} - -static void I830SetCloneVBERefresh(ScrnInfoPtr pScrn, int mode, VbeCRTCInfoBlock * block, int refresh) -{ - I830Ptr pI830 = I830PTR(pScrn); - DisplayModePtr p = NULL; - int RefreshRate; - int clock; - - /* Search for our mode and get a refresh to match */ - for (p = pScrn->monitor->Modes; p != NULL; p = p->next) { - if ((p->HDisplay != pI830->CloneHDisplay) || - (p->VDisplay != pI830->CloneVDisplay) || - (p->Flags & (V_INTERLACE | V_DBLSCAN | V_CLKDIV2))) - continue; - RefreshRate = ((double)(p->Clock * 1000) / - (double)(p->HTotal * p->VTotal)) * 100; - /* we could probably do better here that 2Hz boundaries */ - if (RefreshRate > (refresh - 200) && RefreshRate < (refresh + 200)) { - block->HorizontalTotal = p->HTotal; - block->HorizontalSyncStart = p->HSyncStart; - block->HorizontalSyncEnd = p->HSyncEnd; - block->VerticalTotal = p->VTotal; - block->VerticalSyncStart = p->VSyncStart; - block->VerticalSyncEnd = p->VSyncEnd; - block->Flags = ((p->Flags & V_NHSYNC) ? CRTC_NHSYNC : 0) | - ((p->Flags & V_NVSYNC) ? CRTC_NVSYNC : 0); - block->PixelClock = p->Clock * 1000; - /* XXX May not have this. */ - clock = VBEGetPixelClock(pI830->pVbe, mode, block->PixelClock); -#ifdef DEBUG - ErrorF("Setting clock %.2fMHz, closest is %.2fMHz\n", - (double)data->block->PixelClock / 1000000.0, - (double)clock / 1000000.0); -#endif - if (clock) - block->PixelClock = clock; - block->RefreshRate = RefreshRate; - return; - } - } -} - -static Bool -I830VESASetVBEMode(ScrnInfoPtr pScrn, int mode, VbeCRTCInfoBlock * block) -{ - I830Ptr pI830 = I830PTR(pScrn); - Bool ret = FALSE; - int Mon; - - DPRINTF(PFX, "Setting mode 0x%.8x\n", mode); - -#if 0 - /* Clear the framebuffer (could do this with VBIOS call) */ - if (I830IsPrimary(pScrn)) - memset(pI830->FbBase + pI830->FrontBuffer.Start, 0, - pScrn->virtualY * pI830->displayWidth * pI830->cpp); - else - memset(pI830->FbBase + pI830->FrontBuffer2.Start, 0, - pScrn->virtualY * pI830->displayWidth * pI830->cpp); -#endif - - if (pI830->Clone && - pI830->CloneHDisplay && pI830->CloneVDisplay && - !pI830->preinit && !pI830->closing) { - VbeCRTCInfoBlock newblock; - int newmode = mode; - - if (pI830->pipe == 1) - Mon = pI830->MonType1; - else - Mon = pI830->MonType2; - - SetBIOSPipe(pScrn, !pI830->pipe); - - /* Now recheck refresh operations we can use */ - pI830->useExtendedRefresh = FALSE; - pI830->vesa->useDefaultRefresh = FALSE; - - if (Mon != PIPE_CRT) { - xf86DrvMsg(pScrn->scrnIndex, X_INFO, - "A non-CRT device is attached to Clone pipe %c.\n" - "\tNo refresh rate overrides will be attempted (0x%x).\n", - PIPE_NAME(!pI830->pipe), newmode); - pI830->vesa->useDefaultRefresh = TRUE; - } - /* - * Some desktop platforms might not have 0x5f05, so useExtendedRefresh - * would need to be set to FALSE for those cases. - */ - if (!pI830->vesa->useDefaultRefresh) - pI830->useExtendedRefresh = TRUE; - - newmode |= 1 << 11; - if (pI830->vesa->useDefaultRefresh) - newmode &= ~(1 << 11); - - if (!SetRefreshRate(pScrn, newmode, 60)) { - xf86DrvMsg(pScrn->scrnIndex, X_INFO, - "BIOS call 0x5f05 not supported on Clone Head, " - "setting refresh with VBE 3 method.\n"); - pI830->useExtendedRefresh = FALSE; - } - - if (!pI830->vesa->useDefaultRefresh) { - I830SetCloneVBERefresh(pScrn, newmode, &newblock, pI830->CloneRefresh * 100); - - if (!VBESetVBEMode(pI830->pVbe, newmode, &newblock)) { - if (!VBESetVBEMode(pI830->pVbe, (newmode & ~(1 << 11)), NULL)) - xf86DrvMsg(pScrn->scrnIndex, X_WARNING, - "Failed to set mode for Clone head.\n"); - } else { - xf86DrvMsg(pScrn->scrnIndex, X_INFO, - "Setting refresh on clone head with VBE 3 method.\n"); - pI830->useExtendedRefresh = FALSE; - } - } else { - if (!VBESetVBEMode(pI830->pVbe, (newmode & ~(1 << 11)), NULL)) - xf86DrvMsg(pScrn->scrnIndex, X_WARNING, - "Failed to set mode for Clone head.\n"); - } - - if (pI830->useExtendedRefresh && !pI830->vesa->useDefaultRefresh) { - if (!SetRefreshRate(pScrn, newmode, pI830->CloneRefresh)) - xf86DrvMsg(pScrn->scrnIndex, X_WARNING, - "Failed to set refresh rate to %dHz on Clone head.\n", - pI830->CloneRefresh); - else - xf86DrvMsg(pScrn->scrnIndex, X_INFO, - "Set refresh rate to %dHz on Clone head.\n", - pI830->CloneRefresh); - } - SetPipeAccess(pScrn); - } - - if (pI830->pipe == 0) - Mon = pI830->MonType1; - else - Mon = pI830->MonType2; - - - /* Now recheck refresh operations we can use */ - pI830->useExtendedRefresh = FALSE; - pI830->vesa->useDefaultRefresh = FALSE; - - 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) - mode &= ~(1 << 11); - /* - * Some desktop platforms might not have 0x5f05, so useExtendedRefresh - * would need to be set to FALSE for those cases. - */ - if (!pI830->vesa->useDefaultRefresh) - pI830->useExtendedRefresh = TRUE; - - if (!SetRefreshRate(pScrn, mode, 60)) { - xf86DrvMsg(pScrn->scrnIndex, X_INFO, - "BIOS call 0x5f05 not supported, " - "setting refresh with VBE 3 method.\n"); - pI830->useExtendedRefresh = FALSE; - } - - if (!pI830->vesa->useDefaultRefresh && block) { - ret = VBESetVBEMode(pI830->pVbe, mode, block); - if (!ret) - ret = VBESetVBEMode(pI830->pVbe, (mode & ~(1 << 11)), NULL); - else { - xf86DrvMsg(pScrn->scrnIndex, X_INFO, - "Setting refresh with VBE 3 method.\n"); - pI830->useExtendedRefresh = FALSE; - } - } else { - ret = VBESetVBEMode(pI830->pVbe, (mode & ~(1 << 11)), NULL); - } - - /* Might as well bail now if we've failed */ - if (!ret) return FALSE; - - if (pI830->useExtendedRefresh && !pI830->vesa->useDefaultRefresh && block) { - if (!SetRefreshRate(pScrn, mode, block->RefreshRate / 100)) { - xf86DrvMsg(pScrn->scrnIndex, X_WARNING, - "Failed to set refresh rate to %dHz.\n", - block->RefreshRate / 100); - pI830->useExtendedRefresh = FALSE; - } - } - - return ret; -} - -static Bool -I830VESASetMode(ScrnInfoPtr pScrn, DisplayModePtr pMode) -{ - I830Ptr pI830 = I830PTR(pScrn); - vbeInfoPtr pVbe = pI830->pVbe; - I830ModePrivatePtr mp = (I830ModePrivatePtr) pMode->Private; - int mode, i; - CARD32 planeA, planeB, temp; - int refresh = 60; #ifdef XF86DRI - Bool didLock = FALSE; -#endif - - DPRINTF(PFX, "I830VESASetMode\n"); - - /* Always Enable Linear Addressing */ - mode = mp->vbeData.mode | (1 << 15) | (1 << 14); - -#ifdef XF86DRI - didLock = I830DRILock(pScrn); -#endif - - if (pI830->Clone) { - pI830->CloneHDisplay = pMode->HDisplay; - pI830->CloneVDisplay = pMode->VDisplay; - } - -#ifndef MODESWITCH_RESET_STATE -#define MODESWITCH_RESET_STATE 0 -#endif -#if MODESWITCH_RESET_STATE - ResetState(pScrn, TRUE); + I830DRISetVBlankInterrupt (pScrn, FALSE); #endif - - SetPipeAccess(pScrn); - - if (!pI830->MergedFB) { - if (I830VESASetVBEMode(pScrn, mode, mp->vbeData.block) == FALSE) { - xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Set VBE Mode failed!\n"); - return FALSE; - } - }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); - - 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, (f->vbeData.mode | 1<<15 | 1<<14), f->vbeData.block) == FALSE) { - xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Set VBE Mode failed!\n"); - return FALSE; - } + /* Disable outputs */ + for (i = 0; i < xf86_config->num_output; i++) { + xf86OutputPtr output = xf86_config->output[i]; + output->funcs->dpms(output, DPMSModeOff); } - -#if 0 - { /* I965G ENABLE TILING */ - planeA = INREG(DSPACNTR) | 1<<10; - OUTREG(DSPACNTR, planeA); - /* flush the change. */ - temp = INREG(DSPABASE); - OUTREG(DSPABASE, temp); - } -#else - { /* I965G DISABLE TILING */ - planeA = INREG(DSPACNTR) & ~1<<10; - OUTREG(DSPACNTR, planeA); - /* flush the change. */ - temp = INREG(DSPABASE); - OUTREG(DSPABASE, temp); - OUTREG(DSPASURF, INREG(DSPASURF)); + i830WaitForVblank(pScrn); + + /* Disable pipes */ + for (i = 0; i < xf86_config->num_crtc; i++) { + xf86CrtcPtr crtc = xf86_config->crtc[i]; + crtc->funcs->dpms(crtc, DPMSModeOff); } -#endif + i830WaitForVblank(pScrn); - /* - * The BIOS may not set a scanline pitch that would require more video - * memory than it's aware of. We check for this later, and set it - * explicitly if necessary. - */ - if (mp->vbeData.data->XResolution != pI830->displayWidth) { - if (pI830->Clone || pI830->MergedFB) { - SetBIOSPipe(pScrn, !pI830->pipe); - VBESetLogicalScanline(pVbe, pI830->displayWidth); - } - SetPipeAccess(pScrn); - VBESetLogicalScanline(pVbe, pI830->displayWidth); - } + if (!IS_I830(pI830) && !IS_845G(pI830)) + OUTREG(PFIT_CONTROL, pI830->savePFIT_CONTROL); - if (pScrn->bitsPerPixel >= 8 && pI830->vbeInfo->Capabilities[0] & 0x01) { - if (pI830->Clone || pI830->MergedFB) { - SetBIOSPipe(pScrn, !pI830->pipe); - VBESetGetDACPaletteFormat(pVbe, 8); - } - SetPipeAccess(pScrn); - VBESetGetDACPaletteFormat(pVbe, 8); + if (pI830->saveDPLL_A & DPLL_VCO_ENABLE) + { + OUTREG(DPLL_A, pI830->saveDPLL_A & ~DPLL_VCO_ENABLE); + usleep(150); } - - /* XXX Fix plane A with pipe A, and plane B with pipe B. */ - planeA = INREG(DSPACNTR); - planeB = INREG(DSPBCNTR); - - pI830->planeEnabled[0] = ((planeA & DISPLAY_PLANE_ENABLE) != 0); - pI830->planeEnabled[1] = ((planeB & DISPLAY_PLANE_ENABLE) != 0); - - xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Display plane A is %s and connected to %s.\n", - pI830->planeEnabled[0] ? "enabled" : "disabled", - planeA & DISPPLANE_SEL_PIPE_MASK ? "Pipe B" : "Pipe A"); - if (pI830->availablePipes == 2) - xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Display plane B is %s and connected to %s.\n", - pI830->planeEnabled[1] ? "enabled" : "disabled", - planeB & DISPPLANE_SEL_PIPE_MASK ? "Pipe B" : "Pipe A"); + OUTREG(FPA0, pI830->saveFPA0); + OUTREG(FPA1, pI830->saveFPA1); + OUTREG(DPLL_A, pI830->saveDPLL_A); + usleep(150); + if (IS_I965G(pI830)) + OUTREG(DPLL_A_MD, pI830->saveDPLL_A_MD); + else + OUTREG(DPLL_A, pI830->saveDPLL_A); + usleep(150); + + OUTREG(HTOTAL_A, pI830->saveHTOTAL_A); + OUTREG(HBLANK_A, pI830->saveHBLANK_A); + OUTREG(HSYNC_A, pI830->saveHSYNC_A); + OUTREG(VTOTAL_A, pI830->saveVTOTAL_A); + OUTREG(VBLANK_A, pI830->saveVBLANK_A); + OUTREG(VSYNC_A, pI830->saveVSYNC_A); - if (pI830->operatingDevices & 0xff) { - pI830->planeEnabled[0] = 1; - } else { - pI830->planeEnabled[0] = 0; - } - - if (pI830->operatingDevices & 0xff00) { - pI830->planeEnabled[1] = 1; - } else { - pI830->planeEnabled[1] = 0; - } + OUTREG(DSPASTRIDE, pI830->saveDSPASTRIDE); + OUTREG(DSPASIZE, pI830->saveDSPASIZE); + OUTREG(DSPAPOS, pI830->saveDSPAPOS); + OUTREG(PIPEASRC, pI830->savePIPEASRC); + OUTREG(DSPABASE, pI830->saveDSPABASE); + if (IS_I965G(pI830)) + OUTREG(DSPASURF, pI830->saveDSPASURF); + OUTREG(PIPEACONF, pI830->savePIPEACONF); + i830WaitForVblank(pScrn); + OUTREG(DSPACNTR, pI830->saveDSPACNTR); + OUTREG(DSPABASE, INREG(DSPABASE)); + i830WaitForVblank(pScrn); - if (pI830->planeEnabled[0]) { - xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Enabling plane A.\n"); - planeA |= DISPLAY_PLANE_ENABLE; - planeA &= ~DISPPLANE_SEL_PIPE_MASK; - planeA |= DISPPLANE_SEL_PIPE_A; - OUTREG(DSPACNTR, planeA); - /* flush the change. */ - temp = INREG(DSPABASE); - OUTREG(DSPABASE, temp); - if (IS_I965G(pI830)) { - temp = INREG(DSPASURF); - OUTREG(DSPASURF, temp); - } - } - if (pI830->planeEnabled[1]) { - xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Enabling plane B.\n"); - planeB |= DISPLAY_PLANE_ENABLE; - planeB &= ~DISPPLANE_SEL_PIPE_MASK; - planeB |= DISPPLANE_SEL_PIPE_B; - OUTREG(DSPBCNTR, planeB); - /* flush the change. */ - temp = INREG(DSPBADDR); - OUTREG(DSPBADDR, temp); - if (IS_I965G(pI830)) { - temp = INREG(DSPBSURF); - OUTREG(DSPBSURF, temp); - } + if(xf86_config->num_crtc == 2) + { + if (pI830->saveDPLL_B & DPLL_VCO_ENABLE) + { + OUTREG(DPLL_B, pI830->saveDPLL_B & ~DPLL_VCO_ENABLE); + usleep(150); + } + OUTREG(FPB0, pI830->saveFPB0); + OUTREG(FPB1, pI830->saveFPB1); + OUTREG(DPLL_B, pI830->saveDPLL_B); + usleep(150); + if (IS_I965G(pI830)) + OUTREG(DPLL_B_MD, pI830->saveDPLL_B_MD); + else + OUTREG(DPLL_B, pI830->saveDPLL_B); + usleep(150); + + OUTREG(HTOTAL_B, pI830->saveHTOTAL_B); + OUTREG(HBLANK_B, pI830->saveHBLANK_B); + OUTREG(HSYNC_B, pI830->saveHSYNC_B); + OUTREG(VTOTAL_B, pI830->saveVTOTAL_B); + OUTREG(VBLANK_B, pI830->saveVBLANK_B); + OUTREG(VSYNC_B, pI830->saveVSYNC_B); + OUTREG(DSPBSTRIDE, pI830->saveDSPBSTRIDE); + OUTREG(DSPBSIZE, pI830->saveDSPBSIZE); + OUTREG(DSPBPOS, pI830->saveDSPBPOS); + OUTREG(PIPEBSRC, pI830->savePIPEBSRC); + OUTREG(DSPBBASE, pI830->saveDSPBBASE); + if (IS_I965G(pI830)) + OUTREG(DSPBSURF, pI830->saveDSPBSURF); + OUTREG(PIPEBCONF, pI830->savePIPEBCONF); + i830WaitForVblank(pScrn); + OUTREG(DSPBCNTR, pI830->saveDSPBCNTR); + OUTREG(DSPBBASE, INREG(DSPBBASE)); + i830WaitForVblank(pScrn); } - planeA = INREG(DSPACNTR); - planeB = INREG(DSPBCNTR); - xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Display plane A is now %s and connected to %s.\n", - pI830->planeEnabled[0] ? "enabled" : "disabled", - planeA & DISPPLANE_SEL_PIPE_MASK ? "Pipe B" : "Pipe A"); - if (pI830->availablePipes == 2) - xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Display plane B is now %s and connected to %s.\n", - pI830->planeEnabled[1] ? "enabled" : "disabled", - planeB & DISPPLANE_SEL_PIPE_MASK ? "Pipe B" : "Pipe A"); - - /* XXX Plane C is ignored for now (overlay). */ - - /* - * Print out the PIPEACONF and PIPEBCONF registers. - */ - temp = INREG(PIPEACONF); - xf86DrvMsg(pScrn->scrnIndex, X_INFO, "PIPEACONF is 0x%08lx\n", - (unsigned long) temp); - if (pI830->availablePipes == 2) { - temp = INREG(PIPEBCONF); - xf86DrvMsg(pScrn->scrnIndex, X_INFO, "PIPEBCONF is 0x%08lx\n", - (unsigned long) temp); + /* Restore outputs */ + for (i = 0; i < xf86_config->num_output; i++) { + xf86OutputPtr output = xf86_config->output[i]; + if (output->funcs->restore) + output->funcs->restore(output); } + + OUTREG(VGACNTRL, pI830->saveVGACNTRL); - if (xf86IsEntityShared(pScrn->entityList[0])) { - /* Clean this up !! */ - if (I830IsPrimary(pScrn)) { - CARD32 stridereg = !pI830->pipe ? DSPASTRIDE : DSPBSTRIDE; - CARD32 basereg = !pI830->pipe ? DSPABASE : DSPBBASE; - CARD32 sizereg = !pI830->pipe ? DSPASIZE : DSPBSIZE; - CARD32 surfreg = !pI830->pipe ? DSPASURF : DSPBSURF; - I830Ptr pI8301 = I830PTR(pI830->entityPrivate->pScrn_1); - - temp = INREG(stridereg); - if (temp / pI8301->cpp != (CARD32)(pI830->displayWidth)) { - xf86DrvMsg(pScrn->scrnIndex, X_WARNING, - "Correcting plane %c stride (%d -> %d)\n", PIPE_NAME(!pI830->pipe), - (int)(temp / pI8301->cpp), pI830->displayWidth); - OUTREG(stridereg, pI830->displayWidth * pI8301->cpp); - } - OUTREG(sizereg, (pMode->HDisplay - 1) | ((pMode->VDisplay - 1) << 16)); - /* Trigger update */ - temp = INREG(basereg); - OUTREG(basereg, temp); - if (IS_I965G(pI830)) { - temp = INREG(surfreg); - OUTREG(surfreg, temp); - } - - if (pI830->entityPrivate && pI830->entityPrivate->pScrn_2) { - I830Ptr pI8302 = I830PTR(pI830->entityPrivate->pScrn_2); - stridereg = pI830->pipe ? DSPASTRIDE : DSPBSTRIDE; - basereg = pI830->pipe ? DSPABASE : DSPBBASE; - sizereg = pI830->pipe ? DSPASIZE : DSPBSIZE; - surfreg = pI830->pipe ? DSPASURF : DSPBSURF; - - temp = INREG(stridereg); - if (temp / pI8302->cpp != (CARD32)(pI8302->displayWidth)) { - xf86DrvMsg(pScrn->scrnIndex, X_WARNING, - "Correcting plane %c stride (%d -> %d)\n", PIPE_NAME(pI830->pipe), - (int)(temp / pI8302->cpp), pI8302->displayWidth); - OUTREG(stridereg, pI8302->displayWidth * pI8302->cpp); - } - OUTREG(sizereg, (pI830->entityPrivate->pScrn_2->currentMode->HDisplay - 1) | ((pI830->entityPrivate->pScrn_2->currentMode->VDisplay - 1) << 16)); - /* Trigger update */ - temp = INREG(basereg); - OUTREG(basereg, temp); - if (IS_I965G(pI830)) { - temp = INREG(surfreg); - OUTREG(surfreg, temp); - } - } - } else { - CARD32 stridereg = pI830->pipe ? DSPASTRIDE : DSPBSTRIDE; - CARD32 basereg = pI830->pipe ? DSPABASE : DSPBBASE; - CARD32 sizereg = pI830->pipe ? DSPASIZE : DSPBSIZE; - CARD32 surfreg = pI830->pipe ? DSPASURF : DSPBSURF; - I830Ptr pI8301 = I830PTR(pI830->entityPrivate->pScrn_1); - I830Ptr pI8302 = I830PTR(pI830->entityPrivate->pScrn_2); - - temp = INREG(stridereg); - if (temp / pI8301->cpp != (CARD32)(pI8301->displayWidth)) { - xf86DrvMsg(pScrn->scrnIndex, X_WARNING, - "Correcting plane %c stride (%d -> %d)\n", PIPE_NAME(pI830->pipe), - (int)(temp / pI8301->cpp), pI8301->displayWidth); - OUTREG(stridereg, pI8301->displayWidth * pI8301->cpp); - } - OUTREG(sizereg, (pI830->entityPrivate->pScrn_1->currentMode->HDisplay - 1) | ((pI830->entityPrivate->pScrn_1->currentMode->VDisplay - 1) << 16)); - /* Trigger update */ - temp = INREG(basereg); - OUTREG(basereg, temp); - if (IS_I965G(pI830)) { - temp = INREG(surfreg); - OUTREG(surfreg, temp); - } - - stridereg = !pI830->pipe ? DSPASTRIDE : DSPBSTRIDE; - basereg = !pI830->pipe ? DSPABASE : DSPBBASE; - sizereg = !pI830->pipe ? DSPASIZE : DSPBSIZE; - surfreg = !pI830->pipe ? DSPASURF : DSPBSURF; - - temp = INREG(stridereg); - if (temp / pI8302->cpp != ((CARD32)pI8302->displayWidth)) { - xf86DrvMsg(pScrn->scrnIndex, X_WARNING, - "Correcting plane %c stride (%d -> %d)\n", PIPE_NAME(!pI830->pipe), - (int)(temp / pI8302->cpp), pI8302->displayWidth); - OUTREG(stridereg, pI8302->displayWidth * pI8302->cpp); - } - OUTREG(sizereg, (pMode->HDisplay - 1) | ((pMode->VDisplay - 1) << 16)); - /* Trigger update */ - temp = INREG(basereg); - OUTREG(basereg, temp); - if (IS_I965G(pI830)) { - temp = INREG(surfreg); - OUTREG(surfreg, temp); - } - } - } else { - for (i = 0; i < pI830->availablePipes; i++) { - CARD32 stridereg = i ? DSPBSTRIDE : DSPASTRIDE; - CARD32 basereg = i ? DSPBBASE : DSPABASE; - CARD32 sizereg = i ? DSPBSIZE : DSPASIZE; - CARD32 surfreg = i ? DSPBSURF : DSPASURF; - - if (!pI830->planeEnabled[i]) - continue; - - temp = INREG(stridereg); - if (temp / pI830->cpp != (CARD32)pI830->displayWidth) { - xf86DrvMsg(pScrn->scrnIndex, X_WARNING, - "Correcting plane %c stride (%d -> %d)\n", PIPE_NAME(i), - (int)(temp / pI830->cpp), pI830->displayWidth); - OUTREG(stridereg, pI830->displayWidth * pI830->cpp); - } + OUTREG(VCLK_DIVISOR_VGA0, pI830->saveVCLK_DIVISOR_VGA0); + OUTREG(VCLK_DIVISOR_VGA1, pI830->saveVCLK_DIVISOR_VGA1); + OUTREG(VCLK_POST_DIV, pI830->saveVCLK_POST_DIV); - if (pI830->MergedFB) { - switch (pI830->SecondPosition) { - case PosRightOf: - case PosBelow: - OUTREG(DSPABASE, (CDMPTR.First->HDisplay - 1) | ((CDMPTR.First->VDisplay - 1) << 16)); - OUTREG(DSPBBASE, (CDMPTR.Second->HDisplay - 1) | ((CDMPTR.Second->VDisplay - 1) << 16)); - break; - case PosLeftOf: - case PosAbove: - OUTREG(DSPABASE, (CDMPTR.Second->HDisplay - 1) | ((CDMPTR.Second->VDisplay - 1) << 16)); - OUTREG(DSPBBASE, (CDMPTR.First->HDisplay - 1) | ((CDMPTR.First->VDisplay - 1) << 16)); - break; - } - } else - OUTREG(sizereg, (pMode->HDisplay - 1) | ((pMode->VDisplay - 1) << 16)); - /* Trigger update */ - temp = INREG(basereg); - OUTREG(basereg, temp); - if (IS_I965G(pI830)) { - temp = INREG(surfreg); - OUTREG(surfreg, temp); - } - } + for(i = 0; i < 256; i++) { + OUTREG(PALETTE_A + (i << 2), pI830->savePaletteA[i]); } - -#if 0 - /* Print out some CRTC/display information. */ - temp = INREG(HTOTAL_A); - ErrorF("Horiz active: %d, Horiz total: %d\n", temp & 0x7ff, - (temp >> 16) & 0xfff); - temp = INREG(HBLANK_A); - ErrorF("Horiz blank start: %d, Horiz blank end: %d\n", temp & 0xfff, - (temp >> 16) & 0xfff); - temp = INREG(HSYNC_A); - ErrorF("Horiz sync start: %d, Horiz sync end: %d\n", temp & 0xfff, - (temp >> 16) & 0xfff); - temp = INREG(VTOTAL_A); - ErrorF("Vert active: %d, Vert total: %d\n", temp & 0x7ff, - (temp >> 16) & 0xfff); - temp = INREG(VBLANK_A); - ErrorF("Vert blank start: %d, Vert blank end: %d\n", temp & 0xfff, - (temp >> 16) & 0xfff); - temp = INREG(VSYNC_A); - ErrorF("Vert sync start: %d, Vert sync end: %d\n", temp & 0xfff, - (temp >> 16) & 0xfff); - temp = INREG(PIPEASRC); - ErrorF("Image size: %dx%d (%dx%d)\n", - (temp >> 16) & 0x7ff, temp & 0x7ff, - (((temp >> 16) & 0x7ff) + 1), ((temp & 0x7ff) + 1)); - ErrorF("Pixel multiply is %d\n", (planeA >> 20) & 0x3); - temp = INREG(DSPABASE); - ErrorF("Plane A start offset is %d\n", temp); - temp = INREG(DSPASTRIDE); - ErrorF("Plane A stride is %d bytes (%d pixels)\n", temp, temp / pI830->cpp); - temp = INREG(DSPAPOS); - ErrorF("Plane A position %d %d\n", temp & 0xffff, (temp & 0xffff0000) >> 16); - temp = INREG(DSPASIZE); - ErrorF("Plane A size %d %d\n", temp & 0xffff, (temp & 0xffff0000) >> 16); - - /* Print out some CRTC/display information. */ - temp = INREG(HTOTAL_B); - ErrorF("Horiz active: %d, Horiz total: %d\n", temp & 0x7ff, - (temp >> 16) & 0xfff); - temp = INREG(HBLANK_B); - ErrorF("Horiz blank start: %d, Horiz blank end: %d\n", temp & 0xfff, - (temp >> 16) & 0xfff); - temp = INREG(HSYNC_B); - ErrorF("Horiz sync start: %d, Horiz sync end: %d\n", temp & 0xfff, - (temp >> 16) & 0xfff); - temp = INREG(VTOTAL_B); - ErrorF("Vert active: %d, Vert total: %d\n", temp & 0x7ff, - (temp >> 16) & 0xfff); - temp = INREG(VBLANK_B); - ErrorF("Vert blank start: %d, Vert blank end: %d\n", temp & 0xfff, - (temp >> 16) & 0xfff); - temp = INREG(VSYNC_B); - ErrorF("Vert sync start: %d, Vert sync end: %d\n", temp & 0xfff, - (temp >> 16) & 0xfff); - temp = INREG(PIPEBSRC); - ErrorF("Image size: %dx%d (%dx%d)\n", - (temp >> 16) & 0x7ff, temp & 0x7ff, - (((temp >> 16) & 0x7ff) + 1), ((temp & 0x7ff) + 1)); - ErrorF("Pixel multiply is %d\n", (planeA >> 20) & 0x3); - temp = INREG(DSPBBASE); - ErrorF("Plane B start offset is %d\n", temp); - temp = INREG(DSPBSTRIDE); - ErrorF("Plane B stride is %d bytes (%d pixels)\n", temp, temp / pI830->cpp); - temp = INREG(DSPBPOS); - ErrorF("Plane B position %d %d\n", temp & 0xffff, (temp & 0xffff0000) >> 16); - temp = INREG(DSPBSIZE); - ErrorF("Plane B size %d %d\n", temp & 0xffff, (temp & 0xffff0000) >> 16); -#endif - - xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Mode bandwidth is %d Mpixel/s\n", - pMode->HDisplay * pMode->VDisplay * refresh / 1000000); - - { - int maxBandwidth, bandwidthA, bandwidthB; - - if (GetModeSupport(pScrn, 0x80, 0x80, 0x80, 0x80, - &maxBandwidth, &bandwidthA, &bandwidthB)) { - xf86DrvMsg(pScrn->scrnIndex, X_INFO, "maxBandwidth is %d Mbyte/s, " - "pipe bandwidths are %d Mbyte/s, %d Mbyte/s\n", - maxBandwidth, bandwidthA, bandwidthB); + + if(xf86_config->num_crtc == 2) { + for(i= 0; i < 256; i++) { + OUTREG(PALETTE_B + (i << 2), pI830->savePaletteB[i]); } } -#if 0 - { - int ret; - - ret = GetLFPCompMode(pScrn); - if (ret != -1) { - xf86DrvMsg(pScrn->scrnIndex, X_INFO, - "LFP compensation mode: 0x%x\n", ret); - } + for(i = 0; i < 7; i++) { + OUTREG(SWF0 + (i << 2), pI830->saveSWF[i]); + OUTREG(SWF00 + (i << 2), pI830->saveSWF[i+7]); } -#endif -#if MODESWITCH_RESET_STATE - ResetState(pScrn, TRUE); - SetHWOperatingState(pScrn); -#endif + OUTREG(SWF30, pI830->saveSWF[14]); + OUTREG(SWF31, pI830->saveSWF[15]); + OUTREG(SWF32, pI830->saveSWF[16]); -#if 0 - if (IS_I965G(pI830)) - I965PrintErrorState(pScrn); - else - I830PrintErrorState(pScrn); -#endif - -#ifdef XF86DRI - if (didLock) - I830DRIUnlock(pScrn); -#endif + vgaHWRestore(pScrn, vgaReg, VGA_SR_FONTS); + vgaHWLock(hwp); - pScrn->vtSema = TRUE; return TRUE; } @@ -6710,301 +1904,14 @@ static void InitRegisterRec(ScrnInfoPtr pScrn) { I830Ptr pI830 = I830PTR(pScrn); - I830RegPtr i830Reg = &pI830->ModeReg; int i; if (!I830IsPrimary(pScrn)) return; for (i = 0; i < 8; i++) - i830Reg->Fence[i] = 0; + pI830->fence[i] = 0; } -/* Famous last words - */ -void -I830PrintErrorState(ScrnInfoPtr pScrn) -{ - I830Ptr pI830 = I830PTR(pScrn); - - ErrorF("pgetbl_ctl: 0x%lx pgetbl_err: 0x%lx\n", - (unsigned long)INREG(PGETBL_CTL), (unsigned long)INREG(PGE_ERR)); - - ErrorF("ipeir: %lx iphdr: %lx\n", (unsigned long)INREG(IPEIR), - (unsigned long)INREG(IPEHR)); - - ErrorF("LP ring tail: %lx head: %lx len: %lx start %lx\n", - (unsigned long)INREG(LP_RING + RING_TAIL), - (unsigned long)INREG(LP_RING + RING_HEAD) & HEAD_ADDR, - (unsigned long)INREG(LP_RING + RING_LEN), - (unsigned long)INREG(LP_RING + RING_START)); - - ErrorF("eir: %x esr: %x emr: %x\n", - INREG16(EIR), INREG16(ESR), INREG16(EMR)); - - ErrorF("instdone: %x instpm: %x\n", INREG16(INST_DONE), INREG8(INST_PM)); - - ErrorF("memmode: %lx instps: %lx\n", (unsigned long)INREG(MEMMODE), - (unsigned long)INREG(INST_PS)); - - ErrorF("hwstam: %x ier: %x imr: %x iir: %x\n", - INREG16(HWSTAM), INREG16(IER), INREG16(IMR), INREG16(IIR)); -} - -void -I965PrintErrorState(ScrnInfoPtr pScrn) -{ - I830Ptr pI830 = I830PTR(pScrn); - - ErrorF("pgetbl_ctl: 0x%lx pgetbl_err: 0x%lx\n", - INREG(PGETBL_CTL), INREG(PGE_ERR)); - - ErrorF("ipeir: %lx iphdr: %lx\n", INREG(IPEIR_I965), INREG(IPEHR_I965)); - - ErrorF("LP ring tail: %lx head: %lx len: %lx start %lx\n", - INREG(LP_RING + RING_TAIL), - INREG(LP_RING + RING_HEAD) & HEAD_ADDR, - INREG(LP_RING + RING_LEN), INREG(LP_RING + RING_START)); - - ErrorF("Err ID (eir): %x Err Status (esr): %x Err Mask (emr): %x\n", - (int)INREG(EIR), (int)INREG(ESR), (int)INREG(EMR)); - - ErrorF("instdone: %x instdone_1: %x\n", (int)INREG(INST_DONE_I965), - (int)INREG(INST_DONE_1)); - ErrorF("instpm: %x\n", (int)INREG(INST_PM)); - - ErrorF("memmode: %lx instps: %lx\n", INREG(MEMMODE), INREG(INST_PS_I965)); - - ErrorF("HW Status mask (hwstam): %x\nIRQ enable (ier): %x imr: %x iir: %x\n", - (int)INREG(HWSTAM), (int)INREG(IER), (int)INREG(IMR), - (int)INREG(IIR)); - - ErrorF("acthd: %lx dma_fadd_p: %lx\n", INREG(ACTHD), INREG(DMA_FADD_P)); - ErrorF("ecoskpd: %lx excc: %lx\n", INREG(ECOSKPD), INREG(EXCC)); - - ErrorF("cache_mode: %x/%x\n", (int)INREG(CACHE_MODE_0), - (int)INREG(CACHE_MODE_1)); - ErrorF("mi_arb_state: %x\n", (int)INREG(MI_ARB_STATE)); - - ErrorF("IA_VERTICES_COUNT_QW %x/%x\n", (int)INREG(IA_VERTICES_COUNT_QW), - (int)INREG(IA_VERTICES_COUNT_QW+4)); - ErrorF("IA_PRIMITIVES_COUNT_QW %x/%x\n", (int)INREG(IA_PRIMITIVES_COUNT_QW), - (int)INREG(IA_PRIMITIVES_COUNT_QW+4)); - - ErrorF("VS_INVOCATION_COUNT_QW %x/%x\n", (int)INREG(VS_INVOCATION_COUNT_QW), - (int)INREG(VS_INVOCATION_COUNT_QW+4)); - - ErrorF("GS_INVOCATION_COUNT_QW %x/%x\n", (int)INREG(GS_INVOCATION_COUNT_QW), - (int)INREG(GS_INVOCATION_COUNT_QW+4)); - ErrorF("GS_PRIMITIVES_COUNT_QW %x/%x\n", (int)INREG(GS_PRIMITIVES_COUNT_QW), - (int)INREG(GS_PRIMITIVES_COUNT_QW+4)); - - ErrorF("CL_INVOCATION_COUNT_QW %x/%x\n", (int)INREG(CL_INVOCATION_COUNT_QW), - (int)INREG(CL_INVOCATION_COUNT_QW+4)); - ErrorF("CL_PRIMITIVES_COUNT_QW %x/%x\n", (int)INREG(CL_PRIMITIVES_COUNT_QW), - (int)INREG(CL_PRIMITIVES_COUNT_QW+4)); - - ErrorF("PS_INVOCATION_COUNT_QW %x/%x\n", (int)INREG(PS_INVOCATION_COUNT_QW), - (int)INREG(PS_INVOCATION_COUNT_QW+4)); - ErrorF("PS_DEPTH_COUNT_QW %x/%x\n", (int)INREG(PS_DEPTH_COUNT_QW), - (int)INREG(PS_DEPTH_COUNT_QW+4)); - - ErrorF("WIZ_CTL %x\n", (int)INREG(WIZ_CTL)); - ErrorF("TS_CTL %x TS_DEBUG_DATA %x\n", (int)INREG(TS_CTL), - (int)INREG(TS_DEBUG_DATA)); - ErrorF("TD_CTL %x / %x\n", (int)INREG(TD_CTL), (int)INREG(TD_CTL2)); - - -} - -#ifdef I830DEBUG -static void -dump_DSPACNTR(ScrnInfoPtr pScrn) -{ - I830Ptr pI830 = I830PTR(pScrn); - unsigned int tmp; - - /* Display A Control */ - tmp = INREG(0x70180); - ErrorF("Display A Plane Control Register (0x%.8x)\n", tmp); - - if (tmp & BIT(31)) - ErrorF(" Display Plane A (Primary) Enable\n"); - else - ErrorF(" Display Plane A (Primary) Disabled\n"); - - if (tmp & BIT(30)) - ErrorF(" Display A pixel data is gamma corrected\n"); - else - ErrorF(" Display A pixel data bypasses gamma correction logic (default)\n"); - - switch ((tmp & 0x3c000000) >> 26) { /* bit 29:26 */ - case 0x00: - case 0x01: - case 0x03: - ErrorF(" Reserved\n"); - break; - case 0x02: - ErrorF(" 8-bpp Indexed\n"); - break; - case 0x04: - ErrorF(" 15-bit (5-5-5) pixel format (Targa compatible)\n"); - break; - case 0x05: - ErrorF(" 16-bit (5-6-5) pixel format (XGA compatible)\n"); - break; - case 0x06: - ErrorF(" 32-bit format (X:8:8:8)\n"); - break; - case 0x07: - ErrorF(" 32-bit format (8:8:8:8)\n"); - break; - default: - ErrorF(" Unknown - Invalid register value maybe?\n"); - } - - if (tmp & BIT(25)) - ErrorF(" Stereo Enable\n"); - else - ErrorF(" Stereo Disable\n"); - - if (tmp & BIT(24)) - ErrorF(" Display A, Pipe B Select\n"); - else - ErrorF(" Display A, Pipe A Select\n"); - - if (tmp & BIT(22)) - ErrorF(" Source key is enabled\n"); - else - ErrorF(" Source key is disabled\n"); - - switch ((tmp & 0x00300000) >> 20) { /* bit 21:20 */ - case 0x00: - ErrorF(" No line duplication\n"); - break; - case 0x01: - ErrorF(" Line/pixel Doubling\n"); - break; - case 0x02: - case 0x03: - ErrorF(" Reserved\n"); - break; - } - - if (tmp & BIT(18)) - ErrorF(" Stereo output is high during second image\n"); - else - ErrorF(" Stereo output is high during first image\n"); -} - -static void -dump_DSPBCNTR(ScrnInfoPtr pScrn) -{ - I830Ptr pI830 = I830PTR(pScrn); - unsigned int tmp; - - /* Display B/Sprite Control */ - tmp = INREG(0x71180); - ErrorF("Display B/Sprite Plane Control Register (0x%.8x)\n", tmp); - - if (tmp & BIT(31)) - ErrorF(" Display B/Sprite Enable\n"); - else - ErrorF(" Display B/Sprite Disable\n"); - - if (tmp & BIT(30)) - ErrorF(" Display B pixel data is gamma corrected\n"); - else - ErrorF(" Display B pixel data bypasses gamma correction logic (default)\n"); - - switch ((tmp & 0x3c000000) >> 26) { /* bit 29:26 */ - case 0x00: - case 0x01: - case 0x03: - ErrorF(" Reserved\n"); - break; - case 0x02: - ErrorF(" 8-bpp Indexed\n"); - break; - case 0x04: - ErrorF(" 15-bit (5-5-5) pixel format (Targa compatible)\n"); - break; - case 0x05: - ErrorF(" 16-bit (5-6-5) pixel format (XGA compatible)\n"); - break; - case 0x06: - ErrorF(" 32-bit format (X:8:8:8)\n"); - break; - case 0x07: - ErrorF(" 32-bit format (8:8:8:8)\n"); - break; - default: - ErrorF(" Unknown - Invalid register value maybe?\n"); - } - - if (tmp & BIT(25)) - ErrorF(" Stereo is enabled and both start addresses are used in a two frame sequence\n"); - else - ErrorF(" Stereo disable and only a single start address is used\n"); - - if (tmp & BIT(24)) - ErrorF(" Display B/Sprite, Pipe B Select\n"); - else - ErrorF(" Display B/Sprite, Pipe A Select\n"); - - if (tmp & BIT(22)) - ErrorF(" Sprite source key is enabled\n"); - else - ErrorF(" Sprite source key is disabled (default)\n"); - - switch ((tmp & 0x00300000) >> 20) { /* bit 21:20 */ - case 0x00: - ErrorF(" No line duplication\n"); - break; - case 0x01: - ErrorF(" Line/pixel Doubling\n"); - break; - case 0x02: - case 0x03: - ErrorF(" Reserved\n"); - break; - } - - if (tmp & BIT(18)) - ErrorF(" Stereo output is high during second image\n"); - else - ErrorF(" Stereo output is high during first image\n"); - - if (tmp & BIT(15)) - ErrorF(" Alpha transfer mode enabled\n"); - else - ErrorF(" Alpha transfer mode disabled\n"); - - if (tmp & BIT(0)) - ErrorF(" Sprite is above overlay\n"); - else - ErrorF(" Sprite is above display A (default)\n"); -} - -void -I830_dump_registers(ScrnInfoPtr pScrn) -{ - I830Ptr pI830 = I830PTR(pScrn); - unsigned int i; - - ErrorF("%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\n"); - - dump_DSPACNTR(pScrn); - dump_DSPBCNTR(pScrn); - - ErrorF("0x71400 == 0x%.8x\n", INREG(0x71400)); - ErrorF("0x70008 == 0x%.8x\n", INREG(0x70008)); - for (i = 0x71410; i <= 0x71428; i += 4) - ErrorF("0x%x == 0x%.8x\n", i, INREG(i)); - - ErrorF("%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\n"); -} -#endif - static void I830PointerMoved(int index, int x, int y) { @@ -7042,26 +1949,8 @@ I830CreateScreenResources (ScreenPtr pScreen) if (!(*pScreen->CreateScreenResources)(pScreen)) return FALSE; - if (xf86LoaderCheckSymbol("I830RandRSetConfig") && pI830->rotation != RR_Rotate_0) { - Rotation (*I830RandRSetConfig)(ScreenPtr pScreen, Rotation rr, int rate, RRScreenSizePtr pSize) = NULL; - RRScreenSize p; - Rotation requestedRotation = pI830->rotation; - - pI830->rotation = RR_Rotate_0; - - /* Just setup enough for an initial rotate */ - p.width = pScreen->width; - p.height = pScreen->height; - p.mmWidth = pScreen->mmWidth; - p.mmHeight = pScreen->mmHeight; - - I830RandRSetConfig = LoaderSymbol("I830RandRSetConfig"); - if (I830RandRSetConfig) { - pI830->starting = TRUE; /* abuse this for dual head & rotation */ - (*I830RandRSetConfig) (pScreen, requestedRotation, 0, &p); - pI830->starting = FALSE; - } - } + if (!xf86RandR12CreateScreenResources (pScreen)) + return FALSE; return TRUE; } @@ -7072,7 +1961,6 @@ I830InitFBManager( BoxPtr FullBox ){ ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; - I830Ptr pI830 = I830PTR(pScrn); RegionRec ScreenRegion; RegionRec FullRegion; BoxRec ScreenBox; @@ -7081,7 +1969,7 @@ I830InitFBManager( ScreenBox.x1 = 0; ScreenBox.y1 = 0; ScreenBox.x2 = pScrn->displayWidth; - if (!pI830->MergedFB && pScrn->virtualX > pScrn->virtualY) + if (pScrn->virtualX > pScrn->virtualY) ScreenBox.y2 = pScrn->virtualX; else ScreenBox.y2 = pScrn->virtualY; @@ -7113,18 +2001,29 @@ IntelEmitInvarientState(ScrnInfoPtr pScrn) { I830Ptr pI830 = I830PTR(pScrn); CARD32 ctx_addr; +#ifdef XF86DRI + drmI830Sarea *sarea; +#endif if (pI830->noAccel || !I830IsPrimary(pScrn)) return; - ctx_addr = pI830->ContextMem.Start; - /* Align to a 2k boundry */ - ctx_addr = ((ctx_addr + 2048 - 1) / 2048) * 2048; +#ifdef XF86DRI + if (pI830->directRenderingEnabled) { + sarea = DRIGetSAREAPrivate(pScrn->pScreen); + /* Mark that the X Server was the last holder of the context */ + if (sarea) + sarea->ctxOwner = DRIGetContext(pScrn->pScreen); + } +#endif + + ctx_addr = pI830->logical_context->offset; + assert((pI830->logical_context->offset & 2047) == 0); { BEGIN_LP_RING(2); OUT_RING(MI_SET_CONTEXT); - OUT_RING(ctx_addr | + OUT_RING(pI830->logical_context->offset | CTXT_NO_RESTORE | CTXT_PALETTE_SAVE_DISABLE | CTXT_PALETTE_RESTORE_DISABLE); ADVANCE_LP_RING(); @@ -7139,11 +2038,7 @@ IntelEmitInvarientState(ScrnInfoPtr pScrn) } } -#ifdef XF86DRI -#ifndef DRM_BO_MEM_TT -#error "Wrong drm.h file included. You need to compile and install a recent libdrm." -#endif - +#ifdef XF86DRI_MM #ifndef XSERVER_LIBDRM_MM static int @@ -7218,35 +2113,274 @@ static int I830DrmMMUnlock(int fd, unsigned memType) } #endif -#endif +#endif /* XF86DRI_MM */ static Bool -I830BIOSScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv) +I830ScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv) { ScrnInfoPtr pScrn; vgaHWPtr hwp; I830Ptr pI830; VisualPtr visual; I830Ptr pI8301 = NULL; + unsigned long sys_mem; + int i; + Bool allocation_done = FALSE; + MessageType from; #ifdef XF86DRI Bool driDisabled; + unsigned long savedMMSize; #endif pScrn = xf86Screens[pScreen->myNum]; pI830 = I830PTR(pScrn); hwp = VGAHWPTR(pScrn); - pScrn->displayWidth = pI830->displayWidth; + pScrn->displayWidth = (pScrn->virtualX + 63) & ~63; + + /* + * The "VideoRam" config file parameter specifies the maximum amount of + * memory that will be used/allocated. When not present, we allow the + * driver to allocate as much memory as it wishes to satisfy its + * allocations, but if agpgart support isn't available, it gets limited + * to the amount of pre-allocated ("stolen") memory. + * + * Note that in using this value for allocator initialization, we're + * limiting aperture allocation to the VideoRam option, rather than limiting + * actual memory allocation, so alignment and things will cause less than + * VideoRam to be actually used. + */ + if (pI830->pEnt->device->videoRam == 0) { + from = X_DEFAULT; + pScrn->videoRam = pI830->FbMapSize / KB(1); + } else { + from = X_CONFIG; + pScrn->videoRam = pI830->pEnt->device->videoRam; + } + + /* Limit videoRam to how much we might be able to allocate from AGP */ + sys_mem = I830CheckAvailableMemory(pScrn); + if (sys_mem == -1) { + if (pScrn->videoRam > pI830->stolen_size / KB(1)) { + xf86DrvMsg(pScrn->scrnIndex, X_WARNING, + "/dev/agpgart is either not available, or no memory " + "is available\nfor allocation. " + "Using pre-allocated memory only.\n"); + pScrn->videoRam = pI830->stolen_size / KB(1); + } + pI830->StolenOnly = TRUE; + } else { + if (sys_mem + (pI830->stolen_size / 1024) < pScrn->videoRam) { + pScrn->videoRam = sys_mem + (pI830->stolen_size / 1024); + from = X_PROBED; + if (sys_mem + (pI830->stolen_size / 1024) < + pI830->pEnt->device->videoRam) + { + xf86DrvMsg(pScrn->scrnIndex, X_WARNING, + "VideoRAM reduced to %d kByte " + "(limited to available sysmem)\n", pScrn->videoRam); + } + } + } + + /* Limit video RAM to the actual aperture size */ + if (pScrn->videoRam > pI830->FbMapSize / 1024) { + pScrn->videoRam = pI830->FbMapSize / 1024; + if (pI830->FbMapSize / 1024 < pI830->pEnt->device->videoRam) { + xf86DrvMsg(pScrn->scrnIndex, X_WARNING, + "VideoRam reduced to %d kByte (limited to aperture " + "size)\n", + pScrn->videoRam); + } + } + + /* Make sure it's on a page boundary */ + if (pScrn->videoRam & 3) { + xf86DrvMsg(pScrn->scrnIndex, X_WARNING, "VideoRam reduced to %d KB " + "(page aligned - was %d KB)\n", + pScrn->videoRam & ~3, pScrn->videoRam); + pScrn->videoRam &= ~3; + } + + /* Set up our video memory allocator for the chosen videoRam */ + if (!i830_allocator_init(pScrn, 0, pScrn->videoRam * KB(1))) { + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + "Couldn't initialize video memory allocator\n"); + PreInitCleanup(pScrn); + return FALSE; + } + + xf86DrvMsg(pScrn->scrnIndex, + pI830->pEnt->device->videoRam ? X_CONFIG : X_DEFAULT, + "VideoRam: %d KB\n", pScrn->videoRam); + + if (xf86GetOptValInteger(pI830->Options, OPTION_CACHE_LINES, + &(pI830->CacheLines))) { + xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Requested %d cache lines\n", + pI830->CacheLines); + } else { + pI830->CacheLines = -1; + } + + pI830->disableTiling = FALSE; if (I830IsPrimary(pScrn)) { - /* Rotated Buffer */ - memset(&(pI830->RotatedMem), 0, sizeof(pI830->RotatedMem)); - pI830->RotatedMem.Key = -1; - /* Rotated2 Buffer */ - memset(&(pI830->RotatedMem2), 0, sizeof(pI830->RotatedMem2)); - pI830->RotatedMem2.Key = -1; + /* Alloc our pointers for the primary head */ + if (!pI830->LpRing) + pI830->LpRing = xcalloc(1, sizeof(I830RingBuffer)); + if (!pI830->overlayOn) + pI830->overlayOn = xalloc(sizeof(Bool)); + if (!pI830->used3D) + pI830->used3D = xalloc(sizeof(int)); + if (!pI830->LpRing || !pI830->overlayOn || !pI830->used3D) { + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + "Could not allocate primary data structures.\n"); + return FALSE; + } + *pI830->overlayOn = FALSE; + if (pI830->entityPrivate) + pI830->entityPrivate->XvInUse = -1; + } else { + /* Make our second head point to the first heads structures */ + pI8301 = I830PTR(pI830->entityPrivate->pScrn_1); + pI830->LpRing = pI8301->LpRing; + pI830->overlay_regs = pI8301->overlay_regs; + pI830->overlayOn = pI8301->overlayOn; + pI830->used3D = pI8301->used3D; + } + +#if defined(XF86DRI) + /* + * If DRI is potentially usable, check if there is enough memory available + * for it, and if there's also enough to allow tiling to be enabled. + */ + + if (!I830CheckDRIAvailable(pScrn)) { + pI830->directRenderingDisabled = TRUE; + pI830->mmSize = 0; } + if (!pI830->directRenderingDisabled) { + int savedDisplayWidth = pScrn->displayWidth; + Bool tiled = FALSE; + +#ifdef I830_XV + /* + * Set this so that the overlay allocation is factored in when + * appropriate. + */ + pI830->XvEnabled = !pI830->XvDisabled; +#endif + + if (IS_I965G(pI830)) { + int tile_pixels = 512 / pI830->cpp; + pScrn->displayWidth = (pScrn->displayWidth + tile_pixels - 1) & + ~(tile_pixels - 1); + tiled = TRUE; + } else { + /* Good pitches to allow tiling. Don't care about pitches < 1024 + * pixels. + */ + static const int pitches[] = { + 1024, + 2048, + 4096, + 8192, + 0 + }; + + for (i = 0; pitches[i] != 0; i++) { + if (pitches[i] >= pScrn->displayWidth) { + pScrn->displayWidth = pitches[i]; + tiled = TRUE; + break; + } + } + } + + /* Attempt several rounds of allocation to get 2d and 3d memory to fit: + * + * 0: tiled, large memory manager + * 1: tiled, small memory manager + * 2: untiled, large + * 3: untiled, small + */ + + pI830->disableTiling = FALSE; + savedMMSize = pI830->mmSize; + for (i = 0; i < 4; i++) { + if (!tiled && i < 2) + continue; + + if (i >= 2) { + /* For further allocations, disable tiling */ + pI830->disableTiling = TRUE; + pScrn->displayWidth = savedDisplayWidth; + pI830->allowPageFlip = FALSE; + } + + if (i & 1) { + /* For this allocation, switch to a smaller DRI memory manager + * size. + */ + pI830->mmSize = I830_MM_MINPAGES * GTT_PAGE_SIZE; + } else { + pI830->mmSize = savedMMSize; + } + + xf86DrvMsg(pScrn->scrnIndex, X_INFO, + "Attempting memory allocation with %s buffers and \n" + "\t %s DRI memory manager reservation:\n", + (i & 2) ? "untiled" : "tiled", + (i & 1) ? "small" : "large"); + + if (i830_allocate_2d_memory(pScrn) && + i830_allocate_3d_memory(pScrn)) + { + xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Success.\n"); + if (pScrn->displayWidth != savedDisplayWidth) { + xf86DrvMsg(pScrn->scrnIndex, X_INFO, + "Increasing the scanline pitch to allow tiling mode " + "(%d -> %d).\n", + savedDisplayWidth, pScrn->displayWidth); + } + allocation_done = TRUE; + break; + } + + i830_reset_allocations(pScrn); + } + + if (i == 4) { + xf86DrvMsg(pScrn->scrnIndex, X_WARNING, + "Not enough video memory. Disabling DRI.\n"); + pI830->mmSize = 0; + pI830->directRenderingDisabled = TRUE; + } + } else +#endif + pI830->disableTiling = TRUE; /* no DRI - so disableTiling */ + + if (!allocation_done) { + if (!i830_allocate_2d_memory(pScrn)) { + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + "Couldn't allocate video memory\n"); + return FALSE; + } + allocation_done = TRUE; + } + + i830_describe_allocations(pScrn, 1, ""); + + if (!IS_I965G(pI830) && pScrn->displayWidth > 2048) { + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + "Cannot support DRI with frame buffer width > 2048.\n"); + pI830->disableTiling = TRUE; + pI830->directRenderingDisabled = TRUE; + } + + pScrn->displayWidth = pScrn->displayWidth; + #ifdef HAS_MTRR_SUPPORT { int fd; @@ -7288,86 +2422,8 @@ I830BIOSScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv) } #endif - if (xf86IsEntityShared(pScrn->entityList[0])) { - /* PreInit failed on the second head, so make sure we turn it off */ - if (I830IsPrimary(pScrn) && !pI830->entityPrivate->pScrn_2) { - if (pI830->pipe == 0) { - pI830->operatingDevices &= 0xFF; - } else { - pI830->operatingDevices &= 0xFF00; - } - } - } - pI830->starting = TRUE; - /* Alloc our pointers for the primary head */ - if (I830IsPrimary(pScrn)) { - if (!pI830->LpRing) - pI830->LpRing = xalloc(sizeof(I830RingBuffer)); - if (!pI830->CursorMem) - pI830->CursorMem = xalloc(sizeof(I830MemRange)); - if (!pI830->CursorMemARGB) - pI830->CursorMemARGB = xalloc(sizeof(I830MemRange)); - if (!pI830->OverlayMem) - pI830->OverlayMem = xalloc(sizeof(I830MemRange)); - if (!pI830->overlayOn) - pI830->overlayOn = xalloc(sizeof(Bool)); - if (!pI830->used3D) - pI830->used3D = xalloc(sizeof(int)); - if (!pI830->LpRing || !pI830->CursorMem || !pI830->CursorMemARGB || - !pI830->OverlayMem || !pI830->overlayOn || !pI830->used3D) { - xf86DrvMsg(pScrn->scrnIndex, X_ERROR, - "Could not allocate primary data structures.\n"); - return FALSE; - } - *pI830->overlayOn = FALSE; - if (pI830->entityPrivate) - pI830->entityPrivate->XvInUse = -1; - } - - /* Make our second head point to the first heads structures */ - if (!I830IsPrimary(pScrn)) { - pI8301 = I830PTR(pI830->entityPrivate->pScrn_1); - pI830->LpRing = pI8301->LpRing; - pI830->CursorMem = pI8301->CursorMem; - pI830->CursorMemARGB = pI8301->CursorMemARGB; - pI830->OverlayMem = pI8301->OverlayMem; - pI830->overlayOn = pI8301->overlayOn; - pI830->used3D = pI8301->used3D; - } - - /* - * If we're changing the BIOS's view of the video memory size, do that - * first, then re-initialise the VBE information. - */ - if (I830IsPrimary(pScrn)) { - SetPipeAccess(pScrn); - if (pI830->pVbe) - vbeFree(pI830->pVbe); - pI830->pVbe = VBEInit(NULL, pI830->pEnt->index); - } else { - pI830->pVbe = pI8301->pVbe; - } - - if (I830IsPrimary(pScrn)) { - if (!TweakMemorySize(pScrn, pI830->newBIOSMemSize,FALSE)) - SetBIOSMemSize(pScrn, pI830->newBIOSMemSize); - } - - if (!pI830->pVbe) - return FALSE; - - if (I830IsPrimary(pScrn)) { - if (pI830->vbeInfo) - VBEFreeVBEInfo(pI830->vbeInfo); - pI830->vbeInfo = VBEGetVBEInfo(pI830->pVbe); - } else { - pI830->vbeInfo = pI8301->vbeInfo; - } - - SetPipeAccess(pScrn); - miClearVisualTypes(); if (!miSetVisualTypes(pScrn->depth, miGetDefaultVisualMask(pScrn->depth), @@ -7395,15 +2451,8 @@ I830BIOSScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv) pI830->XvEnabled = FALSE; #endif - if (I830IsPrimary(pScrn)) { - I830ResetAllocations(pScrn, 0); - - if (!I830Allocate2DMemory(pScrn, ALLOC_INITIAL)) - return FALSE; - } - if (!pI830->noAccel) { - if (pI830->LpRing->mem.Size == 0) { + if (pI830->LpRing->mem->size == 0) { xf86DrvMsg(pScrn->scrnIndex, X_WARNING, "Disabling acceleration because the ring buffer " "allocation failed.\n"); @@ -7411,15 +2460,6 @@ I830BIOSScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv) } } - if (!pI830->SWCursor) { - if (pI830->CursorMem->Size == 0) { - xf86DrvMsg(pScrn->scrnIndex, X_WARNING, - "Disabling HW cursor because the cursor memory " - "allocation failed.\n"); - pI830->SWCursor = TRUE; - } - } - #ifdef I830_XV if (pI830->XvEnabled) { if (pI830->noAccel) { @@ -7427,7 +2467,7 @@ I830BIOSScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv) "needs 2D acceleration.\n"); pI830->XvEnabled = FALSE; } - if (pI830->OverlayMem->Physical == 0) { + if (!IS_I9XX(pI830) && pI830->overlay_regs == NULL) { xf86DrvMsg(pScrn->scrnIndex, X_WARNING, "Disabling Xv because the overlay register buffer " "allocation failed.\n"); @@ -7455,6 +2495,7 @@ I830BIOSScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv) xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "DRI is disabled because it " "needs HW cursor, 2D accel and AGPGART.\n"); pI830->directRenderingEnabled = FALSE; + i830_free_3d_memory(pScrn); } } @@ -7463,39 +2504,17 @@ I830BIOSScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv) if (pI830->directRenderingEnabled) pI830->directRenderingEnabled = I830DRIScreenInit(pScreen); - if (pI830->directRenderingEnabled) { - pI830->directRenderingEnabled = - I830Allocate3DMemory(pScrn, - pI830->disableTiling ? ALLOC_NO_TILING : 0); - if (!pI830->directRenderingEnabled) - I830DRICloseScreen(pScreen); + if (!pI830->directRenderingEnabled) { + i830_free_3d_memory(pScrn); } #else pI830->directRenderingEnabled = FALSE; #endif - /* - * After the 3D allocations have been done, see if there's any free space - * that can be added to the framebuffer allocation. - */ - if (I830IsPrimary(pScrn)) { - I830Allocate2DMemory(pScrn, 0); - - DPRINTF(PFX, "assert(if(!I830DoPoolAllocation(pScrn, pI830->StolenPool)))\n"); - if (!I830DoPoolAllocation(pScrn, &(pI830->StolenPool))) - return FALSE; - - DPRINTF(PFX, "assert( if(!I830FixupOffsets(pScrn)) )\n"); - if (!I830FixupOffsets(pScrn)) - return FALSE; - } - #ifdef XF86DRI - if (pI830->directRenderingEnabled) { - I830SetupMemoryTiling(pScrn); + if (pI830->directRenderingEnabled) pI830->directRenderingEnabled = I830DRIDoMappings(pScreen); - } #endif DPRINTF(PFX, "assert( if(!I830MapMem(pScrn)) )\n"); @@ -7505,9 +2524,9 @@ I830BIOSScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv) pScrn->memPhysBase = (unsigned long)pI830->FbBase; if (I830IsPrimary(pScrn)) { - pScrn->fbOffset = pI830->FrontBuffer.Start; + pScrn->fbOffset = pI830->front_buffer->offset; } else { - pScrn->fbOffset = pI8301->FrontBuffer2.Start; + pScrn->fbOffset = pI8301->front_buffer_2->offset; } pI830->xoffset = (pScrn->fbOffset / pI830->cpp) % pScrn->displayWidth; @@ -7519,13 +2538,35 @@ I830BIOSScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv) if (!vgaHWMapMem(pScrn)) return FALSE; - /* Clear SavedReg */ - memset(&pI830->SavedReg, 0, sizeof(pI830->SavedReg)); + DPRINTF(PFX, "assert( if(!I830EnterVT(scrnIndex, 0)) )\n"); - DPRINTF(PFX, "assert( if(!I830BIOSEnterVT(scrnIndex, 0)) )\n"); + if (!pI830->useEXA) { + if (I830IsPrimary(pScrn)) { + if (!I830InitFBManager(pScreen, &(pI830->FbMemBox))) { + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + "Failed to init memory manager\n"); + } - if (!I830BIOSEnterVT(scrnIndex, 0)) - return FALSE; + if (pI830->LinearAlloc && + xf86InitFBManagerLinear(pScreen, + pI830->xaa_linear->offset / pI830->cpp, + pI830->xaa_linear->size / pI830->cpp)) + { + xf86DrvMsg(scrnIndex, X_INFO, + "Using %ld bytes of offscreen memory for linear " + "(offset=0x%lx)\n", pI830->xaa_linear->size, + pI830->xaa_linear->offset); + } + } else { + if (!I830InitFBManager(pScreen, &(pI8301->FbMemBox2))) { + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + "Failed to init memory manager\n"); + } + } + } + + if (pScrn->virtualX > pScrn->displayWidth) + pScrn->displayWidth = pScrn->virtualX; DPRINTF(PFX, "assert( if(!fbScreenInit(pScreen, ...) )\n"); if (!fbScreenInit(pScreen, pI830->FbBase + pScrn->fbOffset, @@ -7553,26 +2594,10 @@ I830BIOSScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv) xf86SetBlackWhitePixels(pScreen); - I830DGAInit(pScreen); + xf86DiDGAInit (pScreen, pI830->LinearAddr + pScrn->fbOffset); DPRINTF(PFX, "assert( if(!I830InitFBManager(pScreen, &(pI830->FbMemBox))) )\n"); - if (I830IsPrimary(pScrn)) { - if (!I830InitFBManager(pScreen, &(pI830->FbMemBox))) { - xf86DrvMsg(pScrn->scrnIndex, X_ERROR, - "Failed to init memory manager\n"); - } - - if (pI830->LinearAlloc && xf86InitFBManagerLinear(pScreen, pI830->LinearMem.Offset / pI830->cpp, pI830->LinearMem.Size / pI830->cpp)) - xf86DrvMsg(scrnIndex, X_INFO, - "Using %ld bytes of offscreen memory for linear (offset=0x%lx)\n", pI830->LinearMem.Size, pI830->LinearMem.Offset); - - } else { - if (!I830InitFBManager(pScreen, &(pI8301->FbMemBox2))) { - xf86DrvMsg(pScrn->scrnIndex, X_ERROR, - "Failed to init memory manager\n"); - } - } if (!pI830->noAccel) { if (!I830AccelInit(pScreen)) { @@ -7581,6 +2606,9 @@ I830BIOSScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv) } } + if (!I830EnterVT(scrnIndex, 0)) + return FALSE; + miInitializeBackingStore(pScreen); xf86SetBackingStore(pScreen); xf86SetSilkenMouse(pScreen); @@ -7605,7 +2633,7 @@ I830BIOSScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv) return FALSE; } - xf86DPMSInit(pScreen, I830DisplayPowerManagementSet, 0); + xf86DPMSInit(pScreen, xf86DPMSSet, 0); #ifdef I830_XV /* Init video */ @@ -7636,36 +2664,33 @@ I830BIOSScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv) xf86DrvMsg(pScrn->scrnIndex, X_INFO, "direct rendering: Not available\n"); #endif - pScreen->SaveScreen = I830BIOSSaveScreen; + pScreen->SaveScreen = xf86SaveScreen; pI830->CloseScreen = pScreen->CloseScreen; - pScreen->CloseScreen = I830BIOSCloseScreen; + pScreen->CloseScreen = I830CloseScreen; - if (pI830->MergedFB) { - pI830->PointerMoved = pScrn->PointerMoved; - pScrn->PointerMoved = I830MergedPointerMoved; - - if(pI830->IntelXinerama) { - I830noPanoramiXExtension = FALSE; - I830XineramaExtensionInit(pScrn); - if(!I830noPanoramiXExtension) { - if(pI830->HaveNonRect) { - /* Reset the viewport (now eventually non-recangular) */ - I830AdjustFrame(scrnIndex, pScrn->frameX0, pScrn->frameY0, 0); - } - } - } else { - pI830->MouseRestrictions = FALSE; - } - } else if (pI830->shadowReq.minorversion >= 1) { + if (pI830->shadowReq.minorversion >= 1) { /* Rotation */ xf86DrvMsg(pScrn->scrnIndex, X_INFO, "RandR enabled, ignore the following RandR disabled message.\n"); xf86DisableRandR(); /* Disable built-in RandR extension */ shadowSetup(pScreen); /* support all rotations */ - if (IS_I965G(pI830)) { - I830RandRInit(pScreen, RR_Rotate_0); /* only 0 degrees for I965G */ + xf86RandR12Init (pScreen); + if (pI830->useEXA) { +#ifdef I830_USE_EXA + if (pI830->EXADriverPtr->exa_minor >= 1) { + xf86RandR12SetRotations (pScreen, RR_Rotate_0 | RR_Rotate_90 | + RR_Rotate_180 | RR_Rotate_270); + } else { + xf86DrvMsg(pScrn->scrnIndex, X_WARNING, + "EXA version %d.%d too old to support rotation\n", + pI830->EXADriverPtr->exa_major, + pI830->EXADriverPtr->exa_minor); + xf86RandR12SetRotations (pScreen, RR_Rotate_0); + } +#endif /* I830_USE_EXA */ } else { - I830RandRInit(pScreen, RR_Rotate_0 | RR_Rotate_90 | RR_Rotate_180 | RR_Rotate_270); + xf86RandR12SetRotations (pScreen, RR_Rotate_0 | RR_Rotate_90 | + RR_Rotate_180 | RR_Rotate_270); } pI830->PointerMoved = pScrn->PointerMoved; pScrn->PointerMoved = I830PointerMoved; @@ -7676,16 +2701,9 @@ I830BIOSScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv) xf86DrvMsg(pScrn->scrnIndex, X_INFO, "libshadow is version %d.%d.%d, required 1.1.0 or greater for rotation.\n",pI830->shadowReq.majorversion,pI830->shadowReq.minorversion,pI830->shadowReq.patchlevel); } - /* Call this unconditionally, as it also sets some fields in the SAREA */ - I830UpdateXineramaScreenInfo(pScrn); - if (serverGeneration == 1) xf86ShowUnusedOptions(pScrn->scrnIndex, pScrn->options); -#ifdef I830DEBUG - I830_dump_registers(pScrn); -#endif - if (IS_I965G(pI830)) { /* turn off clock gating */ #if 0 @@ -7704,52 +2722,25 @@ I830BIOSScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv) pI830->closing = FALSE; pI830->suspended = FALSE; - switch (pI830->InitialRotation) { - case 0: - xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Rotating to 0 degrees\n"); - pI830->rotation = RR_Rotate_0; - break; - case 90: - xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Rotating to 90 degrees\n"); - pI830->rotation = RR_Rotate_90; - break; - case 180: - xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Rotating to 180 degrees\n"); - pI830->rotation = RR_Rotate_180; - break; - case 270: - xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Rotating to 270 degrees\n"); - pI830->rotation = RR_Rotate_270; - break; - default: - xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Bad rotation setting - defaulting to 0 degrees\n"); - pI830->rotation = RR_Rotate_0; - break; - } - - -#ifdef XF86DRI - if (pI830->directRenderingEnabled && (pI830->mmModeFlags & I830_KERNEL_MM)) { - unsigned long aperEnd = ROUND_DOWN_TO(pI830->FbMapSize, GTT_PAGE_SIZE) - / GTT_PAGE_SIZE; - unsigned long aperStart = ROUND_TO(pI830->FbMapSize - KB(pI830->mmSize), GTT_PAGE_SIZE) - / GTT_PAGE_SIZE; - - if (aperEnd < aperStart || aperEnd - aperStart < I830_MM_MINPAGES) { +#ifdef XF86DRI_MM + if (pI830->directRenderingEnabled && (pI830->mmModeFlags & I830_KERNEL_MM)) + { + if (pI830->memory_manager == NULL) { xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Too little AGP aperture space for DRM memory manager.\n" - "\tPlease increase AGP aperture size from BIOS configuration screen\n" - "\tor decrease the amount of video RAM using option \"VideoRam\".\n" + "\tPlease increase AGP aperture size from BIOS configuration screen.\n" "\tDisabling DRI.\n"); pI830->directRenderingOpen = FALSE; I830DRICloseScreen(pScreen); pI830->directRenderingEnabled = FALSE; } else { #ifndef XSERVER_LIBDRM_MM - if (I830DrmMMInit(pI830->drmSubFD, aperStart, aperEnd - aperStart, + if (I830DrmMMInit(pI830->drmSubFD, pI830->memory_manager->offset, + pI830->memory_manager->size, DRM_BO_MEM_TT)) { #else - if (drmMMInit(pI830->drmSubFD, aperStart, aperEnd - aperStart, + if (drmMMInit(pI830->drmSubFD, pI830->memory_manager->offset, + pI830->memory_manager->size, DRM_BO_MEM_TT)) { #endif xf86DrvMsg(pScrn->scrnIndex, X_ERROR, @@ -7758,141 +2749,46 @@ I830BIOSScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv) pI830->directRenderingOpen = FALSE; I830DRICloseScreen(pScreen); pI830->directRenderingEnabled = FALSE; - } else { - xf86DrvMsg(pScrn->scrnIndex, X_INFO, - "Initialized DRM memory manager, %ld AGP pages\n" - "\tat AGP offset 0x%lx\n", - aperEnd - aperStart, - aperStart); } } } -#endif +#endif /* XF86DRI_MM */ return TRUE; } - static void -I830AdjustFrame(int scrnIndex, int x, int y, int flags) +i830AdjustFrame(int scrnIndex, int x, int y, int flags) { - ScrnInfoPtr pScrn; - I830Ptr pI830; - vbeInfoPtr pVbe; - unsigned long Start; - - pScrn = xf86Screens[scrnIndex]; - pI830 = I830PTR(pScrn); - pVbe = pI830->pVbe; + ScrnInfoPtr pScrn = xf86Screens[scrnIndex]; + xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(pScrn); + I830Ptr pI830 = I830PTR(pScrn); + xf86OutputPtr output = config->output[config->compat_output]; + xf86CrtcPtr crtc = output->crtc; - DPRINTF(PFX, "I830AdjustFrame: y = %d (+ %d), x = %d (+ %d)\n", + DPRINTF(PFX, "i830AdjustFrame: y = %d (+ %d), x = %d (+ %d)\n", x, pI830->xoffset, y, pI830->yoffset); - /* Sync the engine before adjust frame */ - if (pI830->AccelInfoRec && pI830->AccelInfoRec->NeedToSync) { - (*pI830->AccelInfoRec->Sync)(pScrn); - pI830->AccelInfoRec->NeedToSync = FALSE; - } - - if (pI830->MergedFB) { - I830AdjustFrameMerged(scrnIndex, x, y, flags); - - 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 { - OUTREG(DSPBBASE, pI830->FrontBuffer.Start + ((pI830->FirstframeY0 * pScrn->displayWidth + pI830->FirstframeX0) * pI830->cpp)); - OUTREG(DSPABASE, pI830->FrontBuffer.Start + ((pI830->pScrn_2->frameY0 * pScrn->displayWidth + pI830->pScrn_2->frameX0) * pI830->cpp)); - } - - return; - } - - if (I830IsPrimary(pScrn)) - Start = pI830->FrontBuffer.Start; - else { - I830Ptr pI8301 = I830PTR(pI830->entityPrivate->pScrn_1); - Start = pI8301->FrontBuffer2.Start; - } - - /* Sigh... - * It seems that there are quite a few Video BIOS' that get this wrong. - * So, we'll bypass the VBE call and hit the hardware directly. - */ - - if (pI830->Clone) { - if (!pI830->pipe == 0) { - if (!IS_I965G(pI830)) { - OUTREG(DSPABASE, Start + ((y * pScrn->displayWidth + x) * pI830->cpp)); - } else { - OUTREG(DSPABASE, 0); - OUTREG(DSPASURF, Start + ((y * pScrn->displayWidth + x) * pI830->cpp)); - } - } else { - if (!IS_I965G(pI830)) { - OUTREG(DSPBBASE, Start + ((y * pScrn->displayWidth + x) * pI830->cpp)); - } else { - OUTREG(DSPBBASE, 0); - OUTREG(DSPBSURF, Start + ((y * pScrn->displayWidth + x) * pI830->cpp)); - } - } - } - - if (pI830->pipe == 0) { - if (!IS_I965G(pI830)) { - OUTREG(DSPABASE, Start + ((y * pScrn->displayWidth + x) * pI830->cpp)); - } else { - OUTREG(DSPABASE, 0); - OUTREG(DSPASURF, Start + ((y * pScrn->displayWidth + x) * pI830->cpp)); - } - } else { - if (!IS_I965G(pI830)) { - OUTREG(DSPBBASE, Start + ((y * pScrn->displayWidth + x) * pI830->cpp)); - } else { - OUTREG(DSPBBASE, 0); - OUTREG(DSPBSURF, Start + ((y * pScrn->displayWidth + x) * pI830->cpp)); - } + if (crtc && crtc->enabled) + { + /* Sync the engine before adjust frame */ + i830WaitSync(pScrn); + i830PipeSetBase(crtc, output->initial_x + x, output->initial_y + y); + crtc->x = output->initial_x + x; + crtc->y = output->initial_y + y; } } static void -I830BIOSFreeScreen(int scrnIndex, int flags) +I830FreeScreen(int scrnIndex, int flags) { - I830BIOSFreeRec(xf86Screens[scrnIndex]); + I830FreeRec(xf86Screens[scrnIndex]); if (xf86LoaderCheckSymbol("vgaHWFreeHWRec")) vgaHWFreeHWRec(xf86Screens[scrnIndex]); } -#ifndef SAVERESTORE_HWSTATE -#define SAVERESTORE_HWSTATE 0 -#endif - -#if SAVERESTORE_HWSTATE static void -SaveHWOperatingState(ScrnInfoPtr pScrn) -{ - I830Ptr pI830 = I830PTR(pScrn); - I830RegPtr save = &pI830->SavedReg; - - DPRINTF(PFX, "SaveHWOperatingState\n"); - - return; -} - -static void -RestoreHWOperatingState(ScrnInfoPtr pScrn) -{ - I830Ptr pI830 = I830PTR(pScrn); - I830RegPtr save = &pI830->SavedReg; - - DPRINTF(PFX, "RestoreHWOperatingState\n"); - - return; -} -#endif - -static void -I830BIOSLeaveVT(int scrnIndex, int flags) +I830LeaveVT(int scrnIndex, int flags) { ScrnInfoPtr pScrn = xf86Screens[scrnIndex]; I830Ptr pI830 = I830PTR(pScrn); @@ -7905,20 +2801,11 @@ I830BIOSLeaveVT(int scrnIndex, int flags) TimerCancel(pI830->devicesTimer); pI830->devicesTimer = NULL; -#ifdef I830_XV - /* Give the video overlay code a chance to shutdown. */ - I830VideoSwitchModeBefore(pScrn, NULL); -#endif - - if (pI830->Clone || pI830->MergedFB) { - /* Ensure we don't try and setup modes on a clone head */ - pI830->CloneHDisplay = 0; - pI830->CloneVDisplay = 0; - } + i830SetHotkeyControl(pScrn, HOTKEY_BIOS_SWITCH); if (!I830IsPrimary(pScrn)) { I830Ptr pI8301 = I830PTR(pI830->entityPrivate->pScrn_1); - if (!pI8301->GttBound) { + if (!pI8301->gtt_acquired) { return; } } @@ -7926,6 +2813,7 @@ I830BIOSLeaveVT(int scrnIndex, int flags) #ifdef XF86DRI if (pI830->directRenderingOpen) { DRILock(screenInfo.screens[pScrn->scrnIndex], 0); +#ifdef XF86DRI_MM if (pI830->mmModeFlags & I830_KERNEL_MM) { #ifndef XSERVER_LIBDRM_MM I830DrmMMLock(pI830->drmSubFD, DRM_BO_MEM_TT); @@ -7933,345 +2821,39 @@ I830BIOSLeaveVT(int scrnIndex, int flags) drmMMLock(pI830->drmSubFD, DRM_BO_MEM_TT); #endif } +#endif /* XF86DRI_MM */ I830DRISetVBlankInterrupt (pScrn, FALSE); drmCtlUninstHandler(pI830->drmSubFD); } #endif -#if SAVERESTORE_HWSTATE - if (!pI830->closing) - SaveHWOperatingState(pScrn); -#endif - if (pI830->CursorInfoRec && pI830->CursorInfoRec->HideCursor) pI830->CursorInfoRec->HideCursor(pScrn); ResetState(pScrn, TRUE); - if (I830IsPrimary(pScrn)) { - if (!SetDisplayDevices(pScrn, pI830->savedDevices)) { - xf86DrvMsg(pScrn->scrnIndex, X_WARNING, - "Failed to switch back to original display devices (0x%x)\n", - pI830->savedDevices); - } else { - xf86DrvMsg(pScrn->scrnIndex, X_WARNING, - "Successfully set original devices\n"); - } - } - RestoreHWState(pScrn); - RestoreBIOSMemSize(pScrn); + + i830CompareRegsToSnapshot(pScrn, "After LeaveVT"); + i830DumpRegs (pScrn); + if (I830IsPrimary(pScrn)) - I830UnbindAGPMemory(pScrn); + i830_unbind_all_memory(pScrn); if (pI830->AccelInfoRec) pI830->AccelInfoRec->NeedToSync = FALSE; - - /* DO IT AGAIN! AS IT SEEMS THAT SOME LFPs FLICKER OTHERWISE */ - if (I830IsPrimary(pScrn)) { - if (!SetDisplayDevices(pScrn, pI830->savedDevices)) { - xf86DrvMsg(pScrn->scrnIndex, X_WARNING, - "Failed to switch back to original display devices (0x%x) (2)\n", - pI830->savedDevices); - } else { - xf86DrvMsg(pScrn->scrnIndex, X_WARNING, - "Successfully set original devices (2)\n"); - } - } } -static Bool -I830DetectMonitorChange(ScrnInfoPtr pScrn) -{ - I830Ptr pI830 = I830PTR(pScrn); - pointer pDDCModule = NULL; - DisplayModePtr p, pMon; - int memsize; - int DDCclock = 0, DDCclock2 = 0; - int displayWidth = pScrn->displayWidth; - int curHDisplay = pScrn->currentMode->HDisplay; - int curVDisplay = pScrn->currentMode->VDisplay; - xf86MonPtr monitor = NULL; - - DPRINTF(PFX, "Detect Monitor Change\n"); - - SetPipeAccess(pScrn); - - /* Re-read EDID */ - pDDCModule = xf86LoadSubModule(pScrn, "ddc"); - - if (pI830->MergedFB) { - pI830->pVbe->ddc = DDC_UNCHECKED; - SetBIOSPipe(pScrn, !pI830->pipe); - monitor = vbeDoEDID(pI830->pVbe, pDDCModule); - if ((pI830->pScrn_2->monitor->DDC = monitor) != NULL) { - xf86PrintEDID(monitor); - xf86SetDDCproperties(pScrn, monitor); - } - SetPipeAccess(pScrn); - } - - pI830->pVbe->ddc = DDC_UNCHECKED; - monitor = vbeDoEDID(pI830->pVbe, pDDCModule); - xf86UnloadSubModule(pDDCModule); - if ((pScrn->monitor->DDC = monitor) != NULL) { - xf86PrintEDID(monitor); - xf86SetDDCproperties(pScrn, monitor); - } - - DDCclock = I830UseDDC(pScrn); - - /* Check if DDC exists on the second head, if not don't abort. */ - if (pI830->MergedFB) - DDCclock2 = I830UseDDC(pI830->pScrn_2); - - /* Revalidate the modes */ - - /* - * Note: VBE modes (> 0x7f) won't work with Intel's extended BIOS - * functions. - */ - SetPipeAccess(pScrn); - - pScrn->modePool = I830GetModePool(pScrn, pI830->pVbe, pI830->vbeInfo); - - if (!pScrn->modePool) { - /* This is bad, which would cause the Xserver to exit, maybe - * we should default to a 640x480 @ 60Hz mode here ??? */ - xf86DrvMsg(pScrn->scrnIndex, X_ERROR, - "No Video BIOS modes for chosen depth.\n"); - return FALSE; - } - - if (pI830->MergedFB) { - SetBIOSPipe(pScrn, !pI830->pipe); - xf86DrvMsg(pScrn->scrnIndex, X_INFO, - "Retrieving mode pool for second head.\n"); - pI830->pScrn_2->modePool = I830GetModePool(pI830->pScrn_2, pI830->pVbe, pI830->vbeInfo); - - if (!pI830->pScrn_2->modePool) { - xf86DrvMsg(pScrn->scrnIndex, X_ERROR, - "No Video BIOS modes for chosen depth.\n"); - PreInitCleanup(pScrn); - return FALSE; - } - SetPipeAccess(pScrn); - } - - VBESetModeNames(pScrn->modePool); - if (pI830->MergedFB) - VBESetModeNames(pI830->pScrn_2->modePool); - - if (pScrn->videoRam > (pI830->vbeInfo->TotalMemory * 64)) - memsize = pI830->vbeInfo->TotalMemory * 64; - else - memsize = pScrn->videoRam; - - VBEValidateModes(pScrn, pScrn->monitor->Modes, pScrn->display->modes, NULL, - NULL, 0, MAX_DISPLAY_PITCH, 1, - 0, MAX_DISPLAY_HEIGHT, - pScrn->display->virtualX, - pScrn->display->virtualY, - memsize, LOOKUP_BEST_REFRESH); - - if (pI830->MergedFB) { - VBEValidateModes(pI830->pScrn_2, pI830->pScrn_2->monitor->Modes, - pI830->pScrn_2->display->modes, NULL, - NULL, 0, MAX_DISPLAY_PITCH, 1, - 0, MAX_DISPLAY_HEIGHT, - pScrn->display->virtualX, - pScrn->display->virtualY, - memsize, LOOKUP_BEST_REFRESH); - } - - if (DDCclock > 0) { - p = pScrn->modes; - if (p == NULL) - return FALSE; - do { - int Clock = 100000000; /* incredible value */ - - if (p->status == MODE_OK) { - for (pMon = pScrn->monitor->Modes; pMon != NULL; pMon = pMon->next) { - if ((pMon->HDisplay != p->HDisplay) || - (pMon->VDisplay != p->VDisplay) || - (pMon->Flags & (V_INTERLACE | V_DBLSCAN | V_CLKDIV2))) - continue; - - /* Find lowest supported Clock for this resolution */ - if (Clock > pMon->Clock) - Clock = pMon->Clock; - } - - if (Clock != 100000000 && DDCclock < 2550 && Clock / 1000.0 > DDCclock) { - ErrorF("(%s,%s) mode clock %gMHz exceeds DDC maximum %dMHz\n", - p->name, pScrn->monitor->id, - Clock/1000.0, DDCclock); - p->status = MODE_BAD; - } - } - p = p->next; - } while (p != NULL && p != pScrn->modes); - } - - /* Only use this if we've got DDC available */ - if (pI830->MergedFB && DDCclock2 > 0) { - p = pI830->pScrn_2->modes; - if (p == NULL) - return FALSE; - do { - int Clock = 100000000; /* incredible value */ - - if (p->status == MODE_OK) { - for (pMon = pI830->pScrn_2->monitor->Modes; pMon != NULL; pMon = pMon->next) { - if ((pMon->HDisplay != p->HDisplay) || - (pMon->VDisplay != p->VDisplay) || - (pMon->Flags & (V_INTERLACE | V_DBLSCAN | V_CLKDIV2))) - continue; - - /* Find lowest supported Clock for this resolution */ - if (Clock > pMon->Clock) - Clock = pMon->Clock; - } - - if (Clock != 100000000 && DDCclock2 < 2550 && Clock / 1000.0 > DDCclock2) { - ErrorF("(%s,%s) mode clock %gMHz exceeds DDC maximum %dMHz\n", - p->name, pI830->pScrn_2->monitor->id, - Clock/1000.0, DDCclock2); - p->status = MODE_BAD; - } - } - p = p->next; - } while (p != NULL && p != pI830->pScrn_2->modes); - } - - xf86PruneDriverModes(pScrn); - - if (pI830->MergedFB) - xf86PruneDriverModes(pI830->pScrn_2); - - if (pI830->MergedFB) { - DisplayModePtr old_modes, cur_mode; - - old_modes = pScrn->modes; - cur_mode = pScrn->currentMode; - - xf86DrvMsg(pScrn->scrnIndex, X_INFO, "MergedFB: Generating mode list\n"); - - pScrn->modes = I830GenerateModeList(pScrn, pI830->MetaModes, - old_modes, pI830->pScrn_2->modes, - pI830->SecondPosition); - - if(!pScrn->modes) { - xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "No modes. Disabling MergedFB.\n"); - pScrn->modes = old_modes; - pScrn->currentMode = cur_mode; - pI830->MergedFB = FALSE; - } - } - - if (!pI830->vesa->useDefaultRefresh) - I830SetModeParameters(pScrn, pI830->pVbe); - - /* Now check if the previously used mode is o.k. for the current monitor. - * This allows VT switching to continue happily when not disconnecting - * and reconnecting monitors */ - - pScrn->currentMode = pScrn->modes; - - if (pI830->MergedFB) { - /* If no virtual dimension was given by the user, - * calculate a sane one now. Adapts pScrn->virtualX, - * pScrn->virtualY and pScrn->displayWidth. - */ - I830RecalcDefaultVirtualSize(pScrn); - - pScrn->modes = pScrn->modes->next; /* We get the last from GenerateModeList(), skip to first */ - pScrn->currentMode = pScrn->modes; - pI830->currentMode = pScrn->currentMode; - } - - pScrn->displayWidth = displayWidth; /* restore old displayWidth */ - - p = pScrn->modes; - if (p == NULL) - return FALSE; - do { - if ((p->HDisplay == curHDisplay) && - (p->VDisplay == curVDisplay) && - (!(p->Flags & (V_INTERLACE | V_DBLSCAN | V_CLKDIV2)))) { - pScrn->currentMode = p; /* previous mode is o.k. */ - } - p = p->next; - } while (p != NULL && p != pScrn->modes); - - I830PrintModes(pScrn); - - /* Now readjust for panning if necessary */ - { - pScrn->frameX0 = (pScrn->frameX0 + pScrn->frameX1 + 1 - pScrn->currentMode->HDisplay) / 2; - - if (pScrn->frameX0 < 0) - pScrn->frameX0 = 0; - - pScrn->frameX1 = pScrn->frameX0 + pScrn->currentMode->HDisplay - 1; - if (pScrn->frameX1 >= pScrn->virtualX) { - pScrn->frameX0 = pScrn->virtualX - pScrn->currentMode->HDisplay; - pScrn->frameX1 = pScrn->virtualX - 1; - } - - pScrn->frameY0 = (pScrn->frameY0 + pScrn->frameY1 + 1 - pScrn->currentMode->VDisplay) / 2; - - if (pScrn->frameY0 < 0) - pScrn->frameY0 = 0; - - pScrn->frameY1 = pScrn->frameY0 + pScrn->currentMode->VDisplay - 1; - if (pScrn->frameY1 >= pScrn->virtualY) { - pScrn->frameY0 = pScrn->virtualY - pScrn->currentMode->VDisplay; - pScrn->frameY1 = pScrn->virtualY - 1; - } - } - - if (pI830->MergedFB) - I830AdjustFrameMerged(pScrn->scrnIndex, pScrn->frameX0, pScrn->frameY0, 0); - - return TRUE; -} - -Bool -I830CheckModeSupport(ScrnInfoPtr pScrn, int x, int y, int mode) -{ - I830Ptr pI830 = I830PTR(pScrn); - Bool ret = TRUE; - - if (pI830->Clone) { - if (pI830->pipeDisplaySize[0].x2 != 0) { - if (x > pI830->pipeDisplaySize[0].x2 || - y > pI830->pipeDisplaySize[0].y2) { - xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Bad Clone Mode removing\n"); - return FALSE; - } - } - if (pI830->pipeDisplaySize[1].x2 != 0) { - if (x > pI830->pipeDisplaySize[1].x2 || - y > pI830->pipeDisplaySize[1].y2) { - xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Bad Clone Mode removing\n"); - return FALSE; - } - } - } - - return ret; -} - /* * This gets called when gaining control of the VT, and from ScreenInit(). */ static Bool -I830BIOSEnterVT(int scrnIndex, int flags) +I830EnterVT(int scrnIndex, int flags) { ScrnInfoPtr pScrn = xf86Screens[scrnIndex]; - I830Ptr pI830 = I830PTR(pScrn); + xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn); + I830Ptr pI830 = I830PTR(pScrn); + int i; DPRINTF(PFX, "Enter VT\n"); @@ -8292,70 +2874,44 @@ I830BIOSEnterVT(int scrnIndex, int flags) pScrn->virtualY * pScrn->displayWidth * pI830->cpp); #endif - if (I830IsPrimary(pScrn)) { - /* - * This is needed for restoring from ACPI modes (especially S3) - * so that we warmboot the Video BIOS. Some platforms have problems, - * warm booting when we don't need to, so check that we can call - * the Video BIOS with our saved devices, and only when that fails, - * we'll warm boot it. - */ - /* Check Pipe conf registers or possibly HTOTAL/VTOTAL for 0x00000000)*/ - CARD32 temp; - Bool set = I830Set640x480(pScrn); - temp = pI830->pipe ? INREG(PIPEBCONF) : INREG(PIPEACONF); - if (!set || !(temp & 0x80000000)) { - xf86Int10InfoPtr pInt; - - xf86DrvMsg(pScrn->scrnIndex, X_INFO, - "Detected resume, re-POSTing.\n"); - - pInt = xf86InitInt10(pI830->pEnt->index); - - /* Now perform our warm boot */ - if (pInt) { - pInt->num = 0xe6; - xf86ExecX86int10 (pInt); - xf86FreeInt10 (pInt); - xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Re-POSTing via int10.\n"); - } else { - xf86DrvMsg(pScrn->scrnIndex, X_WARNING, - "Re-POSTing via int10 failed, trying to continue.\n"); - } - } - - /* Finally, re-setup the display devices */ - if (!SetDisplayDevices(pScrn, pI830->operatingDevices)) { - xf86DrvMsg(pScrn->scrnIndex, X_WARNING, - "Failed to switch to configured display devices\n"); - return FALSE; - } - } - - /* Setup for device monitoring status */ - pI830->monitorSwitch = pI830->toggleDevices = INREG(SWF0) & 0x0000FFFF; - if (I830IsPrimary(pScrn)) - if (!I830BindAGPMemory(pScrn)) + if (!i830_bind_all_memory(pScrn)) return FALSE; - CheckInheritedState(pScrn); - if (I830IsPrimary(pScrn)) { - if (!TweakMemorySize(pScrn, pI830->newBIOSMemSize,FALSE)) - SetBIOSMemSize(pScrn, pI830->newBIOSMemSize); + if (i830_check_error_state(pScrn)) { + xf86DrvMsg(pScrn->scrnIndex, X_WARNING, + "Existing errors found in hardware state.\n"); } ResetState(pScrn, FALSE); SetHWOperatingState(pScrn); - if (!pI830->starting) - I830DetectMonitorChange(pScrn); - - if (!I830VESASetMode(pScrn, pScrn->currentMode)) - return FALSE; - -#ifdef I830_XV - I830VideoSwitchModeAfter(pScrn, pScrn->currentMode); + for (i = 0; i < xf86_config->num_crtc; i++) + { + xf86CrtcPtr crtc = xf86_config->crtc[i]; + + /* Mark that we'll need to re-set the mode for sure */ + memset(&crtc->mode, 0, sizeof(crtc->mode)); + if (!crtc->desiredMode.CrtcHDisplay) + { + crtc->desiredMode = *i830PipeFindClosestMode (crtc, pScrn->currentMode); + crtc->desiredRotation = RR_Rotate_0; + crtc->desiredX = 0; + crtc->desiredY = 0; + } + + if (!xf86CrtcSetMode (crtc, &crtc->desiredMode, crtc->desiredRotation, + crtc->desiredX, crtc->desiredY)) + return FALSE; + } + + xf86DisableUnusedFunctions(pScrn); + + i830DumpRegs (pScrn); + i830DescribeOutputConfiguration(pScrn); + +#ifdef XF86DRI + I830DRISetVBlankInterrupt (pScrn, TRUE); #endif ResetState(pScrn, TRUE); @@ -8363,10 +2919,6 @@ I830BIOSEnterVT(int scrnIndex, int flags) pScrn->AdjustFrame(scrnIndex, pScrn->frameX0, pScrn->frameY0, 0); -#if SAVERESTORE_HWSTATE - RestoreHWOperatingState(pScrn); -#endif - #ifdef XF86DRI if (pI830->directRenderingEnabled) { @@ -8387,6 +2939,7 @@ I830BIOSEnterVT(int scrnIndex, int flags) for(i = 0; i < I830_NR_TEX_REGIONS+1 ; i++) sarea->texList[i].age = sarea->texAge; +#ifdef XF86DRI_MM if (pI830->mmModeFlags & I830_KERNEL_MM) { #ifndef XSERVER_LIBDRM_MM I830DrmMMUnlock(pI830->drmSubFD, DRM_BO_MEM_TT); @@ -8394,6 +2947,7 @@ I830BIOSEnterVT(int scrnIndex, int flags) drmMMUnlock(pI830->drmSubFD, DRM_BO_MEM_TT); #endif } +#endif /* XF86DRI_MM */ DPRINTF(PFX, "calling dri unlock\n"); DRIUnlock(screenInfo.screens[pScrn->scrnIndex]); @@ -8402,6 +2956,13 @@ I830BIOSEnterVT(int scrnIndex, int flags) } #endif + /* Set the hotkey to just notify us. We can check its results periodically + * in the CheckDevicesTimer. Eventually we want the kernel to just hand us + * an input event when someone presses the button, but for now we just have + * to poll. + */ + i830SetHotkeyControl(pScrn, HOTKEY_DRIVER_NOTIFY); + /* Needed for rotation */ IntelEmitInvarientState(pScrn); @@ -8410,204 +2971,41 @@ I830BIOSEnterVT(int scrnIndex, int flags) pI830->currentMode = pScrn->currentMode; - /* Force invarient state when rotated to be emitted */ + /* Force invarient 3D state to be emitted */ *pI830->used3D = 1<<31; return TRUE; } static Bool -I830BIOSSwitchMode(int scrnIndex, DisplayModePtr mode, int flags) +I830SwitchMode(int scrnIndex, DisplayModePtr mode, int flags) { ScrnInfoPtr pScrn = xf86Screens[scrnIndex]; I830Ptr pI830 = I830PTR(pScrn); Bool ret = TRUE; - PixmapPtr pspix = (*pScrn->pScreen->GetScreenPixmap) (pScrn->pScreen); - - DPRINTF(PFX, "I830BIOSSwitchMode: mode == %p\n", mode); - -#ifdef I830_XV - /* Give the video overlay code a chance to see the new mode. */ - I830VideoSwitchModeBefore(pScrn, mode); -#endif - /* Sync the engine before mode switch */ - if (pI830->AccelInfoRec && pI830->AccelInfoRec->NeedToSync) { - (*pI830->AccelInfoRec->Sync)(pScrn); - pI830->AccelInfoRec->NeedToSync = FALSE; - } + DPRINTF(PFX, "I830SwitchMode: mode == %p\n", mode); - /* Check if our currentmode is about to change. We do this so if we - * are rotating, we don't need to call the mode setup again. - */ - if (pI830->currentMode != mode) { - if (!I830VESASetMode(pScrn, mode)) - ret = FALSE; - } - - /* Kludge to detect Rotate or Vidmode switch. Not very elegant, but - * workable given the implementation currently. We only need to call - * the rotation function when we know that the framebuffer has been - * disabled by the EnableDisableFBAccess() function. - * - * The extra WindowTable check detects a rotation at startup. - */ - if ( (!WindowTable[pScrn->scrnIndex] || pspix->devPrivate.ptr == NULL) && - !pI830->DGAactive && (pScrn->PointerMoved == I830PointerMoved) && - !IS_I965G(pI830)) { - if (!I830Rotate(pScrn, mode)) - ret = FALSE; - } - - /* Either the original setmode or rotation failed, so restore the previous - * video mode here, as we'll have already re-instated the original rotation. - */ - if (!ret) { - if (!I830VESASetMode(pScrn, pI830->currentMode)) { - xf86DrvMsg(scrnIndex, X_INFO, - "Failed to restore previous mode (SwitchMode)\n"); - } - -#ifdef I830_XV - /* Give the video overlay code a chance to see the new mode. */ - I830VideoSwitchModeAfter(pScrn, pI830->currentMode); -#endif - } else { + if (!i830SetMode(pScrn, mode, pI830->rotation)) pI830->currentMode = mode; -#ifdef I830_XV - /* Give the video overlay code a chance to see the new mode. */ - I830VideoSwitchModeAfter(pScrn, mode); -#endif - } - - /* Since RandR (indirectly) uses SwitchMode(), we need to - * update our Xinerama info here, too, in case of resizing - * Call this unconditionally, as it also sets some fields in the SAREA - */ - I830UpdateXineramaScreenInfo(pScrn); - return ret; } static Bool -I830BIOSSaveScreen(ScreenPtr pScreen, int mode) -{ - ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; - I830Ptr pI830 = I830PTR(pScrn); - Bool on = xf86IsUnblank(mode); - CARD32 temp, ctrl, base, surf; - - DPRINTF(PFX, "I830BIOSSaveScreen: %d, on is %s\n", mode, BOOLTOSTRING(on)); - - if (pScrn->vtSema) { - if (pI830->pipe == 0) { - ctrl = DSPACNTR; - base = DSPABASE; - surf = DSPASURF; - } else { - ctrl = DSPBCNTR; - base = DSPBADDR; - surf = DSPBSURF; - } - if (pI830->planeEnabled[pI830->pipe]) { - temp = INREG(ctrl); - if (on) - temp |= DISPLAY_PLANE_ENABLE; - else - temp &= ~DISPLAY_PLANE_ENABLE; - OUTREG(ctrl, temp); - /* Flush changes */ - temp = INREG(base); - OUTREG(base, temp); - if (IS_I965G(pI830)) { - temp = INREG(surf); - OUTREG(surf, temp); - } - } - - if (pI830->CursorInfoRec && !pI830->SWCursor && pI830->cursorOn) { - if (on) - pI830->CursorInfoRec->ShowCursor(pScrn); - else - pI830->CursorInfoRec->HideCursor(pScrn); - pI830->cursorOn = TRUE; - } - } - return TRUE; -} - -/* Use the VBE version when available. */ -static void -I830DisplayPowerManagementSet(ScrnInfoPtr pScrn, int PowerManagementMode, - int flags) -{ - I830Ptr pI830 = I830PTR(pScrn); - vbeInfoPtr pVbe = pI830->pVbe; - - if (pI830->Clone || pI830->MergedFB) { - SetBIOSPipe(pScrn, !pI830->pipe); - if (xf86LoaderCheckSymbol("VBEDPMSSet")) { - VBEDPMSSet(pVbe, PowerManagementMode); - } else { - pVbe->pInt10->num = 0x10; - pVbe->pInt10->ax = 0x4f10; - pVbe->pInt10->bx = 0x01; - - switch (PowerManagementMode) { - case DPMSModeOn: - break; - case DPMSModeStandby: - pVbe->pInt10->bx |= 0x0100; - break; - case DPMSModeSuspend: - pVbe->pInt10->bx |= 0x0200; - break; - case DPMSModeOff: - pVbe->pInt10->bx |= 0x0400; - break; - } - xf86ExecX86int10_wrapper(pVbe->pInt10, pScrn); - } - } - - SetPipeAccess(pScrn); - - if (xf86LoaderCheckSymbol("VBEDPMSSet")) { - VBEDPMSSet(pVbe, PowerManagementMode); - } else { - pVbe->pInt10->num = 0x10; - pVbe->pInt10->ax = 0x4f10; - pVbe->pInt10->bx = 0x01; - - switch (PowerManagementMode) { - case DPMSModeOn: - break; - case DPMSModeStandby: - pVbe->pInt10->bx |= 0x0100; - break; - case DPMSModeSuspend: - pVbe->pInt10->bx |= 0x0200; - break; - case DPMSModeOff: - pVbe->pInt10->bx |= 0x0400; - break; - } - xf86ExecX86int10_wrapper(pVbe->pInt10, pScrn); - } -} - -static Bool -I830BIOSCloseScreen(int scrnIndex, ScreenPtr pScreen) +I830CloseScreen(int scrnIndex, ScreenPtr pScreen) { ScrnInfoPtr pScrn = xf86Screens[scrnIndex]; I830Ptr pI830 = I830PTR(pScrn); +#ifdef I830_USE_XAA XAAInfoRecPtr infoPtr = pI830->AccelInfoRec; +#endif pI830->closing = TRUE; #ifdef XF86DRI if (pI830->directRenderingOpen) { +#ifdef XF86DRI_MM if (pI830->mmModeFlags & I830_KERNEL_MM) { #ifndef XSERVER_LIBDRM_MM I830DrmMMTakedown(pI830->drmSubFD, DRM_BO_MEM_TT); @@ -8615,13 +3013,14 @@ I830BIOSCloseScreen(int scrnIndex, ScreenPtr pScreen) drmMMTakedown(pI830->drmSubFD, DRM_BO_MEM_TT); #endif } +#endif /* XF86DRI_MM */ pI830->directRenderingOpen = FALSE; I830DRICloseScreen(pScreen); } #endif if (pScrn->vtSema == TRUE) { - I830BIOSLeaveVT(scrnIndex, 0); + I830LeaveVT(scrnIndex, 0); } if (pI830->devicesTimer) @@ -8636,14 +3035,21 @@ I830BIOSCloseScreen(int scrnIndex, ScreenPtr pScreen) xfree(pI830->ScanlineColorExpandBuffers); pI830->ScanlineColorExpandBuffers = 0; } - +#ifdef I830_USE_XAA if (infoPtr) { if (infoPtr->ScanlineColorExpandBuffers) xfree(infoPtr->ScanlineColorExpandBuffers); XAADestroyInfoRec(infoPtr); pI830->AccelInfoRec = NULL; } - +#endif +#ifdef I830_USE_EXA + if (pI830->useEXA && pI830->EXADriverPtr) { + exaDriverFini(pScreen); + xfree(pI830->EXADriverPtr); + pI830->EXADriverPtr = NULL; + } +#endif if (pI830->CursorInfoRec) { xf86DestroyCursorInfoRec(pI830->CursorInfoRec); pI830->CursorInfoRec = 0; @@ -8654,12 +3060,6 @@ I830BIOSCloseScreen(int scrnIndex, ScreenPtr pScreen) xfree(pI830->LpRing); pI830->LpRing = NULL; - xfree(pI830->CursorMem); - pI830->CursorMem = NULL; - xfree(pI830->CursorMemARGB); - pI830->CursorMemARGB = NULL; - xfree(pI830->OverlayMem); - pI830->OverlayMem = NULL; xfree(pI830->overlayOn); pI830->overlayOn = NULL; xfree(pI830->used3D); @@ -8756,15 +3156,6 @@ I830PMEvent(int scrnIndex, pmEvent event, Bool undo) ErrorF("I830PMEvent: Capability change\n"); - /* ACPI Toggle */ - pI830->toggleDevices = GetNextDisplayDeviceList(pScrn, 1); - if (xf86IsEntityShared(pScrn->entityList[0])) { - I830Ptr pI8302 = I830PTR(pI830->entityPrivate->pScrn_2); - pI8302->toggleDevices = pI830->toggleDevices; - } - - xf86DrvMsg(pScrn->scrnIndex, X_INFO, "ACPI Toggle to 0x%x\n",pI830->toggleDevices); - I830CheckDevicesTimer(NULL, 0, pScrn); SaveScreens(SCREEN_SAVER_FORCER, ScreenSaverReset); break; @@ -8774,338 +3165,127 @@ I830PMEvent(int scrnIndex, pmEvent event, Bool undo) return TRUE; } -static int CountBits(int a) +#if 0 +/** + * This function is used for testing of the screen detect functions from the + * periodic timer. + */ +static void +i830MonitorDetectDebugger(ScrnInfoPtr pScrn) { - int i; - int b = 0; + Bool found_crt; + I830Ptr pI830 = I830PTR(pScrn); + int start, finish, i; - for (i=0;i<8;i++) { - if (a & (1<<i)) - b+=1; - } + if (!pScrn->vtSema) + return 1000; + + for (i = 0; i < xf86_config->num_output; i++) { + enum output_status ret; + char *result; + + start = GetTimeInMillis(); + ret = pI830->output[i].detect(pScrn, &pI830->output[i]); + finish = GetTimeInMillis(); - return b; + if (ret == OUTPUT_STATUS_CONNECTED) + result = "connected"; + else if (ret == OUTPUT_STATUS_DISCONNECTED) + result = "disconnected"; + else + result = "unknown"; + + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Detected SDVO as %s in %dms\n", + result, finish - start); + } } +#endif static CARD32 I830CheckDevicesTimer(OsTimerPtr timer, CARD32 now, pointer arg) { ScrnInfoPtr pScrn = (ScrnInfoPtr) arg; I830Ptr pI830 = I830PTR(pScrn); - int cloned = 0; - - if (pScrn->vtSema) { - /* Check for monitor lid being closed/opened and act accordingly */ - CARD32 adjust; - CARD32 temp = INREG(SWF0) & 0x0000FFFF; - int fixup = 0; - I830Ptr pI8301; - I830Ptr pI8302 = NULL; - - if (I830IsPrimary(pScrn)) - pI8301 = pI830; - else - pI8301 = I830PTR(pI830->entityPrivate->pScrn_1); - - if (xf86IsEntityShared(pScrn->entityList[0])) - pI8302 = I830PTR(pI830->entityPrivate->pScrn_2); - - /* this avoids several BIOS calls if possible */ - if (pI830->monitorSwitch != temp || pI830->monitorSwitch != pI830->toggleDevices) { - xf86DrvMsg(pScrn->scrnIndex, X_INFO, - "Hotkey switch to 0x%lx.\n", (unsigned long) temp); - - if (pI830->AccelInfoRec && pI830->AccelInfoRec->NeedToSync) { - (*pI830->AccelInfoRec->Sync)(pScrn); - pI830->AccelInfoRec->NeedToSync = FALSE; - if (xf86IsEntityShared(pScrn->entityList[0])) - pI8302->AccelInfoRec->NeedToSync = FALSE; - } - - GetAttachableDisplayDeviceList(pScrn); - - pI8301->lastDevice0 = pI8301->lastDevice1; - pI8301->lastDevice1 = pI8301->lastDevice2; - pI8301->lastDevice2 = pI8301->monitorSwitch; - - if (temp != pI8301->lastDevice1 && - temp != pI8301->lastDevice2) { - xf86DrvMsg(pScrn->scrnIndex, X_INFO, - "Detected three device configs.\n"); - } else - if (CountBits(temp & 0xff) > 1) { - xf86DrvMsg(pScrn->scrnIndex, X_INFO, - "Detected cloned pipe mode (A).\n"); - if (xf86IsEntityShared(pScrn->entityList[0]) || pI830->Clone) - temp = pI8301->MonType2 << 8 | pI8301->MonType1; - } else - if (CountBits((temp & 0xff00) >> 8) > 1) { - xf86DrvMsg(pScrn->scrnIndex, X_INFO, - "Detected cloned pipe mode (B).\n"); - if (xf86IsEntityShared(pScrn->entityList[0]) || pI830->Clone) - temp = pI8301->MonType2 << 8 | pI8301->MonType1; - } else - if (pI8301->lastDevice1 && pI8301->lastDevice2) { - if ( ((pI8301->lastDevice1 & 0xFF00) == 0) && - ((pI8301->lastDevice2 & 0x00FF) == 0) ) { - xf86DrvMsg(pScrn->scrnIndex, X_INFO, - "Detected last devices (1).\n"); - cloned = 1; - } else if ( ((pI8301->lastDevice2 & 0xFF00) == 0) && - ((pI8301->lastDevice1 & 0x00FF) == 0) ) { - xf86DrvMsg(pScrn->scrnIndex, X_INFO, - "Detected last devices (2).\n"); - cloned = 1; - } else - cloned = 0; - } - - if (cloned && - ((CountBits(pI8301->lastDevice1 & 0xff) > 1) || - ((CountBits((pI8301->lastDevice1 & 0xff00) >> 8) > 1))) ) { - xf86DrvMsg(pScrn->scrnIndex, X_INFO, - "Detected duplicate (1).\n"); - cloned = 0; - } else - if (cloned && - ((CountBits(pI8301->lastDevice2 & 0xff) > 1) || - ((CountBits((pI8301->lastDevice2 & 0xff00) >> 8) > 1))) ) { - xf86DrvMsg(pScrn->scrnIndex, X_INFO, - "Detected duplicate (2).\n"); - cloned = 0; - } - - xf86DrvMsg(pScrn->scrnIndex, X_INFO, - "Requested display devices 0x%lx.\n", - (unsigned long) temp); - - - /* If the BIOS doesn't flip between CRT, LFP and CRT+LFP we fake - * it here as it seems some just flip between CRT and LFP. Ugh! - * - * So this pushes them onto Pipe B and clones the displays, which - * is what most BIOS' should be doing. - * - * Cloned pipe mode should only be done when running single head. - */ - if (xf86IsEntityShared(pScrn->entityList[0])) { - cloned = 0; - - /* Some BIOS' don't realize we may be in true dual head mode. - * And only display the primary output on both when switching. - * We detect this here and cycle back to both pipes. - */ - if ((pI830->lastDevice0 == temp) && - ((CountBits(pI8301->lastDevice2 & 0xff) > 1) || - ((CountBits((pI8301->lastDevice2 & 0xff00) >> 8) > 1))) ) { - xf86DrvMsg(pScrn->scrnIndex, X_INFO, - "Detected cloned pipe mode when dual head on previous switch. (0x%x -> 0x%x)\n", (int)temp, pI8301->MonType2 << 8 | pI8301->MonType1); - temp = pI8301->MonType2 << 8 | pI8301->MonType1; - } - - } - - if (cloned) { - if (pI830->Clone) - temp = pI8301->MonType2 << 8 | pI8301->MonType1; - else if (pI8301->lastDevice1 & 0xFF) - temp = pI8301->lastDevice1 << 8 | pI8301->lastDevice2; - else - temp = pI8301->lastDevice2 << 8 | pI8301->lastDevice1; - } - - /* Jump to our next mode if we detect we've been here before */ - if (temp == pI8301->lastDevice1 || temp == pI8301->lastDevice2) { - temp = GetToggleList(pScrn, 1); - xf86DrvMsg(pScrn->scrnIndex, X_INFO, - "Detected duplicate devices. Toggling (0x%lx)\n", - (unsigned long) temp); - } - - xf86DrvMsg(pScrn->scrnIndex, X_INFO, - "Detected display change operation (0x%x, 0x%x, 0x%lx).\n", - pI8301->lastDevice1, pI8301->lastDevice2, - (unsigned long) temp); - - /* So that if we close on the wrong config, we restore correctly */ - pI830->specifiedMonitor = TRUE; - - if (!xf86IsEntityShared(pScrn->entityList[0])) { - if ((temp & 0xFF00) && (temp & 0x00FF)) { - pI830->Clone = TRUE; - xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Setting Clone mode\n"); - } else { - pI830->Clone = FALSE; - xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Clearing Clone mode\n"); - } - } - - { - /* Turn Cursor off before switching */ - Bool on = pI830->cursorOn; - if (pI830->CursorInfoRec && pI830->CursorInfoRec->HideCursor) - pI830->CursorInfoRec->HideCursor(pScrn); - pI830->cursorOn = on; - } - - /* double check the display devices are what's configured and try - * not to do it twice because of dual heads with the code above */ - if (!SetDisplayDevices(pScrn, temp)) { - if ( cloned && - ((CountBits(temp & 0xff) > 1) || - (CountBits((temp & 0xff00) >> 8) > 1)) ) { - temp = pI8301->lastDevice2 | pI8301->lastDevice1; - xf86DrvMsg(pScrn->scrnIndex, X_WARNING, "Cloning failed, " - "trying dual pipe clone mode (0x%lx)\n", - (unsigned long) temp); - if (!SetDisplayDevices(pScrn, temp)) - xf86DrvMsg(pScrn->scrnIndex, X_WARNING, "Failed to switch " - "to configured display devices (0x%lx).\n", - (unsigned long) temp); - else { - pI830->Clone = TRUE; - xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Setting Clone mode\n"); - } - } - } - - pI8301->monitorSwitch = temp; - pI8301->operatingDevices = temp; - pI8301->toggleDevices = temp; + CARD8 gr18; - if (xf86IsEntityShared(pScrn->entityList[0])) { - pI8302->operatingDevices = pI8301->operatingDevices; - pI8302->monitorSwitch = pI8301->monitorSwitch; - pI8302->toggleDevices = pI8301->toggleDevices; - } - - fixup = 1; + if (!pScrn->vtSema) + return 1000; #if 0 - xf86DrvMsg(pScrn->scrnIndex, X_INFO, - "ACPI _DGS queried devices is 0x%x, but probed is 0x%x monitorSwitch=0x%x\n", - pI830->toggleDevices, INREG(SWF0), pI830->monitorSwitch); + i830MonitorDetectDebugger(pScrn); #endif - } else { - int offset = -1; - if (I830IsPrimary(pScrn)) - offset = pI8301->FrontBuffer.Start + ((pScrn->frameY0 * pI830->displayWidth + pScrn->frameX0) * pI830->cpp); - else { - offset = pI8301->FrontBuffer2.Start + ((pScrn->frameY0 * pI830->displayWidth + pScrn->frameX0) * pI830->cpp); - } - if (IS_I965G(pI830)) { - if (pI830->pipe == 0) - adjust = INREG(DSPASURF); - else - adjust = INREG(DSPBSURF); - } else { - if (pI830->pipe == 0) - adjust = INREG(DSPABASE); - else - adjust = INREG(DSPBBASE); - } + /* Check for a hotkey press report from the BIOS. */ + gr18 = pI830->readControl(pI830, GRX, 0x18); + if ((gr18 & (HOTKEY_TOGGLE | HOTKEY_SWITCH)) != 0) { + /* The user has pressed the hotkey requesting a toggle or switch. + * Re-probe our connected displays and turn on whatever we find. + * + * In the future, we want the hotkey to dump down to a user app which + * implements a sensible policy using RandR-1.2. For now, all we get + * is this. + */ + + xf86ProbeOutputModes (pScrn, 0, 0); + xf86SetScrnInfoModes (pScrn); + xf86DiDGAReInit (pScrn->pScreen); + xf86SwitchMode(pScrn->pScreen, pScrn->currentMode); - if (adjust != offset) { - xf86DrvMsg(pScrn->scrnIndex, X_WARNING, - "Fixing display offsets.\n"); + /* Clear the BIOS's hotkey press flags */ + gr18 &= ~(HOTKEY_TOGGLE | HOTKEY_SWITCH); + pI830->writeControl(pI830, GRX, 0x18, gr18); + } - I830AdjustFrame(pScrn->pScreen->myNum, pScrn->frameX0, pScrn->frameY0, 0); - } - } + return 1000; +} - if (fixup) { - ScreenPtr pCursorScreen; - int x = 0, y = 0; +void +i830WaitSync(ScrnInfoPtr pScrn) +{ + I830Ptr pI830 = I830PTR(pScrn); - pCursorScreen = miPointerCurrentScreen(); - if (pScrn->pScreen == pCursorScreen) - miPointerPosition(&x, &y); +#ifdef I830_USE_XAA + if (!pI830->noAccel && !pI830->useEXA && pI830->AccelInfoRec + && pI830->AccelInfoRec->NeedToSync) { + (*pI830->AccelInfoRec->Sync)(pScrn); + pI830->AccelInfoRec->NeedToSync = FALSE; + } +#endif +#ifdef I830_USE_EXA + if (!pI830->noAccel && pI830->useEXA && pI830->EXADriverPtr) { + ScreenPtr pScreen = screenInfo.screens[pScrn->scrnIndex]; + exaWaitSync(pScreen); + } +#endif +} - /* Now, when we're single head, make sure we switch pipes */ - if (!(xf86IsEntityShared(pScrn->entityList[0]) || pI830->Clone) || cloned) { - if (temp & 0xFF00) - pI830->pipe = 1; - else - pI830->pipe = 0; - xf86DrvMsg(pScrn->scrnIndex, X_INFO, - "Primary pipe is now %s.\n", pI830->pipe ? "B" : "A"); - } - - pI830->currentMode = NULL; - I830BIOSSwitchMode(pScrn->pScreen->myNum, pScrn->currentMode, 0); - I830AdjustFrame(pScrn->pScreen->myNum, pScrn->frameX0, pScrn->frameY0, 0); - - if (xf86IsEntityShared(pScrn->entityList[0])) { - ScrnInfoPtr pScrn2; - I830Ptr pI8302; - - if (I830IsPrimary(pScrn)) { - pScrn2 = pI830->entityPrivate->pScrn_2; - pI8302 = I830PTR(pI830->entityPrivate->pScrn_2); - } else { - pScrn2 = pI830->entityPrivate->pScrn_1; - pI8302 = I830PTR(pI830->entityPrivate->pScrn_1); - } - - if (pScrn2->pScreen == pCursorScreen) - miPointerPosition(&x, &y); - - pI8302->currentMode = NULL; - I830BIOSSwitchMode(pScrn2->pScreen->myNum, pScrn2->currentMode, 0); - I830AdjustFrame(pScrn2->pScreen->myNum, pScrn2->frameX0, pScrn2->frameY0, 0); - - (*pScrn2->EnableDisableFBAccess) (pScrn2->pScreen->myNum, FALSE); - (*pScrn2->EnableDisableFBAccess) (pScrn2->pScreen->myNum, TRUE); - - if (pScrn2->pScreen == pCursorScreen) { - int sigstate = xf86BlockSIGIO (); - miPointerWarpCursor(pScrn2->pScreen,x,y); - - /* xf86Info.currentScreen = pScrn->pScreen; */ - xf86UnblockSIGIO (sigstate); - if (pI8302->CursorInfoRec && !pI8302->SWCursor && pI8302->cursorOn) { - pI8302->CursorInfoRec->HideCursor(pScrn); - xf86SetCursor(pScrn2->pScreen, pI830->pCurs, x, y); - pI8302->CursorInfoRec->ShowCursor(pScrn); - pI8302->cursorOn = TRUE; - } - } - } +void +i830MarkSync(ScrnInfoPtr pScrn) +{ + I830Ptr pI830 = I830PTR(pScrn); - (*pScrn->EnableDisableFBAccess) (pScrn->pScreen->myNum, FALSE); - (*pScrn->EnableDisableFBAccess) (pScrn->pScreen->myNum, TRUE); - - if (pScrn->pScreen == pCursorScreen) { - int sigstate = xf86BlockSIGIO (); - miPointerWarpCursor(pScrn->pScreen,x,y); - - /* xf86Info.currentScreen = pScrn->pScreen; */ - xf86UnblockSIGIO (sigstate); - if (pI830->CursorInfoRec && !pI830->SWCursor && pI830->cursorOn) { - pI830->CursorInfoRec->HideCursor(pScrn); - xf86SetCursor(pScrn->pScreen, pI830->pCurs, x, y); - pI830->CursorInfoRec->ShowCursor(pScrn); - pI830->cursorOn = TRUE; - } - } - } +#ifdef I830_USE_XAA + if (!pI830->useEXA && pI830->AccelInfoRec) + pI830->AccelInfoRec->NeedToSync = TRUE; +#endif +#ifdef I830_USE_EXA + if (pI830->useEXA && pI830->EXADriverPtr) { + ScreenPtr pScreen = screenInfo.screens[pScrn->scrnIndex]; + exaMarkSync(pScreen); } - - - return 1000; +#endif } void I830InitpScrn(ScrnInfoPtr pScrn) { - pScrn->PreInit = I830BIOSPreInit; - pScrn->ScreenInit = I830BIOSScreenInit; - pScrn->SwitchMode = I830BIOSSwitchMode; - pScrn->AdjustFrame = I830AdjustFrame; - pScrn->EnterVT = I830BIOSEnterVT; - pScrn->LeaveVT = I830BIOSLeaveVT; - pScrn->FreeScreen = I830BIOSFreeScreen; + pScrn->PreInit = I830PreInit; + pScrn->ScreenInit = I830ScreenInit; + pScrn->SwitchMode = I830SwitchMode; + pScrn->AdjustFrame = i830AdjustFrame; + pScrn->EnterVT = I830EnterVT; + pScrn->LeaveVT = I830LeaveVT; + pScrn->FreeScreen = I830FreeScreen; pScrn->ValidMode = I830ValidMode; pScrn->PMEvent = I830PMEvent; } |