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