summaryrefslogtreecommitdiff
path: root/hw/xfree86/fbdevhw/fbdevhw.c
diff options
context:
space:
mode:
Diffstat (limited to 'hw/xfree86/fbdevhw/fbdevhw.c')
-rw-r--r--hw/xfree86/fbdevhw/fbdevhw.c185
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;
contact: Jan Huwald // Impressum