Эх сурвалжийг харах

msm: camera: core: Send event on smmu page fault

Currently when page fault happen, iommu driver callers camera
handler with CB details and iova address which caused the page
fault. With iommu iova address cam smmu driver finds the
closest mapping address for that cb and call the
corresponding driver to find the which port caused page fault.
This has limitation has page fault address always not mapped.
New approach is get the page fault ids from iommu driver.
Based on the Pid and Mid values, get the HW id and port ids,
go through all context which has this hw id and port id and log
the data. Once context id is identified, log the acquire data and
last consumed client address details. Dump the hw register data
in the given buffer. Send the smmu page fault event through
v4l2 queue to user.

CRs-Fixed: 2750690
Change-Id: I87c809b3229992c7c95655a4f3c6c70ebc035ae8
Signed-off-by: Ravikishore Pampana <[email protected]>
Ravikishore Pampana 5 жил өмнө
parent
commit
b746c4f527
35 өөрчлөгдсөн 728 нэмэгдсэн , 162 устгасан
  1. 5 7
      drivers/cam_cdm/cam_cdm_hw_core.c
  2. 3 3
      drivers/cam_core/cam_context.c
  3. 4 4
      drivers/cam_core/cam_context.h
  4. 9 4
      drivers/cam_core/cam_context_utils.c
  5. 4 2
      drivers/cam_core/cam_context_utils.h
  6. 14 2
      drivers/cam_core/cam_hw_mgr_intf.h
  7. 3 0
      drivers/cam_cpas/cam_cpas_hw.c
  8. 4 6
      drivers/cam_cust/cam_custom_dev.c
  9. 5 4
      drivers/cam_icp/cam_icp_context.c
  10. 5 8
      drivers/cam_icp/cam_icp_subdev.c
  11. 60 18
      drivers/cam_isp/cam_isp_context.c
  12. 4 7
      drivers/cam_isp/cam_isp_dev.c
  13. 225 43
      drivers/cam_isp/isp_hw_mgr/cam_ife_hw_mgr.c
  14. 6 1
      drivers/cam_isp/isp_hw_mgr/cam_ife_hw_mgr.h
  15. 52 0
      drivers/cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/cam_ife_csid_core.c
  16. 1 0
      drivers/cam_isp/isp_hw_mgr/isp_hw/include/cam_ife_csid_hw_intf.h
  17. 32 0
      drivers/cam_isp/isp_hw_mgr/isp_hw/include/cam_isp_hw.h
  18. 2 1
      drivers/cam_isp/isp_hw_mgr/isp_hw/include/cam_vfe_hw_intf.h
  19. 1 0
      drivers/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/cam_vfe_core.c
  20. 17 8
      drivers/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/cam_vfe_dev.c
  21. 19 3
      drivers/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/cam_vfe_soc.c
  22. 4 0
      drivers/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/cam_vfe_soc.h
  23. 34 0
      drivers/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe17x/cam_vfe480.h
  24. 4 0
      drivers/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe17x/cam_vfe_lite48x.h
  25. 53 1
      drivers/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe_bus/cam_vfe_bus_ver2.c
  26. 2 0
      drivers/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe_bus/cam_vfe_bus_ver2.h
  27. 74 1
      drivers/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe_bus/cam_vfe_bus_ver3.c
  28. 2 0
      drivers/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe_bus/cam_vfe_bus_ver3.h
  29. 5 4
      drivers/cam_jpeg/cam_jpeg_context.c
  30. 5 7
      drivers/cam_jpeg/cam_jpeg_dev.c
  31. 5 4
      drivers/cam_ope/cam_ope_context.c
  32. 5 7
      drivers/cam_ope/cam_ope_subdev.c
  33. 33 10
      drivers/cam_smmu/cam_smmu_api.c
  34. 25 6
      drivers/cam_smmu/cam_smmu_api.h
  35. 2 1
      include/uapi/camera/media/cam_req_mgr.h

+ 5 - 7
drivers/cam_cdm/cam_cdm_hw_core.c

@@ -1224,16 +1224,14 @@ static void cam_hw_cdm_work(struct work_struct *work)
 
 }
 
