Skip to contentSkip to conversation

fbdev: add E-Ink Broadsheet controller support

RFC In review Jaya Kumar 4 participants 10 messages Dec 21, 2008 – Jan 2, 2009 Framebuffer layer

lore
Share & tools
lore

Jaya Kumar

author
#0 lore raw

RFC 1/2 fbdev: add E-Ink Broadsheet controller support

Hi arm, fbdev friends,

Just reposting this RFC after splitting it into 2 separate patches, 1 to add broadsheetfb and another to add am300 support. Please let me know your feedback. If there aren't any complaints, then I think I'll post to the rmk patch queue. The am300 patch is dependent on the gumstix cleanup merged from Eric's pxa tree.

Thanks,
jaya

This patch adds support for the E-Ink Broadsheet display controller

---
 drivers/video/Kconfig        |   14 +
 drivers/video/Makefile       |    1 +
 drivers/video/broadsheetfb.c |  569 ++++++++++++++++++++++++++++++++++++++++++
 include/video/broadsheetfb.h |   63 +++++
 4 files changed, 647 insertions(+), 0 deletions(-)
 create mode 100644 drivers/video/broadsheetfb.c
 create mode 100644 include/video/broadsheetfb.h
drivers/video/Kconfig +14 -0
index 3f3ce13..053f5f9 100644
@@ -2115,6 +2115,20 @@ config FB_PRE_INIT_FB
 	  Select this option if display contents should be inherited as set by
 	  the bootloader.
 
+config FB_BROADSHEET
+	tristate "E-Ink Broadsheet/Epson S1D13521 controller support"
+	depends on FB
+	select FB_SYS_FILLRECT
+	select FB_SYS_COPYAREA
+	select FB_SYS_IMAGEBLIT
+	select FB_SYS_FOPS
+	select FB_DEFERRED_IO
+	help
+	  This driver implements support for the E-Ink Broadsheet
+	  controller. The release name for this device was Epson S1D13521
+	  and could also have been called by other names when coupled with
+	  a bridge adapter.
+
 source "drivers/video/omap/Kconfig"
 
 source "drivers/video/backlight/Kconfig"
drivers/video/Makefile +1 -0
index e39e33e..ee9ed00 100644
@@ -106,6 +106,7 @@ obj-$(CONFIG_FB_PMAG_BA)	  += pmag-ba-fb.o
 obj-$(CONFIG_FB_PMAGB_B)	  += pmagb-b-fb.o
 obj-$(CONFIG_FB_MAXINE)		  += maxinefb.o
 obj-$(CONFIG_FB_METRONOME)        += metronomefb.o
+obj-$(CONFIG_FB_BROADSHEET)       += broadsheetfb.o
 obj-$(CONFIG_FB_S1D13XXX)	  += s1d13xxxfb.o
 obj-$(CONFIG_FB_SH7760)		  += sh7760fb.o
 obj-$(CONFIG_FB_IMX)              += imxfb.o
drivers/video/broadsheetfb.c new file +569 -0

569 lines not on this page · raw message

include/video/broadsheetfb.h new file +63 -0

63 lines not on this page · raw message

Signature · 4 lines
1.5.2.3


------------------------------------------------------------------------------
#1 lore raw

drivers/video/broadsheetfb.c line 238

