From: Mao HongBo maohongbo@phytium.com.cn
phytium inclusion category: bugfix bugzilla: https://gitee.com/openeuler/kernel/issues/I41AUQ
-----------------------------------
To fix iommu issue of device access in virtualization scenario for ft2000plus and S2500.
Convert to new cputype macros naming of phytium.
Signed-off-by: Mao HongBo maohongbo@phytium.com.cn Signed-off-by: Zheng Zengkai zhengzengkai@huawei.com Reviewed-by: Hanjun Guo guohanjun@huawei.com Signed-off-by: Yang Yingliang yangyingliang@huawei.com --- arch/arm64/include/asm/cputype.h | 14 +++++-- .../arm64/include/asm/phytium_machine_types.h | 37 +++++++++++++++++++ arch/arm64/kernel/topology.c | 2 +- drivers/iommu/arm-smmu.c | 29 +++++++++++++-- drivers/irqchip/irq-gic-v3-its.c | 9 +++++ drivers/pci/quirks.c | 4 ++ drivers/usb/host/xhci-pci.c | 2 +- 7 files changed, 87 insertions(+), 10 deletions(-) create mode 100644 arch/arm64/include/asm/phytium_machine_types.h
diff --git a/arch/arm64/include/asm/cputype.h b/arch/arm64/include/asm/cputype.h index 23298b0aedaf7..aa38796121300 100644 --- a/arch/arm64/include/asm/cputype.h +++ b/arch/arm64/include/asm/cputype.h @@ -101,8 +101,11 @@ #define HISI_CPU_PART_TSV110 0xD01 #define HISI_CPU_PART_TSV200 0xD02
-#define PHYTIUM_CPU_PART_FTC662 0x662 -#define PHYTIUM_CPU_PART_FTC663 0x663 +#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 MIDR_CORTEX_A53 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_A53) #define MIDR_CORTEX_A57 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_A57) @@ -124,8 +127,11 @@ #define MIDR_NVIDIA_CARMEL MIDR_CPU_MODEL(ARM_CPU_IMP_NVIDIA, NVIDIA_CPU_PART_CARMEL) #define MIDR_HISI_TSV110 MIDR_CPU_MODEL(ARM_CPU_IMP_HISI, HISI_CPU_PART_TSV110) #define MIDR_HISI_TSV200 MIDR_CPU_MODEL(ARM_CPU_IMP_HISI, HISI_CPU_PART_TSV200) -#define MIDR_PHYTIUM_FT2000PLUS MIDR_CPU_MODEL(ARM_CPU_IMP_PHYTIUM, PHYTIUM_CPU_PART_FTC662) -#define MIDR_PHYTIUM_FT2500 MIDR_CPU_MODEL(ARM_CPU_IMP_PHYTIUM, PHYTIUM_CPU_PART_FTC663) +#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)
#ifndef __ASSEMBLY__
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 0000000000000..fb791988f0cee --- /dev/null +++ b/arch/arm64/include/asm/phytium_machine_types.h @@ -0,0 +1,37 @@ +/* + * Authors: Wang Yinfeng wangyinfenng@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, see http://www.gnu.org/licenses/. + */ + +#ifndef __PHYTIUM_MACHINE_TYPES_H__ +#define __PHYTIUM_MACHINE_TYPES_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/arch/arm64/kernel/topology.c b/arch/arm64/kernel/topology.c index 02d3e688d657d..2646695e2f2a4 100644 --- a/arch/arm64/kernel/topology.c +++ b/arch/arm64/kernel/topology.c @@ -291,7 +291,7 @@ void store_cpu_topology(unsigned int cpuid) cpuid_topo->package_id = cpu_to_node(cpuid);
/* Some PHYTIUM FT2000PLUS platform firmware has no PPTT table */ - if ((read_cpuid_id() & MIDR_CPU_MODEL_MASK) == MIDR_PHYTIUM_FT2000PLUS + if ((read_cpuid_id() & MIDR_CPU_MODEL_MASK) == MIDR_FT_2000PLUS && cpu_to_node(cpuid) == NUMA_NO_NODE) { cpuid_topo->thread_id = 0; cpuid_topo->package_id = 0; diff --git a/drivers/iommu/arm-smmu.c b/drivers/iommu/arm-smmu.c index 8a268ab82ef02..18863198bb036 100644 --- a/drivers/iommu/arm-smmu.c +++ b/drivers/iommu/arm-smmu.c @@ -56,6 +56,10 @@
#include "arm-smmu-regs.h"
+#ifdef CONFIG_ARCH_PHYTIUM +#include <asm/phytium_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 @@ -1407,6 +1411,20 @@ static int arm_smmu_add_device(struct device *dev) return -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++) { u16 sid = fwspec->ids[i]; @@ -1481,6 +1499,12 @@ 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; } @@ -1614,10 +1638,7 @@ static void arm_smmu_put_resv_regions(struct device *dev, #include <asm/cputype.h> static int phytium_smmu_def_domain_type(struct device *dev, unsigned int *type) { - u32 midr = read_cpuid_id(); - - if (((midr & MIDR_CPU_MODEL_MASK) == MIDR_PHYTIUM_FT2000PLUS) - || ((midr & MIDR_CPU_MODEL_MASK) == MIDR_PHYTIUM_FT2500)) { + if (typeof_ft2000plus() || typeof_s2500()) { *type = IOMMU_DOMAIN_IDENTITY; return 0; } diff --git a/drivers/irqchip/irq-gic-v3-its.c b/drivers/irqchip/irq-gic-v3-its.c index 1a2ecfa23fd8c..79648a2139412 100644 --- a/drivers/irqchip/irq-gic-v3-its.c +++ b/drivers/irqchip/irq-gic-v3-its.c @@ -51,6 +51,10 @@
#include "irq-gic-common.h"
+#ifdef CONFIG_ARCH_PHYTIUM +#include <asm/phytium_machine_types.h> +#endif + #define ITS_FLAGS_CMDQ_NEEDS_FLUSHING (1ULL << 0) #define ITS_FLAGS_WORKAROUND_CAVIUM_22375 (1ULL << 1) #define ITS_FLAGS_WORKAROUND_CAVIUM_23144 (1ULL << 2) @@ -1223,6 +1227,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_map_msi_msg(d->irq, msg); }
diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c index 961003c6dc807..99657b9bc82e0 100644 --- a/drivers/pci/quirks.c +++ b/drivers/pci/quirks.c @@ -4646,6 +4646,10 @@ static const struct pci_dev_acs_enabled { { PCI_VENDOR_ID_ZHAOXIN, 0x9083, pci_quirk_mf_endpoint_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 } };
diff --git a/drivers/usb/host/xhci-pci.c b/drivers/usb/host/xhci-pci.c index 886cd6fc4b640..238a32cc311c9 100644 --- a/drivers/usb/host/xhci-pci.c +++ b/drivers/usb/host/xhci-pci.c @@ -313,7 +313,7 @@ static void phytium_xhci_pci_workaround(struct pci_dev *dev) u32 midr = read_cpuid_id();
/* Firmware bug, DMA mask is not reported by the firmware */ - if ((midr & MIDR_CPU_MODEL_MASK) == MIDR_PHYTIUM_FT2000PLUS) + if ((midr & MIDR_CPU_MODEL_MASK) == MIDR_FT_2000PLUS) dma_set_mask(&dev->dev, DMA_BIT_MASK(64)); } #else