diff options
Diffstat (limited to 'hw')
-rw-r--r-- | hw/xfree86/fbdevhw/fbdevhw.c | 185 |
1 files changed, 156 insertions, 29 deletions
diff --git a/hw/xfree86/fbdevhw/fbdevhw.c b/hw/xfree86/fbdevhw/fbdevhw.c index 17fba36..f65ab1e 100644 --- a/hw/xfree86/fbdevhw/fbdevhw.c +++ b/hw/xfree86/fbdevhw/fbdevhw.c @@ -4,6 +4,7 @@ #endif #include <string.h> +#include <sys/stat.h> #include "xf86.h" #include "xf86_OSproc.h" @@ -67,6 +68,7 @@ typedef struct { unsigned int fboff; char* mmio; unsigned int mmio_len; + Bool rf; // regular file: 1 -> fb-device, 0 -> regular file /* current hardware state */ struct fb_fix_screeninfo fix; @@ -304,6 +306,87 @@ fbdev_open_pci(struct pci_device * pPci, char **namep) return -1; } +// HU: detect if regular file +static Bool +fbdev_detect_rf(int fd) { + struct stat s; + + if (fstat(fd, &s) != 0) { + xf86DrvMsg(-1, X_ERROR, + "stat %s\n", strerror(errno)); + return FALSE; + } + + return (S_ISREG(s.st_mode)); +} + +static void +fbdev_rf_guess_resolution(__u32 size, __u16 *x, __u16 *y) { + /* TODO: guess resolution from file size */ + *x = 1280; + *y = 1024; +} + +static void +fbdev_rf_fake(fbdevHWPtr fPtr) { + struct stat s; + __u16 x, y; + int i; + + if (fstat(fPtr->fd, &s) != 0) { + xf86DrvMsg(-1, X_ERROR, + "stat: %s\n", strerror(errno)); + return; + } + + fbdev_rf_guess_resolution(s.st_size, &x, &y); + + strncpy(fPtr->fix.id, "HU RF FB", 16); + fPtr->fix.smem_start = 0; + fPtr->fix.smem_len = s.st_size; + fPtr->fix.type = FB_TYPE_PACKED_PIXELS; + fPtr->fix.type_aux = 0; + fPtr->fix.visual = FB_VISUAL_TRUECOLOR; + fPtr->fix.xpanstep = 0; + fPtr->fix.ypanstep = 0; + fPtr->fix.ywrapstep = 0; + fPtr->fix.line_length = x; + fPtr->fix.mmio_start = 0; + fPtr->fix.mmio_len = s.st_size; + fPtr->fix.accel = FB_ACCEL_NONE; + for (i=0; i<3; i++) + fPtr->fix.reserved[i] = 0; + + fPtr->var.xres = x; + fPtr->var.yres = y; + fPtr->var.xres_virtual = x; + fPtr->var.yres_virtual = y; + fPtr->var.xoffset = 0; + fPtr->var.yoffset = 0; + fPtr->var.bits_per_pixel = 32; + fPtr->var.grayscale = 0; + /* fPtr->var.red = ?; */ + /* fPtr->var.green = ?; */ + /* fPtr->var.blue = ?; */ + /* fPtr->var.transp = ?; */ + fPtr->var.nonstd = 0; + fPtr->var.activate = FB_ACTIVATE_NOW; + fPtr->var.height = -1; + fPtr->var.width = -1; + fPtr->var.accel_flags = 0; + fPtr->var.pixclock = 0; + fPtr->var.left_margin = 0; + fPtr->var.right_margin = 0; + fPtr->var.upper_margin = 0; + fPtr->var.lower_margin = 0; + fPtr->var.hsync_len = 0; + fPtr->var.vsync_len = 0; + fPtr->var.sync = 0; + fPtr->var.vmode = 0; + for (i=0; i<6; i++) + fPtr->var.reserved[i] = 0; +} + static int fbdev_open(int scrnIndex, char *dev, char** namep) { @@ -330,15 +413,21 @@ fbdev_open(int scrnIndex, char *dev, char** namep) } if (namep) { + if (fbdev_detect_rf(fd)) { + // HU: return virtual name + *namep = xnfalloc(16); + strncpy(*namep,"HU RFFB",16); + } else { if (-1 == ioctl(fd,FBIOGET_FSCREENINFO,(void*)(&fix))) { - *namep = NULL; - xf86DrvMsg(scrnIndex, X_ERROR, - "FBIOGET_FSCREENINFO: %s\n", strerror(errno)); - return -1; + *namep = NULL; + xf86DrvMsg(scrnIndex, X_ERROR, + "(pos 414) FBIOGET_FSCREENINFO: %s\n", strerror(errno)); + return -1; } else { - *namep = xnfalloc(16); - strncpy(*namep,fix.id,16); + *namep = xnfalloc(16); + strncpy(*namep,fix.id,16); } + } } return fd; } @@ -370,10 +459,12 @@ fbdevHWInit(ScrnInfoPtr pScrn, struct pci_device * pPci, char *device) fPtr = FBDEVHWPTR(pScrn); /* open device */ - if (pPci) + if (pPci) { fPtr->fd = fbdev_open_pci(pPci,NULL); - else + } else { fPtr->fd = fbdev_open(pScrn->scrnIndex,device,NULL); + fPtr->rf = fbdev_detect_rf(fPtr->fd); + } if (-1 == fPtr->fd) { xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Failed to open framebuffer device, consult warnings" @@ -384,20 +475,26 @@ fbdevHWInit(ScrnInfoPtr pScrn, struct pci_device * pPci, char *device) } /* 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; + if (fPtr->rf) { // HU + fbdev_rf_fake(fPtr); + fbdev_rf_fake(fPtr); + } else { + if (-1 == ioctl(fPtr->fd,FBIOGET_FSCREENINFO,(void*)(&fPtr->fix))) { + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + "(484) 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; + } } /* we can use the current settings as "buildin mode" */ + /* TODOHU: disable/add own buildin mode ... or supply correct fb var info */ fbdev2xfree_timing(&fPtr->var, &fPtr->buildin); fPtr->buildin.name = "current"; fPtr->buildin.next = &fPtr->buildin; @@ -470,6 +567,9 @@ fbdevHWSetMode(ScrnInfoPtr pScrn, DisplayModePtr mode, Bool check) #endif set_var = req_var; + if (fPtr->rf) + return TRUE; /* HU: assume only allowed builtin modes are passed */ + /* TODOHU: check for illegal modes */ if (check) set_var.activate = FB_ACTIVATE_TEST; @@ -634,6 +734,16 @@ fbdevHWMapMMIO(ScrnInfoPtr pScrn) fbdevHWPtr fPtr = FBDEVHWPTR(pScrn); if (NULL == fPtr->mmio) { + if (fPtr->rf) { + /* HU: own mmap */ + fPtr->mmio = mmap(NULL, fPtr->mmio_len, PROT_READ | PROT_WRITE, + MAP_SHARED, fPtr->fd, 0); + if (-1 == (long)fPtr->mmio) { + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + "mmap mmio: %s\n", strerror(errno)); + fPtr->mmio = NULL; + } + } else { /* tell the kernel not to use accels to speed up console scrolling */ fPtr->var.accel_flags = 0; if (0 != ioctl(fPtr->fd,FBIOPUT_VSCREENINFO,(void*)(&fPtr->var))) { @@ -654,6 +764,7 @@ fbdevHWMapMMIO(ScrnInfoPtr pScrn) fPtr->mmio = NULL; } else fPtr->mmio += mmio_off; + } } return fPtr->mmio; } @@ -687,17 +798,20 @@ fbdevHWModeInit(ScrnInfoPtr pScrn, DisplayModePtr mode) return FALSE; /* read back */ - if (0 != ioctl(fPtr->fd,FBIOGET_FSCREENINFO,(void*)(&fPtr->fix))) { - xf86DrvMsg(pScrn->scrnIndex, X_ERROR, - "FBIOGET_FSCREENINFO: %s\n", strerror(errno)); - return FALSE; - } - if (0 != ioctl(fPtr->fd,FBIOGET_VSCREENINFO,(void*)(&fPtr->var))) { - xf86DrvMsg(pScrn->scrnIndex, X_ERROR, - "FBIOGET_VSCREENINFO: %s\n", strerror(errno)); - return FALSE; + if (!fPtr->rf) { /* HU: skip check; we can't change fb anyway */ + if (0 != ioctl(fPtr->fd,FBIOGET_FSCREENINFO,(void*)(&fPtr->fix))) { + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + "(pos 804) FBIOGET_FSCREENINFO: %s\n", strerror(errno)); + return FALSE; + } + if (0 != ioctl(fPtr->fd,FBIOGET_VSCREENINFO,(void*)(&fPtr->var))) { + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + "FBIOGET_VSCREENINFO: %s\n", strerror(errno)); + return FALSE; + } } + /* TODOHU: good question .. try to skip */ if (pScrn->defaultVisual == TrueColor || pScrn->defaultVisual == DirectColor) { /* XXX: This is a hack, but it should be a NOP for all the setups that @@ -720,7 +834,9 @@ void fbdevHWSave(ScrnInfoPtr pScrn) { fbdevHWPtr fPtr = FBDEVHWPTR(pScrn); - + + if (!fPtr->rf) /* HU */ + return; if (0 != ioctl(fPtr->fd,FBIOGET_VSCREENINFO,(void*)(&fPtr->saved_var))) xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "FBIOGET_VSCREENINFO: %s\n", strerror(errno)); @@ -731,6 +847,8 @@ fbdevHWRestore(ScrnInfoPtr pScrn) { fbdevHWPtr fPtr = FBDEVHWPTR(pScrn); + if (!fPtr->rf) /* HU */ + return; if (0 != ioctl(fPtr->fd,FBIOPUT_VSCREENINFO,(void*)(&fPtr->saved_var))) xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "FBIOPUT_VSCREENINFO: %s\n", strerror(errno)); @@ -748,6 +866,8 @@ fbdevHWLoadPalette(ScrnInfoPtr pScrn, int numColors, int *indices, unsigned short red,green,blue; int i; + if (!fPtr->rf) /* HU */ + return; cmap.len = 1; cmap.red = &red; cmap.green = &green; @@ -802,6 +922,9 @@ fbdevHWAdjustFrame(int scrnIndex, int x, int y, int flags) if ( x < 0 || x + fPtr->var.xres > fPtr->var.xres_virtual || y < 0 || y + fPtr->var.yres > fPtr->var.yres_virtual ) return; + if (!fPtr->rf) /* HU */ + return; + /* TODOHU: ignore ... maybe fail/log if offset != 0*/ fPtr->var.xoffset = x; fPtr->var.yoffset = y; @@ -835,6 +958,8 @@ fbdevHWDPMSSet(ScrnInfoPtr pScrn, int mode, int flags) fbdevHWPtr fPtr = FBDEVHWPTR(pScrn); unsigned long fbmode; + if (!fPtr->rf) /* HU */ + return; if (!pScrn->vtSema) return; @@ -867,6 +992,8 @@ fbdevHWSaveScreen(ScreenPtr pScreen, int mode) fbdevHWPtr fPtr = FBDEVHWPTR(pScrn); unsigned long unblank; + if (!fPtr->rf) /* HU */ + return TRUE; if (!pScrn->vtSema) return TRUE; |