When the number of smi_larb is more than seven, smi_larb id will be divided into COMMON_ID(high three bits, bit[11:9]) and SUB_COMMON_ID(low two bits,bit[8:7]). So we can analyse translation fault id by SUB_COMMON_ID and COMMON_ID. We can distinguish if has SUB_COMMON_ID and SUB_COMMON_ID by has_sub_comm variable. Signed-off-by: Chao Hao <chao.hao@xxxxxxxxxxxx> --- drivers/iommu/mtk_iommu.c | 16 ++++++++++++---- drivers/iommu/mtk_iommu.h | 1 + 2 files changed, 13 insertions(+), 4 deletions(-) diff --git a/drivers/iommu/mtk_iommu.c b/drivers/iommu/mtk_iommu.c index b61785a87764..5de13ab1094e 100644 --- a/drivers/iommu/mtk_iommu.c +++ b/drivers/iommu/mtk_iommu.c @@ -89,6 +89,8 @@ #define REG_MMU1_INVLD_PA 0x148 #define REG_MMU0_INT_ID 0x150 #define REG_MMU1_INT_ID 0x154 +#define F_MMU_INT_ID_COMM_ID(a) (((a) >> 9) & 0x7) +#define F_MMU_INT_ID_SUB_COMM_ID(a) (((a) >> 7) & 0x3) #define F_MMU_INT_ID_LARB_ID(a) (((a) >> 7) & 0x7) #define F_MMU_INT_ID_PORT_ID(a) (((a) >> 2) & 0x1f) @@ -227,7 +229,7 @@ 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; + unsigned int fault_larb, fault_port, sub_comm = 0; bool layer, write; /* Read error info from registers */ @@ -243,8 +245,13 @@ 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; - fault_larb = F_MMU_INT_ID_LARB_ID(regval); fault_port = F_MMU_INT_ID_PORT_ID(regval); + if (data->plat_data->has_sub_comm[data->m4u_id]) { + fault_larb = F_MMU_INT_ID_COMM_ID(regval); + sub_comm = F_MMU_INT_ID_SUB_COMM_ID(regval); + } else { + fault_larb = F_MMU_INT_ID_LARB_ID(regval); + } fault_larb = data->plat_data->larbid_remap[data->m4u_id][fault_larb]; @@ -252,8 +259,9 @@ 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", - int_state, fault_iova, fault_pa, fault_larb, fault_port, + "fault type=0x%x iova=0x%x pa=0x%x larb=%d sub_comm=%d port=%d regval=0x%x layer=%d %s\n", + int_state, fault_iova, fault_pa, fault_larb, + sub_comm, fault_port, regval, layer, write ? "write" : "read"); } diff --git a/drivers/iommu/mtk_iommu.h b/drivers/iommu/mtk_iommu.h index ec3011a50728..d4495230c6e7 100644 --- a/drivers/iommu/mtk_iommu.h +++ b/drivers/iommu/mtk_iommu.h @@ -40,6 +40,7 @@ struct mtk_iommu_plat_data { /* HW will use the EMI clock if there isn't the "bclk". */ bool has_bclk; + bool has_sub_comm[2]; bool has_vld_pa_rng; bool reset_axi; u32 m4u1_mask; -- 2.18.0