The DMA functionality on the Duo board has been tested successfully in the Mem2Mem mode. The following is the test code and the corresponding log output:
Test Code: duo-dma-test.c in attachment
Test Log:
[ 1.735104] dma dma0chan0: dma0chan0: allocating
[ 1.740268] dmaengine: __dma_request_channel: success (dma0chan0)
[ 1.747388] dma dma0chan0: dma0chan0: memcpy: src: 0x0000000081da0000 dst: 0x0000000081da1000 length: 163
[ 1.758468] dma dma0chan0: dma0chan0: len: 16, xfer_width: 2, num: 1
[ 1.765285] dma dma0chan0: dma0chan0: block_ts: 4, max_block_ts: 1024, xfer_width: 2
[ 1.773917] dma dma0chan0: running: len: 0, xfer_width: 2, xfer_len: 16, num: 0
[ 1.781742] dw_axi_dmac_platform 4330000.dma-controller: vchan (____ptrval____): txd (____ptrval____)[2]d
[ 1.792775] dma dma0chan0: dma0chan0: started 2
[ 2.819995] offset 0: af vs af
[ 2.823281] offset 1: af vs af
[ 2.826668] offset 2: af vs af
[ 2.830044] offset 3: af vs af
[ 2.833411] offset 4: af vs af
[ 2.836779] offset 5: af vs af
[ 2.840145] offset 6: af vs af
[ 2.843378] offset 7: af vs af
[ 2.846713] offset 8: af vs af
[ 2.850077] offset 9: af vs af
[ 2.853551] offset 10: af vs af
[ 2.857038] offset 11: af vs af
[ 2.860498] offset 12: af vs af
[ 2.863950] offset 13: af vs af
[ 2.867274] offset 14: af vs af
[ 2.870696] offset 15: af vs af
[ 2.874150] DMA transfer succeeded
[ 2.877956] dma dma0chan0: dma0chan0: 1 descs put, 0 still allocated
[ 2.884864] dma dma0chan0: dma0chan0: free resources, descriptor still allocated: 0
Prior to correcting the snps,data-width value, the driver incorrectly assumed a data width of 128 bits, resulting in only 1/4 of the intended memory being transferred. The earlier (incorrect) test log would look like:
# alloc 16, memcpy 16
[ 1.752567] dma dma0chan0: dma0chan0: allocating
[ 1.757717] dmaengine: __dma_request_channel: success (dma0chan0)
[ 1.764882] dma dma0chan0: dma0chan0: memcpy: src: 0x0000000081da0000 dst: 0x0000000081da1000 length: 3
[ 1.775972] dma dma0chan0: dma0chan0: len: 16, xfer_width: 4, num: 1
[ 1.783195] dw_axi_dmac_platform 4330000.dma-controller: vchan (____ptrval____): txd (____ptrval____)[d
[ 1.794245] dma dma0chan0: dma0chan0: started 2
[ 2.820446] offset 0: af vs af
[ 2.823730] offset 1: af vs af
[ 2.827127] offset 2: af vs af
[ 2.830536] offset 3: af vs af
[ 2.833917] offset 4: af vs 00
[ 2.837278] offset 5: af vs 00
[ 2.840645] offset 6: af vs 00
[ 2.843878] offset 7: af vs 00
[ 2.847219] offset 8: af vs 00
[ 2.850588] offset 9: af vs 00
[ 2.854065] offset 10: af vs 00
[ 2.857552] offset 11: af vs 00
[ 2.861015] offset 12: af vs 00
[ 2.864472] offset 13: af vs 00
[ 2.867793] offset 14: af vs 00
[ 2.871225] offset 15: af vs 00
[ 2.874684] DMA transfer succeeded
[ 2.878487] dma dma0chan0: dma0chan0: 1 descs put, 0 still allocated
[ 2.885385] dma dma0chan0: dma0chan0: free resources, descriptor still allocated: 0
The Duo-S board's DMA controller supports a 32-bit bus width. Although this is not explicitly mentioned in the manual, it has been verified through testing and the vendor's code. When the configuration is incorrect, the block transfer size set by the DMA controller can exceed the hardware's maximum supported size. This results in missing data during each transfer. Relevant Code:
// Extracted from vendor code
/*
* for mem2mem type we defaultly set the src/dst width bits
* to max value 32(axi bus width) consider of performence,
* you can change it by dts.
*/
trans_width = __ffs(data_width | src | dest | len);
snps,data-width stands for power of width, which should be 32 bits (1Byte * 2 ^ 2)
diff --git a/arch/riscv/boot/dts/sophgo/cv18xx.dtsi b/arch/riscv/boot/dts/sophgo/cv18xx.dtsi
index aa635c5d436a..ccb4dfb8a794 100644
--- a/arch/riscv/boot/dts/sophgo/cv18xx.dtsi
+++ b/arch/riscv/boot/dts/sophgo/cv18xx.dtsi
@@ -521,7 +521,7 @@ dmac: dma-controller@4330000 {
1024 1024 1024 1024>;
snps,priority = <0 1 2 3 4 5 6 7>;
snps,dma-masters = <2>;
- snps,data-width = <4>;
+ snps,data-width = <2>;
status = "disabled";
};
Link to mainline dts: https://github.com/torvalds/linux/blob/master/arch/riscv/boot/dts/sophgo/cv18xx.dtsi#L332