From: root <root(a)localhost.localdomain>
---
 arch/arm64/include/asm/cputype.h       | 12 ++++++++
 arch/arm64/include/asm/machine_types.h | 39 ++++++++++++++++++++++++++
 drivers/iommu/arm/arm-smmu/arm-smmu.c  | 24 ++++++++++++++++
 drivers/irqchip/irq-gic-v3-its.c       |  9 ++++++
 drivers/pci/quirks.c                   |  4 +++
 5 files changed, 88 insertions(+)
 create mode 100644 arch/arm64/include/asm/machine_types.h
diff --git a/arch/arm64/include/asm/cputype.h b/arch/arm64/include/asm/cputype.h
index 4e5b34c8f..4e2c3c9ee 100644
--- a/arch/arm64/include/asm/cputype.h
+++ b/arch/arm64/include/asm/cputype.h
@@ -54,6 +54,8 @@
 #define ARM_CPU_IMP_ARM			0x41
 #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
@@ -75,6 +77,11 @@
 #define ARM_CPU_PART_CORTEX_A77		0xD0D
 
 #define APM_CPU_PART_POTENZA		0x000
+#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
 #define CAVIUM_CPU_PART_THUNDERX_81XX	0x0A2
@@ -109,6 +116,11 @@
 #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)
 #define MIDR_CORTEX_A55 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_A55)
 #define MIDR_CORTEX_A76	MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_A76)
diff --git a/arch/arm64/include/asm/machine_types.h
b/arch/arm64/include/asm/machine_types.h
new file mode 100644
index 000000000..b1d2db574
--- /dev/null
+++ b/arch/arm64/include/asm/machine_types.h
@@ -0,0 +1,39 @@
+/*
+ *  Authors: Wang Yinfeng <wangyinfenng(a)phytium.com.cn>
+ *
+ *  Copyright (C) 2021, PHYTIUM Information Technology Co., Ltd.
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public
+ *  License as published by the Free Software Foundation; either
+ *  version 2 of the License, or (at your option) any later version.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this library; if not, write to the
+ *  Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
+ *  Boston, MA 02110-1301, USA.
+ */
+
+#ifndef _MACHINE_TYPE_H_
+#define _MACHINE_TYPE_H_
+
+#include <asm/cputype.h>
+#include <linux/types.h>
+
+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 7d28c426a..d2351ba6a 100644
--- a/drivers/iommu/arm/arm-smmu/arm-smmu.c
+++ b/drivers/iommu/arm/arm-smmu/arm-smmu.c
@@ -43,6 +43,9 @@
 
 #include "arm-smmu.h"
 
+#ifdef CONFIG_ARCH_PHYTIUM
+#include <asm/machine_types.h>
+#endif
 /*
  * Apparently, some Qualcomm arm64 platforms which appear to expose their SMMU
  * global register space are still, in fact, using a hypervisor to mediate it
@@ -54,6 +57,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);
@@ -1371,6 +1375,19 @@ static struct iommu_device *arm_smmu_probe_device(struct device
*dev)
 	} else {
 		return ERR_PTR(-ENODEV);
 	}
+	#ifdef CONFIG_ARCH_PHYTIUM
+        /* ft2000+ */
+        if (typeof_ft2000plus()) {
+                int num = fwspec->num_ids;
+                for (i = 0; i < num; i++) {
+	#define FWID_READ(id) (((u16)(id) >> 3) | (((id) >> SMR_MASK_SHIFT | 0x7000)
<< SMR_MASK_SHIFT))
+                        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++) {
@@ -1460,6 +1477,13 @@ static struct iommu_group *arm_smmu_device_group(struct device
*dev)
 		if (group && smmu->s2crs[idx].group &&
 		    group != smmu->s2crs[idx].group)
 			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 d0487977a..34522f94f 100644
--- a/drivers/irqchip/irq-gic-v3-its.c
+++ b/drivers/irqchip/irq-gic-v3-its.c
@@ -37,6 +37,10 @@
 #include <asm/cputype.h>
 #include <asm/exception.h>
 
+#ifdef CONFIG_ARCH_PHYTIUM
+#include <asm/machine_types.h>
+#endif
+
 #include "irq-gic-common.h"
 
 #define ITS_FLAGS_CMDQ_NEEDS_FLUSHING		(1ULL << 0)
@@ -1696,6 +1700,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 c5d38cb32..a8cc75f62 100644
--- a/drivers/pci/quirks.c
+++ b/drivers/pci/quirks.c
@@ -4950,6 +4950,10 @@ static const struct pci_dev_acs_enabled {
 	{ PCI_VENDOR_ID_NXP, 0x8d9b, pci_quirk_nxp_rp_acs },
 	/* Zhaoxin Root/Downstream Ports */
 	{ PCI_VENDOR_ID_ZHAOXIN, PCI_ANY_ID, pci_quirk_zhaoxin_pcie_ports_acs },
+        /* 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 },	
 	{ 0 }
 };
 
-- 
2.27.0