From a1efc0f6e7d4fcd58c2e9c56a63cc5edd47e4284 Mon Sep 17 00:00:00 2001 From: Simon Xue Date: Tue, 6 Apr 2021 16:18:15 +0800 Subject: [PATCH] iommu/rockchip: skip read vop iommu registers on rk3128 and rk3126 RK3128 and RK3126 failed to read vop iommu register, it is SoC bug. Add this patch as a workaround for this bug, make SoC work as normal Change-Id: I44d4ef7f6e15f85a466563b0b3e8e091db23fba0 Signed-off-by: Simon Xue --- drivers/iommu/rockchip-iommu.c | 37 ++++++++++++++++++++++++++++++++++ 1 file changed, 37 insertions(+) diff --git a/drivers/iommu/rockchip-iommu.c b/drivers/iommu/rockchip-iommu.c index e5d86b7177de..5d4b8955962c 100644 --- a/drivers/iommu/rockchip-iommu.c +++ b/drivers/iommu/rockchip-iommu.c @@ -104,6 +104,7 @@ struct rk_iommu { struct clk_bulk_data *clocks; int num_clocks; bool reset_disabled; + bool skip_read; /* rk3126/rk3128 can't read vop iommu registers */ struct iommu_device iommu; struct list_head node; /* entry in rk_iommu_domain.iommus */ struct iommu_domain *domain; /* domain to which iommu is attached */ @@ -351,6 +352,9 @@ static int rk_iommu_enable_stall(struct rk_iommu *iommu) int ret, i; bool val; + if (iommu->skip_read) + goto read_wa; + if (rk_iommu_is_stall_active(iommu)) return 0; @@ -358,7 +362,10 @@ static int rk_iommu_enable_stall(struct rk_iommu *iommu) if (!rk_iommu_is_paging_enabled(iommu)) return 0; +read_wa: rk_iommu_command(iommu, RK_MMU_CMD_ENABLE_STALL); + if (iommu->skip_read) + return 0; ret = readx_poll_timeout(rk_iommu_is_stall_active, iommu, val, val, RK_MMU_POLL_PERIOD_US, @@ -376,10 +383,16 @@ static int rk_iommu_disable_stall(struct rk_iommu *iommu) int ret, i; bool val; + if (iommu->skip_read) + goto read_wa; + if (!rk_iommu_is_stall_active(iommu)) return 0; +read_wa: rk_iommu_command(iommu, RK_MMU_CMD_DISABLE_STALL); + if (iommu->skip_read) + return 0; ret = readx_poll_timeout(rk_iommu_is_stall_active, iommu, val, !val, RK_MMU_POLL_PERIOD_US, @@ -397,10 +410,16 @@ static int rk_iommu_enable_paging(struct rk_iommu *iommu) int ret, i; bool val; + if (iommu->skip_read) + goto read_wa; + if (rk_iommu_is_paging_enabled(iommu)) return 0; +read_wa: rk_iommu_command(iommu, RK_MMU_CMD_ENABLE_PAGING); + if (iommu->skip_read) + return 0; ret = readx_poll_timeout(rk_iommu_is_paging_enabled, iommu, val, val, RK_MMU_POLL_PERIOD_US, @@ -418,10 +437,16 @@ static int rk_iommu_disable_paging(struct rk_iommu *iommu) int ret, i; bool val; + if (iommu->skip_read) + goto read_wa; + if (!rk_iommu_is_paging_enabled(iommu)) return 0; +read_wa: rk_iommu_command(iommu, RK_MMU_CMD_DISABLE_PAGING); + if (iommu->skip_read) + return 0; ret = readx_poll_timeout(rk_iommu_is_paging_enabled, iommu, val, !val, RK_MMU_POLL_PERIOD_US, @@ -443,6 +468,9 @@ static int rk_iommu_force_reset(struct rk_iommu *iommu) if (iommu->reset_disabled) return 0; + if (iommu->skip_read) + goto read_wa; + /* * Check if register DTE_ADDR is working by writing DTE_ADDR_DUMMY * and verifying that upper 5 nybbles are read back. @@ -457,7 +485,10 @@ static int rk_iommu_force_reset(struct rk_iommu *iommu) } } +read_wa: rk_iommu_command(iommu, RK_MMU_CMD_FORCE_RESET); + if (iommu->skip_read) + return 0; ret = readx_poll_timeout(rk_iommu_is_reset_done, iommu, val, val, RK_MMU_FORCE_RESET_TIMEOUT_US, @@ -1161,6 +1192,8 @@ static int rk_iommu_probe(struct platform_device *pdev) iommu->reset_disabled = device_property_read_bool(dev, "rockchip,disable-mmu-reset"); + iommu->skip_read = device_property_read_bool(dev, + "rockchip,skip-mmu-read"); iommu->num_clocks = ARRAY_SIZE(rk_iommu_clocks); iommu->clocks = devm_kcalloc(iommu->dev, iommu->num_clocks, @@ -1215,6 +1248,9 @@ static int rk_iommu_probe(struct platform_device *pdev) pm_runtime_enable(dev); + if (iommu->skip_read) + goto skip_request_irq; + for (i = 0; i < iommu->num_irq; i++) { int irq = platform_get_irq(pdev, i); @@ -1229,6 +1265,7 @@ static int rk_iommu_probe(struct platform_device *pdev) } } +skip_request_irq: return 0; err_remove_sysfs: iommu_device_sysfs_remove(&iommu->iommu);