MALI: utgard: upgrade DDK to r7p0-00rel0
[firefly-linux-kernel-4.4.55.git] / drivers / gpu / arm / mali400 / mali / linux / mali_memory_util.c
1 /*
2  * Copyright (C) 2013-2016 ARM Limited. All rights reserved.
3  * 
4  * This program is free software and is provided to you under the terms of the GNU General Public License version 2
5  * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
6  * 
7  * A copy of the licence is included with the program, and can also be obtained from Free Software
8  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
9  */
10
11 #include <linux/list.h>
12 #include <linux/mm.h>
13 #include <linux/mm_types.h>
14 #include <linux/fs.h>
15 #include <linux/dma-mapping.h>
16 #include <linux/slab.h>
17 #include <linux/platform_device.h>
18
19 #include "mali_osk.h"
20 #include "mali_osk_mali.h"
21 #include "mali_kernel_linux.h"
22 #include "mali_scheduler.h"
23
24 #include "mali_memory.h"
25 #include "mali_memory_os_alloc.h"
26 #if defined(CONFIG_DMA_SHARED_BUFFER)
27 #include "mali_memory_dma_buf.h"
28 #include "mali_memory_secure.h"
29 #endif
30 #if defined(CONFIG_MALI400_UMP)
31 #include "mali_memory_ump.h"
32 #endif
33 #include "mali_memory_external.h"
34 #include "mali_memory_manager.h"
35 #include "mali_memory_virtual.h"
36 #include "mali_memory_cow.h"
37 #include "mali_memory_block_alloc.h"
38 #include "mali_memory_swap_alloc.h"
39
40
41
42 /**
43 *function @_mali_free_allocation_mem - free a memory allocation
44 */
45 static u32 _mali_free_allocation_mem(mali_mem_allocation *mali_alloc)
46 {
47         mali_mem_backend *mem_bkend = NULL;
48         u32 free_pages_nr = 0;
49
50         struct mali_session_data *session = mali_alloc->session;
51         MALI_DEBUG_PRINT(4, (" _mali_free_allocation_mem, psize =0x%x! \n", mali_alloc->psize));
52         if (0 == mali_alloc->psize)
53                 goto out;
54
55         /* Get backend memory & Map on CPU */
56         mutex_lock(&mali_idr_mutex);
57         mem_bkend = idr_find(&mali_backend_idr, mali_alloc->backend_handle);
58         mutex_unlock(&mali_idr_mutex);
59         MALI_DEBUG_ASSERT(NULL != mem_bkend);
60
61         switch (mem_bkend->type) {
62         case MALI_MEM_OS:
63                 free_pages_nr = mali_mem_os_release(mem_bkend);
64                 atomic_sub(free_pages_nr, &session->mali_mem_allocated_pages);
65                 break;
66         case MALI_MEM_UMP:
67 #if defined(CONFIG_MALI400_UMP)
68                 mali_mem_unbind_ump_buf(mem_bkend);
69                 atomic_sub(mem_bkend->size / MALI_MMU_PAGE_SIZE, &session->mali_mem_array[mem_bkend->type]);
70 #else
71                 MALI_DEBUG_PRINT(1, ("UMP not supported\n"));
72 #endif
73                 break;
74         case MALI_MEM_DMA_BUF:
75 #if defined(CONFIG_DMA_SHARED_BUFFER)
76                 mali_mem_unbind_dma_buf(mem_bkend);
77                 atomic_sub(mem_bkend->size / MALI_MMU_PAGE_SIZE, &session->mali_mem_array[mem_bkend->type]);
78 #else
79                 MALI_DEBUG_PRINT(1, ("DMA not supported\n"));
80 #endif
81                 break;
82         case MALI_MEM_EXTERNAL:
83                 mali_mem_unbind_ext_buf(mem_bkend);
84                 atomic_sub(mem_bkend->size / MALI_MMU_PAGE_SIZE, &session->mali_mem_array[mem_bkend->type]);
85                 break;
86
87         case MALI_MEM_BLOCK:
88                 free_pages_nr = mali_mem_block_release(mem_bkend);
89                 atomic_sub(free_pages_nr, &session->mali_mem_allocated_pages);
90                 break;
91
92         case MALI_MEM_COW:
93                 if (mem_bkend->flags & MALI_MEM_BACKEND_FLAG_SWAP_COWED) {
94                         free_pages_nr = mali_mem_swap_release(mem_bkend, MALI_TRUE);
95                 } else {
96                         free_pages_nr = mali_mem_cow_release(mem_bkend, MALI_TRUE);
97                 }
98                 atomic_sub(free_pages_nr, &session->mali_mem_allocated_pages);
99                 break;
100         case MALI_MEM_SWAP:
101                 free_pages_nr = mali_mem_swap_release(mem_bkend, MALI_TRUE);
102                 atomic_sub(free_pages_nr, &session->mali_mem_allocated_pages);
103                 atomic_sub(free_pages_nr, &session->mali_mem_array[mem_bkend->type]);
104                 break;
105         case MALI_MEM_SECURE:
106 #if defined(CONFIG_DMA_SHARED_BUFFER)
107                 free_pages_nr = mali_mem_secure_release(mem_bkend);
108                 atomic_sub(free_pages_nr, &session->mali_mem_allocated_pages);
109 #else
110                 MALI_DEBUG_PRINT(1, ("DMA not supported for mali secure memory\n"));
111 #endif
112                 break;
113         default:
114                 MALI_DEBUG_PRINT(1, ("mem type %d is not in the mali_mem_type enum.\n", mem_bkend->type));
115                 break;
116         }
117
118         /*Remove backend memory idex */
119         mutex_lock(&mali_idr_mutex);
120         idr_remove(&mali_backend_idr, mali_alloc->backend_handle);
121         mutex_unlock(&mali_idr_mutex);
122         kfree(mem_bkend);
123 out:
124         /* remove memory allocation  */
125         mali_vma_offset_remove(&session->allocation_mgr, &mali_alloc->mali_vma_node);
126         mali_mem_allocation_struct_destory(mali_alloc);
127         return free_pages_nr;
128 }
129
130 /**
131 *  ref_count for allocation
132 */
133 u32 mali_allocation_unref(struct mali_mem_allocation **alloc)
134 {
135         u32 free_pages_nr = 0;
136         mali_mem_allocation *mali_alloc = *alloc;
137         *alloc = NULL;
138         if (0 == _mali_osk_atomic_dec_return(&mali_alloc->mem_alloc_refcount)) {
139                 free_pages_nr = _mali_free_allocation_mem(mali_alloc);
140         }
141         return free_pages_nr;
142 }
143
144 void mali_allocation_ref(struct mali_mem_allocation *alloc)
145 {
146         _mali_osk_atomic_inc(&alloc->mem_alloc_refcount);
147 }
148
149 void mali_free_session_allocations(struct mali_session_data *session)
150 {
151         struct mali_mem_allocation *entry, *next;
152
153         MALI_DEBUG_PRINT(4, (" mali_free_session_allocations! \n"));
154
155         list_for_each_entry_safe(entry, next, &session->allocation_mgr.head, list) {
156                 mali_allocation_unref(&entry);
157         }
158 }