








		      The Linux/m68k Frame Buffer Device

	   Geert Uytterhoeven (Geert.Uytterhoeven@cs.kuleuven.ac.be)

				  14 May 1997



1.  Introduction

The frame buffer device provides an abstraction for the graphics hardware. It
represents the frame buffer of some video hardware and allows application soft-
ware to access the graphics hardware through a well-defined interface, so the
software doesn't need to know anything about the low-level (hardware register)
stuff.

The device is accessed through special device nodes, usually located in the
/dev directory, i.e. /dev/fb*.


2.  User's View of /dev/fb*

From the user's point of view, the frame buffer device looks just like any
other device in /dev. It's a character device using major 29, the minor is
divided into a frame buffer number in the upper 3 bits (allowing max.  8 frame
buffers simultaneously) and a resolution code in the lower 5 bits of the minor.

By convention, the following device nodes are used (numbers indicate the device
minor numbers):

   o First frame buffer

	   0 = /dev/fb0current
		 Current resolution

	   1 = /dev/fb0autodetect
		 Default resolution

	   2 = /dev/fb0predefined0
		 Predefined resolution 1

	   ...

	   23 = /dev/fb0predefined21
		 Predefined resolution 22

	   24 = /dev/fb0user0
		 User defined resolutions 1

	   ...




The Linux/m68k Frame Buffer Device





The Linux/m68k Frame Buffer Device



	   31 = /dev/fb0user7
		 User defined resolutions 8


   o Second frame buffer

	   32 = /dev/fb1current
		 Current resolution

	   33 = /dev/fb1autodetect
		 Default resolution

	   34 = /dev/fb1predefined0
		 Predefined resolutions 1

	   ...

	   55 = /dev/fb1predefined21
		 Predefined resolution 22

	   56 = /dev/fb1user0
		 User defined resolutions 1

	   ...

	   63 = /dev/fb1user7
		 User defined resolutions 8

and so on...

The device with (minor & 31) == 0 (/dev/fb?current) stands for the frame buffer
together with the currently set video parameters; (minor & 31) == 1
(/dev/fb?autodetect) is the video mode detected at boot time. Any other minor
stands for some predefined or user defined video mode.

The predefined entries (/dev/fb?predefined*) usually have a device dependent
name, e.g. for major 29, minor 5, we have /dev/fb0multiscan on Amiga and
/dev/fb0ttmid on Atari. These are meant to contain hardware dependent resolu-
tions.

The user defined resolutions (/dev/fb?user?) are meant to be filled in by the
user. This way the user can store his favorite 8 resolutions during boot up.

Note: if you need more than 8 user defined resolutions, you can always override
the predefined resolutions by storing them in one of the predefined entries.
But this is not recommended. Similarly, if there are more than 22 predefined
resolutions, the device writer can decide to store them in the user defined
entries.

If the device is opened (for writing), the frame buffer driver switches to the
selected video mode. Thus, you can switch video modes by writing to a frame
buffer device, e.g.










The Linux/m68k Frame Buffer Device



	 > /dev/fb0ttlow


will switch your video to TT low mode. Note: if you specify a resolution which
contains a value that's not possible on your hardware, the frame buffer device
will round it up (if possible) or return an error condition.

