diff -urN -x compile-log -x xmakefile -x Makefile* xc/config/cf/Imake.cf my/config/cf/Imake.cf --- xc/config/cf/Imake.cf Wed Feb 3 23:22:12 1999 +++ my/config/cf/Imake.cf Wed Feb 3 23:23:27 1999 @@ -578,8 +578,14 @@ # define Mc68020Architecture # undef mc68000 # endif /* mc68000 */ -# ifdef __powerpc__ +# ifdef powerpc # define PpcArchitecture +# undef powerpc +# endif +# ifdef __powerpc__ +# ifndef PpcArchitecture +# define PpcArchitecture +# endif # undef __powerpc__ # endif # ifdef sparc diff -urN -x compile-log -x xmakefile -x Makefile* xc/config/cf/host.def my/config/cf/host.def --- xc/config/cf/host.def Thu Jan 1 01:00:00 1970 +++ my/config/cf/host.def Wed Feb 3 20:20:57 1999 @@ -0,0 +1 @@ + diff -urN -x compile-log -x xmakefile -x Makefile* xc/config/cf/linux.cf my/config/cf/linux.cf --- xc/config/cf/linux.cf Wed Feb 3 23:21:05 1999 +++ my/config/cf/linux.cf Wed Feb 3 23:23:48 1999 @@ -293,13 +293,13 @@ #define PositionIndependentCplusplusFlags -fpic #endif /* Mc68020Architecture */ -#ifdef PowerPCArchitecture +#ifdef PpcArchitecture #define DefaultCCOptions -fsigned-char #define OptimizedCDebugFlags -O2 #define LinuxMachineDefines -D__powerpc__ #define ServerOSDefines XFree86ServerOSDefines -DDDXTIME -DPART_NET #define ServerExtraDefines -DGCCUSESGAS XFree86ServerDefines -#endif /* PowerPCArchitecture */ +#endif /* PpcArchitecture */ #ifdef SparcArchitecture #define OptimizedCDebugFlags -O2 diff -urN -x compile-log -x xmakefile -x Makefile* xc/config/cf/xf86site.def my/config/cf/xf86site.def --- xc/config/cf/xf86site.def Wed Feb 3 23:22:13 1999 +++ my/config/cf/xf86site.def Wed Feb 3 23:22:18 1999 @@ -17,6 +17,8 @@ */ /******************************************************************************/ +#define XConfigFile XF86Config4 + /* * If you have build-specific modifications in your host.def file, but * want an empty host.def file installed when doing 'make install', diff -urN -x compile-log -x xmakefile -x Makefile* xc/config/cf/xfree86.cf my/config/cf/xfree86.cf --- xc/config/cf/xfree86.cf Wed Feb 3 23:22:13 1999 +++ my/config/cf/xfree86.cf Wed Feb 3 23:28:38 1999 @@ -98,7 +98,7 @@ /* Pure PCI drivers should go first */ #ifndef XF86CardDrivers #define XF86CardDrivers mga glint tga s3virge sis cirrus tseng \ - trident chips vga + trident chips fbdev vga #endif #endif @@ -170,6 +170,70 @@ #endif #endif #endif + +/* + * LinuxPPC + */ +#if defined(PpcArchitecture) && defined(LinuxArchitecture) +#ifndef XF86Server +#define XF86Server YES +#endif +/* 1bpp module */ +#ifndef XF1Bpp +#define XF1Bpp YES +#endif +/* 4bpp module */ +#ifndef XF4Bpp +#define XF4Bpp YES +#endif +/* 8/32bpp overlay module */ +#ifndef XF8_32Bpp +#define XF8_32Bpp YES +#endif +/* 8/16bpp dual fb module */ +#ifndef XF8_16Bpp +#define XF8_16Bpp YES +#endif +/* 24/32bpp conversion module */ +#ifndef XF24_32Bpp +#define XF24_32Bpp YES +#endif +/* shadow fb module */ +#ifndef XFShadowFB +#define XFShadowFB YES +#endif +/* vgahw module */ +#ifndef XF86VgaHw +#define XF86VgaHw YES +#endif +/* XAA module */ +#ifndef XF86XAA +#define XF86XAA YES +#endif +/* ramdac module */ +#ifndef XF86Ramdac +#define XF86Ramdac YES +#endif +/* I2C module */ +#ifndef XF86I2C +#define XF86I2C YES +#endif +/* DDC module */ +#ifndef XF86DDC +#define XF86DDC YES +#endif +/* RAC (Resource Access Control) module */ +#ifndef XF86RAC +#define XF86RAC YES +#endif + +/* Pure PCI drivers should go first */ +#ifndef XF86CardDrivers +#define XF86CardDrivers mga glint tga s3virge sis cirrus tseng \ + trident chips fbdev vga +#endif +#endif + /* * For Mips/Arc platforms, the default is to build all modules which diff -urN -x compile-log -x xmakefile -x Makefile* xc/programs/Xserver/hw/xfree86/common/xf86Bus.c my/programs/Xserver/hw/xfree86/common/xf86Bus.c --- xc/programs/Xserver/hw/xfree86/common/xf86Bus.c Wed Feb 3 23:21:50 1999 +++ my/programs/Xserver/hw/xfree86/common/xf86Bus.c Wed Feb 3 21:54:35 1999 @@ -1296,6 +1296,7 @@ static void xf86DisableAccess(void) { + return; DisablePciAccess(); } diff -urN -x compile-log -x xmakefile -x Makefile* xc/programs/Xserver/hw/xfree86/drivers/fbdev/Imakefile my/programs/Xserver/hw/xfree86/drivers/fbdev/Imakefile --- xc/programs/Xserver/hw/xfree86/drivers/fbdev/Imakefile Thu Jan 1 01:00:00 1970 +++ my/programs/Xserver/hw/xfree86/drivers/fbdev/Imakefile Wed Feb 3 21:55:42 1999 @@ -0,0 +1,37 @@ +XCOMM +XCOMM This is an Imakefile for the fbdev driver. +XCOMM + +#define IHaveModules +#include + +SRCS = fbdev.c +OBJS = fbdev.o + +#if XF86LinkKit +INCLUDES = -I. -I../../../include -I../../../include/X11 -I../.. +#else +INCLUDES = -I. -I$(XF86COMSRC) -I$(XF86OSSRC) \ + -I$(SERVERSRC)/mfb -I$(SERVERSRC)/mi \ + -I$(SERVERSRC)/cfb -I$(XF86SRC)/xaa \ + -I$(XF86SRC)/vgahw -I$(XF86SRC)/ramdac \ + -I$(XF86SRC)/ddc -I$(XF86SRC)/i2c \ + -I$(SERVERSRC)/Xext -I$(XF86SRC)/xf8_32bpp\ + -I$(FONTINCSRC) -I$(SERVERSRC)/include -I$(XINCLUDESRC) \ + -I$(XF86SRC)/shadowfb +#endif + +#if MakeHasPosixVariableSubstitutions +SubdirLibraryRule($(OBJS)) +#endif + +ModuleObjectRule() + +ObjectModuleTarget(fbdev,$(OBJS)) + +InstallLinkKitNonExecFile(fbdev.c,$(LINKKITDIR)/drivers/svga/fbdev) +InstallLinkKitNonExecFile(Imakefile,$(LINKKITDIR)/drivers/svga/fbdev) + +InstallObjectModule(fbdev,$(MODULEDIR),drivers) + +DependTarget() diff -urN -x compile-log -x xmakefile -x Makefile* xc/programs/Xserver/hw/xfree86/drivers/fbdev/fbdev.c my/programs/Xserver/hw/xfree86/drivers/fbdev/fbdev.c --- xc/programs/Xserver/hw/xfree86/drivers/fbdev/fbdev.c Thu Jan 1 01:00:00 1970 +++ my/programs/Xserver/hw/xfree86/drivers/fbdev/fbdev.c Wed Feb 3 23:29:46 1999 @@ -0,0 +1,1035 @@ +/* all driver need this */ +#include "xf86.h" +#include "xf86_OSproc.h" +#include "xf86_ansic.h" + +#include "mipointer.h" +#include "mibstore.h" +#include "micmap.h" +#include "colormapst.h" +#include "xf86cmap.h" +#include "shadowfb.h" + +/* for visuals */ +#define PSZ 8 +#include "cfb.h" +#undef PSZ +#include "cfb16.h" +#include "cfb24.h" +#include "cfb32.h" + +#include "linux/fb.h" + +#define DEBUG 1 + +/* -------------------------------------------------------------------- */ +/* prototypes */ + +/* Mandatory functions */ +static void FBDevIdentify(int flags); +static Bool FBDevProbe(DriverPtr drv, int flags); +static Bool FBDevPreInit(ScrnInfoPtr pScrn, int flags); +static Bool FBDevScreenInit(int Index, ScreenPtr pScreen, int argc, + char **argv); +static Bool FBDevEnterVT(int scrnIndex, int flags); +static void FBDevLeaveVT(int scrnIndex, int flags); +static Bool FBDevCloseScreen(int scrnIndex, ScreenPtr pScreen); +static Bool FBDevSaveScreen(ScreenPtr pScreen, Bool unblank); + +/* panning */ +static void FBDevAdjustFrame(int scrnIndex, int x, int y, int flags); + +/* for modeswitching */ +static Bool FBDevSwitchMode(int scrnIndex, DisplayModePtr mode, int flags); +static int FBDevValidMode(int scrnIndex, DisplayModePtr mode, Bool verbose, + int flags); + +#if 0 +/* optional */ +static void FBDevFreeScreen(int scrnIndex, int flags); +#endif + +/* -------------------------------------------------------------------- */ + +#define VERSION 4000 +#define FBDEV_NAME "FBDev" +#define FBDEV_DRIVER_NAME "fbdev" +#define FBDEV_MAJOR_VERSION 0 +#define FBDEV_MINOR_VERSION 1 + +DriverRec FBDEV = { + VERSION, + "driver for linux framebuffer devices", + FBDevIdentify, + FBDevProbe, + NULL, + 0 +}; + +/* Supported "chipsets" */ +static SymTabRec FBDevChipsets[] = { + { 0, "fbdev" }, + {-1, NULL } +}; + +/* Supported options */ +typedef enum { + OPTION_NOACCEL, + OPTION_SHADOW_FB +} FBDevOpts; + +static OptionInfoRec FBDevOptions[] = { + { OPTION_NOACCEL, "NoAccel", OPTV_BOOLEAN, {0}, FALSE }, + { OPTION_SHADOW_FB, "ShadowFB", OPTV_BOOLEAN, {0}, FALSE }, + { -1, NULL, OPTV_NONE, {0}, FALSE } +}; + + +#ifdef XFree86LOADER + +MODULESETUPPROTO(FBDevSetup); + +static XF86ModuleVersionInfo FBDevVersRec = +{ + "fbdev", + MODULEVENDORSTRING, + MODINFOSTRING1, + MODINFOSTRING2, + XF86_VERSION_CURRENT, + FBDEV_MAJOR_VERSION, FBDEV_MINOR_VERSION, 0, + ABI_CLASS_VIDEODRV, + ABI_VIDEODRV_VERSION, + NULL, + {0,0,0,0} +}; + +XF86ModuleData fbdevModuleData = { &FBDevVersRec, FBDevSetup, NULL }; + +static const char *cfbSymbols[] = { + "cfbScreenInit", + "cfb16ScreenInit", + "cfb24ScreenInit", + "cfb32ScreenInit", + NULL +}; + +static const char *shadowSymbols[] = { + "ShadowFBInit", + NULL +}; + +pointer +FBDevSetup(pointer module, pointer opts, int *errmaj, int *errmin) +{ + static Bool setupDone = FALSE; + + if (!setupDone) { + setupDone = TRUE; + xf86AddDriver(&FBDEV, module, 0); + LoaderRefSymLists(cfbSymbols, shadowSymbols, NULL); + return (pointer)1; + } else { + if (errmaj) *errmaj = LDR_ONCEONLY; + return NULL; + } +} + +#else /* XFree86LOADER */ + +#include +#include + +#endif /* XFree86LOADER */ + +/* -------------------------------------------------------------------- */ +/* our private data, and two functions to allocate/free this */ + +typedef struct { + int fd; + struct fb_fix_screeninfo fix; + struct fb_var_screeninfo var; + struct fb_var_screeninfo var_saved; + DisplayModeRec buildin; + unsigned char* fbmem; + unsigned char* shadowmem; + int shadowPitch; + unsigned char* fbstart; + void* mmio; + Bool need_mmio; + Bool noAccel; + Bool shadowFB; + CloseScreenProcPtr CloseScreen; +} 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; +} + +/* -------------------------------------------------------------------- */ +/* some helpers for printing debug informations */ + +static void print_fbdev_mode(char *txt, struct fb_var_screeninfo *var) +{ + ErrorF( "fbdev %s mode:\t%d %d %d %d %d %d %d %d %d %d %d:%d:%d\n", + txt,var->pixclock, + var->xres, var->right_margin, var->hsync_len, var->left_margin, + var->yres, var->lower_margin, var->vsync_len, var->upper_margin, + var->bits_per_pixel, + var->red.length, var->green.length, var->blue.length); +} + +static void print_xfree_mode(char *txt, DisplayModePtr mode) +{ + ErrorF( "xfree %s mode:\t%d %d %d %d %d %d %d %d %d\n", + txt,mode->Clock, + mode->HDisplay, mode->HSyncStart, mode->HSyncEnd, mode->HTotal, + mode->VDisplay, mode->VSyncStart, mode->VSyncEnd, mode->VTotal); +} + +/* -------------------------------------------------------------------- */ +/* Convert timings between the XFree and the Frame Buffer Device */ + +static void xfree2fbdev_fblayout(ScrnInfoPtr pScrn, struct fb_var_screeninfo *var) +{ + var->xres_virtual = pScrn->virtualX; + var->yres_virtual = pScrn->virtualY; + var->bits_per_pixel = pScrn->bitsPerPixel; + var->red.length = 0; + var->red.offset = 0; + var->green.length = 0; + var->green.offset = 0; + var->blue.length = 0; + var->blue.offset = 0; +} + +static void xfree2fbdev_timing(DisplayModePtr mode, struct fb_var_screeninfo *var) +{ + var->xres = mode->HDisplay; + var->yres = mode->VDisplay; + if (var->xres_virtual < var->xres) + var->xres_virtual = var->xres; + if (var->yres_virtual < var->yres) + var->yres_virtual = var->yres; + var->xoffset = var->yoffset = 0; +#if 0 + if (mode->Clock < MAXCLOCKS) { + var->pixclock = vga256InfoRec.clock[mode->Clock] ? + 1000000000/vga256InfoRec.clock[mode->Clock] : 0; + } else { +#endif + var->pixclock = mode->Clock ? 1000000000/mode->Clock : 0; +#if 0 + } +#endif + var->right_margin = mode->HSyncStart-mode->HDisplay; + var->hsync_len = mode->HSyncEnd-mode->HSyncStart; + var->left_margin = mode->HTotal-mode->HSyncEnd; + var->lower_margin = mode->VSyncStart-mode->VDisplay; + var->vsync_len = mode->VSyncEnd-mode->VSyncStart; + var->upper_margin = mode->VTotal-mode->VSyncEnd; + var->sync = 0; + if (mode->Flags & V_PHSYNC) + var->sync |= FB_SYNC_HOR_HIGH_ACT; + if (mode->Flags & V_PVSYNC) + var->sync |= FB_SYNC_VERT_HIGH_ACT; + if (mode->Flags & V_PCSYNC) + var->sync |= FB_SYNC_COMP_HIGH_ACT; +#if 0 + if (mode->Flags & V_BCAST) + var->sync |= FB_SYNC_BROADCAST; +#endif + if (mode->Flags & V_INTERLACE) + var->vmode = FB_VMODE_INTERLACED; + else if (mode->Flags & V_DBLSCAN) + var->vmode = FB_VMODE_DOUBLE; + else + var->vmode = FB_VMODE_NONINTERLACED; +} + +static void fbdev2xfree_timing(struct fb_var_screeninfo *var, DisplayModePtr mode) +{ + mode->Clock = var->pixclock ? 1000000000/var->pixclock : 28000000; + mode->HDisplay = var->xres; + mode->HSyncStart = mode->HDisplay+var->right_margin; + mode->HSyncEnd = mode->HSyncStart+var->hsync_len; + mode->HTotal = mode->HSyncEnd+var->left_margin; + mode->VDisplay = var->yres; + mode->VSyncStart = mode->VDisplay+var->lower_margin; + mode->VSyncEnd = mode->VSyncStart+var->vsync_len; + mode->VTotal = mode->VSyncEnd+var->upper_margin; + mode->Flags = 0; + mode->Flags |= var->sync & FB_SYNC_HOR_HIGH_ACT ? V_PHSYNC : V_NHSYNC; + mode->Flags |= var->sync & FB_SYNC_VERT_HIGH_ACT ? V_PVSYNC : V_NVSYNC; + mode->Flags |= var->sync & FB_SYNC_COMP_HIGH_ACT ? V_PCSYNC : V_NCSYNC; +#if 0 + if (var->sync & FB_SYNC_BROADCAST) + mode->Flags |= V_BCAST; +#endif + if ((var->vmode & FB_VMODE_MASK) == FB_VMODE_INTERLACED) + mode->Flags |= V_INTERLACE; + else if ((var->vmode & FB_VMODE_MASK) == FB_VMODE_DOUBLE) + mode->Flags |= V_DBLSCAN; + mode->SynthClock = mode->Clock; + mode->CrtcHDisplay = mode->HDisplay; + mode->CrtcHSyncStart = mode->HSyncStart; + mode->CrtcHSyncEnd = mode->HSyncEnd; + mode->CrtcHTotal = mode->HTotal; + mode->CrtcVDisplay = mode->VDisplay; + mode->CrtcVSyncStart = mode->VSyncStart; + mode->CrtcVSyncEnd = mode->VSyncEnd; + mode->CrtcVTotal = mode->VTotal; + mode->CrtcHAdjusted = FALSE; + mode->CrtcVAdjusted = FALSE; +} + +/* + * open correct framebuffer device. + */ + +static int +fbdev_open(char *dev) +{ + struct fb_con2fbmap c2m; + char fbdev[16]; + int fd; + + /* try argument (from XF86Config) first */ + if (NULL != dev) + return open(dev,O_RDWR,0); + + /* second: environment variable */ + dev = getenv("FRAMEBUFFER"); + if (NULL != dev) + return open(dev,O_RDWR,0); + + /* open the first one */ + if (-1 == (fd = open("/dev/fb0",O_RDWR,0))) + return -1; + +#if 1 + /* FIXME: xf86Info is'nt available for drivers :-( */ + return fd; +#else + /* check which fb device the vt is mapped to */ + c2m.console = xf86Info.vtno; + if (-1 == ioctl(fd, FBIOGET_CON2FBMAP, &c2m)) { + perror("ioctl FBIOGET_CON2FBMAP"); + return fd; + } +#if DEBUG + ErrorF("fbdev_open: vt%02d => fb%d\n",c2m.console,c2m.framebuffer); +#endif + if (c2m.framebuffer != 0) { + /* it is'nt the first, open the correct one */ + sprintf(fbdev,"/dev/fb%d\n",c2m.framebuffer); + close(fd); + fd = open(fbdev,O_RDWR,0); + } + return fd; +#endif +} + +/* -------------------------------------------------------------------- */ + +static void +FBDevIdentify(int flags) +{ + xf86PrintChipsets(FBDEV_NAME, "driver for linux framebuffer", FBDevChipsets); +} + +static Bool +FBDevProbe(DriverPtr drv, int flags) +{ + int i,fd; + ScrnInfoPtr pScrn; + GDevPtr *devSections; + int numDevSections; + Bool foundScreen = FALSE; + +#ifdef DEBUG + ErrorF("FBDevProbe\n"); +#endif + + if ((numDevSections = xf86MatchDevice(FBDEV_DRIVER_NAME, &devSections)) <= 0) + return FALSE; + + for (i = 0; i < numDevSections; i++) { + /* TODO: pick /dev/fbx from config file ?? */ + + if (-1 != (fd = fbdev_open(NULL))) { + close(fd); + pScrn = xf86AllocateScreen(drv, 0); + + pScrn->driverVersion = VERSION; + pScrn->driverName = FBDEV_DRIVER_NAME; + pScrn->name = FBDEV_NAME; + pScrn->Probe = FBDevProbe; + pScrn->PreInit = FBDevPreInit; + pScrn->ScreenInit = FBDevScreenInit; + pScrn->SwitchMode = FBDevSwitchMode; + pScrn->AdjustFrame = FBDevAdjustFrame; + pScrn->EnterVT = FBDevEnterVT; + pScrn->LeaveVT = FBDevLeaveVT; +#if 0 + pScrn->FreeScreen = FBDevFreeScreen; +#endif + pScrn->ValidMode = FBDevValidMode; + pScrn->device = devSections[i]; + + foundScreen = TRUE; + +#ifdef DEBUG + ErrorF("FBDevProbe: found one.\n"); +#endif + /* can handle only one for now... */ + break; + } + } + xfree(devSections); + return foundScreen; +} + +static Bool +FBDevPreInit(ScrnInfoPtr pScrn, int flags) +{ + FBDevPtr fPtr; + struct fb_var_screeninfo var; + char *mod = NULL; + const char *reqSym = NULL; + int depth; + Gamma zeros = {0.0, 0.0, 0.0}; + +#ifdef DEBUG + ErrorF("FBDevPreInit %d\n",pScrn->scrnIndex); +#endif + pScrn->monitor = pScrn->confScreen->monitor; + + FBDevGetRec(pScrn); + fPtr = FBDEVPTR(pScrn); + if (-1 == (fPtr->fd = fbdev_open(NULL))) + return FALSE; + + /* get current fb device settings */ + if (-1 == ioctl(fPtr->fd,FBIOGET_FSCREENINFO,(void*)(&fPtr->fix))) { + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + "ioctl FBIOGET_FSCREENINFO: %s\n", + strerror(errno)); + return FALSE; + } + if (-1 == ioctl(fPtr->fd,FBIOGET_VSCREENINFO,(void*)(&fPtr->var))) { + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + "ioctl FBIOGET_VSCREENINFO: %s\n", + strerror(errno)); + return FALSE; + } + + /* copy current fb mode, using this for testing parameters */ + memcpy(&var,&fPtr->var,sizeof(var)); + + /* color depth */ + depth = var.bits_per_pixel; /* use current fbdev setting as default */ + if (!xf86SetDepthBpp(pScrn, depth, depth, depth, Support24bppFb | Support32bppFb)) + return FALSE; + var.activate = FB_ACTIVATE_TEST; + var.bits_per_pixel = pScrn->depth; + var.yres_virtual = var.yres; + if (-1 == ioctl(fPtr->fd,FBIOGET_VSCREENINFO,(void*)(&fPtr->var))) { + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + "Given depth (%d) is not supported by framebuffer device\n", + pScrn->depth); + return FALSE; + } + xf86PrintDepthBpp(pScrn); + + /* 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, "Given default visual" + " (%s) is not supported at depth %d\n", + xf86GetVisualName(pScrn->defaultVisual), pScrn->depth); + return FALSE; + } + + xf86SetGamma(pScrn,zeros); + + pScrn->progClock = TRUE; + pScrn->rgbBits = 8; + pScrn->chipset = "fbdev"; + pScrn->videoRam = fPtr->fix.smem_len; + + /* handle options */ + xf86CollectOptions(pScrn, NULL); + xf86ProcessOptions(pScrn->scrnIndex, pScrn->options, FBDevOptions); + if (xf86IsOptionSet(FBDevOptions, OPTION_NOACCEL)) { + fPtr->noAccel = TRUE; + xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Acceleration disabled\n"); + } + if (xf86IsOptionSet(FBDevOptions, OPTION_SHADOW_FB)) { + fPtr->shadowFB = TRUE; + xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "ShadowFB enabled\n"); + } + + if (NULL != pScrn->display->modes) { + /* verify display modes */ + int virtX = pScrn->display->virtualX; + int virtY = pScrn->display->virtualY; + char **modename; + DisplayModePtr mode,this,last = NULL; + +#ifdef DEBUG + ErrorF("FBDevPreInit: check mode list\n"); +#endif + for (modename = pScrn->display->modes; *modename != NULL; modename++) { + ErrorF("\t%s... ",*modename); + for (mode = pScrn->monitor->Modes; mode != NULL; mode = mode->next) + if (0 == strcmp(mode->name,*modename)) + break; + if (NULL == mode) { + ErrorF("not found\n"); + continue; + } + memset(&var,0,sizeof(var)); + xfree2fbdev_timing(mode,&var); + var.xres_virtual = virtX; + var.yres_virtual = virtY; + var.bits_per_pixel = pScrn->depth; + var.activate = FB_ACTIVATE_TEST; + if (var.xres_virtual < var.xres) var.xres_virtual = var.xres; + if (var.yres_virtual < var.yres) var.yres_virtual = var.yres; + if (-1 == ioctl(fPtr->fd,FBIOPUT_VSCREENINFO,(void*)(&var))) { + ErrorF("failed\n"); + continue; + } + ErrorF("passed\n"); + if (virtX < var.xres) virtX = var.xres; + if (virtY < var.yres) virtY = var.yres; + if (NULL == pScrn->modes) { + pScrn->modes = xnfalloc(sizeof(DisplayModeRec)); + this = pScrn->modes; + memcpy(this,mode,sizeof(DisplayModeRec)); + this->next = this; + this->prev = this; + } else { + this = xnfalloc(sizeof(DisplayModeRec)); + memcpy(this,mode,sizeof(DisplayModeRec)); + this->next = pScrn->modes; + this->prev = last; + last->next = this; + pScrn->modes->prev = this; + } + last = this; + } + pScrn->virtualX = virtX; + pScrn->virtualY = virtY; + } + if (pScrn->modes == NULL) { + /* no valid mode? use the current fb settings as buildin mode */ + fbdev2xfree_timing(&fPtr->var, &fPtr->buildin); +#if DEBUG + print_fbdev_mode("current",&fPtr->var); + print_xfree_mode("current",&fPtr->buildin); +#endif + fPtr->buildin.name = "current"; + fPtr->buildin.next = &fPtr->buildin; + fPtr->buildin.prev = &fPtr->buildin; + fPtr->buildin.type |= M_T_BUILTIN; + pScrn->modes = &fPtr->buildin; + pScrn->virtualX = pScrn->display->virtualX; + pScrn->virtualY = pScrn->display->virtualY; + if (pScrn->virtualX < fPtr->var.xres) + pScrn->virtualX = fPtr->var.xres; + if (pScrn->virtualY < fPtr->var.yres) + pScrn->virtualY = fPtr->var.yres; + } + pScrn->currentMode = pScrn->modes; + pScrn->displayWidth = pScrn->virtualX; /* FIXME */ + xf86PrintModes(pScrn); + + /* Set display resolution */ + xf86SetDpi(pScrn, 0, 0); + + /* Load bpp-specific modules */ + switch (pScrn->bitsPerPixel) + { + /* TODO: add mono, iplan2*, others? */ + case 8: + mod = "cfb"; + reqSym = "cfbScreenInit"; + break; + case 16: + mod = "cfb16"; + reqSym = "cfb16ScreenInit"; + break; + case 24: + mod = "cfb24"; + reqSym = "cfb24ScreenInit"; + break; + case 32: + mod = "cfb32"; + reqSym = "cfb32ScreenInit"; + break; + } + if (mod && xf86LoadSubModule(pScrn, mod) == NULL) { + FBDevFreeRec(pScrn); + return FALSE; + } + xf86LoaderReqSymbols(reqSym, NULL); + + /* Load shadowFB if needed */ + if (fPtr->shadowFB) { + if (!xf86LoadSubModule(pScrn, "shadowfb")) { + FBDevFreeRec(pScrn); + return FALSE; + } + xf86LoaderReqSymLists(shadowSymbols, NULL); + } + + /* TODO: acceleration */ + +#ifdef DEBUG + ErrorF("FBDevPreInit done\n"); +#endif + return TRUE; +} + +static Bool +FBDevMap(ScrnInfoPtr pScrn) +{ + FBDevPtr fPtr = FBDEVPTR(pScrn); + +#ifdef DEBUG + ErrorF("FBDevMap %d\n",pScrn->scrnIndex); +#endif +#if 0 /* FIXME: there is no wrapper for mmap() */ + if (NULL == fPtr->fbmem) { + fPtr->fbmem = mmap(NULL, fPtr->fix.smem_len, PROT_READ | PROT_WRITE, + MAP_SHARED, fPtr->fd, 0); + if (-1 == (int)fPtr->fbmem) { + perror("mmap fbmem"); + fPtr->fbmem = NULL; + return FALSE; + } + } + if (NULL == fPtr->mmio && fPtr->need_mmio) { + fPtr->mmio = mmap(NULL, fPtr->fix.mmio_len, PROT_READ | PROT_WRITE, + MAP_SHARED, fPtr->fd, fPtr->fix.smem_len); + if (-1 == (int)fPtr->fbmem) { + perror("mmap mmio"); + fPtr->mmio = NULL; + return FALSE; + } + } +#else + if (NULL == fPtr->fbmem) { + fPtr->fbmem = xf86MapVidMem(pScrn->scrnIndex, VIDMEM_FRAMEBUFFER, + (pointer)(fPtr->fix.smem_start), fPtr->fix.smem_len); + } +#endif +#ifdef DEBUG + ErrorF("FBDevMap done (%p)\n",fPtr->fbmem); +#endif + return TRUE; +} + +static Bool +FBDevUnmap(ScrnInfoPtr pScrn) +{ +#if 0 + FBDevPtr fPtr = FBDEVPTR(pScrn); + +#ifdef DEBUG + ErrorF("FBDevUnmap %d\n",pScrn->scrnIndex); +#endif + if (NULL != fPtr->fbmem) { + munmap(fPtr->fbmem, fPtr->fix.smem_len); + fPtr->fbmem = NULL; + } + if (NULL != fPtr->mmio) { + munmap(fPtr->mmio, fPtr->fix.mmio_len); + fPtr->mmio = NULL; + } +#endif + return TRUE; +} + +static Bool +FBDevModeInit(ScrnInfoPtr pScrn, DisplayModePtr mode) +{ + FBDevPtr fPtr = FBDEVPTR(pScrn); + + xfree2fbdev_fblayout(pScrn, &fPtr->var); + xfree2fbdev_timing(mode, &fPtr->var); +#if DEBUG + print_xfree_mode("init",mode); + print_fbdev_mode("init",&fPtr->var); +#endif + pScrn->vtSema = TRUE; + + /* set */ + if (0 != ioctl(fPtr->fd,FBIOPUT_VSCREENINFO,(void*)(&fPtr->var))) { + perror("FBIOPUT_VSCREENINFO"); + return FALSE; + } + /* read back */ + if (0 != ioctl(fPtr->fd,FBIOGET_FSCREENINFO,(void*)(&fPtr->fix))) { + perror("FBIOGET_FSCREENINFO"); + return FALSE; + } + if (0 != ioctl(fPtr->fd,FBIOGET_VSCREENINFO,(void*)(&fPtr->var))) { + perror("FBIOGET_VSCREENINFO"); + return FALSE; + } +#if DEBUG + print_fbdev_mode("done",&fPtr->var); +#endif + return TRUE; +} + +static void +FBDevLoadPalette(ScrnInfoPtr pScrn, int numColors, int *indices, + LOCO *colors, short visualClass) +{ + FBDevPtr fPtr = FBDEVPTR(pScrn); + struct fb_cmap cmap; + unsigned short red,green,blue; + int i; + +#ifdef DEBUG + ErrorF("FBDevLoadPalette\n"); +#endif + cmap.len = 1; + cmap.red = &red; + cmap.green = &green; + cmap.blue = &blue; + for (i = 0; i < numColors; i++) { + cmap.start = indices[i]; + red = colors[indices[i]].red << 8; + green = colors[indices[i]].green << 8; + blue = colors[indices[i]].blue << 8; + if (-1 == ioctl(fPtr->fd,FBIOPUTCMAP,(void*)&cmap)) + perror("ioctl FBIOPUTCMAP"); + } +} + +static void +FBDevRefreshArea(ScrnInfoPtr pScrn, int num, BoxPtr pbox) +{ + FBDevPtr fPtr = FBDEVPTR(pScrn); + int width, height, Bpp, FBPitch; + unsigned char *src, *dst; + + Bpp = pScrn->bitsPerPixel >> 3; + FBPitch = pScrn->displayWidth * Bpp; + + while(num--) { + width = (pbox->x2 - pbox->x1) * Bpp; + height = pbox->y2 - pbox->y1; + src = fPtr->shadowmem + (pbox->y1 * fPtr->shadowPitch) + + (pbox->x1 * Bpp); + dst = fPtr->fbmem + (pbox->y1 * FBPitch) + (pbox->x1 * Bpp); + + while(height--) { + memcpy(dst, src, width); + dst += FBPitch; + src += fPtr->shadowPitch; + } + pbox++; + } +} + +static Bool +FBDevSaveScreen(ScreenPtr pScreen, Bool unblank) +{ + ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; + FBDevPtr fPtr = FBDEVPTR(pScrn); + +#ifdef DEBUG + ErrorF("FBDevSaveScreen unblank=%s vtSema=%d\n", + unblank ? "true" : "false", + pScrn->vtSema); +#endif + /* not implemented yet */ + return TRUE; +} + +static void FBDevSave(ScrnInfoPtr pScrn) +{ + FBDevPtr fPtr = FBDEVPTR(pScrn); + +#ifdef DEBUG + ErrorF("FBDevSave %d\n",pScrn->scrnIndex); +#endif + if (0 != ioctl(fPtr->fd,FBIOGET_VSCREENINFO,(void*)(&fPtr->var_saved))) + perror("FBIOGET_VSCREENINFO"); +} + +static void FBDevRestore(ScrnInfoPtr pScrn) +{ + FBDevPtr fPtr = FBDEVPTR(pScrn); + +#ifdef DEBUG + ErrorF("FBDevRestore %d\n",pScrn->scrnIndex); +#endif + if (0 != ioctl(fPtr->fd,FBIOPUT_VSCREENINFO,(void*)(&fPtr->var_saved))) + perror("FBIOPUT_VSCREENINFO"); +} + +static Bool +FBDevScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv) +{ + ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; + FBDevPtr fPtr = FBDEVPTR(pScrn); + VisualPtr visual; + int ret; + +#ifdef DEBUG + ErrorF("FBDevScreenInit %d\n",pScrn->scrnIndex); + 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 (!FBDevMap(pScrn)) + return FALSE; + + FBDevSave(pScrn); + + if (!FBDevModeInit(pScrn, pScrn->currentMode)) + return FALSE; + FBDevAdjustFrame(scrnIndex,0,0,0); + + /* mi layer */ + miClearVisualTypes(); + if (pScrn->bitsPerPixel > 8) { + if (!miSetVisualTypes(pScrn->depth, TrueColorMask, pScrn->rgbBits, TrueColor)) + return FALSE; + } else { + if (!miSetVisualTypes(pScrn->depth, + miGetDefaultVisualMask(pScrn->depth), + pScrn->rgbBits, pScrn->defaultVisual)) + return FALSE; + } + + /* shadowfb */ + if (fPtr->shadowFB) { + fPtr->shadowPitch = + ((pScrn->virtualX * pScrn->bitsPerPixel >> 3) + 3) & ~3L; + fPtr->shadowmem = xalloc(fPtr->shadowPitch * pScrn->virtualY); + fPtr->fbstart = fPtr->shadowmem; + } else { + fPtr->shadowmem = NULL; + fPtr->fbstart = fPtr->fbmem; + } + + switch (pScrn->bitsPerPixel) { + /* TODO: add mono, iplan2*, others? */ + case 8: + ret = cfbScreenInit + (pScreen, fPtr->fbstart, pScrn->virtualX, pScrn->virtualY, + pScrn->xDpi, pScrn->yDpi, pScrn->displayWidth); + break; + case 16: + ret = cfb16ScreenInit + (pScreen, fPtr->fbstart, pScrn->virtualX, pScrn->virtualY, + pScrn->xDpi, pScrn->yDpi, pScrn->displayWidth); + break; + case 24: + ret = cfb24ScreenInit + (pScreen, fPtr->fbstart, pScrn->virtualX, pScrn->virtualY, + pScrn->xDpi, pScrn->yDpi, pScrn->displayWidth); + break; + case 32: + ret = cfb32ScreenInit + (pScreen, fPtr->fbstart, pScrn->virtualX, pScrn->virtualY, + pScrn->xDpi, pScrn->yDpi, pScrn->displayWidth); + break; + default: + xf86DrvMsg(scrnIndex, X_ERROR, + "Internal error: invalid bpp (%d) in FBDevScreenInit\n", + pScrn->bitsPerPixel); + 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; + } + } + } + + xf86SetBlackWhitePixels(pScreen); + miInitializeBackingStore(pScreen); + xf86SetBackingStore(pScreen); + + /* software cursor */ + miDCInitialize(pScreen, xf86GetPointerScreenFuncs()); + + if(fPtr->shadowFB) + ShadowFBInit(pScreen, FBDevRefreshArea); + + /* colormap */ + switch (pScrn->depth) { +#if 0 /* TODO */ + case 1: + if (!xf1bppCreateDefColormap(pScreen)) + return FALSE; + break; + case 4: + if (!xf4bppCreateDefColormap(pScreen)) + return FALSE; + break; +#endif + default: + if (!cfbCreateDefColormap(pScreen)) + return FALSE; + break; + } + if(!xf86HandleColormaps(pScreen, 256, 8, FBDevLoadPalette, NULL, 0)) + /* CMAP_PALETTED_TRUECOLOR | CMAP_RELOAD_ON_MODE_SWITCH)) */ + return FALSE; + + pScreen->SaveScreen = FBDevSaveScreen; + + /* Wrap the current CloseScreen function */ + fPtr->CloseScreen = pScreen->CloseScreen; + pScreen->CloseScreen = FBDevCloseScreen; +#ifdef DEBUG + ErrorF("FBDevScreenInit done\n",pScrn->scrnIndex); +#endif + return TRUE; +} + +static void +FBDevAdjustFrame(int scrnIndex, int x, int y, int flags) +{ + ScrnInfoPtr pScrn = xf86Screens[scrnIndex]; + FBDevPtr fPtr = FBDEVPTR(pScrn); + +#ifdef DEBUG + ErrorF("FBDevAdjustFrame +%d+%d\n",x,y); +#endif + fPtr->var.xoffset = x; + fPtr->var.yoffset = y; + if (-1 == ioctl(fPtr->fd,FBIOPAN_DISPLAY,(void*)&fPtr->var)) + perror("ioctl FBIOPAN_DISPLAY"); +} + +static int +FBDevValidMode(int scrnIndex, DisplayModePtr mode, Bool verbose, int flags) +{ + ScrnInfoPtr pScrn = xf86Screens[scrnIndex]; + FBDevPtr fPtr = FBDEVPTR(pScrn); + struct fb_var_screeninfo var; + +#ifdef DEBUG + ErrorF("FBDevValidMode %d %s\n",pScrn->scrnIndex,mode->name); +#endif + memcpy(&var,&fPtr->var,sizeof(var)); + xfree2fbdev_timing(mode, &var); + var.activate = FB_ACTIVATE_TEST; + if (0 != ioctl(fPtr->fd,FBIOPUT_VSCREENINFO,(void*)(&fPtr->var))) { + perror("FBIOPUT_VSCREENINFO"); + return MODE_BAD; + } + return MODE_OK; +} + +static Bool +FBDevSwitchMode(int scrnIndex, DisplayModePtr mode, int flags) +{ + ScrnInfoPtr pScrn = xf86Screens[scrnIndex]; + FBDevPtr fPtr = FBDEVPTR(pScrn); + +#ifdef DEBUG + ErrorF("FBDevSwitchMode %d %s\n",pScrn->scrnIndex,mode->name); +#endif + xfree2fbdev_timing(mode, &fPtr->var); + if (0 != ioctl(fPtr->fd,FBIOPUT_VSCREENINFO,(void*)(&fPtr->var))) { + perror("FBIOPUT_VSCREENINFO"); + return FALSE; + } + return TRUE; +} + +static Bool +FBDevEnterVT(int scrnIndex, int flags) +{ + ScrnInfoPtr pScrn = xf86Screens[scrnIndex]; + +#ifdef DEBUG + ErrorF("FBDevEnterVT %d flags=%d\n",scrnIndex,flags); +#endif + if (!FBDevModeInit(pScrn, pScrn->currentMode)) + return FALSE; + FBDevAdjustFrame(scrnIndex, pScrn->frameX0, pScrn->frameY0, 0); + return TRUE; +} + +static void +FBDevLeaveVT(int scrnIndex, int flags) +{ + ScrnInfoPtr pScrn = xf86Screens[scrnIndex]; + +#ifdef DEBUG + ErrorF("FBDevLeaveVT %d flags=%d\n",scrnIndex,flags); +#endif + FBDevRestore(pScrn); +} + +static Bool +FBDevCloseScreen(int scrnIndex, ScreenPtr pScreen) +{ + ScrnInfoPtr pScrn = xf86Screens[scrnIndex]; + FBDevPtr fPtr = FBDEVPTR(pScrn); + + FBDevRestore(pScrn); + FBDevUnmap(pScrn); + close(fPtr->fd); + if (fPtr->shadowmem) + xfree(fPtr->shadowmem); + pScrn->vtSema = FALSE; + + pScreen->CloseScreen = fPtr->CloseScreen; + return (*pScreen->CloseScreen)(scrnIndex, pScreen); +}