Orange Pi5 kernel

Deprecated Linux kernel 5.10.110 for OrangePi 5/5B/5+ boards

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