at v5.13 8.3 kB view raw
1/* SPDX-License-Identifier: GPL-2.0-only */ 2/* 3 * Pointer to dma-buf-mapped memory, plus helpers. 4 */ 5 6#ifndef __DMA_BUF_MAP_H__ 7#define __DMA_BUF_MAP_H__ 8 9#include <linux/io.h> 10#include <linux/string.h> 11 12/** 13 * DOC: overview 14 * 15 * Calling dma-buf's vmap operation returns a pointer to the buffer's memory. 16 * Depending on the location of the buffer, users may have to access it with 17 * I/O operations or memory load/store operations. For example, copying to 18 * system memory could be done with memcpy(), copying to I/O memory would be 19 * done with memcpy_toio(). 20 * 21 * .. code-block:: c 22 * 23 * void *vaddr = ...; // pointer to system memory 24 * memcpy(vaddr, src, len); 25 * 26 * void *vaddr_iomem = ...; // pointer to I/O memory 27 * memcpy_toio(vaddr, _iomem, src, len); 28 * 29 * When using dma-buf's vmap operation, the returned pointer is encoded as 30 * :c:type:`struct dma_buf_map <dma_buf_map>`. 31 * :c:type:`struct dma_buf_map <dma_buf_map>` stores the buffer's address in 32 * system or I/O memory and a flag that signals the required method of 33 * accessing the buffer. Use the returned instance and the helper functions 34 * to access the buffer's memory in the correct way. 35 * 36 * The type :c:type:`struct dma_buf_map <dma_buf_map>` and its helpers are 37 * actually independent from the dma-buf infrastructure. When sharing buffers 38 * among devices, drivers have to know the location of the memory to access 39 * the buffers in a safe way. :c:type:`struct dma_buf_map <dma_buf_map>` 40 * solves this problem for dma-buf and its users. If other drivers or 41 * sub-systems require similar functionality, the type could be generalized 42 * and moved to a more prominent header file. 43 * 44 * Open-coding access to :c:type:`struct dma_buf_map <dma_buf_map>` is 45 * considered bad style. Rather then accessing its fields directly, use one 46 * of the provided helper functions, or implement your own. For example, 47 * instances of :c:type:`struct dma_buf_map <dma_buf_map>` can be initialized 48 * statically with DMA_BUF_MAP_INIT_VADDR(), or at runtime with 49 * dma_buf_map_set_vaddr(). These helpers will set an address in system memory. 50 * 51 * .. code-block:: c 52 * 53 * struct dma_buf_map map = DMA_BUF_MAP_INIT_VADDR(0xdeadbeaf); 54 * 55 * dma_buf_map_set_vaddr(&map. 0xdeadbeaf); 56 * 57 * To set an address in I/O memory, use dma_buf_map_set_vaddr_iomem(). 58 * 59 * .. code-block:: c 60 * 61 * dma_buf_map_set_vaddr_iomem(&map. 0xdeadbeaf); 62 * 63 * Instances of struct dma_buf_map do not have to be cleaned up, but 64 * can be cleared to NULL with dma_buf_map_clear(). Cleared mappings 65 * always refer to system memory. 66 * 67 * .. code-block:: c 68 * 69 * dma_buf_map_clear(&map); 70 * 71 * Test if a mapping is valid with either dma_buf_map_is_set() or 72 * dma_buf_map_is_null(). 73 * 74 * .. code-block:: c 75 * 76 * if (dma_buf_map_is_set(&map) != dma_buf_map_is_null(&map)) 77 * // always true 78 * 79 * Instances of :c:type:`struct dma_buf_map <dma_buf_map>` can be compared 80 * for equality with dma_buf_map_is_equal(). Mappings the point to different 81 * memory spaces, system or I/O, are never equal. That's even true if both 82 * spaces are located in the same address space, both mappings contain the 83 * same address value, or both mappings refer to NULL. 84 * 85 * .. code-block:: c 86 * 87 * struct dma_buf_map sys_map; // refers to system memory 88 * struct dma_buf_map io_map; // refers to I/O memory 89 * 90 * if (dma_buf_map_is_equal(&sys_map, &io_map)) 91 * // always false 92 * 93 * A set up instance of struct dma_buf_map can be used to access or manipulate 94 * the buffer memory. Depending on the location of the memory, the provided 95 * helpers will pick the correct operations. Data can be copied into the memory 96 * with dma_buf_map_memcpy_to(). The address can be manipulated with 97 * dma_buf_map_incr(). 98 * 99 * .. code-block:: c 100 * 101 * const void *src = ...; // source buffer 102 * size_t len = ...; // length of src 103 * 104 * dma_buf_map_memcpy_to(&map, src, len); 105 * dma_buf_map_incr(&map, len); // go to first byte after the memcpy 106 */ 107 108/** 109 * struct dma_buf_map - Pointer to vmap'ed dma-buf memory. 110 * @vaddr_iomem: The buffer's address if in I/O memory 111 * @vaddr: The buffer's address if in system memory 112 * @is_iomem: True if the dma-buf memory is located in I/O 113 * memory, or false otherwise. 114 */ 115struct dma_buf_map { 116 union { 117 void __iomem *vaddr_iomem; 118 void *vaddr; 119 }; 120 bool is_iomem; 121}; 122 123/** 124 * DMA_BUF_MAP_INIT_VADDR - Initializes struct dma_buf_map to an address in system memory 125 * @vaddr_: A system-memory address 126 */ 127#define DMA_BUF_MAP_INIT_VADDR(vaddr_) \ 128 { \ 129 .vaddr = (vaddr_), \ 130 .is_iomem = false, \ 131 } 132 133/** 134 * dma_buf_map_set_vaddr - Sets a dma-buf mapping structure to an address in system memory 135 * @map: The dma-buf mapping structure 136 * @vaddr: A system-memory address 137 * 138 * Sets the address and clears the I/O-memory flag. 139 */ 140static inline void dma_buf_map_set_vaddr(struct dma_buf_map *map, void *vaddr) 141{ 142 map->vaddr = vaddr; 143 map->is_iomem = false; 144} 145 146/** 147 * dma_buf_map_set_vaddr_iomem - Sets a dma-buf mapping structure to an address in I/O memory 148 * @map: The dma-buf mapping structure 149 * @vaddr_iomem: An I/O-memory address 150 * 151 * Sets the address and the I/O-memory flag. 152 */ 153static inline void dma_buf_map_set_vaddr_iomem(struct dma_buf_map *map, 154 void __iomem *vaddr_iomem) 155{ 156 map->vaddr_iomem = vaddr_iomem; 157 map->is_iomem = true; 158} 159 160/** 161 * dma_buf_map_is_equal - Compares two dma-buf mapping structures for equality 162 * @lhs: The dma-buf mapping structure 163 * @rhs: A dma-buf mapping structure to compare with 164 * 165 * Two dma-buf mapping structures are equal if they both refer to the same type of memory 166 * and to the same address within that memory. 167 * 168 * Returns: 169 * True is both structures are equal, or false otherwise. 170 */ 171static inline bool dma_buf_map_is_equal(const struct dma_buf_map *lhs, 172 const struct dma_buf_map *rhs) 173{ 174 if (lhs->is_iomem != rhs->is_iomem) 175 return false; 176 else if (lhs->is_iomem) 177 return lhs->vaddr_iomem == rhs->vaddr_iomem; 178 else 179 return lhs->vaddr == rhs->vaddr; 180} 181 182/** 183 * dma_buf_map_is_null - Tests for a dma-buf mapping to be NULL 184 * @map: The dma-buf mapping structure 185 * 186 * Depending on the state of struct dma_buf_map.is_iomem, tests if the 187 * mapping is NULL. 188 * 189 * Returns: 190 * True if the mapping is NULL, or false otherwise. 191 */ 192static inline bool dma_buf_map_is_null(const struct dma_buf_map *map) 193{ 194 if (map->is_iomem) 195 return !map->vaddr_iomem; 196 return !map->vaddr; 197} 198 199/** 200 * dma_buf_map_is_set - Tests is the dma-buf mapping has been set 201 * @map: The dma-buf mapping structure 202 * 203 * Depending on the state of struct dma_buf_map.is_iomem, tests if the 204 * mapping has been set. 205 * 206 * Returns: 207 * True if the mapping is been set, or false otherwise. 208 */ 209static inline bool dma_buf_map_is_set(const struct dma_buf_map *map) 210{ 211 return !dma_buf_map_is_null(map); 212} 213 214/** 215 * dma_buf_map_clear - Clears a dma-buf mapping structure 216 * @map: The dma-buf mapping structure 217 * 218 * Clears all fields to zero; including struct dma_buf_map.is_iomem. So 219 * mapping structures that were set to point to I/O memory are reset for 220 * system memory. Pointers are cleared to NULL. This is the default. 221 */ 222static inline void dma_buf_map_clear(struct dma_buf_map *map) 223{ 224 if (map->is_iomem) { 225 map->vaddr_iomem = NULL; 226 map->is_iomem = false; 227 } else { 228 map->vaddr = NULL; 229 } 230} 231 232/** 233 * dma_buf_map_memcpy_to - Memcpy into dma-buf mapping 234 * @dst: The dma-buf mapping structure 235 * @src: The source buffer 236 * @len: The number of byte in src 237 * 238 * Copies data into a dma-buf mapping. The source buffer is in system 239 * memory. Depending on the buffer's location, the helper picks the correct 240 * method of accessing the memory. 241 */ 242static inline void dma_buf_map_memcpy_to(struct dma_buf_map *dst, const void *src, size_t len) 243{ 244 if (dst->is_iomem) 245 memcpy_toio(dst->vaddr_iomem, src, len); 246 else 247 memcpy(dst->vaddr, src, len); 248} 249 250/** 251 * dma_buf_map_incr - Increments the address stored in a dma-buf mapping 252 * @map: The dma-buf mapping structure 253 * @incr: The number of bytes to increment 254 * 255 * Increments the address stored in a dma-buf mapping. Depending on the 256 * buffer's location, the correct value will be updated. 257 */ 258static inline void dma_buf_map_incr(struct dma_buf_map *map, size_t incr) 259{ 260 if (map->is_iomem) 261 map->vaddr_iomem += incr; 262 else 263 map->vaddr += incr; 264} 265 266#endif /* __DMA_BUF_MAP_H__ */