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

Merge changes Ifd1e0fdb,Icfb6dc1a into camera-kernel.lnx.5.0

* changes:
  msm: camera: common: Add buffer send and receive mechanism
  msm: camera: memmgr: Add presil memory API implementation
Camera Software Integration 3 жил өмнө
parent
commit
cfa89c05e4
33 өөрчлөгдсөн 632 нэмэгдсэн , 55 устгасан
  1. 31 0
      drivers/cam_cdm/cam_cdm_hw_core.c
  2. 2 1
      drivers/cam_core/cam_context.c
  3. 4 2
      drivers/cam_core/cam_context.h
  4. 11 0
      drivers/cam_core/cam_context_utils.c
  5. 2 2
      drivers/cam_cre/cam_cre_context.c
  6. 3 1
      drivers/cam_cre/cam_cre_context.h
  7. 1 1
      drivers/cam_cre/cam_cre_dev.c
  8. 2 2
      drivers/cam_cust/cam_custom_context.c
  9. 2 1
      drivers/cam_cust/cam_custom_context.h
  10. 1 1
      drivers/cam_cust/cam_custom_dev.c
  11. 2 2
      drivers/cam_fd/cam_fd_context.c
  12. 1 1
      drivers/cam_fd/cam_fd_context.h
  13. 1 1
      drivers/cam_fd/cam_fd_dev.c
  14. 2 2
      drivers/cam_icp/cam_icp_context.c
  15. 3 1
      drivers/cam_icp/cam_icp_context.h
  16. 1 1
      drivers/cam_icp/cam_icp_subdev.c
  17. 27 3
      drivers/cam_isp/cam_isp_context.c
  18. 3 1
      drivers/cam_isp/cam_isp_context.h
  19. 1 1
      drivers/cam_isp/cam_isp_dev.c
  20. 15 0
      drivers/cam_isp/isp_hw_mgr/cam_ife_hw_mgr.c
  21. 3 2
      drivers/cam_jpeg/cam_jpeg_context.c
  22. 3 1
      drivers/cam_jpeg/cam_jpeg_context.h
  23. 1 1
      drivers/cam_jpeg/cam_jpeg_dev.c
  24. 3 2
      drivers/cam_lrme/cam_lrme_context.c
  25. 1 1
      drivers/cam_lrme/cam_lrme_context.h
  26. 1 1
      drivers/cam_lrme/cam_lrme_dev.c
  27. 2 2
      drivers/cam_ope/cam_ope_context.c
  28. 3 1
      drivers/cam_ope/cam_ope_context.h
  29. 1 1
      drivers/cam_ope/cam_ope_subdev.c
  30. 280 2
      drivers/cam_req_mgr/cam_mem_mgr.c
  31. 28 16
      drivers/cam_req_mgr/cam_mem_mgr.h
  32. 166 0
      drivers/cam_utils/cam_packet_util.c
  33. 25 1
      drivers/cam_utils/cam_packet_util.h

+ 31 - 0
drivers/cam_cdm/cam_cdm_hw_core.c

@@ -829,6 +829,21 @@ int cam_hw_cdm_submit_gen_irq(
 		goto end;
 	}
 
