msm: camera: Enable Support for secure camera

This patch enables the support for secure camera
feature. Secure camera lets trusted apps in user space
stream camera frames for various security applications.

Change-Id: Ia2204d2d62cef2764c106f57f64fac2981b27b94
Signed-off-by: Seemanta Dutta <seemanta@codeaurora.org>
Signed-off-by: Lakshmi Narayana Kalavala <lkalaval@codeaurora.org>
Signed-off-by: Soundrapandian Jeyaprakash <jsoundra@codeaurora.org>
diff --git a/Documentation/devicetree/bindings/media/video/msm-cam-smmu.txt b/Documentation/devicetree/bindings/media/video/msm-cam-smmu.txt
index 72e2ab4..728c5f9 100644
--- a/Documentation/devicetree/bindings/media/video/msm-cam-smmu.txt
+++ b/Documentation/devicetree/bindings/media/video/msm-cam-smmu.txt
@@ -56,6 +56,11 @@
   Value type: <string>
   Definition: Should specify a string label to identify the context bank.
 
+- qcom,secure-cb
+  Usage: optional
+  Value type: boolean
+  Definition: Specifies if the context bank is a secure context bank.
+
 =============================================
 Third Level Node - CAM SMMU memory map device
 =============================================
diff --git a/arch/arm64/boot/dts/qcom/sdm845-camera.dtsi b/arch/arm64/boot/dts/qcom/sdm845-camera.dtsi
index 8df879a..e4f768f 100644
--- a/arch/arm64/boot/dts/qcom/sdm845-camera.dtsi
+++ b/arch/arm64/boot/dts/qcom/sdm845-camera.dtsi
@@ -325,18 +325,8 @@
 
 		msm_cam_smmu_secure {
 			compatible = "qcom,msm-cam-smmu-cb";
-			iommus = <&apps_smmu 0x1001 0x0>;
 			label = "cam-secure";
-			cam_secure_iova_mem_map: iova-mem-map {
-				/* Secure IO region is approximately 3.4 GB */
-				iova-mem-region-io {
-					iova-region-name = "io";
-					iova-region-start = <0x7400000>;
-					iova-region-len = <0xd8c00000>;
-					iova-region-id = <0x3>;
-					status = "ok";
-				};
-			};
+			qcom,secure-cb;
 		};
 
 		msm_cam_smmu_fd {
diff --git a/arch/arm64/boot/dts/qcom/sdm845-v2-camera.dtsi b/arch/arm64/boot/dts/qcom/sdm845-v2-camera.dtsi
index c42a7be..c070ed6 100644
--- a/arch/arm64/boot/dts/qcom/sdm845-v2-camera.dtsi
+++ b/arch/arm64/boot/dts/qcom/sdm845-v2-camera.dtsi
@@ -243,18 +243,8 @@
 
 		msm_cam_smmu_secure {
 			compatible = "qcom,msm-cam-smmu-cb";
-			iommus = <&apps_smmu 0x1001 0x0>;
 			label = "cam-secure";
-			cam_secure_iova_mem_map: iova-mem-map {
-				/* Secure IO region is approximately 3.4 GB */
-				iova-mem-region-io {
-					iova-region-name = "io";
-					iova-region-start = <0x7400000>;
-					iova-region-len = <0xd8c00000>;
-					iova-region-id = <0x3>;
-					status = "ok";
-				};
-			};
+			qcom,secure-cb;
 		};
 	};
 
diff --git a/drivers/media/platform/msm/camera/cam_fd/fd_hw_mgr/cam_fd_hw_mgr.c b/drivers/media/platform/msm/camera/cam_fd/fd_hw_mgr/cam_fd_hw_mgr.c
index 5ed2222e..37e6954 100644
--- a/drivers/media/platform/msm/camera/cam_fd/fd_hw_mgr/cam_fd_hw_mgr.c
+++ b/drivers/media/platform/msm/camera/cam_fd/fd_hw_mgr/cam_fd_hw_mgr.c
@@ -1376,7 +1376,7 @@
 
 	/* We do not expect any patching, but just do it anyway */
 	rc = cam_packet_util_process_patches(prepare->packet,
-		hw_mgr->device_iommu.non_secure);
+		hw_mgr->device_iommu.non_secure, -1);
 	if (rc) {
 		CAM_ERR(CAM_FD, "Patch FD packet failed, rc=%d", rc);
 		return rc;
diff --git a/drivers/media/platform/msm/camera/cam_icp/icp_hw/icp_hw_mgr/cam_icp_hw_mgr.c b/drivers/media/platform/msm/camera/cam_icp/icp_hw/icp_hw_mgr/cam_icp_hw_mgr.c
index 7c5b405..c415d2f 100644
--- a/drivers/media/platform/msm/camera/cam_icp/icp_hw/icp_hw_mgr/cam_icp_hw_mgr.c
+++ b/drivers/media/platform/msm/camera/cam_icp/icp_hw/icp_hw_mgr/cam_icp_hw_mgr.c
@@ -1550,6 +1550,7 @@
 	cam_icp_mgr_device_deinit(hw_mgr);
 	cam_icp_free_hfi_mem();
 	hw_mgr->fw_download = false;
+	hw_mgr->secure_mode = CAM_SECURE_MODE_NON_SECURE;
 	mutex_unlock(&hw_mgr->hw_mgr_mutex);
 
 	return rc;
@@ -2146,7 +2147,8 @@
 	}
 
 	/* Update Buffer Address from handles and patch information */
-	rc = cam_packet_util_process_patches(packet, hw_mgr->iommu_hdl);
+	rc = cam_packet_util_process_patches(packet, hw_mgr->iommu_hdl,
+		hw_mgr->iommu_sec_hdl);
 	if (rc) {
 		mutex_unlock(&ctx_data->ctx_mutex);
 		return rc;
@@ -2239,6 +2241,7 @@
 			NULL, 0);
 		cam_icp_mgr_hw_close(hw_mgr, NULL);
 		cam_icp_hw_mgr_reset_clk_info(hw_mgr);
+		hw_mgr->secure_mode = CAM_SECURE_MODE_NON_SECURE;
 	}
 
 	return rc;
@@ -2384,6 +2387,12 @@
 		sizeof(struct cam_icp_acquire_dev_info)))
 		return -EFAULT;
 
+	if (icp_dev_acquire_info.secure_mode > CAM_SECURE_MODE_SECURE) {
+		CAM_ERR(CAM_ICP, "Invalid mode:%d",
+			icp_dev_acquire_info.secure_mode);
+		return -EINVAL;
+	}
+
 	if (icp_dev_acquire_info.num_out_res > ICP_MAX_OUTPUT_SUPPORTED) {
 		CAM_ERR(CAM_ICP, "num of out resources exceeding : %u",
 			icp_dev_acquire_info.num_out_res);
@@ -2396,28 +2405,46 @@
 		return -EFAULT;
 	}
 
+	if (!hw_mgr->ctxt_cnt) {
+		hw_mgr->secure_mode = icp_dev_acquire_info.secure_mode;
+	} else {
+		if (hw_mgr->secure_mode != icp_dev_acquire_info.secure_mode) {
+			CAM_ERR(CAM_ICP,
+				"secure mode mismatch driver:%d, context:%d",
+				hw_mgr->secure_mode,
+				icp_dev_acquire_info.secure_mode);
+			return -EINVAL;
+		}
+	}
+
 	acquire_size = sizeof(struct cam_icp_acquire_dev_info) +
 		(icp_dev_acquire_info.num_out_res *
 		sizeof(struct cam_icp_res_info));
 	ctx_data->icp_dev_acquire_info = kzalloc(acquire_size, GFP_KERNEL);
-	if (!ctx_data->icp_dev_acquire_info)
+	if (!ctx_data->icp_dev_acquire_info) {
+		if (!hw_mgr->ctxt_cnt)
+			hw_mgr->secure_mode = CAM_SECURE_MODE_NON_SECURE;
 		return -ENOMEM;
+	}
 
 	if (copy_from_user(ctx_data->icp_dev_acquire_info,
 		(void __user *)args->acquire_info, acquire_size)) {
+		if (!hw_mgr->ctxt_cnt)
+			hw_mgr->secure_mode = CAM_SECURE_MODE_NON_SECURE;
 		kfree(ctx_data->icp_dev_acquire_info);
 		ctx_data->icp_dev_acquire_info = NULL;
 		return -EFAULT;
 	}
 
-	CAM_DBG(CAM_ICP, "%x %x %x %x %x %x %x",
+	CAM_DBG(CAM_ICP, "%x %x %x %x %x %x %x %u",
 		ctx_data->icp_dev_acquire_info->dev_type,
 		ctx_data->icp_dev_acquire_info->in_res.format,
 		ctx_data->icp_dev_acquire_info->in_res.width,
 		ctx_data->icp_dev_acquire_info->in_res.height,
 		ctx_data->icp_dev_acquire_info->in_res.fps,
 		ctx_data->icp_dev_acquire_info->num_out_res,
-		ctx_data->icp_dev_acquire_info->scratch_mem_size);
+		ctx_data->icp_dev_acquire_info->scratch_mem_size,
+		hw_mgr->secure_mode);
 
 	p_icp_out = ctx_data->icp_dev_acquire_info->out_res;
 	for (i = 0; i < icp_dev_acquire_info.num_out_res; i++)
@@ -2470,18 +2497,10 @@
 		goto acquire_info_failed;
 	icp_dev_acquire_info = ctx_data->icp_dev_acquire_info;
 
-	/* Get IOCONFIG command info */
-	if (icp_dev_acquire_info->secure_mode)
-		rc = cam_mem_get_io_buf(
-			icp_dev_acquire_info->io_config_cmd_handle,
-			hw_mgr->iommu_sec_hdl,
-			&io_buf_addr, &io_buf_size);
-	else
-		rc = cam_mem_get_io_buf(
-			icp_dev_acquire_info->io_config_cmd_handle,
-			hw_mgr->iommu_hdl,
-			&io_buf_addr, &io_buf_size);
-
+	rc = cam_mem_get_io_buf(
+		icp_dev_acquire_info->io_config_cmd_handle,
+		hw_mgr->iommu_hdl,
+		&io_buf_addr, &io_buf_size);
 	if (rc) {
 		CAM_ERR(CAM_ICP, "unable to get src buf info from io desc");
 		goto get_io_buf_failed;
@@ -2808,6 +2827,7 @@
 	hw_mgr_intf->download_fw = cam_icp_mgr_download_fw;
 	hw_mgr_intf->hw_close = cam_icp_mgr_hw_close;
 
+	icp_hw_mgr.secure_mode = CAM_SECURE_MODE_NON_SECURE;
 	mutex_init(&icp_hw_mgr.hw_mgr_mutex);
 	spin_lock_init(&icp_hw_mgr.hw_mgr_lock);
 
@@ -2820,7 +2840,7 @@
 
 	rc = cam_smmu_get_handle("icp", &icp_hw_mgr.iommu_hdl);
 	if (rc) {
-		CAM_ERR(CAM_ICP, "icp get iommu handle failed: %d", rc);
+		CAM_ERR(CAM_ICP, "get mmu handle failed: %d", rc);
 		goto icp_get_hdl_failed;
 	}
 
@@ -2830,6 +2850,12 @@
 		goto icp_attach_failed;
 	}
 
+	rc = cam_smmu_get_handle("cam-secure", &icp_hw_mgr.iommu_sec_hdl);
+	if (rc) {
+		CAM_ERR(CAM_ICP, "get secure mmu handle failed: %d", rc);
+		goto secure_hdl_failed;
+	}
+
 	rc = cam_icp_mgr_create_wq();
 	if (rc)
 		goto icp_wq_create_failed;
@@ -2839,6 +2865,9 @@
 	return rc;
 
 icp_wq_create_failed:
+	cam_smmu_destroy_handle(icp_hw_mgr.iommu_sec_hdl);
+	icp_hw_mgr.iommu_sec_hdl = -1;
+secure_hdl_failed:
 	cam_smmu_ops(icp_hw_mgr.iommu_hdl, CAM_SMMU_DETACH);
 icp_attach_failed:
 	cam_smmu_destroy_handle(icp_hw_mgr.iommu_hdl);
diff --git a/drivers/media/platform/msm/camera/cam_icp/icp_hw/icp_hw_mgr/cam_icp_hw_mgr.h b/drivers/media/platform/msm/camera/cam_icp/icp_hw/icp_hw_mgr/cam_icp_hw_mgr.h
index d4f5482..ba7fcd4 100644
--- a/drivers/media/platform/msm/camera/cam_icp/icp_hw/icp_hw_mgr/cam_icp_hw_mgr.h
+++ b/drivers/media/platform/msm/camera/cam_icp/icp_hw/icp_hw_mgr/cam_icp_hw_mgr.h
@@ -226,6 +226,7 @@
  * @icp_debug_clk: Set clock based on debug value
  * @icp_default_clk: Set this clok if user doesn't supply
  * @clk_info: Clock info of hardware
+ * @secure_mode: Flag to enable/disable secure camera
  */
 struct cam_icp_hw_mgr {
 	struct mutex hw_mgr_mutex;
@@ -255,6 +256,7 @@
 	uint64_t icp_debug_clk;
 	uint64_t icp_default_clk;
 	struct cam_icp_clk_info clk_info[ICP_CLK_HW_MAX];
+	bool secure_mode;
 };
 
 static int cam_icp_mgr_hw_close(void *hw_priv, void *hw_close_args);
diff --git a/drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/cam_ife_hw_mgr.c b/drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/cam_ife_hw_mgr.c
index d0b0751..1b9e7b0 100644
--- a/drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/cam_ife_hw_mgr.c
+++ b/drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/cam_ife_hw_mgr.c
@@ -64,7 +64,7 @@
 		sizeof(struct cam_isp_query_cap_cmd)))
 		rc = -EFAULT;
 
-	CAM_DBG(CAM_ISP, "exit rc :%d !", rc);
+	CAM_DBG(CAM_ISP, "exit rc :%d", rc);
 
 	return rc;
 }
@@ -111,7 +111,7 @@
 
 	return 0;
 err:
