RK3368 GPU: Rogue N Init.
[firefly-linux-kernel-4.4.55.git] / drivers / staging / imgtec / rogue / 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 "osmmap.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 /* If we need a "hMapping" but we don't have a server-side mapping, we
73    poison the entry with this value so that it's easily recognised in
74    the debugger.  Note that this is potentially a valid handle, but
75    then so is NULL, which is no better, indeed worse, as it's not
76    obvious in the debugger.  The value doesn't matter.  We _never_ use
77    it (and because it's valid, we never assert it isn't this) but it's
78    nice to have a value in the source code that we can grep for when
79    things go wrong. */
80 #define LACK_OF_MAPPING_POISON ((IMG_HANDLE)0x6116dead)
81 #define LACK_OF_RESERVATION_POISON ((IMG_HANDLE)0x7117dead)
82
83 struct _DEVMEM_CONTEXT_ {
84
85         SHARED_DEV_CONNECTION hDevConnection;
86         
87     /* Number of heaps that have been created in this context
88        (regardless of whether they have allocations) */
89     IMG_UINT32 uiNumHeaps;
90
91     /*
92       Each "DEVMEM_CONTEXT" has a counterpart in the server,
93       which is responsible for handling the mapping into device MMU.
94       We have a handle to that here.
95     */
96     IMG_HANDLE hDevMemServerContext;
97
98     /* Number of automagically created heaps in this context,
99        i.e. those that are born at context creation time from the
100        chosen "heap config" or "blueprint" */
101     IMG_UINT32 uiAutoHeapCount;
102
103     /* pointer to array of such heaps */
104     struct _DEVMEM_HEAP_ **ppsAutoHeapArray;
105
106     /* The cache line size for use when allocating memory, as it is not queryable on the client side */
107     IMG_UINT32 ui32CPUCacheLineSize;
108
109         /* Private data handle for device specific data */
110         IMG_HANDLE hPrivData;
111 };
112
113
114 typedef enum
115 {
116         DEVMEM_HEAP_TYPE_UNKNOWN = 0,
117         DEVMEM_HEAP_TYPE_USER_MANAGED,
118         DEVMEM_HEAP_TYPE_KERNEL_MANAGED,
119         DEVMEM_HEAP_TYPE_RA_MANAGED,
120 }DEVMEM_HEAP_TYPE;
121
122 struct _DEVMEM_HEAP_ {
123         /* Name of heap - for debug and lookup purposes. */
124         IMG_CHAR *pszName;
125
126         /* Number of live imports in the heap */
127         ATOMIC_T hImportCount;
128
129         /*
130         * Base address and size of heap, required by clients due to some requesters
131         * not being full range
132         */
133         IMG_DEV_VIRTADDR sBaseAddress;
134         DEVMEM_SIZE_T uiSize;
135
136         /* The heap type, describing if the space is managed by the user or an RA*/
137         DEVMEM_HEAP_TYPE eHeapType;
138
139         /* This RA is for managing sub-allocations in virtual space.  Two
140         more RA's will be used under the Hood for managing the coarser
141         allocation of virtual space from the heap, and also for
142         managing the physical backing storage. */
143         RA_ARENA *psSubAllocRA;
144         IMG_CHAR *pszSubAllocRAName;
145         /*
146         This RA is for the coarse allocation of virtual space from the heap
147         */
148         RA_ARENA *psQuantizedVMRA;
149         IMG_CHAR *pszQuantizedVMRAName;
150
151         /* We also need to store a copy of the quantum size in order to
152         feed this down to the server */
153         IMG_UINT32 uiLog2Quantum;
154
155         /* Store a copy of the minimum import alignment */
156         IMG_UINT32 uiLog2ImportAlignment;
157
158         /* The relationship between tiled heap alignment and heap byte-stride
159          * (dependent on tiling mode, abstracted here) */
160         IMG_UINT32 uiLog2TilingStrideFactor;
161
162         /* The parent memory context for this heap */
163         struct _DEVMEM_CONTEXT_ *psCtx;
164
165         /* Lock to protect this structure */
166         POS_LOCK hLock;
167
168         /*
169         Each "DEVMEM_HEAP" has a counterpart in the server,
170         which is responsible for handling the mapping into device MMU.
171         We have a handle to that here.
172         */
173         IMG_HANDLE hDevMemServerHeap;
174 };
175
176 typedef IMG_UINT32 DEVMEM_PROPERTIES_T;                 /*!< Typedef for Devicemem properties */
177 #define DEVMEM_PROPERTIES_EXPORTABLE        (1UL<<0)    /*!< Is it exportable? */
178 #define DEVMEM_PROPERTIES_IMPORTED          (1UL<<1)    /*!< Is it imported from another process? */
179 #define DEVMEM_PROPERTIES_SUBALLOCATABLE    (1UL<<2)    /*!< Is it suballocatable? */
180 #define DEVMEM_PROPERTIES_UNPINNED          (1UL<<3)    /*!< Is it currently pinned? */
181 #define DEVMEM_PROPERTIES_IMPORT_IS_ZEROED  (1UL<<4)    /*!< Is the memory fully zeroed? */
182 #define DEVMEM_PROPERTIES_IMPORT_IS_CLEAN   (1UL<<5)    /*!< Is the memory clean, i.e. not been used before? */
183 #define DEVMEM_PROPERTIES_SECURE            (1UL<<6)    /*!< Is it a special secure buffer? No CPU maps allowed! */
184
185
186 typedef struct _DEVMEM_DEVICE_IMPORT_ {
187         DEVMEM_HEAP *psHeap;                    /*!< Heap this import is bound to */
188         IMG_DEV_VIRTADDR sDevVAddr;             /*!< Device virtual address of the import */
189         IMG_UINT32 ui32RefCount;                /*!< Refcount of the device virtual address */
190         IMG_HANDLE hReservation;                /*!< Device memory reservation handle */
191         IMG_HANDLE hMapping;                    /*!< Device mapping handle */
192         IMG_BOOL bMapped;                               /*!< This is import mapped? */
193         POS_LOCK hLock;                                 /*!< Lock to protect the device import */
194 } DEVMEM_DEVICE_IMPORT;
195
196 typedef struct _DEVMEM_CPU_IMPORT_ {
197         void *pvCPUVAddr;                       /*!< CPU virtual address of the import */
198         IMG_UINT32 ui32RefCount;                /*!< Refcount of the CPU virtual address */
199         IMG_HANDLE hOSMMapData;                 /*!< CPU mapping handle */
200         POS_LOCK hLock;                                 /*!< Lock to protect the CPU import */
201 } DEVMEM_CPU_IMPORT;
202
203 typedef struct _DEVMEM_IMPORT_ {
204         SHARED_DEV_CONNECTION hDevConnection;
205         IMG_DEVMEM_ALIGN_T uiAlign;                     /*!< Alignment of the PMR */
206         DEVMEM_SIZE_T uiSize;                           /*!< Size of import */
207     ATOMIC_T hRefCount;                                 /*!< Refcount for this import */
208     DEVMEM_PROPERTIES_T uiProperties;   /*!< Stores properties of an import like if
209                                                                                 it is exportable, pinned or suballocatable */
210     IMG_HANDLE hPMR;                                    /*!< Handle to the PMR */
211     DEVMEM_FLAGS_T uiFlags;                             /*!< Flags for this import */
212     POS_LOCK hLock;                                             /*!< Lock to protect the import */
213
214         DEVMEM_DEVICE_IMPORT sDeviceImport;     /*!< Device specifics of the import */
215         DEVMEM_CPU_IMPORT sCPUImport;           /*!< CPU specifics of the import */
216 #if defined(PDUMP)
217         IMG_CHAR *pszAnnotation;
218 #endif
219 } DEVMEM_IMPORT;
220
221 typedef struct _DEVMEM_DEVICE_MEMDESC_ {
222         IMG_DEV_VIRTADDR sDevVAddr;             /*!< Device virtual address of the allocation */
223         IMG_UINT32 ui32RefCount;                /*!< Refcount of the device virtual address */
224         POS_LOCK hLock;                                 /*!< Lock to protect device memdesc */
225 } DEVMEM_DEVICE_MEMDESC;
226
227 typedef struct _DEVMEM_CPU_MEMDESC_ {
228         void *pvCPUVAddr;                       /*!< CPU virtual address of the import */
229         IMG_UINT32 ui32RefCount;                /*!< Refcount of the device CPU address */
230         POS_LOCK hLock;                                 /*!< Lock to protect CPU memdesc */
231 } DEVMEM_CPU_MEMDESC;
232
233 struct _DEVMEM_MEMDESC_ {
234     DEVMEM_IMPORT *psImport;                            /*!< Import this memdesc is on */
235     IMG_DEVMEM_OFFSET_T uiOffset;                       /*!< Offset into import where our allocation starts */
236         IMG_DEVMEM_SIZE_T uiAllocSize;          /*!< Size of the allocation */
237     ATOMIC_T hRefCount;                                         /*!< Refcount of the memdesc */
238     POS_LOCK hLock;                                                     /*!< Lock to protect memdesc */
239     IMG_HANDLE hPrivData;
240
241         DEVMEM_DEVICE_MEMDESC sDeviceMemDesc;   /*!< Device specifics of the memdesc */
242         DEVMEM_CPU_MEMDESC sCPUMemDesc;         /*!< CPU specifics of the memdesc */
243 #if defined(SUPPORT_PAGE_FAULT_DEBUG)
244         DEVICEMEM_HISTORY_MEMDESC_DATA sTraceData;
245 #endif
246
247 #if defined(PVR_RI_DEBUG)
248     IMG_HANDLE hRIHandle;                                       /*!< Handle to RI information */
249 #endif
250 };
251
252 /* The physical descriptor used to store handles and information of
253  * device physical allocations. */
254 struct _DEVMEMX_PHYS_MEMDESC_ {
255         IMG_UINT32 uiNumPages;                                  /*!< Number of pages that the import has*/
256         IMG_UINT32 uiLog2PageSize;                              /*!< Page size */
257         ATOMIC_T hRefCount;                                             /*!< Refcount of the memdesc */
258         DEVMEM_FLAGS_T uiFlags;                                 /*!< Flags for this import */
259         IMG_HANDLE hPMR;                                                /*!< Handle to the PMR */
260         DEVMEM_CPU_IMPORT sCPUImport;                   /*!< CPU specifics of the memdesc */
261         DEVMEM_BRIDGE_HANDLE hBridge;                   /*!< Bridge connection for the server */
262 };
263
264 /* The virtual descriptor used to store handles and information of a
265  * device virtual range and the mappings to it. */
266 struct _DEVMEMX_VIRT_MEMDESC_ {
267         IMG_UINT32 uiNumPages;                                  /*!< Number of pages that the import has*/
268         DEVMEM_FLAGS_T uiFlags;                                 /*!< Flags for this import */
269         DEVMEMX_PHYSDESC **apsPhysDescTable;            /*!< Table to store links to physical descs */
270         DEVMEM_DEVICE_IMPORT sDeviceImport;             /*!< Device specifics of the memdesc */
271
272 #if defined(SUPPORT_PAGE_FAULT_DEBUG)
273         DEVICEMEM_HISTORY_MEMDESC_DATA sTraceData;      /*!< To track mappings in this range */
274 #endif
275
276 #if defined(PVR_RI_DEBUG)
277         IMG_HANDLE hRIHandle;                                   /*!< Handle to RI information */
278 #endif
279 };
280
281 #define DEVICEMEM_UTILS_NO_ADDRESS 0
282
283 /******************************************************************************
284 @Function       _DevmemValidateParams
285 @Description    Check if flags are conflicting and if align is a size multiple.
286
287 @Input          uiSize      Size of the import.
288 @Input          uiAlign     Alignment of the import.
289 @Input          puiFlags    Pointer to the flags for the import.
290 @return         PVRSRV_ERROR
291 ******************************************************************************/
292 PVRSRV_ERROR _DevmemValidateParams(IMG_DEVMEM_SIZE_T uiSize,
293                                    IMG_DEVMEM_ALIGN_T uiAlign,
294                                    DEVMEM_FLAGS_T *puiFlags);
295
296 /******************************************************************************
297 @Function       _DevmemImportStructAlloc
298 @Description    Allocates memory for an import struct. Does not allocate a PMR!
299                 Create locks for CPU and Devmem mappings.
300
301 @Input          hBridge       Bridge to use for calls from the import.
302 @Input          ppsImport     The import to allocate.
303 @return         PVRSRV_ERROR
304 ******************************************************************************/
305 PVRSRV_ERROR _DevmemImportStructAlloc(SHARED_DEV_CONNECTION hDevConnection,
306                                                                           DEVMEM_IMPORT **ppsImport);
307
308 /******************************************************************************
309 @Function       _DevmemImportStructInit
310 @Description    Initialises the import struct with the given parameters.
311                 Set it's refcount to 1!
312
313 @Input          psImport     The import to initialise.
314 @Input          uiSize       Size of the import.
315 @Input          uiAlign      Alignment of allocations in the import.
316 @Input          uiMapFlags
317 @Input          hPMR         Reference to the PMR of this import struct.
318 @Input          uiProperties Properties of the import. Is it exportable,
319                               imported, suballocatable, unpinned?
320 ******************************************************************************/
321 void _DevmemImportStructInit(DEVMEM_IMPORT *psImport,
322                                                          IMG_DEVMEM_SIZE_T uiSize,
323                                                          IMG_DEVMEM_ALIGN_T uiAlign,
324                                                          PVRSRV_MEMALLOCFLAGS_T uiMapFlags,
325                                                          IMG_HANDLE hPMR,
326                                                          DEVMEM_PROPERTIES_T uiProperties);
327
328 /******************************************************************************
329 @Function       _DevmemImportStructDevMap
330 @Description    NEVER call after the last _DevmemMemDescRelease()
331                 Maps the PMR referenced by the import struct to the device's
332                 virtual address space.
333                 Does nothing but increase the cpu mapping refcount if the
334                 import struct was already mapped.
335
336 @Input          psHeap    The heap to map to.
337 @Input          bMap      Caller can choose if the import should be really
338                           mapped in the page tables or if just a virtual range
339                           should be reserved and the refcounts increased.
340 @Input          psImport  The import we want to map.
341 @Input          uiOptionalMapAddress  An optional address to map to.
342                                       Pass DEVICEMEM_UTILS_NOADDRESS if not used.
343 @return         PVRSRV_ERROR
344 ******************************************************************************/
345 PVRSRV_ERROR _DevmemImportStructDevMap(DEVMEM_HEAP *psHeap,
346                                                                            IMG_BOOL bMap,
347                                                                            DEVMEM_IMPORT *psImport,
348                                                                            IMG_UINT64 uiOptionalMapAddress);
349
350 /******************************************************************************
351 @Function       _DevmemImportStructDevUnmap
352 @Description    Unmaps the PMR referenced by the import struct from the
353                 device's virtual address space.
354                 If this was not the last remaining CPU mapping on the import
355                 struct only the cpu mapping refcount is decreased.
356 ******************************************************************************/
357 void _DevmemImportStructDevUnmap(DEVMEM_IMPORT *psImport);
358
359 /******************************************************************************
360 @Function       _DevmemImportStructCPUMap
361 @Description    NEVER call after the last _DevmemMemDescRelease()
362                 Maps the PMR referenced by the import struct to the CPU's
363                 virtual address space.
364                 Does nothing but increase the cpu mapping refcount if the
365                 import struct was already mapped.
366 @return         PVRSRV_ERROR
367 ******************************************************************************/
368 PVRSRV_ERROR _DevmemImportStructCPUMap(DEVMEM_IMPORT *psImport);
369
370 /******************************************************************************
371 @Function       _DevmemImportStructCPUUnmap
372 @Description    Unmaps the PMR referenced by the import struct from the CPU's
373                 virtual address space.
374                 If this was not the last remaining CPU mapping on the import
375                 struct only the cpu mapping refcount is decreased.
376 ******************************************************************************/
377 void _DevmemImportStructCPUUnmap(DEVMEM_IMPORT *psImport);
378
379
380 /******************************************************************************
381 @Function       _DevmemImportStructAcquire
382 @Description    Acquire an import struct by increasing it's refcount.
383 ******************************************************************************/
384 void _DevmemImportStructAcquire(DEVMEM_IMPORT *psImport);
385
386 /******************************************************************************
387 @Function       _DevmemImportStructRelease
388 @Description    Reduces the refcount of the import struct.
389                 Destroys the import in the case it was the last reference.
390                 Destroys underlying PMR if this import was the last reference
391                 to it.
392 @return         A boolean to signal if the import was destroyed. True = yes.
393 ******************************************************************************/
394 void _DevmemImportStructRelease(DEVMEM_IMPORT *psImport);
395
396 /******************************************************************************
397 @Function       _DevmemImportDiscard
398 @Description    Discard a created, but unitilised import structure.
399                 This must only be called before _DevmemImportStructInit
400                 after which _DevmemImportStructRelease must be used to
401                 "free" the import structure.
402 ******************************************************************************/
403 void _DevmemImportDiscard(DEVMEM_IMPORT *psImport);
404
405 /******************************************************************************
406 @Function       _DevmemMemDescAlloc
407 @Description    Allocates a MemDesc and create it's various locks.
408                 Zero the allocated memory.
409 @return         PVRSRV_ERROR
410 ******************************************************************************/
411 PVRSRV_ERROR _DevmemMemDescAlloc(DEVMEM_MEMDESC **ppsMemDesc);
412
413 /******************************************************************************
414 @Function       _DevmemMemDescInit
415 @Description    Sets the given offset and import struct fields in the MemDesc.
416                 Initialises refcount to 1 and other values to 0.
417
418 @Input          psMemDesc    MemDesc to initialise.
419 @Input          uiOffset     Offset in the import structure.
420 @Input          psImport     Import the MemDesc is on.
421 @Input          uiAllocSize  Size of the allocation
422 ******************************************************************************/
423 void _DevmemMemDescInit(DEVMEM_MEMDESC *psMemDesc,
424                                                 IMG_DEVMEM_OFFSET_T uiOffset,
425                                                 DEVMEM_IMPORT *psImport,
426                                                 IMG_DEVMEM_SIZE_T uiAllocSize);
427
428 /******************************************************************************
429 @Function       _DevmemMemDescAcquire
430 @Description    Acquires the MemDesc by increasing it's refcount.
431 ******************************************************************************/
432 void _DevmemMemDescAcquire(DEVMEM_MEMDESC *psMemDesc);
433
434 /******************************************************************************
435 @Function       _DevmemMemDescRelease
436 @Description    Releases the MemDesc by reducing it's refcount.
437                 Destroy the MemDesc if it's recount is 0.
438                 Destroy the import struct the MemDesc is on if that was the
439                 last MemDesc on the import, probably following the destruction
440                 of the underlying PMR.
441 ******************************************************************************/
442 void _DevmemMemDescRelease(DEVMEM_MEMDESC *psMemDesc);
443
444 /******************************************************************************
445 @Function       _DevmemMemDescDiscard
446 @Description    Discard a created, but unitilised MemDesc structure.
447                 This must only be called before _DevmemMemDescInit
448                 after which _DevmemMemDescRelease must be used to
449                 "free" the MemDesc structure.
450 ******************************************************************************/
451 void _DevmemMemDescDiscard(DEVMEM_MEMDESC *psMemDesc);
452
453 #endif /* _DEVICEMEM_UTILS_H_ */