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 *