The frame buffer devices are also `normal' memory devices, this means, you can
read and write their contents. You can, for example, make a screen snapshot by

	 cp /dev/fb0current myfile


There also can be more than one frame buffer at a time, e.g. if you have a
graphics card in addition to the built-in hardware. The corresponding frame
buffer devices (/dev/fb0* and /dev/fb1* etc.) work independently.

Application software that uses the frame buffer device (e.g. the X server) will
use /dev/fb0current by default. You can specify an alternative resolution by
setting the environment variable $FRAMEBUFFER to the path name of a frame
buffer device, e.g. (for sh/bash users):

	 export FRAMEBUFFER=/dev/fb0multiscan


or (for csh users):

	 setenv FRAMEBUFFER /dev/fb0multiscan


After this the X server will use the multiscan video mode.


3.  Programmer's View of /dev/fb*

As you already know, a frame buffer device is a memory device like /dev/mem and
it has the same features. You can read it, write it, seek to some location in
it and mmap() it (the main usage). The difference is just that the memory that
appears in the special file is not the whole memory, but the frame buffer of
some video hardware.

/dev/fb* also allows several ioctls on it, by which lots of information about
the hardware can be queried and set. The color map handling works via ioctls,
too. Look into <linux/fb.h> for more information on what ioctls exist and on
which data structures they work. Here's just a brief overview:

   o You can request unchangeable information about the hardware, like name,
     organization of the screen memory (planes, packed pixels, ...) and address
     and length of the screen memory.

   o You can request and change variable information about the hardware, like
     visible and virtual geometry, depth, color map format, timing, and so on.
     If you try to change that informations, the driver maybe will round up
     some values to meet the hardware's capabilities (or return EINVAL if that








The Linux/m68k Frame Buffer Device



     isn't possible).

   o You can get and set parts of the color map. Communication is done with 16
     bit per color part (red, green, blue, transparency) to support all exist-
     ing hardware. The driver does all the computations needed to bring it into
     the hardware (round it down to less bits, maybe throw away transparency).

All this hardware abstraction makes the implementation of application programs
easier and more portable. E.g. the X server works completely on /dev/fb* and
thus doesn't need to know, for example, how the color registers of the concrete
hardware are organized. XF68_FBDev is a general X server for bitmapped, unac-
celerated video hardware. The only thing that has to be built into application
programs is the screen organization (bitplanes or chunky pixels etc.), because
it works on the frame buffer image data directly.

For the future it is planned that frame buffer drivers for graphics cards and
the like can be implemented as kernel modules that are loaded at runtime. Such
a driver just has to call register_framebuffer() and supply some functions.
Writing and distributing such drivers independently from the kernel will save
much trouble...


4.  Frame Buffer Resolution Maintenance

Frame buffer resolutions are maintained using the utility fbset. It allows to
change the video mode properties of the current or a user defined resolution.
It's main usage is to tune video modes and to store custom resolutions into one
of the /dev/fb?user?  entries, e.g. during boot up in one of your /etc/rc.* or
/etc/init.d/* files, after which those resolutions can be used by applications.

Fbset uses a video mode database stored in a configuration file, so you can
easily add your own modes and refer to them with a simple identifier. The fbset
install script also creates the special device nodes for the device dependent
predefined resolutions.


5.  The X Server

The X server (XF68_FBDev) is the most notable application program for the frame
buffer device. Starting with XFree68/XFree86 release 3.2, the X server is part
of XFree68/XFree86 and has 2 modes:

   o If the Display subsection for the fbdev driver in the /etc/XF86Config file
     contains a


		  Modes "default"




     line, the X server will use the scheme discussed above, i.e. it will start
     up in the resolution determined by /dev/fb0current (or $FRAMEBUFFER, if
     set). This is the default for the configuration file supplied with








The Linux/m68k Frame Buffer Device



     XFree68. It's the most simple configuration (and the only possible one if
     you want to have a broadcast compatible display, e.g.  PAL or NTSC), but
     it has some limitations.

   o Therefore it's also possible to specify resolutions in the /etc/XF86Config
     file. This allows for on-the-fly resolution switching while retaining the
     same virtual desktop size. The frame buffer device that's used is still
     /dev/fb0current (or $FRAMEBUFFER), but the available resolutions are
     defined by /etc/XF86Config now. The disadvantage is that you have to spec-
     ify the timings in a different format (but fbset -x may help) and that you
     can't have a broadcast compatible display (e.g. no PAL or NTSC).

To tune a video mode, you can use fbset or xvidtune. Note that xvidtune doesn't
work 100% with XF68_FBDev: the reported clock values are always incorrect.

There exists also an accelerated X server for the Cybervision 64 graphics
board, but that's not discussed here.


6.  Video Mode Timings

A monitor draws an image on the screen by using an electron beam (3 electron
beams for most color models, 1 electron beam for Trinitron color monitors and
monochrome monitors). The front of the screen is covered by a pattern of col-
ored phosphors (pixels). If a phosphor is hit by an electron, it emits a photon
and thus becomes visible.

The electron beam draws horizontal lines (scanlines) from left to right, and
from the top to the bottom of the screen. By modifying the intensity of the
electron beam, pixels with various colors and intensities can be shown.

After each scanline the electron beam has to move back to the left side of the
screen and to the next line: this is called the horizontal retrace. After the
whole screen (frame) was painted, the beam moves back to the upper left corner:
this is called the vertical retrace. During both the horizontal and vertical
retrace, the electron beam is turned off (blanked).

The speed at which the electron beam paints the pixels is determined by the
dotclock in the graphics board. For a dotclock of e.g. 28.37516 MHz (millions
of cycles per second), each pixel is 35242 ps (picoseconds) long:




1/(28.37516E6 Hz) = 35.242E-9 s

If the screen resolution is 640x480, it will take

	 640*35.242E-9 s = 22.555E-6 s


to paint the 640 (xres) pixels on one scanline. But the horizontal retrace also
takes time (e.g. 272 `pixels'), so a full scanline takes









The Linux/m68k Frame Buffer Device



	 (640+272)*35.242E-9 s = 32.141E-6 s


We'll say that the horizontal scanrate is about 31 kHz:

	 1/(32.141E-6 s) = 31.113E3 Hz


