From patchwork Wed Nov 11 12:38:35 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: =?utf-8?b?WW9uZyBXdSAo5ZC05YuHKQ==?= X-Patchwork-Id: 11897613 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 9DB4714C0 for ; Wed, 11 Nov 2020 12:49:49 +0000 (UTC) Received: from merlin.infradead.org (merlin.infradead.org [205.233.59.134]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 553B9206F1 for ; Wed, 11 Nov 2020 12:49:49 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=lists.infradead.org header.i=@lists.infradead.org header.b="S564pAqm"; dkim=fail reason="signature verification failed" (1024-bit key) header.d=mediatek.com header.i=@mediatek.com header.b="D2xs1r0e" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 553B9206F1 Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=mediatek.com Authentication-Results: mail.kernel.org; spf=none smtp.mailfrom=linux-mediatek-bounces+patchwork-linux-mediatek=patchwork.kernel.org@lists.infradead.org DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=merlin.20170209; h=Sender:Content-Transfer-Encoding: Content-Type:Cc:List-Subscribe:List-Help:List-Post:List-Archive: List-Unsubscribe:List-Id:MIME-Version:References:In-Reply-To:Message-ID:Date: Subject:To:From:Reply-To:Content-ID:Content-Description:Resent-Date: Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID:List-Owner; bh=RWm2zzu3t5xuteSKogQFqOYibJQrCSLEmKHHxfgY2zg=; b=S564pAqm4pskR7yb6CGqX66lj V9wTvrLQ/3IKdTqZ3HoZUEfFz/VlYJAUd7TCrF5g6TxVsgF/dp5A2BK3+j4wNNKV2pkimcrZh1ilo ogpqb0KRIJ6XZ0NLVk/H967L7fiR87bsyQMCMvdKEcevt6tG9u3dIrYmMNNurgZgtPTdb3tliLoWo Q7d94cec8L0bDoWtPlxhzx+mXeR2WlUM1LAaw1DUA7dSG6GC1Ya9K4h4/CUwlzN94tu7KiBmU5Fc2 ilV754ibdn1oW+Jdz/LR+00/nBDta6EaNo+FxjHUlyMfqsC8gAyQ2CAh5enfcfvqfPLvFVO1Axs6B dESU7qwRA==; Received: from localhost ([::1] helo=merlin.infradead.org) by merlin.infradead.org with esmtp (Exim 4.92.3 #3 (Red Hat Linux)) id 1kcpZK-0003hX-RA; Wed, 11 Nov 2020 12:49:46 +0000 Received: from mailgw02.mediatek.com ([216.200.240.185]) by merlin.infradead.org with esmtps (Exim 4.92.3 #3 (Red Hat Linux)) id 1kcpYm-0003QO-7f; Wed, 11 Nov 2020 12:49:13 +0000 X-UUID: 4b0c6c81ff3b4d32b38041bb6543a705-20201111 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=mediatek.com; s=dk; h=Content-Transfer-Encoding:Content-Type:MIME-Version:References:In-Reply-To:Message-ID:Date:Subject:CC:To:From; bh=jtKs+zNJBVquqsUub9eFHt2GpZNydL4Uo5jy9gWDFfo=; b=D2xs1r0eytBNPesNEwUq+ZfdfDZwuaH+iHA/zRZIWjCW5tEupjv/Ja1uqc6HkdGPWMN1QDx50taivuuZgMyhLnMgEMvdKA1WhP8IKZwCkDz7UQA6fSoplWGFpK7hj915lSRcMRkHnTj04LehAUar65jQ1d2hqrHyFwEEH1Q7GXQ=; X-UUID: 4b0c6c81ff3b4d32b38041bb6543a705-20201111 Received: from mtkcas66.mediatek.inc [(172.29.193.44)] by mailgw02.mediatek.com (envelope-from ) (musrelay.mediatek.com ESMTP with TLSv1.2 ECDHE-RSA-AES256-SHA384 256/256) with ESMTP id 1746617937; Wed, 11 Nov 2020 04:49:07 -0800 Received: from MTKMBS07N2.mediatek.inc (172.21.101.141) by MTKMBS62DR.mediatek.inc (172.29.94.18) with Microsoft SMTP Server (TLS) id 15.0.1497.2; Wed, 11 Nov 2020 04:41:50 -0800 Received: from mtkcas07.mediatek.inc (172.21.101.84) by mtkmbs07n2.mediatek.inc (172.21.101.141) with Microsoft SMTP Server (TLS) id 15.0.1497.2; Wed, 11 Nov 2020 20:41:47 +0800 Received: from localhost.localdomain (10.17.3.153) by mtkcas07.mediatek.inc (172.21.101.73) with Microsoft SMTP Server id 15.0.1497.2 via Frontend Transport; Wed, 11 Nov 2020 20:41:46 +0800 From: Yong Wu To: Joerg Roedel , Matthias Brugger , Rob Herring , Will Deacon , Robin Murphy Subject: [PATCH v4 21/24] iommu/mediatek: Add support for multi domain Date: Wed, 11 Nov 2020 20:38:35 +0800 Message-ID: <20201111123838.15682-22-yong.wu@mediatek.com> X-Mailer: git-send-email 2.18.0 In-Reply-To: <20201111123838.15682-1-yong.wu@mediatek.com> References: <20201111123838.15682-1-yong.wu@mediatek.com> MIME-Version: 1.0 X-MTK: N X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20201111_074912_519503_D45ECDB8 X-CRM114-Status: GOOD ( 24.76 ) X-Spam-Score: -0.2 (/) X-Spam-Report: SpamAssassin version 3.4.4 on merlin.infradead.org summary: Content analysis details: (-0.2 points) pts rule name description ---- ---------------------- -------------------------------------------------- -0.0 SPF_PASS SPF: sender matches SPF record 0.0 SPF_HELO_NONE SPF: HELO does not publish an SPF Record 0.0 MIME_BASE64_TEXT RAW: Message text disguised using base64 encoding 0.1 DKIM_SIGNED Message has a DKIM or DK signature, not necessarily valid -0.1 DKIM_VALID Message has at least one valid DKIM or DK signature -0.1 DKIM_VALID_AU Message has a valid DKIM or DK signature from author's domain -0.1 DKIM_VALID_EF Message has a valid DKIM or DK signature from envelope-from domain 0.0 UNPARSEABLE_RELAY Informational: message has unparseable relay lines X-BeenThere: linux-mediatek@lists.infradead.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: youlin.pei@mediatek.com, devicetree@vger.kernel.org, Nicolas Boichat , srv_heupstream@mediatek.com, chao.hao@mediatek.com, kernel-team@android.com, linux-kernel@vger.kernel.org, Evan Green , yong.wu@mediatek.com, Tomasz Figa , iommu@lists.linux-foundation.org, linux-mediatek@lists.infradead.org, Krzysztof Kozlowski , anan.sun@mediatek.com, Greg Kroah-Hartman , linux-arm-kernel@lists.infradead.org Sender: "Linux-mediatek" Errors-To: linux-mediatek-bounces+patchwork-linux-mediatek=patchwork.kernel.org@lists.infradead.org Some HW IP(ex: CCU) require the special iova range. That means the iova got from dma_alloc_attrs for that devices must locate in his special range. In this patch, we allocate a special iova_range for each a special requirement and create each a iommu domain for each a iova_range. meanwhile we still use one pagetable which support 16GB iova. After this patch, If the iova range of a master is over 4G, the master should: a) Declare its special dma_ranges in its dtsi node. For example, If we preassign the iova 4G-8G for vcodec, then the vcodec dtsi node should add this: /* * iova start at 0x1_0000_0000, pa still start at 0x4000_0000 * size is 0x1_0000_0000. */ dma-ranges = <0x1 0x0 0x0 0x40000000 0x1 0x0>; /* 4G ~ 8G */ Note: we don't have a actual bus concept here. the master doesn't have its special parent node, thus this dma-ranges can only be put in the master's node. b) Update the dma_mask: dma_set_mask_and_coherent(dev, DMA_BIT_MASK(33)); Signed-off-by: Yong Wu --- drivers/iommu/mtk_iommu.c | 47 +++++++++++++++++++++++++++++++-------- drivers/iommu/mtk_iommu.h | 3 ++- 2 files changed, 40 insertions(+), 10 deletions(-) diff --git a/drivers/iommu/mtk_iommu.c b/drivers/iommu/mtk_iommu.c index fdf08e2d9ed5..d9a66b2d55e9 100644 --- a/drivers/iommu/mtk_iommu.c +++ b/drivers/iommu/mtk_iommu.c @@ -354,6 +354,14 @@ static int mtk_iommu_domain_finalise(struct mtk_iommu_domain *dom) { struct mtk_iommu_data *data = mtk_iommu_get_m4u_data(); + /* Use the exist domain as there is only one m4u pgtable here. */ + if (data->m4u_dom) { + dom->iop = data->m4u_dom->iop; + dom->cfg = data->m4u_dom->cfg; + dom->domain.pgsize_bitmap = data->m4u_dom->cfg.pgsize_bitmap; + return 0; + } + dom->cfg = (struct io_pgtable_cfg) { .quirks = IO_PGTABLE_QUIRK_ARM_NS | IO_PGTABLE_QUIRK_NO_PERMS | @@ -379,6 +387,8 @@ static int mtk_iommu_domain_finalise(struct mtk_iommu_domain *dom) static struct iommu_domain *mtk_iommu_domain_alloc(unsigned type) { + struct mtk_iommu_data *data = mtk_iommu_get_m4u_data(); + const struct mtk_iommu_iova_region *region; struct mtk_iommu_domain *dom; if (type != IOMMU_DOMAIN_DMA) @@ -394,8 +404,9 @@ static struct iommu_domain *mtk_iommu_domain_alloc(unsigned type) if (mtk_iommu_domain_finalise(dom)) goto put_dma_cookie; - dom->domain.geometry.aperture_start = 0; - dom->domain.geometry.aperture_end = DMA_BIT_MASK(32); + region = data->plat_data->iova_region + data->cur_domid; + dom->domain.geometry.aperture_start = region->iova_base; + dom->domain.geometry.aperture_end = region->iova_base + region->size - 1; dom->domain.geometry.force_aperture = true; return &dom->domain; @@ -539,19 +550,31 @@ static void mtk_iommu_release_device(struct device *dev) static struct iommu_group *mtk_iommu_device_group(struct device *dev) { struct mtk_iommu_data *data = mtk_iommu_get_m4u_data(); + struct iommu_fwspec *fwspec = dev_iommu_fwspec_get(dev); + struct iommu_group *group; + int domid; if (!data) return ERR_PTR(-ENODEV); - /* All the client devices are in the same m4u iommu-group */ - if (!data->m4u_group) { - data->m4u_group = iommu_group_alloc(); - if (IS_ERR(data->m4u_group)) + domid = MTK_M4U_TO_DOM(fwspec->ids[0]); + if (domid >= data->plat_data->iova_region_nr) { + dev_err(dev, "iommu domain id(%d/%d) is error.\n", domid, + data->plat_data->iova_region_nr); + return ERR_PTR(-EINVAL); + } + + group = data->m4u_group[domid]; + if (!group) { + group = iommu_group_alloc(); + if (IS_ERR(group)) dev_err(dev, "Failed to allocate M4U IOMMU group\n"); + data->m4u_group[domid] = group; } else { - iommu_group_ref_get(data->m4u_group); + iommu_group_ref_get(group); } - return data->m4u_group; + data->cur_domid = domid; + return group; } static int mtk_iommu_of_xlate(struct device *dev, struct of_phandle_args *args) @@ -580,14 +603,20 @@ static void mtk_iommu_get_resv_regions(struct device *dev, struct list_head *head) { struct mtk_iommu_data *data = dev_iommu_priv_get(dev); - const struct mtk_iommu_iova_region *resv; + const struct mtk_iommu_iova_region *resv, *curdom; struct iommu_resv_region *region; int prot = IOMMU_WRITE | IOMMU_READ; unsigned int i; + curdom = data->plat_data->iova_region + data->cur_domid; for (i = 0; i < data->plat_data->iova_region_nr; i++) { resv = data->plat_data->iova_region + i; + /* Only reserve when the region is in the current domain */ + if (resv->iova_base <= curdom->iova_base || + resv->iova_base + resv->size >= curdom->iova_base + curdom->size) + continue; + region = iommu_alloc_resv_region(resv->iova_base, resv->size, prot, IOMMU_RESV_RESERVED); if (!region) diff --git a/drivers/iommu/mtk_iommu.h b/drivers/iommu/mtk_iommu.h index e867cd3aeeac..b54862307128 100644 --- a/drivers/iommu/mtk_iommu.h +++ b/drivers/iommu/mtk_iommu.h @@ -67,7 +67,7 @@ struct mtk_iommu_data { phys_addr_t protect_base; /* protect memory base */ struct mtk_iommu_suspend_reg reg; struct mtk_iommu_domain *m4u_dom; - struct iommu_group *m4u_group; + struct iommu_group *m4u_group[MTK_M4U_DOM_NR_MAX]; bool enable_4GB; spinlock_t tlb_lock; /* lock for tlb range flush */ @@ -77,6 +77,7 @@ struct mtk_iommu_data { struct dma_iommu_mapping *mapping; /* For mtk_iommu_v1.c */ + unsigned int cur_domid; struct list_head list; struct mtk_smi_larb_iommu larb_imu[MTK_LARB_NR_MAX]; };