Browse Source

msm: camera: icp: process one icp frame at a time in presil mode

Added check in presil mode to process icp frames one at a time to
avoid shared memmory buffers and hfi queue corruption.

CRs-Fixed: 3212166
Change-Id: I8eeba4cb34fedf0020c39c1fb3aa221dc26fbb71
Signed-off-by: Suraj Dongre <[email protected]>
Suraj Dongre 3 years ago
parent
commit
87759427d8

+ 45 - 0
drivers/cam_icp/icp_hw/icp_hw_mgr/cam_icp_hw_mgr.c

@@ -17,6 +17,7 @@
 #include <linux/bitops.h>
 #include <linux/delay.h>
 #include <linux/debugfs.h>
+#include <linux/rwsem.h>
 #include <media/cam_defs.h>
 #include <media/cam_icp.h>
 #include <media/cam_cpas.h>
@@ -54,6 +55,8 @@
 
 #define ICP_DEVICE_IDLE_TIMEOUT 400
 
+DECLARE_RWSEM(frame_in_process_sem);
+
 static struct cam_icp_hw_mgr icp_hw_mgr;
 
 static void cam_icp_mgr_process_dbg_buf(unsigned int debug_lvl);
@@ -2457,6 +2460,17 @@ static int cam_icp_mgr_handle_frame_process(uint32_t *msg_ptr, int flag)
 		mutex_unlock(&ctx_data->ctx_mutex);
 	}
 
+	if (cam_presil_mode_enabled()) {
+		if (!atomic_read(&icp_hw_mgr.frame_in_process)) {
+			CAM_ERR(CAM_PRESIL, "presil: frame_in_process not set");
+		} else {
+			icp_hw_mgr.frame_in_process_ctx_id = -1;
+			atomic_set(&icp_hw_mgr.frame_in_process, 0);
+			up_write(&frame_in_process_sem);
+			CAM_DBG(CAM_PRESIL, "presil: unlocked frame_in_process");
+		}
+	}
+
 	return 0;
 }
 
@@ -2654,6 +2668,23 @@ static int cam_icp_mgr_process_direct_ack_msg(uint32_t *msg_ptr)
 		ioconfig_ack = (struct hfi_msg_ipebps_async_ack *)msg_ptr;
 		ctx_data = (struct cam_icp_hw_ctx_data *)
 			U64_TO_PTR(ioconfig_ack->user_data1);
+
+		if (cam_presil_mode_enabled()) {
+			if (atomic_read(&icp_hw_mgr.frame_in_process)) {
+				if (icp_hw_mgr.frame_in_process_ctx_id == ctx_data->ctx_id) {
+					CAM_DBG(CAM_PRESIL, "presil: frame process abort ctx %d",
+						icp_hw_mgr.frame_in_process_ctx_id);
+					icp_hw_mgr.frame_in_process_ctx_id = -1;
+					atomic_set(&icp_hw_mgr.frame_in_process, 0);
+					up_write(&frame_in_process_sem);
+				} else {
+					CAM_WARN(CAM_PRESIL, "presil: abort mismatch %d %d",
+						icp_hw_mgr.frame_in_process_ctx_id,
+						ctx_data->ctx_id);
+				}
+			}
+		}
+
 		if (ctx_data->state != CAM_ICP_CTX_STATE_FREE)
 			complete(&ctx_data->wait_complete);
 		CAM_DBG(CAM_ICP, "received IPE/BPS/ ABORT: ctx_state =%d",
@@ -4728,6 +4759,17 @@ static int cam_icp_mgr_config_hw(void *hw_mgr_priv, void *config_hw_args)
 	}
 
 	ctx_data = config_args->ctxt_to_hw_map;
+	if (cam_presil_mode_enabled()) {
+		CAM_DBG(CAM_PRESIL, "presil: locking frame_in_process %d req id %u",
+			atomic_read(&hw_mgr->frame_in_process), config_args->request_id);
+		down_write(&frame_in_process_sem);
+		atomic_set(&hw_mgr->frame_in_process, 1);
+		hw_mgr->frame_in_process_ctx_id = ctx_data->ctx_id;
+		CAM_DBG(CAM_PRESIL, "presil: locked frame_in_process req id %u ctx_id %d",
+			config_args->request_id, hw_mgr->frame_in_process_ctx_id);
+		msleep(100);
+	}
+
 	mutex_lock(&hw_mgr->hw_mgr_mutex);
 	mutex_lock(&ctx_data->ctx_mutex);
 	if (ctx_data->state != CAM_ICP_CTX_STATE_ACQUIRED) {
@@ -6968,6 +7010,9 @@ int cam_icp_hw_mgr_init(struct device_node *of_node, uint64_t *hw_mgr_hdl,
 	mutex_init(&icp_hw_mgr.hw_mgr_mutex);
 	spin_lock_init(&icp_hw_mgr.hw_mgr_lock);
 
+	atomic_set(&icp_hw_mgr.frame_in_process, 0);
+	icp_hw_mgr.frame_in_process_ctx_id = -1;
+
 	for (i = 0; i < CAM_ICP_CTX_MAX; i++) {
 		mutex_init(&icp_hw_mgr.ctx_data[i].ctx_mutex);
 		if (cam_presil_mode_enabled()) {

+ 5 - 0
drivers/cam_icp/icp_hw/icp_hw_mgr/cam_icp_hw_mgr.h

@@ -9,6 +9,7 @@
 
 #include <linux/types.h>
 #include <linux/completion.h>
+#include <linux/semaphore.h>
 #include <media/cam_icp.h>
 #include "cam_icp_hw_intf.h"
 #include "cam_hw_mgr_intf.h"
@@ -409,6 +410,8 @@ struct cam_icp_clk_info {
  * @recovery: Flag to validate if in previous session FW
  *            reported a fatal error or wdt. If set FW is
  *            re-downloaded for new camera session.
+ * @frame_in_process: Counter for frames in process
+ * @frame_in_process_ctx_id: Contxt id processing frame
  */
 struct cam_icp_hw_mgr {
 	struct mutex hw_mgr_mutex;
@@ -460,6 +463,8 @@ struct cam_icp_hw_mgr {
 	bool disable_ubwc_comp;
 	atomic_t recovery;
 	uint64_t icp_svs_clk;
+	atomic_t frame_in_process;
+	int frame_in_process_ctx_id;
 };
 
 /**