From 7f8158fb41b5cc8e738aaeebc3637c50ebd74cae Mon Sep 17 00:00:00 2001 From: Simon Xue Date: Tue, 6 Apr 2021 19:07:35 +0800 Subject: [PATCH] iommu: rockchip: disable fetch dte time limit Master fetch data and cpu update page table may work in parallel, may have the following procedure: master cpu fetch dte update page tabl | | (make dte invalid) <- zap iotlb entry | | fetch dte again (make dte invalid) <- zap iotlb entry | | fetch dte again (make dte invalid) <- zap iotlb entry | | fetch dte again (make iommu block) <- zap iotlb entry New iommu version has the above bug, if fetch dte consecutively four times, then it will be blocked. Fortunately, we can set bit 31 of register MMU_AUTO_GATING to 1 to make it work as old version which does not have this issue. This issue only appears on RV1126 so far, so make a workaround dedicated to "rockchip,rv1126" machine type. Change-Id: I808bf87898e2dfdd8ada5666234e4c2c3237ffde Signed-off-by: Simon Xue --- drivers/iommu/rockchip-iommu.c | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/drivers/iommu/rockchip-iommu.c b/drivers/iommu/rockchip-iommu.c index 21cad6e801a9..f3e0eb7185e4 100644 --- a/drivers/iommu/rockchip-iommu.c +++ b/drivers/iommu/rockchip-iommu.c @@ -75,6 +75,8 @@ #define SPAGE_ORDER 12 #define SPAGE_SIZE (1 << SPAGE_ORDER) +#define DISABLE_FETCH_DTE_TIME_LIMIT BIT(31) + /* * Support mapping any size that fits in one page table: * 4 KiB to 4 MiB @@ -134,6 +136,7 @@ struct rk_iommu { bool reset_disabled; bool skip_read; /* rk3126/rk3128 can't read vop iommu registers */ bool dlr_disable; /* avoid access iommu when runtime ops called */ + bool fetch_dte_time_limit; /* if have fetch dte time limit */ struct iommu_device iommu; struct list_head node; /* entry in rk_iommu_domain.iommus */ struct iommu_domain *domain; /* domain to which iommu is attached */ @@ -1233,6 +1236,7 @@ static int rk_iommu_enable(struct rk_iommu *iommu) struct rk_iommu_domain *rk_domain = to_rk_domain(domain); int ret, i; u32 dt_v2; + u32 auto_gate; ret = clk_bulk_enable(iommu->num_clocks, iommu->clocks); if (ret) @@ -1257,6 +1261,12 @@ static int rk_iommu_enable(struct rk_iommu *iommu) } rk_iommu_base_command(iommu->bases[i], RK_MMU_CMD_ZAP_CACHE); rk_iommu_write(iommu->bases[i], RK_MMU_INT_MASK, RK_MMU_IRQ_MASK); + + if (iommu->fetch_dte_time_limit) { + auto_gate = rk_iommu_read(iommu->bases[i], RK_MMU_AUTO_GATING); + auto_gate |= DISABLE_FETCH_DTE_TIME_LIMIT; + rk_iommu_write(iommu->bases[i], RK_MMU_AUTO_GATING, auto_gate); + } } ret = rk_iommu_enable_paging(iommu); @@ -1644,6 +1654,10 @@ static int rk_iommu_probe(struct platform_device *pdev) iommu->dlr_disable = device_property_read_bool(dev, "rockchip,disable-device-link-resume"); + if (of_machine_is_compatible("rockchip,rv1126") || + of_machine_is_compatible("rockchip,rv1109")) + iommu->fetch_dte_time_limit = true; + iommu->num_clocks = ARRAY_SIZE(rk_iommu_clocks); iommu->clocks = devm_kcalloc(iommu->dev, iommu->num_clocks, sizeof(*iommu->clocks), GFP_KERNEL);