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