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));