-	CAM_ERR(CAM_ISP, "INIT HW res failed! (type:%d, id:%d)",
+	CAM_ERR(CAM_ISP, "INIT HW res failed: (type:%d, id:%d)",
 		isp_hw_res->res_type, isp_hw_res->res_id);
 	return rc;
 }
@@ -132,7 +132,7 @@
 				isp_hw_res->hw_res[i],
 				sizeof(struct cam_isp_resource_node));
 			if (rc) {
-				CAM_ERR(CAM_ISP, "Can not start HW resources!");
+				CAM_ERR(CAM_ISP, "Can not start HW resources");
 				goto err;
 			}
 		} else {
@@ -143,7 +143,7 @@
 
 	return 0;
 err:
-	CAM_ERR(CAM_ISP, "Start hw res failed! (type:%d, id:%d)",
+	CAM_ERR(CAM_ISP, "Start hw res failed (type:%d, id:%d)",
 		isp_hw_res->res_type, isp_hw_res->res_id);
 	return rc;
 }
@@ -210,7 +210,7 @@
 			struct cam_ife_hw_mgr_res, list);
 		list_del_init(&res_ptr->list);
 	} else {
-		CAM_ERR(CAM_ISP, "No more free ife hw mgr ctx!");
+		CAM_ERR(CAM_ISP, "No more free ife hw mgr ctx");
 		rc = -1;
 	}
 	*res = res_ptr;
@@ -235,7 +235,7 @@
 				sizeof(struct cam_isp_resource_node));
 			if (rc)
 				CAM_ERR(CAM_ISP,
-					"Release hw resrouce id %d failed!",
+					"Release hw resrouce id %d failed",
 					isp_hw_res->res_id);
 			isp_hw_res->hw_res[i] = NULL;
 		} else
@@ -362,7 +362,7 @@
 			struct cam_ife_hw_mgr_ctx, list);
 		list_del_init(&ctx_ptr->list);
 	} else {
-		CAM_ERR(CAM_ISP, "No more free ife hw mgr ctx!");
+		CAM_ERR(CAM_ISP, "No more free ife hw mgr ctx");
 		rc = -1;
 	}
 	*ife_ctx = ctx_ptr;
@@ -417,7 +417,7 @@
 	uint32_t i;
 
 	if (list_empty(&ctx->res_list_ife_src)) {
-		CAM_ERR(CAM_ISP, "Error! Mux List empty");
+		CAM_ERR(CAM_ISP, "Mux List empty");
 		return -ENODEV;
 	}
 
@@ -633,7 +633,8 @@
 				ife_src_res, in_port);
 			break;
 		default:
-			CAM_ERR(CAM_ISP, "Fatal: Unknown IFE SRC resource!");
+			CAM_ERR(CAM_ISP, "Unknown IFE SRC resource: %d",
+				ife_src_res->res_id);
 			break;
 		}
 		if (rc)
@@ -667,7 +668,7 @@
 		rc = cam_ife_hw_mgr_get_res(&ife_ctx->free_res_list,
 			&ife_src_res);
 		if (rc) {
-			CAM_ERR(CAM_ISP, "No more free hw mgr resource!");
+			CAM_ERR(CAM_ISP, "No more free hw mgr resource");
 			goto err;
 		}
 		cam_ife_hw_mgr_put_res(&ife_ctx->res_list_ife_src,
@@ -706,7 +707,7 @@
 			vfe_acquire.vfe_in.sync_mode = CAM_ISP_HW_SYNC_NONE;
 			break;
 		default:
-			CAM_ERR(CAM_ISP, "Wrong IFE CSID Resource Node!");
+			CAM_ERR(CAM_ISP, "Wrong IFE CSID Resource Node");
 			goto err;
 		}
 		ife_src_res->res_type = vfe_acquire.rsrc_type;
@@ -776,7 +777,7 @@
 
 	rc = cam_ife_hw_mgr_get_res(&ife_ctx->free_res_list, &csid_res);
 	if (rc) {
-		CAM_ERR(CAM_ISP, "No more free hw mgr resource!");
+		CAM_ERR(CAM_ISP, "No more free hw mgr resource");
 		goto err;
 	}
 	cam_ife_hw_mgr_put_res(&ife_ctx->res_list_ife_csid, &csid_res);
@@ -808,11 +809,11 @@
 	}
 
 	if (i == CAM_IFE_CSID_HW_NUM_MAX) {
-		CAM_ERR(CAM_ISP, "Can not acquire ife csid ipp resrouce!");
+		CAM_ERR(CAM_ISP, "Can not acquire ife csid ipp resource");
 		goto err;
 	}
 
-	CAM_DBG(CAM_ISP, "acquired csid(%d) left ipp resrouce successfully!",
+	CAM_DBG(CAM_ISP, "acquired csid(%d) left ipp resource successfully",
 		 i);
 
 	csid_res->res_type = CAM_ISP_RESOURCE_PIX_PATH;
@@ -839,13 +840,13 @@
 
 		if (j == CAM_IFE_CSID_HW_NUM_MAX) {
 			CAM_ERR(CAM_ISP,
-				"Can not acquire ife csid rdi resrouce!");
+				"Can not acquire ife csid rdi resrouce");
 			goto err;
 		}
 		csid_res->hw_res[1] = csid_acquire.node_res;
 
 		CAM_DBG(CAM_ISP,
-			"acquired csid(%d)right ipp resrouce successfully!", j);
+			"acquired csid(%d)right ipp resrouce successfully", j);
 
 	}
 	csid_res->parent = &ife_ctx->res_list_ife_in;
@@ -909,7 +910,7 @@
 		rc = cam_ife_hw_mgr_get_res(&ife_ctx->free_res_list,
 			&csid_res);
 		if (rc) {
-			CAM_ERR(CAM_ISP, "No more free hw mgr resource!",
+			CAM_ERR(CAM_ISP, "No more free hw mgr resource",
 				__func__);
 			goto err;
 		}
@@ -945,7 +946,7 @@
 
 		if (j == CAM_IFE_CSID_HW_NUM_MAX) {
 			CAM_ERR(CAM_ISP,
-				"Can not acquire ife csid rdi resrouce!");
+				"Can not acquire ife csid rdi resource");
 			goto err;
 		}
 
@@ -978,7 +979,7 @@
 		ife_ctx->res_list_ife_in.res_id = in_port->res_type;
 		ife_ctx->res_list_ife_in.is_dual_vfe = in_port->usage_type;
 	} else if (ife_ctx->res_list_ife_in.res_id != in_port->res_type) {
-		CAM_ERR(CAM_ISP, "No Free resource for this context!");
+		CAM_ERR(CAM_ISP, "No Free resource for this context");
 		goto err;
 	} else {
 		/* else do nothing */
@@ -1032,7 +1033,7 @@
 	/* no dual vfe for TPG */
 	if ((in_port->res_type == CAM_ISP_IFE_IN_RES_TPG) &&
 		(in_port->usage_type != 0)) {
-		CAM_ERR(CAM_ISP, "No Dual VFE on TPG input!");
+		CAM_ERR(CAM_ISP, "No Dual VFE on TPG input");
 		goto err;
 	}
 
@@ -1040,7 +1041,7 @@
 
 	rc = cam_ife_hw_mgr_get_res(&ife_ctx->free_res_list, &cid_res);
 	if (rc) {
-		CAM_ERR(CAM_ISP, "No more free hw mgr resource!");
+		CAM_ERR(CAM_ISP, "No more free hw mgr resource");
 		goto err;
 	}
 	cam_ife_hw_mgr_put_res(&ife_ctx->res_list_ife_cid, &cid_res);
@@ -1062,7 +1063,7 @@
 	}
 
 	if (i == CAM_IFE_CSID_HW_NUM_MAX || !csid_acquire.node_res) {
-		CAM_ERR(CAM_ISP, "Can not acquire ife csid rdi resrouce!");
+		CAM_ERR(CAM_ISP, "Can not acquire ife csid rdi resource");
 		goto err;
 	}
 
@@ -1093,7 +1094,7 @@
 
 		if (j == CAM_IFE_CSID_HW_NUM_MAX) {
 			CAM_ERR(CAM_ISP,
-				"Can not acquire ife csid rdi resrouce!");
+				"Can not acquire ife csid rdi resource");
 			goto err;
 		}
 		cid_res->hw_res[1] = csid_acquire.node_res;
@@ -1123,14 +1124,14 @@
 	/* get root node resource */
 	rc = cam_ife_hw_mgr_acquire_res_root(ife_ctx, in_port);
 	if (rc) {
-		CAM_ERR(CAM_ISP, "Can not acquire csid rx resource!");
+		CAM_ERR(CAM_ISP, "Can not acquire csid rx resource");
 		goto err;
 	}
 
 	/* get cid resource */
 	rc = cam_ife_mgr_acquire_cid_res(ife_ctx, in_port, &cid_res_id);
 	if (rc) {
-		CAM_ERR(CAM_ISP, "Acquire IFE CID resource Failed!");
+		CAM_ERR(CAM_ISP, "Acquire IFE CID resource Failed");
 		goto err;
 	}
 
@@ -1138,7 +1139,7 @@
 		&pixel_count, &rdi_count);
 
 	if (!pixel_count && !rdi_count) {
-		CAM_ERR(CAM_ISP, "Error! no PIX or RDI resource");
+		CAM_ERR(CAM_ISP, "No PIX or RDI resource");
 		return -EINVAL;
 	}
 
@@ -1148,7 +1149,7 @@
 				cid_res_id);
 		if (rc) {
 			CAM_ERR(CAM_ISP,
-				"Acquire IFE CSID IPP resource Failed!");
+				"Acquire IFE CSID IPP resource Failed");
 			goto err;
 		}
 	}
@@ -1159,7 +1160,7 @@
 			cid_res_id);
 		if (rc) {
 			CAM_ERR(CAM_ISP,
-				"Acquire IFE CSID RDI resource Failed!");
+				"Acquire IFE CSID RDI resource Failed");
 			goto err;
 		}
 	}
@@ -1167,13 +1168,13 @@
 	/* get ife src resource */
 	rc = cam_ife_hw_mgr_acquire_res_ife_src(ife_ctx, in_port);
 	if (rc) {
-		CAM_ERR(CAM_ISP, "Acquire IFE SRC resource Failed!");
+		CAM_ERR(CAM_ISP, "Acquire IFE SRC resource Failed");
 		goto err;
 	}
 
 	rc = cam_ife_hw_mgr_acquire_res_ife_out(ife_ctx, in_port);
 	if (rc) {
-		CAM_ERR(CAM_ISP, "Acquire IFE OUT resource Failed!");
+		CAM_ERR(CAM_ISP, "Acquire IFE OUT resource Failed");
 		goto err;
 	}
 
@@ -1219,7 +1220,7 @@
 	/* get the ife ctx */
 	rc = cam_ife_hw_mgr_get_ctx(&ife_hw_mgr->free_ctx_list, &ife_ctx);
 	if (rc || !ife_ctx) {
-		CAM_ERR(CAM_ISP, "Get ife hw context failed!");
+		CAM_ERR(CAM_ISP, "Get ife hw context failed");
 		goto err;
 	}
 
@@ -1279,7 +1280,7 @@
 			}
 		} else {
 			CAM_ERR(CAM_ISP,
-				"copy from user failed with in_port = %pK",
+				"Copy from user failed with in_port = %pK",
 				in_port);
 			rc = -EFAULT;
 			goto free_res;
@@ -1295,7 +1296,7 @@
 	/* Process base info */
 	rc = cam_ife_mgr_process_base_info(ife_ctx);
 	if (rc) {
-		CAM_ERR(CAM_ISP, "Error process) base info!");
+		CAM_ERR(CAM_ISP, "Process base info failed");
 		return -EINVAL;
 	}
 
@@ -1304,14 +1305,14 @@
 
 	cam_ife_hw_mgr_put_ctx(&ife_hw_mgr->used_ctx_list, &ife_ctx);
 
-	CAM_DBG(CAM_ISP, "Exit...(success)!");
+	CAM_DBG(CAM_ISP, "Exit...(success)");
 
 	return 0;
 free_res:
 	cam_ife_hw_mgr_release_hw_for_ctx(ife_ctx);
 	cam_ife_hw_mgr_put_ctx(&ife_hw_mgr->free_ctx_list, &ife_ctx);
 err:
-	CAM_DBG(CAM_ISP, "Exit...(rc=%d)!", rc);
+	CAM_DBG(CAM_ISP, "Exit...(rc=%d)", rc);
 	return rc;
 }
 
@@ -1334,12 +1335,12 @@
 	cfg = config_hw_args;
 	ctx = (struct cam_ife_hw_mgr_ctx *)cfg->ctxt_to_hw_map;
 	if (!ctx) {
-		CAM_ERR(CAM_ISP, "Fatal: Invalid context is used!");
+		CAM_ERR(CAM_ISP, "Invalid context is used");
 		return -EPERM;
 	}
 
 	if (!ctx->ctx_in_use || !ctx->cdm_cmd) {
-		CAM_ERR(CAM_ISP, "Invalid context parameters !");
+		CAM_ERR(CAM_ISP, "Invalid context parameters");
 		return -EPERM;
 	}
 
@@ -1388,7 +1389,7 @@
 	}
 	ctx = (struct cam_ife_hw_mgr_ctx *)stop_args->ctxt_to_hw_map;
 	if (!ctx || !ctx->ctx_in_use) {
-		CAM_ERR(CAM_ISP, "Fatal: Invalid context is used!");
+		CAM_ERR(CAM_ISP, "Invalid context is used");
 		return -EPERM;
 	}
 
@@ -1397,7 +1398,7 @@
 
 	/* stop resource will remove the irq mask from the hardware */
 	if (!ctx->num_base) {
-		CAM_ERR(CAM_ISP, "error number of bases are zero");
+		CAM_ERR(CAM_ISP, "Number of bases are zero");
 		return -EINVAL;
 	}
 
@@ -1474,7 +1475,7 @@
 	}
 	ctx = (struct cam_ife_hw_mgr_ctx *)stop_args->ctxt_to_hw_map;
 	if (!ctx || !ctx->ctx_in_use) {
-		CAM_ERR(CAM_ISP, "Fatal: Invalid context is used!");
+		CAM_ERR(CAM_ISP, "Invalid context is used");
 		return -EPERM;
 	}
 
