aboutsummaryrefslogtreecommitdiff
path: root/drivers/media/platform/msm/camera/cam_smmu/cam_smmu_api.h
blob: 254e382a99ad6f392f09f8ec5392a84b26087ddc (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
/* Copyright (c) 2014-2017, The Linux Foundation. All rights reserved.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 and
 * only version 2 as published by the Free Software Foundation.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 */

#ifndef _CAM_SMMU_API_H_
#define _CAM_SMMU_API_H_

#include <linux/dma-direction.h>
#include <linux/module.h>
#include <linux/dma-buf.h>
#include <asm/dma-iommu.h>
#include <linux/dma-direction.h>
#include <linux/of_platform.h>
#include <linux/iommu.h>
#include <linux/random.h>
#include <linux/spinlock_types.h>
#include <linux/mutex.h>
#include <linux/msm_ion.h>

/*Enum for possible CAM SMMU operations */
enum cam_smmu_ops_param {
	CAM_SMMU_ATTACH,
	CAM_SMMU_DETACH,
	CAM_SMMU_VOTE,
	CAM_SMMU_DEVOTE,
	CAM_SMMU_OPS_INVALID
};

enum cam_smmu_map_dir {
	CAM_SMMU_MAP_READ,
	CAM_SMMU_MAP_WRITE,
	CAM_SMMU_MAP_RW,
	CAM_SMMU_MAP_INVALID
};

enum cam_smmu_region_id {
	CAM_SMMU_REGION_FIRMWARE,
	CAM_SMMU_REGION_SHARED,
	CAM_SMMU_REGION_SCRATCH,
	CAM_SMMU_REGION_IO,
	CAM_SMMU_REGION_SECHEAP,
	CAM_SMMU_REGION_QDSS
};

/**
 * @brief            : Structure to store region information
 *
 * @param iova_start : Start address of region
 * @param iova_len   : length of region
 */
struct cam_smmu_region_info {
	dma_addr_t iova_start;
	size_t iova_len;
};

/**
 * @brief           : Gets an smmu handle
 *
 * @param identifier: Unique identifier to be used by clients which they
 *                    should get from device tree. CAM SMMU driver will
 *                    not enforce how this string is obtained and will
 *                    only validate this against the list of permitted
 *                    identifiers
 * @param handle_ptr: Based on the indentifier, CAM SMMU drivier will
 *                    fill the handle pointed by handle_ptr
 * @return Status of operation. Negative in case of error. Zero otherwise.
 */
int cam_smmu_get_handle(char *identifier, int *handle_ptr);

/**
 * @brief       : Performs IOMMU operations
 *
 * @param handle: Handle to identify the CAM SMMU client (VFE, CPP, FD etc.)
 * @param op    : Operation to be performed. Can be either CAM_SMMU_ATTACH
 *                or CAM_SMMU_DETACH
 *
 * @return Status of operation. Negative in case of error. Zero otherwise.
 */
int cam_smmu_ops(int handle, enum cam_smmu_ops_param op);

/**
 * @brief       : Maps user space IOVA for calling driver
 *
 * @param handle: Handle to identify the CAM SMMU client (VFE, CPP, FD etc.)
 * @param ion_fd: ION handle identifying the memory buffer.
 * @dir         : Mapping direction: which will traslate toDMA_BIDIRECTIONAL,
 *                DMA_TO_DEVICE or DMA_FROM_DEVICE
 * @dma_addr    : Pointer to physical address where mapped address will be
 *                returned if region_id is CAM_SMMU_REGION_IO. If region_id is
 *                CAM_SMMU_REGION_SHARED, dma_addr is used as an input parameter
 *                which specifies the cpu virtual address to map.
 * @len_ptr     : Length of buffer mapped returned by CAM SMMU driver.
 * @return Status of operation. Negative in case of error. Zero otherwise.
 */
int cam_smmu_map_user_iova(int handle,
	int ion_fd, enum cam_smmu_map_dir dir,
	dma_addr_t *dma_addr, size_t *len_ptr,
	enum cam_smmu_region_id region_id);

/**
 * @brief        : Maps kernel space IOVA for calling driver
 *
 * @param handle : Handle to identify the CAM SMMU client (VFE, CPP, FD etc.)
 * @param buf    : dma_buf allocated for kernel usage in mem_mgr
 * @dir          : Mapping direction: which will traslate toDMA_BIDIRECTIONAL,
 *                 DMA_TO_DEVICE or DMA_FROM_DEVICE
 * @dma_addr     : Pointer to physical address where mapped address will be
 *                 returned if region_id is CAM_SMMU_REGION_IO. If region_id is
 *                 CAM_SMMU_REGION_SHARED, dma_addr is used as an input
 *                 parameter which specifies the cpu virtual address to map.
 * @len_ptr      : Length of buffer mapped returned by CAM SMMU driver.
 * @return Status of operation. Negative in case of error. Zero otherwise.
 */
int cam_smmu_map_kernel_iova(int handle,
	struct dma_buf *buf, enum cam_smmu_map_dir dir,
	dma_addr_t *dma_addr, size_t *len_ptr,
	enum cam_smmu_region_id region_id);

/**
 * @brief       : Unmaps user space IOVA for calling driver
 *
 * @param handle: Handle to identify the CAMSMMU client (VFE, CPP, FD etc.)
 * @param ion_fd: ION handle identifying the memory buffer.
 *
 * @return Status of operation. Negative in case of error. Zero otherwise.
 */
int cam_smmu_unmap_user_iova(int handle,
	int ion_fd, enum cam_smmu_region_id region_id);

/**
 * @brief       : Unmaps kernel IOVA for calling driver
 *
 * @param handle: Handle to identify the CAMSMMU client (VFE, CPP, FD etc.)
 * @param buf   : dma_buf allocated for the kernel
 *
 * @return Status of operation. Negative in case of error. Zero otherwise.
 */
int cam_smmu_unmap_kernel_iova(int handle,
	struct dma_buf *buf, enum cam_smmu_region_id region_id);

/**
 * @brief          : Allocates a scratch buffer
 *
 * This function allocates a scratch virtual buffer of length virt_len in the
 * device virtual address space mapped to phys_len physically contiguous bytes
 * in that device's SMMU.
 *
 * virt_len and phys_len are expected to be aligned to PAGE_SIZE and with each
 * other, otherwise -EINVAL is returned.
 *
 * -EINVAL will be returned if virt_len is less than phys_len.
 *
 * Passing a too large phys_len might also cause failure if that much size is
 * not available for allocation in a physically contiguous way.
 *
 * @param handle   : Handle to identify the CAMSMMU client (VFE, CPP, FD etc.)
 * @param dir      : Direction of mapping which will translate to IOMMU_READ
 *                   IOMMU_WRITE or a bit mask of both.
 * @param paddr_ptr: Device virtual address that the client device will be
 *                   able to read from/write to
 * @param virt_len : Virtual length of the scratch buffer
 * @param phys_len : Physical length of the scratch buffer
 *
 * @return Status of operation. Negative in case of error. Zero otherwise.
 */

int cam_smmu_get_scratch_iova(int handle,
	enum cam_smmu_map_dir dir,
	dma_addr_t *paddr_ptr,
	size_t virt_len,
	size_t phys_len);

/**
 * @brief          : Frees a scratch buffer
 *
 * This function frees a scratch buffer and releases the corresponding SMMU
 * mappings.
 *
 * @param handle   : Handle to identify the CAMSMMU client (IFE, ICP, etc.)
 * @param paddr    : Device virtual address of client's scratch buffer that
 *                   will be freed.
 *
 * @return Status of operation. Negative in case of error. Zero otherwise.
 */

int cam_smmu_put_scratch_iova(int handle,
	dma_addr_t paddr);

/**
 *@brief        : Destroys an smmu handle
 *
 * @param handle: Handle to identify the CAM SMMU client (VFE, CPP, FD etc.)
 *
 * @return Status of operation. Negative in case of error. Zero otherwise.
 */
int cam_smmu_destroy_handle(int handle);

/**
 * @brief       : Finds index by handle in the smmu client table
 *
 * @param handle: Handle to identify the CAM SMMU client (VFE, CPP, FD etc.)
 * @return Index of SMMU client. Nagative in case of error.
 */
int cam_smmu_find_index_by_handle(int hdl);

/**
 * @brief       : Registers smmu fault handler for client
 *
 * @param handle: Handle to identify the CAM SMMU client (VFE, CPP, FD etc.)
 * @param client_page_fault_handler: It is triggered in IOMMU page fault
 * @param token: It is input param when trigger page fault handler
 */
void cam_smmu_reg_client_page_fault_handler(int handle,
	void (*client_page_fault_handler)(struct iommu_domain *,
	struct device *, unsigned long,
	int, void*), void *token);

/**
 * @brief Maps memory from an ION fd into IOVA space
 *
 * @param handle: SMMU handle identifying the context bank to map to
 * @param ion_fd: ION fd of memory to map to
 * @param paddr_ptr: Pointer IOVA address that will be returned
 * @param len_ptr: Length of memory mapped
 *
 * @return Status of operation. Negative in case of error. Zero otherwise.
 */
int cam_smmu_get_iova(int handle, int ion_fd,
	dma_addr_t *paddr_ptr, size_t *len_ptr);

/**
 * @brief Maps memory from an ION fd into IOVA space
 *
 * @param handle: SMMU handle identifying the secure context bank to map to
 * @param ion_fd: ION fd of memory to map to
 * @param paddr_ptr: Pointer IOVA address that will be returned
 * @param len_ptr: Length of memory mapped
 *
 * @return Status of operation. Negative in case of error. Zero otherwise.
 */
int cam_smmu_get_stage2_iova(int handle, int ion_fd,
	dma_addr_t *paddr_ptr, size_t *len_ptr);
/**
 * @brief Unmaps memory from context bank
 *
 * @param handle: SMMU handle identifying the context bank
 * @param ion_fd: ION fd of memory to unmap
 *
 * @return Status of operation. Negative in case of error. Zero otherwise.
 */
int cam_smmu_put_iova(int handle, int ion_fd);

/**
 * @brief Maps secure memory for SMMU handle
 *
 * @param handle: SMMU handle identifying secure context bank
 * @param ion_fd: ION fd to map securely
 * @param dir: DMA Direction for the mapping
 * @param client: Ion client passed by caller
 * @param dma_addr: Returned IOVA address after mapping
 * @param len_ptr: Length of memory mapped
 *
 * @return Status of operation. Negative in case of error. Zero otherwise.
 */
int cam_smmu_map_stage2_iova(int handle,
	int ion_fd, enum cam_smmu_map_dir dir, struct ion_client *client,
	ion_phys_addr_t *dma_addr, size_t *len_ptr);

/**
 * @brief Unmaps secure memopry for SMMU handle
 *
 * @param handle: SMMU handle identifying secure context bank
 * @param ion_fd: ION fd to unmap
 *
 * @return Status of operation. Negative in case of error. Zero otherwise.
 */
int cam_smmu_unmap_stage2_iova(int handle, int ion_fd);


/**
 * @brief Allocates firmware for context bank
 *
 * @param smmu_hdl: SMMU handle identifying context bank
 * @param iova: IOVA address of allocated firmware
 * @param kvaddr: CPU mapped address of allocated firmware
 * @param len: Length of allocated firmware memory
 *
 * @return Status of operation. Negative in case of error. Zero otherwise.
 */
int cam_smmu_alloc_firmware(int32_t smmu_hdl,
	dma_addr_t *iova,
	uint64_t *kvaddr,
	size_t *len);

/**
 * @brief Deallocates firmware memory for context bank
 *
 * @param smmu_hdl: SMMU handle identifying the context bank
 *
 * @return Status of operation. Negative in case of error. Zero otherwise.
 */
int cam_smmu_dealloc_firmware(int32_t smmu_hdl);

/**
 * @brief Gets region information specified by smmu handle and region id
 *
 * @param smmu_hdl: SMMU handle identifying the context bank
 * @param region_id: Region id for which information is desired
 * @param region_info: Struct populated with region information
 *
 * @return Status of operation. Negative in case of error. Zero otherwise.
 */
int cam_smmu_get_region_info(int32_t smmu_hdl,
	enum cam_smmu_region_id region_id,
	struct cam_smmu_region_info *region_info);

/**
 * @brief Reserves secondary heap
 *
 * @param smmu_hdl: SMMU handle identifying the context bank
 * @param iova: IOVA of secondary heap after reservation has completed
 * @param buf: Allocated dma_buf for secondary heap
 * @param request_len: Length of secondary heap after reservation has completed
 *
 * @return Status of operation. Negative in case of error. Zero otherwise.
 */
int cam_smmu_reserve_sec_heap(int32_t smmu_hdl,
	struct dma_buf *buf,
	dma_addr_t *iova,
	size_t *request_len);

/**
 * @brief Releases secondary heap
 *
 * @param smmu_hdl: SMMU handle identifying the context bank
 *
 * @return Status of operation. Negative in case of error. Zero otherwise.
 */
int cam_smmu_release_sec_heap(int32_t smmu_hdl);

/**
 * @brief Allocates qdss for context bank
 *
 * @param smmu_hdl: SMMU handle identifying context bank
 * @param iova: IOVA address of allocated qdss
 * @param len: Length of allocated qdss memory
 *
 * @return Status of operation. Negative in case of error. Zero otherwise.
 */
int cam_smmu_alloc_qdss(int32_t smmu_hdl,
	dma_addr_t *iova,
	size_t *len);

/**
 * @brief Deallocates qdss memory for context bank
 *
 * @param smmu_hdl: SMMU handle identifying the context bank
 *
 * @return Status of operation. Negative in case of error. Zero otherwise.
 */
int cam_smmu_dealloc_qdss(int32_t smmu_hdl);

#endif /* _CAM_SMMU_API_H_ */