| From f10a5c03b4eef5d769a32638f6e5e4d41d023bb3 Mon Sep 17 00:00:00 2001 |
| From: Yong Wu <yong.wu@mediatek.com> |
| Date: Fri, 12 Nov 2021 18:54:59 +0800 |
| Subject: [PATCH] FROMGIT: iommu/mediatek: Add device_link between the consumer |
| and the larb devices |
| |
| MediaTek IOMMU-SMI diagram is like below. all the consumer connect with |
| smi-larb, then connect with smi-common. |
| |
| M4U |
| | |
| smi-common |
| | |
| ------------- |
| | | ... |
| | | |
| larb1 larb2 |
| | | |
| vdec venc |
| |
| When the consumer works, it should enable the smi-larb's power which |
| also need enable the smi-common's power firstly. |
| |
| Thus, First of all, use the device link connect the consumer and the |
| smi-larbs. then add device link between the smi-larb and smi-common. |
| |
| This patch adds device_link between the consumer and the larbs. |
| |
| When device_link_add, I add the flag DL_FLAG_STATELESS to avoid calling |
| pm_runtime_xx to keep the original status of clocks. It can avoid two |
| issues: |
| 1) Display HW show fastlogo abnormally reported in [1]. At the beggining, |
| all the clocks are enabled before entering kernel, but the clocks for |
| display HW(always in larb0) will be gated after clk_enable and clk_disable |
| called from device_link_add(->pm_runtime_resume) and rpm_idle. The clock |
| operation happened before display driver probe. At that time, the display |
| HW will be abnormal. |
| |
| 2) A deadlock issue reported in [2]. Use DL_FLAG_STATELESS to skip |
| pm_runtime_xx to avoid the deadlock. |
| |
| Corresponding, DL_FLAG_AUTOREMOVE_CONSUMER can't be added, then |
| device_link_removed should be added explicitly. |
| |
| Meanwhile, Currently we don't have a device connect with 2 larbs at the |
| same time. Disallow this case, print the error log. |
| |
| [1] https://lore.kernel.org/linux-mediatek/1564213888.22908.4.camel@mhfsdcap03/ |
| [2] https://lore.kernel.org/patchwork/patch/1086569/ |
| |
| Suggested-by: Tomasz Figa <tfiga@chromium.org> |
| Signed-off-by: Yong Wu <yong.wu@mediatek.com> |
| Tested-by: Frank Wunderlich <frank-w@public-files.de> # BPI-R2/MT7623 |
| Acked-by: Joerg Roedel <jroedel@suse.de> |
| Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com> |
| (cherry picked from commit e78e915dd3764a0369f1247c269f8fec566589d1 |
| https://git.linuxtv.org/hverkuil/media_tree.git for-v5.18g) |
| |
| BUG=b:126008328 |
| TEST=emerge-corsola sys-kernel/chromeos-kernel-5_15 succeeds |
| |
| Signed-off-by: Yong Wu <yong.wu@mediatek.com> |
| Change-Id: I32fe040f631ff37dbdd0d06ece90d05cbd909138 |
| Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/kernel/+/3455583 |
| Reviewed-by: Hsin-Yi Wang <hsinyi@chromium.org> |
| Commit-Queue: Hsin-Yi Wang <hsinyi@chromium.org> |
| Tested-by: Hsin-Yi Wang <hsinyi@chromium.org> |
| --- |
| drivers/iommu/mtk_iommu.c | 10 +++++++++- |
| drivers/iommu/mtk_iommu_v1.c | 11 ++++++++++- |
| 2 files changed, 19 insertions(+), 2 deletions(-) |
| |
| diff --git a/drivers/iommu/mtk_iommu.c b/drivers/iommu/mtk_iommu.c |
| index 7d07135b6d2b..5e4ddd22f12d 100644 |
| --- a/drivers/iommu/mtk_iommu.c |
| +++ b/drivers/iommu/mtk_iommu.c |
| @@ -564,7 +564,7 @@ static struct iommu_device *mtk_iommu_probe_device(struct device *dev) |
| struct mtk_iommu_data *data; |
| struct device_link *link; |
| struct device *larbdev; |
| - unsigned int larbid; |
| + unsigned int larbid, larbidx, i; |
| |
| if (!fwspec || fwspec->ops != &mtk_iommu_ops) |
| return ERR_PTR(-ENODEV); /* Not a iommu client device */ |
| @@ -577,6 +577,14 @@ static struct iommu_device *mtk_iommu_probe_device(struct device *dev) |
| * one larb here. |
| */ |
| larbid = MTK_M4U_TO_LARB(fwspec->ids[0]); |
| + for (i = 1; i < fwspec->num_ids; i++) { |
| + larbidx = MTK_M4U_TO_LARB(fwspec->ids[i]); |
| + if (larbid != larbidx) { |
| + dev_err(dev, "Can only use one larb. Fail@larb%d-%d.\n", |
| + larbid, larbidx); |
| + return ERR_PTR(-EINVAL); |
| + } |
| + } |
| larbdev = data->larb_imu[larbid].dev; |
| link = device_link_add(dev, larbdev, |
| DL_FLAG_PM_RUNTIME | DL_FLAG_STATELESS); |
| diff --git a/drivers/iommu/mtk_iommu_v1.c b/drivers/iommu/mtk_iommu_v1.c |
| index 5330c4e7c2e7..cf397436a379 100644 |
| --- a/drivers/iommu/mtk_iommu_v1.c |
| +++ b/drivers/iommu/mtk_iommu_v1.c |
| @@ -425,7 +425,7 @@ static struct iommu_device *mtk_iommu_probe_device(struct device *dev) |
| struct mtk_iommu_data *data; |
| struct device_link *link; |
| struct device *larbdev; |
| - int err, larbid, idx = 0; |
| + int err, larbid, idx = 0, larbidx; |
| |
| /* |
| * In the deferred case, free the existed fwspec. |
| @@ -457,6 +457,15 @@ static struct iommu_device *mtk_iommu_probe_device(struct device *dev) |
| |
| /* Link the consumer device with the smi-larb device(supplier) */ |
| larbid = mt2701_m4u_to_larb(fwspec->ids[0]); |
| + for (idx = 1; idx < fwspec->num_ids; idx++) { |
| + larbidx = mt2701_m4u_to_larb(fwspec->ids[idx]); |
| + if (larbid != larbidx) { |
| + dev_err(dev, "Can only use one larb. Fail@larb%d-%d.\n", |
| + larbid, larbidx); |
| + return ERR_PTR(-EINVAL); |
| + } |
| + } |
| + |
| larbdev = data->larb_imu[larbid].dev; |
| link = device_link_add(dev, larbdev, |
| DL_FLAG_PM_RUNTIME | DL_FLAG_STATELESS); |
| -- |
| 2.35.1.473.g83b2b277ed-goog |
| |