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