From 921bdca4b05bf169195b442561d1ee825e9698d9 Mon Sep 17 00:00:00 2001 From: Trishansh Bhardwaj Date: Fri, 13 Sep 2019 16:03:28 +0530 Subject: [PATCH] msm: camera: isp: Skip reapply of DMI config on bubble recovery Updating same DMI bank, which is consumed by HW, can result in violations so during bubble recvery skip updating DMI config. CRs-Fixed: 2511286 Change-Id: I1af2dbf2f1b49afcd4276d3f5759e5ba6d8da637 Signed-off-by: Trishansh Bhardwaj --- drivers/cam_core/cam_hw_mgr_intf.h | 2 ++ drivers/cam_isp/cam_isp_context.c | 7 +++++ drivers/cam_isp/cam_isp_context.h | 2 ++ drivers/cam_isp/isp_hw_mgr/cam_ife_hw_mgr.c | 24 ++++++++++++----- .../hw_utils/cam_isp_packet_parser.c | 27 ++++++++++++------- .../hw_utils/include/cam_isp_packet_parser.h | 10 ++++++- 6 files changed, 55 insertions(+), 17 deletions(-) diff --git a/drivers/cam_core/cam_hw_mgr_intf.h b/drivers/cam_core/cam_hw_mgr_intf.h index 462b30119b50..33c306b2e6dc 100644 --- a/drivers/cam_core/cam_hw_mgr_intf.h +++ b/drivers/cam_core/cam_hw_mgr_intf.h @@ -234,6 +234,7 @@ struct cam_hw_stream_setttings { * @num_out_map_entries: Number of out map entries * @priv: Private pointer * @request_id: Request ID + * @reapply True if reapplying after bubble * */ struct cam_hw_config_args { @@ -245,6 +246,7 @@ struct cam_hw_config_args { void *priv; uint64_t request_id; bool init_packet; + bool reapply; }; /** diff --git a/drivers/cam_isp/cam_isp_context.c b/drivers/cam_isp/cam_isp_context.c index 0df3b063ce63..0af4a5157343 100644 --- a/drivers/cam_isp/cam_isp_context.c +++ b/drivers/cam_isp/cam_isp_context.c @@ -633,6 +633,7 @@ static int __cam_isp_ctx_handle_buf_done_for_request( } list_del_init(&req->list); list_add_tail(&req->list, &ctx->free_req_list); + req_isp->reapply = false; CAM_DBG(CAM_REQ, "Move active request %lld to free list(cnt = %d) [all fences done], ctx %u", @@ -969,6 +970,7 @@ static int __cam_isp_ctx_epoch_in_applied(struct cam_isp_context *ctx_isp, list); req_isp = (struct cam_isp_ctx_req *)req->req_priv; req_isp->bubble_detected = true; + req_isp->reapply = true; CAM_DBG(CAM_ISP, "Report Bubble flag %d", req_isp->bubble_report); if (req_isp->bubble_report && ctx->ctx_crm_intf && @@ -1121,6 +1123,7 @@ static int __cam_isp_ctx_epoch_in_bubble_applied( list); req_isp = (struct cam_isp_ctx_req *)req->req_priv; req_isp->bubble_detected = true; + req_isp->reapply = true; if (req_isp->bubble_report && ctx->ctx_crm_intf && ctx->ctx_crm_intf->notify_err) { @@ -1891,6 +1894,7 @@ static int __cam_isp_ctx_apply_req_in_activated_state( cfg.num_hw_update_entries = req_isp->num_cfg; cfg.priv = &req_isp->hw_update_data; cfg.init_packet = 0; + cfg.reapply = req_isp->reapply; rc = ctx->hw_mgr_intf->hw_config(ctx->hw_mgr_intf->hw_mgr_priv, &cfg); if (rc) { @@ -2037,6 +2041,7 @@ static int __cam_isp_ctx_flush_req(struct cam_context *ctx, req_isp->fence_map_out[i].sync_id = -1; } } + req_isp->reapply = false; list_add_tail(&req->list, &ctx->free_req_list); } @@ -2336,6 +2341,7 @@ static int __cam_isp_ctx_rdi_only_sof_in_bubble_applied( list); req_isp = (struct cam_isp_ctx_req *)req->req_priv; req_isp->bubble_detected = true; + req_isp->reapply = true; CAM_DBG(CAM_ISP, "Report Bubble flag %d", req_isp->bubble_report); if (req_isp->bubble_report && ctx->ctx_crm_intf && @@ -3516,6 +3522,7 @@ static int __cam_isp_ctx_start_dev_in_ready(struct cam_context *ctx, start_isp.hw_config.num_hw_update_entries = req_isp->num_cfg; start_isp.hw_config.priv = &req_isp->hw_update_data; start_isp.hw_config.init_packet = 1; + start_isp.hw_config.reapply = 0; start_isp.start_only = false; atomic_set(&ctx_isp->process_bubble, 0); diff --git a/drivers/cam_isp/cam_isp_context.h b/drivers/cam_isp/cam_isp_context.h index 5aefa690697a..92db4433b429 100644 --- a/drivers/cam_isp/cam_isp_context.h +++ b/drivers/cam_isp/cam_isp_context.h @@ -108,6 +108,7 @@ struct cam_isp_ctx_irq_ops { * @bubble_report: Flag to track if bubble report is active on * current request * @hw_update_data: HW update data for this request + * @reapply: True if reapplying after bubble * */ struct cam_isp_ctx_req { @@ -124,6 +125,7 @@ struct cam_isp_ctx_req { int32_t bubble_report; struct cam_isp_prepare_hw_update_data hw_update_data; bool bubble_detected; + bool reapply; }; /** diff --git a/drivers/cam_isp/isp_hw_mgr/cam_ife_hw_mgr.c b/drivers/cam_isp/isp_hw_mgr/cam_ife_hw_mgr.c index 8e8da8753235..174b022fe004 100644 --- a/drivers/cam_isp/isp_hw_mgr/cam_ife_hw_mgr.c +++ b/drivers/cam_isp/isp_hw_mgr/cam_ife_hw_mgr.c @@ -3327,7 +3327,7 @@ static int cam_isp_blob_bw_update( static int cam_ife_mgr_config_hw(void *hw_mgr_priv, void *config_hw_args) { - int rc = -1, i; + int rc = -1, i, skip = 0; struct cam_hw_config_args *cfg; struct cam_hw_update_entry *cmd; struct cam_cdm_bl_request *cdm_cmd; @@ -3398,18 +3398,30 @@ static int cam_ife_mgr_config_hw(void *hw_mgr_priv, if (cfg->num_hw_update_entries > 0) { cdm_cmd = ctx->cdm_cmd; - cdm_cmd->cmd_arrary_count = cfg->num_hw_update_entries; cdm_cmd->type = CAM_CDM_BL_CMD_TYPE_MEM_HANDLE; cdm_cmd->flag = true; cdm_cmd->userdata = hw_update_data; cdm_cmd->cookie = cfg->request_id; - for (i = 0 ; i <= cfg->num_hw_update_entries; i++) { + for (i = 0 ; i < cfg->num_hw_update_entries; i++) { cmd = (cfg->hw_update_entries + i); - cdm_cmd->cmd[i].bl_addr.mem_handle = cmd->handle; - cdm_cmd->cmd[i].offset = cmd->offset; - cdm_cmd->cmd[i].len = cmd->len; + + if (cfg->reapply && + cmd->flags == CAM_ISP_IQ_BL) { + skip++; + continue; + } + + if (cmd->flags == CAM_ISP_UNUSED_BL || + cmd->flags >= CAM_ISP_BL_MAX) + CAM_ERR(CAM_ISP, "Unexpected BL type %d", + cmd->flags); + + cdm_cmd->cmd[i - skip].bl_addr.mem_handle = cmd->handle; + cdm_cmd->cmd[i - skip].offset = cmd->offset; + cdm_cmd->cmd[i - skip].len = cmd->len; } + cdm_cmd->cmd_arrary_count = cfg->num_hw_update_entries - skip; reinit_completion(&ctx->config_done_complete); ctx->applied_req_id = cfg->request_id; diff --git a/drivers/cam_isp/isp_hw_mgr/hw_utils/cam_isp_packet_parser.c b/drivers/cam_isp/isp_hw_mgr/hw_utils/cam_isp_packet_parser.c index b57500c16653..9c95b587df26 100644 --- a/drivers/cam_isp/isp_hw_mgr/hw_utils/cam_isp_packet_parser.c +++ b/drivers/cam_isp/isp_hw_mgr/hw_utils/cam_isp_packet_parser.c @@ -63,6 +63,9 @@ int cam_isp_add_change_base( hw_entry[num_ent].handle = kmd_buf_info->handle; hw_entry[num_ent].len = get_base.cmd.used_bytes; hw_entry[num_ent].offset = kmd_buf_info->offset; + + /* Marking change base as IOCFG to reapply on bubble */ + hw_entry[num_ent].flags = CAM_ISP_IOCFG_BL; CAM_DBG(CAM_ISP, "num_ent=%d handle=0x%x, len=%u, offset=%u", num_ent, @@ -303,10 +306,8 @@ int cam_isp_add_command_buffers( hw_entry[num_ent].handle, hw_entry[num_ent].len, hw_entry[num_ent].offset); - - if (cmd_meta_data == - CAM_ISP_PACKET_META_DMI_LEFT) - hw_entry[num_ent].flags = 0x1; + hw_entry[num_ent].flags = + CAM_ISP_IQ_BL; num_ent++; } @@ -324,10 +325,8 @@ int cam_isp_add_command_buffers( hw_entry[num_ent].handle, hw_entry[num_ent].len, hw_entry[num_ent].offset); - - if (cmd_meta_data == - CAM_ISP_PACKET_META_DMI_RIGHT) - hw_entry[num_ent].flags = 0x1; + hw_entry[num_ent].flags = + CAM_ISP_IQ_BL; num_ent++; } break; @@ -343,8 +342,7 @@ int cam_isp_add_command_buffers( hw_entry[num_ent].handle, hw_entry[num_ent].len, hw_entry[num_ent].offset); - if (cmd_meta_data == CAM_ISP_PACKET_META_DMI_COMMON) - hw_entry[num_ent].flags = 0x1; + hw_entry[num_ent].flags = CAM_ISP_IQ_BL; num_ent++; break; @@ -375,6 +373,7 @@ int cam_isp_add_command_buffers( rc); return rc; } + hw_entry[num_ent].flags = CAM_ISP_IQ_BL; num_ent = prepare->num_hw_update_entries; } break; @@ -397,6 +396,7 @@ int cam_isp_add_command_buffers( rc); return rc; } + hw_entry[num_ent].flags = CAM_ISP_IQ_BL; num_ent = prepare->num_hw_update_entries; } break; @@ -417,6 +417,7 @@ int cam_isp_add_command_buffers( "Failed in processing blobs %d", rc); return rc; } + hw_entry[num_ent].flags = CAM_ISP_IQ_BL; num_ent = prepare->num_hw_update_entries; } break; @@ -819,6 +820,8 @@ int cam_isp_add_io_buffers( prepare->hw_update_entries[num_ent].len = io_cfg_used_bytes; prepare->hw_update_entries[num_ent].offset = kmd_buf_info->offset; + prepare->hw_update_entries[num_ent].flags = + CAM_ISP_IOCFG_BL; CAM_DBG(CAM_ISP, "num_ent=%d handle=0x%x, len=%u, offset=%u", num_ent, @@ -919,6 +922,10 @@ int cam_isp_add_reg_update( prepare->hw_update_entries[num_ent].len = reg_update_size; prepare->hw_update_entries[num_ent].offset = kmd_buf_info->offset; + + /* Marking reg update as IOCFG to reapply on bubble */ + prepare->hw_update_entries[num_ent].flags = + CAM_ISP_IOCFG_BL; CAM_DBG(CAM_ISP, "num_ent=%d handle=0x%x, len=%u, offset=%u", num_ent, diff --git a/drivers/cam_isp/isp_hw_mgr/hw_utils/include/cam_isp_packet_parser.h b/drivers/cam_isp/isp_hw_mgr/hw_utils/include/cam_isp_packet_parser.h index 50161ea001f5..c9bd4c4430e9 100644 --- a/drivers/cam_isp/isp_hw_mgr/hw_utils/include/cam_isp_packet_parser.h +++ b/drivers/cam_isp/isp_hw_mgr/hw_utils/include/cam_isp_packet_parser.h @@ -1,6 +1,6 @@ /* SPDX-License-Identifier: GPL-2.0-only */ /* - * Copyright (c) 2017-2018, The Linux Foundation. All rights reserved. + * Copyright (c) 2017-2019, The Linux Foundation. All rights reserved. */ #ifndef _CAM_ISP_HW_PARSER_H_ @@ -13,6 +13,14 @@ #include "cam_hw_intf.h" #include "cam_packet_util.h" +/* enum cam_isp_cdm_bl_type - isp cdm packet type*/ +enum cam_isp_cdm_bl_type { + CAM_ISP_UNUSED_BL, + CAM_ISP_IQ_BL, + CAM_ISP_IOCFG_BL, + CAM_ISP_BL_MAX, +}; + /* * struct cam_isp_generic_blob_info *