@@ -1484,7 +1485,7 @@
 	/* Note:stop resource will remove the irq mask from the hardware */
 
 	if (!ctx->num_base) {
-		CAM_ERR(CAM_ISP, "error number of bases are zero");
+		CAM_ERR(CAM_ISP, "number of bases are zero");
 		return -EINVAL;
 	}
 
@@ -1628,7 +1629,7 @@
 
 	ctx = (struct cam_ife_hw_mgr_ctx *)start_args->ctxt_to_hw_map;
 	if (!ctx || !ctx->ctx_in_use) {
-		CAM_ERR(CAM_ISP, "Invalid context is used!");
+		CAM_ERR(CAM_ISP, "Invalid context is used");
 		return -EPERM;
 	}
 
@@ -1639,7 +1640,7 @@
 	for (i = 0; i < CAM_IFE_HW_OUT_RES_MAX; i++) {
 		rc = cam_ife_hw_mgr_start_hw_res(&ctx->res_list_ife_out[i]);
 		if (rc) {
-			CAM_ERR(CAM_ISP, "Can not start IFE OUT (%d)!", i);
+			CAM_ERR(CAM_ISP, "Can not start IFE OUT (%d)", i);
 			goto err;
 		}
 	}
@@ -1649,7 +1650,7 @@
 	list_for_each_entry(hw_mgr_res, &ctx->res_list_ife_src, list) {
 		rc = cam_ife_hw_mgr_start_hw_res(hw_mgr_res);
 		if (rc) {
-			CAM_ERR(CAM_ISP, "Can not start IFE MUX (%d)!",
+			CAM_ERR(CAM_ISP, "Can not start IFE MUX (%d)",
 				 hw_mgr_res->res_id);
 			goto err;
 		}
@@ -1660,7 +1661,7 @@
 	list_for_each_entry(hw_mgr_res, &ctx->res_list_ife_csid, list) {
 		rc = cam_ife_hw_mgr_start_hw_res(hw_mgr_res);
 		if (rc) {
-			CAM_ERR(CAM_ISP, "Can not start IFE CSID (%d)!",
+			CAM_ERR(CAM_ISP, "Can not start IFE CSID (%d)",
 				 hw_mgr_res->res_id);
 			goto err;
 		}
@@ -1671,7 +1672,7 @@
 	list_for_each_entry(hw_mgr_res, &ctx->res_list_ife_cid, list) {
 		rc = cam_ife_hw_mgr_start_hw_res(hw_mgr_res);
 		if (rc) {
-			CAM_ERR(CAM_ISP, "Can not start IFE CSID (%d)!",
+			CAM_ERR(CAM_ISP, "Can not start IFE CSID (%d)",
 				 hw_mgr_res->res_id);
 			goto err;
 		}
@@ -1702,7 +1703,7 @@
 
 	ctx = (struct cam_ife_hw_mgr_ctx *)start_args->ctxt_to_hw_map;
 	if (!ctx || !ctx->ctx_in_use) {
-		CAM_ERR(CAM_ISP, "Invalid context is used!");
+		CAM_ERR(CAM_ISP, "Invalid context is used");
 		return -EPERM;
 	}
 
@@ -1721,7 +1722,7 @@
 	list_for_each_entry(hw_mgr_res, &ctx->res_list_ife_cid, list) {
 		rc = cam_ife_hw_mgr_init_hw_res(hw_mgr_res);
 		if (rc) {
-			CAM_ERR(CAM_ISP, "Can not INIT IFE CID.(id :%d)!",
+			CAM_ERR(CAM_ISP, "Can not INIT IFE CID(id :%d)",
 				 hw_mgr_res->res_id);
 			goto err;
 		}
@@ -1735,7 +1736,7 @@
 	list_for_each_entry(hw_mgr_res, &ctx->res_list_ife_csid, list) {
 		rc = cam_ife_hw_mgr_init_hw_res(hw_mgr_res);
 		if (rc) {
-			CAM_ERR(CAM_ISP, "Can not INIT IFE CSID.(id :%d)!",
+			CAM_ERR(CAM_ISP, "Can not INIT IFE CSID(id :%d)",
 				 hw_mgr_res->res_id);
 			goto err;
 		}
@@ -1747,7 +1748,7 @@
 	list_for_each_entry(hw_mgr_res, &ctx->res_list_ife_src, list) {
 		rc = cam_ife_hw_mgr_init_hw_res(hw_mgr_res);
 		if (rc) {
-			CAM_ERR(CAM_ISP, "Can not INIT IFE SRC (%d)!",
+			CAM_ERR(CAM_ISP, "Can not INIT IFE SRC (%d)",
 				 hw_mgr_res->res_id);
 			goto err;
 		}
@@ -1760,7 +1761,7 @@
 	for (i = 0; i < CAM_IFE_HW_OUT_RES_MAX; i++) {
 		rc = cam_ife_hw_mgr_init_hw_res(&ctx->res_list_ife_out[i]);
 		if (rc) {
-			CAM_ERR(CAM_ISP, "Can not INIT IFE OUT (%d)!",
+			CAM_ERR(CAM_ISP, "Can not INIT IFE OUT (%d)",
 				 ctx->res_list_ife_out[i].res_id);
 			goto err;
 		}
@@ -1769,7 +1770,7 @@
 	CAM_DBG(CAM_ISP, "start cdm interface");
 	rc = cam_cdm_stream_on(ctx->cdm_handle);
 	if (rc) {
-		CAM_ERR(CAM_ISP, "Can not start cdm (%d)!",
+		CAM_ERR(CAM_ISP, "Can not start cdm (%d)",
 			 ctx->cdm_handle);
 		goto err;
 	}
@@ -1788,7 +1789,7 @@
 	for (i = 0; i < CAM_IFE_HW_OUT_RES_MAX; i++) {
 		rc = cam_ife_hw_mgr_start_hw_res(&ctx->res_list_ife_out[i]);
 		if (rc) {
-			CAM_ERR(CAM_ISP, "Can not start IFE OUT (%d)!",
+			CAM_ERR(CAM_ISP, "Can not start IFE OUT (%d)",
 				 i);
 			goto err;
 		}
@@ -1800,7 +1801,7 @@
 	list_for_each_entry(hw_mgr_res, &ctx->res_list_ife_src, list) {
 		rc = cam_ife_hw_mgr_start_hw_res(hw_mgr_res);
 		if (rc) {
-			CAM_ERR(CAM_ISP, "Can not start IFE MUX (%d)!",
+			CAM_ERR(CAM_ISP, "Can not start IFE MUX (%d)",
 				 hw_mgr_res->res_id);
 			goto err;
 		}
@@ -1812,7 +1813,7 @@
 	list_for_each_entry(hw_mgr_res, &ctx->res_list_ife_csid, list) {
 		rc = cam_ife_hw_mgr_start_hw_res(hw_mgr_res);
 		if (rc) {
-			CAM_ERR(CAM_ISP, "Can not start IFE CSID (%d)!",
+			CAM_ERR(CAM_ISP, "Can not start IFE CSID (%d)",
 				 hw_mgr_res->res_id);
 			goto err;
 		}
@@ -1824,7 +1825,7 @@
 	list_for_each_entry(hw_mgr_res, &ctx->res_list_ife_cid, list) {
 		rc = cam_ife_hw_mgr_start_hw_res(hw_mgr_res);
 		if (rc) {
-			CAM_ERR(CAM_ISP, "Can not start IFE CSID (%d)!",
+			CAM_ERR(CAM_ISP, "Can not start IFE CSID (%d)",
 				 hw_mgr_res->res_id);
 			goto err;
 		}
@@ -1864,7 +1865,7 @@
 
 	ctx = (struct cam_ife_hw_mgr_ctx *)release_args->ctxt_to_hw_map;
 	if (!ctx || !ctx->ctx_in_use) {
-		CAM_ERR(CAM_ISP, "Fatal: Invalid context is used!");
+		CAM_ERR(CAM_ISP, "Invalid context is used");
 		return -EPERM;
 	}
 
@@ -1923,7 +1924,8 @@
 		return rc;
 
 	rc = cam_packet_util_process_patches(prepare->packet,
-		hw_mgr->mgr_common.cmd_iommu_hdl);
+		hw_mgr->mgr_common.cmd_iommu_hdl,
+		hw_mgr->mgr_common.cmd_iommu_hdl_secure);
 	if (rc) {
 		CAM_ERR(CAM_ISP, "Patch ISP packet failed.");
 		return rc;
@@ -1982,6 +1984,7 @@
 
 		/* get IO buffers */
 		rc = cam_isp_add_io_buffers(hw_mgr->mgr_common.img_iommu_hdl,
+			hw_mgr->mgr_common.img_iommu_hdl_secure,
 			prepare, ctx->base[i].idx,
 			&kmd_buf, ctx->res_list_ife_out,
 			CAM_IFE_HW_OUT_RES_MAX, fill_fence);
@@ -2049,7 +2052,7 @@
 
 	ctx = (struct cam_ife_hw_mgr_ctx *)hw_cmd_args->ctxt_to_hw_map;
 	if (!ctx || !ctx->ctx_in_use) {
-		CAM_ERR(CAM_ISP, "Fatal: Invalid context is used!");
+		CAM_ERR(CAM_ISP, "Fatal: Invalid context is used");
 		return -EPERM;
 	}
 
@@ -2117,7 +2120,7 @@
 	}
 end:
 	if (rc)
-		CAM_ERR(CAM_ISP, "error in getting sof time stamp");
+		CAM_ERR(CAM_ISP, "Getting sof time stamp failed");
 
 	return rc;
 }
@@ -2135,7 +2138,7 @@
 	struct cam_ife_hw_mgr_ctx        *ctx = NULL;
 
 	/* Here recovery is performed */
-	CAM_DBG(CAM_ISP, "Enter: ErrorType = %d", error_type);
+	CAM_DBG(CAM_ISP, "ErrorType = %d", error_type);
 
 	switch (error_type) {
 	case CAM_ISP_HW_ERROR_OVERFLOW:
@@ -2757,7 +2760,7 @@
 		break;
 	}
 
-	CAM_DBG(CAM_ISP, "Exit (sof_status = %d)!", sof_status);
+	CAM_DBG(CAM_ISP, "Exit (sof_status = %d)", sof_status);
 
 	return 0;
 }
@@ -2949,7 +2952,7 @@
 		}
 	}
 
-	CAM_DBG(CAM_ISP, "Exit (eof_status = %d)!", eof_status);
+	CAM_DBG(CAM_ISP, "Exit (eof_status = %d)", eof_status);
 
 	return 0;
 }
@@ -3080,7 +3083,7 @@
 	 * for the first phase, we are going to reset entire HW.
 	 */
 
-	CAM_DBG(CAM_ISP, "Exit (buf_done_status (Error) = %d)!",
+	CAM_DBG(CAM_ISP, "Exit buf_done_status Error = %d",
 		buf_done_status);
 	return rc;
 }
@@ -3212,8 +3215,8 @@
 	mutex_init(&g_ife_hw_mgr.ctx_mutex);
 
 	if (CAM_IFE_HW_NUM_MAX != CAM_IFE_CSID_HW_NUM_MAX) {
-		CAM_ERR(CAM_ISP, "Fatal, CSID num is different then IFE num!");
-		goto end;
+		CAM_ERR(CAM_ISP, "CSID num is different then IFE num");
+		return -EINVAL;
 	}
 
 	/* fill ife hw intf information */
@@ -3237,8 +3240,8 @@
 		}
 	}
 	if (j == 0) {
-		CAM_ERR(CAM_ISP, "no valid IFE HW!");
-		goto end;
+		CAM_ERR(CAM_ISP, "no valid IFE HW");
+		return -EINVAL;
 	}
 
 	/* fill csid hw intf information */
@@ -3248,8 +3251,8 @@
 			j++;
 	}
 	if (!j) {
-		CAM_ERR(CAM_ISP, "no valid IFE CSID HW!");
-		goto end;
+		CAM_ERR(CAM_ISP, "no valid IFE CSID HW");
+		return -EINVAL;
 	}
 
 	cam_ife_hw_mgr_sort_dev_with_caps(&g_ife_hw_mgr);
@@ -3267,19 +3270,25 @@
 	 */
 	if (cam_smmu_get_handle("ife",
 		&g_ife_hw_mgr.mgr_common.img_iommu_hdl)) {
-		CAM_ERR(CAM_ISP, "Can not get iommu handle.");
-		goto end;
+		CAM_ERR(CAM_ISP, "Can not get iommu handle");
+		return -EINVAL;
 	}
 
 	if (cam_smmu_ops(g_ife_hw_mgr.mgr_common.img_iommu_hdl,
 		CAM_SMMU_ATTACH)) {
 		CAM_ERR(CAM_ISP, "Attach iommu handle failed.");
-		goto end;
+		goto attach_fail;
 	}
 
-	CAM_DBG(CAM_ISP, "got iommu_handle=%d",
-		g_ife_hw_mgr.mgr_common.img_iommu_hdl);
-	g_ife_hw_mgr.mgr_common.img_iommu_hdl_secure = -1;
+	if (cam_smmu_get_handle("cam-secure",
+		&g_ife_hw_mgr.mgr_common.img_iommu_hdl_secure)) {
+		CAM_ERR(CAM_ISP, "Failed to get secure iommu handle");
+		goto secure_fail;
+	}
+
+	CAM_DBG(CAM_ISP, "iommu_handles: non-secure[0x%x], secure[0x%x]",
+		g_ife_hw_mgr.mgr_common.img_iommu_hdl,
+		g_ife_hw_mgr.mgr_common.img_iommu_hdl_secure);
 
 	if (!cam_cdm_get_iommu_handle("ife", &cdm_handles)) {
 		CAM_DBG(CAM_ISP, "Successfully acquired the CDM iommu handles");
@@ -3341,7 +3350,6 @@
 	/* Create Worker for ife_hw_mgr with 10 tasks */
 	rc = cam_req_mgr_workq_create("cam_ife_worker", 10,
 			&g_ife_hw_mgr.workq, CRM_WORKQ_USAGE_NON_IRQ);
-
 	if (rc < 0) {
 		CAM_ERR(CAM_ISP, "Unable to create worker");
 		goto end;
@@ -3359,14 +3367,28 @@
 	hw_mgr_intf->hw_prepare_update = cam_ife_mgr_prepare_hw_update;
 	hw_mgr_intf->hw_config = cam_ife_mgr_config_hw;
 	hw_mgr_intf->hw_cmd = cam_ife_mgr_cmd;
-
 	CAM_DBG(CAM_ISP, "Exit");
+
 	return 0;
 end:
 	if (rc) {
-		for (i = 0; i < CAM_CTX_MAX; i++)
+		for (i = 0; i < CAM_CTX_MAX; i++) {
+			cam_tasklet_deinit(
+				&g_ife_hw_mgr.mgr_common.tasklet_pool[i]);
 			kfree(g_ife_hw_mgr.ctx_pool[i].cdm_cmd);
+			g_ife_hw_mgr.ctx_pool[i].cdm_cmd = NULL;
+			g_ife_hw_mgr.ctx_pool[i].common.tasklet_info = NULL;
+		}
 	}
+	cam_smmu_destroy_handle(
+		g_ife_hw_mgr.mgr_common.img_iommu_hdl_secure);
+	g_ife_hw_mgr.mgr_common.img_iommu_hdl_secure = -1;
+secure_fail:
+	cam_smmu_ops(g_ife_hw_mgr.mgr_common.img_iommu_hdl,
+		CAM_SMMU_DETACH);
+attach_fail:
+	cam_smmu_destroy_handle(g_ife_hw_mgr.mgr_common.img_iommu_hdl);
+	g_ife_hw_mgr.mgr_common.img_iommu_hdl = -1;
 	return rc;
 }
 
diff --git a/drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/hw_utils/cam_isp_packet_parser.c b/drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/hw_utils/cam_isp_packet_parser.c
index 698a4c8..c58578e 100644
--- a/drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/hw_utils/cam_isp_packet_parser.c
+++ b/drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/hw_utils/cam_isp_packet_parser.c
@@ -408,6 +408,7 @@
 
 int cam_isp_add_io_buffers(
 	int                                   iommu_hdl,
+	int                                   sec_iommu_hdl,
 	struct cam_hw_prepare_update_args    *prepare,
 	uint32_t                              base_idx,
 	struct cam_kmd_buf_info              *kmd_buf_info,
@@ -425,7 +426,10 @@
 	uint32_t                            i, j, num_out_buf, num_in_buf;
 	uint32_t                            res_id_out, res_id_in, plane_id;
 	uint32_t                            io_cfg_used_bytes, num_ent;
-	size_t size;
+	size_t                              size;
+	int32_t                             hdl;
+	int                                 mmu_hdl;
+	bool                                mode, is_buf_secure;
 
 	io_cfg = (struct cam_buf_io_cfg *) ((uint8_t *)
 			&prepare->packet->payload +
@@ -536,9 +540,31 @@
 				if (!io_cfg[i].mem_handle[plane_id])
 					break;
 
+				hdl = io_cfg[i].mem_handle[plane_id];
+				if (res->process_cmd(res,
+						CAM_VFE_HW_CMD_GET_SECURE_MODE,
+						&mode,
+						sizeof(bool)))
+					return -EINVAL;
+
+				is_buf_secure = cam_mem_is_secure_buf(hdl);
+				if ((mode == CAM_SECURE_MODE_SECURE) &&
+					is_buf_secure) {
+					mmu_hdl = sec_iommu_hdl;
+				} else if (
+					(mode == CAM_SECURE_MODE_NON_SECURE) &&
+					(!is_buf_secure)) {
+					mmu_hdl = iommu_hdl;
+				} else {
+					CAM_ERR_RATE_LIMIT(CAM_ISP,
+						"Invalid hdl: port mode[%u], buf mode[%u]",
+						mode, is_buf_secure);
+					return -EINVAL;
+				}
+
 				rc = cam_mem_get_io_buf(
 					io_cfg[i].mem_handle[plane_id],
-					iommu_hdl, &io_addr[plane_id], &size);
+					mmu_hdl, &io_addr[plane_id], &size);
 				if (rc) {
 					CAM_ERR(CAM_ISP,
 						"no io addr for plane%d",
diff --git a/drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/hw_utils/include/cam_isp_packet_parser.h b/drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/hw_utils/include/cam_isp_packet_parser.h
index 187e5bc..24b532e 100644
--- a/drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/hw_utils/include/cam_isp_packet_parser.h
+++ b/drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/hw_utils/include/cam_isp_packet_parser.h
@@ -69,6 +69,8 @@
  *                         index and update the HW entries list
  *
  * @iommu_hdl:             Iommu handle to get the IO buf from memory manager
+ * @sec_iommu_hdl:         Secure iommu handle to get the IO buf from
+ *                         memory manager
  * @prepare:               Contain the  packet and HW update variables
  * @base_idx:              Base or dev index of the IFE/VFE HW instance
  * @kmd_buf_info:          Kmd buffer to store the change base command
@@ -79,7 +81,9 @@
  * @return:                0 for success
  *                         -EINVAL for Fail
  */
-int cam_isp_add_io_buffers(int	 iommu_hdl,
+int cam_isp_add_io_buffers(
+	int                                   iommu_hdl,
+	int                                   sec_iommu_hdl,
 	struct cam_hw_prepare_update_args    *prepare,
 	uint32_t                              base_idx,
 	struct cam_kmd_buf_info              *kmd_buf_info,
diff --git a/drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/isp_hw/include/cam_vfe_hw_intf.h b/drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/isp_hw/include/cam_vfe_hw_intf.h
index a08248d..a64379c 100644
--- a/drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/isp_hw/include/cam_vfe_hw_intf.h
+++ b/drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/isp_hw/include/cam_vfe_hw_intf.h
@@ -49,6 +49,7 @@
 	CAM_VFE_HW_CMD_GET_BUF_UPDATE,
 	CAM_VFE_HW_CMD_GET_REG_UPDATE,
 	CAM_VFE_HW_CMD_GET_HFR_UPDATE,
+	CAM_VFE_HW_CMD_GET_SECURE_MODE,
 	CAM_VFE_HW_CMD_MAX,
 };
 
diff --git a/drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe_bus/cam_vfe_bus_ver2.c b/drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe_bus/cam_vfe_bus_ver2.c
index 1115112..7aa5b9d 100644
--- a/drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe_bus/cam_vfe_bus_ver2.c
+++ b/drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe_bus/cam_vfe_bus_ver2.c
@@ -94,6 +94,9 @@
 	struct cam_vfe_bus_irq_evt_payload          evt_payload[
 		CAM_VFE_BUS_VER2_PAYLOAD_MAX];
 	struct list_head                            free_payload_list;
+	struct mutex                                bus_mutex;
+	uint32_t                                    secure_mode;
+	uint32_t                                    num_sec_out;
 };
 
 struct cam_vfe_bus_ver2_wm_resource_data {
@@ -168,6 +171,7 @@
 	uint32_t                         max_width;
 	uint32_t                         max_height;
 	struct cam_cdm_utils_ops        *cdm_util_ops;
+	uint32_t                         secure_mode;
 };
 
 struct cam_vfe_bus_ver2_priv {
@@ -184,6 +188,10 @@
 	uint32_t                            irq_handle;
 };
 
+static int cam_vfe_bus_process_cmd(
+	struct cam_isp_resource_node *priv,
+	uint32_t cmd_type, void *cmd_args, uint32_t arg_size);
+
 static int cam_vfe_bus_get_evt_payload(
 	struct cam_vfe_bus_ver2_common_data  *common_data,
 	struct cam_vfe_bus_irq_evt_payload  **evt_payload)
@@ -328,6 +336,34 @@
 	return rc;
 }
 
+static bool cam_vfe_bus_can_be_secure(uint32_t out_type)
+{
+	switch (out_type) {
+	case CAM_VFE_BUS_VER2_VFE_OUT_FULL:
+	case CAM_VFE_BUS_VER2_VFE_OUT_DS4:
+	case CAM_VFE_BUS_VER2_VFE_OUT_DS16:
+	case CAM_VFE_BUS_VER2_VFE_OUT_FD:
+	case CAM_VFE_BUS_VER2_VFE_OUT_RAW_DUMP:
+	case CAM_VFE_BUS_VER2_VFE_OUT_RDI0:
+	case CAM_VFE_BUS_VER2_VFE_OUT_RDI1:
+	case CAM_VFE_BUS_VER2_VFE_OUT_RDI2:
+		return true;
+
+	case CAM_VFE_BUS_VER2_VFE_OUT_PDAF:
+	case CAM_VFE_BUS_VER2_VFE_OUT_STATS_HDR_BE:
+	case CAM_VFE_BUS_VER2_VFE_OUT_STATS_HDR_BHIST:
+	case CAM_VFE_BUS_VER2_VFE_OUT_STATS_TL_BG:
+	case CAM_VFE_BUS_VER2_VFE_OUT_STATS_BF:
+	case CAM_VFE_BUS_VER2_VFE_OUT_STATS_AWB_BG:
+	case CAM_VFE_BUS_VER2_VFE_OUT_STATS_BHIST:
+	case CAM_VFE_BUS_VER2_VFE_OUT_STATS_RS:
+	case CAM_VFE_BUS_VER2_VFE_OUT_STATS_CS:
+	case CAM_VFE_BUS_VER2_VFE_OUT_STATS_IHIST:
+	default:
+		return false;
+	}
+}
+
 static enum cam_vfe_bus_ver2_vfe_out_type
 	cam_vfe_bus_get_out_res_id(uint32_t res_type)
 {
@@ -846,7 +882,7 @@
 			case PLANE_Y:
 				break;
 			default:
-				CAM_ERR(CAM_ISP, "Invalid plane %d\n", plane);
+				CAM_ERR(CAM_ISP, "Invalid plane %d", plane);
 				return -EINVAL;
 			}
 			break;
@@ -862,7 +898,7 @@
 			case PLANE_Y:
 				break;
 			default:
-				CAM_ERR(CAM_ISP, "Invalid plane %d\n", plane);
+				CAM_ERR(CAM_ISP, "Invalid plane %d", plane);
 				return -EINVAL;
 			}
 			break;
@@ -877,7 +913,7 @@
 			case PLANE_Y:
 				break;
 			default:
-				CAM_ERR(CAM_ISP, "Invalid plane %d\n", plane);
+				CAM_ERR(CAM_ISP, "Invalid plane %d", plane);
 				return -EINVAL;
 			}
 			break;
@@ -891,12 +927,12 @@
 			case PLANE_Y:
 				break;
 			default:
-				CAM_ERR(CAM_ISP, "Invalid plane %d\n", plane);
+				CAM_ERR(CAM_ISP, "Invalid plane %d", plane);
 				return -EINVAL;
 			}
 			break;
 		default:
-			CAM_ERR(CAM_ISP, "Invalid format %d\n",
+			CAM_ERR(CAM_ISP, "Invalid format %d",
 				rsrc_data->format);
 			return -EINVAL;
 		}
@@ -1068,7 +1104,7 @@
 
 	wm_res = th_payload->handler_priv;
 	if (!wm_res) {
-		CAM_ERR_RATE_LIMIT(CAM_ISP, "Error! No resource\n");
+		CAM_ERR_RATE_LIMIT(CAM_ISP, "Error: No resource");
 		return -ENODEV;
 	}
 
@@ -1080,7 +1116,7 @@
 	rc  = cam_vfe_bus_get_evt_payload(rsrc_data->common_data, &evt_payload);
 	if (rc) {
 		CAM_ERR_RATE_LIMIT(CAM_ISP,
-			"No tasklet_cmd is free in queue\n");
+			"No tasklet_cmd is free in queue");
 		return rc;
 	}
 
@@ -1177,10 +1213,8 @@
 
 	rsrc_data = wm_res->res_priv;
 	wm_res->res_priv = NULL;
-	if (!rsrc_data) {
-		CAM_ERR(CAM_ISP, "Error! WM res priv is NULL");
+	if (!rsrc_data)
 		return -ENOMEM;
-	}
 	kfree(rsrc_data);
 
 	return 0;
@@ -1472,7 +1506,7 @@
 
 	comp_grp = th_payload->handler_priv;
 	if (!comp_grp) {
-		CAM_ERR_RATE_LIMIT(CAM_ISP, "Error! No resource\n");
+		CAM_ERR_RATE_LIMIT(CAM_ISP, "No resource");
 		return -ENODEV;
 	}
 
@@ -1484,7 +1518,7 @@
 	rc  = cam_vfe_bus_get_evt_payload(rsrc_data->common_data, &evt_payload);
 	if (rc) {
 		CAM_ERR_RATE_LIMIT(CAM_ISP,
-			"No tasklet_cmd is free in queue\n");
+			"No tasklet_cmd is free in queue");
 		return rc;
 	}
 
@@ -1611,7 +1645,7 @@
 		break;
 	default:
 		rc = CAM_VFE_IRQ_STATUS_ERR;
-		CAM_ERR(CAM_ISP, "Error! Invalid comp_grp_type %u",
+		CAM_ERR(CAM_ISP, "Invalid comp_grp_type %u",
 			rsrc_data->comp_grp_type);
 		break;
 	}
@@ -1632,10 +1666,9 @@
 
 	rsrc_data = kzalloc(sizeof(struct cam_vfe_bus_ver2_comp_grp_data),
 		GFP_KERNEL);
-	if (!rsrc_data) {
-		CAM_DBG(CAM_ISP, "Failed to alloc for comp_grp_priv");
+	if (!rsrc_data)
 		return -ENOMEM;
-	}
+
 	comp_grp->res_priv = rsrc_data;
 
 	comp_grp->res_state = CAM_ISP_RESOURCE_STATE_AVAILABLE;
@@ -1682,7 +1715,7 @@
 	comp_grp->res_priv = NULL;
 
 	if (!rsrc_data) {
-		CAM_ERR(CAM_ISP, "Error! comp_grp_priv is NULL");
+		CAM_ERR(CAM_ISP, "comp_grp_priv is NULL");
 		return -ENODEV;
 	}
 	kfree(rsrc_data);
@@ -1690,6 +1723,22 @@
 	return 0;
 }
 
+static int cam_vfe_bus_get_secure_mode(void *priv, void *cmd_args,
+	uint32_t arg_size)
+{
+	bool *mode = cmd_args;
+	struct cam_isp_resource_node *res =
+		(struct cam_isp_resource_node *) priv;
+	struct cam_vfe_bus_ver2_vfe_out_data *rsrc_data =
+		(struct cam_vfe_bus_ver2_vfe_out_data *)res->res_priv;
+
+	*mode =
+		(rsrc_data->secure_mode == CAM_SECURE_MODE_SECURE) ?
+		true : false;
+
+	return 0;
+}
+
 static int cam_vfe_bus_acquire_vfe_out(void *bus_priv, void *acquire_args,
 	uint32_t args_size)
 {
@@ -1705,6 +1754,7 @@
 	struct cam_vfe_hw_vfe_out_acquire_args *out_acquire_args;
 	struct cam_isp_resource_node           *rsrc_node = NULL;
 	struct cam_vfe_bus_ver2_vfe_out_data   *rsrc_data = NULL;
+	uint32_t                                secure_caps = 0, mode;
 
 	if (!bus_priv || !acquire_args) {
 		CAM_ERR(CAM_ISP, "Invalid Param");
@@ -1734,6 +1784,33 @@
 	}
 
 	rsrc_data = rsrc_node->res_priv;
+	secure_caps = cam_vfe_bus_can_be_secure(
+		rsrc_data->out_type);
+	mode = out_acquire_args->out_port_info->secure_mode;
+	mutex_lock(&rsrc_data->common_data->bus_mutex);
+	if (secure_caps) {
+		if (!rsrc_data->common_data->num_sec_out) {
+			rsrc_data->secure_mode = mode;
+			rsrc_data->common_data->secure_mode = mode;
+		} else {
+			if (mode == rsrc_data->common_data->secure_mode) {
+				rsrc_data->secure_mode =
+					rsrc_data->common_data->secure_mode;
+			} else {
+				rc = -EINVAL;
+				CAM_ERR_RATE_LIMIT(CAM_ISP,
+					"Mismatch: Acquire mode[%d], drvr mode[%d]",
+					rsrc_data->common_data->secure_mode,
+					mode);
+				mutex_unlock(
+					&rsrc_data->common_data->bus_mutex);
+				return -EINVAL;
+			}
+		}
+		rsrc_data->common_data->num_sec_out++;
+	}
+	mutex_unlock(&rsrc_data->common_data->bus_mutex);
+
 	rsrc_data->num_wm = num_wm;
 	rsrc_node->res_id = out_acquire_args->out_port_info->res_type;
 	rsrc_node->tasklet_info = acq_args->tasklet;
@@ -1814,6 +1891,7 @@
 	uint32_t i;
 	struct cam_isp_resource_node          *vfe_out = NULL;
 	struct cam_vfe_bus_ver2_vfe_out_data  *rsrc_data = NULL;
+	uint32_t                               secure_caps = 0;
 
 	if (!bus_priv || !release_args) {
 		CAM_ERR(CAM_ISP, "Invalid input bus_priv %pK release_args %pK",
@@ -1825,7 +1903,7 @@
 	rsrc_data = vfe_out->res_priv;
 
 	if (vfe_out->res_state != CAM_ISP_RESOURCE_STATE_RESERVED) {
-		CAM_ERR(CAM_ISP, "Error! Invalid resource state:%d",
+		CAM_ERR(CAM_ISP, "Invalid resource state:%d",
 			vfe_out->res_state);
 	}
 
@@ -1841,6 +1919,32 @@
 	vfe_out->cdm_ops = NULL;
 	rsrc_data->cdm_util_ops = NULL;
 
+	secure_caps = cam_vfe_bus_can_be_secure(rsrc_data->out_type);
+	mutex_lock(&rsrc_data->common_data->bus_mutex);
+	if (secure_caps) {
+		if (rsrc_data->secure_mode ==
+			rsrc_data->common_data->secure_mode) {
+			rsrc_data->common_data->num_sec_out--;
+			rsrc_data->secure_mode =
+				CAM_SECURE_MODE_NON_SECURE;
+		} else {
+			/*
+			 * The validity of the mode is properly
+			 * checked while acquiring the output port.
+			 * not expected to reach here, unless there is
+			 * some corruption.
+			 */
+			CAM_ERR(CAM_ISP, "driver[%d],resource[%d] mismatch",
+				rsrc_data->common_data->secure_mode,
+				rsrc_data->secure_mode);
+		}
+
+		if (!rsrc_data->common_data->num_sec_out)
+			rsrc_data->common_data->secure_mode =
+				CAM_SECURE_MODE_NON_SECURE;
+	}
+	mutex_unlock(&rsrc_data->common_data->bus_mutex);
+
 	if (vfe_out->res_state == CAM_ISP_RESOURCE_STATE_RESERVED)
 		vfe_out->res_state = CAM_ISP_RESOURCE_STATE_AVAILABLE;
 
@@ -1865,7 +1969,7 @@
 	CAM_DBG(CAM_ISP, "Start resource index %d", rsrc_data->out_type);
 
 	if (vfe_out->res_state != CAM_ISP_RESOURCE_STATE_RESERVED) {
-		CAM_ERR(CAM_ISP, "Error! Invalid resource state:%d",
+		CAM_ERR(CAM_ISP, "Invalid resource state:%d",
 			vfe_out->res_state);
 		return -EACCES;
 	}
@@ -1972,7 +2076,6 @@
 	rsrc_data = kzalloc(sizeof(struct cam_vfe_bus_ver2_vfe_out_data),
 		GFP_KERNEL);
 	if (!rsrc_data) {
-		CAM_DBG(CAM_ISP, "Error! Failed to alloc for vfe out priv");
 		rc = -ENOMEM;
 		return rc;
 	}
@@ -1988,12 +2091,14 @@
 		ver2_hw_info->vfe_out_hw_info[index].max_width;
 	rsrc_data->max_height  =
 		ver2_hw_info->vfe_out_hw_info[index].max_height;
+	rsrc_data->secure_mode = CAM_SECURE_MODE_NON_SECURE;
 
 	vfe_out->start = cam_vfe_bus_start_vfe_out;
 	vfe_out->stop = cam_vfe_bus_stop_vfe_out;
 	vfe_out->top_half_handler = cam_vfe_bus_handle_vfe_out_done_top_half;
 	vfe_out->bottom_half_handler =
 		cam_vfe_bus_handle_vfe_out_done_bottom_half;
+	vfe_out->process_cmd = cam_vfe_bus_process_cmd;
 	vfe_out->hw_intf = ver2_bus_priv->common_data.hw_intf;
 
 	return 0;
@@ -2014,10 +2119,8 @@
 	INIT_LIST_HEAD(&vfe_out->list);
 	vfe_out->res_priv = NULL;
 
-	if (!rsrc_data) {
-		CAM_ERR(CAM_ISP, "Error! vfe out priv is NULL");
+	if (!rsrc_data)
 		return -ENOMEM;
-	}
 	kfree(rsrc_data);
 
 	return 0;
@@ -2394,7 +2497,7 @@
 	uint32_t                         top_irq_reg_mask[2] = {0};
 
 	if (!bus_priv) {
-		CAM_ERR(CAM_ISP, "Error! Invalid args");
+		CAM_ERR(CAM_ISP, "Invalid args");
 		return -EINVAL;
 	}
 
@@ -2425,7 +2528,7 @@
 	int                              rc;
 
 	if (!bus_priv || (bus_priv->irq_handle <= 0)) {
-		CAM_ERR(CAM_ISP, "Error! Invalid args");
+		CAM_ERR(CAM_ISP, "Error: Invalid args");
 		return -EINVAL;
 	}
 
@@ -2438,13 +2541,20 @@
 	return rc;
 }
 
-static int cam_vfe_bus_process_cmd(void *priv,
+static int __cam_vfe_bus_process_cmd(void *priv,
+	uint32_t cmd_type, void *cmd_args, uint32_t arg_size)
+{
+	return cam_vfe_bus_process_cmd(priv, cmd_type, cmd_args, arg_size);
+}
+
+static int cam_vfe_bus_process_cmd(
+	struct cam_isp_resource_node *priv,
 	uint32_t cmd_type, void *cmd_args, uint32_t arg_size)
 {
 	int rc = -EINVAL;
 
 	if (!priv || !cmd_args) {
-		CAM_ERR_RATE_LIMIT(CAM_ISP, "Error! Invalid input arguments\n");
+		CAM_ERR_RATE_LIMIT(CAM_ISP, "Invalid input arguments");
 		return -EINVAL;
 	}
 
@@ -2455,8 +2565,11 @@
 	case CAM_VFE_HW_CMD_GET_HFR_UPDATE:
 		rc = cam_vfe_bus_update_hfr(priv, cmd_args, arg_size);
 		break;
+	case CAM_VFE_HW_CMD_GET_SECURE_MODE:
+		rc = cam_vfe_bus_get_secure_mode(priv, cmd_args, arg_size);
+		break;
 	default:
-		CAM_ERR_RATE_LIMIT(CAM_ISP, "Inval camif process command:%d\n",
+		CAM_ERR_RATE_LIMIT(CAM_ISP, "Invalid camif process command:%d",
 			cmd_type);
 		break;
 	}
@@ -2503,18 +2616,21 @@
 	}
 	vfe_bus_local->bus_priv = bus_priv;
 
+	bus_priv->common_data.num_sec_out        = 0;
+	bus_priv->common_data.secure_mode        = CAM_SECURE_MODE_NON_SECURE;
 	bus_priv->common_data.core_index         = soc_info->index;
 	bus_priv->common_data.mem_base           =
 		CAM_SOC_GET_REG_MAP_START(soc_info, VFE_CORE_BASE_IDX);
 	bus_priv->common_data.hw_intf            = hw_intf;
 	bus_priv->common_data.vfe_irq_controller = vfe_irq_controller;
 	bus_priv->common_data.common_reg         = &ver2_hw_info->common_reg;
+	mutex_init(&bus_priv->common_data.bus_mutex);
 
 	rc = cam_irq_controller_init(drv_name, bus_priv->common_data.mem_base,
 		&ver2_hw_info->common_reg.irq_reg_info,
 		&bus_priv->common_data.bus_irq_controller);
 	if (rc) {
-		CAM_ERR(CAM_ISP, "Error! cam_irq_controller_init failed");
+		CAM_ERR(CAM_ISP, "cam_irq_controller_init failed");
 		goto free_bus_priv;
 	}
 
@@ -2526,7 +2642,7 @@
 		rc = cam_vfe_bus_init_wm_resource(i, bus_priv, bus_hw_info,
 			&bus_priv->bus_client[i]);
 		if (rc < 0) {
-			CAM_ERR(CAM_ISP, "Error! Init WM failed rc=%d", rc);
+			CAM_ERR(CAM_ISP, "Init WM failed rc=%d", rc);
 			goto deinit_wm;
 		}
 	}
@@ -2564,7 +2680,7 @@
 	vfe_bus_local->hw_ops.deinit       = cam_vfe_bus_deinit_hw;
 	vfe_bus_local->top_half_handler    = cam_vfe_bus_ver2_handle_irq;
 	vfe_bus_local->bottom_half_handler = NULL;
-	vfe_bus_local->hw_ops.process_cmd  = cam_vfe_bus_process_cmd;
+	vfe_bus_local->hw_ops.process_cmd  = __cam_vfe_bus_process_cmd;
 
 	*vfe_bus = vfe_bus_local;
 
@@ -2607,14 +2723,14 @@
 	struct cam_vfe_bus              *vfe_bus_local;
 
 	if (!vfe_bus || !*vfe_bus) {
-		CAM_ERR(CAM_ISP, "Error! Invalid input");
+		CAM_ERR(CAM_ISP, "Invalid input");
 		return -EINVAL;
 	}
 	vfe_bus_local = *vfe_bus;
 
 	bus_priv = vfe_bus_local->bus_priv;
 	if (!bus_priv) {
-		CAM_ERR(CAM_ISP, "Error! bus_priv is NULL");
+		CAM_ERR(CAM_ISP, "bus_priv is NULL");
 		rc = -ENODEV;
 		goto free_bus_local;
 	}
@@ -2627,21 +2743,21 @@
 		rc = cam_vfe_bus_deinit_wm_resource(&bus_priv->bus_client[i]);
 		if (rc < 0)
 			CAM_ERR(CAM_ISP,
-				"Error! Deinit WM failed rc=%d", rc);
+				"Deinit WM failed rc=%d", rc);
 	}
 
 	for (i = 0; i < CAM_VFE_BUS_VER2_COMP_GRP_MAX; i++) {
 		rc = cam_vfe_bus_deinit_comp_grp(&bus_priv->comp_grp[i]);
 		if (rc < 0)
 			CAM_ERR(CAM_ISP,
-				"Error! Deinit Comp Grp failed rc=%d", rc);
+				"Deinit Comp Grp failed rc=%d", rc);
 	}
 
 	for (i = 0; i < CAM_VFE_BUS_VER2_VFE_OUT_MAX; i++) {
 		rc = cam_vfe_bus_deinit_vfe_out_resource(&bus_priv->vfe_out[i]);
 		if (rc < 0)
 			CAM_ERR(CAM_ISP,
-				"Error! Deinit VFE Out failed rc=%d", rc);
+				"Deinit VFE Out failed rc=%d", rc);
 	}
 
 	INIT_LIST_HEAD(&bus_priv->free_comp_grp);
@@ -2652,8 +2768,9 @@
 		&bus_priv->common_data.bus_irq_controller);
 	if (rc)
 		CAM_ERR(CAM_ISP,
-			"Error! Deinit IRQ Controller failed rc=%d", rc);
+			"Deinit IRQ Controller failed rc=%d", rc);
 
+	mutex_destroy(&bus_priv->common_data.bus_mutex);
 	kfree(vfe_bus_local->bus_priv);
 
 free_bus_local:
diff --git a/drivers/media/platform/msm/camera/cam_jpeg/jpeg_hw/cam_jpeg_hw_mgr.c b/drivers/media/platform/msm/camera/cam_jpeg/jpeg_hw/cam_jpeg_hw_mgr.c
index bdfa785..2cd6b04 100644
--- a/drivers/media/platform/msm/camera/cam_jpeg/jpeg_hw/cam_jpeg_hw_mgr.c
+++ b/drivers/media/platform/msm/camera/cam_jpeg/jpeg_hw/cam_jpeg_hw_mgr.c
@@ -579,7 +579,7 @@
 		(void *)packet, (void *)cmd_desc,
 		sizeof(struct cam_cmd_buf_desc));
 
-	rc = cam_packet_util_process_patches(packet, hw_mgr->iommu_hdl);
+	rc = cam_packet_util_process_patches(packet, hw_mgr->iommu_hdl, -1);
 	if (rc) {
 		CAM_ERR(CAM_JPEG, "Patch processing failed %d", rc);
 		return rc;
diff --git a/drivers/media/platform/msm/camera/cam_req_mgr/cam_mem_mgr.c b/drivers/media/platform/msm/camera/cam_req_mgr/cam_mem_mgr.c
index c150244..9d454e9 100644
--- a/drivers/media/platform/msm/camera/cam_req_mgr/cam_mem_mgr.c
+++ b/drivers/media/platform/msm/camera/cam_req_mgr/cam_mem_mgr.c
@@ -52,6 +52,8 @@
 		rc = DMA_FROM_DEVICE;
 	else if (flags & CAM_MEM_FLAG_HW_READ_WRITE)
 		rc = DMA_BIDIRECTIONAL;
+	else if (flags & CAM_MEM_FLAG_PROTECTED_MODE)
+		rc = DMA_BIDIRECTIONAL;
 
 	return rc;
 }
@@ -211,10 +213,16 @@
 		goto handle_mismatch;
 	}
 
-	rc = cam_smmu_get_iova(mmu_handle,
-		tbl.bufq[idx].fd,
-		iova_ptr,
-		len_ptr);
+	if (CAM_MEM_MGR_IS_SECURE_HDL(buf_handle))
+		rc = cam_smmu_get_stage2_iova(mmu_handle,
+			tbl.bufq[idx].fd,
+			iova_ptr,
+			len_ptr);
+	else
+		rc = cam_smmu_get_iova(mmu_handle,
+			tbl.bufq[idx].fd,
+			iova_ptr,
+			len_ptr);
 	if (rc < 0)
 		CAM_ERR(CAM_CRM, "fail to get buf hdl :%d", buf_handle);
 
@@ -376,10 +384,12 @@
 	uint32_t ion_flag = 0;
 	int rc;
 
-	if (cmd->flags & CAM_MEM_FLAG_PROTECTED_MODE)
+	if (cmd->flags & CAM_MEM_FLAG_PROTECTED_MODE) {
 		heap_id = ION_HEAP(ION_SECURE_DISPLAY_HEAP_ID);
-	else
+		ion_flag |= ION_FLAG_SECURE | ION_FLAG_CP_CAMERA;
+	} else {
 		heap_id = ION_HEAP(ION_SYSTEM_HEAP_ID);
+	}
 
 	if (cmd->flags & CAM_MEM_FLAG_CACHE)
 		ion_flag |= ION_FLAG_CACHED;
@@ -466,10 +476,11 @@
 
 	if (flags & CAM_MEM_FLAG_PROTECTED_MODE) {
 		for (i = 0; i < num_hdls; i++) {
-			rc = cam_smmu_map_sec_iova(mmu_hdls[i],
+			rc = cam_smmu_map_stage2_iova(mmu_hdls[i],
 				fd,
 				dir,
-				(dma_addr_t *)hw_vaddr,
+				tbl.client,
+				(ion_phys_addr_t *)hw_vaddr,
 				len);
 
 			if (rc < 0) {
@@ -498,7 +509,7 @@
 multi_map_fail:
 	if (flags & CAM_MEM_FLAG_PROTECTED_MODE)
 		for (--i; i > 0; i--)
-			cam_smmu_unmap_sec_iova(mmu_hdls[i], fd);
+			cam_smmu_unmap_stage2_iova(mmu_hdls[i], fd);
 	else
 		for (--i; i > 0; i--)
 			cam_smmu_unmap_iova(mmu_hdls[i],
@@ -543,8 +554,9 @@
 		goto slot_fail;
 	}
 
-	if (cmd->flags & CAM_MEM_FLAG_HW_READ_WRITE ||
-		cmd->flags & CAM_MEM_FLAG_HW_SHARED_ACCESS) {
+	if ((cmd->flags & CAM_MEM_FLAG_HW_READ_WRITE) ||
+		(cmd->flags & CAM_MEM_FLAG_HW_SHARED_ACCESS) ||
+		(cmd->flags & CAM_MEM_FLAG_PROTECTED_MODE)) {
 
 		enum cam_smmu_region_id region;
 
@@ -570,6 +582,8 @@
 	tbl.bufq[idx].fd = ion_fd;
 	tbl.bufq[idx].flags = cmd->flags;
 	tbl.bufq[idx].buf_handle = GET_MEM_HANDLE(idx, ion_fd);
+	if (cmd->flags & CAM_MEM_FLAG_PROTECTED_MODE)
+		CAM_MEM_MGR_SET_SECURE_HDL(tbl.bufq[idx].buf_handle, true);
 	tbl.bufq[idx].kmdvaddr = 0;
 
 	if (cmd->num_hdl > 0)
@@ -630,7 +644,8 @@
 		return -EINVAL;
 	}
 
-	if (cmd->flags & CAM_MEM_FLAG_HW_READ_WRITE) {
+	if ((cmd->flags & CAM_MEM_FLAG_HW_READ_WRITE) ||
+		(cmd->flags & CAM_MEM_FLAG_PROTECTED_MODE)) {
 		rc = cam_mem_util_map_hw_va(cmd->flags,
 			cmd->mmu_hdls,
 			cmd->num_hdl,
@@ -652,6 +667,8 @@
 	tbl.bufq[idx].fd = cmd->fd;
 	tbl.bufq[idx].flags = cmd->flags;
 	tbl.bufq[idx].buf_handle = GET_MEM_HANDLE(idx, cmd->fd);
+	if (cmd->flags & CAM_MEM_FLAG_PROTECTED_MODE)
+		CAM_MEM_MGR_SET_SECURE_HDL(tbl.bufq[idx].buf_handle, true);
 	tbl.bufq[idx].kmdvaddr = 0;
 
 	if (cmd->num_hdl > 0)
@@ -699,7 +716,7 @@
 
 	if (flags & CAM_MEM_FLAG_PROTECTED_MODE) {
 		for (i = 0; i < num_hdls; i++) {
-			rc = cam_smmu_unmap_sec_iova(mmu_hdls[i], fd);
+			rc = cam_smmu_unmap_stage2_iova(mmu_hdls[i], fd);
 			if (rc < 0)
 				goto unmap_end;
 		}
@@ -741,8 +758,9 @@
 			region = CAM_SMMU_REGION_IO;
 	}
 
-	if (tbl.bufq[idx].flags & CAM_MEM_FLAG_HW_READ_WRITE ||
-		tbl.bufq[idx].flags & CAM_MEM_FLAG_HW_SHARED_ACCESS)
+	if ((tbl.bufq[idx].flags & CAM_MEM_FLAG_HW_READ_WRITE) ||
+		(tbl.bufq[idx].flags & CAM_MEM_FLAG_HW_SHARED_ACCESS) ||
+		(tbl.bufq[idx].flags & CAM_MEM_FLAG_PROTECTED_MODE))
 		rc = cam_mem_util_unmap_hw_va(idx, region);
 
 
diff --git a/drivers/media/platform/msm/camera/cam_req_mgr/cam_mem_mgr_api.h b/drivers/media/platform/msm/camera/cam_req_mgr/cam_mem_mgr_api.h
index 0858b8a..af7962a 100644
--- a/drivers/media/platform/msm/camera/cam_req_mgr/cam_mem_mgr_api.h
+++ b/drivers/media/platform/msm/camera/cam_req_mgr/cam_mem_mgr_api.h
@@ -95,4 +95,9 @@
 int cam_mem_get_cpu_buf(int32_t buf_handle, uint64_t *vaddr_ptr,
 	size_t *len);
 
+static inline bool cam_mem_is_secure_buf(int32_t buf_handle)
+{
+	return CAM_MEM_MGR_IS_SECURE_HDL(buf_handle);
+}
+
 #endif /* _CAM_MEM_MGR_API_H_ */
diff --git a/drivers/media/platform/msm/camera/cam_sensor_module/cam_csiphy/cam_csiphy_core.c b/drivers/media/platform/msm/camera/cam_sensor_module/cam_csiphy/cam_csiphy_core.c
index f455f18..1a3f947 100644
--- a/drivers/media/platform/msm/camera/cam_sensor_module/cam_csiphy/cam_csiphy_core.c
+++ b/drivers/media/platform/msm/camera/cam_sensor_module/cam_csiphy/cam_csiphy_core.c
@@ -14,10 +14,32 @@
 #include "cam_csiphy_core.h"
 #include "cam_csiphy_dev.h"
 #include "cam_csiphy_soc.h"
+
+#include <soc/qcom/scm.h>
 #include <cam_mem_mgr.h>
 
 static int cam_csiphy_mem_dmp_param;
 module_param(cam_csiphy_mem_dmp_param, int, 0644);
+#define SCM_SVC_CAMERASS 0x18
+#define SECURE_SYSCALL_ID 0x6
+
+static int cam_csiphy_notify_secure_mode(int phy, bool protect)
+{
+	struct scm_desc desc = {0};
+
+	desc.arginfo = SCM_ARGS(2, SCM_VAL, SCM_VAL);
+	desc.args[0] = protect;
+	desc.args[1] = phy;
+
+	CAM_DBG(CAM_CSIPHY, "phy : %d, protect : %d", phy, protect);
+	if (scm_call2(SCM_SIP_FNID(SCM_SVC_CAMERASS, SECURE_SYSCALL_ID),
+		&desc)) {
+		CAM_ERR(CAM_CSIPHY, "scm call to hypervisor failed");
+		return -EINVAL;
+	}
+
+	return 0;
+}
 
 void cam_csiphy_query_cap(struct csiphy_device *csiphy_dev,
 	struct cam_csiphy_query_cap *csiphy_cap)
@@ -102,6 +124,7 @@
 	cmd_buf += cmd_desc->offset / 4;
 	cam_cmd_csiphy_info = (struct cam_csiphy_info *)cmd_buf;
 
+	csiphy_dev->config_count++;
 	csiphy_dev->csiphy_info.lane_cnt += cam_cmd_csiphy_info->lane_cnt;
 	csiphy_dev->csiphy_info.lane_mask |= cam_cmd_csiphy_info->lane_mask;
 	csiphy_dev->csiphy_info.csiphy_3phase =
@@ -114,6 +137,13 @@
 		csiphy_dev->csiphy_info.settle_time =
 			cam_cmd_csiphy_info->settle_time;
 	csiphy_dev->csiphy_info.data_rate = cam_cmd_csiphy_info->data_rate;
+	csiphy_dev->csiphy_info.secure_mode = cam_cmd_csiphy_info->secure_mode;
+
+	if (csiphy_dev->csiphy_info.secure_mode &&
+		(csiphy_dev->config_count == 1))
+		rc = cam_csiphy_notify_secure_mode(
+			csiphy_dev->soc_info.index,
+			CAM_SECURE_MODE_SECURE);
 
 	return rc;
 }
@@ -483,9 +513,20 @@
 				session_hdl[1] = -1;
 			csiphy_dev->is_acquired_dev_combo_mode = 0;
 		}
+
+		csiphy_dev->config_count--;
 		csiphy_dev->acquire_count--;
 		if (csiphy_dev->acquire_count == 0)
 			csiphy_dev->csiphy_state = CAM_CSIPHY_RELEASE;
+
+		if (csiphy_dev->csiphy_info.secure_mode &&
+			(!csiphy_dev->config_count)) {
+			csiphy_dev->csiphy_info.secure_mode =
+				CAM_SECURE_MODE_NON_SECURE;
+			rc = cam_csiphy_notify_secure_mode(
+				csiphy_dev->soc_info.index,
+				CAM_SECURE_MODE_NON_SECURE);
+		}
 	}
 		break;
 	case CAM_CONFIG_DEV: {
diff --git a/drivers/media/platform/msm/camera/cam_sensor_module/cam_csiphy/cam_csiphy_dev.h b/drivers/media/platform/msm/camera/cam_sensor_module/cam_csiphy/cam_csiphy_dev.h
index 35e96e4..25891c5 100644
--- a/drivers/media/platform/msm/camera/cam_sensor_module/cam_csiphy/cam_csiphy_dev.h
+++ b/drivers/media/platform/msm/camera/cam_sensor_module/cam_csiphy/cam_csiphy_dev.h
@@ -176,7 +176,7 @@
 	uint8_t     csiphy_3phase;
 	uint8_t     combo_mode;
 	uint8_t     lane_cnt;
-	uint8_t     reserved;
+	uint8_t     secure_mode;
 	uint64_t    settle_time;
 	uint64_t    settle_time_combo_sensor;
 	uint64_t    data_rate;
@@ -233,6 +233,7 @@
 	uint32_t is_acquired_dev_combo_mode;
 	struct cam_hw_soc_info   soc_info;
 	uint32_t cpas_handle;
+	uint32_t config_count;
 };
 
 #endif /* _CAM_CSIPHY_DEV_H_ */
diff --git a/drivers/media/platform/msm/camera/cam_smmu/cam_smmu_api.c b/drivers/media/platform/msm/camera/cam_smmu/cam_smmu_api.c
index ff7a0e5..cbf54f7 100644
--- a/drivers/media/platform/msm/camera/cam_smmu/cam_smmu_api.c
+++ b/drivers/media/platform/msm/camera/cam_smmu/cam_smmu_api.c
@@ -21,7 +21,8 @@
 #include <linux/msm_dma_iommu_mapping.h>
 #include <linux/workqueue.h>
 #include <linux/genalloc.h>
-
+#include <soc/qcom/scm.h>
+#include <soc/qcom/secure_buffer.h>
 #include "cam_smmu_api.h"
 #include "cam_debug_util.h"
 
@@ -118,6 +119,7 @@
 		int, void*);
 	void *token[CAM_SMMU_CB_MAX];
 	int cb_count;
+	int secure_count;
 };
 
 struct cam_iommu_cb_set {
@@ -151,6 +153,17 @@
 	size_t phys_len;
 };
 
+struct cam_sec_buff_info {
+	struct ion_handle *i_hdl;
+	struct ion_client *i_client;
+	enum dma_data_direction dir;
+	int ref_count;
+	dma_addr_t paddr;
+	struct list_head list;
+	int ion_fd;
+	size_t len;
+};
+
 static struct cam_iommu_cb_set iommu_cb_set;
 
 static enum dma_data_direction cam_smmu_translate_dir(
@@ -166,6 +179,9 @@
 static struct cam_dma_buff_info *cam_smmu_find_mapping_by_ion_index(int idx,
 	int ion_fd);
 
+static struct cam_sec_buff_info *cam_smmu_find_mapping_by_sec_buf_idx(int idx,
+	int ion_fd);
+
 static int cam_smmu_init_scratch_map(struct scratch_mapping *scratch_map,
 	dma_addr_t base, size_t size,
 	int order);
@@ -544,7 +560,15 @@
 					"Error: %s already got handle 0x%x",
 					name,
 					iommu_cb_set.cb_info[i].handle);
+
+				if (iommu_cb_set.cb_info[i].is_secure)
+					iommu_cb_set.cb_info[i].secure_count++;
+
 				mutex_unlock(&iommu_cb_set.cb_info[i].lock);
+				if (iommu_cb_set.cb_info[i].is_secure) {
+					*hdl = iommu_cb_set.cb_info[i].handle;
+					return 0;
+				}
 				return -EINVAL;
 			}
 
@@ -556,6 +580,8 @@
 			/* put handle in the table */
 			iommu_cb_set.cb_info[i].handle = handle;
 			iommu_cb_set.cb_info[i].cb_count = 0;
+			if (iommu_cb_set.cb_info[i].is_secure)
+				iommu_cb_set.cb_info[i].secure_count++;
 			*hdl = handle;
 			CAM_DBG(CAM_SMMU, "%s creates handle 0x%x",
 				name, handle);
@@ -693,6 +719,24 @@
 
 	CAM_ERR(CAM_SMMU, "Error: Cannot find fd %d by index %d",
 		ion_fd, idx);
+
+	return NULL;
+}
+
+static struct cam_sec_buff_info *cam_smmu_find_mapping_by_sec_buf_idx(int idx,
+	int ion_fd)
+{
+	struct cam_sec_buff_info *mapping;
+
+	list_for_each_entry(mapping, &iommu_cb_set.cb_info[idx].smmu_buf_list,
+		list) {
+		if (mapping->ion_fd == ion_fd) {
+			CAM_DBG(CAM_SMMU, "find ion_fd %d", ion_fd);
+			return mapping;
+		}
+	}
+	CAM_ERR(CAM_SMMU, "Error: Cannot find fd %d by index %d",
+		ion_fd, idx);
 	return NULL;
 }
 
@@ -1339,6 +1383,25 @@
 	return CAM_SMMU_BUFF_NOT_EXIST;
 }
 
+static enum cam_smmu_buf_state cam_smmu_check_secure_fd_in_list(int idx,
+					int ion_fd, dma_addr_t *paddr_ptr,
+					size_t *len_ptr)
+{
+	struct cam_sec_buff_info *mapping;
+
+	list_for_each_entry(mapping,
+			&iommu_cb_set.cb_info[idx].smmu_buf_list,
+			list) {
+		if (mapping->ion_fd == ion_fd) {
+			*paddr_ptr = mapping->paddr;
+			*len_ptr = mapping->len;
+			return CAM_SMMU_BUFF_EXIST;
+		}
+	}
+
+	return CAM_SMMU_BUFF_NOT_EXIST;
+}
+
 int cam_smmu_get_handle(char *identifier, int *handle_ptr)
 {
 	int ret = 0;
@@ -1722,14 +1785,200 @@
 	return rc;
 }
 
-int cam_smmu_map_sec_iova(int handle, int ion_fd,
-	enum cam_smmu_map_dir dir, dma_addr_t *paddr_ptr,
-	size_t *len_ptr)
+static int cam_smmu_map_stage2_buffer_and_add_to_list(int idx, int ion_fd,
+		 enum dma_data_direction dma_dir, struct ion_client *client,
+		 dma_addr_t *paddr_ptr,
+		 size_t *len_ptr)
 {
-	/* not implemented yet */
-	return -EPERM;
+	int rc = 0;
+	struct ion_handle *i_handle = NULL;
+	struct cam_sec_buff_info *mapping_info;
+
+	/* clean the content from clients */
+	*paddr_ptr = (dma_addr_t)NULL;
+	*len_ptr = (size_t)0;
+
+	i_handle = ion_import_dma_buf_fd(client, ion_fd);
+	if (IS_ERR_OR_NULL((void *)(i_handle))) {
+		CAM_ERR(CAM_SMMU, "ion import dma buffer failed");
+		return -EINVAL;
+	}
+
+	/* return addr and len to client */
+	rc = ion_phys(client, i_handle, paddr_ptr, len_ptr);
+	if (rc) {
+		CAM_ERR(CAM_SMMU, "ION Get Physical failed, rc: %d",
+			rc);
+		return rc;
+	}
+
+	/* fill up mapping_info */
+	mapping_info = kzalloc(sizeof(struct cam_sec_buff_info), GFP_KERNEL);
+	if (!mapping_info)
+		return -ENOMEM;
+
+	mapping_info->ion_fd = ion_fd;
+	mapping_info->paddr = *paddr_ptr;
+	mapping_info->len = *len_ptr;
+	mapping_info->dir = dma_dir;
+	mapping_info->ref_count = 1;
+	mapping_info->i_hdl = i_handle;
+	mapping_info->i_client = client;
+
+	CAM_DBG(CAM_SMMU, "ion_fd = %d, dev = %pK, paddr= %pK, len = %u",
+			ion_fd,
+			(void *)iommu_cb_set.cb_info[idx].dev,
+			(void *)*paddr_ptr, (unsigned int)*len_ptr);
+
+	/* add to the list */
+	list_add(&mapping_info->list, &iommu_cb_set.cb_info[idx].smmu_buf_list);
+
+	return rc;
 }
-EXPORT_SYMBOL(cam_smmu_map_sec_iova);
+
+int cam_smmu_map_stage2_iova(int handle,
+		int ion_fd, enum cam_smmu_map_dir dir,
+		struct ion_client *client, ion_phys_addr_t *paddr_ptr,
+		size_t *len_ptr)
+{
+	int idx, rc;
+	enum dma_data_direction dma_dir;
+	enum cam_smmu_buf_state buf_state;
+
+	if (!paddr_ptr || !len_ptr) {
+		CAM_ERR(CAM_SMMU,
+			"Error: Invalid inputs, paddr_ptr:%pK, len_ptr: %pK",
+			paddr_ptr, len_ptr);
+		return -EINVAL;
+	}
+	/* clean the content from clients */
+	*paddr_ptr = (dma_addr_t)NULL;
+	*len_ptr = (size_t)0;
+
+	dma_dir = cam_smmu_translate_dir(dir);
+	if (dma_dir == DMA_NONE) {
+		CAM_ERR(CAM_SMMU,
+			"Error: translate direction failed. dir = %d", dir);
+		return -EINVAL;
+	}
+
+	idx = GET_SMMU_TABLE_IDX(handle);
+	if ((handle == HANDLE_INIT) ||
+		(idx < 0) ||
+		(idx >= iommu_cb_set.cb_num)) {
+		CAM_ERR(CAM_SMMU,
+			"Error: handle or index invalid. idx = %d hdl = %x",
+			idx, handle);
+		return -EINVAL;
+	}
+
+	if (!iommu_cb_set.cb_info[idx].is_secure) {
+		CAM_ERR(CAM_SMMU,
+			"Error: can't map secure mem to non secure cb");
+		return -EINVAL;
+	}
+
+	mutex_lock(&iommu_cb_set.cb_info[idx].lock);
+	if (iommu_cb_set.cb_info[idx].handle != handle) {
+		CAM_ERR(CAM_SMMU,
+			"Error: hdl is not valid, table_hdl = %x, hdl = %x",
+			iommu_cb_set.cb_info[idx].handle, handle);
+		rc = -EINVAL;
+		goto get_addr_end;
+	}
+
+	buf_state = cam_smmu_check_secure_fd_in_list(idx, ion_fd, paddr_ptr,
+			len_ptr);
+	if (buf_state == CAM_SMMU_BUFF_EXIST) {
+		CAM_DBG(CAM_SMMU, "fd:%d already in list, give same addr back",
+			ion_fd);
+		rc = 0;
+		goto get_addr_end;
+	}
+	rc = cam_smmu_map_stage2_buffer_and_add_to_list(idx, ion_fd, dma_dir,
+			client, paddr_ptr, len_ptr);
+	if (rc < 0) {
+		CAM_ERR(CAM_SMMU, "Error: mapping or add list fail");
+		goto get_addr_end;
+	}
+
+get_addr_end:
+	mutex_unlock(&iommu_cb_set.cb_info[idx].lock);
+	return rc;
+}
+EXPORT_SYMBOL(cam_smmu_map_stage2_iova);
+
+static int cam_smmu_secure_unmap_buf_and_remove_from_list(
+		struct cam_sec_buff_info *mapping_info,
+		int idx)
+{
+	if (!mapping_info) {
+		CAM_ERR(CAM_SMMU, "Error: List doesn't exist");
+		return -EINVAL;
+	}
+	ion_free(mapping_info->i_client, mapping_info->i_hdl);
+	list_del_init(&mapping_info->list);
+
+	CAM_DBG(CAM_SMMU, "unmap fd: %d, idx : %d", mapping_info->ion_fd, idx);
+
+	/* free one buffer */
+	kfree(mapping_info);
+	return 0;
+}
+
+int cam_smmu_unmap_stage2_iova(int handle, int ion_fd)
+{
+	int idx, rc;
+	struct cam_sec_buff_info *mapping_info;
+
+	/* find index in the iommu_cb_set.cb_info */
+	idx = GET_SMMU_TABLE_IDX(handle);
+	if ((handle == HANDLE_INIT) ||
+		(idx < 0) ||
+		(idx >= iommu_cb_set.cb_num)) {
+		CAM_ERR(CAM_SMMU,
+			"Error: handle or index invalid. idx = %d hdl = %x",
+			idx, handle);
+		return -EINVAL;
+	}
+
+	if (!iommu_cb_set.cb_info[idx].is_secure) {
+		CAM_ERR(CAM_SMMU,
+			"Error: can't unmap secure mem from non secure cb");
+		return -EINVAL;
+	}
+
+	mutex_lock(&iommu_cb_set.cb_info[idx].lock);
+	if (iommu_cb_set.cb_info[idx].handle != handle) {
+		CAM_ERR(CAM_SMMU,
+			"Error: hdl is not valid, table_hdl = %x, hdl = %x",
+			iommu_cb_set.cb_info[idx].handle, handle);
+		rc = -EINVAL;
+		goto put_addr_end;
+	}
+
+	/* based on ion fd and index, we can find mapping info of buffer */
+	mapping_info = cam_smmu_find_mapping_by_sec_buf_idx(idx, ion_fd);
+	if (!mapping_info) {
+		CAM_ERR(CAM_SMMU,
+			"Error: Invalid params! idx = %d, fd = %d",
+			idx, ion_fd);
+		rc = -EINVAL;
+		goto put_addr_end;
+	}
+
+	/* unmapping one buffer from device */
+	rc = cam_smmu_secure_unmap_buf_and_remove_from_list(mapping_info, idx);
+	if (rc) {
+		CAM_ERR(CAM_SMMU, "Error: unmap or remove list fail");
+		goto put_addr_end;
+	}
+
+put_addr_end:
+	mutex_unlock(&iommu_cb_set.cb_info[idx].lock);
+	return rc;
+}
+EXPORT_SYMBOL(cam_smmu_unmap_stage2_iova);
 
 int cam_smmu_map_iova(int handle, int ion_fd,
 	enum cam_smmu_map_dir dir, dma_addr_t *paddr_ptr,
@@ -1767,6 +2016,12 @@
 		return -EINVAL;
 	}
 
+	if (iommu_cb_set.cb_info[idx].is_secure) {
+		CAM_ERR(CAM_SMMU,
+			"Error: can't map non-secure mem to secure cb");
+		return -EINVAL;
+	}
+
 	mutex_lock(&iommu_cb_set.cb_info[idx].lock);
 	if (iommu_cb_set.cb_info[idx].handle != handle) {
 		CAM_ERR(CAM_SMMU, "hdl is not valid, table_hdl = %x, hdl = %x",
@@ -1786,9 +2041,7 @@
 	buf_state = cam_smmu_check_fd_in_list(idx, ion_fd, paddr_ptr,
 		len_ptr);
 	if (buf_state == CAM_SMMU_BUFF_EXIST) {
-		CAM_ERR(CAM_SMMU,
-			"ion_fd:%d already in the list, give same addr back",
-			 ion_fd);
+		CAM_ERR(CAM_SMMU, "ion_fd:%d already in the list", ion_fd);
 		rc = -EALREADY;
 		goto get_addr_end;
 	}
@@ -1832,6 +2085,12 @@
 		return -EINVAL;
 	}
 
+	if (iommu_cb_set.cb_info[idx].is_secure) {
+		CAM_ERR(CAM_SMMU,
+			"Error: can't get non-secure mem from secure cb");
+		return -EINVAL;
+	}
+
 	mutex_lock(&iommu_cb_set.cb_info[idx].lock);
 	if (iommu_cb_set.cb_info[idx].handle != handle) {
 		CAM_ERR(CAM_SMMU,
@@ -1854,12 +2113,65 @@
 }
 EXPORT_SYMBOL(cam_smmu_get_iova);
 
-int cam_smmu_unmap_sec_iova(int handle, int ion_fd)
+int cam_smmu_get_stage2_iova(int handle, int ion_fd,
+	dma_addr_t *paddr_ptr, size_t *len_ptr)
 {
-	/* not implemented yet */
-	return -EPERM;
+	int idx, rc = 0;
+	enum cam_smmu_buf_state buf_state;
+
+	if (!paddr_ptr || !len_ptr) {
+		CAM_ERR(CAM_SMMU, "Error: Input pointers are invalid");
+		return -EINVAL;
+	}
+
+	if (handle == HANDLE_INIT) {
+		CAM_ERR(CAM_SMMU, "Error: Invalid handle");
+		return -EINVAL;
+	}
+
+	/* clean the content from clients */
+	*paddr_ptr = (dma_addr_t)NULL;
+	*len_ptr = (size_t)0;
+
+	idx = GET_SMMU_TABLE_IDX(handle);
+	if (idx < 0 || idx >= iommu_cb_set.cb_num) {
+		CAM_ERR(CAM_SMMU,
+			"Error: handle or index invalid. idx = %d hdl = %x",
+			idx, handle);
+		return -EINVAL;
+	}
+
+	if (!iommu_cb_set.cb_info[idx].is_secure) {
+		CAM_ERR(CAM_SMMU,
+			"Error: can't get secure mem from non secure cb");
+		return -EINVAL;
+	}
+
+	mutex_lock(&iommu_cb_set.cb_info[idx].lock);
+	if (iommu_cb_set.cb_info[idx].handle != handle) {
+		CAM_ERR(CAM_SMMU,
+			"Error: hdl is not valid, table_hdl = %x, hdl = %x",
+			iommu_cb_set.cb_info[idx].handle, handle);
+		rc = -EINVAL;
+		goto get_addr_end;
+	}
+
+	buf_state = cam_smmu_check_secure_fd_in_list(idx,
+		ion_fd,
+		paddr_ptr,
+		len_ptr);
+
+	if (buf_state == CAM_SMMU_BUFF_NOT_EXIST) {
+		CAM_ERR(CAM_SMMU, "ion_fd:%d not in the mapped list", ion_fd);
+		rc = -EINVAL;
+		goto get_addr_end;
+	}
+
+get_addr_end:
+	mutex_unlock(&iommu_cb_set.cb_info[idx].lock);
+	return rc;
 }
-EXPORT_SYMBOL(cam_smmu_unmap_sec_iova);
+EXPORT_SYMBOL(cam_smmu_get_stage2_iova);
 
 int cam_smmu_unmap_iova(int handle,
 	int ion_fd,
@@ -1882,6 +2194,12 @@
 		return -EINVAL;
 	}
 
+	if (iommu_cb_set.cb_info[idx].is_secure) {
+		CAM_ERR(CAM_SMMU,
+			"Error: can't unmap non-secure mem from secure cb");
+		return -EINVAL;
+	}
+
 	mutex_lock(&iommu_cb_set.cb_info[idx].lock);
 	if (iommu_cb_set.cb_info[idx].handle != handle) {
 		CAM_ERR(CAM_SMMU,
@@ -1989,6 +2307,22 @@
 		cam_smmu_clean_buffer_list(idx);
 	}
 
+	if (&iommu_cb_set.cb_info[idx].is_secure) {
+		if (iommu_cb_set.cb_info[idx].secure_count == 0) {
+			mutex_unlock(&iommu_cb_set.cb_info[idx].lock);
+			return -EPERM;
+		}
+
+		iommu_cb_set.cb_info[idx].secure_count--;
+		if (iommu_cb_set.cb_info[idx].secure_count == 0) {
+			iommu_cb_set.cb_info[idx].cb_count = 0;
+			iommu_cb_set.cb_info[idx].handle = HANDLE_INIT;
+		}
+
+		mutex_unlock(&iommu_cb_set.cb_info[idx].lock);
+		return 0;
+	}
+
 	iommu_cb_set.cb_info[idx].cb_count = 0;
 	iommu_cb_set.cb_info[idx].handle = HANDLE_INIT;
 	mutex_unlock(&iommu_cb_set.cb_info[idx].lock);
@@ -2168,7 +2502,15 @@
 	}
 
 	mem_map_node = of_get_child_by_name(of_node, "iova-mem-map");
+	cb->is_secure = of_property_read_bool(of_node, "qcom,secure-cb");
+
+	/*
+	 * We always expect a memory map node, except when it is a secure
+	 * context bank.
+	 */
 	if (!mem_map_node) {
+		if (cb->is_secure)
+			return 0;
 		CAM_ERR(CAM_SMMU, "iova-mem-map not present");
 		return -EINVAL;
 	}
@@ -2292,6 +2634,12 @@
 		return rc;
 	}
 
+	if (cb->is_secure) {
+		/* increment count to next bank */
+		iommu_cb_set.cb_init_count++;
+		return 0;
+	}
+
 	/* set up the iommu mapping for the  context bank */
 	if (type == CAM_QSMMU) {
 		CAM_ERR(CAM_SMMU, "Error: QSMMU ctx not supported for : %s",
diff --git a/drivers/media/platform/msm/camera/cam_smmu/cam_smmu_api.h b/drivers/media/platform/msm/camera/cam_smmu/cam_smmu_api.h
index 20445f3..4cb6efb 100644
--- a/drivers/media/platform/msm/camera/cam_smmu/cam_smmu_api.h
+++ b/drivers/media/platform/msm/camera/cam_smmu/cam_smmu_api.h
@@ -204,6 +204,19 @@
  */
 int cam_smmu_get_iova(int handle, int ion_fd,
 	dma_addr_t *paddr_ptr, size_t *len_ptr);
+
+/**
+ * @brief Maps memory from an ION fd into IOVA space
+ *
+ * @param handle: SMMU handle identifying the secure context bank to map to
+ * @param ion_fd: ION fd of memory to map to
+ * @param paddr_ptr: Pointer IOVA address that will be returned
+ * @param len_ptr: Length of memory mapped
+ *
+ * @return Status of operation. Negative in case of error. Zero otherwise.
+ */
+int cam_smmu_get_stage2_iova(int handle, int ion_fd,
+	dma_addr_t *paddr_ptr, size_t *len_ptr);
 /**
  * @brief Unmaps memory from context bank
  *
@@ -217,27 +230,28 @@
 /**
  * @brief Maps secure memory for SMMU handle
  *
- * @param handle: SMMU handle identifying context bank
+ * @param handle: SMMU handle identifying secure context bank
  * @param ion_fd: ION fd to map securely
  * @param dir: DMA Direction for the mapping
+ * @param client: Ion client passed by caller
  * @param dma_addr: Returned IOVA address after mapping
  * @param len_ptr: Length of memory mapped
  *
  * @return Status of operation. Negative in case of error. Zero otherwise.
  */
-int cam_smmu_map_sec_iova(int handle,
-	int ion_fd, enum cam_smmu_map_dir dir,
-	dma_addr_t *dma_addr, size_t *len_ptr);
+int cam_smmu_map_stage2_iova(int handle,
+	int ion_fd, enum cam_smmu_map_dir dir, struct ion_client *client,
+	ion_phys_addr_t *dma_addr, size_t *len_ptr);
 
 /**
  * @brief Unmaps secure memopry for SMMU handle
  *
- * @param handle: SMMU handle identifying context bank
+ * @param handle: SMMU handle identifying secure context bank
  * @param ion_fd: ION fd to unmap
  *
  * @return Status of operation. Negative in case of error. Zero otherwise.
  */
-int cam_smmu_unmap_sec_iova(int handle, int ion_fd);
+int cam_smmu_unmap_stage2_iova(int handle, int ion_fd);
 
 
 /**
diff --git a/drivers/media/platform/msm/camera/cam_utils/cam_packet_util.c b/drivers/media/platform/msm/camera/cam_utils/cam_packet_util.c
index 4323358..44d5d48 100644
--- a/drivers/media/platform/msm/camera/cam_utils/cam_packet_util.c
+++ b/drivers/media/platform/msm/camera/cam_utils/cam_packet_util.c
@@ -124,7 +124,7 @@
 }
 
 int cam_packet_util_process_patches(struct cam_packet *packet,
-	int32_t iommu_hdl)
+	int32_t iommu_hdl, int32_t sec_mmu_hdl)
 {
 	struct cam_patch_desc *patch_desc = NULL;
 	uint64_t   iova_addr;
@@ -136,6 +136,7 @@
 	size_t     src_buf_size;
 	int        i;
 	int        rc = 0;
+	int32_t    hdl;
 
 	/* process patch descriptor */
 	patch_desc = (struct cam_patch_desc *)
@@ -146,8 +147,11 @@
 			sizeof(struct cam_patch_desc));
 
 	for (i = 0; i < packet->num_patches; i++) {
+
+		hdl = cam_mem_is_secure_buf(patch_desc[i].src_buf_hdl) ?
+			sec_mmu_hdl : iommu_hdl;
 		rc = cam_mem_get_io_buf(patch_desc[i].src_buf_hdl,
-			iommu_hdl, &iova_addr, &src_buf_size);
+			hdl, &iova_addr, &src_buf_size);
 		if (rc < 0) {
 			CAM_ERR(CAM_UTIL, "unable to get src buf address");
 			return rc;
diff --git a/drivers/media/platform/msm/camera/cam_utils/cam_packet_util.h b/drivers/media/platform/msm/camera/cam_utils/cam_packet_util.h
index 2fa7585..323a75a 100644
--- a/drivers/media/platform/msm/camera/cam_utils/cam_packet_util.h
+++ b/drivers/media/platform/msm/camera/cam_utils/cam_packet_util.h
@@ -83,12 +83,14 @@
  *
  * @packet:             Input packet containing Command Buffers and Patches
  * @iommu_hdl:          IOMMU handle of the HW Device that received the packet
+ * @sec_iommu_hdl:      Secure IOMMU handle of the HW Device that
+ *                      received the packet
  *
  * @return:             0: Success
  *                      Negative: Failure
  */
 int cam_packet_util_process_patches(struct cam_packet *packet,
-	int32_t iommu_hdl);
+	int32_t iommu_hdl, int32_t sec_mmu_hdl);
 
 /**
  * cam_packet_util_process_generic_cmd_buffer()
diff --git a/include/uapi/media/cam_req_mgr.h b/include/uapi/media/cam_req_mgr.h
index fee26a9..9b7d055 100644
--- a/include/uapi/media/cam_req_mgr.h
+++ b/include/uapi/media/cam_req_mgr.h
@@ -216,7 +216,8 @@
 /* Maximum allowed buffers in existence */
 #define CAM_MEM_BUFQ_MAX                        1024
 
-#define CAM_MEM_MGR_HDL_IDX_SIZE                16
+#define CAM_MEM_MGR_SECURE_BIT_POS              15
+#define CAM_MEM_MGR_HDL_IDX_SIZE                15
 #define CAM_MEM_MGR_HDL_FD_SIZE                 16
 #define CAM_MEM_MGR_HDL_IDX_END_POS             16
 #define CAM_MEM_MGR_HDL_FD_END_POS              32
@@ -224,11 +225,19 @@
 #define CAM_MEM_MGR_HDL_IDX_MASK      ((1 << CAM_MEM_MGR_HDL_IDX_SIZE) - 1)
 
 #define GET_MEM_HANDLE(idx, fd) \
-	((idx << (CAM_MEM_MGR_HDL_IDX_END_POS - CAM_MEM_MGR_HDL_IDX_SIZE)) | \
+	((idx & CAM_MEM_MGR_HDL_IDX_MASK) | \
 	(fd << (CAM_MEM_MGR_HDL_FD_END_POS - CAM_MEM_MGR_HDL_FD_SIZE))) \
 
 #define CAM_MEM_MGR_GET_HDL_IDX(hdl) (hdl & CAM_MEM_MGR_HDL_IDX_MASK)
 
+#define CAM_MEM_MGR_SET_SECURE_HDL(hdl, flag) \
+	((flag) ? (hdl |= (1 << CAM_MEM_MGR_SECURE_BIT_POS)) : \
+	((hdl) &= ~(1 << CAM_MEM_MGR_SECURE_BIT_POS)))
+
+#define CAM_MEM_MGR_IS_SECURE_HDL(hdl) \
+	(((hdl) & \
+	(1<<CAM_MEM_MGR_SECURE_BIT_POS)) >> CAM_MEM_MGR_SECURE_BIT_POS)
+
 /**
  * memory allocation type
  */
diff --git a/include/uapi/media/cam_sensor.h b/include/uapi/media/cam_sensor.h
index 2fe7f2b..87f25b0 100644
--- a/include/uapi/media/cam_sensor.h
+++ b/include/uapi/media/cam_sensor.h
@@ -8,6 +8,7 @@
 #define CAM_SENSOR_PROBE_CMD   (CAM_COMMON_OPCODE_MAX + 1)
 #define CAM_FLASH_MAX_LED_TRIGGERS 3
 #define MAX_OIS_NAME_SIZE 32
+#define CAM_CSIPHY_SECURE_MODE_ENABLED 1
 /**
  * struct cam_sensor_query_cap - capabilities info for sensor
  *
@@ -316,15 +317,15 @@
 
 /**
  * cam_csiphy_info: Provides cmdbuffer structre
- * @lane_mask     :  Lane mask details
- * @lane_assign   :  Lane sensor will be using
- * @csiphy_3phase :  Total number of lanes
- * @combo_mode    :  Info regarding combo_mode is enable / disable
- * @lane_cnt      :  Total number of lanes
- * @reserved
- * @3phase        :  Details whether 3Phase / 2Phase operation
- * @settle_time   :  Settling time in ms
- * @data_rate     :  Data rate
+ * @lane_mask     : Lane mask details
+ * @lane_assign   : Lane sensor will be using
+ * @csiphy_3phase : Total number of lanes
+ * @combo_mode    : Info regarding combo_mode is enable / disable
+ * @lane_cnt      : Total number of lanes
+ * @secure_mode   : Secure mode flag to enable / disable
+ * @3phase        : Details whether 3Phase / 2Phase operation
+ * @settle_time   : Settling time in ms
+ * @data_rate     : Data rate
  *
  */
 struct cam_csiphy_info {
@@ -333,7 +334,7 @@
 	uint8_t     csiphy_3phase;
 	uint8_t     combo_mode;
 	uint8_t     lane_cnt;
-	uint8_t     reserved;
+	uint8_t     secure_mode;
 	uint64_t    settle_time;
 	uint64_t    data_rate;
 } __attribute__((packed));