天天看点

XDMA传输时进入Busy后恢复

最近在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之后没有设置相应的结束状态导致的,更改如下:

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; //++++++++++++++++++++++++++++++

    dbg_tfr("%s(%s) done\n", __func__, engine->name);

    return 0;

}