DMA传输,总的来说就是:
硬件上,会有对应的控制寄存器ctrl和配置寄存器config,
比如你想要从内存一个地址addr传输,N个字word(32bit)的数据到设备dev上,
那么你就要先去根据你的请求,去配置config寄存器,首先是传输方向,
是DMA_TO_DEVICE,然后是源地址source address是你的内存地址addr,
和目标destination address是你的dev的DATA寄存器地址,
然后要传输额transfer size是N个,每个位宽是32bit,
将源地址,目标地址,位宽,DMA传输方向设置好,
整理成一个结构,专有名称叫做LLI(Link List Item),把这个LLi设置到ctrl里面。
然后去enable DMA,DMA就可以按照你的要求,把数据传输过去了。
这样的DMA叫做single DMA传输,LLI中的next lli的域设置为空,表示就一个LLI要传输。
如果源地址或目标地址是多个分散的地址,叫做scatter/gather DMA,
就要将这些LLI组合一下,即将第一个LLI的next lli那个域,设置成下一个LLI的地址,
这样一个个链接起来,最后一个LLI的nex lli的域为空,这样设置好后,将第一个LLI的值写入到ctrl中,DMA就会自动地去执行第一个LLI的数据传输,传完后,发现next lli不为空,就找到next lli的位置,
找到对应的配置,开始这个lli的数据传送,直至传完所有的数据为止。
说完了DMA的由来和基本概念后,下面来分析一下,具体的ARM的PL08x驱动是如何实现的。