video: rockchip: mpp: rkvenc2: Improve dchs process

1. Add rkvenc2 pagefault handler to dump memory region used in task.
2. Move rkvenc2_patch_dchs before write hardware register.
3. Add more dchs status log with DEBUG_CORE flag.

Signed-off-by: Herman Chen <herman.chen@rock-chips.com>
Change-Id: I3fd5e14a3a5dd347373e3bc4e21d41db8c05fd21
This commit is contained in:
Herman Chen
2022-03-17 09:57:56 +08:00
committed by Tao Huang
parent 4e7fb3b61d
commit 77b73c0f4a

View File

@@ -847,11 +847,14 @@ static void *rkvenc2_prepare(struct mpp_dev *mpp, struct mpp_task *mpp_task)
mpp_task = NULL;
mpp_dbg_core("core %d all busy %lx\n", core_id, queue->core_idle);
} else {
mpp_dbg_core("core %d set idle %lx\n", core_id, queue->core_idle);
unsigned long core_idle = queue->core_idle;
clear_bit(core_id, &queue->core_idle);
mpp_task->mpp = queue->cores[core_id];
mpp_task->core_id = core_id;
mpp_dbg_core("core %d set idle %lx -> %lx\n", core_id,
core_idle, queue->core_idle);
}
spin_unlock_irqrestore(&queue->running_lock, flags);
@@ -918,8 +921,8 @@ static void rkvenc2_patch_dchs(struct rkvenc_dev *enc, struct rkvenc_task *task)
if (dependency_core < 0) {
u32 dchs_val = (u32)task_id->val & (~(DCHS_RXE));
task->reg[RKVENC_CLASS_PIC].data[DCHS_CLASS_OFFSET] = dchs_val;
dchs[core_id].rxe = 0;
mpp_write_relaxed(&enc->mpp, DCHS_REG_OFFSET, dchs_val);
}
}
dchs[core_id].working = 1;
@@ -947,6 +950,17 @@ static void rkvenc2_update_dchs(struct rkvenc_dev *enc, struct rkvenc_task *task
spin_lock_irqsave(&ccu->lock_dchs, flags);
ccu->dchs[core_id].val = 0;
if (mpp_debug_unlikely(DEBUG_CORE)) {
union rkvenc2_dual_core_handshake_id *dchs = ccu->dchs;
union rkvenc2_dual_core_handshake_id *task_id = &task->dchs_id;
pr_info("core tx:rx 0 %s %d:%d %d:%d -- 1 %s %d:%d %d:%d -- task %d %d:%d %d:%d\n",
dchs[0].working ? "work" : "idle",
dchs[0].txid, dchs[0].txe, dchs[0].rxid, dchs[0].rxe,
dchs[1].working ? "work" : "idle",
dchs[1].txid, dchs[1].txe, dchs[1].rxid, dchs[1].rxe,
core_id, task_id->txid, task_id->txe, task_id->rxid, task_id->rxe);
}
spin_unlock_irqrestore(&ccu->lock_dchs, flags);
}
@@ -962,6 +976,8 @@ static int rkvenc_run(struct mpp_dev *mpp, struct mpp_task *mpp_task)
/* clear hardware counter */
mpp_write_relaxed(mpp, 0x5300, 0x2);
rkvenc2_patch_dchs(enc, task);
for (i = 0; i < task->w_req_cnt; i++) {
int ret;
u32 s, e, off;
@@ -987,14 +1003,16 @@ static int rkvenc_run(struct mpp_dev *mpp, struct mpp_task *mpp_task)
}
}
if (mpp_debug_unlikely(DEBUG_CORE))
dev_info(mpp->dev, "core %d dchs %08x\n", mpp->core_id,
mpp_read_relaxed(&enc->mpp, DCHS_REG_OFFSET));
/* flush tlb before starting hardware */
mpp_iommu_flush_tlb(mpp->iommu_info);
/* init current task */
mpp->cur_task = mpp_task;
rkvenc2_patch_dchs(enc, task);
/* Flush the register before the start the device */
wmb();
mpp_write(mpp, enc->hw_info->enc_start_base, start_val);
@@ -1079,6 +1097,7 @@ static int rkvenc_isr(struct mpp_dev *mpp)
struct mpp_task *mpp_task;
struct rkvenc_dev *enc = to_rkvenc_dev(mpp);
struct mpp_taskqueue *queue = mpp->queue;
unsigned long core_idle;
mpp_debug_enter();
@@ -1111,8 +1130,11 @@ static int rkvenc_isr(struct mpp_dev *mpp)
}
mpp_task_finish(mpp_task->session, mpp_task);
core_idle = queue->core_idle;
set_bit(mpp->core_id, &queue->core_idle);
mpp_dbg_core("core %d isr idle %lx\n", mpp->core_id, queue->core_idle);
mpp_dbg_core("core %d isr idle %lx -> %lx\n", mpp->core_id, core_idle,
queue->core_idle);
mpp_debug_leave();
@@ -1143,6 +1165,7 @@ static int rkvenc_finish(struct mpp_dev *mpp, struct mpp_task *mpp_task)
reg[j] = mpp_read_relaxed(mpp, msg.offset + j * sizeof(u32));
}
/* revert hack for irq status */
reg = rkvenc_get_class_reg(task, task->hw_info->int_sta_base);
if (reg)
@@ -1469,6 +1492,9 @@ static int rkvenc_reset(struct mpp_dev *mpp)
}
set_bit(mpp->core_id, &queue->core_idle);
if (enc->ccu)
enc->ccu->dchs[mpp->core_id].val = 0;
mpp_dbg_core("core %d reset idle %lx\n", mpp->core_id, queue->core_idle);
mpp_debug_leave();
@@ -1894,6 +1920,23 @@ err_sram_map:
return ret;
}
static int rkvenc2_iommu_fault_handle(struct iommu_domain *iommu,
struct device *iommu_dev,
unsigned long iova, int status, void *arg)
{
struct mpp_dev *mpp = (struct mpp_dev *)arg;
struct rkvenc_dev *enc = to_rkvenc_dev(mpp);
struct mpp_task *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;
}
static int rkvenc_core_probe(struct platform_device *pdev)
{
int ret = 0;
@@ -1943,6 +1986,7 @@ static int rkvenc_core_probe(struct platform_device *pdev)
}
mpp->session_max_buffers = RKVENC_SESSION_MAX_BUFFERS;
enc->hw_info = to_rkvenc_info(mpp->var->hw_info);
mpp->iommu_info->hdl = rkvenc2_iommu_fault_handle;
rkvenc_procfs_init(mpp);
rkvenc_procfs_ccu_init(mpp);