diff --git a/drivers/video/rockchip/mpp/mpp_iommu.c b/drivers/video/rockchip/mpp/mpp_iommu.c index d96afc7fe7f3..ee1bea35248c 100644 --- a/drivers/video/rockchip/mpp/mpp_iommu.c +++ b/drivers/video/rockchip/mpp/mpp_iommu.c @@ -445,6 +445,13 @@ static int mpp_iommu_handle(struct iommu_domain *iommu, { struct mpp_dev *mpp = (struct mpp_dev *)arg; + /* + * Mask iommu irq, in order for iommu not repeatedly trigger pagefault. + * Until the pagefault task finish by hw timeout. + */ + if (mpp) + rockchip_iommu_mask_irq(mpp->dev); + dev_err(iommu_dev, "fault addr 0x%08lx status %x arg %p\n", iova, status, arg); @@ -461,12 +468,6 @@ static int mpp_iommu_handle(struct iommu_domain *iommu, else mpp_task_dump_hw_reg(mpp); - /* - * Mask iommu irq, in order for iommu not repeatedly trigger pagefault. - * Until the pagefault task finish by hw timeout. - */ - rockchip_iommu_mask_irq(mpp->dev); - return 0; } diff --git a/drivers/video/rockchip/mpp/mpp_rkvdec2_link.c b/drivers/video/rockchip/mpp/mpp_rkvdec2_link.c index 5b7fd442d132..eab85abcf26f 100644 --- a/drivers/video/rockchip/mpp/mpp_rkvdec2_link.c +++ b/drivers/video/rockchip/mpp/mpp_rkvdec2_link.c @@ -966,6 +966,14 @@ static int rkvdec2_link_iommu_fault_handle(struct iommu_domain *iommu, struct rkvdec2_dev *dec = to_rkvdec2_dev(mpp); struct mpp_task *mpp_task = NULL, *n; struct mpp_taskqueue *queue; + u32 dump_mem_region = 0; + + /* + * Mask iommu irq, in order for iommu not repeatedly trigger pagefault. + * Until the pagefault task finish by hw timeout. + */ + if (mpp) + rockchip_iommu_mask_irq(mpp->dev); dev_err(iommu_dev, "fault addr 0x%08lx status %x arg %p\n", iova, status, arg); @@ -982,17 +990,15 @@ static int rkvdec2_link_iommu_fault_handle(struct iommu_domain *iommu, u32 irq_status = tb_reg[info->tb_reg_int]; if (!irq_status) { - mpp_task_dump_mem_region(mpp, mpp_task); + dump_mem_region = 1; break; } } + if (dump_mem_region) + mpp_task_dump_mem_region(mpp, mpp_task); mpp_task_dump_hw_reg(mpp); - /* - * Mask iommu irq, in order for iommu not repeatedly trigger pagefault. - * Until the pagefault task finish by hw timeout. - */ - rockchip_iommu_mask_irq(mpp->dev); + dec->mmu_fault = 1; return 0; @@ -1791,15 +1797,15 @@ int rkvdec2_soft_ccu_iommu_fault_handle(struct iommu_domain *iommu, dev_err(iommu_dev, "iommu fault, but no dev match\n"); return 0; } - mpp_task = mpp->cur_task; - if (mpp_task) - mpp_task_dump_mem_region(mpp, mpp_task); - /* * Mask iommu irq, in order for iommu not repeatedly trigger pagefault. * Until the pagefault task finish by hw timeout. */ rockchip_iommu_mask_irq(mpp->dev); + mpp_task = mpp->cur_task; + if (mpp_task) + mpp_task_dump_mem_region(mpp, mpp_task); + atomic_inc(&mpp->queue->reset_request); kthread_queue_work(&mpp->queue->worker, &mpp->work); diff --git a/drivers/video/rockchip/mpp/mpp_rkvenc2.c b/drivers/video/rockchip/mpp/mpp_rkvenc2.c index 25c4d42539a7..3827b607cb0d 100644 --- a/drivers/video/rockchip/mpp/mpp_rkvenc2.c +++ b/drivers/video/rockchip/mpp/mpp_rkvenc2.c @@ -2729,12 +2729,6 @@ static int rkvenc2_iommu_fault_handle(struct iommu_domain *iommu, } } } - mpp_task = mpp->cur_task; - dev_info(mpp->dev, "core %d page fault found dchs %08x\n", - mpp->core_id, mpp_read_relaxed(&enc->mpp, DCHS_REG_OFFSET)); - - if (mpp_task) - mpp_task_dump_mem_region(mpp, mpp_task); /* * Mask iommu irq, in order for iommu not repeatedly trigger pagefault. @@ -2742,6 +2736,13 @@ static int rkvenc2_iommu_fault_handle(struct iommu_domain *iommu, */ rockchip_iommu_mask_irq(mpp->dev); + mpp_task = mpp->cur_task; + dev_info(mpp->dev, "core %d page fault found dchs %08x\n", + mpp->core_id, mpp_read_relaxed(&enc->mpp, DCHS_REG_OFFSET)); + + if (mpp_task) + mpp_task_dump_mem_region(mpp, mpp_task); + return 0; } diff --git a/drivers/video/rockchip/mpp/mpp_vepu2.c b/drivers/video/rockchip/mpp/mpp_vepu2.c index 05a5556e0f8d..1e66dd530b35 100644 --- a/drivers/video/rockchip/mpp/mpp_vepu2.c +++ b/drivers/video/rockchip/mpp/mpp_vepu2.c @@ -891,9 +891,6 @@ static int vepu2_iommu_fault_handle(struct iommu_domain *iommu, struct device *i struct vepu_dev *enc = to_vepu_dev(mpp); struct vepu_ccu *ccu = enc->ccu; - dev_err(iommu_dev, "fault addr 0x%08lx status %x arg %p\n", - iova, status, arg); - if (ccu) { int i; struct mpp_dev *core; @@ -907,6 +904,16 @@ static int vepu2_iommu_fault_handle(struct iommu_domain *iommu, struct device *i } } + /* + * Mask iommu irq, in order for iommu not repeatedly trigger pagefault. + * Until the pagefault task finish by hw timeout. + */ + if (mpp) + rockchip_iommu_mask_irq(mpp->dev); + + dev_err(iommu_dev, "fault addr 0x%08lx status %x arg %p\n", + iova, status, arg); + if (!mpp) { dev_err(iommu_dev, "pagefault without device to handle\n"); return 0; @@ -916,11 +923,6 @@ static int vepu2_iommu_fault_handle(struct iommu_domain *iommu, struct device *i mpp_task_dump_mem_region(mpp, mpp_task); mpp_task_dump_hw_reg(mpp); - /* - * Mask iommu irq, in order for iommu not repeatedly trigger pagefault. - * Until the pagefault task finish by hw timeout. - */ - rockchip_iommu_mask_irq(mpp->dev); return 0; }