If the iova is over 32bit, the fault status register bit is a little
different. Add a flag for the special register bits.

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 11af0780e4dd..fdf08e2d9ed5 100644
--- a/drivers/iommu/mtk_iommu.c
+++ b/drivers/iommu/mtk_iommu.c
@@ -89,6 +89,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)
 
@@ -113,6 +116,7 @@
 #define HAS_SUB_COMM                   BIT(5)
 #define WR_THROT_EN                    BIT(6)
 #define HAS_LEGACY_IVRP_PADDR          BIT(7)
+#define IOVA_34_EN                     BIT(8)
 
 #define MTK_IOMMU_HAS_FLAG(pdata, _x) \
                ((((pdata)->flags) & (_x)) == (_x))
@@ -263,8 +267,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 */
@@ -280,6 +285,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);
@@ -293,7 +306,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

_______________________________________________
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu

Reply via email to