xref: /openbmc/linux/Documentation/driver-api/io-mapping.rst (revision 9a87ffc99ec8eb8d35eed7c4f816d75f5cc9662e)
1fcd68072SPragat Pandya========================
2fcd68072SPragat PandyaThe io_mapping functions
3fcd68072SPragat Pandya========================
4fcd68072SPragat Pandya
5fcd68072SPragat PandyaAPI
6fcd68072SPragat Pandya===
7fcd68072SPragat Pandya
8fcd68072SPragat PandyaThe io_mapping functions in linux/io-mapping.h provide an abstraction for
9fcd68072SPragat Pandyaefficiently mapping small regions of an I/O device to the CPU. The initial
10fcd68072SPragat Pandyausage is to support the large graphics aperture on 32-bit processors where
11fcd68072SPragat Pandyaioremap_wc cannot be used to statically map the entire aperture to the CPU
12fcd68072SPragat Pandyaas it would consume too much of the kernel address space.
13fcd68072SPragat Pandya
14fcd68072SPragat PandyaA mapping object is created during driver initialization using::
15fcd68072SPragat Pandya
16fcd68072SPragat Pandya	struct io_mapping *io_mapping_create_wc(unsigned long base,
17fcd68072SPragat Pandya						unsigned long size)
18fcd68072SPragat Pandya
19fcd68072SPragat Pandya'base' is the bus address of the region to be made
20fcd68072SPragat Pandyamappable, while 'size' indicates how large a mapping region to
21fcd68072SPragat Pandyaenable. Both are in bytes.
22fcd68072SPragat Pandya
23e66f6e09SThomas GleixnerThis _wc variant provides a mapping which may only be used with
24e66f6e09SThomas Gleixnerio_mapping_map_atomic_wc(), io_mapping_map_local_wc() or
25e66f6e09SThomas Gleixnerio_mapping_map_wc().
26fcd68072SPragat Pandya
27e66f6e09SThomas GleixnerWith this mapping object, individual pages can be mapped either temporarily
28e66f6e09SThomas Gleixneror long term, depending on the requirements. Of course, temporary maps are
29e66f6e09SThomas Gleixnermore efficient. They come in two flavours::
30e66f6e09SThomas Gleixner
31e66f6e09SThomas Gleixner	void *io_mapping_map_local_wc(struct io_mapping *mapping,
32e66f6e09SThomas Gleixner				      unsigned long offset)
33fcd68072SPragat Pandya
34fcd68072SPragat Pandya	void *io_mapping_map_atomic_wc(struct io_mapping *mapping,
35fcd68072SPragat Pandya				       unsigned long offset)
36fcd68072SPragat Pandya
37e66f6e09SThomas Gleixner'offset' is the offset within the defined mapping region.  Accessing
38e66f6e09SThomas Gleixneraddresses beyond the region specified in the creation function yields
39e66f6e09SThomas Gleixnerundefined results. Using an offset which is not page aligned yields an
40e66f6e09SThomas Gleixnerundefined result. The return value points to a single page in CPU address
41e66f6e09SThomas Gleixnerspace.
42fcd68072SPragat Pandya
43e66f6e09SThomas GleixnerThis _wc variant returns a write-combining map to the page and may only be
44e66f6e09SThomas Gleixnerused with mappings created by io_mapping_create_wc()
45fcd68072SPragat Pandya
46e66f6e09SThomas GleixnerTemporary mappings are only valid in the context of the caller. The mapping
47*7852fe3aSRandy Dunlapis not guaranteed to be globally visible.
48fcd68072SPragat Pandya
49e66f6e09SThomas Gleixnerio_mapping_map_local_wc() has a side effect on X86 32bit as it disables
50e66f6e09SThomas Gleixnermigration to make the mapping code work. No caller can rely on this side
51e66f6e09SThomas Gleixnereffect.
52fcd68072SPragat Pandya
53e66f6e09SThomas Gleixnerio_mapping_map_atomic_wc() has the side effect of disabling preemption and
54e66f6e09SThomas Gleixnerpagefaults. Don't use in new code. Use io_mapping_map_local_wc() instead.
55e66f6e09SThomas Gleixner
56e66f6e09SThomas GleixnerNested mappings need to be undone in reverse order because the mapping
57e66f6e09SThomas Gleixnercode uses a stack for keeping track of them::
58e66f6e09SThomas Gleixner
59e66f6e09SThomas Gleixner addr1 = io_mapping_map_local_wc(map1, offset1);
60e66f6e09SThomas Gleixner addr2 = io_mapping_map_local_wc(map2, offset2);
61e66f6e09SThomas Gleixner ...
62e66f6e09SThomas Gleixner io_mapping_unmap_local(addr2);
63e66f6e09SThomas Gleixner io_mapping_unmap_local(addr1);
64e66f6e09SThomas Gleixner
65e66f6e09SThomas GleixnerThe mappings are released with::
66e66f6e09SThomas Gleixner
67e66f6e09SThomas Gleixner	void io_mapping_unmap_local(void *vaddr)
68fcd68072SPragat Pandya	void io_mapping_unmap_atomic(void *vaddr)
69fcd68072SPragat Pandya
70e66f6e09SThomas Gleixner'vaddr' must be the value returned by the last io_mapping_map_local_wc() or
71e66f6e09SThomas Gleixnerio_mapping_map_atomic_wc() call. This unmaps the specified mapping and
72e66f6e09SThomas Gleixnerundoes the side effects of the mapping functions.
73fcd68072SPragat Pandya
74e66f6e09SThomas GleixnerIf you need to sleep while holding a mapping, you can use the regular
75e66f6e09SThomas Gleixnervariant, although this may be significantly slower::
76fcd68072SPragat Pandya
77fcd68072SPragat Pandya	void *io_mapping_map_wc(struct io_mapping *mapping,
78fcd68072SPragat Pandya				unsigned long offset)
79fcd68072SPragat Pandya
80e66f6e09SThomas GleixnerThis works like io_mapping_map_atomic/local_wc() except it has no side
81*7852fe3aSRandy Dunlapeffects and the pointer is globally visible.
82fcd68072SPragat Pandya
83e66f6e09SThomas GleixnerThe mappings are released with::
84fcd68072SPragat Pandya
85fcd68072SPragat Pandya	void io_mapping_unmap(void *vaddr)
86fcd68072SPragat Pandya
87e66f6e09SThomas GleixnerUse for pages mapped with io_mapping_map_wc().
88fcd68072SPragat Pandya
89fcd68072SPragat PandyaAt driver close time, the io_mapping object must be freed::
90fcd68072SPragat Pandya
91fcd68072SPragat Pandya	void io_mapping_free(struct io_mapping *mapping)
92