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 319cba6207..2d129b58a4 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 @@ -1847,6 +1847,7 @@ static int cam_ife_hw_mgr_acquire_res_ife_out_rdi( vfe_acquire.event_cb = cam_ife_hw_mgr_event_handler; vfe_acquire.buf_done_controller = ife_ctx->buf_done_controller; hw_intf = ife_src_res->hw_res[0]->hw_intf; + vfe_acquire.vfe_out.use_wm_pack = ife_src_res->use_wm_pack; rc = hw_intf->hw_ops.reserve(hw_intf->hw_priv, &vfe_acquire, sizeof(struct cam_vfe_acquire_args)); @@ -1867,6 +1868,7 @@ static int cam_ife_hw_mgr_acquire_res_ife_out_rdi( ife_out_res->hw_res[0] = vfe_acquire.vfe_out.rsrc_node; ife_out_res->is_dual_isp = 0; + ife_out_res->use_wm_pack = ife_src_res->use_wm_pack; ife_out_res->res_id = vfe_out_res_id; ife_out_res->res_type = CAM_ISP_RESOURCE_VFE_OUT; ife_src_res->num_children++; @@ -2038,6 +2040,7 @@ static int cam_ife_hw_mgr_acquire_res_sfe_out_rdi( sfe_acquire.sfe_out.is_dual = 0; sfe_acquire.buf_done_controller = ife_ctx->buf_done_controller; sfe_acquire.event_cb = cam_ife_hw_mgr_event_handler; + sfe_acquire.sfe_out.use_wm_pack = sfe_src_res->use_wm_pack; hw_intf = sfe_src_res->hw_res[0]->hw_intf; rc = hw_intf->hw_ops.reserve(hw_intf->hw_priv, &sfe_acquire, @@ -2060,6 +2063,7 @@ static int cam_ife_hw_mgr_acquire_res_sfe_out_rdi( sfe_out_res->hw_res[0] = sfe_acquire.sfe_out.rsrc_node; sfe_out_res->is_dual_isp = 0; + sfe_out_res->use_wm_pack = sfe_src_res->use_wm_pack; sfe_out_res->res_id = sfe_out_res_id; sfe_out_res->res_type = CAM_ISP_RESOURCE_SFE_OUT; sfe_src_res->num_children++; @@ -2468,6 +2472,7 @@ static int cam_ife_hw_mgr_acquire_res_sfe_src( sfe_src_res->res_type = sfe_acquire.rsrc_type; sfe_src_res->res_id = sfe_acquire.sfe_in.res_id; sfe_src_res->is_dual_isp = csid_res->is_dual_isp; + sfe_src_res->use_wm_pack = csid_res->use_wm_pack; for (i = sfe_src_res->is_dual_isp; i >= 0; i--) { rc = cam_ife_hw_mgr_acquire_sfe_hw( ((is_rdi) && (!sfe_src_res->is_dual_isp) && @@ -3025,6 +3030,7 @@ static int cam_ife_hw_mgr_acquire_res_ife_src( ife_src_res->res_type = vfe_acquire.rsrc_type; ife_src_res->res_id = vfe_acquire.vfe_in.res_id; ife_src_res->is_dual_isp = csid_res->is_dual_isp; + ife_src_res->use_wm_pack = csid_res->use_wm_pack; for (i = 0; i < CAM_ISP_HW_SPLIT_MAX; i++) { if (!csid_res->hw_res[i]) @@ -3426,6 +3432,9 @@ static int cam_ife_hw_mgr_acquire_res_ife_csid_rdi( csid_acquire.tasklet = ife_ctx->common.tasklet_info; csid_acquire.cb_priv = ife_ctx; csid_acquire.cdm_ops = ife_ctx->cdm_ops; + if (ife_ctx->ctx_type == CAM_IFE_CTX_TYPE_SFE) + csid_acquire.sfe_en = true; + if (cam_ife_hw_mgr_is_shdr_fs_rdi_res( out_port->res_type, ife_ctx->flags.is_sfe_shdr, ife_ctx->flags.is_sfe_fs)) { @@ -3499,6 +3508,7 @@ static int cam_ife_hw_mgr_acquire_res_ife_csid_rdi( csid_res->is_dual_isp = 0; csid_res->hw_res[0] = csid_acquire.node_res; csid_res->hw_res[1] = NULL; + csid_res->use_wm_pack = csid_acquire.use_wm_pack; if ((ife_ctx->flags.is_rdi_only_context) || (ife_ctx->flags.is_sfe_fs) || (ife_ctx->flags.is_sfe_shdr)) { @@ -8541,6 +8551,213 @@ static int cam_isp_blob_bw_limit_update( return rc; } +static int cam_isp_hw_mgr_add_cmd_buf_util( + struct cam_isp_hw_mgr_res *hw_mgr_res, + struct cam_hw_prepare_update_args *prepare, + struct cam_isp_generic_blob_info *blob_info, + void *data, + uint32_t hw_cmd_type, + uint32_t blob_type) +{ + uint32_t total_used_bytes = 0; + uint32_t kmd_buf_remain_size; + struct cam_kmd_buf_info *kmd_buf_info; + uint32_t *cmd_buf_addr; + int rc = 0; + + kmd_buf_info = blob_info->kmd_buf_info; + if (kmd_buf_info->used_bytes < kmd_buf_info->size) { + kmd_buf_remain_size = kmd_buf_info->size - kmd_buf_info->used_bytes; + } else { + CAM_ERR(CAM_ISP, "No free kmd memory for base idx: %d used_bytes %u buf_size %u", + blob_info->base_info->idx, kmd_buf_info->used_bytes, kmd_buf_info->size); + return -ENOMEM; + } + + cmd_buf_addr = kmd_buf_info->cpu_addr + (kmd_buf_info->used_bytes / 4); + rc = cam_isp_add_cmd_buf_update(hw_mgr_res, blob_type, + hw_cmd_type, blob_info->base_info->idx, (void *)cmd_buf_addr, + kmd_buf_remain_size, data, &total_used_bytes); + if (rc) { + CAM_ERR(CAM_ISP, "Add cmd buffer failed idx: %d", + blob_info->base_info->idx); + return -EINVAL; + } + + if (total_used_bytes) + cam_ife_mgr_update_hw_entries_util( + CAM_ISP_IQ_BL, total_used_bytes, kmd_buf_info, prepare); + return rc; +} + +static int cam_isp_update_ife_pdaf_cfg( + struct cam_ife_hw_mgr_ctx *ctx, + struct cam_hw_prepare_update_args *prepare, + struct cam_isp_generic_blob_info *blob_info, + struct cam_isp_lcr_rdi_cfg_args *isp_lcr_cfg, + uint32_t blob_type) +{ + struct cam_isp_hw_mgr_res *hw_mgr_res; + uint32_t i; + uint32_t ife_res_id; + struct cam_isp_resource_node *res; + int rc = -EINVAL; + + ife_res_id = cam_convert_rdi_out_res_id_to_src(isp_lcr_cfg->rdi_lcr_cfg->res_id); + if (ife_res_id == CAM_ISP_HW_VFE_IN_MAX) { + CAM_ERR(CAM_ISP, "Invalid res_id %u", isp_lcr_cfg->rdi_lcr_cfg->res_id); + return -EINVAL; + } + + CAM_DBG(CAM_ISP, "Ctx %d res: %u lcr %u id %u ctx_type %u", ctx->ctx_index, ife_res_id, + isp_lcr_cfg->rdi_lcr_cfg->res_id, blob_info->base_info->idx, ctx->ctx_type); + list_for_each_entry(hw_mgr_res, &ctx->res_list_ife_src, list) { + if (hw_mgr_res->res_type == CAM_ISP_RESOURCE_UNINT) + continue; + + for (i = 0; i < CAM_ISP_HW_SPLIT_MAX; i++) { + if (!hw_mgr_res->hw_res[i]) + continue; + + res = hw_mgr_res->hw_res[i]; + /* + * for SFE cases, only CAMIF resource is + * acquired. We need any res to go to vfe drivers + * to update the buffer. For non-sfe case, we match + * with the incoming res_id + */ + if ((ctx->ctx_type == CAM_IFE_CTX_TYPE_SFE && + res->res_id == CAM_ISP_HW_VFE_IN_CAMIF) || + res->res_id == ife_res_id) { + + rc = cam_isp_hw_mgr_add_cmd_buf_util(hw_mgr_res, prepare, + blob_info, (void *)isp_lcr_cfg, + CAM_ISP_HW_CMD_RDI_LCR_CFG, blob_type); + if (rc) + CAM_ERR(CAM_ISP, + "Ctx %d res: %u lcr %u id %u ctx_type %u rc %u", + ctx->ctx_index, ife_res_id, + isp_lcr_cfg->rdi_lcr_cfg->res_id, + blob_info->base_info->idx, ctx->ctx_type, rc); + goto end; + } + } + } +end: + return rc; +} + +static int cam_isp_config_rdi_lcr_csid_init_params( + struct cam_ife_hw_mgr_ctx *ctx, + struct cam_hw_prepare_update_args *prepare, + struct cam_isp_generic_blob_info *blob_info, + struct cam_isp_lcr_rdi_config *rdi_lcr_cfg, + uint32_t blob_type) +{ + struct cam_isp_hw_mgr_res *hw_mgr_res; + struct cam_isp_resource_node *res; + int rc = -EINVAL; + uint32_t csid_res_id = 0; + uint32_t acquired_res_id_mask = 0; + + csid_res_id = cam_ife_hw_mgr_get_ife_csid_rdi_res_type( + rdi_lcr_cfg->res_id); + CAM_DBG(CAM_ISP, + "Ctx: %d csid_res_id: %u rdi_lcr: %u sfe_shdr %u ctx_ctype %u", ctx->ctx_index, + csid_res_id, rdi_lcr_cfg->res_id, ctx->flags.is_sfe_shdr, ctx->ctx_type); + + list_for_each_entry(hw_mgr_res, &ctx->res_list_ife_csid, list) { + if (hw_mgr_res->res_type == CAM_ISP_RESOURCE_UNINT) + continue; + + if (!hw_mgr_res->hw_res[0]) + continue; + + if (hw_mgr_res->res_id < CAM_IFE_PIX_PATH_RES_RDI_0 || + hw_mgr_res->res_id > CAM_IFE_PIX_PATH_RES_RDI_2) + continue; + + if (!ctx->flags.is_sfe_shdr && hw_mgr_res->res_id != csid_res_id) + continue; + + res = hw_mgr_res->hw_res[0]; + rc = res->hw_intf->hw_ops.process_cmd(res->hw_intf->hw_priv, + CAM_ISP_HW_CMD_RDI_LCR_CFG, res, sizeof(*res)); + acquired_res_id_mask |= BIT(res->res_id); + if (rc) { + CAM_ERR(CAM_ISP, + "Ctx: %d csid_res_id: %u rdi_lcr: %u sfe_shdr %u ctx_ctype %u", + ctx->ctx_index, csid_res_id, rdi_lcr_cfg->res_id, + ctx->flags.is_sfe_shdr, ctx->ctx_type); + break; + } + } + + if (!(acquired_res_id_mask & BIT(csid_res_id))) { + CAM_ERR(CAM_ISP, + "Ctx: %d Unacquired csid_res_id: %u rdi_lcr: %u sfe_shdr %u ctx_ctype %u", + ctx->ctx_index, csid_res_id, rdi_lcr_cfg->res_id, + ctx->flags.is_sfe_shdr, ctx->ctx_type); + rc = -EINVAL; + } + return rc; +} + +static int cam_isp_blob_ife_rdi_lcr_config( + struct cam_ife_hw_mgr_ctx *ctx, + struct cam_hw_prepare_update_args *prepare, + struct cam_isp_generic_blob_info *blob_info, + struct cam_isp_lcr_rdi_config *rdi_lcr_cfg, + uint32_t blob_type) +{ + struct cam_isp_prepare_hw_update_data *prepare_hw_data; + struct cam_isp_lcr_rdi_cfg_args isp_cfg_args = {0}; + int rc = -EINVAL; + + prepare_hw_data = (struct cam_isp_prepare_hw_update_data *)prepare->priv; + CAM_DBG(CAM_ISP, + "Blob opcode %u res %u ctx_type %u shdr %u rdi_lcr %u", + prepare_hw_data->packet_opcode_type, rdi_lcr_cfg->res_id, ctx->ctx_type, + ctx->flags.is_sfe_shdr, ctx->flags.rdi_lcr_en); + + if (prepare_hw_data->packet_opcode_type == CAM_ISP_PACKET_INIT_DEV) { + rc = cam_isp_config_rdi_lcr_csid_init_params(ctx, + prepare, blob_info, rdi_lcr_cfg, blob_type); + if (rc) { + CAM_ERR(CAM_ISP, + "CSID param failed Ctx: %d rdi_lcr: %u ctx_type: %u", + ctx->ctx_index, rdi_lcr_cfg->res_id, ctx->ctx_type); + return rc; + } + + isp_cfg_args.is_init = true; + ctx->flags.rdi_lcr_en = true; + } else if (!ctx->flags.rdi_lcr_en || !ctx->flags.is_sfe_shdr) { + /* + * we don't expect blob for non-shdr cases other than Init Packet, + * as the RDI input would remain same for the session. + */ + CAM_ERR(CAM_ISP, + "Unexpected Blob opcode %u res %u ctx_type %u shdr %u rdi_lcr %u", + prepare_hw_data->packet_opcode_type, rdi_lcr_cfg->res_id, ctx->ctx_type, + ctx->flags.is_sfe_shdr, ctx->flags.rdi_lcr_en); + return rc; + } + + isp_cfg_args.rdi_lcr_cfg = rdi_lcr_cfg; + rc = cam_isp_update_ife_pdaf_cfg(ctx, prepare, blob_info, + &isp_cfg_args, blob_type); + if (rc) { + CAM_ERR(CAM_ISP, + "IFE param failed %u res %u ctx_type %u shdr %u rdi_lcr %u", + prepare_hw_data->packet_opcode_type, rdi_lcr_cfg->res_id, ctx->ctx_type, + ctx->flags.is_sfe_shdr, ctx->flags.rdi_lcr_en); + return rc; + } + + return rc; +} + static inline int cam_isp_validate_bw_limiter_blob( uint32_t blob_size, struct cam_isp_out_rsrc_bw_limiter_config *bw_limit_config) @@ -9218,6 +9435,25 @@ static int cam_isp_packet_generic_blob_handler(void *user_data, CAM_ERR(CAM_ISP, "Init config failed for req: %llu rc: %d", prepare->packet->header.request_id, rc); + } + break; + case CAM_ISP_GENERIC_BLOB_TYPE_RDI_LCR_CONFIG: { + struct cam_isp_lcr_rdi_config *lcr_rdi_config; + + if (blob_size < sizeof(struct cam_isp_lcr_rdi_config)) { + CAM_ERR(CAM_ISP, "Invalid lcr blob size %u expected %u", + blob_size, sizeof(struct cam_isp_lcr_rdi_config)); + return -EINVAL; + } + + lcr_rdi_config = (struct cam_isp_lcr_rdi_config *)blob_data; + rc = cam_isp_blob_ife_rdi_lcr_config(ife_mgr_ctx, prepare, + blob_info, lcr_rdi_config, blob_type); + if (rc) + CAM_ERR(CAM_ISP, + "RDI LCR config failed for res %u", + lcr_rdi_config->res_id); + } break; default: @@ -9683,6 +9919,7 @@ static int cam_sfe_packet_generic_blob_handler(void *user_data, case CAM_ISP_GENERIC_BLOB_TYPE_DISCARD_INITIAL_FRAMES: case CAM_ISP_GENERIC_BLOB_TYPE_INIT_CONFIG: case CAM_ISP_GENERIC_BLOB_TYPE_FPS_CONFIG: + case CAM_ISP_GENERIC_BLOB_TYPE_RDI_LCR_CONFIG: break; default: CAM_WARN(CAM_ISP, "Invalid blob type: %u", blob_type); 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 4f87ce59ec..1389b7a305 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 @@ -153,6 +153,7 @@ struct cam_ife_hw_mgr_sfe_info { * @dump_on_flush: Set if reg dump triggered on flush * @dump_on_error: Set if reg dump triggered on error * @custom_aeb_mode: Set if custom AEB stream + * @rdi_lcr_en: To indicate if RDI LCR is enabled * @sys_cache_usage: Per context sys cache usage * The corresponding index will be set * for the cache type @@ -175,6 +176,7 @@ struct cam_ife_hw_mgr_ctx_flags { bool dump_on_flush; bool dump_on_error; bool is_aeb_mode; + bool rdi_lcr_en; bool sys_cache_usage[CAM_LLCC_MAX]; }; 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 1556a70497..7ff9056c9f 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 @@ -69,6 +69,7 @@ struct cam_isp_hw_mgr { * acquired * @is_secure informs whether the resource is in secure mode or not * @num_children: number of the child resource node. + * @use_wm_pack: Flag to indicate if WM is to be used for packing * */ struct cam_isp_hw_mgr_res { @@ -79,6 +80,7 @@ struct cam_isp_hw_mgr_res { struct cam_isp_resource_node *hw_res[CAM_ISP_HW_SPLIT_MAX]; uint32_t is_secure; uint32_t num_children; + bool use_wm_pack; }; 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 08e2192588..40010e042f 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 @@ -370,6 +370,18 @@ struct cam_isp_start_args { bool start_only; }; +/** + * struct cam_isp_lcr_rdi_cfg_args - isp hardware start arguments + * + * @rdi_lcr_cfg: RDI LCR cfg received from User space. + * @is_init: Flag to indicate if init packet. + * + */ +struct cam_isp_lcr_rdi_cfg_args { + struct cam_isp_lcr_rdi_config *rdi_lcr_cfg; + bool is_init; +}; + /** * cam_isp_hw_mgr_init() * diff --git a/drivers/cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/cam_ife_csid780.h b/drivers/cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/cam_ife_csid780.h index 8c89bce50c..8508c87d52 100644 --- a/drivers/cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/cam_ife_csid780.h +++ b/drivers/cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/cam_ife_csid780.h @@ -625,6 +625,10 @@ static struct cam_ife_csid_ver2_path_reg_info /* configurations */ .resume_frame_boundary = 1, .overflow_ctrl_en = 1, + .capabilities = CAM_IFE_CSID_CAP_INPUT_LCR | + CAM_IFE_CSID_CAP_MIPI10_UNPACK | + CAM_IFE_CSID_CAP_MIPI12_UNPACK | + CAM_IFE_CSID_CAP_MIPI14_UNPACK, .overflow_ctrl_mode_val = 0x8, .offline_mode_supported = 1, .mipi_pack_supported = 1, @@ -719,6 +723,10 @@ static struct cam_ife_csid_ver2_path_reg_info /* configurations */ .resume_frame_boundary = 1, .overflow_ctrl_en = 1, + .capabilities = CAM_IFE_CSID_CAP_INPUT_LCR | + CAM_IFE_CSID_CAP_MIPI10_UNPACK | + CAM_IFE_CSID_CAP_MIPI12_UNPACK | + CAM_IFE_CSID_CAP_MIPI14_UNPACK, .overflow_ctrl_mode_val = 0x8, .mipi_pack_supported = 1, .offline_mode_supported = 1, @@ -813,6 +821,10 @@ static struct cam_ife_csid_ver2_path_reg_info /* configurations */ .resume_frame_boundary = 1, .overflow_ctrl_en = 1, + .capabilities = CAM_IFE_CSID_CAP_INPUT_LCR | + CAM_IFE_CSID_CAP_MIPI10_UNPACK | + CAM_IFE_CSID_CAP_MIPI12_UNPACK | + CAM_IFE_CSID_CAP_MIPI14_UNPACK, .overflow_ctrl_mode_val = 0x8, .mipi_pack_supported = 1, .offline_mode_supported = 1, @@ -907,6 +919,7 @@ static struct cam_ife_csid_ver2_path_reg_info /* configurations */ .resume_frame_boundary = 1, .overflow_ctrl_en = 1, + .capabilities = 0, .overflow_ctrl_mode_val = 0x8, .offline_mode_supported = 1, .mipi_pack_supported = 1, @@ -1001,6 +1014,7 @@ static struct cam_ife_csid_ver2_path_reg_info /* configurations */ .resume_frame_boundary = 1, .overflow_ctrl_en = 1, + .capabilities = 0, .overflow_ctrl_mode_val = 0x8, .offline_mode_supported = 1, .mipi_pack_supported = 1, @@ -1142,6 +1156,7 @@ static struct cam_ife_csid_ver2_common_reg_info .timestamp_stb_sel_shift_val = 8, .vfr_en_shift_val = 0, .mup_shift_val = 28, + .shdr_slave_ppp_shift = 20, .shdr_slave_rdi2_shift = 22, .shdr_slave_rdi1_shift = 21, .shdr_master_rdi0_shift = 5, @@ -1203,6 +1218,7 @@ static struct cam_ife_csid_ver2_top_reg_info .dual_sync_sel_shift_val = 8, .dual_en_shift_val = 0, .master_slave_sel_shift_val = 1, + .rdi_lcr_shift_val = 16, .master_sel_val = 0, .slave_sel_val = 1, .io_path_cfg_rst_val = 1, diff --git a/drivers/cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/cam_ife_csid_common.c b/drivers/cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/cam_ife_csid_common.c index 4cc1cc23f9..4711f3f86a 100644 --- a/drivers/cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/cam_ife_csid_common.c +++ b/drivers/cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/cam_ife_csid_common.c @@ -96,7 +96,8 @@ int cam_ife_csid_is_pix_res_format_supported( int cam_ife_csid_get_format_rdi( uint32_t in_format, uint32_t out_format, - struct cam_ife_csid_path_format *path_format, bool rpp) + struct cam_ife_csid_path_format *path_format, bool rpp, + bool mipi_unpacked) { int rc = 0; @@ -109,10 +110,17 @@ int cam_ife_csid_get_format_rdi( path_format->decode_fmt = 0x0; path_format->packing_fmt = 0x1; } + + if (mipi_unpacked) { + path_format->decode_fmt = 0x0; + path_format->packing_fmt = 0x0; + path_format->plain_fmt = 0x0; + } break; case CAM_FORMAT_PLAIN8: path_format->decode_fmt = 0x0; path_format->plain_fmt = 0x0; + path_format->packing_fmt = 0; break; default: rc = -EINVAL; @@ -129,9 +137,16 @@ int cam_ife_csid_get_format_rdi( path_format->decode_fmt = 0x1; path_format->packing_fmt = 0x1; } + + if (mipi_unpacked) { + path_format->decode_fmt = 0x1; + path_format->packing_fmt = 0x0; + path_format->plain_fmt = 0x0; + } break; case CAM_FORMAT_PLAIN8: path_format->decode_fmt = 0x1; + path_format->packing_fmt = 0; path_format->plain_fmt = 0x0; break; default: @@ -149,10 +164,17 @@ int cam_ife_csid_get_format_rdi( path_format->decode_fmt = 0x2; path_format->packing_fmt = 0x1; } + + if (mipi_unpacked) { + path_format->decode_fmt = 0x2; + path_format->packing_fmt = 0x0; + path_format->plain_fmt = 0x1; + } break; case CAM_FORMAT_PLAIN16_10: path_format->decode_fmt = 0x2; path_format->plain_fmt = 0x1; + path_format->packing_fmt = 0; break; default: rc = -EINVAL; @@ -168,10 +190,17 @@ int cam_ife_csid_get_format_rdi( path_format->decode_fmt = 0x3; path_format->packing_fmt = 0x1; } + + if (mipi_unpacked) { + path_format->decode_fmt = 0x3; + path_format->packing_fmt = 0x0; + path_format->plain_fmt = 0x1; + } break; case CAM_FORMAT_PLAIN16_12: path_format->decode_fmt = 0x3; path_format->plain_fmt = 0x1; + path_format->packing_fmt = 0; break; default: rc = -EINVAL; @@ -187,10 +216,17 @@ int cam_ife_csid_get_format_rdi( path_format->decode_fmt = 0x4; path_format->packing_fmt = 0x1; } + + if (mipi_unpacked) { + path_format->decode_fmt = 0x4; + path_format->packing_fmt = 0x0; + path_format->plain_fmt = 0x1; + } break; case CAM_FORMAT_PLAIN16_14: path_format->decode_fmt = 0x4; path_format->plain_fmt = 0x1; + path_format->packing_fmt = 0; break; default: rc = -EINVAL; @@ -206,10 +242,17 @@ int cam_ife_csid_get_format_rdi( path_format->decode_fmt = 0x5; path_format->packing_fmt = 0x1; } + + if (mipi_unpacked) { + path_format->decode_fmt = 0x5; + path_format->packing_fmt = 0x0; + path_format->plain_fmt = 0x1; + } break; case CAM_FORMAT_PLAIN16_16: path_format->decode_fmt = 0x5; path_format->plain_fmt = 0x1; + path_format->packing_fmt = 0; break; default: rc = -EINVAL; @@ -225,10 +268,17 @@ int cam_ife_csid_get_format_rdi( path_format->decode_fmt = 0x6; path_format->packing_fmt = 0x1; } + + if (mipi_unpacked) { + path_format->decode_fmt = 0x6; + path_format->packing_fmt = 0x0; + path_format->plain_fmt = 0x2; + } break; case CAM_FORMAT_PLAIN32_20: path_format->decode_fmt = 0x6; path_format->plain_fmt = 0x2; + path_format->packing_fmt = 0; break; default: rc = -EINVAL; @@ -239,30 +289,37 @@ int cam_ife_csid_get_format_rdi( case CAM_FORMAT_DPCM_10_6_10: path_format->decode_fmt = 0x7; path_format->plain_fmt = 0x1; + path_format->packing_fmt = 0; break; case CAM_FORMAT_DPCM_10_8_10: path_format->decode_fmt = 0x8; path_format->plain_fmt = 0x1; + path_format->packing_fmt = 0; break; case CAM_FORMAT_DPCM_12_6_12: path_format->decode_fmt = 0x9; path_format->plain_fmt = 0x1; + path_format->packing_fmt = 0; break; case CAM_FORMAT_DPCM_12_8_12: path_format->decode_fmt = 0xA; path_format->plain_fmt = 0x1; + path_format->packing_fmt = 0; break; case CAM_FORMAT_DPCM_14_8_14: path_format->decode_fmt = 0xB; path_format->plain_fmt = 0x1; + path_format->packing_fmt = 0; break; case CAM_FORMAT_DPCM_14_10_14: path_format->decode_fmt = 0xC; path_format->plain_fmt = 0x1; + path_format->packing_fmt = 0; break; case CAM_FORMAT_DPCM_12_10_12: path_format->decode_fmt = 0xD; path_format->plain_fmt = 0x1; + path_format->packing_fmt = 0; break; case CAM_FORMAT_YUV422: path_format->decode_fmt = 0x1; diff --git a/drivers/cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/cam_ife_csid_common.h b/drivers/cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/cam_ife_csid_common.h index 5ba9592038..9434bd37bf 100644 --- a/drivers/cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/cam_ife_csid_common.h +++ b/drivers/cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/cam_ife_csid_common.h @@ -33,6 +33,13 @@ #define CAM_IFE_CSID_LOG_BUF_LEN 512 +#define CAM_IFE_CSID_CAP_INPUT_LCR 0x1 +#define CAM_IFE_CSID_CAP_MIPI8_UNPACK 0x2 +#define CAM_IFE_CSID_CAP_MIPI10_UNPACK 0x4 +#define CAM_IFE_CSID_CAP_MIPI12_UNPACK 0x8 +#define CAM_IFE_CSID_CAP_MIPI14_UNPACK 0x10 +#define CAM_IFE_CSID_CAP_MIPI16_UNPACK 0x20 +#define CAM_IFE_CSID_CAP_MIPI20_UNPACK 0x40 /* * Debug values enable the corresponding interrupts and debug logs provide * necessary information @@ -283,6 +290,8 @@ struct cam_ife_csid_debug_info { * @tpg_configured: flag to indicate if internal_tpg is configured * @reset_awaited: flag to indicate if reset is awaited * @offline_mode: flag to indicate if csid in offline mode + * @rdi_lcr_en: flag to indicate if RDI to lcr is enabled + * @sfe_en: flag to indicate if SFE is enabled */ struct cam_ife_csid_hw_flags { bool device_enabled; @@ -295,10 +304,12 @@ struct cam_ife_csid_hw_flags { bool tpg_configured; bool reset_awaited; bool offline_mode; + bool rdi_lcr_en; + bool sfe_en; }; /* - * struct cam_ife_csid_hw_flags: place holder for flags + * struct am_ife_csid_cid_data: place holder for cid data * * @vc_dt: vc_dt structure * @cid_cnt: count of cid acquired @@ -311,7 +322,7 @@ struct cam_ife_csid_cid_data { }; /* - * struct cam_ife_csid_hw_flags: place holder for flags + * struct cam_ife_csid_rx_cfg: place holder for rx cfg * * @phy_sel: Selected phy * @lane_type: type of lane selected @@ -344,7 +355,8 @@ int cam_ife_csid_is_pix_res_format_supported( int cam_ife_csid_get_format_rdi( uint32_t in_format, uint32_t out_format, - struct cam_ife_csid_path_format *path_format, bool rpp); + struct cam_ife_csid_path_format *path_format, bool rpp, + bool mipi_unpacked); int cam_ife_csid_get_format_ipp_ppp( uint32_t in_format, diff --git a/drivers/cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/cam_ife_csid_hw_ver1.c b/drivers/cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/cam_ife_csid_hw_ver1.c index a52d52a1fa..2f35841f1c 100644 --- a/drivers/cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/cam_ife_csid_hw_ver1.c +++ b/drivers/cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/cam_ife_csid_hw_ver1.c @@ -2172,7 +2172,7 @@ static int cam_ife_csid_ver1_init_config_rdi_path( mem_base = soc_info->reg_map[0].mem_base; is_rpp = path_cfg->crop_enable || path_cfg->drop_enable; rc = cam_ife_csid_get_format_rdi(path_cfg->in_format, - path_cfg->out_format, &path_format, is_rpp); + path_cfg->out_format, &path_format, is_rpp, false); if (rc) return rc; @@ -2330,7 +2330,7 @@ static int cam_ife_csid_ver1_init_config_udi_path( mem_base = soc_info->reg_map[0].mem_base; is_rpp = path_cfg->crop_enable || path_cfg->drop_enable; rc = cam_ife_csid_get_format_rdi(path_cfg->in_format, - path_cfg->out_format, &path_format, is_rpp); + path_cfg->out_format, &path_format, is_rpp, false); if (rc) return rc; diff --git a/drivers/cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/cam_ife_csid_hw_ver2.c b/drivers/cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/cam_ife_csid_hw_ver2.c index d2ae979b4c..c0e15293cd 100644 --- a/drivers/cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/cam_ife_csid_hw_ver2.c +++ b/drivers/cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/cam_ife_csid_hw_ver2.c @@ -2108,6 +2108,45 @@ err: return rc; } +static bool cam_ife_csid_hw_ver2_need_unpack_mipi( + struct cam_ife_csid_ver2_hw *csid_hw, + struct cam_csid_hw_reserve_resource_args *reserve, + const struct cam_ife_csid_ver2_path_reg_info *path_reg, + uint32_t format) +{ + bool need_unpack = false; + + switch(format) { + case CAM_FORMAT_MIPI_RAW_8: + need_unpack = (bool)(path_reg->capabilities & CAM_IFE_CSID_CAP_MIPI8_UNPACK); + break; + case CAM_FORMAT_MIPI_RAW_10: + need_unpack = (bool)(path_reg->capabilities & CAM_IFE_CSID_CAP_MIPI10_UNPACK); + break; + case CAM_FORMAT_MIPI_RAW_12: + need_unpack = (bool)(path_reg->capabilities & CAM_IFE_CSID_CAP_MIPI12_UNPACK); + break; + case CAM_FORMAT_MIPI_RAW_14: + need_unpack = (bool)(path_reg->capabilities & CAM_IFE_CSID_CAP_MIPI14_UNPACK); + break; + case CAM_FORMAT_MIPI_RAW_16: + need_unpack = (bool)(path_reg->capabilities & CAM_IFE_CSID_CAP_MIPI16_UNPACK); + break; + case CAM_FORMAT_MIPI_RAW_20: + need_unpack = (bool)(path_reg->capabilities & CAM_IFE_CSID_CAP_MIPI20_UNPACK); + break; + default: + need_unpack = false; + break; + } + + CAM_DBG(CAM_ISP, "CSID[%u], RDI_%u format %u need_unpack %u sfe_shdr %u", + csid_hw->hw_intf->hw_idx, reserve->res_id, format, need_unpack, + reserve->sfe_inline_shdr); + + return need_unpack; +} + static int cam_ife_csid_hw_ver2_config_path_data( struct cam_ife_csid_ver2_hw *csid_hw, struct cam_ife_csid_ver2_path_cfg *path_cfg, @@ -2120,6 +2159,7 @@ static int cam_ife_csid_hw_ver2_config_path_data( (struct cam_ife_csid_ver2_reg_info *)csid_hw->core_info->csid_reg; struct cam_ife_csid_cid_data *cid_data = &csid_hw->cid_data[cid]; struct cam_isp_resource_node *res = &csid_hw->path_res[reserve->res_id]; + const struct cam_ife_csid_ver2_path_reg_info *path_reg = NULL; for(i = 0; i < reserve->in_port->num_valid_vc_dt; i++) path_cfg->in_format[i] = reserve->in_port->format[i]; @@ -2138,6 +2178,7 @@ static int cam_ife_csid_hw_ver2_config_path_data( path_cfg->num_bytes_out = reserve->in_port->num_bytes_out; path_cfg->sec_evt_config.en_secondary_evt = reserve->sec_evt_config.en_secondary_evt; path_cfg->sec_evt_config.evt_type = reserve->sec_evt_config.evt_type; + path_reg = csid_reg->path_reg[res->res_id]; if (reserve->sync_mode == CAM_ISP_HW_SYNC_MASTER) { path_cfg->start_pixel = reserve->in_port->left_start; @@ -2191,11 +2232,18 @@ static int cam_ife_csid_hw_ver2_config_path_data( case CAM_IFE_PIX_PATH_RES_RDI_3: case CAM_IFE_PIX_PATH_RES_RDI_4: is_rpp = path_cfg->crop_enable || path_cfg->drop_enable; + /* + * if csid gives unpacked out, packing needs to be done at + * WM side if needed, based on the format the decision is + * taken at WM side + */ + reserve->use_wm_pack = cam_ife_csid_hw_ver2_need_unpack_mipi(csid_hw, + reserve, path_reg, path_cfg->out_format); rc = cam_ife_csid_get_format_rdi( path_cfg->in_format[CAM_IFE_CSID_MULTI_VC_DT_GRP_0], path_cfg->out_format, &path_cfg->path_format[CAM_IFE_CSID_MULTI_VC_DT_GRP_0], - is_rpp); + is_rpp, reserve->use_wm_pack); if (rc) goto end; @@ -2206,7 +2254,7 @@ static int cam_ife_csid_hw_ver2_config_path_data( path_cfg->in_format[CAM_IFE_CSID_MULTI_VC_DT_GRP_1], path_cfg->out_format, &path_cfg->path_format[CAM_IFE_CSID_MULTI_VC_DT_GRP_1], - is_rpp); + is_rpp, reserve->use_wm_pack); if (rc) goto end; } @@ -2516,9 +2564,9 @@ int cam_ife_csid_ver2_reserve(void *hw_priv, csid_hw->token = reserve->cb_priv; reserve->buf_done_controller = csid_hw->buf_done_irq_controller; res->cdm_ops = reserve->cdm_ops; - path_cfg->sfe_inline_shdr = reserve->sfe_inline_shdr; + csid_hw->flags.sfe_en = reserve->sfe_en; + path_cfg->sfe_shdr = reserve->sfe_inline_shdr; csid_hw->flags.offline_mode = reserve->is_offline; - reserve->need_top_cfg = csid_reg->need_top_cfg; CAM_DBG(CAM_ISP, "CSID[%u] Resource[id: %d name:%s] state %d cid %d", @@ -2614,7 +2662,7 @@ end: return rc; } -static int cam_ife_csid_ver2_shdr_cfg( +static int cam_ife_csid_ver2_res_master_slave_cfg( struct cam_ife_csid_ver2_hw *csid_hw, uint32_t res_id) { @@ -2641,6 +2689,9 @@ static int cam_ife_csid_ver2_shdr_cfg( case CAM_IFE_PIX_PATH_RES_RDI_2: val |= BIT(csid_reg->cmn_reg->shdr_slave_rdi2_shift); break; + case CAM_IFE_PIX_PATH_RES_PPP: + val |= BIT(csid_reg->cmn_reg->shdr_slave_ppp_shift); + break; default: break; } @@ -2803,8 +2854,10 @@ static int cam_ife_csid_ver2_init_config_rdi_path( path_reg->err_recovery_cfg0_addr); } - if (path_cfg->sfe_inline_shdr) - cam_ife_csid_ver2_shdr_cfg(csid_hw, res->res_id); + if (path_cfg->sfe_shdr || + (csid_hw->flags.rdi_lcr_en && + res->res_id == CAM_IFE_PIX_PATH_RES_RDI_0)) + cam_ife_csid_ver2_res_master_slave_cfg(csid_hw, res->res_id); if (csid_hw->debug_info.debug_val & CAM_IFE_CSID_DEBUG_ENABLE_HBI_VBI_INFO) { @@ -2990,6 +3043,9 @@ static int cam_ife_csid_ver2_init_config_pxl_path( mem_base + path_reg->format_measure_cfg0_addr); } + if (csid_hw->flags.rdi_lcr_en && res->res_id == CAM_IFE_PIX_PATH_RES_PPP) + cam_ife_csid_ver2_res_master_slave_cfg(csid_hw, res->res_id); + res->res_state = CAM_ISP_RESOURCE_STATE_INIT_HW; return rc; } @@ -3088,7 +3144,7 @@ static int cam_ife_csid_ver2_program_rdi_path( } if ((csid_hw->flags.offline_mode || - path_cfg->sfe_inline_shdr) && + path_cfg->sfe_shdr) && (res->res_id == CAM_IFE_PIX_PATH_RES_RDI_0)) { val |= path_reg->camif_irq_mask; path_cfg->handle_camif_irq = true; @@ -3693,7 +3749,6 @@ err: return rc; } - static int cam_ife_csid_ver2_program_top( struct cam_ife_csid_ver2_hw *csid_hw) { @@ -3735,6 +3790,8 @@ static int cam_ife_csid_ver2_program_top( val |= csid_hw->top_cfg.out_ife_en << top_reg->out_ife_en_shift_val; + val |= csid_hw->top_cfg.rdi_lcr; + cam_io_w_mb(val, soc_info->reg_map[CAM_IFE_CSID_TOP_MEM_BASE_ID].mem_base + top_reg->io_path_cfg0_addr[csid_hw->hw_intf->hw_idx]); @@ -4058,6 +4115,7 @@ static int cam_ife_csid_ver2_disable_core( spin_lock_bh(&csid_hw->lock_state); csid_hw->flags.device_enabled = false; csid_hw->hw_info->hw_state = CAM_HW_STATE_POWER_DOWN; + csid_hw->flags.rdi_lcr_en = false; spin_unlock_bh(&csid_hw->lock_state); rc = cam_ife_csid_disable_soc_resources(soc_info); if (rc) @@ -4065,7 +4123,6 @@ static int cam_ife_csid_ver2_disable_core( csid_hw->hw_intf->hw_idx); csid_hw->counters.error_irq_count = 0; - return rc; } @@ -4280,6 +4337,7 @@ int cam_ife_csid_ver2_stop(void *hw_priv, csid_stop->num_res); csid_hw->flags.device_enabled = false; + csid_hw->flags.rdi_lcr_en = false; reset.reset_type = (csid_hw->flags.fatal_err_detected) ? CAM_IFE_CSID_RESET_GLOBAL : CAM_IFE_CSID_RESET_PATH; @@ -4906,6 +4964,58 @@ end: return 0; } +static int cam_ife_csid_ver2_rdi_lcr_cfg( + struct cam_ife_csid_ver2_hw *csid_hw, void *cmd_args) +{ + const struct cam_ife_csid_ver2_path_reg_info *path_reg; + struct cam_ife_csid_ver2_reg_info *csid_reg; + struct cam_ife_csid_ver2_path_cfg *path_cfg = NULL; + struct cam_isp_resource_node *res = cmd_args; + + if (!csid_hw || !cmd_args) { + CAM_ERR(CAM_ISP, "Invalid params"); + return -EINVAL; + } + + csid_reg = (struct cam_ife_csid_ver2_reg_info *) + csid_hw->core_info->csid_reg; + + path_reg = csid_reg->path_reg[res->res_id]; + path_cfg = (struct cam_ife_csid_ver2_path_cfg *)res->res_priv; + if (!path_cfg || !path_reg || !path_reg->capabilities || + !(path_reg->capabilities & CAM_IFE_CSID_CAP_INPUT_LCR)) { + CAM_ERR(CAM_ISP, "Invalid res %s", res->res_name); + return -EINVAL; + } + + if (!path_cfg->sfe_shdr && (res->res_id != CAM_IFE_PIX_PATH_RES_RDI_0)) { + CAM_ERR(CAM_ISP, "Invalid res: %s, capabilities 0x%x sfe_shdr: %u", + res->res_name, path_reg->capabilities, path_cfg->sfe_shdr); + return -EINVAL; + } + + /* + * LCR should not be on for a resource if CSID is giving packed data + * this case would come for formats which are not supported + * */ + if (path_cfg->path_format[CAM_IFE_CSID_MULTI_VC_DT_GRP_0].packing_fmt) { + CAM_ERR(CAM_ISP, "LCR enabled for %s, csid out packed not supported", + res->res_name); + return -EINVAL; + } + + if (csid_hw->flags.sfe_en) + csid_hw->top_cfg.rdi_lcr |= BIT(res->res_id) << + csid_reg->top_reg->rdi_lcr_shift_val; + + csid_hw->flags.rdi_lcr_en = true; + + CAM_DBG(CAM_ISP, "CSID[%u] %s top_cfg %u", + csid_hw->hw_intf->hw_idx, res->res_name, csid_hw->top_cfg.rdi_lcr); + + return 0; +} + static int cam_ife_csid_ver2_process_cmd(void *hw_priv, uint32_t cmd_type, void *cmd_args, uint32_t arg_size) { @@ -4983,6 +5093,9 @@ static int cam_ife_csid_ver2_process_cmd(void *hw_priv, case CAM_ISP_HW_CMD_CSID_DISCARD_INIT_FRAMES: rc = cam_ife_csid_ver2_set_discard_frame_cfg(csid_hw, cmd_args); break; + case CAM_ISP_HW_CMD_RDI_LCR_CFG: + rc = cam_ife_csid_ver2_rdi_lcr_cfg(csid_hw, cmd_args); + break; default: CAM_ERR(CAM_ISP, "CSID:%d unsupported cmd:%d", csid_hw->hw_intf->hw_idx, cmd_type); diff --git a/drivers/cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/cam_ife_csid_hw_ver2.h b/drivers/cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/cam_ife_csid_hw_ver2.h index b447ed4f55..69afcb33e9 100644 --- a/drivers/cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/cam_ife_csid_hw_ver2.h +++ b/drivers/cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/cam_ife_csid_hw_ver2.h @@ -108,6 +108,7 @@ struct cam_ife_csid_ver2_top_cfg { bool dual_en; bool offline_sfe_en; bool out_ife_en; + bool rdi_lcr; }; struct cam_ife_csid_ver2_evt_payload { @@ -166,7 +167,7 @@ struct cam_ife_csid_ver2_camif_data { * If we know the number of paths to avoid configuring discard * for before processing discard config we can skip it for * the corresponding paths - * @sfe_inline_shdr: flag to indicate if sfe is inline shdr + * @sfe_shdr: flag to indicate if sfe is inline shdr * */ struct cam_ife_csid_ver2_path_cfg { @@ -204,7 +205,7 @@ struct cam_ife_csid_ver2_path_cfg { bool handle_camif_irq; bool discard_init_frames; bool skip_discard_frame_cfg; - bool sfe_inline_shdr; + bool sfe_shdr; }; struct cam_ife_csid_ver2_top_reg_info { @@ -216,6 +217,7 @@ struct cam_ife_csid_ver2_top_reg_info { uint32_t dual_sync_sel_shift_val; uint32_t dual_en_shift_val; uint32_t master_slave_sel_shift_val; + uint32_t rdi_lcr_shift_val; uint32_t master_sel_val; uint32_t slave_sel_val; uint32_t io_path_cfg_rst_val; @@ -349,6 +351,7 @@ struct cam_ife_csid_ver2_path_reg_info { uint32_t epoch1_cfg_val; uint32_t epoch0_shift_val; uint32_t epoch1_shift_val; + uint32_t capabilities; }; struct cam_ife_csid_ver2_common_reg_info { @@ -422,6 +425,7 @@ struct cam_ife_csid_ver2_common_reg_info { uint32_t multi_vcdt_ts_combo_en_shift_val; uint32_t multi_vcdt_en_shift_val; uint32_t mup_shift_val; + uint32_t shdr_slave_ppp_shift; uint32_t shdr_slave_rdi2_shift; uint32_t shdr_slave_rdi1_shift; uint32_t shdr_master_rdi0_shift; diff --git a/drivers/cam_isp/isp_hw_mgr/isp_hw/include/cam_ife_csid_hw_intf.h b/drivers/cam_isp/isp_hw_mgr/isp_hw/include/cam_ife_csid_hw_intf.h index d5d1238688..cc7361be6f 100644 --- a/drivers/cam_isp/isp_hw_mgr/isp_hw/include/cam_ife_csid_hw_intf.h +++ b/drivers/cam_isp/isp_hw_mgr/isp_hw/include/cam_ife_csid_hw_intf.h @@ -192,10 +192,12 @@ struct cam_csid_secondary_evt_config { * @buf_done_controller: IRQ controller for buf done for version 680 hw * @cdm_ops: CDM Ops * @event_cb: Callback function to hw mgr in case of hw events - * @cb_priv: Private pointer to return to callback * @phy_sel: Phy selection number if tpg is enabled from userspace + * @cb_priv: Private pointer to return to callback * @can_use_lite: Flag to indicate if current call qualifies for * acquire lite + * @sfe_en: Flag to indicate if SFE is enabled + * @use_wm_pack: [OUT]Flag to indicate if WM packing is to be used for packing * */ struct cam_csid_hw_reserve_resource_args { @@ -218,8 +220,10 @@ struct cam_csid_hw_reserve_resource_args { void *cdm_ops; cam_hw_mgr_event_cb_func event_cb; uint32_t phy_sel; - bool can_use_lite; void *cb_priv; + bool can_use_lite; + bool sfe_en; + bool use_wm_pack; }; /** 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 765d486fb0..3ec7db0ef7 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 @@ -203,6 +203,7 @@ enum cam_isp_hw_cmd_type { CAM_ISP_HW_CMD_INIT_CONFIG_UPDATE, CAM_ISP_HW_CSID_MINI_DUMP, CAM_ISP_HW_BUS_MINI_DUMP, + CAM_ISP_HW_CMD_RDI_LCR_CFG, CAM_ISP_HW_CMD_MAX, }; diff --git a/drivers/cam_isp/isp_hw_mgr/isp_hw/include/cam_sfe_hw_intf.h b/drivers/cam_isp/isp_hw_mgr/isp_hw/include/cam_sfe_hw_intf.h index 74ec631686..a7484890e8 100644 --- a/drivers/cam_isp/isp_hw_mgr/isp_hw/include/cam_sfe_hw_intf.h +++ b/drivers/cam_isp/isp_hw_mgr/isp_hw/include/cam_sfe_hw_intf.h @@ -307,6 +307,7 @@ struct cam_sfe_hw_sfe_in_acquire_args { * @split_id: In case of Dual SFE, this is Left or Right. * @is_master: In case of Dual SFE, this is Master or Slave. * @cdm_ops: CDM operations + * @use_wm_pack: Flag to indicalte packing at WM side */ struct cam_sfe_hw_sfe_out_acquire_args { struct cam_isp_resource_node *rsrc_node; @@ -316,6 +317,7 @@ struct cam_sfe_hw_sfe_out_acquire_args { enum cam_isp_hw_split_id split_id; uint32_t is_master; struct cam_cdm_utils_ops *cdm_ops; + bool use_wm_pack; }; /* diff --git a/drivers/cam_isp/isp_hw_mgr/isp_hw/include/cam_vfe_hw_intf.h b/drivers/cam_isp/isp_hw_mgr/isp_hw/include/cam_vfe_hw_intf.h index d3cbc8cf6a..d8aecb4ce0 100644 --- a/drivers/cam_isp/isp_hw_mgr/isp_hw/include/cam_vfe_hw_intf.h +++ b/drivers/cam_isp/isp_hw_mgr/isp_hw/include/cam_vfe_hw_intf.h @@ -142,6 +142,7 @@ struct cam_vfe_hw_vfe_bus_rd_acquire_args { * @dual_slave_core: If Master and Slave exists, HW Index of Slave * @cdm_ops: CDM operations * @disable_ubwc_comp: Disable UBWC compression + * @use_wm_pack: Use WM Packing */ struct cam_vfe_hw_vfe_out_acquire_args { struct cam_isp_resource_node *rsrc_node; @@ -153,6 +154,7 @@ struct cam_vfe_hw_vfe_out_acquire_args { uint32_t dual_slave_core; struct cam_cdm_utils_ops *cdm_ops; bool disable_ubwc_comp; + bool use_wm_pack; }; /* diff --git a/drivers/cam_isp/isp_hw_mgr/isp_hw/sfe_hw/sfe_bus/cam_sfe_bus_wr.c b/drivers/cam_isp/isp_hw_mgr/isp_hw/sfe_hw/sfe_bus/cam_sfe_bus_wr.c index 8c9fdd7c05..375d713fe0 100644 --- a/drivers/cam_isp/isp_hw_mgr/isp_hw/sfe_hw/sfe_bus/cam_sfe_bus_wr.c +++ b/drivers/cam_isp/isp_hw_mgr/isp_hw/sfe_hw/sfe_bus/cam_sfe_bus_wr.c @@ -113,8 +113,6 @@ struct cam_sfe_bus_wr_wm_resource_data { struct cam_sfe_bus_reg_offset_bus_client *hw_regs; struct cam_sfe_wr_scratch_buf_info scratch_buf_info; - bool init_cfg_done; - bool hfr_cfg_done; uint32_t offset; uint32_t width; @@ -137,9 +135,12 @@ struct cam_sfe_bus_wr_wm_resource_data { uint32_t acquired_width; uint32_t acquired_height; - bool enable_caching; uint32_t cache_cfg; int32_t current_scid; + bool enable_caching; + bool init_cfg_done; + bool hfr_cfg_done; + bool use_wm_pack; }; struct cam_sfe_bus_wr_comp_grp_data { @@ -501,7 +502,8 @@ static inline void cam_sfe_bus_config_rdi_wm_frame_based_mode( static int cam_sfe_bus_config_rdi_wm( struct cam_sfe_bus_wr_wm_resource_data *rsrc_data) { - rsrc_data->pack_fmt = 0x0; + + rsrc_data->pack_fmt = PACKER_FMT_PLAIN_128; switch (rsrc_data->format) { case CAM_FORMAT_MIPI_RAW_10: if (rsrc_data->wm_mode == CAM_SFE_WM_LINE_BASED_MODE) { @@ -514,6 +516,12 @@ static int cam_sfe_bus_config_rdi_wm( CAM_WARN(CAM_SFE, "No index mode support for SFE WM: %u", rsrc_data->index); } + + if (rsrc_data->use_wm_pack) { + rsrc_data->pack_fmt = PACKER_FMT_MIPI10; + if (rsrc_data->wm_mode == CAM_SFE_WM_LINE_BASED_MODE) + rsrc_data->width = ALIGNUP((rsrc_data->acquired_width), 16); + } break; case CAM_FORMAT_MIPI_RAW_6: if (rsrc_data->wm_mode == CAM_SFE_WM_LINE_BASED_MODE) { @@ -550,6 +558,12 @@ static int cam_sfe_bus_config_rdi_wm( CAM_WARN(CAM_SFE, "No index mode support for SFE WM: %u", rsrc_data->index); } + + if (rsrc_data->use_wm_pack) { + rsrc_data->pack_fmt = PACKER_FMT_MIPI12; + if (rsrc_data->wm_mode == CAM_SFE_WM_LINE_BASED_MODE) + rsrc_data->width = ALIGNUP((rsrc_data->acquired_width), 16); + } break; case CAM_FORMAT_MIPI_RAW_14: if (rsrc_data->wm_mode == CAM_SFE_WM_LINE_BASED_MODE) { @@ -562,6 +576,11 @@ static int cam_sfe_bus_config_rdi_wm( CAM_WARN(CAM_SFE, "No index mode support for SFE WM: %u", rsrc_data->index); } + if (rsrc_data->use_wm_pack) { + rsrc_data->pack_fmt = PACKER_FMT_MIPI14; + if (rsrc_data->wm_mode == CAM_SFE_WM_LINE_BASED_MODE) + rsrc_data->width = ALIGNUP((rsrc_data->acquired_width), 16); + } break; case CAM_FORMAT_MIPI_RAW_16: if (rsrc_data->wm_mode == CAM_SFE_WM_LINE_BASED_MODE) { @@ -659,15 +678,14 @@ static int cam_sfe_bus_config_rdi_wm( } static int cam_sfe_bus_acquire_wm( - struct cam_sfe_bus_wr_priv *bus_priv, - struct cam_isp_out_port_generic_info *out_port_info, - void *tasklet, - enum cam_sfe_bus_sfe_out_type sfe_out_res_id, - enum cam_sfe_bus_plane_type plane, - struct cam_isp_resource_node *wm_res, - uint32_t *comp_done_mask, - uint32_t is_dual, - enum cam_sfe_bus_wr_comp_grp_type *comp_grp_id) + struct cam_sfe_bus_wr_priv *bus_priv, + struct cam_sfe_hw_sfe_out_acquire_args *out_acq_args, + void *tasklet, + enum cam_sfe_bus_sfe_out_type sfe_out_res_id, + enum cam_sfe_bus_plane_type plane, + struct cam_isp_resource_node *wm_res, + uint32_t *comp_done_mask, + enum cam_sfe_bus_wr_comp_grp_type *comp_grp_id) { int32_t wm_idx = 0, rc; struct cam_sfe_bus_wr_wm_resource_data *rsrc_data = NULL; @@ -681,15 +699,16 @@ static int cam_sfe_bus_acquire_wm( rsrc_data = wm_res->res_priv; wm_idx = rsrc_data->index; - rsrc_data->format = out_port_info->format; + rsrc_data->format = out_acq_args->out_port_info->format; + rsrc_data->use_wm_pack = out_acq_args->use_wm_pack; rsrc_data->pack_fmt = cam_sfe_bus_get_packer_fmt(bus_priv, rsrc_data->format, wm_idx); - rsrc_data->width = out_port_info->width; - rsrc_data->height = out_port_info->height; - rsrc_data->acquired_width = out_port_info->width; - rsrc_data->acquired_height = out_port_info->height; - rsrc_data->is_dual = is_dual; + rsrc_data->width = out_acq_args->out_port_info->width; + rsrc_data->height = out_acq_args->out_port_info->height; + rsrc_data->acquired_width = out_acq_args->out_port_info->width; + rsrc_data->acquired_height = out_acq_args->out_port_info->height; + rsrc_data->is_dual = out_acq_args->is_dual; rsrc_data->enable_caching = false; rsrc_data->offset = 0; @@ -1350,13 +1369,12 @@ static int cam_sfe_bus_acquire_sfe_out(void *priv, void *acquire_args, /* Acquire WM and retrieve COMP GRP ID */ for (i = 0; i < rsrc_data->num_wm; i++) { rc = cam_sfe_bus_acquire_wm(bus_priv, - out_acquire_args->out_port_info, + out_acquire_args, acq_args->tasklet, sfe_out_res_id, i, &rsrc_data->wm_res[i], &client_done_mask, - out_acquire_args->is_dual, &comp_grp_id); if (rc) { CAM_ERR(CAM_SFE, 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 3781630e98..18273023ab 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 @@ -517,6 +517,7 @@ int cam_vfe_process_cmd(void *hw_priv, uint32_t cmd_type, case CAM_ISP_HW_CMD_GET_PATH_PORT_MAP: case CAM_ISP_HW_CMD_APPLY_CLK_BW_UPDATE: case CAM_ISP_HW_CMD_INIT_CONFIG_UPDATE: + case CAM_ISP_HW_CMD_RDI_LCR_CFG: 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/vfe17x/cam_vfe780.h b/drivers/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe17x/cam_vfe780.h index 2eb872b06a..9487c174fa 100644 --- a/drivers/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe17x/cam_vfe780.h +++ b/drivers/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe17x/cam_vfe780.h @@ -472,6 +472,21 @@ static struct cam_vfe_top_ver4_pdaf_violation_desc vfe780_pdaf_violation_desc[] }, }; +static struct cam_vfe_top_ver4_pdaf_lcr_res_info vfe780_pdaf_lcr_res_mask[] = { + { + .res_id = CAM_ISP_HW_VFE_IN_RDI0, + .val = 0, + }, + { + .res_id = CAM_ISP_HW_VFE_IN_RDI1, + .val = 1, + }, + { + .res_id = CAM_ISP_HW_VFE_IN_RDI2, + .val= 2, + }, +}; + static struct cam_irq_register_set vfe780_top_irq_reg_set[2] = { { .mask_reg_offset = 0x00000034, @@ -530,6 +545,8 @@ static struct cam_vfe_top_ver4_reg_offset_common vfe780_top_common_reg = { .bus_overflow_status = 0x00000C68, .top_debug_cfg = 0x000000FC, .num_top_debug_reg = CAM_VFE_780_NUM_DBG_REG, + .pdaf_input_cfg_0 = 0x00000130, + .pdaf_input_cfg_1 = 0x00000134, .top_debug = { 0x000000A0, 0x000000A4, @@ -818,6 +835,8 @@ static struct cam_vfe_top_ver4_hw_info vfe780_top_hw_info = { .num_pdaf_violation_errors = ARRAY_SIZE(vfe780_pdaf_violation_desc), .pdaf_violation_desc = vfe780_pdaf_violation_desc, .debug_reg_info = &vfe780_dbg_reg_info, + .pdaf_lcr_res_mask = vfe780_pdaf_lcr_res_mask, + .num_pdaf_lcr_res = ARRAY_SIZE(vfe780_pdaf_lcr_res_mask), }; static struct cam_irq_register_set vfe780_bus_irq_reg[2] = { diff --git a/drivers/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe_bus/cam_vfe_bus_ver3.c b/drivers/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe_bus/cam_vfe_bus_ver3.c index 4d9a3fd9c2..82a489aca6 100644 --- a/drivers/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe_bus/cam_vfe_bus_ver3.c +++ b/drivers/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe_bus/cam_vfe_bus_ver3.c @@ -151,6 +151,7 @@ struct cam_vfe_bus_ver3_wm_resource_data { uint32_t acquired_width; uint32_t acquired_height; uint32_t default_line_based; + bool use_wm_pack; }; struct cam_vfe_bus_ver3_comp_grp_data { @@ -847,7 +848,7 @@ static int cam_vfe_bus_ver3_handle_rup_bottom_half(void *handler_priv, static int cam_vfe_bus_ver3_config_rdi_wm( struct cam_vfe_bus_ver3_wm_resource_data *rsrc_data) { - /* Force RDI to use PLAIN128 */ + rsrc_data->pack_fmt = PACKER_FMT_VER3_PLAIN_128; switch (rsrc_data->format) { case CAM_FORMAT_MIPI_RAW_10: @@ -861,6 +862,12 @@ static int cam_vfe_bus_ver3_config_rdi_wm( rsrc_data->stride = CAM_VFE_RDI_BUS_DEFAULT_STRIDE; rsrc_data->en_cfg = (0x1 << 16) | 0x1; } + + if (rsrc_data->use_wm_pack) { + rsrc_data->pack_fmt = PACKER_FMT_VER3_MIPI10; + if (rsrc_data->default_line_based) + rsrc_data->width = ALIGNUP((rsrc_data->acquired_width), 16); + } break; case CAM_FORMAT_MIPI_RAW_6: if (rsrc_data->default_line_based) { @@ -898,6 +905,12 @@ static int cam_vfe_bus_ver3_config_rdi_wm( rsrc_data->stride = CAM_VFE_RDI_BUS_DEFAULT_STRIDE; rsrc_data->en_cfg = (0x1 << 16) | 0x1; } + + if (rsrc_data->use_wm_pack) { + rsrc_data->pack_fmt = PACKER_FMT_VER3_MIPI12; + if (rsrc_data->default_line_based) + rsrc_data->width = ALIGNUP((rsrc_data->acquired_width), 16); + } break; case CAM_FORMAT_MIPI_RAW_14: if (rsrc_data->default_line_based) { @@ -910,6 +923,12 @@ static int cam_vfe_bus_ver3_config_rdi_wm( rsrc_data->stride = CAM_VFE_RDI_BUS_DEFAULT_STRIDE; rsrc_data->en_cfg = (0x1 << 16) | 0x1; } + + if (rsrc_data->use_wm_pack) { + rsrc_data->pack_fmt = PACKER_FMT_VER3_MIPI14; + if (rsrc_data->default_line_based) + rsrc_data->width = ALIGNUP((rsrc_data->acquired_width), 16); + } break; case CAM_FORMAT_MIPI_RAW_16: if (rsrc_data->default_line_based) { @@ -934,6 +953,9 @@ static int cam_vfe_bus_ver3_config_rdi_wm( rsrc_data->stride = CAM_VFE_RDI_BUS_DEFAULT_STRIDE; rsrc_data->en_cfg = (0x1 << 16) | 0x1; } + + if (rsrc_data->use_wm_pack) + rsrc_data->pack_fmt = PACKER_FMT_VER3_MIPI20; break; case CAM_FORMAT_PLAIN128: if (rsrc_data->default_line_based) { @@ -998,13 +1020,12 @@ static int cam_vfe_bus_ver3_config_rdi_wm( } static int cam_vfe_bus_ver3_acquire_wm( - struct cam_vfe_bus_ver3_priv *ver3_bus_priv, - struct cam_isp_out_port_generic_info *out_port_info, - void *tasklet, - enum cam_vfe_bus_ver3_vfe_out_type vfe_out_res_id, - enum cam_vfe_bus_plane_type plane, - struct cam_isp_resource_node *wm_res, - uint32_t is_dual, + struct cam_vfe_bus_ver3_priv *ver3_bus_priv, + struct cam_vfe_hw_vfe_out_acquire_args *out_acq_args, + void *tasklet, + enum cam_vfe_bus_ver3_vfe_out_type vfe_out_res_id, + enum cam_vfe_bus_plane_type plane, + struct cam_isp_resource_node *wm_res, enum cam_vfe_bus_ver3_comp_grp_type *comp_grp_id) { int32_t wm_idx = 0, rc; @@ -1021,15 +1042,16 @@ static int cam_vfe_bus_ver3_acquire_wm( rsrc_data = wm_res->res_priv; wm_idx = rsrc_data->index; - rsrc_data->format = out_port_info->format; + rsrc_data->format = out_acq_args->out_port_info->format; + rsrc_data->use_wm_pack = out_acq_args->use_wm_pack; rsrc_data->pack_fmt = cam_vfe_bus_ver3_get_packer_fmt(rsrc_data->format, wm_idx); - rsrc_data->width = out_port_info->width; - rsrc_data->height = out_port_info->height; - rsrc_data->acquired_width = out_port_info->width; - rsrc_data->acquired_height = out_port_info->height; - rsrc_data->is_dual = is_dual; + rsrc_data->width = out_acq_args->out_port_info->width; + rsrc_data->height = out_acq_args->out_port_info->height; + rsrc_data->acquired_width = out_acq_args->out_port_info->width; + rsrc_data->acquired_height = out_acq_args->out_port_info->height; + rsrc_data->is_dual = out_acq_args->is_dual; /* Set WM offset value to default */ rsrc_data->offset = 0; CAM_DBG(CAM_ISP, "WM:%d width %d height %d", rsrc_data->index, @@ -2029,12 +2051,11 @@ static int cam_vfe_bus_ver3_acquire_vfe_out(void *bus_priv, void *acquire_args, /* Acquire WM and retrieve COMP GRP ID */ for (i = 0; i < rsrc_data->num_wm; i++) { rc = cam_vfe_bus_ver3_acquire_wm(ver3_bus_priv, - out_acquire_args->out_port_info, + out_acquire_args, acq_args->tasklet, vfe_out_res_id, i, &rsrc_data->wm_res[i], - out_acquire_args->is_dual, &comp_acq_args.comp_grp_id); if (rc) { CAM_ERR(CAM_ISP, diff --git a/drivers/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe_top/cam_vfe_top_ver4.c b/drivers/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe_top/cam_vfe_top_ver4.c index a3e2c0ec45..966d49a87f 100644 --- a/drivers/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe_top/cam_vfe_top_ver4.c +++ b/drivers/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe_top/cam_vfe_top_ver4.c @@ -99,6 +99,82 @@ static int cam_vfe_top_ver4_get_path_port_map(struct cam_vfe_top_ver4_priv *top_ return 0; } +static int cam_vfe_top_ver4_pdaf_lcr_config(struct cam_vfe_top_ver4_priv *top_priv, + void *cmd_args, uint32_t arg_size) +{ + struct cam_vfe_top_ver4_hw_info *hw_info; + struct cam_isp_hw_get_cmd_update *cdm_args = NULL; + struct cam_cdm_utils_ops *cdm_util_ops = NULL; + uint32_t i; + uint32_t reg_val_idx = 0; + uint32_t num_reg_vals; + uint32_t reg_val_pair[4]; + struct cam_isp_lcr_rdi_cfg_args *cfg_args; + size_t size; + + if (!cmd_args || !top_priv) { + CAM_ERR(CAM_ISP, "Error, Invalid args"); + return -EINVAL; + } + + cdm_args = (struct cam_isp_hw_get_cmd_update *)cmd_args; + if (!cdm_args->res) { + CAM_ERR(CAM_ISP, "Error, Invalid res"); + return -EINVAL; + } + + hw_info = top_priv->common_data.hw_info; + if (!hw_info->num_pdaf_lcr_res || !hw_info->pdaf_lcr_res_mask) { + CAM_DBG(CAM_ISP, "PDAF LCR is not supported"); + return 0; + } + + cfg_args = (struct cam_isp_lcr_rdi_cfg_args *)cdm_args->data; + 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; + } + + for (i = 0; i < hw_info->num_pdaf_lcr_res; i++) + if (cdm_args->res->res_id == + hw_info->pdaf_lcr_res_mask[i].res_id) + break; + + if (i == hw_info->num_pdaf_lcr_res) { + CAM_ERR(CAM_ISP, "Res :%d is not supported for mux", + cfg_args->rdi_lcr_cfg->res_id); + return -EINVAL; + } + + if (cfg_args->is_init) + num_reg_vals = 2; + else + num_reg_vals = 1; + + size = cdm_util_ops->cdm_required_size_reg_random(num_reg_vals); + /* 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*4)); + return -EINVAL; + } + + if (cfg_args->is_init) { + reg_val_pair[reg_val_idx++] = hw_info->common_reg->pdaf_input_cfg_1; + reg_val_pair[reg_val_idx++] = 0; + } + + reg_val_pair[reg_val_idx++] = hw_info->common_reg->pdaf_input_cfg_0; + reg_val_pair[reg_val_idx++] = hw_info->pdaf_lcr_res_mask[i].val; + cdm_util_ops->cdm_write_regrandom(cdm_args->cmd.cmd_buf_addr, + num_reg_vals, reg_val_pair); + cdm_args->cmd.used_bytes = size * 4; + + return 0; +} + static int cam_vfe_top_ver4_mux_get_base(struct cam_vfe_top_ver4_priv *top_priv, void *cmd_args, uint32_t arg_size) { @@ -887,6 +963,10 @@ int cam_vfe_top_ver4_process_cmd(void *device_priv, uint32_t cmd_type, case CAM_ISP_HW_CMD_INIT_CONFIG_UPDATE: rc = cam_vfe_init_config_update(cmd_args, arg_size); break; + case CAM_ISP_HW_CMD_RDI_LCR_CFG: + rc = cam_vfe_top_ver4_pdaf_lcr_config(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_ver4.h b/drivers/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe_top/cam_vfe_top_ver4.h index f529201aae..4c9fcd6511 100644 --- a/drivers/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe_top/cam_vfe_top_ver4.h +++ b/drivers/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe_top/cam_vfe_top_ver4.h @@ -57,6 +57,8 @@ struct cam_vfe_top_ver4_reg_offset_common { uint32_t epoch1_pattern_cfg; uint32_t epoch_height_cfg; uint32_t top_debug_cfg; + uint32_t pdaf_input_cfg_0; + uint32_t pdaf_input_cfg_1; uint32_t num_top_debug_reg; uint32_t top_debug[CAM_VFE_TOP_DBG_REG_MAX]; }; @@ -93,6 +95,11 @@ struct cam_vfe_top_ver4_pdaf_violation_desc { char *desc; }; +struct cam_vfe_top_ver4_pdaf_lcr_res_info { + uint32_t res_id; + uint32_t val; +}; + struct cam_vfe_ver4_path_hw_info { struct cam_vfe_top_ver4_reg_offset_common *common_reg; struct cam_vfe_ver4_path_reg_data *reg_data; @@ -121,6 +128,8 @@ struct cam_vfe_top_ver4_hw_info { struct cam_vfe_top_ver4_top_err_irq_desc *top_err_desc; uint32_t num_pdaf_violation_errors; struct cam_vfe_top_ver4_pdaf_violation_desc *pdaf_violation_desc; + struct cam_vfe_top_ver4_pdaf_lcr_res_info *pdaf_lcr_res_mask; + uint32_t num_pdaf_lcr_res; }; struct cam_vfe_ver4_path_reg_data { diff --git a/include/uapi/camera/media/cam_isp.h b/include/uapi/camera/media/cam_isp.h index 5851997f84..9cd37e01ed 100644 --- a/include/uapi/camera/media/cam_isp.h +++ b/include/uapi/camera/media/cam_isp.h @@ -124,6 +124,7 @@ #define CAM_ISP_GENERIC_BLOB_TYPE_BW_LIMITER_CFG 16 #define CAM_ISP_GENERIC_BLOB_TYPE_FPS_CONFIG 17 #define CAM_ISP_GENERIC_BLOB_TYPE_INIT_CONFIG 18 +#define CAM_ISP_GENERIC_BLOB_TYPE_RDI_LCR_CONFIG 19 #define CAM_ISP_GENERIC_BLOB_TYPE_SFE_CLOCK_CONFIG 21 #define CAM_ISP_GENERIC_BLOB_TYPE_SFE_CORE_CONFIG 22 #define CAM_ISP_GENERIC_BLOB_TYPE_SFE_OUT_CONFIG 23 @@ -1002,6 +1003,32 @@ struct cam_isp_init_config { __u32 additional_params[19]; }; +/** + * struct cam_isp_lcr_rdi_config - RDI res id to be muxed to LCR + * + * Configure RDI Res id for LCR + * + * @res_id : Out port Res id, it is same as the out port + * configured during acquire. It would vary + * as per SFE or IFE. Based on this res id, + * Mux register in IFE will be programmed. + * Examples: + * IFE: + * CAM_ISP_IFE_OUT_RES_RDI_0 + * SFE: + * CAM_ISP_SFE_OUT_RES_RDI_0 + * This blob is expected as a part of init packet for + * all LCR cases. For SHDR-LCR cases, this can be used + * per request. For non-shdr cases, this blob is not + * expected as the input to LCR will remain same throughout + * the session + * @reserved : Reserved field + */ +struct cam_isp_lcr_rdi_config { + __u32 res_id; + __u32 reserved[5]; +}; + #define CAM_ISP_ACQUIRE_COMMON_VER0 0x1000 #define CAM_ISP_ACQUIRE_COMMON_SIZE_VER0 0x0