-static void cam_hw_cdm_iommu_fault_handler(struct iommu_domain *domain,
-	struct device *dev, unsigned long iova, int flags, void *token,
-	uint32_t buf_info)
+static void cam_hw_cdm_iommu_fault_handler(struct cam_smmu_pf_info *pf_info)
 {
 	struct cam_hw_info *cdm_hw = NULL;
 	struct cam_cdm *core = NULL;
 	int i;
 
-	if (token) {
-		cdm_hw = (struct cam_hw_info *)token;
+	if (pf_info->token) {
+		cdm_hw = (struct cam_hw_info *)pf_info->token;
 		core = (struct cam_cdm *)cdm_hw->core_info;
 		set_bit(CAM_CDM_ERROR_HW_STATUS, &core->cdm_status);
 		mutex_lock(&cdm_hw->hw_mutex);
@@ -1254,9 +1252,9 @@ static void cam_hw_cdm_iommu_fault_handler(struct iommu_domain *domain,
 			mutex_unlock(&core->bl_fifo[i].fifo_lock);
 		mutex_unlock(&cdm_hw->hw_mutex);
 		CAM_ERR_RATE_LIMIT(CAM_CDM, "Page fault iova addr %pK\n",
-			(void *)iova);
+			(void *)pf_info->iova);
 		cam_cdm_notify_clients(cdm_hw, CAM_CDM_CB_STATUS_PAGEFAULT,
-			(void *)iova);
+			(void *)pf_info->iova);
 		clear_bit(CAM_CDM_ERROR_HW_STATUS, &core->cdm_status);
 	} else {
 		CAM_ERR(CAM_CDM, "Invalid token");

+ 3 - 3
drivers/cam_core/cam_context.c

@@ -287,8 +287,8 @@ int cam_context_handle_crm_dump_req(struct cam_context *ctx,
 	return rc;
 }
 
-int cam_context_dump_pf_info(struct cam_context *ctx, unsigned long iova,
-	uint32_t buf_info)
+int cam_context_dump_pf_info(struct cam_context *ctx,
+	struct cam_smmu_pf_info *pf_info)
 {
 	int rc = 0;
 
@@ -301,7 +301,7 @@ int cam_context_dump_pf_info(struct cam_context *ctx, unsigned long iova,
 		(ctx->state < CAM_CTX_STATE_MAX)) {
 		if (ctx->state_machine[ctx->state].pagefault_ops) {
 			rc = ctx->state_machine[ctx->state].pagefault_ops(
-				ctx, iova, buf_info);
+				ctx, pf_info);
 		} else {
 			CAM_WARN(CAM_CORE, "No dump ctx in dev %d, state %d",
 				ctx->dev_hdl, ctx->state);

+ 4 - 4
drivers/cam_core/cam_context.h

@@ -11,6 +11,7 @@
 #include <linux/kref.h>
 #include "cam_req_mgr_interface.h"
 #include "cam_hw_mgr_intf.h"
+#include "cam_smmu_api.h"
 
 /* Forward declarations */
 struct cam_context;
@@ -360,12 +361,11 @@ int cam_context_handle_crm_dump_req(struct cam_context *ctx,
  * @brief:        Handle dump active request request command
  *
  * @ctx:          Object pointer for cam_context
- * @iova:         Page fault address
- * @buf_info:     Information about closest memory handle
+ * @pf_info:      Smmu page fault info
  *
  */
-int cam_context_dump_pf_info(struct cam_context *ctx, unsigned long iova,
-	uint32_t buf_info);
+int cam_context_dump_pf_info(struct cam_context *ctx,
+	struct cam_smmu_pf_info *pf_info);
 
 /**
  * cam_context_handle_acquire_dev()

+ 9 - 4
drivers/cam_core/cam_context_utils.c

@@ -994,8 +994,8 @@ end:
 }
 
 int32_t cam_context_dump_pf_info_to_hw(struct cam_context *ctx,
-	struct cam_packet *packet, unsigned long iova, uint32_t buf_info,
-	bool *mem_found)
+	struct cam_packet *packet, bool *mem_found, bool *ctx_found,
+	uint32_t  *resource_type, struct cam_smmu_pf_info *pf_info)
 {
 	int rc = 0;
 	struct cam_hw_cmd_args cmd_args;
@@ -1017,9 +1017,14 @@ int32_t cam_context_dump_pf_info_to_hw(struct cam_context *ctx,
 		cmd_args.ctxt_to_hw_map = ctx->ctxt_to_hw_map;
 		cmd_args.cmd_type = CAM_HW_MGR_CMD_DUMP_PF_INFO;
 		cmd_args.u.pf_args.pf_data.packet = packet;
-		cmd_args.u.pf_args.iova = iova;
-		cmd_args.u.pf_args.buf_info = buf_info;
+		cmd_args.u.pf_args.iova = pf_info->iova;
+		cmd_args.u.pf_args.buf_info = pf_info->buf_info;
 		cmd_args.u.pf_args.mem_found = mem_found;
+		cmd_args.u.pf_args.ctx_found = ctx_found;
+		cmd_args.u.pf_args.resource_type = resource_type;
+		cmd_args.u.pf_args.bid = pf_info->bid;
+		cmd_args.u.pf_args.pid = pf_info->pid;
+		cmd_args.u.pf_args.mid = pf_info->mid;
 		ctx->hw_mgr_intf->hw_cmd(ctx->hw_mgr_intf->hw_mgr_priv,
 			&cmd_args);
 	}

+ 4 - 2
drivers/cam_core/cam_context_utils.h

@@ -7,6 +7,7 @@
 #define _CAM_CONTEXT_UTILS_H_
 
 #include <linux/types.h>
+#include "cam_smmu_api.h"
 
 int cam_context_buf_done_from_hw(struct cam_context *ctx,
 	void *done_event_data, uint32_t evt_id);
@@ -27,8 +28,9 @@ int32_t cam_context_flush_ctx_to_hw(struct cam_context *ctx);
 int32_t cam_context_flush_req_to_hw(struct cam_context *ctx,
 	struct cam_flush_dev_cmd *cmd);
 int32_t cam_context_dump_pf_info_to_hw(struct cam_context *ctx,
-	struct cam_packet *packet, unsigned long iova, uint32_t buf_info,
-	bool *mem_found);
+	struct cam_packet *packet, bool *mem_found, bool *ctx_found,
+	uint32_t  *resource_type,
+	struct cam_smmu_pf_info *pf_info);
 int32_t cam_context_dump_hw_acq_info(struct cam_context *ctx);
 int32_t cam_context_dump_dev_to_hw(struct cam_context *ctx,
 	struct cam_dump_req_cmd *cmd);

+ 14 - 2
drivers/cam_core/cam_hw_mgr_intf.h

@@ -9,6 +9,8 @@
 #include <linux/time.h>
 #include <linux/types.h>
 #include <media/cam_defs.h>
+#include "cam_smmu_api.h"
+
 /*
  * This file declares Constants, Enums, Structures and APIs to be used as
  * Interface between HW Manager and Context.
@@ -44,8 +46,8 @@ typedef int (*cam_hw_event_cb_func)(void *context, uint32_t evt_id,
 	void *evt_data);
 
 /* hardware page fault callback function type */
-typedef int (*cam_hw_pagefault_cb_func)(void *context, unsigned long iova,
-	uint32_t buf_info);
+typedef int (*cam_hw_pagefault_cb_func)(void *context,
+	struct cam_smmu_pf_info *pf_info);
 
 /* ctx dump callback function type */
 typedef int (*cam_ctx_info_dump_cb_func)(void *context,
@@ -293,6 +295,11 @@ struct cam_hw_flush_args {
  *                               fault occurred
  * @mem_found:             If fault memory found in current
  *                               request
+ * @ctx_found              If fault pid found in context acquired hardware
+ * @resource_type          Resource type of the port which caused pf
+ * @bid:                   Indicate the bus id
+ * @pid:                   Indicates unique hw group ports
+ * @mid:                   Indicates port id of the camera hw
  *
  */
 struct cam_hw_dump_pf_args {
@@ -300,6 +307,11 @@ struct cam_hw_dump_pf_args {
 	unsigned long                   iova;
 	uint32_t                        buf_info;
 	bool                           *mem_found;
+	bool                           *ctx_found;
+	uint32_t                       *resource_type;
+	uint32_t                        bid;
+	uint32_t                        pid;
+	uint32_t                        mid;
 };
 
 /**

+ 3 - 0
drivers/cam_cpas/cam_cpas_hw.c

@@ -14,6 +14,7 @@
 #include "cam_cpas_hw_intf.h"
 #include "cam_cpas_soc.h"
 #include "cam_req_mgr_dev.h"
+#include "cam_smmu_api.h"
 
 static uint cam_min_camnoc_ib_bw;
 module_param(cam_min_camnoc_ib_bw, uint, 0644);
@@ -1431,6 +1432,8 @@ static int cam_cpas_hw_start(void *hw_priv, void *start_args,
 		}
 		CAM_DBG(CAM_CPAS, "irq_count=%d\n",
 			atomic_read(&cpas_core->irq_count));
+
+		cam_smmu_reset_cb_page_fault_cnt();
 		cpas_hw->hw_state = CAM_HW_STATE_POWER_UP;
 	}
 

+ 4 - 6
drivers/cam_cust/cam_custom_dev.c

@@ -25,22 +25,20 @@
 static struct cam_custom_dev g_custom_dev;
 
 static void cam_custom_dev_iommu_fault_handler(
-	struct iommu_domain *domain, struct device *dev, unsigned long iova,
-	int flags, void *token, uint32_t buf_info)
+	struct cam_smmu_pf_info *pf_info)
 {
 	int i = 0;
 	struct cam_node *node = NULL;
 
-	if (!token) {
+	if (!pf_info || !pf_info->token) {
 		CAM_ERR(CAM_CUSTOM, "invalid token in page handler cb");
 		return;
 	}
 
-	node = (struct cam_node *)token;
+	node = (struct cam_node *)pf_info->token;
 
 	for (i = 0; i < node->ctx_size; i++)
-		cam_context_dump_pf_info(&(node->ctx_list[i]), iova,
-			buf_info);
+		cam_context_dump_pf_info(&(node->ctx_list[i]), pf_info);
 }
 
 static const struct of_device_id cam_custom_dt_match[] = {

+ 5 - 4
drivers/cam_icp/cam_icp_context.c

@@ -22,15 +22,16 @@
 
 static const char icp_dev_name[] = "cam-icp";
 
-static int cam_icp_context_dump_active_request(void *data, unsigned long iova,
-	uint32_t buf_info)
+static int cam_icp_context_dump_active_request(void *data,
+	struct cam_smmu_pf_info *pf_info)
 {
 	struct cam_context *ctx = (struct cam_context *)data;
 	struct cam_ctx_request          *req = NULL;
 	struct cam_ctx_request          *req_temp = NULL;
 	struct cam_hw_mgr_dump_pf_data  *pf_dbg_entry = NULL;
+	uint32_t  resource_type = 0;
 	int rc = 0;
-	bool b_mem_found = false;
+	bool b_mem_found = false, b_ctx_found = false;
 
 	if (!ctx) {
 		CAM_ERR(CAM_ICP, "Invalid ctx");
@@ -52,7 +53,7 @@ static int cam_icp_context_dump_active_request(void *data, unsigned long iova,
 		CAM_INFO(CAM_ICP, "req_id : %lld", req->request_id);
 
 		rc = cam_context_dump_pf_info_to_hw(ctx, pf_dbg_entry->packet,
-			iova, buf_info, &b_mem_found);
+			&b_mem_found, &b_ctx_found, &resource_type, pf_info);
 		if (rc)
 			CAM_ERR(CAM_ICP, "Failed to dump pf info");
 

+ 5 - 8
drivers/cam_icp/cam_icp_subdev.c

@@ -50,23 +50,20 @@ static const struct of_device_id cam_icp_dt_match[] = {
 	{}
 };
 
-static void cam_icp_dev_iommu_fault_handler(
-	struct iommu_domain *domain, struct device *dev, unsigned long iova,
-	int flags, void *token, uint32_t buf_info)
+static void cam_icp_dev_iommu_fault_handler(struct cam_smmu_pf_info *pf_info)
 {
 	int i = 0;
 	struct cam_node *node = NULL;
 
-	if (!token) {
-		CAM_ERR(CAM_ICP, "invalid token in page handler cb");
+	if (!pf_info || !pf_info->token) {
+		CAM_ERR(CAM_ISP, "invalid token in page handler cb");
 		return;
 	}
 
-	node = (struct cam_node *)token;
+	node = (struct cam_node *)pf_info->token;
 
 	for (i = 0; i < node->ctx_size; i++)
-		cam_context_dump_pf_info(&(node->ctx_list[i]), iova,
-			buf_info);
+		cam_context_dump_pf_info(&(node->ctx_list[i]), pf_info);
 }
 
 static int cam_icp_subdev_open(struct v4l2_subdev *sd,

+ 60 - 18
drivers/cam_isp/cam_isp_context.c

@@ -28,8 +28,8 @@ static struct cam_isp_ctx_debug isp_ctx_debug;
 	div_u64_rem(atomic64_add_return(1, head),\
 	max_entries, (ret))
 
-static int cam_isp_context_dump_requests(void *data, unsigned long iova,
-	uint32_t buf_info);
+static int cam_isp_context_dump_requests(void *data,
+	struct cam_smmu_pf_info *pf_info);
 
 static int __cam_isp_ctx_start_dev_in_ready(struct cam_context *ctx,
 	struct cam_start_stop_dev_cmd *cmd);
@@ -5390,9 +5390,8 @@ static struct cam_ctx_ops
 	},
 };
 
-
-static int cam_isp_context_dump_requests(void *data, unsigned long iova,
-	uint32_t buf_info)
+static int cam_isp_context_dump_requests(void *data,
+	struct cam_smmu_pf_info *pf_info)
 {
 
 	struct cam_context *ctx = (struct cam_context *)data;
@@ -5401,7 +5400,10 @@ static int cam_isp_context_dump_requests(void *data, unsigned long iova,
 	struct cam_isp_ctx_req *req_isp  = NULL;
 	struct cam_isp_prepare_hw_update_data *hw_update_data = NULL;
 	struct cam_hw_mgr_dump_pf_data *pf_dbg_entry = NULL;
-	bool mem_found = false;
+	struct cam_req_mgr_message       req_msg;
+	struct cam_isp_context          *ctx_isp;
+	uint32_t  resource_type = 0;
+	bool mem_found = false, ctx_found = false, send_error = false;
 	int rc = 0;
 
 	struct cam_isp_context *isp_ctx =
@@ -5424,13 +5426,12 @@ static int cam_isp_context_dump_requests(void *data, unsigned long iova,
 			req->request_id);
 
 		rc = cam_context_dump_pf_info_to_hw(ctx, pf_dbg_entry->packet,
-			iova, buf_info, &mem_found);
+			&mem_found, &ctx_found, &resource_type, pf_info);
 		if (rc)
 			CAM_ERR(CAM_ISP, "Failed to dump pf info");
 
-		if (mem_found)
-			CAM_ERR(CAM_ISP, "Found page fault in req %lld %d",
-				req->request_id, rc);
+		if (ctx_found)
+			send_error = true;
 	}
 
 	CAM_INFO(CAM_ISP, "Iterating over wait_list of isp ctx %d state %d",
@@ -5444,13 +5445,12 @@ static int cam_isp_context_dump_requests(void *data, unsigned long iova,
 		CAM_INFO(CAM_ISP, "Wait List: req_id : %lld ", req->request_id);
 
 		rc = cam_context_dump_pf_info_to_hw(ctx, pf_dbg_entry->packet,
-			iova, buf_info, &mem_found);
+			&mem_found, &ctx_found, &resource_type, pf_info);
 		if (rc)
 			CAM_ERR(CAM_ISP, "Failed to dump pf info");
 
-		if (mem_found)
-			CAM_ERR(CAM_ISP, "Found page fault in req %lld %d",
-				req->request_id, rc);
+		if (ctx_found)
+			send_error = true;
 	}
 
 	/*
@@ -5475,15 +5475,57 @@ static int cam_isp_context_dump_requests(void *data, unsigned long iova,
 			req->request_id);
 
 		rc = cam_context_dump_pf_info_to_hw(ctx, pf_dbg_entry->packet,
-			iova, buf_info, &mem_found);
+			&mem_found, &ctx_found, &resource_type, pf_info);
 		if (rc)
 			CAM_ERR(CAM_ISP, "Failed to dump pf info");
 
-		if (mem_found)
-			CAM_ERR(CAM_ISP, "Found page fault in req %lld %d",
-				req->request_id, rc);
+		if (ctx_found)
+			send_error = true;
 	}
 
+	if (resource_type) {
+		ctx_isp = (struct cam_isp_context *) ctx->ctx_priv;
+		if (ctx_isp->isp_device_type == CAM_IFE_DEVICE_TYPE)
+			CAM_ERR(CAM_ISP,
+				"Page fault on resource id:%s (0x%x) ctx id:%d frame id:%d reported id:%lld applied id:%lld",
+				__cam_isp_resource_handle_id_to_type(
+				resource_type),
+				resource_type, ctx->ctx_id, ctx_isp->frame_id,
+				ctx_isp->reported_req_id,
+				ctx_isp->last_applied_req_id);
+		else
+			CAM_ERR(CAM_ISP,
+				"Page fault on resource id:%s (0x%x) ctx id:%d frame id:%d reported id:%lld applied id:%lld",
+				__cam_isp_tfe_resource_handle_id_to_type(
+				resource_type),
+				resource_type, ctx->ctx_id, ctx_isp->frame_id,
+				ctx_isp->reported_req_id,
+				ctx_isp->last_applied_req_id);
+
+	}
+
+	if (send_error) {
+		CAM_INFO(CAM_ISP,
+			"page fault notifying to umd ctx %u session_hdl:%d device_hdl:%d link_hdl:%d",
+			ctx->ctx_id, ctx->session_hdl,
+			ctx->dev_hdl, ctx->link_hdl);
+
+		req_msg.session_hdl = ctx->session_hdl;
+		req_msg.u.err_msg.device_hdl = ctx->dev_hdl;
+		req_msg.u.err_msg.error_type =
+			CAM_REQ_MGR_ERROR_TYPE_PAGE_FAULT;
+		req_msg.u.err_msg.link_hdl = ctx->link_hdl;
+		req_msg.u.err_msg.request_id = 0;
+		req_msg.u.err_msg.resource_size = 0x0;
+
+		if (cam_req_mgr_notify_message(&req_msg,
+				V4L_EVENT_CAM_REQ_MGR_ERROR,
+				V4L_EVENT_CAM_REQ_MGR_EVENT))
+			CAM_ERR(CAM_ISP,
+				"could not send page fault notification ctx %u session_hdl:%d device_hdl:%d link_hdl:%d",
+				ctx->ctx_id, ctx->session_hdl,
+				ctx->dev_hdl, ctx->link_hdl);
+	}
 	return rc;
 }
 

+ 4 - 7
drivers/cam_isp/cam_isp_dev.c

@@ -22,23 +22,20 @@
 
 static struct cam_isp_dev g_isp_dev;
 
-static void cam_isp_dev_iommu_fault_handler(
-	struct iommu_domain *domain, struct device *dev, unsigned long iova,
-	int flags, void *token, uint32_t buf_info)
+static void cam_isp_dev_iommu_fault_handler(struct cam_smmu_pf_info *pf_info)
 {
 	int i = 0;
 	struct cam_node *node = NULL;
 
-	if (!token) {
+	if (!pf_info || !pf_info->token) {
 		CAM_ERR(CAM_ISP, "invalid token in page handler cb");
 		return;
 	}
 
-	node = (struct cam_node *)token;
+	node = (struct cam_node *)pf_info->token;
 
 	for (i = 0; i < node->ctx_size; i++)
-		cam_context_dump_pf_info(&(node->ctx_list[i]), iova,
-			buf_info);
+		cam_context_dump_pf_info(&(node->ctx_list[i]), pf_info);
 }
 
 static const struct of_device_id cam_isp_dt_match[] = {

+ 225 - 43
drivers/cam_isp/isp_hw_mgr/cam_ife_hw_mgr.c

@@ -1527,7 +1527,7 @@ static int cam_ife_hw_mgr_acquire_res_ife_src(
 				continue;
 
 			hw_intf = ife_hw_mgr->ife_devices[
-				csid_res->hw_res[i]->hw_intf->hw_idx];
+				csid_res->hw_res[i]->hw_intf->hw_idx]->hw_intf;
 
 			if (i == CAM_ISP_HW_SPLIT_LEFT &&
 				ife_src_res->is_dual_isp) {
@@ -2348,7 +2348,7 @@ static int cam_ife_hw_mgr_acquire_res_ife_bus_rd(
 		if (!ife_hw_mgr->ife_devices[j])
 			continue;
 
-		hw_intf = ife_hw_mgr->ife_devices[j];
+		hw_intf = ife_hw_mgr->ife_devices[j]->hw_intf;
 		rc = hw_intf->hw_ops.reserve(hw_intf->hw_priv,
 			&vfe_acquire, sizeof(struct cam_vfe_acquire_args));
 
@@ -2379,7 +2379,7 @@ static int cam_ife_hw_mgr_acquire_res_ife_bus_rd(
 			if (j == ife_bus_rd_res->hw_res[i]->hw_intf->hw_idx)
 				continue;
 
-			hw_intf = ife_hw_mgr->ife_devices[j];
+			hw_intf = ife_hw_mgr->ife_devices[j]->hw_intf;
 			rc = hw_intf->hw_ops.reserve(hw_intf->hw_priv,
 				&vfe_acquire,
 				sizeof(struct cam_vfe_acquire_args));
@@ -2463,7 +2463,7 @@ static int cam_ife_hw_mgr_acquire_offline_res_ife_camif(
 		vfe_acquire.vfe_in.sync_mode = CAM_ISP_HW_SYNC_NONE;
 
 	hw_intf = ife_hw_mgr->ife_devices[
-		ife_bus_rd_res->hw_res[i]->hw_intf->hw_idx];
+		ife_bus_rd_res->hw_res[i]->hw_intf->hw_idx]->hw_intf;
 
 	rc = hw_intf->hw_ops.reserve(hw_intf->hw_priv, &vfe_acquire,
 		sizeof(struct cam_vfe_acquire_args));
@@ -2493,7 +2493,7 @@ static int cam_ife_hw_mgr_acquire_offline_res_ife_camif(
 		vfe_acquire.vfe_in.sync_mode = CAM_ISP_HW_SYNC_SLAVE;
 
 		hw_intf = ife_hw_mgr->ife_devices[
-			ife_bus_rd_res->hw_res[++i]->hw_intf->hw_idx];
+			ife_bus_rd_res->hw_res[++i]->hw_intf->hw_idx]->hw_intf;
 
 		rc = hw_intf->hw_ops.reserve(hw_intf->hw_priv, &vfe_acquire,
 			sizeof(struct cam_vfe_acquire_args));
@@ -4163,10 +4163,10 @@ static int cam_ife_mgr_reset_vfe_hw(struct cam_ife_hw_mgr *hw_mgr,
 		if (!hw_mgr->ife_devices[i])
 			continue;
 
-		if (hw_idx != hw_mgr->ife_devices[i]->hw_idx)
+		if (hw_idx != hw_mgr->ife_devices[i]->hw_intf->hw_idx)
 			continue;
 		CAM_DBG(CAM_ISP, "VFE (id = %d) reset", hw_idx);
-		vfe_hw_intf = hw_mgr->ife_devices[i];
+		vfe_hw_intf = hw_mgr->ife_devices[i]->hw_intf;
 		vfe_hw_intf->hw_ops.reset(vfe_hw_intf->hw_priv,
 			&vfe_reset_type, sizeof(vfe_reset_type));
 		break;
@@ -4188,12 +4188,15 @@ static int cam_ife_mgr_unmask_bus_wr_irq(struct cam_ife_hw_mgr *hw_mgr,
 	}
 
 	for (i = 0; i < CAM_VFE_HW_NUM_MAX; i++) {
-		if (hw_idx != hw_mgr->ife_devices[i]->hw_idx)
+		if (!hw_mgr->ife_devices[i])
+			continue;
+
+		if (hw_idx != hw_mgr->ife_devices[i]->hw_intf->hw_idx)
 			continue;
 
 		CAM_DBG(CAM_ISP, "Unmask VFE:%d BUS_WR IRQ", hw_idx);
 
-		vfe_hw_intf = hw_mgr->ife_devices[i];
+		vfe_hw_intf = hw_mgr->ife_devices[i]->hw_intf;
 
 		vfe_hw_intf->hw_ops.process_cmd(vfe_hw_intf->hw_priv,
 			CAM_ISP_HW_CMD_UNMASK_BUS_WR_IRQ,
@@ -4632,6 +4635,7 @@ static int cam_ife_mgr_release_hw(void *hw_mgr_priv,
 	ctx->dsp_enabled = false;
 	ctx->is_fe_enabled = false;
 	ctx->is_offline = false;
+	ctx->pf_mid_found = false;
 	atomic_set(&ctx->overflow_pending, 0);
 	for (i = 0; i < CAM_IFE_HW_NUM_MAX; i++) {
 		ctx->sof_cnt[i] = 0;
@@ -6421,42 +6425,43 @@ static int cam_ife_mgr_sof_irq_debug(
 	return rc;
 }
 
-static void cam_ife_mgr_print_io_bufs(struct cam_packet *packet,
-	int32_t iommu_hdl, int32_t sec_mmu_hdl, uint32_t pf_buf_info,
-	bool *mem_found)
+static void cam_ife_mgr_print_io_bufs(struct cam_ife_hw_mgr  *hw_mgr,
+		uint32_t res_id, struct cam_packet *packet,
+		bool    *ctx_found, struct cam_ife_hw_mgr_ctx *ctx)
 {
-	dma_addr_t   iova_addr;
-	size_t     src_buf_size;
-	int        i;
-	int        j;
-	int        rc = 0;
-	int32_t    mmu_hdl;
 
 	struct cam_buf_io_cfg  *io_cfg = NULL;
+	int32_t      mmu_hdl, iommu_hdl, sec_mmu_hdl;
+	dma_addr_t   iova_addr;
+	size_t        src_buf_size;
+	int  i, j, rc = 0;
 
-	if (mem_found)
-		*mem_found = false;
+	iommu_hdl = hw_mgr->mgr_common.img_iommu_hdl;
+	sec_mmu_hdl = hw_mgr->mgr_common.img_iommu_hdl_secure;
 
 	io_cfg = (struct cam_buf_io_cfg *)((uint32_t *)&packet->payload +
 		packet->io_configs_offset / 4);
 
 	for (i = 0; i < packet->num_io_configs; i++) {
+		if (io_cfg[i].resource_type != res_id)
+			continue;
+		else
+			break;
+		}
+
+		if (i == packet->num_io_configs) {
+			*ctx_found = false;
+			CAM_ERR(CAM_ISP,
+				"getting io port for mid resource id failed ctx id:%d req id:%lld res id:0x%x",
+				ctx->ctx_index, packet->header.request_id,
+				res_id);
+			return;
+		}
+
 		for (j = 0; j < CAM_PACKET_MAX_PLANES; j++) {
 			if (!io_cfg[i].mem_handle[j])
 				break;
 
-			if (pf_buf_info &&
-				GET_FD_FROM_HANDLE(io_cfg[i].mem_handle[j]) ==
-				GET_FD_FROM_HANDLE(pf_buf_info)) {
-				CAM_INFO(CAM_ISP,
-					"Found PF at port: 0x%x mem 0x%x fd: 0x%x",
-					io_cfg[i].resource_type,
-					io_cfg[i].mem_handle[j],
-					pf_buf_info);
-				if (mem_found)
-					*mem_found = true;
-			}
-
 			CAM_INFO(CAM_ISP, "port: 0x%x f: %u format: %d dir %d",
 				io_cfg[i].resource_type,
 				io_cfg[i].fence,
@@ -6476,7 +6481,6 @@ static void cam_ife_mgr_print_io_bufs(struct cam_packet *packet,
 			}
 			if ((iova_addr & 0xFFFFFFFF) != iova_addr) {
 				CAM_ERR(CAM_ISP, "Invalid mapped address");
-				rc = -EINVAL;
 				continue;
 			}
 
@@ -6492,9 +6496,187 @@ static void cam_ife_mgr_print_io_bufs(struct cam_packet *packet,
 				io_cfg[i].offsets[j],
 				io_cfg[i].mem_handle[j]);
 		}
+}
+
+static void cam_ife_mgr_pf_dump(uint32_t res_id,
+	struct cam_ife_hw_mgr_ctx *ctx)
+{
+	struct cam_isp_hw_mgr_res      *hw_mgr_res;
+	struct cam_hw_intf             *hw_intf;
+	struct cam_isp_hw_event_info    event_info;
+	uint32_t                        res_id_out;
+	int  i, rc = 0;
+
+	/* dump the registers  */
+	rc = cam_ife_mgr_handle_reg_dump(ctx, ctx->reg_dump_buf_desc,
+		ctx->num_reg_dump_buf,
+		CAM_ISP_PACKET_META_REG_DUMP_ON_ERROR, NULL, false);
+	if (rc)
+		CAM_ERR(CAM_ISP,
+			"Reg dump on pf failed req id: %llu rc: %d",
+			ctx->applied_req_id, rc);
+
+
+	/* dump the acquire data */
+	list_for_each_entry(hw_mgr_res, &ctx->res_list_ife_csid, list) {
+		for (i = 0; i < CAM_ISP_HW_SPLIT_MAX; i++) {
+			if (!hw_mgr_res->hw_res[i])
+				continue;
+
+			hw_intf = hw_mgr_res->hw_res[i]->hw_intf;
+			if (hw_intf && hw_intf->hw_ops.process_cmd) {
+				rc = hw_intf->hw_ops.process_cmd(
+					hw_intf->hw_priv,
+					CAM_IFE_CSID_LOG_ACQUIRE_DATA,
+					hw_mgr_res->hw_res[i],
+					sizeof(void *));
+				if (rc)
+					CAM_ERR(CAM_ISP,
+						"csid acquire data dump failed");
+			} else
+				CAM_ERR(CAM_ISP, "NULL hw_intf!");
+		}
+	}
+
+	event_info.res_id = res_id;
+	res_id_out = res_id & 0xFF;
+
+	if (res_id_out >= CAM_IFE_HW_OUT_RES_MAX) {
+		CAM_ERR(CAM_ISP, "Invalid out resource id :%x",
+			res_id);
+		return;
+	}
+
+	hw_mgr_res = &ctx->res_list_ife_out[res_id_out];
+	for (i = 0; i < CAM_ISP_HW_SPLIT_MAX; i++) {
+		if (!hw_mgr_res->hw_res[i])
+			continue;
+		hw_intf = hw_mgr_res->hw_res[i]->hw_intf;
+		if (hw_intf->hw_ops.process_cmd) {
+			rc = hw_intf->hw_ops.process_cmd(
+				hw_intf->hw_priv,
+				CAM_ISP_HW_CMD_DUMP_BUS_INFO,
+				(void *)&event_info,
+				sizeof(struct cam_isp_hw_event_info));
+		}
 	}
 }
 
+static void cam_ife_mgr_dump_pf_data(
+	struct cam_ife_hw_mgr  *hw_mgr,
+	struct cam_hw_cmd_args *hw_cmd_args)
+{
+	struct cam_ife_hw_mgr_ctx *ctx;
+
+	struct cam_isp_hw_mgr_res          *hw_mgr_res;
+	struct cam_isp_hw_get_cmd_update    cmd_update;
+	struct cam_isp_hw_get_res_for_mid   get_res;
+	struct cam_packet                  *packet;
+	uint32_t    hw_id;
+	uint32_t    *resource_type;
+	bool         *ctx_found, hw_id_found = false;
+	int        i, j, rc = 0;
+
+	ctx = (struct cam_ife_hw_mgr_ctx *)hw_cmd_args->ctxt_to_hw_map;
+
+	packet  = hw_cmd_args->u.pf_args.pf_data.packet;
+	ctx_found = hw_cmd_args->u.pf_args.ctx_found;
+	resource_type = hw_cmd_args->u.pf_args.resource_type;
+
+	if ((*ctx_found) && (*resource_type))
+		goto outportlog;
+
+	if (ctx->pf_mid_found)
+		goto outportlog;
+
+	if (!g_ife_hw_mgr.hw_pid_support)
+		goto mid_check;
+
+	for (i = 0; i < CAM_IFE_HW_NUM_MAX; i++) {
+		if (!hw_mgr->ife_devices[i])
+			continue;
+
+		for (j = 0; j < g_ife_hw_mgr.ife_devices[i]->num_hw_pid; j++) {
+			if (g_ife_hw_mgr.ife_devices[i]->hw_pid[j] ==
+				hw_cmd_args->u.pf_args.pid) {
+				hw_id_found = true;
+				hw_id = i;
+				break;
+			}
+		}
+		if (hw_id_found)
+			break;
+	}
+
+	if (i == CAM_IFE_HW_NUM_MAX) {
+		CAM_INFO(CAM_ISP,
+			"PID:%d  is not matching with any IFE HW PIDs ctx id:%d",
+			hw_cmd_args->u.pf_args.pid,  ctx->ctx_index);
+		return;
+	}
+
+	for (i = 0; i < ctx->num_base; i++) {
+		if (ctx->base[i].idx == hw_id) {
+			*ctx_found = true;
+			break;
+		}
+	}
+
+	if (!(*ctx_found)) {
+		CAM_INFO(CAM_ISP,
+			"This context does not cause pf:pid:%d hw id:%d ctx_id:%d",
+			hw_cmd_args->u.pf_args.pid, hw_id, ctx->ctx_index);
+		return;
+	}
+
+mid_check:
+	for (i = 0; i < CAM_IFE_HW_OUT_RES_MAX; i++) {
+		hw_mgr_res = &ctx->res_list_ife_out[i];
+		if (!hw_mgr_res->hw_res[0])
+			continue;
+
+		break;
+	}
+
+	if (i >= CAM_IFE_HW_OUT_RES_MAX) {
+		CAM_ERR(CAM_ISP,
+			"NO valid outport resources ctx id:%d req id:%lld",
+			ctx->ctx_index, packet->header.request_id);
+		return;
+	}
+
+	get_res.mid = hw_cmd_args->u.pf_args.mid;
+	cmd_update.res = hw_mgr_res->hw_res[0];
+	cmd_update.cmd_type = CAM_ISP_HW_CMD_GET_RES_FOR_MID;
+	cmd_update.data = (void *) &get_res;
+
+	/* get resource id for given mid */
+	rc = hw_mgr_res->hw_res[0]->hw_intf->hw_ops.process_cmd(
+		hw_mgr_res->hw_res[0]->hw_intf->hw_priv,
+		cmd_update.cmd_type, &cmd_update,
+		sizeof(struct cam_isp_hw_get_cmd_update));
+
+	if (rc) {
+		CAM_ERR(CAM_ISP,
+			"getting mid port resource id failed ctx id:%d req id:%lld",
+			ctx->ctx_index, packet->header.request_id);
+		return;
+	}
+
+	CAM_ERR(CAM_ISP,
+		"Page fault on resource id:(0x%x) ctx id:%d req id:%lld",
+		get_res.out_res_id, ctx->ctx_index, packet->header.request_id);
+	*resource_type = get_res.out_res_id;
+	ctx->pf_mid_found = true;
+
+	cam_ife_mgr_pf_dump(get_res.out_res_id, ctx);
+
+outportlog:
+	cam_ife_mgr_print_io_bufs(hw_mgr, *resource_type, packet,
+		ctx_found, ctx);
+
+}
+
 static int cam_ife_mgr_cmd(void *hw_mgr_priv, void *cmd_args)
 {
 	int rc = 0;
@@ -6567,12 +6749,8 @@ static int cam_ife_mgr_cmd(void *hw_mgr_priv, void *cmd_args)
 		}
 		break;
 	case CAM_HW_MGR_CMD_DUMP_PF_INFO:
-		cam_ife_mgr_print_io_bufs(
-			hw_cmd_args->u.pf_args.pf_data.packet,
-			hw_mgr->mgr_common.img_iommu_hdl,
-			hw_mgr->mgr_common.img_iommu_hdl_secure,
-			hw_cmd_args->u.pf_args.buf_info,
-			hw_cmd_args->u.pf_args.mem_found);
+		cam_ife_mgr_dump_pf_data(hw_mgr, hw_cmd_args);
+
 		break;
 	case CAM_HW_MGR_CMD_REG_DUMP_ON_FLUSH:
 		if (ctx->last_dump_flush_req_id == ctx->applied_req_id)
@@ -7548,9 +7726,9 @@ static int cam_ife_hw_mgr_sort_dev_with_caps(
 	for (i = 0; i < CAM_IFE_HW_NUM_MAX; i++) {
 		if (!ife_hw_mgr->ife_devices[i])
 			continue;
-		if (ife_hw_mgr->ife_devices[i]->hw_ops.get_hw_caps) {
-			ife_hw_mgr->ife_devices[i]->hw_ops.get_hw_caps(
-				ife_hw_mgr->ife_devices[i]->hw_priv,
+		if (ife_hw_mgr->ife_devices[i]->hw_intf->hw_ops.get_hw_caps) {
+			ife_hw_mgr->ife_devices[i]->hw_intf->hw_ops.get_hw_caps(
+				ife_hw_mgr->ife_devices[i]->hw_intf->hw_priv,
 				&ife_hw_mgr->ife_dev_caps[i],
 				sizeof(ife_hw_mgr->ife_dev_caps[i]));
 		}
@@ -7671,7 +7849,7 @@ int cam_ife_hw_mgr_init(struct cam_hw_mgr_intf *hw_mgr_intf, int *iommu_hdl)
 		rc = cam_vfe_hw_init(&g_ife_hw_mgr.ife_devices[i], i);
 		if (!rc) {
 			struct cam_hw_intf *ife_device =
-				g_ife_hw_mgr.ife_devices[i];
+				g_ife_hw_mgr.ife_devices[i]->hw_intf;
 			struct cam_hw_info *vfe_hw =
 				(struct cam_hw_info *)
 				ife_device->hw_priv;
@@ -7690,6 +7868,10 @@ int cam_ife_hw_mgr_init(struct cam_hw_mgr_intf *hw_mgr_intf, int *iommu_hdl)
 				"reg_map: mem base = %pK cam_base = 0x%llx",
 				(void __iomem *)soc_info->reg_map[0].mem_base,
 				(uint64_t) soc_info->reg_map[0].mem_cam_base);
+
+			if (g_ife_hw_mgr.ife_devices[i]->num_hw_pid)
+				g_ife_hw_mgr.hw_pid_support = true;
+
 		} else {
 			g_ife_hw_mgr.cdm_reg_map[i] = NULL;
 		}

+ 6 - 1
drivers/cam_isp/isp_hw_mgr/cam_ife_hw_mgr.h

@@ -99,6 +99,7 @@ struct cam_ife_hw_mgr_debug {
  * @dsp_enabled             Indicate whether dsp is enabled in this context
  * @hw_enabled              Array to indicate active HW
  * @internal_cdm            Indicate whether context uses internal CDM
+ * @pf_mid_found            in page fault, mid found for this ctx.
  */
 struct cam_ife_hw_mgr_ctx {
 	struct list_head                list;
@@ -154,6 +155,7 @@ struct cam_ife_hw_mgr_ctx {
 	bool                            is_offline;
 	bool                            dsp_enabled;
 	bool                            internal_cdm;
+	bool                            pf_mid_found;
 };
 
 /**
@@ -172,13 +174,15 @@ struct cam_ife_hw_mgr_ctx {
  * @ife_dev_caps           ife device capability per core
  * @work q                 work queue for IFE hw manager
  * @debug_cfg              debug configuration
+ * @ctx_lock               context lock
  * @support_consumed_addr  indicate whether hw supports last consumed address
+ * @hw_pid_support         hw pid support for this target
  */
 struct cam_ife_hw_mgr {
 	struct cam_isp_hw_mgr          mgr_common;
 	struct cam_hw_intf            *tpg_devices[CAM_TOP_TPG_HW_NUM_MAX];
 	struct cam_hw_intf            *csid_devices[CAM_IFE_CSID_HW_NUM_MAX];
-	struct cam_hw_intf            *ife_devices[CAM_IFE_HW_NUM_MAX];
+	struct cam_isp_hw_intf_data   *ife_devices[CAM_IFE_HW_NUM_MAX];
 	struct cam_soc_reg_map        *cdm_reg_map[CAM_IFE_HW_NUM_MAX];
 
 	struct mutex                   ctx_mutex;
@@ -194,6 +198,7 @@ struct cam_ife_hw_mgr {
 	struct cam_ife_hw_mgr_debug    debug_cfg;
 	spinlock_t                     ctx_lock;
 	bool                           support_consumed_addr;
+	bool                           hw_pid_support;
 };
 
 /**

+ 52 - 0
drivers/cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/cam_ife_csid_core.c

@@ -4118,6 +4118,55 @@ static int cam_ife_csid_dump_hw(
 	return 0;
 }
 
+static int cam_ife_csid_log_acquire_data(
+	struct cam_ife_csid_hw   *csid_hw,  void *cmd_args)
+{
+	struct cam_isp_resource_node  *res =
+		(struct cam_isp_resource_node *)cmd_args;
+	struct cam_ife_csid_path_cfg       *path_data;
+	struct cam_hw_soc_info                         *soc_info;
+	const struct cam_ife_csid_reg_offset           *csid_reg;
+	const struct cam_ife_csid_rdi_reg_offset       *rdi_reg;
+	uint32_t byte_cnt_ping, byte_cnt_pong;
+
+	path_data = (struct cam_ife_csid_path_cfg *)res->res_priv;
+	csid_reg = csid_hw->csid_info->csid_reg;
+	soc_info = &csid_hw->hw_info->soc_info;
+
+	if (res->res_state <= CAM_ISP_RESOURCE_STATE_AVAILABLE) {
+		CAM_ERR(CAM_ISP,
+			"CSID:%d invalid res id:%d res type: %d state:%d",
+			csid_hw->hw_intf->hw_idx, res->res_id, res->res_type,
+			res->res_state);
+		return -EINVAL;
+	}
+
+	/* Dump all the acquire data for this hardware */
+	CAM_INFO(CAM_ISP,
+		"CSID:%d res id:%d type:%d state:%d in f:%d out f:%d st pix:%d end pix:%d st line:%d end line:%d h bin:%d qcfa bin:%d",
+		csid_hw->hw_intf->hw_idx, res->res_id, res->res_type,
+		res->res_type, path_data->in_format, path_data->out_format,
+		path_data->start_pixel, path_data->end_pixel,
+		path_data->start_line, path_data->end_line,
+		path_data->horizontal_bin, path_data->qcfa_bin);
+
+	if (res->res_id >= CAM_IFE_PIX_PATH_RES_RDI_0  &&
+		res->res_id <= CAM_IFE_PIX_PATH_RES_RDI_3) {
+		rdi_reg = csid_reg->rdi_reg[res->res_id];
+		/* read total number of bytes transmitted through RDI */
+		byte_cnt_ping = cam_io_r_mb(soc_info->reg_map[0].mem_base +
+			rdi_reg->csid_rdi_byte_cntr_ping_addr);
+		byte_cnt_pong = cam_io_r_mb(soc_info->reg_map[0].mem_base +
+			rdi_reg->csid_rdi_byte_cntr_pong_addr);
+		CAM_INFO(CAM_ISP,
+			"CSID:%d res id:%d byte cnt val ping:%d pong:%d",
+			csid_hw->hw_intf->hw_idx, res->res_id,
+			byte_cnt_ping, byte_cnt_pong);
+	}
+
+	return 0;
+}
+
 static int cam_ife_csid_process_cmd(void *hw_priv,
 	uint32_t cmd_type, void *cmd_args, uint32_t arg_size)
 {
@@ -4164,6 +4213,9 @@ static int cam_ife_csid_process_cmd(void *hw_priv,
 	case CAM_IFE_CSID_SET_SENSOR_DIMENSION_CFG:
 		rc = cam_ife_csid_set_sensor_dimension(csid_hw, cmd_args);
 		break;
+	case CAM_IFE_CSID_LOG_ACQUIRE_DATA:
+		rc = cam_ife_csid_log_acquire_data(csid_hw, cmd_args);
+		break;
 	default:
 		CAM_ERR(CAM_ISP, "CSID:%d unsupported cmd:%d",
 			csid_hw->hw_intf->hw_idx, cmd_type);

+ 1 - 0
drivers/cam_isp/isp_hw_mgr/isp_hw/include/cam_ife_csid_hw_intf.h

@@ -212,6 +212,7 @@ enum cam_ife_csid_cmd_type {
 	CAM_IFE_CSID_SOF_IRQ_DEBUG,
 	CAM_IFE_CSID_SET_CONFIG,
 	CAM_IFE_CSID_SET_SENSOR_DIMENSION_CFG,
+	CAM_IFE_CSID_LOG_ACQUIRE_DATA,
 	CAM_IFE_CSID_CMD_MAX,
 };
 

+ 32 - 0
drivers/cam_isp/isp_hw_mgr/isp_hw/include/cam_isp_hw.h

@@ -15,6 +15,8 @@
 
 /* Maximum length of tag while dumping */
 #define CAM_ISP_HW_DUMP_TAG_MAX_LEN 32
+/* Max isp hw pid values number */
+#define CAM_ISP_HW_MAX_PID_VAL      4
 /*
  * struct cam_isp_timestamp:
  *
@@ -121,6 +123,7 @@ enum cam_isp_hw_cmd_type {
 	CAM_ISP_HW_CMD_FE_TRIGGER_CMD,
 	CAM_ISP_HW_CMD_UNMASK_BUS_WR_IRQ,
 	CAM_ISP_HW_CMD_IS_CONSUMED_ADDR_SUPPORT,
+	CAM_ISP_HW_CMD_GET_RES_FOR_MID,
 	CAM_ISP_HW_CMD_MAX,
 };
 
@@ -233,6 +236,20 @@ struct cam_isp_hw_get_wm_update {
 	struct cam_buf_io_cfg          *io_cfg;
 };
 
+/*
+ * struct cam_isp_hw_get_res_for_mid:
+ *
+ * @Brief:           Get the out resource id for given mid
+ *
+ * @mid:             Mid number of hw outport numb
+ * @out_res_id:      Out resource id
+ *
+ */
+struct cam_isp_hw_get_res_for_mid {
+	uint32_t                       mid;
+	uint32_t                       out_res_id;
+};
+
 /*
  * struct cam_isp_hw_get_cmd_update:
  *
@@ -308,4 +325,19 @@ struct cam_isp_hw_dump_header {
 	uint32_t  word_size;
 };
 
+/**
+ * struct cam_isp_hw_intf_data - ISP hw intf data
+ *
+ * @Brief:        isp hw intf pointer and pid list data
+ *
+ * @isp_hw_intf:      Isp hw intf pointer
+ * @num_hw_pid:       Number of pids for this hw
+ * @isp_hw_pid:       Isp hw pid values
+ *
+ */
+struct cam_isp_hw_intf_data {
+	struct cam_hw_intf     *hw_intf;
+	uint32_t                num_hw_pid;
+	uint32_t                hw_pid[CAM_ISP_HW_MAX_PID_VAL];
+};
 #endif /* _CAM_ISP_HW_H_ */

+ 2 - 1
drivers/cam_isp/isp_hw_mgr/isp_hw/include/cam_vfe_hw_intf.h

@@ -389,7 +389,8 @@ struct cam_vfe_generic_ubwc_config {
  *                          successful initialization
  * @hw_idx:                 Index of VFE HW
  */
-int cam_vfe_hw_init(struct cam_hw_intf **vfe_hw, uint32_t hw_idx);
+int cam_vfe_hw_init(struct cam_isp_hw_intf_data **vfe_hw,
+	uint32_t hw_idx);
 
 /*
  * cam_vfe_put_evt_payload()

+ 1 - 0
drivers/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/cam_vfe_core.c

@@ -616,6 +616,7 @@ int cam_vfe_process_cmd(void *hw_priv, uint32_t cmd_type,
 	case CAM_ISP_HW_CMD_UNMASK_BUS_WR_IRQ:
 	case CAM_ISP_HW_CMD_DUMP_BUS_INFO:
 	case CAM_ISP_HW_CMD_IS_CONSUMED_ADDR_SUPPORT:
+	case CAM_ISP_HW_CMD_GET_RES_FOR_MID:
 		rc = core_info->vfe_bus->hw_ops.process_cmd(
 			core_info->vfe_bus->bus_priv, cmd_type, cmd_args,
 			arg_size);

+ 17 - 8
drivers/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/cam_vfe_dev.c

@@ -14,8 +14,7 @@
 #include "cam_vfe_soc.h"
 #include "cam_debug_util.h"
 
-static struct cam_hw_intf *cam_vfe_hw_list[CAM_VFE_HW_NUM_MAX];
-
+static  struct cam_isp_hw_intf_data cam_vfe_hw_list[CAM_VFE_HW_NUM_MAX];
 static char vfe_dev_name[8];
 
 static int cam_vfe_component_bind(struct device *dev,
@@ -28,6 +27,8 @@ static int cam_vfe_component_bind(struct device *dev,
 	struct cam_vfe_hw_info            *hw_info = NULL;
 	int                                rc = 0;
 	struct platform_device *pdev = to_platform_device(dev);
+	struct cam_vfe_soc_private   *vfe_soc_priv;
+	uint32_t  i;
 
 	vfe_hw_intf = kzalloc(sizeof(struct cam_hw_intf), GFP_KERNEL);
 	if (!vfe_hw_intf) {
@@ -109,7 +110,13 @@ static int cam_vfe_component_bind(struct device *dev,
 	init_completion(&vfe_hw->hw_complete);
 
 	if (vfe_hw_intf->hw_idx < CAM_VFE_HW_NUM_MAX)
-		cam_vfe_hw_list[vfe_hw_intf->hw_idx] = vfe_hw_intf;
+		cam_vfe_hw_list[vfe_hw_intf->hw_idx].hw_intf = vfe_hw_intf;
+
+	vfe_soc_priv = vfe_hw->soc_info.soc_private;
+	cam_vfe_hw_list[vfe_hw_intf->hw_idx].num_hw_pid = vfe_soc_priv->num_pid;
+	for (i = 0; i < vfe_soc_priv->num_pid; i++)
+		cam_vfe_hw_list[vfe_hw_intf->hw_idx].hw_pid[i] =
+			vfe_soc_priv->pid[i];
 
 	cam_vfe_init_hw(vfe_hw, NULL, 0);
 	cam_vfe_deinit_hw(vfe_hw, NULL, 0);
@@ -150,7 +157,7 @@ static void cam_vfe_component_unbind(struct device *dev,
 		vfe_hw_intf->hw_type, vfe_hw_intf->hw_idx);
 
 	if (vfe_hw_intf->hw_idx < CAM_VFE_HW_NUM_MAX)
-		cam_vfe_hw_list[vfe_hw_intf->hw_idx] = NULL;
+		cam_vfe_hw_list[vfe_hw_intf->hw_idx].hw_intf = NULL;
 
 	vfe_hw = vfe_hw_intf->hw_priv;
 	if (!vfe_hw) {
@@ -207,15 +214,17 @@ int cam_vfe_remove(struct platform_device *pdev)
 	return 0;
 }
 
-int cam_vfe_hw_init(struct cam_hw_intf **vfe_hw, uint32_t hw_idx)
+int cam_vfe_hw_init(struct cam_isp_hw_intf_data **vfe_hw_intf,
+	uint32_t hw_idx)
 {
 	int rc = 0;
 
-	if (cam_vfe_hw_list[hw_idx]) {
-		*vfe_hw = cam_vfe_hw_list[hw_idx];
+	if (cam_vfe_hw_list[hw_idx].hw_intf) {
+		*vfe_hw_intf = &cam_vfe_hw_list[hw_idx];
 		rc = 0;
 	} else {
-		*vfe_hw = NULL;
+		CAM_ERR(CAM_ISP, "inval param");
+		*vfe_hw_intf = NULL;
 		rc = -ENODEV;
 	}
 	return rc;

+ 19 - 3
drivers/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/cam_vfe_soc.c

@@ -36,7 +36,7 @@ static bool cam_vfe_cpas_cb(uint32_t client_handle, void *userdata,
 
 static int cam_vfe_get_dt_properties(struct cam_hw_soc_info *soc_info)
 {
-	int rc = 0, num_ubwc_cfg = 0, i = 0;
+	int rc = 0, num_ubwc_cfg = 0, i = 0, num_pid = 0;
 	struct device_node *of_node = NULL;
 	struct platform_device *pdev = NULL;
 	struct cam_vfe_soc_private *vfe_soc_private;
@@ -55,7 +55,7 @@ static int cam_vfe_get_dt_properties(struct cam_hw_soc_info *soc_info)
 	if (strnstr(soc_info->compatible, "lite",
 		strlen(soc_info->compatible)) != NULL) {
 		vfe_soc_private->is_ife_lite = true;
-		goto end;
+		goto pid;
 	}
 
 	switch (soc_info->hw_version) {
@@ -69,7 +69,7 @@ static int cam_vfe_get_dt_properties(struct cam_hw_soc_info *soc_info)
 			CAM_ERR(CAM_ISP, "wrong num_ubwc_cfg: %d",
 				num_ubwc_cfg);
 			rc = num_ubwc_cfg;
-			goto end;
+			goto pid;
 		}
 
 		for (i = 0; i < num_ubwc_cfg; i++) {
@@ -86,8 +86,24 @@ static int cam_vfe_get_dt_properties(struct cam_hw_soc_info *soc_info)
 	default:
 		break;
 	}
+pid:
+	/* set some default values */
+	vfe_soc_private->num_pid = 0;
+
+	num_pid = of_property_count_u32_elems(pdev->dev.of_node, "cam_hw_pid");
+	CAM_DBG(CAM_CPAS, "vfe:%d pid count %d", soc_info->index, num_pid);
+
+	if (num_pid <= 0  || num_pid > CAM_ISP_HW_MAX_PID_VAL)
+		goto end;
+
+	for (i = 0; i < num_pid; i++)
+		of_property_read_u32_index(pdev->dev.of_node, "cam_hw_pid", i,
+		&vfe_soc_private->pid[i]);
+
+	vfe_soc_private->num_pid = num_pid;
 
 end:
+
 	return rc;
 }
 

+ 4 - 0
drivers/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/cam_vfe_soc.h

@@ -25,6 +25,8 @@
  * @ubwc_static_ctrl:        UBWC static control configuration
  * @is_ife_lite:             Flag to indicate full vs lite IFE
  * @ife_clk_src:             IFE source clock
+ * @num_pid:                 Number of pids of ife
+ * @pid:                     IFE pid values list
  */
 struct cam_vfe_soc_private {
 	uint32_t    cpas_handle;
@@ -35,6 +37,8 @@ struct cam_vfe_soc_private {
 	uint32_t    ubwc_static_ctrl[UBWC_STATIC_CONFIG_MAX];
 	bool        is_ife_lite;
 	uint64_t    ife_clk_src;
+	uint32_t    num_pid;
+	uint32_t    pid[CAM_ISP_HW_MAX_PID_VAL];
 };
 
 /*

+ 34 - 0
drivers/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe17x/cam_vfe480.h

@@ -1176,60 +1176,77 @@ static struct cam_vfe_bus_ver3_hw_info vfe480_bus_hw_info = {
 			.max_width     = -1,
 			.max_height    = -1,
 			.source_group  = CAM_VFE_BUS_VER3_SRC_GRP_3,
+			.mid[0]        = 8,
 		},
 		{
 			.vfe_out_type  = CAM_VFE_BUS_VER3_VFE_OUT_RDI1,
 			.max_width     = -1,
 			.max_height    = -1,
 			.source_group  = CAM_VFE_BUS_VER3_SRC_GRP_4,
+			.mid[0]        = 9,
 		},
 		{
 			.vfe_out_type  = CAM_VFE_BUS_VER3_VFE_OUT_RDI2,
 			.max_width     = -1,
 			.max_height    = -1,
 			.source_group  = CAM_VFE_BUS_VER3_SRC_GRP_5,
+			.mid[0]        = 10,
 		},
 		{
 			.vfe_out_type  = CAM_VFE_BUS_VER3_VFE_OUT_FULL,
 			.max_width     = 4096,
 			.max_height    = 4096,
 			.source_group  = CAM_VFE_BUS_VER3_SRC_GRP_0,
+			.mid[0]        = 32,
+			.mid[1]        = 33,
+			.mid[2]        = 34,
+			.mid[3]        = 35,
 		},
 		{
 			.vfe_out_type  = CAM_VFE_BUS_VER3_VFE_OUT_DS4,
 			.max_width     = 1920,
 			.max_height    = 1080,
 			.source_group  = CAM_VFE_BUS_VER3_SRC_GRP_0,
+			.mid[0]        = 16,
 		},
 		{
 			.vfe_out_type  = CAM_VFE_BUS_VER3_VFE_OUT_DS16,
 			.max_width     = 1920,
 			.max_height    = 1080,
 			.source_group  = CAM_VFE_BUS_VER3_SRC_GRP_0,
+			.mid[0]        = 17,
 		},
 		{
 			.vfe_out_type  = CAM_VFE_BUS_VER3_VFE_OUT_RAW_DUMP,
 			.max_width     = -1,
 			.max_height    = -1,
 			.source_group  = CAM_VFE_BUS_VER3_SRC_GRP_0,
+			.mid[0]        = 11,
+			.mid[1]        = 12,
 		},
 		{
 			.vfe_out_type  = CAM_VFE_BUS_VER3_VFE_OUT_FD,
 			.max_width     = 1920,
 			.max_height    = 1080,
 			.source_group  = CAM_VFE_BUS_VER3_SRC_GRP_0,
+			.mid[0]        = 20,
+			.mid[1]        = 21,
+			.mid[2]        = 22,
 		},
 		{
 			.vfe_out_type  = CAM_VFE_BUS_VER3_VFE_OUT_PDAF,
 			.max_width     = -1,
 			.max_height    = -1,
 			.source_group  = CAM_VFE_BUS_VER3_SRC_GRP_0,
+			.mid[0]        = 25,
+			.mid[1]        = 26,
 		},
 		{
 			.vfe_out_type  = CAM_VFE_BUS_VER3_VFE_OUT_STATS_HDR_BE,
 			.max_width     = -1,
 			.max_height    = -1,
 			.source_group  = CAM_VFE_BUS_VER3_SRC_GRP_0,
+			.mid[0]        = 40,
 		},
 		{
 			.vfe_out_type  =
@@ -1237,6 +1254,7 @@ static struct cam_vfe_bus_ver3_hw_info vfe480_bus_hw_info = {
 			.max_width     = 1920,
 			.max_height    = 1080,
 			.source_group  = CAM_VFE_BUS_VER3_SRC_GRP_0,
+			.mid[0]        = 41,
 		},
 		{
 			.vfe_out_type  =
@@ -1244,72 +1262,88 @@ static struct cam_vfe_bus_ver3_hw_info vfe480_bus_hw_info = {
 			.max_width     = -1,
 			.max_height    = -1,
 			.source_group  = CAM_VFE_BUS_VER3_SRC_GRP_0,
+			.mid[0]        = 42,
 		},
 		{
 			.vfe_out_type  = CAM_VFE_BUS_VER3_VFE_OUT_STATS_BF,
 			.max_width     = -1,
 			.max_height    = -1,
 			.source_group  = CAM_VFE_BUS_VER3_SRC_GRP_0,
+			.mid[0]        = 43,
 		},
 		{
 			.vfe_out_type  = CAM_VFE_BUS_VER3_VFE_OUT_STATS_AWB_BG,
 			.max_width     = -1,
 			.max_height    = -1,
 			.source_group  = CAM_VFE_BUS_VER3_SRC_GRP_0,
+			.mid[0]         = 44,
 		},
 		{
 			.vfe_out_type  = CAM_VFE_BUS_VER3_VFE_OUT_STATS_BHIST,
 			.max_width     = -1,
 			.max_height    = -1,
 			.source_group  = CAM_VFE_BUS_VER3_SRC_GRP_0,
+			.mid[0]        = 45,
 		},
 		{
 			.vfe_out_type  = CAM_VFE_BUS_VER3_VFE_OUT_STATS_RS,
 			.max_width     = -1,
 			.max_height    = -1,
 			.source_group  = CAM_VFE_BUS_VER3_SRC_GRP_0,
+			.mid[0]        = 46,
 		},
 		{
 			.vfe_out_type  = CAM_VFE_BUS_VER3_VFE_OUT_STATS_CS,
 			.max_width     = -1,
 			.max_height    = -1,
 			.source_group  = CAM_VFE_BUS_VER3_SRC_GRP_0,
+			.mid[0]        = 47,
 		},
 		{
 			.vfe_out_type  = CAM_VFE_BUS_VER3_VFE_OUT_STATS_IHIST,
 			.max_width     = -1,
 			.max_height    = -1,
 			.source_group  = CAM_VFE_BUS_VER3_SRC_GRP_0,
+			.mid[0]        = 48,
 		},
 		{
 			.vfe_out_type  = CAM_VFE_BUS_VER3_VFE_OUT_FULL_DISP,
 			.max_width     = 4096,
 			.max_height    = 4096,
 			.source_group  = CAM_VFE_BUS_VER3_SRC_GRP_0,
+			.mid[0]        = 36,
+			.mid[1]        = 37,
+			.mid[2]        = 38,
+			.mid[3]        = 39,
 		},
 		{
 			.vfe_out_type  = CAM_VFE_BUS_VER3_VFE_OUT_DS4_DISP,
 			.max_width     = 1920,
 			.max_height    = 1080,
 			.source_group  = CAM_VFE_BUS_VER3_SRC_GRP_0,
+			.mid[0]        = 18,
 		},
 		{
 			.vfe_out_type  = CAM_VFE_BUS_VER3_VFE_OUT_DS16_DISP,
 			.max_width     = 1920,
 			.max_height    = 1080,
 			.source_group  = CAM_VFE_BUS_VER3_SRC_GRP_0,
+			.mid[0]        = 19,
 		},
 		{
 			.vfe_out_type  = CAM_VFE_BUS_VER3_VFE_OUT_2PD,
 			.max_width     = 1920,
 			.max_height    = 1080,
 			.source_group  = CAM_VFE_BUS_VER3_SRC_GRP_1,
+			.mid[0]        = 23,
+			.mid[1]        = 24,
 		},
 		{
 			.vfe_out_type  = CAM_VFE_BUS_VER3_VFE_OUT_LCR,
 			.max_width     = -1,
 			.max_height    = -1,
 			.source_group  = CAM_VFE_BUS_VER3_SRC_GRP_2,
+			.mid[0]        = 27,
 		},
 	},
 	.comp_done_shift = 6,

+ 4 - 0
drivers/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe17x/cam_vfe_lite48x.h

@@ -373,24 +373,28 @@ static struct cam_vfe_bus_ver3_hw_info vfe48x_bus_hw_info = {
 			.max_width     = -1,
 			.max_height    = -1,
 			.source_group  = CAM_VFE_BUS_VER3_SRC_GRP_0,
+			.mid[0]        = 16,
 		},
 		{
 			.vfe_out_type  = CAM_VFE_BUS_VER3_VFE_OUT_RDI1,
 			.max_width     = -1,
 			.max_height    = -1,
 			.source_group  = CAM_VFE_BUS_VER3_SRC_GRP_1,
+			.mid[0]        = 17,
 		},
 		{
 			.vfe_out_type  = CAM_VFE_BUS_VER3_VFE_OUT_RDI2,
 			.max_width     = -1,
 			.max_height    = -1,
 			.source_group  = CAM_VFE_BUS_VER3_SRC_GRP_2,
+			.mid[0]        = 18,
 		},
 		{
 			.vfe_out_type  = CAM_VFE_BUS_VER3_VFE_OUT_RDI3,
 			.max_width     = -1,
 			.max_height    = -1,
 			.source_group  = CAM_VFE_BUS_VER3_SRC_GRP_3,
+			.mid[0]        = 19,
 		},
 	},
 	.comp_done_shift = 4,

+ 53 - 1
drivers/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe_bus/cam_vfe_bus_ver2.c

@@ -180,6 +180,7 @@ struct cam_vfe_bus_ver2_vfe_out_data {
 	struct cam_cdm_utils_ops        *cdm_util_ops;
 	uint32_t                         secure_mode;
 	void                            *priv;
+	uint32_t                         mid[CAM_VFE_BUS_VER2_MAX_MID_PER_PORT];
 };
 
 struct cam_vfe_bus_ver2_priv {
@@ -2431,7 +2432,7 @@ static int cam_vfe_bus_init_vfe_out_resource(uint32_t  index,
 {
 	struct cam_isp_resource_node         *vfe_out = NULL;
 	struct cam_vfe_bus_ver2_vfe_out_data *rsrc_data = NULL;
-	int rc = 0;
+	int rc = 0, i;
 	int32_t vfe_out_type =
 		ver2_hw_info->vfe_out_hw_info[index].vfe_out_type;
 
@@ -2481,6 +2482,9 @@ static int cam_vfe_bus_init_vfe_out_resource(uint32_t  index,
 	vfe_out->hw_intf = ver2_bus_priv->common_data.hw_intf;
 	vfe_out->irq_handle = 0;
 
+	for (i = 0; i < CAM_VFE_BUS_VER2_MAX_MID_PER_PORT; i++)
+		rsrc_data->mid[i] = ver2_hw_info->vfe_out_hw_info[index].mid[i];
+
 	return 0;
 }
 
@@ -3576,6 +3580,50 @@ int cam_vfe_bus_dump_wm_data(void *priv, void *cmd_args, uint32_t arg_size)
 	return 0;
 }
 
+static int cam_vfe_bus_get_res_for_mid(
+	struct cam_vfe_bus_ver2_priv *bus_priv,
+	void *cmd_args, uint32_t arg_size)
+{
+	struct cam_vfe_bus_ver2_vfe_out_data   *out_data = NULL;
+	struct cam_isp_hw_get_cmd_update       *cmd_update = cmd_args;
+	struct cam_isp_hw_get_res_for_mid       *get_res = NULL;
+	int i, j;
+
+	get_res = (struct cam_isp_hw_get_res_for_mid *)cmd_update->data;
+	if (!get_res) {
+		CAM_ERR(CAM_ISP,
+			"invalid get resource for mid paramas");
+		return -EINVAL;
+	}
+
+	for (i = 0; i < bus_priv->num_out; i++) {
+		out_data = (struct cam_vfe_bus_ver2_vfe_out_data   *)
+			bus_priv->vfe_out[i].res_priv;
+
+		if (!out_data)
+			continue;
+
+		for (j = 0; j < CAM_VFE_BUS_VER2_MAX_MID_PER_PORT; j++) {
+			if (out_data->mid[j] == get_res->mid)
+				goto end;
+		}
+	}
+
+	if (i == bus_priv->num_out) {
+		CAM_ERR(CAM_ISP,
+			"mid:%d does not match with any out resource",
+			get_res->mid);
+		get_res->out_res_id = 0;
+		return -EINVAL;
+	}
+
+end:
+	CAM_INFO(CAM_ISP, "match mid :%d  out resource:0x%x found",
+		get_res->mid, bus_priv->vfe_out[i].res_id);
+	get_res->out_res_id = bus_priv->vfe_out[i].res_id;
+	return 0;
+}
+
 static int cam_vfe_bus_process_cmd(
 	struct cam_isp_resource_node *priv,
 	uint32_t cmd_type, void *cmd_args, uint32_t arg_size)
@@ -3636,6 +3684,10 @@ static int cam_vfe_bus_process_cmd(
 		*support_consumed_addr =
 			bus_priv->common_data.support_consumed_addr;
 		break;
+	case CAM_ISP_HW_CMD_GET_RES_FOR_MID:
+		bus_priv = (struct cam_vfe_bus_ver2_priv *) priv;
+		rc = cam_vfe_bus_get_res_for_mid(bus_priv, cmd_args, arg_size);
+		break;
 	default:
 		CAM_ERR_RATE_LIMIT(CAM_ISP, "Invalid camif process command:%d",
 			cmd_type);

+ 2 - 0
drivers/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe_bus/cam_vfe_bus_ver2.h

@@ -10,6 +10,7 @@
 #include "cam_vfe_bus.h"
 
 #define CAM_VFE_BUS_VER2_MAX_CLIENTS 24
+#define CAM_VFE_BUS_VER2_MAX_MID_PER_PORT 4
 
 enum cam_vfe_bus_ver2_vfe_core_id {
 	CAM_VFE_BUS_VER2_VFE_CORE_0,
@@ -167,6 +168,7 @@ struct cam_vfe_bus_ver2_vfe_out_hw_info {
 	enum cam_vfe_bus_ver2_vfe_out_type  vfe_out_type;
 	uint32_t                            max_width;
 	uint32_t                            max_height;
+	uint32_t                         mid[CAM_VFE_BUS_VER2_MAX_MID_PER_PORT];
 };
 
 /*

+ 74 - 1
drivers/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe_bus/cam_vfe_bus_ver3.c

@@ -177,6 +177,7 @@ struct cam_vfe_bus_ver3_vfe_out_data {
 	struct cam_cdm_utils_ops        *cdm_util_ops;
 	uint32_t                         secure_mode;
 	void                            *priv;
+	uint32_t                         mid[CAM_VFE_BUS_VER3_MAX_MID_PER_PORT];
 };
 
 struct cam_vfe_bus_ver3_priv {
@@ -2641,7 +2642,7 @@ static int cam_vfe_bus_ver3_init_vfe_out_resource(uint32_t  index,
 {
 	struct cam_isp_resource_node         *vfe_out = NULL;
 	struct cam_vfe_bus_ver3_vfe_out_data *rsrc_data = NULL;
-	int rc = 0;
+	int rc = 0, i;
 	int32_t vfe_out_type =
 		ver3_hw_info->vfe_out_hw_info[index].vfe_out_type;
 
@@ -2694,6 +2695,10 @@ static int cam_vfe_bus_ver3_init_vfe_out_resource(uint32_t  index,
 	vfe_out->hw_intf = ver3_bus_priv->common_data.hw_intf;
 	vfe_out->irq_handle = 0;
 
+	for (i = 0; i < CAM_VFE_BUS_VER3_MAX_MID_PER_PORT; i++)
+		rsrc_data->mid[i] = ver3_hw_info->vfe_out_hw_info[index].mid[i];
+
+
 	return 0;
 }
 
@@ -2735,7 +2740,9 @@ static int cam_vfe_bus_ver3_print_dimensions(
 	struct cam_isp_resource_node              *rsrc_node = NULL;
 	struct cam_vfe_bus_ver3_vfe_out_data      *rsrc_data = NULL;
 	struct cam_vfe_bus_ver3_wm_resource_data  *wm_data   = NULL;
+	struct cam_vfe_bus_ver3_common_data  *common_data = NULL;
 	int                                        i, wm_idx;
+	uint32_t addr_status0, addr_status1, addr_status2, addr_status3;
 
 	rsrc_node = &bus_priv->vfe_out[vfe_out_res_id];
 	rsrc_data = rsrc_node->res_priv;
@@ -2748,6 +2755,16 @@ static int cam_vfe_bus_ver3_print_dimensions(
 			return -EINVAL;
 		}
 		wm_data = bus_priv->bus_client[wm_idx].res_priv;
+		common_data = rsrc_data->common_data;
+		addr_status0 = cam_io_r_mb(common_data->mem_base +
+			wm_data->hw_regs->addr_status_0);
+		addr_status1 = cam_io_r_mb(common_data->mem_base +
+			wm_data->hw_regs->addr_status_1);
+		addr_status2 = cam_io_r_mb(common_data->mem_base +
+			wm_data->hw_regs->addr_status_2);
+		addr_status3 = cam_io_r_mb(common_data->mem_base +
+			wm_data->hw_regs->addr_status_3);
+
 		CAM_INFO(CAM_ISP,
 			"VFE:%d WM:%d width:%u height:%u stride:%u x_init:%u en_cfg:%u acquired width:%u height:%u",
 			wm_data->common_data->core_index, wm_idx,
@@ -2757,6 +2774,14 @@ static int cam_vfe_bus_ver3_print_dimensions(
 			wm_data->en_cfg,
 			wm_data->acquired_width,
 			wm_data->acquired_height);
+		CAM_INFO(CAM_ISP,
+			"hw:%d WM:%d last consumed address:0x%x last frame addr:0x%x fifo cnt:0x%x current client address:0x%x",
+			common_data->hw_intf->hw_idx,
+			wm_data->index,
+			addr_status0,
+			addr_status1,
+			addr_status2,
+			addr_status3);
 	}
 	return 0;
 }
@@ -3689,6 +3714,50 @@ static int cam_vfe_bus_ver3_deinit_hw(void *hw_priv,
 	return rc;
 }
 
+static int cam_vfe_bus_get_res_for_mid(
+	struct cam_vfe_bus_ver3_priv *bus_priv,
+	void *cmd_args, uint32_t arg_size)
+{
+	struct cam_vfe_bus_ver3_vfe_out_data   *out_data = NULL;
+	struct cam_isp_hw_get_cmd_update       *cmd_update = cmd_args;
+	struct cam_isp_hw_get_res_for_mid       *get_res = NULL;
+	int i, j;
+
+	get_res = (struct cam_isp_hw_get_res_for_mid *)cmd_update->data;
+	if (!get_res) {
+		CAM_ERR(CAM_ISP,
+			"invalid get resource for mid paramas");
+		return -EINVAL;
+	}
+
+	for (i = 0; i < bus_priv->num_out; i++) {
+		out_data = (struct cam_vfe_bus_ver3_vfe_out_data   *)
+			bus_priv->vfe_out[i].res_priv;
+
+		if (!out_data)
+			continue;
+
+		for (j = 0; j < CAM_VFE_BUS_VER3_MAX_MID_PER_PORT; j++) {
+			if (out_data->mid[j] == get_res->mid)
+				goto end;
+		}
+	}
+
+	if (i == bus_priv->num_out) {
+		CAM_ERR(CAM_ISP,
+			"mid:%d does not match with any out resource",
+			get_res->mid);
+		get_res->out_res_id = 0;
+		return -EINVAL;
+	}
+
+end:
+	CAM_INFO(CAM_ISP, "match mid :%d  out resource:0x%x found",
+		get_res->mid, bus_priv->vfe_out[i].res_id);
+	get_res->out_res_id = bus_priv->vfe_out[i].res_id;
+	return 0;
+}
+
 static int __cam_vfe_bus_ver3_process_cmd(void *priv,
 	uint32_t cmd_type, void *cmd_args, uint32_t arg_size)
 {
@@ -3766,6 +3835,10 @@ static int cam_vfe_bus_ver3_process_cmd(
 		*support_consumed_addr =
 			bus_priv->common_data.support_consumed_addr;
 		break;
+	case CAM_ISP_HW_CMD_GET_RES_FOR_MID:
+		bus_priv = (struct cam_vfe_bus_ver3_priv *) priv;
+		rc = cam_vfe_bus_get_res_for_mid(bus_priv, cmd_args, arg_size);
+		break;
 	default:
 		CAM_ERR_RATE_LIMIT(CAM_ISP, "Invalid camif process command:%d",
 			cmd_type);

+ 2 - 0
drivers/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe_bus/cam_vfe_bus_ver3.h

@@ -12,6 +12,7 @@
 
 #define CAM_VFE_BUS_VER3_MAX_CLIENTS     26
 #define CAM_VFE_BUS_VER3_MAX_SUB_GRPS     6
+#define CAM_VFE_BUS_VER3_MAX_MID_PER_PORT 4
 
 enum cam_vfe_bus_ver3_vfe_core_id {
 	CAM_VFE_BUS_VER3_VFE_CORE_0,
@@ -160,6 +161,7 @@ struct cam_vfe_bus_ver3_vfe_out_hw_info {
 	uint32_t                            max_width;
 	uint32_t                            max_height;
 	uint32_t                            source_group;
+	uint32_t                         mid[CAM_VFE_BUS_VER3_MAX_MID_PER_PORT];
 };
 
 /*

+ 5 - 4
drivers/cam_jpeg/cam_jpeg_context.c

@@ -16,17 +16,18 @@
 
 static const char jpeg_dev_name[] = "cam-jpeg";
 
-static int cam_jpeg_context_dump_active_request(void *data, unsigned long iova,
-	uint32_t buf_info)
+static int cam_jpeg_context_dump_active_request(void *data,
+	struct cam_smmu_pf_info *pf_info)
 {
 
 	struct cam_context *ctx = (struct cam_context *)data;
 	struct cam_ctx_request          *req = NULL;
 	struct cam_ctx_request          *req_temp = NULL;
 	struct cam_hw_mgr_dump_pf_data  *pf_dbg_entry = NULL;
+	uint32_t  resource_type = 0;
 	int rc = 0;
 	int closest_port;
-	bool b_mem_found = false;
+	bool b_mem_found = false, b_ctx_found = false;
 
 
 	if (!ctx) {
@@ -44,7 +45,7 @@ static int cam_jpeg_context_dump_active_request(void *data, unsigned long iova,
 		CAM_INFO(CAM_JPEG, "req_id : %lld ", req->request_id);
 
 		rc = cam_context_dump_pf_info_to_hw(ctx, pf_dbg_entry->packet,
-			iova, buf_info, &b_mem_found);
+			&b_mem_found, &b_ctx_found, &resource_type, pf_info);
 		if (rc)
 			CAM_ERR(CAM_JPEG, "Failed to dump pf info");
 

+ 5 - 7
drivers/cam_jpeg/cam_jpeg_dev.c

@@ -22,22 +22,20 @@
 static struct cam_jpeg_dev g_jpeg_dev;
 
 static void cam_jpeg_dev_iommu_fault_handler(
-	struct iommu_domain *domain, struct device *dev, unsigned long iova,
-	int flags, void *token, uint32_t buf_info)
+	struct cam_smmu_pf_info *pf_info)
 {
 	int i = 0;
 	struct cam_node *node = NULL;
 
-	if (!token) {
-		CAM_ERR(CAM_JPEG, "invalid token in page handler cb");
+	if (!pf_info || !pf_info->token) {
+		CAM_ERR(CAM_ISP, "invalid token in page handler cb");
 		return;
 	}
 
-	node = (struct cam_node *)token;
+	node = (struct cam_node *)pf_info->token;
 
 	for (i = 0; i < node->ctx_size; i++)
-		cam_context_dump_pf_info(&(node->ctx_list[i]), iova,
-			buf_info);
+		cam_context_dump_pf_info(&(node->ctx_list[i]), pf_info);
 }
 
 static const struct of_device_id cam_jpeg_dt_match[] = {

+ 5 - 4
drivers/cam_ope/cam_ope_context.c

@@ -23,15 +23,16 @@
 
 static const char ope_dev_name[] = "cam-ope";
 
-static int cam_ope_context_dump_active_request(void *data, unsigned long iova,
-	uint32_t buf_info)
+static int cam_ope_context_dump_active_request(void *data,
+	struct cam_smmu_pf_info *pf_info)
 {
 	struct cam_context *ctx = (struct cam_context *)data;
 	struct cam_ctx_request          *req = NULL;
 	struct cam_ctx_request          *req_temp = NULL;
 	struct cam_hw_mgr_dump_pf_data  *pf_dbg_entry = NULL;
+	uint32_t  resource_type = 0;
 	int rc = 0;
-	bool b_mem_found = false;
+	bool b_mem_found = false, b_ctx_found = false;
 
 	if (!ctx) {
 		CAM_ERR(CAM_OPE, "Invalid ctx");
@@ -54,7 +55,7 @@ static int cam_ope_context_dump_active_request(void *data, unsigned long iova,
 		CAM_INFO(CAM_OPE, "req_id : %lld", req->request_id);
 
 		rc = cam_context_dump_pf_info_to_hw(ctx, pf_dbg_entry->packet,
-			iova, buf_info, &b_mem_found);
+			&b_mem_found, &b_ctx_found, &resource_type, pf_info);
 		if (rc)
 			CAM_ERR(CAM_OPE, "Failed to dump pf info");
 

+ 5 - 7
drivers/cam_ope/cam_ope_subdev.c

@@ -46,22 +46,20 @@ struct cam_ope_subdev {
 static struct cam_ope_subdev g_ope_dev;
 
 static void cam_ope_dev_iommu_fault_handler(
-	struct iommu_domain *domain, struct device *dev, unsigned long iova,
-	int flags, void *token, uint32_t buf_info)
+	struct cam_smmu_pf_info *pf_info)
 {
 	int i = 0;
 	struct cam_node *node = NULL;
 
-	if (!token) {
-		CAM_ERR(CAM_OPE, "invalid token in page handler cb");
+	if (!pf_info || !pf_info->token) {
+		CAM_ERR(CAM_ISP, "invalid token in page handler cb");
 		return;
 	}
 
-	node = (struct cam_node *)token;
+	node = (struct cam_node *)pf_info->token;
 
 	for (i = 0; i < node->ctx_size; i++)
-		cam_context_dump_pf_info(&(node->ctx_list[i]), iova,
-			buf_info);
+		cam_context_dump_pf_info(&(node->ctx_list[i]), pf_info);
 }
 
 static int cam_ope_subdev_open(struct v4l2_subdev *sd,

+ 33 - 10
drivers/cam_smmu/cam_smmu_api.c

@@ -47,7 +47,7 @@
 	div_u64_rem(atomic64_add_return(1, head),\
 	CAM_SMMU_MONITOR_MAX_ENTRIES, (ret))
 
-static int g_num_pf_handled = 4;
+static int g_num_pf_handled = 1;
 module_param(g_num_pf_handled, int, 0644);
 
 struct cam_fw_alloc_info icp_fw;
@@ -145,7 +145,7 @@ struct cam_context_bank_info {
 	int handle;
 	enum cam_smmu_ops_param state;
 
-	cam_smmu_client_page_fault_handler handler[CAM_SMMU_CB_MAX];
+	void (*handler[CAM_SMMU_CB_MAX]) (struct cam_smmu_pf_info  *pf_info);
 	void *token[CAM_SMMU_CB_MAX];
 	int cb_count;
 	int secure_count;
@@ -363,6 +363,8 @@ static void cam_smmu_page_fault_work(struct work_struct *work)
 	int idx;
 	struct cam_smmu_work_payload *payload;
 	uint32_t buf_info;
+	struct iommu_fault_ids fault_ids = {0, 0, 0};
+	struct cam_smmu_pf_info  pf_info;
 
 	mutex_lock(&iommu_cb_set.payload_list_lock);
 	if (list_empty(&iommu_cb_set.payload_list)) {
@@ -377,21 +379,33 @@ static void cam_smmu_page_fault_work(struct work_struct *work)
 	list_del(&payload->list);
 	mutex_unlock(&iommu_cb_set.payload_list_lock);
 
+
+	if ((iommu_get_fault_ids(payload->domain, &fault_ids)))
+		CAM_ERR(CAM_SMMU,
+			"Error: Can not get smmu fault ids");
+
+	CAM_ERR(CAM_SMMU, "smmu fault ids bid:%d pid:%d mid:%d",
+		fault_ids.bid, fault_ids.pid, fault_ids.mid);
+
 	/* Dereference the payload to call the handler */
 	idx = payload->idx;
 	buf_info = cam_smmu_find_closest_mapping(idx, (void *)payload->iova);
 	if (buf_info != 0)
 		CAM_INFO(CAM_SMMU, "closest buf 0x%x idx %d", buf_info, idx);
 
+	pf_info.domain = payload->domain;
+	pf_info.dev    = payload->dev;
+	pf_info.iova  = payload->iova;
+	pf_info.flags = payload->flags;
+	pf_info.buf_info = buf_info;
+	pf_info.bid = fault_ids.bid;
+	pf_info.pid = fault_ids.pid;
+	pf_info.mid = fault_ids.mid;
+
 	for (j = 0; j < CAM_SMMU_CB_MAX; j++) {
 		if ((iommu_cb_set.cb_info[idx].handler[j])) {
-			iommu_cb_set.cb_info[idx].handler[j](
-				payload->domain,
-				payload->dev,
-				payload->iova,
-				payload->flags,
-				iommu_cb_set.cb_info[idx].token[j],
-				buf_info);
+			pf_info.token = iommu_cb_set.cb_info[idx].token[j];
+			iommu_cb_set.cb_info[idx].handler[j](&pf_info);
 		}
 	}
 	cam_smmu_dump_cb_info(idx);
@@ -565,7 +579,7 @@ end:
 }
 
 void cam_smmu_set_client_page_fault_handler(int handle,
-	cam_smmu_client_page_fault_handler handler_cb, void *token)
+	void (*handler_cb)(struct cam_smmu_pf_info  *pf_info), void *token)
 {
 	int idx, i = 0;
 
@@ -726,6 +740,15 @@ static int cam_smmu_iommu_fault_handler(struct iommu_domain *domain,
 	return -EINVAL;
 }
 
+void cam_smmu_reset_cb_page_fault_cnt(void)
+{
+	int idx;
+
+	for (idx = 0; idx < iommu_cb_set.cb_num; idx++)
+		iommu_cb_set.cb_info[idx].pf_count = 0;
+
+}
+
 static int cam_smmu_translate_dir_to_iommu_dir(
 	enum cam_smmu_map_dir dir)
 {

+ 25 - 6
drivers/cam_smmu/cam_smmu_api.h

@@ -43,8 +43,7 @@ enum cam_smmu_region_id {
 };
 
 /**
- * @brief        : Callback function type that gets called back on cam
- *                     smmu page fault.
+ * @brief          : cam_smmu_pf_info
  *
  * @param domain   : Iommu domain received in iommu page fault handler
  * @param dev      : Device received in iommu page fault handler
@@ -52,10 +51,22 @@ enum cam_smmu_region_id {
  * @param flags    : Flags received in iommu page fault handler
  * @param token    : Userdata given during callback registration
  * @param buf_info : Closest mapped buffer info
+ * @bid            : bus id
+ * @pid            : unique id for hw group of ports
+ * @mid            : port id of hw
  */
-typedef void (*cam_smmu_client_page_fault_handler)(struct iommu_domain *domain,
-	struct device *dev, unsigned long iova, int flags, void *token,
-	uint32_t buf_info);
+
+struct cam_smmu_pf_info {
+	struct iommu_domain *domain;
+	struct device        *dev;
+	unsigned long        iova;
+	int                  flags;
+	void                *token;
+	uint32_t             buf_info;
+	uint32_t             bid;
+	uint32_t             pid;
+	uint32_t             mid;
+};
 
 /**
  * @brief            : Structure to store region information
@@ -234,7 +245,7 @@ int cam_smmu_find_index_by_handle(int hdl);
  * @param token: It is input param when trigger page fault handler
  */
 void cam_smmu_set_client_page_fault_handler(int handle,
-	cam_smmu_client_page_fault_handler handler_cb, void *token);
+	void (*handler_cb)(struct cam_smmu_pf_info  *pf_info), void *token);
 
 /**
  * @brief       : Unregisters smmu fault handler for client
@@ -403,6 +414,13 @@ int cam_smmu_get_io_region_info(int32_t smmu_hdl,
 	dma_addr_t *iova, size_t *len,
 	dma_addr_t *discard_iova_start, size_t *discard_iova_len);
 
+/**
+ * @brief : API to reset the call context bank page fault count
+ *          This should be done on the starting of new camera open
+ * @return void.
+ */
+void cam_smmu_reset_cb_page_fault_cnt(void);
+
 /**
  * @brief : API to register SMMU hw to platform framework.
  * @return struct platform_device pointer on on success, or ERR_PTR() on error.
@@ -413,4 +431,5 @@ int cam_smmu_init_module(void);
  * @brief : API to remove SMMU Hw from platform framework.
  */
 void cam_smmu_exit_module(void);
+
 #endif /* _CAM_SMMU_API_H_ */

+ 2 - 1
include/uapi/camera/media/cam_req_mgr.h

@@ -424,6 +424,7 @@ struct cam_mem_cache_ops_cmd {
  * @CAM_REQ_MGR_ERROR_TYPE_BUFFER: Buffer was not filled, not fatal
  * @CAM_REQ_MGR_ERROR_TYPE_RECOVERY: Fatal error, can be recovered
  * @CAM_REQ_MGR_ERROR_TYPE_SOF_FREEZE: SOF freeze, can be recovered
+ * @CAM_REQ_MGR_ERROR_TYPE_PAGE_FAULT: page fault, can be recovered
  */
 #define CAM_REQ_MGR_ERROR_TYPE_DEVICE           0
 #define CAM_REQ_MGR_ERROR_TYPE_REQUEST          1
@@ -431,7 +432,7 @@ struct cam_mem_cache_ops_cmd {
 #define CAM_REQ_MGR_ERROR_TYPE_RECOVERY         3
 #define CAM_REQ_MGR_ERROR_TYPE_SOF_FREEZE       4
 #define CAM_REQ_MGR_ERROR_TYPE_FULL_RECOVERY    5
-
+#define CAM_REQ_MGR_ERROR_TYPE_PAGE_FAULT       6
 
 /**
  * struct cam_req_mgr_error_msg