If the iova is over 32bit, the fault status register bit is a little
different.

Signed-off-by: Yong Wu <yong...@mediatek.com>
---
 drivers/iommu/mtk_iommu.c | 17 +++++++++++++++--
 1 file changed, 15 insertions(+), 2 deletions(-)

diff --git a/drivers/iommu/mtk_iommu.c b/drivers/iommu/mtk_iommu.c
index 164479e1f5c5..ed771133643d 100644
--- a/drivers/iommu/mtk_iommu.c
+++ b/drivers/iommu/mtk_iommu.c
@@ -3,6 +3,7 @@
  * Copyright (c) 2015-2016 MediaTek Inc.
  * Author: Yong Wu <yong...@mediatek.com>
  */
+#include <linux/bitfield.h>
 #include <linux/bug.h>
 #include <linux/clk.h>
 #include <linux/component.h>
@@ -89,6 +90,9 @@
 #define F_REG_MMU1_FAULT_MASK                  GENMASK(13, 7)
 
 #define REG_MMU0_FAULT_VA                      0x13c
+#define F_MMU_INVAL_VA_31_12_MASK              GENMASK(31, 12)
+#define F_MMU_INVAL_VA_34_32_MASK              GENMASK(11, 9)
+#define F_MMU_INVAL_PA_34_32_MASK              GENMASK(8, 6)
 #define F_MMU_FAULT_VA_WRITE_BIT               BIT(1)
 #define F_MMU_FAULT_VA_LAYER_BIT               BIT(0)
 
@@ -264,8 +268,9 @@ static irqreturn_t mtk_iommu_isr(int irq, void *dev_id)
 {
        struct mtk_iommu_data *data = dev_id;
        struct mtk_iommu_domain *dom = data->m4u_dom;
-       u32 int_state, regval, fault_iova, fault_pa;
        unsigned int fault_larb, fault_port, sub_comm = 0;
+       u32 int_state, regval, va34_32, pa34_32;
+       u64 fault_iova, fault_pa;
        bool layer, write;
 
        /* Read error info from registers */
@@ -281,6 +286,14 @@ static irqreturn_t mtk_iommu_isr(int irq, void *dev_id)
        }
        layer = fault_iova & F_MMU_FAULT_VA_LAYER_BIT;
        write = fault_iova & F_MMU_FAULT_VA_WRITE_BIT;
+       if (MTK_IOMMU_HAS_FLAG(data->plat_data, IOVA_34_EN)) {
+               va34_32 = FIELD_GET(F_MMU_INVAL_VA_34_32_MASK, fault_iova);
+               pa34_32 = FIELD_GET(F_MMU_INVAL_PA_34_32_MASK, fault_iova);
+               fault_iova = fault_iova & F_MMU_INVAL_VA_31_12_MASK;
+               fault_iova |=  (u64)va34_32 << 32;
+               fault_pa |= (u64)pa34_32 << 32;
+       }
+
        fault_port = F_MMU_INT_ID_PORT_ID(regval);
        if (MTK_IOMMU_HAS_FLAG(data->plat_data, HAS_SUB_COMM)) {
                fault_larb = F_MMU_INT_ID_COMM_ID(regval);
@@ -294,7 +307,7 @@ static irqreturn_t mtk_iommu_isr(int irq, void *dev_id)
                               write ? IOMMU_FAULT_WRITE : IOMMU_FAULT_READ)) {
                dev_err_ratelimited(
                        data->dev,
-                       "fault type=0x%x iova=0x%x pa=0x%x larb=%d port=%d 
layer=%d %s\n",
+                       "fault type=0x%x iova=0x%llx pa=0x%llx larb=%d port=%d 
layer=%d %s\n",
                        int_state, fault_iova, fault_pa, fault_larb, fault_port,
                        layer, write ? "write" : "read");
        }
-- 
2.18.0

Reply via email to