summaryrefslogtreecommitdiff
path: root/drivers/iommu/exynos-iommu.c
diff options
context:
space:
mode:
authorMarek Szyprowski <m.szyprowski@samsung.com>2016-02-18 17:12:56 +0300
committerJoerg Roedel <jroedel@suse.de>2016-02-25 17:32:10 +0300
commit850d313e2ed52d19b781e38536fc44ba0b58c434 (patch)
tree5dbbf63a1b402499b8345fa26e5c55b72ecaaa69 /drivers/iommu/exynos-iommu.c
parentd631ea9809785da06a048cfb25c2714f18a9cd63 (diff)
downloadlinux-850d313e2ed52d19b781e38536fc44ba0b58c434.tar.xz
iommu/exynos: Add support for SYSMMU controller with bogus version reg
SYSMMU on some SoCs reports bogus values in VERSION register. Force hardware version to 1.0 for such controllers. This patch also moves reading version register to driver's probe() function. Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com> Signed-off-by: Joerg Roedel <jroedel@suse.de>
Diffstat (limited to 'drivers/iommu/exynos-iommu.c')
-rw-r--r--drivers/iommu/exynos-iommu.c24
1 files changed, 23 insertions, 1 deletions
diff --git a/drivers/iommu/exynos-iommu.c b/drivers/iommu/exynos-iommu.c
index e42a76cc9674..8e289e2a05fb 100644
--- a/drivers/iommu/exynos-iommu.c
+++ b/drivers/iommu/exynos-iommu.c
@@ -284,6 +284,28 @@ static void __sysmmu_set_ptbase(struct sysmmu_drvdata *data, phys_addr_t pgd)
__sysmmu_tlb_invalidate(data);
}
+static void __sysmmu_get_version(struct sysmmu_drvdata *data)
+{
+ u32 ver;
+
+ clk_enable(data->clk_master);
+ clk_enable(data->clk);
+
+ ver = __raw_readl(data->sfrbase + REG_MMU_VERSION);
+
+ /* controllers on some SoCs don't report proper version */
+ if (ver == 0x80000001u)
+ data->version = MAKE_MMU_VER(1, 0);
+ else
+ data->version = MMU_RAW_VER(ver);
+
+ dev_dbg(data->sysmmu, "hardware version: %d.%d\n",
+ MMU_MAJ_VER(data->version), MMU_MIN_VER(data->version));
+
+ clk_disable(data->clk);
+ clk_disable(data->clk_master);
+}
+
static void show_fault_information(struct sysmmu_drvdata *data,
const struct sysmmu_fault_info *finfo,
sysmmu_iova_t fault_addr)
@@ -385,7 +407,6 @@ static void __sysmmu_init_config(struct sysmmu_drvdata *data)
{
unsigned int cfg;
- data->version = MMU_RAW_VER(__raw_readl(data->sfrbase + REG_MMU_VERSION));
if (data->version <= MAKE_MMU_VER(3, 1))
cfg = CFG_LRU | CFG_QOS(15);
else if (data->version <= MAKE_MMU_VER(3, 2))
@@ -551,6 +572,7 @@ static int __init exynos_sysmmu_probe(struct platform_device *pdev)
platform_set_drvdata(pdev, data);
+ __sysmmu_get_version(data);
pm_runtime_enable(dev);
return 0;