1706f2543Smrg/* all driver need this */ 2706f2543Smrg#ifdef HAVE_XORG_CONFIG_H 3706f2543Smrg#include <xorg-config.h> 4706f2543Smrg#endif 5706f2543Smrg 6706f2543Smrg#include <string.h> 7706f2543Smrg 8706f2543Smrg#include "xf86.h" 9706f2543Smrg#include "xf86Modes.h" 10706f2543Smrg#include "xf86_OSproc.h" 11706f2543Smrg 12706f2543Smrg/* pci stuff */ 13706f2543Smrg#include "xf86PciInfo.h" 14706f2543Smrg#include "xf86Pci.h" 15706f2543Smrg 16706f2543Smrg#include "xf86cmap.h" 17706f2543Smrg 18706f2543Smrg#include "fbdevhw.h" 19706f2543Smrg#include "fbpriv.h" 20706f2543Smrg#include "globals.h" 21706f2543Smrg#include <X11/extensions/dpmsconst.h> 22706f2543Smrg 23706f2543Smrg#define PAGE_MASK (~(getpagesize() - 1)) 24706f2543Smrg 25706f2543Smrgstatic XF86ModuleVersionInfo fbdevHWVersRec = 26706f2543Smrg{ 27706f2543Smrg "fbdevhw", 28706f2543Smrg MODULEVENDORSTRING, 29706f2543Smrg MODINFOSTRING1, 30706f2543Smrg MODINFOSTRING2, 31706f2543Smrg XORG_VERSION_CURRENT, 32706f2543Smrg 0, 0, 2, 33706f2543Smrg ABI_CLASS_VIDEODRV, 34706f2543Smrg ABI_VIDEODRV_VERSION, 35706f2543Smrg MOD_CLASS_NONE, 36706f2543Smrg {0,0,0,0} 37706f2543Smrg}; 38706f2543Smrg 39706f2543Smrg_X_EXPORT XF86ModuleData fbdevhwModuleData = { 40706f2543Smrg &fbdevHWVersRec, 41706f2543Smrg NULL, 42706f2543Smrg NULL 43706f2543Smrg}; 44706f2543Smrg 45706f2543Smrg#include <fcntl.h> 46706f2543Smrg#include <errno.h> 47706f2543Smrg#include <sys/mman.h> 48706f2543Smrg#include <sys/ioctl.h> 49706f2543Smrg#include <stdio.h> 50706f2543Smrg#include <stdlib.h> 51706f2543Smrg#include <unistd.h> 52706f2543Smrg#include <string.h> 53706f2543Smrg 54706f2543Smrg/* -------------------------------------------------------------------- */ 55706f2543Smrg/* our private data, and two functions to allocate/free this */ 56706f2543Smrg 57706f2543Smrg#define FBDEVHWPTRLVAL(p) (p)->privates[fbdevHWPrivateIndex].ptr 58706f2543Smrg#define FBDEVHWPTR(p) ((fbdevHWPtr)(FBDEVHWPTRLVAL(p))) 59706f2543Smrg 60706f2543Smrgstatic int fbdevHWPrivateIndex = -1; 61706f2543Smrg 62706f2543Smrgtypedef struct { 63706f2543Smrg /* framebuffer device: filename (/dev/fb*), handle, more */ 64706f2543Smrg char* device; 65706f2543Smrg int fd; 66706f2543Smrg void* fbmem; 67706f2543Smrg unsigned int fbmem_len; 68706f2543Smrg unsigned int fboff; 69706f2543Smrg char* mmio; 70706f2543Smrg unsigned int mmio_len; 71706f2543Smrg 72706f2543Smrg /* current hardware state */ 73706f2543Smrg struct fb_fix_screeninfo fix; 74706f2543Smrg struct fb_var_screeninfo var; 75706f2543Smrg 76706f2543Smrg /* saved video mode */ 77706f2543Smrg struct fb_var_screeninfo saved_var; 78706f2543Smrg 79706f2543Smrg /* buildin video mode */ 80706f2543Smrg DisplayModeRec buildin; 81706f2543Smrg 82706f2543Smrg} fbdevHWRec, *fbdevHWPtr; 83706f2543Smrg 84706f2543SmrgBool 85706f2543SmrgfbdevHWGetRec(ScrnInfoPtr pScrn) 86706f2543Smrg{ 87706f2543Smrg fbdevHWPtr fPtr; 88706f2543Smrg 89706f2543Smrg if (fbdevHWPrivateIndex < 0) 90706f2543Smrg fbdevHWPrivateIndex = xf86AllocateScrnInfoPrivateIndex(); 91706f2543Smrg 92706f2543Smrg if (FBDEVHWPTR(pScrn) != NULL) 93706f2543Smrg return TRUE; 94706f2543Smrg 95706f2543Smrg fPtr = FBDEVHWPTRLVAL(pScrn) = xnfcalloc(sizeof(fbdevHWRec), 1); 96706f2543Smrg return TRUE; 97706f2543Smrg} 98706f2543Smrg 99706f2543Smrgvoid 100706f2543SmrgfbdevHWFreeRec(ScrnInfoPtr pScrn) 101706f2543Smrg{ 102706f2543Smrg if (fbdevHWPrivateIndex < 0) 103706f2543Smrg return; 104706f2543Smrg if (FBDEVHWPTR(pScrn) == NULL) 105706f2543Smrg return; 106706f2543Smrg free(FBDEVHWPTR(pScrn)); 107706f2543Smrg FBDEVHWPTRLVAL(pScrn) = NULL; 108706f2543Smrg} 109706f2543Smrg 110706f2543Smrgint 111706f2543SmrgfbdevHWGetFD(ScrnInfoPtr pScrn) 112706f2543Smrg{ 113706f2543Smrg fbdevHWPtr fPtr; 114706f2543Smrg 115706f2543Smrg fbdevHWGetRec(pScrn); 116706f2543Smrg fPtr = FBDEVHWPTR(pScrn); 117706f2543Smrg 118706f2543Smrg return fPtr->fd; 119706f2543Smrg} 120706f2543Smrg 121706f2543Smrg/* -------------------------------------------------------------------- */ 122706f2543Smrg/* some helpers for printing debug informations */ 123706f2543Smrg 124706f2543Smrg#if DEBUG 125706f2543Smrgstatic void 126706f2543Smrgprint_fbdev_mode(char *txt, struct fb_var_screeninfo *var) 127706f2543Smrg{ 128706f2543Smrg ErrorF( "fbdev %s mode:\t%d %d %d %d %d %d %d %d %d %d %d:%d:%d\n", 129706f2543Smrg txt,var->pixclock, 130706f2543Smrg var->xres, var->right_margin, var->hsync_len, var->left_margin, 131706f2543Smrg var->yres, var->lower_margin, var->vsync_len, var->upper_margin, 132706f2543Smrg var->bits_per_pixel, 133706f2543Smrg var->red.length, var->green.length, var->blue.length); 134706f2543Smrg} 135706f2543Smrg 136706f2543Smrgstatic void 137706f2543Smrgprint_xfree_mode(char *txt, DisplayModePtr mode) 138706f2543Smrg{ 139706f2543Smrg ErrorF( "xfree %s mode:\t%d %d %d %d %d %d %d %d %d\n", 140706f2543Smrg txt,mode->Clock, 141706f2543Smrg mode->HDisplay, mode->HSyncStart, mode->HSyncEnd, mode->HTotal, 142706f2543Smrg mode->VDisplay, mode->VSyncStart, mode->VSyncEnd, mode->VTotal); 143706f2543Smrg} 144706f2543Smrg#endif 145706f2543Smrg 146706f2543Smrg/* -------------------------------------------------------------------- */ 147706f2543Smrg/* Convert timings between the XFree and the Frame Buffer Device */ 148706f2543Smrg 149706f2543Smrgstatic void 150706f2543Smrgxfree2fbdev_fblayout(ScrnInfoPtr pScrn, struct fb_var_screeninfo *var) 151706f2543Smrg{ 152706f2543Smrg var->xres_virtual = pScrn->displayWidth ? pScrn->displayWidth : 153706f2543Smrg pScrn->virtualX; 154706f2543Smrg var->yres_virtual = pScrn->virtualY; 155706f2543Smrg var->bits_per_pixel = pScrn->bitsPerPixel; 156706f2543Smrg if (pScrn->defaultVisual == TrueColor || 157706f2543Smrg pScrn->defaultVisual == DirectColor) { 158706f2543Smrg var->red.length = pScrn->weight.red; 159706f2543Smrg var->green.length = pScrn->weight.green; 160706f2543Smrg var->blue.length = pScrn->weight.blue; 161706f2543Smrg } else { 162706f2543Smrg var->red.length = 8; 163706f2543Smrg var->green.length = 8; 164706f2543Smrg var->blue.length = 8; 165706f2543Smrg } 166706f2543Smrg} 167706f2543Smrg 168706f2543Smrgstatic void 169706f2543Smrgxfree2fbdev_timing(DisplayModePtr mode, struct fb_var_screeninfo *var) 170706f2543Smrg{ 171706f2543Smrg var->xres = mode->HDisplay; 172706f2543Smrg var->yres = mode->VDisplay; 173706f2543Smrg if (var->xres_virtual < var->xres) 174706f2543Smrg var->xres_virtual = var->xres; 175706f2543Smrg if (var->yres_virtual < var->yres) 176706f2543Smrg var->yres_virtual = var->yres; 177706f2543Smrg var->xoffset = var->yoffset = 0; 178706f2543Smrg var->pixclock = mode->Clock ? 1000000000/mode->Clock : 0; 179706f2543Smrg var->right_margin = mode->HSyncStart-mode->HDisplay; 180706f2543Smrg var->hsync_len = mode->HSyncEnd-mode->HSyncStart; 181706f2543Smrg var->left_margin = mode->HTotal-mode->HSyncEnd; 182706f2543Smrg var->lower_margin = mode->VSyncStart-mode->VDisplay; 183706f2543Smrg var->vsync_len = mode->VSyncEnd-mode->VSyncStart; 184706f2543Smrg var->upper_margin = mode->VTotal-mode->VSyncEnd; 185706f2543Smrg var->sync = 0; 186706f2543Smrg if (mode->Flags & V_PHSYNC) 187706f2543Smrg var->sync |= FB_SYNC_HOR_HIGH_ACT; 188706f2543Smrg if (mode->Flags & V_PVSYNC) 189706f2543Smrg var->sync |= FB_SYNC_VERT_HIGH_ACT; 190706f2543Smrg if (mode->Flags & V_PCSYNC) 191706f2543Smrg var->sync |= FB_SYNC_COMP_HIGH_ACT; 192706f2543Smrg if (mode->Flags & V_BCAST) 193706f2543Smrg var->sync |= FB_SYNC_BROADCAST; 194706f2543Smrg if (mode->Flags & V_INTERLACE) 195706f2543Smrg var->vmode = FB_VMODE_INTERLACED; 196706f2543Smrg else if (mode->Flags & V_DBLSCAN) 197706f2543Smrg var->vmode = FB_VMODE_DOUBLE; 198706f2543Smrg else 199706f2543Smrg var->vmode = FB_VMODE_NONINTERLACED; 200706f2543Smrg} 201706f2543Smrg 202706f2543Smrgstatic Bool 203706f2543Smrgfbdev_modes_equal(struct fb_var_screeninfo *set, struct fb_var_screeninfo *req) 204706f2543Smrg{ 205706f2543Smrg return (set->xres_virtual >= req->xres_virtual && 206706f2543Smrg set->yres_virtual >= req->yres_virtual && 207706f2543Smrg set->bits_per_pixel == req->bits_per_pixel && 208706f2543Smrg set->red.length == req->red.length && 209706f2543Smrg set->green.length == req->green.length && 210706f2543Smrg set->blue.length == req->blue.length && 211706f2543Smrg set->xres == req->xres && set->yres == req->yres && 212706f2543Smrg set->right_margin == req->right_margin && 213706f2543Smrg set->hsync_len == req->hsync_len && 214706f2543Smrg set->left_margin == req->left_margin && 215706f2543Smrg set->lower_margin == req->lower_margin && 216706f2543Smrg set->vsync_len == req->vsync_len && 217706f2543Smrg set->upper_margin == req->upper_margin && 218706f2543Smrg set->sync == req->sync && set->vmode == req->vmode); 219706f2543Smrg} 220706f2543Smrg 221706f2543Smrgstatic void 222706f2543Smrgfbdev2xfree_timing(struct fb_var_screeninfo *var, DisplayModePtr mode) 223706f2543Smrg{ 224706f2543Smrg mode->Clock = var->pixclock ? 1000000000/var->pixclock : 0; 225706f2543Smrg mode->HDisplay = var->xres; 226706f2543Smrg mode->HSyncStart = mode->HDisplay+var->right_margin; 227706f2543Smrg mode->HSyncEnd = mode->HSyncStart+var->hsync_len; 228706f2543Smrg mode->HTotal = mode->HSyncEnd+var->left_margin; 229706f2543Smrg mode->VDisplay = var->yres; 230706f2543Smrg mode->VSyncStart = mode->VDisplay+var->lower_margin; 231706f2543Smrg mode->VSyncEnd = mode->VSyncStart+var->vsync_len; 232706f2543Smrg mode->VTotal = mode->VSyncEnd+var->upper_margin; 233706f2543Smrg mode->Flags = 0; 234706f2543Smrg mode->Flags |= var->sync & FB_SYNC_HOR_HIGH_ACT ? V_PHSYNC : V_NHSYNC; 235706f2543Smrg mode->Flags |= var->sync & FB_SYNC_VERT_HIGH_ACT ? V_PVSYNC : V_NVSYNC; 236706f2543Smrg mode->Flags |= var->sync & FB_SYNC_COMP_HIGH_ACT ? V_PCSYNC : V_NCSYNC; 237706f2543Smrg if (var->sync & FB_SYNC_BROADCAST) 238706f2543Smrg mode->Flags |= V_BCAST; 239706f2543Smrg if ((var->vmode & FB_VMODE_MASK) == FB_VMODE_INTERLACED) 240706f2543Smrg mode->Flags |= V_INTERLACE; 241706f2543Smrg else if ((var->vmode & FB_VMODE_MASK) == FB_VMODE_DOUBLE) 242706f2543Smrg mode->Flags |= V_DBLSCAN; 243706f2543Smrg mode->SynthClock = mode->Clock; 244706f2543Smrg mode->CrtcHDisplay = mode->HDisplay; 245706f2543Smrg mode->CrtcHSyncStart = mode->HSyncStart; 246706f2543Smrg mode->CrtcHSyncEnd = mode->HSyncEnd; 247706f2543Smrg mode->CrtcHTotal = mode->HTotal; 248706f2543Smrg mode->CrtcVDisplay = mode->VDisplay; 249706f2543Smrg mode->CrtcVSyncStart = mode->VSyncStart; 250706f2543Smrg mode->CrtcVSyncEnd = mode->VSyncEnd; 251706f2543Smrg mode->CrtcVTotal = mode->VTotal; 252706f2543Smrg mode->CrtcHAdjusted = FALSE; 253706f2543Smrg mode->CrtcVAdjusted = FALSE; 254706f2543Smrg} 255706f2543Smrg 256706f2543Smrg 257706f2543Smrg/* -------------------------------------------------------------------- */ 258706f2543Smrg/* open correct framebuffer device */ 259706f2543Smrg 260706f2543Smrg/** 261706f2543Smrg * Try to find the framebuffer device for a given PCI device 262706f2543Smrg */ 263706f2543Smrgstatic int 264706f2543Smrgfbdev_open_pci(struct pci_device * pPci, char **namep) 265706f2543Smrg{ 266706f2543Smrg struct fb_fix_screeninfo fix; 267706f2543Smrg char filename[256]; 268706f2543Smrg int fd, i; 269706f2543Smrg 270706f2543Smrg for (i = 0; i < 8; i++) { 271706f2543Smrg sprintf(filename, 272706f2543Smrg "/sys/bus/pci/devices/%04x:%02x:%02x.%d/graphics/fb%d", 273706f2543Smrg pPci->domain, pPci->bus, pPci->dev, pPci->func, i); 274706f2543Smrg 275706f2543Smrg fd = open(filename, O_RDONLY, 0); 276706f2543Smrg if (fd < 0) { 277706f2543Smrg sprintf(filename, 278706f2543Smrg "/sys/bus/pci/devices/%04x:%02x:%02x.%d/graphics:fb%d", 279706f2543Smrg pPci->domain, pPci->bus, pPci->dev, pPci->func, i); 280706f2543Smrg fd = open(filename, O_RDONLY, 0); 281706f2543Smrg } 282706f2543Smrg if (fd >= 0) { 283706f2543Smrg close(fd); 284706f2543Smrg sprintf(filename, "/dev/fb%d", i); 285706f2543Smrg 286706f2543Smrg fd = open(filename, O_RDWR, 0); 287706f2543Smrg if (fd != -1) { 288706f2543Smrg if (ioctl(fd, FBIOGET_FSCREENINFO, (void*) & fix) != -1) { 289706f2543Smrg if (namep) { 290706f2543Smrg *namep = xnfalloc(16); 291706f2543Smrg strncpy(*namep,fix.id,16); 292706f2543Smrg } 293706f2543Smrg 294706f2543Smrg return fd; 295706f2543Smrg } 296706f2543Smrg close(fd); 297706f2543Smrg } 298706f2543Smrg } 299706f2543Smrg } 300706f2543Smrg 301706f2543Smrg if (namep) 302706f2543Smrg *namep = NULL; 303706f2543Smrg 304706f2543Smrg xf86DrvMsg(-1, X_ERROR, "Unable to find a valid framebuffer device\n"); 305706f2543Smrg return -1; 306706f2543Smrg} 307706f2543Smrg 308706f2543Smrgstatic int 309706f2543Smrgfbdev_open(int scrnIndex, char *dev, char** namep) 310706f2543Smrg{ 311706f2543Smrg struct fb_fix_screeninfo fix; 312706f2543Smrg int fd; 313706f2543Smrg 314706f2543Smrg /* try argument (from XF86Config) first */ 315706f2543Smrg if (dev) { 316706f2543Smrg fd = open(dev,O_RDWR,0); 317706f2543Smrg } else { 318706f2543Smrg /* second: environment variable */ 319706f2543Smrg dev = getenv("FRAMEBUFFER"); 320706f2543Smrg if ((NULL == dev) || ((fd = open(dev,O_RDWR,0)) == -1)) { 321706f2543Smrg /* last try: default device */ 322706f2543Smrg dev = "/dev/fb0"; 323706f2543Smrg fd = open(dev,O_RDWR,0); 324706f2543Smrg } 325706f2543Smrg } 326706f2543Smrg 327706f2543Smrg if (fd == -1) { 328706f2543Smrg xf86DrvMsg(scrnIndex, X_ERROR, 329706f2543Smrg "open %s: %s\n", dev, strerror(errno)); 330706f2543Smrg return -1; 331706f2543Smrg } 332706f2543Smrg 333706f2543Smrg if (namep) { 334706f2543Smrg if (-1 == ioctl(fd,FBIOGET_FSCREENINFO,(void*)(&fix))) { 335706f2543Smrg *namep = NULL; 336706f2543Smrg xf86DrvMsg(scrnIndex, X_ERROR, 337706f2543Smrg "FBIOGET_FSCREENINFO: %s\n", strerror(errno)); 338706f2543Smrg return -1; 339706f2543Smrg } else { 340706f2543Smrg *namep = xnfalloc(16); 341706f2543Smrg strncpy(*namep,fix.id,16); 342706f2543Smrg } 343706f2543Smrg } 344706f2543Smrg return fd; 345706f2543Smrg} 346706f2543Smrg 347706f2543Smrg/* -------------------------------------------------------------------- */ 348706f2543Smrg 349706f2543SmrgBool 350706f2543SmrgfbdevHWProbe(struct pci_device * pPci, char *device,char **namep) 351706f2543Smrg{ 352706f2543Smrg int fd; 353706f2543Smrg 354706f2543Smrg if (pPci) 355706f2543Smrg fd = fbdev_open_pci(pPci,namep); 356706f2543Smrg else 357706f2543Smrg fd = fbdev_open(-1,device,namep); 358706f2543Smrg 359706f2543Smrg if (-1 == fd) 360706f2543Smrg return FALSE; 361706f2543Smrg close(fd); 362706f2543Smrg return TRUE; 363706f2543Smrg} 364706f2543Smrg 365706f2543SmrgBool 366706f2543SmrgfbdevHWInit(ScrnInfoPtr pScrn, struct pci_device * pPci, char *device) 367706f2543Smrg{ 368706f2543Smrg fbdevHWPtr fPtr; 369706f2543Smrg 370706f2543Smrg fbdevHWGetRec(pScrn); 371706f2543Smrg fPtr = FBDEVHWPTR(pScrn); 372706f2543Smrg 373706f2543Smrg /* open device */ 374706f2543Smrg if (pPci) 375706f2543Smrg fPtr->fd = fbdev_open_pci(pPci,NULL); 376706f2543Smrg else 377706f2543Smrg fPtr->fd = fbdev_open(pScrn->scrnIndex,device,NULL); 378706f2543Smrg if (-1 == fPtr->fd) { 379706f2543Smrg xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 380706f2543Smrg "Failed to open framebuffer device, consult warnings" 381706f2543Smrg " and/or errors above for possible reasons\n" 382706f2543Smrg "\t(you may have to look at the server log to see" 383706f2543Smrg " warnings)\n"); 384706f2543Smrg return FALSE; 385706f2543Smrg } 386706f2543Smrg 387706f2543Smrg /* get current fb device settings */ 388706f2543Smrg if (-1 == ioctl(fPtr->fd,FBIOGET_FSCREENINFO,(void*)(&fPtr->fix))) { 389706f2543Smrg xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 390706f2543Smrg "ioctl FBIOGET_FSCREENINFO: %s\n", 391706f2543Smrg strerror(errno)); 392706f2543Smrg return FALSE; 393706f2543Smrg } 394706f2543Smrg if (-1 == ioctl(fPtr->fd,FBIOGET_VSCREENINFO,(void*)(&fPtr->var))) { 395706f2543Smrg xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 396706f2543Smrg "ioctl FBIOGET_VSCREENINFO: %s\n", 397706f2543Smrg strerror(errno)); 398706f2543Smrg return FALSE; 399706f2543Smrg } 400706f2543Smrg 401706f2543Smrg /* we can use the current settings as "buildin mode" */ 402706f2543Smrg fbdev2xfree_timing(&fPtr->var, &fPtr->buildin); 403706f2543Smrg fPtr->buildin.name = "current"; 404706f2543Smrg fPtr->buildin.next = &fPtr->buildin; 405706f2543Smrg fPtr->buildin.prev = &fPtr->buildin; 406706f2543Smrg fPtr->buildin.type |= M_T_BUILTIN; 407706f2543Smrg 408706f2543Smrg return TRUE; 409706f2543Smrg} 410706f2543Smrg 411706f2543Smrgchar* 412706f2543SmrgfbdevHWGetName(ScrnInfoPtr pScrn) 413706f2543Smrg{ 414706f2543Smrg fbdevHWPtr fPtr = FBDEVHWPTR(pScrn); 415706f2543Smrg return fPtr->fix.id; 416706f2543Smrg} 417706f2543Smrg 418706f2543Smrgint 419706f2543SmrgfbdevHWGetDepth(ScrnInfoPtr pScrn, int *fbbpp) 420706f2543Smrg{ 421706f2543Smrg fbdevHWPtr fPtr = FBDEVHWPTR(pScrn); 422706f2543Smrg 423706f2543Smrg if (fbbpp) 424706f2543Smrg *fbbpp = fPtr->var.bits_per_pixel; 425706f2543Smrg 426706f2543Smrg if (fPtr->fix.visual == FB_VISUAL_TRUECOLOR || 427706f2543Smrg fPtr->fix.visual == FB_VISUAL_DIRECTCOLOR) 428706f2543Smrg return fPtr->var.red.length+fPtr->var.green.length+ 429706f2543Smrg fPtr->var.blue.length; 430706f2543Smrg else 431706f2543Smrg return fPtr->var.bits_per_pixel; 432706f2543Smrg} 433706f2543Smrg 434706f2543Smrgint 435706f2543SmrgfbdevHWGetLineLength(ScrnInfoPtr pScrn) 436706f2543Smrg{ 437706f2543Smrg fbdevHWPtr fPtr = FBDEVHWPTR(pScrn); 438706f2543Smrg 439706f2543Smrg if (fPtr->fix.line_length) 440706f2543Smrg return fPtr->fix.line_length; 441706f2543Smrg else 442706f2543Smrg return fPtr->var.xres_virtual*fPtr->var.bits_per_pixel/8; 443706f2543Smrg} 444706f2543Smrg 445706f2543Smrgint 446706f2543SmrgfbdevHWGetType(ScrnInfoPtr pScrn) 447706f2543Smrg{ 448706f2543Smrg fbdevHWPtr fPtr = FBDEVHWPTR(pScrn); 449706f2543Smrg return fPtr->fix.type; 450706f2543Smrg} 451706f2543Smrg 452706f2543Smrgint 453706f2543SmrgfbdevHWGetVidmem(ScrnInfoPtr pScrn) 454706f2543Smrg{ 455706f2543Smrg fbdevHWPtr fPtr = FBDEVHWPTR(pScrn); 456706f2543Smrg return fPtr->fix.smem_len; 457706f2543Smrg} 458706f2543Smrg 459706f2543Smrgstatic Bool 460706f2543SmrgfbdevHWSetMode(ScrnInfoPtr pScrn, DisplayModePtr mode, Bool check) 461706f2543Smrg{ 462706f2543Smrg fbdevHWPtr fPtr = FBDEVHWPTR(pScrn); 463706f2543Smrg struct fb_var_screeninfo req_var = fPtr->var, set_var; 464706f2543Smrg 465706f2543Smrg xfree2fbdev_fblayout(pScrn, &req_var); 466706f2543Smrg xfree2fbdev_timing(mode, &req_var); 467706f2543Smrg 468706f2543Smrg#if DEBUG 469706f2543Smrg print_xfree_mode("init", mode); 470706f2543Smrg print_fbdev_mode("init", &req_var); 471706f2543Smrg#endif 472706f2543Smrg 473706f2543Smrg set_var = req_var; 474706f2543Smrg 475706f2543Smrg if (check) 476706f2543Smrg set_var.activate = FB_ACTIVATE_TEST; 477706f2543Smrg 478706f2543Smrg if (0 != ioctl(fPtr->fd, FBIOPUT_VSCREENINFO, (void*)(&set_var))) { 479706f2543Smrg xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 480706f2543Smrg "FBIOPUT_VSCREENINFO: %s\n", strerror(errno)); 481706f2543Smrg return FALSE; 482706f2543Smrg } 483706f2543Smrg 484706f2543Smrg if (!fbdev_modes_equal(&set_var, &req_var)) { 485706f2543Smrg if (!check) 486706f2543Smrg xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 487706f2543Smrg "FBIOPUT_VSCREENINFO succeeded but modified " 488706f2543Smrg "mode\n"); 489706f2543Smrg#if DEBUG 490706f2543Smrg print_fbdev_mode("returned", &set_var); 491706f2543Smrg#endif 492706f2543Smrg return FALSE; 493706f2543Smrg } 494706f2543Smrg 495706f2543Smrg if (!check) 496706f2543Smrg fPtr->var = set_var; 497706f2543Smrg 498706f2543Smrg return TRUE; 499706f2543Smrg} 500706f2543Smrg 501706f2543Smrgvoid 502706f2543SmrgfbdevHWSetVideoModes(ScrnInfoPtr pScrn) 503706f2543Smrg{ 504706f2543Smrg char **modename; 505706f2543Smrg DisplayModePtr mode,this,last = pScrn->modes; 506706f2543Smrg 507706f2543Smrg if (NULL == pScrn->display->modes) 508706f2543Smrg return; 509706f2543Smrg 510706f2543Smrg pScrn->virtualX = pScrn->display->virtualX; 511706f2543Smrg pScrn->virtualY = pScrn->display->virtualY; 512706f2543Smrg 513706f2543Smrg for (modename = pScrn->display->modes; *modename != NULL; modename++) { 514706f2543Smrg for (mode = pScrn->monitor->Modes; mode != NULL; mode = mode->next) { 515706f2543Smrg if (0 == strcmp(mode->name,*modename)) { 516706f2543Smrg if (fbdevHWSetMode(pScrn, mode, TRUE)) 517706f2543Smrg break; 518706f2543Smrg 519706f2543Smrg xf86DrvMsg(pScrn->scrnIndex, X_INFO, 520706f2543Smrg "\tmode \"%s\" test failed\n", *modename); 521706f2543Smrg } 522706f2543Smrg } 523706f2543Smrg 524706f2543Smrg if (NULL == mode) { 525706f2543Smrg xf86DrvMsg(pScrn->scrnIndex, X_INFO, 526706f2543Smrg "\tmode \"%s\" not found\n", *modename); 527706f2543Smrg continue; 528706f2543Smrg } 529706f2543Smrg 530706f2543Smrg xf86DrvMsg(pScrn->scrnIndex, X_INFO, 531706f2543Smrg "\tmode \"%s\" ok\n", *modename); 532706f2543Smrg 533706f2543Smrg if (pScrn->virtualX < mode->HDisplay) 534706f2543Smrg pScrn->virtualX = mode->HDisplay; 535706f2543Smrg if (pScrn->virtualY < mode->VDisplay) 536706f2543Smrg pScrn->virtualY = mode->VDisplay; 537706f2543Smrg 538706f2543Smrg if (NULL == pScrn->modes) { 539706f2543Smrg this = pScrn->modes = xf86DuplicateMode(mode); 540706f2543Smrg this->next = this; 541706f2543Smrg this->prev = this; 542706f2543Smrg } else { 543706f2543Smrg this = xf86DuplicateMode(mode); 544706f2543Smrg this->next = pScrn->modes; 545706f2543Smrg this->prev = last; 546706f2543Smrg last->next = this; 547706f2543Smrg pScrn->modes->prev = this; 548706f2543Smrg } 549706f2543Smrg last = this; 550706f2543Smrg } 551706f2543Smrg} 552706f2543Smrg 553706f2543SmrgDisplayModePtr 554706f2543SmrgfbdevHWGetBuildinMode(ScrnInfoPtr pScrn) 555706f2543Smrg{ 556706f2543Smrg fbdevHWPtr fPtr = FBDEVHWPTR(pScrn); 557706f2543Smrg return &fPtr->buildin; 558706f2543Smrg} 559706f2543Smrg 560706f2543Smrgvoid 561706f2543SmrgfbdevHWUseBuildinMode(ScrnInfoPtr pScrn) 562706f2543Smrg{ 563706f2543Smrg fbdevHWPtr fPtr = FBDEVHWPTR(pScrn); 564706f2543Smrg 565706f2543Smrg pScrn->modes = &fPtr->buildin; 566706f2543Smrg pScrn->virtualX = pScrn->display->virtualX; 567706f2543Smrg pScrn->virtualY = pScrn->display->virtualY; 568706f2543Smrg if (pScrn->virtualX < fPtr->buildin.HDisplay) 569706f2543Smrg pScrn->virtualX = fPtr->buildin.HDisplay; 570706f2543Smrg if (pScrn->virtualY < fPtr->buildin.VDisplay) 571706f2543Smrg pScrn->virtualY = fPtr->buildin.VDisplay; 572706f2543Smrg} 573706f2543Smrg 574706f2543Smrg/* -------------------------------------------------------------------- */ 575706f2543Smrg 576706f2543Smrgstatic void 577706f2543SmrgcalculateFbmem_len(fbdevHWPtr fPtr) 578706f2543Smrg{ 579706f2543Smrg fPtr->fboff = (unsigned long) fPtr->fix.smem_start & ~PAGE_MASK; 580706f2543Smrg fPtr->fbmem_len = (fPtr->fboff+fPtr->fix.smem_len+~PAGE_MASK) & 581706f2543Smrg PAGE_MASK; 582706f2543Smrg} 583706f2543Smrg 584706f2543Smrg 585706f2543Smrgvoid* 586706f2543SmrgfbdevHWMapVidmem(ScrnInfoPtr pScrn) 587706f2543Smrg{ 588706f2543Smrg fbdevHWPtr fPtr = FBDEVHWPTR(pScrn); 589706f2543Smrg 590706f2543Smrg if (NULL == fPtr->fbmem) { 591706f2543Smrg calculateFbmem_len(fPtr); 592706f2543Smrg fPtr->fbmem = mmap(NULL, fPtr->fbmem_len, PROT_READ | PROT_WRITE, 593706f2543Smrg MAP_SHARED, fPtr->fd, 0); 594706f2543Smrg if (-1 == (long)fPtr->fbmem) { 595706f2543Smrg xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 596706f2543Smrg "mmap fbmem: %s\n", strerror(errno)); 597706f2543Smrg fPtr->fbmem = NULL; 598706f2543Smrg } else { 599706f2543Smrg /* Perhaps we'd better add fboff to fbmem and return 0 in 600706f2543Smrg fbdevHWLinearOffset()? Of course we then need to mask 601706f2543Smrg fPtr->fbmem with PAGE_MASK in fbdevHWUnmapVidmem() as 602706f2543Smrg well. [geert] */ 603706f2543Smrg } 604706f2543Smrg } 605706f2543Smrg pScrn->memPhysBase = (unsigned long)fPtr->fix.smem_start & (unsigned long)(PAGE_MASK); 606706f2543Smrg pScrn->fbOffset = (unsigned long)fPtr->fix.smem_start & (unsigned long)(~PAGE_MASK); 607706f2543Smrg return fPtr->fbmem; 608706f2543Smrg} 609706f2543Smrg 610706f2543Smrgint 611706f2543SmrgfbdevHWLinearOffset(ScrnInfoPtr pScrn) 612706f2543Smrg{ 613706f2543Smrg fbdevHWPtr fPtr = FBDEVHWPTR(pScrn); 614706f2543Smrg 615706f2543Smrg return fPtr->fboff; 616706f2543Smrg} 617706f2543Smrg 618706f2543SmrgBool 619706f2543SmrgfbdevHWUnmapVidmem(ScrnInfoPtr pScrn) 620706f2543Smrg{ 621706f2543Smrg fbdevHWPtr fPtr = FBDEVHWPTR(pScrn); 622706f2543Smrg 623706f2543Smrg if (NULL != fPtr->fbmem) { 624706f2543Smrg if (-1 == munmap(fPtr->fbmem, fPtr->fbmem_len)) 625706f2543Smrg xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 626706f2543Smrg "munmap fbmem: %s\n", strerror(errno)); 627706f2543Smrg fPtr->fbmem = NULL; 628706f2543Smrg } 629706f2543Smrg return TRUE; 630706f2543Smrg} 631706f2543Smrg 632706f2543Smrgvoid* 633706f2543SmrgfbdevHWMapMMIO(ScrnInfoPtr pScrn) 634706f2543Smrg{ 635706f2543Smrg unsigned int mmio_off; 636706f2543Smrg 637706f2543Smrg fbdevHWPtr fPtr = FBDEVHWPTR(pScrn); 638706f2543Smrg 639706f2543Smrg if (NULL == fPtr->mmio) { 640706f2543Smrg /* tell the kernel not to use accels to speed up console scrolling */ 641706f2543Smrg fPtr->var.accel_flags = 0; 642706f2543Smrg if (0 != ioctl(fPtr->fd,FBIOPUT_VSCREENINFO,(void*)(&fPtr->var))) { 643706f2543Smrg xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 644706f2543Smrg "FBIOPUT_VSCREENINFO: %s\n", strerror(errno)); 645706f2543Smrg return FALSE; 646706f2543Smrg } 647706f2543Smrg mmio_off = (unsigned long) fPtr->fix.mmio_start & ~PAGE_MASK; 648706f2543Smrg fPtr->mmio_len = (mmio_off+fPtr->fix.mmio_len+~PAGE_MASK) & 649706f2543Smrg PAGE_MASK; 650706f2543Smrg if (NULL == fPtr->fbmem) 651706f2543Smrg calculateFbmem_len(fPtr); 652706f2543Smrg fPtr->mmio = mmap(NULL, fPtr->mmio_len, PROT_READ | PROT_WRITE, 653706f2543Smrg MAP_SHARED, fPtr->fd, fPtr->fbmem_len); 654706f2543Smrg if (-1 == (long)fPtr->mmio) { 655706f2543Smrg xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 656706f2543Smrg "mmap mmio: %s\n", strerror(errno)); 657706f2543Smrg fPtr->mmio = NULL; 658706f2543Smrg } else 659706f2543Smrg fPtr->mmio += mmio_off; 660706f2543Smrg } 661706f2543Smrg return fPtr->mmio; 662706f2543Smrg} 663706f2543Smrg 664706f2543SmrgBool 665706f2543SmrgfbdevHWUnmapMMIO(ScrnInfoPtr pScrn) 666706f2543Smrg{ 667706f2543Smrg fbdevHWPtr fPtr = FBDEVHWPTR(pScrn); 668706f2543Smrg 669706f2543Smrg if (NULL != fPtr->mmio) { 670706f2543Smrg if (-1 == munmap((void *)((unsigned long)fPtr->mmio & PAGE_MASK), fPtr->mmio_len)) 671706f2543Smrg xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 672706f2543Smrg "munmap mmio: %s\n", strerror(errno)); 673706f2543Smrg fPtr->mmio = NULL; 674706f2543Smrg /* FIXME: restore var.accel_flags [geert] */ 675706f2543Smrg } 676706f2543Smrg return TRUE; 677706f2543Smrg} 678706f2543Smrg 679706f2543Smrg/* -------------------------------------------------------------------- */ 680706f2543Smrg 681706f2543SmrgBool 682706f2543SmrgfbdevHWModeInit(ScrnInfoPtr pScrn, DisplayModePtr mode) 683706f2543Smrg{ 684706f2543Smrg fbdevHWPtr fPtr = FBDEVHWPTR(pScrn); 685706f2543Smrg 686706f2543Smrg pScrn->vtSema = TRUE; 687706f2543Smrg 688706f2543Smrg /* set */ 689706f2543Smrg if (!fbdevHWSetMode(pScrn, mode, FALSE)) 690706f2543Smrg return FALSE; 691706f2543Smrg 692706f2543Smrg /* read back */ 693706f2543Smrg if (0 != ioctl(fPtr->fd,FBIOGET_FSCREENINFO,(void*)(&fPtr->fix))) { 694706f2543Smrg xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 695706f2543Smrg "FBIOGET_FSCREENINFO: %s\n", strerror(errno)); 696706f2543Smrg return FALSE; 697706f2543Smrg } 698706f2543Smrg if (0 != ioctl(fPtr->fd,FBIOGET_VSCREENINFO,(void*)(&fPtr->var))) { 699706f2543Smrg xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 700706f2543Smrg "FBIOGET_VSCREENINFO: %s\n", strerror(errno)); 701706f2543Smrg return FALSE; 702706f2543Smrg } 703706f2543Smrg 704706f2543Smrg if (pScrn->defaultVisual == TrueColor || 705706f2543Smrg pScrn->defaultVisual == DirectColor) { 706706f2543Smrg /* XXX: This is a hack, but it should be a NOP for all the setups that 707706f2543Smrg * worked before and actually seems to fix some others... 708706f2543Smrg */ 709706f2543Smrg pScrn->offset.red = fPtr->var.red.offset; 710706f2543Smrg pScrn->offset.green = fPtr->var.green.offset; 711706f2543Smrg pScrn->offset.blue = fPtr->var.blue.offset; 712706f2543Smrg pScrn->mask.red = ((1 << fPtr->var.red.length) - 1) << fPtr->var.red.offset; 713706f2543Smrg pScrn->mask.green = ((1 << fPtr->var.green.length) - 1) << fPtr->var.green.offset; 714706f2543Smrg pScrn->mask.blue = ((1 << fPtr->var.blue.length) - 1) << fPtr->var.blue.offset; 715706f2543Smrg } 716706f2543Smrg 717706f2543Smrg return TRUE; 718706f2543Smrg} 719706f2543Smrg 720706f2543Smrg/* -------------------------------------------------------------------- */ 721706f2543Smrg/* video mode save/restore */ 722706f2543Smrgvoid 723706f2543SmrgfbdevHWSave(ScrnInfoPtr pScrn) 724706f2543Smrg{ 725706f2543Smrg fbdevHWPtr fPtr = FBDEVHWPTR(pScrn); 726706f2543Smrg 727706f2543Smrg if (0 != ioctl(fPtr->fd,FBIOGET_VSCREENINFO,(void*)(&fPtr->saved_var))) 728706f2543Smrg xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 729706f2543Smrg "FBIOGET_VSCREENINFO: %s\n", strerror(errno)); 730706f2543Smrg} 731706f2543Smrg 732706f2543Smrgvoid 733706f2543SmrgfbdevHWRestore(ScrnInfoPtr pScrn) 734706f2543Smrg{ 735706f2543Smrg fbdevHWPtr fPtr = FBDEVHWPTR(pScrn); 736706f2543Smrg 737706f2543Smrg if (0 != ioctl(fPtr->fd,FBIOPUT_VSCREENINFO,(void*)(&fPtr->saved_var))) 738706f2543Smrg xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 739706f2543Smrg "FBIOPUT_VSCREENINFO: %s\n", strerror(errno)); 740706f2543Smrg} 741706f2543Smrg 742706f2543Smrg/* -------------------------------------------------------------------- */ 743706f2543Smrg/* callback for xf86HandleColormaps */ 744706f2543Smrg 745706f2543Smrgvoid 746706f2543SmrgfbdevHWLoadPalette(ScrnInfoPtr pScrn, int numColors, int *indices, 747706f2543Smrg LOCO *colors, VisualPtr pVisual) 748706f2543Smrg{ 749706f2543Smrg fbdevHWPtr fPtr = FBDEVHWPTR(pScrn); 750706f2543Smrg struct fb_cmap cmap; 751706f2543Smrg unsigned short red,green,blue; 752706f2543Smrg int i; 753706f2543Smrg 754706f2543Smrg cmap.len = 1; 755706f2543Smrg cmap.red = &red; 756706f2543Smrg cmap.green = &green; 757706f2543Smrg cmap.blue = &blue; 758706f2543Smrg cmap.transp = NULL; 759706f2543Smrg for (i = 0; i < numColors; i++) { 760706f2543Smrg cmap.start = indices[i]; 761706f2543Smrg red = (colors[indices[i]].red << 8) | 762706f2543Smrg colors[indices[i]].red; 763706f2543Smrg green = (colors[indices[i]].green << 8) | 764706f2543Smrg colors[indices[i]].green; 765706f2543Smrg blue = (colors[indices[i]].blue << 8) | 766706f2543Smrg colors[indices[i]].blue; 767706f2543Smrg if (-1 == ioctl(fPtr->fd,FBIOPUTCMAP,(void*)&cmap)) 768706f2543Smrg xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 769706f2543Smrg "FBIOPUTCMAP: %s\n", strerror(errno)); 770706f2543Smrg } 771706f2543Smrg} 772706f2543Smrg 773706f2543Smrg/* -------------------------------------------------------------------- */ 774706f2543Smrg/* these can be hooked directly into ScrnInfoRec */ 775706f2543Smrg 776706f2543SmrgModeStatus 777706f2543SmrgfbdevHWValidMode(int scrnIndex, DisplayModePtr mode, Bool verbose, int flags) 778706f2543Smrg{ 779706f2543Smrg ScrnInfoPtr pScrn = xf86Screens[scrnIndex]; 780706f2543Smrg 781706f2543Smrg if (!fbdevHWSetMode(pScrn, mode, TRUE)) 782706f2543Smrg return MODE_BAD; 783706f2543Smrg 784706f2543Smrg return MODE_OK; 785706f2543Smrg} 786706f2543Smrg 787706f2543SmrgBool 788706f2543SmrgfbdevHWSwitchMode(int scrnIndex, DisplayModePtr mode, int flags) 789706f2543Smrg{ 790706f2543Smrg ScrnInfoPtr pScrn = xf86Screens[scrnIndex]; 791706f2543Smrg 792706f2543Smrg 793706f2543Smrg if (!fbdevHWSetMode(pScrn, mode, FALSE)) 794706f2543Smrg return FALSE; 795706f2543Smrg 796706f2543Smrg return TRUE; 797706f2543Smrg} 798706f2543Smrg 799706f2543Smrgvoid 800706f2543SmrgfbdevHWAdjustFrame(int scrnIndex, int x, int y, int flags) 801706f2543Smrg{ 802706f2543Smrg ScrnInfoPtr pScrn = xf86Screens[scrnIndex]; 803706f2543Smrg fbdevHWPtr fPtr = FBDEVHWPTR(pScrn); 804706f2543Smrg 805706f2543Smrg if ( x < 0 || x + fPtr->var.xres > fPtr->var.xres_virtual || 806706f2543Smrg y < 0 || y + fPtr->var.yres > fPtr->var.yres_virtual ) 807706f2543Smrg return; 808706f2543Smrg 809706f2543Smrg fPtr->var.xoffset = x; 810706f2543Smrg fPtr->var.yoffset = y; 811706f2543Smrg if (-1 == ioctl(fPtr->fd,FBIOPAN_DISPLAY,(void*)&fPtr->var)) 812706f2543Smrg xf86DrvMsgVerb(scrnIndex, X_WARNING, 5, 813706f2543Smrg "FBIOPAN_DISPLAY: %s\n", strerror(errno)); 814706f2543Smrg} 815706f2543Smrg 816706f2543SmrgBool 817706f2543SmrgfbdevHWEnterVT(int scrnIndex, int flags) 818706f2543Smrg{ 819706f2543Smrg ScrnInfoPtr pScrn = xf86Screens[scrnIndex]; 820706f2543Smrg 821706f2543Smrg if (!fbdevHWModeInit(pScrn, pScrn->currentMode)) 822706f2543Smrg return FALSE; 823706f2543Smrg fbdevHWAdjustFrame(scrnIndex, pScrn->frameX0, pScrn->frameY0, 0); 824706f2543Smrg return TRUE; 825706f2543Smrg} 826706f2543Smrg 827706f2543Smrgvoid 828706f2543SmrgfbdevHWLeaveVT(int scrnIndex, int flags) 829706f2543Smrg{ 830706f2543Smrg ScrnInfoPtr pScrn = xf86Screens[scrnIndex]; 831706f2543Smrg 832706f2543Smrg fbdevHWRestore(pScrn); 833706f2543Smrg} 834706f2543Smrg 835706f2543Smrgvoid 836706f2543SmrgfbdevHWDPMSSet(ScrnInfoPtr pScrn, int mode, int flags) 837706f2543Smrg{ 838706f2543Smrg fbdevHWPtr fPtr = FBDEVHWPTR(pScrn); 839706f2543Smrg unsigned long fbmode; 840706f2543Smrg 841706f2543Smrg if (!pScrn->vtSema) 842706f2543Smrg return; 843706f2543Smrg 844706f2543Smrg switch (mode) { 845706f2543Smrg case DPMSModeOn: 846706f2543Smrg fbmode = 0; 847706f2543Smrg break; 848706f2543Smrg case DPMSModeStandby: 849706f2543Smrg fbmode = 2; 850706f2543Smrg break; 851706f2543Smrg case DPMSModeSuspend: 852706f2543Smrg fbmode = 3; 853706f2543Smrg break; 854706f2543Smrg case DPMSModeOff: 855706f2543Smrg fbmode = 4; 856706f2543Smrg break; 857706f2543Smrg default: 858706f2543Smrg return; 859706f2543Smrg } 860706f2543Smrg 861706f2543Smrg if (-1 == ioctl(fPtr->fd, FBIOBLANK, (void *)fbmode)) 862706f2543Smrg xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 863706f2543Smrg "FBIOBLANK: %s\n", strerror(errno)); 864706f2543Smrg} 865706f2543Smrg 866706f2543SmrgBool 867706f2543SmrgfbdevHWSaveScreen(ScreenPtr pScreen, int mode) 868706f2543Smrg{ 869706f2543Smrg ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; 870706f2543Smrg fbdevHWPtr fPtr = FBDEVHWPTR(pScrn); 871706f2543Smrg unsigned long unblank; 872706f2543Smrg 873706f2543Smrg if (!pScrn->vtSema) 874706f2543Smrg return TRUE; 875706f2543Smrg 876706f2543Smrg unblank = xf86IsUnblank(mode); 877706f2543Smrg 878706f2543Smrg if (-1 == ioctl(fPtr->fd, FBIOBLANK, (void *)(1-unblank))) { 879706f2543Smrg xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 880706f2543Smrg "FBIOBLANK: %s\n", strerror(errno)); 881706f2543Smrg return FALSE; 882706f2543Smrg } 883706f2543Smrg 884706f2543Smrg return TRUE; 885706f2543Smrg} 886706f2543Smrg 887706f2543Smrgxf86SwitchModeProc * 888706f2543SmrgfbdevHWSwitchModeWeak(void) { return fbdevHWSwitchMode; } 889706f2543Smrg 890706f2543Smrgxf86AdjustFrameProc * 891706f2543SmrgfbdevHWAdjustFrameWeak(void) { return fbdevHWAdjustFrame; } 892706f2543Smrg 893706f2543Smrgxf86EnterVTProc * 894706f2543SmrgfbdevHWEnterVTWeak(void) { return fbdevHWEnterVT; } 895706f2543Smrg 896706f2543Smrgxf86LeaveVTProc * 897706f2543SmrgfbdevHWLeaveVTWeak(void) { return fbdevHWLeaveVT; } 898706f2543Smrg 899706f2543Smrgxf86ValidModeProc * 900706f2543SmrgfbdevHWValidModeWeak(void) { return fbdevHWValidMode; } 901706f2543Smrg 902706f2543Smrgxf86DPMSSetProc * 903706f2543SmrgfbdevHWDPMSSetWeak(void) { return fbdevHWDPMSSet; } 904706f2543Smrg 905706f2543Smrgxf86LoadPaletteProc * 906706f2543SmrgfbdevHWLoadPaletteWeak(void) { return fbdevHWLoadPalette; } 907706f2543Smrg 908706f2543SmrgSaveScreenProcPtr 909706f2543SmrgfbdevHWSaveScreenWeak(void) { return fbdevHWSaveScreen; } 910