diff --git a/drivers/iommu/arm/arm-smmu/arm-smmu.c b/drivers/iommu/arm/arm-smmu/arm-smmu.c index 42c5012ba8aac..fb69d852b3b66 100644 --- a/drivers/iommu/arm/arm-smmu/arm-smmu.c +++ b/drivers/iommu/arm/arm-smmu/arm-smmu.c @@ -1374,6 +1374,19 @@ static struct iommu_device *arm_smmu_probe_device(struct device *dev) return ERR_PTR(-ENODEV); } +#ifdef CONFIG_ARCH_PHYTIUM + /* Phytium Ps17064 workaround patch */ + if ((read_cpuid_id() & MIDR_CPU_MODEL_MASK) == MIDR_PHYTIUM_PS17064) { + int num = fwspec->num_ids; + + for (i = 0; i < num; i++) { + u32 fwid = FWID_READ(fwspec->ids[i]); + + iommu_fwspec_add_ids(dev, &fwid, 1); + } + } +#endif + ret = -EINVAL; for (i = 0; i < fwspec->num_ids; i++) { u16 sid = FIELD_GET(ARM_SMMU_SMR_ID, fwspec->ids[i]); diff --git a/drivers/iommu/arm/arm-smmu/arm-smmu.h b/drivers/iommu/arm/arm-smmu/arm-smmu.h index 703fd5817ec11..723532e24f60f 100644 --- a/drivers/iommu/arm/arm-smmu/arm-smmu.h +++ b/drivers/iommu/arm/arm-smmu/arm-smmu.h @@ -10,6 +10,7 @@ #ifndef _ARM_SMMU_H #define _ARM_SMMU_H +#include #include #include #include @@ -23,6 +24,10 @@ #include #include +#ifdef CONFIG_ARCH_PHYTIUM +#define FWID_READ(id) (((u16)(id) >> 3) | (((id) >> 16 | 0x7000) << 16)) +#endif + /* Configuration registers */ #define ARM_SMMU_GR0_sCR0 0x0 #define ARM_SMMU_sCR0_VMID16EN BIT(31) diff --git a/drivers/iommu/iommu.c b/drivers/iommu/iommu.c index 987e307de64f2..de1dc6a4e0ef2 100644 --- a/drivers/iommu/iommu.c +++ b/drivers/iommu/iommu.c @@ -32,6 +32,9 @@ #include #include #include +#ifdef CONFIG_ARCH_PHYTIUM +#include +#endif #include "dma-iommu.h" #include "iommu-priv.h" @@ -198,6 +201,15 @@ static int __init iommu_subsys_init(void) iommu_set_default_passthrough(false); else iommu_set_default_translated(false); +#ifdef CONFIG_ARCH_PHYTIUM + /* + * Always set default iommu type to IOMMU_DOMAIN_IDENTITY + * on Phytium Ps17064 SoC to avoid unnecessary troubles + * introduced by the SMMU workaround. + */ + if ((read_cpuid_id() & MIDR_CPU_MODEL_MASK) == MIDR_PHYTIUM_PS17064) + iommu_set_default_passthrough(true); +#endif if (iommu_default_passthrough() && cc_platform_has(CC_ATTR_MEM_ENCRYPT)) { pr_info("Memory encryption detected - Disabling default IOMMU Passthrough\n"); @@ -660,6 +672,19 @@ static int __init iommu_set_def_domain_type(char *str) if (ret) return ret; +#ifdef CONFIG_ARCH_PHYTIUM + /* + * Always set default iommu type to IOMMU_DOMAIN_IDENTITY + * on Phytium Ps17064 SoC to avoid unnecessary troubles + * introduced by the SMMU workaround. + */ + if ((read_cpuid_id() & MIDR_CPU_MODEL_MASK) == MIDR_PHYTIUM_PS17064) { + iommu_def_domain_type = IOMMU_DOMAIN_IDENTITY; + iommu_set_default_passthrough(true); + return 0; + } +#endif + if (pt) iommu_set_default_passthrough(true); else diff --git a/drivers/irqchip/irq-gic-v3-its.c b/drivers/irqchip/irq-gic-v3-its.c index 7b3a992ee4149..ac305d5744032 100644 --- a/drivers/irqchip/irq-gic-v3-its.c +++ b/drivers/irqchip/irq-gic-v3-its.c @@ -1736,6 +1736,10 @@ static void its_irq_compose_msi_msg(struct irq_data *d, struct msi_msg *msg) msg->address_hi = upper_32_bits(addr); msg->data = its_get_event_id(d); +#ifdef CONFIG_ARCH_PHYTIUM + if ((read_cpuid_id() & MIDR_CPU_MODEL_MASK) == MIDR_PHYTIUM_PS17064) + return; +#endif iommu_dma_compose_msi_msg(irq_data_get_msi_desc(d), msg); }