Pārlūkot izejas kodu

Merge "msm: camera: core: Send event on smmu page fault" into camera-kernel.lnx.4.0

Camera Software Integration 4 gadi atpakaļ
vecāks
revīzija
73fd4e6bef
35 mainītis faili ar 728 papildinājumiem un 162 dzēšanām
  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

@@ -998,8 +998,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;
@@ -1021,9 +1021,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,
@@ -295,6 +297,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 {
@@ -302,6 +309,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);
@@ -5423,9 +5423,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;
@@ -5434,7 +5433,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 =
@@ -5457,13 +5459,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",
@@ -5477,13 +5478,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;
 	}
 
 	/*
@@ -5508,15 +5508,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