Loading Documentation/devicetree/bindings/iommu/arm,smmu.txt +9 −0 Original line number Diff line number Diff line Loading @@ -101,6 +101,15 @@ conditions. Any sid X for which X&~mask==sid will be programmed with the given actlr-setting. - qcom,enable-static-cb : Enables option to use pre-defined static context bank allocation programmed by TZ. Global register including SMR and S2CR registers are configured by TZ before kernel comes up and this programming is not altered throughout the life of system. We would be reading through these registers at run time to identify CB allocated for a particular sid. SID masking isn't supported as we are directly comparing client SID with ID bits of SMR registers. - qcom,deferred-regulator-disable-delay : The time delay for deferred regulator disable in ms. In case of unmap call, regulator is enabled/disabled. This may introduce additional delay. For Loading drivers/iommu/arm-smmu.c +10 −1 Original line number Diff line number Diff line Loading @@ -248,6 +248,7 @@ struct arm_smmu_device { #define ARM_SMMU_OPT_DYNAMIC (1 << 3) #define ARM_SMMU_OPT_3LVL_TABLES (1 << 4) #define ARM_SMMU_OPT_NO_ASID_RETENTION (1 << 5) #define ARM_SMMU_OPT_STATIC_CB (1 << 6) u32 options; enum arm_smmu_arch_version version; enum arm_smmu_implementation model; Loading Loading @@ -379,6 +380,7 @@ static struct arm_smmu_option_prop arm_smmu_options[] = { { ARM_SMMU_OPT_DYNAMIC, "qcom,dynamic" }, { ARM_SMMU_OPT_3LVL_TABLES, "qcom,use-3-lvl-tables" }, { ARM_SMMU_OPT_NO_ASID_RETENTION, "qcom,no-asid-retention" }, { ARM_SMMU_OPT_STATIC_CB, "qcom,enable-static-cb"}, { 0, NULL}, }; Loading @@ -402,6 +404,8 @@ static int arm_smmu_alloc_cb(struct iommu_domain *domain, struct arm_smmu_device *smmu, struct device *dev); static bool arm_smmu_is_static_cb(struct arm_smmu_device *smmu); static struct arm_smmu_domain *to_smmu_domain(struct iommu_domain *dom) { return container_of(dom, struct arm_smmu_domain, domain); Loading Loading @@ -439,6 +443,11 @@ static bool is_iommu_pt_coherent(struct arm_smmu_domain *smmu_domain) return false; } static bool arm_smmu_is_static_cb(struct arm_smmu_device *smmu) { return smmu->options & ARM_SMMU_OPT_STATIC_CB; } static bool arm_smmu_is_domain_secure(struct arm_smmu_domain *smmu_domain) { return (smmu_domain->secure_vmid != VMID_INVAL); Loading Loading @@ -3592,7 +3601,7 @@ static int arm_smmu_alloc_cb(struct iommu_domain *domain, cb = smmu->s2crs[idx].cbndx; } if (cb < 0) { if (cb < 0 && !arm_smmu_is_static_cb(smmu)) { mutex_unlock(&smmu->stream_map_mutex); return __arm_smmu_alloc_bitmap(smmu->context_map, smmu->num_s2_context_banks, Loading drivers/soc/qcom/scm.c +51 −1 Original line number Diff line number Diff line Loading @@ -278,7 +278,7 @@ static enum scm_interface_version { /* This will be set to specify SMC32 or SMC64 */ static u32 scm_version_mask; static bool is_scm_armv8(void) bool is_scm_armv8(void) { int ret; u64 ret1, x0; Loading Loading @@ -589,6 +589,56 @@ int scm_is_call_available(u32 svc_id, u32 cmd_id) } EXPORT_SYMBOL(scm_is_call_available); #define GET_FEAT_VERSION_CMD 3 int scm_get_feat_version(u32 feat) { struct scm_desc desc = {0}; int ret; ret = scm_is_call_available(SCM_SVC_INFO, GET_FEAT_VERSION_CMD); if (ret <= 0) return 0; desc.args[0] = feat; desc.arginfo = SCM_ARGS(1); ret = scm_call2(SCM_SIP_FNID(SCM_SVC_INFO, GET_FEAT_VERSION_CMD), &desc); if (!ret) return desc.ret[0]; return 0; } EXPORT_SYMBOL(scm_get_feat_version); #define RESTORE_SEC_CFG 2 int scm_restore_sec_cfg(u32 device_id, u32 spare, int *scm_ret) { struct scm_desc desc = {0}; int ret; struct restore_sec_cfg { u32 device_id; u32 spare; } cfg; cfg.device_id = device_id; cfg.spare = spare; if (IS_ERR_OR_NULL(scm_ret)) return -EINVAL; desc.args[0] = device_id; desc.args[1] = spare; desc.arginfo = SCM_ARGS(2); ret = scm_call2(SCM_SIP_FNID(SCM_SVC_MP, RESTORE_SEC_CFG), &desc); if (ret) return ret; *scm_ret = desc.ret[0]; return 0; } EXPORT_SYMBOL(scm_restore_sec_cfg); /* * SCM call command ID to check secure mode * Return zero for secure device. Loading include/soc/qcom/scm.h +13 −0 Original line number Diff line number Diff line Loading @@ -103,10 +103,13 @@ extern int scm_call2_noretry(u32 cmd_id, struct scm_desc *desc); extern int scm_call2_atomic(u32 cmd_id, struct scm_desc *desc); extern u32 scm_get_version(void); extern int scm_is_call_available(u32 svc_id, u32 cmd_id); extern int scm_restore_sec_cfg(u32 device_id, u32 spare, int *scm_ret); extern u32 scm_io_read(phys_addr_t address); extern int scm_io_write(phys_addr_t address, u32 val); extern bool scm_is_secure_device(void); extern int scm_enable_mem_protection(void); extern int scm_get_feat_version(u32 feat); extern bool is_scm_armv8(void); extern struct mutex scm_lmh_lock; Loading @@ -132,6 +135,11 @@ static inline u32 scm_get_version(void) return 0; } static inline int scm_get_feat_version(u32 feat) { return 0; } static inline int scm_is_call_available(u32 svc_id, u32 cmd_id) { return 0; Loading @@ -142,6 +150,11 @@ static inline bool is_scm_armv8(void) return true; } static inline int scm_restore_sec_cfg(u32 device_id, u32 spare, int *scm_ret) { return 0; } static inline u32 scm_io_read(phys_addr_t address) { return 0; Loading Loading
Documentation/devicetree/bindings/iommu/arm,smmu.txt +9 −0 Original line number Diff line number Diff line Loading @@ -101,6 +101,15 @@ conditions. Any sid X for which X&~mask==sid will be programmed with the given actlr-setting. - qcom,enable-static-cb : Enables option to use pre-defined static context bank allocation programmed by TZ. Global register including SMR and S2CR registers are configured by TZ before kernel comes up and this programming is not altered throughout the life of system. We would be reading through these registers at run time to identify CB allocated for a particular sid. SID masking isn't supported as we are directly comparing client SID with ID bits of SMR registers. - qcom,deferred-regulator-disable-delay : The time delay for deferred regulator disable in ms. In case of unmap call, regulator is enabled/disabled. This may introduce additional delay. For Loading
drivers/iommu/arm-smmu.c +10 −1 Original line number Diff line number Diff line Loading @@ -248,6 +248,7 @@ struct arm_smmu_device { #define ARM_SMMU_OPT_DYNAMIC (1 << 3) #define ARM_SMMU_OPT_3LVL_TABLES (1 << 4) #define ARM_SMMU_OPT_NO_ASID_RETENTION (1 << 5) #define ARM_SMMU_OPT_STATIC_CB (1 << 6) u32 options; enum arm_smmu_arch_version version; enum arm_smmu_implementation model; Loading Loading @@ -379,6 +380,7 @@ static struct arm_smmu_option_prop arm_smmu_options[] = { { ARM_SMMU_OPT_DYNAMIC, "qcom,dynamic" }, { ARM_SMMU_OPT_3LVL_TABLES, "qcom,use-3-lvl-tables" }, { ARM_SMMU_OPT_NO_ASID_RETENTION, "qcom,no-asid-retention" }, { ARM_SMMU_OPT_STATIC_CB, "qcom,enable-static-cb"}, { 0, NULL}, }; Loading @@ -402,6 +404,8 @@ static int arm_smmu_alloc_cb(struct iommu_domain *domain, struct arm_smmu_device *smmu, struct device *dev); static bool arm_smmu_is_static_cb(struct arm_smmu_device *smmu); static struct arm_smmu_domain *to_smmu_domain(struct iommu_domain *dom) { return container_of(dom, struct arm_smmu_domain, domain); Loading Loading @@ -439,6 +443,11 @@ static bool is_iommu_pt_coherent(struct arm_smmu_domain *smmu_domain) return false; } static bool arm_smmu_is_static_cb(struct arm_smmu_device *smmu) { return smmu->options & ARM_SMMU_OPT_STATIC_CB; } static bool arm_smmu_is_domain_secure(struct arm_smmu_domain *smmu_domain) { return (smmu_domain->secure_vmid != VMID_INVAL); Loading Loading @@ -3592,7 +3601,7 @@ static int arm_smmu_alloc_cb(struct iommu_domain *domain, cb = smmu->s2crs[idx].cbndx; } if (cb < 0) { if (cb < 0 && !arm_smmu_is_static_cb(smmu)) { mutex_unlock(&smmu->stream_map_mutex); return __arm_smmu_alloc_bitmap(smmu->context_map, smmu->num_s2_context_banks, Loading
drivers/soc/qcom/scm.c +51 −1 Original line number Diff line number Diff line Loading @@ -278,7 +278,7 @@ static enum scm_interface_version { /* This will be set to specify SMC32 or SMC64 */ static u32 scm_version_mask; static bool is_scm_armv8(void) bool is_scm_armv8(void) { int ret; u64 ret1, x0; Loading Loading @@ -589,6 +589,56 @@ int scm_is_call_available(u32 svc_id, u32 cmd_id) } EXPORT_SYMBOL(scm_is_call_available); #define GET_FEAT_VERSION_CMD 3 int scm_get_feat_version(u32 feat) { struct scm_desc desc = {0}; int ret; ret = scm_is_call_available(SCM_SVC_INFO, GET_FEAT_VERSION_CMD); if (ret <= 0) return 0; desc.args[0] = feat; desc.arginfo = SCM_ARGS(1); ret = scm_call2(SCM_SIP_FNID(SCM_SVC_INFO, GET_FEAT_VERSION_CMD), &desc); if (!ret) return desc.ret[0]; return 0; } EXPORT_SYMBOL(scm_get_feat_version); #define RESTORE_SEC_CFG 2 int scm_restore_sec_cfg(u32 device_id, u32 spare, int *scm_ret) { struct scm_desc desc = {0}; int ret; struct restore_sec_cfg { u32 device_id; u32 spare; } cfg; cfg.device_id = device_id; cfg.spare = spare; if (IS_ERR_OR_NULL(scm_ret)) return -EINVAL; desc.args[0] = device_id; desc.args[1] = spare; desc.arginfo = SCM_ARGS(2); ret = scm_call2(SCM_SIP_FNID(SCM_SVC_MP, RESTORE_SEC_CFG), &desc); if (ret) return ret; *scm_ret = desc.ret[0]; return 0; } EXPORT_SYMBOL(scm_restore_sec_cfg); /* * SCM call command ID to check secure mode * Return zero for secure device. Loading
include/soc/qcom/scm.h +13 −0 Original line number Diff line number Diff line Loading @@ -103,10 +103,13 @@ extern int scm_call2_noretry(u32 cmd_id, struct scm_desc *desc); extern int scm_call2_atomic(u32 cmd_id, struct scm_desc *desc); extern u32 scm_get_version(void); extern int scm_is_call_available(u32 svc_id, u32 cmd_id); extern int scm_restore_sec_cfg(u32 device_id, u32 spare, int *scm_ret); extern u32 scm_io_read(phys_addr_t address); extern int scm_io_write(phys_addr_t address, u32 val); extern bool scm_is_secure_device(void); extern int scm_enable_mem_protection(void); extern int scm_get_feat_version(u32 feat); extern bool is_scm_armv8(void); extern struct mutex scm_lmh_lock; Loading @@ -132,6 +135,11 @@ static inline u32 scm_get_version(void) return 0; } static inline int scm_get_feat_version(u32 feat) { return 0; } static inline int scm_is_call_available(u32 svc_id, u32 cmd_id) { return 0; Loading @@ -142,6 +150,11 @@ static inline bool is_scm_armv8(void) return true; } static inline int scm_restore_sec_cfg(u32 device_id, u32 spare, int *scm_ret) { return 0; } static inline u32 scm_io_read(phys_addr_t address) { return 0; Loading