xref: /OK3568_Linux_fs/kernel/Documentation/driver-api/io-mapping.rst (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1*4882a593Smuzhiyun========================
2*4882a593SmuzhiyunThe io_mapping functions
3*4882a593Smuzhiyun========================
4*4882a593Smuzhiyun
5*4882a593SmuzhiyunAPI
6*4882a593Smuzhiyun===
7*4882a593Smuzhiyun
8*4882a593SmuzhiyunThe io_mapping functions in linux/io-mapping.h provide an abstraction for
9*4882a593Smuzhiyunefficiently mapping small regions of an I/O device to the CPU. The initial
10*4882a593Smuzhiyunusage is to support the large graphics aperture on 32-bit processors where
11*4882a593Smuzhiyunioremap_wc cannot be used to statically map the entire aperture to the CPU
12*4882a593Smuzhiyunas it would consume too much of the kernel address space.
13*4882a593Smuzhiyun
14*4882a593SmuzhiyunA mapping object is created during driver initialization using::
15*4882a593Smuzhiyun
16*4882a593Smuzhiyun	struct io_mapping *io_mapping_create_wc(unsigned long base,
17*4882a593Smuzhiyun						unsigned long size)
18*4882a593Smuzhiyun
19*4882a593Smuzhiyun'base' is the bus address of the region to be made
20*4882a593Smuzhiyunmappable, while 'size' indicates how large a mapping region to
21*4882a593Smuzhiyunenable. Both are in bytes.
22*4882a593Smuzhiyun
23*4882a593SmuzhiyunThis _wc variant provides a mapping which may only be used
24*4882a593Smuzhiyunwith the io_mapping_map_atomic_wc or io_mapping_map_wc.
25*4882a593Smuzhiyun
26*4882a593SmuzhiyunWith this mapping object, individual pages can be mapped either atomically
27*4882a593Smuzhiyunor not, depending on the necessary scheduling environment. Of course, atomic
28*4882a593Smuzhiyunmaps are more efficient::
29*4882a593Smuzhiyun
30*4882a593Smuzhiyun	void *io_mapping_map_atomic_wc(struct io_mapping *mapping,
31*4882a593Smuzhiyun				       unsigned long offset)
32*4882a593Smuzhiyun
33*4882a593Smuzhiyun'offset' is the offset within the defined mapping region.
34*4882a593SmuzhiyunAccessing addresses beyond the region specified in the
35*4882a593Smuzhiyuncreation function yields undefined results. Using an offset
36*4882a593Smuzhiyunwhich is not page aligned yields an undefined result. The
37*4882a593Smuzhiyunreturn value points to a single page in CPU address space.
38*4882a593Smuzhiyun
39*4882a593SmuzhiyunThis _wc variant returns a write-combining map to the
40*4882a593Smuzhiyunpage and may only be used with mappings created by
41*4882a593Smuzhiyunio_mapping_create_wc
42*4882a593Smuzhiyun
43*4882a593SmuzhiyunNote that the task may not sleep while holding this page
44*4882a593Smuzhiyunmapped.
45*4882a593Smuzhiyun
46*4882a593Smuzhiyun::
47*4882a593Smuzhiyun
48*4882a593Smuzhiyun	void io_mapping_unmap_atomic(void *vaddr)
49*4882a593Smuzhiyun
50*4882a593Smuzhiyun'vaddr' must be the value returned by the last
51*4882a593Smuzhiyunio_mapping_map_atomic_wc call. This unmaps the specified
52*4882a593Smuzhiyunpage and allows the task to sleep once again.
53*4882a593Smuzhiyun
54*4882a593SmuzhiyunIf you need to sleep while holding the lock, you can use the non-atomic
55*4882a593Smuzhiyunvariant, although they may be significantly slower.
56*4882a593Smuzhiyun
57*4882a593Smuzhiyun::
58*4882a593Smuzhiyun
59*4882a593Smuzhiyun	void *io_mapping_map_wc(struct io_mapping *mapping,
60*4882a593Smuzhiyun				unsigned long offset)
61*4882a593Smuzhiyun
62*4882a593SmuzhiyunThis works like io_mapping_map_atomic_wc except it allows
63*4882a593Smuzhiyunthe task to sleep while holding the page mapped.
64*4882a593Smuzhiyun
65*4882a593Smuzhiyun
66*4882a593Smuzhiyun::
67*4882a593Smuzhiyun
68*4882a593Smuzhiyun	void io_mapping_unmap(void *vaddr)
69*4882a593Smuzhiyun
70*4882a593SmuzhiyunThis works like io_mapping_unmap_atomic, except it is used
71*4882a593Smuzhiyunfor pages mapped with io_mapping_map_wc.
72*4882a593Smuzhiyun
73*4882a593SmuzhiyunAt driver close time, the io_mapping object must be freed::
74*4882a593Smuzhiyun
75*4882a593Smuzhiyun	void io_mapping_free(struct io_mapping *mapping)
76*4882a593Smuzhiyun
77*4882a593SmuzhiyunCurrent Implementation
78*4882a593Smuzhiyun======================
79*4882a593Smuzhiyun
80*4882a593SmuzhiyunThe initial implementation of these functions uses existing mapping
81*4882a593Smuzhiyunmechanisms and so provides only an abstraction layer and no new
82*4882a593Smuzhiyunfunctionality.
83*4882a593Smuzhiyun
84*4882a593SmuzhiyunOn 64-bit processors, io_mapping_create_wc calls ioremap_wc for the whole
85*4882a593Smuzhiyunrange, creating a permanent kernel-visible mapping to the resource. The
86*4882a593Smuzhiyunmap_atomic and map functions add the requested offset to the base of the
87*4882a593Smuzhiyunvirtual address returned by ioremap_wc.
88*4882a593Smuzhiyun
89*4882a593SmuzhiyunOn 32-bit processors with HIGHMEM defined, io_mapping_map_atomic_wc uses
90*4882a593Smuzhiyunkmap_atomic_pfn to map the specified page in an atomic fashion;
91*4882a593Smuzhiyunkmap_atomic_pfn isn't really supposed to be used with device pages, but it
92*4882a593Smuzhiyunprovides an efficient mapping for this usage.
93*4882a593Smuzhiyun
94*4882a593SmuzhiyunOn 32-bit processors without HIGHMEM defined, io_mapping_map_atomic_wc and
95*4882a593Smuzhiyunio_mapping_map_wc both use ioremap_wc, a terribly inefficient function which
96*4882a593Smuzhiyunperforms an IPI to inform all processors about the new mapping. This results
97*4882a593Smuzhiyunin a significant performance penalty.
98