1 /*
2 * Copyright 2020 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 #define MODULE_TAG "mpp_cfg"
18
19 #include <string.h>
20
21 #include "mpp_env.h"
22 #include "mpp_cfg.h"
23 #include "mpp_debug.h"
24
25 #define MPP_CFG_DBG_SET (0x00000001)
26 #define MPP_CFG_DBG_GET (0x00000002)
27
28 #define mpp_cfg_dbg(flag, fmt, ...) _mpp_dbg(mpp_cfg_debug, flag, fmt, ## __VA_ARGS__)
29
30 #define mpp_cfg_dbg_set(fmt, ...) mpp_cfg_dbg(MPP_CFG_DBG_SET, fmt, ## __VA_ARGS__)
31 #define mpp_cfg_dbg_get(fmt, ...) mpp_cfg_dbg(MPP_CFG_DBG_GET, fmt, ## __VA_ARGS__)
32
33 #define CFG_TO_PTR(info, cfg) ((char *)cfg + info->data_offset)
34 #define CFG_TO_S32_PTR(info, cfg) ((RK_S32 *)CFG_TO_PTR(info, cfg))
35 #define CFG_TO_U32_PTR(info, cfg) ((RK_U32 *)CFG_TO_PTR(info, cfg))
36 #define CFG_TO_S64_PTR(info, cfg) ((RK_S64 *)CFG_TO_PTR(info, cfg))
37 #define CFG_TO_U64_PTR(info, cfg) ((RK_U64 *)CFG_TO_PTR(info, cfg))
38 #define CFG_TO_PTR_PTR(info, cfg) ((void **)CFG_TO_PTR(info, cfg))
39
40 #define CFG_TO_FLAG_PTR(info, cfg) ((RK_U32 *)((char *)cfg + info->flag_offset))
41
42 const char *cfg_type_names[] = {
43 "RK_S32",
44 "RK_U32",
45 "RK_S64",
46 "RK_U64",
47 "void *",
48 "struct",
49 };
50
51 static RK_U32 mpp_cfg_debug = 0;
52
show_cfg_info_err(MppCfgInfoNode * node,CfgType type,const char * func)53 static void show_cfg_info_err(MppCfgInfoNode *node, CfgType type, const char *func)
54 {
55 mpp_err("%s cfg %s expect %s input NOT %s\n", func, node->name,
56 cfg_type_names[node->data_type],
57 cfg_type_names[type]);
58 }
59
mpp_cfg_set(MppCfgInfoNode * info,void * cfg,void * val)60 static MPP_RET mpp_cfg_set(MppCfgInfoNode *info, void *cfg, void *val)
61 {
62 if (memcmp((char *)cfg + info->data_offset, val, info->data_size)) {
63 memcpy((char *)cfg + info->data_offset, val, info->data_size);
64 *((RK_U32 *)((char *)cfg + info->flag_offset)) |= info->flag_value;
65 }
66 return MPP_OK;
67 }
68
mpp_cfg_get(MppCfgInfoNode * info,void * cfg,void * val)69 static MPP_RET mpp_cfg_get(MppCfgInfoNode *info, void *cfg, void *val)
70 {
71 memcpy(val, (char *)cfg + info->data_offset, info->data_size);
72 return MPP_OK;
73 }
74
mpp_cfg_set_s32(MppCfgInfoNode * info,void * cfg,RK_S32 val)75 static MPP_RET mpp_cfg_set_s32(MppCfgInfoNode *info, void *cfg, RK_S32 val)
76 {
77 RK_S32 *dst = CFG_TO_S32_PTR(info, cfg);
78
79 if (dst[0] != val) {
80 mpp_cfg_dbg_set("set s32 %-25s update %d -> %d\n", info->name, dst[0], val);
81 dst[0] = val;
82 CFG_TO_FLAG_PTR(info, cfg)[0] |= info->flag_value;
83 } else {
84 mpp_cfg_dbg_set("set s32 %-25s keep %d\n", info->name, dst[0]);
85 }
86
87 return MPP_OK;
88 }
89
mpp_cfg_get_s32(MppCfgInfoNode * info,void * cfg,RK_S32 * val)90 static MPP_RET mpp_cfg_get_s32(MppCfgInfoNode *info, void *cfg, RK_S32 *val)
91 {
92 return mpp_cfg_get(info, cfg, val);
93 }
94
mpp_cfg_set_u32(MppCfgInfoNode * info,void * cfg,RK_U32 val)95 static MPP_RET mpp_cfg_set_u32(MppCfgInfoNode *info, void *cfg, RK_U32 val)
96 {
97 RK_U32 *dst = CFG_TO_U32_PTR(info, cfg);
98
99 if (dst[0] != val) {
100 mpp_cfg_dbg_set("set u32 %-25s update %u -> %u\n", info->name, dst[0], val);
101 dst[0] = val;
102 CFG_TO_FLAG_PTR(info, cfg)[0] |= info->flag_value;
103 } else {
104 mpp_cfg_dbg_set("set u32 %-25s keep %u\n", info->name, dst[0]);
105 }
106
107 return MPP_OK;
108 }
109
mpp_cfg_get_u32(MppCfgInfoNode * info,void * cfg,RK_U32 * val)110 static MPP_RET mpp_cfg_get_u32(MppCfgInfoNode *info, void *cfg, RK_U32 *val)
111 {
112 return mpp_cfg_get(info, cfg, val);
113 }
114
mpp_cfg_set_s64(MppCfgInfoNode * info,void * cfg,RK_S64 val)115 static MPP_RET mpp_cfg_set_s64(MppCfgInfoNode *info, void *cfg, RK_S64 val)
116 {
117 RK_S64 *dst = CFG_TO_S64_PTR(info, cfg);
118
119 if (dst[0] != val) {
120 mpp_cfg_dbg_set("set s64 %-25s update %lld -> %lld\n", info->name, dst[0], val);
121 dst[0] = val;
122 CFG_TO_FLAG_PTR(info, cfg)[0] |= info->flag_value;
123 } else {
124 mpp_cfg_dbg_set("set s64 %-25s keep %lld\n", info->name, dst[0]);
125 }
126
127 return MPP_OK;
128 }
129
mpp_cfg_get_s64(MppCfgInfoNode * info,void * cfg,RK_S64 * val)130 static MPP_RET mpp_cfg_get_s64(MppCfgInfoNode *info, void *cfg, RK_S64 *val)
131 {
132 return mpp_cfg_get(info, cfg, val);
133 }
134
mpp_cfg_set_u64(MppCfgInfoNode * info,void * cfg,RK_U64 val)135 static MPP_RET mpp_cfg_set_u64(MppCfgInfoNode *info, void *cfg, RK_U64 val)
136 {
137 RK_U64 *dst = CFG_TO_U64_PTR(info, cfg);
138
139 if (dst[0] != val) {
140 mpp_cfg_dbg_set("set u64 %-25s update %llu -> %llu\n", info->name, dst[0], val);
141 dst[0] = val;
142 CFG_TO_FLAG_PTR(info, cfg)[0] |= info->flag_value;
143 } else {
144 mpp_cfg_dbg_set("set u64 %-25s keep %llu\n", info->name, dst[0]);
145 }
146
147 return MPP_OK;
148 }
149
mpp_cfg_get_u64(MppCfgInfoNode * info,void * cfg,RK_U64 * val)150 static MPP_RET mpp_cfg_get_u64(MppCfgInfoNode *info, void *cfg, RK_U64 *val)
151 {
152 return mpp_cfg_get(info, cfg, val);
153 }
154
mpp_cfg_set_st(MppCfgInfoNode * info,void * cfg,void * val)155 static MPP_RET mpp_cfg_set_st(MppCfgInfoNode *info, void *cfg, void *val)
156 {
157 return mpp_cfg_set(info, cfg, val);
158 }
159
mpp_cfg_get_st(MppCfgInfoNode * info,void * cfg,void * val)160 static MPP_RET mpp_cfg_get_st(MppCfgInfoNode *info, void *cfg, void *val)
161 {
162 return mpp_cfg_get(info, cfg, val);
163 }
164
mpp_cfg_set_ptr(MppCfgInfoNode * info,void * cfg,void * val)165 static MPP_RET mpp_cfg_set_ptr(MppCfgInfoNode *info, void *cfg, void *val)
166 {
167 void **dst = CFG_TO_PTR_PTR(info, cfg);
168
169 mpp_cfg_dbg_set("set ptr %-25s update %p -> %p\n", info->name, dst[0], val);
170 dst[0] = val;
171 CFG_TO_FLAG_PTR(info, cfg)[0] |= info->flag_value;
172
173 return MPP_OK;
174 }
175
mpp_cfg_get_ptr(MppCfgInfoNode * info,void * cfg,void ** val)176 static MPP_RET mpp_cfg_get_ptr(MppCfgInfoNode *info, void *cfg, void **val)
177 {
178 return mpp_cfg_get(info, cfg, val);
179 }
180
181 MppCfgOps mpp_cfg_ops = {
182 mpp_cfg_set_s32,
183 mpp_cfg_get_s32,
184 mpp_cfg_set_u32,
185 mpp_cfg_get_u32,
186 mpp_cfg_set_s64,
187 mpp_cfg_get_s64,
188 mpp_cfg_set_u64,
189 mpp_cfg_get_u64,
190 mpp_cfg_set_st,
191 mpp_cfg_get_st,
192 mpp_cfg_set_ptr,
193 mpp_cfg_get_ptr,
194 };
195
196 #define MPP_CFG_SET_OPS(type) ((long)(((void **)&mpp_cfg_ops)[type * 2 + 0]))
197 #define MPP_CFG_GET_OPS(type) ((long)(((void **)&mpp_cfg_ops)[type * 2 + 1]))
198
mpp_cfg_node_fixup_func(MppCfgInfoNode * node)199 MPP_RET mpp_cfg_node_fixup_func(MppCfgInfoNode *node)
200 {
201 RK_S32 data_type = node->data_type;
202
203 mpp_env_get_u32("mpp_cfg_debug", &mpp_cfg_debug, 0);
204
205 mpp_assert(data_type < CFG_FUNC_TYPE_BUTT);
206 node->set_func = MPP_CFG_SET_OPS(data_type);
207 node->get_func = MPP_CFG_GET_OPS(data_type);
208 return MPP_OK;
209 }
210
check_cfg_info(MppCfgInfoNode * node,const char * name,CfgType type,const char * func)211 MPP_RET check_cfg_info(MppCfgInfoNode *node, const char *name, CfgType type,
212 const char *func)
213 {
214 if (NULL == node) {
215 mpp_err("%s: cfg %s is invalid\n", func, name);
216 return MPP_NOK;
217 }
218
219 CfgType cfg_type = (CfgType)node->data_type;
220 RK_S32 cfg_size = node->data_size;
221 MPP_RET ret = MPP_OK;
222
223 switch (type) {
224 case CFG_FUNC_TYPE_St : {
225 if (cfg_type != type) {
226 show_cfg_info_err(node, type, func);
227 ret = MPP_NOK;
228 }
229 if (cfg_size <= 0) {
230 mpp_err("%s: cfg %s found invalid size %d\n", func, node->name, cfg_size);
231 ret = MPP_NOK;
232 }
233 } break;
234 case CFG_FUNC_TYPE_Ptr : {
235 if (cfg_type != type) {
236 show_cfg_info_err(node, type, func);
237 ret = MPP_NOK;
238 }
239 } break;
240 case CFG_FUNC_TYPE_S32 :
241 case CFG_FUNC_TYPE_U32 : {
242 if (cfg_size != sizeof(RK_S32)) {
243 show_cfg_info_err(node, type, func);
244 ret = MPP_NOK;
245 }
246 } break;
247 case CFG_FUNC_TYPE_S64 :
248 case CFG_FUNC_TYPE_U64 : {
249 if (cfg_size != sizeof(RK_S64)) {
250 show_cfg_info_err(node, type, func);
251 ret = MPP_NOK;
252 }
253 } break;
254 default : {
255 mpp_err("%s: cfg %s found invalid cfg type %d\n", func, node->name, type);
256 ret = MPP_NOK;
257 } break;
258 }
259
260 return ret;
261 }
262