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 76717c5aaa..6b7823a1f7 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 @@ -639,6 +639,50 @@ err: return rc; } +static int cam_ife_mgr_csid_start_hw( + struct cam_ife_hw_mgr_ctx *ctx) +{ + struct cam_isp_hw_mgr_res *hw_mgr_res; + struct cam_isp_resource_node *isp_res; + struct cam_isp_resource_node *res[CAM_IFE_PIX_PATH_RES_MAX - 1]; + struct cam_csid_hw_start_args start_args; + struct cam_hw_intf *hw_intf; + uint32_t cnt; + int j; + + for (j = ctx->num_base - 1 ; j >= 0; j--) { + + cnt = 0; + + if (ctx->base[j].hw_type != CAM_ISP_HW_TYPE_CSID) + continue; + + list_for_each_entry(hw_mgr_res, &ctx->res_list_ife_csid, list) { + + isp_res = hw_mgr_res->hw_res[ctx->base[j].split_id]; + + if (!isp_res || ctx->base[j].idx != isp_res->hw_intf->hw_idx) + continue; + + CAM_DBG(CAM_ISP, "csid[%u] res:%s res_id %d cnt %u", + isp_res->hw_intf->hw_idx, + isp_res->res_name, isp_res->res_id, cnt); + res[cnt] = isp_res; + cnt++; + } + + if (cnt) { + hw_intf = res[0]->hw_intf; + start_args.num_res = cnt; + start_args.node_res = res; + hw_intf->hw_ops.start(hw_intf->hw_priv, &start_args, + sizeof(start_args)); + } + } + + return 0; +} + static int cam_ife_hw_mgr_start_hw_res( struct cam_isp_hw_mgr_res *isp_hw_res, struct cam_ife_hw_mgr_ctx *ctx) @@ -1569,9 +1613,6 @@ static int cam_ife_mgr_process_base_info( csid_caps = &hw_mgr->csid_hw_caps[res->hw_intf->hw_idx]; - if (!csid_caps->need_separate_base) - continue; - cam_ife_mgr_add_base_info(ctx, i, res->hw_intf->hw_idx, CAM_ISP_HW_TYPE_CSID); @@ -6096,14 +6137,7 @@ static int cam_ife_mgr_restart_hw(void *start_hw_args) CAM_DBG(CAM_ISP, "START CSID HW ... in ctx id:%d", ctx->ctx_index); /* Start the IFE CSID HW devices */ - list_for_each_entry(hw_mgr_res, &ctx->res_list_ife_csid, list) { - rc = cam_ife_hw_mgr_start_hw_res(hw_mgr_res, ctx); - if (rc) { - CAM_ERR(CAM_ISP, "Can not start IFE CSID (%d)", - hw_mgr_res->res_id); - goto err; - } - } + cam_ife_mgr_csid_start_hw(ctx); /* Start IFE root node: do nothing */ CAM_DBG(CAM_ISP, "Exit...(success)"); @@ -6435,18 +6469,7 @@ start_only: CAM_DBG(CAM_ISP, "START CSID HW ... in ctx id:%d", ctx->ctx_index); /* Start the IFE CSID HW devices */ - list_for_each_entry(hw_mgr_res, &ctx->res_list_ife_csid, list) { - if (primary_rdi_csid_res == hw_mgr_res->res_id) { - hw_mgr_res->hw_res[0]->rdi_only_ctx = - ctx->flags.is_rdi_only_context; - } - rc = cam_ife_hw_mgr_start_hw_res(hw_mgr_res, ctx); - if (rc) { - CAM_ERR(CAM_ISP, "Can not start IFE CSID (%d)", - hw_mgr_res->res_id); - goto err; - } - } + cam_ife_mgr_csid_start_hw(ctx); if (ctx->flags.is_tpg) { CAM_DBG(CAM_ISP, "START TPG HW ... in ctx id:%d", 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 2c624fd6fb..7cc30e828f 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 @@ -2956,70 +2956,70 @@ int cam_ife_csid_ver1_deinit_hw(void *hw_priv, return rc; } -int cam_ife_csid_ver1_start(void *hw_priv, void *start_args, +int cam_ife_csid_ver1_start(void *hw_priv, void *args, uint32_t arg_size) { struct cam_ife_csid_ver1_hw *csid_hw = NULL; struct cam_isp_resource_node *res; struct cam_hw_info *hw_info; + struct cam_csid_hw_start_args *start_args; int rc = 0; + uint32_t i = 0; hw_info = (struct cam_hw_info *)hw_priv; csid_hw = (struct cam_ife_csid_ver1_hw *)hw_info->core_info; - res = (struct cam_isp_resource_node *)start_args; - - if (res->res_type != CAM_ISP_RESOURCE_PIX_PATH) { - CAM_ERR(CAM_ISP, "CSID:%d Invalid res type%d", - csid_hw->hw_intf->hw_idx, res->res_type); - rc = -EINVAL; - goto end; - } - - if (res->res_type == CAM_ISP_RESOURCE_PIX_PATH && - res->res_id >= CAM_IFE_PIX_PATH_RES_MAX) { - CAM_ERR(CAM_ISP, "CSID:%d Invalid res tpe:%d res id:%d", - csid_hw->hw_intf->hw_idx, res->res_type, - res->res_id); - rc = -EINVAL; - goto end; - } + start_args = (struct cam_csid_hw_start_args *)args; csid_hw->flags.sof_irq_triggered = false; csid_hw->counters.irq_debug_cnt = 0; - CAM_DBG(CAM_ISP, "CSID:%d res_type :%d res_id:%d", - csid_hw->hw_intf->hw_idx, res->res_type, res->res_id); + CAM_DBG(CAM_ISP, "CSID:%d num_res %u", + csid_hw->hw_intf->hw_idx, start_args->num_res); cam_ife_csid_ver1_enable_csi2(csid_hw); if (csid_hw->res_type == CAM_ISP_IFE_IN_RES_TPG) cam_ife_csid_ver1_tpg_start(csid_hw); - switch (res->res_id) { - case CAM_IFE_PIX_PATH_RES_IPP: - case CAM_IFE_PIX_PATH_RES_PPP: - rc = cam_ife_csid_ver1_start_pix_path(csid_hw, res); - break; - case CAM_IFE_PIX_PATH_RES_RDI_0: - case CAM_IFE_PIX_PATH_RES_RDI_1: - case CAM_IFE_PIX_PATH_RES_RDI_2: - case CAM_IFE_PIX_PATH_RES_RDI_3: - case CAM_IFE_PIX_PATH_RES_RDI_4: - rc = cam_ife_csid_ver1_start_rdi_path(csid_hw, res); - break; - case CAM_IFE_PIX_PATH_RES_UDI_0: - case CAM_IFE_PIX_PATH_RES_UDI_1: - case CAM_IFE_PIX_PATH_RES_UDI_2: - rc = cam_ife_csid_ver1_start_udi_path(csid_hw, res); - break; - default: - CAM_ERR(CAM_ISP, "CSID:%d Invalid res type%d", - csid_hw->hw_intf->hw_idx, res->res_type); - rc = -EINVAL; - break; + for (i = 0; i < start_args->num_res; i++) { + + res = start_args->node_res[i]; + if (!res || res->res_type != CAM_ISP_RESOURCE_PIX_PATH) { + CAM_ERR(CAM_ISP, "CSID:%d Invalid res type%d", + csid_hw->hw_intf->hw_idx, res->res_type); + rc = -EINVAL; + goto end; + } + CAM_DBG(CAM_ISP, "CSID:%d res_type :%d res: %s", + csid_hw->hw_intf->hw_idx, res->res_type, + res->res_name); + + switch (res->res_id) { + case CAM_IFE_PIX_PATH_RES_IPP: + case CAM_IFE_PIX_PATH_RES_PPP: + rc = cam_ife_csid_ver1_start_pix_path(csid_hw, res); + break; + case CAM_IFE_PIX_PATH_RES_RDI_0: + case CAM_IFE_PIX_PATH_RES_RDI_1: + case CAM_IFE_PIX_PATH_RES_RDI_2: + case CAM_IFE_PIX_PATH_RES_RDI_3: + case CAM_IFE_PIX_PATH_RES_RDI_4: + rc = cam_ife_csid_ver1_start_rdi_path(csid_hw, res); + break; + case CAM_IFE_PIX_PATH_RES_UDI_0: + case CAM_IFE_PIX_PATH_RES_UDI_1: + case CAM_IFE_PIX_PATH_RES_UDI_2: + rc = cam_ife_csid_ver1_start_udi_path(csid_hw, res); + break; + default: + CAM_ERR(CAM_ISP, "CSID:%d Invalid res type%d", + csid_hw->hw_intf->hw_idx, res->res_type); + rc = -EINVAL; + break; + } } - if (rc) + if (rc && res) CAM_ERR(CAM_ISP, "CSID:%d start fail res type:%d res id:%d", csid_hw->hw_intf->hw_idx, res->res_type, res->res_id); 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 469f1277a0..c326289d64 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 @@ -2696,7 +2696,6 @@ static int cam_ife_csid_ver2_init_config_pxl_path( } res->res_state = CAM_ISP_RESOURCE_STATE_INIT_HW; - return rc; } @@ -2735,7 +2734,7 @@ static inline int cam_ife_csid_ver2_subscribe_sof_for_discard( return rc; } -static int cam_ife_csid_ver2_start_rdi_path( +static int cam_ife_csid_ver2_program_rdi_path( struct cam_ife_csid_ver2_hw *csid_hw, struct cam_isp_resource_node *res) { @@ -2760,15 +2759,6 @@ static int cam_ife_csid_ver2_start_rdi_path( return rc; } - if (res->res_state != CAM_ISP_RESOURCE_STATE_INIT_HW || - res->res_id > CAM_IFE_PIX_PATH_RES_RDI_4) { - CAM_ERR(CAM_ISP, - "CSID:%d %s path res type:%d res_id:%d Invalid state%d", - csid_hw->hw_intf->hw_idx, - res->res_type, res->res_id, res->res_state); - return -EINVAL; - } - soc_info = &csid_hw->hw_info->soc_info; csid_reg = (struct cam_ife_csid_ver2_reg_info *) csid_hw->core_info->csid_reg; @@ -2784,11 +2774,6 @@ static int cam_ife_csid_ver2_start_rdi_path( mem_base = soc_info->reg_map[CAM_IFE_CSID_CLC_MEM_BASE_ID].mem_base; path_cfg = (struct cam_ife_csid_ver2_path_cfg *)res->res_priv; if (!csid_hw->flags.offline_mode) { - /* Resume at frame boundary if skip not requested */ - if (!path_cfg->discard_init_frames) - cam_io_w_mb(path_reg->resume_frame_boundary, - mem_base + path_reg->ctrl_addr); - CAM_DBG(CAM_ISP, "CSID:%d Rdi res: %d", csid_hw->hw_intf->hw_idx, res->res_id); @@ -2901,7 +2886,7 @@ end: } -static int cam_ife_csid_ver2_start_ipp_path( +static int cam_ife_csid_ver2_program_ipp_path( struct cam_ife_csid_ver2_hw *csid_hw, struct cam_isp_resource_node *res) { @@ -2926,15 +2911,6 @@ static int cam_ife_csid_ver2_start_ipp_path( return rc; } - if (res->res_state != CAM_ISP_RESOURCE_STATE_INIT_HW || - res->res_id != CAM_IFE_PIX_PATH_RES_IPP) { - CAM_ERR(CAM_ISP, - "CSID:%d %s path res type:%d res_id:%d Invalid state%d", - csid_hw->hw_intf->hw_idx, - res->res_type, res->res_id, res->res_state); - return -EINVAL; - } - soc_info = &csid_hw->hw_info->soc_info; csid_reg = (struct cam_ife_csid_ver2_reg_info *) csid_hw->core_info->csid_reg; @@ -3041,16 +3017,6 @@ static int cam_ife_csid_ver2_start_ipp_path( val = 0; } - /* - * Resume at frame boundary if Master or No Sync. - * Slave will get resume command from Master. - * If init frame drop requested skip resume - */ - if ((!path_cfg->discard_init_frames) && - (path_cfg->sync_mode == CAM_ISP_HW_SYNC_MASTER || - path_cfg->sync_mode == CAM_ISP_HW_SYNC_NONE)) - val |= path_reg->resume_frame_boundary; - cam_io_w_mb(val, mem_base + path_reg->ctrl_addr); CAM_DBG(CAM_ISP, "CSID:%d Pix res: %d ctrl val: 0x%x", @@ -3071,7 +3037,73 @@ end: return rc; } -static int cam_ife_csid_ver2_start_ppp_path( +static int cam_ife_csid_ver2_enable_path( + struct cam_ife_csid_ver2_hw *csid_hw, + struct cam_isp_resource_node *res) +{ + const struct cam_ife_csid_ver2_reg_info *csid_reg; + struct cam_hw_soc_info *soc_info; + const struct cam_ife_csid_ver2_pxl_reg_info *pxl_reg = NULL; + const struct cam_ife_csid_ver2_rdi_reg_info *rdi_reg; + uint32_t val = 0; + uint32_t ctrl_addr = 0; + struct cam_ife_csid_ver2_path_cfg *path_cfg; + void __iomem *mem_base; + + csid_reg = (struct cam_ife_csid_ver2_reg_info *) + csid_hw->core_info->csid_reg; + path_cfg = (struct cam_ife_csid_ver2_path_cfg *)res->res_priv; + soc_info = &csid_hw->hw_info->soc_info; + mem_base = soc_info->reg_map[CAM_IFE_CSID_CLC_MEM_BASE_ID].mem_base; + + if (path_cfg->discard_init_frames) { + CAM_DBG(CAM_ISP, "CSID[%u] skip start cmd for res: %s", + csid_hw->hw_intf->hw_idx, res->res_id); + goto end; + } + + switch (res->res_id) { + case CAM_IFE_PIX_PATH_RES_IPP: + if (path_cfg->sync_mode == CAM_ISP_HW_SYNC_SLAVE) + return 0; + pxl_reg = csid_reg->ipp_reg; + val = pxl_reg->resume_frame_boundary; + ctrl_addr = pxl_reg->ctrl_addr; + break; + case CAM_IFE_PIX_PATH_RES_PPP: + if (path_cfg->sync_mode == CAM_ISP_HW_SYNC_SLAVE) + return 0; + pxl_reg = csid_reg->ppp_reg; + val = pxl_reg->resume_frame_boundary; + ctrl_addr = pxl_reg->ctrl_addr; + break; + case CAM_IFE_PIX_PATH_RES_RDI_0: + case CAM_IFE_PIX_PATH_RES_RDI_1: + case CAM_IFE_PIX_PATH_RES_RDI_2: + case CAM_IFE_PIX_PATH_RES_RDI_3: + case CAM_IFE_PIX_PATH_RES_RDI_4: + if (csid_hw->flags.offline_mode) + return 0; + rdi_reg = csid_reg->rdi_reg[res->res_id]; + val = rdi_reg->resume_frame_boundary; + ctrl_addr = rdi_reg->ctrl_addr; + break; + default: + return -EINVAL; + } + + val |= cam_io_r_mb(mem_base + ctrl_addr); + cam_io_w_mb(val, mem_base + ctrl_addr); + + CAM_DBG(CAM_ISP, "CSID[%u] start cmd programmed for res: %s", + csid_hw->hw_intf->hw_idx, res->res_id); +end: + /* Change state even if we don't configure start cmd */ + res->res_state = CAM_ISP_RESOURCE_STATE_STREAMING; + return 0; +} + +static int cam_ife_csid_ver2_program_ppp_path( struct cam_ife_csid_ver2_hw *csid_hw, struct cam_isp_resource_node *res) { @@ -3096,15 +3128,6 @@ static int cam_ife_csid_ver2_start_ppp_path( return rc; } - if (res->res_state != CAM_ISP_RESOURCE_STATE_INIT_HW || - res->res_id != CAM_IFE_PIX_PATH_RES_PPP) { - CAM_ERR(CAM_ISP, - "CSID:%d %s path res type:%d res_id:%d Invalid state%d", - csid_hw->hw_intf->hw_idx, - res->res_type, res->res_id, res->res_state); - return -EINVAL; - } - soc_info = &csid_hw->hw_info->soc_info; csid_reg = (struct cam_ife_csid_ver2_reg_info *) csid_hw->core_info->csid_reg; @@ -3152,16 +3175,6 @@ static int cam_ife_csid_ver2_start_ppp_path( path_reg->start_master_sel_shift; } - /* - * Resume at frame boundary if Master or No Sync. - * Slave will get resume command from Master. - * If init frame drop requested skip resume - */ - if ((!path_cfg->discard_init_frames) && - (csid_hw->sync_mode == CAM_ISP_HW_SYNC_MASTER || - csid_hw->sync_mode == CAM_ISP_HW_SYNC_NONE)) - val |= path_reg->resume_frame_boundary; - cam_io_w_mb(val, mem_base + path_reg->ctrl_addr); CAM_DBG(CAM_ISP, "CSID:%d Pix res: %d ctrl val: 0x%x", @@ -3176,7 +3189,6 @@ static int cam_ife_csid_ver2_start_ppp_path( val = csid_hw->debug_info.path_mask; - res->res_state = CAM_ISP_RESOURCE_STATE_STREAMING; irq_mask[CAM_IFE_CSID_IRQ_REG_TOP] = top_irq_mask; irq_mask[path_cfg->irq_reg_idx] = val; @@ -3786,72 +3798,68 @@ disable_hw: return rc; } -int cam_ife_csid_ver2_start(void *hw_priv, void *start_args, +int cam_ife_csid_ver2_start(void *hw_priv, void *args, uint32_t arg_size) { struct cam_ife_csid_ver2_hw *csid_hw = NULL; - struct cam_isp_resource_node *res; + struct cam_isp_resource_node *res; + struct cam_csid_hw_start_args *start_args; struct cam_hw_info *hw_info; - int rc = 0; + int rc = 0, i; - if (!hw_priv || !start_args) { + if (!hw_priv || !args) { CAM_ERR(CAM_ISP, "CSID Invalid params"); return -EINVAL; } hw_info = (struct cam_hw_info *)hw_priv; csid_hw = (struct cam_ife_csid_ver2_hw *)hw_info->core_info; - res = (struct cam_isp_resource_node *)start_args; - - if (res->res_type != CAM_ISP_RESOURCE_PIX_PATH) { - CAM_ERR(CAM_ISP, "CSID:%d Invalid res type%d", - csid_hw->hw_intf->hw_idx, res->res_type); - rc = -EINVAL; - goto end; - } - - if (res->res_type == CAM_ISP_RESOURCE_PIX_PATH && - res->res_id >= CAM_IFE_PIX_PATH_RES_MAX) { - CAM_ERR(CAM_ISP, "CSID:%d Invalid res tpe:%d res id:%d", - csid_hw->hw_intf->hw_idx, res->res_type, - res->res_id); - rc = -EINVAL; - goto end; - } + start_args = (struct cam_csid_hw_start_args *)args; + mutex_lock(&csid_hw->hw_info->hw_mutex); csid_hw->flags.sof_irq_triggered = false; csid_hw->counters.irq_debug_cnt = 0; - CAM_DBG(CAM_ISP, "CSID:%d res_type :%d res_id:%d", - csid_hw->hw_intf->hw_idx, res->res_type, res->res_id); - - mutex_lock(&csid_hw->hw_info->hw_mutex); rc = cam_ife_csid_ver2_enable_hw(csid_hw); - cam_ife_csid_ver2_enable_csi2(csid_hw); - switch (res->res_id) { - case CAM_IFE_PIX_PATH_RES_IPP: - rc = cam_ife_csid_ver2_start_ipp_path(csid_hw, res); - break; - case CAM_IFE_PIX_PATH_RES_PPP: - rc = cam_ife_csid_ver2_start_ppp_path(csid_hw, res); - break; - case CAM_IFE_PIX_PATH_RES_RDI_0: - case CAM_IFE_PIX_PATH_RES_RDI_1: - case CAM_IFE_PIX_PATH_RES_RDI_2: - case CAM_IFE_PIX_PATH_RES_RDI_3: - case CAM_IFE_PIX_PATH_RES_RDI_4: - rc = cam_ife_csid_ver2_start_rdi_path(csid_hw, res); - break; - default: - CAM_ERR(CAM_ISP, "CSID:%d Invalid res type%d", - csid_hw->hw_intf->hw_idx, res->res_type); - break; + for (i = 0; i < start_args->num_res; i++) { + + res = start_args->node_res[i]; + CAM_DBG(CAM_ISP, "CSID:%d res_type :%d res_id:%d", + csid_hw->hw_intf->hw_idx, res->res_type, + res->res_id); + + switch (res->res_id) { + case CAM_IFE_PIX_PATH_RES_IPP: + rc = cam_ife_csid_ver2_program_ipp_path(csid_hw, res); + break; + case CAM_IFE_PIX_PATH_RES_PPP: + rc = cam_ife_csid_ver2_program_ppp_path(csid_hw, res); + break; + case CAM_IFE_PIX_PATH_RES_RDI_0: + case CAM_IFE_PIX_PATH_RES_RDI_1: + case CAM_IFE_PIX_PATH_RES_RDI_2: + case CAM_IFE_PIX_PATH_RES_RDI_3: + case CAM_IFE_PIX_PATH_RES_RDI_4: + rc = cam_ife_csid_ver2_program_rdi_path(csid_hw, res); + break; + default: + CAM_ERR(CAM_ISP, "CSID:%d Invalid res type%d", + csid_hw->hw_intf->hw_idx, res->res_type); + break; + } } - mutex_unlock(&csid_hw->hw_info->hw_mutex); + for (i = 0; i < start_args->num_res; i++) { + res = start_args->node_res[i]; + CAM_DBG(CAM_ISP, "CSID:%d res_type :%d res_id:%d", + csid_hw->hw_intf->hw_idx, res->res_type, + res->res_id); + cam_ife_csid_ver2_enable_path(csid_hw, res); + } -end: + cam_ife_csid_ver2_enable_csi2(csid_hw); + mutex_unlock(&csid_hw->hw_info->hw_mutex); return rc; } 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 9cd703efa4..732f81ca7e 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 @@ -250,6 +250,12 @@ struct cam_csid_hw_stop_args { uint32_t num_res; }; +struct cam_csid_hw_start_args { + struct cam_isp_resource_node **node_res; + uint32_t num_res; +}; + + /** * enum cam_ife_csid_reset_type - Specify the reset type */