Loading drivers/cam_core/cam_hw_mgr_intf.h +5 −1 Original line number Diff line number Diff line /* 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_ Loading Loading @@ -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, Loading @@ -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]; Loading drivers/cam_isp/cam_isp_context.c +79 −11 Original line number Diff line number Diff line Loading @@ -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)) { Loading Loading @@ -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); Loading Loading @@ -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, Loading @@ -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, Loading @@ -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; Loading @@ -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)) Loading @@ -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( Loading Loading @@ -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) { Loading Loading @@ -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); Loading Loading @@ -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; Loading Loading @@ -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; Loading Loading @@ -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; Loading drivers/cam_isp/cam_isp_context.h +8 −0 Original line number Diff line number Diff line Loading @@ -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 Loading Loading @@ -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 * Loading Loading @@ -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; }; Loading drivers/cam_isp/isp_hw_mgr/cam_ife_hw_mgr.c +104 −3 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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], Loading Loading @@ -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; Loading Loading @@ -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; Loading Loading @@ -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) { Loading @@ -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"); Loading @@ -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); Loading Loading @@ -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, Loading @@ -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); } } /* Loading Loading @@ -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; Loading drivers/cam_isp/isp_hw_mgr/cam_ife_hw_mgr.h +4 −0 Original line number Diff line number Diff line Loading @@ -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 { Loading Loading @@ -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; }; Loading Loading
drivers/cam_core/cam_hw_mgr_intf.h +5 −1 Original line number Diff line number Diff line /* 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_ Loading Loading @@ -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, Loading @@ -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]; Loading
drivers/cam_isp/cam_isp_context.c +79 −11 Original line number Diff line number Diff line Loading @@ -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)) { Loading Loading @@ -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); Loading Loading @@ -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, Loading @@ -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, Loading @@ -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; Loading @@ -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)) Loading @@ -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( Loading Loading @@ -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) { Loading Loading @@ -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); Loading Loading @@ -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; Loading Loading @@ -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; Loading Loading @@ -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; Loading
drivers/cam_isp/cam_isp_context.h +8 −0 Original line number Diff line number Diff line Loading @@ -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 Loading Loading @@ -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 * Loading Loading @@ -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; }; Loading
drivers/cam_isp/isp_hw_mgr/cam_ife_hw_mgr.c +104 −3 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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], Loading Loading @@ -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; Loading Loading @@ -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; Loading Loading @@ -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) { Loading @@ -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"); Loading @@ -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); Loading Loading @@ -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, Loading @@ -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); } } /* Loading Loading @@ -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; Loading
drivers/cam_isp/isp_hw_mgr/cam_ife_hw_mgr.h +4 −0 Original line number Diff line number Diff line Loading @@ -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 { Loading Loading @@ -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; }; Loading