Commit de7c6d15 authored by Jaya Kumar's avatar Jaya Kumar Committed by Linus Torvalds

fbdev: defio and Metronomefb

Implement support for the E-Ink Metronome controller.  It provides an mmapable
interface to the controller using defio support.  It was tested with a gumstix
pxa255 with Vizplex media using Xfbdev and various X clients such as xeyes,
xpdf, xloadimage.

This patch also fixes the following bug: Defio would cause a hang on write
access to the framebuffer as the page fault would be called ad-infinitum.  It
fixes fb_defio by setting the mapping to be used by page_mkclean.
Signed-off-by: default avatarJaya Kumar <jayakumar.lkml@gmail.com>
Cc: "Antonino A. Daplas" <adaplas@pol.net>
Signed-off-by: default avatarAndrew Morton <akpm@linux-foundation.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@linux-foundation.org>
parent 9fedc9f1
Understanding fbdev's cmap
--------------------------
These notes explain how X's dix layer uses fbdev's cmap structures.
*. example of relevant structures in fbdev as used for a 3-bit grayscale cmap
struct fb_var_screeninfo {
.bits_per_pixel = 8,
.grayscale = 1,
.red = { 4, 3, 0 },
.green = { 0, 0, 0 },
.blue = { 0, 0, 0 },
}
struct fb_fix_screeninfo {
.visual = FB_VISUAL_STATIC_PSEUDOCOLOR,
}
for (i = 0; i < 8; i++)
info->cmap.red[i] = (((2*i)+1)*(0xFFFF))/16;
memcpy(info->cmap.green, info->cmap.red, sizeof(u16)*8);
memcpy(info->cmap.blue, info->cmap.red, sizeof(u16)*8);
*. X11 apps do something like the following when trying to use grayscale.
for (i=0; i < 8; i++) {
char colorspec[64];
memset(colorspec,0,64);
sprintf(colorspec, "rgb:%x/%x/%x", i*36,i*36,i*36);
if (!XParseColor(outputDisplay, testColormap, colorspec, &wantedColor))
printf("Can't get color %s\n",colorspec);
XAllocColor(outputDisplay, testColormap, &wantedColor);
grays[i] = wantedColor;
}
There's also named equivalents like gray1..x provided you have an rgb.txt.
Somewhere in X's callchain, this results in a call to X code that handles the
colormap. For example, Xfbdev hits the following:
xc-011010/programs/Xserver/dix/colormap.c:
FindBestPixel(pentFirst, size, prgb, channel)
dr = (long) pent->co.local.red - prgb->red;
dg = (long) pent->co.local.green - prgb->green;
db = (long) pent->co.local.blue - prgb->blue;
sq = dr * dr;
UnsignedToBigNum (sq, &sum);
BigNumAdd (&sum, &temp, &sum);
co.local.red are entries that were brought in through FBIOGETCMAP which come
directly from the info->cmap.red that was listed above. The prgb is the rgb
that the app wants to match to. The above code is doing what looks like a least
squares matching function. That's why the cmap entries can't be set to the left
hand side boundaries of a color range.
Metronomefb
-----------
Maintained by Jaya Kumar <jayakumar.lkml.gmail.com>
Last revised: Nov 20, 2007
Metronomefb is a driver for the Metronome display controller. The controller
is from E-Ink Corporation. It is intended to be used to drive the E-Ink
Vizplex display media. E-Ink hosts some details of this controller and the
display media here http://www.e-ink.com/products/matrix/metronome.html .
Metronome is interfaced to the host CPU through the AMLCD interface. The
host CPU generates the control information and the image in a framebuffer
which is then delivered to the AMLCD interface by a host specific method.
Currently, that's implemented for the PXA's LCDC controller. The display and
error status are each pulled through individual GPIOs.
Metronomefb was written for the PXA255/gumstix/lyre combination and
therefore currently has board set specific code in it. If other boards based on
other architectures are available, then the host specific code can be separated
and abstracted out.
Metronomefb requires waveform information which is delivered via the AMLCD
interface to the metronome controller. The waveform information is expected to
be delivered from userspace via the firmware class interface. The waveform file
can be compressed as long as your udev or hotplug script is aware of the need
to uncompress it before delivering it. metronomefb will ask for waveform.wbf
which would typically go into /lib/firmware/waveform.wbf depending on your
udev/hotplug setup. I have only tested with a single waveform file which was
originally labeled 23P01201_60_WT0107_MTC. I do not know what it stands for.
Caution should be exercised when manipulating the waveform as there may be
a possibility that it could have some permanent effects on the display media.
I neither have access to nor know exactly what the waveform does in terms of
the physical media.
Metronomefb uses the deferred IO interface so that it can provide a memory
mappable frame buffer. It has been tested with tinyx (Xfbdev). It is known
to work at this time with xeyes, xclock, xloadimage, xpdf.
...@@ -1893,6 +1893,20 @@ config FB_XILINX ...@@ -1893,6 +1893,20 @@ config FB_XILINX
framebuffer. ML300 carries a 640*480 LCD display on the board, framebuffer. ML300 carries a 640*480 LCD display on the board,
ML403 uses a standard DB15 VGA connector. ML403 uses a standard DB15 VGA connector.
config FB_METRONOME
tristate "Metronome display controller support"
depends on FB && ARCH_PXA && MMU
select FB_SYS_FILLRECT
select FB_SYS_COPYAREA
select FB_SYS_IMAGEBLIT
select FB_SYS_FOPS
select FB_DEFERRED_IO
help
This enables support for the Metronome display controller. Tested
with an E-Ink 800x600 display and Gumstix Connex through an AMLCD
interface. Please read <file:Documentation/fb/metronomefb.txt>
for more information.
config FB_VIRTUAL config FB_VIRTUAL
tristate "Virtual Frame Buffer support (ONLY FOR TESTING!)" tristate "Virtual Frame Buffer support (ONLY FOR TESTING!)"
depends on FB depends on FB
......
...@@ -103,6 +103,7 @@ obj-$(CONFIG_FB_PMAG_AA) += pmag-aa-fb.o ...@@ -103,6 +103,7 @@ obj-$(CONFIG_FB_PMAG_AA) += pmag-aa-fb.o
obj-$(CONFIG_FB_PMAG_BA) += pmag-ba-fb.o obj-$(CONFIG_FB_PMAG_BA) += pmag-ba-fb.o
obj-$(CONFIG_FB_PMAGB_B) += pmagb-b-fb.o obj-$(CONFIG_FB_PMAGB_B) += pmagb-b-fb.o
obj-$(CONFIG_FB_MAXINE) += maxinefb.o obj-$(CONFIG_FB_MAXINE) += maxinefb.o
obj-$(CONFIG_FB_METRONOME) += metronomefb.o
obj-$(CONFIG_FB_S1D13XXX) += s1d13xxxfb.o obj-$(CONFIG_FB_S1D13XXX) += s1d13xxxfb.o
obj-$(CONFIG_FB_IMX) += imxfb.o obj-$(CONFIG_FB_IMX) += imxfb.o
obj-$(CONFIG_FB_S3C2410) += s3c2410fb.o obj-$(CONFIG_FB_S3C2410) += s3c2410fb.o
......
...@@ -4,7 +4,7 @@ ...@@ -4,7 +4,7 @@
* Copyright (C) 2006 Jaya Kumar * Copyright (C) 2006 Jaya Kumar
* *
* This file is subject to the terms and conditions of the GNU General Public * This file is subject to the terms and conditions of the GNU General Public
* License. See the file COPYING in the main directory of this archive * License. See the file COPYING in the main directory of this archive
* for more details. * for more details.
*/ */
...@@ -31,7 +31,7 @@ static int fb_deferred_io_fault(struct vm_area_struct *vma, ...@@ -31,7 +31,7 @@ static int fb_deferred_io_fault(struct vm_area_struct *vma,
unsigned long offset; unsigned long offset;
struct page *page; struct page *page;
struct fb_info *info = vma->vm_private_data; struct fb_info *info = vma->vm_private_data;
/* info->screen_base is in System RAM */ /* info->screen_base is virtual memory */
void *screen_base = (void __force *) info->screen_base; void *screen_base = (void __force *) info->screen_base;
offset = vmf->pgoff << PAGE_SHIFT; offset = vmf->pgoff << PAGE_SHIFT;
...@@ -43,6 +43,15 @@ static int fb_deferred_io_fault(struct vm_area_struct *vma, ...@@ -43,6 +43,15 @@ static int fb_deferred_io_fault(struct vm_area_struct *vma,
return VM_FAULT_SIGBUS; return VM_FAULT_SIGBUS;
get_page(page); get_page(page);
if (vma->vm_file)
page->mapping = vma->vm_file->f_mapping;
else
printk(KERN_ERR "no mapping available\n");
BUG_ON(!page->mapping);
page->index = vmf->pgoff;
vmf->page = page; vmf->page = page;
return 0; return 0;
} }
...@@ -138,11 +147,20 @@ EXPORT_SYMBOL_GPL(fb_deferred_io_init); ...@@ -138,11 +147,20 @@ EXPORT_SYMBOL_GPL(fb_deferred_io_init);
void fb_deferred_io_cleanup(struct fb_info *info) void fb_deferred_io_cleanup(struct fb_info *info)
{ {
void *screen_base = (void __force *) info->screen_base;
struct fb_deferred_io *fbdefio = info->fbdefio; struct fb_deferred_io *fbdefio = info->fbdefio;
struct page *page;
int i;
BUG_ON(!fbdefio); BUG_ON(!fbdefio);
cancel_delayed_work(&info->deferred_work); cancel_delayed_work(&info->deferred_work);
flush_scheduled_work(); flush_scheduled_work();
/* clear out the mapping that we setup */
for (i = 0 ; i < info->fix.smem_len; i += PAGE_SIZE) {
page = vmalloc_to_page(screen_base + i);
page->mapping = NULL;
}
} }
EXPORT_SYMBOL_GPL(fb_deferred_io_cleanup); EXPORT_SYMBOL_GPL(fb_deferred_io_cleanup);
......
This diff is collapsed.
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment