Unverified Commit 1f393017 authored by openeuler-ci-bot's avatar openeuler-ci-bot Committed by Gitee
Browse files

!8539 v2 iommu/arm-smmu-v3: Reducing the CMD_SYNC times

parents 12e18800 2da3f687
Loading
Loading
Loading
Loading
+52 −5
Original line number Diff line number Diff line
@@ -2309,6 +2309,14 @@ static void arm_smmu_tlb_inv_page_nosync(struct iommu_iotlb_gather *gather,
static void arm_smmu_tlb_inv_walk(unsigned long iova, size_t size,
				  size_t granule, void *cookie)
{
#ifdef CONFIG_HISILICON_ERRATUM_162100602
	struct arm_smmu_domain *smmu_domain = cookie;

	if (!size && smmu_domain->smmu->options & ARM_SMMU_OPT_SYNC_BATCH) {
		arm_smmu_tlb_inv_range_domain(iova, granule, granule, true, cookie);
		return;
	}
#endif
	arm_smmu_tlb_inv_range_domain(iova, size, granule, false, cookie);
}

@@ -2951,6 +2959,9 @@ static void arm_smmu_iotlb_sync_map(struct iommu_domain *domain,
	if (!(smmu_domain->smmu->options & ARM_SMMU_OPT_SYNC_MAP))
		return;

	if (smmu_domain->smmu->options & ARM_SMMU_OPT_SYNC_BATCH)
		return;

	granule_size = 1 <<  __ffs(smmu_domain->domain.pgsize_bitmap);

	/* Add a SYNC command to sync io-pgtale to avoid errors in pgtable prefetch*/
@@ -4932,6 +4943,46 @@ static void arm_smmu_get_httu(struct arm_smmu_device *smmu, u32 reg)
			 fw_features);
}

#ifdef CONFIG_HISILICON_ERRATUM_162100602
static void hisi_smmu_check_errata(struct arm_smmu_device *smmu)
{
	u32 reg, i;

	/* IIDR */
	reg = readl_relaxed(smmu->base + ARM_SMMU_IIDR);
	if (!(FIELD_GET(IIDR_VARIANT, reg) == 0x3) ||
	    !(FIELD_GET(IIDR_REVISON, reg) == 0x2))
		return;

	smmu->options |= ARM_SMMU_OPT_SYNC_MAP;

	reg = readl_relaxed(smmu->base + ARM_SMMU_USER_CFG1);
	reg = reg & GENMASK(15, 0);
	for (i = 0; i < 8; i++) {
		unsigned long val;

		val = (reg >> 2 * i) & GENMASK(1, 0);
		switch (PAGE_SIZE) {
		case SZ_4K:
			if (!val)
				return;
			break;
		case SZ_16K:
			if (!val || val == 0x1)
				return;
			break;
		case SZ_64K:
			if (!val || val == 0x1 || val == 0x3)
				return;
			break;
		default:
			return;
		}
	}
	smmu->options |= ARM_SMMU_OPT_SYNC_BATCH;
}
#endif

static int arm_smmu_device_hw_probe(struct arm_smmu_device *smmu)
{
	u32 reg;
@@ -5163,11 +5214,7 @@ static int arm_smmu_device_hw_probe(struct arm_smmu_device *smmu)
	}

#ifdef CONFIG_HISILICON_ERRATUM_162100602
	/* IIDR */
	reg = readl_relaxed(smmu->base + ARM_SMMU_IIDR);
	if (FIELD_GET(IIDR_VARIANT, reg) == 0x3 &&
	    FIELD_GET(IIDR_REVISON, reg) == 0x2)
		smmu->options |= ARM_SMMU_OPT_SYNC_MAP;
	hisi_smmu_check_errata(smmu);
#endif

	if (arm_smmu_ops.pgsize_bitmap == -1UL)
+3 −0
Original line number Diff line number Diff line
@@ -175,6 +175,8 @@
#define ARM_SMMU_USER_CFG0		0xe00
#define ARM_SMMU_USER_MPAM_EN		(1UL << 30)

#define ARM_SMMU_USER_CFG1		0xe04

#define ARM_SMMU_IDR6			0x190
#define IDR6_LOG2NUMP			GENMASK(27, 24)
#define IDR6_LOG2NUMQ			GENMASK(19, 16)
@@ -717,6 +719,7 @@ struct arm_smmu_device {
#define ARM_SMMU_OPT_PAGE0_REGS_ONLY	(1 << 1)
#define ARM_SMMU_OPT_MSIPOLL		(1 << 2)
#define ARM_SMMU_OPT_SYNC_MAP		(1 << 3)
#define ARM_SMMU_OPT_SYNC_BATCH		(1 << 4)
	u32				options;

	union {
+4 −0
Original line number Diff line number Diff line
@@ -364,6 +364,10 @@ static int __arm_lpae_map(struct arm_lpae_io_pgtable *data, unsigned long iova,
		pte = arm_lpae_install_table(cptep, ptep, 0, data);
		if (pte)
			__arm_lpae_free_pages(cptep, tblsz, cfg);
#ifdef CONFIG_HISILICON_ERRATUM_162100602
		if (lvl <= 2)
			io_pgtable_tlb_flush_walk(&data->iop, iova, 0, ARM_LPAE_GRANULE(data));
#endif
	} else if (!cfg->coherent_walk && !(pte & ARM_LPAE_PTE_SW_SYNC)) {
		__arm_lpae_sync_pte(ptep, cfg);
	}