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 ec2daf03ac..ceb8034f47 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 @@ -1,7 +1,7 @@ // SPDX-License-Identifier: GPL-2.0-only /* * Copyright (c) 2019-2021, The Linux Foundation. All rights reserved. - * Copyright (c) 2022-2023 Qualcomm Innovation Center, Inc. All rights reserved. + * Copyright (c) 2022-2023, Qualcomm Innovation Center, Inc. All rights reserved. */ #include @@ -4200,6 +4200,39 @@ static int cam_isp_tfe_blob_csid_clock_update( return rc; } +static int cam_isp_blob_tfe_init_config_update( + struct cam_hw_prepare_update_args *prepare, + struct cam_isp_init_config *init_config) +{ + int i, rc = 0; + struct cam_tfe_hw_mgr_ctx *ctx = NULL; + struct cam_isp_hw_init_config_update init_cfg_update; + struct cam_hw_intf *hw_intf; + + ctx = prepare->ctxt_to_hw_map; + init_cfg_update.init_config = init_config; + + for (i = 0; i < ctx->num_base; i++) { + if (ctx->base[i].hw_type != CAM_ISP_HW_TYPE_TFE) + continue; + + hw_intf = g_tfe_hw_mgr.tfe_devices[ctx->base[i].idx]->hw_intf; + if (hw_intf && hw_intf->hw_ops.process_cmd) { + CAM_DBG(CAM_ISP, "Epoch/init config update for ctx %d", + ctx->ctx_index); + rc = hw_intf->hw_ops.process_cmd(hw_intf->hw_priv, + CAM_ISP_HW_CMD_INIT_CONFIG_UPDATE, + &init_cfg_update, + sizeof(struct cam_isp_hw_init_config_update)); + if (rc) + CAM_ERR(CAM_ISP, "Epoch/init config failed rc %d ctx %d", + rc, ctx->ctx_index); + } + } + + return rc; +} + static int cam_isp_tfe_blob_clock_update( uint32_t blob_type, struct cam_isp_generic_blob_info *blob_info, @@ -4673,8 +4706,40 @@ static int cam_isp_tfe_packet_generic_blob_handler(void *user_data, prepare_hw_data->num_exp = mup_config->num_expoures; } break; + case CAM_ISP_TFE_GENERIC_BLOB_TYPE_INIT_CONFIG: { + struct cam_isp_init_config *init_config; + struct cam_isp_prepare_hw_update_data *prepare_hw_data; + + prepare_hw_data = (struct cam_isp_prepare_hw_update_data *)prepare->priv; + + if (prepare_hw_data->packet_opcode_type != CAM_ISP_PACKET_INIT_DEV) { + CAM_ERR(CAM_ISP, + "Epoch config blob not supported packet type: %u req: %llu Ctx %d", + prepare_hw_data->packet_opcode_type, + prepare->packet->header.request_id, + tfe_mgr_ctx->ctx_index); + return -EINVAL; + } + + if (blob_size != sizeof(struct cam_isp_init_config)) { + CAM_ERR(CAM_ISP, + "Invalid init config blob size %u expected %u ctx %d", + blob_size, sizeof(struct cam_isp_init_config), + tfe_mgr_ctx->ctx_index); + return -EINVAL; + } + + init_config = (struct cam_isp_init_config *)blob_data; + rc = cam_isp_blob_tfe_init_config_update(prepare, init_config); + if (rc) + CAM_ERR(CAM_ISP, + "Init config failed for req: %llu rc: %d ctx %d", + prepare->packet->header.request_id, rc, tfe_mgr_ctx->ctx_index); + } + break; default: - CAM_WARN(CAM_ISP, "Invalid blob type %d", blob_type); + CAM_WARN(CAM_ISP, "Invalid blob type %d ctx %d", blob_type, + tfe_mgr_ctx->ctx_index); break; } 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 c829f1823a..23d024501a 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 @@ -95,6 +95,7 @@ struct cam_tfe_camif_data { uint32_t core_cfg; bool shdr_en; bool is_shdr_master; + uint32_t epoch_factor; }; struct cam_tfe_rdi_data { @@ -113,6 +114,7 @@ struct cam_tfe_rdi_data { uint32_t last_line; bool shdr_en; bool is_shdr_master; + uint32_t epoch_factor; }; struct cam_tfe_ppp_data { @@ -1575,6 +1577,54 @@ static int cam_tfe_top_get_reg_update( return 0; } +static int cam_tfe_top_init_config_update( + struct cam_tfe_top_priv *top_priv, + void *cmd_args, uint32_t arg_size) +{ + int i = 0; + struct cam_isp_hw_init_config_update *init_cfg = NULL; + struct cam_isp_resource_node *rsrc_node = NULL; + struct cam_tfe_camif_data *camif_data; + + init_cfg = (struct cam_isp_hw_init_config_update *)cmd_args; + + if (arg_size != sizeof(struct cam_isp_hw_init_config_update)) { + CAM_ERR(CAM_ISP, "Invalid args size expected: %zu actual: %zu", + sizeof(struct cam_isp_hw_init_config_update), arg_size); + return -EINVAL; + } + + for (i = 0; i < CAM_TFE_TOP_IN_PORT_MAX; i++) { + if (top_priv->in_rsrc[i].res_id == CAM_ISP_HW_TFE_IN_CAMIF) { + rsrc_node = &top_priv->in_rsrc[i]; + break; + } + } + + if (!rsrc_node) { + CAM_ERR(CAM_ISP, "TFE %d null input res node", + top_priv->common_data.hw_intf->hw_idx); + return -EINVAL; + } + + if (rsrc_node->res_type != CAM_ISP_RESOURCE_TFE_IN) { + CAM_ERR(CAM_ISP, "TFE %d Invalid res_type %d res id %d ", + rsrc_node->hw_intf->hw_idx, rsrc_node->res_type, + rsrc_node->res_id); + return -EINVAL; + } + + camif_data = (struct cam_tfe_camif_data *)rsrc_node->res_priv; + camif_data->epoch_factor = init_cfg->init_config->epoch_cfg.epoch_factor; + + CAM_DBG(CAM_ISP, + "Init Update TFE %d res type: %d res id %d epoch_factor: %u", + rsrc_node->hw_intf->hw_idx, rsrc_node->res_type, + rsrc_node->res_id, camif_data->epoch_factor); + + return 0; +} + static int cam_tfe_top_clock_update( struct cam_tfe_top_priv *top_priv, void *cmd_args, uint32_t arg_size) @@ -2309,7 +2359,7 @@ static int cam_tfe_camif_resource_start( struct cam_tfe_camif_data *rsrc_data; struct cam_tfe_soc_private *soc_private; struct cam_tfe_top_priv *top_priv; - uint32_t val = 0; + uint32_t val = 0, epoch_factor = 50; uint32_t epoch0_irq_mask; uint32_t epoch1_irq_mask; uint32_t computed_epoch_line_cfg; @@ -2403,8 +2453,12 @@ static int cam_tfe_camif_resource_start( } /* Epoch config */ + if ((rsrc_data->epoch_factor) && (rsrc_data->epoch_factor <= 100)) + epoch_factor = rsrc_data->epoch_factor; + epoch0_irq_mask = (((rsrc_data->last_line + rsrc_data->vbi_value) - - rsrc_data->first_line) / 2); + rsrc_data->first_line) * epoch_factor / 100); + if (epoch0_irq_mask > (rsrc_data->last_line - rsrc_data->first_line)) epoch0_irq_mask = (rsrc_data->last_line - rsrc_data->first_line); @@ -2421,11 +2475,11 @@ static int cam_tfe_camif_resource_start( rsrc_data->camif_reg->epoch_irq_cfg); CAM_DBG(CAM_ISP, "TFE:%d first_line: %u\n" "last_line: %u\n" - "epoch_line_cfg: 0x%x", + "epoch_line_cfg: 0x%x epoch factor %d", core_info->core_index, rsrc_data->first_line, rsrc_data->last_line, - computed_epoch_line_cfg); + computed_epoch_line_cfg, epoch_factor); camif_res->res_state = CAM_ISP_RESOURCE_STATE_STREAMING; @@ -3344,6 +3398,10 @@ int cam_tfe_process_cmd(void *hw_priv, uint32_t cmd_type, rc = cam_tfe_top_dynamic_clock_update(core_info->top_priv, cmd_args, arg_size); break; + case CAM_ISP_HW_CMD_INIT_CONFIG_UPDATE: + rc = cam_tfe_top_init_config_update(core_info->top_priv, cmd_args, + arg_size); + break; case CAM_ISP_HW_CMD_GET_BUF_UPDATE: case CAM_ISP_HW_CMD_GET_HFR_UPDATE: case CAM_ISP_HW_CMD_STRIPE_UPDATE: diff --git a/include/uapi/camera/media/cam_tfe.h b/include/uapi/camera/media/cam_tfe.h index 90e728cd0b..0826a8b4d9 100644 --- a/include/uapi/camera/media/cam_tfe.h +++ b/include/uapi/camera/media/cam_tfe.h @@ -72,6 +72,7 @@ #define CAM_ISP_TFE_GENERIC_BLOB_TYPE_CLOCK_CONFIG 1 #define CAM_ISP_TFE_GENERIC_BLOB_TYPE_BW_CONFIG_V2 2 #define CAM_ISP_TFE_GENERIC_BLOB_TYPE_CSID_CLOCK_CONFIG 3 +#define CAM_ISP_TFE_GENERIC_BLOB_TYPE_INIT_CONFIG 4 #define CAM_ISP_TFE_GENERIC_BLOB_TYPE_BW_LIMITER_CFG 16 #define CAM_ISP_TFE_GENERIC_BLOB_TYPE_DYNAMIC_MODE_SWITCH 15