hi3531 pcie 控制器内含dma 控制器,dma 控制器包含有兩個dma 通道(一個
dma 讀通道和一個dma 寫通道)。pcie 控制器内包含的dma 控制器用于大資料量
的存儲器讀寫事務,以提高資料傳輸的速率。
dma 控制器可以實作如下的存儲器讀寫事務:
dma 控制寄存器
軟體可通過dma 控制寄存器來配置dma 傳輸,也可以通過dma 控制寄存器啟動和
停止dma 傳輸。dma 控制寄存器位于pcie 控制器的配置寄存器空間内,dma 控制
寄存器的定義請參考本章的pcie 寄存器描述。
注意中提到的部分dma 控制寄存器包含:
dma_ch_ctrl 寄存器;
dma_trans_size 寄存器;
dma_sar_low 和dma_sar_high 寄存器;
dma_dar_low 和dma_dar_high 寄存器;
dma_link_pt_low 和dma_link_pt_high 寄存器。
1. 軟體設定dma_ch_index[ch_dir]=1,表明後續操作目标寄存器為讀通道控制寄存
器。
2. 軟體設定dma_trans_size=0x400,表明傳輸長度為1024byte。
dma 讀/寫通道使能
dma 通道在系統複位後預設是沒有使能的,要使用pcie 的dma 通道,需使能dma
的讀寫通道。
通過設定dma_rd_engine_en[dma_rd_engine_en]為1,使能dma 讀通道。
通過設定dma_wr_engine_en[dma_wr_engine_en]為1,使能dma 寫通道。
dma 源位址和目标位址
dma 寫:源位址(sar)為本地記憶體空間,目标位址(dar)為對端裝置記憶體空間。
dma 讀:源位址(sar)為對端裝置記憶體空間,目标位址(dar)為本地記憶體空間。
配置dma 讀或寫通道的dma_sar_low 和dma_sar_high 寄存器可以指定dma
傳輸的源位址,配置dma 讀或寫通道的dma_dar_low 和dma_dar_high 寄存
器可以指定dma 傳輸的目的位址。dma 源位址和目的位址寄存器請參看pcie dma
控制寄存器定義。
dma 傳輸過程中,源位址和目的位址寄存器随着傳輸過程而遞增。可以通過讀取源地
址和目的位址寄存器的值來确定dma 目前傳輸所擷取資料的源位址和目前所寫資料
的目标位址。
dma 源位址和dma 目的位址都是雙位元組對齊的,是以最低兩比特都必須設定為0。
在傳輸過程中此最低兩比特也一直為0。
dma 傳輸長度
dma 讀或寫操作的傳輸長度由dma 讀或寫通道的dma_trans_size 寄存器來指
定。該寄存器的值表示dma 請求傳輸的資料的位元組數。在dma 傳輸過程,此寄存器
的值會随着傳輸過程遞減,可以通過讀取此寄存器确定目前還有多少位元組未傳輸。傳
輸成功結束後此寄存器值應該為0。
dma 傳輸長度取值範圍為:最小為1 個位元組,最大為4g 位元組。
啟動dma 傳輸
在配置好dma 讀通道的控制寄存器之後,通過向
dma_rd_doorbell[rd_doorbell_num]寫入0 來啟動dma 讀傳輸。
在配置好dma 寫通道的控制寄存器之後,通過向
dma_wr_doorbell[wr_doorbell_num]寫入0 來啟動dma 寫傳輸。
停止dma 傳輸
在dma 傳輸過程中如果需要停止dma 傳輸,可以通過如下寄存器控制來手動停止
dma 讀或者dma 寫傳輸:
通過向dma_rd_doorbell[dma_rd_stop]寫入1 來停止dma 讀傳輸。
通過向dma_rd_doorbell[dma_wr_stop]寫入1 來停止dma 讀傳輸。
如果dma 傳輸過程中沒有發生錯誤,dma 傳輸将在所有的資料傳輸完成後自動停
止。
hi_mpi_sys_setreg(0x20800a6c,0x00000000);//bit31 0 write dma_ch_index
hi_mpi_sys_setreg(0x20800a78,0x00000010);//dma_trans_size 10
hi_mpi_sys_setreg(0x2080097c,0x00000001);//使能寫操作
hi_mpi_sys_setreg(0x20800a7c,0xc0000000);// 源位址—低位
hi_mpi_sys_setreg(0x20800a80,0x00000000);// 源位址—高位
hi_mpi_sys_setreg(0x20800a84,0x0544f000);// 目标位址—低位 pc機申請的實體位址
hi_mpi_sys_setreg(0x20800a88,0x00000000);// 目标位址—高位
hi_mpi_sys_setreg(0x20800980,0x00000000);//啟動寫操作