/* SPDX-License-Identifier: Apache-2.0 OR MIT */ /* * Copyright (c) 2020 Rockchip Electronics Co., Ltd. */ #define MODULE_TAG "mpp_cfg" #include #include "mpp_env.h" #include "mpp_cfg.h" #include "mpp_debug.h" #define MPP_CFG_DBG_SET (0x00000001) #define MPP_CFG_DBG_GET (0x00000002) #define mpp_cfg_dbg(flag, fmt, ...) _mpp_dbg(mpp_cfg_debug, flag, fmt, ## __VA_ARGS__) #define mpp_cfg_dbg_set(fmt, ...) mpp_cfg_dbg(MPP_CFG_DBG_SET, fmt, ## __VA_ARGS__) #define mpp_cfg_dbg_get(fmt, ...) mpp_cfg_dbg(MPP_CFG_DBG_GET, fmt, ## __VA_ARGS__) #define CFG_TO_PTR(info, cfg) ((char *)cfg + info->data_offset) #define CFG_TO_s32_PTR(info, cfg) ((RK_S32 *)CFG_TO_PTR(info, cfg)) #define CFG_TO_u32_PTR(info, cfg) ((RK_U32 *)CFG_TO_PTR(info, cfg)) #define CFG_TO_s64_PTR(info, cfg) ((RK_S64 *)CFG_TO_PTR(info, cfg)) #define CFG_TO_u64_PTR(info, cfg) ((RK_U64 *)CFG_TO_PTR(info, cfg)) #define CFG_TO_ptr_PTR(info, cfg) ((void **)CFG_TO_PTR(info, cfg)) /* 32bit unsigned long pointer */ #define ELEM_FLAG_U32_POS(offset) (((offset) & (~31)) / 8) #define ELEM_FLAG_BIT_POS(offset) ((offset) & 31) #define CFG_TO_FLAG_PTR(info, cfg) ((rk_ul *)((rk_u8 *)cfg + ELEM_FLAG_U32_POS(info->flag_offset))) #define CFG_SET_FLAG(info, cfg) \ *CFG_TO_FLAG_PTR(info, cfg) |= 1ul << (ELEM_FLAG_BIT_POS(info->flag_offset)) static RK_U32 mpp_cfg_debug = 0; const char *strof_cfg_type(CfgType type) { static const char *cfg_type_names[] = { "RK_S32", "RK_U32", "RK_S64", "RK_U64", "struct", "void *", "unknown" }; if (type < 0 || type >= CFG_FUNC_TYPE_BUTT) type = CFG_FUNC_TYPE_BUTT; return cfg_type_names[type]; } static void show_cfg_info_err(MppCfgInfo *node, CfgType type, const char *func, const char *name) { mpp_err("%s cfg %s expect %s input NOT %s\n", func, name, strof_cfg_type(node->data_type), strof_cfg_type(type)); } static MPP_RET mpp_cfg_set(MppCfgInfo *info, void *cfg, void *val) { if (memcmp((char *)cfg + info->data_offset, val, info->data_size)) { memcpy((char *)cfg + info->data_offset, val, info->data_size); CFG_SET_FLAG(info, cfg); } return MPP_OK; } static MPP_RET mpp_cfg_get(MppCfgInfo *info, void *cfg, void *val) { memcpy(val, (char *)cfg + info->data_offset, info->data_size); return MPP_OK; } #define MPP_CFG_ACCESS(type, base_type) \ MPP_RET mpp_cfg_set_##type(MppCfgInfo *info, void *cfg, base_type val) \ { \ base_type *dst = CFG_TO_##type##_PTR(info, cfg); \ base_type old = dst[0]; \ dst[0] = val; \ if (!info->flag_offset) { \ mpp_cfg_dbg_set("%p + %d set " #type " change %d -> %d\n", cfg, info->data_offset, old, val); \ } else { \ if (old != val) { \ mpp_cfg_dbg_set("%p + %d set " #type " update %d -> %d flag %d\n", \ cfg, info->data_offset, old, val, info->flag_offset); \ CFG_SET_FLAG(info, cfg); \ } else { \ mpp_cfg_dbg_set("%p + %d set " #type " keep %d\n", cfg, info->data_offset, old); \ } \ } \ return MPP_OK; \ } \ MPP_RET mpp_cfg_get_##type(MppCfgInfo *info, void *cfg, base_type *val) \ { \ if (info && info->data_size) { \ base_type *src = CFG_TO_##type##_PTR(info, cfg); \ mpp_cfg_dbg_set("%p + %d get " #type " value %d\n", cfg, info->data_offset, src[0]); \ val[0] = src[0]; \ return MPP_OK; \ } \ return MPP_NOK; \ } MPP_CFG_ACCESS(s32, RK_S32) MPP_CFG_ACCESS(u32, RK_U32) MPP_CFG_ACCESS(s64, RK_S64) MPP_CFG_ACCESS(u64, RK_U64) MPP_CFG_ACCESS(ptr, void *) MPP_RET mpp_cfg_set_st(MppCfgInfo *info, void *cfg, void *val) { return mpp_cfg_set(info, cfg, val); } MPP_RET mpp_cfg_get_st(MppCfgInfo *info, void *cfg, void *val) { return mpp_cfg_get(info, cfg, val); } MPP_RET check_cfg_info(MppCfgInfo *node, const char *name, CfgType type, const char *func) { if (NULL == node) { mpp_err("%s: cfg %s is invalid\n", func, name); return MPP_NOK; } CfgType cfg_type = (CfgType)node->data_type; RK_S32 cfg_size = node->data_size; MPP_RET ret = MPP_OK; switch (type) { case CFG_FUNC_TYPE_st : { if (cfg_type != type) { show_cfg_info_err(node, type, func, name); ret = MPP_NOK; } if (cfg_size <= 0) { mpp_err("%s: cfg %s found invalid size %d\n", func, name, cfg_size); ret = MPP_NOK; } } break; case CFG_FUNC_TYPE_ptr : { if (cfg_type != type) { show_cfg_info_err(node, type, func, name); ret = MPP_NOK; } } break; case CFG_FUNC_TYPE_s32 : case CFG_FUNC_TYPE_u32 : { if (cfg_size != sizeof(RK_S32)) { show_cfg_info_err(node, type, func, name); ret = MPP_NOK; } } break; case CFG_FUNC_TYPE_s64 : case CFG_FUNC_TYPE_u64 : { if (cfg_size != sizeof(RK_S64)) { show_cfg_info_err(node, type, func, name); ret = MPP_NOK; } } break; default : { mpp_err("%s: cfg %s found invalid cfg type %d\n", func, name, type); ret = MPP_NOK; } break; } return ret; }