1 /* all driver need this */
2 #ifdef HAVE_XORG_CONFIG_H
3 #include <xorg-config.h>
10 #include "xf86_OSproc.h"
20 #include <X11/extensions/dpmsconst.h>
22 #define PAGE_MASK (~(getpagesize() - 1))
24 static XF86ModuleVersionInfo fbdevHWVersRec
= {
37 _X_EXPORT XF86ModuleData fbdevhwModuleData
= {
46 #include <sys/ioctl.h>
51 /* -------------------------------------------------------------------- */
52 /* our private data, and two functions to allocate/free this */
54 #define FBDEVHWPTRLVAL(p) (p)->privates[fbdevHWPrivateIndex].ptr
55 #define FBDEVHWPTR(p) ((fbdevHWPtr)(FBDEVHWPTRLVAL(p)))
57 static int fbdevHWPrivateIndex
= -1;
60 /* framebuffer device: filename (/dev/fb*), handle, more */
64 unsigned int fbmem_len
;
67 unsigned int mmio_len
;
69 /* current hardware state */
70 struct fb_fix_screeninfo fix
;
71 struct fb_var_screeninfo var
;
73 /* saved video mode */
74 struct fb_var_screeninfo saved_var
;
76 /* buildin video mode */
77 DisplayModeRec buildin
;
79 } fbdevHWRec
, *fbdevHWPtr
;
82 fbdevHWGetRec(ScrnInfoPtr pScrn
)
86 if (fbdevHWPrivateIndex
< 0)
87 fbdevHWPrivateIndex
= xf86AllocateScrnInfoPrivateIndex();
89 if (FBDEVHWPTR(pScrn
) != NULL
)
92 fPtr
= FBDEVHWPTRLVAL(pScrn
) = xnfcalloc(sizeof(fbdevHWRec
), 1);
97 fbdevHWFreeRec(ScrnInfoPtr pScrn
)
99 if (fbdevHWPrivateIndex
< 0)
101 free(FBDEVHWPTR(pScrn
));
102 FBDEVHWPTRLVAL(pScrn
) = NULL
;
106 fbdevHWGetFD(ScrnInfoPtr pScrn
)
110 fbdevHWGetRec(pScrn
);
111 fPtr
= FBDEVHWPTR(pScrn
);
116 /* -------------------------------------------------------------------- */
117 /* some helpers for printing debug informations */
121 print_fbdev_mode(char *txt
, struct fb_var_screeninfo
*var
)
123 ErrorF("fbdev %s mode:\t%d %d %d %d %d %d %d %d %d %d %d:%d:%d\n",
125 var
->xres
, var
->right_margin
, var
->hsync_len
, var
->left_margin
,
126 var
->yres
, var
->lower_margin
, var
->vsync_len
, var
->upper_margin
,
128 var
->red
.length
, var
->green
.length
, var
->blue
.length
);
132 print_xfree_mode(char *txt
, DisplayModePtr mode
)
134 ErrorF("xfree %s mode:\t%d %d %d %d %d %d %d %d %d\n",
136 mode
->HDisplay
, mode
->HSyncStart
, mode
->HSyncEnd
, mode
->HTotal
,
137 mode
->VDisplay
, mode
->VSyncStart
, mode
->VSyncEnd
, mode
->VTotal
);
141 /* -------------------------------------------------------------------- */
142 /* Convert timings between the XFree and the Frame Buffer Device */
145 xfree2fbdev_fblayout(ScrnInfoPtr pScrn
, struct fb_var_screeninfo
*var
)
147 var
->xres_virtual
= pScrn
->displayWidth
? pScrn
->displayWidth
:
149 var
->yres_virtual
= pScrn
->virtualY
;
150 var
->bits_per_pixel
= pScrn
->bitsPerPixel
;
151 if (pScrn
->defaultVisual
== TrueColor
||
152 pScrn
->defaultVisual
== DirectColor
) {
153 var
->red
.length
= pScrn
->weight
.red
;
154 var
->green
.length
= pScrn
->weight
.green
;
155 var
->blue
.length
= pScrn
->weight
.blue
;
159 var
->green
.length
= 8;
160 var
->blue
.length
= 8;
165 xfree2fbdev_timing(DisplayModePtr mode
, struct fb_var_screeninfo
*var
)
167 var
->xres
= mode
->HDisplay
;
168 var
->yres
= mode
->VDisplay
;
169 if (var
->xres_virtual
< var
->xres
)
170 var
->xres_virtual
= var
->xres
;
171 if (var
->yres_virtual
< var
->yres
)
172 var
->yres_virtual
= var
->yres
;
173 var
->xoffset
= var
->yoffset
= 0;
174 var
->pixclock
= mode
->Clock
? 1000000000 / mode
->Clock
: 0;
175 var
->right_margin
= mode
->HSyncStart
- mode
->HDisplay
;
176 var
->hsync_len
= mode
->HSyncEnd
- mode
->HSyncStart
;
177 var
->left_margin
= mode
->HTotal
- mode
->HSyncEnd
;
178 var
->lower_margin
= mode
->VSyncStart
- mode
->VDisplay
;
179 var
->vsync_len
= mode
->VSyncEnd
- mode
->VSyncStart
;
180 var
->upper_margin
= mode
->VTotal
- mode
->VSyncEnd
;
182 if (mode
->Flags
& V_PHSYNC
)
183 var
->sync
|= FB_SYNC_HOR_HIGH_ACT
;
184 if (mode
->Flags
& V_PVSYNC
)
185 var
->sync
|= FB_SYNC_VERT_HIGH_ACT
;
186 if (mode
->Flags
& V_PCSYNC
)
187 var
->sync
|= FB_SYNC_COMP_HIGH_ACT
;
188 if (mode
->Flags
& V_BCAST
)
189 var
->sync
|= FB_SYNC_BROADCAST
;
190 if (mode
->Flags
& V_INTERLACE
)
191 var
->vmode
= FB_VMODE_INTERLACED
;
192 else if (mode
->Flags
& V_DBLSCAN
)
193 var
->vmode
= FB_VMODE_DOUBLE
;
195 var
->vmode
= FB_VMODE_NONINTERLACED
;
199 fbdev_modes_equal(struct fb_var_screeninfo
*set
, struct fb_var_screeninfo
*req
)
201 return (set
->xres_virtual
>= req
->xres_virtual
&&
202 set
->yres_virtual
>= req
->yres_virtual
&&
203 set
->bits_per_pixel
== req
->bits_per_pixel
&&
204 set
->red
.length
== req
->red
.length
&&
205 set
->green
.length
== req
->green
.length
&&
206 set
->blue
.length
== req
->blue
.length
&&
207 set
->xres
== req
->xres
&& set
->yres
== req
->yres
&&
208 set
->right_margin
== req
->right_margin
&&
209 set
->hsync_len
== req
->hsync_len
&&
210 set
->left_margin
== req
->left_margin
&&
211 set
->lower_margin
== req
->lower_margin
&&
212 set
->vsync_len
== req
->vsync_len
&&
213 set
->upper_margin
== req
->upper_margin
&&
214 set
->sync
== req
->sync
&& set
->vmode
== req
->vmode
);
218 fbdev2xfree_timing(struct fb_var_screeninfo
*var
, DisplayModePtr mode
)
220 mode
->Clock
= var
->pixclock
? 1000000000 / var
->pixclock
: 0;
221 mode
->HDisplay
= var
->xres
;
222 mode
->HSyncStart
= mode
->HDisplay
+ var
->right_margin
;
223 mode
->HSyncEnd
= mode
->HSyncStart
+ var
->hsync_len
;
224 mode
->HTotal
= mode
->HSyncEnd
+ var
->left_margin
;
225 mode
->VDisplay
= var
->yres
;
226 mode
->VSyncStart
= mode
->VDisplay
+ var
->lower_margin
;
227 mode
->VSyncEnd
= mode
->VSyncStart
+ var
->vsync_len
;
228 mode
->VTotal
= mode
->VSyncEnd
+ var
->upper_margin
;
230 mode
->Flags
|= var
->sync
& FB_SYNC_HOR_HIGH_ACT
? V_PHSYNC
: V_NHSYNC
;
231 mode
->Flags
|= var
->sync
& FB_SYNC_VERT_HIGH_ACT
? V_PVSYNC
: V_NVSYNC
;
232 mode
->Flags
|= var
->sync
& FB_SYNC_COMP_HIGH_ACT
? V_PCSYNC
: V_NCSYNC
;
233 if (var
->sync
& FB_SYNC_BROADCAST
)
234 mode
->Flags
|= V_BCAST
;
235 if ((var
->vmode
& FB_VMODE_MASK
) == FB_VMODE_INTERLACED
)
236 mode
->Flags
|= V_INTERLACE
;
237 else if ((var
->vmode
& FB_VMODE_MASK
) == FB_VMODE_DOUBLE
)
238 mode
->Flags
|= V_DBLSCAN
;
239 mode
->SynthClock
= mode
->Clock
;
240 mode
->CrtcHDisplay
= mode
->HDisplay
;
241 mode
->CrtcHSyncStart
= mode
->HSyncStart
;
242 mode
->CrtcHSyncEnd
= mode
->HSyncEnd
;
243 mode
->CrtcHTotal
= mode
->HTotal
;
244 mode
->CrtcVDisplay
= mode
->VDisplay
;
245 mode
->CrtcVSyncStart
= mode
->VSyncStart
;
246 mode
->CrtcVSyncEnd
= mode
->VSyncEnd
;
247 mode
->CrtcVTotal
= mode
->VTotal
;
248 mode
->CrtcHAdjusted
= FALSE
;
249 mode
->CrtcVAdjusted
= FALSE
;
252 /* -------------------------------------------------------------------- */
253 /* open correct framebuffer device */
256 * Try to find the framebuffer device for a given PCI device
259 fbdev_open_pci(struct pci_device
*pPci
, char **namep
)
261 struct fb_fix_screeninfo fix
;
265 for (i
= 0; i
< 8; i
++) {
266 snprintf(filename
, sizeof(filename
),
267 "/sys/bus/pci/devices/%04x:%02x:%02x.%d/graphics/fb%d",
268 pPci
->domain
, pPci
->bus
, pPci
->dev
, pPci
->func
, i
);
270 fd
= open(filename
, O_RDONLY
, 0);
272 snprintf(filename
, sizeof(filename
),
273 "/sys/bus/pci/devices/%04x:%02x:%02x.%d/graphics:fb%d",
274 pPci
->domain
, pPci
->bus
, pPci
->dev
, pPci
->func
, i
);
275 fd
= open(filename
, O_RDONLY
, 0);
279 snprintf(filename
, sizeof(filename
), "/dev/fb%d", i
);
281 fd
= open(filename
, O_RDWR
, 0);
283 if (ioctl(fd
, FBIOGET_FSCREENINFO
, (void *) &fix
) != -1) {
285 *namep
= xnfalloc(16);
286 strncpy(*namep
, fix
.id
, 16);
299 xf86DrvMsg(-1, X_ERROR
, "Unable to find a valid framebuffer device\n");
304 fbdev_open(int scrnIndex
, char *dev
, char **namep
)
306 struct fb_fix_screeninfo fix
;
309 /* try argument (from XF86Config) first */
311 fd
= open(dev
, O_RDWR
, 0);
314 /* second: environment variable */
315 dev
= getenv("FRAMEBUFFER");
316 if ((NULL
== dev
) || ((fd
= open(dev
, O_RDWR
, 0)) == -1)) {
317 /* last try: default device */
319 fd
= open(dev
, O_RDWR
, 0);
324 xf86DrvMsg(scrnIndex
, X_ERROR
, "open %s: %s\n", dev
, strerror(errno
));
329 if (-1 == ioctl(fd
, FBIOGET_FSCREENINFO
, (void *) (&fix
))) {
331 xf86DrvMsg(scrnIndex
, X_ERROR
,
332 "FBIOGET_FSCREENINFO: %s\n", strerror(errno
));
336 *namep
= xnfalloc(16);
337 strncpy(*namep
, fix
.id
, 16);
343 /* -------------------------------------------------------------------- */
346 fbdevHWProbe(struct pci_device
*pPci
, char *device
, char **namep
)
351 fd
= fbdev_open_pci(pPci
, namep
);
353 fd
= fbdev_open(-1, device
, namep
);
362 fbdevHWInit(ScrnInfoPtr pScrn
, struct pci_device
*pPci
, char *device
)
366 fbdevHWGetRec(pScrn
);
367 fPtr
= FBDEVHWPTR(pScrn
);
371 fPtr
->fd
= fbdev_open_pci(pPci
, NULL
);
373 fPtr
->fd
= fbdev_open(pScrn
->scrnIndex
, device
, NULL
);
374 if (-1 == fPtr
->fd
) {
375 xf86DrvMsg(pScrn
->scrnIndex
, X_ERROR
,
376 "Failed to open framebuffer device, consult warnings"
377 " and/or errors above for possible reasons\n"
378 "\t(you may have to look at the server log to see"
383 /* get current fb device settings */
384 if (-1 == ioctl(fPtr
->fd
, FBIOGET_FSCREENINFO
, (void *) (&fPtr
->fix
))) {
385 xf86DrvMsg(pScrn
->scrnIndex
, X_ERROR
,
386 "ioctl FBIOGET_FSCREENINFO: %s\n", strerror(errno
));
389 if (-1 == ioctl(fPtr
->fd
, FBIOGET_VSCREENINFO
, (void *) (&fPtr
->var
))) {
390 xf86DrvMsg(pScrn
->scrnIndex
, X_ERROR
,
391 "ioctl FBIOGET_VSCREENINFO: %s\n", strerror(errno
));
395 /* we can use the current settings as "buildin mode" */
396 fbdev2xfree_timing(&fPtr
->var
, &fPtr
->buildin
);
397 fPtr
->buildin
.name
= "current";
398 fPtr
->buildin
.next
= &fPtr
->buildin
;
399 fPtr
->buildin
.prev
= &fPtr
->buildin
;
400 fPtr
->buildin
.type
|= M_T_BUILTIN
;
406 fbdevHWGetName(ScrnInfoPtr pScrn
)
408 fbdevHWPtr fPtr
= FBDEVHWPTR(pScrn
);
414 fbdevHWGetDepth(ScrnInfoPtr pScrn
, int *fbbpp
)
416 fbdevHWPtr fPtr
= FBDEVHWPTR(pScrn
);
419 *fbbpp
= fPtr
->var
.bits_per_pixel
;
421 if (fPtr
->fix
.visual
== FB_VISUAL_TRUECOLOR
||
422 fPtr
->fix
.visual
== FB_VISUAL_DIRECTCOLOR
)
423 return fPtr
->var
.red
.length
+ fPtr
->var
.green
.length
+
424 fPtr
->var
.blue
.length
;
426 return fPtr
->var
.bits_per_pixel
;
430 fbdevHWGetLineLength(ScrnInfoPtr pScrn
)
432 fbdevHWPtr fPtr
= FBDEVHWPTR(pScrn
);
434 if (fPtr
->fix
.line_length
)
435 return fPtr
->fix
.line_length
;
437 return fPtr
->var
.xres_virtual
* fPtr
->var
.bits_per_pixel
/ 8;
441 fbdevHWGetType(ScrnInfoPtr pScrn
)
443 fbdevHWPtr fPtr
= FBDEVHWPTR(pScrn
);
445 return fPtr
->fix
.type
;
449 fbdevHWGetVidmem(ScrnInfoPtr pScrn
)
451 fbdevHWPtr fPtr
= FBDEVHWPTR(pScrn
);
453 return fPtr
->fix
.smem_len
;
457 fbdevHWSetMode(ScrnInfoPtr pScrn
, DisplayModePtr mode
, Bool check
)
459 fbdevHWPtr fPtr
= FBDEVHWPTR(pScrn
);
460 struct fb_var_screeninfo req_var
= fPtr
->var
, set_var
;
462 xfree2fbdev_fblayout(pScrn
, &req_var
);
463 xfree2fbdev_timing(mode
, &req_var
);
466 print_xfree_mode("init", mode
);
467 print_fbdev_mode("init", &req_var
);
473 set_var
.activate
= FB_ACTIVATE_TEST
;
475 if (0 != ioctl(fPtr
->fd
, FBIOPUT_VSCREENINFO
, (void *) (&set_var
))) {
476 xf86DrvMsg(pScrn
->scrnIndex
, X_ERROR
,
477 "FBIOPUT_VSCREENINFO: %s\n", strerror(errno
));
481 if (!fbdev_modes_equal(&set_var
, &req_var
)) {
483 xf86DrvMsg(pScrn
->scrnIndex
, X_ERROR
,
484 "FBIOPUT_VSCREENINFO succeeded but modified " "mode\n");
486 print_fbdev_mode("returned", &set_var
);
498 fbdevHWSetVideoModes(ScrnInfoPtr pScrn
)
501 DisplayModePtr mode
, this, last
= pScrn
->modes
;
503 if (NULL
== pScrn
->display
->modes
)
506 pScrn
->virtualX
= pScrn
->display
->virtualX
;
507 pScrn
->virtualY
= pScrn
->display
->virtualY
;
509 for (modename
= pScrn
->display
->modes
; *modename
!= NULL
; modename
++) {
510 for (mode
= pScrn
->monitor
->Modes
; mode
!= NULL
; mode
= mode
->next
) {
511 if (0 == strcmp(mode
->name
, *modename
)) {
512 if (fbdevHWSetMode(pScrn
, mode
, TRUE
))
515 xf86DrvMsg(pScrn
->scrnIndex
, X_INFO
,
516 "\tmode \"%s\" test failed\n", *modename
);
521 xf86DrvMsg(pScrn
->scrnIndex
, X_INFO
,
522 "\tmode \"%s\" not found\n", *modename
);
526 xf86DrvMsg(pScrn
->scrnIndex
, X_INFO
, "\tmode \"%s\" ok\n", *modename
);
528 if (pScrn
->virtualX
< mode
->HDisplay
)
529 pScrn
->virtualX
= mode
->HDisplay
;
530 if (pScrn
->virtualY
< mode
->VDisplay
)
531 pScrn
->virtualY
= mode
->VDisplay
;
533 if (NULL
== pScrn
->modes
) {
534 this = pScrn
->modes
= xf86DuplicateMode(mode
);
539 this = xf86DuplicateMode(mode
);
540 this->next
= pScrn
->modes
;
543 pScrn
->modes
->prev
= this;
550 fbdevHWGetBuildinMode(ScrnInfoPtr pScrn
)
552 fbdevHWPtr fPtr
= FBDEVHWPTR(pScrn
);
554 return &fPtr
->buildin
;
558 fbdevHWUseBuildinMode(ScrnInfoPtr pScrn
)
560 fbdevHWPtr fPtr
= FBDEVHWPTR(pScrn
);
562 pScrn
->modes
= &fPtr
->buildin
;
563 pScrn
->virtualX
= pScrn
->display
->virtualX
;
564 pScrn
->virtualY
= pScrn
->display
->virtualY
;
565 if (pScrn
->virtualX
< fPtr
->buildin
.HDisplay
)
566 pScrn
->virtualX
= fPtr
->buildin
.HDisplay
;
567 if (pScrn
->virtualY
< fPtr
->buildin
.VDisplay
)
568 pScrn
->virtualY
= fPtr
->buildin
.VDisplay
;
571 /* -------------------------------------------------------------------- */
574 calculateFbmem_len(fbdevHWPtr fPtr
)
576 fPtr
->fboff
= (unsigned long) fPtr
->fix
.smem_start
& ~PAGE_MASK
;
577 fPtr
->fbmem_len
= (fPtr
->fboff
+ fPtr
->fix
.smem_len
+ ~PAGE_MASK
) &
582 fbdevHWMapVidmem(ScrnInfoPtr pScrn
)
584 fbdevHWPtr fPtr
= FBDEVHWPTR(pScrn
);
586 if (NULL
== fPtr
->fbmem
) {
587 calculateFbmem_len(fPtr
);
588 fPtr
->fbmem
= mmap(NULL
, fPtr
->fbmem_len
, PROT_READ
| PROT_WRITE
,
589 MAP_SHARED
, fPtr
->fd
, 0);
590 if (-1 == (long) fPtr
->fbmem
) {
591 xf86DrvMsg(pScrn
->scrnIndex
, X_ERROR
,
592 "mmap fbmem: %s\n", strerror(errno
));
596 /* Perhaps we'd better add fboff to fbmem and return 0 in
597 fbdevHWLinearOffset()? Of course we then need to mask
598 fPtr->fbmem with PAGE_MASK in fbdevHWUnmapVidmem() as
603 (unsigned long) fPtr
->fix
.smem_start
& (unsigned long) (PAGE_MASK
);
605 (unsigned long) fPtr
->fix
.smem_start
& (unsigned long) (~PAGE_MASK
);
610 fbdevHWLinearOffset(ScrnInfoPtr pScrn
)
612 fbdevHWPtr fPtr
= FBDEVHWPTR(pScrn
);
618 fbdevHWUnmapVidmem(ScrnInfoPtr pScrn
)
620 fbdevHWPtr fPtr
= FBDEVHWPTR(pScrn
);
622 if (NULL
!= fPtr
->fbmem
) {
623 if (-1 == munmap(fPtr
->fbmem
, fPtr
->fbmem_len
))
624 xf86DrvMsg(pScrn
->scrnIndex
, X_ERROR
,
625 "munmap fbmem: %s\n", strerror(errno
));
632 fbdevHWMapMMIO(ScrnInfoPtr pScrn
)
634 unsigned int mmio_off
;
636 fbdevHWPtr fPtr
= FBDEVHWPTR(pScrn
);
638 if (NULL
== fPtr
->mmio
) {
639 /* tell the kernel not to use accels to speed up console scrolling */
640 fPtr
->var
.accel_flags
= 0;
641 if (0 != ioctl(fPtr
->fd
, FBIOPUT_VSCREENINFO
, (void *) (&fPtr
->var
))) {
642 xf86DrvMsg(pScrn
->scrnIndex
, X_ERROR
,
643 "FBIOPUT_VSCREENINFO: %s\n", strerror(errno
));
646 mmio_off
= (unsigned long) fPtr
->fix
.mmio_start
& ~PAGE_MASK
;
647 fPtr
->mmio_len
= (mmio_off
+ fPtr
->fix
.mmio_len
+ ~PAGE_MASK
) &
649 if (NULL
== fPtr
->fbmem
)
650 calculateFbmem_len(fPtr
);
651 fPtr
->mmio
= mmap(NULL
, fPtr
->mmio_len
, PROT_READ
| PROT_WRITE
,
652 MAP_SHARED
, fPtr
->fd
, fPtr
->fbmem_len
);
653 if (-1 == (long) fPtr
->mmio
) {
654 xf86DrvMsg(pScrn
->scrnIndex
, X_ERROR
,
655 "mmap mmio: %s\n", strerror(errno
));
659 fPtr
->mmio
+= mmio_off
;
665 fbdevHWUnmapMMIO(ScrnInfoPtr pScrn
)
667 fbdevHWPtr fPtr
= FBDEVHWPTR(pScrn
);
669 if (NULL
!= fPtr
->mmio
) {
671 munmap((void *) ((unsigned long) fPtr
->mmio
& PAGE_MASK
),
673 xf86DrvMsg(pScrn
->scrnIndex
, X_ERROR
, "munmap mmio: %s\n",
676 /* FIXME: restore var.accel_flags [geert] */
681 /* -------------------------------------------------------------------- */
684 fbdevHWModeInit(ScrnInfoPtr pScrn
, DisplayModePtr mode
)
686 fbdevHWPtr fPtr
= FBDEVHWPTR(pScrn
);
688 pScrn
->vtSema
= TRUE
;
691 if (!fbdevHWSetMode(pScrn
, mode
, FALSE
))
695 if (0 != ioctl(fPtr
->fd
, FBIOGET_FSCREENINFO
, (void *) (&fPtr
->fix
))) {
696 xf86DrvMsg(pScrn
->scrnIndex
, X_ERROR
,
697 "FBIOGET_FSCREENINFO: %s\n", strerror(errno
));
700 if (0 != ioctl(fPtr
->fd
, FBIOGET_VSCREENINFO
, (void *) (&fPtr
->var
))) {
701 xf86DrvMsg(pScrn
->scrnIndex
, X_ERROR
,
702 "FBIOGET_VSCREENINFO: %s\n", strerror(errno
));
706 if (pScrn
->defaultVisual
== TrueColor
||
707 pScrn
->defaultVisual
== DirectColor
) {
708 /* XXX: This is a hack, but it should be a NOP for all the setups that
709 * worked before and actually seems to fix some others...
711 pScrn
->offset
.red
= fPtr
->var
.red
.offset
;
712 pScrn
->offset
.green
= fPtr
->var
.green
.offset
;
713 pScrn
->offset
.blue
= fPtr
->var
.blue
.offset
;
715 ((1 << fPtr
->var
.red
.length
) - 1) << fPtr
->var
.red
.offset
;
717 ((1 << fPtr
->var
.green
.length
) - 1) << fPtr
->var
.green
.offset
;
719 ((1 << fPtr
->var
.blue
.length
) - 1) << fPtr
->var
.blue
.offset
;
725 /* -------------------------------------------------------------------- */
726 /* video mode save/restore */
728 fbdevHWSave(ScrnInfoPtr pScrn
)
730 fbdevHWPtr fPtr
= FBDEVHWPTR(pScrn
);
732 if (0 != ioctl(fPtr
->fd
, FBIOGET_VSCREENINFO
, (void *) (&fPtr
->saved_var
)))
733 xf86DrvMsg(pScrn
->scrnIndex
, X_ERROR
,
734 "FBIOGET_VSCREENINFO: %s\n", strerror(errno
));
738 fbdevHWRestore(ScrnInfoPtr pScrn
)
740 fbdevHWPtr fPtr
= FBDEVHWPTR(pScrn
);
742 if (0 != ioctl(fPtr
->fd
, FBIOPUT_VSCREENINFO
, (void *) (&fPtr
->saved_var
)))
743 xf86DrvMsg(pScrn
->scrnIndex
, X_ERROR
,
744 "FBIOPUT_VSCREENINFO: %s\n", strerror(errno
));
747 /* -------------------------------------------------------------------- */
748 /* callback for xf86HandleColormaps */
751 fbdevHWLoadPalette(ScrnInfoPtr pScrn
, int numColors
, int *indices
,
752 LOCO
* colors
, VisualPtr pVisual
)
754 fbdevHWPtr fPtr
= FBDEVHWPTR(pScrn
);
756 unsigned short red
, green
, blue
;
764 for (i
= 0; i
< numColors
; i
++) {
765 cmap
.start
= indices
[i
];
766 red
= (colors
[indices
[i
]].red
<< 8) | colors
[indices
[i
]].red
;
767 green
= (colors
[indices
[i
]].green
<< 8) | colors
[indices
[i
]].green
;
768 blue
= (colors
[indices
[i
]].blue
<< 8) | colors
[indices
[i
]].blue
;
769 if (-1 == ioctl(fPtr
->fd
, FBIOPUTCMAP
, (void *) &cmap
))
770 xf86DrvMsg(pScrn
->scrnIndex
, X_ERROR
,
771 "FBIOPUTCMAP: %s\n", strerror(errno
));
775 /* -------------------------------------------------------------------- */
776 /* these can be hooked directly into ScrnInfoRec */
779 fbdevHWValidMode(ScrnInfoPtr pScrn
, DisplayModePtr mode
, Bool verbose
, int flags
)
781 if (!fbdevHWSetMode(pScrn
, mode
, TRUE
))
788 fbdevHWSwitchMode(ScrnInfoPtr pScrn
, DisplayModePtr mode
)
790 if (!fbdevHWSetMode(pScrn
, mode
, FALSE
))
797 fbdevHWAdjustFrame(ScrnInfoPtr pScrn
, int x
, int y
)
799 fbdevHWPtr fPtr
= FBDEVHWPTR(pScrn
);
801 if (x
< 0 || x
+ fPtr
->var
.xres
> fPtr
->var
.xres_virtual
||
802 y
< 0 || y
+ fPtr
->var
.yres
> fPtr
->var
.yres_virtual
)
805 fPtr
->var
.xoffset
= x
;
806 fPtr
->var
.yoffset
= y
;
807 if (-1 == ioctl(fPtr
->fd
, FBIOPAN_DISPLAY
, (void *) &fPtr
->var
))
808 xf86DrvMsgVerb(pScrn
->scrnIndex
, X_WARNING
, 5,
809 "FBIOPAN_DISPLAY: %s\n", strerror(errno
));
813 fbdevHWEnterVT(ScrnInfoPtr pScrn
)
815 if (!fbdevHWModeInit(pScrn
, pScrn
->currentMode
))
817 fbdevHWAdjustFrame(pScrn
, pScrn
->frameX0
, pScrn
->frameY0
);
822 fbdevHWLeaveVT(ScrnInfoPtr pScrn
)
824 fbdevHWRestore(pScrn
);
828 fbdevHWDPMSSet(ScrnInfoPtr pScrn
, int mode
, int flags
)
830 fbdevHWPtr fPtr
= FBDEVHWPTR(pScrn
);
831 unsigned long fbmode
;
840 case DPMSModeStandby
:
843 case DPMSModeSuspend
:
853 if (-1 == ioctl(fPtr
->fd
, FBIOBLANK
, (void *) fbmode
))
854 xf86DrvMsg(pScrn
->scrnIndex
, X_ERROR
,
855 "FBIOBLANK: %s\n", strerror(errno
));
859 fbdevHWSaveScreen(ScreenPtr pScreen
, int mode
)
861 ScrnInfoPtr pScrn
= xf86ScreenToScrn(pScreen
);
862 fbdevHWPtr fPtr
= FBDEVHWPTR(pScrn
);
863 unsigned long unblank
;
868 unblank
= xf86IsUnblank(mode
);
870 if (-1 == ioctl(fPtr
->fd
, FBIOBLANK
, (void *) (1 - unblank
))) {
871 xf86DrvMsg(pScrn
->scrnIndex
, X_ERROR
,
872 "FBIOBLANK: %s\n", strerror(errno
));
880 fbdevHWSwitchModeWeak(void)
882 return fbdevHWSwitchMode
;
885 xf86AdjustFrameProc
*
886 fbdevHWAdjustFrameWeak(void)
888 return fbdevHWAdjustFrame
;
892 fbdevHWEnterVTWeak(void)
894 return fbdevHWEnterVT
;
898 fbdevHWLeaveVTWeak(void)
900 return fbdevHWLeaveVT
;
904 fbdevHWValidModeWeak(void)
906 return fbdevHWValidMode
;
910 fbdevHWDPMSSetWeak(void)
912 return fbdevHWDPMSSet
;
915 xf86LoadPaletteProc
*
916 fbdevHWLoadPaletteWeak(void)
918 return fbdevHWLoadPalette
;
922 fbdevHWSaveScreenWeak(void)
924 return fbdevHWSaveScreen
;