diff --git a/drivers/video/rockchip/mpp/mpp_common.c b/drivers/video/rockchip/mpp/mpp_common.c index 9bd50ae14aa1..a27919f499fe 100644 --- a/drivers/video/rockchip/mpp/mpp_common.c +++ b/drivers/video/rockchip/mpp/mpp_common.c @@ -1928,15 +1928,12 @@ int mpp_task_dump_reg(struct mpp_dev *mpp, return 0; } -int mpp_task_dump_hw_reg(struct mpp_dev *mpp, struct mpp_task *task) +int mpp_task_dump_hw_reg(struct mpp_dev *mpp) { - if (!task) - return -EIO; - if (mpp_debug_unlikely(DEBUG_DUMP_ERR_REG)) { u32 i; - u32 s = task->hw_info->reg_start; - u32 e = task->hw_info->reg_end; + u32 s = mpp->var->hw_info->reg_start; + u32 e = mpp->var->hw_info->reg_end; mpp_err("--- dump hardware register ---\n"); for (i = s; i <= e; i++) { @@ -1955,22 +1952,10 @@ static int mpp_iommu_handle(struct iommu_domain *iommu, unsigned long iova, int status, void *arg) { - struct mpp_taskqueue *queue = (struct mpp_taskqueue *)arg; - struct mpp_task *task = mpp_taskqueue_get_running_task(queue); - struct mpp_dev *mpp; + struct mpp_dev *mpp = (struct mpp_dev *)arg; - /* - * NOTE: In link mode, this task may not be the task of the current - * hardware processing error - */ - if (!task || !task->session) - return -EIO; - /* get mpp from cur task */ - mpp = mpp_get_task_used_device(task, task->session); dev_err(mpp->dev, "fault addr 0x%08lx status %x\n", iova, status); - - mpp_task_dump_mem_region(mpp, task); - mpp_task_dump_hw_reg(mpp, task); + mpp_task_dump_hw_reg(mpp); if (mpp->iommu_info->hdl) mpp->iommu_info->hdl(iommu, iommu_dev, iova, status, arg); @@ -2075,7 +2060,7 @@ int mpp_dev_probe(struct mpp_dev *mpp, /* set iommu fault handler */ if (mpp->iommu_info) iommu_set_fault_handler(mpp->iommu_info->domain, - mpp_iommu_handle, mpp->queue); + mpp_iommu_handle, mpp); /* read hardware id */ if (hw_info->reg_id >= 0) { diff --git a/drivers/video/rockchip/mpp/mpp_common.h b/drivers/video/rockchip/mpp/mpp_common.h index 6528b5cabef1..1027ff1f944d 100644 --- a/drivers/video/rockchip/mpp/mpp_common.h +++ b/drivers/video/rockchip/mpp/mpp_common.h @@ -625,8 +625,7 @@ int mpp_task_dump_mem_region(struct mpp_dev *mpp, struct mpp_task *task); int mpp_task_dump_reg(struct mpp_dev *mpp, struct mpp_task *task); -int mpp_task_dump_hw_reg(struct mpp_dev *mpp, - struct mpp_task *task); +int mpp_task_dump_hw_reg(struct mpp_dev *mpp); void mpp_free_task(struct kref *ref); int mpp_session_deinit(struct mpp_session *session); diff --git a/drivers/video/rockchip/mpp/mpp_rkvdec2.c b/drivers/video/rockchip/mpp/mpp_rkvdec2.c index 4a77fd7e92e1..b5093a3ed4e8 100644 --- a/drivers/video/rockchip/mpp/mpp_rkvdec2.c +++ b/drivers/video/rockchip/mpp/mpp_rkvdec2.c @@ -384,9 +384,8 @@ static int rkvdec2_isr(struct mpp_dev *mpp) RKVDEC_TIMEOUT_STA | RKVDEC_ERROR_STA; if (err_mask & task->irq_status) { atomic_inc(&mpp->reset_request); - mpp_debug(DEBUG_DUMP_ERR_REG, "irq_status: %08x\n", - task->irq_status); - mpp_task_dump_hw_reg(mpp, mpp_task); + mpp_debug(DEBUG_DUMP_ERR_REG, "irq_status: %08x\n", task->irq_status); + mpp_task_dump_hw_reg(mpp); } mpp_task_finish(mpp_task->session, mpp_task); @@ -1111,6 +1110,7 @@ static int rkvdec2_core_probe(struct platform_device *pdev) mpp->dev_ops->task_worker = rkvdec2_soft_ccu_worker; kthread_init_work(&mpp->work, rkvdec2_soft_ccu_worker); + mpp->iommu_info->hdl = rkvdec2_ccu_iommu_fault_handle; /* get irq request */ ret = devm_request_threaded_irq(dev, mpp->irq, rkvdec2_soft_ccu_irq, NULL, IRQF_SHARED, dev_name(dev), mpp); diff --git a/drivers/video/rockchip/mpp/mpp_rkvdec2_link.c b/drivers/video/rockchip/mpp/mpp_rkvdec2_link.c index e85472a5574c..db959b2c23dc 100644 --- a/drivers/video/rockchip/mpp/mpp_rkvdec2_link.c +++ b/drivers/video/rockchip/mpp/mpp_rkvdec2_link.c @@ -1672,8 +1672,11 @@ static int rkvdec2_soft_ccu_dequeue(struct mpp_taskqueue *queue) task->irq_status = irq_status; mpp_debug(DEBUG_IRQ_CHECK, "irq_status=%08x, timeout=%u, abort=%u\n", irq_status, timeout_flag, abort_flag); - if (mpp->dev_ops->finish) + if (irq_status && mpp->dev_ops->finish) mpp->dev_ops->finish(mpp, mpp_task); + else + task->reg[RKVDEC_REG_INT_EN_INDEX] = RKVDEC_TIMEOUT_STA; + set_bit(TASK_STATE_FINISH, &mpp_task->state); set_bit(TASK_STATE_DONE, &mpp_task->state); @@ -1771,6 +1774,26 @@ void *rkvdec2_ccu_alloc_task(struct mpp_session *session, return &task->mpp_task; } +int rkvdec2_ccu_iommu_fault_handle(struct iommu_domain *iommu, + struct device *iommu_dev, + unsigned long iova, int status, void *arg) +{ + u32 i = 0; + struct mpp_dev *mpp = (struct mpp_dev *)arg; + + mpp_debug_enter(); + + atomic_inc(&mpp->queue->reset_request); + for (i = 0; i < mpp->queue->core_count; i++) + rk_iommu_mask_irq(mpp->queue->cores[i]->dev); + + kthread_queue_work(&mpp->queue->worker, &mpp->work); + + mpp_debug_leave(); + + return 0; +} + irqreturn_t rkvdec2_soft_ccu_irq(int irq, void *param) { struct mpp_dev *mpp = param; diff --git a/drivers/video/rockchip/mpp/mpp_rkvdec2_link.h b/drivers/video/rockchip/mpp/mpp_rkvdec2_link.h index 537235cc8b89..781ab9f75612 100644 --- a/drivers/video/rockchip/mpp/mpp_rkvdec2_link.h +++ b/drivers/video/rockchip/mpp/mpp_rkvdec2_link.h @@ -171,6 +171,9 @@ void rkvdec2_link_session_deinit(struct mpp_session *session); int rkvdec2_attach_ccu(struct device *dev, struct rkvdec2_dev *dec); int rkvdec2_ccu_link_init(struct platform_device *pdev, struct rkvdec2_dev *dec); void *rkvdec2_ccu_alloc_task(struct mpp_session *session, struct mpp_task_msgs *msgs); +int rkvdec2_ccu_iommu_fault_handle(struct iommu_domain *iommu, + struct device *iommu_dev, + unsigned long iova, int status, void *arg); irqreturn_t rkvdec2_soft_ccu_irq(int irq, void *param); void rkvdec2_soft_ccu_worker(struct kthread_work *work_s); diff --git a/drivers/video/rockchip/mpp/mpp_rkvenc.c b/drivers/video/rockchip/mpp/mpp_rkvenc.c index c73f9dff1263..cf14d639f6de 100644 --- a/drivers/video/rockchip/mpp/mpp_rkvenc.c +++ b/drivers/video/rockchip/mpp/mpp_rkvenc.c @@ -524,11 +524,8 @@ static int rkvenc_isr(struct mpp_dev *mpp) if (task->irq_status & RKVENC_INT_ERROR_BITS) { atomic_inc(&mpp->reset_request); /* dump register */ - if (mpp_debug_unlikely(DEBUG_DUMP_ERR_REG)) { - mpp_debug(DEBUG_DUMP_ERR_REG, "irq_status: %08x\n", - task->irq_status); - mpp_task_dump_hw_reg(mpp, mpp_task); - } + mpp_debug(DEBUG_DUMP_ERR_REG, "irq_status: %08x\n", task->irq_status); + mpp_task_dump_hw_reg(mpp); } /* unmap reserve buffer */ diff --git a/drivers/video/rockchip/mpp/mpp_rkvenc2.c b/drivers/video/rockchip/mpp/mpp_rkvenc2.c index 86adb0185271..b331df91bcd9 100644 --- a/drivers/video/rockchip/mpp/mpp_rkvenc2.c +++ b/drivers/video/rockchip/mpp/mpp_rkvenc2.c @@ -857,8 +857,8 @@ static int rkvenc_isr(struct mpp_dev *mpp) if (task->irq_status & enc->hw_info->err_mask) { atomic_inc(&mpp->reset_request); /* dump register */ - if (mpp_debug_unlikely(DEBUG_DUMP_ERR_REG)) - mpp_task_dump_hw_reg(mpp, mpp_task); + + mpp_task_dump_hw_reg(mpp); } mpp_task_finish(mpp_task->session, mpp_task);