diff options
author | Francisco Jerez <currojerez@gmail.com> | 2008-10-11 14:24:48 +0200 |
---|---|---|
committer | Paulo Cesar Pereira de Andrade <pcpa@mandriva.com.br> | 2008-10-14 13:25:27 -0300 |
commit | 6e0837305533f940adb7a09f9b013077c0888f2d (patch) | |
tree | b918a274669daea2cebd0a8d69f151b73aded587 /src/smi_driver.c | |
parent | 605199b1fa80d5a65e11a38270f6d0974466d1dc (diff) |
RandR1.2 initial implementation (WIP)
Moved most of the Lynx-specific code out of the main
functions at smi_driver.c to some new files: smilynx_hw.c
(With CRTC-independent code like global hardware initialization and
mode saving/restoring), smilynx_crtc.c (With the CRTC-local
procedures) and smilynx_output.c (Output power management, DDC and
monitor detection, currently).
Done something similar with the SMI501 code: split
SMI501_ModeInit in three separate functions: SMI501_HWInit that does
the global initialization, and the CRTC mode_set callbacks
SMI501_ModeSet_crt and SMI501_ModeSet_lcd at smi501_crtc.c.
The SMI501_ModeSet code is divided into SMI501_WriteMode_common,
SMI501_WriteMode_lcd and SMI501_WriteMode_crt, each one updates a
different register set in the hardware.
Inside smi_crtc.c, there is mainly hardware independent
code... Initial CRT controller allocation, shadows, rotation and
framebuffer resizing code.
The shadow code currently relies on EXA... I'm not sure what are the
problems of the EXA implementation in MSOC. Does it work?
I think it would be a good thing to get rid of XAA soon: The next
thing I'll be working on will be EXA Composite... I hope it's possible
to get EXA acceleration working at least as fast as the current
XAA. (Although Teddy Wang confirmed me that the SMI720 DMA engine is
broken...)
So, the patch adds some features like new Lynx dualhead modesetting
code, but it probably breaks some other things:
* Video Overlay: I suppose it does work with EXA activated. It seems
it is also possible to have simultaneous overlays in both CRTCs with the
Lynx hardware (I have some code for this, but still work in progress).
* Hardware Cursor (It needs more integration in the CRTC interfaces).
* The old Shadow FB / rotation code, which we should probably drop.
These are in my TODO list... Along with some more cleaning and other
minor issues in the modesetting code.
About the SMI501 RandR1.2 implementation... I suppose it's specially
lacking per-output DPMS (The DPMS field in the System Control register
only affects the CRT, doesn't it?).
Diffstat (limited to 'src/smi_driver.c')
-rw-r--r-- | src/smi_driver.c | 1976 |
1 files changed, 181 insertions, 1795 deletions
diff --git a/src/smi_driver.c b/src/smi_driver.c index 64db50f..61077c7 100644 --- a/src/smi_driver.c +++ b/src/smi_driver.c @@ -40,6 +40,8 @@ authorization from The XFree86 Project or Silicon Motion. #include "smi.h" #include "smi_501.h" +#include "smilynx.h" +#include "smi_crtc.h" #include "globals.h" #define DPMS_SERVER @@ -52,6 +54,7 @@ static Bool SMI_MapMmio(ScrnInfoPtr pScrn); static Bool SMI_DetectMem(ScrnInfoPtr pScrn); static void SMI_EnableMmio(ScrnInfoPtr pScrn); static void SMI_DisableMmio(ScrnInfoPtr pScrn); +static Bool SMI_HWInit(ScrnInfoPtr pScrn); /* * Forward definitions for the functions that make up the driver. @@ -63,28 +66,16 @@ static Bool SMI_Probe(DriverPtr drv, int flags); static Bool SMI_PreInit(ScrnInfoPtr pScrn, int flags); static Bool SMI_EnterVT(int scrnIndex, int flags); static void SMI_LeaveVT(int scrnIndex, int flags); -static void SMI_Save (ScrnInfoPtr pScrn); -static void SMI_WriteMode (ScrnInfoPtr pScrn, vgaRegPtr, SMIRegPtr); static Bool SMI_ScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv); -static int SMI_InternalScreenInit(int scrnIndex, ScreenPtr pScreen); -static void SMI_PrintRegs(ScrnInfoPtr); -static ModeStatus SMI_ValidMode(int scrnIndex, DisplayModePtr mode, - Bool verbose, int flags); static void SMI_DisableVideo(ScrnInfoPtr pScrn); static void SMI_EnableVideo(ScrnInfoPtr pScrn); -static Bool SMI_ModeInit(ScrnInfoPtr pScrn, DisplayModePtr mode); static Bool SMI_CloseScreen(int scrnIndex, ScreenPtr pScreen); static Bool SMI_SaveScreen(ScreenPtr pScreen, int mode); -static void SMI_DisplayPowerManagementSet(ScrnInfoPtr pScrn, - int PowerManagementMode, int flags); -static Bool SMI_ddc1(int scrnIndex); -static unsigned int SMI_ddc1Read(ScrnInfoPtr pScrn); static void SMI_FreeScreen(int ScrnIndex, int flags); static void SMI_ProbeDDC(ScrnInfoPtr pScrn, int index); static void SMI_DetectPanelSize(ScrnInfoPtr pScrn); static void SMI_DetectMCLK(ScrnInfoPtr pScrn); -static Bool SMI_DriverFunc(ScrnInfoPtr pScrn , xorgDriverFuncOp op,pointer ptr); /* * xf86VDrvMsgVerb prints up to 14 characters prefix, where prefix has the @@ -166,8 +157,6 @@ typedef enum OPTION_SHOWCACHE, OPTION_SWCURSOR, OPTION_HWCURSOR, - OPTION_SHADOW_FB, - OPTION_ROTATE, OPTION_VIDEOKEY, OPTION_BYTESWAP, /* CZ 26.10.2001: interlaced video */ @@ -177,7 +166,6 @@ typedef enum OPTION_ZOOMONLCD, OPTION_DUALHEAD, OPTION_ACCELMETHOD, - OPTION_RANDRROTATION, OPTION_PANEL_SIZE, OPTION_USE_FBDEV, NUMBER_OF_OPTIONS @@ -195,8 +183,6 @@ static const OptionInfoRec SMIOptions[] = { OPTION_SHOWCACHE, "show_cache", OPTV_BOOLEAN, {0}, FALSE }, { OPTION_HWCURSOR, "HWCursor", OPTV_BOOLEAN, {0}, TRUE }, { OPTION_SWCURSOR, "SWCursor", OPTV_BOOLEAN, {0}, FALSE }, - { OPTION_SHADOW_FB, "ShadowFB", OPTV_BOOLEAN, {0}, FALSE }, - { OPTION_ROTATE, "Rotate", OPTV_ANYSTR, {0}, FALSE }, { OPTION_VIDEOKEY, "VideoKey", OPTV_INTEGER, {0}, FALSE }, { OPTION_BYTESWAP, "ByteSwap", OPTV_BOOLEAN, {0}, FALSE }, /* CZ 26.10.2001: interlaced video */ @@ -206,7 +192,6 @@ static const OptionInfoRec SMIOptions[] = { OPTION_ZOOMONLCD, "ZoomOnLCD", OPTV_BOOLEAN, {0}, FALSE }, { OPTION_DUALHEAD, "Dualhead", OPTV_BOOLEAN, {0}, FALSE }, { OPTION_ACCELMETHOD, "AccelMethod", OPTV_STRING, {0}, FALSE }, - { OPTION_RANDRROTATION, "RandRRotation", OPTV_BOOLEAN, {0}, FALSE }, { OPTION_PANEL_SIZE, "PanelSize", OPTV_ANYSTR, {0}, FALSE }, { OPTION_USE_FBDEV, "UseFBDev", OPTV_BOOLEAN, {0}, FALSE }, { -1, NULL, OPTV_NONE, {0}, FALSE } @@ -500,18 +485,11 @@ SMI_Probe(DriverPtr drv, int flags) pScrn->AdjustFrame = SMI_AdjustFrame; if ((pEnt = xf86GetEntityInfo(usedChips[i]))) { - if (pEnt->chipset == PCI_CHIP_SMI501) { - pScrn->EnterVT = SMI501_EnterVT; - pScrn->LeaveVT = SMI501_LeaveVT; - } - else { pScrn->EnterVT = SMI_EnterVT; pScrn->LeaveVT = SMI_LeaveVT; - } xfree(pEnt); } pScrn->FreeScreen = SMI_FreeScreen; - pScrn->ValidMode = SMI_ValidMode; foundScreen = TRUE; } } @@ -527,12 +505,8 @@ SMI_PreInit(ScrnInfoPtr pScrn, int flags) EntityInfoPtr pEnt; SMIPtr pSmi; MessageType from; - int i; - ClockRangePtr clockRanges; - char *s; vgaHWPtr hwp; int vgaCRIndex, vgaIOBase; - vbeInfoPtr pVbe = NULL; ENTER(); @@ -555,13 +529,11 @@ SMI_PreInit(ScrnInfoPtr pScrn, int flags) if (IS_MSOC(pSmi)) { pSmi->Save = SMI501_Save; - pSmi->ModeInit = SMI501_ModeInit; pSmi->save = xnfcalloc(sizeof(MSOCRegRec), 1); pSmi->mode = xnfcalloc(sizeof(MSOCRegRec), 1); } else { - pSmi->Save = SMI_Save; - pSmi->ModeInit = SMI_ModeInit; + pSmi->Save = SMILynx_Save; pSmi->save = xnfcalloc(sizeof(SMIRegRec), 1); pSmi->mode = xnfcalloc(sizeof(SMIRegRec), 1); } @@ -611,6 +583,15 @@ SMI_PreInit(ScrnInfoPtr pScrn, int flags) RETURN(FALSE); } + + if(pScrn->bitsPerPixel != 8 && pScrn->bitsPerPixel != 16 && + pScrn->bitsPerPixel != 24 && pScrn->bitsPerPixel != 32){ + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + "Given bpp (%d) is not supported by this driver\n", + pScrn->bitsPerPixel); + RETURN(FALSE); + } + xf86PrintDepthBpp(pScrn); /* @@ -648,8 +629,12 @@ SMI_PreInit(ScrnInfoPtr pScrn, int flags) xf86CollectOptions(pScrn, NULL); /* Set the bits per RGB for 8bpp mode */ - if (pScrn->depth == 8) + if (pScrn->depth == 8){ pScrn->rgbBits = IS_MSOC(pSmi) ? 8 : 6; + }else if(pScrn->depth == 16){ + /* Use 8 bit LUT for gamma correction*/ + pScrn->rgbBits = 8; + } /* Process the options */ if (!(pSmi->Options = xalloc(sizeof(SMIOptions)))) @@ -717,11 +702,6 @@ SMI_PreInit(ScrnInfoPtr pScrn, int flags) pSmi->ShowCache = FALSE; } - if(!pSmi->randrRotation && xf86GetOptValBool(pSmi->Options, OPTION_RANDRROTATION, &pSmi->randrRotation)){ - xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "RandRRotation %s.\n", - pSmi->randrRotation ? "enabled" : "disabled"); - } - if (IS_MSOC(pSmi)) { from = X_DEFAULT; if (xf86GetOptValBool(pSmi->Options, OPTION_USE_FBDEV, &pSmi->UseFBDev)) @@ -738,52 +718,9 @@ SMI_PreInit(ScrnInfoPtr pScrn, int flags) else if (!xf86GetOptValBool(pSmi->Options, OPTION_HWCURSOR, &pSmi->HwCursor)) from = X_DEFAULT; - if (pSmi->HwCursor && pSmi->randrRotation) { - xf86DrvMsg(pScrn->scrnIndex, X_WARNING, - "RandRRotation enabled: Disabling hardware cursor.\n"); - pSmi->HwCursor = FALSE; - } xf86DrvMsg(pScrn->scrnIndex, from, "Using %sware Cursor\n", pSmi->HwCursor ? "Hard" : "Soft"); - if (xf86GetOptValBool(pSmi->Options, OPTION_SHADOW_FB, &pSmi->shadowFB)) { - xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "ShadowFB %s.\n", - pSmi->shadowFB ? "enabled" : "disabled"); - } - - if(!pSmi->shadowFB && pSmi->randrRotation){ - xf86DrvMsg(pScrn->scrnIndex, X_INFO, "RandRRotation enabled: Enabling ShadowFB.\n"); - pSmi->shadowFB = TRUE; - } - -#if 1 /* PDR#932 */ - if ((pScrn->depth == 8) || (pScrn->depth == 16)) { -#endif /* PDR#932 */ - if ((s = xf86GetOptValString(pSmi->Options, OPTION_ROTATE))) { - if (!xf86NameCmp(s, "CW")) { - pSmi->shadowFB = TRUE; - pSmi->rotate = SMI_ROTATE_CCW; - xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Rotating screen " - "clockwise\n"); - } else if (!xf86NameCmp(s, "CCW")) { - pSmi->shadowFB = TRUE; - pSmi->rotate = SMI_ROTATE_CW; - xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Rotating screen counter " - "clockwise\n"); - } else { - xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "\"%s\" is not a valid " - "value for Option \"Rotate\"\n", s); - xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Valid options are \"CW\" or " - "\"CCW\"\n"); - } - } - } - - if (pSmi->rotate) { - /* Disable the RandR extension, it messes up the internal rotation stuff */ - xf86DisableRandR(); - } - if (xf86GetOptValInteger(pSmi->Options, OPTION_VIDEOKEY, &pSmi->videoKey)) { xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Option: Video key set to " "0x%08X\n", pSmi->videoKey); @@ -838,7 +775,7 @@ SMI_PreInit(ScrnInfoPtr pScrn, int flags) if (pSmi->pInt10 && xf86LoadSubModule(pScrn, "vbe")) { xf86LoaderReqSymLists(vbeSymbols, NULL); - pVbe = VBEInit(pSmi->pInt10, pEnt->index); + pSmi->pVbe = VBEInit(pSmi->pInt10, pEnt->index); } } @@ -902,25 +839,7 @@ SMI_PreInit(ScrnInfoPtr pScrn, int flags) pSmi->Dualhead = FALSE; - if (IS_MSOC(pSmi)) { - pSmi->pEnt = xf86GetEntityInfo(pScrn->entityList[pScrn->numEntities - 1]); - - /* FIXME this assumes the first head is always lcd and second - * always crt */ - pSmi->IsSecondary = FALSE; - pSmi->lcd = TRUE; - - if (xf86IsEntityShared(pSmi->pEnt->index)) { - pSmi->Dualhead = TRUE; - if (xf86IsPrimInitDone(pSmi->pEnt->index)) { - pSmi->IsSecondary = TRUE; - pSmi->lcd = FALSE; - } - else - xf86SetPrimInitDone(pSmi->pEnt->index); - } - } - else { + if (!IS_MSOC(pSmi)){ if (SMI_LYNXM_SERIES(pSmi->Chipset) && xf86ReturnOptValBool(pSmi->Options, OPTION_DUALHEAD, FALSE)) pSmi->Dualhead = TRUE; @@ -952,50 +871,16 @@ SMI_PreInit(ScrnInfoPtr pScrn, int flags) SMI_MapMem(pScrn); SMI_DisableVideo(pScrn); - /* FIXME shouldn't have been already set? */ - if (IS_MSOC(pSmi)) - pSmi->lcd = pSmi->IsSecondary == FALSE; - /* detect the panel size */ SMI_DetectPanelSize(pScrn); - if (pVbe) { + if(!IS_MSOC(pSmi)){ if (xf86LoadSubModule(pScrn, "i2c")) { xf86LoaderReqSymLists(i2cSymbols, NULL); SMI_I2CInit(pScrn); } - if (xf86LoadSubModule(pScrn, "ddc")) { - xf86MonPtr pMon = NULL; - xf86LoaderReqSymLists(ddcSymbols, NULL); - pMon = vbeDoEDID(pVbe, NULL); - if (pMon != NULL) { - if ((pMon->rawData[0] == 0x00) && - (pMon->rawData[1] == 0xFF) && - (pMon->rawData[2] == 0xFF) && - (pMon->rawData[3] == 0xFF) && - (pMon->rawData[4] == 0xFF) && - (pMon->rawData[5] == 0xFF) && - (pMon->rawData[6] == 0xFF) && - (pMon->rawData[7] == 0x00)) { - pMon = xf86PrintEDID(pMon); - if (pMon != NULL) { - xf86SetDDCproperties(pScrn, pMon); - } - } - } else if (!SMI_ddc1(pScrn->scrnIndex)) { - if (pSmi->I2C) { - xf86SetDDCproperties(pScrn, - xf86PrintEDID(xf86DoEDID_DDC2(pScrn->scrnIndex, - pSmi->I2C))); - } - } - } - vbeFree(pVbe); - if (pSmi->pInt10) { - xf86FreeInt10(pSmi->pInt10); - pSmi->pInt10 = NULL; } } @@ -1016,85 +901,47 @@ SMI_PreInit(ScrnInfoPtr pScrn, int flags) SMI_DetectMCLK(pScrn); - SMI_EnableVideo(pScrn); - SMI_UnmapMem(pScrn); - pSmi->IsSwitching = FALSE; - if (pSmi->Dualhead) { - pScrn->display->virtualX = 2 * pSmi->lcdWidth; - pScrn->display->virtualY = pSmi->lcdHeight; - } - - pScrn->virtualX = pScrn->display->virtualX; - /* * Setup the ClockRanges, which describe what clock ranges are available, * and what sort of modes they can be used for. */ - clockRanges = xnfcalloc(sizeof(ClockRange),1); - clockRanges->next = NULL; - clockRanges->minClock = 20000; + pSmi->clockRange.next = NULL; + pSmi->clockRange.minClock = 20000; if (pSmi->Chipset == SMI_LYNX3DM || pSmi->Chipset == SMI_COUGAR3DR || IS_MSOC(pSmi)) - clockRanges->maxClock = 200000; + pSmi->clockRange.maxClock = 200000; else - clockRanges->maxClock = 135000; - - clockRanges->clockIndex = -1; - clockRanges->interlaceAllowed = FALSE; - clockRanges->doubleScanAllowed = FALSE; - - /* FIXME Maybe this should be done only for the 501/502? - * as it doesn't have any method of detecting monitors, other then - * reading what is in the hardware, and hoping the kernel received - * the proper parameters, and correctly programmed the hardware. */ - if (pSmi->lcdWidth && pSmi->lcdHeight) - pScrn->monitor->Modes = - xf86ModesAdd(pScrn->monitor->Modes, - xf86CVTMode(pSmi->lcdWidth, pSmi->lcdHeight, 60.0f, - FALSE, FALSE)); - - i = xf86ValidateModes( - pScrn, /* Screen pointer */ - pScrn->monitor->Modes, /* Available monitor modes */ - pScrn->display->modes, /* req mode names for screen */ - clockRanges, /* list of clock ranges allowed */ - NULL, /* use min/max below */ - 128, /* min line pitch (width) */ - 4096, /* maximum line pitch (width) */ - 128, /* bits of granularity for line pitch */ - /* (width) above */ - 128, /* min virtual height */ - 4096, /* max virtual height */ - pScrn->display->virtualX, /* force virtual x */ - pScrn->display->virtualY, /* force virtual Y */ - pSmi->videoRAMBytes, /* size of aperture used to access */ - /* video memory */ - LOOKUP_BEST_REFRESH); /* how to pick modes */ - - if (i == -1) { - SMI_FreeRec(pScrn); + pSmi->clockRange.maxClock = 135000; + + pSmi->clockRange.clockIndex = -1; + pSmi->clockRange.interlaceAllowed = FALSE; + pSmi->clockRange.doubleScanAllowed = FALSE; + + if(!SMI_CrtcPreInit(pScrn)) RETURN(FALSE); - } - /* Prune the modes marked as invalid */ - xf86PruneDriverModes(pScrn); + if(!SMI_OutputPreInit(pScrn)) + RETURN(FALSE); - if (i == 0 || pScrn->modes == NULL) { + if (!xf86InitialConfiguration (pScrn, TRUE)){ xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "No valid modes found\n"); - SMI_FreeRec(pScrn); RETURN(FALSE); } - xf86SetCrtcForModes(pScrn, 0); - /* Set the current mode to the first in the list */ - pScrn->currentMode = pScrn->modes; - /* Print the list of modes being used */ - xf86PrintModes(pScrn); + SMI_EnableVideo(pScrn); + SMI_UnmapMem(pScrn); + + if(pSmi->useBIOS){ + vbeFree(pSmi->pVbe); + pSmi->pVbe = NULL; + xf86FreeInt10(pSmi->pInt10); + pSmi->pInt10 = NULL; + } /* Set display resolution */ xf86SetDpi(pScrn, 0, 0); @@ -1139,7 +986,7 @@ SMI_PreInit(ScrnInfoPtr pScrn, int flags) memset(&req, 0, sizeof(XF86ModReqInfo)); req.majorversion = 2; - req.minorversion = 0; + req.minorversion = 1; if (!LoadSubModule(pScrn->module, "exa", NULL, NULL, NULL, &req, &errmaj, &errmin)) { @@ -1181,7 +1028,6 @@ SMI_EnterVT(int scrnIndex, int flags) { ScrnInfoPtr pScrn = xf86Screens[scrnIndex]; SMIPtr pSmi = SMIPTR(pScrn); - Bool ret; ENTER(); @@ -1191,56 +1037,23 @@ SMI_EnterVT(int scrnIndex, int flags) pSmi->Save(pScrn); /* FBBase may have changed after remapping the memory */ - pScrn->pixmapPrivate.ptr=pSmi->FBBase; + pScrn->pixmapPrivate.ptr=pSmi->FBBase + pSmi->FBOffset; if(pSmi->useEXA) pSmi->EXADriverPtr->memoryBase=pSmi->FBBase; - /* #670 */ - if (pSmi->shadowFB) { - pSmi->FBOffset = pSmi->savedFBOffset; - pSmi->FBReserved = pSmi->savedFBReserved; - } - - ret = pSmi->ModeInit(pScrn, pScrn->currentMode); - - /* #670 */ - if (ret && pSmi->shadowFB) { - BoxRec box; - - /* #920 */ - if (pSmi->paletteBuffer) { - int i; - - VGAOUT8(pSmi, VGA_DAC_WRITE_ADDR, 0); - for (i = 0; i < 256 * 3; i++) { - VGAOUT8(pSmi, VGA_DAC_DATA, pSmi->paletteBuffer[i]); - } - xfree(pSmi->paletteBuffer); - pSmi->paletteBuffer = NULL; - } - - if (pSmi->pSaveBuffer) { - memcpy(pSmi->FBBase, pSmi->pSaveBuffer, pSmi->saveBufferSize); - xfree(pSmi->pSaveBuffer); - pSmi->pSaveBuffer = NULL; - } + /* Do the CRTC independent initialization */ + if(!SMI_HWInit(pScrn)) + RETURN(FALSE); - box.x1 = 0; - box.y1 = 0; - box.x2 = pSmi->width; - box.y2 = pSmi->height; - if (pSmi->Chipset == SMI_COUGAR3DR) { - SMI_RefreshArea730(pScrn, 1, &box); - } else { - SMI_RefreshArea(pScrn, 1, &box); - } - } + /* Initialize the chosen modes */ + if (!xf86SetDesiredModes(pScrn)) + RETURN(FALSE); /* Reset the grapics engine */ if (!pSmi->NoAccel) SMI_EngineReset(pScrn); - RETURN(ret); + RETURN(TRUE); } /* @@ -1254,427 +1067,22 @@ SMI_LeaveVT(int scrnIndex, int flags) { ScrnInfoPtr pScrn = xf86Screens[scrnIndex]; SMIPtr pSmi = SMIPTR(pScrn); - SMIRegPtr SMISavePtr = pSmi->save; - vgaHWPtr hwp = VGAHWPTR(pScrn); - vgaRegPtr vgaSavePtr = &hwp->SavedReg; ENTER(); - /* #670 */ - if (pSmi->shadowFB) { - pSmi->pSaveBuffer = xnfalloc(pSmi->saveBufferSize); - if (pSmi->pSaveBuffer) { - memcpy(pSmi->pSaveBuffer, pSmi->FBBase, pSmi->saveBufferSize); - } - - pSmi->savedFBOffset = pSmi->FBOffset; - pSmi->savedFBReserved = pSmi->FBReserved; - - /* #920 */ - if (pSmi->Bpp == 1) { - pSmi->paletteBuffer = xnfalloc(256 * 3); - if (pSmi->paletteBuffer) { - int i; - - VGAOUT8(pSmi, VGA_DAC_READ_ADDR, 0); - for (i = 0; i < 256 * 3; i++) { - pSmi->paletteBuffer[i] = VGAIN8(pSmi, VGA_DAC_DATA); - } - } - } - } + /* Ensure that the rotation BlockHandler is unwrapped, and the shadow + pixmaps are deallocated, as the video memory is going to be + unmapped. */ + xf86RotateCloseScreen(pScrn->pScreen); memset(pSmi->FBBase, 0, 256 * 1024); /* #689 */ - SMI_WriteMode(pScrn, vgaSavePtr, SMISavePtr); - SMI_UnmapMem(pScrn); - - LEAVE(); -} - -/* - * This function performs the inverse of the restore function: It saves all the - * standard and extended registers that we are going to modify to set up a video - * mode. - */ - -static void -SMI_Save(ScrnInfoPtr pScrn) -{ - SMIPtr pSmi = SMIPTR(pScrn); - int i; - CARD32 offset; - SMIRegPtr save = pSmi->save; - vgaHWPtr hwp = VGAHWPTR(pScrn); - vgaRegPtr vgaSavePtr = &hwp->SavedReg; - int vgaIOBase = hwp->IOBase; - int vgaCRIndex = vgaIOBase + VGA_CRTC_INDEX_OFFSET; - int vgaCRData = vgaIOBase + VGA_CRTC_DATA_OFFSET; - - ENTER(); - - /* Save the standard VGA registers */ - vgaHWSave(pScrn, vgaSavePtr, VGA_SR_ALL); - save->smiDACMask = VGAIN8(pSmi, VGA_DAC_MASK); - VGAOUT8(pSmi, VGA_DAC_READ_ADDR, 0); - for (i = 0; i < 256; i++) { - save->smiDacRegs[i][0] = VGAIN8(pSmi, VGA_DAC_DATA); - save->smiDacRegs[i][1] = VGAIN8(pSmi, VGA_DAC_DATA); - save->smiDacRegs[i][2] = VGAIN8(pSmi, VGA_DAC_DATA); - } - for (i = 0, offset = 2; i < 8192; i++, offset += 8) - save->smiFont[i] = *(pSmi->FBBase + offset); - - /* Now we save all the extended registers we need. */ - save->SR17 = VGAIN8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x17); - save->SR18 = VGAIN8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x18); - save->SR21 = VGAIN8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x21); - save->SR31 = VGAIN8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x31); - save->SR32 = VGAIN8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x32); - save->SR6A = VGAIN8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x6A); - save->SR6B = VGAIN8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x6B); - save->SR81 = VGAIN8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x81); - save->SRA0 = VGAIN8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0xA0); - - /* vclk1 */ - save->SR6C = VGAIN8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x6C); - save->SR6D = VGAIN8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x6D); - /* vclk1 control */ - save->SR68 = VGAIN8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x68); - - if (pSmi->Dualhead) { - /* dualhead stuff */ - save->SR22 = VGAIN8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x22); - save->SR40 = VGAIN8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x40); - save->SR41 = VGAIN8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x41); - save->SR42 = VGAIN8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x42); - save->SR43 = VGAIN8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x43); - save->SR44 = VGAIN8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x44); - save->SR45 = VGAIN8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x45); - save->SR48 = VGAIN8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x48); - save->SR49 = VGAIN8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x49); - save->SR4A = VGAIN8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x4A); - save->SR4B = VGAIN8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x4B); - save->SR4C = VGAIN8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x4C); - /* PLL2 stuff */ - save->SR69 = VGAIN8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x69); - save->SR6E = VGAIN8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x6E); - save->SR6F = VGAIN8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x6F); - } - - if (SMI_LYNXM_SERIES(pSmi->Chipset)) { - /* Save primary registers */ - save->CR90[14] = VGAIN8_INDEX(pSmi, vgaCRIndex, vgaCRData, 0x9E); - VGAOUT8_INDEX(pSmi, vgaCRIndex, vgaCRData, 0x9E, save->CR90[14] & ~0x20); - - for (i = 0; i < 16; i++) { - save->CR90[i] = VGAIN8_INDEX(pSmi, vgaCRIndex, vgaCRData, 0x90 + i); - } - save->CR33 = VGAIN8_INDEX(pSmi, vgaCRIndex, vgaCRData, 0x33); - save->CR3A = VGAIN8_INDEX(pSmi, vgaCRIndex, vgaCRData, 0x3A); - for (i = 0; i < 14; i++) { - save->CR40[i] = VGAIN8_INDEX(pSmi, vgaCRIndex, vgaCRData, 0x40 + i); - } - - /* Save secondary registers */ - VGAOUT8_INDEX(pSmi, vgaCRIndex, vgaCRData, 0x9E, save->CR90[14] | 0x20); - save->CR33_2 = VGAIN8_INDEX(pSmi, vgaCRIndex, vgaCRData, 0x33); - for (i = 0; i < 14; i++) { - save->CR40_2[i] = VGAIN8_INDEX(pSmi, vgaCRIndex, vgaCRData, 0x40 + i); - } - save->CR9F_2 = VGAIN8_INDEX(pSmi, vgaCRIndex, vgaCRData, 0x9F); - - /* Save common registers */ - for (i = 0; i < 14; i++) { - save->CRA0[i] = VGAIN8_INDEX(pSmi, vgaCRIndex, vgaCRData, 0xA0 + i); - } - - /* PDR#1069 */ - VGAOUT8_INDEX(pSmi, vgaCRIndex, vgaCRData, 0x9E, save->CR90[14]); - } - else { - save->CR33 = VGAIN8_INDEX(pSmi, vgaCRIndex, vgaCRData, 0x33); - save->CR3A = VGAIN8_INDEX(pSmi, vgaCRIndex, vgaCRData, 0x3A); - for (i = 0; i < 14; i++) { - save->CR40[i] = VGAIN8_INDEX(pSmi, vgaCRIndex, vgaCRData, 0x40 + i); - } - } - - /* CZ 2.11.2001: for gamma correction (TODO: other chipsets?) */ - if ((pSmi->Chipset == SMI_LYNX3DM) || (pSmi->Chipset == SMI_COUGAR3DR)) { - save->CCR66 = VGAIN8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x66); - } - /* end CZ */ - - save->DPR10 = READ_DPR(pSmi, 0x10); - save->DPR1C = READ_DPR(pSmi, 0x1C); - save->DPR20 = READ_DPR(pSmi, 0x20); - save->DPR24 = READ_DPR(pSmi, 0x24); - save->DPR28 = READ_DPR(pSmi, 0x28); - save->DPR2C = READ_DPR(pSmi, 0x2C); - save->DPR30 = READ_DPR(pSmi, 0x30); - save->DPR3C = READ_DPR(pSmi, 0x3C); - save->DPR40 = READ_DPR(pSmi, 0x40); - save->DPR44 = READ_DPR(pSmi, 0x44); - - save->VPR00 = READ_VPR(pSmi, 0x00); - save->VPR0C = READ_VPR(pSmi, 0x0C); - save->VPR10 = READ_VPR(pSmi, 0x10); - - if (pSmi->Chipset == SMI_COUGAR3DR) { - save->FPR00_ = READ_FPR(pSmi, FPR00); - save->FPR0C_ = READ_FPR(pSmi, FPR0C); - save->FPR10_ = READ_FPR(pSmi, FPR10); - } - - save->CPR00 = READ_CPR(pSmi, 0x00); - - if (!pSmi->ModeStructInit) { - /* XXX Should check the return value of vgaHWCopyReg() */ - vgaHWCopyReg(&hwp->ModeReg, vgaSavePtr); - memcpy(pSmi->mode, save, sizeof(SMIRegRec)); - pSmi->ModeStructInit = TRUE; - } - - if (pSmi->useBIOS && pSmi->pInt10 != NULL) { - pSmi->pInt10->num = 0x10; - pSmi->pInt10->ax = 0x0F00; - xf86ExecX86int10(pSmi->pInt10); - save->mode = pSmi->pInt10->ax & 0x007F; - xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Current mode 0x%02X.\n", - save->mode); - } - - if (xf86GetVerbosity() > 1) { - xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, VERBLEV, - "Saved current video mode. Register dump:\n"); - SMI_PrintRegs(pScrn); - } - - LEAVE(); -} - -/* - * This function is used to restore a video mode. It writes out all of the - * standard VGA and extended registers needed to setup a video mode. - */ - -static void -SMI_WriteMode(ScrnInfoPtr pScrn, vgaRegPtr vgaSavePtr, SMIRegPtr restore) -{ - SMIPtr pSmi = SMIPTR(pScrn); - - ENTER(); if (!IS_MSOC(pSmi)) { - int i; - CARD8 tmp; - CARD32 offset; vgaHWPtr hwp = VGAHWPTR(pScrn); - int vgaIOBase = hwp->IOBase; - int vgaCRIndex = vgaIOBase + VGA_CRTC_INDEX_OFFSET; - int vgaCRData = vgaIOBase + VGA_CRTC_DATA_OFFSET; - - /* Wait for engine to become idle */ - if (pSmi->IsSwitching) - WaitIdle(); - - if (pSmi->useBIOS && pSmi->pInt10 != NULL && restore->mode != 0) { - pSmi->pInt10->num = 0x10; - pSmi->pInt10->ax = restore->mode | 0x80; - xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Setting mode 0x%02X\n", - restore->mode); - xf86ExecX86int10(pSmi->pInt10); - - /* Enable linear mode. */ - outb(pSmi->PIOBase + VGA_SEQ_INDEX, 0x18); - tmp = inb(pSmi->PIOBase + VGA_SEQ_DATA); - outb(pSmi->PIOBase + VGA_SEQ_DATA, tmp | 0x01); - - /* Enable DPR/VPR registers. */ - tmp = VGAIN8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x21); - VGAOUT8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x21, tmp & ~0x03); - } else { - VGAOUT8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x17, restore->SR17); - tmp = VGAIN8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x18) & ~0x1F; - VGAOUT8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x18, tmp | - (restore->SR18 & 0x1F)); - tmp = VGAIN8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x21); - VGAOUT8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x21, tmp & ~0x03); - tmp = VGAIN8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x31) & ~0xC0; - VGAOUT8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x31, tmp | - (restore->SR31 & 0xC0)); - tmp = VGAIN8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x32) & ~0x07; - VGAOUT8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x32, tmp | - (restore->SR32 & 0x07)); - if (restore->SR6B != 0xFF) { - VGAOUT8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x6A, restore->SR6A); - VGAOUT8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x6B, restore->SR6B); - } - VGAOUT8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x81, restore->SR81); - VGAOUT8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0xA0, restore->SRA0); - - /* Restore the standard VGA registers */ - vgaHWRestore(pScrn, vgaSavePtr, VGA_SR_ALL); - if (restore->smiDACMask) { - VGAOUT8(pSmi, VGA_DAC_MASK, restore->smiDACMask); - } else { - VGAOUT8(pSmi, VGA_DAC_MASK, 0xFF); - } - VGAOUT8(pSmi, VGA_DAC_WRITE_ADDR, 0); - for (i = 0; i < 256; i++) { - VGAOUT8(pSmi, VGA_DAC_DATA, restore->smiDacRegs[i][0]); - VGAOUT8(pSmi, VGA_DAC_DATA, restore->smiDacRegs[i][1]); - VGAOUT8(pSmi, VGA_DAC_DATA, restore->smiDacRegs[i][2]); - } - for (i = 0, offset = 2; i < 8192; i++, offset += 8) { - *(pSmi->FBBase + offset) = restore->smiFont[i]; + SMILynx_WriteMode(pScrn, &hwp->SavedReg, pSmi->save); } - if (SMI_LYNXM_SERIES(pSmi->Chipset)) { - /* Restore secondary registers */ - VGAOUT8_INDEX(pSmi, vgaCRIndex, vgaCRData, 0x9E, - restore->CR90[14] | 0x20); - - VGAOUT8_INDEX(pSmi, vgaCRIndex, vgaCRData, 0x33, restore->CR33_2); - for (i = 0; i < 14; i++) { - VGAOUT8_INDEX(pSmi, vgaCRIndex, vgaCRData, 0x40 + i, - restore->CR40_2[i]); - } - VGAOUT8_INDEX(pSmi, vgaCRIndex, vgaCRData, 0x9F, restore->CR9F_2); - - /* Restore primary registers */ - VGAOUT8_INDEX(pSmi, vgaCRIndex, vgaCRData, 0x9E, - restore->CR90[14] & ~0x20); - - VGAOUT8_INDEX(pSmi, vgaCRIndex, vgaCRData, 0x33, restore->CR33); - VGAOUT8_INDEX(pSmi, vgaCRIndex, vgaCRData, 0x3A, restore->CR3A); - for (i = 0; i < 14; i++) { - VGAOUT8_INDEX(pSmi, vgaCRIndex, vgaCRData, 0x40 + i, - restore->CR40[i]); - } - for (i = 0; i < 16; i++) { - if (i != 14) { - VGAOUT8_INDEX(pSmi, vgaCRIndex, vgaCRData, 0x90 + i, - restore->CR90[i]); - } - } - VGAOUT8_INDEX(pSmi, vgaCRIndex, vgaCRData, 0x9E, restore->CR90[14]); - - /* Restore common registers */ - for (i = 0; i < 14; i++) { - VGAOUT8_INDEX(pSmi, vgaCRIndex, vgaCRData, 0xA0 + i, - restore->CRA0[i]); - } - } - - /* Restore the standard VGA registers */ - if (xf86IsPrimaryPci(pSmi->PciInfo)) { - vgaHWRestore(pScrn, vgaSavePtr, VGA_SR_CMAP | VGA_SR_FONTS); - } - - if (restore->modeInit) - vgaHWRestore(pScrn, vgaSavePtr, VGA_SR_ALL); - - if (!SMI_LYNXM_SERIES(pSmi->Chipset)) { - VGAOUT8_INDEX(pSmi, vgaCRIndex, vgaCRData, 0x33, restore->CR33); - VGAOUT8_INDEX(pSmi, vgaCRIndex, vgaCRData, 0x3A, restore->CR3A); - for (i = 0; i < 14; i++) { - VGAOUT8_INDEX(pSmi, vgaCRIndex, vgaCRData, 0x40 + i, - restore->CR40[i]); - } - } - - /* vclk1 */ - VGAOUT8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x68, restore->SR68); - VGAOUT8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x6C, restore->SR6C); - VGAOUT8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x6D, restore->SR6D); - - if (pSmi->Dualhead) { - - /* TFT panel uses FIFO1, DSTN panel uses FIFO1 for upper panel and - * FIFO2 for lower panel. I don't have a DSTN panel, so it's untested. - * -- AGD - */ - - /* PLL2 regs */ - - VGAOUT8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x69, restore->SR69); - - VGAOUT8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x6E, restore->SR6E); - VGAOUT8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x6F, restore->SR6F); - - /* setting SR21 bit 2 disables ZV circuitry, - * if ZV is needed, SR21 = 0x20 - */ - /* enable DAC, PLL, etc. */ - VGAOUT8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x21, restore->SR21); - - /* clear DPMS state */ - VGAOUT8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x22, restore->SR22); - - /* enable virtual refresh and LCD and CRT outputs */ - VGAOUT8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x31, restore->SR31); - - /* FIFO1 Read Offset */ - VGAOUT8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x44, restore->SR44); - /* FIFO2 Read Offset */ - VGAOUT8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x4B, restore->SR4B); - /* FIFO1/2 Read Offset overflow */ - VGAOUT8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x4C, restore->SR4C); - - /* FIFO Write Offset */ - VGAOUT8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x48, restore->SR48); - VGAOUT8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x49, restore->SR49); - - /* set FIFO levels */ - VGAOUT8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x4A, restore->SR4A); - - VGAOUT8_INDEX(pSmi, vgaCRIndex, vgaCRData, 0x33, restore->CR33); - - } - } - - /* CZ 2.11.2001: for gamma correction (TODO: other chipsets?) */ - if ((pSmi->Chipset == SMI_LYNX3DM) || (pSmi->Chipset == SMI_COUGAR3DR)) { - VGAOUT8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x66, restore->CCR66); - } - /* end CZ */ - - VGAOUT8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x81, 0x00); - - /* Reset the graphics engine */ - WRITE_DPR(pSmi, 0x10, restore->DPR10); - WRITE_DPR(pSmi, 0x1C, restore->DPR1C); - WRITE_DPR(pSmi, 0x20, restore->DPR20); - WRITE_DPR(pSmi, 0x24, restore->DPR24); - WRITE_DPR(pSmi, 0x28, restore->DPR28); - WRITE_DPR(pSmi, 0x2C, restore->DPR2C); - WRITE_DPR(pSmi, 0x30, restore->DPR30); - WRITE_DPR(pSmi, 0x3C, restore->DPR3C); - WRITE_DPR(pSmi, 0x40, restore->DPR40); - WRITE_DPR(pSmi, 0x44, restore->DPR44); - - /* write video controller regs */ - WRITE_VPR(pSmi, 0x00, restore->VPR00); - WRITE_VPR(pSmi, 0x0C, restore->VPR0C); - WRITE_VPR(pSmi, 0x10, restore->VPR10); - - if(pSmi->Chipset == SMI_COUGAR3DR) { - WRITE_FPR(pSmi, FPR00, restore->FPR00_); - WRITE_FPR(pSmi, FPR0C, restore->FPR0C_); - WRITE_FPR(pSmi, FPR10, restore->FPR10_); - } - - WRITE_CPR(pSmi, 0x00, restore->CPR00); - - if (xf86GetVerbosity() > 1) { - xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, VERBLEV, - "Done restoring mode. Register dump:\n"); - SMI_PrintRegs(pScrn); - } - - vgaHWProtect(pScrn, FALSE); - } + SMI_UnmapMem(pScrn); LEAVE(); } @@ -2054,14 +1462,7 @@ SMI_MapMem(ScrnInfoPtr pScrn) pScrn->memPhysBase = PCI_REGION_BASE(pSmi->PciInfo, 0, REGION_MEM); if (IS_MSOC(pSmi)) { - if (pSmi->IsSecondary) { - pSmi->FBOffset = 0; - pScrn->fbOffset = pSmi->fbMapOffset = pScrn->videoRam * 1024; - } - else { - pSmi->FBOffset = pScrn->videoRam * 1024; - pScrn->fbOffset = pSmi->fbMapOffset = 0; - } + pSmi->fbMapOffset = 0; } else { SMI_EnableMmio(pScrn); @@ -2071,8 +1472,6 @@ SMI_MapMem(ScrnInfoPtr pScrn) else pSmi->fbMapOffset = 0x0; - pSmi->FBOffset = 0; - pScrn->fbOffset = pSmi->FBOffset + pSmi->fbMapOffset; } #ifndef XSERVER_LIBPCIACCESS @@ -2105,7 +1504,7 @@ SMI_MapMem(ScrnInfoPtr pScrn) xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, VERBLEV, "Physical frame buffer at 0x%08lX offset: 0x%08lX\n", - pScrn->memPhysBase, pScrn->fbOffset); + pScrn->memPhysBase, pSmi->fbMapOffset); xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, VERBLEV, "Logical frame buffer at %p - %p\n", pSmi->FBBase, pSmi->FBBase + pSmi->videoRAMBytes - 1); @@ -2211,6 +1610,9 @@ SMI_ScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv) if (!pSmi->pInt10 && pSmi->useBIOS) { pSmi->pInt10 = xf86InitInt10(pEnt->index); } + if (!pSmi->pVbe && pSmi->pInt10 && xf86LoaderCheckSymbol("VBEInit")) { + pSmi->pVbe = VBEInit(pSmi->pInt10, pEnt->index); + } /* Save the chip/graphics state */ pSmi->Save(pScrn); @@ -2218,14 +1620,16 @@ SMI_ScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv) /* Zero the frame buffer, #258 */ memset(pSmi->FBBase, 0, pSmi->videoRAMBytes); - /* Callback for RandR rotation */ - pScrn->DriverFunc = SMI_DriverFunc; - if(pSmi->randrRotation) - pSmi->rotate=0; + /* Fill in some needed pScrn fields */ + pScrn->vtSema = TRUE; + pScrn->pScreen = pScreen; + + pSmi->Bpp = pScrn->bitsPerPixel >> 3; + pScrn->displayWidth = ((pScrn->virtualX * pSmi->Bpp + 15) & ~15) / pSmi->Bpp; - /* Initialize the first mode */ - if (!pSmi->ModeInit(pScrn, pScrn->currentMode)) - RETURN(FALSE); + pSmi->fbArea = NULL; + pSmi->FBOffset = 0; + pScrn->fbOffset = pSmi->FBOffset + pSmi->fbMapOffset; /* * The next step is to setup the screen's visuals, and initialise the @@ -2250,7 +1654,14 @@ SMI_ScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv) if (!miSetPixmapDepths ()) RETURN(FALSE); - if (!SMI_InternalScreenInit(scrnIndex, pScreen)) + /* + * Call the framebuffer layer's ScreenInit function + */ + + DEBUG("\tInitializing FB @ 0x%08X for %dx%d (%d)\n", + pSmi->FBBase, pScrn->virtualX, pScrn->virtualY, pScrn->displayWidth); + if(!fbScreenInit(pScreen, pSmi->FBBase, pScrn->virtualX, pScrn->virtualY, pScrn->xDpi, + pScrn->yDpi, pScrn->displayWidth, pScrn->bitsPerPixel)) RETURN(FALSE); xf86SetBlackWhitePixels(pScreen); @@ -2274,55 +1685,19 @@ SMI_ScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv) /* must be after RGB ordering fixed */ fbPictureInit(pScreen, 0, 0); - /* CZ 18.06.2001: moved here from smi_accel.c to have offscreen - framebuffer in NoAccel mode */ - if (!pSmi->useEXA) { - int numLines, maxLines; - BoxRec AvailFBArea; - RegionRec AvailFBRegion; - - maxLines = pSmi->FBReserved / (pScrn->displayWidth * pSmi->Bpp); - if (pSmi->rotate) { - numLines = maxLines; - } else { - /* CZ 3.11.2001: What does the following code? see also smi_video.c aaa line 1226 */ -/*#if SMI_USE_VIDEO */ -#if 0 - numLines = ((pSmi->FBReserved - pSmi->width * pSmi->Bpp - * pSmi->height) * 25 / 100 + pSmi->width - * pSmi->Bpp - 1) / (pSmi->width * pSmi->Bpp); - numLines += pSmi->height; -#else - numLines = maxLines; -#endif - } - - AvailFBArea.x1 = 0; - if(pSmi->randrRotation) /* The rotated mode could need more memory */ - AvailFBArea.y1= max(((pScrn->virtualX * pSmi->Bpp + 15) & ~15)*pScrn->virtualY, - ((pScrn->virtualY * pSmi->Bpp + 15) & ~15)*pScrn->virtualX)/(pScrn->virtualX*pSmi->Bpp); - else - AvailFBArea.y1 = pScrn->virtualY; - AvailFBArea.x2 = pScrn->virtualX; - AvailFBArea.y2 = numLines; - xf86DrvMsg(pScrn->scrnIndex, X_INFO, - "FrameBuffer Box: %d,%d - %d,%d\n", - AvailFBArea.x1, AvailFBArea.y1, AvailFBArea.x2, - AvailFBArea.y2); - REGION_INIT(pScreen,&AvailFBRegion,&AvailFBArea,1); - xf86InitFBManagerRegion(pScreen, &AvailFBRegion); - REGION_UNINIT(pScreen,&AvailFBRegion); - } - /* end CZ */ - + /* Do the CRTC independent initialization */ + if(!SMI_HWInit(pScrn)) + RETURN(FALSE); /* Initialize acceleration layer */ - if (!pSmi->NoAccel) { - if (!pSmi->useEXA && !SMI_XAAInit(pScreen)) - RETURN(FALSE); - else if (pSmi->useEXA && !SMI_EXAInit(pScreen)) + if (!pSmi->NoAccel && pSmi->useEXA) + SMI_EXAInit(pScreen); + + /* Initialize the chosen modes */ + if (!xf86SetDesiredModes(pScrn)) RETURN(FALSE); - } + + SMI_PrintRegs(pScrn); miInitializeBackingStore(pScreen); @@ -2343,25 +1718,6 @@ SMI_ScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv) } } - if (pSmi->shadowFB) { - RefreshAreaFuncPtr refreshArea; - - if (pSmi->Chipset == SMI_COUGAR3DR) { - refreshArea = SMI_RefreshArea730; - } else { - refreshArea = SMI_RefreshArea; - } - - if (pSmi->rotate) { - if (pSmi->PointerMoved == NULL) { - pSmi->PointerMoved = pScrn->PointerMoved; - pScrn->PointerMoved = SMI_PointerMoved; - } - } - - ShadowFBInit(pScreen, refreshArea); - } - /* Initialise default colormap */ if (!miCreateDefColormap(pScreen)) RETURN(FALSE); @@ -2370,10 +1726,8 @@ SMI_ScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv) * colormap. And SetGamma call, else it will load palette with solid white. */ /* CZ 2.11.2001: CMAP_PALETTED_TRUECOLOR for gamma correction */ - if (!xf86HandleColormaps(pScreen, 256, pScrn->rgbBits, IS_MSOC(pSmi) ? - SMI501_LoadPalette : SMI_LoadPalette, NULL, - CMAP_RELOAD_ON_MODE_SWITCH | - CMAP_PALETTED_TRUECOLOR)) + if (!xf86HandleColormaps(pScreen, 256, pScrn->rgbBits,SMI_LoadPalette, NULL, + CMAP_RELOAD_ON_MODE_SWITCH | CMAP_PALETTED_TRUECOLOR)) RETURN(FALSE); pScreen->SaveScreen = SMI_SaveScreen; @@ -2383,7 +1737,7 @@ SMI_ScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv) if ((IS_MSOC(pSmi) && !xf86DPMSInit(pScreen, SMI501_DisplayPowerManagementSet, 0)) || (!IS_MSOC(pSmi) && - !xf86DPMSInit(pScreen, SMI_DisplayPowerManagementSet, 0))) + !xf86DPMSInit(pScreen, SMILynx_DisplayPowerManagementSet, 0))) xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "DPMS initialization failed!\n"); if (!pSmi->Dualhead) @@ -2391,6 +1745,9 @@ SMI_ScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv) else xf86DrvMsg(pScrn->scrnIndex, X_INFO, "No overlay in dualhead mode\n"); + if(!xf86CrtcScreenInit(pScreen)) + RETURN(FALSE); + /* Report any unused options (only for the first generation) */ if (serverGeneration == 1) { xf86ShowUnusedOptions(pScrn->scrnIndex, pScrn->options); @@ -2399,673 +1756,6 @@ SMI_ScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv) RETURN(TRUE); } -/* Common init routines needed in EnterVT and ScreenInit */ - -static int -SMI_InternalScreenInit(int scrnIndex, ScreenPtr pScreen) -{ - ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; - SMIPtr pSmi = SMIPTR(pScrn); - int width, height; - int bytesPerPixel = pScrn->bitsPerPixel / 8; - int xDpi, yDpi; - int ret; - - ENTER(); - - if (pSmi->rotate) { - width = pScrn->virtualY; - height = pScrn->virtualX; - xDpi = pScrn->yDpi; - yDpi = pScrn->xDpi; - } else { - width = pScrn->virtualX; - height = pScrn->virtualY; - xDpi = pScrn->xDpi; - yDpi = pScrn->yDpi; - } - pScrn->displayWidth = ((width * bytesPerPixel + 15) & ~15) / bytesPerPixel; - - if (pSmi->shadowFB) { - pSmi->ShadowWidth = width; - pSmi->ShadowHeight = height; - pSmi->ShadowWidthBytes = pScrn->displayWidth*bytesPerPixel; - pSmi->screenStride = ((pScrn->virtualX * pSmi->Bpp + 15) & ~15)/ pSmi->Bpp; - if(pScrn->bitsPerPixel==24) - pSmi->screenStride *= 3; - - pSmi->saveBufferSize = pSmi->ShadowWidthBytes * pSmi->ShadowHeight; - pSmi->FBReserved -= pSmi->saveBufferSize; - pSmi->FBReserved &= ~0x15; - - if (!IS_MSOC(pSmi)) - WRITE_VPR(pSmi, 0x0c, (pSmi->FBOffset = pSmi->FBReserved) >> 3); - - if (pSmi->Chipset == SMI_COUGAR3DR) - WRITE_FPR(pSmi, FPR0C, (pSmi->FBOffset = pSmi->FBReserved) >> 3); - else if (IS_MSOC(pSmi)) { - if (pSmi->IsSecondary) - WRITE_DCR(pSmi, 0x0204, pSmi->FBOffset); - else - WRITE_DCR(pSmi, 0x000c, pSmi->FBOffset); - } - - pScrn->fbOffset = pSmi->FBOffset + pSmi->fbMapOffset; - xf86DrvMsg(pScrn->scrnIndex, X_INFO, - "Shadow: width=%d height=%d " - "offset=0x%08lX\n", - pSmi->ShadowWidth, pSmi->ShadowHeight, - (unsigned long)pSmi->FBOffset); - } else { - pSmi->FBOffset = 0; - pScrn->fbOffset = pSmi->FBOffset + pSmi->fbMapOffset; - } - - /* - * Call the framebuffer layer's ScreenInit function, and fill in other - * pScreen fields. - */ - - DEBUG("\tInitializing FB @ 0x%08X for %dx%d (%d)\n", - pSmi->FBBase, width, height, pScrn->displayWidth); - switch (pScrn->bitsPerPixel) { - case 8: - case 16: - case 24: - case 32: - ret = fbScreenInit(pScreen, pSmi->FBBase, width, height, xDpi, - yDpi, pScrn->displayWidth, pScrn->bitsPerPixel); - break; - default: - xf86DrvMsg(scrnIndex, X_ERROR, "Internal error: invalid bpp (%d) " - "in SMI_InternalScreenInit\n", pScrn->bitsPerPixel); - RETURN(FALSE); - } - - if (IS_MSOC(pSmi) && pScrn->bitsPerPixel == 8) { - /* Initialize Palette entries 0 and 1, they don't seem to get hit */ - if (pSmi->IsSecondary) { - WRITE_DCR(pSmi, 0x0400 + 0, 0x00000000); /* CRT Palette */ - WRITE_DCR(pSmi, 0x0400 + 4, 0x00FFFFFF); /* CRT Palette */ - } - else { - WRITE_DCR(pSmi, 0x0800 + 0, 0x00000000); /* Panel Palette */ - WRITE_DCR(pSmi, 0x0800 + 4, 0x00FFFFFF); /* Panel Palette */ - } - } - - RETURN(ret); -} - -/* Checks if a mode is suitable for the selected configuration. */ -static ModeStatus -SMI_ValidMode(int scrnIndex, DisplayModePtr mode, Bool verbose, int flags) -{ - ScrnInfoPtr pScrn = xf86Screens[scrnIndex]; - SMIPtr pSmi = SMIPTR(pScrn); - float refresh; - - ENTER(); - refresh = (mode->VRefresh > 0) ? mode->VRefresh - : mode->Clock * 1000.0 / mode->VTotal / mode->HTotal; - xf86DrvMsg(scrnIndex, X_INFO, "Mode: %dx%d %d-bpp, %fHz\n", mode->HDisplay, - mode->VDisplay, pScrn->bitsPerPixel, refresh); - - if (pSmi->shadowFB) { - int mem; - - if (pScrn->bitsPerPixel == 24) - RETURN(MODE_BAD); - - mem = (pScrn->virtualX * pScrn->bitsPerPixel / 8 + 15) & ~15; - mem *= pScrn->virtualY * 2; - - if (mem > pSmi->FBReserved) /* PDR#1074 */ - RETURN(MODE_MEM); - } - - if (!(((mode->HDisplay == 1280) && (mode->VDisplay == 1024)) || - ((mode->HDisplay == 1024) && (mode->VDisplay == 768)) || - ((mode->HDisplay == 800) && (mode->VDisplay == 600)) || - ((mode->HDisplay == 640) && (mode->VDisplay == 480)) || - ((mode->HDisplay == 320) && (mode->VDisplay == 240)) || - ((mode->HDisplay == 400) && (mode->VDisplay == 300)) || - ((mode->HDisplay == 1280) && (mode->VDisplay == 960)) || - ((mode->HDisplay == 1280) && (mode->VDisplay == 768)) || - ((mode->HDisplay == 1024) && (mode->VDisplay == 600)) || - ((mode->HDisplay == 800) && (mode->VDisplay == 480)) || - ((mode->HDisplay == 720) && (mode->VDisplay == 540)) || - ((mode->HDisplay == 720) && (mode->VDisplay == 480)))) { - xf86DrvMsg (pScrn->scrnIndex, X_INFO, "HDisplay %d, VDisplay %d\n", - mode->HDisplay, mode->VDisplay); - RETURN(MODE_BAD_WIDTH); - } - - RETURN(MODE_OK); -} - -static void -SMI_DPRInit(ScrnInfoPtr pScrn) -{ - SMIPtr pSmi = SMIPTR(pScrn); - int i; - int xyAddress[] = { 320, 400, 512, 640, 800, 1024, 1280, 1600, 2048 }; - CARD32 DEDataFormat = 0; - - /* Store values to current mode register structs */ - SMIRegPtr new = pSmi->mode; - - /* Set DPR registers */ - pSmi->Stride = ((pSmi->width * pSmi->Bpp + 15) & ~15) / pSmi->Bpp; - if(pScrn->bitsPerPixel==24) - pSmi->Stride *= 3; - - DEDataFormat=SMI_DEDataFormat(pScrn->bitsPerPixel); - - for (i = 0; i < sizeof(xyAddress) / sizeof(xyAddress[0]); i++) { - if (pSmi->rotate) { - if (xyAddress[i] == pSmi->height) { - DEDataFormat |= i << 16; - break; - } - } else { - if (xyAddress[i] == pSmi->width) { - DEDataFormat |= i << 16; - break; - } - } - } - - new->DPR10 = (pSmi->Stride << 16) | pSmi->Stride; - new->DPR1C = DEDataFormat; - new->DPR20 = 0; - new->DPR24 = 0xFFFFFFFF; - new->DPR28 = 0xFFFFFFFF; - new->DPR2C = 0; - new->DPR30 = 0; - new->DPR3C = (pSmi->Stride << 16) | pSmi->Stride; - if(pSmi->shadowFB){ - new->DPR40 = 0; - new->DPR44 = 0; /* The shadow framebuffer is located at offset 0 */ - }else{ - new->DPR40 = pSmi->FBOffset >> 3; - new->DPR44 = pSmi->FBOffset >> 3; - } - -} - -static Bool -SMI_ModeInit(ScrnInfoPtr pScrn, DisplayModePtr mode) -{ - SMIPtr pSmi = SMIPTR(pScrn); - SMIRegPtr new = pSmi->mode; - vgaHWPtr hwp = VGAHWPTR(pScrn); - vgaRegPtr vganew = &hwp->ModeReg; - int panelIndex, modeIndex, i, vclk; - unsigned char tmp; - - ENTER(); - - pSmi->Bpp = pScrn->bitsPerPixel / 8; - if (pSmi->rotate) { - pSmi->width = pScrn->virtualY; - pSmi->height = pScrn->virtualX; - pSmi->Stride = (pSmi->height * pSmi->Bpp + 15) & ~15; - } - else { - pSmi->width = pScrn->virtualX; - pSmi->height = pScrn->virtualY; - pSmi->Stride = (pSmi->width * pSmi->Bpp + 15) & ~15; - } - - if (!vgaHWInit(pScrn, mode)) - RETURN(FALSE); - - new->modeInit = TRUE; - - outb(pSmi->PIOBase + VGA_SEQ_INDEX, 0x17); - tmp = inb(pSmi->PIOBase + VGA_SEQ_DATA); - if (pSmi->PCIBurst) { - new->SR17 = tmp | 0x20; - } else { - new->SR17 = tmp & ~0x20; - } - - outb(pSmi->PIOBase + VGA_SEQ_INDEX, 0x18); - new->SR18 = inb(pSmi->PIOBase + VGA_SEQ_DATA) | 0x11; - - outb(pSmi->PIOBase + VGA_SEQ_INDEX, 0x21); - new->SR21 = inb(pSmi->PIOBase + VGA_SEQ_DATA) & ~0x03; - - if (pSmi->Chipset != SMI_COUGAR3DR) { - outb(pSmi->PIOBase + VGA_SEQ_INDEX, 0x31); - new->SR31 = inb(pSmi->PIOBase + VGA_SEQ_DATA) & ~0xC0; - - outb(pSmi->PIOBase + VGA_SEQ_INDEX, 0x32); - new->SR32 = inb(pSmi->PIOBase + VGA_SEQ_DATA) & ~0x07; - - if (SMI_LYNXM_SERIES(pSmi->Chipset)) { - new->SR32 |= 0x04; - } - } - - new->SRA0 = new->CR33 = new->CR3A = 0x00; - - switch (pSmi->lcdWidth) { - case 640: panelIndex = 0; break; - case 800: panelIndex = 1; break; - case 1024: panelIndex = 2; break; - default: panelIndex = 3; break; - } - - switch (mode->HDisplay) { - case 640: modeIndex = 0; break; - case 800: modeIndex = 1; break; - case 1024: modeIndex = 2; break; - default: modeIndex = 3; break; - } - -#ifdef LCD_SIZE_DETECT - if (SMI_LYNXM_SERIES(pSmi->Chipset)) { - static unsigned char PanelTable[4][16] = { - /* 640x480 */ - {0x5F, 0x4F, 0x00, 0x52, 0x1E, 0x0B, 0xDF, 0x00, 0xE9, 0x0B, - 0x2E, - 0x00, 0x4F, 0xDF, 0x07, 0x82}, - /* 8000x600 */ - {0x7F, 0x63, 0x00, 0x69, 0x19, 0x72, 0x57, 0x00, 0x58, 0x0C, - 0xA2, - 0x20, 0x4F, 0xDF, 0x1C, 0x85}, - /* 1024x768 */ - {0xA3, 0x7F, 0x00, 0x83, 0x14, 0x24, 0xFF, 0x00, 0x02, 0x08, - 0xA7, - 0xE0, 0x4F, 0xDF, 0x52, 0x89}, - /* other */ - {0xCE, 0x9F, 0x00, 0xA7, 0x15, 0x28, 0xFF, 0x28, 0x00, 0xA3, - 0x5A, - 0x20, 0x9F, 0xFF, 0x53, 0x0B}, - }; - - for (i = 0; i < 14; i++) - new->CR40[i] = PanelTable[panelIndex][i]; - - new->SR6C = PanelTable[panelIndex][14]; - new->SR6D = PanelTable[panelIndex][15]; - - if (panelIndex == 3) - new->CR90[14] = 0x18; - else - new->CR90[14] = 0x00; - - if (mode->VDisplay < pSmi->lcdHeight) - new->CRA0[6] = (pSmi->lcdHeight - mode->VDisplay) / 8; - else - new->CRA0[6] = 0; - - if (mode->HDisplay < pSmi->lcdWidth) - new->CRA0[7] = (pSmi->lcdWidth - mode->HDisplay) / 16; - else - new->CRA0[7] = 0; - } - else { - static unsigned char ModeTable[5][3][16] = { - /* 640x480 */ - { - /* 60 Hz */ - { - 0x5F, 0x4F, 0x00, 0x54, 0x00, 0x0B, 0xDF, 0x00, - 0xEA, 0x0C, 0x2E, 0x00, 0x4F, 0xDF, 0x07, 0x82, - }, - /* 75 Hz */ - { - 0x64, 0x4F, 0x00, 0x52, 0x1A, 0xF2, 0xDF, 0x00, - 0xE0, 0x03, 0x0F, 0xC0, 0x4F, 0xDF, 0x16, 0x85, - }, - /* 85 Hz */ - { - 0x63, 0x4F, 0x00, 0x57, 0x1E, 0xFB, 0xDF, 0x00, - 0xE0, 0x03, 0x0F, 0xC0, 0x4F, 0xDF, 0x88, 0x9B, - }, - }, - /* 800x480 */ - { - /* 60 Hz */ - { - 0x6B, 0x63, 0x00, 0x69, 0x1B, 0xF2, 0xDF, 0x00, - 0xE2, 0xE4, 0x1F, 0xC0, 0x63, 0xDF, 0x2C, 0x17, - }, - /* 75 Hz */ - { - 0x6B, 0x63, 0x00, 0x69, 0x1B, 0xF2, 0xDF, 0x00, - 0xE2, 0xE4, 0x1F, 0xC0, 0x63, 0xDF, 0x2C, 0x17, - }, - /* 85 Hz */ - { - 0x6B, 0x63, 0x00, 0x69, 0x1B, 0xF2, 0xDF, 0x00, - 0xE2, 0xE4, 0x1F, 0xC0, 0x63, 0xDF, 0x2C, 0x17, - }, - }, - /* 800x600 */ - { - /* 60 Hz */ - { - 0x7F, 0x63, 0x00, 0x69, 0x18, 0x72, 0x57, 0x00, - 0x58, 0x0C, 0xE0, 0x20, 0x63, 0x57, 0x1C, 0x85, - }, - /* 75 Hz */ - { - 0x7F, 0x63, 0x00, 0x66, 0x10, 0x6F, 0x57, 0x00, - 0x58, 0x0B, 0xE0, 0x20, 0x63, 0x57, 0x4C, 0x8B, - }, - /* 85 Hz */ - { - 0x7E, 0x63, 0x00, 0x68, 0x10, 0x75, 0x57, 0x00, - 0x58, 0x0B, 0xE0, 0x20, 0x63, 0x57, 0x37, 0x87, - }, - }, - /* 1024x768 */ - { - /* 60 Hz */ - { - 0xA3, 0x7F, 0x00, 0x86, 0x15, 0x24, 0xFF, 0x00, - 0x01, 0x07, 0xE5, 0x20, 0x7F, 0xFF, 0x52, 0x89, - }, - /* 75 Hz */ - { - 0x9F, 0x7F, 0x00, 0x82, 0x0E, 0x1E, 0xFF, 0x00, - 0x00, 0x03, 0xE5, 0x20, 0x7F, 0xFF, 0x0B, 0x02, - }, - /* 85 Hz */ - { - 0xA7, 0x7F, 0x00, 0x86, 0x12, 0x26, 0xFF, 0x00, - 0x00, 0x03, 0xE5, 0x20, 0x7F, 0xFF, 0x70, 0x11, - }, - }, - /* 1280x1024 */ - { - /* 60 Hz */ - { - 0xCE, 0x9F, 0x00, 0xA7, 0x15, 0x28, 0xFF, 0x00, - 0x00, 0x03, 0x4A, 0x20, 0x9F, 0xFF, 0x53, 0x0B, - }, - /* 75 Hz */ - { - 0xCE, 0x9F, 0x00, 0xA2, 0x14, 0x28, 0xFF, 0x00, - 0x00, 0x03, 0x4A, 0x20, 0x9F, 0xFF, 0x13, 0x02, - }, - /* 85 Hz */ - { - 0xD3, 0x9F, 0x00, 0xA8, 0x1C, 0x2E, 0xFF, 0x00, - 0x00, 0x03, 0x4A, 0x20, 0x9F, 0xFF, 0x16, 0x42, - }, - }, - }; - int refresh_rate_index = 0; - - if (abs(mode->VRefresh - 60.0) < 5) - refresh_rate_index = 0; - else if (abs(mode->VRefresh - 75.0) < 5) - refresh_rate_index = 1; - else if (abs(mode->VRefresh - 85.0) < 5) - refresh_rate_index = 2; - - for (i = 0; i < 14; i++) - new->CR40[i] = ModeTable[modeIndex][refresh_rate_index][i]; - - new->SR6C = ModeTable[modeIndex][refresh_rate_index][14]; - new->SR6D = ModeTable[modeIndex][refresh_rate_index][15]; - - if (panelIndex == 3) - new->CR90[14] = 0x18; - else - new->CR90[14] = 0x00; - - if (mode->VDisplay < pSmi->lcdHeight) - new->CRA0[6] = (pSmi->lcdHeight - mode->VDisplay) / 8; - else - new->CRA0[6] = 0; - if (mode->HDisplay < pSmi->lcdWidth) - new->CRA0[7] = (pSmi->lcdWidth - mode->HDisplay) / 16; - else - new->CRA0[7] = 0; - } - - /* CZ 2.11.2001: for gamma correction (TODO: other chipsets?) */ - new->CCR66 = VGAIN8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x66); - if (pSmi->Chipset == SMI_LYNX3DM || pSmi->Chipset == SMI_COUGAR3DR) { - switch (pScrn->bitsPerPixel) { - case 8: - new->CCR66 = (new->CCR66 & 0xF3) | 0x00; /* 6 bits-RAM */ - break; - case 16: - new->CCR66 = (new->CCR66 & 0xF3) | 0x00; /* 6 bits-RAM */ - /* no Gamma correction in 16 Bit mode (s. Release.txt 1.3.1) */ - break; - case 24: - case 32: - new->CCR66 = (new->CCR66 & 0xF3) | 0x04; /* Gamma correct ON */ - break; - default: - RETURN(FALSE); - } - } -#endif - - if (pSmi->Chipset != SMI_COUGAR3DR) { - outb(pSmi->PIOBase + VGA_SEQ_INDEX, 0x30); - if (inb(pSmi->PIOBase + VGA_SEQ_DATA) & 0x01) - new->SR21 = 0x00; - } - - if (pSmi->MCLK > 0) - SMI_CommonCalcClock(pScrn->scrnIndex, pSmi->MCLK, - 1, 1, 63, 0, 0, - pScrn->clockRanges->minClock, - pScrn->clockRanges->maxClock, - &new->SR6A, &new->SR6B); - else - new->SR6B = 0xFF; - - if ((mode->HDisplay == 640) && SMI_LYNXM_SERIES(pSmi->Chipset)) { - vganew->MiscOutReg &= ~0x0C; - } else { - vganew->MiscOutReg |= 0x0C; - } - vganew->MiscOutReg |= 0xE0; - if (mode->HDisplay == 800) { - vganew->MiscOutReg &= ~0xC0; - } - if ((mode->HDisplay == 1024) && SMI_LYNXM_SERIES(pSmi->Chipset)) { - vganew->MiscOutReg &= ~0xC0; - } - - /* calculate vclk1 */ - vclk = mode->Clock; - if (SMI_LYNX_SERIES(pSmi->Chipset)) { - SMI_CommonCalcClock(pScrn->scrnIndex, vclk, - 1, 1, 63, 0, 3, - pScrn->clockRanges->minClock, - pScrn->clockRanges->maxClock, - &new->SR6C, &new->SR6D); - } else { - SMI_CommonCalcClock(pScrn->scrnIndex, vclk, - 1, 1, 63, 0, 1, - pScrn->clockRanges->minClock, - pScrn->clockRanges->maxClock, - &new->SR6C, &new->SR6D); - } - - /* use vclk1 */ - new->SR68 = 0x54; - - /* dualhead */ - if (pSmi->Dualhead) { - /* TFT panel uses FIFO1, DSTN panel uses FIFO1 for upper panel and - * FIFO2 for lower panel. I don't have a DSTN panel, so it's untested. - * -- AGD - */ - CARD32 fifo1_readoffset, fifo2_readoffset, fifo_writeoffset; - - /* PLL controls */ - /* set LCD to vclk2 */ - new->SR69 = 0x04; - - if (pSmi->lcdWidth == 640) { - /* vclk */ - new->SR6C = 0x07; - new->SR6D = 0x04; - - /* vclk2 */ - new->SR6E = 0x07; - new->SR6F = 0x04; - } else if (pSmi->lcdWidth == 800) { - /* vclk */ - new->SR6C = 0x0B; - new->SR6D = 0x82; - - /* vclk2 */ - new->SR6E = 0x0B; - new->SR6F = 0x82; - } else { - /* vclk */ - new->SR6C = 0x52; - new->SR6D = 0x89; - - /* vclk2 */ - new->SR6E = 0x52; - new->SR6F = 0x89; - } - - /* setting SR21 bit 2 disables ZV circuitry, - * if ZV is needed, SR21 = 0x20 - */ - /* enable DAC, PLL, etc. */ - new->SR21 = 0x24; - - /* clear DPMS state */ - new->SR22 = VGAIN8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x22) & ~0x30; - - /* enable virtual refresh and LCD and CRT outputs */ - if (pScrn->bitsPerPixel > 8) - new->SR31 = /*0xCB*/ 0xC3; /* 16 bpp */ - else - new->SR31 = /*0x8B*/ 0x83; /* 8 bpp */ - - /* FIFO1 Read Offset */ - fifo1_readoffset = pSmi->lcdWidth / 2; - fifo2_readoffset = pSmi->lcdWidth / 2; - new->SR44 = fifo1_readoffset & 0x000000FF; - /* FIFO2 Read Offset */ - new->SR4B = fifo2_readoffset & 0x000000FF; - /* FIFO1/2 Read Offset overflow */ - new->SR4C = (((fifo1_readoffset & 0x00000300) >> 8) << 2) | - (((fifo2_readoffset & 0x00000300) >> 8) << 6); - - /* FIFO Write Offset */ - fifo_writeoffset = pSmi->lcdWidth / 4; - new->SR48 = fifo_writeoffset & 0x000000FF; - new->SR49 = (fifo_writeoffset & 0x00000300) >> 8; - - /* set FIFO levels */ - new->SR4A = 0x41; - - /* something related to tv... */ - new->CR33 |= 0x07; - - } - - /* init graphics engine regs */ - SMI_DPRInit(pScrn); - - /* Set VPR registers (and FPR registers for SM731) */ - switch (pScrn->bitsPerPixel) { - case 8: - new->VPR00 = 0x00000000; - new->FPR00_= 0x00080000; - break; - case 16: - new->VPR00 = 0x00020000; - new->FPR00_= 0x000A0000; - break; - case 24: - new->VPR00 = 0x00040000; - new->FPR00_= 0x000C0000; - break; - case 32: - new->VPR00 = 0x00030000; - new->FPR00_= 0x000B0000; - break; - } - new->VPR0C = pSmi->FBOffset >> 3; - if (pSmi->rotate) { - new->VPR10 = (((( pSmi->height * pSmi->Bpp) >> 3) + 2) << 16) | - ((pSmi->height * pSmi->Bpp) >> 3); - } else { - new->VPR10 = ((((pSmi->width * pSmi->Bpp) >> 3) + 2) << 16) | - ((pSmi->width * pSmi->Bpp) >> 3); - } - - new->FPR0C_ = new->VPR0C; - new->FPR10_ = new->VPR10; - - /* Set CPR registers */ - new->CPR00 = 0x00000000; - - pScrn->vtSema = TRUE; - - /* Find the INT 10 mode number */ - { - static struct { - int x, y, bpp; - CARD16 mode; - } modeTable[] = - { - { 640, 480, 8, 0x50 }, - { 640, 480, 16, 0x52 }, - { 640, 480, 24, 0x53 }, - { 640, 480, 32, 0x54 }, - { 800, 480, 8, 0x4A }, - { 800, 480, 16, 0x4C }, - { 800, 480, 24, 0x4D }, - { 800, 600, 8, 0x55 }, - { 800, 600, 16, 0x57 }, - { 800, 600, 24, 0x58 }, - { 800, 600, 32, 0x59 }, - { 1024, 768, 8, 0x60 }, - { 1024, 768, 16, 0x62 }, - { 1024, 768, 24, 0x63 }, - { 1024, 768, 32, 0x64 }, - { 1280, 1024, 8, 0x65 }, - { 1280, 1024, 16, 0x67 }, - { 1280, 1024, 24, 0x68 }, - { 1280, 1024, 32, 0x69 }, - }; - - new->mode = 0; - for (i = 0; i < sizeof(modeTable) / sizeof(modeTable[0]); i++) { - if ((modeTable[i].x == mode->HDisplay) && - (modeTable[i].y == mode->VDisplay) && - (modeTable[i].bpp == pScrn->bitsPerPixel)) { - new->mode = modeTable[i].mode; - break; - } - } - } - - /* Zero the font memory */ - memset(new->smiFont, 0, sizeof(new->smiFont)); - - /* Write the mode registers to hardware */ - SMI_WriteMode(pScrn, vganew, new); - - /* Adjust the viewport */ - pScrn->frameX1=pScrn->frameX0 + pScrn->currentMode->HDisplay - 1; - pScrn->frameY1=pScrn->frameY0 + pScrn->currentMode->VDisplay - 1; - SMI_AdjustFrame(pScrn->scrnIndex, pScrn->frameX0, pScrn->frameY0, 0); - - RETURN(TRUE); -} - /* * This is called at the end of each server generation. It restores the * original (text) mode. It should also unmap the video memory, and free any @@ -3086,7 +1776,7 @@ SMI_CloseScreen(int scrnIndex, ScreenPtr pScreen) if (!IS_MSOC(pSmi)) { vgaHWPtr hwp = VGAHWPTR(pScrn); - SMI_WriteMode(pScrn, &hwp->SavedReg, pSmi->save); + SMILynx_WriteMode(pScrn, &hwp->SavedReg, pSmi->save); vgaHWLock(hwp); } SMI_UnmapMem(pScrn); @@ -3109,6 +1799,10 @@ SMI_CloseScreen(int scrnIndex, ScreenPtr pScreen) xf86FreeInt10(pSmi->pInt10); pSmi->pInt10 = NULL; } + if (pSmi->pVbe != NULL) { + vbeFree(pSmi->pVbe); + pSmi->pVbe = NULL; + } if (pSmi->ptrAdaptor != NULL) { xfree(pSmi->ptrAdaptor); } @@ -3140,79 +1834,28 @@ SMI_FreeScreen(int scrnIndex, int flags) static Bool SMI_SaveScreen(ScreenPtr pScreen, int mode) { - SMIPtr pSmi = SMIPTR(xf86Screens[pScreen->myNum]); - Bool ret; + ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; ENTER(); - ret = !IS_MSOC(pSmi) && vgaHWSaveScreen(pScreen, mode); + if(xf86IsUnblank(mode)){ + pScrn->DPMSSet(pScrn, DPMSModeOn, 0); + }else{ + pScrn->DPMSSet(pScrn, DPMSModeOff, 0); + } - RETURN(ret); + RETURN(TRUE); } void SMI_AdjustFrame(int scrnIndex, int x, int y, int flags) { - ScrnInfoPtr pScrn = xf86Screens[scrnIndex]; - SMIPtr pSmi = SMIPTR(pScrn); - CARD32 Base, lcdBase; + xf86CrtcConfigPtr crtcConf = XF86_CRTC_CONFIG_PTR(xf86Screens[scrnIndex]); + xf86CrtcPtr compat_crtc = crtcConf->output[crtcConf->compat_output]->crtc; ENTER(); - if (pSmi->ShowCache && y) { - y += pScrn->virtualY - 1; - } - - if (pSmi->Dualhead) { - lcdBase = 0; - x = pSmi->lcdWidth; - y = 0; - } - - Base = pSmi->FBOffset + (x + y * pScrn->virtualX) * pSmi->Bpp; - if (SMI_LYNX3D_SERIES(pSmi->Chipset) || - SMI_COUGAR_SERIES(pSmi->Chipset)) { - Base = (Base + 15) & ~15; -#if 1 /* PDR#1058 */ - while ((Base % pSmi->Bpp) > 0) { - Base -= 16; - } -#endif - } - else if (IS_MSOC(pSmi)) { - if (!pSmi->IsSecondary) - WRITE_DCR(pSmi, 0x0204, Base); - else - WRITE_DCR(pSmi, 0x000C, 0); - } - else { - Base = (Base + 7) & ~7; - while ((Base % pSmi->Bpp) > 0) - Base -= 8; - - if (pSmi->Dualhead) { - /* FIFO1 read start address */ - VGAOUT8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x40, - (lcdBase & 0x000000FF)); - VGAOUT8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x41, - ((lcdBase & 0x0000FF00) >> 8)); - - /* FIFO2 read start address */ - VGAOUT8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x42, - (lcdBase & 0x000000FF)); - VGAOUT8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x43, - ((lcdBase & 0x0000FF00) >> 8)); - - /* FIFO1/2 read start address overflow */ - VGAOUT8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x45, - ((lcdBase & 0x000F0000) >> 12) | (((lcdBase & 0x000F0000) >> 12) << 4)); - } - } - - WRITE_VPR(pSmi, 0x0C, Base >> 3); - if (pSmi->Chipset == SMI_COUGAR3DR) { - WRITE_FPR(pSmi, FPR0C, Base >> 3); - } + SMICRTC(compat_crtc)->adjust_frame(compat_crtc,x,y); LEAVE(); } @@ -3221,15 +1864,15 @@ Bool SMI_SwitchMode(int scrnIndex, DisplayModePtr mode, int flags) { Bool ret; - SMIPtr pSmi = SMIPTR(xf86Screens[scrnIndex]); + ScrnInfoPtr pScrn = xf86Screens[scrnIndex]; + SMIPtr pSmi = SMIPTR(pScrn); ENTER(); - pSmi->IsSwitching = TRUE; - ret = pSmi->ModeInit(xf86Screens[scrnIndex], mode); + ret = xf86SetSingleMode(pScrn, mode, RR_Rotate_0); + if (!pSmi->NoAccel) - SMI_EngineReset(xf86Screens[scrnIndex]); - pSmi->IsSwitching = FALSE; + SMI_EngineReset(pScrn); RETURN(ret); } @@ -3238,27 +1881,47 @@ void SMI_LoadPalette(ScrnInfoPtr pScrn, int numColors, int *indicies, LOCO *colors, VisualPtr pVisual) { - SMIPtr pSmi = SMIPTR(pScrn); - int i; + xf86CrtcConfigPtr crtcConf = XF86_CRTC_CONFIG_PTR(pScrn); + int crtc_idx,i,j; ENTER(); - /* Enable both the CRT and LCD DAC RAM paths, so both palettes are updated */ - if (pSmi->Chipset == SMI_LYNX3DM || pSmi->Chipset == SMI_COUGAR3DR) { - CARD8 ccr66; + if(pScrn->bitsPerPixel == 16){ + /* Expand the RGB 565 palette into the 256-elements LUT */ + + for(crtc_idx=0; crtc_idx<crtcConf->num_crtc; crtc_idx++){ + SMICrtcPrivatePtr crtcPriv = SMICRTC(crtcConf->crtc[crtc_idx]); + + for(i=0; i<numColors; i++){ + int idx = indicies[i]; - ccr66 = VGAIN8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x66); - ccr66 &= 0x0f; - VGAOUT8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x66, ccr66); + if(idx<32){ + for(j=0; j<8; j++){ + crtcPriv->lut_r[idx*8 + j] = colors[idx].red << 8; + crtcPriv->lut_b[idx*8 + j] = colors[idx].blue << 8; + } + } + + for(j=0; j<4; j++) + crtcPriv->lut_g[idx*4 + j] = colors[idx].green << 8; + } + + crtcPriv->load_lut(crtcConf->crtc[crtc_idx]); } + }else{ + for(crtc_idx=0; crtc_idx<crtcConf->num_crtc; crtc_idx++){ + SMICrtcPrivatePtr crtcPriv = SMICRTC(crtcConf->crtc[crtc_idx]); for(i = 0; i < numColors; i++) { - DEBUG("pal[%d] = %d %d %d\n", indicies[i], - colors[indicies[i]].red, colors[indicies[i]].green, colors[indicies[i]].blue); - VGAOUT8(pSmi, VGA_DAC_WRITE_ADDR, indicies[i]); - VGAOUT8(pSmi, VGA_DAC_DATA, colors[indicies[i]].red); - VGAOUT8(pSmi, VGA_DAC_DATA, colors[indicies[i]].green); - VGAOUT8(pSmi, VGA_DAC_DATA, colors[indicies[i]].blue); + int idx = indicies[i]; + + crtcPriv->lut_r[idx] = colors[idx].red << 8; + crtcPriv->lut_g[idx] = colors[idx].green << 8; + crtcPriv->lut_b[idx] = colors[idx].blue << 8; + } + + crtcPriv->load_lut(crtcConf->crtc[crtc_idx]); + } } LEAVE(); @@ -3346,66 +2009,46 @@ SMI_DisableMmio(ScrnInfoPtr pScrn) LEAVE(); } -/* This function is used to debug, it prints out the contents of Lynx regs */ static void +SMI_ProbeDDC(ScrnInfoPtr pScrn, int index) +{ + vbeInfoPtr pVbe; + if (xf86LoadSubModule(pScrn, "vbe")) { + pVbe = VBEInit(NULL, index); + ConfiguredMonitor = vbeDoEDID(pVbe, NULL); + vbeFree(pVbe); + } +} + +static Bool +SMI_HWInit(ScrnInfoPtr pScrn) +{ + SMIPtr pSmi = SMIPTR(pScrn); + + ENTER(); + + if(IS_MSOC(pSmi)) + RETURN(SMI501_HWInit(pScrn)); + else + RETURN(SMILynx_HWInit(pScrn)); +} + +void SMI_PrintRegs(ScrnInfoPtr pScrn) { - unsigned char i; SMIPtr pSmi = SMIPTR(pScrn); + int i; + + ENTER(); xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, VERBLEV, "START register dump ------------------\n"); - if (!IS_MSOC(pSmi)) { - vgaHWPtr hwp = VGAHWPTR(pScrn); - int vgaCRIndex = hwp->IOBase + VGA_CRTC_INDEX_OFFSET; - int vgaCRReg = hwp->IOBase + VGA_CRTC_DATA_OFFSET; - int vgaStatus = hwp->IOBase + VGA_IN_STAT_1_OFFSET; - - xf86ErrorFVerb(VERBLEV, "MISCELLANEOUS OUTPUT\n %02X\n", - VGAIN8(pSmi, VGA_MISC_OUT_R)); - - xf86ErrorFVerb(VERBLEV, "\nSEQUENCER\n" - " x0 x1 x2 x3 x4 x5 x6 x7 x8 x9 xA xB xC xD xE xF"); - for (i = 0x00; i <= 0xAF; i++) { - if ((i & 0xF) == 0x0) xf86ErrorFVerb(VERBLEV, "\n%02X|", i); - if ((i & 0x3) == 0x0) xf86ErrorFVerb(VERBLEV, " "); - xf86ErrorFVerb(VERBLEV, "%02X ", - VGAIN8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, i)); - } - - xf86ErrorFVerb(VERBLEV, "\n\nCRT CONTROLLER\n" - " x0 x1 x2 x3 x4 x5 x6 x7 x8 x9 xA xB xC xD xE xF"); - for (i = 0x00; i <= 0xAD; i++) { - if (i == 0x20) i = 0x30; - if (i == 0x50) i = 0x90; - if ((i & 0xF) == 0x0) xf86ErrorFVerb(VERBLEV, "\n%02X|", i); - if ((i & 0x3) == 0x0) xf86ErrorFVerb(VERBLEV, " "); - xf86ErrorFVerb(VERBLEV, "%02X ", - VGAIN8_INDEX(pSmi, vgaCRIndex, vgaCRReg, i)); - } - - xf86ErrorFVerb(VERBLEV, "\n\nGRAPHICS CONTROLLER\n" - " x0 x1 x2 x3 x4 x5 x6 x7 x8 x9 xA xB xC xD xE xF"); - for (i = 0x00; i <= 0x08; i++) { - if ((i & 0xF) == 0x0) xf86ErrorFVerb(VERBLEV, "\n%02X|", i); - if ((i & 0x3) == 0x0) xf86ErrorFVerb(VERBLEV, " "); - xf86ErrorFVerb(VERBLEV, "%02X ", - VGAIN8_INDEX(pSmi, VGA_GRAPH_INDEX, VGA_GRAPH_DATA, i)); - } + if(IS_MSOC(pSmi)) + SMI501_PrintRegs(pScrn); + else + SMILynx_PrintRegs(pScrn); - xf86ErrorFVerb(VERBLEV, "\n\nATTRIBUTE 0CONTROLLER\n" - " x0 x1 x2 x3 x4 x5 x6 x7 x8 x9 xA xB xC xD xE xF"); - for (i = 0x00; i <= 0x14; i++) { - (void) VGAIN8(pSmi, vgaStatus); - if ((i & 0xF) == 0x0) xf86ErrorFVerb(VERBLEV, "\n%02X|", i); - if ((i & 0x3) == 0x0) xf86ErrorFVerb(VERBLEV, " "); - xf86ErrorFVerb(VERBLEV, "%02X ", - VGAIN8_INDEX(pSmi, VGA_ATTR_INDEX, VGA_ATTR_DATA_R, i)); - } - (void) VGAIN8(pSmi, vgaStatus); - VGAOUT8(pSmi, VGA_ATTR_INDEX, 0x20); - } xf86ErrorFVerb(VERBLEV, "\n\nDPR x0 x4 x8 xC"); for (i = 0x00; i <= 0x44; i += 4) { @@ -3428,263 +2071,6 @@ SMI_PrintRegs(ScrnInfoPtr pScrn) xf86ErrorFVerb(VERBLEV, "\n\n"); xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, VERBLEV, "END register dump --------------------\n"); -} - -/* - * SMI_DisplayPowerManagementSet -- Sets VESA Display Power Management - * Signaling (DPMS) Mode. - */ -static void -SMI_DisplayPowerManagementSet(ScrnInfoPtr pScrn, int PowerManagementMode, - int flags) -{ - SMIPtr pSmi = SMIPTR(pScrn); - vgaHWPtr hwp = VGAHWPTR(pScrn); - CARD8 SR01, SR20, SR21, SR22, SR23, SR24, SR31, SR34; - - ENTER(); - - /* If we already are in the requested DPMS mode, just return */ - if (pSmi->CurrentDPMS != PowerManagementMode) { -#if 0 - if (pSmi->useBIOS && pSmi->pInt10 != NULL) { - pSmi->pInt10->ax = 0x4F10; - switch (PowerManagementMode) { - case DPMSModeOn: - pSmi->pInt10->bx = 0x0001; - break; - case DPMSModeStandby: - pSmi->pInt10->bx = 0x0101; - break; - case DPMSModeSuspend: - pSmi->pInt10->bx = 0x0201; - break; - case DPMSModeOff: - pSmi->pInt10->bx = 0x0401; - break; - } - pSmi->pInt10->cx = 0x0000; - pSmi->pInt10->num = 0x10; - xf86ExecX86int10(pSmi->pInt10); - if (pSmi->pInt10->ax == 0x004F) { - pSmi->CurrentDPMS = PowerManagementMode; - if (PowerManagementMode == DPMSModeOn) { - SR01 = VGAIN8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x01); - VGAOUT8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x01, - SR01 & ~0x20); - } - LEAVE(); - return; - } - } -#else - /* Save the current SR registers */ - if (pSmi->CurrentDPMS == DPMSModeOn) { - pSmi->DPMS_SR20 = VGAIN8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x20); - pSmi->DPMS_SR21 = VGAIN8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x21); - pSmi->DPMS_SR31 = VGAIN8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x31); - pSmi->DPMS_SR34 = VGAIN8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x34); - } - - /* Read the required SR registers for the DPMS handler */ - SR01 = VGAIN8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x01); - SR20 = VGAIN8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x20); - SR21 = VGAIN8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x21); - SR22 = VGAIN8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x22); - SR23 = VGAIN8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x23); - SR24 = VGAIN8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x24); - SR31 = VGAIN8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x31); - SR34 = VGAIN8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x34); - - switch (PowerManagementMode) { - case DPMSModeOn: - /* Screen On: HSync: On, VSync : On */ - SR01 &= ~0x20; - SR20 = pSmi->DPMS_SR20; - SR21 = pSmi->DPMS_SR21; - SR22 &= ~0x30; - SR23 &= ~0xC0; - SR24 |= 0x01; - SR31 = pSmi->DPMS_SR31; - SR34 = pSmi->DPMS_SR34; - break; - case DPMSModeStandby: - /* Screen: Off; HSync: Off, VSync: On */ - SR01 |= 0x20; - SR20 = (SR20 & ~0xB0) | 0x10; - SR21 |= 0x88; - SR22 = (SR22 & ~0x30) | 0x10; - SR23 = (SR23 & ~0x07) | 0xD8; - SR24 &= ~0x01; - SR31 = (SR31 & ~0x07) | 0x00; - SR34 |= 0x80; - break; - case DPMSModeSuspend: - /* Screen: Off; HSync: On, VSync: Off */ - SR01 |= 0x20; - SR20 = (SR20 & ~0xB0) | 0x10; - SR21 |= 0x88; - SR22 = (SR22 & ~0x30) | 0x20; - SR23 = (SR23 & ~0x07) | 0xD8; - SR24 &= ~0x01; - SR31 = (SR31 & ~0x07) | 0x00; - SR34 |= 0x80; - break; - case DPMSModeOff: - /* Screen: Off; HSync: Off, VSync: Off */ - SR01 |= 0x20; - SR20 = (SR20 & ~0xB0) | 0x10; - SR21 |= 0x88; - SR22 = (SR22 & ~0x30) | 0x30; - SR23 = (SR23 & ~0x07) | 0xD8; - SR24 &= ~0x01; - SR31 = (SR31 & ~0x07) | 0x00; - SR34 |= 0x80; - break; - default: - xf86ErrorFVerb(VERBLEV, "Invalid PowerManagementMode %d passed to " - "SMI_DisplayPowerManagementSet\n", PowerManagementMode); - LEAVE(); - return; - } - - /* Wait for vertical retrace */ - while (hwp->readST01(hwp) & 0x8) ; - while (!(hwp->readST01(hwp) & 0x8)) ; - - /* Write the registers */ - VGAOUT8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x01, SR01); - VGAOUT8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x34, SR34); - VGAOUT8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x31, SR31); - VGAOUT8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x20, SR20); - VGAOUT8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x22, SR22); - VGAOUT8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x23, SR23); - VGAOUT8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x21, SR21); - VGAOUT8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x24, SR24); -#endif - - /* Save the current power state */ - pSmi->CurrentDPMS = PowerManagementMode; - } LEAVE(); } - -static void -SMI_ProbeDDC(ScrnInfoPtr pScrn, int index) -{ - vbeInfoPtr pVbe; - if (xf86LoadSubModule(pScrn, "vbe")) { - pVbe = VBEInit(NULL, index); - ConfiguredMonitor = vbeDoEDID(pVbe, NULL); - vbeFree(pVbe); - } -} - -static unsigned int -SMI_ddc1Read(ScrnInfoPtr pScrn) -{ - register vgaHWPtr hwp = VGAHWPTR(pScrn); - SMIPtr pSmi = SMIPTR(pScrn); - unsigned int ret; - - ENTER(); - - while (hwp->readST01(hwp) & 0x8) ; - while (!(hwp->readST01(hwp) & 0x8)) ; - - ret = VGAIN8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x72) & 0x08; - - RETURN(ret); -} - -static Bool -SMI_ddc1(int scrnIndex) -{ - ScrnInfoPtr pScrn = xf86Screens[scrnIndex]; - SMIPtr pSmi = SMIPTR(pScrn); - Bool success = FALSE; - xf86MonPtr pMon; - unsigned char tmp; - - ENTER(); - - tmp = VGAIN8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x72); - VGAOUT8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x72, tmp | 0x20); - - pMon = xf86PrintEDID(xf86DoEDID_DDC1(scrnIndex, - vgaHWddc1SetSpeedWeak(), - SMI_ddc1Read)); - if (pMon != NULL) { - success = TRUE; - } - xf86SetDDCproperties(pScrn, pMon); - - VGAOUT8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x72, tmp); - - RETURN(success); -} - -static void SMI_SetShadowDimensions(ScrnInfoPtr pScrn,int width,int height){ - SMIPtr pSmi = SMIPTR(pScrn); - pScrn->displayWidth=width; - pSmi->ShadowWidth = pSmi->width = width; - pSmi->ShadowHeight = pSmi->height= height; - pSmi->ShadowWidthBytes = width * pSmi->Bpp; - pSmi->saveBufferSize = pSmi->ShadowWidthBytes * height; - pSmi->Stride = ((pScrn->displayWidth * pSmi->Bpp + 15) & ~15) / pSmi->Bpp; - if(pScrn->bitsPerPixel==24) - pSmi->Stride*=3; - pScrn->pScreen->ModifyPixmapHeader(pScrn->pScreen->GetScreenPixmap(pScrn->pScreen),width,height,-1,-1,width*pSmi->Bpp,NULL); - if(pSmi->EXADriverPtr){ - pSmi->EXADriverPtr->offScreenBase = pScrn->displayWidth * pSmi->height * pSmi->Bpp; - } -} - -static Bool -SMI_DriverFunc(ScrnInfoPtr pScrn, xorgDriverFuncOp op, pointer ptr) -{ - xorgRRConfig rconf = ((xorgRRRotation*)ptr)->RRConfig; - SMIPtr pSmi = SMIPTR(pScrn); - - ENTER(); - if(op==RR_GET_INFO){ - if(pSmi->randrRotation) - ((xorgRRRotation*)ptr)->RRRotations = RR_Rotate_0 | RR_Rotate_90 | RR_Rotate_270; - else - ((xorgRRRotation*)ptr)->RRRotations = RR_Rotate_0; - - }else if(op==RR_SET_CONFIG){ - if(!pSmi->randrRotation) - RETURN(FALSE); - - if(rconf.rotation==RR_Rotate_0){ - if(pSmi->rotate!=0){ - if(pSmi->PointerMoved != NULL){ - pScrn->PointerMoved = pSmi->PointerMoved; - pSmi->PointerMoved = NULL; - } - SMI_SetShadowDimensions(pScrn,rconf.width,rconf.height); - } - pSmi->rotate=0; - }else if(rconf.rotation==RR_Rotate_90 || rconf.rotation==RR_Rotate_270){ - if(pSmi->rotate==0){ - if(pSmi->PointerMoved == NULL){ - pSmi->PointerMoved = pScrn->PointerMoved; - pScrn->PointerMoved = SMI_PointerMoved; - } - SMI_SetShadowDimensions(pScrn,rconf.height,rconf.width); - } - - if(rconf.rotation==RR_Rotate_90) - pSmi->rotate=SMI_ROTATE_CCW; - else - pSmi->rotate=SMI_ROTATE_CW; - - }else - RETURN(FALSE); - }else - RETURN(FALSE); - - RETURN(TRUE); -} |