xref: /OK3568_Linux_fs/kernel/Documentation/fb/deferred_io.rst (revision 4882a59341e53eb6f0b4789bf948001014eff981)
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