aboutsummaryrefslogtreecommitdiff
path: root/drivers/iommu
diff options
context:
space:
mode:
authorYong Wu2022-05-03 15:14:11 +0800
committerJoerg Roedel2022-05-04 10:39:39 +0200
commit6077c7e5d22f2e0ffdb1dd97bf37cba66f317627 (patch)
tree2583cd23c6800126dd31ef16fb7c51cbbd8f0d81 /drivers/iommu
parent32e1cccf68123bcd357c0115567d2ce3453cd3ed (diff)
iommu/mediatek: Add a PM_CLK_AO flag for infra iommu
The power/clock of infra iommu is always on, and it doesn't have the device link with the master devices, then the infra iommu device's PM status is not active, thus we add A PM_CLK_AO flag for infra iommu. The tlb operation is a bit not clear here, there are 2 special cases. Comment them in the code. Signed-off-by: Yong Wu <yong.wu@mediatek.com> Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com> Reviewed-by: Matthias Brugger <matthias.bgg@gmail.com> Link: https://lore.kernel.org/r/20220503071427.2285-21-yong.wu@mediatek.com Signed-off-by: Joerg Roedel <jroedel@suse.de>
Diffstat (limited to 'drivers/iommu')
-rw-r--r--drivers/iommu/mtk_iommu.c29
1 files changed, 26 insertions, 3 deletions
diff --git a/drivers/iommu/mtk_iommu.c b/drivers/iommu/mtk_iommu.c
index 0121d71c315f..cd89c109e8c4 100644
--- a/drivers/iommu/mtk_iommu.c
+++ b/drivers/iommu/mtk_iommu.c
@@ -130,6 +130,8 @@
#define MTK_IOMMU_TYPE_MM (0x0 << 13)
#define MTK_IOMMU_TYPE_INFRA (0x1 << 13)
#define MTK_IOMMU_TYPE_MASK (0x3 << 13)
+/* PM and clock always on. e.g. infra iommu */
+#define PM_CLK_AO BIT(15)
#define MTK_IOMMU_HAS_FLAG_MASK(pdata, _x, mask) \
((((pdata)->flags) & (mask)) == (_x))
@@ -235,13 +237,33 @@ static void mtk_iommu_tlb_flush_range_sync(unsigned long iova, size_t size,
struct mtk_iommu_data *data)
{
struct list_head *head = data->hw_list;
+ bool check_pm_status;
unsigned long flags;
int ret;
u32 tmp;
for_each_m4u(data, head) {
- if (pm_runtime_get_if_in_use(data->dev) <= 0)
- continue;
+ /*
+ * To avoid resume the iommu device frequently when the iommu device
+ * is not active, it doesn't always call pm_runtime_get here, then tlb
+ * flush depends on the tlb flush all in the runtime resume.
+ *
+ * There are 2 special cases:
+ *
+ * Case1: The iommu dev doesn't have power domain but has bclk. This case
+ * should also avoid the tlb flush while the dev is not active to mute
+ * the tlb timeout log. like mt8173.
+ *
+ * Case2: The power/clock of infra iommu is always on, and it doesn't
+ * have the device link with the master devices. This case should avoid
+ * the PM status check.
+ */
+ check_pm_status = !MTK_IOMMU_HAS_FLAG(data->plat_data, PM_CLK_AO);
+
+ if (check_pm_status) {
+ if (pm_runtime_get_if_in_use(data->dev) <= 0)
+ continue;
+ }
spin_lock_irqsave(&data->tlb_lock, flags);
writel_relaxed(F_INVLD_EN1 | F_INVLD_EN0,
@@ -268,7 +290,8 @@ static void mtk_iommu_tlb_flush_range_sync(unsigned long iova, size_t size,
mtk_iommu_tlb_flush_all(data);
}
- pm_runtime_put(data->dev);
+ if (check_pm_status)
+ pm_runtime_put(data->dev);
}
}