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);