From 30eb2be25b63231f279c984fca8d2b76b59ff15d Mon Sep 17 00:00:00 2001 From: Herman Chen Date: Mon, 6 Dec 2021 10:35:36 +0800 Subject: [PATCH] iommu/rockchip: Add shootdown_entire prop Replace IOMMU_TLB_SHOT_ENTIRE by shootdown_entire defined in iommu DT node for clean IOMMU framework code and more convenient for masters. The master should call iommu_flush_iotlb_all to zap cache manually. Signed-off-by: Simon Xue Signed-off-by: Herman Chen Change-Id: I5feab72fa12782d0715ad84a98cbd96a88bcd598 --- drivers/gpu/drm/rockchip/rockchip_drm_gem.c | 2 ++ drivers/iommu/rockchip-iommu.c | 13 +++++++++++-- 2 files changed, 13 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_gem.c b/drivers/gpu/drm/rockchip/rockchip_drm_gem.c index 9a55a12cfbf3..42fb4cff7443 100644 --- a/drivers/gpu/drm/rockchip/rockchip_drm_gem.c +++ b/drivers/gpu/drm/rockchip/rockchip_drm_gem.c @@ -58,6 +58,8 @@ static int rockchip_gem_iommu_map(struct rockchip_gem_object *rk_obj) goto err_remove_node; } + iommu_flush_iotlb_all(private->domain); + rk_obj->size = ret; return 0; diff --git a/drivers/iommu/rockchip-iommu.c b/drivers/iommu/rockchip-iommu.c index a5e318c9cfbe..9f1e801bd60a 100644 --- a/drivers/iommu/rockchip-iommu.c +++ b/drivers/iommu/rockchip-iommu.c @@ -117,6 +117,7 @@ struct rk_iommu_domain { dma_addr_t dt_dma; spinlock_t iommus_lock; /* lock for iommus list */ spinlock_t dt_lock; /* lock for modifying page directory table */ + bool shootdown_entire; struct iommu_domain domain; }; @@ -141,6 +142,7 @@ struct rk_iommu { struct iommu_domain *domain; /* domain to which iommu is attached */ struct iommu_group *group; u32 version; + bool shootdown_entire; }; struct rk_iommudata { @@ -989,7 +991,9 @@ static int rk_iommu_map_iova(struct rk_iommu_domain *rk_domain, u32 *pte_addr, * We only zap the first and last iova, since only they could have * dte or pte shared with an existing mapping. */ - rk_iommu_zap_iova_first_last(rk_domain, iova, size); + /* Do not zap tlb cache line if shootdown_entire set */ + if (!rk_domain->shootdown_entire) + rk_iommu_zap_iova_first_last(rk_domain, iova, size); return 0; unwind: @@ -1034,7 +1038,9 @@ static int rk_iommu_map_iova_v2(struct rk_iommu_domain *rk_domain, u32 *pte_addr * We only zap the first and last iova, since only they could have * dte or pte shared with an existing mapping. */ - rk_iommu_zap_iova_first_last(rk_domain, iova, size); + /* Do not zap tlb cache line if shootdown_entire set */ + if (!rk_domain->shootdown_entire) + rk_iommu_zap_iova_first_last(rk_domain, iova, size); return 0; unwind: @@ -1394,6 +1400,7 @@ static int rk_iommu_attach_device(struct iommu_domain *domain, list_add_tail(&iommu->node, &rk_domain->iommus); spin_unlock_irqrestore(&rk_domain->iommus_lock, flags); + rk_domain->shootdown_entire = iommu->shootdown_entire; ret = pm_runtime_get_if_in_use(iommu->dev); if (!ret || WARN_ON_ONCE(ret < 0)) return 0; @@ -1732,6 +1739,8 @@ static int rk_iommu_probe(struct platform_device *pdev) "rockchip,skip-mmu-read"); iommu->dlr_disable = device_property_read_bool(dev, "rockchip,disable-device-link-resume"); + iommu->shootdown_entire = device_property_read_bool(dev, + "rockchip,shootdown-entire"); if (of_machine_is_compatible("rockchip,rv1126") || of_machine_is_compatible("rockchip,rv1109"))