1*4882a593Smuzhiyun=========== 2*4882a593SmuzhiyunDeferred IO 3*4882a593Smuzhiyun=========== 4*4882a593Smuzhiyun 5*4882a593SmuzhiyunDeferred IO is a way to delay and repurpose IO. It uses host memory as a 6*4882a593Smuzhiyunbuffer and the MMU pagefault as a pretrigger for when to perform the device 7*4882a593SmuzhiyunIO. The following example may be a useful explanation of how one such setup 8*4882a593Smuzhiyunworks: 9*4882a593Smuzhiyun 10*4882a593Smuzhiyun- userspace app like Xfbdev mmaps framebuffer 11*4882a593Smuzhiyun- deferred IO and driver sets up fault and page_mkwrite handlers 12*4882a593Smuzhiyun- userspace app tries to write to mmaped vaddress 13*4882a593Smuzhiyun- we get pagefault and reach fault handler 14*4882a593Smuzhiyun- fault handler finds and returns physical page 15*4882a593Smuzhiyun- we get page_mkwrite where we add this page to a list 16*4882a593Smuzhiyun- schedule a workqueue task to be run after a delay 17*4882a593Smuzhiyun- app continues writing to that page with no additional cost. this is 18*4882a593Smuzhiyun the key benefit. 19*4882a593Smuzhiyun- the workqueue task comes in and mkcleans the pages on the list, then 20*4882a593Smuzhiyun completes the work associated with updating the framebuffer. this is 21*4882a593Smuzhiyun the real work talking to the device. 22*4882a593Smuzhiyun- app tries to write to the address (that has now been mkcleaned) 23*4882a593Smuzhiyun- get pagefault and the above sequence occurs again 24*4882a593Smuzhiyun 25*4882a593SmuzhiyunAs can be seen from above, one benefit is roughly to allow bursty framebuffer 26*4882a593Smuzhiyunwrites to occur at minimum cost. Then after some time when hopefully things 27*4882a593Smuzhiyunhave gone quiet, we go and really update the framebuffer which would be 28*4882a593Smuzhiyuna relatively more expensive operation. 29*4882a593Smuzhiyun 30*4882a593SmuzhiyunFor some types of nonvolatile high latency displays, the desired image is 31*4882a593Smuzhiyunthe final image rather than the intermediate stages which is why it's okay 32*4882a593Smuzhiyunto not update for each write that is occurring. 33*4882a593Smuzhiyun 34*4882a593SmuzhiyunIt may be the case that this is useful in other scenarios as well. Paul Mundt 35*4882a593Smuzhiyunhas mentioned a case where it is beneficial to use the page count to decide 36*4882a593Smuzhiyunwhether to coalesce and issue SG DMA or to do memory bursts. 37*4882a593Smuzhiyun 38*4882a593SmuzhiyunAnother one may be if one has a device framebuffer that is in an usual format, 39*4882a593Smuzhiyunsay diagonally shifting RGB, this may then be a mechanism for you to allow 40*4882a593Smuzhiyunapps to pretend to have a normal framebuffer but reswizzle for the device 41*4882a593Smuzhiyunframebuffer at vsync time based on the touched pagelist. 42*4882a593Smuzhiyun 43*4882a593SmuzhiyunHow to use it: (for applications) 44*4882a593Smuzhiyun--------------------------------- 45*4882a593SmuzhiyunNo changes needed. mmap the framebuffer like normal and just use it. 46*4882a593Smuzhiyun 47*4882a593SmuzhiyunHow to use it: (for fbdev drivers) 48*4882a593Smuzhiyun---------------------------------- 49*4882a593SmuzhiyunThe following example may be helpful. 50*4882a593Smuzhiyun 51*4882a593Smuzhiyun1. Setup your structure. Eg:: 52*4882a593Smuzhiyun 53*4882a593Smuzhiyun static struct fb_deferred_io hecubafb_defio = { 54*4882a593Smuzhiyun .delay = HZ, 55*4882a593Smuzhiyun .deferred_io = hecubafb_dpy_deferred_io, 56*4882a593Smuzhiyun }; 57*4882a593Smuzhiyun 58*4882a593SmuzhiyunThe delay is the minimum delay between when the page_mkwrite trigger occurs 59*4882a593Smuzhiyunand when the deferred_io callback is called. The deferred_io callback is 60*4882a593Smuzhiyunexplained below. 61*4882a593Smuzhiyun 62*4882a593Smuzhiyun2. Setup your deferred IO callback. Eg:: 63*4882a593Smuzhiyun 64*4882a593Smuzhiyun static void hecubafb_dpy_deferred_io(struct fb_info *info, 65*4882a593Smuzhiyun struct list_head *pagelist) 66*4882a593Smuzhiyun 67*4882a593SmuzhiyunThe deferred_io callback is where you would perform all your IO to the display 68*4882a593Smuzhiyundevice. You receive the pagelist which is the list of pages that were written 69*4882a593Smuzhiyunto during the delay. You must not modify this list. This callback is called 70*4882a593Smuzhiyunfrom a workqueue. 71*4882a593Smuzhiyun 72*4882a593Smuzhiyun3. Call init:: 73*4882a593Smuzhiyun 74*4882a593Smuzhiyun info->fbdefio = &hecubafb_defio; 75*4882a593Smuzhiyun fb_deferred_io_init(info); 76*4882a593Smuzhiyun 77*4882a593Smuzhiyun4. Call cleanup:: 78*4882a593Smuzhiyun 79*4882a593Smuzhiyun fb_deferred_io_cleanup(info); 80