From: Yong Wu <yong.wu@mediatek.com>
To: Joerg Roedel <joro@8bytes.org>,
Matthias Brugger <matthias.bgg@gmail.com>,
Rob Herring <robh+dt@kernel.org>, Will Deacon <will@kernel.org>,
Robin Murphy <robin.murphy@arm.com>
Cc: Krzysztof Kozlowski <krzk@kernel.org>,
Evan Green <evgreen@chromium.org>, Tomasz Figa <tfiga@google.com>,
<linux-mediatek@lists.infradead.org>,
<srv_heupstream@mediatek.com>, <devicetree@vger.kernel.org>,
<linux-kernel@vger.kernel.org>,
<linux-arm-kernel@lists.infradead.org>,
<iommu@lists.linux-foundation.org>, <yong.wu@mediatek.com>,
<youlin.pei@mediatek.com>,
Nicolas Boichat <drinkcat@chromium.org>, <anan.sun@mediatek.com>,
<chao.hao@mediatek.com>
Subject: [PATCH v5 24/27] iommu/mediatek: Add support for multi domain
Date: Wed, 9 Dec 2020 16:00:59 +0800 [thread overview]
Message-ID: <20201209080102.26626-25-yong.wu@mediatek.com> (raw)
In-Reply-To: <20201209080102.26626-1-yong.wu@mediatek.com>
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 <yong.wu@mediatek.com>
---
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 ed771133643d..160690d56bd2 100644
--- a/drivers/iommu/mtk_iommu.c
+++ b/drivers/iommu/mtk_iommu.c
@@ -355,6 +355,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 |
@@ -380,6 +388,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)
@@ -395,8 +405,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;
@@ -548,19 +559,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)
@@ -589,14 +612,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
next prev parent reply other threads:[~2020-12-09 8:08 UTC|newest]
Thread overview: 56+ messages / expand[flat|nested] mbox.gz Atom feed top
2020-12-09 8:00 [PATCH v5 00/27] MT8192 IOMMU support Yong Wu
2020-12-09 8:00 ` [PATCH v5 01/27] dt-bindings: iommu: mediatek: Convert IOMMU to DT schema Yong Wu
2020-12-09 8:00 ` [PATCH v5 02/27] dt-bindings: memory: mediatek: Add a common larb-port header file Yong Wu
2020-12-09 8:00 ` [PATCH v5 03/27] dt-bindings: memory: mediatek: Extend LARB_NR_MAX to 32 Yong Wu
2020-12-09 8:00 ` [PATCH v5 04/27] dt-bindings: memory: mediatek: Add domain definition Yong Wu
2020-12-23 8:15 ` Tomasz Figa
2020-12-24 11:26 ` Yong Wu
2021-01-13 5:22 ` Tomasz Figa
2020-12-09 8:00 ` [PATCH v5 05/27] dt-bindings: memory: mediatek: Rename header guard for SMI header file Yong Wu
2020-12-09 12:12 ` Krzysztof Kozlowski
2020-12-11 3:26 ` Rob Herring
2020-12-09 8:00 ` [PATCH v5 06/27] dt-bindings: mediatek: Add binding for mt8192 IOMMU Yong Wu
2020-12-09 12:13 ` Krzysztof Kozlowski
2020-12-23 8:18 ` Tomasz Figa
2020-12-24 11:35 ` Yong Wu
2021-01-13 5:30 ` Tomasz Figa
2021-01-13 6:45 ` Yong Wu
2021-01-20 4:15 ` Tomasz Figa
2021-01-20 7:07 ` Yong Wu
2021-01-25 4:18 ` Tomasz Figa
2021-01-25 7:33 ` Yong Wu
[not found] ` <CAAFQd5A6rAL5iLt0iSDxNPQq5TgZ9=ZJQSkGG3GKwv+FPk9p3g@mail.gmail.com>
2021-02-01 5:36 ` Yong Wu
2021-02-01 10:44 ` Robin Murphy
2021-02-09 11:05 ` Tomasz Figa
2020-12-09 8:00 ` [PATCH v5 07/27] iommu/mediatek: Use the common mtk-smi-larb-port.h Yong Wu
2020-12-09 8:00 ` [PATCH v5 08/27] iommu/io-pgtable-arm-v7s: Use ias to check the valid iova in unmap Yong Wu
2020-12-09 8:00 ` [PATCH v5 09/27] iommu/io-pgtable-arm-v7s: Extend PA34 for MediaTek Yong Wu
2020-12-23 8:20 ` Tomasz Figa
2020-12-29 11:17 ` Yong Wu
2020-12-09 8:00 ` [PATCH v5 10/27] iommu/io-pgtable-arm-v7s: Clarify LVL_SHIFT/BITS macro Yong Wu
2020-12-09 8:00 ` [PATCH v5 11/27] iommu/io-pgtable-arm-v7s: Add cfg as a param in some macros Yong Wu
2020-12-09 8:00 ` [PATCH v5 12/27] iommu/io-pgtable-arm-v7s: Quad lvl1 pgtable for MediaTek Yong Wu
2020-12-09 8:00 ` [PATCH v5 13/27] iommu/mediatek: Add a flag for iova_34 bit case Yong Wu
2020-12-09 8:00 ` [PATCH v5 14/27] iommu/mediatek: Move hw_init into attach_device Yong Wu
2020-12-09 8:00 ` [PATCH v5 15/27] iommu/mediatek: Add fail handle for sysfs_add and device_register Yong Wu
2020-12-23 8:25 ` Tomasz Figa
2020-12-29 11:00 ` Yong Wu
2020-12-09 8:00 ` [PATCH v5 16/27] iommu/mediatek: Add device link for smi-common and m4u Yong Wu
2020-12-23 8:29 ` Tomasz Figa
2020-12-29 11:25 ` Yong Wu
2020-12-09 8:00 ` [PATCH v5 17/27] iommu/mediatek: Add pm runtime callback Yong Wu
2020-12-23 8:32 ` Tomasz Figa
2020-12-29 11:06 ` Yong Wu
2020-12-09 8:00 ` [PATCH v5 18/27] iommu/mediatek: Add power-domain operation Yong Wu
2020-12-23 8:36 ` Tomasz Figa
2020-12-29 11:06 ` Yong Wu
2021-01-08 9:54 ` Tomasz Figa
2020-12-09 8:00 ` [PATCH v5 19/27] iommu/mediatek: Add iova reserved function Yong Wu
2020-12-09 8:00 ` [PATCH v5 20/27] iommu/mediatek: Add single domain Yong Wu
2020-12-09 8:00 ` [PATCH v5 21/27] iommu/mediatek: Support master use iova over 32bit Yong Wu
2020-12-09 8:00 ` [PATCH v5 22/27] iommu/mediatek: Support up to 34bit iova in tlb flush Yong Wu
2020-12-09 8:00 ` [PATCH v5 23/27] iommu/mediatek: Support report iova 34bit translation fault in ISR Yong Wu
2020-12-09 8:00 ` Yong Wu [this message]
2020-12-09 8:01 ` [PATCH v5 25/27] iommu/mediatek: Adjust the structure Yong Wu
2020-12-09 8:01 ` [PATCH v5 26/27] iommu/mediatek: Add mt8192 support Yong Wu
2020-12-09 8:01 ` [PATCH v5 27/27] MAINTAINERS: Add entry for MediaTek IOMMU Yong Wu
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20201209080102.26626-25-yong.wu@mediatek.com \
--to=yong.wu@mediatek.com \
--cc=anan.sun@mediatek.com \
--cc=chao.hao@mediatek.com \
--cc=devicetree@vger.kernel.org \
--cc=drinkcat@chromium.org \
--cc=evgreen@chromium.org \
--cc=iommu@lists.linux-foundation.org \
--cc=joro@8bytes.org \
--cc=krzk@kernel.org \
--cc=linux-arm-kernel@lists.infradead.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-mediatek@lists.infradead.org \
--cc=matthias.bgg@gmail.com \
--cc=robh+dt@kernel.org \
--cc=robin.murphy@arm.com \
--cc=srv_heupstream@mediatek.com \
--cc=tfiga@google.com \
--cc=will@kernel.org \
--cc=youlin.pei@mediatek.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).