From 762751a88cd4dd3a9f8afc4ae04350251e0a164f Mon Sep 17 00:00:00 2001 From: Shravya Samala Date: Mon, 3 Aug 2020 19:16:27 +0530 Subject: [PATCH] msm: camera: ife: Configure epoch to exactly half of the frame Some customers have sensor mode with more blanking width. Due to this, time is not sufficient for applying setting thus resulted in frame drops. To avoid this situation, epoch is calculated on complete frame and configured at half the frame. CRs-Fixed: 2757095 Change-Id: I92927c23762f717d6ddca67a7e641422e8fb6d8f Signed-off-by: Shravya Samala --- drivers/cam_isp/isp_hw_mgr/cam_ife_hw_mgr.c | 67 +++++++++++++++++++ .../isp_hw_mgr/isp_hw/include/cam_isp_hw.h | 15 +++++ .../isp_hw_mgr/isp_hw/tfe_hw/cam_tfe_core.c | 15 ++++- .../isp_hw_mgr/isp_hw/vfe_hw/cam_vfe_core.c | 1 + .../vfe_hw/vfe_top/cam_vfe_camif_lite_ver2.c | 3 + .../vfe_hw/vfe_top/cam_vfe_camif_lite_ver3.c | 3 + .../vfe_hw/vfe_top/cam_vfe_camif_ver2.c | 33 ++++++++- .../vfe_hw/vfe_top/cam_vfe_camif_ver3.c | 29 +++++++- .../isp_hw/vfe_hw/vfe_top/cam_vfe_fe_ver1.c | 37 ++++++++-- .../isp_hw/vfe_hw/vfe_top/cam_vfe_top_ver2.c | 28 ++++++++ .../isp_hw/vfe_hw/vfe_top/cam_vfe_top_ver3.c | 29 ++++++++ include/uapi/camera/media/cam_isp.h | 12 ++++ 12 files changed, 263 insertions(+), 9 deletions(-) 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 196a558799d3..0780034df25c 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 @@ -49,6 +49,7 @@ static uint32_t blob_type_hw_cmd_map[CAM_ISP_GENERIC_BLOB_TYPE_MAX] = { CAM_ISP_HW_CMD_CORE_CONFIG, CAM_ISP_HW_CMD_WM_CONFIG_UPDATE, CAM_ISP_HW_CMD_BW_UPDATE_V2, + CAM_ISP_HW_CMD_BLANKING_UPDATE, }; static struct cam_ife_hw_mgr g_ife_hw_mgr; @@ -5577,6 +5578,53 @@ static int cam_isp_blob_csid_config_update( return rc; } + +static int cam_isp_blob_sensor_blanking_config( + uint32_t blob_type, + struct cam_isp_generic_blob_info *blob_info, + struct cam_isp_sensor_blanking_config *sensor_blanking_config, + struct cam_hw_prepare_update_args *prepare) + +{ + struct cam_ife_hw_mgr_ctx *ctx = NULL; + struct cam_isp_hw_mgr_res *hw_mgr_res; + struct cam_hw_intf *hw_intf; + struct cam_isp_blanking_config blanking_config; + int rc = 0, i; + + ctx = prepare->ctxt_to_hw_map; + if (list_empty(&ctx->res_list_ife_src)) { + CAM_ERR(CAM_ISP, "Mux List empty"); + return -ENODEV; + } + + list_for_each_entry(hw_mgr_res, + &ctx->res_list_ife_src, list) { + for (i = 0; i < CAM_ISP_HW_SPLIT_MAX; i++) { + if (!hw_mgr_res->hw_res[i]) + continue; + + hw_intf = hw_mgr_res->hw_res[i]->hw_intf; + blanking_config.node_res = hw_mgr_res->hw_res[i]; + blanking_config.vbi = sensor_blanking_config->vbi; + blanking_config.hbi = sensor_blanking_config->hbi; + + if (hw_intf && hw_intf->hw_ops.process_cmd) { + rc = hw_intf->hw_ops.process_cmd( + hw_intf->hw_priv, + CAM_ISP_HW_CMD_BLANKING_UPDATE, + &blanking_config, + sizeof( + struct cam_isp_blanking_config)); + if (rc) + CAM_ERR(CAM_ISP, + "blanking update failed"); + } + } + } + return rc; +} + static int cam_isp_packet_generic_blob_handler(void *user_data, uint32_t blob_type, uint32_t blob_size, uint8_t *blob_data) { @@ -6057,6 +6105,25 @@ static int cam_isp_packet_generic_blob_handler(void *user_data, CAM_ERR(CAM_ISP, "CSID Config failed rc: %d", rc); } break; + case CAM_ISP_GENERIC_BLOB_TYPE_SENSOR_BLANKING_CONFIG: { + struct cam_isp_sensor_blanking_config *sensor_blanking_config; + + if (blob_size < sizeof(struct cam_isp_sensor_blanking_config)) { + CAM_ERR(CAM_ISP, "Invalid blob size %zu expected %zu", + blob_size, + sizeof(struct cam_isp_sensor_blanking_config)); + return -EINVAL; + } + sensor_blanking_config = + (struct cam_isp_sensor_blanking_config *)blob_data; + + rc = cam_isp_blob_sensor_blanking_config(blob_type, blob_info, + sensor_blanking_config, prepare); + if (rc) + CAM_ERR(CAM_ISP, + "Epoch Configuration Update Failed rc:%d", rc); + } + break; case CAM_ISP_GENERIC_BLOB_TYPE_SENSOR_DIMENSION_CONFIG: { struct cam_isp_sensor_config *csid_dim_config; 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 03e76b627d8b..443d1550772d 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 @@ -124,6 +124,7 @@ enum cam_isp_hw_cmd_type { CAM_ISP_HW_CMD_UNMASK_BUS_WR_IRQ, CAM_ISP_HW_CMD_IS_CONSUMED_ADDR_SUPPORT, CAM_ISP_HW_CMD_GET_RES_FOR_MID, + CAM_ISP_HW_CMD_BLANKING_UPDATE, CAM_ISP_HW_CMD_MAX, }; @@ -178,6 +179,20 @@ struct cam_isp_resource_node { CAM_IRQ_HANDLER_BOTTOM_HALF bottom_half_handler; }; +/* + * struct cam_isp_blanking_config: + * + * @Brief: Structure to pass blanking details + * @hbi: HBI Value + * @vbi: VBI Value + * node_res: Pointer to Resource Node object + */ +struct cam_isp_blanking_config { + uint32_t hbi; + uint32_t vbi; + struct cam_isp_resource_node *node_res; +}; + /* * struct cam_isp_hw_event_info: * 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 f4b7d669e800..c1914ec97686 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 @@ -79,6 +79,8 @@ struct cam_tfe_camif_data { uint32_t camif_debug; uint32_t camif_pd_enable; uint32_t dual_tfe_sync_sel; + uint32_t hbi_value; + uint32_t vbi_value; }; struct cam_tfe_rdi_data { @@ -265,6 +267,10 @@ static void cam_tfe_log_tfe_in_debug_status( "Acquired line start:0x%x line end:0x%x", camif_data->first_line, camif_data->last_line); + CAM_INFO(CAM_ISP, "vbi_value:0x%x hbi_value:0x%x", + camif_data->vbi_value, + camif_data->hbi_value); + } else if ((top_priv->in_rsrc[i].res_id >= CAM_ISP_HW_TFE_IN_RDI0) || (top_priv->in_rsrc[i].res_id <= @@ -1815,6 +1821,10 @@ int cam_tfe_top_reserve(void *device_priv, acquire_args->in_port->line_start; camif_data->last_line = acquire_args->in_port->line_end; + camif_data->vbi_value = + acquire_args->in_port->sensor_vbi; + camif_data->hbi_value = + acquire_args->in_port->sensor_hbi; camif_data->camif_pd_enable = acquire_args->camif_pd_enable; camif_data->dual_tfe_sync_sel = @@ -1978,9 +1988,12 @@ static int cam_tfe_camif_resource_start( } /* Epoch config */ - epoch0_irq_mask = ((rsrc_data->last_line - + epoch0_irq_mask = (((rsrc_data->last_line + rsrc_data->vbi_value) - rsrc_data->first_line) / 2) + rsrc_data->first_line; + if (epoch0_irq_mask > rsrc_data->last_line) + epoch0_irq_mask = rsrc_data->last_line; + epoch1_irq_mask = rsrc_data->reg_data->epoch_line_cfg & 0xFFFF; computed_epoch_line_cfg = (epoch0_irq_mask << 16) | 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 158190296478..b741cc153732 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 @@ -601,6 +601,7 @@ int cam_vfe_process_cmd(void *hw_priv, uint32_t cmd_type, case CAM_ISP_HW_CMD_ADD_WAIT: case CAM_ISP_HW_CMD_ADD_WAIT_TRIGGER: case CAM_ISP_HW_CMD_CAMIF_DATA: + case CAM_ISP_HW_CMD_BLANKING_UPDATE: 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_camif_lite_ver2.c b/drivers/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe_top/cam_vfe_camif_lite_ver2.c index ad4e7eca7186..1c2f03c28e85 100644 --- a/drivers/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe_top/cam_vfe_camif_lite_ver2.c +++ b/drivers/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe_top/cam_vfe_camif_lite_ver2.c @@ -371,6 +371,9 @@ static int cam_vfe_camif_lite_process_cmd( break; case CAM_ISP_HW_CMD_SET_CAMIF_DEBUG: break; + case CAM_ISP_HW_CMD_BLANKING_UPDATE: + rc = 0; + break; default: CAM_ERR(CAM_ISP, "unsupported process command:%d", cmd_type); diff --git a/drivers/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe_top/cam_vfe_camif_lite_ver3.c b/drivers/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe_top/cam_vfe_camif_lite_ver3.c index 1cc89c32013a..be5c41976098 100644 --- a/drivers/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe_top/cam_vfe_camif_lite_ver3.c +++ b/drivers/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe_top/cam_vfe_camif_lite_ver3.c @@ -772,6 +772,9 @@ static int cam_vfe_camif_lite_process_cmd( rsrc_node->res_priv; camif_lite_priv->camif_debug = *((uint32_t *)cmd_args); break; + case CAM_ISP_HW_CMD_BLANKING_UPDATE: + rc = 0; + break; default: CAM_ERR(CAM_ISP, "unsupported process command:%d", cmd_type); diff --git a/drivers/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe_top/cam_vfe_camif_ver2.c b/drivers/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe_top/cam_vfe_camif_ver2.c index 1f7824763cfe..6b7efaa2c4cf 100644 --- a/drivers/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe_top/cam_vfe_camif_ver2.c +++ b/drivers/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe_top/cam_vfe_camif_ver2.c @@ -45,6 +45,8 @@ struct cam_vfe_mux_camif_data { uint32_t first_line; uint32_t last_pixel; uint32_t last_line; + uint32_t hbi_value; + uint32_t vbi_value; bool enable_sof_irq_debug; uint32_t irq_debug_cnt; uint32_t camif_debug; @@ -269,6 +271,8 @@ int cam_vfe_camif_ver2_acquire_resource( camif_data->event_cb = acquire_data->event_cb; camif_data->priv = acquire_data->priv; camif_data->is_dual = acquire_data->vfe_in.is_dual; + camif_data->hbi_value = 0; + camif_data->vbi_value = 0; if (acquire_data->vfe_in.is_dual) camif_data->dual_hw_idx = @@ -420,9 +424,13 @@ static int cam_vfe_camif_resource_start( rsrc_data->camif_reg->epoch_irq); break; default: - epoch0_irq_mask = ((rsrc_data->last_line - + epoch0_irq_mask = (((rsrc_data->last_line + + rsrc_data->vbi_value) - rsrc_data->first_line) / 2) + rsrc_data->first_line; + if (epoch0_irq_mask > rsrc_data->last_line) + epoch0_irq_mask = rsrc_data->last_line; + epoch1_irq_mask = rsrc_data->reg_data->epoch_line_cfg & 0xFFFF; computed_epoch_line_cfg = (epoch0_irq_mask << 16) | @@ -431,10 +439,11 @@ static int cam_vfe_camif_resource_start( rsrc_data->mem_base + rsrc_data->camif_reg->epoch_irq); CAM_DBG(CAM_ISP, "first_line: %u\n" - "last_line: %u\n" + "last_line: %u vbi: %u\n" "epoch_line_cfg: 0x%x", rsrc_data->first_line, rsrc_data->last_line, + rsrc_data->vbi_value, computed_epoch_line_cfg); break; } @@ -669,6 +678,23 @@ int cam_vfe_camif_dump_timestamps( return 0; } +static int cam_vfe_camif_blanking_update( + struct cam_isp_resource_node *rsrc_node, void *cmd_args) +{ + struct cam_vfe_mux_camif_data *camif_priv = + (struct cam_vfe_mux_camif_data *)rsrc_node->res_priv; + + struct cam_isp_blanking_config *blanking_config = + (struct cam_isp_blanking_config *)cmd_args; + + camif_priv->hbi_value = blanking_config->hbi; + camif_priv->vbi_value = blanking_config->vbi; + + CAM_DBG(CAM_ISP, "hbi:%d vbi:%d", + camif_priv->hbi_value, camif_priv->vbi_value); + return 0; +} + static int cam_vfe_camif_process_cmd(struct cam_isp_resource_node *rsrc_node, uint32_t cmd_type, void *cmd_args, uint32_t arg_size) { @@ -696,6 +722,9 @@ static int cam_vfe_camif_process_cmd(struct cam_isp_resource_node *rsrc_node, case CAM_ISP_HW_CMD_CAMIF_DATA: rc = cam_vfe_camif_dump_timestamps(rsrc_node, cmd_args); break; + case CAM_ISP_HW_CMD_BLANKING_UPDATE: + rc = cam_vfe_camif_blanking_update(rsrc_node, cmd_args); + break; default: CAM_ERR(CAM_ISP, "unsupported process command:%d", cmd_type); diff --git a/drivers/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe_top/cam_vfe_camif_ver3.c b/drivers/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe_top/cam_vfe_camif_ver3.c index 67cd7f4cd587..f5e2f7a0ea15 100644 --- a/drivers/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe_top/cam_vfe_camif_ver3.c +++ b/drivers/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe_top/cam_vfe_camif_ver3.c @@ -48,6 +48,8 @@ struct cam_vfe_mux_camif_ver3_data { uint32_t first_line; uint32_t last_pixel; uint32_t last_line; + uint32_t hbi_value; + uint32_t vbi_value; bool enable_sof_irq_debug; uint32_t irq_debug_cnt; uint32_t camif_debug; @@ -276,6 +278,8 @@ int cam_vfe_camif_ver3_acquire_resource( camif_data->qcfa_bin = acquire_data->vfe_in.in_port->qcfa_bin; camif_data->horizontal_bin = acquire_data->vfe_in.in_port->horizontal_bin; + camif_data->hbi_value = 0; + camif_data->vbi_value = 0; if (camif_data->is_dual) camif_data->dual_hw_idx = acquire_data->vfe_in.dual_hw_idx; @@ -464,8 +468,11 @@ static int cam_vfe_camif_ver3_resource_start( case CAM_CPAS_TITAN_480_V100: case CAM_CPAS_TITAN_580_V100: case CAM_CPAS_TITAN_570_V200: - epoch0_line_cfg = (rsrc_data->last_line - + epoch0_line_cfg = ((rsrc_data->last_line + + rsrc_data->vbi_value) - rsrc_data->first_line) / 4; + if (epoch0_line_cfg > rsrc_data->last_line) + epoch0_line_cfg = rsrc_data->last_line; /* epoch line cfg will still be configured at midpoint of the * frame width. We use '/ 4' instead of '/ 2' * cause it is multipixel path @@ -811,6 +818,23 @@ int cam_vfe_camif_ver3_dump_timestamps( return 0; } +static int cam_vfe_camif_ver3_blanking_update( + struct cam_isp_resource_node *rsrc_node, void *cmd_args) +{ + struct cam_vfe_mux_camif_ver3_data *camif_priv = + (struct cam_vfe_mux_camif_ver3_data *)rsrc_node->res_priv; + + struct cam_isp_blanking_config *blanking_config = + (struct cam_isp_blanking_config *)cmd_args; + + camif_priv->hbi_value = blanking_config->hbi; + camif_priv->vbi_value = blanking_config->vbi; + + CAM_DBG(CAM_ISP, "hbi:%d vbi:%d", + camif_priv->hbi_value, camif_priv->vbi_value); + return 0; +} + static int cam_vfe_camif_ver3_process_cmd( struct cam_isp_resource_node *rsrc_node, uint32_t cmd_type, void *cmd_args, uint32_t arg_size) @@ -850,6 +874,9 @@ static int cam_vfe_camif_ver3_process_cmd( case CAM_ISP_HW_CMD_CAMIF_DATA: rc = cam_vfe_camif_ver3_dump_timestamps(rsrc_node, cmd_args); break; + case CAM_ISP_HW_CMD_BLANKING_UPDATE: + rc = cam_vfe_camif_ver3_blanking_update(rsrc_node, cmd_args); + break; default: CAM_ERR(CAM_ISP, "unsupported process command:%d", cmd_type); diff --git a/drivers/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe_top/cam_vfe_fe_ver1.c b/drivers/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe_top/cam_vfe_fe_ver1.c index 7815da674872..85868105bb74 100644 --- a/drivers/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe_top/cam_vfe_fe_ver1.c +++ b/drivers/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe_top/cam_vfe_fe_ver1.c @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-2.0-only /* - * Copyright (c) 2018-2019, The Linux Foundation. All rights reserved. + * Copyright (c) 2018-2020, The Linux Foundation. All rights reserved. */ #include @@ -36,6 +36,8 @@ struct cam_vfe_mux_fe_data { uint32_t first_line; uint32_t last_pixel; uint32_t last_line; + uint32_t hbi_value; + uint32_t vbi_value; bool enable_sof_irq_debug; uint32_t irq_debug_cnt; uint32_t fe_cfg_data; @@ -179,6 +181,8 @@ int cam_vfe_fe_ver1_acquire_resource( fe_data->last_pixel = acquire_data->vfe_in.in_port->left_stop; fe_data->first_line = acquire_data->vfe_in.in_port->line_start; fe_data->last_line = acquire_data->vfe_in.in_port->line_stop; + fe_data->hbi_value = 0; + fe_data->vbi_value = 0; CAM_DBG(CAM_ISP, "hw id:%d pix_pattern:%d dsp_mode=%d", fe_res->hw_intf->hw_idx, @@ -302,16 +306,19 @@ static int cam_vfe_fe_resource_start( CAM_VFE_TOP_VER2_MODULE_STATS]->cgc_ovd); /* epoch config */ - epoch0_irq_mask = ((rsrc_data->last_line - rsrc_data->first_line) / 2) + - rsrc_data->first_line; + epoch0_irq_mask = (((rsrc_data->last_line + rsrc_data->vbi_value) - + rsrc_data->first_line) / 2) + rsrc_data->first_line; + if (epoch0_irq_mask > rsrc_data->last_line) + epoch0_irq_mask = rsrc_data->last_line; epoch1_irq_mask = rsrc_data->reg_data->epoch_line_cfg & 0xFFFF; computed_epoch_line_cfg = (epoch0_irq_mask << 16) | epoch1_irq_mask; cam_io_w_mb(computed_epoch_line_cfg, rsrc_data->mem_base + rsrc_data->fe_reg->epoch_irq); - CAM_DBG(CAM_ISP, "first_line:0x%x last_line:0x%x epoch_line_cfg: 0x%x", + CAM_DBG(CAM_ISP, + "first_line:0x%x last_line:0x%x vbi:0x%x epoch_line_cfg: 0x%x", rsrc_data->first_line, rsrc_data->last_line, - computed_epoch_line_cfg); + rsrc_data->vbi_value, computed_epoch_line_cfg); fe_res->res_state = CAM_ISP_RESOURCE_STATE_STREAMING; @@ -446,6 +453,23 @@ static int cam_vfe_fe_sof_irq_debug( return 0; } +static int cam_vfe_fe_blanking_update( + struct cam_isp_resource_node *rsrc_node, void *cmd_args) +{ + struct cam_vfe_mux_fe_data *fe_priv = + (struct cam_vfe_mux_fe_data *)rsrc_node->res_priv; + + struct cam_isp_blanking_config *blanking_config = + (struct cam_isp_blanking_config *)cmd_args; + + fe_priv->hbi_value = blanking_config->hbi; + fe_priv->vbi_value = blanking_config->vbi; + CAM_DBG(CAM_ISP, "hbi:%d vbi:%d", + fe_priv->hbi_value, fe_priv->vbi_value); + + return 0; +} + static int cam_vfe_fe_process_cmd(struct cam_isp_resource_node *rsrc_node, uint32_t cmd_type, void *cmd_args, uint32_t arg_size) { @@ -467,6 +491,9 @@ static int cam_vfe_fe_process_cmd(struct cam_isp_resource_node *rsrc_node, case CAM_ISP_HW_CMD_FE_UPDATE_IN_RD: rc = cam_vfe_fe_update(rsrc_node, cmd_args, arg_size); break; + case CAM_ISP_HW_CMD_BLANKING_UPDATE: + rc = cam_vfe_fe_blanking_update(rsrc_node, cmd_args); + break; default: CAM_ERR(CAM_ISP, "unsupported process command:%d", cmd_type); 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 6e1ae838bca3..1e5f66df4c1c 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 @@ -169,6 +169,31 @@ static int cam_vfe_top_clock_update( return rc; } +static int cam_vfe_top_blanking_update(uint32_t cmd_type, + void *cmd_args, uint32_t arg_size) +{ + struct cam_isp_blanking_config *blanking_config = NULL; + struct cam_isp_resource_node *node_res = NULL; + + blanking_config = + (struct cam_isp_blanking_config *)cmd_args; + node_res = blanking_config->node_res; + + if (!node_res) { + CAM_ERR(CAM_PERF, "Invalid input res %pK", node_res); + return -EINVAL; + } + + if (!node_res->process_cmd) { + CAM_ERR(CAM_PERF, "Invalid input res process_cmd %pK", + node_res->process_cmd); + return -EINVAL; + } + + return node_res->process_cmd(node_res, + cmd_type, cmd_args, arg_size); +} + static int cam_vfe_top_mux_get_reg_update( struct cam_vfe_top_ver2_priv *top_priv, void *cmd_args, uint32_t arg_size) @@ -795,6 +820,9 @@ int cam_vfe_top_process_cmd(void *device_priv, uint32_t cmd_type, case CAM_ISP_HW_CMD_ADD_WAIT_TRIGGER: rc = cam_vfe_top_add_wait_trigger(top_priv, cmd_args, arg_size); break; + case CAM_ISP_HW_CMD_BLANKING_UPDATE: + rc = cam_vfe_top_blanking_update(cmd_type, 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 f3a8217dbe6e..9bd442f8d96e 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 @@ -189,6 +189,31 @@ static int cam_vfe_top_ver3_clock_update( return rc; } +static int cam_vfe_top_ver3_blanking_update(uint32_t cmd_type, + void *cmd_args, uint32_t arg_size) +{ + struct cam_isp_blanking_config *blanking_config = NULL; + struct cam_isp_resource_node *node_res = NULL; + + blanking_config = + (struct cam_isp_blanking_config *)cmd_args; + node_res = blanking_config->node_res; + + if (!node_res) { + CAM_ERR(CAM_PERF, "Invalid input res %pK", node_res); + return -EINVAL; + } + + if (!node_res->process_cmd) { + CAM_ERR(CAM_PERF, "Invalid input res process_cmd %pK", + node_res->process_cmd); + return -EINVAL; + } + + return node_res->process_cmd(node_res, + cmd_type, cmd_args, arg_size); +} + static int cam_vfe_core_config_control( struct cam_vfe_top_ver3_priv *top_priv, void *cmd_args, uint32_t arg_size) @@ -727,6 +752,10 @@ int cam_vfe_top_ver3_process_cmd(void *device_priv, uint32_t cmd_type, case CAM_ISP_HW_CMD_ADD_WAIT_TRIGGER: rc = cam_vfe_top_add_wait_trigger(top_priv, cmd_args, arg_size); break; + case CAM_ISP_HW_CMD_BLANKING_UPDATE: + rc = cam_vfe_top_ver3_blanking_update(cmd_type, + cmd_args, arg_size); + break; default: rc = -EINVAL; CAM_ERR(CAM_ISP, "Error, Invalid cmd:%d", cmd_type); diff --git a/include/uapi/camera/media/cam_isp.h b/include/uapi/camera/media/cam_isp.h index 5e0acdf496e0..d99e0476fc18 100644 --- a/include/uapi/camera/media/cam_isp.h +++ b/include/uapi/camera/media/cam_isp.h @@ -107,6 +107,7 @@ #define CAM_ISP_GENERIC_BLOB_TYPE_CSID_CONFIG 10 #define CAM_ISP_GENERIC_BLOB_TYPE_SENSOR_DIMENSION_CONFIG 11 #define CAM_ISP_GENERIC_BLOB_TYPE_CSID_QCFA_CONFIG 12 +#define CAM_ISP_GENERIC_BLOB_TYPE_SENSOR_BLANKING_CONFIG 13 #define CAM_ISP_VC_DT_CFG 4 @@ -616,6 +617,17 @@ struct cam_isp_sensor_dimension { __u32 measure_enabled; } __attribute__((packed)); +/** + * struct cam_isp_sensor_blanking_config + * + * @hbi HBI value + * @vbi VBI value + */ +struct cam_isp_sensor_blanking_config { + __u32 hbi; + __u32 vbi; +} __attribute__((packed)); + /** * struct cam_isp_sensor_config - Sensor Dimension configuration *