Merge "msm: camera: isp: Add support to obtain frame index" into camera-kernel.lnx.4.0

This commit is contained in:
Camera Software Integration 2020-02-10 11:47:28 -08:00 • committed by Gerrit - the friendly Code Review server
commit 2460a8e82a
10 changed files with 128 additions and 52 deletions

View file

@ -470,6 +470,7 @@ static void __cam_isp_ctx_send_sof_boot_timestamp(
req_msg.u.frame_msg.timestamp = ctx_isp->boot_timestamp;
req_msg.u.frame_msg.link_hdl = ctx_isp->base->link_hdl;
req_msg.u.frame_msg.sof_status = sof_event_status;
req_msg.u.frame_msg.frame_id_meta = ctx_isp->frame_id_meta;
CAM_DBG(CAM_ISP,
"request id:%lld frame number:%lld boot time stamp:0x%llx",
@ -497,6 +498,7 @@ static void __cam_isp_ctx_send_sof_timestamp(
req_msg.u.frame_msg.timestamp = ctx_isp->sof_timestamp_val;
req_msg.u.frame_msg.link_hdl = ctx_isp->base->link_hdl;
req_msg.u.frame_msg.sof_status = sof_event_status;
req_msg.u.frame_msg.frame_id_meta = ctx_isp->frame_id_meta;
CAM_DBG(CAM_ISP,
"request id:%lld frame number:%lld SOF time stamp:0x%llx",
@ -863,11 +865,20 @@ static int __cam_isp_ctx_notify_sof_in_activated_state(
struct cam_isp_context *ctx_isp, void *evt_data)
{
int rc = 0;
uint64_t request_id = 0;
struct cam_req_mgr_trigger_notify notify;
struct cam_context *ctx = ctx_isp->base;
struct cam_ctx_request *req;
struct cam_isp_ctx_req *req_isp;
uint64_t request_id = 0;
struct cam_isp_hw_epoch_event_data *epoch_done_event_data =
(struct cam_isp_hw_epoch_event_data *)evt_data;
if (!evt_data) {
CAM_ERR(CAM_ISP, "invalid event data");
return -EINVAL;
}
ctx_isp->frame_id_meta = epoch_done_event_data->frame_id_meta;
/*
* notify reqmgr with sof signal. Note, due to scheduling delay
@ -1082,11 +1093,19 @@ end:
static int __cam_isp_ctx_epoch_in_applied(struct cam_isp_context *ctx_isp,
void *evt_data)
{
struct cam_ctx_request *req;
struct cam_isp_ctx_req *req_isp;
struct cam_context *ctx = ctx_isp->base;
uint64_t request_id = 0;
uint64_t request_id = 0;
struct cam_ctx_request *req;
struct cam_isp_ctx_req *req_isp;
struct cam_context *ctx = ctx_isp->base;
struct cam_isp_hw_epoch_event_data *epoch_done_event_data =
(struct cam_isp_hw_epoch_event_data *)evt_data;
if (!evt_data) {
CAM_ERR(CAM_ISP, "invalid event data");
return -EINVAL;
}
ctx_isp->frame_id_meta = epoch_done_event_data->frame_id_meta;
if (list_empty(&ctx->wait_req_list)) {
/*
* If no wait req in epoch, this is an error case.
@ -1248,10 +1267,19 @@ static int __cam_isp_ctx_buf_done_in_bubble(
static int __cam_isp_ctx_epoch_in_bubble_applied(
struct cam_isp_context *ctx_isp, void *evt_data)
{
struct cam_ctx_request *req;
struct cam_isp_ctx_req *req_isp;
struct cam_context *ctx = ctx_isp->base;
uint64_t request_id = 0;
struct cam_ctx_request *req;
struct cam_isp_ctx_req *req_isp;
struct cam_context *ctx = ctx_isp->base;
struct cam_isp_hw_epoch_event_data *epoch_done_event_data =
(struct cam_isp_hw_epoch_event_data *)evt_data;
if (!evt_data) {
CAM_ERR(CAM_ISP, "invalid event data");
return -EINVAL;
}
ctx_isp->frame_id_meta = epoch_done_event_data->frame_id_meta;
/*
* This means we missed the reg upd ack. So we need to

View file

@ -166,6 +166,8 @@ struct cam_isp_context_req_id_info {
*
* @base: Common context object pointer
* @frame_id: Frame id tracking for the isp context
* @frame_id_meta: Frame id read every epoch for the ctx
* meta from the sensor
* @substate_actiavted: Current substate for the activated state.
* @process_bubble: Atomic variable to check if ctx is still
* processing bubble.
@ -195,27 +197,28 @@ struct cam_isp_context_req_id_info {
*
*/
struct cam_isp_context {
struct cam_context *base;
struct cam_context *base;
int64_t frame_id;
enum cam_isp_ctx_activated_substate substate_activated;
atomic_t process_bubble;
uint32_t bubble_frame_cnt;
struct cam_ctx_ops *substate_machine;
struct cam_isp_ctx_irq_ops *substate_machine_irq;
int64_t frame_id;
uint32_t frame_id_meta;
uint32_t substate_activated;
atomic_t process_bubble;
uint32_t bubble_frame_cnt;
struct cam_ctx_ops *substate_machine;
struct cam_isp_ctx_irq_ops *substate_machine_irq;
struct cam_ctx_request req_base[CAM_CTX_REQ_MAX];
struct cam_isp_ctx_req req_isp[CAM_CTX_REQ_MAX];
struct cam_ctx_request req_base[CAM_CTX_REQ_MAX];
struct cam_isp_ctx_req req_isp[CAM_CTX_REQ_MAX];
void *hw_ctx;
uint64_t sof_timestamp_val;
uint64_t boot_timestamp;
int32_t active_req_cnt;
int64_t reported_req_id;
uint32_t subscribe_event;
int64_t last_applied_req_id;
atomic64_t state_monitor_head;
struct cam_isp_context_state_monitor cam_isp_ctx_state_monitor[
void *hw_ctx;
uint64_t sof_timestamp_val;
uint64_t boot_timestamp;
int32_t active_req_cnt;
int64_t reported_req_id;
uint32_t subscribe_event;
int64_t last_applied_req_id;
atomic64_t state_monitor_head;
struct cam_isp_context_state_monitor cam_isp_ctx_state_monitor[
CAM_ISP_CTX_STATE_MONITOR_MAX_ENTRIES];
struct cam_isp_context_req_id_info req_info;
bool rdi_only_context;

View file

@ -4775,29 +4775,36 @@ static int cam_isp_blob_core_cfg_update(
list_for_each_entry(hw_mgr_res, &ctx->res_list_ife_src, list) {
for (i = 0; i < CAM_ISP_HW_SPLIT_MAX; i++) {
clk_rate = 0;
if (!hw_mgr_res->hw_res[i] ||
hw_mgr_res->res_id != CAM_ISP_HW_VFE_IN_CAMIF)
if (!hw_mgr_res->hw_res[i])
continue;
hw_intf = hw_mgr_res->hw_res[i]->hw_intf;
if (hw_intf && hw_intf->hw_ops.process_cmd) {
vfe_core_config.node_res =
hw_mgr_res->hw_res[i];
if ((hw_mgr_res->res_id ==
CAM_ISP_HW_VFE_IN_CAMIF) ||
(hw_mgr_res->res_id ==
CAM_ISP_HW_VFE_IN_PDLIB)) {
hw_intf = hw_mgr_res->hw_res[i]->hw_intf;
if (hw_intf && hw_intf->hw_ops.process_cmd) {
vfe_core_config.node_res =
hw_mgr_res->hw_res[i];
memcpy(&vfe_core_config.core_config,
core_config,
sizeof(struct cam_isp_core_config));
memcpy(&vfe_core_config.core_config,
core_config,
sizeof(
struct cam_isp_core_config));
rc = hw_intf->hw_ops.process_cmd(
hw_intf->hw_priv,
CAM_ISP_HW_CMD_CORE_CONFIG,
&vfe_core_config,
sizeof(
struct cam_vfe_core_config_args));
if (rc)
CAM_ERR(CAM_ISP, "Core cfg parse fail");
} else {
CAM_WARN(CAM_ISP, "NULL hw_intf!");
rc = hw_intf->hw_ops.process_cmd(
hw_intf->hw_priv,
CAM_ISP_HW_CMD_CORE_CONFIG,
&vfe_core_config,
sizeof(
struct cam_vfe_core_config_args)
);
if (rc)
CAM_ERR(CAM_ISP,
"Core cfg parse fail");
} else {
CAM_WARN(CAM_ISP, "NULL hw_intf!");
}
}
}
}
@ -6434,6 +6441,9 @@ static int cam_ife_hw_mgr_handle_hw_epoch(
if (!rc) {
if (atomic_read(&ife_hw_mgr_ctx->overflow_pending))
break;
epoch_done_event_data.frame_id_meta =
event_info->th_reg_val;
ife_hw_irq_epoch_cb(ife_hw_mgr_ctx->common.cb_priv,
CAM_ISP_HW_EVENT_EPOCH, &epoch_done_event_data);
}

View file

@ -170,10 +170,11 @@ struct cam_isp_hw_reg_update_event_data {
* struct cam_isp_hw_epoch_event_data - Event payload for CAM_HW_EVENT_EPOCH
*
* @timestamp: Time stamp for the epoch event
*
* @frame_id_meta: Frame id value corresponding to this frame
*/
struct cam_isp_hw_epoch_event_data {
uint64_t timestamp;
uint32_t frame_id_meta;
};
/**

View file

@ -174,6 +174,7 @@ struct cam_isp_resource_node {
* @res_id: Unique resource ID
* @hw_idx: IFE hw index
* @err_type: Error type if any
* @th_reg_val: Any critical register value captured during th
*
*/
struct cam_isp_hw_event_info {
@ -181,6 +182,7 @@ struct cam_isp_hw_event_info {
uint32_t res_id;
uint32_t hw_idx;
uint32_t err_type;
uint32_t th_reg_val;
};
/*

View file

@ -263,11 +263,15 @@ struct cam_vfe_bw_control_args {
* @list: list_head node for the payload
* @irq_reg_val: IRQ and Error register values, read when IRQ was
* handled
* @th_reg_val: Value of any critical register that needs to be
* read at th to avoid any latencies in bh processing
*
* @ts: Timestamp
*/
struct cam_vfe_top_irq_evt_payload {
struct list_head list;
uint32_t irq_reg_val[CAM_IFE_IRQ_REGISTERS_MAX];
uint32_t th_reg_val;
struct cam_isp_timestamp ts;
};

View file

@ -1,6 +1,6 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/*
* Copyright (c) 2019, The Linux Foundation. All rights reserved.
* Copyright (c) 2019-2020, The Linux Foundation. All rights reserved.
*/
@ -77,6 +77,7 @@ static struct cam_vfe_camif_ver3_reg_data vfe_480_camif_reg_data = {
.error_irq_mask0 = 0x82000200,
.error_irq_mask2 = 0x30301F80,
.subscribe_irq_mask1 = 0x00000007,
.frame_id_irq_mask = 0x400,
.enable_diagnostic_hw = 0x1,
.pp_camif_cfg_en_shift = 0,
.pp_camif_cfg_ife_out_en_shift = 8,
@ -101,7 +102,7 @@ static struct cam_vfe_top_ver3_reg_offset_common vfe480_top_common_reg = {
.ahb_cgc_ovd = 0x00000024,
.noc_cgc_ovd = 0x00000028,
.trigger_cdm_events = 0x00000090,
.sbi_frame_idx = 0x00000110,
.custom_frame_idx = 0x00000110,
.dsp_status = 0x0000007C,
.diag_config = 0x00000064,
.diag_sensor_status_0 = 0x00000068,

View file

@ -507,6 +507,9 @@ static int cam_vfe_camif_ver3_resource_start(
irq_mask[CAM_IFE_IRQ_CAMIF_REG_STATUS1] =
rsrc_data->reg_data->sof_irq_mask;
if (rsrc_data->cam_common_cfg.input_mux_sel_pp & 0x3)
irq_mask[CAM_IFE_IRQ_CAMIF_REG_STATUS0] =
rsrc_data->reg_data->frame_id_irq_mask;
if (!rsrc_data->sof_irq_handle) {
rsrc_data->sof_irq_handle = cam_irq_controller_subscribe_irq(
@ -1191,10 +1194,21 @@ static int cam_vfe_camif_ver3_handle_irq_top_half(uint32_t evt_id,
}
cam_isp_hw_get_timestamp(&evt_payload->ts);
evt_payload->th_reg_val = 0;
for (i = 0; i < th_payload->num_registers; i++)
evt_payload->irq_reg_val[i] = th_payload->evt_status_arr[i];
/* Read frame_id meta at every epoch if custom hw is enabled */
if (evt_payload->irq_reg_val[CAM_IFE_IRQ_CAMIF_REG_STATUS1]
& camif_priv->reg_data->epoch0_irq_mask) {
if ((camif_priv->common_reg->custom_frame_idx) &&
(camif_priv->cam_common_cfg.input_mux_sel_pp & 0x3))
evt_payload->th_reg_val = cam_io_r_mb(
camif_priv->mem_base +
camif_priv->common_reg->custom_frame_idx);
}
th_payload->evt_payload_priv = evt_payload;
CAM_DBG(CAM_ISP, "Exit");
@ -1210,6 +1224,7 @@ static int cam_vfe_camif_ver3_handle_irq_bottom_half(void *handler_priv,
struct cam_vfe_top_irq_evt_payload *payload;
struct cam_isp_hw_event_info evt_info;
uint32_t irq_status[CAM_IFE_IRQ_REGISTERS_MAX] = {0};
uint32_t val = 0;
int i = 0;
if (!handler_priv || !evt_payload_priv) {
@ -1229,6 +1244,7 @@ static int cam_vfe_camif_ver3_handle_irq_bottom_half(void *handler_priv,
evt_info.hw_idx = camif_node->hw_intf->hw_idx;
evt_info.res_id = camif_node->res_id;
evt_info.res_type = camif_node->res_type;
evt_info.th_reg_val = 0;
if (irq_status[CAM_IFE_IRQ_CAMIF_REG_STATUS1]
& camif_priv->reg_data->sof_irq_mask) {
@ -1259,6 +1275,7 @@ static int cam_vfe_camif_ver3_handle_irq_bottom_half(void *handler_priv,
if (irq_status[CAM_IFE_IRQ_CAMIF_REG_STATUS1]
& camif_priv->reg_data->epoch0_irq_mask) {
CAM_DBG(CAM_ISP, "VFE:%d Received EPOCH", evt_info.hw_idx);
evt_info.th_reg_val = payload->th_reg_val;
if (camif_priv->event_cb)
camif_priv->event_cb(camif_priv->priv,
@ -1294,6 +1311,15 @@ static int cam_vfe_camif_ver3_handle_irq_bottom_half(void *handler_priv,
cam_vfe_camif_ver3_reg_dump(camif_node);
}
if (irq_status[CAM_IFE_IRQ_CAMIF_REG_STATUS0]
& camif_priv->reg_data->frame_id_irq_mask) {
val = cam_io_r_mb(camif_priv->mem_base +
camif_priv->common_reg->custom_frame_idx);
CAM_DBG(CAM_ISP,
"VFE:%d Frame id change to: %u", evt_info.hw_idx,
val);
}
if (irq_status[CAM_IFE_IRQ_CAMIF_REG_STATUS2]) {
CAM_ERR(CAM_ISP, "VFE:%d Violation", evt_info.hw_idx);

View file

@ -53,6 +53,7 @@ struct cam_vfe_camif_ver3_reg_data {
uint32_t error_irq_mask0;
uint32_t error_irq_mask2;
uint32_t subscribe_irq_mask1;
uint32_t frame_id_irq_mask;
uint32_t enable_diagnostic_hw;
uint32_t pp_camif_cfg_en_shift;

View file

@ -1,6 +1,6 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/*
* Copyright (c) 2019, The Linux Foundation. All rights reserved.
* Copyright (c) 2019-2020, The Linux Foundation. All rights reserved.
*/
#ifndef _CAM_VFE_TOP_VER3_H_
@ -41,7 +41,7 @@ struct cam_vfe_top_ver3_reg_offset_common {
uint32_t reg_update_cmd;
uint32_t trigger_cdm_events;
uint32_t violation_status;
uint32_t sbi_frame_idx;
uint32_t custom_frame_idx;
uint32_t dsp_status;
uint32_t diag_config;
uint32_t diag_sensor_status_0;