Quoted 5 lines · Jaya Kumar
drivers/video/broadsheetfb.c new file +5 -0
+static void broadsheetfb_dpy_update_pages(struct broadsheetfb_par *par,
+						u16 y1, u16 y2)
+{
+	u16 args[5];
+	unsigned char *buf = (unsigned char __force *)par->info->screen_base;

You shouldn't add __force inside drivers.

drivers/video/broadsheetfb.c line 461

Quoted 8 lines
drivers/video/broadsheetfb.c new file +8 -0
+	videomemorysize = (DPY_W*DPY_H);
+	videomemory = vmalloc(videomemorysize);
+	if (!videomemory)
+		goto err_fb_rel;
+
+	memset(videomemory, 0, videomemorysize);
+
+	info->screen_base = (char __force __iomem *)videomemory;

Ditto.

Also, using vmalloc for the backing store means this memory can't be mmap()'d into userspace, which is a very common thing for framebuffer using programs to do. If mmap() is to be denied, then you should provide a mmap implementation in the fb_ops structure.

------------------------------------------------------------------------------

author
#2 lore raw
Quoted 8 lines · On Sun, Dec 21, 2008 at 6:06 AM, <[email protected]> wrote:

drivers/video/broadsheetfb.c line 238

Quoted 5 lines · Jaya Kumar
drivers/video/broadsheetfb.c new file +5 -0
+static void broadsheetfb_dpy_update_pages(struct broadsheetfb_par *par,
+                                             u16 y1, u16 y2)
+{
+     u16 args[5];
+     unsigned char *buf = (unsigned char __force *)par->info->screen_base;

You shouldn't add __force inside drivers.

Ok, will take that out.

Quoted 11 lines

drivers/video/broadsheetfb.c line 461

Quoted 9 lines
drivers/video/broadsheetfb.c new file +8 -0
+     videomemorysize = (DPY_W*DPY_H);
+     videomemory = vmalloc(videomemorysize);
+     if (!videomemory)
+             goto err_fb_rel;
+
+     memset(videomemory, 0, videomemorysize);
+
+     info->screen_base = (char __force __iomem *)videomemory;

Ditto.

Ok, will take that out.

Quoted 6 lines

Also, using vmalloc for the backing store means this memory can't be mmap()'d into userspace, which is a very common thing for framebuffer using programs to do. If mmap() is to be denied, then you should provide a mmap implementation in the fb_ops structure.

I'm not sure I understand. broadsheetfb relies on defio to handle the mmap and setup the fb_ops mmap handler. I'm using Xfbdev with this and it works fine.

youtube clip of broadsheetfb with xeyes, xclock and rgbpaint here:
http://www.youtube.com/watch?v=ph48pWz2B3s

Thanks,
jaya

------------------------------------------------------------------------------

#3 lore raw
Quoted 10 lines · Jaya Kumar
Quoted 5 lines · On Sun, Dec 21, 2008 at 6:06 AM, <[email protected]> wrote:

Also, using vmalloc for the backing store means this memory can't be mmap()'d into userspace, which is a very common thing for framebuffer using programs to do. If mmap() is to be denied, then you should provide a mmap implementation in the fb_ops structure.

I'm not sure I understand. broadsheetfb relies on defio to handle the mmap and setup the fb_ops mmap handler. I'm using Xfbdev with this and it works fine.

Ah, I see how it's working. That's fine.

------------------------------------------------------------------------------

#4 lore raw
In reply to Jaya Kumar

Hi Jaya,

Quoted 1 line · Jaya Kumar

This patch adds support for the E-Ink Broadsheet display controller

Looking good. While at the topic of deferred io I took the opportunity to ask a bit about that below.

Quoted 42 lines

+++ b/drivers/video/broadsheetfb.c

drivers/video/broadsheetfb.c new file +40 -0
+/*
+ * this is the slow path from userspace. they can seek and write to
+ * the fb. it's inefficient to do anything less than a full screen draw
+ */
+static ssize_t broadsheetfb_write(struct fb_info *info, const char __user *buf,
+                               size_t count, loff_t *ppos)
+{
+       struct broadsheetfb_par *par = info->par;
+       unsigned long p = *ppos;
+       void *dst;
+       int err = 0;
+       unsigned long total_size;
+
+       if (info->state != FBINFO_STATE_RUNNING)
+               return -EPERM;
+
+       total_size = info->fix.smem_len;
+
+       if (p > total_size)
+               return -EFBIG;
+
+       if (count > total_size) {
+               err = -EFBIG;
+               count = total_size;
+       }
+
+       if (count + p > total_size) {
+               if (!err)
+                       err = -ENOSPC;
+
+               count = total_size - p;
+       }
+
+       dst = (void __force *) (info->screen_base + p);
+
+       if (copy_from_user(dst, buf, count))
+               err = -EFAULT;
+
+       if  (!err)
+               *ppos += count;

drivers/video/broadsheetfb.c line 420

Quoted 10 lines
drivers/video/broadsheetfb.c new file +10 -0
+
+       broadsheetfb_dpy_update(par);
+
+       return (err) ? err : count;
+}
+
+static struct fb_ops broadsheetfb_ops = {
+       .owner          = THIS_MODULE,
+       .fb_read        = fb_sys_read,
+       .fb_write       = broadsheetfb_write,

I sort of expected to see fb_sys_write here. Same thing for metronomefb. I wonder why you chose a custom write callback instead of fb_sys_write. Maybe I need to do the same thing for sh_mobile_lcdcfb and if so then we could hopefully share that code between our drivers. =)

By using the xxx_dpy_update() function these drivers seem to force a full screen update in their write() path. I'm not sure why though, shouldn't the write() case should just let the fb_sync callback do the sync for you? The fb_sys_write() function calls fb_sync _before_ writing though, I wonder why. Doesn't make sense to me - _after_ copying data sounds like a better place to flush. I don't know the history of the code though, so there may be a good reason for this.

Also, this brings up to another interesting topic. While I was hacking on deferred io for the sh_mobile_lcdcfb driver I realized that I needed hooks to update the screen for the callbacks fb_fillarea, fb_copyarea and fb_imageblit. The metronomefb driver and this one both force a full screen update for each operation. In sh_mobile_lcdcfb I chose to just schedule the delayed work instead. Either way is fine of course, but this issue does not seem driver specific to me. So I wonder if it is worth breaking out these sys-functions and handle all that in fb_defio.c instead. But maybe we're just covering for the fact that the fb console isn't syncing as it should?

Cheers,

/ magnus

------------------------------------------------------------------------------

#5 lore raw
Quoted 14 lines · Magnus Damm

Hi Jaya,

Quoted 1 line · Jaya Kumar

This patch adds support for the E-Ink Broadsheet display controller

Looking good. While at the topic of deferred io I took the opportunity to ask a bit about that below.

I sort of expected to see fb_sys_write here. Same thing for metronomefb. I wonder why you chose a custom write callback instead of fb_sys_write. Maybe I need to do the same thing for sh_mobile_lcdcfb and if so then we could hopefully share that code between our drivers. =)

Quoted 7 lines

By using the xxx_dpy_update() function these drivers seem to force a full screen update in their write() path. I'm not sure why though, shouldn't the write() case should just let the fb_sync callback do the sync for you? The fb_sys_write() function calls fb_sync _before_ writing though, I wonder why. Doesn't make sense to me - _after_ copying data sounds like a better place to flush. I don't know the history of the code though, so there may be a good reason for this.

Ok, I think I can answer that myself now:
The fb_sync() callback is used to synchronize hardware acceleration, not to flush data. That's why it is syncing before the write operation. My bad, I mixed fb_sync() up with the fsync() operation.

Quoted 10 lines

Also, this brings up to another interesting topic. While I was hacking on deferred io for the sh_mobile_lcdcfb driver I realized that I needed hooks to update the screen for the callbacks fb_fillarea, fb_copyarea and fb_imageblit. The metronomefb driver and this one both force a full screen update for each operation. In sh_mobile_lcdcfb I chose to just schedule the delayed work instead. Either way is fine of course, but this issue does not seem driver specific to me. So I wonder if it is worth breaking out these sys-functions and handle all that in fb_defio.c instead. But maybe we're just covering for the fact that the fb console isn't syncing as it should?

I'm still not sure if it's a sane idea to modify the fb console so it fsyncs. It's a separate issue I guess. Anyway, fsyncing data for each accelerated operation sounds a bit slow to me, especially if that triggers a full screen update. Think softcursor modifying a tiny part of the screen and we redraw the entire screen. Otoh, console may not be the biggest use case for deferred io. =)

I may hack up some shared some code later this week that triggers the delayed work for sys_xxx operations - same type of delayed flushing as my sh_mobile_lcdcfb driver. I plan on putting it in fb_defio.c and letting it call the sys operations. Then the deferred io drivers can install those callbacks into struct fb_ops directly. That way we can remove similar code in 3 drivers at least. I'll begin with sh_mobile_lcdcfb and we can do the other drivers one by one later on.

I'm not sure if you think it's a good idea. It's a bit different from the direct fsyncing like you do today.

Thanks for your help!

/ magnus

------------------------------------------------------------------------------

author
#6 lore raw
Quoted 6 lines · Magnus Damm

I'm still not sure if it's a sane idea to modify the fb console so it fsyncs. It's a separate issue I guess. Anyway, fsyncing data for each accelerated operation sounds a bit slow to me, especially if that triggers a full screen update. Think softcursor modifying a tiny part of the screen and we redraw the entire screen. Otoh, console may not be the biggest use case for deferred io. =)

Yes, you are correct that console isn't a good fit for e-ink displays because drawing a flashing cursor will cause the whole screen to flash every second (800ms is the minimum latency and yes, there's no partial update capability on the metronome controller).

