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:
@@ -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;
|
||||
}
|
||||
|
@@ -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;
|
||||
|
@@ -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;
|
||||
|
@@ -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];
|
||||
};
|
||||
|
||||
|
@@ -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;
|
||||
};
|
||||
|
@@ -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 =
|
||||
|
@@ -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 {
|
||||
|
@@ -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;
|
||||
|
@@ -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_ */
|
||||
|
@@ -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);
|
||||
|
@@ -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);
|
||||
|
Referência em uma nova issue
Block a user