diff --git a/Android.mk b/Android.mk index 78d72d8be0..9a2fd6ec26 100644 --- a/Android.mk +++ b/Android.mk @@ -19,6 +19,9 @@ MMRM_BOARDS := taro parrot kalama pineapple # List of board platforms for which Synx V2 vendor driver API should be enabled SYNX_VENDOR_BOARDS := pineapple +# List of board platforms for which SMCINVOKE_DLKM driver API should be enabled +SMCINVOKE_DLKM_BOARDS := pineapple + CAMERA_SRC_FILES := \ $(addprefix $(LOCAL_PATH)/, $(call all-named-files-under,*.h,drivers dt-bindings include))\ $(addprefix $(LOCAL_PATH)/, $(call all-named-files-under,*.mk,config))\ diff --git a/Kbuild b/Kbuild index a143c8f331..cac15ee148 100644 --- a/Kbuild +++ b/Kbuild @@ -76,6 +76,8 @@ ccflags-$(CONFIG_MSM_GLOBAL_SYNX) += -I$(KERNEL_ROOT)/drivers/media/platform/msm ccflags-$(TARGET_SYNX_ENABLE) += -I$(SYNXVENDORDIR)/include/uapi/synx/media ccflags-$(TARGET_SYNX_ENABLE) += -I$(SYNXVENDORDIR)/msm/synx ccflags-$(TARGET_SYNX_ENABLE) += -DCONFIG_TARGET_SYNX_ENABLE=1 +ccflags-y += -I$(CAMERA_KERNEL_ROOT)/../securemsm-kernel/ +ccflags-y += -I$(CAMERA_KERNEL_ROOT)/../securemsm-kernel/include/ # After creating lists, add content of 'ccflags-m' variable to 'ccflags-y' one. ccflags-y += ${ccflags-m} diff --git a/dependency.mk b/dependency.mk index c602bd2b85..9154e41905 100644 --- a/dependency.mk +++ b/dependency.mk @@ -9,7 +9,7 @@ ifeq ($(call is-board-platform-in-list, $(MMRM_BOARDS)),true) CAM_MMRM_EXTRA_SYMBOLS ?= $(realpath $(TOP))/$(call intermediates-dir-for,DLKM,mmrm-module-symvers)/Module.symvers $(info camera-kernel: Found msm-mmrm driver, adding symbol dependency! $(CAM_MMRM_EXTRA_SYMBOLS)) ifneq ($(TARGET_BOARD_PLATFORM), pineapple) -LOCAL_REQUIRED_MODULES := mmrm-module-symvers +LOCAL_REQUIRED_MODULES := mmrm-module-symvers endif # End of check lanai CAM_MMRM_EXTRA_CONFIGS ?= $(realpath $(TOP))/vendor/qcom/opensource/mmrm-driver/config/waipiommrm.conf LOCAL_ADDITIONAL_DEPENDENCIES := $(call intermediates-dir-for,DLKM,mmrm-module-symvers)/Module.symvers @@ -34,5 +34,19 @@ endif # End of check for board platform SYNX_VENDOR_BOARDS endif # End of find synx driver -KBUILD_OPTIONS += KBUILD_EXTRA_SYMBOLS=$(CAM_MMRM_EXTRA_SYMBOLS) KBUILD_EXTRA_SYMBOLS+=$(CAM_SYNX_EXTRA_SYMBOLS) -KBUILD_OPTIONS += KBUILD_EXTRA_CONFIGS=$(CAM_MMRM_EXTRA_CONFIGS) KBUILD_EXTRA_CONFIGS+=$(CAM_SYNX_EXTRA_CONFIGS) +# Check if this board's product.mk finds smcinvoke_dlkm.ko driver +ifeq ($(findstring smcinvoke_dlkm.ko, $(BOARD_VENDOR_KERNEL_MODULES)), smcinvoke_dlkm.ko) + +ifeq ($(call is-board-platform-in-list, $(SMCINVOKE_DLKM_BOARDS)),true) +SMCINVOKE_EXTRA_SYMBOLS ?= $(realpath $(TOP))/$(call intermediates-dir-for,DLKM,smcinvoke_dlkm.ko)/Module.symvers +$(info camera-kernel: Found smcinvoke driver, adding symbol dependency! $(SMCINVOKE_EXTRA_SYMBOLS)) +LOCAL_REQUIRED_MODULES += smcinvoke_dlkm.ko +CAM_SMCINOKE_EXTRA_CONFIGS ?= $(realpath $(TOP))/vendor/qcom/opensource/securemsm-kernel/config/sec-kernel_defconfig_smcinvoke.conf +LOCAL_ADDITIONAL_DEPENDENCIES += $(call intermediates-dir-for,DLKM,smcinvoke_dlkm.ko)/Module.symvers + +endif # End of check for board platform SMCINVOKE_DLKM_BOARDS + +endif # End of find smcinvoke_dlkm driver + +KBUILD_OPTIONS += KBUILD_EXTRA_SYMBOLS=$(CAM_MMRM_EXTRA_SYMBOLS) KBUILD_EXTRA_SYMBOLS+=$(CAM_SYNX_EXTRA_SYMBOLS) KBUILD_EXTRA_SYMBOLS+=$(SMCINVOKE_EXTRA_SYMBOLS) +KBUILD_OPTIONS += KBUILD_EXTRA_CONFIGS=$(CAM_MMRM_EXTRA_CONFIGS) KBUILD_EXTRA_CONFIGS+=$(CAM_SYNX_EXTRA_CONFIGS) KBUILD_EXTRA_CONFIGS+=$(CAM_SMCINOKE_EXTRA_CONFIGS) diff --git a/drivers/cam_sensor_module/cam_csiphy/cam_csiphy_core.c b/drivers/cam_sensor_module/cam_csiphy/cam_csiphy_core.c index d8bd159287..49b54a8d50 100644 --- a/drivers/cam_sensor_module/cam_csiphy/cam_csiphy_core.c +++ b/drivers/cam_sensor_module/cam_csiphy/cam_csiphy_core.c @@ -1,7 +1,7 @@ // SPDX-License-Identifier: GPL-2.0-only /* * Copyright (c) 2017-2021, The Linux Foundation. All rights reserved. - * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved. + * Copyright (c) 2022-2023 Qualcomm Innovation Center, Inc. All rights reserved. */ #include @@ -482,6 +482,13 @@ static int cam_csiphy_update_secure_info(struct csiphy_device *csiphy_dev, int32 uint32_t cpas_version; int rc; + if (csiphy_dev->domain_id_security) { + CAM_DBG(CAM_CSIPHY, "Domain ID scheme for CSIPHY [%u], skipping legacy update", + csiphy_dev->soc_info.index); + + return 0; + } + lane_assign = csiphy_dev->csiphy_info[index].lane_assign; lane_cnt = csiphy_dev->csiphy_info[index].lane_cnt; @@ -1226,22 +1233,26 @@ static int cam_csiphy_program_secure_mode(struct csiphy_device *csiphy_dev, { int rc = 0; - if (!csiphy_dev->domain_id_security) - rc = cam_csiphy_notify_secure_mode(csiphy_dev, protect, offset); + if (csiphy_dev->domain_id_security && protect) { + if (!csiphy_dev->csiphy_info[offset].secure_info_updated) { + CAM_ERR(CAM_CSIPHY, + "PHY[%u] domain id info not updated, aborting secure call", + csiphy_dev->soc_info.index); - /* Else a new scm call here */ - else { - if (protect && !csiphy_dev->csiphy_info[offset].secure_info_updated) { - CAM_ERR(CAM_CSIPHY, "Secure info not updated prior to stream on"); return -EINVAL; } - csiphy_dev->csiphy_info[offset].secure_info.protect = protect; - CAM_DBG(CAM_CSIPHY, "To call new scm, protect: %d, offset: %d", - protect, offset); + rc = cam_cpas_enable_clks_for_domain_id(true); + if (rc) + return rc; + } - if (!protect) - csiphy_dev->csiphy_info[offset].secure_info_updated = false; + rc = cam_csiphy_notify_secure_mode(csiphy_dev, protect, offset); + + if (csiphy_dev->domain_id_security && !protect) { + cam_cpas_enable_clks_for_domain_id(false); + + csiphy_dev->csiphy_info[offset].secure_info_updated = false; } return rc; diff --git a/drivers/cam_sensor_module/cam_csiphy/cam_csiphy_dev.c b/drivers/cam_sensor_module/cam_csiphy/cam_csiphy_dev.c index 08caa03943..c72214a39b 100644 --- a/drivers/cam_sensor_module/cam_csiphy/cam_csiphy_dev.c +++ b/drivers/cam_sensor_module/cam_csiphy/cam_csiphy_dev.c @@ -1,7 +1,7 @@ // SPDX-License-Identifier: GPL-2.0-only /* * Copyright (c) 2017-2021, The Linux Foundation. All rights reserved. - * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved. + * Copyright (c) 2022-2023 Qualcomm Innovation Center, Inc. All rights reserved. */ #include "cam_csiphy_dev.h" @@ -28,27 +28,13 @@ static inline void cam_csiphy_trigger_reg_dump(struct csiphy_device *csiphy_dev) } } -int cam_csiphy_format_secure_phy_lane_info( - struct csiphy_device *csiphy_dev, int offset) +static int cam_csiphy_format_secure_phy_lane_info( + struct csiphy_device *csiphy_dev, int offset, uint64_t *mask) { - struct cam_csiphy_tz_secure_info *tz_secure_info; struct cam_csiphy_param *param; uint64_t phy_lane_sel_mask = 0; - if (!csiphy_dev) { - CAM_ERR(CAM_CSIPHY, "Invalid param, csiphy_dev: %s", - CAM_IS_NULL_TO_STR(csiphy_dev)); - return -EINVAL; - } - - if (offset >= CSIPHY_MAX_INSTANCES_PER_PHY) { - CAM_ERR(CAM_CSIPHY, "Invalid CSIPHY param offset: %d", - offset); - return -EINVAL; - } - param = &csiphy_dev->csiphy_info[offset]; - tz_secure_info = ¶m->secure_info; if (param->csiphy_3phase) { if (param->lane_enable & CPHY_LANE_0) @@ -74,12 +60,12 @@ int cam_csiphy_format_secure_phy_lane_info( csiphy_dev->soc_info.index); return -EINVAL; } + phy_lane_sel_mask |= BIT(csiphy_dev->soc_info.index); - tz_secure_info->phy_lane_sel_mask |= phy_lane_sel_mask; + *mask = phy_lane_sel_mask; CAM_DBG(CAM_CSIPHY, "Formatted PHY[%u] phy_lane_sel_mask: 0x%llx", - csiphy_dev->soc_info.index, - tz_secure_info->phy_lane_sel_mask); + csiphy_dev->soc_info.index, *mask); return 0; @@ -108,35 +94,34 @@ static void cam_csiphy_populate_secure_info( struct cam_csiphy_secure_info *secure_info = (struct cam_csiphy_secure_info *)data; struct cam_csiphy_param *param; - struct cam_csiphy_tz_secure_info *tz_secure_info; for (i = 0; i < CSIPHY_MAX_INSTANCES_PER_PHY; i++) { param = &csiphy_dev->csiphy_info[i]; if (param->secure_mode && param->lane_assign == secure_info->lane_assign) { - tz_secure_info = ¶m->secure_info; - tz_secure_info->cdm_hw_idx_mask = secure_info->cdm_hw_idx_mask; - tz_secure_info->csid_hw_idx_mask = secure_info->csid_hw_idx_mask; - tz_secure_info->vc_mask = secure_info->vc_mask; - tz_secure_info->phy_lane_sel_mask = 0; + param->secure_info.cdm_hw_idx_mask = secure_info->cdm_hw_idx_mask; + param->secure_info.csid_hw_idx_mask = secure_info->csid_hw_idx_mask; + param->secure_info.vc_mask = secure_info->vc_mask; + param->secure_info.phy_lane_sel_mask = 0; - if (!cam_csiphy_format_secure_phy_lane_info(csiphy_dev, i)) { + if (!cam_csiphy_format_secure_phy_lane_info(csiphy_dev, i, + ¶m->csiphy_phy_lane_sel_mask)) { param->secure_info_updated = true; CAM_DBG(CAM_CSIPHY, "PHY[%d] secure info, phy_lane_mask: 0x%llx, ife: 0x%x, cdm: 0x%x, vc_mask: 0x%llx", csiphy_dev->soc_info.index, - tz_secure_info->phy_lane_sel_mask, - tz_secure_info->csid_hw_idx_mask, - tz_secure_info->cdm_hw_idx_mask, - tz_secure_info->vc_mask); + param->csiphy_phy_lane_sel_mask, + param->secure_info.csid_hw_idx_mask, + param->secure_info.cdm_hw_idx_mask, + param->secure_info.vc_mask); } else CAM_ERR(CAM_CSIPHY, "Error in formatting PHY[%u] phy_lane_sel_mask: 0x%llx", csiphy_dev->soc_info.index, - tz_secure_info->phy_lane_sel_mask); + param->csiphy_phy_lane_sel_mask); break; } diff --git a/drivers/cam_sensor_module/cam_csiphy/cam_csiphy_dev.h b/drivers/cam_sensor_module/cam_csiphy/cam_csiphy_dev.h index 9525699471..51b75225b8 100644 --- a/drivers/cam_sensor_module/cam_csiphy/cam_csiphy_dev.h +++ b/drivers/cam_sensor_module/cam_csiphy/cam_csiphy_dev.h @@ -1,7 +1,7 @@ /* SPDX-License-Identifier: GPL-2.0-only */ /* * Copyright (c) 2017-2021, The Linux Foundation. All rights reserved. - * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved. + * Copyright (c) 2022-2023 Qualcomm Innovation Center, Inc. All rights reserved. */ #ifndef _CAM_CSIPHY_DEV_H_ @@ -123,28 +123,6 @@ struct cam_csiphy_secure_info { uint32_t cdm_hw_idx_mask; }; -/** - * struct cam_csiphy_tz_secure_info - * - * This is the struct containing all the necessary values - * for scm programming of domain id - * - * @phy_lane_sel_mask: This value to be filled completely by csiphy - * @csid_hw_idx_mask: Bit position denoting CSID(s) in use for secure - * session - * @cdm_hw_idx_mask: Bit position denoting CDM in use for secure - * session - * @vc_mask: VC mask (unused in mobile case) - * @protect: To protect or reset previously protected lanes - */ -struct cam_csiphy_tz_secure_info { - uint64_t phy_lane_sel_mask; - uint32_t csid_hw_idx_mask; - uint32_t cdm_hw_idx_mask; - uint32_t vc_mask; - uint32_t protect; -}; - /** * struct cam_csiphy_aon_sel_params_t * @aon_cam_sel_offset : AON Cam Select Register offset in cpas top @@ -329,9 +307,10 @@ struct csiphy_ctrl_t { * @csiphy_3phase : To identify DPHY or CPHY * @mipi_flags : MIPI phy flags * @csiphy_cpas_cp_reg_mask : CP reg mask for phy instance + * @csiphy_phy_lane_sel_mask : Generic format for CP information for PHY and lane * @hdl_data : CSIPHY handle table * @secure_info : All domain-id security related information packed in proper - * format for scm call + * format for mink call * @secure_info_updated : If all information in the secure_info struct above * is passed and formatted properly from CSID driver * @conn_csid_idx : Connected CSID core idx (Primary csid in case of dual ife) @@ -348,8 +327,9 @@ struct cam_csiphy_param { int csiphy_3phase; uint16_t mipi_flags; uint64_t csiphy_cpas_cp_reg_mask; + uint64_t csiphy_phy_lane_sel_mask; struct csiphy_hdl_tbl hdl_data; - struct cam_csiphy_tz_secure_info secure_info; + struct cam_csiphy_secure_info secure_info; bool secure_info_updated; int32_t conn_csid_idx; bool use_hw_client_voting; diff --git a/drivers/cam_utils/cam_compat.c b/drivers/cam_utils/cam_compat.c index e7d1a5470d..031e3c4ded 100644 --- a/drivers/cam_utils/cam_compat.c +++ b/drivers/cam_utils/cam_compat.c @@ -1,7 +1,7 @@ // SPDX-License-Identifier: GPL-2.0-only /* * Copyright (c) 2014-2021, The Linux Foundation. All rights reserved. - * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved. + * Copyright (c) 2022-2023 Qualcomm Innovation Center, Inc. All rights reserved. */ #include @@ -173,23 +173,6 @@ int cam_ife_notify_safe_lut_scm(bool safe_trigger) return rc; } -int cam_csiphy_notify_secure_mode(struct csiphy_device *csiphy_dev, - bool protect, int32_t offset) -{ - int rc = 0; - - if (offset >= CSIPHY_MAX_INSTANCES_PER_PHY) { - CAM_ERR(CAM_CSIPHY, "Invalid CSIPHY offset"); - rc = -EINVAL; - } else if (qcom_scm_camera_protect_phy_lanes(protect, - csiphy_dev->csiphy_info[offset].csiphy_cpas_cp_reg_mask)) { - CAM_ERR(CAM_CSIPHY, "SCM call to hypervisor failed"); - rc = -EINVAL; - } - - return rc; -} - void cam_cpastop_scm_write(struct cam_cpas_hw_errata_wa *errata_wa) { int reg_val; @@ -257,28 +240,6 @@ int cam_ife_notify_safe_lut_scm(bool safe_trigger) return rc; } -int cam_csiphy_notify_secure_mode(struct csiphy_device *csiphy_dev, - bool protect, int32_t offset) -{ - int rc = 0; - struct scm_desc description = { - .arginfo = SCM_ARGS(2, SCM_VAL, SCM_VAL), - .args[0] = protect, - .args[1] = csiphy_dev->csiphy_info[offset] - .csiphy_cpas_cp_reg_mask, - }; - - if (offset >= CSIPHY_MAX_INSTANCES_PER_PHY) { - CAM_ERR(CAM_CSIPHY, "Invalid CSIPHY offset"); - rc = -EINVAL; - } else if (scm_call2(SCM_SIP_FNID(0x18, 0x7), &description)) { - CAM_ERR(CAM_CSIPHY, "SCM call to hypervisor failed"); - rc = -EINVAL; - } - - return rc; -} - void cam_cpastop_scm_write(struct cam_cpas_hw_errata_wa *errata_wa) { int reg_val; @@ -311,6 +272,116 @@ void cam_free_clear(const void * ptr) } #endif +#if KERNEL_VERSION(6, 0, 0) <= LINUX_VERSION_CODE +int cam_csiphy_notify_secure_mode(struct csiphy_device *csiphy_dev, + bool protect, int32_t offset) +{ + int rc = 0; + struct Object client_env, sc_object; + ITCDriverSensorInfo params = {0}; + struct cam_csiphy_secure_info *secure_info; + + if (offset >= CSIPHY_MAX_INSTANCES_PER_PHY) { + CAM_ERR(CAM_CSIPHY, "Invalid CSIPHY offset"); + return -EINVAL; + } + + rc = get_client_env_object(&client_env); + if (rc) { + CAM_ERR(CAM_CSIPHY, "Failed getting mink env object, rc: %d", rc); + return rc; + } + + rc = IClientEnv_open(client_env, CTrustedCameraDriver_UID, &sc_object); + if (rc) { + CAM_ERR(CAM_CSIPHY, "Failed getting mink sc_object, rc: %d", rc); + return rc; + } + + secure_info = &csiphy_dev->csiphy_info[offset].secure_info; + params.csid_hw_idx_mask = secure_info->csid_hw_idx_mask; + params.cdm_hw_idx_mask = secure_info->cdm_hw_idx_mask; + params.vc_mask = secure_info->vc_mask; + params.phy_lane_sel_mask = + csiphy_dev->csiphy_info[offset].csiphy_phy_lane_sel_mask; + params.protect = protect ? 1 : 0; + + rc = ITrustedCameraDriver_dynamicProtectSensor(sc_object, ¶ms); + if (rc) { + CAM_ERR(CAM_CSIPHY, "Mink secure call failed, rc: %d", rc); + return rc; + } + + rc = Object_release(sc_object); + if (rc) { + CAM_ERR(CAM_CSIPHY, "Failed releasing secure camera object, rc: %d", rc); + return rc; + } + rc = Object_release(client_env); + if (rc) { + CAM_ERR(CAM_CSIPHY, "Failed releasing mink env object, rc: %d", rc); + return rc; + } + + return 0; +} +#elif KERNEL_VERSION(5, 4, 0) <= LINUX_VERSION_CODE +int cam_csiphy_notify_secure_mode(struct csiphy_device *csiphy_dev, + bool protect, int32_t offset) +{ + int rc = 0; + + /** + * A check here is made if the target is using + * an older version of the kernel driver (< 6.0) + * with domain id feature present. In this case, + * we are to fail this call, as the new mink call + * is only supported on kernel driver versions 6.0 + * and above, and the new domain id scheme is not + * backwards compatible with the older scheme. + */ + if (csiphy_dev->domain_id_security) { + CAM_ERR(CAM_CSIPHY, + "Domain id support not present on current kernel driver: %d", + LINUX_VERSION_CODE); + return -EINVAL; + } + + if (offset >= CSIPHY_MAX_INSTANCES_PER_PHY) { + CAM_ERR(CAM_CSIPHY, "Invalid CSIPHY offset"); + rc = -EINVAL; + } else if (qcom_scm_camera_protect_phy_lanes(protect, + csiphy_dev->csiphy_info[offset].csiphy_cpas_cp_reg_mask)) { + CAM_ERR(CAM_CSIPHY, "SCM call to hypervisor failed"); + rc = -EINVAL; + } + + return rc; +} +#else +int cam_csiphy_notify_secure_mode(struct csiphy_device *csiphy_dev, + bool protect, int32_t offset) +{ + int rc = 0; + struct scm_desc description = { + .arginfo = SCM_ARGS(2, SCM_VAL, SCM_VAL), + .args[0] = protect, + .args[1] = csiphy_dev->csiphy_info[offset] + .csiphy_cpas_cp_reg_mask, + }; + + if (offset >= CSIPHY_MAX_INSTANCES_PER_PHY) { + CAM_ERR(CAM_CSIPHY, "Invalid CSIPHY offset"); + rc = -EINVAL; + } else if (scm_call2(SCM_SIP_FNID(0x18, 0x7), &description)) { + CAM_ERR(CAM_CSIPHY, "SCM call to hypervisor failed"); + rc = -EINVAL; + } + + return rc; +} +#endif + /* Callback to compare device from match list before adding as component */ static inline int camera_component_compare_dev(struct device *dev, void *data) { diff --git a/drivers/cam_utils/cam_compat.h b/drivers/cam_utils/cam_compat.h index f92ecf7604..e38b37e52a 100644 --- a/drivers/cam_utils/cam_compat.h +++ b/drivers/cam_utils/cam_compat.h @@ -1,7 +1,7 @@ /* SPDX-License-Identifier: GPL-2.0-only */ /* * Copyright (c) 2014-2021, The Linux Foundation. All rights reserved. - * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved. + * Copyright (c) 2022-2023 Qualcomm Innovation Center, Inc. All rights reserved. */ #ifndef _CAM_COMPAT_H_ @@ -39,6 +39,13 @@ MODULE_IMPORT_NS(DMA_BUF); #endif +#if KERNEL_VERSION(6, 0, 0) <= LINUX_VERSION_CODE +#include +#include +#include +#include +#endif + struct cam_fw_alloc_info { struct device *fw_dev; void *fw_kva;