From bdac1e68ba4fe8b08a0836c2992df1f1d59ca306 Mon Sep 17 00:00:00 2001 From: Guchun Chen Date: Tue, 13 Jun 2017 15:11:53 +0800 Subject: [PATCH] msm: smmu: add re-route calling for specified iova when mapping When calling smmu mapping, if iova is specified directly by user, not allocated dynamically in dma-mapping.c, smmu driver needs to provide support for this. This is needed in early display case. In this scenario, LK has set physical memory to display hardware for fetching, so if iova is not explicitly specified in kernel, but instead dynamically produced by "alloc_iova" in dma-mapping.c, display hardware has no chance to know this new iova, then smmu fault will happen if enabling the iommu stage-1 translation. To fix this smmu fault problem, add re-routing to the right path when iova specified by user is not 0 in smmu map function. Change-Id: I555fe7ae44464f25245d2d0a6740a2411a8624ba Signed-off-by: Guchun Chen --- drivers/gpu/drm/msm/msm_smmu.c | 28 +++++++++++++++++++++------- 1 file changed, 21 insertions(+), 7 deletions(-) diff --git a/drivers/gpu/drm/msm/msm_smmu.c b/drivers/gpu/drm/msm/msm_smmu.c index 7d0dda032c59..7673f54b7691 100644 --- a/drivers/gpu/drm/msm/msm_smmu.c +++ b/drivers/gpu/drm/msm/msm_smmu.c @@ -120,16 +120,30 @@ static int msm_smmu_map(struct msm_mmu *mmu, uint64_t iova, { struct msm_smmu *smmu = to_msm_smmu(mmu); struct msm_smmu_client *client = msm_smmu_to_client(smmu); + struct iommu_domain *domain; int ret; - if (priv) - ret = msm_dma_map_sg_lazy(client->dev, sgt->sgl, sgt->nents, - DMA_BIDIRECTIONAL, priv); - else - ret = dma_map_sg(client->dev, sgt->sgl, sgt->nents, - DMA_BIDIRECTIONAL); + if (!client || !sgt) + return -EINVAL; - return (ret != sgt->nents) ? -ENOMEM : 0; + if (iova != 0) { + if (!client->mmu_mapping || !client->mmu_mapping->domain) + return -EINVAL; + + domain = client->mmu_mapping->domain; + + return iommu_map_sg(domain, iova, sgt->sgl, + sgt->nents, flags); + } else { + if (priv) + ret = msm_dma_map_sg_lazy(client->dev, sgt->sgl, + sgt->nents, DMA_BIDIRECTIONAL, priv); + else + ret = dma_map_sg(client->dev, sgt->sgl, sgt->nents, + DMA_BIDIRECTIONAL); + + return (ret != sgt->nents) ? -ENOMEM : 0; + } } static void msm_smmu_unmap(struct msm_mmu *mmu, uint64_t iova,