s3c2440的dma操作的一般步驟
一般的,在s3c2440中,要想進(jìn)行dma傳輸,需要一下七個(gè)步驟:
本文引用地址:http://www.biyoush.com/article/201611/318126.htm一:
int s3c2410_dma_request(unsigned int channel,
struct s3c2410_dma_client *client,
void *dev)
s3c2410_dma_client的定義為:
struct s3c2410_dma_client {
char *name;
};
以u(píng)da1314的驅(qū)動(dòng)為例,驅(qū)動(dòng)中定義了兩個(gè)s3c2410_dma_client
static struct s3c2410_dma_client s3c2410iis_dma_out= {
.name = "I2SSDO",
};
static struct s3c2410_dma_client s3c2410iis_dma_in = {
.name = "I2SSDI",
};
二:
s3c2410_dma_config(dmach_t channel,int xferunit,int dcon)
s3c2410_dma_config(dmach_t channel,int xferunit,int dcon)
根據(jù)xferunit以及dcon設(shè)置通道的控制寄存器DCONx
xferunit為每次傳輸?shù)臄?shù)據(jù)大?。?:byte 1:half word 2:word
三:
int s3c2410_dma_set_buffdone_fn(dmach_t channel, s3c2410_dma_cbfn_t rtn)
設(shè)置相應(yīng)的dma通道完成一次dma傳輸后的回調(diào)函數(shù),也即是s3c2410_dma_enqueue完成后會(huì)調(diào)用的函數(shù)
回調(diào)函數(shù)應(yīng)具有一下格式:
typedef void (*s3c2410_dma_cbfn_t)(struct s3c2410_dma_chan *,
void *buf, int size,
enum s3c2410_dma_buffresult result);
buf可以傳遞一些有用的數(shù)據(jù),在uda1314的驅(qū)動(dòng)中,傳遞的是audio_buf_t結(jié)構(gòu)體
四:
int s3c2410_dma_setflags(dmach_t channel, unsigned int flags)
在1314驅(qū)動(dòng)中,
flags = S3C2410_DMAF_AUTOSTART;
s3c2410_dma_setflags(channel, flags);
五:
int s3c2410_dma_devconfig(int channel,
enum s3c2410_dmasrc source,
int hwcfg,
unsigned long devaddr)
參數(shù)意義:
* source: S3C2410_DMASRC_HW: source is hardware
* S3C2410_DMASRC_MEM: source is memory
*
* hwcfg: the value for xxxSTCn register,
* bit 0: 0=increment pointer, 1=leave pointer
* bit 1: 0=soucre is AHB, 1=soucre is APB
*
* devaddr: physical address of the source
如果source為S3C2410_DMASRC_HW(外設(shè)), 配置它的S3C2410_DMA_DISRCC,S3C2410_DMA_DISRC,S3C2410_DMA_DIDSTC
如果source為S3C2410_DMASRC_MEM(內(nèi)存),配置它的S3C2410_DMA_DISRCC,S3C2410_DMA_DIDST,S3C2410_DMA_DIDSTC
由此可見,地址方面,只配置涉及外設(shè)的地址
以u(píng)da1341的驅(qū)動(dòng)為例,這幾個(gè)值為
source = S3C2410_DMASRC_MEM;
hwcfg = 3;
devaddr = 0x55000010;
六:
void *dma_alloc_coherent(struct device *dev,size_t size,dma_addr_t *dma_handle,int flag)
利用此函數(shù),申請(qǐng)dmabuf,建立一致性映射
以u(píng)da1314的驅(qū)動(dòng)為例,調(diào)應(yīng)的實(shí)例為:
dmabuf = dma_alloc_coherent(NULL, dmasize, &dmaphys, GFP_KERNEL);(在audio_setup_buf函數(shù)中)
dmabuf為虛擬地址,dmaphys是總線地址,虛擬地址用來讓驅(qū)動(dòng)寫buf用,dmaphys用來傳給dma。
dma關(guān)心的是總線地址。
關(guān)于總線地址與物理地址的區(qū)別,這里有很好的說明http://hi.baidu.com/zengzhaonong/blog/item/eeb8003083276e9ba9018ee3.html,感謝儒雅,現(xiàn)摘錄如下:
1) 物理地址是與CPU相關(guān)的。在CPU的地址信號(hào)線上產(chǎn)生的就是物理地址。在程序指令中的虛擬地址經(jīng)過段映射和頁面映射后,就生成了物理地址,這個(gè)物理地址被放到CPU的地址線上。
2) 總線地址,顧名思義,是與總線相關(guān)的,就是總線的地址線或在地址周期上產(chǎn)生的信號(hào)。外設(shè)使用的是總線地址。
3) 物理地址與總線地址之間的關(guān)系由系統(tǒng)的設(shè)計(jì)決定的。在x86平臺(tái)上,物理地址與PCI總線地址是相同的。在其他平臺(tái)上,也許會(huì)有某種轉(zhuǎn)換,通常是線性的轉(zhuǎn)換。
比如:CPU需要訪問物理地址是0xfa000的單元,那么在x86平臺(tái)上,會(huì)產(chǎn)生一個(gè)PCI總線上對(duì)0xfa000地址的訪問。這個(gè)單元或者是內(nèi)存中,或者是某個(gè)卡上的存儲(chǔ)單元,甚至可能這個(gè)地址上沒有對(duì)應(yīng)的存儲(chǔ)器。而在另外一個(gè)平臺(tái)上,或許在PCI總線上產(chǎn)生的訪問是針對(duì)地址為0x1fa000的單元。
上述函數(shù)是建立一致性映射。使用dma_map_single函數(shù)可以建立一致性映射:
2.當(dāng)只有一個(gè)緩沖區(qū)要被傳輸?shù)臅r(shí)候,使用dma_map_single函數(shù)來映射它
dma_addr_t dma_map_single(struct device *dev,void *buffer,size_t size, enum dma_data_direction direction)
3.為page結(jié)構(gòu)指針指向的緩沖區(qū)建立映射,單頁流式映射:
dma_addr_t dma_map_page(struct device *dev,struct page *page ,unsigned long offset ,size_t size,enum dma_data_direction direction);
4.分散/聚集映射
int dma_map_sg(struct device *dev,struct scatterlist *sg,int nents,enum dma_alloc_coherent direction);
還不知道哪種情況下用流式映射,哪種用一致映射。對(duì)于s3c2440,其mmc驅(qū)動(dòng)中用到了分散聚集(流式)映射,聲卡驅(qū)動(dòng)中又用到了一致映射。
七:
int s3c2410_dma_enqueue(unsigned int channel, void *id,
dma_addr_t data, int size)
發(fā)起一次dma傳輸
參數(shù)意義:
* id the device drivers id information for this buffer
* data the physical address of the buffer data
* size the size of the buffer in bytes
將dma_alloc_coherent中得到的dmaphys傳遞給s3c2410_dma_enqueue. s3c2410_dma_enqueue提交一次dma請(qǐng)求,當(dāng)dma通道可用的時(shí)候通過s3c2410_dma_loadbuffer開始一次傳輸,傳輸完成后會(huì)產(chǎn)生irq中斷。其dma的中斷服務(wù)函數(shù)中會(huì)繼續(xù)啟動(dòng)dma請(qǐng)求隊(duì)列中的請(qǐng)求,傳輸剩下的數(shù)據(jù)。
評(píng)論