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"))