diff --git a/Documentation/devicetree/bindings/media/video/msm-cam-smmu.txt b/Documentation/devicetree/bindings/media/video/msm-cam-smmu.txt index 4b1f08612865..b22615bdafef 100644 --- a/Documentation/devicetree/bindings/media/video/msm-cam-smmu.txt +++ b/Documentation/devicetree/bindings/media/video/msm-cam-smmu.txt @@ -67,6 +67,11 @@ Second Level Node - CAM SMMU context bank device or firmware device Value type: boolean Definition: Specifies if the context bank is a secure context bank. +- qcom,secure-pixel-cb + Usage: optional + Value type: boolean + Definition: Specifies if the context bank is a secure pixel context bank. + ============================================= Third Level Node - CAM SMMU memory map device ============================================= diff --git a/arch/arm64/boot/dts/qcom/sa6155p-camera.dtsi b/arch/arm64/boot/dts/qcom/sa6155p-camera.dtsi index 3eb01a1b915b..d9b3dd8a4490 100644 --- a/arch/arm64/boot/dts/qcom/sa6155p-camera.dtsi +++ b/arch/arm64/boot/dts/qcom/sa6155p-camera.dtsi @@ -46,6 +46,26 @@ status = "disabled"; }; +&cam_smmu { + msm_cam_smmu_ife_cp { + compatible = "qcom,msm-cam-smmu-cb"; + iommus = <&apps_smmu 0x821 0x1C0>, + <&apps_smmu 0x841 0x0>, + <&apps_smmu 0x861 0x1C0>; + label = "ife-cp"; + qcom,secure-pixel-cb; + ife_cp_iova_mem_map: iova-mem-map { + /* IO region is approximately 2.5 GB */ + iova-mem-region-io { + iova-region-name = "io"; + iova-region-start = <0x7400000>; + iova-region-len = <0x98C00000>; + iova-region-id = <0x3>; + status = "ok"; + }; + }; + }; +}; &soc { /delete-node/ cam_isp_mgr; diff --git a/arch/arm64/boot/dts/qcom/sa8155-camera.dtsi b/arch/arm64/boot/dts/qcom/sa8155-camera.dtsi index 2ded8cd4df2f..708cc284af93 100644 --- a/arch/arm64/boot/dts/qcom/sa8155-camera.dtsi +++ b/arch/arm64/boot/dts/qcom/sa8155-camera.dtsi @@ -62,6 +62,31 @@ status = "disabled"; }; +&cam_smmu { + msm_cam_smmu_ife_cp { + compatible = "qcom,msm-cam-smmu-cb"; + iommus = <&apps_smmu 0x841 0x620>, + <&apps_smmu 0x861 0x620>, + <&apps_smmu 0xA41 0x620>, + <&apps_smmu 0xA61 0x620>, + <&apps_smmu 0xC41 0x620>, + <&apps_smmu 0xC61 0x620>, + <&apps_smmu 0xE41 0x620>, + <&apps_smmu 0xE61 0x620>; + label = "ife-cp"; + qcom,secure-pixel-cb; + ife_cp_iova_mem_map: iova-mem-map { + /* IO region is approximately 2.5 GB */ + iova-mem-region-io { + iova-region-name = "io"; + iova-region-start = <0x7400000>; + iova-region-len = <0x98C00000>; + iova-region-id = <0x3>; + status = "ok"; + }; + }; + }; +}; &soc { /delete-node/ cam_isp_mgr; diff --git a/arch/arm64/boot/dts/qcom/sa8195p-camera.dtsi b/arch/arm64/boot/dts/qcom/sa8195p-camera.dtsi index 7a3bd743658a..b869b06b6f97 100644 --- a/arch/arm64/boot/dts/qcom/sa8195p-camera.dtsi +++ b/arch/arm64/boot/dts/qcom/sa8195p-camera.dtsi @@ -532,14 +532,22 @@ msm_cam_smmu_ife { compatible = "qcom,msm-cam-smmu-cb"; - iommus = <&apps_smmu 0xAA0 0x4E0>, - <&apps_smmu 0xA20 0x4E0>, - <&apps_smmu 0xA00 0x4E0>, + iommus = <&apps_smmu 0xA00 0x4E0>, + <&apps_smmu 0xAA0 0x4E0>, + <&apps_smmu 0xA40 0x4E0>, + <&apps_smmu 0xA60 0x4E0>, <&apps_smmu 0xA80 0x4E0>, - <&apps_smmu 0xEA0 0x4E0>, - <&apps_smmu 0xE20 0x4E0>, + <&apps_smmu 0xA20 0x4E0>, + <&apps_smmu 0xAC0 0x4E0>, + <&apps_smmu 0xAE0 0x4E0>, <&apps_smmu 0xE00 0x4E0>, - <&apps_smmu 0xE80 0x4E0>; + <&apps_smmu 0xEA0 0x4E0>, + <&apps_smmu 0xE40 0x4E0>, + <&apps_smmu 0xE60 0x4E0>, + <&apps_smmu 0xE80 0x4E0>, + <&apps_smmu 0xE20 0x4E0>, + <&apps_smmu 0xEC0 0x4E0>, + <&apps_smmu 0xEE0 0x4E0>; label = "ife"; ife_iova_mem_map: iova-mem-map { /* IO region is approximately 3.4 GB */ @@ -553,6 +561,38 @@ }; }; + msm_cam_smmu_ife_cp { + compatible = "qcom,msm-cam-smmu-cb"; + iommus = <&apps_smmu 0xA01 0x5E0>, + <&apps_smmu 0xAA1 0x5E0>, + <&apps_smmu 0xA41 0x5E0>, + <&apps_smmu 0xA61 0x5E0>, + <&apps_smmu 0xA81 0x5E0>, + <&apps_smmu 0xA21 0x5E0>, + <&apps_smmu 0xAC1 0x5E0>, + <&apps_smmu 0xAE1 0x5E0>, + <&apps_smmu 0xE01 0x5E0>, + <&apps_smmu 0xEA1 0x5E0>, + <&apps_smmu 0xE41 0x5E0>, + <&apps_smmu 0xE61 0x5E0>, + <&apps_smmu 0xE81 0x5E0>, + <&apps_smmu 0xE21 0x5E0>, + <&apps_smmu 0xEC1 0x5E0>, + <&apps_smmu 0xEE1 0x5E0>; + label = "ife-cp"; + qcom,secure-pixel-cb; + ife_cp_iova_mem_map: iova-mem-map { + /* IO region is approximately 2.5 GB */ + iova-mem-region-io { + iova-region-name = "io"; + iova-region-start = <0x7400000>; + iova-region-len = <0x98C00000>; + iova-region-id = <0x3>; + status = "ok"; + }; + }; + }; + msm_cam_smmu_jpeg { compatible = "qcom,msm-cam-smmu-cb"; iommus = <&apps_smmu 0x2100 0x20>, diff --git a/arch/arm64/boot/dts/qcom/sm6150-camera.dtsi b/arch/arm64/boot/dts/qcom/sm6150-camera.dtsi index f0acba499904..7ce2aec6b3a8 100644 --- a/arch/arm64/boot/dts/qcom/sm6150-camera.dtsi +++ b/arch/arm64/boot/dts/qcom/sm6150-camera.dtsi @@ -227,7 +227,7 @@ }; }; - qcom,cam_smmu { + cam_smmu: qcom,cam_smmu { compatible = "qcom,msm-cam-smmu"; status = "ok"; diff --git a/arch/arm64/boot/dts/qcom/sm8150-camera.dtsi b/arch/arm64/boot/dts/qcom/sm8150-camera.dtsi index c5bef86838ea..666fa3ffa818 100644 --- a/arch/arm64/boot/dts/qcom/sm8150-camera.dtsi +++ b/arch/arm64/boot/dts/qcom/sm8150-camera.dtsi @@ -316,7 +316,7 @@ }; }; - qcom,cam_smmu { + cam_smmu: qcom,cam_smmu { compatible = "qcom,msm-cam-smmu"; status = "ok"; diff --git a/drivers/media/platform/msm/ais/ais_isp/ais_ife_dev.c b/drivers/media/platform/msm/ais/ais_isp/ais_ife_dev.c index 5ff489592c9e..89e378afcebe 100644 --- a/drivers/media/platform/msm/ais/ais_isp/ais_ife_dev.c +++ b/drivers/media/platform/msm/ais/ais_isp/ais_ife_dev.c @@ -498,7 +498,8 @@ static void ais_ife_dev_iommu_fault_handler( p_ife_dev = (struct ais_ife_dev *)token; - CAM_ERR(CAM_ISP, "IFE%d Pagefault at %lu", p_ife_dev->hw_idx, iova); + CAM_ERR(CAM_ISP, "IFE%d Pagefault at iova 0x%x %s", + p_ife_dev->hw_idx, iova, domain->name); } static int ais_ife_dev_remove(struct platform_device *pdev) @@ -549,7 +550,6 @@ static int ais_ife_dev_probe(struct platform_device *pdev) } mutex_init(&p_ife_dev->mutex); - spin_lock_init(&p_ife_dev->eventq_lock); /* * for now, we only support one iommu handle. later @@ -571,13 +571,19 @@ static int ais_ife_dev_probe(struct platform_device *pdev) goto attach_fail; } - rc = cam_smmu_get_handle("cam-secure", + rc = cam_smmu_get_handle("ife-cp", &p_ife_dev->iommu_hdl_secure); if (rc) { CAM_ERR(CAM_ISP, "Failed to get secure iommu handle %d", rc); goto secure_fail; } + rc = cam_smmu_ops(p_ife_dev->iommu_hdl_secure, CAM_SMMU_ATTACH); + if (rc && rc != -EALREADY) { + CAM_ERR(CAM_ISP, "Attach secure iommu handle failed %d", rc); + goto secure_fail; + } + CAM_DBG(CAM_ISP, "iommu_handles: non-secure[0x%x], secure[0x%x]", p_ife_dev->iommu_hdl, p_ife_dev->iommu_hdl_secure); @@ -585,6 +591,9 @@ static int ais_ife_dev_probe(struct platform_device *pdev) cam_smmu_set_client_page_fault_handler(p_ife_dev->iommu_hdl, ais_ife_dev_iommu_fault_handler, p_ife_dev); + cam_smmu_set_client_page_fault_handler(p_ife_dev->iommu_hdl_secure, + ais_ife_dev_iommu_fault_handler, p_ife_dev); + hw_init.hw_idx = p_ife_dev->hw_idx; hw_init.iommu_hdl = p_ife_dev->iommu_hdl; hw_init.iommu_hdl_secure = p_ife_dev->iommu_hdl_secure; @@ -594,14 +603,14 @@ static int ais_ife_dev_probe(struct platform_device *pdev) rc = ais_ife_csid_hw_init(&p_ife_dev->p_csid_drv, &hw_init); if (rc) { CAM_ERR(CAM_ISP, "IFE%d no CSID dev", p_ife_dev->hw_idx, rc); - goto secure_fail; + goto secure_attach_fail; } rc = ais_vfe_hw_init(&p_ife_dev->p_vfe_drv, &hw_init, p_ife_dev->p_csid_drv); if (rc) { CAM_ERR(CAM_ISP, "IFE%d no VFE dev", p_ife_dev->hw_idx, rc); - goto secure_fail; + goto secure_attach_fail; } CAM_INFO(CAM_ISP, "IFE%d probe complete", p_ife_dev->hw_idx); @@ -610,6 +619,9 @@ static int ais_ife_dev_probe(struct platform_device *pdev) return 0; +secure_attach_fail: + cam_smmu_ops(p_ife_dev->iommu_hdl_secure, + CAM_SMMU_DETACH); secure_fail: cam_smmu_ops(p_ife_dev->iommu_hdl, CAM_SMMU_DETACH); diff --git a/drivers/media/platform/msm/ais/ais_isp/ais_ife_dev.h b/drivers/media/platform/msm/ais/ais_isp/ais_ife_dev.h index 340b6ee91b43..4273c4c1f7ab 100644 --- a/drivers/media/platform/msm/ais/ais_isp/ais_ife_dev.h +++ b/drivers/media/platform/msm/ais/ais_isp/ais_ife_dev.h @@ -40,7 +40,6 @@ struct ais_ife_dev { int iommu_hdl; int iommu_hdl_secure; - spinlock_t eventq_lock; struct mutex mutex; int32_t open_cnt; }; diff --git a/drivers/media/platform/msm/ais/ais_isp/vfe_hw/ais_vfe_core.c b/drivers/media/platform/msm/ais/ais_isp/vfe_hw/ais_vfe_core.c index b8a1909520ec..62cc7a8d485d 100644 --- a/drivers/media/platform/msm/ais/ais_isp/vfe_hw/ais_vfe_core.c +++ b/drivers/media/platform/msm/ais/ais_isp/vfe_hw/ais_vfe_core.c @@ -438,6 +438,8 @@ int ais_vfe_reserve(void *hw_priv, void *reserve_args, uint32_t arg_size) goto EXIT; } + rdi_path->secure_mode = rdi_cfg->out_cfg.secure_mode; + cam_io_w(0xf, core_info->mem_base + client_regs->burst_limit); /*disable pack as it is done in CSID*/ cam_io_w(0x0, core_info->mem_base + client_regs->packer_cfg); @@ -766,8 +768,11 @@ static int ais_vfe_cmd_enq_buf(struct ais_vfe_hw_core_info *core_info, vfe_buf->bufIdx = enq_buf->buffer.idx; vfe_buf->mem_handle = enq_buf->buffer.mem_handle; - mmu_hdl = cam_mem_is_secure_buf(vfe_buf->mem_handle) ? - core_info->iommu_hdl_secure : core_info->iommu_hdl; + mmu_hdl = core_info->iommu_hdl; + + if (cam_mem_is_secure_buf(vfe_buf->mem_handle) || rdi_path->secure_mode) + mmu_hdl = core_info->iommu_hdl_secure; + rc = cam_mem_get_io_buf(vfe_buf->mem_handle, mmu_hdl, &vfe_buf->iova_addr, &src_buf_size); if (rc < 0) { @@ -1098,6 +1103,7 @@ static int ais_vfe_handle_error( continue; p_rdi = &core_info->rdi_out[path]; + if (p_rdi->state != AIS_ISP_RESOURCE_STATE_STREAMING) continue; diff --git a/drivers/media/platform/msm/ais/ais_isp/vfe_hw/ais_vfe_core.h b/drivers/media/platform/msm/ais/ais_isp/vfe_hw/ais_vfe_core.h index 3b5ee36182bc..c4bd0648dd27 100644 --- a/drivers/media/platform/msm/ais/ais_isp/vfe_hw/ais_vfe_core.h +++ b/drivers/media/platform/msm/ais/ais_isp/vfe_hw/ais_vfe_core.h @@ -96,6 +96,7 @@ struct ais_vfe_rdi_output { enum ais_isp_resource_state state; uint32_t en_cfg; + uint32_t secure_mode; spinlock_t buffer_lock; struct ais_vfe_buffer_t buffers[AIS_VFE_MAX_BUF]; diff --git a/drivers/media/platform/msm/ais/cam_req_mgr/cam_mem_mgr.c b/drivers/media/platform/msm/ais/cam_req_mgr/cam_mem_mgr.c index 33094cd010a1..33949b9161fb 100644 --- a/drivers/media/platform/msm/ais/cam_req_mgr/cam_mem_mgr.c +++ b/drivers/media/platform/msm/ais/cam_req_mgr/cam_mem_mgr.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2016-2019, The Linux Foundation. All rights reserved. +/* Copyright (c) 2016-2020, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -217,6 +217,7 @@ int cam_mem_get_io_buf(int32_t buf_handle, int32_t mmu_handle, tbl.bufq[idx].fd, iova_ptr, len_ptr); + if (rc) { CAM_ERR(CAM_MEM, "fail to map buf_hdl:0x%x, mmu_hdl: 0x%x for fd:%d", @@ -511,6 +512,9 @@ static int cam_mem_util_ion_alloc(struct cam_mem_mgr_alloc_cmd *cmd, } else if (cmd->flags & CAM_MEM_FLAG_PROTECTED_MODE) { heap_id = ION_HEAP(ION_SECURE_DISPLAY_HEAP_ID); ion_flag |= ION_FLAG_SECURE | ION_FLAG_CP_CAMERA; + } else if (cmd->flags & CAM_MEM_FLAG_CP_PIXEL) { + heap_id = ION_HEAP(ION_SECURE_HEAP_ID); + ion_flag |= ION_FLAG_SECURE | ION_FLAG_CP_PIXEL; } else { heap_id = ION_HEAP(ION_SYSTEM_HEAP_ID) | ION_HEAP(ION_CAMERA_HEAP_ID); @@ -540,8 +544,9 @@ static int cam_mem_util_check_alloc_flags(struct cam_mem_mgr_alloc_cmd *cmd) return -EINVAL; } - if (cmd->flags & CAM_MEM_FLAG_PROTECTED_MODE && - cmd->flags & CAM_MEM_FLAG_KMD_ACCESS) { + if (((cmd->flags & CAM_MEM_FLAG_PROTECTED_MODE) || + (cmd->flags & CAM_MEM_FLAG_CP_PIXEL)) && + (cmd->flags & CAM_MEM_FLAG_KMD_ACCESS)) { CAM_ERR(CAM_MEM, "Kernel mapping in secure mode not allowed"); return -EINVAL; } @@ -562,8 +567,9 @@ static int cam_mem_util_check_map_flags(struct cam_mem_mgr_map_cmd *cmd) return -EINVAL; } - if (cmd->flags & CAM_MEM_FLAG_PROTECTED_MODE && - cmd->flags & CAM_MEM_FLAG_KMD_ACCESS) { + if (((cmd->flags & CAM_MEM_FLAG_PROTECTED_MODE) || + (cmd->flags & CAM_MEM_FLAG_CP_PIXEL)) && + (cmd->flags & CAM_MEM_FLAG_KMD_ACCESS)) { CAM_ERR(CAM_MEM, "Kernel mapping in secure mode not allowed, flags=0x%x", cmd->flags); diff --git a/drivers/media/platform/msm/ais/cam_smmu/cam_smmu_api.c b/drivers/media/platform/msm/ais/cam_smmu/cam_smmu_api.c index a89270254ca4..256842c73c20 100644 --- a/drivers/media/platform/msm/ais/cam_smmu/cam_smmu_api.c +++ b/drivers/media/platform/msm/ais/cam_smmu/cam_smmu_api.c @@ -36,7 +36,7 @@ #define COOKIE_SIZE (BYTE_SIZE*COOKIE_NUM_BYTE) #define COOKIE_MASK ((1<> COOKIE_SIZE) & COOKIE_MASK) @@ -105,7 +105,10 @@ struct cam_context_bank_info { dma_addr_t va_start; size_t va_len; const char *name; + /* stage 2 only */ bool is_secure; + /* stage 1 */ + bool is_secure_pixel; uint8_t scratch_buf_support; uint8_t firmware_support; uint8_t shared_support; @@ -3269,6 +3272,20 @@ static int cam_smmu_setup_cb(struct cam_context_bank_info *cb, goto end; } + if (cb->is_secure_pixel) { + int secure_vmid = VMID_CP_PIXEL; + + rc = iommu_domain_set_attr(cb->mapping->domain, + DOMAIN_ATTR_SECURE_VMID, &secure_vmid); + if (rc) { + CAM_ERR(CAM_SMMU, + "programming secure vmid failed: %s %d", + dev_name(dev), rc); + rc = -ENODEV; + goto end; + } + } + return rc; end: if (cb->shared_support) { @@ -3345,6 +3362,10 @@ static int cam_smmu_get_memory_regions_info(struct device_node *of_node, 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"); + if (!cb->is_secure) + cb->is_secure_pixel = of_property_read_bool(of_node, + "qcom,secure-pixel-cb"); + /* * We always expect a memory map node, except when it is a secure * context bank. diff --git a/include/uapi/media/cam_req_mgr.h b/include/uapi/media/cam_req_mgr.h index 55105fd903b0..50b81276d0e1 100644 --- a/include/uapi/media/cam_req_mgr.h +++ b/include/uapi/media/cam_req_mgr.h @@ -269,6 +269,7 @@ struct cam_req_mgr_link_control { #define CAM_MEM_FLAG_CACHE (1<<10) #define CAM_MEM_FLAG_HW_SHARED_ACCESS (1<<11) #define CAM_MEM_FLAG_CDSP_OUTPUT (1<<12) +#define CAM_MEM_FLAG_CP_PIXEL (1<<13) #define CAM_MEM_MMU_MAX_HANDLE 16