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