From 45c76af959d75dd78cf2c5941859029b08412a35 Mon Sep 17 00:00:00 2001 From: Wang Chenlu Date: Thu, 14 May 2026 11:00:32 +0800 Subject: [PATCH 1/3] iommu/arm-smmu: Add SMMU workaround for Phytium Ps17064 There are two hacks needed for IOMMU enablement on Phytium Ps17064 SoC. One is the MSI hack, the other is the SMMU hack. When using this enablement, we assumes that users would set CONIFIG_IOMMU_DEFAULT_PASSTHROUGH=y or pass 'iommu.passthrough=on' or 'iommu.pt' as the kernel command-line parameters. Therefore, we also force default iommu domain type to IOMMU_DOMAIN_IDENTITY on Ps17064 to avoid unnecessary troubles. Signed-off-by: Wang Yinfeng Signed-off-by: Chen Baozi Signed-off-by: Wang Chenlu --- drivers/iommu/arm/arm-smmu/arm-smmu.c | 13 +++++++++++++ drivers/iommu/arm/arm-smmu/arm-smmu.h | 5 +++++ drivers/iommu/iommu.c | 25 +++++++++++++++++++++++++ drivers/irqchip/irq-gic-v3-its.c | 3 ++- 4 files changed, 45 insertions(+), 1 deletion(-) 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..5845b7ecae55f 100644 --- a/drivers/irqchip/irq-gic-v3-its.c +++ b/drivers/irqchip/irq-gic-v3-its.c @@ -1736,7 +1736,8 @@ 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); - iommu_dma_compose_msi_msg(irq_data_get_msi_desc(d), msg); + if ((read_cpuid_id() & MIDR_CPU_MODEL_MASK) != MIDR_PHYTIUM_PS17064) + iommu_dma_compose_msi_msg(irq_data_get_msi_desc(d), msg); } static int its_irq_set_irqchip_state(struct irq_data *d, From 23310ee75719c5f74e3b838245f59f1f73b561f0 Mon Sep 17 00:00:00 2001 From: Wang Chenlu Date: Thu, 14 May 2026 11:07:08 +0800 Subject: [PATCH 2/3] arm64: Phytium: Slove the error on aarch32 compiler When compiling with the aarch32 compiler, the arm64-specific macros were not defined. Add restriction to bring these macros only into effect on arm64 architecture. Mainline: NA Signed-off-by: Li Mingzhe Signed-off-by: Wang Yinfeng Signed-off-by: Wang Chenlu --- drivers/irqchip/irq-gic-v3-its.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/irqchip/irq-gic-v3-its.c b/drivers/irqchip/irq-gic-v3-its.c index 5845b7ecae55f..e6125260866fa 100644 --- a/drivers/irqchip/irq-gic-v3-its.c +++ b/drivers/irqchip/irq-gic-v3-its.c @@ -1736,8 +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) iommu_dma_compose_msi_msg(irq_data_get_msi_desc(d), msg); +#endif } static int its_irq_set_irqchip_state(struct irq_data *d, From 346cfd5cce01abc08ffa7d308b034c0bcfeb231f Mon Sep 17 00:00:00 2001 From: Wang Chenlu Date: Thu, 14 May 2026 11:09:20 +0800 Subject: [PATCH 3/3] arm64: Phytium: Fix incorrect MSI compose logic on Phytium PS17064 SoCs Fix the logic in its_irq_compose_msi() where CONFIG_ARCH_PHYTIUM filtering accidentally changed the original behavior. Now iommu_dma_compose_msi_msg() is skipped only on PS17064 SoCs, and executed on all other platforms as intended. Mainline: NA Signed-off-by: Li Mingzhe Signed-off-by: Wang Yinfeng Signed-off-by: Wang Chenlu --- drivers/irqchip/irq-gic-v3-its.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/drivers/irqchip/irq-gic-v3-its.c b/drivers/irqchip/irq-gic-v3-its.c index e6125260866fa..ac305d5744032 100644 --- a/drivers/irqchip/irq-gic-v3-its.c +++ b/drivers/irqchip/irq-gic-v3-its.c @@ -1737,9 +1737,10 @@ static void its_irq_compose_msi_msg(struct irq_data *d, struct msi_msg *msg) msg->data = its_get_event_id(d); #ifdef CONFIG_ARCH_PHYTIUM - if ((read_cpuid_id() & MIDR_CPU_MODEL_MASK) != MIDR_PHYTIUM_PS17064) - iommu_dma_compose_msi_msg(irq_data_get_msi_desc(d), msg); + 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); } static int its_irq_set_irqchip_state(struct irq_data *d,