From ca48923671053821deb6d7d38b8bda83e5c7c4a0 Mon Sep 17 00:00:00 2001 From: Vishalsingh Hajeri Date: Fri, 28 Feb 2020 19:09:34 -0800 Subject: [PATCH] msm: camera: cdm: Enable internal CDM Add support to acquire IFE CDM instead of CPAS CDM. CRs-Fixed: 2571273 Change-Id: Iea3bcf236d00d39bf19e0997e6d21efcd5406a61 Signed-off-by: Jigar Agrawal Signed-off-by: Vishalsingh Hajeri --- drivers/cam_cdm/cam_cdm_hw_core.c | 12 +- drivers/cam_cdm/cam_cdm_intf_api.h | 8 + drivers/cam_isp/cam_isp_context.c | 230 +++-- drivers/cam_isp/cam_isp_context.h | 15 +- drivers/cam_isp/isp_hw_mgr/cam_ife_hw_mgr.c | 852 ++++++++++++------ drivers/cam_isp/isp_hw_mgr/cam_ife_hw_mgr.h | 19 +- drivers/cam_isp/isp_hw_mgr/cam_isp_hw_mgr.h | 3 +- drivers/cam_isp/isp_hw_mgr/cam_tfe_hw_mgr.c | 194 ++-- .../hw_utils/cam_isp_packet_parser.c | 356 ++++++-- .../hw_utils/include/cam_isp_packet_parser.h | 59 +- .../isp_hw_mgr/include/cam_isp_hw_mgr_intf.h | 120 ++- .../isp_hw_mgr/isp_hw/include/cam_isp_hw.h | 3 + .../isp_hw_mgr/isp_hw/vfe_hw/cam_vfe_core.c | 2 + .../isp_hw/vfe_hw/vfe_top/cam_vfe_top_ver2.c | 92 ++ .../isp_hw/vfe_hw/vfe_top/cam_vfe_top_ver3.c | 103 +++ 15 files changed, 1519 insertions(+), 549 deletions(-) diff --git a/drivers/cam_cdm/cam_cdm_hw_core.c b/drivers/cam_cdm/cam_cdm_hw_core.c index e5a8efeb6e..762cb4090a 100644 --- a/drivers/cam_cdm/cam_cdm_hw_core.c +++ b/drivers/cam_cdm/cam_cdm_hw_core.c @@ -1654,8 +1654,7 @@ static int cam_hw_cdm_component_bind(struct device *dev, platform_set_drvdata(pdev, cdm_hw_intf); - snprintf(cdm_name, sizeof(cdm_name), "%s%d", - cdm_hw->soc_info.label_name, cdm_hw->soc_info.index); + snprintf(cdm_name, sizeof(cdm_name), "%s", cdm_hw->soc_info.label_name); rc = cam_smmu_get_handle(cdm_name, &cdm_core->iommu_hdl.non_secure); if (rc < 0) { @@ -1766,6 +1765,15 @@ static int cam_hw_cdm_component_bind(struct device *dev, } cdm_hw->open_count++; + cdm_core->ops = cam_cdm_get_ops(cdm_core->hw_version, NULL, + false); + + if (!cdm_core->ops) { + CAM_ERR(CAM_CDM, "Failed to util ops for hw"); + rc = -EINVAL; + goto deinit; + } + if (!cam_cdm_set_cam_hw_version(cdm_core->hw_version, &cdm_core->version)) { CAM_ERR(CAM_CDM, "Failed to set cam hw version for hw"); diff --git a/drivers/cam_cdm/cam_cdm_intf_api.h b/drivers/cam_cdm/cam_cdm_intf_api.h index 0c9508db41..37f1f1503c 100644 --- a/drivers/cam_cdm/cam_cdm_intf_api.h +++ b/drivers/cam_cdm/cam_cdm_intf_api.h @@ -222,6 +222,14 @@ int cam_cdm_stream_off(uint32_t handle); */ int cam_cdm_reset_hw(uint32_t handle); +/** + * @brief : API to publish CDM ops to HW blocks like IFE + * + * @return : CDM operations + * + */ +struct cam_cdm_utils_ops *cam_cdm_publish_ops(void); + /** * @brief : API to register CDM hw to platform framework. * @return struct platform_device pointer on on success, or ERR_PTR() on error. diff --git a/drivers/cam_isp/cam_isp_context.c b/drivers/cam_isp/cam_isp_context.c index 5f05139af2..cb9e6814b7 100644 --- a/drivers/cam_isp/cam_isp_context.c +++ b/drivers/cam_isp/cam_isp_context.c @@ -314,61 +314,71 @@ static int cam_isp_ctx_dump_req( size_t *offset, bool dump_to_buff) { - int i = 0, rc = 0; + int i, j, rc = 0; size_t len = 0; uint32_t *buf_addr; uint32_t *buf_start, *buf_end; - size_t remain_len = 0; + size_t remain_len = 0; struct cam_cdm_cmd_buf_dump_info dump_info; + uint32_t num_cfg; + struct cam_hw_update_entry *cfg; - for (i = 0; i < req_isp->num_cfg; i++) { - rc = cam_packet_util_get_cmd_mem_addr( - req_isp->cfg[i].handle, &buf_addr, &len); - if (rc) { - CAM_ERR_RATE_LIMIT(CAM_ISP, - "Failed to get_cmd_mem_addr, rc=%d", - rc); - } else { - if (req_isp->cfg[i].offset >= ((uint32_t)len)) { - CAM_ERR(CAM_ISP, - "Invalid offset exp %u actual %u", - req_isp->cfg[i].offset, (uint32_t)len); - return rc; - } - remain_len = len - req_isp->cfg[i].offset; - - if (req_isp->cfg[i].len > - ((uint32_t)remain_len)) { - CAM_ERR(CAM_ISP, - "Invalid len exp %u remain_len %u", - req_isp->cfg[i].len, - (uint32_t)remain_len); - return rc; - } - - buf_start = (uint32_t *)((uint8_t *) buf_addr + - req_isp->cfg[i].offset); - buf_end = (uint32_t *)((uint8_t *) buf_start + - req_isp->cfg[i].len - 1); - if (dump_to_buff) { - if (!cpu_addr || !offset || !buf_len) { - CAM_ERR(CAM_ISP, "Invalid args"); - break; - } - dump_info.src_start = buf_start; - dump_info.src_end = buf_end; - dump_info.dst_start = cpu_addr; - dump_info.dst_offset = *offset; - dump_info.dst_max_size = buf_len; - rc = cam_cdm_util_dump_cmd_bufs_v2(&dump_info); - *offset = dump_info.dst_offset; - if (rc) - return rc; + for (j = 0; j < CAM_IFE_HW_NUM_MAX; j++) { + num_cfg = req_isp->cfg_info[j].num_hw_entries; + cfg = req_isp->cfg_info[j].hw_entries; + for (i = 0; i < num_cfg; i++) { + rc = cam_packet_util_get_cmd_mem_addr( + cfg[i].handle, &buf_addr, &len); + if (rc) { + CAM_ERR_RATE_LIMIT(CAM_ISP, + "Failed to get_cmd_mem_addr, rc=%d", + rc); } else { - cam_cdm_util_dump_cmd_buf(buf_start, buf_end); + if (cfg[i].offset >= ((uint32_t)len)) { + CAM_ERR(CAM_ISP, + "Invalid offset exp %u actual %u", + cfg[i].offset, (uint32_t)len); + return -EINVAL; + } + remain_len = len - cfg[i].offset; + + if (req_isp->cfg_info[j].hw_entries[i].len > + ((uint32_t)remain_len)) { + CAM_ERR(CAM_ISP, + "Invalid len exp %u remain_len %u", + cfg[i].len, + (uint32_t)remain_len); + return -EINVAL; + } + + buf_start = (uint32_t *)((uint8_t *) buf_addr + + cfg[i].offset); + buf_end = (uint32_t *)((uint8_t *) buf_start + + cfg[i].len - 1); + + if (dump_to_buff) { + if (!cpu_addr || !offset || !buf_len) { + CAM_ERR(CAM_ISP, + "Invalid args"); + break; + } + dump_info.src_start = buf_start; + dump_info.src_end = buf_end; + dump_info.dst_start = cpu_addr; + dump_info.dst_offset = *offset; + dump_info.dst_max_size = buf_len; + rc = cam_cdm_util_dump_cmd_bufs_v2( + &dump_info); + *offset = dump_info.dst_offset; + if (rc) + return rc; + } else + cam_cdm_util_dump_cmd_buf(buf_start, + buf_end); } } } + return rc; } @@ -419,13 +429,17 @@ static int __cam_isp_ctx_enqueue_request_in_order( static int __cam_isp_ctx_enqueue_init_request( struct cam_context *ctx, struct cam_ctx_request *req) { - int rc = 0; + int rc = 0, i = 0; struct cam_ctx_request *req_old; struct cam_isp_ctx_req *req_isp_old; struct cam_isp_ctx_req *req_isp_new; struct cam_isp_prepare_hw_update_data *req_update_old; struct cam_isp_prepare_hw_update_data *req_update_new; struct cam_isp_prepare_hw_update_data *hw_update_data; + struct cam_hw_update_entry *cfg_old; + struct cam_hw_update_entry *cfg_new; + uint32_t num_cfg_old; + uint32_t num_cfg_new; spin_lock_bh(&ctx->lock); if (list_empty(&ctx->pending_req_list)) { @@ -441,9 +455,12 @@ static int __cam_isp_ctx_enqueue_init_request( req_isp_new = (struct cam_isp_ctx_req *) req->req_priv; if (req_isp_old->hw_update_data.packet_opcode_type == CAM_ISP_PACKET_INIT_DEV) { - if ((req_isp_old->num_cfg + req_isp_new->num_cfg) >= + if ((req_isp_old->total_num_cfg + req_isp_new->total_num_cfg) >= CAM_ISP_CTX_CFG_MAX) { - CAM_WARN(CAM_ISP, "Can not merge INIT pkt"); + CAM_WARN(CAM_ISP, + "Can not merge INIT pkt total_num_cfgs = %d", + (req_isp_old->total_num_cfg + + req_isp_new->total_num_cfg)); rc = -ENOMEM; } @@ -468,11 +485,19 @@ static int __cam_isp_ctx_enqueue_init_request( req_isp_old->num_fence_map_in = req_isp_new->num_fence_map_in; - memcpy(&req_isp_old->cfg[req_isp_old->num_cfg], - req_isp_new->cfg, - sizeof(req_isp_new->cfg[0])* - req_isp_new->num_cfg); - req_isp_old->num_cfg += req_isp_new->num_cfg; + for (i = 0; i < CAM_IFE_HW_NUM_MAX; i++) { + cfg_old = req_isp_old->cfg_info[i].hw_entries; + cfg_new = req_isp_new->cfg_info[i].hw_entries; + num_cfg_old = + req_isp_old->cfg_info[i].num_hw_entries; + num_cfg_new = + req_isp_old->cfg_info[i].num_hw_entries; + memcpy(&cfg_old[num_cfg_old], + cfg_new, + sizeof(cfg_new[0]) * num_cfg_new); + req_isp_old->cfg_info[i].num_hw_entries + += num_cfg_new; + } memcpy(&req_old->pf_data, &req->pf_data, sizeof(struct cam_hw_mgr_dump_pf_data)); @@ -1049,12 +1074,12 @@ static int __cam_isp_ctx_handle_buf_done_in_activated_state( static int __cam_isp_ctx_apply_req_offline( void *priv, void *data) { - int rc = 0; + int rc = 0, i = 0; struct cam_context *ctx = NULL; struct cam_isp_context *ctx_isp = priv; struct cam_ctx_request *req; struct cam_isp_ctx_req *req_isp; - struct cam_hw_config_args cfg; + struct cam_isp_hw_config_args cfg; if (!ctx_isp) { CAM_ERR(CAM_ISP, "Invalid ctx_isp:%pK", ctx); @@ -1088,8 +1113,12 @@ static int __cam_isp_ctx_apply_req_offline( cfg.ctxt_to_hw_map = ctx_isp->hw_ctx; cfg.request_id = req->request_id; - cfg.hw_update_entries = req_isp->cfg; - cfg.num_hw_update_entries = req_isp->num_cfg; + for (i = 0; i < CAM_IFE_HW_NUM_MAX; i++) { + cfg.hw_update_info[i].num_hw_entries = + req_isp->cfg_info[i].num_hw_entries; + cfg.hw_update_info[i].hw_entries = + req_isp->cfg_info[i].hw_entries; + } cfg.priv = &req_isp->hw_update_data; cfg.init_packet = 0; @@ -2455,13 +2484,13 @@ static int __cam_isp_ctx_apply_req_in_activated_state( struct cam_context *ctx, struct cam_req_mgr_apply_request *apply, enum cam_isp_ctx_activated_substate next_state) { - int rc = 0; + int rc = 0, i; struct cam_ctx_request *req; struct cam_ctx_request *active_req = NULL; struct cam_isp_ctx_req *req_isp; struct cam_isp_ctx_req *active_req_isp; struct cam_isp_context *ctx_isp = NULL; - struct cam_hw_config_args cfg; + struct cam_isp_hw_config_args isp_cfg; if (list_empty(&ctx->pending_req_list)) { CAM_ERR(CAM_ISP, "No available request for Apply id %lld", @@ -2547,15 +2576,22 @@ static int __cam_isp_ctx_apply_req_in_activated_state( } req_isp->bubble_report = apply->report_if_bubble; - cfg.ctxt_to_hw_map = ctx_isp->hw_ctx; - cfg.request_id = req->request_id; - cfg.hw_update_entries = req_isp->cfg; - cfg.num_hw_update_entries = req_isp->num_cfg; - cfg.priv = &req_isp->hw_update_data; - cfg.init_packet = 0; - cfg.reapply = req_isp->reapply; + memset(&isp_cfg, 0, sizeof(isp_cfg)); - rc = ctx->hw_mgr_intf->hw_config(ctx->hw_mgr_intf->hw_mgr_priv, &cfg); + isp_cfg.ctxt_to_hw_map = ctx_isp->hw_ctx; + isp_cfg.request_id = req->request_id; + for (i = 0; i < CAM_IFE_HW_NUM_MAX; i++) { + isp_cfg.hw_update_info[i].num_hw_entries = + req_isp->cfg_info[i].num_hw_entries; + isp_cfg.hw_update_info[i].hw_entries = + req_isp->cfg_info[i].hw_entries; + } + isp_cfg.priv = &req_isp->hw_update_data; + isp_cfg.init_packet = 0; + isp_cfg.reapply = req_isp->reapply; + + rc = ctx->hw_mgr_intf->hw_config(ctx->hw_mgr_intf->hw_mgr_priv, + &isp_cfg); if (rc) { CAM_ERR_RATE_LIMIT(CAM_ISP, "Can not apply the configuration"); } else { @@ -3759,7 +3795,7 @@ static int __cam_isp_ctx_config_dev_in_top_state( struct cam_packet *packet; size_t len = 0; size_t remain_len = 0; - struct cam_hw_prepare_update_args cfg; + struct cam_isp_hw_update_args isp_cfg; struct cam_req_mgr_add_request add_req; struct cam_isp_context *ctx_isp = (struct cam_isp_context *) ctx->ctx_priv; @@ -3840,31 +3876,43 @@ static int __cam_isp_ctx_config_dev_in_top_state( } /* preprocess the configuration */ - memset(&cfg, 0, sizeof(cfg)); - cfg.packet = packet; - cfg.remain_len = remain_len; - cfg.ctxt_to_hw_map = ctx_isp->hw_ctx; - cfg.max_hw_update_entries = CAM_ISP_CTX_CFG_MAX; - cfg.hw_update_entries = req_isp->cfg; - cfg.max_out_map_entries = CAM_ISP_CTX_RES_MAX; - cfg.max_in_map_entries = CAM_ISP_CTX_RES_MAX; - cfg.out_map_entries = req_isp->fence_map_out; - cfg.in_map_entries = req_isp->fence_map_in; - cfg.priv = &req_isp->hw_update_data; - cfg.pf_data = &(req->pf_data); + memset(&isp_cfg, 0, sizeof(isp_cfg)); + + isp_cfg.packet = packet; + isp_cfg.remain_len = remain_len; + isp_cfg.ctxt_to_hw_map = ctx_isp->hw_ctx; + isp_cfg.max_hw_update_entries = CAM_ISP_CTX_CFG_MAX; + isp_cfg.max_out_map_entries = CAM_ISP_CTX_RES_MAX; + isp_cfg.max_in_map_entries = CAM_ISP_CTX_RES_MAX; + isp_cfg.out_map_entries = req_isp->fence_map_out; + isp_cfg.in_map_entries = req_isp->fence_map_in; + isp_cfg.priv = &req_isp->hw_update_data; + isp_cfg.pf_data = &(req->pf_data); + + for (i = 0; i < CAM_IFE_HW_NUM_MAX; i++) + isp_cfg.hw_update_info[i].hw_entries + = req_isp->cfg_info[i].hw_entries; CAM_DBG(CAM_ISP, "try to prepare config packet......"); rc = ctx->hw_mgr_intf->hw_prepare_update( - ctx->hw_mgr_intf->hw_mgr_priv, &cfg); + ctx->hw_mgr_intf->hw_mgr_priv, &isp_cfg); if (rc != 0) { CAM_ERR(CAM_ISP, "Prepare config packet failed in HW layer"); rc = -EFAULT; goto free_req; } - req_isp->num_cfg = cfg.num_hw_update_entries; - req_isp->num_fence_map_out = cfg.num_out_map_entries; - req_isp->num_fence_map_in = cfg.num_in_map_entries; + + req_isp->total_num_cfg = 0; + for (i = 0; i < CAM_IFE_HW_NUM_MAX; i++) { + req_isp->cfg_info[i].num_hw_entries + = isp_cfg.hw_update_info[i].num_hw_entries; + req_isp->total_num_cfg += + req_isp->cfg_info[i].num_hw_entries; + } + + req_isp->num_fence_map_out = isp_cfg.num_out_map_entries; + req_isp->num_fence_map_in = isp_cfg.num_in_map_entries; req_isp->num_acked = 0; req_isp->bubble_detected = false; @@ -3878,7 +3926,7 @@ static int __cam_isp_ctx_config_dev_in_top_state( } CAM_DBG(CAM_ISP, "num_entry: %d, num fence out: %d, num fence in: %d", - req_isp->num_cfg, req_isp->num_fence_map_out, + req_isp->total_num_cfg, req_isp->num_fence_map_out, req_isp->num_fence_map_in); req->request_id = packet->header.request_id; @@ -4604,8 +4652,14 @@ static int __cam_isp_ctx_start_dev_in_ready(struct cam_context *ctx, start_isp.hw_config.ctxt_to_hw_map = ctx_isp->hw_ctx; start_isp.hw_config.request_id = req->request_id; - start_isp.hw_config.hw_update_entries = req_isp->cfg; - start_isp.hw_config.num_hw_update_entries = req_isp->num_cfg; + + for (i = 0; i < CAM_IFE_HW_NUM_MAX; i++) { + start_isp.hw_config.hw_update_info[i].hw_entries + = req_isp->cfg_info[i].hw_entries; + start_isp.hw_config.hw_update_info[i].num_hw_entries = + req_isp->cfg_info[i].num_hw_entries; + } + start_isp.hw_config.priv = &req_isp->hw_update_data; start_isp.hw_config.init_packet = 1; start_isp.hw_config.reapply = 0; diff --git a/drivers/cam_isp/cam_isp_context.h b/drivers/cam_isp/cam_isp_context.h index 2baabe8b24..a05e44221a 100644 --- a/drivers/cam_isp/cam_isp_context.h +++ b/drivers/cam_isp/cam_isp_context.h @@ -26,12 +26,6 @@ */ #define CAM_ISP_CTX_RES_MAX 24 -/* - * Maximum configuration entry size - This is based on the - * worst case DUAL IFE use case plus some margin. - */ -#define CAM_ISP_CTX_CFG_MAX 22 - /* * Maximum entries in state monitoring array for error logging */ @@ -135,8 +129,8 @@ struct cam_isp_ctx_irq_ops { * struct cam_isp_ctx_req - ISP context request object * * @base: Common request object ponter - * @cfg: ISP hardware configuration array - * @num_cfg: Number of ISP hardware configuration entries + * @cfg_info: ISP hardware configuration array + * @total_num_cfg: Number of ISP hardware configuration entries * @fence_map_out: Output fence mapping array * @num_fence_map_out: Number of the output fence map * @fence_map_in: Input fence mapping array @@ -153,9 +147,8 @@ struct cam_isp_ctx_irq_ops { */ struct cam_isp_ctx_req { struct cam_ctx_request *base; - - struct cam_hw_update_entry cfg[CAM_ISP_CTX_CFG_MAX]; - uint32_t num_cfg; + struct cam_isp_hw_update_info cfg_info[CAM_IFE_HW_NUM_MAX]; + uint32_t total_num_cfg; struct cam_hw_fence_map_entry fence_map_out [CAM_ISP_CTX_RES_MAX]; uint32_t num_fence_map_out; diff --git a/drivers/cam_isp/isp_hw_mgr/cam_ife_hw_mgr.c b/drivers/cam_isp/isp_hw_mgr/cam_ife_hw_mgr.c index 7ee21351e5..d1cf9fd3eb 100644 --- a/drivers/cam_isp/isp_hw_mgr/cam_ife_hw_mgr.c +++ b/drivers/cam_isp/isp_hw_mgr/cam_ife_hw_mgr.c @@ -1419,7 +1419,8 @@ static int cam_ife_hw_mgr_acquire_res_ife_src( vfe_acquire.vfe_in.sync_mode = CAM_ISP_HW_SYNC_NONE; break; default: - CAM_ERR(CAM_ISP, "Wrong IFE CSID Resource Node"); + CAM_ERR(CAM_ISP, "Wrong IFE CSID Path Resource ID : %d", + csid_res->res_id); goto err; } ife_src_res->res_type = vfe_acquire.rsrc_type; @@ -1473,7 +1474,7 @@ static int cam_ife_hw_mgr_acquire_res_ife_src( ife_src_res->hw_res[i]->res_id); CAM_DBG(CAM_ISP, - "acquire success IFE:%d res type :0x%x res id:0x%x", + "acquire success IFE:%d res type :0x%x res id:0x%x", hw_intf->hw_idx, ife_src_res->hw_res[i]->res_type, ife_src_res->hw_res[i]->res_id); @@ -1849,6 +1850,17 @@ static int cam_ife_hw_mgr_acquire_res_ife_csid_pxl( cam_ife_hw_mgr_put_res(&ife_ctx->res_list_ife_csid, &csid_res); cid_res->num_children++; + if (is_ipp) { + for (i = 0; i < CAM_IFE_HW_NUM_MAX; i++) { + if (master_idx == i) + ife_ctx->master_slave[i] = CAM_IFE_RES_MASTER; + else + ife_ctx->master_slave[i] = CAM_IFE_RES_SLAVE; + CAM_DBG(CAM_ISP, "hw %d, slave/master %d", + i, ife_ctx->master_slave[i]); + } + } + CAM_DBG(CAM_ISP, "acquire res %d CID children = %d", csid_acquire.res_id, cid_res->num_children); @@ -2590,8 +2602,10 @@ err: void cam_ife_cam_cdm_callback(uint32_t handle, void *userdata, enum cam_cdm_cb_status status, uint64_t cookie) { - struct cam_isp_prepare_hw_update_data *hw_update_data = NULL; - struct cam_ife_hw_mgr_ctx *ctx = NULL; + struct cam_isp_prepare_hw_update_data *hw_update_data = NULL; + struct cam_ife_hw_mgr_ctx *ctx = NULL; + int i; + uint32_t idx = 0; if (!userdata) { CAM_ERR(CAM_ISP, "Invalid args"); @@ -2601,10 +2615,27 @@ void cam_ife_cam_cdm_callback(uint32_t handle, void *userdata, hw_update_data = (struct cam_isp_prepare_hw_update_data *)userdata; ctx = (struct cam_ife_hw_mgr_ctx *)hw_update_data->isp_mgr_ctx; + if (!ctx->internal_cdm) + idx = 0; + else { + for (i = 0; i < ctx->num_base; i++) { + if (ctx->cdm_handle[ctx->base[i].idx] == handle) { + idx = ctx->base[i].idx; + break; + } + } + + if (i == ctx->num_base) { + CAM_ERR(CAM_ISP, "Incorrect CDM handle=0x%x", handle); + return; + } + } + if (status == CAM_CDM_CB_STATUS_BL_SUCCESS) { - complete_all(&ctx->config_done_complete); + complete_all(&ctx->config_done_complete[idx]); atomic_set(&ctx->cdm_done, 1); - if (g_ife_hw_mgr.debug_cfg.per_req_reg_dump) + if ((g_ife_hw_mgr.debug_cfg.per_req_reg_dump) && + (idx == ctx->master_hw_idx)) cam_ife_mgr_handle_reg_dump(ctx, hw_update_data->reg_dump_buf_desc, hw_update_data->num_reg_dump_buf, @@ -2612,11 +2643,11 @@ void cam_ife_cam_cdm_callback(uint32_t handle, void *userdata, NULL, false); CAM_DBG(CAM_ISP, - "Called by CDM hdl=%x, udata=%pK, status=%d, cookie=%llu ctx_index=%d", + "Called by CDM hdl=0x%x, udata=%pK, status=%d, cookie=%llu ctx_index=%d", handle, userdata, status, cookie, ctx->ctx_index); } else { CAM_WARN(CAM_ISP, - "Called by CDM hdl=%x, udata=%pK, status=%d, cookie=%llu", + "Called by CDM hdl=0x%x, udata=%pK, status=%d, cookie=%llu", handle, userdata, status, cookie); } } @@ -2850,7 +2881,7 @@ static int cam_ife_mgr_acquire_hw(void *hw_mgr_priv, void *acquire_hw_args) struct cam_ife_hw_mgr *ife_hw_mgr = hw_mgr_priv; struct cam_hw_acquire_args *acquire_args = acquire_hw_args; int rc = -1; - int i, j; + int i, j = 0, k; struct cam_ife_hw_mgr_ctx *ife_ctx; struct cam_isp_in_port_generic_info *in_port = NULL; struct cam_cdm_acquire_data cdm_acquire; @@ -2862,6 +2893,7 @@ static int cam_ife_mgr_acquire_hw(void *hw_mgr_priv, void *acquire_hw_args) uint32_t total_pd_port = 0; struct cam_isp_acquire_hw_info *acquire_hw_info = NULL; uint32_t input_size = 0; + uint32_t hw_version, idx; CAM_DBG(CAM_ISP, "Enter..."); @@ -2878,39 +2910,15 @@ static int cam_ife_mgr_acquire_hw(void *hw_mgr_priv, void *acquire_hw_args) } ife_ctx->custom_enabled = false; + memset(ife_ctx->cdm_handle, 0, sizeof(ife_ctx->cdm_handle)); + ife_ctx->common.cb_priv = acquire_args->context_data; + ife_ctx->internal_cdm = false; for (i = 0; i < CAM_ISP_HW_EVENT_MAX; i++) ife_ctx->common.event_cb[i] = acquire_args->event_cb; ife_ctx->hw_mgr = ife_hw_mgr; - - - memcpy(cdm_acquire.identifier, "ife", sizeof("ife")); - cdm_acquire.cell_index = 0; - cdm_acquire.handle = 0; - cdm_acquire.userdata = ife_ctx; - cdm_acquire.base_array_cnt = CAM_IFE_HW_NUM_MAX; - for (i = 0, j = 0; i < CAM_IFE_HW_NUM_MAX; i++) { - if (ife_hw_mgr->cdm_reg_map[i]) - cdm_acquire.base_array[j++] = - ife_hw_mgr->cdm_reg_map[i]; - } - - cdm_acquire.base_array_cnt = j; - cdm_acquire.priority = CAM_CDM_BL_FIFO_0; - cdm_acquire.id = CAM_CDM_VIRTUAL; - cdm_acquire.cam_cdm_callback = cam_ife_cam_cdm_callback; - rc = cam_cdm_acquire(&cdm_acquire); - if (rc) { - CAM_ERR(CAM_ISP, "Failed to acquire the CDM HW"); - goto free_ctx; - } - - CAM_DBG(CAM_ISP, "Successfully acquired the CDM HW hdl=%x", - cdm_acquire.handle); - ife_ctx->cdm_handle = cdm_acquire.handle; - ife_ctx->cdm_ops = cdm_acquire.ops; - atomic_set(&ife_ctx->cdm_done, 1); + ife_ctx->cdm_ops = cam_cdm_publish_ops(); acquire_hw_info = (struct cam_isp_acquire_hw_info *)acquire_args->acquire_info; @@ -2986,9 +2994,44 @@ static int cam_ife_mgr_acquire_hw(void *hw_mgr_priv, void *acquire_hw_args) rc = cam_ife_mgr_process_base_info(ife_ctx); if (rc) { CAM_ERR(CAM_ISP, "Process base info failed"); - goto free_res; + goto free_cdm; } + cam_cpas_get_cpas_hw_version(&hw_version); + ife_ctx->hw_version = hw_version; + + for (k = 0; k < ife_ctx->num_base; k++) { + CAM_DBG(CAM_ISP, "Acquire cdm for ife_hw_idx %d", + ife_ctx->base[k].idx); + + memcpy(cdm_acquire.identifier, "ife", sizeof("ife")); + cdm_acquire.cell_index = ife_ctx->base[k].idx; + cdm_acquire.handle = 0; + cdm_acquire.userdata = ife_ctx; + if (ife_hw_mgr->cdm_reg_map[ife_ctx->base[k].idx]) + cdm_acquire.base_array[j++] = + ife_hw_mgr->cdm_reg_map[ife_ctx->base[k].idx]; + cdm_acquire.base_array_cnt = j; + cdm_acquire.priority = CAM_CDM_BL_FIFO_0; + cdm_acquire.id = CAM_CDM_VIRTUAL; + cdm_acquire.cam_cdm_callback = cam_ife_cam_cdm_callback; + rc = cam_cdm_acquire(&cdm_acquire); + if (rc) { + CAM_ERR(CAM_ISP, "Failed to acquire the CDM HW"); + goto free_cdm; + } + + CAM_DBG(CAM_ISP, + "Successfully acquired CDM id=0%d, handle :0x%x", + cdm_acquire.id, cdm_acquire.handle); + if (cdm_acquire.id == CAM_CDM_IFE) + ife_ctx->internal_cdm = true; + ife_ctx->cdm_handle[ife_ctx->base[k].idx] = cdm_acquire.handle; + ife_ctx->base[k].cdm_id = cdm_acquire.id; + } + + atomic_set(&ife_ctx->cdm_done, 1); + acquire_args->ctxt_to_hw_map = ife_ctx; acquire_args->custom_enabled = ife_ctx->custom_enabled; acquire_args->use_frame_header_ts = ife_ctx->use_frame_header_ts; @@ -3009,11 +3052,14 @@ static int cam_ife_mgr_acquire_hw(void *hw_mgr_priv, void *acquire_hw_args) free_mem: kfree(in_port->data); kfree(in_port); +free_cdm: + for (i = 0; i < ife_ctx->num_base; i++) { + idx = ife_ctx->base[i].idx; + if (ife_ctx->cdm_handle[idx] != 0) + cam_cdm_release(ife_ctx->cdm_handle[idx]); + } free_res: cam_ife_hw_mgr_release_hw_for_ctx(ife_ctx); -free_cdm: - cam_cdm_release(ife_ctx->cdm_handle); -free_ctx: cam_ife_hw_mgr_put_ctx(&ife_hw_mgr->free_ctx_list, &ife_ctx); err: CAM_DBG(CAM_ISP, "Exit...(rc=%d)", rc); @@ -3069,7 +3115,7 @@ static int cam_ife_mgr_acquire_dev(void *hw_mgr_priv, void *acquire_hw_args) struct cam_ife_hw_mgr *ife_hw_mgr = hw_mgr_priv; struct cam_hw_acquire_args *acquire_args = acquire_hw_args; int rc = -1; - int i, j; + int i, j = 0, k; struct cam_ife_hw_mgr_ctx *ife_ctx; struct cam_isp_in_port_info *in_port = NULL; struct cam_isp_resource *isp_resource = NULL; @@ -3082,6 +3128,7 @@ static int cam_ife_mgr_acquire_dev(void *hw_mgr_priv, void *acquire_hw_args) uint32_t total_pix_port = 0; uint32_t total_rdi_port = 0; uint32_t in_port_length = 0; + uint32_t hw_version, idx; CAM_DBG(CAM_ISP, "Enter..."); @@ -3097,39 +3144,15 @@ static int cam_ife_mgr_acquire_dev(void *hw_mgr_priv, void *acquire_hw_args) goto err; } + memset(ife_ctx->cdm_handle, 0, sizeof(ife_ctx->cdm_handle)); + ife_ctx->common.cb_priv = acquire_args->context_data; for (i = 0; i < CAM_ISP_HW_EVENT_MAX; i++) ife_ctx->common.event_cb[i] = acquire_args->event_cb; ife_ctx->hw_mgr = ife_hw_mgr; - - memcpy(cdm_acquire.identifier, "ife", sizeof("ife")); - cdm_acquire.cell_index = 0; - cdm_acquire.handle = 0; - cdm_acquire.userdata = ife_ctx; - cdm_acquire.base_array_cnt = CAM_IFE_HW_NUM_MAX; - for (i = 0, j = 0; i < CAM_IFE_HW_NUM_MAX; i++) { - if (ife_hw_mgr->cdm_reg_map[i]) - cdm_acquire.base_array[j++] = - ife_hw_mgr->cdm_reg_map[i]; - } - - cdm_acquire.base_array_cnt = j; - cdm_acquire.priority = CAM_CDM_BL_FIFO_0; - cdm_acquire.id = CAM_CDM_VIRTUAL; - cdm_acquire.cam_cdm_callback = cam_ife_cam_cdm_callback; - rc = cam_cdm_acquire(&cdm_acquire); - if (rc) { - CAM_ERR(CAM_ISP, "Failed to acquire the CDM HW"); - goto free_ctx; - } - - CAM_DBG(CAM_ISP, "Successfully acquired the CDM HW hdl=%x", - cdm_acquire.handle); - ife_ctx->cdm_handle = cdm_acquire.handle; - ife_ctx->cdm_ops = cdm_acquire.ops; - atomic_set(&ife_ctx->cdm_done, 1); + ife_ctx->cdm_ops = cam_cdm_publish_ops(); isp_resource = (struct cam_isp_resource *)acquire_args->acquire_info; @@ -3240,6 +3263,40 @@ static int cam_ife_mgr_acquire_dev(void *hw_mgr_priv, void *acquire_hw_args) goto free_res; } + cam_cpas_get_cpas_hw_version(&hw_version); + + ife_ctx->hw_version = hw_version; + + for (k = 0; k < ife_ctx->num_base; k++) { + CAM_DBG(CAM_ISP, "Acquire cdm for ife_hw_idx %d", k); + + memcpy(cdm_acquire.identifier, "ife", sizeof("ife")); + cdm_acquire.cell_index = ife_ctx->base[k].idx; + cdm_acquire.handle = 0; + cdm_acquire.userdata = ife_ctx; + if (ife_hw_mgr->cdm_reg_map[ife_ctx->base[k].idx]) + cdm_acquire.base_array[j++] = + ife_hw_mgr->cdm_reg_map[ife_ctx->base[k].idx]; + cdm_acquire.base_array_cnt = j; + cdm_acquire.priority = CAM_CDM_BL_FIFO_0; + cdm_acquire.id = CAM_CDM_VIRTUAL; + cdm_acquire.cam_cdm_callback = cam_ife_cam_cdm_callback; + rc = cam_cdm_acquire(&cdm_acquire); + if (rc) { + CAM_ERR(CAM_ISP, "Failed to acquire the CDM HW"); + goto free_res; + } + + CAM_DBG(CAM_ISP, "Successfully acquired the CDM HW hdl=0x%x", + cdm_acquire.handle); + + if (cdm_acquire.id == CAM_CDM_IFE) + ife_ctx->internal_cdm = true; + ife_ctx->cdm_handle[ife_ctx->base[k].idx] = cdm_acquire.handle; + } + + atomic_set(&ife_ctx->cdm_done, 1); + acquire_args->ctxt_to_hw_map = ife_ctx; ife_ctx->ctx_in_use = 1; ife_ctx->num_reg_dump_buf = 0; @@ -3252,8 +3309,11 @@ static int cam_ife_mgr_acquire_dev(void *hw_mgr_priv, void *acquire_hw_args) return 0; free_res: cam_ife_hw_mgr_release_hw_for_ctx(ife_ctx); - cam_cdm_release(ife_ctx->cdm_handle); -free_ctx: + for (i = 0; i < ife_ctx->num_base; i++) { + idx = ife_ctx->base[i].idx; + if (ife_ctx->cdm_handle[idx] != 0) + cam_cdm_release(ife_ctx->cdm_handle[idx]); + } cam_ife_hw_mgr_put_ctx(&ife_hw_mgr->free_ctx_list, &ife_ctx); err: CAM_DBG(CAM_ISP, "Exit...(rc=%d)", rc); @@ -3556,17 +3616,197 @@ static int cam_isp_blob_bw_update( return rc; } +static int cam_ife_config_hw_internal_cdm(struct cam_ife_hw_mgr_ctx *ctx, + struct cam_isp_hw_config_args *cfg, + struct cam_isp_prepare_hw_update_data *hw_update_data) +{ + int rc = -1, i, j, skip = 0; + struct cam_hw_update_entry *cmd; + struct cam_cdm_bl_request *cdm_cmd; + uint32_t num_ent; + struct cam_hw_update_entry *cfg_info; + unsigned long rem_jiffies = 0; + uint32_t idx; + + if (ctx->num_base >= CAM_IFE_HW_NUM_MAX) { + CAM_ERR(CAM_ISP, + "Invalid number of IFE acquired = %d", + ctx->num_base); + return -EINVAL; + } + + for (i = 0; i < ctx->num_base; i++) { + idx = ctx->base[i].idx; + num_ent = cfg->hw_update_info[idx].num_hw_entries; + cfg_info = cfg->hw_update_info[idx].hw_entries; + if (num_ent > 0) { + cdm_cmd = ctx->cdm_cmd; + cdm_cmd->type = CAM_CDM_BL_CMD_TYPE_MEM_HANDLE; + cdm_cmd->flag = true; + cdm_cmd->userdata = hw_update_data; + cdm_cmd->cookie = cfg->request_id; + cdm_cmd->gen_irq_arb = false; + skip = 0; + + for (j = 0 ; j < num_ent; j++) { + cmd = (cfg_info + j); + + if (cfg->reapply && + cmd->flags == CAM_ISP_IQ_BL) { + skip++; + continue; + } + + if (cmd->flags == CAM_ISP_UNUSED_BL || + cmd->flags >= CAM_ISP_BL_MAX) + CAM_ERR(CAM_ISP, + "Unexpected BL type %d", + cmd->flags); + + cdm_cmd->cmd[j - skip].bl_addr.mem_handle = + cmd->handle; + cdm_cmd->cmd[j - skip].offset = cmd->offset; + cdm_cmd->cmd[j - skip].len = cmd->len; + cdm_cmd->cmd[j - skip].arbitrate = false; + } + cdm_cmd->cmd_arrary_count = num_ent - skip; + + reinit_completion(&ctx->config_done_complete[idx]); + ctx->applied_req_id = cfg->request_id; + + CAM_DBG(CAM_ISP, "Submit to CDM for IFE idx = %d", + ctx->base[i].idx); + atomic_set(&ctx->cdm_done, 0); + rc = cam_cdm_submit_bls(ctx->cdm_handle[idx], cdm_cmd); + if (rc) { + CAM_ERR(CAM_ISP, + "Failed to apply the configs for req %llu, rc %d", + cfg->request_id, rc); + return rc; + } + } + } + + for (i = 0; i < ctx->num_base; i++) { + idx = ctx->base[i].idx; + if (cfg->init_packet) { + rem_jiffies = wait_for_completion_timeout( + &ctx->config_done_complete[idx], + msecs_to_jiffies(30)); + if (rem_jiffies == 0) { + CAM_ERR(CAM_ISP, + "config done completion timeout for req_id=%llu ctx_index %d IFE:%d", + cfg->request_id, + ctx->ctx_index, idx); + rc = -ETIMEDOUT; + } else + CAM_DBG(CAM_ISP, + "config done Success for req_id=%llu ctx_index %d IFE:%d", + cfg->request_id, + ctx->ctx_index, idx); + } + } + + return rc; +} + +static int cam_ife_config_hw_external_cdm(struct cam_ife_hw_mgr_ctx *ctx, + struct cam_isp_hw_config_args *cfg, + struct cam_isp_prepare_hw_update_data *hw_update_data) +{ + int rc = -1, i, j, k = 0, skip = 0; + struct cam_hw_update_entry *cmd; + struct cam_cdm_bl_request *cdm_cmd; + uint32_t num_ent; + struct cam_hw_update_entry *cfg_info; + unsigned long rem_jiffies = 0; + + if (ctx->num_base >= CAM_IFE_HW_NUM_MAX) { + CAM_ERR(CAM_ISP, + "Invalid number of IFE acquired = %d", + ctx->num_base); + return -EINVAL; + } + + cdm_cmd = ctx->cdm_cmd; + cdm_cmd->type = CAM_CDM_BL_CMD_TYPE_MEM_HANDLE; + cdm_cmd->flag = true; + cdm_cmd->userdata = hw_update_data; + cdm_cmd->cookie = cfg->request_id; + cdm_cmd->gen_irq_arb = false; + cdm_cmd->cmd_arrary_count = 0; + + for (i = 0; i < ctx->num_base; i++) { + num_ent = cfg->hw_update_info[ctx->base[i].idx].num_hw_entries; + cfg_info = cfg->hw_update_info[ctx->base[i].idx].hw_entries; + if (num_ent > 0) { + for (j = 0 ; j < num_ent; j++) { + cmd = (cfg_info + j); + + if (cfg->reapply && + cmd->flags == CAM_ISP_IQ_BL) { + skip++; + continue; + } + + if (cmd->flags == CAM_ISP_UNUSED_BL || + cmd->flags >= CAM_ISP_BL_MAX) + CAM_ERR(CAM_ISP, + "Unexpected BL type %d", + cmd->flags); + + cdm_cmd->cmd[j - skip + k].bl_addr.mem_handle = + cmd->handle; + cdm_cmd->cmd[j - skip + k].offset = cmd->offset; + cdm_cmd->cmd[j - skip + k].len = cmd->len; + cdm_cmd->cmd[j - skip + k].arbitrate = false; + } + cdm_cmd->cmd_arrary_count += num_ent - skip; + k = cdm_cmd->cmd_arrary_count; + } + } + + ctx->applied_req_id = cfg->request_id; + CAM_DBG(CAM_ISP, "Submit to CDM for IFE idx = %d", + ctx->base[i].idx); + atomic_set(&ctx->cdm_done, 0); + reinit_completion(&ctx->config_done_complete[0]); + rc = cam_cdm_submit_bls(ctx->cdm_handle[ctx->base[0].idx], cdm_cmd); + if (rc) { + CAM_ERR(CAM_ISP, + "Failed to apply the configs for req %llu, rc %d", + cfg->request_id, rc); + return rc; + } + + if (cfg->init_packet) { + rem_jiffies = wait_for_completion_timeout( + &ctx->config_done_complete[0], + msecs_to_jiffies(30)); + if (rem_jiffies == 0) { + CAM_ERR(CAM_ISP, + "config done completion timeout for req_id=%llu ctx_index %d IFE:%d", + cfg->request_id, + ctx->ctx_index, ctx->base[0].idx); + rc = -ETIMEDOUT; + } else + CAM_DBG(CAM_ISP, + "config done Success for req_id=%llu ctx_index %d IFE:%d", + cfg->request_id, + ctx->ctx_index, ctx->base[0].idx); + } + + return rc; +} + /* entry function: config_hw */ static int cam_ife_mgr_config_hw(void *hw_mgr_priv, void *config_hw_args) { - int rc = -1, i, skip = 0; - struct cam_hw_config_args *cfg; - struct cam_hw_update_entry *cmd; - struct cam_cdm_bl_request *cdm_cmd; + int rc = -1, i, idx; + struct cam_isp_hw_config_args *cfg; struct cam_ife_hw_mgr_ctx *ctx; struct cam_isp_prepare_hw_update_data *hw_update_data; - unsigned long rem_jiffies = 0; if (!hw_mgr_priv || !config_hw_args) { CAM_ERR(CAM_ISP, @@ -3602,18 +3842,18 @@ static int cam_ife_mgr_config_hw(void *hw_mgr_priv, CAM_DBG(CAM_ISP, "Ctx[%pK][%d] : Applying Req %lld, init_packet=%d", ctx, ctx->ctx_index, cfg->request_id, cfg->init_packet); - for (i = 0; i < CAM_IFE_HW_NUM_MAX; i++) { - if (hw_update_data->bw_config_valid[i] == true) { + for (i = 0; i < ctx->num_base; i++) { + idx = ctx->base[i].idx; + if (hw_update_data->bw_config_valid[idx] == true) { CAM_DBG(CAM_PERF, "idx=%d, bw_config_version=%d", - ctx, ctx->ctx_index, i, - hw_update_data->bw_config_version); + idx, hw_update_data->bw_config_version); if (hw_update_data->bw_config_version == CAM_ISP_BW_CONFIG_V1) { rc = cam_isp_blob_bw_update( (struct cam_isp_bw_config *) - &hw_update_data->bw_config[i], ctx); + &hw_update_data->bw_config[idx], ctx); if (rc) CAM_ERR(CAM_PERF, "Bandwidth Update Failed rc: %d", rc); @@ -3621,7 +3861,8 @@ static int cam_ife_mgr_config_hw(void *hw_mgr_priv, CAM_ISP_BW_CONFIG_V2) { rc = cam_isp_blob_bw_update_v2( (struct cam_isp_bw_config_v2 *) - &hw_update_data->bw_config_v2[i], ctx); + &hw_update_data->bw_config_v2[idx], + ctx); if (rc) CAM_ERR(CAM_PERF, "Bandwidth Update Failed rc: %d", rc); @@ -3635,68 +3876,19 @@ static int cam_ife_mgr_config_hw(void *hw_mgr_priv, } CAM_DBG(CAM_ISP, - "Enter ctx id:%d num_hw_upd_entries %d request id: %llu", - ctx->ctx_index, cfg->num_hw_update_entries, cfg->request_id); + "Enter ctx id:%d request id: %llu", ctx->ctx_index, + cfg->request_id); - if (cfg->num_hw_update_entries > 0) { - cdm_cmd = ctx->cdm_cmd; - cdm_cmd->type = CAM_CDM_BL_CMD_TYPE_MEM_HANDLE; - cdm_cmd->flag = true; - cdm_cmd->userdata = hw_update_data; - cdm_cmd->cookie = cfg->request_id; - cdm_cmd->gen_irq_arb = false; + if (ctx->internal_cdm) + rc = cam_ife_config_hw_internal_cdm(ctx, cfg, hw_update_data); + else + rc = cam_ife_config_hw_external_cdm(ctx, cfg, hw_update_data); - for (i = 0 ; i < cfg->num_hw_update_entries; i++) { - cmd = (cfg->hw_update_entries + i); - - if (cfg->reapply && - cmd->flags == CAM_ISP_IQ_BL) { - skip++; - continue; - } - - if (cmd->flags == CAM_ISP_UNUSED_BL || - cmd->flags >= CAM_ISP_BL_MAX) - CAM_ERR(CAM_ISP, "Unexpected BL type %d", - cmd->flags); - - cdm_cmd->cmd[i - skip].bl_addr.mem_handle = cmd->handle; - cdm_cmd->cmd[i - skip].offset = cmd->offset; - cdm_cmd->cmd[i - skip].len = cmd->len; - cdm_cmd->cmd[i - skip].arbitrate = false; - } - cdm_cmd->cmd_arrary_count = cfg->num_hw_update_entries - skip; - - reinit_completion(&ctx->config_done_complete); - ctx->applied_req_id = cfg->request_id; - - CAM_DBG(CAM_ISP, "Submit to CDM"); - atomic_set(&ctx->cdm_done, 0); - rc = cam_cdm_submit_bls(ctx->cdm_handle, cdm_cmd); - if (rc) { - CAM_ERR(CAM_ISP, - "Failed to apply the configs for req %llu, rc %d", - cfg->request_id, rc); - return rc; - } - - if (cfg->init_packet) { - rem_jiffies = wait_for_completion_timeout( - &ctx->config_done_complete, - msecs_to_jiffies(30)); - if (rem_jiffies == 0) { - CAM_ERR(CAM_ISP, - "config done completion timeout for req_id=%llu ctx_index %d", - cfg->request_id, ctx->ctx_index); - rc = -ETIMEDOUT; - } else - CAM_DBG(CAM_ISP, - "config done Success for req_id=%llu ctx_index %d", - cfg->request_id, ctx->ctx_index); - } - } else { - CAM_ERR(CAM_ISP, "No commands to config"); + if (rc) { + CAM_ERR(CAM_ISP, "Config HW failure"); + return rc; } + CAM_DBG(CAM_ISP, "Exit: Config Done: %llu", cfg->request_id); return rc; @@ -3841,6 +4033,7 @@ static int cam_ife_mgr_stop_hw(void *hw_mgr_priv, void *stop_hw_args) enum cam_ife_csid_halt_cmd csid_halt_type; uint32_t i, master_base_idx = 0; unsigned long rem_jiffies = 0; + uint32_t idx; if (!hw_mgr_priv || !stop_hw_args) { CAM_ERR(CAM_ISP, "Invalid arguments"); @@ -3941,18 +4134,40 @@ static int cam_ife_mgr_stop_hw(void *hw_mgr_priv, void *stop_hw_args) cam_ife_mgr_pause_hw(ctx); - rem_jiffies = wait_for_completion_timeout(&ctx->config_done_complete, - msecs_to_jiffies(10)); - if (rem_jiffies == 0) - CAM_WARN(CAM_ISP, - "config done completion timeout for last applied req_id=%llu rc=%d ctx_index %d", - ctx->applied_req_id, rc, ctx->ctx_index); + if (ctx->internal_cdm) { + for (i = 0; i < ctx->num_base; i++) { + idx = ctx->base[i].idx; + rem_jiffies = wait_for_completion_timeout( + &ctx->config_done_complete[idx], + msecs_to_jiffies(5)); + if (rem_jiffies == 0) + CAM_WARN(CAM_ISP, + "config done completion timeout for last applied req_id=%llu ctx_index %d IFE:%d", + ctx->applied_req_id, ctx->ctx_index, + idx); + } + } else { + rem_jiffies = wait_for_completion_timeout( + &ctx->config_done_complete[0], + msecs_to_jiffies(5)); + if (rem_jiffies == 0) + CAM_WARN(CAM_ISP, + "config done completion timeout for last applied req_id=%llu ctx_index %d IFE:%d", + ctx->applied_req_id, ctx->ctx_index, + ctx->master_hw_idx); + } if (stop_isp->stop_only) goto end; - if (cam_cdm_stream_off(ctx->cdm_handle)) - CAM_ERR(CAM_ISP, "CDM stream off failed %d", ctx->cdm_handle); + for (i = 0; i < ctx->num_base; i++) { + idx = ctx->base[i].idx; + if (ctx->cdm_handle[idx] != 0) { + if (cam_cdm_stream_off(ctx->cdm_handle[idx])) + CAM_ERR(CAM_ISP, "CDM stream off failed %d", + ctx->cdm_handle[i]); + } + } if (ctx->is_tpg) cam_ife_hw_mgr_stop_hw_res(&ctx->res_list_tpg); @@ -4121,7 +4336,7 @@ static int cam_ife_mgr_start_hw(void *hw_mgr_priv, void *start_hw_args) struct cam_ife_hw_mgr_ctx *ctx; struct cam_isp_hw_mgr_res *hw_mgr_res; struct cam_isp_resource_node *rsrc_node = NULL; - uint32_t i, camif_debug; + uint32_t i, camif_debug, idx; bool res_rdi_context_set = false; uint32_t primary_rdi_src_res; uint32_t primary_rdi_out_res; @@ -4215,12 +4430,16 @@ static int cam_ife_mgr_start_hw(void *hw_mgr_priv, void *start_hw_args) } mutex_unlock(&g_ife_hw_mgr.ctx_mutex); - CAM_DBG(CAM_ISP, "start cdm interface"); - rc = cam_cdm_stream_on(ctx->cdm_handle); - if (rc) { - CAM_ERR(CAM_ISP, "Can not start cdm (%d)", - ctx->cdm_handle); - goto safe_disable; + for (i = 0; i < ctx->num_base; i++) { + idx = ctx->base[i].idx; + if (ctx->cdm_handle[idx] != 0) { + rc = cam_cdm_stream_on(ctx->cdm_handle[idx]); + if (rc) { + CAM_ERR(CAM_ISP, "Can not start cdm (%d)", + ctx->cdm_handle); + goto safe_disable; + } + } } start_only: @@ -4348,8 +4567,10 @@ err: return rc; cdm_streamoff: - cam_cdm_stream_off(ctx->cdm_handle); - + for (i = 0; i < ctx->num_base; i++) { + if (ctx->cdm_handle[ctx->base[i].idx] != 0) + cam_cdm_stream_off(ctx->cdm_handle[ctx->base[i].idx]); + } safe_disable: cam_ife_notify_safe_lut_scm(CAM_IFE_SAFE_DISABLE); @@ -4448,13 +4669,16 @@ static int cam_ife_mgr_release_hw(void *hw_mgr_priv, memset(ctx->base, 0, sizeof(ctx->base)); /* release cdm handle */ - cam_cdm_release(ctx->cdm_handle); + for (i = 0; i < CAM_IFE_HW_NUM_MAX; i++) { + if (ctx->cdm_handle[i] != 0) + cam_cdm_release(ctx->cdm_handle[i]); + ctx->cdm_handle[i] = 0; + } /* clean context */ list_del_init(&ctx->list); ctx->ctx_in_use = 0; ctx->is_rdi_only_context = 0; - ctx->cdm_handle = 0; ctx->cdm_ops = NULL; ctx->num_reg_dump_buf = 0; ctx->custom_enabled = false; @@ -4483,7 +4707,7 @@ static int cam_isp_blob_fe_update( uint32_t blob_type, struct cam_isp_generic_blob_info *blob_info, struct cam_fe_config *fe_config, - struct cam_hw_prepare_update_args *prepare) + struct cam_isp_hw_update_args *prepare) { struct cam_ife_hw_mgr_ctx *ctx = NULL; struct cam_isp_hw_mgr_res *hw_mgr_res; @@ -4555,13 +4779,14 @@ static int cam_isp_blob_ubwc_update( uint32_t blob_type, struct cam_isp_generic_blob_info *blob_info, struct cam_ubwc_config *ubwc_config, - struct cam_hw_prepare_update_args *prepare) + struct cam_isp_hw_update_args *prepare) { struct cam_ubwc_plane_cfg_v1 *ubwc_plane_cfg; struct cam_kmd_buf_info *kmd_buf_info; struct cam_ife_hw_mgr_ctx *ctx = NULL; struct cam_isp_hw_mgr_res *hw_mgr_res; - uint32_t res_id_out, i; + struct cam_hw_update_entry *hw_entry; + uint32_t res_id_out, i, slot_idx = 0; uint32_t total_used_bytes = 0; uint32_t kmd_buf_remain_size; uint32_t *cmd_buf_addr; @@ -4575,10 +4800,14 @@ static int cam_isp_blob_ubwc_update( goto end; } - if ((prepare->num_hw_update_entries + 1) >= + slot_idx = blob_info->base_info->idx; + hw_entry = prepare->hw_update_info[slot_idx].hw_entries; + num_ent = prepare->hw_update_info[slot_idx].num_hw_entries; + + if ((num_ent + 1) >= prepare->max_hw_update_entries) { CAM_ERR(CAM_ISP, "Insufficient HW entries :%d max:%d", - prepare->num_hw_update_entries, + num_ent, prepare->max_hw_update_entries); rc = -EINVAL; goto end; @@ -4650,18 +4879,18 @@ static int cam_isp_blob_ubwc_update( if (total_used_bytes) { /* Update the HW entries */ - num_ent = prepare->num_hw_update_entries; - prepare->hw_update_entries[num_ent].handle = + hw_entry[num_ent].handle = kmd_buf_info->handle; - prepare->hw_update_entries[num_ent].len = + hw_entry[num_ent].len = total_used_bytes; - prepare->hw_update_entries[num_ent].offset = + hw_entry[num_ent].offset = kmd_buf_info->offset; num_ent++; kmd_buf_info->used_bytes += total_used_bytes; kmd_buf_info->offset += total_used_bytes; - prepare->num_hw_update_entries = num_ent; + prepare->hw_update_info[slot_idx].num_hw_entries + = num_ent; } break; default: @@ -4726,12 +4955,13 @@ static int cam_isp_blob_ubwc_update_v2( uint32_t blob_type, struct cam_isp_generic_blob_info *blob_info, struct cam_ubwc_config_v2 *ubwc_config, - struct cam_hw_prepare_update_args *prepare) + struct cam_isp_hw_update_args *prepare) { struct cam_ubwc_plane_cfg_v2 *ubwc_plane_cfg; struct cam_kmd_buf_info *kmd_buf_info; struct cam_ife_hw_mgr_ctx *ctx = NULL; struct cam_isp_hw_mgr_res *hw_mgr_res; + struct cam_hw_update_entry *hw_entry; uint32_t res_id_out, i; uint32_t total_used_bytes = 0; uint32_t kmd_buf_remain_size; @@ -4739,6 +4969,7 @@ static int cam_isp_blob_ubwc_update_v2( uint32_t bytes_used = 0; int num_ent, rc = 0; struct cam_vfe_generic_ubwc_config generic_ubwc_cfg; + uint32_t slot_idx; ctx = prepare->ctxt_to_hw_map; if (!ctx) { @@ -4747,10 +4978,14 @@ static int cam_isp_blob_ubwc_update_v2( goto end; } - if (prepare->num_hw_update_entries + 1 >= + slot_idx = blob_info->base_info->idx; + hw_entry = prepare->hw_update_info[slot_idx].hw_entries; + num_ent = prepare->hw_update_info[slot_idx].num_hw_entries; + + if (num_ent + 1 >= prepare->max_hw_update_entries) { CAM_ERR(CAM_ISP, "Insufficient HW entries :%d max:%d", - prepare->num_hw_update_entries, + prepare->hw_update_info[slot_idx].num_hw_entries, prepare->max_hw_update_entries); rc = -EINVAL; goto end; @@ -4823,18 +5058,18 @@ static int cam_isp_blob_ubwc_update_v2( if (total_used_bytes) { /* Update the HW entries */ - num_ent = prepare->num_hw_update_entries; - prepare->hw_update_entries[num_ent].handle = + hw_entry[num_ent].handle = kmd_buf_info->handle; - prepare->hw_update_entries[num_ent].len = + hw_entry[num_ent].len = total_used_bytes; - prepare->hw_update_entries[num_ent].offset = + hw_entry[num_ent].offset = kmd_buf_info->offset; num_ent++; kmd_buf_info->used_bytes += total_used_bytes; kmd_buf_info->offset += total_used_bytes; - prepare->num_hw_update_entries = num_ent; + prepare->hw_update_info[slot_idx].num_hw_entries + = num_ent; } end: return rc; @@ -4844,13 +5079,14 @@ static int cam_isp_blob_hfr_update( uint32_t blob_type, struct cam_isp_generic_blob_info *blob_info, struct cam_isp_resource_hfr_config *hfr_config, - struct cam_hw_prepare_update_args *prepare) + struct cam_isp_hw_update_args *prepare) { struct cam_isp_port_hfr_config *port_hfr_config; struct cam_kmd_buf_info *kmd_buf_info; struct cam_ife_hw_mgr_ctx *ctx = NULL; struct cam_isp_hw_mgr_res *hw_mgr_res; - uint32_t res_id_out, i; + struct cam_hw_update_entry *hw_entry; + uint32_t res_id_out, i, slot_idx = 0; uint32_t total_used_bytes = 0; uint32_t kmd_buf_remain_size; uint32_t *cmd_buf_addr; @@ -4861,11 +5097,15 @@ static int cam_isp_blob_hfr_update( CAM_DBG(CAM_ISP, "num_ports= %d", hfr_config->num_ports); + slot_idx = blob_info->base_info->idx; + hw_entry = prepare->hw_update_info[slot_idx].hw_entries; + num_ent = prepare->hw_update_info[slot_idx].num_hw_entries; + /* Max one hw entries required for hfr config update */ - if (prepare->num_hw_update_entries + 1 >= + if (prepare->hw_update_info[slot_idx].num_hw_entries + 1 >= prepare->max_hw_update_entries) { CAM_ERR(CAM_ISP, "Insufficient HW entries :%d %d", - prepare->num_hw_update_entries, + prepare->hw_update_info[slot_idx].num_hw_entries, prepare->max_hw_update_entries); return -EINVAL; } @@ -4923,17 +5163,17 @@ static int cam_isp_blob_hfr_update( if (total_used_bytes) { /* Update the HW entries */ - num_ent = prepare->num_hw_update_entries; - prepare->hw_update_entries[num_ent].handle = + hw_entry[num_ent].handle = kmd_buf_info->handle; - prepare->hw_update_entries[num_ent].len = total_used_bytes; - prepare->hw_update_entries[num_ent].offset = + hw_entry[num_ent].len = + total_used_bytes; + hw_entry[num_ent].offset = kmd_buf_info->offset; num_ent++; - kmd_buf_info->used_bytes += total_used_bytes; - kmd_buf_info->offset += total_used_bytes; - prepare->num_hw_update_entries = num_ent; + kmd_buf_info->offset += total_used_bytes; + prepare->hw_update_info[slot_idx].num_hw_entries + = num_ent; } return rc; @@ -4943,7 +5183,7 @@ static int cam_isp_blob_csid_clock_update( uint32_t blob_type, struct cam_isp_generic_blob_info *blob_info, struct cam_isp_csid_clock_config *clock_config, - struct cam_hw_prepare_update_args *prepare) + struct cam_isp_hw_update_args *prepare) { struct cam_ife_hw_mgr_ctx *ctx = NULL; struct cam_isp_hw_mgr_res *hw_mgr_res; @@ -4990,7 +5230,7 @@ static int cam_isp_blob_csid_qcfa_update( uint32_t blob_type, struct cam_isp_generic_blob_info *blob_info, struct cam_isp_csid_qcfa_config *qcfa_config, - struct cam_hw_prepare_update_args *prepare) + struct cam_isp_hw_update_args *prepare) { struct cam_ife_hw_mgr_ctx *ctx = NULL; struct cam_isp_hw_mgr_res *hw_mgr_res; @@ -5038,7 +5278,7 @@ static int cam_isp_blob_core_cfg_update( uint32_t blob_type, struct cam_isp_generic_blob_info *blob_info, struct cam_isp_core_config *core_config, - struct cam_hw_prepare_update_args *prepare) + struct cam_isp_hw_update_args *prepare) { struct cam_ife_hw_mgr_ctx *ctx = NULL; struct cam_isp_hw_mgr_res *hw_mgr_res; @@ -5093,7 +5333,7 @@ static int cam_isp_blob_clock_update( uint32_t blob_type, struct cam_isp_generic_blob_info *blob_info, struct cam_isp_clock_config *clock_config, - struct cam_hw_prepare_update_args *prepare) + struct cam_isp_hw_update_args *prepare) { struct cam_ife_hw_mgr_ctx *ctx = NULL; struct cam_isp_hw_mgr_res *hw_mgr_res; @@ -5203,26 +5443,30 @@ static int cam_isp_blob_vfe_out_update( uint32_t blob_type, struct cam_isp_generic_blob_info *blob_info, struct cam_isp_vfe_out_config *vfe_out_config, - struct cam_hw_prepare_update_args *prepare) + struct cam_isp_hw_update_args *prepare) { struct cam_isp_vfe_wm_config *wm_config; struct cam_kmd_buf_info *kmd_buf_info; struct cam_ife_hw_mgr_ctx *ctx = NULL; struct cam_isp_hw_mgr_res *ife_out_res; + struct cam_hw_update_entry *hw_entry; uint32_t res_id_out, i; uint32_t total_used_bytes = 0; uint32_t kmd_buf_remain_size; uint32_t *cmd_buf_addr; uint32_t bytes_used = 0; + uint32_t slot_idx = 0; int num_ent, rc = 0; ctx = prepare->ctxt_to_hw_map; + slot_idx = blob_info->base_info->idx; + hw_entry = prepare->hw_update_info[slot_idx].hw_entries; + num_ent = prepare->hw_update_info[slot_idx].num_hw_entries; - if (prepare->num_hw_update_entries + 1 >= + if (num_ent + 1 >= prepare->max_hw_update_entries) { - CAM_ERR(CAM_ISP, "Insufficient HW entries :%d %d", - prepare->num_hw_update_entries, - prepare->max_hw_update_entries); + CAM_ERR(CAM_ISP, "Insufficient HW entries :%d", + num_ent); return -EINVAL; } @@ -5278,17 +5522,17 @@ static int cam_isp_blob_vfe_out_update( } if (total_used_bytes) { - num_ent = prepare->num_hw_update_entries; - prepare->hw_update_entries[num_ent].handle = + hw_entry[num_ent].handle = kmd_buf_info->handle; - prepare->hw_update_entries[num_ent].len = total_used_bytes; - prepare->hw_update_entries[num_ent].offset = + hw_entry[num_ent].len = + total_used_bytes; + hw_entry[num_ent].offset = kmd_buf_info->offset; num_ent++; - kmd_buf_info->used_bytes += total_used_bytes; kmd_buf_info->offset += total_used_bytes; - prepare->num_hw_update_entries = num_ent; + prepare->hw_update_info[slot_idx].num_hw_entries + = num_ent; } return rc; @@ -5298,7 +5542,7 @@ static int cam_isp_blob_csid_config_update( uint32_t blob_type, struct cam_isp_generic_blob_info *blob_info, struct cam_isp_csid_epd_config *epd_config, - struct cam_hw_prepare_update_args *prepare) + struct cam_isp_hw_update_args *prepare) { struct cam_ife_hw_mgr_ctx *ctx = NULL; struct cam_isp_hw_mgr_res *hw_mgr_res; @@ -5343,9 +5587,9 @@ static int cam_isp_packet_generic_blob_handler(void *user_data, uint32_t blob_type, uint32_t blob_size, uint8_t *blob_data) { int rc = 0; - struct cam_isp_generic_blob_info *blob_info = user_data; - struct cam_hw_prepare_update_args *prepare = NULL; - struct cam_ife_hw_mgr_ctx *ife_mgr_ctx = NULL; + struct cam_isp_generic_blob_info *blob_info = user_data; + struct cam_ife_hw_mgr_ctx *ife_mgr_ctx = NULL; + struct cam_isp_hw_update_args *prepare = NULL; if (!blob_data || (blob_size == 0) || !blob_info) { CAM_ERR(CAM_ISP, "Invalid args data %pK size %d info %pK", @@ -5883,12 +6127,13 @@ static int cam_ife_mgr_prepare_hw_update(void *hw_mgr_priv, void *prepare_hw_update_args) { int rc = 0; - struct cam_hw_prepare_update_args *prepare = - (struct cam_hw_prepare_update_args *) prepare_hw_update_args; + struct cam_isp_hw_update_args *ife_cfg = + (struct cam_isp_hw_update_args *) prepare_hw_update_args; + struct cam_ife_hw_mgr_ctx *ctx; struct cam_ife_hw_mgr *hw_mgr; struct cam_kmd_buf_info kmd_buf; - uint32_t i; + uint32_t i, idx; bool fill_fence = true; bool frame_header_enable = false; struct cam_isp_prepare_hw_update_data *prepare_hw_data; @@ -5900,22 +6145,22 @@ static int cam_ife_mgr_prepare_hw_update(void *hw_mgr_priv, } prepare_hw_data = (struct cam_isp_prepare_hw_update_data *) - prepare->priv; + ife_cfg->priv; - ctx = (struct cam_ife_hw_mgr_ctx *) prepare->ctxt_to_hw_map; + ctx = (struct cam_ife_hw_mgr_ctx *) ife_cfg->ctxt_to_hw_map; hw_mgr = (struct cam_ife_hw_mgr *)hw_mgr_priv; CAM_DBG(CAM_REQ, "ctx[%pK][%d] Enter for req_id %lld", - ctx, ctx->ctx_index, prepare->packet->header.request_id); + ctx, ctx->ctx_index, ife_cfg->packet->header.request_id); - rc = cam_packet_util_validate_packet(prepare->packet, - prepare->remain_len); + rc = cam_packet_util_validate_packet(ife_cfg->packet, + ife_cfg->remain_len); if (rc) return rc; /* Pre parse the packet*/ - rc = cam_packet_util_get_kmd_buffer(prepare->packet, &kmd_buf); + rc = cam_packet_util_get_kmd_buffer(ife_cfg->packet, &kmd_buf); if (rc) return rc; @@ -5928,18 +6173,28 @@ static int cam_ife_mgr_prepare_hw_update(void *hw_mgr_priv, frame_header_enable = true; } - rc = cam_packet_util_process_patches(prepare->packet, - hw_mgr->mgr_common.cmd_iommu_hdl, - hw_mgr->mgr_common.cmd_iommu_hdl_secure); + if (ctx->internal_cdm) + rc = cam_packet_util_process_patches(ife_cfg->packet, + hw_mgr->mgr_common.img_iommu_hdl, + hw_mgr->mgr_common.img_iommu_hdl_secure); + else + rc = cam_packet_util_process_patches(ife_cfg->packet, + hw_mgr->mgr_common.cmd_iommu_hdl, + hw_mgr->mgr_common.cmd_iommu_hdl_secure); + if (rc) { CAM_ERR(CAM_ISP, "Patch ISP packet failed."); return rc; } - prepare->num_hw_update_entries = 0; - prepare->num_in_map_entries = 0; - prepare->num_out_map_entries = 0; - prepare->num_reg_dump_buf = 0; + + for (i = 0; i < ctx->num_base; i++) { + idx = ctx->base[i].idx; + ife_cfg->hw_update_info[idx].num_hw_entries = 0; + } + ife_cfg->num_in_map_entries = 0; + ife_cfg->num_out_map_entries = 0; + ife_cfg->num_reg_dump_buf = 0; memset(&prepare_hw_data->bw_config[0], 0x0, sizeof(prepare_hw_data->bw_config[0]) * @@ -5948,23 +6203,42 @@ static int cam_ife_mgr_prepare_hw_update(void *hw_mgr_priv, sizeof(prepare_hw_data->bw_config_valid[0]) * CAM_IFE_HW_NUM_MAX); + /* Add reset trigger_cdm_event */ + if ((ctx->hw_version >= CAM_CPAS_TITAN_480_V100) && ctx->is_dual + && ctx->internal_cdm) { + for (i = 0; i < ctx->num_base; i++) { + if (ctx->master_slave[ctx->base[i].idx] + == CAM_IFE_RES_SLAVE && + ctx->base[i].cdm_id == CAM_CDM_IFE) + rc = cam_isp_add_wait_trigger(ife_cfg, + &ctx->res_list_ife_src, + ctx->base[i].idx, &kmd_buf, false); + } + } + for (i = 0; i < ctx->num_base; i++) { CAM_DBG(CAM_ISP, "process cmd buffer for device %d", i); + CAM_DBG(CAM_ISP, + "change base i=%d, idx=%d, ctx->internal_cdm = %d cdm_id = %d", + i, ctx->base[i].idx, ctx->internal_cdm, + ctx->base[i].cdm_id); + /* Add change base */ - rc = cam_isp_add_change_base(prepare, &ctx->res_list_ife_src, - ctx->base[i].idx, &kmd_buf); - if (rc) { - CAM_ERR(CAM_ISP, + if (!ctx->internal_cdm || ctx->base[i].cdm_id == CAM_CDM_CPAS) { + rc = cam_isp_add_change_base(ife_cfg, + &ctx->res_list_ife_src, + ctx->base[i].idx, &kmd_buf); + if (rc) { + CAM_ERR(CAM_ISP, "Failed in change base i=%d, idx=%d, rc=%d", i, ctx->base[i].idx, rc); - goto end; + goto end; + } } - - /* get command buffers */ if (ctx->base[i].split_id != CAM_ISP_HW_SPLIT_MAX) { - rc = cam_isp_add_command_buffers(prepare, &kmd_buf, + rc = cam_isp_add_command_buffers(ife_cfg, &kmd_buf, &ctx->base[i], cam_isp_packet_generic_blob_handler, ctx->res_list_ife_out, CAM_IFE_HW_OUT_RES_MAX); @@ -5988,7 +6262,7 @@ static int cam_ife_mgr_prepare_hw_update(void *hw_mgr_priv, rc = cam_isp_add_io_buffers( hw_mgr->mgr_common.img_iommu_hdl, hw_mgr->mgr_common.img_iommu_hdl_secure, - prepare, ctx->base[i].idx, + ife_cfg, ctx->base[i].idx, &kmd_buf, ctx->res_list_ife_out, &ctx->res_list_ife_in_rd, CAM_IFE_HW_OUT_RES_MAX, fill_fence, @@ -6018,11 +6292,10 @@ static int cam_ife_mgr_prepare_hw_update(void *hw_mgr_priv, } } - /* add go_cmd for offline context */ - if (prepare->num_out_map_entries && prepare->num_in_map_entries && + if (ife_cfg->num_out_map_entries && ife_cfg->num_in_map_entries && ctx->is_offline) { - rc = cam_isp_add_go_cmd(prepare, &ctx->res_list_ife_in_rd, + rc = cam_isp_add_go_cmd(ife_cfg, &ctx->res_list_ife_in_rd, ctx->base[i].idx, &kmd_buf); if (rc) CAM_ERR(CAM_ISP, @@ -6036,25 +6309,26 @@ static int cam_ife_mgr_prepare_hw_update(void *hw_mgr_priv, * bits to get the type of operation since UMD definition * of op_code has some difference from KMD. */ - if (((prepare->packet->header.op_code + 1) & 0xF) == + if (((ife_cfg->packet->header.op_code + 1) & 0xF) == CAM_ISP_PACKET_INIT_DEV) { prepare_hw_data->packet_opcode_type = CAM_ISP_PACKET_INIT_DEV; - if ((!prepare->num_reg_dump_buf) || (prepare->num_reg_dump_buf > + if ((!ife_cfg->num_reg_dump_buf) || (ife_cfg->num_reg_dump_buf > CAM_REG_DUMP_MAX_BUF_ENTRIES)) goto end; if (!ctx->num_reg_dump_buf) { - ctx->num_reg_dump_buf = prepare->num_reg_dump_buf; + ctx->num_reg_dump_buf = ife_cfg->num_reg_dump_buf; + memcpy(ctx->reg_dump_buf_desc, - prepare->reg_dump_buf_desc, + ife_cfg->reg_dump_buf_desc, sizeof(struct cam_cmd_buf_desc) * - prepare->num_reg_dump_buf); + ife_cfg->num_reg_dump_buf); } else { prepare_hw_data->num_reg_dump_buf = - prepare->num_reg_dump_buf; + ife_cfg->num_reg_dump_buf; memcpy(prepare_hw_data->reg_dump_buf_desc, - prepare->reg_dump_buf_desc, + ife_cfg->reg_dump_buf_desc, sizeof(struct cam_cmd_buf_desc) * prepare_hw_data->num_reg_dump_buf); } @@ -6062,32 +6336,49 @@ static int cam_ife_mgr_prepare_hw_update(void *hw_mgr_priv, goto end; } else { prepare_hw_data->packet_opcode_type = CAM_ISP_PACKET_UPDATE_DEV; - prepare_hw_data->num_reg_dump_buf = prepare->num_reg_dump_buf; + prepare_hw_data->num_reg_dump_buf = ife_cfg->num_reg_dump_buf; if ((prepare_hw_data->num_reg_dump_buf) && (prepare_hw_data->num_reg_dump_buf < CAM_REG_DUMP_MAX_BUF_ENTRIES)) { memcpy(prepare_hw_data->reg_dump_buf_desc, - prepare->reg_dump_buf_desc, + ife_cfg->reg_dump_buf_desc, sizeof(struct cam_cmd_buf_desc) * prepare_hw_data->num_reg_dump_buf); } } + /* Add wait for comp event */ + if ((ctx->hw_version >= CAM_CPAS_TITAN_480_V100) && ctx->is_dual + && ctx->internal_cdm) { + for (i = 0; i < ctx->num_base; i++) { + if (ctx->master_slave[ctx->base[i].idx] == + CAM_IFE_RES_MASTER && + ctx->base[i].cdm_id == CAM_CDM_IFE) + rc = cam_isp_add_comp_wait(ife_cfg, + &ctx->res_list_ife_src, + ctx->base[i].idx, &kmd_buf); + } + } + /* add reg update commands */ for (i = 0; i < ctx->num_base; i++) { /* Add change base */ - rc = cam_isp_add_change_base(prepare, &ctx->res_list_ife_src, - ctx->base[i].idx, &kmd_buf); - if (rc) { - CAM_ERR(CAM_ISP, - "Failed in change base adding reg_update cmd i=%d, idx=%d, rc=%d", - i, ctx->base[i].idx, rc); - goto end; - } + if (!ctx->internal_cdm || ctx->base[i].cdm_id == CAM_CDM_CPAS) { + rc = cam_isp_add_change_base(ife_cfg, + &ctx->res_list_ife_src, + ctx->base[i].idx, &kmd_buf); + if (rc) { + CAM_ERR(CAM_ISP, + "Failed in change base adding reg_update cmd i=%d, idx=%d, rc=%d", + i, ctx->base[i].idx, rc); + goto end; + } + } /*Add reg update */ - rc = cam_isp_add_reg_update(prepare, &ctx->res_list_ife_src, + rc = cam_isp_add_reg_update(ife_cfg, &ctx->res_list_ife_src, ctx->base[i].idx, &kmd_buf); + if (rc) { CAM_ERR(CAM_ISP, "Add Reg_update cmd Failed i=%d, idx=%d, rc=%d", @@ -6096,6 +6387,18 @@ static int cam_ife_mgr_prepare_hw_update(void *hw_mgr_priv, } } + /* Add trigger_cdm_event */ + if ((ctx->hw_version >= CAM_CPAS_TITAN_480_V100) && ctx->is_dual + && ctx->internal_cdm) { + for (i = 0; i < ctx->num_base; i++) { + if (ctx->master_slave[ctx->base[i].idx] + == CAM_IFE_RES_SLAVE) + rc = cam_isp_add_wait_trigger(ife_cfg, + &ctx->res_list_ife_src, + ctx->base[i].idx, &kmd_buf, true); + } + } + end: return rc; } @@ -6227,7 +6530,7 @@ static void cam_ife_mgr_print_io_bufs(struct cam_packet *packet, static int cam_ife_mgr_cmd(void *hw_mgr_priv, void *cmd_args) { - int rc = 0; + int rc = 0, i = 0; struct cam_hw_cmd_args *hw_cmd_args = cmd_args; struct cam_ife_hw_mgr *hw_mgr = hw_mgr_priv; struct cam_ife_hw_mgr_ctx *ctx = (struct cam_ife_hw_mgr_ctx *) @@ -6235,6 +6538,7 @@ static int cam_ife_mgr_cmd(void *hw_mgr_priv, void *cmd_args) struct cam_isp_hw_cmd_args *isp_hw_cmd_args = NULL; struct cam_packet *packet; unsigned long rem_jiffies = 0; + uint32_t idx; if (!hw_mgr_priv || !cmd_args) { CAM_ERR(CAM_ISP, "Invalid arguments"); @@ -6308,13 +6612,17 @@ static int cam_ife_mgr_cmd(void *hw_mgr_priv, void *cmd_args) if (ctx->last_dump_flush_req_id == ctx->applied_req_id) return 0; - rem_jiffies = wait_for_completion_timeout( - &ctx->config_done_complete, - msecs_to_jiffies(30)); - if (rem_jiffies == 0) - CAM_ERR(CAM_ISP, - "config done completion timeout, Reg dump will be unreliable ctx_index %d", - ctx->ctx_index); + for (i = 0; i < ctx->num_base; i++) { + idx = ctx->base[i].idx; + rem_jiffies = wait_for_completion_timeout( + &ctx->config_done_complete[idx], + msecs_to_jiffies(5)); + if (rem_jiffies == 0) + CAM_ERR(CAM_ISP, + "config done completion timeout, Reg dump will be unreliable rc=%d ctx_index %d", + rc, ctx->ctx_index); + rc = 0; + } ctx->last_dump_flush_req_id = ctx->applied_req_id; rc = cam_ife_mgr_handle_reg_dump(ctx, ctx->reg_dump_buf_desc, @@ -7345,8 +7653,10 @@ int cam_ife_hw_mgr_init(struct cam_hw_mgr_intf *hw_mgr_intf, int *iommu_hdl) * Also, we have to release them once we have the * deinit support */ - if (cam_smmu_get_handle("ife", - &g_ife_hw_mgr.mgr_common.img_iommu_hdl)) { + rc = cam_smmu_get_handle("ife", + &g_ife_hw_mgr.mgr_common.img_iommu_hdl); + + if (rc && rc != -EALREADY) { CAM_ERR(CAM_ISP, "Can not get iommu handle"); return -EINVAL; } @@ -7361,13 +7671,15 @@ int cam_ife_hw_mgr_init(struct cam_hw_mgr_intf *hw_mgr_intf, int *iommu_hdl) g_ife_hw_mgr.mgr_common.img_iommu_hdl, g_ife_hw_mgr.mgr_common.img_iommu_hdl_secure); - if (!cam_cdm_get_iommu_handle("ife", &cdm_handles)) { - CAM_DBG(CAM_ISP, "Successfully acquired the CDM iommu handles"); + if (!cam_cdm_get_iommu_handle("ife3", &cdm_handles)) { + CAM_DBG(CAM_ISP, + "Successfully acquired CDM iommu handles 0x%x, 0x%x", + cdm_handles.non_secure, cdm_handles.secure); g_ife_hw_mgr.mgr_common.cmd_iommu_hdl = cdm_handles.non_secure; g_ife_hw_mgr.mgr_common.cmd_iommu_hdl_secure = cdm_handles.secure; } else { - CAM_DBG(CAM_ISP, "Failed to acquire the CDM iommu handles"); + CAM_ERR(CAM_ISP, "Failed to acquire CDM iommu handle"); g_ife_hw_mgr.mgr_common.cmd_iommu_hdl = -1; g_ife_hw_mgr.mgr_common.cmd_iommu_hdl_secure = -1; } @@ -7418,8 +7730,10 @@ int cam_ife_hw_mgr_init(struct cam_hw_mgr_intf *hw_mgr_intf, int *iommu_hdl) g_ife_hw_mgr.ctx_pool[i].common.tasklet_info = g_ife_hw_mgr.mgr_common.tasklet_pool[i]; - - init_completion(&g_ife_hw_mgr.ctx_pool[i].config_done_complete); + for (j = 0; j < CAM_IFE_HW_NUM_MAX; j++) + init_completion( + &g_ife_hw_mgr.ctx_pool[i] + .config_done_complete[j]); list_add_tail(&g_ife_hw_mgr.ctx_pool[i].list, &g_ife_hw_mgr.free_ctx_list); } diff --git a/drivers/cam_isp/isp_hw_mgr/cam_ife_hw_mgr.h b/drivers/cam_isp/isp_hw_mgr/cam_ife_hw_mgr.h index bd83f89372..b6124ba566 100644 --- a/drivers/cam_isp/isp_hw_mgr/cam_ife_hw_mgr.h +++ b/drivers/cam_isp/isp_hw_mgr/cam_ife_hw_mgr.h @@ -13,6 +13,15 @@ #include "cam_ife_csid_hw_intf.h" #include "cam_top_tpg_hw_intf.h" #include "cam_tasklet_util.h" +#include "cam_cdm_intf_api.h" + +/* enum cam_ife_res_master_slave - HW resource master/slave */ +enum cam_ife_res_master_slave { + CAM_IFE_RES_NONE, + CAM_IFE_RES_MASTER, + CAM_IFE_RES_SLAVE, + CAM_IFE_RES_MAX, +}; /* IFE resource constants */ #define CAM_IFE_HW_IN_RES_MAX (CAM_ISP_IFE_IN_RES_MAX & 0xFF) @@ -90,6 +99,8 @@ struct cam_ife_hw_mgr_debug { * @is_tpg indicate whether context is using PHY TPG * @is_offline Indicate whether context is for offline IFE * @dsp_enabled Indicate whether dsp is enabled in this context + * @hw_enabled Array to indicate active HW + * @internal_cdm Indicate whether context uses internal CDM */ struct cam_ife_hw_mgr_ctx { struct list_head list; @@ -117,7 +128,7 @@ struct cam_ife_hw_mgr_ctx { uint32_t irq_status1_mask[CAM_IFE_HW_NUM_MAX]; struct cam_isp_ctx_base_info base[CAM_IFE_HW_NUM_MAX]; uint32_t num_base; - uint32_t cdm_handle; + uint32_t cdm_handle[CAM_IFE_HW_NUM_MAX]; struct cam_cdm_utils_ops *cdm_ops; struct cam_cdm_bl_request *cdm_cmd; @@ -127,7 +138,10 @@ struct cam_ife_hw_mgr_ctx { atomic_t overflow_pending; atomic_t cdm_done; uint32_t is_rdi_only_context; - struct completion config_done_complete; + struct completion config_done_complete[ + CAM_IFE_HW_NUM_MAX]; + enum cam_ife_res_master_slave master_slave[CAM_IFE_HW_NUM_MAX]; + uint32_t hw_version; struct cam_cmd_buf_desc reg_dump_buf_desc[ CAM_REG_DUMP_MAX_BUF_ENTRIES]; uint32_t num_reg_dump_buf; @@ -143,6 +157,7 @@ struct cam_ife_hw_mgr_ctx { bool is_tpg; bool is_offline; bool dsp_enabled; + bool internal_cdm; }; /** diff --git a/drivers/cam_isp/isp_hw_mgr/cam_isp_hw_mgr.h b/drivers/cam_isp/isp_hw_mgr/cam_isp_hw_mgr.h index fcb62ff891..edd1d33be8 100644 --- a/drivers/cam_isp/isp_hw_mgr/cam_isp_hw_mgr.h +++ b/drivers/cam_isp/isp_hw_mgr/cam_isp_hw_mgr.h @@ -10,7 +10,7 @@ #include "cam_isp_hw_mgr_intf.h" #include "cam_tasklet_util.h" #include "cam_isp_hw.h" - +#include "cam_cdm_intf_api.h" #define CAM_ISP_HW_NUM_MAX 7 @@ -91,5 +91,6 @@ struct cam_isp_hw_mgr_res { struct cam_isp_ctx_base_info { uint32_t idx; enum cam_isp_hw_split_id split_id; + enum cam_cdm_id cdm_id; }; #endif /* _CAM_ISP_HW_MGR_H_ */ diff --git a/drivers/cam_isp/isp_hw_mgr/cam_tfe_hw_mgr.c b/drivers/cam_isp/isp_hw_mgr/cam_tfe_hw_mgr.c index fc40510115..02ca27f7f4 100644 --- a/drivers/cam_isp/isp_hw_mgr/cam_tfe_hw_mgr.c +++ b/drivers/cam_isp/isp_hw_mgr/cam_tfe_hw_mgr.c @@ -1759,6 +1759,8 @@ static int cam_tfe_mgr_acquire_hw(void *hw_mgr_priv, void *acquire_hw_args) goto err; } + memset(&tfe_ctx->cdm_handle, 0, sizeof(tfe_ctx->cdm_handle)); + tfe_ctx->common.cb_priv = acquire_args->context_data; for (i = 0; i < CAM_ISP_HW_EVENT_MAX; i++) tfe_ctx->common.event_cb[i] = acquire_args->event_cb; @@ -1778,7 +1780,6 @@ static int cam_tfe_mgr_acquire_hw(void *hw_mgr_priv, void *acquire_hw_args) } cdm_acquire.base_array_cnt = j; - cdm_acquire.id = CAM_CDM_VIRTUAL; cdm_acquire.cam_cdm_callback = cam_tfe_cam_cdm_callback; rc = cam_cdm_acquire(&cdm_acquire); @@ -1992,6 +1993,8 @@ static int cam_tfe_mgr_acquire_dev(void *hw_mgr_priv, void *acquire_hw_args) goto err; } + memset(&tfe_ctx->cdm_handle, 0, sizeof(tfe_ctx->cdm_handle)); + tfe_ctx->common.cb_priv = acquire_args->context_data; for (i = 0; i < CAM_ISP_HW_EVENT_MAX; i++) tfe_ctx->common.event_cb[i] = acquire_args->event_cb; @@ -2322,14 +2325,15 @@ static int cam_isp_tfe_blob_bw_update( static int cam_tfe_mgr_config_hw(void *hw_mgr_priv, void *config_hw_args) { - int rc = -EINVAL, i, skip = 0; - struct cam_hw_config_args *cfg; + int rc = -EINVAL, i, j, k = 0, skip = 0; + struct cam_isp_hw_config_args *cfg; struct cam_hw_update_entry *cmd; struct cam_cdm_bl_request *cdm_cmd; struct cam_tfe_hw_mgr_ctx *ctx; struct cam_isp_prepare_hw_update_data *hw_update_data; + uint32_t num_ent; + struct cam_hw_update_entry *cfg_info; - CAM_DBG(CAM_ISP, "Enter"); if (!hw_mgr_priv || !config_hw_args) { CAM_ERR(CAM_ISP, "Invalid arguments"); return -EINVAL; @@ -2373,68 +2377,79 @@ static int cam_tfe_mgr_config_hw(void *hw_mgr_priv, } } - CAM_DBG(CAM_ISP, - "Enter ctx id:%d num_hw_upd_entries %d request id: %llu", - ctx->ctx_index, cfg->num_hw_update_entries, cfg->request_id); + CAM_DBG(CAM_ISP, "Enter ctx id:%d request id: %llu", + ctx->ctx_index, cfg->request_id); - if (cfg->num_hw_update_entries > 0) { - cdm_cmd = ctx->cdm_cmd; - cdm_cmd->cmd_arrary_count = cfg->num_hw_update_entries; - cdm_cmd->type = CAM_CDM_BL_CMD_TYPE_MEM_HANDLE; - cdm_cmd->flag = true; - cdm_cmd->userdata = hw_update_data; - cdm_cmd->cookie = cfg->request_id; - cdm_cmd->gen_irq_arb = false; + cdm_cmd = ctx->cdm_cmd; + cdm_cmd->type = CAM_CDM_BL_CMD_TYPE_MEM_HANDLE; + cdm_cmd->flag = true; + cdm_cmd->userdata = hw_update_data; + cdm_cmd->cookie = cfg->request_id; + cdm_cmd->gen_irq_arb = false; + cdm_cmd->cmd_arrary_count = 0; - for (i = 0 ; i < cfg->num_hw_update_entries; i++) { - cmd = (cfg->hw_update_entries + i); - if (cfg->reapply && cmd->flags == CAM_ISP_IQ_BL) { - skip++; - continue; + for (i = 0; i < ctx->num_base; i++) { + num_ent = cfg->hw_update_info[ctx->base[i].idx].num_hw_entries; + cfg_info = cfg->hw_update_info[ctx->base[i].idx].hw_entries; + if (num_ent > 0) { + for (j = 0 ; j < num_ent; j++) { + cmd = (cfg_info + j); + + if (cfg->reapply && + cmd->flags == CAM_ISP_IQ_BL) { + skip++; + continue; + } + + if (cmd->flags == CAM_ISP_UNUSED_BL || + cmd->flags >= CAM_ISP_BL_MAX) + CAM_ERR(CAM_ISP, + "Unexpected BL type %d", + cmd->flags); + + cdm_cmd->cmd[j - skip + k].bl_addr.mem_handle = + cmd->handle; + cdm_cmd->cmd[j - skip + k].offset = cmd->offset; + cdm_cmd->cmd[j - skip + k].len = cmd->len; + cdm_cmd->cmd[j - skip + k].arbitrate = false; } - - if (cmd->flags == CAM_ISP_UNUSED_BL || - cmd->flags >= CAM_ISP_BL_MAX) - CAM_ERR(CAM_ISP, "Unexpected BL type %d", - cmd->flags); - - cdm_cmd->cmd[i - skip].bl_addr.mem_handle = cmd->handle; - cdm_cmd->cmd[i - skip].offset = cmd->offset; - cdm_cmd->cmd[i - skip].len = cmd->len; - cdm_cmd->cmd[i - skip].arbitrate = false; + cdm_cmd->cmd_arrary_count += num_ent - skip; + k = cdm_cmd->cmd_arrary_count; } - cdm_cmd->cmd_arrary_count = cfg->num_hw_update_entries - skip; + } - reinit_completion(&ctx->config_done_complete); - ctx->applied_req_id = cfg->request_id; + ctx->applied_req_id = cfg->request_id; + CAM_DBG(CAM_ISP, "Submit to CDM"); - CAM_DBG(CAM_ISP, "Submit to CDM"); - atomic_set(&ctx->cdm_done, 0); - rc = cam_cdm_submit_bls(ctx->cdm_handle, cdm_cmd); - if (rc) { - CAM_ERR(CAM_ISP, "Failed to apply the configs"); - return rc; + atomic_set(&ctx->cdm_done, 0); + reinit_completion(&ctx->config_done_complete); + rc = cam_cdm_submit_bls(ctx->cdm_handle, cdm_cmd); + if (rc) { + CAM_ERR(CAM_ISP, + "Failed to apply the configs for req %llu, rc %d", + cfg->request_id, rc); + return rc; + } + + if (cfg->init_packet) { + rc = wait_for_completion_timeout( + &ctx->config_done_complete, + msecs_to_jiffies( + CAM_TFE_HW_CONFIG_TIMEOUT)); + if (rc <= 0) { + CAM_ERR(CAM_ISP, + "config done completion timeout for req_id=%llu rc=%d ctx_index %d", + cfg->request_id, rc, + ctx->ctx_index); + if (rc == 0) + rc = -ETIMEDOUT; + } else { + rc = 0; + CAM_DBG(CAM_ISP, + "config done Success for req_id=%llu ctx_index %d", + cfg->request_id, + ctx->ctx_index); } - - if (cfg->init_packet) { - rc = wait_for_completion_timeout( - &ctx->config_done_complete, - msecs_to_jiffies(CAM_TFE_HW_CONFIG_TIMEOUT)); - if (rc <= 0) { - CAM_ERR(CAM_ISP, - "config done completion timeout for req_id=%llu rc=%d ctx_index %d", - cfg->request_id, rc, ctx->ctx_index); - if (rc == 0) - rc = -ETIMEDOUT; - } else { - rc = 0; - CAM_DBG(CAM_ISP, - "config done Success for req_id=%llu ctx_index %d", - cfg->request_id, ctx->ctx_index); - } - } - } else { - CAM_ERR(CAM_ISP, "No commands to config"); } CAM_DBG(CAM_ISP, "Exit: Config Done: %llu", cfg->request_id); @@ -2642,7 +2657,8 @@ static int cam_tfe_mgr_stop_hw(void *hw_mgr_priv, void *stop_hw_args) cam_tfe_mgr_pause_hw(ctx); - wait_for_completion(&ctx->config_done_complete); + wait_for_completion_timeout(&ctx->config_done_complete, + msecs_to_jiffies(5)); if (stop_isp->stop_only) goto end; @@ -3069,18 +3085,18 @@ static int cam_tfe_mgr_release_hw(void *hw_mgr_priv, return rc; } - static int cam_isp_tfe_blob_hfr_update( uint32_t blob_type, struct cam_isp_generic_blob_info *blob_info, struct cam_isp_tfe_resource_hfr_config *hfr_config, - struct cam_hw_prepare_update_args *prepare) + struct cam_isp_hw_update_args *prepare) { struct cam_isp_tfe_port_hfr_config *port_hfr_config; struct cam_kmd_buf_info *kmd_buf_info; struct cam_tfe_hw_mgr_ctx *ctx = NULL; struct cam_isp_hw_mgr_res *hw_mgr_res; - uint32_t res_id_out, i; + struct cam_hw_update_entry *hw_entry; + uint32_t res_id_out, i, slot_idx = 0; uint32_t total_used_bytes = 0; uint32_t kmd_buf_remain_size; uint32_t *cmd_buf_addr; @@ -3090,11 +3106,15 @@ static int cam_isp_tfe_blob_hfr_update( ctx = prepare->ctxt_to_hw_map; CAM_DBG(CAM_ISP, "num_ports= %d", hfr_config->num_ports); + slot_idx = blob_info->base_info->idx; + hw_entry = prepare->hw_update_info[slot_idx].hw_entries; + num_ent = prepare->hw_update_info[slot_idx].num_hw_entries; + /* Max one hw entries required for hfr config update */ - if (prepare->num_hw_update_entries + 1 >= + if (prepare->hw_update_info[slot_idx].num_hw_entries + 1 >= prepare->max_hw_update_entries) { CAM_ERR(CAM_ISP, "Insufficient HW entries :%d %d", - prepare->num_hw_update_entries, + prepare->hw_update_info[slot_idx].num_hw_entries, prepare->max_hw_update_entries); return -EINVAL; } @@ -3150,17 +3170,17 @@ static int cam_isp_tfe_blob_hfr_update( if (total_used_bytes) { /* Update the HW entries */ - num_ent = prepare->num_hw_update_entries; - prepare->hw_update_entries[num_ent].handle = + hw_entry[num_ent].handle = kmd_buf_info->handle; - prepare->hw_update_entries[num_ent].len = total_used_bytes; - prepare->hw_update_entries[num_ent].offset = + hw_entry[num_ent].len = + total_used_bytes; + hw_entry[num_ent].offset = kmd_buf_info->offset; num_ent++; - kmd_buf_info->used_bytes += total_used_bytes; kmd_buf_info->offset += total_used_bytes; - prepare->num_hw_update_entries = num_ent; + prepare->hw_update_info[slot_idx].num_hw_entries + = num_ent; } return rc; @@ -3170,7 +3190,7 @@ static int cam_isp_tfe_blob_csid_clock_update( uint32_t blob_type, struct cam_isp_generic_blob_info *blob_info, struct cam_isp_tfe_csid_clock_config *clock_config, - struct cam_hw_prepare_update_args *prepare) + struct cam_isp_hw_update_args *prepare) { struct cam_tfe_hw_mgr_ctx *ctx = NULL; struct cam_isp_hw_mgr_res *hw_mgr_res; @@ -3234,7 +3254,7 @@ static int cam_isp_tfe_blob_clock_update( uint32_t blob_type, struct cam_isp_generic_blob_info *blob_info, struct cam_isp_tfe_clock_config *clock_config, - struct cam_hw_prepare_update_args *prepare) + struct cam_isp_hw_update_args *prepare) { struct cam_tfe_hw_mgr_ctx *ctx = NULL; struct cam_isp_hw_mgr_res *hw_mgr_res; @@ -3323,7 +3343,7 @@ static int cam_isp_tfe_packet_generic_blob_handler(void *user_data, { int rc = 0; struct cam_isp_generic_blob_info *blob_info = user_data; - struct cam_hw_prepare_update_args *prepare = NULL; + struct cam_isp_hw_update_args *prepare = NULL; if (!blob_data || (blob_size == 0) || !blob_info) { CAM_ERR(CAM_ISP, "Invalid args data %pK size %d info %pK", @@ -3524,7 +3544,7 @@ static int cam_isp_tfe_packet_generic_blob_handler(void *user_data, } static int cam_tfe_update_dual_config( - struct cam_hw_prepare_update_args *prepare, + struct cam_isp_hw_update_args *prepare, struct cam_cmd_buf_desc *cmd_desc, uint32_t split_id, uint32_t base_idx, @@ -3633,7 +3653,7 @@ end: } int cam_tfe_add_command_buffers( - struct cam_hw_prepare_update_args *prepare, + struct cam_isp_hw_update_args *prepare, struct cam_kmd_buf_info *kmd_buf_info, struct cam_isp_ctx_base_info *base_info, cam_packet_generic_blob_handler blob_handler_cb, @@ -3645,12 +3665,13 @@ int cam_tfe_add_command_buffers( uint32_t base_idx; enum cam_isp_hw_split_id split_id; struct cam_cmd_buf_desc *cmd_desc = NULL; - struct cam_hw_update_entry *hw_entry; + struct cam_hw_update_entry *hw_entry = NULL; + struct cam_isp_hw_update_entry_info *hw_info; - hw_entry = prepare->hw_update_entries; split_id = base_info->split_id; base_idx = base_info->idx; - + hw_entry = prepare->hw_update_info[base_idx].hw_entries; + hw_info = prepare->hw_update_info; /* * set the cmd_desc to point the first command descriptor in the * packet @@ -3663,7 +3684,7 @@ int cam_tfe_add_command_buffers( split_id, prepare->packet->num_cmd_buf); for (i = 0; i < prepare->packet->num_cmd_buf; i++) { - num_ent = prepare->num_hw_update_entries; + num_ent = prepare->hw_update_info[base_idx].num_hw_entries; if (!cmd_desc[i].length) continue; @@ -3748,7 +3769,8 @@ int cam_tfe_add_command_buffers( case CAM_ISP_TFE_PACKET_META_GENERIC_BLOB_COMMON: { struct cam_isp_generic_blob_info blob_info; - prepare->num_hw_update_entries = num_ent; + prepare->hw_update_info[base_idx].num_hw_entries = + num_ent; blob_info.prepare = prepare; blob_info.base_info = base_info; blob_info.kmd_buf_info = kmd_buf_info; @@ -3763,7 +3785,7 @@ int cam_tfe_add_command_buffers( return rc; } hw_entry[num_ent].flags = CAM_ISP_IQ_BL; - num_ent = prepare->num_hw_update_entries; + num_ent = hw_info[base_idx].num_hw_entries; } break; case CAM_ISP_TFE_PACKET_META_REG_DUMP_ON_FLUSH: @@ -3791,7 +3813,8 @@ int cam_tfe_add_command_buffers( cmd_meta_data); return -EINVAL; } - prepare->num_hw_update_entries = num_ent; + prepare->hw_update_info[base_idx].num_hw_entries + = num_ent; } return rc; @@ -3801,8 +3824,8 @@ static int cam_tfe_mgr_prepare_hw_update(void *hw_mgr_priv, void *prepare_hw_update_args) { int rc = 0; - struct cam_hw_prepare_update_args *prepare = - (struct cam_hw_prepare_update_args *) prepare_hw_update_args; + struct cam_isp_hw_update_args *prepare = + (struct cam_isp_hw_update_args *) prepare_hw_update_args; struct cam_tfe_hw_mgr_ctx *ctx; struct cam_tfe_hw_mgr *hw_mgr; struct cam_kmd_buf_info kmd_buf; @@ -3843,7 +3866,6 @@ static int cam_tfe_mgr_prepare_hw_update(void *hw_mgr_priv, return rc; } - prepare->num_hw_update_entries = 0; prepare->num_in_map_entries = 0; prepare->num_out_map_entries = 0; prepare->num_reg_dump_buf = 0; diff --git a/drivers/cam_isp/isp_hw_mgr/hw_utils/cam_isp_packet_parser.c b/drivers/cam_isp/isp_hw_mgr/hw_utils/cam_isp_packet_parser.c index 282c458d1b..c4931d85e7 100644 --- a/drivers/cam_isp/isp_hw_mgr/hw_utils/cam_isp_packet_parser.c +++ b/drivers/cam_isp/isp_hw_mgr/hw_utils/cam_isp_packet_parser.c @@ -10,9 +10,10 @@ #include "cam_vfe_hw_intf.h" #include "cam_isp_packet_parser.h" #include "cam_debug_util.h" +#include "cam_isp_hw_mgr_intf.h" int cam_isp_add_change_base( - struct cam_hw_prepare_update_args *prepare, + struct cam_isp_hw_update_args *prepare, struct list_head *res_list_isp_src, uint32_t base_idx, struct cam_kmd_buf_info *kmd_buf_info) @@ -24,8 +25,8 @@ int cam_isp_add_change_base( struct cam_hw_update_entry *hw_entry; uint32_t num_ent, i; - hw_entry = prepare->hw_update_entries; - num_ent = prepare->num_hw_update_entries; + hw_entry = prepare->hw_update_info[base_idx].hw_entries; + num_ent = prepare->hw_update_info[base_idx].num_hw_entries; /* Max one hw entries required for each base */ if (num_ent + 1 >= prepare->max_hw_update_entries) { @@ -76,7 +77,8 @@ int cam_isp_add_change_base( kmd_buf_info->used_bytes += get_base.cmd.used_bytes; kmd_buf_info->offset += get_base.cmd.used_bytes; num_ent++; - prepare->num_hw_update_entries = num_ent; + prepare->hw_update_info[base_idx].num_hw_entries + = num_ent; /* return success */ return 0; @@ -87,7 +89,7 @@ int cam_isp_add_change_base( } static int cam_isp_update_dual_config( - struct cam_hw_prepare_update_args *prepare, + struct cam_isp_hw_update_args *prepare, struct cam_cmd_buf_desc *cmd_desc, uint32_t split_id, uint32_t base_idx, @@ -241,7 +243,7 @@ int cam_isp_add_cmd_buf_update( } int cam_isp_add_command_buffers( - struct cam_hw_prepare_update_args *prepare, + struct cam_isp_hw_update_args *prepare, struct cam_kmd_buf_info *kmd_buf_info, struct cam_isp_ctx_base_info *base_info, cam_packet_generic_blob_handler blob_handler_cb, @@ -253,12 +255,13 @@ int cam_isp_add_command_buffers( uint32_t base_idx; enum cam_isp_hw_split_id split_id; struct cam_cmd_buf_desc *cmd_desc = NULL; - struct cam_hw_update_entry *hw_entry; + struct cam_hw_update_entry *hw_entry = NULL; + struct cam_isp_hw_update_entry_info *hw_info; - hw_entry = prepare->hw_update_entries; split_id = base_info->split_id; base_idx = base_info->idx; - + hw_entry = prepare->hw_update_info[base_idx].hw_entries; + hw_info = prepare->hw_update_info; /* * set the cmd_desc to point the first command descriptor in the * packet @@ -271,7 +274,8 @@ int cam_isp_add_command_buffers( split_id, prepare->packet->num_cmd_buf); for (i = 0; i < prepare->packet->num_cmd_buf; i++) { - num_ent = prepare->num_hw_update_entries; + num_ent = + prepare->hw_update_info[base_idx].num_hw_entries; if (!cmd_desc[i].length) continue; @@ -358,7 +362,8 @@ int cam_isp_add_command_buffers( if (split_id == CAM_ISP_HW_SPLIT_LEFT) { struct cam_isp_generic_blob_info blob_info; - prepare->num_hw_update_entries = num_ent; + prepare->hw_update_info[base_idx].num_hw_entries + = num_ent; blob_info.prepare = prepare; blob_info.base_info = base_info; blob_info.kmd_buf_info = kmd_buf_info; @@ -374,14 +379,15 @@ int cam_isp_add_command_buffers( return rc; } hw_entry[num_ent].flags = CAM_ISP_IQ_BL; - num_ent = prepare->num_hw_update_entries; + num_ent = hw_info[base_idx].num_hw_entries; } break; case CAM_ISP_PACKET_META_GENERIC_BLOB_RIGHT: if (split_id == CAM_ISP_HW_SPLIT_RIGHT) { struct cam_isp_generic_blob_info blob_info; - prepare->num_hw_update_entries = num_ent; + prepare->hw_update_info[base_idx].num_hw_entries + = num_ent; blob_info.prepare = prepare; blob_info.base_info = base_info; blob_info.kmd_buf_info = kmd_buf_info; @@ -397,13 +403,14 @@ int cam_isp_add_command_buffers( return rc; } hw_entry[num_ent].flags = CAM_ISP_IQ_BL; - num_ent = prepare->num_hw_update_entries; + num_ent = hw_info[base_idx].num_hw_entries; } break; case CAM_ISP_PACKET_META_GENERIC_BLOB_COMMON: { struct cam_isp_generic_blob_info blob_info; - prepare->num_hw_update_entries = num_ent; + prepare->hw_update_info[base_idx].num_hw_entries = + num_ent; blob_info.prepare = prepare; blob_info.base_info = base_info; blob_info.kmd_buf_info = kmd_buf_info; @@ -418,7 +425,7 @@ int cam_isp_add_command_buffers( return rc; } hw_entry[num_ent].flags = CAM_ISP_IQ_BL; - num_ent = prepare->num_hw_update_entries; + num_ent = hw_info[base_idx].num_hw_entries; } break; case CAM_ISP_PACKET_META_REG_DUMP_ON_FLUSH: @@ -448,7 +455,8 @@ int cam_isp_add_command_buffers( cmd_meta_data); return -EINVAL; } - prepare->num_hw_update_entries = num_ent; + prepare->hw_update_info[base_idx].num_hw_entries + = num_ent; } return rc; @@ -457,7 +465,7 @@ int cam_isp_add_command_buffers( int cam_isp_add_io_buffers( int iommu_hdl, int sec_iommu_hdl, - struct cam_hw_prepare_update_args *prepare, + struct cam_isp_hw_update_args *prepare, uint32_t base_idx, struct cam_kmd_buf_info *kmd_buf_info, struct cam_isp_hw_mgr_res *res_list_isp_out, @@ -473,6 +481,7 @@ int cam_isp_add_io_buffers( struct cam_isp_hw_mgr_res *hw_mgr_res; struct cam_isp_hw_get_cmd_update update_buf; struct cam_isp_hw_get_wm_update wm_update; + struct cam_hw_update_entry *hw_entry; struct cam_isp_hw_get_wm_update bus_rd_update; struct cam_hw_fence_map_entry *out_map_entries; struct cam_hw_fence_map_entry *in_map_entries; @@ -495,12 +504,14 @@ int cam_isp_add_io_buffers( num_in_buf = 0; io_cfg_used_bytes = 0; prepare->pf_data->packet = prepare->packet; + hw_entry = prepare->hw_update_info[base_idx].hw_entries; + num_ent = prepare->hw_update_info[base_idx].num_hw_entries; /* Max one hw entries required for each base */ - if (prepare->num_hw_update_entries + 1 >= + if (num_ent + 1 >= prepare->max_hw_update_entries) { CAM_ERR(CAM_ISP, "Insufficient HW entries :%d %d", - prepare->num_hw_update_entries, + prepare->hw_update_info[base_idx].num_hw_entries, prepare->max_hw_update_entries); return -EINVAL; } @@ -852,25 +863,21 @@ int cam_isp_add_io_buffers( io_cfg_used_bytes, fill_fence); if (io_cfg_used_bytes) { /* Update the HW entries */ - num_ent = prepare->num_hw_update_entries; - prepare->hw_update_entries[num_ent].handle = - kmd_buf_info->handle; - prepare->hw_update_entries[num_ent].len = io_cfg_used_bytes; - prepare->hw_update_entries[num_ent].offset = - kmd_buf_info->offset; - prepare->hw_update_entries[num_ent].flags = - CAM_ISP_IOCFG_BL; + hw_entry[num_ent].handle = kmd_buf_info->handle; + hw_entry[num_ent].len = io_cfg_used_bytes; + hw_entry[num_ent].offset = kmd_buf_info->offset; + hw_entry[num_ent].flags = CAM_ISP_IOCFG_BL; CAM_DBG(CAM_ISP, "num_ent=%d handle=0x%x, len=%u, offset=%u", num_ent, - prepare->hw_update_entries[num_ent].handle, - prepare->hw_update_entries[num_ent].len, - prepare->hw_update_entries[num_ent].offset); + hw_entry[num_ent].handle, + hw_entry[num_ent].len, + hw_entry[num_ent].offset); num_ent++; kmd_buf_info->used_bytes += io_cfg_used_bytes; kmd_buf_info->offset += io_cfg_used_bytes; - prepare->num_hw_update_entries = num_ent; + prepare->hw_update_info[base_idx].num_hw_entries = num_ent; } if (fill_fence) { @@ -881,9 +888,8 @@ int cam_isp_add_io_buffers( return rc; } - int cam_isp_add_reg_update( - struct cam_hw_prepare_update_args *prepare, + struct cam_isp_hw_update_args *prepare, struct list_head *res_list_isp_src, uint32_t base_idx, struct cam_kmd_buf_info *kmd_buf_info) @@ -895,12 +901,13 @@ int cam_isp_add_reg_update( struct cam_isp_hw_get_cmd_update get_regup; uint32_t kmd_buf_remain_size, num_ent, i, reg_update_size; - hw_entry = prepare->hw_update_entries; + hw_entry = prepare->hw_update_info[base_idx].hw_entries; + num_ent = prepare->hw_update_info[base_idx].num_hw_entries; + /* Max one hw entries required for each base */ - if (prepare->num_hw_update_entries + 1 >= - prepare->max_hw_update_entries) { + if (num_ent + 1 >= prepare->max_hw_update_entries) { CAM_ERR(CAM_ISP, "Insufficient HW entries :%d %d", - prepare->num_hw_update_entries, + num_ent, prepare->max_hw_update_entries); return -EINVAL; } @@ -946,35 +953,32 @@ int cam_isp_add_reg_update( if (rc) return rc; - CAM_DBG(CAM_ISP, "Reg update added for res %d hw_id %d", - res->res_type, res->hw_intf->hw_idx); + CAM_DBG(CAM_ISP, + "Reg update added for res %d hw_id %d cdm_idx %d", + res->res_id, res->hw_intf->hw_idx, base_idx); reg_update_size += get_regup.cmd.used_bytes; } } if (reg_update_size) { /* Update the HW entries */ - num_ent = prepare->num_hw_update_entries; - prepare->hw_update_entries[num_ent].handle = - kmd_buf_info->handle; - prepare->hw_update_entries[num_ent].len = reg_update_size; - prepare->hw_update_entries[num_ent].offset = - kmd_buf_info->offset; + hw_entry[num_ent].handle = kmd_buf_info->handle; + hw_entry[num_ent].len = reg_update_size; + hw_entry[num_ent].offset = kmd_buf_info->offset; /* Marking reg update as IOCFG to reapply on bubble */ - prepare->hw_update_entries[num_ent].flags = - CAM_ISP_IOCFG_BL; + hw_entry[num_ent].flags = CAM_ISP_IOCFG_BL; CAM_DBG(CAM_ISP, "num_ent=%d handle=0x%x, len=%u, offset=%u", num_ent, - prepare->hw_update_entries[num_ent].handle, - prepare->hw_update_entries[num_ent].len, - prepare->hw_update_entries[num_ent].offset); + hw_entry[num_ent].handle, + hw_entry[num_ent].len, + hw_entry[num_ent].offset); num_ent++; kmd_buf_info->used_bytes += reg_update_size; kmd_buf_info->offset += reg_update_size; - prepare->num_hw_update_entries = num_ent; + prepare->hw_update_info[base_idx].num_hw_entries = num_ent; /* reg update is success return status 0 */ rc = 0; } @@ -983,7 +987,7 @@ int cam_isp_add_reg_update( } int cam_isp_add_go_cmd( - struct cam_hw_prepare_update_args *prepare, + struct cam_isp_hw_update_args *prepare, struct list_head *res_list_isp_rd, uint32_t base_idx, struct cam_kmd_buf_info *kmd_buf_info) @@ -995,11 +999,13 @@ int cam_isp_add_go_cmd( struct cam_isp_hw_get_cmd_update get_regup; uint32_t kmd_buf_remain_size, num_ent, i, reg_update_size; - hw_entry = prepare->hw_update_entries; - if (prepare->num_hw_update_entries + 1 >= - prepare->max_hw_update_entries) { - CAM_ERR(CAM_ISP, "Insufficient HW entries current: %d max: %d", - prepare->num_hw_update_entries, + hw_entry = prepare->hw_update_info[base_idx].hw_entries; + num_ent = prepare->hw_update_info[base_idx].num_hw_entries; + + /* Max one hw entries required for each base */ + if (num_ent + 1 >= prepare->max_hw_update_entries) { + CAM_ERR(CAM_ISP, "Insufficient HW entries :%d %d", + num_ent, prepare->max_hw_update_entries); return -EINVAL; } @@ -1052,26 +1058,236 @@ int cam_isp_add_go_cmd( if (reg_update_size) { /* Update the HW entries */ - num_ent = prepare->num_hw_update_entries; - prepare->hw_update_entries[num_ent].handle = - kmd_buf_info->handle; - prepare->hw_update_entries[num_ent].len = reg_update_size; - prepare->hw_update_entries[num_ent].offset = - kmd_buf_info->offset; + hw_entry[num_ent].handle = kmd_buf_info->handle; + hw_entry[num_ent].len = reg_update_size; + hw_entry[num_ent].offset = kmd_buf_info->offset; - prepare->hw_update_entries[num_ent].flags = - CAM_ISP_IOCFG_BL; + hw_entry[num_ent].flags = CAM_ISP_IOCFG_BL; CAM_DBG(CAM_ISP, "num_ent=%d handle=0x%x, len=%u, offset=%u", num_ent, - prepare->hw_update_entries[num_ent].handle, - prepare->hw_update_entries[num_ent].len, - prepare->hw_update_entries[num_ent].offset); + hw_entry[num_ent].handle, + hw_entry[num_ent].len, + hw_entry[num_ent].offset); num_ent++; kmd_buf_info->used_bytes += reg_update_size; kmd_buf_info->offset += reg_update_size; - prepare->num_hw_update_entries = num_ent; + prepare->hw_update_info[base_idx].num_hw_entries = num_ent; + + rc = 0; + } + + return rc; +} + +int cam_isp_add_comp_wait( + struct cam_isp_hw_update_args *prepare, + struct list_head *res_list_isp_src, + uint32_t base_idx, + struct cam_kmd_buf_info *kmd_buf_info) +{ + int rc = -EINVAL; + struct cam_isp_hw_mgr_res *hw_mgr_res; + struct cam_hw_update_entry *hw_entry; + struct cam_isp_hw_get_cmd_update add_wait; + struct cam_hw_intf *hw_intf; + bool hw_res_valid = false; + uint32_t kmd_buf_remain_size, num_ent, add_wait_size; + + hw_entry = prepare->hw_update_info[base_idx].hw_entries; + num_ent = prepare->hw_update_info[base_idx].num_hw_entries; + + /* Max one hw entries required for each base */ + if (num_ent >= prepare->max_hw_update_entries) { + CAM_ERR(CAM_ISP, "Insufficient HW entries"); + return -EINVAL; + } + + add_wait_size = 0; + list_for_each_entry(hw_mgr_res, res_list_isp_src, list) { + if (hw_mgr_res->res_type == CAM_ISP_RESOURCE_UNINT) + continue; + if (hw_mgr_res->hw_res[CAM_ISP_HW_SPLIT_LEFT] && + hw_mgr_res->hw_res[CAM_ISP_HW_SPLIT_RIGHT]) { + hw_res_valid = true; + break; + } + } + + if (!hw_mgr_res || !hw_res_valid) { + CAM_ERR(CAM_ISP, "No src with multi_vfe config"); + return -EINVAL; + } + + hw_intf = hw_mgr_res->hw_res[CAM_ISP_HW_SPLIT_LEFT]->hw_intf; + + if (kmd_buf_info->size > (kmd_buf_info->used_bytes + + add_wait_size)) { + kmd_buf_remain_size = kmd_buf_info->size - + (kmd_buf_info->used_bytes + add_wait_size); + } else { + CAM_ERR(CAM_ISP, "no free mem %d %d %d", + base_idx, kmd_buf_info->size, + kmd_buf_info->used_bytes + + add_wait_size); + rc = -EINVAL; + return rc; + } + + add_wait.cmd.cmd_buf_addr = kmd_buf_info->cpu_addr + + kmd_buf_info->used_bytes/4 + + add_wait_size/4; + add_wait.cmd.size = kmd_buf_remain_size; + add_wait.cmd_type = CAM_ISP_HW_CMD_ADD_WAIT; + add_wait.res = hw_mgr_res->hw_res[CAM_ISP_HW_SPLIT_LEFT]; + + rc = hw_intf->hw_ops.process_cmd( + hw_intf->hw_priv, + CAM_ISP_HW_CMD_ADD_WAIT, + &add_wait, + sizeof(struct cam_isp_hw_get_cmd_update)); + + if (rc) { + CAM_ERR(CAM_ISP, + "wait_comp_event addition failed for dual vfe"); + return rc; + } + + add_wait_size += add_wait.cmd.used_bytes; + if (add_wait_size) { + /* Update the HW entries */ + hw_entry[num_ent].handle = + kmd_buf_info->handle; + hw_entry[num_ent].len = + add_wait_size; + hw_entry[num_ent].offset = + kmd_buf_info->offset; + hw_entry[num_ent].flags = CAM_ISP_IOCFG_BL; + CAM_DBG(CAM_ISP, + "num_ent=%d handle=0x%x, len=%u, offset=%u", + num_ent, + hw_entry[num_ent].handle, + hw_entry[num_ent].len, + hw_entry[num_ent].offset); + num_ent++; + + kmd_buf_info->used_bytes += add_wait_size; + kmd_buf_info->offset += add_wait_size; + prepare->hw_update_info[base_idx].num_hw_entries + = num_ent; + /* add wait_comp_event is success return status 0 */ + rc = 0; + } + + return rc; +} + +int cam_isp_add_wait_trigger( + struct cam_isp_hw_update_args *prepare, + struct list_head *res_list_isp_src, + uint32_t base_idx, + struct cam_kmd_buf_info *kmd_buf_info, + bool trigger_cdm_en) +{ + int rc = -EINVAL; + struct cam_isp_hw_mgr_res *hw_mgr_res; + struct cam_hw_update_entry *hw_entry; + struct cam_isp_hw_get_cmd_update add_trigger; + struct cam_hw_intf *hw_intf; + bool hw_res_valid = false; + uint32_t kmd_buf_remain_size, num_ent, add_trigger_size; + + hw_entry = prepare->hw_update_info[base_idx].hw_entries; + num_ent = prepare->hw_update_info[base_idx].num_hw_entries; + + /* Max one hw entries required for each base */ + if (num_ent + 1 >= + prepare->max_hw_update_entries) { + CAM_ERR(CAM_ISP, "Insufficient HW entries :%d %d"); + return -EINVAL; + } + + add_trigger_size = 0; + + list_for_each_entry(hw_mgr_res, res_list_isp_src, list) { + if (hw_mgr_res->res_type == CAM_ISP_RESOURCE_UNINT) + continue; + if (hw_mgr_res->hw_res[CAM_ISP_HW_SPLIT_LEFT] && + hw_mgr_res->hw_res[CAM_ISP_HW_SPLIT_RIGHT]) { + hw_res_valid = true; + break; + } + } + + if (!hw_mgr_res || !hw_res_valid) { + CAM_ERR(CAM_ISP, "No src with multi_vfe config"); + return -EINVAL; + } + + hw_intf = hw_mgr_res->hw_res[CAM_ISP_HW_SPLIT_RIGHT]->hw_intf; + + if (kmd_buf_info->size > (kmd_buf_info->used_bytes + + add_trigger_size)) { + kmd_buf_remain_size = kmd_buf_info->size - + (kmd_buf_info->used_bytes + add_trigger_size); + } else { + CAM_ERR(CAM_ISP, "no free mem %d %d %d", + base_idx, kmd_buf_info->size, + kmd_buf_info->used_bytes + + add_trigger_size); + rc = -EINVAL; + return rc; + } + + add_trigger.cmd.cmd_buf_addr = kmd_buf_info->cpu_addr + + kmd_buf_info->used_bytes/4 + + add_trigger_size/4; + add_trigger.cmd.size = kmd_buf_remain_size; + add_trigger.cmd_type = CAM_ISP_HW_CMD_ADD_WAIT_TRIGGER; + add_trigger.res = hw_mgr_res->hw_res[CAM_ISP_HW_SPLIT_RIGHT]; + + if (trigger_cdm_en) + add_trigger.trigger_cdm_en = true; + else + add_trigger.trigger_cdm_en = false; + + rc = hw_intf->hw_ops.process_cmd( + hw_intf->hw_priv, + CAM_ISP_HW_CMD_ADD_WAIT_TRIGGER, + &add_trigger, + sizeof(struct cam_isp_hw_get_cmd_update)); + + if (rc) { + CAM_ERR(CAM_ISP, + "wait_trigger_event addition failed for dual vfe"); + return rc; + } + + add_trigger_size += add_trigger.cmd.used_bytes; + + if (add_trigger_size) { + /* Update the HW entries */ + hw_entry[num_ent].handle = + kmd_buf_info->handle; + hw_entry[num_ent].len = + add_trigger_size; + hw_entry[num_ent].offset = + kmd_buf_info->offset; + hw_entry[num_ent].flags = CAM_ISP_IOCFG_BL; + CAM_DBG(CAM_ISP, + "num_ent=%d handle=0x%x, len=%u, offset=%u", + num_ent, + hw_entry[num_ent].handle, + hw_entry[num_ent].len, + hw_entry[num_ent].offset); + num_ent++; + + kmd_buf_info->used_bytes += add_trigger_size; + kmd_buf_info->offset += add_trigger_size; + prepare->hw_update_info[base_idx].num_hw_entries + = num_ent; + /* add wait trigger is success return status 0 */ rc = 0; } diff --git a/drivers/cam_isp/isp_hw_mgr/hw_utils/include/cam_isp_packet_parser.h b/drivers/cam_isp/isp_hw_mgr/hw_utils/include/cam_isp_packet_parser.h index 92632b689a..3c13ee52ae 100644 --- a/drivers/cam_isp/isp_hw_mgr/hw_utils/include/cam_isp_packet_parser.h +++ b/drivers/cam_isp/isp_hw_mgr/hw_utils/include/cam_isp_packet_parser.h @@ -29,7 +29,7 @@ enum cam_isp_cdm_bl_type { * @kmd_buf_info: Kmd buffer to store the custom cmd data */ struct cam_isp_generic_blob_info { - struct cam_hw_prepare_update_args *prepare; + struct cam_isp_hw_update_args *prepare; struct cam_isp_ctx_base_info *base_info; struct cam_kmd_buf_info *kmd_buf_info; }; @@ -59,12 +59,11 @@ struct cam_isp_frame_header_info { * @base_idx: Base or dev index of the IFE/VFE HW instance for * which change change base need to be added * @kmd_buf_info: Kmd buffer to store the change base command - * * @return: 0 for success * -EINVAL for Fail */ int cam_isp_add_change_base( - struct cam_hw_prepare_update_args *prepare, + struct cam_isp_hw_update_args *prepare, struct list_head *res_list_isp_src, uint32_t base_idx, struct cam_kmd_buf_info *kmd_buf_info); @@ -116,7 +115,7 @@ int cam_isp_add_cmd_buf_update( * Negative for Failure */ int cam_isp_add_command_buffers( - struct cam_hw_prepare_update_args *prepare, + struct cam_isp_hw_update_args *prepare, struct cam_kmd_buf_info *kmd_buf_info, struct cam_isp_ctx_base_info *base_info, cam_packet_generic_blob_handler blob_handler_cb, @@ -147,7 +146,7 @@ int cam_isp_add_command_buffers( int cam_isp_add_io_buffers( int iommu_hdl, int sec_iommu_hdl, - struct cam_hw_prepare_update_args *prepare, + struct cam_isp_hw_update_args *prepare, uint32_t base_idx, struct cam_kmd_buf_info *kmd_buf_info, struct cam_isp_hw_mgr_res *res_list_isp_out, @@ -171,11 +170,56 @@ int cam_isp_add_io_buffers( * -EINVAL for Fail */ int cam_isp_add_reg_update( - struct cam_hw_prepare_update_args *prepare, + struct cam_isp_hw_update_args *prepare, struct list_head *res_list_isp_src, uint32_t base_idx, struct cam_kmd_buf_info *kmd_buf_info); +/* + * cam_isp_add_comp_wait() + * + * @brief Add reg update in the hw entries list + * processe the isp source list get the reg update from + * ISP HW instance + * + * @prepare: Contain the packet and HW update variables + * @res_list_isp_src: Resource list for IFE/VFE source + * @base_idx: Base or dev index of the IFE/VFE HW instance + * @kmd_buf_info: Kmd buffer to store the change base command + * + * @return: 0 for success + * -EINVAL for Fail + */ +int cam_isp_add_comp_wait( + struct cam_isp_hw_update_args *prepare, + struct list_head *res_list_isp_src, + uint32_t base_idx, + struct cam_kmd_buf_info *kmd_buf_info); + +/* + * cam_isp_add_wait_trigger() + * + * @brief Add reg update in the hw entries list + * processe the isp source list get the reg update from + * ISP HW instance + * + * @prepare: Contain the packet and HW update variables + * @res_list_isp_src: Resource list for IFE/VFE source + * @base_idx: Base or dev index of the IFE/VFE HW instance + * @kmd_buf_info: Kmd buffer to store the change base command + * @trigger_cdm_en Used to reset and set trigger_cdm_events register + * + * @return: 0 for success + * -EINVAL for Fail + */ +int cam_isp_add_wait_trigger( + struct cam_isp_hw_update_args *prepare, + struct list_head *res_list_isp_src, + uint32_t base_idx, + struct cam_kmd_buf_info *kmd_buf_info, + bool trigger_cdm_en); + + /* * cam_isp_add_go_cmd() * @@ -189,10 +233,9 @@ int cam_isp_add_reg_update( * -EINVAL for Fail */ int cam_isp_add_go_cmd( - struct cam_hw_prepare_update_args *prepare, + struct cam_isp_hw_update_args *prepare, struct list_head *res_list_isp_rd, uint32_t base_idx, struct cam_kmd_buf_info *kmd_buf_info); - #endif /*_CAM_ISP_HW_PARSER_H */ diff --git a/drivers/cam_isp/isp_hw_mgr/include/cam_isp_hw_mgr_intf.h b/drivers/cam_isp/isp_hw_mgr/include/cam_isp_hw_mgr_intf.h index 9ee05756c3..32f38d81b5 100644 --- a/drivers/cam_isp/isp_hw_mgr/include/cam_isp_hw_mgr_intf.h +++ b/drivers/cam_isp/isp_hw_mgr/include/cam_isp_hw_mgr_intf.h @@ -22,6 +22,13 @@ /* Appliacble vote paths for dual ife, based on no. of UAPI definitions */ #define CAM_ISP_MAX_PER_PATH_VOTES 30 + +/* + * Maximum configuration entry size - This is based on the + * worst case DUAL IFE use case plus some margin. + */ + #define CAM_ISP_CTX_CFG_MAX 25 + /** * enum cam_isp_hw_event_type - Collection of the ISP hardware events */ @@ -71,18 +78,7 @@ struct cam_isp_stop_args { bool stop_only; }; -/** - * struct cam_isp_start_args - isp hardware start arguments - * - * @config_args: Hardware configuration commands. - * @start_only Send start only to hw drivers. No init to - * be done. - * - */ -struct cam_isp_start_args { - struct cam_hw_config_args hw_config; - bool start_only; -}; + /** * struct cam_isp_bw_config_internal_v2 - Bandwidth configuration @@ -261,6 +257,106 @@ struct cam_isp_hw_cmd_args { } u; }; +/** + * struct cam_isp_hw_update_entry_info - hardware config info + * + * @hw_update_entries Entry for hardware config + * @num_hw_update_entries: Number of IFE hw + * + */ +struct cam_isp_hw_update_entry_info { + struct cam_hw_update_entry *hw_entries; + uint32_t num_hw_entries; +}; + +/** + * struct cam_isp_hw_update_info - hardware config info + * + * @hw_update_entries Entry for hardware config + * @num_hw_update_entries: number of IFE hw + * + */ + +struct cam_isp_hw_update_info { + struct cam_hw_update_entry hw_entries[CAM_ISP_CTX_CFG_MAX]; + uint32_t num_hw_entries; +}; + +/** + * struct cam_isp_hw_update_args - Payload for prepare command + * + * @packet: CSL packet from user mode driver + * @remain_len Remaining length of CPU buffer after config offset + * @ctxt_to_hw_map: HW context from the acquire + * @max_hw_update_entries: Maximum hardware update entries supported + * @hw_update_info: Actual hardware update configuration (returned) + * @max_out_map_entries: Maximum output fence mapping supported + * @out_map_entries: Actual output fence mapping list (returned) + * @num_out_map_entries: Number of actual output fence mapping (returned) + * @max_in_map_entries: Maximum input fence mapping supported + * @in_map_entries: Actual input fence mapping list (returned) + * @num_in_map_entries: Number of acutal input fence mapping (returned) + * @priv: Private pointer of hw update + * @pf_data: Debug data for page fault + * + */ + +struct cam_isp_hw_update_args { + struct cam_packet *packet; + uint32_t remain_len; + void *ctxt_to_hw_map; + uint32_t max_hw_update_entries; + struct cam_isp_hw_update_entry_info hw_update_info[CAM_IFE_HW_NUM_MAX]; + uint32_t max_out_map_entries; + struct cam_hw_fence_map_entry *out_map_entries; + uint32_t num_out_map_entries; + uint32_t max_in_map_entries; + struct cam_hw_fence_map_entry *in_map_entries; + uint32_t num_in_map_entries; + void *priv; + struct cam_hw_mgr_dump_pf_data *pf_data; + struct cam_cmd_buf_desc reg_dump_buf_desc[ + CAM_REG_DUMP_MAX_BUF_ENTRIES]; + uint32_t num_reg_dump_buf; +}; + +/** + * struct cam_isp_hw_config_args - Payload for config command + * + * @ctxt_to_hw_map: HW context from the acquire + * @hw_update_info: Hardware update info for every IFE + * @out_map_entries: Out map info + * @num_out_map_entries: Number of out map entries + * @priv: Private pointer + * @request_id: Request ID + * @init_packet: check init packet or update packet + * @reapply: check if current req is reapplied + * + */ + +struct cam_isp_hw_config_args { + void *ctxt_to_hw_map; + struct cam_isp_hw_update_entry_info hw_update_info[CAM_IFE_HW_NUM_MAX]; + struct cam_hw_fence_map_entry *out_map_entries; + uint32_t num_out_map_entries; + void *priv; + uint64_t request_id; + bool init_packet; + bool reapply; +}; + +/** + * struct cam_isp_start_args - isp hardware start arguments + * + * @config_args: Hardware configuration commands. + * @start_only Send start only to hw drivers. No init to + * be done. + * + */ +struct cam_isp_start_args { + struct cam_isp_hw_config_args hw_config; + bool start_only; +}; /** * cam_isp_hw_mgr_init() diff --git a/drivers/cam_isp/isp_hw_mgr/isp_hw/include/cam_isp_hw.h b/drivers/cam_isp/isp_hw_mgr/isp_hw/include/cam_isp_hw.h index b55af3ec2e..b48416c355 100644 --- a/drivers/cam_isp/isp_hw_mgr/isp_hw/include/cam_isp_hw.h +++ b/drivers/cam_isp/isp_hw_mgr/isp_hw/include/cam_isp_hw.h @@ -110,6 +110,8 @@ enum cam_isp_hw_cmd_type { CAM_ISP_HW_CMD_CORE_CONFIG, CAM_ISP_HW_CMD_WM_CONFIG_UPDATE, CAM_ISP_HW_CMD_CSID_QCFA_SUPPORTED, + CAM_ISP_HW_CMD_ADD_WAIT, + CAM_ISP_HW_CMD_ADD_WAIT_TRIGGER, CAM_ISP_HW_CMD_QUERY_REGSPACE_DATA, CAM_ISP_HW_CMD_TPG_PHY_CLOCK_UPDATE, CAM_ISP_HW_CMD_GET_IRQ_REGISTER_DUMP, @@ -245,6 +247,7 @@ struct cam_isp_hw_get_cmd_update { struct cam_isp_hw_get_wm_update *wm_update; struct cam_isp_hw_get_wm_update *rm_update; }; + bool trigger_cdm_en; }; /* diff --git a/drivers/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/cam_vfe_core.c b/drivers/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/cam_vfe_core.c index 13e3263ff2..7b991a3168 100644 --- a/drivers/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/cam_vfe_core.c +++ b/drivers/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/cam_vfe_core.c @@ -596,6 +596,8 @@ int cam_vfe_process_cmd(void *hw_priv, uint32_t cmd_type, case CAM_ISP_HW_CMD_CORE_CONFIG: case CAM_ISP_HW_CMD_BW_UPDATE_V2: case CAM_ISP_HW_CMD_DUMP_HW: + case CAM_ISP_HW_CMD_ADD_WAIT: + case CAM_ISP_HW_CMD_ADD_WAIT_TRIGGER: rc = core_info->vfe_top->hw_ops.process_cmd( core_info->vfe_top->top_priv, cmd_type, cmd_args, arg_size); diff --git a/drivers/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe_top/cam_vfe_top_ver2.c b/drivers/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe_top/cam_vfe_top_ver2.c index 6774be8cda..b174c21d8b 100644 --- a/drivers/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe_top/cam_vfe_top_ver2.c +++ b/drivers/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe_top/cam_vfe_top_ver2.c @@ -179,6 +179,92 @@ static int cam_vfe_top_mux_get_reg_update( return -EINVAL; } +static int cam_vfe_top_wait_comp_event(struct cam_vfe_top_ver2_priv *top_priv, + void *cmd_args, uint32_t arg_size) +{ + uint32_t size = 0; + struct cam_isp_hw_get_cmd_update *cdm_args = cmd_args; + struct cam_cdm_utils_ops *cdm_util_ops = NULL; + + if (arg_size != sizeof(struct cam_isp_hw_get_cmd_update)) { + CAM_ERR(CAM_ISP, "Error! Invalid cmd size"); + return -EINVAL; + } + + if (!cdm_args || !cdm_args->res || !top_priv || + !top_priv->common_data.soc_info) { + CAM_ERR(CAM_ISP, "Error! Invalid args"); + return -EINVAL; + } + + cdm_util_ops = + (struct cam_cdm_utils_ops *)cdm_args->res->cdm_ops; + + if (!cdm_util_ops) { + CAM_ERR(CAM_ISP, "Invalid CDM ops"); + return -EINVAL; + } + + size = cdm_util_ops->cdm_required_size_comp_wait(); + /* since cdm returns dwords, we need to convert it into bytes */ + if ((size * 4) > cdm_args->cmd.size) { + CAM_ERR(CAM_ISP, "buf size:%d is not sufficient, expected: %d", + cdm_args->cmd.size, size); + return -EINVAL; + } + + cdm_util_ops->cdm_write_wait_comp_event(cdm_args->cmd.cmd_buf_addr, + 0, 0x2); + cdm_args->cmd.used_bytes = (size * 4); + + return 0; +} + +static int cam_vfe_top_add_wait_trigger(struct cam_vfe_top_ver2_priv *top_priv, + void *cmd_args, uint32_t arg_size) +{ + uint32_t size = 0; + uint32_t reg_val_pair[2]; + struct cam_isp_hw_get_cmd_update *cdm_args = cmd_args; + struct cam_cdm_utils_ops *cdm_util_ops = NULL; + + if (arg_size != sizeof(struct cam_isp_hw_get_cmd_update)) { + CAM_ERR(CAM_ISP, "Error! Invalid cmd size"); + return -EINVAL; + } + + if (!cdm_args || !cdm_args->res || !top_priv || + !top_priv->common_data.soc_info) { + CAM_ERR(CAM_ISP, "Error! Invalid args"); + return -EINVAL; + } + + cdm_util_ops = + (struct cam_cdm_utils_ops *)cdm_args->res->cdm_ops; + + if (!cdm_util_ops) { + CAM_ERR(CAM_ISP, "Invalid CDM ops"); + return -EINVAL; + } + + size = cdm_util_ops->cdm_required_size_reg_random(1); + /* since cdm returns dwords, we need to convert it into bytes */ + if ((size * 4) > cdm_args->cmd.size) { + CAM_ERR(CAM_ISP, "buf size:%d is not sufficient, expected: %d", + cdm_args->cmd.size, size); + return -EINVAL; + } + + reg_val_pair[0] = 0x90; + reg_val_pair[1] = 0x1; + + cdm_util_ops->cdm_write_regrandom(cdm_args->cmd.cmd_buf_addr, + 1, reg_val_pair); + cdm_args->cmd.used_bytes = (size * 4); + + return 0; +} + int cam_vfe_top_get_hw_caps(void *device_priv, void *get_hw_cap_args, uint32_t arg_size) { @@ -644,6 +730,12 @@ int cam_vfe_top_process_cmd(void *device_priv, uint32_t cmd_type, rc = cam_vfe_hw_dump(top_priv, cmd_args, arg_size); break; + case CAM_ISP_HW_CMD_ADD_WAIT: + rc = cam_vfe_top_wait_comp_event(top_priv, cmd_args, arg_size); + break; + case CAM_ISP_HW_CMD_ADD_WAIT_TRIGGER: + rc = cam_vfe_top_add_wait_trigger(top_priv, cmd_args, arg_size); + break; default: rc = -EINVAL; CAM_ERR(CAM_ISP, "Error! Invalid cmd:%d", cmd_type); diff --git a/drivers/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe_top/cam_vfe_top_ver3.c b/drivers/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe_top/cam_vfe_top_ver3.c index dc15cab5e2..a750e7d2ee 100644 --- a/drivers/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe_top/cam_vfe_top_ver3.c +++ b/drivers/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe_top/cam_vfe_top_ver3.c @@ -16,6 +16,7 @@ #define CAM_VFE_HW_RESET_HW_VAL 0x00010000 #define CAM_VFE_LITE_HW_RESET_AND_REG_VAL 0x00000002 #define CAM_VFE_LITE_HW_RESET_HW_VAL 0x00000001 +#define CAM_CDM_WAIT_COMP_EVENT_BIT 0x2 struct cam_vfe_top_ver3_common_data { struct cam_hw_soc_info *soc_info; @@ -212,6 +213,102 @@ static int cam_vfe_top_ver3_mux_get_reg_update( return -EINVAL; } +static int cam_vfe_top_wait_comp_event(struct cam_vfe_top_ver3_priv *top_priv, + void *cmd_args, uint32_t arg_size) +{ + uint32_t size = 0; + struct cam_isp_hw_get_cmd_update *cdm_args = cmd_args; + struct cam_cdm_utils_ops *cdm_util_ops = NULL; + + if (arg_size != sizeof(struct cam_isp_hw_get_cmd_update)) { + CAM_ERR(CAM_ISP, "Error, Invalid arg size = %d expected = %d", + arg_size, sizeof(struct cam_isp_hw_get_cmd_update)); + return -EINVAL; + } + + if (!cdm_args || !cdm_args->res || !top_priv || + !top_priv->common_data.soc_info) { + CAM_ERR(CAM_ISP, "Error, Invalid args"); + return -EINVAL; + } + + cdm_util_ops = + (struct cam_cdm_utils_ops *)cdm_args->res->cdm_ops; + + if (!cdm_util_ops) { + CAM_ERR(CAM_ISP, "Invalid CDM ops"); + return -EINVAL; + } + + size = cdm_util_ops->cdm_required_size_comp_wait(); + /* since cdm returns dwords, we need to convert it into bytes */ + if ((size * 4) > cdm_args->cmd.size) { + CAM_ERR(CAM_ISP, "buf size:%d is not sufficient, expected: %d", + cdm_args->cmd.size, size); + return -EINVAL; + } + + cdm_util_ops->cdm_write_wait_comp_event(cdm_args->cmd.cmd_buf_addr, + 0, CAM_CDM_WAIT_COMP_EVENT_BIT); + cdm_args->cmd.used_bytes = (size * 4); + + return 0; +} + +static int cam_vfe_top_add_wait_trigger(struct cam_vfe_top_ver3_priv *top_priv, + void *cmd_args, uint32_t arg_size) +{ + uint32_t size = 0; + uint32_t reg_val_pair[2]; + struct cam_isp_hw_get_cmd_update *cdm_args = cmd_args; + struct cam_cdm_utils_ops *cdm_util_ops = NULL; + struct cam_vfe_top_ver3_reg_offset_common *reg_common = NULL; + uint32_t set_cdm_trigger_event; + + if (arg_size != sizeof(struct cam_isp_hw_get_cmd_update)) { + CAM_ERR(CAM_ISP, "Error, Invalid arg size = %d expected = %d", + arg_size, sizeof(struct cam_isp_hw_get_cmd_update)); + return -EINVAL; + } + + if (!cdm_args || !cdm_args->res || !top_priv || + !top_priv->common_data.soc_info) { + CAM_ERR(CAM_ISP, "Error, Invalid args"); + return -EINVAL; + } + + cdm_util_ops = + (struct cam_cdm_utils_ops *)cdm_args->res->cdm_ops; + + if (!cdm_util_ops) { + CAM_ERR(CAM_ISP, "Invalid CDM ops"); + return -EINVAL; + } + + size = cdm_util_ops->cdm_required_size_reg_random(1); + /* since cdm returns dwords, we need to convert it into bytes */ + if ((size * 4) > cdm_args->cmd.size) { + CAM_ERR(CAM_ISP, "buf size:%d is not sufficient, expected: %d", + cdm_args->cmd.size, size); + return -EINVAL; + } + + if (cdm_args->trigger_cdm_en == true) + set_cdm_trigger_event = 1; + else + set_cdm_trigger_event = 0; + + reg_common = top_priv->common_data.common_reg; + reg_val_pair[0] = reg_common->trigger_cdm_events; + reg_val_pair[1] = set_cdm_trigger_event; + + cdm_util_ops->cdm_write_regrandom(cdm_args->cmd.cmd_buf_addr, + 1, reg_val_pair); + cdm_args->cmd.used_bytes = (size * 4); + + return 0; +} + int cam_vfe_top_ver3_get_hw_caps(void *device_priv, void *get_hw_cap_args, uint32_t arg_size) { @@ -561,6 +658,12 @@ int cam_vfe_top_ver3_process_cmd(void *device_priv, uint32_t cmd_type, case CAM_ISP_HW_CMD_CORE_CONFIG: rc = cam_vfe_core_config_control(top_priv, cmd_args, arg_size); break; + case CAM_ISP_HW_CMD_ADD_WAIT: + rc = cam_vfe_top_wait_comp_event(top_priv, cmd_args, arg_size); + break; + case CAM_ISP_HW_CMD_ADD_WAIT_TRIGGER: + rc = cam_vfe_top_add_wait_trigger(top_priv, cmd_args, arg_size); + break; default: rc = -EINVAL; CAM_ERR(CAM_ISP, "Error, Invalid cmd:%d", cmd_type);