Re: [RFC 2.6.19 1/1] fbdev,mm: hecuba/E-Ink fbdev driver v2
On 12/22/06, Franck Bui-Huu <[EMAIL PROTECTED]> wrote: Well thinking more about it, this wouldn't work for all cache types. For example, if your cache is not a direct maped one, this workaround won't work. So this is definitely not a portable solution. From asking peterz on #mm, I think page_mkclean will do the right thing and call something like flush_cache_page. I think that resolves the issue which I think you identified where the end symptom on archs with virtually tagged caches could be a line of pixels written by userspace through one PTE remain in-cache and therefore "undisplayed" when the kernel reads through another PTE that may fall on a different cacheline. Thanks, jayakumar - To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [RFC 2.6.19 1/1] fbdev,mm: hecuba/E-Ink fbdev driver v2
On 12/22/06, Franck Bui-Huu [EMAIL PROTECTED] wrote: Well thinking more about it, this wouldn't work for all cache types. For example, if your cache is not a direct maped one, this workaround won't work. So this is definitely not a portable solution. From asking peterz on #mm, I think page_mkclean will do the right thing and call something like flush_cache_page. I think that resolves the issue which I think you identified where the end symptom on archs with virtually tagged caches could be a line of pixels written by userspace through one PTE remain in-cache and therefore undisplayed when the kernel reads through another PTE that may fall on a different cacheline. Thanks, jayakumar - To unsubscribe from this list: send the line unsubscribe linux-kernel in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [RFC 2.6.19 1/1] fbdev,mm: hecuba/E-Ink fbdev driver v2
On 12/20/06, Franck Bui-Huu <[EMAIL PROTECTED]> wrote: - when mmaping your frame buffer , be sure that the virtual address returned by mmap() to the application shares the same cache lines than the ones the kernel is using. Well thinking more about it, this wouldn't work for all cache types. For example, if your cache is not a direct maped one, this workaround won't work. So this is definitely not a portable solution. -- Franck - To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [RFC 2.6.19 1/1] fbdev,mm: hecuba/E-Ink fbdev driver v2
On 12/20/06, Franck Bui-Huu [EMAIL PROTECTED] wrote: - when mmaping your frame buffer , be sure that the virtual address returned by mmap() to the application shares the same cache lines than the ones the kernel is using. Well thinking more about it, this wouldn't work for all cache types. For example, if your cache is not a direct maped one, this workaround won't work. So this is definitely not a portable solution. -- Franck - To unsubscribe from this list: send the line unsubscribe linux-kernel in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [RFC 2.6.19 1/1] fbdev,mm: hecuba/E-Ink fbdev driver v2
On 12/17/06, Jaya Kumar <[EMAIL PROTECTED]> wrote: Ok. I now see what you mean. In typical cases, only one path is used to write. Meaning an app will decide to use the mmap path or the slow write path and the kernel only ever reads from its pte entry (unless fbcon is used which is not suited for this type of display). Even if the kernel does only reads, you can be in trouble. For example, the kernel access (by reading) to a data A through the cache line 1. The application access (by writing a new value) data A through the cahe line 5. Now it's time to update your frame buffer, so the kernel access to data A through the cache line 1 which still contains the _stall_ value. Note that flushing data before the kernel access it does not solve any problems. If the kernel is allowed to write into the frame buffer, the kernel don't know which line stores the up to date data... But you are right that it is possible for a situation to arise where one app does mmap and another is doing write. I would say that should be a safe case. Nornally the kernel takes care to flush caches between context switches (depending on your cache architecture). But it's only a guess, I haven't checked the code... My hope is that something takes care of flushing the data cache for me in this case. Do you recommend I add something to force that? Well I'm not the right person to answer this question. I haven't looked at how Linux handles cache consistency yet. Knowing that I can give you only 2 recommandations: - disable the cache when accessing your frame buffer (kernel and applications). - when mmaping your frame buffer , be sure that the virtual address returned by mmap() to the application shares the same cache lines than the ones the kernel is using. Hoping it helps, -- Franck - To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [RFC 2.6.19 1/1] fbdev,mm: hecuba/E-Ink fbdev driver v2
On 12/17/06, Jaya Kumar [EMAIL PROTECTED] wrote: Ok. I now see what you mean. In typical cases, only one path is used to write. Meaning an app will decide to use the mmap path or the slow write path and the kernel only ever reads from its pte entry (unless fbcon is used which is not suited for this type of display). Even if the kernel does only reads, you can be in trouble. For example, the kernel access (by reading) to a data A through the cache line 1. The application access (by writing a new value) data A through the cahe line 5. Now it's time to update your frame buffer, so the kernel access to data A through the cache line 1 which still contains the _stall_ value. Note that flushing data before the kernel access it does not solve any problems. If the kernel is allowed to write into the frame buffer, the kernel don't know which line stores the up to date data... But you are right that it is possible for a situation to arise where one app does mmap and another is doing write. I would say that should be a safe case. Nornally the kernel takes care to flush caches between context switches (depending on your cache architecture). But it's only a guess, I haven't checked the code... My hope is that something takes care of flushing the data cache for me in this case. Do you recommend I add something to force that? Well I'm not the right person to answer this question. I haven't looked at how Linux handles cache consistency yet. Knowing that I can give you only 2 recommandations: - disable the cache when accessing your frame buffer (kernel and applications). - when mmaping your frame buffer , be sure that the virtual address returned by mmap() to the application shares the same cache lines than the ones the kernel is using. Hoping it helps, -- Franck - To unsubscribe from this list: send the line unsubscribe linux-kernel in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [RFC 2.6.19 1/1] fbdev,mm: hecuba/E-Ink fbdev driver v2
On 12/13/06, Franck Bui-Huu <[EMAIL PROTECTED]> wrote: On 12/12/06, Jaya Kumar <[EMAIL PROTECTED]> wrote: > I think that PTEs set up by vmalloc are marked cacheable and via the > above nopage end up as cacheable. I'm not doing DMA. So the accesses > are through the cache so I don't think cache aliasing is an issue for > this case. Please let me know if I misunderstood. > This issue is not related to DMA: there are 2 different virtual addresses that can map the same physical address. If these 2 virtual addresses use 2 different data cache entries then you have a cache aliasing issue. In your case the 2 different virtual addresses are (1) Ok. I now see what you mean. In typical cases, only one path is used to write. Meaning an app will decide to use the mmap path or the slow write path and the kernel only ever reads from its pte entry (unless fbcon is used which is not suited for this type of display). But you are right that it is possible for a situation to arise where one app does mmap and another is doing write. My hope is that something takes care of flushing the data cache for me in this case. Do you recommend I add something to force that? I'm worried about having an fbdev driver that is too involved with mm. Thanks, jayakumar the one got by the kernel (returned by vmalloc) (2) the one got by the application (returned by mmap). Hope that helps. -- Franck - To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [RFC 2.6.19 1/1] fbdev,mm: hecuba/E-Ink fbdev driver v2
On 12/13/06, Franck Bui-Huu [EMAIL PROTECTED] wrote: On 12/12/06, Jaya Kumar [EMAIL PROTECTED] wrote: I think that PTEs set up by vmalloc are marked cacheable and via the above nopage end up as cacheable. I'm not doing DMA. So the accesses are through the cache so I don't think cache aliasing is an issue for this case. Please let me know if I misunderstood. This issue is not related to DMA: there are 2 different virtual addresses that can map the same physical address. If these 2 virtual addresses use 2 different data cache entries then you have a cache aliasing issue. In your case the 2 different virtual addresses are (1) Ok. I now see what you mean. In typical cases, only one path is used to write. Meaning an app will decide to use the mmap path or the slow write path and the kernel only ever reads from its pte entry (unless fbcon is used which is not suited for this type of display). But you are right that it is possible for a situation to arise where one app does mmap and another is doing write. My hope is that something takes care of flushing the data cache for me in this case. Do you recommend I add something to force that? I'm worried about having an fbdev driver that is too involved with mm. Thanks, jayakumar the one got by the kernel (returned by vmalloc) (2) the one got by the application (returned by mmap). Hope that helps. -- Franck - To unsubscribe from this list: send the line unsubscribe linux-kernel in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [RFC 2.6.19 1/1] fbdev,mm: hecuba/E-Ink fbdev driver v2
On 12/12/06, Jaya Kumar <[EMAIL PROTECTED]> wrote: I think that PTEs set up by vmalloc are marked cacheable and via the above nopage end up as cacheable. I'm not doing DMA. So the accesses are through the cache so I don't think cache aliasing is an issue for this case. Please let me know if I misunderstood. This issue is not related to DMA: there are 2 different virtual addresses that can map the same physical address. If these 2 virtual addresses use 2 different data cache entries then you have a cache aliasing issue. In your case the 2 different virtual addresses are (1) the one got by the kernel (returned by vmalloc) (2) the one got by the application (returned by mmap). Hope that helps. -- Franck - To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [RFC 2.6.19 1/1] fbdev,mm: hecuba/E-Ink fbdev driver v2
On 12/12/06, Jaya Kumar [EMAIL PROTECTED] wrote: I think that PTEs set up by vmalloc are marked cacheable and via the above nopage end up as cacheable. I'm not doing DMA. So the accesses are through the cache so I don't think cache aliasing is an issue for this case. Please let me know if I misunderstood. This issue is not related to DMA: there are 2 different virtual addresses that can map the same physical address. If these 2 virtual addresses use 2 different data cache entries then you have a cache aliasing issue. In your case the 2 different virtual addresses are (1) the one got by the kernel (returned by vmalloc) (2) the one got by the application (returned by mmap). Hope that helps. -- Franck - To unsubscribe from this list: send the line unsubscribe linux-kernel in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [RFC 2.6.19 1/1] fbdev,mm: hecuba/E-Ink fbdev driver v2
On 12/11/06, Franck Bui-Huu <[EMAIL PROTECTED]> wrote: [EMAIL PROTECTED] wrote: > + atomic_t ref_count; > + atomic_t vma_count; what purpose do these counters deserve ? You are right. I can remove them. > + > +void hcb_wait_for_ack(struct hecubafb_par *par) > +{ > + > + int timeout; > + unsigned char ctl; > + > + timeout=500; > + do { > + ctl = hcb_get_ctl(par); > + if ((ctl & HCB_ACK_BIT)) > + return; > + udelay(1); > + } while (timeout--); > + printk(KERN_ERR "timed out waiting for ack\n"); > +} When timeout occur this function does not return any error values. the callers needn't to be warn in this case ? You are right. I need to figure out what exactly to do. Currently, if a timeout is observed it normally means the display controller is hung. However, in some cases the controller does seem to recover after some period of time. I guess I should probably return an error and terminate pending activity. > + > +/* this is to find and return the vmalloc-ed fb pages */ > +static struct page* hecubafb_vm_nopage(struct vm_area_struct *vma, > + unsigned long vaddr, int *type) > +{ > + unsigned long offset; > + struct page *page; > + struct fb_info *info = vma->vm_private_data; > + > + offset = (vaddr - vma->vm_start) + (vma->vm_pgoff << PAGE_SHIFT); > + if (offset >= (DPY_W*DPY_H)/8) > + return NOPAGE_SIGBUS; > + > + page = vmalloc_to_page(info->screen_base + offset); > + if (!page) > + return NOPAGE_OOM; > + > + get_page(page); > + if (type) > + *type = VM_FAULT_MINOR; > + return page; > +} > + so page can be accessed by using vma->start virtual address The userspace app would be doing: ioctl(fd, FBIOGET_FSCREENINFO, ); ioctl(fd, FBIOGET_VSCREENINFO, ); screensize = ( vinfo.xres * vinfo.yres * vinfo.bits_per_pixel) / 8; maddr = mmap(finfo.mmio_start, screensize, PROT_WRITE, MAP_SHARED, fd, 0); > +static int hecubafb_page_mkwrite(struct vm_area_struct *vma, [snip] > + > + if (!(videomemory = vmalloc(videomemorysize))) > + return retval; and here the kernel access to the same page by using address returned by vmalloc which are different from the previous one. So 2 different addresses map the same physical page. In this case are there any cache aliasing issues specially for x86 arch ? I think that PTEs set up by vmalloc are marked cacheable and via the above nopage end up as cacheable. I'm not doing DMA. So the accesses are through the cache so I don't think cache aliasing is an issue for this case. Please let me know if I misunderstood. Thanks, jayakumar - To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [RFC 2.6.19 1/1] fbdev,mm: hecuba/E-Ink fbdev driver v2
Hi, [EMAIL PROTECTED] wrote: > Hi Geert, James, FBdev, MM folk, > > Appended is my attempt to support the Hecuba/E-Ink display. I've added > some code to do deferred IO. This is there in order to hide the latency > associated with updating the display (500ms to 800ms). The method used > is to fake a framebuffer in memory. Then use pagefaults followed by delayed > unmaping and only then do the actual framebuffer update. To explain this > better, the usage scenario is like this: > > - userspace app like Xfbdev mmaps framebuffer > - driver handles and sets up nopage and page_mkwrite handlers > - app tries to write to mmaped vaddress > - get pagefault and reaches driver's nopage handler > - driver's nopage handler finds and returns physical page ( no > actual framebuffer ) > - write so get page_mkwrite where we add this page to a list > - also schedules a workqueue task to be run after a delay > - app continues writing to that page with no additional cost > - the workqueue task comes in and unmaps the pages on the list, then > completes the work associated with updating the framebuffer > - app tries to write to the address (that has now been unmapped) > - get pagefault and the above sequence occurs again > > The desire is roughly to allow bursty framebuffer writes to occur. > Then after some time when hopefully things have gone quiet, we go and > really update the framebuffer. For this type of nonvolatile high latency > display, the desired image is the final image rather than intermediate > stages which is why it's okay to not update for each write that is > occuring. > > Please let me know if this looks okay so far and if you have any feedback > or suggestions. Thanks to peterz for the page_mkwrite/clean suggestions > that made this possible. > [snip] > +struct hecubafb_par { > + unsigned long dio_addr; > + unsigned long cio_addr; > + unsigned long c2io_addr; > + unsigned char ctl; > + atomic_t ref_count; > + atomic_t vma_count; what purpose do these counters deserve ? > + struct fb_info *info; > + unsigned int irq; > + spinlock_t lock; > + struct workqueue_struct *wq; > + struct work_struct work; > + struct list_head pagelist; > +}; > + [snip] > + > +void hcb_wait_for_ack(struct hecubafb_par *par) > +{ > + > + int timeout; > + unsigned char ctl; > + > + timeout=500; > + do { > + ctl = hcb_get_ctl(par); > + if ((ctl & HCB_ACK_BIT)) > + return; > + udelay(1); > + } while (timeout--); > + printk(KERN_ERR "timed out waiting for ack\n"); > +} When timeout occur this function does not return any error values. the callers needn't to be warn in this case ? > + > +void hcb_wait_for_ack_clear(struct hecubafb_par *par) [snip] > +} > + > +/* this is to find and return the vmalloc-ed fb pages */ > +static struct page* hecubafb_vm_nopage(struct vm_area_struct *vma, > + unsigned long vaddr, int *type) > +{ > + unsigned long offset; > + struct page *page; > + struct fb_info *info = vma->vm_private_data; > + > + offset = (vaddr - vma->vm_start) + (vma->vm_pgoff << PAGE_SHIFT); > + if (offset >= (DPY_W*DPY_H)/8) > + return NOPAGE_SIGBUS; > + > + page = vmalloc_to_page(info->screen_base + offset); > + if (!page) > + return NOPAGE_OOM; > + > + get_page(page); > + if (type) > + *type = VM_FAULT_MINOR; > + return page; > +} > + so page can be accessed by using vma->start virtual address > +static int hecubafb_page_mkwrite(struct vm_area_struct *vma, [snip] > + > + if (!(videomemory = vmalloc(videomemorysize))) > + return retval; and here the kernel access to the same page by using address returned by vmalloc which are different from the previous one. So 2 different addresses map the same physical page. In this case are there any cache aliasing issues specially for x86 arch ? thanks Franck - To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[RFC 2.6.19 1/1] fbdev,mm: hecuba/E-Ink fbdev driver v2
Hi Geert, James, FBdev, MM folk, Appended is my attempt to support the Hecuba/E-Ink display. I've added some code to do deferred IO. This is there in order to hide the latency associated with updating the display (500ms to 800ms). The method used is to fake a framebuffer in memory. Then use pagefaults followed by delayed unmaping and only then do the actual framebuffer update. To explain this better, the usage scenario is like this: - userspace app like Xfbdev mmaps framebuffer - driver handles and sets up nopage and page_mkwrite handlers - app tries to write to mmaped vaddress - get pagefault and reaches driver's nopage handler - driver's nopage handler finds and returns physical page ( no actual framebuffer ) - write so get page_mkwrite where we add this page to a list - also schedules a workqueue task to be run after a delay - app continues writing to that page with no additional cost - the workqueue task comes in and unmaps the pages on the list, then completes the work associated with updating the framebuffer - app tries to write to the address (that has now been unmapped) - get pagefault and the above sequence occurs again The desire is roughly to allow bursty framebuffer writes to occur. Then after some time when hopefully things have gone quiet, we go and really update the framebuffer. For this type of nonvolatile high latency display, the desired image is the final image rather than intermediate stages which is why it's okay to not update for each write that is occuring. Please let me know if this looks okay so far and if you have any feedback or suggestions. Thanks to peterz for the page_mkwrite/clean suggestions that made this possible. Thanks, Jaya Kumar Signed-off-by: Jaya Kumar <[EMAIL PROTECTED]> --- drivers/video/Kconfig| 13 drivers/video/Makefile |1 drivers/video/hecubafb.c | 643 +++ mm/filemap.c |1 mm/rmap.c|1 5 files changed, 659 insertions(+) --- diff -X linux-2.6.19/Documentation/dontdiff -uprN linux-2.6.19-vanilla/drivers/video/hecubafb.c linux-2.6.19/drivers/video/hecubafb.c --- linux-2.6.19-vanilla/drivers/video/hecubafb.c 1970-01-01 07:30:00.0 +0730 +++ linux-2.6.19/drivers/video/hecubafb.c 2006-12-11 18:52:07.0 +0800 @@ -0,0 +1,643 @@ +/* + * linux/drivers/video/hecubafb.c -- FB driver for Hecuba controller + * + * Copyright (C) 2006, Jaya Kumar + * This work was sponsored by CIS(M) Sdn Bhd + * + * 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 for + * more details. + * + * Layout is based on skeletonfb.c by James Simmons and Geert Uytterhoeven. + * This work was possible because of apollo display code from E-Ink's website + * http://support.eink.com/community + * All information used to write this code is from public material made + * available by E-Ink on its support site. Some commands such as 0xA4 + * were found by looping through cmd=0x00 thru 0xFF and supplying random + * values. There are other commands that the display is capable of, + * beyond the 5 used here but they are more complex. + * + * This driver is written to be used with the Hecuba display controller + * board, and tested with the EInk 800x600 display in 1 bit mode. + * The interface between Hecuba and the host is TTL based GPIO. The + * GPIO requirements are 8 writable data lines and 6 lines for control. + * Only 4 of the controls are actually used here but 6 for future use. + * The driver requires the IO addresses for data and control GPIO at + * load time. It is also possible to use this display with a standard + * PC parallel port. + * + * General notes: + * - User must set hecubafb_enable=1 to enable it + * - User must set dio_addr=0xIOADDR cio_addr=0xIOADDR c2io_addr=0xIOADDR + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* to support deferred IO */ +#include +#include + +/* Apollo controller specific defines */ +#define APOLLO_START_NEW_IMG 0xA0 +#define APOLLO_STOP_IMG_DATA 0xA1 +#define APOLLO_DISPLAY_IMG 0xA2 +#define APOLLO_ERASE_DISPLAY 0xA3 +#define APOLLO_INIT_DISPLAY0xA4 + +/* Hecuba interface specific defines */ +/* WUP is inverted, CD is inverted, DS is inverted */ +#define HCB_NWUP_BIT 0x01 +#define HCB_NDS_BIT0x02 +#define HCB_RW_BIT 0x04 +#define HCB_NCD_BIT0x08 +#define HCB_ACK_BIT0x80 + +/* Display specific information */ +#define DPY_W 600 +#define DPY_H 800 + +struct hecubafb_par { + unsigned long dio_addr; + unsigned long cio_addr; + unsigned long c2io_addr; + unsigned char ctl; + atomic_t ref_count; + atomic_t vma_count; + struct fb_info *info; + unsigned int irq; + spinlock_t lock; + struct workqueue_struct *wq;
[RFC 2.6.19 1/1] fbdev,mm: hecuba/E-Ink fbdev driver v2
Hi Geert, James, FBdev, MM folk, Appended is my attempt to support the Hecuba/E-Ink display. I've added some code to do deferred IO. This is there in order to hide the latency associated with updating the display (500ms to 800ms). The method used is to fake a framebuffer in memory. Then use pagefaults followed by delayed unmaping and only then do the actual framebuffer update. To explain this better, the usage scenario is like this: - userspace app like Xfbdev mmaps framebuffer - driver handles and sets up nopage and page_mkwrite handlers - app tries to write to mmaped vaddress - get pagefault and reaches driver's nopage handler - driver's nopage handler finds and returns physical page ( no actual framebuffer ) - write so get page_mkwrite where we add this page to a list - also schedules a workqueue task to be run after a delay - app continues writing to that page with no additional cost - the workqueue task comes in and unmaps the pages on the list, then completes the work associated with updating the framebuffer - app tries to write to the address (that has now been unmapped) - get pagefault and the above sequence occurs again The desire is roughly to allow bursty framebuffer writes to occur. Then after some time when hopefully things have gone quiet, we go and really update the framebuffer. For this type of nonvolatile high latency display, the desired image is the final image rather than intermediate stages which is why it's okay to not update for each write that is occuring. Please let me know if this looks okay so far and if you have any feedback or suggestions. Thanks to peterz for the page_mkwrite/clean suggestions that made this possible. Thanks, Jaya Kumar Signed-off-by: Jaya Kumar [EMAIL PROTECTED] --- drivers/video/Kconfig| 13 drivers/video/Makefile |1 drivers/video/hecubafb.c | 643 +++ mm/filemap.c |1 mm/rmap.c|1 5 files changed, 659 insertions(+) --- diff -X linux-2.6.19/Documentation/dontdiff -uprN linux-2.6.19-vanilla/drivers/video/hecubafb.c linux-2.6.19/drivers/video/hecubafb.c --- linux-2.6.19-vanilla/drivers/video/hecubafb.c 1970-01-01 07:30:00.0 +0730 +++ linux-2.6.19/drivers/video/hecubafb.c 2006-12-11 18:52:07.0 +0800 @@ -0,0 +1,643 @@ +/* + * linux/drivers/video/hecubafb.c -- FB driver for Hecuba controller + * + * Copyright (C) 2006, Jaya Kumar + * This work was sponsored by CIS(M) Sdn Bhd + * + * 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 for + * more details. + * + * Layout is based on skeletonfb.c by James Simmons and Geert Uytterhoeven. + * This work was possible because of apollo display code from E-Ink's website + * http://support.eink.com/community + * All information used to write this code is from public material made + * available by E-Ink on its support site. Some commands such as 0xA4 + * were found by looping through cmd=0x00 thru 0xFF and supplying random + * values. There are other commands that the display is capable of, + * beyond the 5 used here but they are more complex. + * + * This driver is written to be used with the Hecuba display controller + * board, and tested with the EInk 800x600 display in 1 bit mode. + * The interface between Hecuba and the host is TTL based GPIO. The + * GPIO requirements are 8 writable data lines and 6 lines for control. + * Only 4 of the controls are actually used here but 6 for future use. + * The driver requires the IO addresses for data and control GPIO at + * load time. It is also possible to use this display with a standard + * PC parallel port. + * + * General notes: + * - User must set hecubafb_enable=1 to enable it + * - User must set dio_addr=0xIOADDR cio_addr=0xIOADDR c2io_addr=0xIOADDR + * + */ + +#include asm/uaccess.h +#include linux/module.h +#include linux/kernel.h +#include linux/errno.h +#include linux/string.h +#include linux/mm.h +#include linux/slab.h +#include linux/vmalloc.h +#include linux/delay.h +#include linux/interrupt.h +#include linux/fb.h +#include linux/init.h +#include linux/platform_device.h +#include linux/list.h + +/* to support deferred IO */ +#include linux/rmap.h +#include linux/pagemap.h + +/* Apollo controller specific defines */ +#define APOLLO_START_NEW_IMG 0xA0 +#define APOLLO_STOP_IMG_DATA 0xA1 +#define APOLLO_DISPLAY_IMG 0xA2 +#define APOLLO_ERASE_DISPLAY 0xA3 +#define APOLLO_INIT_DISPLAY0xA4 + +/* Hecuba interface specific defines */ +/* WUP is inverted, CD is inverted, DS is inverted */ +#define HCB_NWUP_BIT 0x01 +#define HCB_NDS_BIT0x02 +#define HCB_RW_BIT 0x04 +#define HCB_NCD_BIT0x08 +#define HCB_ACK_BIT0x80 + +/* Display specific information */ +#define DPY_W 600 +#define DPY_H 800 + +struct hecubafb_par { + unsigned long dio_addr; + unsigned long cio_addr; + unsigned
Re: [RFC 2.6.19 1/1] fbdev,mm: hecuba/E-Ink fbdev driver v2
Hi, [EMAIL PROTECTED] wrote: Hi Geert, James, FBdev, MM folk, Appended is my attempt to support the Hecuba/E-Ink display. I've added some code to do deferred IO. This is there in order to hide the latency associated with updating the display (500ms to 800ms). The method used is to fake a framebuffer in memory. Then use pagefaults followed by delayed unmaping and only then do the actual framebuffer update. To explain this better, the usage scenario is like this: - userspace app like Xfbdev mmaps framebuffer - driver handles and sets up nopage and page_mkwrite handlers - app tries to write to mmaped vaddress - get pagefault and reaches driver's nopage handler - driver's nopage handler finds and returns physical page ( no actual framebuffer ) - write so get page_mkwrite where we add this page to a list - also schedules a workqueue task to be run after a delay - app continues writing to that page with no additional cost - the workqueue task comes in and unmaps the pages on the list, then completes the work associated with updating the framebuffer - app tries to write to the address (that has now been unmapped) - get pagefault and the above sequence occurs again The desire is roughly to allow bursty framebuffer writes to occur. Then after some time when hopefully things have gone quiet, we go and really update the framebuffer. For this type of nonvolatile high latency display, the desired image is the final image rather than intermediate stages which is why it's okay to not update for each write that is occuring. Please let me know if this looks okay so far and if you have any feedback or suggestions. Thanks to peterz for the page_mkwrite/clean suggestions that made this possible. [snip] +struct hecubafb_par { + unsigned long dio_addr; + unsigned long cio_addr; + unsigned long c2io_addr; + unsigned char ctl; + atomic_t ref_count; + atomic_t vma_count; what purpose do these counters deserve ? + struct fb_info *info; + unsigned int irq; + spinlock_t lock; + struct workqueue_struct *wq; + struct work_struct work; + struct list_head pagelist; +}; + [snip] + +void hcb_wait_for_ack(struct hecubafb_par *par) +{ + + int timeout; + unsigned char ctl; + + timeout=500; + do { + ctl = hcb_get_ctl(par); + if ((ctl HCB_ACK_BIT)) + return; + udelay(1); + } while (timeout--); + printk(KERN_ERR timed out waiting for ack\n); +} When timeout occur this function does not return any error values. the callers needn't to be warn in this case ? + +void hcb_wait_for_ack_clear(struct hecubafb_par *par) [snip] +} + +/* this is to find and return the vmalloc-ed fb pages */ +static struct page* hecubafb_vm_nopage(struct vm_area_struct *vma, + unsigned long vaddr, int *type) +{ + unsigned long offset; + struct page *page; + struct fb_info *info = vma-vm_private_data; + + offset = (vaddr - vma-vm_start) + (vma-vm_pgoff PAGE_SHIFT); + if (offset = (DPY_W*DPY_H)/8) + return NOPAGE_SIGBUS; + + page = vmalloc_to_page(info-screen_base + offset); + if (!page) + return NOPAGE_OOM; + + get_page(page); + if (type) + *type = VM_FAULT_MINOR; + return page; +} + so page can be accessed by using vma-start virtual address +static int hecubafb_page_mkwrite(struct vm_area_struct *vma, [snip] + + if (!(videomemory = vmalloc(videomemorysize))) + return retval; and here the kernel access to the same page by using address returned by vmalloc which are different from the previous one. So 2 different addresses map the same physical page. In this case are there any cache aliasing issues specially for x86 arch ? thanks Franck - To unsubscribe from this list: send the line unsubscribe linux-kernel in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [RFC 2.6.19 1/1] fbdev,mm: hecuba/E-Ink fbdev driver v2
On 12/11/06, Franck Bui-Huu [EMAIL PROTECTED] wrote: [EMAIL PROTECTED] wrote: + atomic_t ref_count; + atomic_t vma_count; what purpose do these counters deserve ? You are right. I can remove them. + +void hcb_wait_for_ack(struct hecubafb_par *par) +{ + + int timeout; + unsigned char ctl; + + timeout=500; + do { + ctl = hcb_get_ctl(par); + if ((ctl HCB_ACK_BIT)) + return; + udelay(1); + } while (timeout--); + printk(KERN_ERR timed out waiting for ack\n); +} When timeout occur this function does not return any error values. the callers needn't to be warn in this case ? You are right. I need to figure out what exactly to do. Currently, if a timeout is observed it normally means the display controller is hung. However, in some cases the controller does seem to recover after some period of time. I guess I should probably return an error and terminate pending activity. + +/* this is to find and return the vmalloc-ed fb pages */ +static struct page* hecubafb_vm_nopage(struct vm_area_struct *vma, + unsigned long vaddr, int *type) +{ + unsigned long offset; + struct page *page; + struct fb_info *info = vma-vm_private_data; + + offset = (vaddr - vma-vm_start) + (vma-vm_pgoff PAGE_SHIFT); + if (offset = (DPY_W*DPY_H)/8) + return NOPAGE_SIGBUS; + + page = vmalloc_to_page(info-screen_base + offset); + if (!page) + return NOPAGE_OOM; + + get_page(page); + if (type) + *type = VM_FAULT_MINOR; + return page; +} + so page can be accessed by using vma-start virtual address The userspace app would be doing: ioctl(fd, FBIOGET_FSCREENINFO, finfo); ioctl(fd, FBIOGET_VSCREENINFO, vinfo); screensize = ( vinfo.xres * vinfo.yres * vinfo.bits_per_pixel) / 8; maddr = mmap(finfo.mmio_start, screensize, PROT_WRITE, MAP_SHARED, fd, 0); +static int hecubafb_page_mkwrite(struct vm_area_struct *vma, [snip] + + if (!(videomemory = vmalloc(videomemorysize))) + return retval; and here the kernel access to the same page by using address returned by vmalloc which are different from the previous one. So 2 different addresses map the same physical page. In this case are there any cache aliasing issues specially for x86 arch ? I think that PTEs set up by vmalloc are marked cacheable and via the above nopage end up as cacheable. I'm not doing DMA. So the accesses are through the cache so I don't think cache aliasing is an issue for this case. Please let me know if I misunderstood. Thanks, jayakumar - To unsubscribe from this list: send the line unsubscribe linux-kernel in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/