/*
* Overall DMAC remains enabled always.
*
* Disabling individual channels could lose data.
*
* Disable the peripheral DMA after disabling the DMAC
* in order to allow the DMAC FIFO to drain, and
* hence allow the channel to show inactive
*
*/
void pl08x_disable_dmac_chan(unsigned int ci)
{
unsigned int reg;
unsigned int chan_base = (unsigned int)pd.base
+ PL08X_OS_CHAN_BASE;
chan_base += ci * PL08X_OS_CHAN;
/*
* Ignore subsequent requests
*/
reg = readl(chan_base + PL08X_OS_CCFG);
reg |= PL08X_MASK_HALT;
writel(reg, chan_base + PL08X_OS_CCFG);
/* Wait for channel inactive */
reg = readl(chan_base + PL08X_OS_CCFG);
while (reg & PL08X_MASK_ACTIVE)
reg = readl(chan_base + PL08X_OS_CCFG);
reg = readl(chan_base + PL08X_OS_CCFG);
reg &= ~PL08X_MASK_CEN;
writel(reg, chan_base + PL08X_OS_CCFG);
mb();
return;
}
|
此处对于disable一个DMA的channel的做法,是根据datasheet中的描述: “Disabling a DMA channel without losing data in the FIFO To disable a DMA channel without losing data in the FIFO:
即先设置Halt位,然后一直轮询检测对应channel,直到inactive,然后再清空对应的Channel Enable位,如果直接不做任何检测判断,上来就去清空对应的Enable位,那么就会“losing data in the FIFO ”,丢失了FIFO中的数据,是不太安全的 |