1 /*
2 * Copyright 2015 Rockchip Electronics Co. LTD
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17 #include <string.h>
18
19 #include "mpp_mem.h"
20 #include "mpp_env.h"
21 #include "mpp_debug.h"
22 #include "mpp_buffer.h"
23
24 #include "vpu.h"
25 #include "vpu_mem_legacy.h"
26
27 #define VPU_MEM_DBG_FUNCTION (0x00000001)
28
29 static RK_U32 vpu_mem_debug = 0;
30
31 #define vpu_mem_dbg(flag, fmt, ...) _mpp_dbg(vpu_mem_debug, flag, fmt, ## __VA_ARGS__)
32 #define vpu_mem_dbg_f(flag, fmt, ...) _mpp_dbg_f(vpu_mem_debug, flag, fmt, ## __VA_ARGS__)
33
34 #define vpu_mem_dbg_func(fmt, ...) vpu_mem_dbg_f(VPU_MEM_DBG_FUNCTION, fmt, ## __VA_ARGS__)
35
36 static RK_S32
commit_memory_handle(vpu_display_mem_pool * p,RK_S32 mem_hdl,RK_S32 size)37 commit_memory_handle(vpu_display_mem_pool *p, RK_S32 mem_hdl, RK_S32 size)
38 {
39 MppBufferInfo info;
40 vpu_display_mem_pool_impl *p_mempool = (vpu_display_mem_pool_impl *)p;
41
42 vpu_mem_dbg_func("in pool %p hnl %p size %d\n", p, mem_hdl, size);
43 memset(&info, 0, sizeof(MppBufferInfo));
44 info.type = MPP_BUFFER_TYPE_ION;
45 info.fd = mem_hdl;
46 info.size = size & 0x07ffffff;
47 info.index = (size & 0xf8000000) >> 27;
48
49 p_mempool->size = size;
50 p_mempool->buff_size = size;
51
52 mpp_buffer_commit(p_mempool->group, &info);
53 vpu_mem_dbg_func("out pool %p fd %d\n", p, info.fd);
54 return info.fd;
55 }
56
get_free_memory_vpumem(vpu_display_mem_pool * p)57 static void* get_free_memory_vpumem(vpu_display_mem_pool *p)
58 {
59 MPP_RET ret = MPP_OK;
60 MppBuffer buffer = NULL;
61 VPUMemLinear_t *dmabuf = mpp_calloc(VPUMemLinear_t, 1);
62 vpu_display_mem_pool_impl *p_mempool = (vpu_display_mem_pool_impl *)p;
63 if (dmabuf == NULL) {
64 return NULL;
65 }
66 vpu_mem_dbg_func("in pool %p\n", p);
67 ret = mpp_buffer_get(p_mempool->group, &buffer, p_mempool->size);
68 if (MPP_OK != ret) {
69 mpp_free(dmabuf);
70 return NULL;
71 }
72 dmabuf->phy_addr = (RK_U32)mpp_buffer_get_fd(buffer);
73 dmabuf->vir_addr = (RK_U32*)mpp_buffer_get_ptr(buffer);
74 dmabuf->size = p_mempool->size;
75 dmabuf->offset = (RK_U32*)buffer;
76 vpu_mem_dbg_func("out pool %p ret %p fd %d size %d buffer %p\n", p, dmabuf,
77 dmabuf->phy_addr, dmabuf->size, buffer);
78 return dmabuf;
79
80 }
81
inc_used_memory_handle_ref(vpu_display_mem_pool * p,void * hdl)82 static RK_S32 inc_used_memory_handle_ref(vpu_display_mem_pool *p, void * hdl)
83 {
84 VPUMemLinear_t *dmabuf = (VPUMemLinear_t *)hdl;
85 MppBuffer buffer = (MppBuffer)dmabuf->offset;
86 vpu_mem_dbg_func("pool %p hnd %p buffer %p\n", p, hdl, buffer);
87 if (buffer != NULL) {
88 mpp_buffer_inc_ref(buffer);
89 }
90
91 (void)p;
92 return MPP_OK;
93 }
94
put_used_memory_handle(vpu_display_mem_pool * p,void * hdl)95 static RK_S32 put_used_memory_handle(vpu_display_mem_pool *p, void *hdl)
96 {
97 VPUMemLinear_t *dmabuf = (VPUMemLinear_t *)hdl;
98 MppBuffer buf = (MppBuffer)dmabuf->offset;
99 vpu_mem_dbg_func("pool %p hnd %p buffer %p\n", p, hdl, buf);
100 if (buf != NULL) {
101 mpp_buffer_put(buf);
102 memset(dmabuf, 0, sizeof(VPUMemLinear_t));
103 }
104 (void)p;
105 return MPP_OK;
106 }
107
get_free_memory_num(vpu_display_mem_pool * p)108 static RK_S32 get_free_memory_num(vpu_display_mem_pool *p)
109 {
110 vpu_display_mem_pool_impl *p_mempool = (vpu_display_mem_pool_impl *)p;
111 RK_S32 ret = (p_mempool->group) ?
112 (mpp_buffer_group_unused(p_mempool->group)) : (0);
113
114 vpu_mem_dbg_func("pool %p ret %d\n", p, ret);
115 return ret;
116 }
117
reset_vpu_mem_pool(vpu_display_mem_pool * p)118 static RK_S32 reset_vpu_mem_pool(vpu_display_mem_pool *p)
119 {
120 vpu_display_mem_pool_impl *p_mempool = (vpu_display_mem_pool_impl *)p;
121 mpp_buffer_group_clear(p_mempool->group);
122 return 0;
123 }
124
125
open_vpu_memory_pool()126 vpu_display_mem_pool* open_vpu_memory_pool()
127 {
128 vpu_display_mem_pool_impl *p_mempool =
129 mpp_calloc(vpu_display_mem_pool_impl, 1);
130
131 mpp_env_get_u32("vpu_mem_debug", &vpu_mem_debug, 0);
132 vpu_mem_dbg_func("in pool %p\n", p_mempool);
133
134 if (NULL == p_mempool) {
135 return NULL;
136 }
137 mpp_buffer_group_get_external(&p_mempool->group, MPP_BUFFER_TYPE_ION);
138 if (NULL == p_mempool->group) {
139 return NULL;
140 }
141 p_mempool->commit_hdl = commit_memory_handle;
142 p_mempool->get_free = get_free_memory_vpumem;
143 p_mempool->put_used = put_used_memory_handle;
144 p_mempool->inc_used = inc_used_memory_handle_ref;
145 p_mempool->reset = reset_vpu_mem_pool;
146 p_mempool->get_unused_num = get_free_memory_num;
147 p_mempool->version = 1;
148 p_mempool->buff_size = -1;
149
150 vpu_mem_dbg_func("out pool %p group %p\n", p_mempool, p_mempool->group);
151 return (vpu_display_mem_pool*)p_mempool;
152 }
153
close_vpu_memory_pool(vpu_display_mem_pool * p)154 void close_vpu_memory_pool(vpu_display_mem_pool *p)
155 {
156 vpu_display_mem_pool_impl *p_mempool = (vpu_display_mem_pool_impl *)p;
157
158 vpu_mem_dbg_func("pool %p group %p\n", p_mempool, p_mempool->group);
159 mpp_buffer_group_put(p_mempool->group);
160 mpp_free(p_mempool);
161 return;
162 }
163
create_vpu_memory_pool_allocator(vpu_display_mem_pool ** ipool,int num,int size)164 int create_vpu_memory_pool_allocator(vpu_display_mem_pool **ipool,
165 int num, int size)
166 {
167 vpu_display_mem_pool_impl *p_mempool =
168 mpp_calloc(vpu_display_mem_pool_impl, 1);
169
170 mpp_env_get_u32("vpu_mem_debug", &vpu_mem_debug, 0);
171 vpu_mem_dbg_func("in pool %p num %d size %d\n", p_mempool, num, size);
172
173 if (NULL == p_mempool)
174 return -1;
175
176 mpp_buffer_group_get_internal(&p_mempool->group, MPP_BUFFER_TYPE_ION);
177 mpp_buffer_group_limit_config(p_mempool->group, 0, num + 4);
178 p_mempool->commit_hdl = commit_memory_handle;
179 p_mempool->get_free = get_free_memory_vpumem;
180 p_mempool->put_used = put_used_memory_handle;
181 p_mempool->inc_used = inc_used_memory_handle_ref;
182 p_mempool->reset = reset_vpu_mem_pool;
183 p_mempool->get_unused_num = get_free_memory_num;
184 p_mempool->version = 0;
185 p_mempool->buff_size = size;
186 p_mempool->size = size;
187 *ipool = (vpu_display_mem_pool*)p_mempool;
188
189 vpu_mem_dbg_func("out pool %p group %p\n", p_mempool, p_mempool->group);
190 return 0;
191 }
192
release_vpu_memory_pool_allocator(vpu_display_mem_pool * ipool)193 void release_vpu_memory_pool_allocator(vpu_display_mem_pool *ipool)
194 {
195 vpu_display_mem_pool_impl *p_mempool = (vpu_display_mem_pool_impl *)ipool;
196 if (p_mempool == NULL)
197 return;
198
199 vpu_mem_dbg_func("pool %p group %p\n", p_mempool, p_mempool->group);
200
201 if (p_mempool->group) {
202 mpp_buffer_group_put(p_mempool->group);
203 p_mempool->group = NULL;
204 }
205
206 vpu_mem_dbg_func("free %p\n", p_mempool);
207 mpp_free(p_mempool);
208 return;
209 }
210
VPUMemJudgeIommu()211 RK_S32 VPUMemJudgeIommu()
212 {
213 int ret = 0;
214
215 if (VPUClientGetIOMMUStatus() > 0) {
216 //mpp_err("media.used.iommu");
217 ret = 1;
218 }
219
220 return ret;
221 }
222
223
VPUMallocLinear(VPUMemLinear_t * p,RK_U32 size)224 RK_S32 VPUMallocLinear(VPUMemLinear_t *p, RK_U32 size)
225 {
226 int ret = 0;
227 MppBuffer buffer = NULL;
228 ret = mpp_buffer_get(NULL, &buffer, size);
229 if (ret != MPP_OK) {
230 return -1;
231 }
232 p->phy_addr = (RK_U32)mpp_buffer_get_fd(buffer);
233 p->vir_addr = (RK_U32*)mpp_buffer_get_ptr(buffer);
234 p->size = size;
235 p->offset = (RK_U32*)buffer;
236 return 0;
237 }
238
VPUMallocLinearFromRender(VPUMemLinear_t * p,RK_U32 size,void * ctx)239 RK_S32 VPUMallocLinearFromRender(VPUMemLinear_t *p, RK_U32 size, void *ctx)
240 {
241 VPUMemLinear_t *dma_buf = NULL;
242 vpu_display_mem_pool_impl *p_mempool = (vpu_display_mem_pool_impl *)ctx;
243 if (ctx == NULL) {
244 return VPUMallocLinear(p, size);
245 }
246 dma_buf = (VPUMemLinear_t *)
247 p_mempool->get_free((vpu_display_mem_pool *)ctx);
248 memset(p, 0, sizeof(VPUMemLinear_t));
249 if (dma_buf != NULL) {
250 if (dma_buf->size < size) {
251 mpp_free(dma_buf);
252 return -1;
253 }
254 memcpy(p, dma_buf, sizeof(VPUMemLinear_t));
255 mpp_free(dma_buf);
256 return 0;
257 }
258 return -1;
259 }
260
VPUFreeLinear(VPUMemLinear_t * p)261 RK_S32 VPUFreeLinear(VPUMemLinear_t *p)
262 {
263 if (p->offset != NULL) {
264 put_used_memory_handle(NULL, p);
265 }
266 return 0;
267 }
268
VPUMemDuplicate(VPUMemLinear_t * dst,VPUMemLinear_t * src)269 RK_S32 VPUMemDuplicate(VPUMemLinear_t *dst, VPUMemLinear_t *src)
270 {
271 MppBuffer buffer = (MppBuffer)src->offset;
272 if (buffer != NULL) {
273 mpp_buffer_inc_ref(buffer);
274 }
275 memcpy(dst, src, sizeof(VPUMemLinear_t));
276 return 0;
277 }
278
VPUMemLink(VPUMemLinear_t * p)279 RK_S32 VPUMemLink(VPUMemLinear_t *p)
280 {
281 (void)p;
282 return 0;
283 }
284
VPUMemFlush(VPUMemLinear_t * p)285 RK_S32 VPUMemFlush(VPUMemLinear_t *p)
286 {
287 (void)p;
288 return 0;
289 }
290
VPUMemClean(VPUMemLinear_t * p)291 RK_S32 VPUMemClean(VPUMemLinear_t *p)
292 {
293 (void)p;
294 return 0;
295 }
296
297
VPUMemInvalidate(VPUMemLinear_t * p)298 RK_S32 VPUMemInvalidate(VPUMemLinear_t *p)
299 {
300 (void)p;
301 return 0;
302 }
303
VPUMemGetFD(VPUMemLinear_t * p)304 RK_S32 VPUMemGetFD(VPUMemLinear_t *p)
305 {
306 RK_S32 fd = 0;
307 MppBuffer buffer = (MppBuffer)p->offset;
308 fd = mpp_buffer_get_fd(buffer);
309 return fd;
310 }
311
312