Does the RPi* DMA code in the kernel handle the distinctions between the 3 kinds of DMA engines?

From: Mark Millard <>
Date: Fri, 02 Dec 2022 23:34:24 UTC
Does the RPi* DMA code in the kernel handle the distinctions between
the 3 kinds of DMA engines?

The engine types are named:

DMA engine	(30-bit DMA addressing: 1 GiByte, 256-bit burst space)

DMA lite engine (only 128 bit burst space,
		only 16 bits for DMA length (?_TXFR_LEN XLENGTH),
		only about half the bandwidth of type DMA,
		uses ENABLE Regsiter 31:28 "PAGELITE" instead of
                27:24 "PAGE" to control the "1G SDRAM ram page" used)

DMA4 engine	(not the same as dma4 of specific engines dma0..dma15;
		different register map offset pattern after ??_CB,
		more register map offsets than the other DMA types,
		40 address bits with 40:32 in ??_SRCI/??_DESTI 7:0,
		??_CB bits 31:0 are for Control Block Address 36:5,
		higher performance via "uncoupled read/write design",
		write burst capable,
		directly accesses the BCM2711 35-bit address bus
		so bypasses the paginging registers that are used
		for types DMA and DMA lite)

The specific instances of engines (channels) have types:

dma0 ..dma6 : Always type DMA (so far?)
dma7 ..dma10: Always type DMA lite (so far?)
dma11..dma14: Not the same for BCM2711:
		For BCM2711, type DMA4
		Otherwise, type DMA lite (so far?)

BCM2711 specific note:
dma11 "is additionally able to access the PCIe interface".

For reference, the live device tree for the BCM2711 has
(examples from an 8 GiByte RPi4B):

		dma@7e007000 {
			compatible = "brcm,bcm2835-dma";
			reg = <0x7e007000 0x00000b00>;
			interrupts = <0x00000000 0x00000050 0x00000004 0x00000000 0x00000051 0x00000004 0x00000000 0x00000052 0x00000004 0x00000000 0x00000053 0x00000004 0x00000000 0x00000054 0x00000004 0x00000000 0x00000055 0x00000004 0x00000000 0x00000056 0x00000004 0x00000000 0x00000057 0x00000004 0x00000000 0x00000057 0x00000004 0x00000000 0x00000058 0x00000004 0x00000000 0x00000058 0x00000004>;
			interrupt-names = "dma0", "dma1", "dma2", "dma3", "dma4", "dma5", "dma6", "dma7", "dma8", "dma9", "dma10";
			#dma-cells = <0x00000001>;
			brcm,dma-channel-mask = <0x000007f5>;
			phandle = <0x0000000b>;
. . .
		dma@7e007b00 {
			compatible = "brcm,bcm2711-dma";
			reg = <0x00000000 0x7e007b00 0x00000000 0x00000400>;
			interrupts = <0x00000000 0x00000059 0x00000004 0x00000000 0x0000005a 0x00000004 0x00000000 0x0000005b 0x00000004 0x00000000 0x0000005c 0x00000004>;
			interrupt-names = "dma11", "dma12", "dma13", "dma14";
			#dma-cells = <0x00000001>;
			brcm,dma-channel-mask = <0x00003000>;
			phandle = <0x00000040>;

Note: dma15 "is exclusively used by the VPU" and I ignore it here.

I ask, in part, because of:

#define    BCM_DMA_CH_MAX          12

that is used via the likes of:

struct bcm_dma_ch sc_dma_ch[BCM_DMA_CH_MAX];


for (i = 0; i < BCM_DMA_CH_MAX; i++) {

But the BCM2711 only has 0..10 defined for brcm,bcm2835-dma
in its device live device tree, although brcm,dma-channel-mask
allows avoiding what is missing. 11..14 are defined in
brcm,bcm2711-dma instead --but the code makes no use of it,
given the brcm,bcm2835-dma's brcm,dma-channel-mask.

But/also, the brcm,bcm2835-dma's brcm,dma-channel-mask includes
examples of both "DMA engine" and "DMA lite engine", so still
leading to some distinctions that should be made.

So far, I've not been able to identify code/data making any
distinctions for the likes of dma7..dma14 beyond what
brcm,dma-channel-mask completely avoids.

Note:	So far as I can tell, the PCIe bus-mastering that is
	associated with the XHCI in the BCM2711 is separate
	from the above.

	The "B0T" BCM2711 parts have a 3 GiByte limitation just
	for this PCIe bus-mastering(/XHCI) and the "C0T" BCM2711
	parts no longer are limited to a subset of the available
	RAM for PCIe bus-mastering(/XHCI). Examples from 8 GiByte

		dma-ranges = <0x02000000 0x00000004 0x00000000 0x00000000 0x00000000 0x00000000 0xc0000000>;
		dma-ranges = <0x02000000 0x00000004 0x00000000 0x00000000 0x00000000 0x00000002 0x00000000>;

	So, XHCI related bounce buffering could be avoided on 
	"C0T" parts.

	For BCM2711 "B0T" vs. "C0T" there is also emmc2bus with:

		dma-ranges = <0x00000000 0xc0000000 0x00000000 0x00000000 0x40000000>;
		(so: matching the soc dma-ranges, other than the #of cells for holding the 1st addr)
		dma-ranges = <0x00000000 0x00000000 0x00000000 0x00000000 0xfc000000>;
		(so not matching the soc dma-ranges)

	emmc2bus contains:

		emmc2@7e340000 {
			compatible = "brcm,bcm2711-emmc2";
			. . .

	which looks to mean that the dma_ranges for brcm,bcm2711-emmc2
	changed to not match the soc dma-ranges. I've not noticed any
	code/data that would track this change.

	I do not know the implications of the difference for
	what FreeBSD's code does --or if FreeBSD ever tries to
	use the brcm,bcm2711-emmc2 .

Mark Millard
marklmi at