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