最近在xilinx论坛上看到以下的讨论:
XDMA 异常状态(busy) 如何恢复?
使用zynq7035 xdma gen2, x8,mem模式x ,正常运行时没有问题。
c2h模式下,mem 接口是由 stream 的数据转换而来。
一旦 windows 驱动侧开启的c2h.read ,FPGA当中的stream 没有产生数据,读取就会卡住,在这个过程中软件关闭,xdma 的逻辑就会陷入异常,一直处在busy状态。
无论是重装驱动还是 重启软件都不能正常启动,必须重启电脑。才能恢复?
有没有什么方式能够在xdma 进入busy状态后 强行恢复?比如说控制寄存器,或者对驱动进行软件操作?
论坛中始终没有答案,恰巧自己在用的时候也出现了上述的问题,我的运行环境如下:
硬件:NVIDIA TX2I
软件:官方的XDMA驱动,github上的201901版本
通过查看输出的信息,调试发现是由于在XDMA引擎stop之后没有设置相应的结束状态导致的,更改如下:
/**
* xdma_engine_stop() - stop an SG DMA engine
*
*/
static int xdma_engine_stop(struct xdma_engine *engine)
{
u32 w;
if (!engine) {
pr_err("dma engine NULL\n");
return -EINVAL;
}
dbg_tfr("%s(engine=%p)\n", __func__, engine);
w = 0;
w |= (u32)XDMA_CTRL_IE_DESC_ALIGN_MISMATCH;
w |= (u32)XDMA_CTRL_IE_MAGIC_STOPPED;
w |= (u32)XDMA_CTRL_IE_READ_ERROR;
w |= (u32)XDMA_CTRL_IE_DESC_ERROR;
if (poll_mode) {
w |= (u32)XDMA_CTRL_POLL_MODE_WB;
} else {
w |= (u32)XDMA_CTRL_IE_DESC_STOPPED;
w |= (u32)XDMA_CTRL_IE_DESC_COMPLETED;
}
dbg_tfr("Stopping SG DMA %s engine; writing 0x%08x to 0x%p.\n",
engine->name, w, (u32 *)&engine->regs->control);
write_register(w, &engine->regs->control,
(unsigned long)(&engine->regs->control) -
(unsigned long)(&engine->regs));
engine->running = 0; //++++++++++++++++++++++++++++++
/* dummy read of status register to flush all previous writes */
dbg_tfr("%s(%s) done\n", __func__, engine->name);
return 0;
}