msm: camera: isp: Obtain timestamp as part of frame header

In use-cases that involve custom HW retrieve the timestamp
for shutter from frame header as opposed to csid registers.

CRs-Fixed: 2524308
Change-Id: I5de789cf939546affbfe6d537d8090982f39189d
Signed-off-by: Karthik Anantha Ram <kartanan@codeaurora.org>
This commit is contained in:
Karthik Anantha Ram
2019-09-13 11:08:05 -07:00
committed by Venkat Chinta
parent e3f5738e43
commit 381bb12c68
12 changed files with 278 additions and 24 deletions

View File

@@ -1,6 +1,6 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/*
* Copyright (c) 2017-2019, The Linux Foundation. All rights reserved.
* Copyright (c) 2017-2020, The Linux Foundation. All rights reserved.
*/
#ifndef _CAM_HW_MGR_INTF_H_
@@ -101,6 +101,8 @@ struct cam_hw_done_event_data {
* @num_acq: Total number of acquire in the payload
* @acquire_info: Acquired resource array pointer
* @ctxt_to_hw_map: HW context (returned)
* @custom_enabled: ctx has custom enabled
* @use_frame_header_ts: Use frame header for qtimer ts
* @acquired_hw_id: Acquired hardware mask
* @acquired_hw_path: Acquired path mask for an input
* if input splits into multiple paths,
@@ -115,6 +117,8 @@ struct cam_hw_acquire_args {
uint32_t acquire_info_size;
uintptr_t acquire_info;
void *ctxt_to_hw_map;
bool custom_enabled;
bool use_frame_header_ts;
uint32_t acquired_hw_id[CAM_MAX_ACQ_RES];
uint32_t acquired_hw_path[CAM_MAX_ACQ_RES][CAM_MAX_HW_SPLIT];

View File

@@ -425,6 +425,7 @@ static int __cam_isp_ctx_enqueue_init_request(
struct cam_isp_ctx_req *req_isp_new;
struct cam_isp_prepare_hw_update_data *req_update_old;
struct cam_isp_prepare_hw_update_data *req_update_new;
struct cam_isp_prepare_hw_update_data *hw_update_data;
spin_lock_bh(&ctx->lock);
if (list_empty(&ctx->pending_req_list)) {
@@ -487,6 +488,13 @@ static int __cam_isp_ctx_enqueue_init_request(
req_update_new->num_reg_dump_buf;
}
/* Update frame header params for EPCR */
hw_update_data = &req_isp_new->hw_update_data;
req_isp_old->hw_update_data.frame_header_res_id =
req_isp_new->hw_update_data.frame_header_res_id;
req_isp_old->hw_update_data.frame_header_cpu_addr =
hw_update_data->frame_header_cpu_addr;
req_old->request_id = req->request_id;
list_add_tail(&req->list, &ctx->free_req_list);
@@ -645,9 +653,9 @@ static void __cam_isp_ctx_send_sof_boot_timestamp(
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",
"request id:%lld frame number:%lld boot time stamp:0x%llx status:%u",
request_id, ctx_isp->frame_id,
ctx_isp->boot_timestamp);
ctx_isp->boot_timestamp, sof_event_status);
if (cam_req_mgr_notify_message(&req_msg,
V4L_EVENT_CAM_REQ_MGR_SOF_BOOT_TS,
@@ -657,6 +665,41 @@ static void __cam_isp_ctx_send_sof_boot_timestamp(
request_id);
}
static void __cam_isp_ctx_send_sof_timestamp_frame_header(
struct cam_isp_context *ctx_isp, uint32_t *frame_header_cpu_addr,
uint64_t request_id, uint32_t sof_event_status)
{
uint32_t *time32 = NULL;
uint64_t timestamp = 0;
struct cam_req_mgr_message req_msg;
time32 = frame_header_cpu_addr;
timestamp = (uint64_t) time32[1];
timestamp = timestamp << 24;
timestamp |= (uint64_t)(time32[0] >> 8);
timestamp = mul_u64_u32_div(timestamp,
CAM_IFE_QTIMER_MUL_FACTOR,
CAM_IFE_QTIMER_DIV_FACTOR);
ctx_isp->sof_timestamp_val = timestamp;
req_msg.session_hdl = ctx_isp->base->session_hdl;
req_msg.u.frame_msg.frame_id = ctx_isp->frame_id;
req_msg.u.frame_msg.request_id = request_id;
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;
CAM_DBG(CAM_ISP,
"request id:%lld frame number:%lld SOF time stamp:0x%llx status:%u",
request_id, ctx_isp->frame_id,
ctx_isp->sof_timestamp_val, sof_event_status);
if (cam_req_mgr_notify_message(&req_msg,
V4L_EVENT_CAM_REQ_MGR_SOF, V4L_EVENT_CAM_REQ_MGR_EVENT))
CAM_ERR(CAM_ISP,
"Error in notifying the sof time for req id:%lld",
request_id);
}
static void __cam_isp_ctx_send_sof_timestamp(
struct cam_isp_context *ctx_isp, uint64_t request_id,
@@ -664,6 +707,10 @@ static void __cam_isp_ctx_send_sof_timestamp(
{
struct cam_req_mgr_message req_msg;
if ((ctx_isp->use_frame_header_ts) && (request_id) &&
(sof_event_status == CAM_REQ_MGR_SOF_EVENT_SUCCESS))
goto end;
req_msg.session_hdl = ctx_isp->base->session_hdl;
req_msg.u.frame_msg.frame_id = ctx_isp->frame_id;
req_msg.u.frame_msg.request_id = request_id;
@@ -673,10 +720,9 @@ static void __cam_isp_ctx_send_sof_timestamp(
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",
"request id:%lld frame number:%lld SOF time stamp:0x%llx status:%u",
request_id, ctx_isp->frame_id,
ctx_isp->sof_timestamp_val);
CAM_DBG(CAM_ISP, "sof status:%d", sof_event_status);
ctx_isp->sof_timestamp_val, sof_event_status);
if (cam_req_mgr_notify_message(&req_msg,
V4L_EVENT_CAM_REQ_MGR_SOF, V4L_EVENT_CAM_REQ_MGR_EVENT))
@@ -684,9 +730,9 @@ static void __cam_isp_ctx_send_sof_timestamp(
"Error in notifying the sof time for req id:%lld",
request_id);
end:
__cam_isp_ctx_send_sof_boot_timestamp(ctx_isp,
request_id, sof_event_status);
}
static void __cam_isp_ctx_handle_buf_done_fail_log(
@@ -738,7 +784,7 @@ static int __cam_isp_ctx_handle_buf_done_for_request(
{
int rc = 0;
int i, j;
struct cam_isp_ctx_req *req_isp;
struct cam_isp_ctx_req *req_isp;
struct cam_context *ctx = ctx_isp->base;
uint64_t buf_done_req_id;
const char *handle_type;
@@ -840,6 +886,14 @@ static int __cam_isp_ctx_handle_buf_done_for_request(
req_isp->num_acked++;
req_isp->fence_map_out[j].sync_id = -1;
}
if ((ctx_isp->use_frame_header_ts) &&
(req_isp->hw_update_data.frame_header_res_id ==
req_isp->fence_map_out[j].resource_handle))
__cam_isp_ctx_send_sof_timestamp_frame_header(
ctx_isp,
req_isp->hw_update_data.frame_header_cpu_addr,
req->request_id, CAM_REQ_MGR_SOF_EVENT_SUCCESS);
}
if (req_isp->num_acked > req_isp->num_fence_map_out) {
@@ -883,10 +937,14 @@ static int __cam_isp_ctx_handle_buf_done_for_request(
ctx->ctx_id);
}
} else {
if (ctx_isp->reported_req_id < buf_done_req_id) {
ctx_isp->reported_req_id = buf_done_req_id;
__cam_isp_ctx_send_sof_timestamp(ctx_isp,
buf_done_req_id, CAM_REQ_MGR_SOF_EVENT_SUCCESS);
if (!ctx_isp->use_frame_header_ts) {
if (ctx_isp->reported_req_id < buf_done_req_id) {
ctx_isp->reported_req_id = buf_done_req_id;
__cam_isp_ctx_send_sof_timestamp(ctx_isp,
buf_done_req_id,
CAM_REQ_MGR_SOF_EVENT_SUCCESS);
}
}
list_del_init(&req->list);
list_add_tail(&req->list, &ctx->free_req_list);
@@ -3375,6 +3433,8 @@ static int __cam_isp_ctx_release_hw_in_top_state(struct cam_context *ctx,
}
ctx->last_flush_req = 0;
ctx_isp->custom_enabled = false;
ctx_isp->use_frame_header_ts = false;
ctx_isp->frame_id = 0;
ctx_isp->active_req_cnt = 0;
ctx_isp->reported_req_id = 0;
@@ -4030,6 +4090,12 @@ static int __cam_isp_ctx_acquire_hw_v2(struct cam_context *ctx,
goto free_res;
}
/* Set custom flag if applicable
* custom hw is supported only on v2
*/
ctx_isp->custom_enabled = param.custom_enabled;
ctx_isp->use_frame_header_ts = param.use_frame_header_ts;
/* Query the context has rdi only resource */
hw_cmd_args.ctxt_to_hw_map = param.ctxt_to_hw_map;
hw_cmd_args.cmd_type = CAM_HW_MGR_CMD_INTERNAL;
@@ -4935,6 +5001,8 @@ int cam_isp_context_init(struct cam_isp_context *ctx,
ctx->base = ctx_base;
ctx->frame_id = 0;
ctx->custom_enabled = false;
ctx->use_frame_header_ts = false;
ctx->active_req_cnt = 0;
ctx->reported_req_id = 0;
ctx->req_info.last_bufdone_req_id = 0;

View File

@@ -15,6 +15,10 @@
#include "cam_context.h"
#include "cam_isp_hw_mgr_intf.h"
#define CAM_IFE_QTIMER_MUL_FACTOR 10000
#define CAM_IFE_QTIMER_DIV_FACTOR 192
/*
* Maximum hw resource - This number is based on the maximum
* output port resource. The current maximum resource number
@@ -246,6 +250,8 @@ struct cam_isp_context_event_record {
* @hw_acquired: Indicate whether HW resources are acquired
* @init_received: Indicate whether init config packet is received
* @split_acquire: Indicate whether a separate acquire is expected
* @custom_enabled: Custom HW enabled for this ctx
* @use_frame_header_ts: Use frame header for qtimer ts
* @init_timestamp: Timestamp at which this context is initialized
* @isp_device_type ISP device type
*
@@ -283,6 +289,8 @@ struct cam_isp_context {
bool hw_acquired;
bool init_received;
bool split_acquire;
bool custom_enabled;
bool use_frame_header_ts;
unsigned int init_timestamp;
uint32_t isp_device_type;
};

View File

@@ -2695,6 +2695,7 @@ static int cam_ife_mgr_acquire_hw(void *hw_mgr_priv, void *acquire_hw_args)
goto err;
}
ife_ctx->custom_enabled = false;
ife_ctx->common.cb_priv = acquire_args->context_data;
for (i = 0; i < CAM_ISP_HW_EVENT_MAX; i++)
ife_ctx->common.event_cb[i] = acquire_args->event_cb;
@@ -2748,6 +2749,12 @@ static int cam_ife_mgr_acquire_hw(void *hw_mgr_priv, void *acquire_hw_args)
}
CAM_DBG(CAM_ISP, "in_res_type %x", in_port->res_type);
if ((in_port->cust_node) && (!ife_ctx->custom_enabled)) {
ife_ctx->custom_enabled = true;
/* This can be obtained from uapi */
ife_ctx->use_frame_header_ts = true;
}
rc = cam_ife_mgr_acquire_hw_for_ctx(ife_ctx, in_port,
&num_pix_port_per_in, &num_rdi_port_per_in,
&acquire_args->acquired_hw_id[i],
@@ -2782,6 +2789,8 @@ static int cam_ife_mgr_acquire_hw(void *hw_mgr_priv, void *acquire_hw_args)
}
acquire_args->ctxt_to_hw_map = ife_ctx;
acquire_args->custom_enabled = ife_ctx->custom_enabled;
acquire_args->use_frame_header_ts = ife_ctx->use_frame_header_ts;
ife_ctx->ctx_in_use = 1;
ife_ctx->num_reg_dump_buf = 0;
@@ -4193,6 +4202,8 @@ static int cam_ife_mgr_release_hw(void *hw_mgr_priv,
ctx->cdm_handle = 0;
ctx->cdm_ops = NULL;
ctx->num_reg_dump_buf = 0;
ctx->custom_enabled = false;
ctx->use_frame_header_ts = false;
atomic_set(&ctx->overflow_pending, 0);
for (i = 0; i < CAM_IFE_HW_NUM_MAX; i++) {
ctx->sof_cnt[i] = 0;
@@ -5555,6 +5566,58 @@ static int cam_isp_packet_generic_blob_handler(void *user_data,
return rc;
}
static int cam_ife_mgr_util_insert_frame_header(
struct cam_kmd_buf_info *kmd_buf,
struct cam_isp_prepare_hw_update_data *prepare_hw_data)
{
int mmu_hdl = -1, rc = 0;
dma_addr_t iova_addr;
uint32_t frame_header_iova, padded_bytes = 0;
size_t len;
struct cam_ife_hw_mgr *hw_mgr = &g_ife_hw_mgr;
mmu_hdl = cam_mem_is_secure_buf(
kmd_buf->handle) ?
hw_mgr->mgr_common.img_iommu_hdl_secure :
hw_mgr->mgr_common.img_iommu_hdl;
rc = cam_mem_get_io_buf(kmd_buf->handle, mmu_hdl,
&iova_addr, &len);
if (rc) {
CAM_ERR(CAM_ISP,
"Failed to get io addr for handle = %d for mmu_hdl = %u",
kmd_buf->handle, mmu_hdl);
return rc;
}
frame_header_iova = (uint32_t)iova_addr;
frame_header_iova += kmd_buf->offset;
/* frame header address needs to be 16 byte aligned */
if (frame_header_iova % 16) {
padded_bytes = (uint32_t)(16 - (frame_header_iova % 16));
iova_addr += padded_bytes;
}
prepare_hw_data->frame_header_iova = frame_header_iova;
/* update the padding if any for the cpu addr as well */
prepare_hw_data->frame_header_cpu_addr = kmd_buf->cpu_addr +
(padded_bytes / 4);
CAM_DBG(CAM_ISP,
"Frame Header iova_addr: %pK cpu_addr: %pK padded_bytes: %llu",
prepare_hw_data->frame_header_iova,
prepare_hw_data->frame_header_cpu_addr,
padded_bytes);
/* Reserve memory for frame header */
kmd_buf->used_bytes += 128;
kmd_buf->offset += kmd_buf->used_bytes;
return rc;
}
static int cam_ife_mgr_prepare_hw_update(void *hw_mgr_priv,
void *prepare_hw_update_args)
{
@@ -5566,7 +5629,9 @@ static int cam_ife_mgr_prepare_hw_update(void *hw_mgr_priv,
struct cam_kmd_buf_info kmd_buf;
uint32_t i;
bool fill_fence = true;
bool frame_header_enable = false;
struct cam_isp_prepare_hw_update_data *prepare_hw_data;
struct cam_isp_frame_header_info frame_header_info;
if (!hw_mgr_priv || !prepare_hw_update_args) {
CAM_ERR(CAM_ISP, "Invalid args");
@@ -5593,6 +5658,15 @@ static int cam_ife_mgr_prepare_hw_update(void *hw_mgr_priv,
if (rc)
return rc;
if (ctx->use_frame_header_ts) {
rc = cam_ife_mgr_util_insert_frame_header(&kmd_buf,
prepare_hw_data);
if (rc)
return rc;
frame_header_enable = true;
}
rc = cam_packet_util_process_patches(prepare->packet,
hw_mgr->mgr_common.cmd_iommu_hdl,
hw_mgr->mgr_common.cmd_iommu_hdl_secure);
@@ -5641,13 +5715,23 @@ static int cam_ife_mgr_prepare_hw_update(void *hw_mgr_priv,
}
}
memset(&frame_header_info, 0,
sizeof(struct cam_isp_frame_header_info));
if (frame_header_enable) {
frame_header_info.frame_header_enable = true;
frame_header_info.frame_header_iova_addr =
prepare_hw_data->frame_header_iova;
}
/* get IO buffers */
rc = cam_isp_add_io_buffers(hw_mgr->mgr_common.img_iommu_hdl,
rc = cam_isp_add_io_buffers(
hw_mgr->mgr_common.img_iommu_hdl,
hw_mgr->mgr_common.img_iommu_hdl_secure,
prepare, ctx->base[i].idx,
&kmd_buf, ctx->res_list_ife_out,
&ctx->res_list_ife_in_rd,
CAM_IFE_HW_OUT_RES_MAX, fill_fence);
CAM_IFE_HW_OUT_RES_MAX, fill_fence,
&frame_header_info);
if (rc) {
CAM_ERR(CAM_ISP,
@@ -5659,6 +5743,18 @@ static int cam_ife_mgr_prepare_hw_update(void *hw_mgr_priv,
/* fence map table entries need to fill only once in the loop */
if (fill_fence)
fill_fence = false;
if (frame_header_info.frame_header_res_id &&
frame_header_enable) {
frame_header_enable = false;
prepare_hw_data->frame_header_res_id =
frame_header_info.frame_header_res_id;
CAM_DBG(CAM_ISP,
"Frame header enabled for res_id 0x%x cpu_addr %pK",
prepare_hw_data->frame_header_res_id,
prepare_hw_data->frame_header_cpu_addr);
}
}
/*
@@ -6643,10 +6739,15 @@ static int cam_ife_hw_mgr_handle_hw_sof(
rc = cam_ife_hw_mgr_check_irq_for_dual_vfe(ife_hw_mgr_ctx,
CAM_ISP_HW_EVENT_SOF);
if (!rc) {
cam_ife_mgr_cmd_get_sof_timestamp(ife_hw_mgr_ctx,
cam_ife_mgr_cmd_get_sof_timestamp(
ife_hw_mgr_ctx,
&sof_done_event_data.timestamp,
&sof_done_event_data.boot_time);
/* if frame header is enabled reset qtimer ts */
if (ife_hw_mgr_ctx->use_frame_header_ts)
sof_done_event_data.timestamp = 0x0;
if (atomic_read(&ife_hw_mgr_ctx->overflow_pending))
break;

View File

@@ -82,6 +82,8 @@ struct cam_ife_hw_mgr_debug {
* @init_done indicate whether init hw is done
* @is_fe_enable indicate whether fetch engine\read path is enabled
* @is_dual indicate whether context is in dual VFE mode
* @custom_enabled update the flag if context is connected to custom HW
* @use_frame_header_ts obtain qtimer ts using frame header
* @ts captured timestamp when the ctx is acquired
*/
struct cam_ife_hw_mgr_ctx {
@@ -129,6 +131,8 @@ struct cam_ife_hw_mgr_ctx {
bool init_done;
bool is_fe_enable;
bool is_dual;
bool custom_enabled;
bool use_frame_header_ts;
struct timespec64 ts;
};

View File

@@ -3809,6 +3809,7 @@ static int cam_tfe_mgr_prepare_hw_update(void *hw_mgr_priv,
uint32_t i;
bool fill_fence = true;
struct cam_isp_prepare_hw_update_data *prepare_hw_data;
struct cam_isp_frame_header_info frame_header_info;
if (!hw_mgr_priv || !prepare_hw_update_args) {
CAM_ERR(CAM_ISP, "Invalid args");
@@ -3886,13 +3887,18 @@ static int cam_tfe_mgr_prepare_hw_update(void *hw_mgr_priv,
}
}
memset(&frame_header_info, 0,
sizeof(struct cam_isp_frame_header_info));
frame_header_info.frame_header_enable = false;
/* get IO buffers */
rc = cam_isp_add_io_buffers(hw_mgr->mgr_common.img_iommu_hdl,
hw_mgr->mgr_common.img_iommu_hdl_secure,
prepare, ctx->base[i].idx,
&kmd_buf, ctx->res_list_tfe_out,
NULL,
CAM_TFE_HW_OUT_RES_MAX, fill_fence);
CAM_TFE_HW_OUT_RES_MAX, fill_fence,
&frame_header_info);
if (rc) {
CAM_ERR(CAM_ISP,

View File

@@ -463,7 +463,8 @@ int cam_isp_add_io_buffers(
struct cam_isp_hw_mgr_res *res_list_isp_out,
struct list_head *res_list_ife_in_rd,
uint32_t size_isp_out,
bool fill_fence)
bool fill_fence,
struct cam_isp_frame_header_info *frame_header_info)
{
int rc = 0;
dma_addr_t io_addr[CAM_PACKET_MAX_PLANES];
@@ -480,6 +481,7 @@ int cam_isp_add_io_buffers(
uint32_t i, j, num_out_buf, num_in_buf;
uint32_t res_id_out, res_id_in, plane_id;
uint32_t io_cfg_used_bytes, num_ent;
uint64_t iova_addr;
size_t size;
int32_t hdl;
int mmu_hdl;
@@ -693,6 +695,21 @@ int cam_isp_add_io_buffers(
wm_update.image_buf = io_addr;
wm_update.num_buf = plane_id;
wm_update.io_cfg = &io_cfg[i];
wm_update.frame_header = 0;
iova_addr = frame_header_info->frame_header_iova_addr;
if ((frame_header_info->frame_header_enable) &&
!(frame_header_info->frame_header_res_id)) {
wm_update.frame_header = iova_addr;
frame_header_info->frame_header_res_id =
res->res_id;
wm_update.local_id =
prepare->packet->header.request_id;
CAM_DBG(CAM_ISP,
"Frame header enabled for res: 0x%x iova: %pK",
frame_header_info->frame_header_res_id,
wm_update.frame_header);
}
update_buf.cmd.size = kmd_buf_remain_size;
update_buf.wm_update = &wm_update;

View File

@@ -34,6 +34,19 @@ struct cam_isp_generic_blob_info {
struct cam_kmd_buf_info *kmd_buf_info;
};
/*
* struct cam_isp_frame_header_info
*
* @frame_header_enable: Enable frame header
* @frame_header_iova_addr: frame header iova
* @frame_header_res_id: res id for which frame header is enabled
*/
struct cam_isp_frame_header_info {
bool frame_header_enable;
uint64_t frame_header_iova_addr;
uint32_t frame_header_res_id;
};
/*
* cam_isp_add_change_base()
*
@@ -127,7 +140,7 @@ int cam_isp_add_command_buffers(
* @res_list_ife_in_rd: IFE /VFE in rd resource list
* @size_isp_out: Size of the res_list_isp_out array
* @fill_fence: If true, Fence map table will be filled
*
* @frame_header_info: Frame header related params
* @return: 0 for success
* -EINVAL for Fail
*/
@@ -140,7 +153,8 @@ int cam_isp_add_io_buffers(
struct cam_isp_hw_mgr_res *res_list_isp_out,
struct list_head *res_list_ife_in_rd,
uint32_t size_isp_out,
bool fill_fence);
bool fill_fence,
struct cam_isp_frame_header_info *frame_header_info);
/*
* cam_isp_add_reg_update()

View File

@@ -121,6 +121,9 @@ struct cam_isp_bw_config_internal {
* @packet_opcode_type: Packet header opcode in the packet header
* this opcode defines, packet is init packet or
* update packet
* @frame_header_cpu_addr: Frame header cpu addr
* @frame_header_iova: Frame header iova
* @frame_header_res_id: Out port res_id corresponding to frame header
* @bw_config_version: BW config version indicator
* @bw_config: BW config information
* @bw_config_v2: BW config info for AXI bw voting v2
@@ -133,10 +136,13 @@ struct cam_isp_bw_config_internal {
struct cam_isp_prepare_hw_update_data {
void *isp_mgr_ctx;
uint32_t packet_opcode_type;
uint32_t *frame_header_cpu_addr;
uint64_t frame_header_iova;
uint32_t frame_header_res_id;
uint32_t bw_config_version;
struct cam_isp_bw_config_internal bw_config[CAM_IFE_HW_NUM_MAX];
struct cam_isp_bw_config_internal_v2 bw_config_v2[CAM_IFE_HW_NUM_MAX];
bool bw_config_valid[CAM_IFE_HW_NUM_MAX];
bool bw_config_valid[CAM_IFE_HW_NUM_MAX];
struct cam_cmd_buf_desc reg_dump_buf_desc[
CAM_REG_DUMP_MAX_BUF_ENTRIES];
uint32_t num_reg_dump_buf;

View File

@@ -1,6 +1,6 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/*
* Copyright (c) 2017-2019, The Linux Foundation. All rights reserved.
* Copyright (c) 2017-2020, The Linux Foundation. All rights reserved.
*/
#ifndef _CAM_CSID_HW_INTF_H_
@@ -187,9 +187,9 @@ struct cam_csid_reset_cfg_args {
/**
* struct cam_csid_get_time_stamp_args- time stamp capture arguments
* @res_node : resource to get the time stamp
* @time_stamp_val : captured time stamp
* @boot_timestamp : boot time stamp
* @node_res : resource to get the time stamp
* @time_stamp_val : captured time stamp
* @boot_timestamp : boot time stamp
*/
struct cam_csid_get_time_stamp_args {
struct cam_isp_resource_node *node_res;

View File

@@ -211,12 +211,16 @@ struct cam_isp_hw_cmd_buf_update {
*
* @ image_buf: image buffer address array
* @ num_buf: Number of buffers in the image_buf array
* @ frame_header: frame header iova
* @ local_id: local id for the wm
* @ io_cfg: IO buffer config information sent from UMD
*
*/
struct cam_isp_hw_get_wm_update {
dma_addr_t *image_buf;
uint32_t num_buf;
uint64_t frame_header;
uint32_t local_id;
struct cam_buf_io_cfg *io_cfg;
};

View File

@@ -3010,6 +3010,7 @@ static int cam_vfe_bus_ver3_update_wm(void *priv, void *cmd_args,
uint32_t i, j, k, size = 0;
uint32_t frame_inc = 0, val;
uint32_t loop_size = 0;
bool frame_header_enable = false;
bus_priv = (struct cam_vfe_bus_ver3_priv *) priv;
update_buf = (struct cam_isp_hw_get_cmd_update *) cmd_args;
@@ -3043,6 +3044,27 @@ static int cam_vfe_bus_ver3_update_wm(void *priv, void *cmd_args,
wm_data = vfe_out_data->wm_res[i]->res_priv;
ubwc_client = wm_data->hw_regs->ubwc_regs;
/* Disable frame header in case it was previously enabled */
if ((wm_data->en_cfg) & (1 << 2))
wm_data->en_cfg &= ~(1 << 2);
if (update_buf->wm_update->frame_header &&
!frame_header_enable) {
wm_data->en_cfg |= 1 << 2;
frame_header_enable = true;
CAM_VFE_ADD_REG_VAL_PAIR(reg_val_pair, j,
wm_data->hw_regs->frame_header_addr,
update_buf->wm_update->frame_header);
CAM_VFE_ADD_REG_VAL_PAIR(reg_val_pair, j,
wm_data->hw_regs->frame_header_cfg,
update_buf->wm_update->local_id);
CAM_DBG(CAM_ISP,
"WM: %d en_cfg 0x%x frame_header %pK local_id %u",
wm_data->index, wm_data->en_cfg,
update_buf->wm_update->frame_header,
update_buf->wm_update->local_id);
}
CAM_VFE_ADD_REG_VAL_PAIR(reg_val_pair, j,
wm_data->hw_regs->cfg, wm_data->en_cfg);
CAM_DBG(CAM_ISP, "WM:%d en_cfg 0x%X",