xref: /rockchip-linux_mpp/mpp/base/inc/mpp_buffer_impl.h (revision 437bfbeb9567cca9cd9080e3f6954aa9d6a94f18)
1 /* SPDX-License-Identifier: Apache-2.0 OR MIT */
2 /*
3  * Copyright (c) 2015 Rockchip Electronics Co., Ltd.
4  */
5 
6 #ifndef __MPP_BUFFER_IMPL_H__
7 #define __MPP_BUFFER_IMPL_H__
8 
9 #include "mpp_list.h"
10 #include "mpp_hash.h"
11 #include "mpp_common.h"
12 #include "mpp_allocator.h"
13 #include "mpp_device.h"
14 
15 #define MPP_BUF_DBG_FUNCTION            (0x00000001)
16 #define MPP_BUF_DBG_OPS_RUNTIME         (0x00000002)
17 #define MPP_BUF_DBG_OPS_HISTORY         (0x00000004)
18 #define MPP_BUF_DBG_CLR_ON_EXIT         (0x00000010)
19 #define MPP_BUF_DBG_DUMP_ON_EXIT        (0x00000020)
20 #define MPP_BUF_DBG_CHECK_SIZE          (0x00000100)
21 
22 #define mpp_buf_dbg(flag, fmt, ...)     _mpp_dbg(mpp_buffer_debug, flag, fmt, ## __VA_ARGS__)
23 #define mpp_buf_dbg_f(flag, fmt, ...)   _mpp_dbg_f(mpp_buffer_debug, flag, fmt, ## __VA_ARGS__)
24 
25 #define MPP_BUF_FUNCTION_ENTER()        mpp_buf_dbg_f(MPP_BUF_DBG_FUNCTION, "enter\n")
26 #define MPP_BUF_FUNCTION_LEAVE()        mpp_buf_dbg_f(MPP_BUF_DBG_FUNCTION, "leave\n")
27 #define MPP_BUF_FUNCTION_LEAVE_OK()     mpp_buf_dbg_f(MPP_BUF_DBG_FUNCTION, "success\n")
28 #define MPP_BUF_FUNCTION_LEAVE_FAIL()   mpp_buf_dbg_f(MPP_BUF_DBG_FUNCTION, "failed\n")
29 
30 typedef enum MppBufOps_e {
31     GRP_CREATE,
32     GRP_RELEASE,
33     GRP_RESET,
34     GRP_ORPHAN,
35     GRP_DESTROY,
36 
37     GRP_OPS_BUTT    = GRP_DESTROY,
38     BUF_COMMIT,
39     BUF_CREATE,
40     BUF_MMAP,
41     BUF_REF_INC,
42     BUF_REF_DEC,
43     BUF_DISCARD,
44     BUF_DESTROY,
45     BUF_OPS_BUTT,
46 } MppBufOps;
47 
48 typedef struct MppBufLog_t {
49     RK_U32              group_id;
50     RK_S32              buffer_id;
51     MppBufOps           ops;
52     RK_S32              ref_count;
53     const char          *caller;
54 } MppBufLog;
55 
56 typedef struct MppBufLogs_t {
57     pthread_mutex_t     lock;
58     RK_U16              max_count;
59     RK_U16              log_count;
60     RK_U16              log_write;
61     RK_U16              log_read;
62     MppBufLog           *logs;
63 } MppBufLogs;
64 
65 typedef struct MppBufferImpl_t          MppBufferImpl;
66 typedef struct MppBufferGroupImpl_t     MppBufferGroupImpl;
67 typedef void (*MppBufCallback)(void *, void *);
68 
69 // use index instead of pointer to avoid invalid pointer
70 struct MppBufferImpl_t {
71     char                tag[MPP_TAG_SIZE];
72     const char          *caller;
73     pthread_mutex_t     lock;
74     /* parameter store from MppBufferGroup */
75     MppAllocator        allocator;
76     MppAllocatorApi     *alloc_api;
77     RK_U32              log_runtime_en;
78     RK_U32              log_history_en;
79     RK_U32              group_id;
80     RK_S32              buffer_id;
81     MppBufferMode       mode;
82     MppBufferType       type;
83     MppBufLogs          *logs;
84 
85     MppBufferInfo       info;
86     size_t              offset;
87     size_t              length;
88 
89     /* cacheable flag */
90     RK_U32              uncached;
91 
92     /*
93      * discard:
94      * used for buf on group reset mode
95      * set disard value to 1 when frame refcount no zero ,
96      * we will delay relesase buffer after refcount to zero,
97      * not put this buf to unused list
98      */
99     RK_S32              discard;
100     // used flag is for used/unused list detection
101     RK_U32              used;
102     RK_S32              ref_count;
103     struct list_head    list_status;
104 
105     /*
106      * mpp_device map for attach / detach operation
107      */
108     struct list_head    list_maps;
109 };
110 
111 struct MppBufferGroupImpl_t {
112     char                tag[MPP_TAG_SIZE];
113     const char          *caller;
114     /* parameter store for MppBuffer */
115     MppAllocator        allocator;
116     MppAllocatorApi     *alloc_api;
117     MppAllocFlagType    flags;
118     RK_U32              log_runtime_en;
119     RK_U32              log_history_en;
120     RK_U32              group_id;
121     MppBufferMode       mode;
122     MppBufferType       type;
123 
124     /* group status flag */
125     // buffer force clear mode flag
126     RK_U32              clear_on_exit;
127     RK_U32              dump_on_exit;
128     // is_misc: 0 - normal group 1 - misc group
129     RK_U32              is_misc;
130     // is_orphan: 0 - normal group 1 - orphan group
131     RK_U32              is_orphan;
132     RK_U32              is_finalizing;
133     // used in limit mode only
134     size_t              limit_size;
135     RK_S32              limit_count;
136     // status record
137     size_t              limit;
138     size_t              usage;
139     RK_S32              buffer_id;
140     RK_S32              buffer_count;
141 
142     // thread that will be signal on buffer return
143     MppBufCallback      callback;
144     void                *arg;
145 
146     // link to list_status in MppBufferImpl
147     pthread_mutex_t     buf_lock;
148     struct hlist_node   hlist;
149     struct list_head    list_used;
150     struct list_head    list_unused;
151     RK_S32              count_used;
152     RK_S32              count_unused;
153 
154     // buffer log function
155     MppBufLogs          *logs;
156 
157     // link to the other MppBufferGroupImpl
158     struct list_head    list_group;
159 };
160 
161 #ifdef __cplusplus
162 extern "C" {
163 #endif
164 
165 extern RK_U32 mpp_buffer_debug;
166 
167 /*
168  *  mpp_buffer_create       : create a unused buffer with parameter tag/size/data
169  *                            if input buffer is NULL then buffer will be register to unused list
170  *                            otherwise the buffer will be register to used list and set to paramter buffer
171  *
172  *  mpp_buffer_mmap         : The created mpp_buffer can not be accessed directly.
173  *                            It required map to access. This is an optimization
174  *                            for reducing virtual memory usage.
175  *
176  *  mpp_buffer_get_unused   : get unused buffer with size. it will first search
177  *                            the unused list. if failed it will create on from
178  *                            group allocator.
179  *
180  *  mpp_buffer_ref_inc      : increase buffer's reference counter. if it is unused
181  *                            then it will be moved to used list.
182  *
183  *  mpp_buffer_ref_dec      : decrease buffer's reference counter. if the reference
184  *                            reduce to zero buffer will be moved to unused list.
185  *
186  * normal call flow will be like this:
187  *
188  * mpp_buffer_create        - create a unused buffer
189  * mpp_buffer_get_unused    - get the unused buffer
190  * mpp_buffer_ref_inc/dec   - use the buffer
191  * mpp_buffer_destory       - destroy the buffer
192  */
193 MPP_RET mpp_buffer_create(const char *tag, const char *caller, MppBufferGroupImpl *group, MppBufferInfo *info, MppBufferImpl **buffer);
194 MPP_RET mpp_buffer_mmap(MppBufferImpl *buffer, const char* caller);
195 MPP_RET mpp_buffer_ref_inc(MppBufferImpl *buffer, const char* caller);
196 MPP_RET mpp_buffer_ref_dec(MppBufferImpl *buffer, const char* caller);
197 MPP_RET mpp_buffer_discard(MppBufferImpl *buffer, const char* caller);
198 MppBufferImpl *mpp_buffer_get_unused(MppBufferGroupImpl *p, size_t size, const char* caller);
199 RK_U32  mpp_buffer_to_addr(MppBuffer buffer, size_t offset);
200 MPP_RET mpp_buffer_attach_dev_f(const char *caller, MppBuffer buffer, MppDev dev);
201 MPP_RET mpp_buffer_detach_dev_f(const char *caller, MppBuffer buffer, MppDev dev);
202 RK_U32  mpp_buffer_get_iova_f(const char *caller, MppBuffer buffer, MppDev dev);
203 
204 #define mpp_buffer_attach_dev(buf, dev) mpp_buffer_attach_dev_f(__FUNCTION__, buf, dev)
205 #define mpp_buffer_detach_dev(buf, dev) mpp_buffer_detach_dev_f(__FUNCTION__, buf, dev)
206 #define mpp_buffer_get_iova(buf, dev)   mpp_buffer_get_iova_f(__FUNCTION__, buf, dev)
207 
208 MPP_RET mpp_buffer_group_init(MppBufferGroupImpl **group, const char *tag, const char *caller, MppBufferMode mode, MppBufferType type);
209 MPP_RET mpp_buffer_group_deinit(MppBufferGroupImpl *p);
210 MPP_RET mpp_buffer_group_reset(MppBufferGroupImpl *p);
211 MPP_RET mpp_buffer_group_set_callback(MppBufferGroupImpl *p,
212                                       MppBufCallback callback, void *arg);
213 // mpp_buffer_group helper function
214 void mpp_buffer_group_dump(MppBufferGroupImpl *p, const char *caller);
215 MppBufferGroupImpl *mpp_buffer_get_misc_group(MppBufferMode mode, MppBufferType type);
216 
217 #ifdef __cplusplus
218 }
219 #endif
220 
221 #endif /*__MPP_BUFFER_IMPL_H__*/
222