From fe11f99415f708316a06145c85ecbbf4c2ba562c Mon Sep 17 00:00:00 2001 From: Herman Chen Date: Wed, 9 Feb 2022 17:04:32 +0800 Subject: [PATCH] [osal]: Add multi register offset config function Add new multi config mode function. Change-Id: I37c9c319e93e96fbd3d2bb5d598aef8d1b8fe2c8 Signed-off-by: Herman Chen --- osal/driver/mpp_device.c | 73 +++++++++++++++++++++++++++++++++++- osal/driver/mpp_service.c | 40 ++++++++++++++++++++ osal/driver/vcodec_service.c | 1 + osal/inc/mpp_device.h | 16 ++++++++ 4 files changed, 129 insertions(+), 1 deletion(-) diff --git a/osal/driver/mpp_device.c b/osal/driver/mpp_device.c index 02283cbc..4e9f7913 100644 --- a/osal/driver/mpp_device.c +++ b/osal/driver/mpp_device.c @@ -151,6 +151,10 @@ MPP_RET mpp_dev_ioctl(MppDev ctx, RK_S32 cmd, void *param) if (api->reg_offset) ret = api->reg_offset(impl_ctx, param); } break; + case MPP_DEV_REG_OFFS : { + if (api->reg_offs) + ret = api->reg_offs(impl_ctx, param); + } break; case MPP_DEV_RCB_INFO : { if (api->rcb_info) ret = api->rcb_info(impl_ctx, param); @@ -182,7 +186,74 @@ MPP_RET mpp_dev_set_reg_offset(MppDev dev, RK_S32 index, RK_U32 offset) trans_cfg.reg_idx = index; trans_cfg.offset = offset; - mpp_dev_ioctl(dev, MPP_DEV_REG_OFFSET, &trans_cfg); + return mpp_dev_ioctl(dev, MPP_DEV_REG_OFFSET, &trans_cfg); +} + +/* register offset multi config */ +MPP_RET mpp_dev_multi_offset_init(MppDevRegOffCfgs **cfgs, RK_S32 size) +{ + RK_S32 cfg_size = sizeof(MppDevRegOffCfgs) + size * sizeof(MppDevRegOffsetCfg); + MppDevRegOffCfgs *p = NULL; + + if (NULL == cfgs || size <= 0) { + mpp_err_f("invalid pointer %p size %d\n", cfgs, size); + return MPP_NOK; + } + + p = mpp_calloc_size(MppDevRegOffCfgs, cfg_size); + if (p) + p->size = size; + + *cfgs = p; + + return (p) ? MPP_OK : MPP_NOK; +} + +MPP_RET mpp_dev_multi_offset_deinit(MppDevRegOffCfgs *cfgs) +{ + MPP_FREE(cfgs); + + return MPP_OK; +} + +MPP_RET mpp_dev_multi_offset_reset(MppDevRegOffCfgs *cfgs) +{ + if (cfgs) { + memset(cfgs->cfgs, 0, cfgs->count * sizeof(cfgs->cfgs[0])); + cfgs->count = 0; + } + + return MPP_OK; +} + +MPP_RET mpp_dev_multi_offset_update(MppDevRegOffCfgs *cfgs, RK_S32 index, RK_U32 offset) +{ + MppDevRegOffsetCfg *cfg; + RK_S32 count; + RK_S32 i; + + if (NULL == cfgs) + return MPP_NOK; + + if (cfgs->count >= cfgs->size) { + mpp_err_f("invalid cfgs count %d : %d\n", cfgs->count, cfgs->size); + return MPP_NOK; + } + + count = cfgs->count; + cfg = cfgs->cfgs; + + for (i = 0; i < count; i++, cfg++) { + + if (cfg->reg_idx == (RK_U32)index) { + cfg->offset = offset; + return MPP_OK; + } + } + + cfg->reg_idx = index; + cfg->offset = offset; + cfgs->count++; return MPP_OK; } diff --git a/osal/driver/mpp_service.c b/osal/driver/mpp_service.c index 113ff9a9..8e2b3c92 100644 --- a/osal/driver/mpp_service.c +++ b/osal/driver/mpp_service.c @@ -477,6 +477,45 @@ MPP_RET mpp_service_reg_offset(void *ctx, MppDevRegOffsetCfg *cfg) return MPP_OK; } +MPP_RET mpp_service_reg_offsets(void *ctx, MppDevRegOffCfgs *cfgs) +{ + MppDevMppService *p = (MppDevMppService *)ctx; + RegOffsetInfo *info; + RK_S32 i; + + if (cfgs->count <= 0) + return MPP_OK; + + if (p->reg_offset_count >= MAX_REG_OFFSET || + p->reg_offset_count + cfgs->count >= MAX_REG_OFFSET) { + mpp_err_f("reach max offset definition\n", MAX_REG_OFFSET); + return MPP_NOK; + } + + for (i = 0; i < cfgs->count; i++) { + MppDevRegOffsetCfg *cfg = &cfgs->cfgs[i]; + RK_S32 j; + + for (j = 0; j < p->reg_offset_count; j++) { + info = &p->reg_offset_info[p->reg_offset_pos + j]; + + if (info->reg_idx == cfg->reg_idx) { + mpp_err_f("reg[%d] offset has been set, cover old %d -> %d\n", + info->reg_idx, info->offset, cfg->offset); + info->offset = cfg->offset; + continue; + } + } + + info = mpp_service_next_reg_offset(p);; + info->reg_idx = cfg->reg_idx; + info->offset = cfg->offset; + p->reg_offset_count++; + } + + return MPP_OK; +} + MPP_RET mpp_service_rcb_info(void *ctx, MppDevRcbInfoCfg *cfg) { MppDevMppService *p = (MppDevMppService *)ctx; @@ -636,6 +675,7 @@ const MppDevApi mpp_service_api = { mpp_service_reg_wr, mpp_service_reg_rd, mpp_service_reg_offset, + mpp_service_reg_offsets, mpp_service_rcb_info, mpp_service_set_info, mpp_service_cmd_send, diff --git a/osal/driver/vcodec_service.c b/osal/driver/vcodec_service.c index b9479150..ec51c616 100644 --- a/osal/driver/vcodec_service.c +++ b/osal/driver/vcodec_service.c @@ -707,6 +707,7 @@ const MppDevApi vcodec_service_api = { vcodec_service_reg_rd, vcodec_service_fd_trans, NULL, + NULL, vcodec_service_set_info, vcodec_service_cmd_send, vcodec_service_cmd_poll, diff --git a/osal/inc/mpp_device.h b/osal/inc/mpp_device.h index 7685841a..99039ca7 100644 --- a/osal/inc/mpp_device.h +++ b/osal/inc/mpp_device.h @@ -32,6 +32,7 @@ typedef enum MppDevIoctlCmd_e { MPP_DEV_REG_WR, MPP_DEV_REG_RD, MPP_DEV_REG_OFFSET, + MPP_DEV_REG_OFFS, MPP_DEV_RCB_INFO, MPP_DEV_SET_INFO, @@ -61,6 +62,13 @@ typedef struct MppDevRegOffsetCfg_t { RK_U32 offset; } MppDevRegOffsetCfg; +/* for multi MPP_DEV_REG_OFFSET */ +typedef struct MppDevRegOffsCfg_t { + RK_S32 size; + RK_S32 count; + MppDevRegOffsetCfg cfgs[]; +} MppDevRegOffCfgs; + /* for MPP_DEV_RCB_INFO */ typedef struct MppDevRcbInfoCfg_t { RK_U32 reg_idx; @@ -90,6 +98,7 @@ typedef struct MppDevApi_t { MPP_RET (*reg_wr)(void *ctx, MppDevRegWrCfg *cfg); MPP_RET (*reg_rd)(void *ctx, MppDevRegRdCfg *cfg); MPP_RET (*reg_offset)(void *ctx, MppDevRegOffsetCfg *cfg); + MPP_RET (*reg_offs)(void *ctx, MppDevRegOffCfgs *cfg); MPP_RET (*rcb_info)(void *ctx, MppDevRcbInfoCfg *cfg); MPP_RET (*set_info)(void *ctx, MppDevInfoCfg *cfg); @@ -114,6 +123,13 @@ MPP_RET mpp_dev_ioctl(MppDev ctx, RK_S32 cmd, void *param); /* special helper function for large address offset config */ MPP_RET mpp_dev_set_reg_offset(MppDev dev, RK_S32 index, RK_U32 offset); +/* register offset multi config */ +MPP_RET mpp_dev_multi_offset_init(MppDevRegOffCfgs **cfgs, RK_S32 size); +MPP_RET mpp_dev_multi_offset_deinit(MppDevRegOffCfgs *cfgs); + +MPP_RET mpp_dev_multi_offset_reset(MppDevRegOffCfgs *cfgs); +MPP_RET mpp_dev_multi_offset_update(MppDevRegOffCfgs *cfgs, RK_S32 index, RK_U32 offset); + #ifdef __cplusplus } #endif