+	if (cam_presil_mode_enabled()) {
+		CAM_DBG(CAM_PRESIL,
+			"Sending CDM gen irq cmd buffer:%d with iommu_hdl:%d",
+			core->gen_irq[fifo_idx].handle, core->iommu_hdl.non_secure);
+
+		rc = cam_mem_mgr_send_buffer_to_presil(core->iommu_hdl.non_secure,
+			core->gen_irq[fifo_idx].handle);
+		if (rc) {
+			CAM_ERR(CAM_PRESIL,
+				"Failed to send CDM gen irq cmd buffer fifo_idx:%d mem_handle:%d rc:%d",
+				fifo_idx, core->gen_irq[fifo_idx].handle, rc);
+			goto end;
+		}
+	}
+
 	if (cam_hw_cdm_commit_bl_write(cdm_hw, fifo_idx)) {
 		CAM_ERR(CAM_CDM,
 			"Cannot commit the genirq BL with tag tag=%d",
@@ -948,6 +963,22 @@ static int cam_hw_cdm_arb_submit_bl(struct cam_hw_info *cdm_hw,
 			kfree(node);
 			return -EIO;
 	}
+
+	if (cam_presil_mode_enabled()) {
+		CAM_DBG(CAM_PRESIL,
+			"Sending CDM arb cmd buffer:%d with iommu_hdl:%d",
+			cdm_cmd->cmd[i].bl_addr.mem_handle, core->iommu_hdl.non_secure);
+
+		rc = cam_mem_mgr_send_buffer_to_presil(core->iommu_hdl.non_secure,
+			cdm_cmd->cmd[i].bl_addr.mem_handle);
+		if (rc) {
+			CAM_ERR(CAM_PRESIL,
+				"Failed to send CDM arb cmd buffer i:%d mem_handle:%d rc:%d",
+				i, cdm_cmd->cmd[i].bl_addr.mem_handle, rc);
+			return rc;
+		}
+	}
+
 	rc = cam_hw_cdm_commit_bl_write(cdm_hw,
 		fifo_idx);
 	if (rc) {

+ 2 - 1
drivers/cam_core/cam_context.c

@@ -729,7 +729,7 @@ int cam_context_init(struct cam_context *ctx,
 	struct cam_req_mgr_kmd_ops *crm_node_intf,
 	struct cam_hw_mgr_intf *hw_mgr_intf,
 	struct cam_ctx_request *req_list,
-	uint32_t req_size)
+	uint32_t req_size, int img_iommu_hdl)
 {
 	int i;
 
@@ -772,6 +772,7 @@ int cam_context_init(struct cam_context *ctx,
 	ctx->state = CAM_CTX_AVAILABLE;
 	ctx->state_machine = NULL;
 	ctx->ctx_priv = NULL;
+	ctx->img_iommu_hdl = img_iommu_hdl;
 
 	return 0;
 }

+ 4 - 2
drivers/cam_core/cam_context.h

@@ -221,6 +221,7 @@ struct cam_ctx_ops {
  * @in_map_entries:        In map update entry
  * @out_map_entries:       Out map entry
  * @mini dump cb:          Mini dump cb
+ * @img_iommu_hdl:         Image IOMMU handle
  *
  */
 struct cam_context {
@@ -266,7 +267,7 @@ struct cam_context {
 	struct cam_hw_fence_map_entry *in_map_entries;
 	struct cam_hw_fence_map_entry *out_map_entries;
 	cam_ctx_mini_dump_cb_func      mini_dump_cb;
-
+	int                            img_iommu_hdl;
 };
 
 /**
@@ -592,6 +593,7 @@ int cam_context_deinit(struct cam_context *ctx);
  * @hw_mgr_intf:           Function table for context to hw interface
  * @req_list:              Requests storage
  * @req_size:              Size of the request storage
+ * @img_iommu_hdl:         IOMMU Handle for image buffers
  *
  */
 int cam_context_init(struct cam_context *ctx,
@@ -601,7 +603,7 @@ int cam_context_init(struct cam_context *ctx,
 		struct cam_req_mgr_kmd_ops *crm_node_intf,
 		struct cam_hw_mgr_intf *hw_mgr_intf,
 		struct cam_ctx_request *req_list,
-		uint32_t req_size);
+		uint32_t req_size, int img_iommu_hdl);
 
 /**
  * cam_context_putref()

+ 11 - 0
drivers/cam_core/cam_context_utils.c

@@ -19,6 +19,7 @@
 #include "cam_trace.h"
 #include "cam_debug_util.h"
 #include "cam_cpas_api.h"
+#include "cam_packet_util.h"
 
 static uint cam_debug_ctx_req_list;
 module_param(cam_debug_ctx_req_list, uint, 0644);
@@ -173,6 +174,16 @@ int cam_context_buf_done_from_hw(struct cam_context *ctx,
 		ctx->dev_name, ctx->ctx_id, req->request_id, result);
 
 	for (j = 0; j < req->num_out_map_entries; j++) {
+		/* Get buf handles from packet and retrieve them from presil framework */
+		if (cam_presil_mode_enabled()) {
+			rc = cam_presil_retrieve_buffers_from_packet(req->pf_data.packet,
+				ctx->img_iommu_hdl, req->out_map_entries[j].resource_handle);
+			if (rc) {
+				CAM_ERR(CAM_CTXT, "Failed to retrieve image buffers rc:%d", rc);
+				return rc;
+			}
+		}
+
 		CAM_DBG(CAM_REQ, "fence %d signal with %d",
 			req->out_map_entries[j].sync_id, result);
 		cam_sync_signal(req->out_map_entries[j].sync_id, result,

+ 2 - 2
drivers/cam_cre/cam_cre_context.c

@@ -239,7 +239,7 @@ static struct cam_ctx_ops
 
 int cam_cre_context_init(struct cam_cre_context *ctx,
 	struct cam_hw_mgr_intf *hw_intf,
-	uint32_t ctx_id)
+	uint32_t ctx_id, int img_iommu_hdl)
 {
 	int rc;
 	int i;
@@ -254,7 +254,7 @@ int cam_cre_context_init(struct cam_cre_context *ctx,
 		ctx->req_base[i].req_priv = ctx;
 
 	rc = cam_context_init(ctx->base, cre_dev_name, CAM_CRE, ctx_id,
-		NULL, hw_intf, ctx->req_base, CAM_CTX_REQ_MAX);
+		NULL, hw_intf, ctx->req_base, CAM_CTX_REQ_MAX, img_iommu_hdl);
 	if (rc) {
 		CAM_ERR(CAM_CRE, "Camera Context Base init failed");
 		goto err;

+ 3 - 1
drivers/cam_cre/cam_cre_context.h

@@ -46,11 +46,13 @@ struct cam_cre_ctx_irq_ops {
  * @ctx: CRE context obj to be initialized
  * @hw_intf: CRE hw manager interface
  * @ctx_id: ID for this context
+ * @img_iommu_hdl: IOMMU HDL for image buffers
  *
  */
 int cam_cre_context_init(struct cam_cre_context *ctx,
 	struct cam_hw_mgr_intf *hw_intf,
-	uint32_t ctx_id);
+	uint32_t ctx_id,
+	int img_iommu_hdl);
 
 /**
  * cam_cre_context_deinit()

+ 1 - 1
drivers/cam_cre/cam_cre_dev.c

@@ -144,7 +144,7 @@ static int cam_cre_subdev_component_bind(struct device *dev,
 	for (i = 0; i < CAM_CRE_CTX_MAX; i++) {
 		g_cre_dev.ctx_cre[i].base = &g_cre_dev.ctx[i];
 		rc = cam_cre_context_init(&g_cre_dev.ctx_cre[i],
-			hw_mgr_intf, i);
+			hw_mgr_intf, i, iommu_hdl);
 		if (rc) {
 			CAM_ERR(CAM_CRE, "CRE context init failed %d %d",
 				i, rc);

+ 2 - 2
drivers/cam_cust/cam_custom_context.c

@@ -1683,7 +1683,7 @@ int cam_custom_dev_context_init(struct cam_custom_context *ctx,
 	struct cam_context *ctx_base,
 	struct cam_req_mgr_kmd_ops *crm_node_intf,
 	struct cam_hw_mgr_intf *hw_intf,
-	uint32_t ctx_id)
+	uint32_t ctx_id, int img_iommu_hdl)
 {
 	int rc = -1, i = 0;
 
@@ -1707,7 +1707,7 @@ int cam_custom_dev_context_init(struct cam_custom_context *ctx,
 
 	/* camera context setup */
 	rc = cam_context_init(ctx_base, custom_dev_name, CAM_CUSTOM, ctx_id,
-		crm_node_intf, hw_intf, ctx->req_base, CAM_CTX_REQ_MAX);
+		crm_node_intf, hw_intf, ctx->req_base, CAM_CTX_REQ_MAX, img_iommu_hdl);
 	if (rc) {
 		CAM_ERR(CAM_CUSTOM, "Camera Context Base init failed");
 		return rc;

+ 2 - 1
drivers/cam_cust/cam_custom_context.h

@@ -132,13 +132,14 @@ struct cam_custom_context {
  * @bridge_ops:         Bridge call back funciton
  * @hw_intf:            Cust hw manager interface
  * @ctx_id:             ID for this context
+ * @img_iommu_hdl:      IOMMU HDL for Image buffers
  *
  */
 int cam_custom_dev_context_init(struct cam_custom_context *ctx,
 	struct cam_context *ctx_base,
 	struct cam_req_mgr_kmd_ops *bridge_ops,
 	struct cam_hw_mgr_intf *hw_intf,
-	uint32_t ctx_id);
+	uint32_t ctx_id, int img_iommu_hdl);
 
 /**
  * cam_custom_dev_context_deinit()

+ 1 - 1
drivers/cam_cust/cam_custom_dev.c

@@ -138,7 +138,7 @@ static int cam_custom_component_bind(struct device *dev,
 			&g_custom_dev.ctx[i],
 			&node->crm_node_intf,
 			&node->hw_mgr_intf,
-			i);
+			i, iommu_hdl);
 		if (rc) {
 			CAM_ERR(CAM_CUSTOM, "Custom context init failed!");
 			goto unregister;

+ 2 - 2
drivers/cam_fd/cam_fd_context.c

@@ -223,7 +223,7 @@ static struct cam_ctx_ops
 
 int cam_fd_context_init(struct cam_fd_context *fd_ctx,
 	struct cam_context *base_ctx, struct cam_hw_mgr_intf *hw_intf,
-	uint32_t ctx_id)
+	uint32_t ctx_id, int img_iommu_hdl)
 {
 	int rc;
 
@@ -235,7 +235,7 @@ int cam_fd_context_init(struct cam_fd_context *fd_ctx,
 	memset(fd_ctx, 0, sizeof(*fd_ctx));
 
 	rc = cam_context_init(base_ctx, fd_dev_name, CAM_FD, ctx_id,
-		NULL, hw_intf, fd_ctx->req_base, CAM_CTX_REQ_MAX);
+		NULL, hw_intf, fd_ctx->req_base, CAM_CTX_REQ_MAX, img_iommu_hdl);
 	if (rc) {
 		CAM_ERR(CAM_FD, "Camera Context Base init failed, rc=%d", rc);
 		return rc;

+ 1 - 1
drivers/cam_fd/cam_fd_context.h

@@ -24,7 +24,7 @@ struct cam_fd_context {
 
 int cam_fd_context_init(struct cam_fd_context *fd_ctx,
 	struct cam_context *base_ctx, struct cam_hw_mgr_intf *hw_intf,
-	uint32_t ctx_id);
+	uint32_t ctx_id, int img_iommu_hdl);
 int cam_fd_context_deinit(struct cam_fd_context *ctx);
 
 #endif /* _CAM_FD_CONTEXT_H_ */

+ 1 - 1
drivers/cam_fd/cam_fd_dev.c

@@ -136,7 +136,7 @@ static int cam_fd_dev_component_bind(struct device *dev,
 
 	for (i = 0; i < CAM_CTX_MAX; i++) {
 		rc = cam_fd_context_init(&g_fd_dev.fd_ctx[i],
-			&g_fd_dev.base_ctx[i], &node->hw_mgr_intf, i);
+			&g_fd_dev.base_ctx[i], &node->hw_mgr_intf, i, -1);
 		if (rc) {
 			CAM_ERR(CAM_FD, "FD context init failed i=%d, rc=%d",
 				i, rc);

+ 2 - 2
drivers/cam_icp/cam_icp_context.c

@@ -300,7 +300,7 @@ static struct cam_ctx_ops
 };
 
 int cam_icp_context_init(struct cam_icp_context *ctx,
-	struct cam_hw_mgr_intf *hw_intf, uint32_t ctx_id)
+	struct cam_hw_mgr_intf *hw_intf, uint32_t ctx_id, int img_iommu_hdl)
 {
 	int rc;
 
@@ -311,7 +311,7 @@ int cam_icp_context_init(struct cam_icp_context *ctx,
 	}
 
 	rc = cam_context_init(ctx->base, icp_dev_name, CAM_ICP, ctx_id,
-		NULL, hw_intf, ctx->req_base, CAM_CTX_ICP_REQ_MAX);
+		NULL, hw_intf, ctx->req_base, CAM_CTX_ICP_REQ_MAX, img_iommu_hdl);
 	if (rc) {
 		CAM_ERR(CAM_ICP, "Camera Context Base init failed");
 		goto err;

+ 3 - 1
drivers/cam_icp/cam_icp_context.h

@@ -29,9 +29,11 @@ struct cam_icp_context {
  * @ctx: Pointer to context
  * @hw_intf: Pointer to ICP hardware interface
  * @ctx_id: ID for this context
+ * @img_iommu_hdl: IOMMU HDL for image buffers
+ *
  */
 int cam_icp_context_init(struct cam_icp_context *ctx,
-	struct cam_hw_mgr_intf *hw_intf, uint32_t ctx_id);
+	struct cam_hw_mgr_intf *hw_intf, uint32_t ctx_id, int img_iommu_hdl);
 
 /**
  * cam_icp_context_deinit() - ICP context deinit

+ 1 - 1
drivers/cam_icp/cam_icp_subdev.c

@@ -209,7 +209,7 @@ static int cam_icp_component_bind(struct device *dev,
 	for (i = 0; i < CAM_ICP_CTX_MAX; i++) {
 		g_icp_dev.ctx_icp[i].base = &g_icp_dev.ctx[i];
 		rc = cam_icp_context_init(&g_icp_dev.ctx_icp[i],
-					hw_mgr_intf, i);
+					hw_mgr_intf, i, iommu_hdl);
 		if (rc) {
 			CAM_ERR(CAM_ICP, "ICP context init failed");
 			goto ctx_fail;

+ 27 - 3
drivers/cam_isp/cam_isp_context.c

@@ -1213,6 +1213,18 @@ static int __cam_isp_ctx_handle_buf_done_for_request(
 			continue;
 		}
 
+		/* Get buf handles from packet and retrieve them from presil framework */
+		if (cam_presil_mode_enabled()) {
+			rc = cam_presil_retrieve_buffers_from_packet(req_isp->hw_update_data.packet,
+				ctx->img_iommu_hdl, req_isp->fence_map_out[i].resource_handle);
+			if (rc) {
+				CAM_ERR(CAM_ISP,
+					"Failed to retrieve image buffers req_id:%d ctx_id:%d bubble detected:%d rc:%d",
+					req->request_id, ctx->ctx_id, req_isp->bubble_detected, rc);
+				return rc;
+			}
+		}
+
 		if (!req_isp->bubble_detected) {
 			if (req_isp->is_sync_mode) {
 				CAM_DBG(CAM_ISP,
@@ -1424,6 +1436,18 @@ static int __cam_isp_ctx_handle_buf_done_for_request_verify_addr(
 			continue;
 		}
 
+		/* Get buf handles from packet and retrieve them from presil framework */
+		if (cam_presil_mode_enabled()) {
+			rc = cam_presil_retrieve_buffers_from_packet(req_isp->hw_update_data.packet,
+				ctx->img_iommu_hdl, req_isp->fence_map_out[i].resource_handle);
+			if (rc) {
+				CAM_ERR(CAM_ISP,
+					"Failed to retrieve image buffers req_id:%d ctx_id:%d bubble detected:%d rc:%d",
+					req->request_id, ctx->ctx_id, req_isp->bubble_detected, rc);
+				return rc;
+			}
+		}
+
 		if (defer_buf_done) {
 			uint32_t deferred_indx = req_isp->num_deferred_acks;
 
@@ -6911,8 +6935,8 @@ int cam_isp_context_init(struct cam_isp_context *ctx,
 	struct cam_req_mgr_kmd_ops *crm_node_intf,
 	struct cam_hw_mgr_intf *hw_intf,
 	uint32_t ctx_id,
-	uint32_t isp_device_type)
-
+	uint32_t isp_device_type,
+	int img_iommu_hdl)
 {
 	int rc = -1;
 	int i;
@@ -6951,7 +6975,7 @@ int cam_isp_context_init(struct cam_isp_context *ctx,
 
 	/* camera context setup */
 	rc = cam_context_init(ctx_base, isp_dev_name, CAM_ISP, ctx_id,
-		crm_node_intf, hw_intf, ctx->req_base, CAM_ISP_CTX_REQ_MAX);
+		crm_node_intf, hw_intf, ctx->req_base, CAM_ISP_CTX_REQ_MAX, img_iommu_hdl);
 	if (rc) {
 		CAM_ERR(CAM_ISP, "Camera Context Base init failed");
 		goto err;

+ 3 - 1
drivers/cam_isp/cam_isp_context.h

@@ -474,6 +474,7 @@ struct cam_isp_ctx_mini_dump_info {
  * @hw_intf:            ISP hw manager interface
  * @ctx_id:             ID for this context
  * @isp_device_type     Isp device type
+ * @img_iommu_hdl       IOMMU HDL for image buffers
  *
  */
 int cam_isp_context_init(struct cam_isp_context *ctx,
@@ -481,7 +482,8 @@ int cam_isp_context_init(struct cam_isp_context *ctx,
 	struct cam_req_mgr_kmd_ops *bridge_ops,
 	struct cam_hw_mgr_intf *hw_intf,
 	uint32_t ctx_id,
-	uint32_t isp_device_type);
+	uint32_t isp_device_type,
+	int img_iommu_hdl);
 
 /**
  * cam_isp_context_deinit()

+ 1 - 1
drivers/cam_isp/cam_isp_dev.c

@@ -173,7 +173,7 @@ static int cam_isp_dev_component_bind(struct device *dev,
 			&node->crm_node_intf,
 			&node->hw_mgr_intf,
 			i,
-			g_isp_dev.isp_device_type);
+			g_isp_dev.isp_device_type, iommu_hdl);
 		if (rc) {
 			CAM_ERR(CAM_ISP, "ISP context init failed!");
 			goto kfree;

+ 15 - 0
drivers/cam_isp/isp_hw_mgr/cam_ife_hw_mgr.c

@@ -24,8 +24,10 @@
 #include "cam_packet_util.h"
 #include "cam_debug_util.h"
 #include "cam_cpas_api.h"
+#include "cam_mem_mgr.h"
 #include "cam_mem_mgr_api.h"
 #include "cam_common_util.h"
+#include "cam_presil_hw_access.h"
 
 #define CAM_IFE_SAFE_DISABLE 0
 #define CAM_IFE_SAFE_ENABLE 1
@@ -5809,6 +5811,19 @@ static int cam_ife_mgr_config_hw(void *hw_mgr_priv,
 		}
 		cdm_cmd->cmd_arrary_count = cfg->num_hw_update_entries - skip;
 
+		if (cam_presil_mode_enabled()) {
+			CAM_INFO(CAM_ISP, "Sending relevant buffers for request:%llu to presil",
+				cfg->request_id);
+			rc = cam_presil_send_buffers_from_packet(hw_update_data->packet,
+				g_ife_hw_mgr.mgr_common.img_iommu_hdl,
+				g_ife_hw_mgr.mgr_common.cmd_iommu_hdl);
+			if (rc) {
+				CAM_ERR(CAM_ISP, "Error sending buffers for request:%llu to presil",
+					cfg->request_id);
+				return rc;
+			}
+		}
+
 		reinit_completion(&ctx->config_done_complete);
 		ctx->applied_req_id = cfg->request_id;
 

+ 3 - 2
drivers/cam_jpeg/cam_jpeg_context.c

@@ -202,7 +202,8 @@ static struct cam_ctx_ops
 int cam_jpeg_context_init(struct cam_jpeg_context *ctx,
 	struct cam_context *ctx_base,
 	struct cam_hw_mgr_intf *hw_intf,
-	uint32_t ctx_id)
+	uint32_t ctx_id,
+	int img_iommu_hdl)
 {
 	int rc;
 	int i;
@@ -221,7 +222,7 @@ int cam_jpeg_context_init(struct cam_jpeg_context *ctx,
 		ctx->req_base[i].req_priv = &ctx->jpeg_req[i];
 
 	rc = cam_context_init(ctx_base, jpeg_dev_name, CAM_JPEG, ctx_id,
-		NULL, hw_intf, ctx->req_base, CAM_CTX_REQ_MAX);
+		NULL, hw_intf, ctx->req_base, CAM_CTX_REQ_MAX, img_iommu_hdl);
 	if (rc) {
 		CAM_ERR(CAM_JPEG, "Camera Context Base init failed");
 		goto err;

+ 3 - 1
drivers/cam_jpeg/cam_jpeg_context.h

@@ -49,12 +49,14 @@ struct cam_jpeg_ctx_irq_ops {
  * @ctx_base: Context base from cam_context
  * @hw_intf: JPEG hw manager interface
  * @ctx_id: ID for this context
+ * @img_iommu_hdl: IOMMU HDL for image buffers
  *
  */
 int cam_jpeg_context_init(struct cam_jpeg_context *ctx,
 	struct cam_context *ctx_base,
 	struct cam_hw_mgr_intf *hw_intf,
-	uint32_t ctx_id);
+	uint32_t ctx_id,
+	int img_iommu_hdl);
 
 /**
  * cam_jpeg_context_deinit()

+ 1 - 1
drivers/cam_jpeg/cam_jpeg_dev.c

@@ -147,7 +147,7 @@ static int cam_jpeg_dev_component_bind(struct device *dev,
 		rc = cam_jpeg_context_init(&g_jpeg_dev.ctx_jpeg[i],
 			&g_jpeg_dev.ctx[i],
 			&node->hw_mgr_intf,
-			i);
+			i, iommu_hdl);
 		if (rc) {
 			CAM_ERR(CAM_JPEG, "JPEG context init failed %d %d",
 				i, rc);

+ 3 - 2
drivers/cam_lrme/cam_lrme_context.c

@@ -226,7 +226,8 @@ static struct cam_ctx_ops
 int cam_lrme_context_init(struct cam_lrme_context *lrme_ctx,
 	struct cam_context *base_ctx,
 	struct cam_hw_mgr_intf *hw_intf,
-	uint32_t index)
+	uint32_t index
+	int img_iommu_hdl)
 {
 	int rc = 0;
 
@@ -240,7 +241,7 @@ int cam_lrme_context_init(struct cam_lrme_context *lrme_ctx,
 	memset(lrme_ctx, 0, sizeof(*lrme_ctx));
 
 	rc = cam_context_init(base_ctx, lrme_dev_name, CAM_LRME, index,
-		NULL, hw_intf, lrme_ctx->req_base, CAM_CTX_REQ_MAX);
+		NULL, hw_intf, lrme_ctx->req_base, CAM_CTX_REQ_MAX, img_iommu_hdl);
 	if (rc) {
 		CAM_ERR(CAM_LRME, "Failed to init context");
 		return rc;

+ 1 - 1
drivers/cam_lrme/cam_lrme_context.h

@@ -27,7 +27,7 @@ struct cam_lrme_context {
 
 int cam_lrme_context_init(struct cam_lrme_context *lrme_ctx,
 	struct cam_context *base_ctx, struct cam_hw_mgr_intf *hw_intf,
-	uint32_t index);
+	uint32_t index, int img_iommu_hdl);
 int cam_lrme_context_deinit(struct cam_lrme_context *lrme_ctx);
 
 #endif /* _CAM_LRME_CONTEXT_H_ */

+ 1 - 1
drivers/cam_lrme/cam_lrme_dev.c

@@ -159,7 +159,7 @@ static int cam_lrme_component_bind(struct device *dev,
 	for (i = 0; i < CAM_CTX_MAX; i++) {
 		rc = cam_lrme_context_init(&g_lrme_dev->lrme_ctx[i],
 				&g_lrme_dev->ctx[i],
-				&node->hw_mgr_intf, i);
+				&node->hw_mgr_intf, i, -1);
 		if (rc) {
 			CAM_ERR(CAM_LRME, "LRME context init failed");
 			goto deinit_ctx;

+ 2 - 2
drivers/cam_ope/cam_ope_context.c

@@ -251,7 +251,7 @@ static struct cam_ctx_ops
 };
 
 int cam_ope_context_init(struct cam_ope_context *ctx,
-	struct cam_hw_mgr_intf *hw_intf, uint32_t ctx_id)
+	struct cam_hw_mgr_intf *hw_intf, uint32_t ctx_id, int img_iommu_hdl)
 {
 	int rc;
 
@@ -262,7 +262,7 @@ int cam_ope_context_init(struct cam_ope_context *ctx,
 	}
 
 	rc = cam_context_init(ctx->base, ope_dev_name, CAM_OPE, ctx_id,
-		NULL, hw_intf, ctx->req_base, CAM_CTX_REQ_MAX);
+		NULL, hw_intf, ctx->req_base, CAM_CTX_REQ_MAX, img_iommu_hdl);
 	if (rc) {
 		CAM_ERR(CAM_OPE, "Camera Context Base init failed");
 		goto err;

+ 3 - 1
drivers/cam_ope/cam_ope_context.h

@@ -31,9 +31,11 @@ struct cam_ope_context {
  * @ctx:     Pointer to context
  * @hw_intf: Pointer to OPE hardware interface
  * @ctx_id:  ID for this context
+ * @img_iommu_hdl: IOMMU HDL for image buffers
+ *
  */
 int cam_ope_context_init(struct cam_ope_context *ctx,
-	struct cam_hw_mgr_intf *hw_intf, uint32_t ctx_id);
+	struct cam_hw_mgr_intf *hw_intf, uint32_t ctx_id, int img_iommu_hdl);
 
 /**
  * cam_ope_context_deinit() - OPE context deinit

+ 1 - 1
drivers/cam_ope/cam_ope_subdev.c

@@ -195,7 +195,7 @@ static int cam_ope_subdev_component_bind(struct device *dev,
 	for (i = 0; i < OPE_CTX_MAX; i++) {
 		g_ope_dev.ctx_ope[i].base = &g_ope_dev.ctx[i];
 		rc = cam_ope_context_init(&g_ope_dev.ctx_ope[i],
-			hw_mgr_intf, i);
+			hw_mgr_intf, i, iommu_hdl);
 		if (rc) {
 			CAM_ERR(CAM_OPE, "OPE context init failed");
 			goto ctx_fail;

+ 280 - 2
drivers/cam_req_mgr/cam_mem_mgr.c

@@ -22,6 +22,7 @@
 #include "cam_debug_util.h"
 #include "cam_trace.h"
 #include "cam_common_util.h"
+#include "cam_presil_hw_access.h"
 
 #define CAM_MEM_SHARED_BUFFER_PAD_4K (4 * 1024)
 
@@ -33,6 +34,19 @@ static void cam_mem_mgr_put_dma_heaps(void);
 static int cam_mem_mgr_get_dma_heaps(void);
 #endif
 
+#ifdef CONFIG_CAM_PRESIL
+static inline void cam_mem_mgr_reset_presil_params(int idx)
+{
+        tbl.bufq[idx].presil_params.fd_for_umd_daemon = -1;
+        tbl.bufq[idx].presil_params.refcount = 0;
+}
+#else
+static inline void cam_mem_mgr_reset_presil_params(int idx)
+{
+        return;
+}
+#endif
+
 static unsigned long cam_mem_mgr_mini_dump_cb(void *dst, unsigned long len)
 {
 	struct cam_mem_table_mini_dump      *md;
@@ -220,6 +234,7 @@ int cam_mem_mgr_init(void)
 	for (i = 1; i < CAM_MEM_BUFQ_MAX; i++) {
 		tbl.bufq[i].fd = -1;
 		tbl.bufq[i].buf_handle = -1;
+		cam_mem_mgr_reset_presil_params(i);
 	}
 	mutex_init(&tbl.m_lock);
 
@@ -1020,6 +1035,7 @@ int cam_mem_mgr_alloc_and_map(struct cam_mem_mgr_alloc_cmd *cmd)
 	tbl.bufq[idx].dma_buf = dmabuf;
 	tbl.bufq[idx].len = len;
 	tbl.bufq[idx].num_hdl = cmd->num_hdl;
+	cam_mem_mgr_reset_presil_params(idx);
 	memcpy(tbl.bufq[idx].hdls, cmd->mmu_hdls,
 		sizeof(int32_t) * cmd->num_hdl);
 	tbl.bufq[idx].is_imported = false;
@@ -1297,6 +1313,7 @@ static int cam_mem_mgr_cleanup_table(void)
 		tbl.bufq[i].dma_buf = NULL;
 		tbl.bufq[i].active = false;
 		tbl.bufq[i].is_internal = false;
+		cam_mem_mgr_reset_presil_params(i);
 		mutex_unlock(&tbl.bufq[i].q_lock);
 		mutex_destroy(&tbl.bufq[i].q_lock);
 	}
@@ -1408,6 +1425,7 @@ static int cam_mem_util_unmap(int32_t idx,
 	tbl.bufq[idx].is_internal = false;
 	tbl.bufq[idx].len = 0;
 	tbl.bufq[idx].num_hdl = 0;
+	cam_mem_mgr_reset_presil_params(idx);
 	memset(&tbl.bufq[idx].timestamp, 0, sizeof(struct timespec64));
 	mutex_unlock(&tbl.bufq[idx].q_lock);
 	mutex_destroy(&tbl.bufq[idx].q_lock);
@@ -1821,8 +1839,268 @@ int cam_mem_mgr_free_memory_region(struct cam_mem_mgr_memory_desc *inp)
 }
 EXPORT_SYMBOL(cam_mem_mgr_free_memory_region);
 
-#ifndef CONFIG_CAM_PRESIL
+#ifdef CONFIG_CAM_PRESIL
+struct dma_buf *cam_mem_mgr_get_dma_buf(int fd)
+{
+	struct dma_buf *dmabuf = NULL;
+
+	dmabuf = dma_buf_get(fd);
+	if (IS_ERR_OR_NULL((void *)(dmabuf))) {
+		CAM_ERR(CAM_MEM, "Failed to import dma_buf for fd");
+		return NULL;
+	}
+
+	CAM_INFO(CAM_PRESIL, "Received DMA Buf* %pK", dmabuf);
+
+	return dmabuf;
+}
+
+int cam_presil_put_dmabuf_from_fd(uint64_t input_dmabuf)
+{
+	struct dma_buf *dmabuf = (struct dma_buf *)(uint64_t)input_dmabuf;
+	int idx = 0;
+
+	CAM_INFO(CAM_PRESIL, "Received dma_buf :%pK", dmabuf);
+
+	if (!dmabuf) {
+		CAM_ERR(CAM_PRESIL, "NULL to import dma_buf fd");
+		return -EINVAL;
+	}
+
+	for (idx = 0; idx < CAM_MEM_BUFQ_MAX; idx++) {
+		if ((tbl.bufq[idx].dma_buf != NULL) && (tbl.bufq[idx].dma_buf == dmabuf)) {
+			if (tbl.bufq[idx].presil_params.refcount)
+				tbl.bufq[idx].presil_params.refcount--;
+			else
+				CAM_ERR(CAM_PRESIL, "Unbalanced dmabuf put: %pK", dmabuf);
+
+			if (!tbl.bufq[idx].presil_params.refcount) {
+				dma_buf_put(dmabuf);
+				cam_mem_mgr_reset_presil_params(idx);
+				CAM_DBG(CAM_PRESIL, "Done dma_buf_put for %pK", dmabuf);
+			}
+		}
+	}
+
+	return 0;
+}
+EXPORT_SYMBOL(cam_presil_put_dmabuf_from_fd);
+
+int cam_presil_get_fd_from_dmabuf(uint64_t input_dmabuf)
+{
+	int fd_for_dmabuf = -1;
+	struct dma_buf *dmabuf = (struct dma_buf *)(uint64_t)input_dmabuf;
+	int idx = 0;
+
+	CAM_DBG(CAM_PRESIL, "Received dma_buf :%pK", dmabuf);
+
+	if (!dmabuf) {
+		CAM_ERR(CAM_PRESIL, "NULL to import dma_buf fd");
+		return -EINVAL;
+	}
+
+	for (idx = 0; idx < CAM_MEM_BUFQ_MAX; idx++) {
+		if ((tbl.bufq[idx].dma_buf != NULL) && (tbl.bufq[idx].dma_buf == dmabuf)) {
+			CAM_DBG(CAM_PRESIL,
+				"Found entry for request from Presil UMD Daemon at %d, dmabuf %pK fd_for_umd_daemon %d refcount: %d",
+				idx, tbl.bufq[idx].dma_buf,
+				tbl.bufq[idx].presil_params.fd_for_umd_daemon,
+				tbl.bufq[idx].presil_params.refcount);
+
+			if (tbl.bufq[idx].presil_params.fd_for_umd_daemon < 0) {
+				fd_for_dmabuf = dma_buf_fd(dmabuf, O_CLOEXEC);
+				if (fd_for_dmabuf < 0) {
+					CAM_ERR(CAM_PRESIL, "get fd fail, fd_for_dmabuf=%d",
+						fd_for_dmabuf);
+					return -EINVAL;
+				}
+
+				tbl.bufq[idx].presil_params.fd_for_umd_daemon = fd_for_dmabuf;
+				CAM_INFO(CAM_PRESIL,
+					"Received generated idx %d fd_for_dmabuf Buf* %lld", idx,
+					fd_for_dmabuf);
+			} else {
+				fd_for_dmabuf = tbl.bufq[idx].presil_params.fd_for_umd_daemon;
+				CAM_INFO(CAM_PRESIL,
+					"Received existing at idx %d fd_for_dmabuf Buf* %lld", idx,
+					fd_for_dmabuf);
+			}
+
+			tbl.bufq[idx].presil_params.refcount++;
+		} else {
+			CAM_DBG(CAM_MEM,
+				"Not found dmabuf at idx=%d, dma_buf %pK handle 0x%0x active %d ",
+				idx, tbl.bufq[idx].dma_buf, tbl.bufq[idx].buf_handle,
+				tbl.bufq[idx].active);
+		}
+	}
+
+	return (int)fd_for_dmabuf;
+}
+EXPORT_SYMBOL(cam_presil_get_fd_from_dmabuf);
+
+int cam_mem_mgr_send_buffer_to_presil(int32_t iommu_hdl, int32_t buf_handle)
+{
+	int rc = 0;
+
+	/* Sending Presil IO Buf to PC side ( as iova start address indicates) */
+	uint64_t io_buf_addr;
+	size_t io_buf_size;
+	int i, fd = -1, idx = 0;
+	uint8_t *iova_ptr = NULL;
+	uint64_t dmabuf = 0;
+	bool is_mapped_in_cb = false;
+
+
+	CAM_DBG(CAM_PRESIL, "buf handle 0x%0x", buf_handle);
+
+	idx = CAM_MEM_MGR_GET_HDL_IDX(buf_handle);
+	for (i = 0; i < tbl.bufq[idx].num_hdl; i++) {
+		if (tbl.bufq[idx].hdls[i] == iommu_hdl)
+			is_mapped_in_cb = true;
+	}
+
+	if (!is_mapped_in_cb)
+		return 0;
+
+	if ((tbl.bufq[idx].buf_handle != 0) && (tbl.bufq[idx].active) &&
+		(tbl.bufq[idx].buf_handle == buf_handle)) {
+		CAM_DBG(CAM_PRESIL,
+			"Found dmabuf in bufq idx %d, FD %d handle 0x%0x dmabuf %pK",
+			idx, tbl.bufq[idx].fd, tbl.bufq[idx].buf_handle, tbl.bufq[idx].dma_buf);
+		dmabuf = (uint64_t)tbl.bufq[idx].dma_buf;
+		fd = tbl.bufq[idx].fd;
+	} else {
+		CAM_ERR(CAM_PRESIL,
+			"Could not find dmabuf Invalid Mem idx=%d, FD %d handle 0x%0x active %d",
+			idx, tbl.bufq[idx].fd, tbl.bufq[idx].buf_handle, tbl.bufq[idx].active);
+		return -EINVAL;
+	}
+
+	rc = cam_mem_get_io_buf(buf_handle, iommu_hdl, &io_buf_addr, &io_buf_size, NULL);
+	if (rc || NULL == (void *)io_buf_addr) {
+		CAM_DBG(CAM_PRESIL, "Invalid ioaddr : 0x%x, fd = %d,  dmabuf = %pK",
+			io_buf_addr, fd, dmabuf);
+		return -EINVAL;
+	}
+
+	iova_ptr = (uint8_t *)io_buf_addr;
+	CAM_INFO(CAM_PRESIL, "Sending buffer with ioaddr : 0x%x, fd = %d, dmabuf = %pK",
+		io_buf_addr, fd, dmabuf);
+
+	rc = cam_presil_send_buffer(dmabuf, 0, 0, (uint32_t)io_buf_size, (uint64_t)iova_ptr);
+
+	return rc;
+}
+
+int cam_mem_mgr_send_all_buffers_to_presil(int32_t iommu_hdl)
+{
+	int idx = 0;
+	int rc = 0;
+	int32_t fd_already_sent[128];
+	int fd_already_sent_count = 0;
+	int fd_already_index = 0;
+	int fd_already_sent_found = 0;
+
 
+	memset(&fd_already_sent, 0x0, sizeof(fd_already_sent));
+
+	for (idx = 0; idx < CAM_MEM_BUFQ_MAX; idx++) {
+		if ((tbl.bufq[idx].buf_handle != 0) && (tbl.bufq[idx].active)) {
+			CAM_DBG(CAM_PRESIL, "Sending %d, FD %d handle 0x%0x", idx, tbl.bufq[idx].fd,
+				tbl.bufq[idx].buf_handle);
+			fd_already_sent_found = 0;
+
+			for (fd_already_index = 0; fd_already_index < fd_already_sent_count;
+				fd_already_index++) {
+
+				if (fd_already_sent[fd_already_index] == tbl.bufq[idx].fd) {
+					fd_already_sent_found = 1;
+					CAM_DBG(CAM_PRESIL,
+						"fd_already_sent %d, FD %d handle 0x%0x flags=0x%0x",
+						idx, tbl.bufq[idx].fd, tbl.bufq[idx].buf_handle,
+						tbl.bufq[idx].flags);
+				}
+			}
+
+			if (fd_already_sent_found)
+				continue;
+
+			CAM_DBG(CAM_PRESIL, "Sending %d, FD %d handle 0x%0x flags=0x%0x", idx,
+				tbl.bufq[idx].fd, tbl.bufq[idx].buf_handle, tbl.bufq[idx].flags);
+
+			rc = cam_mem_mgr_send_buffer_to_presil(iommu_hdl, tbl.bufq[idx].buf_handle);
+			fd_already_sent[fd_already_sent_count++] = tbl.bufq[idx].fd;
+
+		} else {
+			CAM_DBG(CAM_PRESIL, "Invalid Mem idx=%d, FD %d handle 0x%0x active %d",
+				idx, tbl.bufq[idx].fd, tbl.bufq[idx].buf_handle,
+				tbl.bufq[idx].active);
+		}
+	}
+
+	return rc;
+}
+EXPORT_SYMBOL(cam_mem_mgr_send_all_buffers_to_presil);
+
+int cam_mem_mgr_retrieve_buffer_from_presil(int32_t buf_handle, uint32_t buf_size,
+	uint32_t offset, int32_t iommu_hdl)
+{
+	int rc = 0;
+
+	/* Receive output buffer from Presil IO Buf to PC side (as iova start address indicates) */
+	uint64_t io_buf_addr;
+	size_t io_buf_size;
+	uint64_t dmabuf = 0;
+	int fd = 0;
+	uint8_t *iova_ptr = NULL;
+	int idx = 0;
+
+
+	CAM_DBG(CAM_PRESIL, "buf handle 0x%0x ", buf_handle);
+	rc = cam_mem_get_io_buf(buf_handle, iommu_hdl, &io_buf_addr, &io_buf_size, NULL);
+	if (rc) {
+		CAM_ERR(CAM_PRESIL, "Unable to get IOVA for buffer buf_hdl: 0x%0x iommu_hdl: 0x%0x",
+			buf_handle, iommu_hdl);
+		return -EINVAL;
+	}
+
+	iova_ptr = (uint8_t *)io_buf_addr;
+	iova_ptr += offset;   // correct target address to start writing buffer to.
+
+	if (!buf_size) {
+		buf_size = io_buf_size;
+		CAM_DBG(CAM_PRESIL, "Updated buf_size from Zero to 0x%0x", buf_size);
+	}
+
+	fd = GET_FD_FROM_HANDLE(buf_handle);
+
+	idx = CAM_MEM_MGR_GET_HDL_IDX(buf_handle);
+	if ((tbl.bufq[idx].buf_handle != 0) && (tbl.bufq[idx].active) &&
+		(tbl.bufq[idx].buf_handle == buf_handle)) {
+		CAM_DBG(CAM_PRESIL, "Found dmabuf in bufq idx %d, FD %d handle 0x%0x dmabuf %pK",
+			idx, tbl.bufq[idx].fd, tbl.bufq[idx].buf_handle, tbl.bufq[idx].dma_buf);
+		dmabuf = (uint64_t)tbl.bufq[idx].dma_buf;
+	} else {
+		CAM_ERR(CAM_PRESIL,
+			"Could not find dmabuf Invalid Mem idx=%d, FD %d handle 0x%0x active %d ",
+			idx, tbl.bufq[idx].fd, tbl.bufq[idx].buf_handle, tbl.bufq[idx].active);
+	}
+
+	CAM_DBG(CAM_PRESIL,
+		"Retrieving buffer with ioaddr : 0x%x, offset = %d, size = %d, fd = %d, dmabuf = %pK",
+		io_buf_addr, offset, buf_size, fd, dmabuf);
+
+	rc = cam_presil_retrieve_buffer(dmabuf, 0, 0, (uint32_t)buf_size, (uint64_t)io_buf_addr);
+
+	CAM_INFO(CAM_PRESIL,
+		"Retrieved buffer with ioaddr : 0x%x, offset = %d, size = %d, fd = %d, dmabuf = %pK",
+		io_buf_addr, 0, buf_size, fd, dmabuf);
+
+	return rc;
+}
+
+#else /* ifdef CONFIG_CAM_PRESIL */
 struct dma_buf * cam_mem_mgr_get_dma_buf(int fd)
 {
 	return NULL;
@@ -1845,4 +2123,4 @@ int cam_mem_mgr_retrieve_buffer_from_presil(int32_t buf_handle,
 {
 	return 0;
 }
-#endif
+#endif /* ifdef CONFIG_CAM_PRESIL */

+ 28 - 16
drivers/cam_req_mgr/cam_mem_mgr.h

@@ -26,25 +26,33 @@ enum cam_smmu_mapping_client {
 	CAM_SMMU_MAPPING_KERNEL,
 };
 
+#ifdef CONFIG_CAM_PRESIL
+struct cam_presil_dmabuf_params {
+	int32_t fd_for_umd_daemon;
+	uint32_t refcount;
+};
+#endif
+
 /**
  * struct cam_mem_buf_queue
  *
- * @dma_buf:     pointer to the allocated dma_buf in the table
- * @q_lock:      mutex lock for buffer
- * @hdls:        list of mapped handles
- * @num_hdl:     number of handles
- * @fd:          file descriptor of buffer
- * @i_ino:       inode number of this dmabuf. Uniquely identifies a buffer
- * @buf_handle:  unique handle for buffer
- * @align:       alignment for allocation
- * @len:         size of buffer
- * @flags:       attributes of buffer
- * @vaddr:       IOVA of buffer
- * @kmdvaddr:    Kernel virtual address
- * @active:      state of the buffer
- * @is_imported: Flag indicating if buffer is imported from an FD in user space
- * @is_internal: Flag indicating kernel allocated buffer
- * @timestamp:   Timestamp at which this entry in tbl was made
+ * @dma_buf:        pointer to the allocated dma_buf in the table
+ * @q_lock:         mutex lock for buffer
+ * @hdls:           list of mapped handles
+ * @num_hdl:        number of handles
+ * @fd:             file descriptor of buffer
+ * @i_ino:          inode number of this dmabuf. Uniquely identifies a buffer
+ * @buf_handle:     unique handle for buffer
+ * @align:          alignment for allocation
+ * @len:            size of buffer
+ * @flags:          attributes of buffer
+ * @vaddr:          IOVA of buffer
+ * @kmdvaddr:       Kernel virtual address
+ * @active:         state of the buffer
+ * @is_imported:    Flag indicating if buffer is imported from an FD in user space
+ * @is_internal:    Flag indicating kernel allocated buffer
+ * @timestamp:      Timestamp at which this entry in tbl was made
+ * @presil_params:  Parameters specific to presil environment
  */
 struct cam_mem_buf_queue {
 	struct dma_buf *dma_buf;
@@ -63,6 +71,10 @@ struct cam_mem_buf_queue {
 	bool is_imported;
 	bool is_internal;
 	struct timespec64 timestamp;
+
+#ifdef CONFIG_CAM_PRESIL
+	struct cam_presil_dmabuf_params presil_params;
+#endif
 };
 
 /**

+ 166 - 0
drivers/cam_utils/cam_packet_util.c

@@ -12,6 +12,7 @@
 #include "cam_common_util.h"
 
 #define CAM_UNIQUE_SRC_HDL_MAX 50
+#define CAM_PRESIL_UNIQUE_HDL_MAX 50
 
 struct cam_patch_unique_src_buf_tbl {
 	int32_t       hdl;
@@ -462,3 +463,168 @@ int cam_packet_util_process_generic_cmd_buffer(
 end:
 	return rc;
 }
+
+int cam_presil_retrieve_buffers_from_packet(struct cam_packet *packet, int iommu_hdl,
+	int out_res_id)
+{
+	int rc = 0, i, j;
+	struct cam_buf_io_cfg   *io_cfg = NULL;
+	dma_addr_t               io_addr[CAM_PACKET_MAX_PLANES];
+	size_t                   size;
+
+	if (!packet || (iommu_hdl < 0)) {
+		CAM_ERR(CAM_PRESIL, "Invalid params packet %pK iommu_hdl: %d", packet, iommu_hdl);
+		return -EINVAL;
+	}
+
+	CAM_DBG(CAM_PRESIL, "Retrieving output buffer corresponding to res: 0x%x", out_res_id);
+	io_cfg = (struct cam_buf_io_cfg *)((uint8_t *)&packet->payload + packet->io_configs_offset);
+	for (i = 0; i < packet->num_io_configs; i++) {
+		if ((io_cfg[i].direction != CAM_BUF_OUTPUT) ||
+			(io_cfg[i].resource_type != out_res_id))
+			continue;
+
+		memset(io_addr, 0, sizeof(io_addr));
+		for (j = 0; j < CAM_PACKET_MAX_PLANES; j++) {
+			if (!io_cfg[i].mem_handle[j])
+				break;
+
+			rc = cam_mem_get_io_buf(io_cfg[i].mem_handle[j], iommu_hdl, &io_addr[j],
+				&size, NULL);
+			if (rc) {
+				CAM_ERR(CAM_PRESIL, "no io addr for plane%d", j);
+				rc = -ENOMEM;
+				return rc;
+			}
+
+			/* For presil, address should be within 32 bit */
+			if (io_addr[j] >> 32) {
+				CAM_ERR(CAM_PRESIL,
+					"Invalid address, presil mapped address should be 32 bit");
+				rc = -EINVAL;
+				return rc;
+			}
+
+			CAM_INFO(CAM_PRESIL,
+				"Retrieving IO CFG buffer:%d addr: 0x%x offset 0x%x res_id: 0x%x",
+				io_cfg[i].mem_handle[j], io_addr[j], io_cfg[i].offsets[j],
+				io_cfg[i].resource_type);
+			cam_mem_mgr_retrieve_buffer_from_presil(io_cfg[i].mem_handle[j], size,
+				io_cfg[i].offsets[j], iommu_hdl);
+		}
+	}
+
+	return rc;
+}
+
+static void cam_presil_add_unique_buf_hdl_to_list(int32_t buf_hdl,
+	int32_t *hdl_list, int *num_hdls, int max_handles)
+{
+	int k;
+	bool hdl_found = false;
+
+	if (!buf_hdl)
+		return;
+
+	if (*num_hdls >= max_handles) {
+		CAM_ERR(CAM_PRESIL, "Failed to add entry num_hdls: %d max_handles:%d", *num_hdls,
+			max_handles);
+		return;
+	}
+
+	for (k = 0; k < *num_hdls; k++) {
+		if (hdl_list[k] == buf_hdl) {
+			hdl_found = true;
+			break;
+		}
+	}
+
+	if (!hdl_found)
+		hdl_list[(*num_hdls)++] = buf_hdl;
+}
+
+int cam_presil_send_buffers_from_packet(struct cam_packet *packet, int img_iommu_hdl,
+	int cdm_iommu_hdl)
+{
+	struct cam_buf_io_cfg   *io_cfg = NULL;
+	struct cam_cmd_buf_desc *cmd_desc = NULL;
+	struct cam_patch_desc *patch_desc = NULL;
+	int  i, j, rc = 0;
+	int32_t unique_img_buffers[CAM_PRESIL_UNIQUE_HDL_MAX] = {0};
+	int32_t unique_cmd_buffers[CAM_PRESIL_UNIQUE_HDL_MAX] = {0};
+	int num_img_handles = 0, num_cmd_handles = 0;
+
+	if(!packet) {
+		CAM_ERR(CAM_PRESIL, "Packet is NULL");
+		return -EINVAL;
+	}
+
+	if (img_iommu_hdl == -1) {
+		goto send_cmd_buffers;
+	}
+
+	/* Adding IO config buffer handles to list*/
+	io_cfg = (struct cam_buf_io_cfg *)((uint8_t *)&packet->payload + packet->io_configs_offset);
+	for (i = 0; i < packet->num_io_configs; i++) {
+		if (io_cfg[i].direction == CAM_BUF_OUTPUT)
+			continue;
+
+		for (j = 0; j < CAM_PACKET_MAX_PLANES; j++) {
+			if (!io_cfg[i].mem_handle[j])
+				break;
+
+			CAM_DBG(CAM_PRESIL, "Adding IO CFG buffer:%d", io_cfg[i].mem_handle[j]);
+			cam_presil_add_unique_buf_hdl_to_list(io_cfg[i].mem_handle[j],
+				unique_img_buffers, &num_img_handles, CAM_PRESIL_UNIQUE_HDL_MAX);
+		}
+	}
+
+	for (i = 0; i < num_img_handles; i++) {
+		CAM_DBG(CAM_PRESIL, "Sending Image buffer i:%d mem_handle:%d", i,
+			unique_img_buffers[i]);
+		rc = cam_mem_mgr_send_buffer_to_presil(img_iommu_hdl,
+			unique_img_buffers[i]);
+		if (rc) {
+			CAM_ERR(CAM_PRESIL, "Failed to send buffer i:%d mem_handle:%d rc:%d",
+					i, unique_img_buffers[i], rc);
+			return rc;
+		}
+	}
+
+send_cmd_buffers:
+	if (cdm_iommu_hdl == -1) {
+		goto end;
+	}
+
+	/* Adding CMD buffer handles to list*/
+	cmd_desc = (struct cam_cmd_buf_desc *) ((uint8_t *)&packet->payload +
+		packet->cmd_buf_offset);
+	for (i = 0; i < packet->num_cmd_buf; i++) {
+		CAM_DBG(CAM_PRESIL, "Adding CMD buffer:%d", cmd_desc[i].mem_handle);
+		cam_presil_add_unique_buf_hdl_to_list(cmd_desc[i].mem_handle,
+				unique_cmd_buffers, &num_cmd_handles, CAM_PRESIL_UNIQUE_HDL_MAX);
+	}
+
+	/* Adding Patch src buffer handles to list */
+	patch_desc = (struct cam_patch_desc *) ((uint8_t *)&packet->payload + packet->patch_offset);
+	for (i = 0; i < packet->num_patches; i++) {
+		CAM_DBG(CAM_PRESIL, "Adding Patch src buffer:%d", patch_desc[i].src_buf_hdl);
+		cam_presil_add_unique_buf_hdl_to_list(patch_desc[i].src_buf_hdl,
+				unique_cmd_buffers, &num_cmd_handles, CAM_PRESIL_UNIQUE_HDL_MAX);
+	}
+
+	for (i = 0; i < num_cmd_handles; i++) {
+		CAM_DBG(CAM_PRESIL, "Sending Command buffer i:%d mem_handle:%d", i,
+			unique_cmd_buffers[i]);
+		rc = cam_mem_mgr_send_buffer_to_presil(cdm_iommu_hdl,
+			unique_cmd_buffers[i]);
+		if (rc) {
+			CAM_ERR(CAM_PRESIL, "Failed to send buffer i:%d mem_handle:%d rc:%d",
+					i, unique_cmd_buffers[i], rc);
+			return rc;
+		}
+	}
+
+end:
+	return rc;
+}

+ 25 - 1
drivers/cam_utils/cam_packet_util.h

@@ -1,6 +1,6 @@
 /* SPDX-License-Identifier: GPL-2.0-only */
 /*
- * Copyright (c) 2017-2020, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2017-2021, The Linux Foundation. All rights reserved.
  */
 
 #ifndef _CAM_PACKET_UTIL_H_
@@ -137,4 +137,28 @@ int cam_packet_util_process_generic_cmd_buffer(
 	struct cam_cmd_buf_desc *cmd_buf,
 	cam_packet_generic_blob_handler blob_handler_cb, void *user_data);
 
+/**
+ * @brief :            API to retrieve image buffers from presil after processing is
+ *                     done,using packet from request
+ *
+ * @packet:            Packet pointer for current request
+ * @iommu_hdl:         IOMMU hdl for Image buffers
+ * @out_res_id:        Resource ID corresponding to the output buffer
+ *
+ * @return:            Success or Failure
+ */
+int cam_presil_retrieve_buffers_from_packet(struct cam_packet *packet, int iommu_hdl,
+	int out_res_id);
+
+/**
+ * @brief : API to send relevant buffers to presil
+ *
+ * @packet :            Packet pointer for current request
+ * @img_iommu_hdl:      IOMMU hdl for Image buffers
+ * @cdm_iommu_hdl:      IOMMU hdl for cdm buffers
+ *
+ */
+int cam_presil_send_buffers_from_packet(struct cam_packet *packet, int img_iommu_hdl,
+	int cdm_iommu_hdl);
+
 #endif /* _CAM_PACKET_UTIL_H_ */