diff --git a/arch/arm64/include/asm/cputype.h b/arch/arm64/include/asm/cputype.h
index fd38a49c29998a31303b51ad4155ffaaa1fe547d..7680358dd09c3220fc129c10bc8b3eab9bce43de 100644
--- a/arch/arm64/include/asm/cputype.h
+++ b/arch/arm64/include/asm/cputype.h
@@ -55,6 +55,7 @@
#define ARM_CPU_IMP_APM 0x50
#define ARM_CPU_IMP_CAVIUM 0x43
#define ARM_CPU_IMP_PHYTIUM 0x70
+
#define ARM_CPU_IMP_BRCM 0x42
#define ARM_CPU_IMP_QCOM 0x51
#define ARM_CPU_IMP_NVIDIA 0x4E
@@ -89,6 +90,10 @@
#define APM_CPU_PART_XGENE 0x000
#define APM_CPU_VAR_POTENZA 0x00
+#define PHYTIUM_CPU_PART_1500A 0X660
+#define PHYTIUM_CPU_PART_2000AHK 0X661
+#define PHYTIUM_CPU_PART_2000PLUS 0X662
+#define PHYTIUM_CPU_PART_2004 0X663
#define PHYTIUM_CPU_PART_2500 0X663
#define CAVIUM_CPU_PART_THUNDERX 0x0A1
@@ -143,6 +148,10 @@
#define MIDR_CORTEX_A72 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_A72)
#define MIDR_CORTEX_A73 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_A73)
#define MIDR_CORTEX_A75 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_A75)
+#define MIDR_FT_1500A MIDR_CPU_MODEL(ARM_CPU_IMP_PHYTIUM, PHYTIUM_CPU_PART_1500A)
+#define MIDR_FT_2000AHK MIDR_CPU_MODEL(ARM_CPU_IMP_PHYTIUM, PHYTIUM_CPU_PART_2000AHK)
+#define MIDR_FT_2000PLUS MIDR_CPU_MODEL(ARM_CPU_IMP_PHYTIUM, PHYTIUM_CPU_PART_2000PLUS)
+#define MIDR_FT_2004 MIDR_CPU_MODEL(ARM_CPU_IMP_PHYTIUM, PHYTIUM_CPU_PART_2004)
#define MIDR_FT_2500 MIDR_CPU_MODEL(ARM_CPU_IMP_PHYTIUM, PHYTIUM_CPU_PART_2500)
#define MIDR_CORTEX_A35 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_A35)
diff --git a/arch/arm64/include/asm/phytium_machine_types.h b/arch/arm64/include/asm/phytium_machine_types.h
new file mode 100644
index 0000000000000000000000000000000000000000..8aed50daca4bce4ec55421b63b6b811446a90954
--- /dev/null
+++ b/arch/arm64/include/asm/phytium_machine_types.h
@@ -0,0 +1,37 @@
+/* SPDX-License-Identifier: GPL-2.0
+ * Authors: Wang Yinfeng .
+ */
+
+#ifndef _MACHINE_TYPE_H_
+#define _MACHINE_TYPE_H_
+
+#include
+#include
+
+static inline bool phytium_part(u32 cpuid)
+{
+ return ((read_cpuid_id() & MIDR_CPU_MODEL_MASK) == cpuid);
+}
+
+#define typeof_ft1500a() phytium_part(MIDR_FT_1500A)
+#define typeof_ft2000ahk() phytium_part(MIDR_FT_2000AHK)
+#define typeof_ft2000plus() phytium_part(MIDR_FT_2000PLUS)
+#define typeof_ft2004() phytium_part(MIDR_FT_2004)
+#define typeof_s2500() phytium_part(MIDR_FT_2500)
+
+#endif
diff --git a/drivers/iommu/arm/arm-smmu/arm-smmu.c b/drivers/iommu/arm/arm-smmu/arm-smmu.c
index d6d1a2a55cc0692fb02f0f58b901ac438c71604c..8ce9d33e7840c1eac90b197536e480a08ae6ad2b 100644
--- a/drivers/iommu/arm/arm-smmu/arm-smmu.c
+++ b/drivers/iommu/arm/arm-smmu/arm-smmu.c
@@ -35,6 +35,10 @@
#include
#include
+#ifdef CONFIG_ARCH_PHYTIUM
+#include
+#endif
+
#include
#include "arm-smmu.h"
@@ -51,6 +55,7 @@
#define MSI_IOVA_BASE 0x8000000
#define MSI_IOVA_LENGTH 0x100000
+#define SMR_MASK_SHIFT 16
static int force_stage;
module_param(force_stage, int, S_IRUGO);
@@ -1363,6 +1368,19 @@ static struct iommu_device *arm_smmu_probe_device(struct device *dev)
return ERR_PTR(-ENODEV);
}
+#ifdef CONFIG_ARCH_PHYTIUM
+#define FWID_READ(id) (((u16)(id) >> 3) | (((id) >> SMR_MASK_SHIFT | 0x7000) << SMR_MASK_SHIFT))
+ if (typeof_ft2000plus()) {
+ 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]);
@@ -1458,7 +1476,12 @@ static struct iommu_group *arm_smmu_device_group(struct device *dev)
mutex_unlock(&smmu->stream_map_mutex);
return ERR_PTR(-EINVAL);
}
-
+#ifdef CONFIG_ARCH_PHYTIUM
+ if (typeof_s2500())
+ break;
+ if (typeof_ft2000plus() && !smmu->s2crs[idx].group)
+ continue;
+#endif
group = smmu->s2crs[idx].group;
}
diff --git a/drivers/irqchip/irq-gic-v3-its.c b/drivers/irqchip/irq-gic-v3-its.c
index 9a7a74239eabb7cd3d2a3a077316d54833ec18cb..cefe81cbe493fd1c1a75dad3751751b680fc81c3 100644
--- a/drivers/irqchip/irq-gic-v3-its.c
+++ b/drivers/irqchip/irq-gic-v3-its.c
@@ -37,6 +37,10 @@
#include
#include
+#ifdef CONFIG_ARCH_PHYTIUM
+#include
+#endif
+
#include "irq-gic-common.h"
#define ITS_FLAGS_CMDQ_NEEDS_FLUSHING (1ULL << 0)
@@ -1725,6 +1729,11 @@ 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 (typeof_ft2000plus())
+ return;
+#endif
+
iommu_dma_compose_msi_msg(irq_data_get_msi_desc(d), msg);
}
diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c
index 83a875b53111cfcf09fb4e2aeb48bec50248f75f..9f2356a52085d7e12fbc2553615132c3f24fe3a3 100644
--- a/drivers/pci/quirks.c
+++ b/drivers/pci/quirks.c
@@ -5069,6 +5069,13 @@ static const struct pci_dev_acs_enabled {
{ PCI_VENDOR_ID_AMPERE, 0xE00A, pci_quirk_xgene_acs },
{ PCI_VENDOR_ID_AMPERE, 0xE00B, pci_quirk_xgene_acs },
{ PCI_VENDOR_ID_AMPERE, 0xE00C, pci_quirk_xgene_acs },
+#ifdef CONFIG_ARCH_PHYTIUM
+ /* because PLX switch Vendor id is 0x10b5 on phytium cpu */
+ { 0x10b5, PCI_ANY_ID, pci_quirk_xgene_acs },
+ /* because rootcomplex Vendor id is 0x17cd on phytium cpu */
+ { 0x17cd, PCI_ANY_ID, pci_quirk_xgene_acs },
+#endif
+
/* Broadcom multi-function device */
{ PCI_VENDOR_ID_BROADCOM, 0x16D7, pci_quirk_mf_endpoint_acs },
{ PCI_VENDOR_ID_BROADCOM, 0x1750, pci_quirk_mf_endpoint_acs },