Commit 1f4fd624 authored by Yong Wu's avatar Yong Wu Committed by Joerg Roedel
Browse files

iommu/mediatek: Move the tlb_sync into tlb_flush



Right now, the tlb_add_flush_nosync and tlb_sync always appear together.
we merge the two functions into one(also move the tlb_lock into the new
function). No functional change.

Signed-off-by: default avatarChao Hao <chao.hao@mediatek.com>
Signed-off-by: default avatarYong Wu <yong.wu@mediatek.com>
Signed-off-by: default avatarJoerg Roedel <jroedel@suse.de>
parent 67caf7e2
Loading
Loading
Loading
Loading
+10 −35
Original line number Diff line number Diff line
@@ -173,12 +173,16 @@ static void mtk_iommu_tlb_flush_all(void *cookie)
	}
}

static void mtk_iommu_tlb_add_flush_nosync(unsigned long iova, size_t size,
static void mtk_iommu_tlb_flush_range_sync(unsigned long iova, size_t size,
					   size_t granule, void *cookie)
{
	struct mtk_iommu_data *data = cookie;
	unsigned long flags;
	int ret;
	u32 tmp;

	for_each_m4u(data) {
		spin_lock_irqsave(&data->tlb_lock, flags);
		writel_relaxed(F_INVLD_EN1 | F_INVLD_EN0,
			       data->base + REG_MMU_INV_SEL);

@@ -187,21 +191,8 @@ static void mtk_iommu_tlb_add_flush_nosync(unsigned long iova, size_t size,
			       data->base + REG_MMU_INVLD_END_A);
		writel_relaxed(F_MMU_INV_RANGE,
			       data->base + REG_MMU_INVALIDATE);
		data->tlb_flush_active = true;
	}
}

static void mtk_iommu_tlb_sync(void *cookie)
{
	struct mtk_iommu_data *data = cookie;
	int ret;
	u32 tmp;

	for_each_m4u(data) {
		/* Avoid timing out if there's nothing to wait for */
		if (!data->tlb_flush_active)
			return;

		/* tlb sync */
		ret = readl_poll_timeout_atomic(data->base + REG_MMU_CPE_DONE,
						tmp, tmp != 0, 10, 100000);
		if (ret) {
@@ -211,21 +202,9 @@ static void mtk_iommu_tlb_sync(void *cookie)
		}
		/* Clear the CPE status */
		writel_relaxed(0, data->base + REG_MMU_CPE_DONE);
		data->tlb_flush_active = false;
	}
}

static void mtk_iommu_tlb_flush_walk(unsigned long iova, size_t size,
				     size_t granule, void *cookie)
{
	struct mtk_iommu_data *data = cookie;
	unsigned long flags;

	spin_lock_irqsave(&data->tlb_lock, flags);
	mtk_iommu_tlb_add_flush_nosync(iova, size, granule, cookie);
	mtk_iommu_tlb_sync(cookie);
		spin_unlock_irqrestore(&data->tlb_lock, flags);
	}
}

static void mtk_iommu_tlb_flush_page_nosync(struct iommu_iotlb_gather *gather,
					    unsigned long iova, size_t granule,
@@ -239,8 +218,8 @@ static void mtk_iommu_tlb_flush_page_nosync(struct iommu_iotlb_gather *gather,

static const struct iommu_flush_ops mtk_iommu_flush_ops = {
	.tlb_flush_all = mtk_iommu_tlb_flush_all,
	.tlb_flush_walk = mtk_iommu_tlb_flush_walk,
	.tlb_flush_leaf = mtk_iommu_tlb_flush_walk,
	.tlb_flush_walk = mtk_iommu_tlb_flush_range_sync,
	.tlb_flush_leaf = mtk_iommu_tlb_flush_range_sync,
	.tlb_add_page = mtk_iommu_tlb_flush_page_nosync,
};

@@ -455,16 +434,12 @@ static void mtk_iommu_iotlb_sync(struct iommu_domain *domain,
{
	struct mtk_iommu_data *data = mtk_iommu_get_m4u_data();
	size_t length = gather->end - gather->start;
	unsigned long flags;

	if (gather->start == ULONG_MAX)
		return;

	spin_lock_irqsave(&data->tlb_lock, flags);
	mtk_iommu_tlb_add_flush_nosync(gather->start, length, gather->pgsize,
	mtk_iommu_tlb_flush_range_sync(gather->start, length, gather->pgsize,
				       data);
	mtk_iommu_tlb_sync(data);
	spin_unlock_irqrestore(&data->tlb_lock, flags);
}

static phys_addr_t mtk_iommu_iova_to_phys(struct iommu_domain *domain,
+0 −1
Original line number Diff line number Diff line
@@ -57,7 +57,6 @@ struct mtk_iommu_data {
	struct mtk_iommu_domain		*m4u_dom;
	struct iommu_group		*m4u_group;
	bool                            enable_4GB;
	bool				tlb_flush_active;
	spinlock_t			tlb_lock; /* lock for tlb range flush */

	struct iommu_device		iommu;