From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-12.7 required=3.0 tests=BAYES_00, HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_PATCH,MAILING_LIST_MULTI,SIGNED_OFF_BY, SPF_HELO_NONE,SPF_PASS,UNPARSEABLE_RELAY,URIBL_BLOCKED,USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 3E693C388F9 for ; Wed, 11 Nov 2020 12:41:57 +0000 (UTC) Received: from hemlock.osuosl.org (smtp2.osuosl.org [140.211.166.133]) (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 CB15A206F1 for ; Wed, 11 Nov 2020 12:41:56 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org CB15A206F1 Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=mediatek.com Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=iommu-bounces@lists.linux-foundation.org Received: from localhost (localhost [127.0.0.1]) by hemlock.osuosl.org (Postfix) with ESMTP id 30E7D87564; Wed, 11 Nov 2020 12:41:56 +0000 (UTC) X-Virus-Scanned: amavisd-new at osuosl.org Received: from hemlock.osuosl.org ([127.0.0.1]) by localhost (.osuosl.org [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id ScIFsq9hZesg; Wed, 11 Nov 2020 12:41:55 +0000 (UTC) Received: from lists.linuxfoundation.org (lf-lists.osuosl.org [140.211.9.56]) by hemlock.osuosl.org (Postfix) with ESMTP id 758AC87555; Wed, 11 Nov 2020 12:41:55 +0000 (UTC) Received: from lf-lists.osuosl.org (localhost [127.0.0.1]) by lists.linuxfoundation.org (Postfix) with ESMTP id 6F1EFC088B; Wed, 11 Nov 2020 12:41:55 +0000 (UTC) Received: from hemlock.osuosl.org (smtp2.osuosl.org [140.211.166.133]) by lists.linuxfoundation.org (Postfix) with ESMTP id 768A5C016F for ; Wed, 11 Nov 2020 12:41:54 +0000 (UTC) Received: from localhost (localhost [127.0.0.1]) by hemlock.osuosl.org (Postfix) with ESMTP id 7241887559 for ; Wed, 11 Nov 2020 12:41:54 +0000 (UTC) X-Virus-Scanned: amavisd-new at osuosl.org Received: from hemlock.osuosl.org ([127.0.0.1]) by localhost (.osuosl.org [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id 1sygxqq9sB0a for ; Wed, 11 Nov 2020 12:41:53 +0000 (UTC) X-Greylist: domain auto-whitelisted by SQLgrey-1.7.6 Received: from mailgw02.mediatek.com (unknown [210.61.82.184]) by hemlock.osuosl.org (Postfix) with ESMTP id 78E7287555 for ; Wed, 11 Nov 2020 12:41:53 +0000 (UTC) X-UUID: e0e83c3fcd1847118c204756a062f229-20201111 X-UUID: e0e83c3fcd1847118c204756a062f229-20201111 Received: from mtkcas10.mediatek.inc [(172.21.101.39)] by mailgw02.mediatek.com (envelope-from ) (Cellopoint E-mail Firewall v4.1.14 Build 0819 with TLSv1.2 ECDHE-RSA-AES256-SHA384 256/256) with ESMTP id 1912702079; Wed, 11 Nov 2020 20: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 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 , 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 X-BeenThere: iommu@lists.linux-foundation.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: Development issues for Linux IOMMU support List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit Errors-To: iommu-bounces@lists.linux-foundation.org Sender: "iommu" 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]; }; -- 2.18.0 _______________________________________________ iommu mailing list iommu@lists.linux-foundation.org https://lists.linuxfoundation.org/mailman/listinfo/iommu