/* * Authors: Alan Hourihane, * Michel Dänzer, */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include /* all driver need this */ #include "xf86.h" #include "xf86_OSproc.h" #include "mipointer.h" #include "mibstore.h" #include "micmap.h" #include "colormapst.h" #include "xf86cmap.h" #include "shadow.h" #include "dgaproc.h" /* for visuals */ #include "fb.h" #ifdef USE_AFB #include "afb.h" #endif #define XAALINES 800 #define COLEXPBUF (XAALINES*800*2) #include "xaa.h" #include "xaarop.h" #include "xf86Resources.h" #include "xf86RAC.h" #include "fbdevhw.h" #include "xf86xv.h" #ifdef XSERVER_LIBPCIACCESS #include #endif static Bool debug = 1; #define TRACE_ENTER(str) \ do { if (debug) ErrorF("fbdev: " str " %d\n",pScrn->scrnIndex); } while (0) #define TRACE_EXIT(str) \ do { if (debug) ErrorF("fbdev: " str " done\n"); } while (0) #define TRACE(str) \ do { if (debug) ErrorF("fbdev trace: " str "\n"); } while (0) // ------------------------------------------------------------------------------------------------------- #include #include #include #include #include #include #include #define FB_BA 0x20 #define COLOR_MODE 0x200 #define HORI_RES 0x204 #define VERT_RES 0x208 #define SC_WINDOW_X 0x214 #define SC_WINDOW_Y 0x218 #define CW_LEFT 0x224 #define CW_TOP 0x228 #define CW_RIGHT 0x234 #define CW_BOT 0x238 #define COORD_0 0x300 #define COORD_0_X 0x304 #define COORD_0_Y 0x308 #define COORD_1 0x310 #define COORD_1_X 0x314 #define COORD_1_Y 0x318 #define COORD_2 0x320 #define COORD_2_X 0x324 #define COORD_2_Y 0x328 #define COORD_3 0x330 #define COORD_3_X 0x334 #define COORD_3_Y 0x338 #define X_INCR 0x400 #define Y_INCR 0x404 #define FG_COLOR 0x500 #define BG_COLOR 0x504 #define BS_COLOR 0x508 #define SRC_COL_M 0x510 #define DEST_COL_M 0x514 #define CMD_0 0x100 #define CMD_1 0x104 #define CMD_4 0x110 #define CMD_5 0x114 #define CMD_7 0x11c #define ROP 0x410 #define ALPHA 0x420 #define SRC_BA 0x730 #define DEST_BA 0x734 #define CMD_0_POINT 0x1 volatile unsigned int *l; const char *s3cXaaSymbols[] = { "XAACreateInfoRec", "XAADestroyInfoRec", "XAAInit", NULL }; Bool s3cXAAScreenInit(ScreenPtr pScreen); Bool s3cXAAModeInit(ScrnInfoPtr pScrn, DisplayModePtr mode); // ------------------------------------------------------------------------------------------------------- /* -------------------------------------------------------------------- */ /* prototypes */ static const OptionInfoRec * FBDevAvailableOptions(int chipid, int busid); static void FBDevIdentify(int flags); static Bool FBDevProbe(DriverPtr drv, int flags); #ifdef XSERVER_LIBPCIACCESS static Bool FBDevPciProbe(DriverPtr drv, int entity_num, struct pci_device *dev, intptr_t match_data); #endif static Bool FBDevPreInit(ScrnInfoPtr pScrn, int flags); static Bool FBDevScreenInit(int Index, ScreenPtr pScreen, int argc, char **argv); static Bool FBDevCloseScreen(int scrnIndex, ScreenPtr pScreen); static void * FBDevWindowLinear(ScreenPtr pScreen, CARD32 row, CARD32 offset, int mode, CARD32 *size, void *closure); static void FBDevPointerMoved(int index, int x, int y); static Bool FBDevDGAInit(ScrnInfoPtr pScrn, ScreenPtr pScreen); static Bool FBDevDriverFunc(ScrnInfoPtr pScrn, xorgDriverFuncOp op, pointer ptr); enum { FBDEV_ROTATE_NONE=0, FBDEV_ROTATE_CW=270, FBDEV_ROTATE_UD=180, FBDEV_ROTATE_CCW=90 }; /* -------------------------------------------------------------------- */ /* * This is intentionally screen-independent. It indicates the binding * choice made in the first PreInit. */ static int pix24bpp = 0; #define FBDEV_VERSION 4000 #define FBDEV_NAME "FBDEV" #define FBDEV_DRIVER_NAME "fbdev" #ifdef XSERVER_LIBPCIACCESS static const struct pci_id_match fbdev_device_match[] = { { PCI_MATCH_ANY, PCI_MATCH_ANY, PCI_MATCH_ANY, PCI_MATCH_ANY, 0x00030000, 0x00ffffff, 0 }, { 0, 0, 0 }, }; #endif _X_EXPORT DriverRec FBDEV = { FBDEV_VERSION, FBDEV_DRIVER_NAME, #if 0 "driver for linux framebuffer devices", #endif FBDevIdentify, FBDevProbe, FBDevAvailableOptions, NULL, 0, FBDevDriverFunc, #ifdef XSERVER_LIBPCIACCESS fbdev_device_match, FBDevPciProbe #endif }; /* Supported "chipsets" */ static SymTabRec FBDevChipsets[] = { { 0, "fbdev" }, #ifdef USE_AFB { 0, "afb" }, #endif {-1, NULL } }; /* Supported options */ typedef enum { OPTION_SHADOW_FB, OPTION_ROTATE, OPTION_FBDEV, OPTION_DEBUG } FBDevOpts; static const OptionInfoRec FBDevOptions[] = { { OPTION_SHADOW_FB, "ShadowFB", OPTV_BOOLEAN, {0}, FALSE }, { OPTION_ROTATE, "Rotate", OPTV_STRING, {0}, FALSE }, { OPTION_FBDEV, "fbdev", OPTV_STRING, {0}, FALSE }, { OPTION_DEBUG, "debug", OPTV_BOOLEAN, {0}, FALSE }, { -1, NULL, OPTV_NONE, {0}, FALSE } }; /* -------------------------------------------------------------------- */ static const char *afbSymbols[] = { "afbScreenInit", "afbCreateDefColormap", NULL }; static const char *fbSymbols[] = { "fbScreenInit", "fbPictureInit", NULL }; static const char *shadowSymbols[] = { "shadowAdd", "shadowInit", "shadowSetup", "shadowUpdatePacked", "shadowUpdatePackedWeak", "shadowUpdateRotatePacked", "shadowUpdateRotatePackedWeak", NULL }; static const char *fbdevHWSymbols[] = { "fbdevHWInit", "fbdevHWProbe", "fbdevHWSetVideoModes", "fbdevHWUseBuildinMode", "fbdevHWGetDepth", "fbdevHWGetLineLength", "fbdevHWGetName", "fbdevHWGetType", "fbdevHWGetVidmem", "fbdevHWLinearOffset", "fbdevHWLoadPalette", "fbdevHWMapVidmem", "fbdevHWUnmapVidmem", /* colormap */ "fbdevHWLoadPalette", "fbdevHWLoadPaletteWeak", /* ScrnInfo hooks */ "fbdevHWAdjustFrameWeak", "fbdevHWEnterVTWeak", "fbdevHWLeaveVTWeak", "fbdevHWModeInit", "fbdevHWRestore", "fbdevHWSave", "fbdevHWSaveScreen", "fbdevHWSaveScreenWeak", "fbdevHWSwitchModeWeak", "fbdevHWValidModeWeak", "fbdevHWDPMSSet", "fbdevHWDPMSSetWeak", NULL }; #ifdef XFree86LOADER MODULESETUPPROTO(FBDevSetup); static XF86ModuleVersionInfo FBDevVersRec = { "fbdev", MODULEVENDORSTRING, MODINFOSTRING1, MODINFOSTRING2, XORG_VERSION_CURRENT, PACKAGE_VERSION_MAJOR, PACKAGE_VERSION_MINOR, PACKAGE_VERSION_PATCHLEVEL, ABI_CLASS_VIDEODRV, ABI_VIDEODRV_VERSION, NULL, {0,0,0,0} }; _X_EXPORT XF86ModuleData fbdevModuleData = { &FBDevVersRec, FBDevSetup, NULL }; pointer FBDevSetup(pointer module, pointer opts, int *errmaj, int *errmin) { static Bool setupDone = FALSE; if (!setupDone) { setupDone = TRUE; xf86AddDriver(&FBDEV, module, HaveDriverFuncs); LoaderRefSymLists(afbSymbols, fbSymbols, shadowSymbols, fbdevHWSymbols, NULL); return (pointer)1; } else { if (errmaj) *errmaj = LDR_ONCEONLY; return NULL; } } #endif /* XFree86LOADER */ /* -------------------------------------------------------------------- */ /* our private data, and two functions to allocate/free this */ typedef struct { unsigned char* fbstart; unsigned char* fbmem; int fboff; int lineLength; int rotate; Bool shadowFB; void *shadow; CloseScreenProcPtr CloseScreen; CreateScreenResourcesProcPtr CreateScreenResources; void (*PointerMoved)(int index, int x, int y); EntityInfoPtr pEnt; /* DGA info */ DGAModePtr pDGAMode; int nDGAMode; OptionInfoPtr Options; XAAInfoRecPtr xaaInfo; int xaaFGColor; int xaaBGColor; int xaaRop; unsigned int *xaaColorExpb; int xaaColorExpp; int xaaColorExpw; unsigned char* xaaColorExpScanLine[1]; unsigned int xaaColorExpSize; /* size of current scan line in DWords */ } FBDevRec, *FBDevPtr; #define FBDevPTR(p) ((FBDevPtr)((p)->driverPrivate)) static Bool FBDevGetRec(ScrnInfoPtr pScrn) { if (pScrn->driverPrivate != NULL) return TRUE; pScrn->driverPrivate = xnfcalloc(sizeof(FBDevRec), 1); return TRUE; } static void FBDevFreeRec(ScrnInfoPtr pScrn) { if (pScrn->driverPrivate == NULL) return; xfree(pScrn->driverPrivate); pScrn->driverPrivate = NULL; } /* -------------------------------------------------------------------- */ static const OptionInfoRec * FBDevAvailableOptions(int chipid, int busid) { return FBDevOptions; } static void FBDevIdentify(int flags) { xf86PrintChipsets(FBDEV_NAME, "driver for framebuffer", FBDevChipsets); } #ifdef XSERVER_LIBPCIACCESS static Bool FBDevPciProbe(DriverPtr drv, int entity_num, struct pci_device *dev, intptr_t match_data) { ScrnInfoPtr pScrn = NULL; if (!xf86LoadDrvSubModule(drv, "fbdevhw")) return FALSE; xf86LoaderReqSymLists(fbdevHWSymbols, NULL); pScrn = xf86ConfigPciEntity(NULL, 0, entity_num, NULL, NULL, NULL, NULL, NULL, NULL); if (pScrn) { char *device; GDevPtr devSection = xf86GetDevFromEntity(pScrn->entityList[0], pScrn->entityInstanceList[0]); device = xf86FindOptionValue(devSection->options, "fbdev"); if (fbdevHWProbe(NULL, device, NULL)) { pScrn->driverVersion = FBDEV_VERSION; pScrn->driverName = FBDEV_DRIVER_NAME; pScrn->name = FBDEV_NAME; pScrn->Probe = FBDevProbe; pScrn->PreInit = FBDevPreInit; pScrn->ScreenInit = FBDevScreenInit; pScrn->SwitchMode = fbdevHWSwitchModeWeak(); pScrn->AdjustFrame = fbdevHWAdjustFrameWeak(); pScrn->EnterVT = fbdevHWEnterVTWeak(); pScrn->LeaveVT = fbdevHWLeaveVTWeak(); pScrn->ValidMode = fbdevHWValidModeWeak(); xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "claimed PCI slot %d@%d:%d:%d\n", dev->bus, dev->domain, dev->dev, dev->func); xf86DrvMsg(pScrn->scrnIndex, X_INFO, "using %s\n", device ? device : "default device"); } else { pScrn = NULL; } } return (pScrn != NULL); } #endif static Bool FBDevProbe(DriverPtr drv, int flags) { int i; ScrnInfoPtr pScrn; GDevPtr *devSections; int numDevSections; //< int bus,device,func; char *dev; Bool foundScreen = FALSE; TRACE("probe start"); /* For now, just bail out for PROBE_DETECT. */ if (flags & PROBE_DETECT) return FALSE; if ((numDevSections = xf86MatchDevice(FBDEV_DRIVER_NAME, &devSections)) <= 0) return FALSE; if (!xf86LoadDrvSubModule(drv, "fbdevhw")) return FALSE; xf86LoaderReqSymLists(fbdevHWSymbols, NULL); for (i = 0; i < numDevSections; i++) { Bool isIsa = FALSE; Bool isPci = FALSE; dev = xf86FindOptionValue(devSections[i]->options,"fbdev"); if (devSections[i]->busID) { #ifndef XSERVER_LIBPCIACCESS if (xf86ParsePciBusString(devSections[i]->busID,&bus,&device, &func)) { if (!xf86CheckPciSlot(bus,device,func)) continue; isPci = TRUE; } else #endif #ifdef HAVE_ISA if (xf86ParseIsaBusString(devSections[i]->busID)) isIsa = TRUE; else #endif 0; } if (fbdevHWProbe(NULL,dev,NULL)) { pScrn = NULL; if (isPci) { #ifndef XSERVER_LIBPCIACCESS /* XXX what about when there's no busID set? */ int entity; entity = xf86ClaimPciSlot(bus,device,func,drv, 0,devSections[i], TRUE); pScrn = xf86ConfigPciEntity(pScrn,0,entity, NULL,RES_SHARED_VGA, NULL,NULL,NULL,NULL); /* xf86DrvMsg() can't be called without setting these */ pScrn->driverName = FBDEV_DRIVER_NAME; pScrn->name = FBDEV_NAME; xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "claimed PCI slot %d:%d:%d\n",bus,device,func); #endif } else if (isIsa) { #ifdef HAVE_ISA int entity; entity = xf86ClaimIsaSlot(drv, 0, devSections[i], TRUE); pScrn = xf86ConfigIsaEntity(pScrn,0,entity, NULL,RES_SHARED_VGA, NULL,NULL,NULL,NULL); #endif } else { int entity; entity = xf86ClaimFbSlot(drv, 0, devSections[i], TRUE); pScrn = xf86ConfigFbEntity(pScrn,0,entity, NULL,NULL,NULL,NULL); } if (pScrn) { foundScreen = TRUE; pScrn->driverVersion = FBDEV_VERSION; pScrn->driverName = FBDEV_DRIVER_NAME; pScrn->name = FBDEV_NAME; pScrn->Probe = FBDevProbe; pScrn->PreInit = FBDevPreInit; pScrn->ScreenInit = FBDevScreenInit; pScrn->SwitchMode = fbdevHWSwitchModeWeak(); pScrn->AdjustFrame = fbdevHWAdjustFrameWeak(); pScrn->EnterVT = fbdevHWEnterVTWeak(); pScrn->LeaveVT = fbdevHWLeaveVTWeak(); pScrn->ValidMode = fbdevHWValidModeWeak(); xf86DrvMsg(pScrn->scrnIndex, X_INFO, "using %s\n", dev ? dev : "default device"); } } } xfree(devSections); TRACE("probe done"); return foundScreen; } static Bool FBDevPreInit(ScrnInfoPtr pScrn, int flags) { FBDevPtr fPtr; int default_depth, fbbpp; const char *mod = NULL, *s; const char **syms = NULL; int type; if (flags & PROBE_DETECT) return FALSE; TRACE_ENTER("PreInit"); /* Check the number of entities, and fail if it isn't one. */ if (pScrn->numEntities != 1) return FALSE; pScrn->monitor = pScrn->confScreen->monitor; FBDevGetRec(pScrn); fPtr = FBDevPTR(pScrn); fPtr->pEnt = xf86GetEntityInfo(pScrn->entityList[0]); pScrn->racMemFlags = RAC_FB | RAC_COLORMAP | RAC_CURSOR | RAC_VIEWPORT; /* XXX Is this right? Can probably remove RAC_FB */ pScrn->racIoFlags = RAC_FB | RAC_COLORMAP | RAC_CURSOR | RAC_VIEWPORT; if (fPtr->pEnt->location.type == BUS_PCI && xf86RegisterResources(fPtr->pEnt->index,NULL,ResExclusive)) { xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "xf86RegisterResources() found resource conflicts\n"); return FALSE; } /* open device */ if (!fbdevHWInit(pScrn,NULL,xf86FindOptionValue(fPtr->pEnt->device->options,"fbdev"))) return FALSE; default_depth = fbdevHWGetDepth(pScrn,&fbbpp); if (!xf86SetDepthBpp(pScrn, default_depth, default_depth, fbbpp, Support24bppFb | Support32bppFb | SupportConvert32to24 | SupportConvert24to32)) return FALSE; xf86PrintDepthBpp(pScrn); /* Get the depth24 pixmap format */ if (pScrn->depth == 24 && pix24bpp == 0) pix24bpp = xf86GetBppFromDepth(pScrn, 24); /* color weight */ if (pScrn->depth > 8) { rgb zeros = { 0, 0, 0 }; if (!xf86SetWeight(pScrn, zeros, zeros)) return FALSE; } /* visual init */ if (!xf86SetDefaultVisual(pScrn, -1)) return FALSE; /* We don't currently support DirectColor at > 8bpp */ if (pScrn->depth > 8 && pScrn->defaultVisual != TrueColor) { xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "requested default visual" " (%s) is not supported at depth %d\n", xf86GetVisualName(pScrn->defaultVisual), pScrn->depth); return FALSE; } { Gamma zeros = {0.0, 0.0, 0.0}; if (!xf86SetGamma(pScrn,zeros)) { return FALSE; } } pScrn->progClock = TRUE; pScrn->rgbBits = 8; pScrn->chipset = "fbdev"; pScrn->videoRam = fbdevHWGetVidmem(pScrn); xf86DrvMsg(pScrn->scrnIndex, X_INFO, "hardware: %s (video memory:" " %dkB)\n", fbdevHWGetName(pScrn), pScrn->videoRam/1024); /* handle options */ xf86CollectOptions(pScrn, NULL); if (!(fPtr->Options = xalloc(sizeof(FBDevOptions)))) return FALSE; memcpy(fPtr->Options, FBDevOptions, sizeof(FBDevOptions)); xf86ProcessOptions(pScrn->scrnIndex, fPtr->pEnt->device->options, fPtr->Options); /* use shadow framebuffer by default */ fPtr->shadowFB = xf86ReturnOptValBool(fPtr->Options, OPTION_SHADOW_FB, FALSE); debug = xf86ReturnOptValBool(fPtr->Options, OPTION_DEBUG, FALSE); debug = 1; /* rotation */ fPtr->rotate = FBDEV_ROTATE_NONE; if ((s = xf86GetOptValString(fPtr->Options, OPTION_ROTATE))) { if(!xf86NameCmp(s, "CW")) { fPtr->shadowFB = TRUE; fPtr->rotate = FBDEV_ROTATE_CW; xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "rotating screen clockwise\n"); } else if(!xf86NameCmp(s, "CCW")) { fPtr->shadowFB = TRUE; fPtr->rotate = FBDEV_ROTATE_CCW; xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "rotating screen counter-clockwise\n"); } else if(!xf86NameCmp(s, "UD")) { fPtr->shadowFB = TRUE; fPtr->rotate = FBDEV_ROTATE_UD; xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "rotating screen upside-down\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\", \"CCW\" and \"UD\"\n"); } } /* select video modes */ xf86DrvMsg(pScrn->scrnIndex, X_INFO, "checking modes against framebuffer device...\n"); fbdevHWSetVideoModes(pScrn); xf86DrvMsg(pScrn->scrnIndex, X_INFO, "checking modes against monitor...\n"); { DisplayModePtr mode, first = mode = pScrn->modes; if (mode != NULL) do { mode->status = xf86CheckModeForMonitor(mode, pScrn->monitor); mode = mode->next; } while (mode != NULL && mode != first); xf86PruneDriverModes(pScrn); } if (NULL == pScrn->modes) fbdevHWUseBuildinMode(pScrn); pScrn->currentMode = pScrn->modes; /* First approximation, may be refined in ScreenInit */ pScrn->displayWidth = pScrn->virtualX; xf86PrintModes(pScrn); /* Set display resolution */ xf86SetDpi(pScrn, 0, 0); /* Load bpp-specific modules */ switch ((type = fbdevHWGetType(pScrn))) { case FBDEVHW_PLANES: mod = "afb"; syms = afbSymbols; break; case FBDEVHW_PACKED_PIXELS: switch (pScrn->bitsPerPixel) { case 8: case 16: case 24: case 32: mod = "fb"; syms = fbSymbols; break; default: xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "unsupported number of bits per pixel: %d", pScrn->bitsPerPixel); return FALSE; } break; case FBDEVHW_INTERLEAVED_PLANES: /* Not supported yet, don't know what to do with this */ xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "interleaved planes are not yet supported by the " "fbdev driver\n"); return FALSE; case FBDEVHW_TEXT: /* This should never happen ... * we should check for this much much earlier ... */ xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "text mode is not supported by the fbdev driver\n"); return FALSE; case FBDEVHW_VGA_PLANES: /* Not supported yet */ xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "EGA/VGA planes are not yet supported by the fbdev " "driver\n"); return FALSE; default: xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "unrecognised fbdev hardware type (%d)\n", type); return FALSE; } if (mod && xf86LoadSubModule(pScrn, mod) == NULL) { FBDevFreeRec(pScrn); return FALSE; } if (mod && syms) { xf86LoaderReqSymLists(syms, NULL); } xf86LoadSubModule(pScrn, "xaa"); xf86LoaderReqSymLists(s3cXaaSymbols, NULL); /* Load shadow if needed */ if (fPtr->shadowFB) { xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "using shadow" " framebuffer\n"); if (!xf86LoadSubModule(pScrn, "shadow")) { FBDevFreeRec(pScrn); return FALSE; } xf86LoaderReqSymLists(shadowSymbols, NULL); } TRACE_EXIT("PreInit"); return TRUE; } static Bool FBDevCreateScreenResources(ScreenPtr pScreen) { PixmapPtr pPixmap; ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; FBDevPtr fPtr = FBDevPTR(pScrn); Bool ret; pScreen->CreateScreenResources = fPtr->CreateScreenResources; ret = pScreen->CreateScreenResources(pScreen); pScreen->CreateScreenResources = FBDevCreateScreenResources; if (!ret) return FALSE; pPixmap = pScreen->GetScreenPixmap(pScreen); if (!shadowAdd(pScreen, pPixmap, fPtr->rotate ? shadowUpdateRotatePackedWeak() : shadowUpdatePackedWeak(), FBDevWindowLinear, fPtr->rotate, NULL)) { return FALSE; } return TRUE; } static Bool FBDevShadowInit(ScreenPtr pScreen) { ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; FBDevPtr fPtr = FBDevPTR(pScrn); if (!shadowSetup(pScreen)) { return FALSE; } fPtr->CreateScreenResources = pScreen->CreateScreenResources; pScreen->CreateScreenResources = FBDevCreateScreenResources; return TRUE; } static Bool FBDevScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv) { ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; FBDevPtr fPtr = FBDevPTR(pScrn); VisualPtr visual; int init_picture = 0; int ret, flags; int type; TRACE_ENTER("FBDevScreenInit"); #if DEBUG ErrorF("\tbitsPerPixel=%d, depth=%d, defaultVisual=%s\n" "\tmask: %x,%x,%x, offset: %d,%d,%d\n", pScrn->bitsPerPixel, pScrn->depth, xf86GetVisualName(pScrn->defaultVisual), pScrn->mask.red,pScrn->mask.green,pScrn->mask.blue, pScrn->offset.red,pScrn->offset.green,pScrn->offset.blue); #endif if (NULL == (fPtr->fbmem = fbdevHWMapVidmem(pScrn))) { xf86DrvMsg(scrnIndex,X_ERROR,"mapping of video memory" " failed\n"); return FALSE; } fPtr->fboff = fbdevHWLinearOffset(pScrn); fbdevHWSave(pScrn); if (!fbdevHWModeInit(pScrn, pScrn->currentMode)) { xf86DrvMsg(scrnIndex,X_ERROR,"mode initialization failed\n"); return FALSE; } fbdevHWSaveScreen(pScreen, SCREEN_SAVER_ON); fbdevHWAdjustFrame(scrnIndex,0,0,0); /* mi layer */ miClearVisualTypes(); if (pScrn->bitsPerPixel > 8) { if (!miSetVisualTypes(pScrn->depth, TrueColorMask, pScrn->rgbBits, TrueColor)) { xf86DrvMsg(scrnIndex,X_ERROR,"visual type setup failed" " for %d bits per pixel [1]\n", pScrn->bitsPerPixel); return FALSE; } } else { if (!miSetVisualTypes(pScrn->depth, miGetDefaultVisualMask(pScrn->depth), pScrn->rgbBits, pScrn->defaultVisual)) { xf86DrvMsg(scrnIndex,X_ERROR,"visual type setup failed" " for %d bits per pixel [2]\n", pScrn->bitsPerPixel); return FALSE; } } if (!miSetPixmapDepths()) { xf86DrvMsg(scrnIndex,X_ERROR,"pixmap depth setup failed\n"); return FALSE; } if(fPtr->rotate==FBDEV_ROTATE_CW || fPtr->rotate==FBDEV_ROTATE_CCW) { int tmp = pScrn->virtualX; pScrn->virtualX = pScrn->displayWidth = pScrn->virtualY; pScrn->virtualY = tmp; } else if (!fPtr->shadowFB) { /* FIXME: this doesn't work for all cases, e.g. when each scanline has a padding which is independent from the depth (controlfb) */ pScrn->displayWidth = fbdevHWGetLineLength(pScrn) / (pScrn->bitsPerPixel / 8); if (pScrn->displayWidth != pScrn->virtualX) { xf86DrvMsg(scrnIndex, X_INFO, "Pitch updated to %d after ModeInit\n", pScrn->displayWidth); } } if(fPtr->rotate && !fPtr->PointerMoved) { fPtr->PointerMoved = pScrn->PointerMoved; pScrn->PointerMoved = FBDevPointerMoved; } fPtr->fbstart = fPtr->fbmem + fPtr->fboff; if (fPtr->shadowFB) { fPtr->shadow = xcalloc(1, pScrn->virtualX * pScrn->virtualY * pScrn->bitsPerPixel); if (!fPtr->shadow) { xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Failed to allocate shadow framebuffer\n"); return FALSE; } } switch ((type = fbdevHWGetType(pScrn))) { #ifdef USE_AFB case FBDEVHW_PLANES: if (fPtr->rotate) { xf86DrvMsg(scrnIndex, X_ERROR, "internal error: rotate not supported for afb\n"); ret = FALSE; break; } if (fPtr->shadowFB) { xf86DrvMsg(scrnIndex, X_ERROR, "internal error: shadow framebuffer not supported" " for afb\n"); ret = FALSE; break; } ret = afbScreenInit (pScreen, fPtr->fbstart, pScrn->virtualX, pScrn->virtualY, pScrn->xDpi, pScrn->yDpi, pScrn->displayWidth); break; #endif case FBDEVHW_PACKED_PIXELS: switch (pScrn->bitsPerPixel) { case 8: case 16: case 24: case 32: ret = fbScreenInit(pScreen, fPtr->shadowFB ? fPtr->shadow : fPtr->fbstart, pScrn->virtualX, pScrn->virtualY, pScrn->xDpi, pScrn->yDpi, pScrn->displayWidth, pScrn->bitsPerPixel); init_picture = 1; break; default: xf86DrvMsg(scrnIndex, X_ERROR, "internal error: invalid number of bits per" " pixel (%d) encountered in" " FBDevScreenInit()\n", pScrn->bitsPerPixel); ret = FALSE; break; } break; case FBDEVHW_INTERLEAVED_PLANES: /* This should never happen ... * we should check for this much much earlier ... */ xf86DrvMsg(scrnIndex, X_ERROR, "internal error: interleaved planes are not yet " "supported by the fbdev driver\n"); ret = FALSE; break; case FBDEVHW_TEXT: /* This should never happen ... * we should check for this much much earlier ... */ xf86DrvMsg(scrnIndex, X_ERROR, "internal error: text mode is not supported by the " "fbdev driver\n"); ret = FALSE; break; case FBDEVHW_VGA_PLANES: /* Not supported yet */ xf86DrvMsg(scrnIndex, X_ERROR, "internal error: EGA/VGA Planes are not yet " "supported by the fbdev driver\n"); ret = FALSE; break; default: xf86DrvMsg(scrnIndex, X_ERROR, "internal error: unrecognised hardware type (%d) " "encountered in FBDevScreenInit()\n", type); ret = FALSE; break; } if (!ret) return FALSE; if (pScrn->bitsPerPixel > 8) { /* Fixup RGB ordering */ visual = pScreen->visuals + pScreen->numVisuals; while (--visual >= pScreen->visuals) { if ((visual->class | DynamicClass) == DirectColor) { visual->offsetRed = pScrn->offset.red; visual->offsetGreen = pScrn->offset.green; visual->offsetBlue = pScrn->offset.blue; visual->redMask = pScrn->mask.red; visual->greenMask = pScrn->mask.green; visual->blueMask = pScrn->mask.blue; } } } /* must be after RGB ordering fixed */ if (init_picture && !fbPictureInit(pScreen, NULL, 0)) xf86DrvMsg(pScrn->scrnIndex, X_WARNING, "Render extension initialisation failed\n"); if (fPtr->shadowFB && !FBDevShadowInit(pScreen)) { xf86DrvMsg(scrnIndex, X_ERROR, "shadow framebuffer initialization failed\n"); return FALSE; } if (!fPtr->rotate) FBDevDGAInit(pScrn, pScreen); else { xf86DrvMsg(scrnIndex, X_INFO, "display rotated; disabling DGA\n"); xf86DrvMsg(scrnIndex, X_INFO, "using driver rotation; disabling " "XRandR\n"); xf86DisableRandR(); if (pScrn->bitsPerPixel == 24) xf86DrvMsg(scrnIndex, X_WARNING, "rotation might be broken at 24 " "bits per pixel\n"); } xf86SetBlackWhitePixels(pScreen); miInitializeBackingStore(pScreen); xf86SetBackingStore(pScreen); /* software cursor */ miDCInitialize(pScreen, xf86GetPointerScreenFuncs()); /* colormap */ switch ((type = fbdevHWGetType(pScrn))) { /* XXX It would be simpler to use miCreateDefColormap() in all cases. */ #ifdef USE_AFB case FBDEVHW_PLANES: if (!afbCreateDefColormap(pScreen)) { xf86DrvMsg(scrnIndex, X_ERROR, "internal error: afbCreateDefColormap " "failed in FBDevScreenInit()\n"); return FALSE; } break; #endif case FBDEVHW_PACKED_PIXELS: if (!miCreateDefColormap(pScreen)) { xf86DrvMsg(scrnIndex, X_ERROR, "internal error: miCreateDefColormap failed " "in FBDevScreenInit()\n"); return FALSE; } break; case FBDEVHW_INTERLEAVED_PLANES: xf86DrvMsg(scrnIndex, X_ERROR, "internal error: interleaved planes are not yet " "supported by the fbdev driver\n"); return FALSE; case FBDEVHW_TEXT: xf86DrvMsg(scrnIndex, X_ERROR, "internal error: text mode is not supported by " "the fbdev driver\n"); return FALSE; case FBDEVHW_VGA_PLANES: xf86DrvMsg(scrnIndex, X_ERROR, "internal error: EGA/VGA planes are not yet " "supported by the fbdev driver\n"); return FALSE; default: xf86DrvMsg(scrnIndex, X_ERROR, "internal error: unrecognised fbdev hardware type " "(%d) encountered in FBDevScreenInit()\n", type); return FALSE; } flags = CMAP_PALETTED_TRUECOLOR; if(!xf86HandleColormaps(pScreen, 256, 8, fbdevHWLoadPaletteWeak(), NULL, flags)) return FALSE; xf86DPMSInit(pScreen, fbdevHWDPMSSetWeak(), 0); pScreen->SaveScreen = fbdevHWSaveScreenWeak(); /* Wrap the current CloseScreen function */ fPtr->CloseScreen = pScreen->CloseScreen; pScreen->CloseScreen = FBDevCloseScreen; { XF86VideoAdaptorPtr *ptr; int n = xf86XVListGenericAdaptors(pScrn,&ptr); if (n) { xf86XVScreenInit(pScreen,ptr,n); } } s3cXAAScreenInit(pScreen); s3cXAAModeInit(pScrn, pScrn->currentMode); TRACE_EXIT("FBDevScreenInit"); return TRUE; } static Bool FBDevCloseScreen(int scrnIndex, ScreenPtr pScreen) { ScrnInfoPtr pScrn = xf86Screens[scrnIndex]; FBDevPtr fPtr = FBDevPTR(pScrn); fbdevHWRestore(pScrn); fbdevHWUnmapVidmem(pScrn); if (fPtr->shadow) { xfree(fPtr->shadow); fPtr->shadow = NULL; } if (fPtr->pDGAMode) { xfree(fPtr->pDGAMode); fPtr->pDGAMode = NULL; fPtr->nDGAMode = 0; } pScrn->vtSema = FALSE; pScreen->CreateScreenResources = fPtr->CreateScreenResources; pScreen->CloseScreen = fPtr->CloseScreen; return (*pScreen->CloseScreen)(scrnIndex, pScreen); } /*********************************************************************** * Shadow stuff ***********************************************************************/ static void * FBDevWindowLinear(ScreenPtr pScreen, CARD32 row, CARD32 offset, int mode, CARD32 *size, void *closure) { ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; FBDevPtr fPtr = FBDevPTR(pScrn); if (!pScrn->vtSema) return NULL; if (fPtr->lineLength) *size = fPtr->lineLength; else *size = fPtr->lineLength = fbdevHWGetLineLength(pScrn); return ((CARD8 *)fPtr->fbstart + row * fPtr->lineLength + offset); } static void FBDevPointerMoved(int index, int x, int y) { ScrnInfoPtr pScrn = xf86Screens[index]; FBDevPtr fPtr = FBDevPTR(pScrn); int newX, newY; switch (fPtr->rotate) { case FBDEV_ROTATE_CW: /* 90 degrees CW rotation. */ newX = pScrn->pScreen->height - y - 1; newY = x; break; case FBDEV_ROTATE_CCW: /* 90 degrees CCW rotation. */ newX = y; newY = pScrn->pScreen->width - x - 1; break; case FBDEV_ROTATE_UD: /* 180 degrees UD rotation. */ newX = pScrn->pScreen->width - x - 1; newY = pScrn->pScreen->height - y - 1; break; default: /* No rotation. */ newX = x; newY = y; break; } /* Pass adjusted pointer coordinates to wrapped PointerMoved function. */ (*fPtr->PointerMoved)(index, newX, newY); } /*********************************************************************** * DGA stuff ***********************************************************************/ static Bool FBDevDGAOpenFramebuffer(ScrnInfoPtr pScrn, char **DeviceName, unsigned char **ApertureBase, int *ApertureSize, int *ApertureOffset, int *flags); static Bool FBDevDGASetMode(ScrnInfoPtr pScrn, DGAModePtr pDGAMode); static void FBDevDGASetViewport(ScrnInfoPtr pScrn, int x, int y, int flags); static Bool FBDevDGAOpenFramebuffer(ScrnInfoPtr pScrn, char **DeviceName, unsigned char **ApertureBase, int *ApertureSize, int *ApertureOffset, int *flags) { *DeviceName = NULL; /* No special device */ *ApertureBase = (unsigned char *)(pScrn->memPhysBase); *ApertureSize = pScrn->videoRam; *ApertureOffset = pScrn->fbOffset; *flags = 0; return TRUE; } static Bool FBDevDGASetMode(ScrnInfoPtr pScrn, DGAModePtr pDGAMode) { DisplayModePtr pMode; int scrnIdx = pScrn->pScreen->myNum; int frameX0, frameY0; if (pDGAMode) { pMode = pDGAMode->mode; frameX0 = frameY0 = 0; } else { if (!(pMode = pScrn->currentMode)) return TRUE; frameX0 = pScrn->frameX0; frameY0 = pScrn->frameY0; } if (!(*pScrn->SwitchMode)(scrnIdx, pMode, 0)) return FALSE; (*pScrn->AdjustFrame)(scrnIdx, frameX0, frameY0, 0); return TRUE; } static void FBDevDGASetViewport(ScrnInfoPtr pScrn, int x, int y, int flags) { (*pScrn->AdjustFrame)(pScrn->pScreen->myNum, x, y, flags); } static int FBDevDGAGetViewport(ScrnInfoPtr pScrn) { return (0); } static DGAFunctionRec FBDevDGAFunctions = { FBDevDGAOpenFramebuffer, NULL, /* CloseFramebuffer */ FBDevDGASetMode, FBDevDGASetViewport, FBDevDGAGetViewport, NULL, /* Sync */ NULL, /* FillRect */ NULL, /* BlitRect */ NULL, /* BlitTransRect */ }; static void FBDevDGAAddModes(ScrnInfoPtr pScrn) { FBDevPtr fPtr = FBDevPTR(pScrn); DisplayModePtr pMode = pScrn->modes; DGAModePtr pDGAMode; do { pDGAMode = xrealloc(fPtr->pDGAMode, (fPtr->nDGAMode + 1) * sizeof(DGAModeRec)); if (!pDGAMode) break; fPtr->pDGAMode = pDGAMode; pDGAMode += fPtr->nDGAMode; (void)memset(pDGAMode, 0, sizeof(DGAModeRec)); ++fPtr->nDGAMode; pDGAMode->mode = pMode; pDGAMode->flags = DGA_CONCURRENT_ACCESS | DGA_PIXMAP_AVAILABLE; pDGAMode->byteOrder = pScrn->imageByteOrder; pDGAMode->depth = pScrn->depth; pDGAMode->bitsPerPixel = pScrn->bitsPerPixel; pDGAMode->red_mask = pScrn->mask.red; pDGAMode->green_mask = pScrn->mask.green; pDGAMode->blue_mask = pScrn->mask.blue; pDGAMode->visualClass = pScrn->bitsPerPixel > 8 ? TrueColor : PseudoColor; pDGAMode->xViewportStep = 1; pDGAMode->yViewportStep = 1; pDGAMode->viewportWidth = pMode->HDisplay; pDGAMode->viewportHeight = pMode->VDisplay; if (fPtr->lineLength) pDGAMode->bytesPerScanline = fPtr->lineLength; else pDGAMode->bytesPerScanline = fPtr->lineLength = fbdevHWGetLineLength(pScrn); pDGAMode->imageWidth = pMode->HDisplay; pDGAMode->imageHeight = pMode->VDisplay; pDGAMode->pixmapWidth = pDGAMode->imageWidth; pDGAMode->pixmapHeight = pDGAMode->imageHeight; pDGAMode->maxViewportX = pScrn->virtualX - pDGAMode->viewportWidth; pDGAMode->maxViewportY = pScrn->virtualY - pDGAMode->viewportHeight; pDGAMode->address = fPtr->fbstart; pMode = pMode->next; } while (pMode != pScrn->modes); } static Bool FBDevDGAInit(ScrnInfoPtr pScrn, ScreenPtr pScreen) { FBDevPtr fPtr = FBDevPTR(pScrn); if (pScrn->depth < 8) return FALSE; if (!fPtr->nDGAMode) FBDevDGAAddModes(pScrn); return (DGAInit(pScreen, &FBDevDGAFunctions, fPtr->pDGAMode, fPtr->nDGAMode)); } static Bool FBDevDriverFunc(ScrnInfoPtr pScrn, xorgDriverFuncOp op, pointer ptr) { xorgHWFlags *flag; switch (op) { case GET_REQUIRED_HW_INTERFACES: flag = (CARD32*)ptr; (*flag) = 0; return TRUE; default: return FALSE; } } Bool s3cXAAModeInit(ScrnInfoPtr pScrn, DisplayModePtr mode) { FBDevPtr pFBDEV = FBDevPTR(pScrn); /* * Alloc a sufficiently large buffer for XAA to render scanlines * for a color expand into. */ #if 1 if (1) { /* * This formula came straight from the XAA.HOWTO doc. The +62 is * there because we potentially have 31 extra bits off to the left, * since we claim LEFT_EDGE_CLIPPING support. */ int scanLineSize = ((pScrn->virtualX + 62)/32) * 4; if (pFBDEV->xaaColorExpScanLine[0]) { xfree(pFBDEV->xaaColorExpScanLine[0]); } pFBDEV->xaaColorExpScanLine[0] = xalloc(scanLineSize); return pFBDEV->xaaColorExpScanLine[0] != NULL; } #endif return TRUE; } static void s3cSetupForSolidFill(ScrnInfoPtr pScrn, int color, int rop, unsigned int planemask) { FBDevPtr pFBDEV = FBDevPTR(pScrn); pFBDEV->xaaFGColor = color; pFBDEV->xaaRop = rop; __clear_cache(pFBDEV->fbmem,pFBDEV->fbmem+1280000); } static void s3cSubsequentSolidFillRect(ScrnInfoPtr pScrn, int x, int y, int w, int h) { FBDevPtr pFBDEV = FBDevPTR(pScrn); TRACE_ENTER("SolidFill"); if (pFBDEV->xaaRop != GXcopy) { /* * We'll never get here if SVGA_CAP_RASTER_OP isn't set, since * we tell XAA we are GXCOPY_ONLY. */ } else { int x2,y2; x2=x+w-1; y2=y+h-1; if(debug)ErrorF("fbdev SolidFill %d %d %d %d %x\n", x, y, w, h, pFBDEV->xaaFGColor); while(l[4]&1); l[COORD_0>>2]=x+(y<<16); l[COORD_1>>2]=x2+(y2<<16); l[COORD_2>>2]=x+(y<<16); l[COORD_3>>2]=x2+(y2<<16); l[FG_COLOR>>2]=pFBDEV->xaaFGColor; l[ROP>>2] = 0xaa|(1<<13); l[CMD_1>>2] = 1; } } static void s3cSetupForScreenToScreenCopy(ScrnInfoPtr pScrn, int xdir, int ydir, int rop, unsigned int planemask, int trans_color) { int r; r=XAAGetCopyROP(rop); if(debug)ErrorF("fbdev Prepare S2SCopy %d %d %d %02x %i %i\n", xdir, ydir, rop, r, planemask, trans_color); FBDevPtr pFBDEV = FBDevPTR(pScrn); r=XAAGetCopyROP(rop); pFBDEV->xaaRop = rop; __clear_cache(pFBDEV->fbmem,pFBDEV->fbmem+1280000); } static void s3cSubsequentScreenToScreenCopy(ScrnInfoPtr pScrn, int x1, int y1, int x2, int y2, int w, int h) { FBDevPtr pFBDEV = FBDevPTR(pScrn); // int i,j; TRACE_ENTER("S2SCopy"); if (pFBDEV->xaaRop != GXcopy) { /* * We'll never get here if SVGA_CAP_RASTER_OP isn't set, since * we tell XAA we are GXCOPY_ONLY. */ if(debug)ErrorF("fbdev S2SCopy no-gxcopy %d %d %d %d %d %d \n", x1, y1, x2, y2, w, h); } else { int x3,y3,x4,y4; x3=x1+w-1; y3=y1+h-1; x4=x2+w-1; y4=y2+h-1; if(debug)ErrorF("fbdev S2SCopy %d %d %d %d %d %d \n", x1, y1, x2, y2, w, h); #if 0 ErrorF("before: S="); for(j=0;j<4800;j+=1600) { for(i=0;i<16;i++) ErrorF("%02x ", pFBDEV->fbmem[x1*2+y1*1600+i+j]); ErrorF(" D="); for(i=0;i<16;i++) ErrorF("%02x ", pFBDEV->fbmem[x2*2+y2*1600+i+j]); ErrorF("\n"); } #endif while(l[4]&1); l[COORD_0>>2]=x1+(y1<<16); l[COORD_1>>2]=x3+(y3<<16); l[COORD_2>>2]=x2+(y2<<16); l[COORD_3>>2]=x4+(y4<<16); l[ROP>>2] = (1<<13) | 0xf0; l[CMD_1>>2] = 1; #if 0 ErrorF("STAT0=%04x\n", l[4]); usleep(1); ErrorF("STAT1=%04x\n", l[4]); while(!(l[4]&0x200)); ErrorF("STAT2=%04x\n", l[4]); for(j=0;j<4800;j+=1600) { ErrorF("after: S="); for(i=0;i<16;i++) ErrorF("%02x ", pFBDEV->fbmem[x1*2+y1*1600+i+j]); ErrorF(" D="); for(i=0;i<16;i++) ErrorF("%02x ", pFBDEV->fbmem[x2*2+y2*1600+i+j]); ErrorF("\n"); } #endif } } int jjj; static void s3cXAASync(ScrnInfoPtr pScrn) { FBDevPtr pFBDEV = FBDevPTR(pScrn); if(debug)ErrorF("XAASync %d\n", jjj++); __clear_cache(pFBDEV->fbmem,pFBDEV->fbmem+1280000); while(!(l[4]&0x200)); } static void s3cSetupForScanlineCPUToScreenColorExpandFill( ScrnInfoPtr pScrn, int fg, int bg, int rop, unsigned int planemask ) { FBDevPtr pFBDEV = FBDevPTR(pScrn); pFBDEV->xaaFGColor = fg; pFBDEV->xaaBGColor = bg; if(debug)ErrorF("CPU2S-setup %04x %04x\n", fg, bg); } static int firstc2sce; static void s3cSubsequentScanlineCPUToScreenColorExpandFill( ScrnInfoPtr pScrn, int x, int y, int w, int h, int skipleft ) { FBDevPtr pFBDEV = FBDevPTR(pScrn); int x2,y2,r; x2=x+w-1; y2=y+h-1; while(l[4]&1); l[COORD_0>>2]=x+(y<<16); l[COORD_1>>2]=x2+(y2<<16); l[FG_COLOR>>2]=pFBDEV->xaaFGColor; l[BG_COLOR>>2]=pFBDEV->xaaBGColor; r= (pFBDEV->xaaBGColor==-1) ? 0x200:0; l[ROP>>2]=r | 0xf0; firstc2sce=h; pFBDEV->xaaColorExpp=0; pFBDEV->xaaColorExpw=w; bzero(pFBDEV->xaaColorExpb, (w*h+7)/8); if(debug)ErrorF("CPU2S-Expand %d %d %d %d %d\n", x, y, w, h, r); } static void s3cSubsequentColorExpandScanline( ScrnInfoPtr pScrn, int bufno ){ FBDevPtr pFBDEV = FBDevPTR(pScrn); int a,b,c,e; unsigned int d; int w1,w; w1=pFBDEV->xaaColorExpw; e=0; while(w1) { if(w1<=32) { w=w1; } else { w=32; } w1-=w; a=pFBDEV->xaaColorExpp>>5; b=32-(pFBDEV->xaaColorExpp&0x1f); c=-(1<<(32-w)); d=be32toh(*(unsigned int *)(pFBDEV->xaaColorExpScanLine[0]+e)) & c; e+=4; if(b>=w) { pFBDEV->xaaColorExpb[a] |= d>>(pFBDEV->xaaColorExpp&0x1f); } else { pFBDEV->xaaColorExpb[a] |= d>>(pFBDEV->xaaColorExpp&0x1f); pFBDEV->xaaColorExpb[a+1] = d << b; } pFBDEV->xaaColorExpp+=w; } if (!(--firstc2sce)) { l[CMD_7>>2] = l[DEST_BA>>2]+COLEXPBUF; } } static void s3cSetupForScreenToScreenColorExpandFill (ScrnInfoPtr pScrn, int fg, int bg, int rop, unsigned int planemask) { FBDevPtr pFBDEV = FBDevPTR(pScrn); pFBDEV->xaaFGColor = fg; pFBDEV->xaaBGColor = bg; if(debug)ErrorF("S2SE-setup %04x %04x\n", fg, bg); } static void s3cSubsequentScreenToScreenColorExpandFill( ScrnInfoPtr pScrn, int x, int y, int w, int h, int srcx, int srcy, int offset ) { } static void s3cSetupForSolidLine(ScrnInfoPtr pScrn, int color, int rop, unsigned int planemask) { FBDevPtr pFBDEV = FBDevPTR(pScrn); pFBDEV->xaaFGColor = color; if(debug)ErrorF("line-setup %04x\n", color); } static void s3cSubsequentSolidTwoPointLine(ScrnInfoPtr pScrn, int x1, int y1, int x2, int y2, int flags) { int o = (flags&OMIT_LAST) ? (1<<9):0; FBDevPtr pFBDEV = FBDevPTR(pScrn); while(l[4]&1); l[FG_COLOR>>2] = pFBDEV->xaaFGColor; if((x1==x2)&&(y1==y2)) { l[COORD_0>>2] = x1+(x2<<16); l[CMD_0>>2] = 1; return; } if(abs(x1-x2)>abs(y1-y2)) { int dy; dy=(y2-y1)*(1<<11)/(x2-x1); l[COORD_0>>2]=x1+(y1<<16); l[COORD_2>>2]=x2+(y2<<16); l[Y_INCR>>2] = dy & 0x7ff; l[CMD_0>>2] = 0x102 | o; } else { int dx; dx=(x2-x1)*(1<<11)/(y2-y1); l[COORD_0>>2]=x1+(y1<<16); l[COORD_2>>2]=x2+(y2<<16); l[X_INCR>>2] = dx; l[CMD_0>>2] = 0x002 | o; } } Bool s3cXAAScreenInit(ScreenPtr pScreen) { ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; FBDevPtr pFBDEV = FBDevPTR(pScrn); XAAInfoRecPtr xaaInfo; int f; f=open("/dev/s3c-2d", O_RDWR); l=(unsigned int *)mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_SHARED, f, 0); close(f); ErrorF("pScrn->memPhysBase=%08x\n", pScrn->memPhysBase); l[DEST_BA>>2] = pScrn->memPhysBase; // l[DEST_BA>>2] = 0x56a00000; l[FB_BA>>2] = l[DEST_BA>>2]; l[SRC_BA>>2] = l[DEST_BA>>2]; l[HORI_RES>>2] = 800 ; l[VERT_RES>>2] = 960 ; l[SC_WINDOW_X>>2] = 800 ; l[SC_WINDOW_Y>>2] = 960 ; l[CW_LEFT>>2]=0; l[CW_TOP>>2]=0; l[CW_RIGHT>>2]=799; l[CW_BOT>>2]=959; l[ALPHA>>2] = 0xff; l[FG_COLOR>>2] = 0xffff; l[BG_COLOR>>2] = 0; l[BS_COLOR>>2] = 0x001f; l[ROP>>2]= (1<<13) | 0xf0; l[0x344>>2] = 0; l[0x348>>2] = 0; l[0x34c>>2] = 1; l[ALPHA>>2] = 0; TRACE("Calling XAACreateInfoRec"); pFBDEV->xaaInfo = XAACreateInfoRec(); if (!pFBDEV->xaaInfo) { TRACE("Calling XAACreateInfoRec failed"); return FALSE; } xaaInfo = pFBDEV->xaaInfo; xaaInfo->Flags = PIXMAP_CACHE | OFFSCREEN_PIXMAPS | LINEAR_FRAMEBUFFER; xaaInfo->Sync = s3cXAASync; if(1) { xaaInfo->SetupForSolidFill = s3cSetupForSolidFill; xaaInfo->SubsequentSolidFillRect = s3cSubsequentSolidFillRect; xaaInfo->SolidFillFlags = NO_PLANEMASK | GXCOPY_ONLY; } if(1) { xaaInfo->SetupForScreenToScreenCopy = s3cSetupForScreenToScreenCopy; xaaInfo->SubsequentScreenToScreenCopy = s3cSubsequentScreenToScreenCopy; xaaInfo->ScreenToScreenCopyFlags = 0; } if(1) { xaaInfo->SetupForSolidLine = s3cSetupForSolidLine; xaaInfo->SubsequentSolidTwoPointLine = s3cSubsequentSolidTwoPointLine; } if(1) { xaaInfo->SetupForScreenToScreenColorExpandFill = s3cSetupForScreenToScreenColorExpandFill; xaaInfo->SubsequentScreenToScreenColorExpandFill = s3cSubsequentScreenToScreenColorExpandFill; xaaInfo->ScreenToScreenColorExpandFillFlags = NO_PLANEMASK | BIT_ORDER_IN_BYTE_MSBFIRST ; } if(1) { BoxRec AvailFBArea; AvailFBArea.x1 = 0; AvailFBArea.y1 = 0; AvailFBArea.x2 = 800; AvailFBArea.y2 = XAALINES; xf86InitFBManager(pScreen, &AvailFBArea); xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Using %d scanlines of offscreen memory\n", XAALINES-480); } pFBDEV->xaaColorExpb = (unsigned int *)(pFBDEV->fbmem+COLEXPBUF); if (1) { xaaInfo->SetupForScanlineCPUToScreenColorExpandFill = s3cSetupForScanlineCPUToScreenColorExpandFill; xaaInfo->SubsequentScanlineCPUToScreenColorExpandFill = s3cSubsequentScanlineCPUToScreenColorExpandFill; xaaInfo->SubsequentColorExpandScanline = s3cSubsequentColorExpandScanline; xaaInfo->NumScanlineColorExpandBuffers = 1; xaaInfo->ScanlineColorExpandBuffers = pFBDEV->xaaColorExpScanLine; xaaInfo->ScanlineCPUToScreenColorExpandFillFlags = NO_PLANEMASK | BIT_ORDER_IN_BYTE_MSBFIRST ; } #if 1 TRACE("Calling XAAInit"); if (!XAAInit(pScreen, xaaInfo)) { // DESTROY_XAA_INFO(pFBDEV); TRACE("XAAInit failed"); return FALSE; } #endif return TRUE; }