Skip to content

Commit ef0f098

Browse files
YongWu-HFwilldeacon
authored andcommitted
iommu/mediatek: Support report iova 34bit translation fault in ISR
If the iova is over 32bit, the fault status register bit is a little different. Signed-off-by: Yong Wu <yong.wu@mediatek.com> Reviewed-by: Tomasz Figa <tfiga@chromium.org> Link: https://lore.kernel.org/r/20210111111914.22211-23-yong.wu@mediatek.com Signed-off-by: Will Deacon <will@kernel.org>
1 parent bfed873 commit ef0f098

1 file changed

Lines changed: 15 additions & 2 deletions

File tree

drivers/iommu/mtk_iommu.c

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
* Copyright (c) 2015-2016 MediaTek Inc.
44
* Author: Yong Wu <yong.wu@mediatek.com>
55
*/
6+
#include <linux/bitfield.h>
67
#include <linux/bug.h>
78
#include <linux/clk.h>
89
#include <linux/component.h>
@@ -89,6 +90,9 @@
8990
#define F_REG_MMU1_FAULT_MASK GENMASK(13, 7)
9091

9192
#define REG_MMU0_FAULT_VA 0x13c
93+
#define F_MMU_INVAL_VA_31_12_MASK GENMASK(31, 12)
94+
#define F_MMU_INVAL_VA_34_32_MASK GENMASK(11, 9)
95+
#define F_MMU_INVAL_PA_34_32_MASK GENMASK(8, 6)
9296
#define F_MMU_FAULT_VA_WRITE_BIT BIT(1)
9397
#define F_MMU_FAULT_VA_LAYER_BIT BIT(0)
9498

@@ -246,8 +250,9 @@ static irqreturn_t mtk_iommu_isr(int irq, void *dev_id)
246250
{
247251
struct mtk_iommu_data *data = dev_id;
248252
struct mtk_iommu_domain *dom = data->m4u_dom;
249-
u32 int_state, regval, fault_iova, fault_pa;
250253
unsigned int fault_larb, fault_port, sub_comm = 0;
254+
u32 int_state, regval, va34_32, pa34_32;
255+
u64 fault_iova, fault_pa;
251256
bool layer, write;
252257

253258
/* Read error info from registers */
@@ -263,6 +268,14 @@ static irqreturn_t mtk_iommu_isr(int irq, void *dev_id)
263268
}
264269
layer = fault_iova & F_MMU_FAULT_VA_LAYER_BIT;
265270
write = fault_iova & F_MMU_FAULT_VA_WRITE_BIT;
271+
if (MTK_IOMMU_HAS_FLAG(data->plat_data, IOVA_34_EN)) {
272+
va34_32 = FIELD_GET(F_MMU_INVAL_VA_34_32_MASK, fault_iova);
273+
pa34_32 = FIELD_GET(F_MMU_INVAL_PA_34_32_MASK, fault_iova);
274+
fault_iova = fault_iova & F_MMU_INVAL_VA_31_12_MASK;
275+
fault_iova |= (u64)va34_32 << 32;
276+
fault_pa |= (u64)pa34_32 << 32;
277+
}
278+
266279
fault_port = F_MMU_INT_ID_PORT_ID(regval);
267280
if (MTK_IOMMU_HAS_FLAG(data->plat_data, HAS_SUB_COMM)) {
268281
fault_larb = F_MMU_INT_ID_COMM_ID(regval);
@@ -276,7 +289,7 @@ static irqreturn_t mtk_iommu_isr(int irq, void *dev_id)
276289
write ? IOMMU_FAULT_WRITE : IOMMU_FAULT_READ)) {
277290
dev_err_ratelimited(
278291
data->dev,
279-
"fault type=0x%x iova=0x%x pa=0x%x larb=%d port=%d layer=%d %s\n",
292+
"fault type=0x%x iova=0x%llx pa=0x%llx larb=%d port=%d layer=%d %s\n",
280293
int_state, fault_iova, fault_pa, fault_larb, fault_port,
281294
layer, write ? "write" : "read");
282295
}

0 commit comments

Comments
 (0)