天天看點

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;

}