Quoted 9 lines

I may hack up some shared some code later this week that triggers the delayed work for sys_xxx operations - same type of delayed flushing as my sh_mobile_lcdcfb driver. I plan on putting it in fb_defio.c and letting it call the sys operations. Then the deferred io drivers can install those callbacks into struct fb_ops directly. That way we can remove similar code in 3 drivers at least. I'll begin with sh_mobile_lcdcfb and we can do the other drivers one by one later on.

Quoted 3 lines

I'm not sure if you think it's a good idea. It's a bit different from the direct fsyncing like you do today.

In general, your proposal sounds like a good idea to me. I'll take a look at your patches now to understand if we're thinking the same thing.

Thanks,
jaya

------------------------------------------------------------------------------

#7 lore raw
In reply to Magnus Damm
Quoted 1 line · Magnus Damm

By using the <censored>_dpy_update() function these drivers seem to force a

Please don't use "ex ex ex" in email messages, it causes list admins grief when they get lots of errors from stupidly setup domains such as:

host asuka.sanyo.co.in [202.54.90.7]: 554 5.7.1 This message has been blocked because it contains a banned word.

Thank you.

------------------------------------------------------------------------------

#8 lore raw
In reply to Jaya Kumar

drivers/video/broadsheetfb.c line 58

Quoted 11 lines · Jaya Kumar
drivers/video/broadsheetfb.c new file +8 -0
 
