xref: /rockchip-linux_mpp/mpp/base/mpp_cfg.c (revision 437bfbeb9567cca9cd9080e3f6954aa9d6a94f18)
1*437bfbebSnyanmisaka /* SPDX-License-Identifier: Apache-2.0 OR MIT */
2*437bfbebSnyanmisaka /*
3*437bfbebSnyanmisaka  * Copyright (c) 2020 Rockchip Electronics Co., Ltd.
4*437bfbebSnyanmisaka  */
5*437bfbebSnyanmisaka 
6*437bfbebSnyanmisaka #define MODULE_TAG "mpp_cfg"
7*437bfbebSnyanmisaka 
8*437bfbebSnyanmisaka #include <string.h>
9*437bfbebSnyanmisaka 
10*437bfbebSnyanmisaka #include "mpp_env.h"
11*437bfbebSnyanmisaka #include "mpp_cfg.h"
12*437bfbebSnyanmisaka #include "mpp_debug.h"
13*437bfbebSnyanmisaka 
14*437bfbebSnyanmisaka #define MPP_CFG_DBG_SET             (0x00000001)
15*437bfbebSnyanmisaka #define MPP_CFG_DBG_GET             (0x00000002)
16*437bfbebSnyanmisaka 
17*437bfbebSnyanmisaka #define mpp_cfg_dbg(flag, fmt, ...) _mpp_dbg(mpp_cfg_debug, flag, fmt, ## __VA_ARGS__)
18*437bfbebSnyanmisaka 
19*437bfbebSnyanmisaka #define mpp_cfg_dbg_set(fmt, ...)   mpp_cfg_dbg(MPP_CFG_DBG_SET, fmt, ## __VA_ARGS__)
20*437bfbebSnyanmisaka #define mpp_cfg_dbg_get(fmt, ...)   mpp_cfg_dbg(MPP_CFG_DBG_GET, fmt, ## __VA_ARGS__)
21*437bfbebSnyanmisaka 
22*437bfbebSnyanmisaka #define CFG_TO_PTR(info, cfg)       ((char *)cfg + info->data_offset)
23*437bfbebSnyanmisaka #define CFG_TO_s32_PTR(info, cfg)   ((RK_S32 *)CFG_TO_PTR(info, cfg))
24*437bfbebSnyanmisaka #define CFG_TO_u32_PTR(info, cfg)   ((RK_U32 *)CFG_TO_PTR(info, cfg))
25*437bfbebSnyanmisaka #define CFG_TO_s64_PTR(info, cfg)   ((RK_S64 *)CFG_TO_PTR(info, cfg))
26*437bfbebSnyanmisaka #define CFG_TO_u64_PTR(info, cfg)   ((RK_U64 *)CFG_TO_PTR(info, cfg))
27*437bfbebSnyanmisaka #define CFG_TO_ptr_PTR(info, cfg)   ((void **)CFG_TO_PTR(info, cfg))
28*437bfbebSnyanmisaka 
29*437bfbebSnyanmisaka /* 32bit unsigned long pointer */
30*437bfbebSnyanmisaka #define ELEM_FLAG_U32_POS(offset)       (((offset) & (~31)) / 8)
31*437bfbebSnyanmisaka #define ELEM_FLAG_BIT_POS(offset)       ((offset) & 31)
32*437bfbebSnyanmisaka #define CFG_TO_FLAG_PTR(info, cfg)      ((rk_ul *)((rk_u8 *)cfg + ELEM_FLAG_U32_POS(info->flag_offset)))
33*437bfbebSnyanmisaka 
34*437bfbebSnyanmisaka #define CFG_SET_FLAG(info, cfg) \
35*437bfbebSnyanmisaka     *CFG_TO_FLAG_PTR(info, cfg) |= 1ul << (ELEM_FLAG_BIT_POS(info->flag_offset))
36*437bfbebSnyanmisaka 
37*437bfbebSnyanmisaka static RK_U32 mpp_cfg_debug = 0;
38*437bfbebSnyanmisaka 
strof_cfg_type(CfgType type)39*437bfbebSnyanmisaka const char *strof_cfg_type(CfgType type)
40*437bfbebSnyanmisaka {
41*437bfbebSnyanmisaka     static const char *cfg_type_names[] = {
42*437bfbebSnyanmisaka         "RK_S32",
43*437bfbebSnyanmisaka         "RK_U32",
44*437bfbebSnyanmisaka         "RK_S64",
45*437bfbebSnyanmisaka         "RK_U64",
46*437bfbebSnyanmisaka         "struct",
47*437bfbebSnyanmisaka         "void *",
48*437bfbebSnyanmisaka         "unknown"
49*437bfbebSnyanmisaka     };
50*437bfbebSnyanmisaka 
51*437bfbebSnyanmisaka     if (type < 0 || type >= CFG_FUNC_TYPE_BUTT)
52*437bfbebSnyanmisaka         type = CFG_FUNC_TYPE_BUTT;
53*437bfbebSnyanmisaka 
54*437bfbebSnyanmisaka     return cfg_type_names[type];
55*437bfbebSnyanmisaka }
56*437bfbebSnyanmisaka 
show_cfg_info_err(MppCfgInfo * node,CfgType type,const char * func,const char * name)57*437bfbebSnyanmisaka static void show_cfg_info_err(MppCfgInfo *node, CfgType type, const char *func, const char *name)
58*437bfbebSnyanmisaka {
59*437bfbebSnyanmisaka     mpp_err("%s cfg %s expect %s input NOT %s\n", func, name,
60*437bfbebSnyanmisaka             strof_cfg_type(node->data_type), strof_cfg_type(type));
61*437bfbebSnyanmisaka }
62*437bfbebSnyanmisaka 
mpp_cfg_set(MppCfgInfo * info,void * cfg,void * val)63*437bfbebSnyanmisaka static MPP_RET mpp_cfg_set(MppCfgInfo *info, void *cfg, void *val)
64*437bfbebSnyanmisaka {
65*437bfbebSnyanmisaka     if (memcmp((char *)cfg + info->data_offset, val, info->data_size)) {
66*437bfbebSnyanmisaka         memcpy((char *)cfg + info->data_offset, val, info->data_size);
67*437bfbebSnyanmisaka         CFG_SET_FLAG(info, cfg);
68*437bfbebSnyanmisaka     }
69*437bfbebSnyanmisaka     return MPP_OK;
70*437bfbebSnyanmisaka }
71*437bfbebSnyanmisaka 
mpp_cfg_get(MppCfgInfo * info,void * cfg,void * val)72*437bfbebSnyanmisaka static MPP_RET mpp_cfg_get(MppCfgInfo *info, void *cfg, void *val)
73*437bfbebSnyanmisaka {
74*437bfbebSnyanmisaka     memcpy(val, (char *)cfg + info->data_offset, info->data_size);
75*437bfbebSnyanmisaka     return MPP_OK;
76*437bfbebSnyanmisaka }
77*437bfbebSnyanmisaka 
78*437bfbebSnyanmisaka #define MPP_CFG_ACCESS(type, base_type) \
79*437bfbebSnyanmisaka     MPP_RET mpp_cfg_set_##type(MppCfgInfo *info, void *cfg, base_type val) \
80*437bfbebSnyanmisaka     { \
81*437bfbebSnyanmisaka         base_type *dst = CFG_TO_##type##_PTR(info, cfg); \
82*437bfbebSnyanmisaka         base_type old = dst[0]; \
83*437bfbebSnyanmisaka         dst[0] = val; \
84*437bfbebSnyanmisaka         if (!info->flag_offset) { \
85*437bfbebSnyanmisaka             mpp_cfg_dbg_set("%p + %d set " #type " change %d -> %d\n", cfg, info->data_offset, old, val); \
86*437bfbebSnyanmisaka         } else { \
87*437bfbebSnyanmisaka             if (old != val) { \
88*437bfbebSnyanmisaka                 mpp_cfg_dbg_set("%p + %d set " #type " update %d -> %d flag %d\n", \
89*437bfbebSnyanmisaka                                 cfg, info->data_offset, old, val, info->flag_offset); \
90*437bfbebSnyanmisaka                 CFG_SET_FLAG(info, cfg); \
91*437bfbebSnyanmisaka             } else { \
92*437bfbebSnyanmisaka                 mpp_cfg_dbg_set("%p + %d set " #type " keep   %d\n", cfg, info->data_offset, old); \
93*437bfbebSnyanmisaka             } \
94*437bfbebSnyanmisaka         } \
95*437bfbebSnyanmisaka         return MPP_OK; \
96*437bfbebSnyanmisaka     } \
97*437bfbebSnyanmisaka     MPP_RET mpp_cfg_get_##type(MppCfgInfo *info, void *cfg, base_type *val) \
98*437bfbebSnyanmisaka     { \
99*437bfbebSnyanmisaka         if (info && info->data_size) { \
100*437bfbebSnyanmisaka             base_type *src = CFG_TO_##type##_PTR(info, cfg); \
101*437bfbebSnyanmisaka             mpp_cfg_dbg_set("%p + %d get " #type " value  %d\n", cfg, info->data_offset, src[0]); \
102*437bfbebSnyanmisaka             val[0] = src[0]; \
103*437bfbebSnyanmisaka             return MPP_OK; \
104*437bfbebSnyanmisaka         } \
105*437bfbebSnyanmisaka         return MPP_NOK; \
106*437bfbebSnyanmisaka     }
107*437bfbebSnyanmisaka 
MPP_CFG_ACCESS(s32,RK_S32)108*437bfbebSnyanmisaka MPP_CFG_ACCESS(s32, RK_S32)
109*437bfbebSnyanmisaka MPP_CFG_ACCESS(u32, RK_U32)
110*437bfbebSnyanmisaka MPP_CFG_ACCESS(s64, RK_S64)
111*437bfbebSnyanmisaka MPP_CFG_ACCESS(u64, RK_U64)
112*437bfbebSnyanmisaka MPP_CFG_ACCESS(ptr, void *)
113*437bfbebSnyanmisaka 
114*437bfbebSnyanmisaka MPP_RET mpp_cfg_set_st(MppCfgInfo *info, void *cfg, void *val)
115*437bfbebSnyanmisaka {
116*437bfbebSnyanmisaka     return mpp_cfg_set(info, cfg, val);
117*437bfbebSnyanmisaka }
118*437bfbebSnyanmisaka 
mpp_cfg_get_st(MppCfgInfo * info,void * cfg,void * val)119*437bfbebSnyanmisaka MPP_RET mpp_cfg_get_st(MppCfgInfo *info, void *cfg, void *val)
120*437bfbebSnyanmisaka {
121*437bfbebSnyanmisaka     return mpp_cfg_get(info, cfg, val);
122*437bfbebSnyanmisaka }
123*437bfbebSnyanmisaka 
check_cfg_info(MppCfgInfo * node,const char * name,CfgType type,const char * func)124*437bfbebSnyanmisaka MPP_RET check_cfg_info(MppCfgInfo *node, const char *name, CfgType type,
125*437bfbebSnyanmisaka                        const char *func)
126*437bfbebSnyanmisaka {
127*437bfbebSnyanmisaka     if (NULL == node) {
128*437bfbebSnyanmisaka         mpp_err("%s: cfg %s is invalid\n", func, name);
129*437bfbebSnyanmisaka         return MPP_NOK;
130*437bfbebSnyanmisaka     }
131*437bfbebSnyanmisaka 
132*437bfbebSnyanmisaka     CfgType cfg_type = (CfgType)node->data_type;
133*437bfbebSnyanmisaka     RK_S32 cfg_size = node->data_size;
134*437bfbebSnyanmisaka     MPP_RET ret = MPP_OK;
135*437bfbebSnyanmisaka 
136*437bfbebSnyanmisaka     switch (type) {
137*437bfbebSnyanmisaka     case CFG_FUNC_TYPE_st : {
138*437bfbebSnyanmisaka         if (cfg_type != type) {
139*437bfbebSnyanmisaka             show_cfg_info_err(node, type, func, name);
140*437bfbebSnyanmisaka             ret = MPP_NOK;
141*437bfbebSnyanmisaka         }
142*437bfbebSnyanmisaka         if (cfg_size <= 0) {
143*437bfbebSnyanmisaka             mpp_err("%s: cfg %s found invalid size %d\n", func, name, cfg_size);
144*437bfbebSnyanmisaka             ret = MPP_NOK;
145*437bfbebSnyanmisaka         }
146*437bfbebSnyanmisaka     } break;
147*437bfbebSnyanmisaka     case CFG_FUNC_TYPE_ptr : {
148*437bfbebSnyanmisaka         if (cfg_type != type) {
149*437bfbebSnyanmisaka             show_cfg_info_err(node, type, func, name);
150*437bfbebSnyanmisaka             ret = MPP_NOK;
151*437bfbebSnyanmisaka         }
152*437bfbebSnyanmisaka     } break;
153*437bfbebSnyanmisaka     case CFG_FUNC_TYPE_s32 :
154*437bfbebSnyanmisaka     case CFG_FUNC_TYPE_u32 : {
155*437bfbebSnyanmisaka         if (cfg_size != sizeof(RK_S32)) {
156*437bfbebSnyanmisaka             show_cfg_info_err(node, type, func, name);
157*437bfbebSnyanmisaka             ret = MPP_NOK;
158*437bfbebSnyanmisaka         }
159*437bfbebSnyanmisaka     } break;
160*437bfbebSnyanmisaka     case CFG_FUNC_TYPE_s64 :
161*437bfbebSnyanmisaka     case CFG_FUNC_TYPE_u64 : {
162*437bfbebSnyanmisaka         if (cfg_size != sizeof(RK_S64)) {
163*437bfbebSnyanmisaka             show_cfg_info_err(node, type, func, name);
164*437bfbebSnyanmisaka             ret = MPP_NOK;
165*437bfbebSnyanmisaka         }
166*437bfbebSnyanmisaka     } break;
167*437bfbebSnyanmisaka     default : {
168*437bfbebSnyanmisaka         mpp_err("%s: cfg %s found invalid cfg type %d\n", func, name, type);
169*437bfbebSnyanmisaka         ret = MPP_NOK;
170*437bfbebSnyanmisaka     } break;
171*437bfbebSnyanmisaka     }
172*437bfbebSnyanmisaka 
173*437bfbebSnyanmisaka     return ret;
174*437bfbebSnyanmisaka }
175