RK3368 GPU version: Rogue L 0.22
[firefly-linux-kernel-4.4.55.git] / drivers / gpu / rogue / services / shared / include / devicemem_utils.h
1 /*************************************************************************/ /*!
2 @File
3 @Title          Device Memory Management internal utility functions
4 @Copyright      Copyright (c) Imagination Technologies Ltd. All Rights Reserved
5 @Description    Utility functions used internally by device memory management
6                 code.
7 @License        Dual MIT/GPLv2
8
9 The contents of this file are subject to the MIT license as set out below.
10
11 Permission is hereby granted, free of charge, to any person obtaining a copy
12 of this software and associated documentation files (the "Software"), to deal
13 in the Software without restriction, including without limitation the rights
14 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
15 copies of the Software, and to permit persons to whom the Software is
16 furnished to do so, subject to the following conditions:
17
18 The above copyright notice and this permission notice shall be included in
19 all copies or substantial portions of the Software.
20
21 Alternatively, the contents of this file may be used under the terms of
22 the GNU General Public License Version 2 ("GPL") in which case the provisions
23 of GPL are applicable instead of those above.
24
25 If you wish to allow use of your version of this file only under the terms of
26 GPL, and not to allow others to use your version of this file under the terms
27 of the MIT license, indicate your decision by deleting the provisions above
28 and replace them with the notice and other provisions required by GPL as set
29 out in the file called "GPL-COPYING" included in this distribution. If you do
30 not delete the provisions above, a recipient may use your version of this file
31 under the terms of either the MIT license or GPL.
32
33 This License is also included in this distribution in the file called
34 "MIT-COPYING".
35
36 EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
37 PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
38 BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
39 PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
40 COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
41 IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
42 CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
43 */ /**************************************************************************/
44
45 #ifndef _DEVICEMEM_UTILS_H_
46 #define _DEVICEMEM_UTILS_H_
47
48 #include "devicemem.h"
49 #include "img_types.h"
50 #include "pvrsrv_error.h"
51 #include "pvr_debug.h"
52 #include "allocmem.h"
53 #include "ra.h"
54 #include "osfunc.h"
55 #include "lock.h"
56 #include "devicemem_mmap.h"
57 #include "devicemem_utils.h"
58 #if defined(SUPPORT_PAGE_FAULT_DEBUG)
59 #include "mm_common.h"
60 #include "devicemem_history_shared.h"
61 #endif
62
63 #define DEVMEM_HEAPNAME_MAXLENGTH 160
64
65
66 #if defined(DEVMEM_DEBUG) && defined(REFCOUNT_DEBUG)
67 #define DEVMEM_REFCOUNT_PRINT(fmt, ...) PVRSRVDebugPrintf(PVR_DBG_ERROR, __FILE__, __LINE__, fmt, __VA_ARGS__)
68 #else
69 #define DEVMEM_REFCOUNT_PRINT(fmt, ...)
70 #endif
71
72
73 /* If we need a "hMapping" but we don't have a server-side mapping, we
74    poison the entry with this value so that it's easily recognised in
75    the debugger.  Note that this is potentially a valid handle, but
76    then so is IMG_NULL, which is no better, indeed worse, as it's not
77    obvious in the debugger.  The value doesn't matter.  We _never_ use
78    it (and because it's valid, we never assert it isn't this) but it's
79    nice to have a value in the source code that we can grep for when
80    things go wrong. */
81 #define LACK_OF_MAPPING_POISON ((IMG_HANDLE)0x6116dead)
82 #define LACK_OF_RESERVATION_POISON ((IMG_HANDLE)0x7117dead)
83
84 struct _DEVMEM_CONTEXT_ {
85     /* Cookie of the device on which this memory context resides */
86     IMG_HANDLE hDeviceNode;
87
88     /* Number of heaps that have been created in this context
89        (regardless of whether they have allocations) */
90     IMG_UINT32 uiNumHeaps;
91
92     /* Sometimes we need to talk to Kernel Services.  In order to do
93        so, we need the connection handle */
94     DEVMEM_BRIDGE_HANDLE hBridge;
95
96     /*
97       Each "DEVMEM_CONTEXT" has a counterpart in the server,
98       which is responsible for handling the mapping into device MMU.
99       We have a handle to that here.
100     */
101     IMG_HANDLE hDevMemServerContext;
102
103     /* Number of automagically created heaps in this context,
104        i.e. those that are born at context creation time from the
105        chosen "heap config" or "blueprint" */
106     IMG_UINT32 uiAutoHeapCount;
107
108     /* pointer to array of such heaps */
109     struct _DEVMEM_HEAP_ **ppsAutoHeapArray;
110
111         /* Private data handle for device specific data */
112         IMG_HANDLE hPrivData;
113 };
114
115 struct _DEVMEM_HEAP_ {
116     /* Name of heap - for debug and lookup purposes. */
117     IMG_CHAR *pszName;
118
119     /* Number of live imports in the heap */
120     IMG_UINT32 uiImportCount;
121
122     /*
123      * Base address of heap, required by clients due to some requesters
124      * not being full range 
125      */
126     IMG_DEV_VIRTADDR sBaseAddress;
127
128     /* This RA is for managing sub-allocations in virtual space.  Two
129        more RA's will be used under the Hood for managing the coarser
130        allocation of virtual space from the heap, and also for
131        managing the physical backing storage. */
132     RA_ARENA *psSubAllocRA;
133     IMG_CHAR *pszSubAllocRAName;
134     /*
135       This RA is for the coarse allocation of virtual space from the heap
136     */
137     RA_ARENA *psQuantizedVMRA;
138     IMG_CHAR *pszQuantizedVMRAName;
139
140     /* We also need to store a copy of the quantum size in order to
141        feed this down to the server */
142     IMG_UINT32 uiLog2Quantum;
143
144     /* The parent memory context for this heap */
145     struct _DEVMEM_CONTEXT_ *psCtx;
146
147         POS_LOCK hLock;                                                 /*!< Lock to protect this structure */
148
149     /*
150       Each "DEVMEM_HEAP" has a counterpart in the server,
151       which is responsible for handling the mapping into device MMU.
152       We have a handle to that here.
153     */
154     IMG_HANDLE hDevMemServerHeap;
155 };
156
157
158 typedef struct _DEVMEM_DEVICE_IMPORT_ {
159         DEVMEM_HEAP *psHeap;                    /*!< Heap this import is bound to */
160         IMG_DEV_VIRTADDR sDevVAddr;             /*!< Device virtual address of the import */
161         IMG_UINT32 ui32RefCount;                /*!< Refcount of the device virtual address */
162         IMG_HANDLE hReservation;                /*!< Device memory reservation handle */
163         IMG_HANDLE hMapping;                    /*!< Device mapping handle */
164         IMG_BOOL bMapped;                               /*!< This is import mapped? */
165         POS_LOCK hLock;                                 /*!< Lock to protect the device import */
166 } DEVMEM_DEVICE_IMPORT;
167
168 typedef struct _DEVMEM_CPU_IMPORT_ {
169         IMG_PVOID pvCPUVAddr;                   /*!< CPU virtual address of the import */
170         IMG_UINT32 ui32RefCount;                /*!< Refcount of the CPU virtual address */
171         IMG_HANDLE hOSMMapData;                 /*!< CPU mapping handle */
172         POS_LOCK hLock;                                 /*!< Lock to protect the CPU import */
173 #if !defined(__KERNEL__) && defined(SUPPORT_ION)
174         int iDmaBufFd;                                  /*!< >=0 if this was an imported ion allocation */
175 #endif
176 } DEVMEM_CPU_IMPORT;
177
178 typedef struct _DEVMEM_IMPORT_ {
179     DEVMEM_BRIDGE_HANDLE hBridge;               /*!< Bridge connection for the server */
180     IMG_DEVMEM_ALIGN_T uiAlign;                 /*!< Alignment requirement */
181         DEVMEM_SIZE_T uiSize;                           /*!< Size of import */
182     IMG_UINT32 ui32RefCount;                    /*!< Refcount for this import */
183     IMG_BOOL bExportable;                               /*!< Is this import exportable? */
184     IMG_HANDLE hPMR;                                    /*!< Handle to the PMR */
185     DEVMEM_FLAGS_T uiFlags;                             /*!< Flags for this import */
186     POS_LOCK hLock;                                             /*!< Lock to protect the import */
187
188         DEVMEM_DEVICE_IMPORT sDeviceImport;     /*!< Device specifics of the import */
189         DEVMEM_CPU_IMPORT sCPUImport;           /*!< CPU specifics of the import */
190 } DEVMEM_IMPORT;
191
192 typedef struct _DEVMEM_DEVICE_MEMDESC_ {
193         IMG_DEV_VIRTADDR sDevVAddr;             /*!< Device virtual address of the allocation */
194         IMG_UINT32 ui32RefCount;                /*!< Refcount of the device virtual address */
195         POS_LOCK hLock;                                 /*!< Lock to protect device memdesc */
196 } DEVMEM_DEVICE_MEMDESC;
197
198 typedef struct _DEVMEM_CPU_MEMDESC_ {
199         IMG_PVOID pvCPUVAddr;                   /*!< CPU virtual address of the import */
200         IMG_UINT32 ui32RefCount;                /*!< Refcount of the device CPU address */
201         POS_LOCK hLock;                                 /*!< Lock to protect CPU memdesc */
202 } DEVMEM_CPU_MEMDESC;
203
204 struct _DEVMEM_MEMDESC_ {
205     DEVMEM_IMPORT *psImport;                            /*!< Import this memdesc is on */
206     IMG_DEVMEM_OFFSET_T uiOffset;                       /*!< Offset into import where our allocation starts */
207     IMG_UINT32 ui32RefCount;                            /*!< Refcount of the memdesc */
208     POS_LOCK hLock;                                                     /*!< Lock to protect memdesc */
209
210         DEVMEM_DEVICE_MEMDESC sDeviceMemDesc;   /*!< Device specifics of the memdesc */
211         DEVMEM_CPU_MEMDESC sCPUMemDesc;         /*!< CPU specifics of the memdesc */
212 #if defined(SUPPORT_PAGE_FAULT_DEBUG)
213         DEVICEMEM_HISTORY_MEMDESC_DATA sTraceData;
214 #endif
215
216 #if defined(PVR_RI_DEBUG)
217     IMG_HANDLE hRIHandle;                                       /*!< Handle to RI information */
218 #endif
219 };
220
221 /******************************************************************************
222 @Function       _DevmemValidateParams
223 @Description    Check if flags are conflicting and if align is a size multiple.
224
225 @Input          uiSize      Size of the import.
226 @Input          uiAlign     Alignment of the import.
227 @Input          uiFlags     Flags for the import.
228 @return         PVRSRV_ERROR
229 ******************************************************************************/
230 PVRSRV_ERROR _DevmemValidateParams(IMG_DEVMEM_SIZE_T uiSize,
231                                                                    IMG_DEVMEM_ALIGN_T uiAlign,
232                                                                    DEVMEM_FLAGS_T uiFlags);
233
234 /******************************************************************************
235 @Function       _DevmemImportStructAlloc
236 @Description    Allocates memory for an import struct. Does not allocate a PMR!
237                 Create locks for CPU and Devmem mappings.
238
239 @Input          hBridge       Bridge to use for calls from the import.
240 @Input          bExportable   Is this import is exportable?
241 @Input          ppsImport     The import to allocate.
242 @return         PVRSRV_ERROR
243 ******************************************************************************/
244 PVRSRV_ERROR _DevmemImportStructAlloc(IMG_HANDLE hBridge,
245                                                                           IMG_BOOL bExportable,
246                                                                           DEVMEM_IMPORT **ppsImport);
247
248 /******************************************************************************
249 @Function       _DevmemImportStructInit
250 @Description    Initialises the import struct with the given parameters.
251                 Set it's refcount to 1!
252
253 @Input          psImport    The import to initialise.
254 @Input          uiSize      Size of the import.
255 @Input          uiAlign     Alignment of allocations in the import.
256 @Input          uiMapFlags
257 @Input          hPMR        Reference to the PMR of this import struct.
258 ******************************************************************************/
259 IMG_VOID _DevmemImportStructInit(DEVMEM_IMPORT *psImport,
260                                                                  IMG_DEVMEM_SIZE_T uiSize,
261                                                                  IMG_DEVMEM_ALIGN_T uiAlign,
262                                                                  PVRSRV_MEMALLOCFLAGS_T uiMapFlags,
263                                                                  IMG_HANDLE hPMR);
264
265 /******************************************************************************
266 @Function       _DevmemImportStructDevMap
267 @Description    NEVER call after the last _DevmemMemDescRelease()
268                 Maps the PMR referenced by the import struct to the device's
269                 virtual address space.
270                 Does nothing but increase the cpu mapping refcount if the
271                 import struct was already mapped.
272
273 @Input          psHeap    The heap to map to.
274 @Input          bMap      Caller can choose if the import should be really
275                           mapped in the page tables or if just a virtual range
276                           should be reserved and the refcounts increased.
277 @Input          psImport  The import we want to map.
278 @return         PVRSRV_ERROR
279 ******************************************************************************/
280 PVRSRV_ERROR _DevmemImportStructDevMap(DEVMEM_HEAP *psHeap,
281                                                                            IMG_BOOL bMap,
282                                                                            DEVMEM_IMPORT *psImport);
283
284 /******************************************************************************
285 @Function       _DevmemImportStructDevUnmap
286 @Description    Unmaps the PMR referenced by the import struct from the
287                 device's virtual address space.
288                 If this was not the last remaining CPU mapping on the import
289                 struct only the cpu mapping refcount is decreased.
290 ******************************************************************************/
291 IMG_VOID _DevmemImportStructDevUnmap(DEVMEM_IMPORT *psImport);
292
293 /******************************************************************************
294 @Function       _DevmemImportStructCPUMap
295 @Description    NEVER call after the last _DevmemMemDescRelease()
296                 Maps the PMR referenced by the import struct to the CPU's
297                 virtual address space.
298                 Does nothing but increase the cpu mapping refcount if the
299                 import struct was already mapped.
300 @return         PVRSRV_ERROR
301 ******************************************************************************/
302 PVRSRV_ERROR _DevmemImportStructCPUMap(DEVMEM_IMPORT *psImport);
303
304 /******************************************************************************
305 @Function       _DevmemImportStructCPUUnmap
306 @Description    Unmaps the PMR referenced by the import struct from the CPU's
307                 virtual address space.
308                 If this was not the last remaining CPU mapping on the import
309                 struct only the cpu mapping refcount is decreased.
310 ******************************************************************************/
311 IMG_VOID _DevmemImportStructCPUUnmap(DEVMEM_IMPORT *psImport);
312
313
314 /******************************************************************************
315 @Function       _DevmemImportStructAcquire
316 @Description    Acquire an import struct by increasing it's refcount.
317 ******************************************************************************/
318 IMG_VOID _DevmemImportStructAcquire(DEVMEM_IMPORT *psImport);
319
320 /******************************************************************************
321 @Function       _DevmemImportStructRelease
322 @Description    Reduces the refcount of the import struct.
323                 Destroys the import in the case it was the last reference.
324                 Destroys underlying PMR if this import was the last reference
325                 to it.
326 @return         A boolean to signal if the import was destroyed. True = yes.
327 ******************************************************************************/
328 IMG_VOID _DevmemImportStructRelease(DEVMEM_IMPORT *psImport);
329
330 /******************************************************************************
331 @Function       _DevmemImportDiscard
332 @Description    Discard a created, but unitilised import structure.
333                 This must only be called before _DevmemImportStructInit
334                 after which _DevmemImportStructRelease must be used to
335                 "free" the import structure.
336 ******************************************************************************/
337 IMG_VOID _DevmemImportDiscard(DEVMEM_IMPORT *psImport);
338
339 /******************************************************************************
340 @Function       _DevmemMemDescAlloc
341 @Description    Allocates a MemDesc and create it's various locks.
342                 Zero the allocated memory.
343 @return         PVRSRV_ERROR
344 ******************************************************************************/
345 PVRSRV_ERROR _DevmemMemDescAlloc(DEVMEM_MEMDESC **ppsMemDesc);
346
347 /******************************************************************************
348 @Function       _DevmemMemDescInit
349 @Description    Sets the given offset and import struct fields in the MemDesc.
350                 Initialises refcount to 1 and other values to 0.
351
352 @Input          psMemDesc    MemDesc to initialise.
353 @Input          uiOffset     Offset in the import structure.
354 @Input          psImport     Import the MemDesc is on.
355 ******************************************************************************/
356 IMG_VOID _DevmemMemDescInit(DEVMEM_MEMDESC *psMemDesc,
357                                                         IMG_DEVMEM_OFFSET_T uiOffset,
358                                                         DEVMEM_IMPORT *psImport);
359
360 /******************************************************************************
361 @Function       _DevmemMemDescAcquire
362 @Description    Acquires the MemDesc by increasing it's refcount.
363 ******************************************************************************/
364 IMG_VOID _DevmemMemDescAcquire(DEVMEM_MEMDESC *psMemDesc);
365
366 /******************************************************************************
367 @Function       _DevmemMemDescRelease
368 @Description    Releases the MemDesc by reducing it's refcount.
369                 Destroy the MemDesc if it's recount is 0.
370                 Destroy the import struct the MemDesc is on if that was the
371                 last MemDesc on the import, probably following the destruction
372                 of the underlying PMR.
373 ******************************************************************************/
374 IMG_VOID _DevmemMemDescRelease(DEVMEM_MEMDESC *psMemDesc);
375
376 /******************************************************************************
377 @Function       _DevmemMemDescDiscard
378 @Description    Discard a created, but unitilised MemDesc structure.
379                 This must only be called before _DevmemMemDescInit
380                 after which _DevmemMemDescRelease must be used to
381                 "free" the MemDesc structure.
382 ******************************************************************************/
383 IMG_VOID _DevmemMemDescDiscard(DEVMEM_MEMDESC *psMemDesc);
384
385 #endif /* _DEVICEMEM_UTILS_H_ */