mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/next/linux-next.git
synced 2025-01-09 23:39:18 +00:00
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>
This commit is contained in:
parent
bfed873114
commit
ef0f0986b6
@ -3,6 +3,7 @@
|
|||||||
* Copyright (c) 2015-2016 MediaTek Inc.
|
* Copyright (c) 2015-2016 MediaTek Inc.
|
||||||
* Author: Yong Wu <yong.wu@mediatek.com>
|
* Author: Yong Wu <yong.wu@mediatek.com>
|
||||||
*/
|
*/
|
||||||
|
#include <linux/bitfield.h>
|
||||||
#include <linux/bug.h>
|
#include <linux/bug.h>
|
||||||
#include <linux/clk.h>
|
#include <linux/clk.h>
|
||||||
#include <linux/component.h>
|
#include <linux/component.h>
|
||||||
@ -89,6 +90,9 @@
|
|||||||
#define F_REG_MMU1_FAULT_MASK GENMASK(13, 7)
|
#define F_REG_MMU1_FAULT_MASK GENMASK(13, 7)
|
||||||
|
|
||||||
#define REG_MMU0_FAULT_VA 0x13c
|
#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_WRITE_BIT BIT(1)
|
||||||
#define F_MMU_FAULT_VA_LAYER_BIT BIT(0)
|
#define F_MMU_FAULT_VA_LAYER_BIT BIT(0)
|
||||||
|
|
||||||
@ -246,8 +250,9 @@ static irqreturn_t mtk_iommu_isr(int irq, void *dev_id)
|
|||||||
{
|
{
|
||||||
struct mtk_iommu_data *data = dev_id;
|
struct mtk_iommu_data *data = dev_id;
|
||||||
struct mtk_iommu_domain *dom = data->m4u_dom;
|
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;
|
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;
|
bool layer, write;
|
||||||
|
|
||||||
/* Read error info from registers */
|
/* Read error info from registers */
|
||||||
@ -263,6 +268,14 @@ static irqreturn_t mtk_iommu_isr(int irq, void *dev_id)
|
|||||||
}
|
}
|
||||||
layer = fault_iova & F_MMU_FAULT_VA_LAYER_BIT;
|
layer = fault_iova & F_MMU_FAULT_VA_LAYER_BIT;
|
||||||
write = fault_iova & F_MMU_FAULT_VA_WRITE_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);
|
fault_port = F_MMU_INT_ID_PORT_ID(regval);
|
||||||
if (MTK_IOMMU_HAS_FLAG(data->plat_data, HAS_SUB_COMM)) {
|
if (MTK_IOMMU_HAS_FLAG(data->plat_data, HAS_SUB_COMM)) {
|
||||||
fault_larb = F_MMU_INT_ID_COMM_ID(regval);
|
fault_larb = F_MMU_INT_ID_COMM_ID(regval);
|
||||||
@ -276,7 +289,7 @@ static irqreturn_t mtk_iommu_isr(int irq, void *dev_id)
|
|||||||
write ? IOMMU_FAULT_WRITE : IOMMU_FAULT_READ)) {
|
write ? IOMMU_FAULT_WRITE : IOMMU_FAULT_READ)) {
|
||||||
dev_err_ratelimited(
|
dev_err_ratelimited(
|
||||||
data->dev,
|
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,
|
int_state, fault_iova, fault_pa, fault_larb, fault_port,
|
||||||
layer, write ? "write" : "read");
|
layer, write ? "write" : "read");
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user