uart...
[GitHub/mt8127/android_kernel_alcatel_ttab.git] / drivers / misc / mediatek / gpu / mt8127 / mali / mali / linux / mali_memory_ump.c
CommitLineData
6fa3eb70
S
1/*
2 * This confidential and proprietary software may be used only as
3 * authorised by a licensing agreement from ARM Limited
4 * (C) COPYRIGHT 2012-2013 ARM Limited
5 * ALL RIGHTS RESERVED
6 * The entire notice above must be reproduced on all authorised
7 * copies and copies may only be made to the extent permitted
8 * by a licensing agreement from ARM Limited.
9 */
10
11#include "mali_ukk.h"
12#include "mali_osk.h"
13#include "mali_kernel_common.h"
14#include "mali_session.h"
15#include "mali_kernel_linux.h"
16
17#include "mali_memory.h"
18
19#include "ump_kernel_interface.h"
20
21static int mali_ump_map(struct mali_session_data *session, mali_mem_allocation *descriptor)
22{
23 ump_dd_handle ump_mem;
24 u32 nr_blocks;
25 u32 i;
26 ump_dd_physical_block *ump_blocks;
27 struct mali_page_directory *pagedir;
28 u32 offset = 0;
29 u32 prop;
30 _mali_osk_errcode_t err;
31
32 MALI_DEBUG_ASSERT_POINTER(session);
33 MALI_DEBUG_ASSERT_POINTER(descriptor);
34 MALI_DEBUG_ASSERT(MALI_MEM_UMP == descriptor->type);
35
36 ump_mem = descriptor->ump_mem.handle;
37 MALI_DEBUG_ASSERT(UMP_DD_HANDLE_INVALID != ump_mem);
38
39 nr_blocks = ump_dd_phys_block_count_get(ump_mem);
40 if (nr_blocks == 0) {
41 MALI_DEBUG_PRINT(1, ("No block count\n"));
42 return -EINVAL;
43 }
44
45 ump_blocks = _mali_osk_malloc(sizeof(*ump_blocks)*nr_blocks);
46 if (NULL == ump_blocks) {
47 return -ENOMEM;
48 }
49
50 if (UMP_DD_INVALID == ump_dd_phys_blocks_get(ump_mem, ump_blocks, nr_blocks)) {
51 _mali_osk_free(ump_blocks);
52 return -EFAULT;
53 }
54
55 pagedir = session->page_directory;
56 prop = descriptor->mali_mapping.properties;
57
58 err = mali_mem_mali_map_prepare(descriptor);
59 if (_MALI_OSK_ERR_OK != err) {
60 MALI_DEBUG_PRINT(1, ("Mapping of UMP memory failed\n"));
61
62 _mali_osk_free(ump_blocks);
63 return -ENOMEM;
64 }
65
66 for(i = 0; i < nr_blocks; ++i) {
67 u32 virt = descriptor->mali_mapping.addr + offset;
68
69 MALI_DEBUG_PRINT(7, ("Mapping in 0x%08x size %d\n", ump_blocks[i].addr , ump_blocks[i].size));
70
71 mali_mmu_pagedir_update(pagedir, virt, ump_blocks[i].addr,
72 ump_blocks[i].size, prop);
73
74 offset += ump_blocks[i].size;
75 }
76
77 if (descriptor->flags & _MALI_MAP_EXTERNAL_MAP_GUARD_PAGE) {
78 u32 virt = descriptor->mali_mapping.addr + offset;
79
80 /* Map in an extra virtual guard page at the end of the VMA */
81 MALI_DEBUG_PRINT(6, ("Mapping in extra guard page\n"));
82
83 mali_mmu_pagedir_update(pagedir, virt, ump_blocks[0].addr, _MALI_OSK_MALI_PAGE_SIZE, prop);
84
85 offset += _MALI_OSK_MALI_PAGE_SIZE;
86 }
87
88 _mali_osk_free(ump_blocks);
89
90 return 0;
91}
92
93void mali_ump_unmap(struct mali_session_data *session, mali_mem_allocation *descriptor)
94{
95 ump_dd_handle ump_mem;
96 struct mali_page_directory *pagedir;
97
98 ump_mem = descriptor->ump_mem.handle;
99 pagedir = session->page_directory;
100
101 MALI_DEBUG_ASSERT(UMP_DD_HANDLE_INVALID != ump_mem);
102
103 mali_mem_mali_map_free(descriptor);
104
105 ump_dd_reference_release(ump_mem);
106 return;
107}
108
109_mali_osk_errcode_t _mali_ukk_attach_ump_mem(_mali_uk_attach_ump_mem_s *args)
110{
111 ump_dd_handle ump_mem;
112 struct mali_session_data *session;
113 mali_mem_allocation *descriptor;
114 int md, ret;
115
116 MALI_DEBUG_ASSERT_POINTER(args);
117 MALI_CHECK_NON_NULL(args->ctx, _MALI_OSK_ERR_INVALID_ARGS);
118
119 session = (struct mali_session_data *)args->ctx;
120 MALI_CHECK_NON_NULL(session, _MALI_OSK_ERR_INVALID_ARGS);
121
122 /* check arguments */
123 /* NULL might be a valid Mali address */
124 if (!args->size) MALI_ERROR(_MALI_OSK_ERR_INVALID_ARGS);
125
126 /* size must be a multiple of the system page size */
127 if (args->size % _MALI_OSK_MALI_PAGE_SIZE) MALI_ERROR(_MALI_OSK_ERR_INVALID_ARGS);
128
129 MALI_DEBUG_PRINT(3,
130 ("Requested to map ump memory with secure id %d into virtual memory 0x%08X, size 0x%08X\n",
131 args->secure_id, args->mali_address, args->size));
132
133 ump_mem = ump_dd_handle_create_from_secure_id((int)args->secure_id);
134
135 if (UMP_DD_HANDLE_INVALID == ump_mem) MALI_ERROR(_MALI_OSK_ERR_FAULT);
136
137 descriptor = mali_mem_descriptor_create(session, MALI_MEM_UMP);
138 if (NULL == descriptor) {
139 ump_dd_reference_release(ump_mem);
140 MALI_ERROR(_MALI_OSK_ERR_NOMEM);
141 }
142
143 descriptor->ump_mem.handle = ump_mem;
144 descriptor->mali_mapping.addr = args->mali_address;
145 descriptor->size = args->size;
146 descriptor->mali_mapping.properties = MALI_MMU_FLAGS_DEFAULT;
147 descriptor->flags |= MALI_MEM_FLAG_DONT_CPU_MAP;
148
149 if (args->flags & _MALI_MAP_EXTERNAL_MAP_GUARD_PAGE) {
150 descriptor->flags = MALI_MEM_FLAG_MALI_GUARD_PAGE;
151 }
152
153 _mali_osk_mutex_wait(session->memory_lock);
154
155 ret = mali_ump_map(session, descriptor);
156 if (0 != ret) {
157 _mali_osk_mutex_signal(session->memory_lock);
158 ump_dd_reference_release(ump_mem);
159 mali_mem_descriptor_destroy(descriptor);
160 MALI_ERROR(_MALI_OSK_ERR_NOMEM);
161 }
162
163 _mali_osk_mutex_signal(session->memory_lock);
164
165
166 if (_MALI_OSK_ERR_OK != mali_descriptor_mapping_allocate_mapping(session->descriptor_mapping, descriptor, &md)) {
167 ump_dd_reference_release(ump_mem);
168 mali_mem_descriptor_destroy(descriptor);
169 MALI_ERROR(_MALI_OSK_ERR_FAULT);
170 }
171
172 args->cookie = md;
173
174 MALI_DEBUG_PRINT(5,("Returning from UMP attach\n"));
175
176 MALI_SUCCESS;
177}
178
179void mali_mem_ump_release(mali_mem_allocation *descriptor)
180{
181 struct mali_session_data *session = descriptor->session;
182
183 MALI_DEBUG_ASSERT(MALI_MEM_UMP == descriptor->type);
184
185 mali_ump_unmap(session, descriptor);
186}
187
188_mali_osk_errcode_t _mali_ukk_release_ump_mem(_mali_uk_release_ump_mem_s *args)
189{
190 mali_mem_allocation * descriptor;
191 struct mali_session_data *session;
192
193 MALI_DEBUG_ASSERT_POINTER(args);
194 MALI_CHECK_NON_NULL(args->ctx, _MALI_OSK_ERR_INVALID_ARGS);
195
196 session = (struct mali_session_data *)args->ctx;
197 MALI_CHECK_NON_NULL(session, _MALI_OSK_ERR_INVALID_ARGS);
198
199 if (_MALI_OSK_ERR_OK != mali_descriptor_mapping_get(session->descriptor_mapping, args->cookie, (void**)&descriptor)) {
200 MALI_DEBUG_PRINT(1, ("Invalid memory descriptor %d used to release ump memory\n", args->cookie));
201 MALI_ERROR(_MALI_OSK_ERR_FAULT);
202 }
203
204 descriptor = mali_descriptor_mapping_free(session->descriptor_mapping, args->cookie);
205
206 if (NULL != descriptor) {
207 _mali_osk_mutex_wait(session->memory_lock);
208 mali_mem_ump_release(descriptor);
209 _mali_osk_mutex_signal(session->memory_lock);
210
211 mali_mem_descriptor_destroy(descriptor);
212 }
213
214 MALI_SUCCESS;
215}