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:

committed by
Venkat Chinta

parent
e3f5738e43
commit
381bb12c68
@@ -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];
|
||||
|
@@ -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(
|
||||
@@ -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->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);
|
||||
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;
|
||||
|
@@ -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;
|
||||
};
|
||||
|
@@ -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;
|
||||
|
||||
|
@@ -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;
|
||||
};
|
||||
|
||||
|
@@ -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,
|
||||
|
@@ -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;
|
||||
|
||||
|
@@ -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()
|
||||
|
@@ -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,6 +136,9 @@ 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];
|
||||
|
@@ -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,7 +187,7 @@ 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
|
||||
* @node_res : resource to get the time stamp
|
||||
* @time_stamp_val : captured time stamp
|
||||
* @boot_timestamp : boot time stamp
|
||||
*/
|
||||
|
@@ -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;
|
||||
};
|
||||
|
||||
|
@@ -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",
|
||||
|
Reference in New Issue
Block a user