diff --git a/drivers/cam_core/cam_hw_mgr_intf.h b/drivers/cam_core/cam_hw_mgr_intf.h index cc9890c4a7..d3d91e2d2a 100644 --- a/drivers/cam_core/cam_hw_mgr_intf.h +++ b/drivers/cam_core/cam_hw_mgr_intf.h @@ -169,6 +169,7 @@ struct cam_hw_acquire_stream_caps { * @hw_mgr_ctx_id HWMgr context id(returned) * @op_flags: Used as bitwise params from hw_mgr to ctx * See xxx_hw_mgr_intf.h for definitions + * @link_hdl: Link handle * @acquired_hw_id: Acquired hardware mask * @acquired_hw_path: Acquired path mask for an input * if input splits into multiple paths, @@ -189,11 +190,10 @@ struct cam_hw_acquire_args { void *ctxt_to_hw_map; uint32_t hw_mgr_ctx_id; uint32_t op_flags; - - uint32_t acquired_hw_id[CAM_MAX_ACQ_RES]; - uint32_t acquired_hw_path[CAM_MAX_ACQ_RES][CAM_MAX_HW_SPLIT]; - uint32_t valid_acquired_hw; - + int32_t link_hdl; + uint32_t acquired_hw_id[CAM_MAX_ACQ_RES]; + uint32_t acquired_hw_path[CAM_MAX_ACQ_RES][CAM_MAX_HW_SPLIT]; + uint32_t valid_acquired_hw; struct cam_hw_acquire_stream_caps op_params; cam_ctx_mini_dump_cb_func mini_dump_cb; }; diff --git a/drivers/cam_isp/cam_isp_context.c b/drivers/cam_isp/cam_isp_context.c index a51964e8ab..bdfff772fb 100644 --- a/drivers/cam_isp/cam_isp_context.c +++ b/drivers/cam_isp/cam_isp_context.c @@ -7431,6 +7431,7 @@ static int __cam_isp_ctx_acquire_hw_v1(struct cam_context *ctx, param.acquire_info_size = cmd->data_size; param.acquire_info = (uint64_t) acquire_hw_info; param.mini_dump_cb = __cam_isp_ctx_minidump_cb; + param.link_hdl = ctx->link_hdl; rc = __cam_isp_ctx_allocate_mem_hw_entries(ctx, ¶m); @@ -7598,6 +7599,7 @@ static int __cam_isp_ctx_acquire_hw_v2(struct cam_context *ctx, param.acquire_info_size = cmd->data_size; param.acquire_info = (uint64_t) acquire_hw_info; param.mini_dump_cb = __cam_isp_ctx_minidump_cb; + param.link_hdl = ctx->link_hdl; /* call HW manager to reserve the resource */ rc = ctx->hw_mgr_intf->hw_acquire(ctx->hw_mgr_intf->hw_mgr_priv, 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 ceb8034f47..9360fa554a 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 @@ -2371,8 +2371,10 @@ static int cam_tfe_mgr_acquire_hw(void *hw_mgr_priv, void *acquire_hw_args) for (i = 0; i < acquire_hw_info->num_inputs; i++) { if (in_port[i].usage_type) tfe_ctx->is_dual = true; - if (in_port[i].shdr_en) + if (in_port[i].shdr_en) { is_shdr_en = true; + tfe_ctx->is_shdr = true; + } if (in_port[i].is_shdr_master) is_shdr_master = true; } @@ -2448,8 +2450,14 @@ static int cam_tfe_mgr_acquire_hw(void *hw_mgr_priv, void *acquire_hw_args) acquire_args->op_flags |= CAM_IFE_CTX_SHDR_EN; if (is_shdr_master) acquire_args->op_flags |= CAM_IFE_CTX_SHDR_IS_MASTER; + g_tfe_hw_mgr.session_data[tfe_ctx->base[0].idx].is_shdr = true; + + CAM_DBG(CAM_ISP, "ctx %d TFE index %d link hdl %x", + tfe_ctx->ctx_index, tfe_ctx->base[0].idx, acquire_args->link_hdl); } + g_tfe_hw_mgr.session_data[tfe_ctx->base[0].idx].link_hdl = acquire_args->link_hdl; + cam_tfe_hw_mgr_put_ctx(&tfe_hw_mgr->used_ctx_list, &tfe_ctx); CAM_DBG(CAM_ISP, "Exit...(success)"); @@ -3583,7 +3591,7 @@ static int cam_tfe_mgr_start_hw(void *hw_mgr_priv, void *start_hw_args) struct cam_tfe_hw_mgr_ctx *ctx; struct cam_isp_hw_mgr_res *hw_mgr_res; struct cam_hw_intf *hw_intf; - uint32_t i; + uint32_t i, j, hw_index = 0; bool res_rdi_context_set = false; uint32_t primary_rdi_in_res; uint32_t primary_rdi_out_res; @@ -3654,6 +3662,25 @@ static int cam_tfe_mgr_start_hw(void *hw_mgr_priv, void *start_hw_args) &g_tfe_hw_mgr.debug_cfg.camif_debug, sizeof(g_tfe_hw_mgr.debug_cfg.camif_debug)); hw_id[hw_intf->hw_idx] = true; + + if (ctx->is_shdr) { + for (j = 0; j < CAM_TFE_HW_NUM_MAX; j++) { + if (g_tfe_hw_mgr.session_data[j].link_hdl == + g_tfe_hw_mgr.session_data[ctx->base[0].idx].link_hdl + && (j != ctx->base[0].idx) && + g_tfe_hw_mgr.session_data[j].is_shdr) { + hw_index = j; + break; + } + } + + rc = hw_intf->hw_ops.process_cmd( + hw_intf->hw_priv, + CAM_ISP_HW_CMD_SET_SYNC_HW_IDX, + &hw_index, + sizeof(hw_index)); + CAM_DBG(CAM_ISP, "TFE: %d sync idx %d", ctx->base[0].idx, hw_index); + } } } @@ -4007,6 +4034,11 @@ static int cam_tfe_mgr_release_hw(void *hw_mgr_priv, CAM_DBG(CAM_ISP, "Enter...ctx id:%d", ctx->ctx_index); + if (ctx->is_shdr) { + g_tfe_hw_mgr.session_data[ctx->base[0].idx].link_hdl = 0; + g_tfe_hw_mgr.session_data[ctx->base[0].idx].is_shdr = false; + } + if (ctx->init_done) cam_tfe_hw_mgr_deinit_hw(ctx); @@ -4032,6 +4064,8 @@ static int cam_tfe_mgr_release_hw(void *hw_mgr_priv, ctx->last_cdm_done_req = 0; kfree(ctx->tfe_bus_comp_grp); ctx->tfe_bus_comp_grp = NULL; + ctx->is_shdr = false; + ctx->is_shdr_slave = false; atomic_set(&ctx->overflow_pending, 0); for (i = 0; i < ctx->last_submit_bl_cmd.bl_count; i++) { @@ -6745,6 +6779,8 @@ int cam_tfe_hw_mgr_init(struct cam_hw_mgr_intf *hw_mgr_intf, int *iommu_hdl) j++; g_tfe_hw_mgr.cdm_reg_map[i] = &soc_info->reg_map[0]; + g_tfe_hw_mgr.session_data[i].link_hdl = 0; + g_tfe_hw_mgr.session_data[i].is_shdr = false; CAM_DBG(CAM_ISP, "reg_map: mem base = %pK cam_base = 0x%llx", (void __iomem *)soc_info->reg_map[0].mem_base, diff --git a/drivers/cam_isp/isp_hw_mgr/cam_tfe_hw_mgr.h b/drivers/cam_isp/isp_hw_mgr/cam_tfe_hw_mgr.h index d6276480b7..4d971d2b19 100644 --- a/drivers/cam_isp/isp_hw_mgr/cam_tfe_hw_mgr.h +++ b/drivers/cam_isp/isp_hw_mgr/cam_tfe_hw_mgr.h @@ -129,7 +129,8 @@ struct cam_tfe_cdm_user_data { * @try_recovery_cnt Retry count for overflow recovery * @current_mup Current MUP val * @recovery_req_id The request id on which overflow recovery happens - * @is_shdr_slave indicate whether context is slave in shdr usecase + * @is_shdr Indicate if the usecase is SHDR + * @is_shdr_slave Indicate whether context is slave in shdr usecase */ struct cam_tfe_hw_mgr_ctx { struct list_head list; @@ -178,6 +179,7 @@ struct cam_tfe_hw_mgr_ctx { uint32_t try_recovery_cnt; uint64_t recovery_req_id; enum cam_cdm_id cdm_id; + bool is_shdr; bool is_shdr_slave; }; @@ -195,6 +197,7 @@ struct cam_tfe_hw_mgr_ctx { * @free_ctx_list: free hw context list * @used_ctx_list: used hw context list * @ctx_pool: context storage + * @session_data: Data related to current session * @tfe_csid_dev_caps csid device capability stored per core * @tfe_dev_caps tfe device capability per core * @work q work queue for TFE hw manager @@ -204,24 +207,25 @@ struct cam_tfe_hw_mgr_ctx { * @ctx_lock Spinlock for HW manager */ struct cam_tfe_hw_mgr { - struct cam_isp_hw_mgr mgr_common; - struct cam_hw_intf *csid_devices[CAM_TFE_CSID_HW_NUM_MAX]; - struct cam_isp_hw_intf_data *tfe_devices[CAM_TFE_HW_NUM_MAX]; - struct cam_soc_reg_map *cdm_reg_map[CAM_TFE_HW_NUM_MAX]; - struct mutex ctx_mutex; - atomic_t active_ctx_cnt; - struct list_head free_ctx_list; - struct list_head used_ctx_list; - struct cam_tfe_hw_mgr_ctx ctx_pool[CAM_TFE_CTX_MAX]; + struct cam_isp_hw_mgr mgr_common; + struct cam_hw_intf *csid_devices[CAM_TFE_CSID_HW_NUM_MAX]; + struct cam_isp_hw_intf_data *tfe_devices[CAM_TFE_HW_NUM_MAX]; + struct cam_soc_reg_map *cdm_reg_map[CAM_TFE_HW_NUM_MAX]; + struct mutex ctx_mutex; + atomic_t active_ctx_cnt; + struct list_head free_ctx_list; + struct list_head used_ctx_list; + struct cam_tfe_hw_mgr_ctx ctx_pool[CAM_TFE_CTX_MAX]; + struct cam_isp_session_data session_data[CAM_TFE_HW_NUM_MAX]; - struct cam_tfe_csid_hw_caps tfe_csid_dev_caps[ + struct cam_tfe_csid_hw_caps tfe_csid_dev_caps[ CAM_TFE_CSID_HW_NUM_MAX]; - struct cam_tfe_hw_get_hw_cap tfe_dev_caps[CAM_TFE_HW_NUM_MAX]; - struct cam_req_mgr_core_workq *workq; - struct cam_tfe_hw_mgr_debug debug_cfg; + struct cam_tfe_hw_get_hw_cap tfe_dev_caps[CAM_TFE_HW_NUM_MAX]; + struct cam_req_mgr_core_workq *workq; + struct cam_tfe_hw_mgr_debug debug_cfg; struct cam_isp_hw_path_port_map path_port_map; - bool support_consumed_addr; - spinlock_t ctx_lock; + bool support_consumed_addr; + spinlock_t ctx_lock; }; /** 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 fe64c76954..c3a9543d0d 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 @@ -257,6 +257,7 @@ enum cam_isp_hw_cmd_type { CAM_ISP_HW_CMD_DUMP_IRQ_DESCRIPTION, CAM_ISP_HW_CMD_GET_SET_PRIM_SOF_TS_ADDR, CAM_ISP_HW_CMD_DYNAMIC_CLOCK_UPDATE, + CAM_ISP_HW_CMD_SET_SYNC_HW_IDX, CAM_ISP_HW_CMD_MAX, }; @@ -588,6 +589,20 @@ struct cam_isp_hw_dump_header { uint32_t word_size; }; +/** + * struct cam_isp_session_data - Session data + * + * @Brief: ISP session or usecase data + * + * @link_hdl: Link handle + * @is_shdr: Indicate is usecase is shdr + * + */ +struct cam_isp_session_data { + int32_t link_hdl; + bool is_shdr; +}; + /** * struct cam_isp_hw_intf_data - ISP hw intf data * diff --git a/drivers/cam_isp/isp_hw_mgr/isp_hw/tfe_hw/cam_tfe770.h b/drivers/cam_isp/isp_hw_mgr/isp_hw/tfe_hw/cam_tfe770.h index 96f967d906..2a0126c690 100644 --- a/drivers/cam_isp/isp_hw_mgr/isp_hw/tfe_hw/cam_tfe770.h +++ b/drivers/cam_isp/isp_hw_mgr/isp_hw/tfe_hw/cam_tfe770.h @@ -153,6 +153,8 @@ static struct cam_tfe_camif_reg_data tfe770_camif_reg_data = { .ai_c_srl_en_shift = 11, .ds16_c_srl_en_shift = 10, .ds4_c_srl_en_shift = 9, + .shdr_mode_shift = 21, + .extern_mup_shift = 22, }; static struct cam_tfe_rdi_reg tfe770_rdi0_reg = { diff --git a/drivers/cam_isp/isp_hw_mgr/isp_hw/tfe_hw/cam_tfe_core.c b/drivers/cam_isp/isp_hw_mgr/isp_hw/tfe_hw/cam_tfe_core.c index 23d024501a..bb453a3984 100644 --- a/drivers/cam_isp/isp_hw_mgr/isp_hw/tfe_hw/cam_tfe_core.c +++ b/drivers/cam_isp/isp_hw_mgr/isp_hw/tfe_hw/cam_tfe_core.c @@ -31,6 +31,7 @@ static const char drv_name[] = "tfe"; #define CAM_TFE_CAMIF_IRQ_SOF_DEBUG_CNT_MAX 2 #define CAM_TFE_DELAY_BW_REDUCTION_NUM_FRAMES 3 #define CAM_TFE_MAX_OUT_OF_SYNC_ERR_COUNT 3 +#define CAM_TFE_DUAL_TFE_SYNC_SEL_IDX_FACTOR 1 struct cam_tfe_top_common_data { struct cam_hw_soc_info *soc_info; @@ -60,6 +61,7 @@ struct cam_tfe_top_priv { struct timespec64 error_ts; uint32_t top_debug; uint32_t last_mup_val; + uint32_t sync_hw_id; atomic_t switch_out_of_sync_cnt; }; @@ -1764,6 +1766,27 @@ static int cam_tfe_top_bw_control( return rc; } +static int cam_tfe_set_sync_hw_idx( + struct cam_tfe_hw_core_info *core_info, + void *cmd_args, uint32_t arg_size) +{ + struct cam_tfe_top_priv *top_priv; + uint32_t *hw_idx; + + if (!cmd_args) { + CAM_ERR(CAM_ISP, "Error! Invalid input arguments"); + return -EINVAL; + } + + top_priv = (struct cam_tfe_top_priv *)core_info->top_priv; + hw_idx = (uint32_t *)cmd_args; + top_priv->sync_hw_id = *hw_idx; + + CAM_DBG(CAM_ISP, "TFE:%d top sync hw idx %d", core_info->core_index, + top_priv->sync_hw_id); + return 0; +} + static int cam_tfe_top_get_reg_dump( struct cam_tfe_top_priv *top_priv, void *cmd_args, uint32_t arg_size) @@ -2397,7 +2420,7 @@ static int cam_tfe_camif_resource_start( if ((rsrc_data->sync_mode == CAM_ISP_HW_SYNC_SLAVE) || (rsrc_data->sync_mode == CAM_ISP_HW_SYNC_MASTER)) { val |= (1 << rsrc_data->reg_data->dual_tfe_pix_en_shift); - val |= ((rsrc_data->dual_tfe_sync_sel + 1) << + val |= ((rsrc_data->dual_tfe_sync_sel + CAM_TFE_DUAL_TFE_SYNC_SEL_IDX_FACTOR) << rsrc_data->reg_data->dual_tfe_sync_sel_shift); } @@ -2426,11 +2449,14 @@ static int cam_tfe_camif_resource_start( } if (rsrc_data->shdr_en) { - val |= rsrc_data->core_cfg & - (1 << rsrc_data->reg_data->shdr_mode_shift); - if (!rsrc_data->is_shdr_master) - val |= rsrc_data->core_cfg & - (1 << rsrc_data->reg_data->extern_mup_shift); + val |= (1 << rsrc_data->reg_data->shdr_mode_shift); + val |= (1 << rsrc_data->reg_data->dual_tfe_pix_en_shift); + val |= ((top_priv->sync_hw_id + CAM_TFE_DUAL_TFE_SYNC_SEL_IDX_FACTOR) << + rsrc_data->reg_data->dual_tfe_sync_sel_shift); + if (!rsrc_data->is_shdr_master) { + val |= (1 << rsrc_data->reg_data->extern_mup_shift); + val |= (1 << rsrc_data->reg_data->extern_reg_update_shift); + } } cam_io_w_mb(val, rsrc_data->mem_base + @@ -3421,6 +3447,9 @@ int cam_tfe_process_cmd(void *hw_priv, uint32_t cmd_type, rc = cam_tfe_bus_get_path_port_map(hw_info->top_hw_info, cmd_args, arg_size); break; + case CAM_ISP_HW_CMD_SET_SYNC_HW_IDX: + rc = cam_tfe_set_sync_hw_idx(core_info, cmd_args, arg_size); + break; default: CAM_ERR(CAM_ISP, "TFE:%d Invalid cmd type:%d", core_info->core_index, cmd_type);