From c02add3f5b543361d2a2de38f8a8600bab3e0ab1 Mon Sep 17 00:00:00 2001 From: Prakash Gupta Date: Mon, 12 Oct 2020 17:09:08 +0530 Subject: [PATCH] iommu: arm-smmu: domain power on arm_smmu_map/map_sg Enable domain power in arm_smmu_map/map_sg. This is not required with QGKI kernel due to downstream fixes. So limit the domain power enable only for QGKI build. Add config ARM_SMMU_SKIP_MAP_POWER_ON to limit this for specific targets. Change-Id: I299666da1b812fc3dd06960e75ddd1fb08e9a8d0 Signed-off-by: Prakash Gupta --- arch/arm/configs/vendor/sdxlemur.config | 1 + arch/arm64/configs/vendor/holi_QGKI.config | 1 + arch/arm64/configs/vendor/lahaina_QGKI.config | 1 + drivers/iommu/Kconfig | 10 ++++++++++ drivers/iommu/arm-smmu.c | 19 +++++++++++++++++++ 5 files changed, 32 insertions(+) diff --git a/arch/arm/configs/vendor/sdxlemur.config b/arch/arm/configs/vendor/sdxlemur.config index 873d6b119519..bffe2339d09f 100644 --- a/arch/arm/configs/vendor/sdxlemur.config +++ b/arch/arm/configs/vendor/sdxlemur.config @@ -19,6 +19,7 @@ CONFIG_IOMMU_DYNAMIC_DOMAINS=y CONFIG_IOMMU_IO_PGTABLE_FAST=y CONFIG_QCOM_IOMMU_IO_PGTABLE_QUIRKS=y CONFIG_IOMMU_LIMIT_IOVA_ALIGNMENT=y +CONFIG_ARM_SMMU_SKIP_MAP_POWER_ON=y CONFIG_QTI_IOMMU_SUPPORT=y CONFIG_QCOM_SCM=y CONFIG_QCOM_SECURE_BUFFER=y diff --git a/arch/arm64/configs/vendor/holi_QGKI.config b/arch/arm64/configs/vendor/holi_QGKI.config index 980adceee633..302edee1137b 100644 --- a/arch/arm64/configs/vendor/holi_QGKI.config +++ b/arch/arm64/configs/vendor/holi_QGKI.config @@ -4,6 +4,7 @@ CONFIG_QCOM_IOMMU_IO_PGTABLE_QUIRKS=y CONFIG_QCOM_LAZY_MAPPING=y CONFIG_DEBUG_FS=y CONFIG_IOMMU_DYNAMIC_DOMAINS=y +CONFIG_ARM_SMMU_SKIP_MAP_POWER_ON=y CONFIG_QCOM_SECURE_BUFFER=y # CONFIG_ZONE_DMA32 is not set CONFIG_EDAC_KRYO_ARM64=y diff --git a/arch/arm64/configs/vendor/lahaina_QGKI.config b/arch/arm64/configs/vendor/lahaina_QGKI.config index 98271d09343a..1be3c62bde50 100644 --- a/arch/arm64/configs/vendor/lahaina_QGKI.config +++ b/arch/arm64/configs/vendor/lahaina_QGKI.config @@ -12,6 +12,7 @@ CONFIG_STM_PROTO_BASIC=y CONFIG_ION_MSM_HEAPS=y CONFIG_IOMMU_IO_PGTABLE_FAST=y CONFIG_IOMMU_DYNAMIC_DOMAINS=y +CONFIG_ARM_SMMU_SKIP_MAP_POWER_ON=y # CONFIG_IOMMU_IO_PGTABLE_FAST_SELFTEST is not set # CONFIG_IOMMU_IO_PGTABLE_FAST_PROVE_TLB is not set # CONFIG_SOFTLOCKUP_DETECTOR is not set diff --git a/drivers/iommu/Kconfig b/drivers/iommu/Kconfig index f0b0789d8505..c89039fad7ff 100644 --- a/drivers/iommu/Kconfig +++ b/drivers/iommu/Kconfig @@ -538,6 +538,16 @@ config ARM_SMMU_TESTBUS_DEBUGFS on an SMMU. This also exposes debugfs nodes to read testbus output after the output has been selected. +config ARM_SMMU_SKIP_MAP_POWER_ON + bool "Skip power on in map/map_sg path" + depends on ARM_SMMU && QGKI + help + Support for skipping domain power on in arm_smmu_map/map_sg path. + This is required to be enabled if no tlb flush needs to be performed + in map/map_sg path. + + If unsure, say N here. + config ARM_SMMU_V3 tristate "ARM Ltd. System MMU Version 3 (SMMUv3) Support" depends on ARM64 diff --git a/drivers/iommu/arm-smmu.c b/drivers/iommu/arm-smmu.c index 8ab9b389b58c..eab3087df00d 100644 --- a/drivers/iommu/arm-smmu.c +++ b/drivers/iommu/arm-smmu.c @@ -3149,6 +3149,13 @@ static int arm_smmu_map(struct iommu_domain *domain, unsigned long iova, return PTR_ERR(ops); else if (!ops) return -EINVAL; + + if (!IS_ENABLED(CONFIG_ARM_SMMU_SKIP_MAP_POWER_ON)) { + ret = arm_smmu_domain_power_on(domain, smmu_domain->smmu); + if (ret) + return ret; + } + iova = arm_smmu_mask_iova(smmu_domain, iova); arm_smmu_secure_domain_lock(smmu_domain); arm_smmu_rpm_get(smmu); @@ -3174,6 +3181,9 @@ static int arm_smmu_map(struct iommu_domain *domain, unsigned long iova, } + if (!IS_ENABLED(CONFIG_ARM_SMMU_SKIP_MAP_POWER_ON)) + arm_smmu_domain_power_off(domain, smmu_domain->smmu); + arm_smmu_assign_table(smmu_domain); arm_smmu_secure_domain_unlock(smmu_domain); @@ -3300,6 +3310,12 @@ static size_t arm_smmu_map_sg(struct iommu_domain *domain, unsigned long iova, return 0; iova = arm_smmu_mask_iova(smmu_domain, iova); + if (!IS_ENABLED(CONFIG_ARM_SMMU_SKIP_MAP_POWER_ON)) { + ret = arm_smmu_domain_power_on(domain, smmu_domain->smmu); + if (ret) + return ret; + } + arm_smmu_secure_domain_lock(smmu_domain); __saved_iova_start = iova; @@ -3357,6 +3373,9 @@ static size_t arm_smmu_map_sg(struct iommu_domain *domain, unsigned long iova, } out: + if (!IS_ENABLED(CONFIG_ARM_SMMU_SKIP_MAP_POWER_ON)) + arm_smmu_domain_power_off(domain, smmu_domain->smmu); + arm_smmu_assign_table(smmu_domain); arm_smmu_secure_domain_unlock(smmu_domain);