A full screen counts 480 (yres) lines, but we have to consider the vertical
retrace too (e.g. 49 `pixels'). So a full screen will take

	 (480+49)*32.141E-6 s = 17.002E-3 s


The vertical scanrate is about 59 Hz:

	 1/(17.002E-3 s) = 58.815 Hz


This means the screen data is refreshed about 59 times per second. To have a
stable picture without visible flicker, VESA recommends a vertical scanrate of
at least 72 Hz. But the perceived flicker is very human dependent: some people
can use 50 Hz without any trouble, while I'll notice if it's less than 80 Hz.

Since the monitor doesn't know when a new scanline starts, the graphics board
will supply a synchronization pulse (horizontal sync or hsync) for each scan-
line.  Similarly it supplies a synchronization pulse (vertical sync or vsync)
for each new frame. The position of the image on the screen is influenced by
the moments at which the synchronization pulses occur.

The following picture summarizes all timings. The horizontal retrace time is
the sum of the left margin, the right margin and the hsync length, while the
vertical retrace time is the sum of the upper margin, the lower margin and the
vsync length.




























The Linux/m68k Frame Buffer Device



       +----------+---------------------------------------------+----------+-------+
       |	  |		   x				|	   |	   |
       |	  |		   |upper_margin		|	   |	   |
       |	  |		   x				|	   |	   |
       +----------###############################################----------+-------+
       |	  #		   x				#	   |	   |
       |	  #		   |				#	   |	   |
       |	  #		   |				#	   |	   |
       |	  #		   |				#	   |	   |
       |   left   #		   |				#  right   | hsync |
       |  margin  #		   |	   xres 		#  margin  |  len  |
       |<-------->#<---------------+--------------------------->#<-------->|<----->|
       |	  #		   |				#	   |	   |
       |	  #		   |				#	   |	   |
       |	  #		   |				#	   |	   |
       |	  #		   |yres			#	   |	   |
       |	  #		   |				#	   |	   |
       |	  #		   |				#	   |	   |
       |	  #		   |				#	   |	   |
       |	  #		   |				#	   |	   |
       |	  #		   |				#	   |	   |
       |	  #		   |				#	   |	   |
       |	  #		   |				#	   |	   |
       |	  #		   |				#	   |	   |
       |	  #		   x				#	   |	   |
       +----------###############################################----------+-------+
       |	  |		   x				|	   |	   |
       |	  |		   |lower_margin		|	   |	   |
       |	  |		   x				|	   |	   |
       +----------+---------------------------------------------+----------+-------+
       |	  |		   x				|	   |	   |
       |	  |		   |vsync_len			|	   |	   |
       |	  |		   x				|	   |	   |
       +----------+---------------------------------------------+----------+-------+

The frame buffer device expects all horizontal timings in number of dotclocks
(in picoseconds, 1E-12 s), and vertical timings in number of scanlines.


7.  Converting XFree86 timing values into frame buffer device timings

An XFree86 mode line consists of the following fields:

	 "800x600"     50      800  856  976 1040    600  637  643  666
	 < name >     DCF	HR  SH1  SH2  HFL     VR  SV1  SV2  VFL


The frame buffer device uses the following fields:

      pixclock
	    pixel clock in ps (pico seconds)

      left_margin
	    time from sync to picture








The Linux/m68k Frame Buffer Device



      right_margin
	    time from picture to sync

      upper_margin
	    time from sync to picture

      lower_margin
	    time from picture to sync

      hsync_len
	    length of horizontal sync

      vsync_len
	    length of vertical sync

      Pixelclock

	       o xfree: in MHz

	       o fb: In Picoseconds (ps)

	       o pixclock = 1000000 / DCF

      Horizontal timings

	       o left_margin = HFL - SH2

	       o right_margin = SH1 - HR

	       o hsync_len = SH2 - SH1

      Vertical timings

	       o upper_margin = VFL - SV2

	       o lower_margin = SV1 - VR

	       o vsync_len = SV2 - SV1

Good examples for VESA timings can be found in the XFree86 source tree, under
xc/programs/Xserver/hw/xfree86/doc/modeDB.txt.


8.  References

For more specific information about the frame buffer device and its applica-
tions, please refer to the following documentation:

   o The manual pages for fbset: fbset(8), fb.modes(5)

   o The manual pages for XFree68: XF68_FBDev(1), XF86Config(4/5)

   o The mighty kernel sources:









The Linux/m68k Frame Buffer Device



	o linux/Documentation/m68k/framebuffer.txt, which may be more up-to-
	  date than the document you're reading now

	o linux/include/linux/fb.h

	o linux/drivers/char/fbmem.c

	o linux/arch/m68k/*/*fb.c


9.  Downloading

All necessary files can be found at

	 ftp://ftp.uni-erlangen.de/pub/Linux/LOCAL/680x0/


and on its mirrors.


10.  Credits


This readme was written by Geert Uytterhoeven, partly based on the original X-
framebuffer.README by Roman Hodek and Martin Schaller. Section `Converting
XFree86 timing values into frame buffer device timings' was provided by Frank
Neumann.

The frame buffer device abstraction was designed by Martin Schaller.

     Generated from XFree86: xc/programs/Xserver/hw/xfree68/doc/sgml/fbdev.sgml,v 1.1.2.5 1997/08/08 03:09:07 dawes Exp $































The Linux/m68k Frame Buffer Device





































































				   CONTENTS



1.  Introduction ............................................................ 1

2.  User's View of /dev/fb* ................................................. 1

3.  Programmer's View of /dev/fb* ........................................... 3

4.  Frame Buffer Resolution Maintenance ..................................... 4

5.  The X Server ............................................................ 4

6.  Video Mode Timings ...................................................... 5

7.  Converting XFree86 timing values into frame buffer device timings ....... 7

8.  References .............................................................. 8

9.  Downloading ............................................................. 9

10. Credits  ................................................................ 9

































				       i


