xref: /rockchip-linux_mpp/mpp/hal/common/hal_bufs.c (revision 437bfbeb9567cca9cd9080e3f6954aa9d6a94f18)
1*437bfbebSnyanmisaka /*
2*437bfbebSnyanmisaka  * Copyright 2015 - 2017 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 #define MODULE_TAG "hal_bufs"
17*437bfbebSnyanmisaka 
18*437bfbebSnyanmisaka #include <string.h>
19*437bfbebSnyanmisaka 
20*437bfbebSnyanmisaka #include "mpp_env.h"
21*437bfbebSnyanmisaka #include "mpp_mem.h"
22*437bfbebSnyanmisaka #include "mpp_debug.h"
23*437bfbebSnyanmisaka #include "mpp_common.h"
24*437bfbebSnyanmisaka 
25*437bfbebSnyanmisaka #include "hal_bufs.h"
26*437bfbebSnyanmisaka 
27*437bfbebSnyanmisaka #define HAL_BUFS_DBG_FUNCTION           (0x00000001)
28*437bfbebSnyanmisaka 
29*437bfbebSnyanmisaka #define hal_bufs_dbg(flag, fmt, ...)    _mpp_dbg(hal_bufs_debug, flag, fmt, ## __VA_ARGS__)
30*437bfbebSnyanmisaka #define hal_bufs_dbg_f(flag, fmt, ...)  _mpp_dbg_f(hal_bufs_debug, flag, fmt, ## __VA_ARGS__)
31*437bfbebSnyanmisaka 
32*437bfbebSnyanmisaka #define hal_bufs_dbg_func(fmt, ...)     hal_bufs_dbg_f(HAL_BUFS_DBG_FUNCTION, fmt, ## __VA_ARGS__)
33*437bfbebSnyanmisaka 
34*437bfbebSnyanmisaka #define hal_bufs_enter()                hal_bufs_dbg_func("enter\n");
35*437bfbebSnyanmisaka #define hal_bufs_leave()                hal_bufs_dbg_func("leave\n");
36*437bfbebSnyanmisaka 
37*437bfbebSnyanmisaka #define MAX_HAL_BUFS_CNT                40
38*437bfbebSnyanmisaka #define MAX_HAL_BUFS_SIZE_CNT           8
39*437bfbebSnyanmisaka 
40*437bfbebSnyanmisaka typedef struct HalBufsImpl_t {
41*437bfbebSnyanmisaka     MppBufferGroup  group;
42*437bfbebSnyanmisaka 
43*437bfbebSnyanmisaka     RK_S32          max_cnt;
44*437bfbebSnyanmisaka     RK_S32          size_cnt;
45*437bfbebSnyanmisaka     RK_S32          size_sum;
46*437bfbebSnyanmisaka     RK_S32          slot_sum;
47*437bfbebSnyanmisaka     RK_S32          elem_size;
48*437bfbebSnyanmisaka 
49*437bfbebSnyanmisaka     RK_U32          valid;
50*437bfbebSnyanmisaka     size_t          sizes[MAX_HAL_BUFS_SIZE_CNT];
51*437bfbebSnyanmisaka     RK_U8           *bufs;
52*437bfbebSnyanmisaka } HalBufsImpl;
53*437bfbebSnyanmisaka 
54*437bfbebSnyanmisaka static RK_U32 hal_bufs_debug = 0;
55*437bfbebSnyanmisaka 
hal_bufs_pos(HalBufsImpl * impl,RK_S32 idx)56*437bfbebSnyanmisaka static HalBuf *hal_bufs_pos(HalBufsImpl *impl, RK_S32 idx)
57*437bfbebSnyanmisaka {
58*437bfbebSnyanmisaka     RK_S32 elem_size = impl->elem_size;
59*437bfbebSnyanmisaka 
60*437bfbebSnyanmisaka     return (HalBuf *)(impl->bufs + idx * elem_size);
61*437bfbebSnyanmisaka }
62*437bfbebSnyanmisaka 
hal_bufs_clear(HalBufsImpl * impl)63*437bfbebSnyanmisaka static MPP_RET hal_bufs_clear(HalBufsImpl *impl)
64*437bfbebSnyanmisaka {
65*437bfbebSnyanmisaka     MPP_RET ret = MPP_OK;
66*437bfbebSnyanmisaka 
67*437bfbebSnyanmisaka     if (impl->valid && impl->size_sum) {
68*437bfbebSnyanmisaka         RK_S32 i;
69*437bfbebSnyanmisaka 
70*437bfbebSnyanmisaka         for (i = 0; i < impl->max_cnt; i++) {
71*437bfbebSnyanmisaka             RK_U32 mask = 1 << i;
72*437bfbebSnyanmisaka 
73*437bfbebSnyanmisaka             if (impl->valid & mask) {
74*437bfbebSnyanmisaka                 HalBuf *buf = hal_bufs_pos(impl, i);
75*437bfbebSnyanmisaka                 RK_S32 j = 0;
76*437bfbebSnyanmisaka 
77*437bfbebSnyanmisaka                 for (j = 0; j < impl->size_cnt; j++) {
78*437bfbebSnyanmisaka                     if (buf->buf[j]) {
79*437bfbebSnyanmisaka                         impl->size_sum -= impl->sizes[j];
80*437bfbebSnyanmisaka                         ret |= mpp_buffer_put(buf->buf[j]);
81*437bfbebSnyanmisaka                         buf->buf[j] = NULL;
82*437bfbebSnyanmisaka                     }
83*437bfbebSnyanmisaka                 }
84*437bfbebSnyanmisaka                 impl->valid &= ~mask;
85*437bfbebSnyanmisaka             }
86*437bfbebSnyanmisaka         }
87*437bfbebSnyanmisaka 
88*437bfbebSnyanmisaka         mpp_assert(impl->valid == 0);
89*437bfbebSnyanmisaka         mpp_assert(impl->size_sum == 0);
90*437bfbebSnyanmisaka     }
91*437bfbebSnyanmisaka 
92*437bfbebSnyanmisaka     impl->max_cnt = 0;
93*437bfbebSnyanmisaka     impl->size_cnt = 0;
94*437bfbebSnyanmisaka     impl->size_sum = 0;
95*437bfbebSnyanmisaka     impl->slot_sum = 0;
96*437bfbebSnyanmisaka     impl->valid = 0;
97*437bfbebSnyanmisaka     memset(impl->sizes, 0, sizeof(impl->sizes));
98*437bfbebSnyanmisaka     MPP_FREE(impl->bufs);
99*437bfbebSnyanmisaka 
100*437bfbebSnyanmisaka     return ret;
101*437bfbebSnyanmisaka }
102*437bfbebSnyanmisaka 
hal_bufs_init(HalBufs * bufs)103*437bfbebSnyanmisaka MPP_RET hal_bufs_init(HalBufs *bufs)
104*437bfbebSnyanmisaka {
105*437bfbebSnyanmisaka     MPP_RET ret = MPP_OK;
106*437bfbebSnyanmisaka 
107*437bfbebSnyanmisaka     if (NULL == bufs) {
108*437bfbebSnyanmisaka         mpp_err_f("invalid NULL input\n");
109*437bfbebSnyanmisaka         return MPP_ERR_NULL_PTR;
110*437bfbebSnyanmisaka     }
111*437bfbebSnyanmisaka 
112*437bfbebSnyanmisaka     mpp_env_get_u32("hal_bufs_debug", &hal_bufs_debug, 0);
113*437bfbebSnyanmisaka 
114*437bfbebSnyanmisaka     hal_bufs_enter();
115*437bfbebSnyanmisaka 
116*437bfbebSnyanmisaka     HalBufsImpl *impl = mpp_calloc(HalBufsImpl, 1);
117*437bfbebSnyanmisaka     if (impl) {
118*437bfbebSnyanmisaka         ret = mpp_buffer_group_get_internal(&impl->group, MPP_BUFFER_TYPE_ION);
119*437bfbebSnyanmisaka     } else {
120*437bfbebSnyanmisaka         mpp_err_f("failed to malloc HalBufs\n");
121*437bfbebSnyanmisaka         ret = MPP_ERR_MALLOC;
122*437bfbebSnyanmisaka     }
123*437bfbebSnyanmisaka 
124*437bfbebSnyanmisaka     *bufs = impl;
125*437bfbebSnyanmisaka 
126*437bfbebSnyanmisaka     hal_bufs_leave();
127*437bfbebSnyanmisaka 
128*437bfbebSnyanmisaka     return ret;
129*437bfbebSnyanmisaka }
130*437bfbebSnyanmisaka 
hal_bufs_deinit(HalBufs bufs)131*437bfbebSnyanmisaka MPP_RET hal_bufs_deinit(HalBufs bufs)
132*437bfbebSnyanmisaka {
133*437bfbebSnyanmisaka     HalBufsImpl *impl = (HalBufsImpl *)bufs;
134*437bfbebSnyanmisaka     MPP_RET ret = MPP_OK;
135*437bfbebSnyanmisaka 
136*437bfbebSnyanmisaka     if (NULL == bufs) {
137*437bfbebSnyanmisaka         mpp_err_f("invalid NULL input\n");
138*437bfbebSnyanmisaka         return MPP_ERR_NULL_PTR;
139*437bfbebSnyanmisaka     }
140*437bfbebSnyanmisaka 
141*437bfbebSnyanmisaka     hal_bufs_enter();
142*437bfbebSnyanmisaka 
143*437bfbebSnyanmisaka     ret = hal_bufs_clear(impl);
144*437bfbebSnyanmisaka 
145*437bfbebSnyanmisaka     if (impl->group) {
146*437bfbebSnyanmisaka         ret |= mpp_buffer_group_put(impl->group);
147*437bfbebSnyanmisaka         impl->group = NULL;
148*437bfbebSnyanmisaka     }
149*437bfbebSnyanmisaka 
150*437bfbebSnyanmisaka     memset(impl, 0, sizeof(*impl));
151*437bfbebSnyanmisaka     MPP_FREE(impl);
152*437bfbebSnyanmisaka 
153*437bfbebSnyanmisaka     hal_bufs_leave();
154*437bfbebSnyanmisaka 
155*437bfbebSnyanmisaka     return ret;
156*437bfbebSnyanmisaka }
157*437bfbebSnyanmisaka 
hal_bufs_setup(HalBufs bufs,RK_S32 max_cnt,RK_S32 size_cnt,size_t sizes[])158*437bfbebSnyanmisaka MPP_RET hal_bufs_setup(HalBufs bufs, RK_S32 max_cnt, RK_S32 size_cnt, size_t sizes[])
159*437bfbebSnyanmisaka {
160*437bfbebSnyanmisaka     HalBufsImpl *impl = (HalBufsImpl *)bufs;
161*437bfbebSnyanmisaka     MPP_RET ret = MPP_OK;
162*437bfbebSnyanmisaka     RK_S32 elem_size = 0;
163*437bfbebSnyanmisaka     RK_S32 impl_size = 0;
164*437bfbebSnyanmisaka 
165*437bfbebSnyanmisaka     if (NULL == bufs || NULL == sizes) {
166*437bfbebSnyanmisaka         mpp_err_f("invalid NULL input bufs %p sizes %p\n", bufs, sizes);
167*437bfbebSnyanmisaka         return MPP_ERR_NULL_PTR;
168*437bfbebSnyanmisaka     }
169*437bfbebSnyanmisaka 
170*437bfbebSnyanmisaka     if (max_cnt <= 0 || max_cnt > MAX_HAL_BUFS_CNT ||
171*437bfbebSnyanmisaka         size_cnt <= 0 || size_cnt > MAX_HAL_BUFS_SIZE_CNT) {
172*437bfbebSnyanmisaka         mpp_err_f("invalid max cnt %d size cnt %d\n", max_cnt, size_cnt);
173*437bfbebSnyanmisaka         return MPP_ERR_VALUE;
174*437bfbebSnyanmisaka     }
175*437bfbebSnyanmisaka 
176*437bfbebSnyanmisaka     hal_bufs_enter();
177*437bfbebSnyanmisaka 
178*437bfbebSnyanmisaka     hal_bufs_clear(impl);
179*437bfbebSnyanmisaka 
180*437bfbebSnyanmisaka     if (impl->group)
181*437bfbebSnyanmisaka         ret = mpp_buffer_group_clear(impl->group);
182*437bfbebSnyanmisaka     else
183*437bfbebSnyanmisaka         ret = mpp_buffer_group_get_internal(&impl->group, MPP_BUFFER_TYPE_ION);
184*437bfbebSnyanmisaka 
185*437bfbebSnyanmisaka     mpp_assert(impl->group);
186*437bfbebSnyanmisaka 
187*437bfbebSnyanmisaka     elem_size = sizeof(HalBuf) + sizeof(MppBuffer) * size_cnt;
188*437bfbebSnyanmisaka     impl_size = elem_size * max_cnt;
189*437bfbebSnyanmisaka 
190*437bfbebSnyanmisaka     impl->elem_size = elem_size;
191*437bfbebSnyanmisaka     impl->bufs = mpp_calloc_size(void, impl_size);
192*437bfbebSnyanmisaka     if (impl->bufs) {
193*437bfbebSnyanmisaka         RK_S32 slot_sum = 0;
194*437bfbebSnyanmisaka         RK_S32 i;
195*437bfbebSnyanmisaka 
196*437bfbebSnyanmisaka         for (i = 0; i < size_cnt; i++) {
197*437bfbebSnyanmisaka             slot_sum += sizes[i];
198*437bfbebSnyanmisaka             impl->sizes[i] = sizes[i];
199*437bfbebSnyanmisaka         }
200*437bfbebSnyanmisaka 
201*437bfbebSnyanmisaka         impl->slot_sum = slot_sum;
202*437bfbebSnyanmisaka 
203*437bfbebSnyanmisaka         for (i = 0; i < max_cnt; i++) {
204*437bfbebSnyanmisaka             HalBuf *buf = hal_bufs_pos(impl, i);
205*437bfbebSnyanmisaka 
206*437bfbebSnyanmisaka             buf->cnt = size_cnt;
207*437bfbebSnyanmisaka             buf->buf = (MppBuffer)(buf + 1);
208*437bfbebSnyanmisaka         }
209*437bfbebSnyanmisaka 
210*437bfbebSnyanmisaka         impl->max_cnt = max_cnt;
211*437bfbebSnyanmisaka         impl->size_cnt = size_cnt;
212*437bfbebSnyanmisaka     } else {
213*437bfbebSnyanmisaka         mpp_err_f("failed to malloc size %d for impl\n", impl_size);
214*437bfbebSnyanmisaka         ret = MPP_ERR_MALLOC;
215*437bfbebSnyanmisaka     }
216*437bfbebSnyanmisaka 
217*437bfbebSnyanmisaka     hal_bufs_leave();
218*437bfbebSnyanmisaka 
219*437bfbebSnyanmisaka     return ret;
220*437bfbebSnyanmisaka }
221*437bfbebSnyanmisaka 
hal_bufs_get_buf(HalBufs bufs,RK_S32 buf_idx)222*437bfbebSnyanmisaka HalBuf *hal_bufs_get_buf(HalBufs bufs, RK_S32 buf_idx)
223*437bfbebSnyanmisaka {
224*437bfbebSnyanmisaka     HalBufsImpl *impl = (HalBufsImpl *)bufs;
225*437bfbebSnyanmisaka     RK_S32 i;
226*437bfbebSnyanmisaka 
227*437bfbebSnyanmisaka     if (NULL == impl || buf_idx < 0 || buf_idx >= impl->max_cnt) {
228*437bfbebSnyanmisaka         mpp_err_f("invalid input impl %p buf_idx %d max_cnt %d\n", impl, buf_idx, impl->max_cnt);
229*437bfbebSnyanmisaka         return NULL;
230*437bfbebSnyanmisaka     }
231*437bfbebSnyanmisaka 
232*437bfbebSnyanmisaka     hal_bufs_enter();
233*437bfbebSnyanmisaka 
234*437bfbebSnyanmisaka     HalBuf *hal_buf = hal_bufs_pos(impl, buf_idx);
235*437bfbebSnyanmisaka     RK_U32 mask = 1 << buf_idx;
236*437bfbebSnyanmisaka 
237*437bfbebSnyanmisaka     if (!(impl->valid & mask)) {
238*437bfbebSnyanmisaka         MppBufferGroup group = impl->group;
239*437bfbebSnyanmisaka 
240*437bfbebSnyanmisaka         for (i = 0; i < impl->size_cnt; i++) {
241*437bfbebSnyanmisaka             size_t size = impl->sizes[i];
242*437bfbebSnyanmisaka             MppBuffer buf = hal_buf->buf[i];
243*437bfbebSnyanmisaka 
244*437bfbebSnyanmisaka             if (size && NULL == buf) {
245*437bfbebSnyanmisaka                 mpp_buffer_get(group, &buf, size);
246*437bfbebSnyanmisaka                 if (!buf)
247*437bfbebSnyanmisaka                     goto failed;
248*437bfbebSnyanmisaka                 impl->size_sum += size;
249*437bfbebSnyanmisaka             }
250*437bfbebSnyanmisaka 
251*437bfbebSnyanmisaka             mpp_assert(buf);
252*437bfbebSnyanmisaka             hal_buf->buf[i] = buf;
253*437bfbebSnyanmisaka         }
254*437bfbebSnyanmisaka 
255*437bfbebSnyanmisaka         impl->valid |= mask;
256*437bfbebSnyanmisaka     }
257*437bfbebSnyanmisaka 
258*437bfbebSnyanmisaka     hal_bufs_leave();
259*437bfbebSnyanmisaka 
260*437bfbebSnyanmisaka     return hal_buf;
261*437bfbebSnyanmisaka 
262*437bfbebSnyanmisaka failed:
263*437bfbebSnyanmisaka     for (i = 0; i < impl->size_cnt; i++) {
264*437bfbebSnyanmisaka         if (hal_buf->buf[i]) {
265*437bfbebSnyanmisaka             mpp_buffer_put(hal_buf->buf[i]);
266*437bfbebSnyanmisaka             hal_buf->buf[i] = NULL;
267*437bfbebSnyanmisaka         }
268*437bfbebSnyanmisaka     }
269*437bfbebSnyanmisaka     return NULL;
270*437bfbebSnyanmisaka }
271