DMA Enablement with ACPI

DMA Controllers

DMA controllers are declared in Core System Resource Tabel ( CSRT ).

https://uefi.org/sites/default/files/resources/CSRT v2.pdf

Example from an intel platform

[000h 0000 4] Signature : "CSRT" [Core System Resource Table] [004h 0004 4] Table Length : 0000014C [008h 0008 1] Revision : 00 [009h 0009 1] Checksum : 8E [00Ah 0010 6] Oem ID : "INTEL " [010h 0016 8] Oem Table ID : "LANFORDC" [018h 0024 4] Oem Revision : 00000005 [01Ch 0028 4] Asl Compiler ID : "MSFT" [020h 0032 4] Asl Compiler Revision : 0100000D [024h 0036 4] Length : 00000088 [028h 0040 4] Vendor ID : 4C544E49 [02Ch 0044 4] Subvendor ID : 00000000 [030h 0048 2] Device ID : 9C60 [032h 0050 2] Subdevice ID : 0000 [034h 0052 2] Revision : 0002 [036h 0054 2] Reserved : 0000 [038h 0056 4] Shared Info Length : 0000001C [03Ch 0060 2] Major Version : 0001 [03Eh 0062 2] Minor Version : 0000 [040h 0064 4] MMIO Base Address Low : D1A10000 [044h 0068 4] MMIO Base Address High : 00000000 [048h 0072 4] GSI Interrupt : 0000002A [04Ch 0076 1] Interrupt Polarity : 02 [04Dh 0077 1] Interrupt Mode : 00 [04Eh 0078 1] Num Channels : 06 [04Fh 0079 1] DMA Address Width : 20 [050h 0080 2] Base Request Line : 0000 [052h 0082 2] Num Handshake Signals : 0010 [054h 0084 4] Max Block Size : 00001000 [058h 0088 4] Length : 0000000C [05Ch 0092 2] Type : 0003 [05Eh 0094 2] Subtype : 0001 [060h 0096 4] UID : 20495053 [064h 0100 4] Length : 0000000C [068h 0104 2] Type : 0003 [06Ah 0106 2] Subtype : 0000 [06Ch 0108 4] UID : 30414843

Vendor-specific data can be provided as part of shared group info descriptor or resource descriptor for individual controllers, including information like IRQ, allocated, register base address, and any other vendor-specific data.

ACPI doesn’t mandate a separate entry for DMA controllers in DSDT table and it is up to the implementation. Intel platforms seem to have a separate DMA controller entry in DSDT but some of the Arm platforms looked at ( NXP I.MX8MP, Qualcomm snapdragon, etc.) don’t seem to have a DSDT entry.

DMA Clients

DMA clients can request for resources using FixedDMA resource descriptor.

FixedDMA (SDMA_REQ_SAI3_TX /*request line */, 1 /* channel id*/ , Width32Bit, )

Linux ACPI Implementation

https://git.linaro.org/kernel-org/linux-next.git/tree/drivers/dma/acpi-dma.c

Linux has an acpi-dma layer that provides the following main features

  • Register ACPI-based DMA controller with CSRT table

  • Handle FixedDMA from DMA clients and match it with the DMA controller

The current implementation requires the following ACPI definitions

  • DMA Controller definition in DSDT with resource allocated

  • Shared Group Info in CSRT table. This is Intel specific and few important properties are below:

    • MMIO Base Address Low

    • MMIO Base Address High

    • GSI Interrupt

    • Interrupt Polarity

    • Base Request Line

    • Num Handshake Signals

  • _CCA (cache coherency attribute) ASL method definition for Arm platforms.

    • DMA will not be registered if the kernel doesn’t see this attribute.

NXP I.MX8MP Enablement

The following changes had to be made to the ACPI table to enumerate DMA controllers in Linux

  • Add DMA controllers in DSDT

Device(DMA1) { Name (_HID, "NXP0181") // _HID: Hardware ID Name (_UID, One) // _UID: Unique ID Method (_STA) { Return(0xF) } // Hardware based cache coherency is not available // OS must do cache flushing to avoid stale data Method (_CCA) { Return(Zero) } Method (_CRS, 0x0, NotSerialized) { Name (RBUF, ResourceTemplate () { MEMORY32FIXED(ReadWrite, 0x30BD0000, 0x1000, ) Interrupt(ResourceConsumer, Level, ActiveHigh, Exclusive) { 34 } }) Return(RBUF) } Name (_DSD, Package () { ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"), Package () { Package () {"clk-ratio", 0}, Package () {"fsl,sdma-ram-script-name", "imx/sdma/sdma-imx7d.bin"}, Package () {"spba-start-addr", 0x30c00000}, Package () {"spba-end-addr", 0x30c01000}, } }) }
  • Extend the CSRT table to add shared info ( This is Intel specific descriptor and cannot be used on Arm. We need to standardise this descriptor or add APIs in Linux to register DMA controller without shared info)

The I.MX SDMA drivers have been updated to handle the new properties from DSD and do the ACPI DMA registration.

Linux:: https://gitlab.com/LinaroLtd/clientpc/linux/-/merge_requests/7/

EDK2: https://gitlab.com/LinaroLtd/clientpc/edk2-platforms/-/merge_requests/5

We’ve tested the DMA controllers with UART(3) in a test loop mode with linux-serial-test tool.

UART Device definition is given below. FixedDMA property is used to request the DMA lines needed for the device.