+static struct fb_var_screeninfo broadsheetfb_var __devinitdata = {
+	.xres		= DPY_W,
+	.yres		= DPY_H,
+	.xres_virtual	= DPY_W,
+	.yres_virtual	= DPY_H,
+	.bits_per_pixel	= 8,
+	.grayscale	= 1,
+	.nonstd		= 1,

Why do you set .nonstd?

#define FB_NONSTD_HAM 1 /* Hold-And-Modify (HAM) */

Gr{oetje,eeting}s,

Geert

--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- [email protected]

In personal conversations with technical people, I call myself a hacker. But when I'm talking to journalists I just say "programmer" or something like that.
-- Linus Torvalds

------------------------------------------------------------------------------

author
#9 lore raw
Quoted 13 lines · Geert Uytterhoeven

drivers/video/broadsheetfb.c line 58

Quoted 11 lines · Jaya Kumar
drivers/video/broadsheetfb.c new file +8 -0
 
+static struct fb_var_screeninfo broadsheetfb_var __devinitdata = {
+     .xres           = DPY_W,
+     .yres           = DPY_H,
+     .xres_virtual   = DPY_W,
+     .yres_virtual   = DPY_H,
+     .bits_per_pixel = 8,
+     .grayscale      = 1,
+     .nonstd         = 1,
Quoted 4 lines

Why do you set .nonstd?

#define FB_NONSTD_HAM 1 /* Hold-And-Modify (HAM) */

Good point, shouldn't be set. Will take it out of broadsheetfb and also the other e-ink drivers that set it.

Thanks,
jaya

------------------------------------------------------------------------------