msm: camera: isp: Add support for AEB use-case

Add support to ensure epoch is programmed post second
exposure frame. Validate this, if this check fails
flag an error. The % factor of frame height to be configured
for epoch is obtained from userspace. This % factor will
depend on how the frame is spread for IFE to process.

CRs-Fixed: 2986303
Change-Id: I2d7d34ccdfde0192ebb73bbd920a4c738bbf9ca2
Signed-off-by: Karthik Anantha Ram <kartanan@codeaurora.org>
Esse commit está contido em:
Karthik Anantha Ram
2021-06-23 12:34:58 -07:00
commit 5d5b3a5144
11 arquivos alterados com 297 adições e 36 exclusões

Ver arquivo

@@ -5579,6 +5579,8 @@ static int __cam_isp_ctx_acquire_hw_v2(struct cam_context *ctx,
(param.op_flags & CAM_IFE_CTX_APPLY_DEFAULT_CFG);
ctx_isp->support_consumed_addr =
(param.op_flags & CAM_IFE_CTX_CONSUME_ADDR_EN);
ctx_isp->aeb_enabled =
(param.op_flags & CAM_IFE_CTX_AEB_EN);
/* Query the context has rdi only resource */
hw_cmd_args.ctxt_to_hw_map = param.ctxt_to_hw_map;
@@ -6387,6 +6389,28 @@ static int __cam_isp_ctx_handle_irq_in_activated(void *context,
(struct cam_isp_context *)ctx->ctx_priv;
spin_lock(&ctx->lock);
/*
* In case of custom AEB ensure first exposure frame has
* not moved forward with its settings without second/third
* expoure frame coming in. If this scenario occurs flag as error,
* and recover
*/
if ((ctx_isp->aeb_enabled) && (evt_id == CAM_ISP_HW_EVENT_SOF)) {
bool is_secondary_evt =
((struct cam_isp_hw_sof_event_data *)evt_data)->is_secondary_evt;
if (is_secondary_evt) {
if ((ctx_isp->substate_activated ==
CAM_ISP_CTX_ACTIVATED_APPLIED) ||
(ctx_isp->substate_activated ==
CAM_ISP_CTX_ACTIVATED_BUBBLE_APPLIED)) {
CAM_ERR(CAM_ISP,
"AEB settings mismatch between exposures - needs a reset");
rc = -EAGAIN;
}
goto end;
}
}
trace_cam_isp_activated_irq(ctx, ctx_isp->substate_activated, evt_id,
__cam_isp_ctx_get_event_ts(evt_id, evt_data));
@@ -6408,6 +6432,7 @@ static int __cam_isp_ctx_handle_irq_in_activated(void *context,
CAM_DBG(CAM_ISP, "Exit: State %d Substate[%s]",
ctx->state, __cam_isp_ctx_substate_val_to_type(
ctx_isp->substate_activated));
end:
spin_unlock(&ctx->lock);
return rc;
}

Ver arquivo

@@ -269,6 +269,7 @@ struct cam_isp_context_event_record {
* @custom_enabled: Custom HW enabled for this ctx
* @use_frame_header_ts: Use frame header for qtimer ts
* @support_consumed_addr: Indicate whether HW has last consumed addr reg
* @aeb_enabled: Indicate if stream is for AEB
* @apply_in_progress Whether request apply is in progress
* @use_default_apply: Use default settings in case of frame skip
* @init_timestamp: Timestamp at which this context is initialized
@@ -319,6 +320,7 @@ struct cam_isp_context {
bool custom_enabled;
bool use_frame_header_ts;
bool support_consumed_addr;
bool aeb_enabled;
atomic_t apply_in_progress;
bool use_default_apply;
unsigned int init_timestamp;

Ver arquivo

@@ -3404,6 +3404,21 @@ static int cam_ife_hw_mgr_acquire_res_ife_csid_rdi(
CAM_DBG(CAM_ISP, "setting inline shdr mode for res: 0x%x",
out_port->res_type);
csid_acquire.sfe_inline_shdr = true;
/*
* Merged output will only be from the first n RDIs
* starting from RDI0. Any other RDI[1:2] resource
* if only being dumped will be considered as a
* no merge resource
*/
if ((ife_ctx->flags.is_aeb_mode) &&
((out_port->res_type - CAM_ISP_SFE_OUT_RES_RDI_0) >=
ife_ctx->sfe_info.num_fetches)) {
csid_acquire.en_secondary_evt = true;
CAM_DBG(CAM_ISP,
"Secondary evt enabled for path: 0x%x",
out_port->res_type);
}
}
/*
@@ -4202,6 +4217,10 @@ static int cam_ife_mgr_acquire_hw_for_ctx(
ife_ctx->flags.dsp_enabled = (bool)in_port->dsp_mode;
ife_ctx->flags.is_dual = (bool)in_port->usage_type;
/* Update aeb mode for the given in_port once */
if ((in_port->aeb_mode) && (!ife_ctx->flags.is_aeb_mode))
ife_ctx->flags.is_aeb_mode = true;
/* get root node resource */
rc = cam_ife_hw_mgr_acquire_res_root(ife_ctx, in_port);
if (rc) {
@@ -4515,6 +4534,18 @@ static inline int cam_ife_mgr_hw_check_in_res_type(
}
}
static inline void cam_ife_mgr_acquire_get_feature_flag_params(
struct cam_isp_in_port_info_v2 *in,
struct cam_isp_in_port_generic_info *in_port)
{
in_port->secure_mode = in->feature_flag & CAM_ISP_PARAM_FETCH_SECURITY_MODE;
in_port->dynamic_sensor_switch_en = in->feature_flag & CAM_ISP_DYNAMIC_SENOR_SWITCH_EN;
in_port->can_use_lite = in->feature_flag & CAM_ISP_CAN_USE_LITE_MODE;
in_port->sfe_binned_epoch_cfg = in->feature_flag & CAM_ISP_SFE_BINNED_EPOCH_CFG_ENABLE;
in_port->epd_supported = in->feature_flag & CAM_ISP_EPD_SUPPORT;
in_port->aeb_mode = in->feature_flag & CAM_ISP_AEB_MODE_EN;
}
static int cam_ife_mgr_acquire_get_unified_structure_v2(
struct cam_isp_acquire_hw_info *acquire_hw_info,
uint32_t offset, uint32_t *input_size,
@@ -4589,16 +4620,8 @@ static int cam_ife_mgr_acquire_get_unified_structure_v2(
in_port->num_out_res = in->num_out_res;
in_port->sfe_in_path_type = (in->sfe_in_path_type & 0xFFFF);
in_port->sfe_ife_enable = in->sfe_in_path_type >> 16;
in_port->secure_mode = (in->feature_flag &
CAM_ISP_PARAM_FETCH_SECURITY_MODE);
in_port->dynamic_sensor_switch_en = (in->feature_flag &
CAM_ISP_DYNAMIC_SENOR_SWITCH_EN);
in_port->can_use_lite = in->feature_flag &
CAM_ISP_CAN_USE_LITE_MODE;
in_port->sfe_binned_epoch_cfg = (in->feature_flag &
CAM_ISP_SFE_BINNED_EPOCH_CFG_ENABLE);
in_port->epd_supported = (in->feature_flag &
CAM_ISP_EPD_SUPPORT);
cam_ife_mgr_acquire_get_feature_flag_params(in, in_port);
in_port->data = kcalloc(in->num_out_res,
sizeof(struct cam_isp_out_port_generic_info),
@@ -4875,6 +4898,9 @@ static int cam_ife_mgr_acquire_hw(void *hw_mgr_priv, void *acquire_hw_args)
acquire_args->op_flags |=
CAM_IFE_CTX_SFE_EN;
if (ife_ctx->flags.is_aeb_mode)
acquire_args->op_flags |= CAM_IFE_CTX_AEB_EN;
ife_ctx->flags.ctx_in_use = true;
ife_ctx->num_reg_dump_buf = 0;
@@ -8373,6 +8399,50 @@ static inline int cam_isp_validate_bw_limiter_blob(
return 0;
}
static int cam_isp_blob_ife_init_config_update(
struct cam_hw_prepare_update_args *prepare,
struct cam_isp_init_config *init_config)
{
int i, rc = -EINVAL;
struct cam_hw_intf *hw_intf;
struct cam_ife_hw_mgr_ctx *ctx = NULL;
struct cam_isp_hw_mgr_res *hw_mgr_res;
struct cam_isp_hw_init_config_update init_cfg_update;
ctx = prepare->ctxt_to_hw_map;
/* Assign init config */
init_cfg_update.init_config = init_config;
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;
if (hw_mgr_res->res_id != CAM_ISP_HW_VFE_IN_CAMIF)
continue;
hw_intf = hw_mgr_res->hw_res[i]->hw_intf;
if (hw_intf && hw_intf->hw_ops.process_cmd) {
init_cfg_update.node_res =
hw_mgr_res->hw_res[i];
CAM_DBG(CAM_ISP, "Init config update for res_id: %u",
hw_mgr_res->res_id);
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, "Init cfg update failed rc: %d", rc);
}
}
}
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)
{
@@ -8956,6 +9026,38 @@ static int cam_isp_packet_generic_blob_handler(void *user_data,
fps_config->fps, ife_mgr_ctx->ctx_index,
prepare_hw_data->packet->header.request_id);
}
break;
case CAM_ISP_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,
"Init config blob not supported for packet type: %u req: %llu",
prepare_hw_data->packet_opcode_type,
prepare->packet->header.request_id);
return -EINVAL;
}
if (blob_size < sizeof(struct cam_isp_init_config)) {
CAM_ERR(CAM_ISP,
"Invalid init config blob size %u expected %u",
blob_size, sizeof(struct cam_isp_init_config));
return -EINVAL;
}
init_config = (struct cam_isp_init_config *)blob_data;
rc = cam_isp_blob_ife_init_config_update(
prepare, init_config);
if (rc)
CAM_ERR(CAM_ISP,
"Init config failed for req: %llu rc: %d",
prepare->packet->header.request_id, rc);
}
break;
default:
@@ -9420,6 +9522,7 @@ static int cam_sfe_packet_generic_blob_handler(void *user_data,
case CAM_ISP_GENERIC_BLOB_TYPE_SENSOR_BLANKING_CONFIG:
case CAM_ISP_GENERIC_BLOB_TYPE_DISCARD_INITIAL_FRAMES:
case CAM_ISP_GENERIC_BLOB_TYPE_FPS_CONFIG:
case CAM_ISP_GENERIC_BLOB_TYPE_INIT_CONFIG:
break;
default:
CAM_WARN(CAM_ISP, "Invalid blob type: %u", blob_type);
@@ -11591,6 +11694,40 @@ static int cam_ife_hw_mgr_handle_hw_epoch(
return 0;
}
static int cam_ife_hw_mgr_handle_csid_camif_sof(
struct cam_ife_hw_mgr_ctx *ctx,
struct cam_isp_hw_event_info *event_info)
{
struct cam_isp_hw_sof_event_data sof_done_event_data;
cam_hw_event_cb_func ife_hw_irq_sof_cb;
/*
* Currently SOF update is from IFE TOP - this CSID CAMIF SOF
* is only to monitor second/third exposure frame for custom
* AEB use-case hence the checks
*/
if (!(ctx->flags.is_aeb_mode && event_info->is_secondary_evt)) {
CAM_DBG(CAM_ISP,
"Received CSID CAMIF SOF aeb_mode: %d secondary_evt: %d - skip update",
ctx->flags.is_aeb_mode, event_info->is_secondary_evt);
return 0;
}
CAM_DBG(CAM_ISP,
"Received CSID CAMIF SOF res: %d as secondary evt",
event_info->res_id);
ife_hw_irq_sof_cb = ctx->common.event_cb;
sof_done_event_data.is_secondary_evt = true;
sof_done_event_data.boot_time = 0;
sof_done_event_data.timestamp = 0;
ife_hw_irq_sof_cb(ctx->common.cb_priv,
CAM_ISP_HW_EVENT_SOF, (void *)&sof_done_event_data);
return 0;
}
static int cam_ife_hw_mgr_handle_hw_sof(
void *ctx,
void *evt_info)
@@ -11601,6 +11738,9 @@ static int cam_ife_hw_mgr_handle_hw_sof(
struct cam_isp_hw_sof_event_data sof_done_event_data;
struct timespec64 ts;
if (event_info->hw_type == CAM_ISP_HW_TYPE_CSID)
return cam_ife_hw_mgr_handle_csid_camif_sof(ctx, event_info);
memset(&sof_done_event_data, 0, sizeof(sof_done_event_data));
ife_hw_irq_sof_cb = ife_hw_mgr_ctx->common.event_cb;

Ver arquivo

@@ -141,6 +141,7 @@ struct cam_ife_hw_mgr_sfe_info {
* @is_sfe_fs: indicate if stream is for inline SFE FS
* @dump_on_flush: Set if reg dump triggered on flush
* @dump_on_error: Set if reg dump triggered on error
* @custom_aeb_mode: Set if custom AEB stream
* @sys_cache_usage: Per context sys cache usage
* The corresponding index will be set
* for the cache type
@@ -162,6 +163,7 @@ struct cam_ife_hw_mgr_ctx_flags {
bool is_sfe_fs;
bool dump_on_flush;
bool dump_on_error;
bool is_aeb_mode;
bool sys_cache_usage[CAM_LLCC_MAX];
};

Ver arquivo

@@ -38,6 +38,7 @@
#define CAM_IFE_CTX_CONSUME_ADDR_EN BIT(2)
#define CAM_IFE_CTX_APPLY_DEFAULT_CFG BIT(3)
#define CAM_IFE_CTX_SFE_EN BIT(4)
#define CAM_IFE_CTX_AEB_EN BIT(5)
/*
* Maximum configuration entry size - This is based on the
@@ -215,11 +216,13 @@ struct cam_isp_prepare_hw_update_data {
/**
* struct cam_isp_hw_sof_event_data - Event payload for CAM_HW_EVENT_SOF
*
* @timestamp: Time stamp for the sof event
* @boot_time: Boot time stamp for the sof event
* @is_secondary_event: Event notified as secondary
* @timestamp : Time stamp for the sof event
* @boot_time : Boot time stamp for the sof event
*
*/
struct cam_isp_hw_sof_event_data {
bool is_secondary_evt;
uint64_t timestamp;
uint64_t boot_time;
};

Ver arquivo

@@ -1495,6 +1495,7 @@ static int cam_ife_csid_ver2_rdi_bottom_half(
uint32_t err_type = 0;
uint32_t expected_frame = 0;
uint32_t actual_frame = 0;
bool skip_sof_notify = false;
struct cam_isp_hw_event_info evt_info;
if (!handler_priv || !evt_payload_priv) {
@@ -1567,9 +1568,6 @@ static int cam_ife_csid_ver2_rdi_bottom_half(
goto end;
}
if (!path_cfg->handle_camif_irq)
goto end;
if (!csid_hw->event_cb) {
CAM_DBG(CAM_ISP, "CSID[%u] no cb registered",
csid_hw->hw_intf->hw_idx);
@@ -1578,13 +1576,30 @@ static int cam_ife_csid_ver2_rdi_bottom_half(
evt_info.res_id = res->res_id;
evt_info.reg_val = irq_status_rdi;
evt_info.hw_type = CAM_ISP_HW_TYPE_CSID;
/* Check for secondary evt */
if ((path_cfg->en_secondary_evt) &&
(irq_status_rdi & IFE_CSID_VER2_PATH_INFO_INPUT_SOF)) {
evt_info.is_secondary_evt = true;
CAM_DBG(CAM_ISP,
"CSID[%u] RDI:%u notify CAMIF SOF as secondary evt",
csid_hw->hw_intf->hw_idx, res->res_id);
csid_hw->event_cb(csid_hw->token,
CAM_ISP_HW_EVENT_SOF, (void *)&evt_info);
skip_sof_notify = true;
}
if (!path_cfg->handle_camif_irq)
goto end;
if (irq_status_rdi & IFE_CSID_VER2_PATH_CAMIF_EOF)
csid_hw->event_cb(csid_hw->token,
CAM_ISP_HW_EVENT_EOF,
(void *)&evt_info);
if (irq_status_rdi & IFE_CSID_VER2_PATH_CAMIF_SOF)
if (!skip_sof_notify && (irq_status_rdi & IFE_CSID_VER2_PATH_CAMIF_SOF))
csid_hw->event_cb(csid_hw->token,
CAM_ISP_HW_EVENT_SOF,
(void *)&evt_info);
@@ -1885,6 +1900,8 @@ static int cam_ife_csid_hw_ver2_config_path_data(
path_cfg->vertical_bin = reserve->in_port->vertical_bin;
path_cfg->qcfa_bin = reserve->in_port->qcfa_bin;
path_cfg->num_bytes_out = reserve->in_port->num_bytes_out;
path_cfg->en_secondary_evt = reserve->en_secondary_evt;
if (reserve->sync_mode == CAM_ISP_HW_SYNC_MASTER) {
path_cfg->start_pixel = reserve->in_port->left_start;
path_cfg->end_pixel = reserve->in_port->left_stop;
@@ -1958,9 +1975,9 @@ static int cam_ife_csid_hw_ver2_config_rx(
reserve->in_port->lane_num;
csid_hw->res_type = reserve->in_port->res_type;
csid_hw->rx_cfg.dynamic_sensor_switch_en =
(bool)reserve->in_port->dynamic_sensor_switch_en;
csid_hw->rx_cfg.epd_supported =
reserve->in_port->epd_supported;
reserve->in_port->dynamic_sensor_switch_en;
if (reserve->in_port->epd_supported)
csid_hw->rx_cfg.epd_supported = 1;
switch (reserve->in_port->res_type) {
case CAM_ISP_IFE_IN_RES_TPG:
@@ -2769,6 +2786,14 @@ static int cam_ife_csid_ver2_program_rdi_path(
path_cfg->handle_camif_irq = true;
}
/* Currently CAMIF SOF is the secondary evt enabled for HW mgr */
if (path_cfg->en_secondary_evt) {
val |= IFE_CSID_VER2_PATH_CAMIF_SOF;
CAM_DBG(CAM_ISP,
"Enable camif SOF irq for res: %s",
res->res_name);
}
res->res_state = CAM_ISP_RESOURCE_STATE_STREAMING;
path_cfg->irq_reg_idx =

Ver arquivo

@@ -157,6 +157,8 @@ struct cam_ife_csid_ver2_camif_data {
* @crop_enable: flag to indicate crop enable
* @drop_enable: flag to indicate drop enable
* @discard_init_frames: discard initial frames
* @en_secondary_evt: Enable secondary evt for this path, to notify
* hw manager
*
*/
struct cam_ife_csid_ver2_path_cfg {
@@ -191,6 +193,7 @@ struct cam_ife_csid_ver2_path_cfg {
bool drop_enable;
bool handle_camif_irq;
bool discard_init_frames;
bool en_secondary_evt;
};
struct cam_ife_csid_ver2_top_reg_info {

Ver arquivo

@@ -132,11 +132,13 @@ struct cam_isp_in_port_generic_info {
uint32_t lite_path_count;
uint32_t sfe_in_path_type;
uint32_t sfe_ife_enable;
uint32_t secure_mode;
uint32_t dynamic_sensor_switch_en;
uint32_t can_use_lite;
uint32_t sfe_binned_epoch_cfg;
uint32_t epd_supported;
uint32_t epoch_factor;
bool secure_mode;
bool dynamic_sensor_switch_en;
bool can_use_lite;
bool sfe_binned_epoch_cfg;
bool epd_supported;
bool aeb_mode;
struct cam_isp_out_port_generic_info *data;
};
@@ -162,6 +164,8 @@ struct cam_isp_in_port_generic_info {
* @sfe_inline_shdr: Flag to indicate if sfe is inline shdr
* @is_offline : Flag to indicate offline
* @need_top_cfg: Flag to indicate if top cfg is needed
* @en_secondary_evt: Flag to enable secondary event for the given resource
* depending on the use-case
* @tasklet: Tasklet to schedule bottom halves
* @buf_done_controller: IRQ controller for buf done for version 680 hw
* @cdm_ops: CDM Ops
@@ -186,6 +190,7 @@ struct cam_csid_hw_reserve_resource_args {
bool sfe_inline_shdr;
bool is_offline;
bool need_top_cfg;
bool en_secondary_evt;
void *tasklet;
void *buf_done_controller;
void *cdm_ops;

Ver arquivo

@@ -197,6 +197,7 @@ enum cam_isp_hw_cmd_type {
CAM_ISP_HW_CMD_WM_BW_LIMIT_CONFIG,
CAM_ISP_HW_CMD_RM_ENABLE_DISABLE,
CAM_ISP_HW_CMD_APPLY_CLK_BW_UPDATE,
CAM_ISP_HW_CMD_INIT_CONFIG_UPDATE,
CAM_ISP_HW_CMD_MAX,
};
@@ -270,19 +271,21 @@ struct cam_isp_blanking_config {
/*
* struct cam_isp_hw_event_info:
*
* @Brief: Structure to pass event details to hw mgr
* @Brief: Structure to pass event details to hw mgr
*
* @res_type: Type of IFE resource
* @res_id: Unique resource ID
* @hw_idx: IFE hw index
* @err_type: Error type if any
* @reg_val: Any critical register value captured during irq handling
* @hw_type: Hw Type sending the event
* @in_core_idx: Input core type if CSID error evt
* @res_type: Type of IFE resource
* @is_secondary_evt: Indicates if event was requested by hw mgr
* @res_id: Unique resource ID
* @hw_idx: IFE hw index
* @err_type: Error type if any
* @reg_val: Any critical register value captured during irq handling
* @hw_type: Hw Type sending the event
* @in_core_idx: Input core type if CSID error evt
*
*/
struct cam_isp_hw_event_info {
enum cam_isp_resource_type res_type;
bool is_secondary_evt;
uint32_t res_id;
uint32_t hw_idx;
uint32_t err_type;
@@ -502,4 +505,18 @@ struct cam_isp_hw_path_port_map {
uint32_t entry[CAM_ISP_HW_PATH_PORT_MAP_MAX][2];
};
/**
* struct cam_isp_hw_init_config_update:
*
* @Brief: Init config params for CSID/SFE/IFE resources
*
* @node_res: HW Resource
* @init_config: Init config params from userspace
*/
struct cam_isp_hw_init_config_update {
struct cam_isp_resource_node *node_res;
struct cam_isp_init_config *init_config;
};
#endif /* _CAM_ISP_HW_H_ */

Ver arquivo

@@ -516,6 +516,7 @@ int cam_vfe_process_cmd(void *hw_priv, uint32_t cmd_type,
case CAM_ISP_HW_CMD_FE_UPDATE_IN_RD:
case CAM_ISP_HW_CMD_GET_PATH_PORT_MAP:
case CAM_ISP_HW_CMD_APPLY_CLK_BW_UPDATE:
case CAM_ISP_HW_CMD_INIT_CONFIG_UPDATE:
rc = core_info->vfe_top->hw_ops.process_cmd(
core_info->vfe_top->top_priv, cmd_type, cmd_args,
arg_size);

Ver arquivo

@@ -69,6 +69,7 @@ struct cam_vfe_mux_ver4_data {
uint32_t qcfa_bin;
uint32_t dual_hw_idx;
uint32_t is_dual;
uint32_t epoch_factor;
bool is_fe_enabled;
bool is_offline;
bool is_lite;
@@ -1063,6 +1064,30 @@ static int cam_vfe_core_config_control(
return 0;
}
static int cam_vfe_init_config_update(
void *cmd_args, uint32_t arg_size)
{
struct cam_isp_hw_init_config_update *init_cfg = cmd_args;
struct cam_isp_resource_node *rsrc_node = init_cfg->node_res;
struct cam_vfe_mux_ver4_data *mux_data = rsrc_node->res_priv;
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;
}
mux_data->epoch_factor =
init_cfg->init_config->epoch_cfg.epoch_factor;
CAM_DBG(CAM_ISP,
"Init Update for res_name: %s epoch_factor: %u%%",
rsrc_node->res_name, mux_data->epoch_factor);
return 0;
}
static int cam_vfe_top_ver4_mux_get_reg_update(
struct cam_vfe_top_ver4_priv *top_priv,
void *cmd_args, uint32_t arg_size)
@@ -1185,7 +1210,7 @@ int cam_vfe_top_acquire_resource(
acquire_data->vfe_in.in_port->horizontal_bin;
res_data->vbi_value = 0;
res_data->hbi_value = 0;
res_data->sfe_binned_epoch_cfg = (bool)
res_data->sfe_binned_epoch_cfg =
acquire_data->vfe_in.in_port->sfe_binned_epoch_cfg;
if (res_data->is_dual)
@@ -1472,6 +1497,9 @@ int cam_vfe_top_ver4_process_cmd(void *device_priv, uint32_t cmd_type,
case CAM_ISP_HW_CMD_APPLY_CLK_BW_UPDATE:
rc = cam_vfe_top_apply_clk_bw_update(&top_priv->top_common, cmd_args, arg_size);
break;
case CAM_ISP_HW_CMD_INIT_CONFIG_UPDATE:
rc = cam_vfe_init_config_update(cmd_args, arg_size);
break;
default:
rc = -EINVAL;
CAM_ERR(CAM_ISP, "Error, Invalid cmd:%d", cmd_type);
@@ -1621,6 +1649,7 @@ static int cam_vfe_handle_irq_bottom_half(void *handler_priv,
irq_status[i] = payload->irq_reg_val[i];
evt_info.hw_idx = vfe_res->hw_intf->hw_idx;
evt_info.hw_type = CAM_ISP_HW_TYPE_VFE;
evt_info.res_id = vfe_res->res_id;
evt_info.res_type = vfe_res->res_type;
evt_info.reg_val = 0;
@@ -1781,7 +1810,7 @@ static int cam_vfe_resource_start(
struct cam_isp_resource_node *vfe_res)
{
struct cam_vfe_mux_ver4_data *rsrc_data;
uint32_t val = 0;
uint32_t val = 0, epoch_factor = 50;
int rc = 0;
uint32_t err_irq_mask[CAM_IFE_IRQ_REGISTERS_MAX];
uint32_t irq_mask[CAM_IFE_IRQ_REGISTERS_MAX];
@@ -1817,8 +1846,13 @@ static int cam_vfe_resource_start(
cam_io_r_mb(rsrc_data->mem_base +
rsrc_data->common_reg->core_cfg_1));
/* % epoch factor from userland */
if ((rsrc_data->epoch_factor) && (rsrc_data->epoch_factor <= 100))
epoch_factor = rsrc_data->epoch_factor;
val = ((rsrc_data->last_line + rsrc_data->vbi_value) -
rsrc_data->first_line) / 2;
rsrc_data->first_line) * epoch_factor / 100;
if (val > rsrc_data->last_line)
val = rsrc_data->last_line;
@@ -1828,7 +1862,10 @@ static int cam_vfe_resource_start(
cam_io_w_mb(val, rsrc_data->mem_base +
rsrc_data->common_reg->epoch_height_cfg);
CAM_DBG(CAM_ISP, "epoch_line_cfg: 0x%X", val);
CAM_DBG(CAM_ISP,
"height [0x%x : 0x%x] vbi_val: 0x%x epoch_factor: %u%% epoch_line_cfg: 0x%x",
rsrc_data->first_line, rsrc_data->last_line,
rsrc_data->vbi_value, epoch_factor, val);
skip_core_cfg:
vfe_res->res_state = CAM_ISP_RESOURCE_STATE_STREAMING;
@@ -1986,6 +2023,7 @@ skip_core_decfg:
vfe_priv->irq_err_handle = 0;
}
vfe_priv->epoch_factor = 0;
CAM_DBG(CAM_ISP, "VFE:%d Res: %s Stopped",
vfe_res->hw_intf->hw_idx,
vfe_res->res_name);