arm64/imx9: Add eDMA driver

This driver supports both eDMA3 and eDMA4 (also referred to as DMA0 / DMA1
in some contexts..)

The IP blocks are almost identical, with sufficiently minor differences
to use them via a unified driver. The price is a great amount of code
obfuscation in the hardware description layer.
This commit is contained in:
Ville Juven 2024-04-05 12:59:22 +03:00 committed by Xiang Xiao
parent 5c3fc2796b
commit 89752e9993
10 changed files with 2807 additions and 4 deletions

View File

@ -31,6 +31,11 @@
* Pre-processor Definitions
****************************************************************************/
/* Cache line sizes (in bytes)for the i.MX9 (Cortex-A55) */
#define ARMV8A_DCACHE_LINESIZE 64 /* 64 bytes (16 words) */
#define ARMV8A_ICACHE_LINESIZE 64 /* 64 bytes (16 words) */
/* Number of bytes in x kibibytes/mebibytes/gibibytes */
#define KB(x) ((x) << 10)

View File

@ -31,6 +31,11 @@ config IMX9_FLEXIO_PWM
menu "i.MX9 Peripheral Selection"
config IMX9_EDMA
bool "eDMA"
default n
select ARCH_DMA
menu "LPUART"
config IMX9_LPUART
@ -293,8 +298,6 @@ endmenu # USB device controller driver (DCD) options
endif # IMX9_USBDEV
endmenu # iMX Peripheral Selection
config IMX9_GPIO_IRQ
bool "GPIO Interrupt Support"
default n
@ -547,6 +550,87 @@ menuconfig IMX9_LPSPI8
endmenu # LPSPI Peripherals
menu "eDMA Configuration"
depends on IMX9_EDMA
config IMX9_EDMA_NTCD
int "Number of transfer descriptors"
default 0
---help---
Number of pre-allocated transfer descriptors. Needed for scatter-
gather DMA. Make to be set to zero to disable in-memory TCDs in
which case only the TCD channel registers will be used and scatter-
will not be supported.
config IMX9_EDMA_ELINK
bool "Channeling Linking"
default n
---help---
This option enables optional minor or major loop channel linking:
Minor loop channel linking: As the channel completes the minor
loop, this flag enables linking to another channel. The link target
channel initiates a channel service request via an internal
mechanism that sets the TCDn_CSR[START] bit of the specified
channel.
If minor loop channel linking is disabled, this link mechanism is
suppressed in favor of the major loop channel linking.
Major loop channel linking: As the channel completes the minor
loop, this option enables the linking to another channel. The link
target channel initiates a channel service request via an internal
mechanism that sets the TCDn_CSR[START] bit of the linked channel.
config IMX9_EDMA_ERCA
bool "Round Robin Channel Arbitration"
default n
---help---
Normally, a fixed priority arbitration is used for channel
selection. If this option is selected, round robin arbitration is
used for channel selection.
config IMX9_EDMA_HOE
bool "Halt On Error"
default y
---help---
Any error causes the HALT bit to set. Subsequently, all service
requests are ignored until the HALT bit is cleared.
config IMX9_EDMA_CLM
bool "Continuous Link Mode"
default n
---help---
By default, A minor loop channel link made to itself goes through
channel arbitration before being activated again. If this option is
selected, a minor loop channel link made to itself does not go
through channel arbitration before being activated again. Upon minor
loop completion, the channel activates again if that channel has a
minor loop channel link enabled and the link channel is itself. This
effectively applies the minor loop offsets and restarts the next
minor loop.
config IMX9_EDMA_EMLIM
bool "Minor Loop Mapping"
default n
---help---
Normally TCD word 2 is a 32-bit NBYTES field. When this option is
enabled, TCD word 2 is redefined to include individual enable fields,
an offset field, and the NBYTES field. The individual enable fields
allow the minor loop offset to be applied to the source address, the
destination address, or both. The NBYTES field is reduced when either
offset is enabled.
config IMX9_EDMA_EDBG
bool "Enable Debug"
default n
---help---
When in debug mode, the DMA stalls the start of a new channel. Executing
channels are allowed to complete. Channel execution resumes when the
system exits debug mode or the EDBG bit is cleared
endmenu # eDMA Global Configuration
menu "LPI2C Configuration"
depends on IMX9_LPI2C
@ -678,4 +762,6 @@ config IMX9_LPSPI8_DMA
endmenu # LPSPI Configuration
endmenu # iMX Peripheral Selection
endif # ARCH_CHIP_IMX9

View File

@ -51,3 +51,7 @@ endif
ifeq ($(CONFIG_IMX9_LPSPI), y)
CHIP_CSRCS += imx9_lpspi.c
endif
ifeq ($(CONFIG_IMX9_EDMA), y)
CHIP_CSRCS += imx9_edma.c
endif

View File

@ -454,8 +454,8 @@
#define CCM_LPCG_SEMA2 18
#define CCM_LPCG_MU_A 19
#define CCM_LPCG_MU_B 20
#define CCM_LPCG_EDMA1 21
#define CCM_LPCG_EDMA2 22
#define CCM_LPCG_EDMA3 21
#define CCM_LPCG_EDMA4 22
#define CCM_LPCG_ROMCP_A55 23
#define CCM_LPCG_ROMCP_M33 24
#define CCM_LPCG_FLEXSPI1 25

View File

@ -0,0 +1,209 @@
/****************************************************************************
* arch/arm64/src/imx9/hardware/imx93/imx93_dmamux.h
*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership. The
* ASF licenses this file to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance with the
* License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*
****************************************************************************/
#ifndef __ARCH_ARM64_SRC_IMX9_HARDWARE_IMX93_IMX93_DMAMUX_H
#define __ARCH_ARM64_SRC_IMX9_HARDWARE_IMX93_IMX93_DMAMUX_H
/****************************************************************************
* Included Files
****************************************************************************/
#include <nuttx/config.h>
#include <stdint.h>
#include "imx93_memorymap.h"
/****************************************************************************
* Pre-processor Definitions
****************************************************************************/
/* Identify channel MUX from 9th bit */
#define EDMA3_MUX_ID 0x0000
#define EDMA4_MUX_ID 0x0100
#define EDMA_MUX_ID_MASK 0xff00
#define EDMA_MUX_MASK 0x00ff
/* eDMA3 MUXs */
#define DMA_REQUEST_DISABLED (0) /**< Channel disabled */
#define DMA_REQUEST_MUXCAN1 (1 | EDMA3_MUX_ID) /**< CAN1 */
#define DMA_REQUEST_MUXGPIO1_0 (3 | EDMA3_MUX_ID) /**< GPIO1 channel 0 */
#define DMA_REQUEST_MUXGPIO1_1 (4 | EDMA3_MUX_ID) /**< GPIO1 channel 1 */
#define DMA_REQUEST_MUXI3C1TOBUS (5 | EDMA3_MUX_ID) /**< I3C1 To-bus Request */
#define DMA_REQUEST_MUXI3C1FROMBUS (6 | EDMA3_MUX_ID) /**< I3C1 From-bus Request */
#define DMA_REQUEST_MUXLPI2C1TX (7 | EDMA3_MUX_ID) /**< LPI2C1 */
#define DMA_REQUEST_MUXLPI2C1RX (8 | EDMA3_MUX_ID) /**< LPI2C1 */
#define DMA_REQUEST_MUXLPI2C2TX (9 | EDMA3_MUX_ID) /**< LPI2C2 */
#define DMA_REQUEST_MUXLPI2C2RX (10 | EDMA3_MUX_ID) /**< LPI2C2 */
#define DMA_REQUEST_MUXLPSPI1TX (11 | EDMA3_MUX_ID) /**< LPSPI1 Transmit */
#define DMA_REQUEST_MUXLPSPI1RX (12 | EDMA3_MUX_ID) /**< LPSPI1 Receive */
#define DMA_REQUEST_MUXLPSPI2TX (13 | EDMA3_MUX_ID) /**< LPSPI2 Transmit */
#define DMA_REQUEST_MUXLPSPI2RX (14 | EDMA3_MUX_ID) /**< LPSPI2 Receive */
#define DMA_REQUEST_MUXLPTMR1 (15 | EDMA3_MUX_ID) /**< LPTMR1 Request */
#define DMA_REQUEST_MUXLPUART1TX (16 | EDMA3_MUX_ID) /**< LPUART1 Transmit */
#define DMA_REQUEST_MUXLPUART1RX (17 | EDMA3_MUX_ID) /**< LPUART1 Receive */
#define DMA_REQUEST_MUXLPUART2TX (18 | EDMA3_MUX_ID) /**< LPUART2 Transmit */
#define DMA_REQUEST_MUXLPUART2RX (19 | EDMA3_MUX_ID) /**< LPUART2 Receive */
#define DMA_REQUEST_MUXEDGELOCK (20 | EDMA3_MUX_ID) /**< Edgelock enclave DMA Request */
#define DMA_REQUEST_MUXSAI1TX (21 | EDMA3_MUX_ID) /**< SAI1 Transmit */
#define DMA_REQUEST_MUXSAI1RX (22 | EDMA3_MUX_ID) /**< SAI1 Receive */
#define DMA_REQUEST_MUXTPM1_0_2 (23 | EDMA3_MUX_ID) /**< TPM1 request 0 and request 2 */
#define DMA_REQUEST_MUXTPM1_1_3 (24 | EDMA3_MUX_ID) /**< TPM1 request 1 and request 3 */
#define DMA_REQUEST_MUXTPM1OVERFLOW (25 | EDMA3_MUX_ID) /**< TPM1 Overflow request */
#define DMA_REQUEST_MUXTPM2_0_2 (26 | EDMA3_MUX_ID) /**< TPM2 request 0 and request 2 */
#define DMA_REQUEST_MUXTPM2_1_3 (27 | EDMA3_MUX_ID) /**< TPM2 request 1 and request 3 */
#define DMA_REQUEST_MUXTPM2OVERFLOW (28 | EDMA3_MUX_ID) /**< TPM2 Overflow request */
#define DMA_REQUEST_MUXPDM (29 | EDMA3_MUX_ID) /**< PDM */
#define DMA_REQUEST_MUXADC1 (30 | EDMA3_MUX_ID) /**< ADC1 */
#define DMA3_REQUEST_MUX_COUNT (31)
/* eDMA4 MUXs */
#define DMA_REQUEST_MUXCAN2 (1 | EDMA4_MUX_ID) /**< CAN2 */
#define DMA_REQUEST_MUXGPIO2_0 (2 | EDMA4_MUX_ID) /**< GPIO2 channel 0 */
#define DMA_REQUEST_MUXGPIO2_1 (3 | EDMA4_MUX_ID) /**< GPIO2 channel 1 */
#define DMA_REQUEST_MUXGPIO3_0 (4 | EDMA4_MUX_ID) /**< GPIO3 channel 0 */
#define DMA_REQUEST_MUXGPIO3_1 (5 | EDMA4_MUX_ID) /**< GPIO3 channel 1 */
#define DMA_REQUEST_MUXI3C2TOBUS (6 | EDMA4_MUX_ID) /**< I3C2 To-bus Request */
#define DMA_REQUEST_MUXI3C2FROMBUS (7 | EDMA4_MUX_ID) /**< I3C2 From-bus Request */
#define DMA_REQUEST_MUXLPI2C3TX (8 | EDMA4_MUX_ID) /**< LPI2C3 */
#define DMA_REQUEST_MUXLPI2C3RX (9 | EDMA4_MUX_ID) /**< LPI2C3 */
#define DMA_REQUEST_MUXLPI2C4TX (10 | EDMA4_MUX_ID) /**< LPI2C4 */
#define DMA_REQUEST_MUXLPI2C4RX (11 | EDMA4_MUX_ID) /**< LPI2C4 */
#define DMA_REQUEST_MUXLPSPI3TX (12 | EDMA4_MUX_ID) /**< LPSPI3 Transmit */
#define DMA_REQUEST_MUXLPSPI3RX (13 | EDMA4_MUX_ID) /**< LPSPI3 Receive */
#define DMA_REQUEST_MUXLPSPI4TX (14 | EDMA4_MUX_ID) /**< LPSPI4 Transmit */
#define DMA_REQUEST_MUXLPSPI4RX (15 | EDMA4_MUX_ID) /**< LPSPI4 Receive */
#define DMA_REQUEST_MUXLPTMR2 (16 | EDMA4_MUX_ID) /**< LPTMR2 Request */
#define DMA_REQUEST_MUXLPUART3TX (17 | EDMA4_MUX_ID) /**< LPUART3 Transmit */
#define DMA_REQUEST_MUXLPUART3RX (18 | EDMA4_MUX_ID) /**< LPUART3 Receive */
#define DMA_REQUEST_MUXLPUART4TX (19 | EDMA4_MUX_ID) /**< LPUART4 Transmit */
#define DMA_REQUEST_MUXLPUART4RX (20 | EDMA4_MUX_ID) /**< LPUART4 Receive */
#define DMA_REQUEST_MUXLPUART5TX (21 | EDMA4_MUX_ID) /**< LPUART5 Transmit */
#define DMA_REQUEST_MUXLPUART5RX (22 | EDMA4_MUX_ID) /**< LPUART5 Receive */
#define DMA_REQUEST_MUXLPUART6TX (23 | EDMA4_MUX_ID) /**< LPUART6 Transmit */
#define DMA_REQUEST_MUXLPUART6RX (24 | EDMA4_MUX_ID) /**< LPUART6 Receive */
#define DMA_REQUEST_MUXTPM3_0_2 (25 | EDMA4_MUX_ID) /**< TPM3 request 0 and request 2 */
#define DMA_REQUEST_MUXTPM3_1_3 (26 | EDMA4_MUX_ID) /**< TPM3 request 1 and request 3 */
#define DMA_REQUEST_MUXTPM3OVERFLOW (27 | EDMA4_MUX_ID) /**< TPM3 Overflow request */
#define DMA_REQUEST_MUXTPM4_0_2 (28 | EDMA4_MUX_ID) /**< TPM4 request 0 and request 2 */
#define DMA_REQUEST_MUXTPM4_1_3 (29 | EDMA4_MUX_ID) /**< TPM4 request 1 and request 3 */
#define DMA_REQUEST_MUXTPM4OVERFLOW (30 | EDMA4_MUX_ID) /**< TPM4 Overflow request */
#define DMA_REQUEST_MUXTPM5_0_2 (31 | EDMA4_MUX_ID) /**< TPM5 request 0 and request 2 */
#define DMA_REQUEST_MUXTPM5_1_3 (32 | EDMA4_MUX_ID) /**< TPM5 request 1 and request 3 */
#define DMA_REQUEST_MUXTPM5OVERFLOW (33 | EDMA4_MUX_ID) /**< TPM5 Overflow request */
#define DMA_REQUEST_MUXTPM6_0_2 (34 | EDMA4_MUX_ID) /**< TPM6 request 0 and request 2 */
#define DMA_REQUEST_MUXTPM6_1_3 (35 | EDMA4_MUX_ID) /**< TPM6 request 1 and request 3 */
#define DMA_REQUEST_MUXTPM6OVERFLOW (36 | EDMA4_MUX_ID) /**< TPM6 Overflow request */
#define DMA_REQUEST_MUXFLEXIO1_0 (37 | EDMA4_MUX_ID) /**< FlexIO1 Request0 */
#define DMA_REQUEST_MUXFLEXIO1_1 (38 | EDMA4_MUX_ID) /**< FlexIO1 Request1 */
#define DMA_REQUEST_MUXFLEXIO1_2 (39 | EDMA4_MUX_ID) /**< FlexIO1 Request2 */
#define DMA_REQUEST_MUXFLEXIO1_3 (40 | EDMA4_MUX_ID) /**< FlexIO1 Request3 */
#define DMA_REQUEST_MUXFLEXIO1_4 (41 | EDMA4_MUX_ID) /**< FlexIO1 Request4 */
#define DMA_REQUEST_MUXFLEXIO1_5 (42 | EDMA4_MUX_ID) /**< FlexIO1 Request5 */
#define DMA_REQUEST_MUXFLEXIO1_6 (43 | EDMA4_MUX_ID) /**< FlexIO1 Request6 */
#define DMA_REQUEST_MUXFLEXIO1_7 (44 | EDMA4_MUX_ID) /**< FlexIO1 Request7 */
#define DMA_REQUEST_MUXFLEXIO2_0 (45 | EDMA4_MUX_ID) /**< FlexIO2 Request0 */
#define DMA_REQUEST_MUXFLEXIO2_1 (46 | EDMA4_MUX_ID) /**< FlexIO2 Request1 */
#define DMA_REQUEST_MUXFLEXIO2_2 (47 | EDMA4_MUX_ID) /**< FlexIO2 Request2 */
#define DMA_REQUEST_MUXFLEXIO2_3 (48 | EDMA4_MUX_ID) /**< FlexIO2 Request3 */
#define DMA_REQUEST_MUXFLEXIO2_4 (49 | EDMA4_MUX_ID) /**< FlexIO2 Request4 */
#define DMA_REQUEST_MUXFLEXIO2_5 (50 | EDMA4_MUX_ID) /**< FlexIO2 Request5 */
#define DMA_REQUEST_MUXFLEXIO2_6 (51 | EDMA4_MUX_ID) /**< FlexIO2 Request6 */
#define DMA_REQUEST_MUXFLEXIO2_7 (52 | EDMA4_MUX_ID) /**< FlexIO2 Request7 */
#define DMA_REQUEST_MUXFLEXSPI1TX (53 | EDMA4_MUX_ID) /**< FlexSPI1 Transmit */
#define DMA_REQUEST_MUXFLEXSPI1RX (54 | EDMA4_MUX_ID) /**< FlexSPI1 Receive */
#define DMA_REQUEST_MUXSAI2TX (58 | EDMA4_MUX_ID) /**< SAI2 Transmit */
#define DMA_REQUEST_MUXSAI2RX (59 | EDMA4_MUX_ID) /**< SAI2 Receive */
#define DMA_REQUEST_MUXSAI3TX (60 | EDMA4_MUX_ID) /**< SAI3 Transmit */
#define DMA_REQUEST_MUXSAI3RX (61 | EDMA4_MUX_ID) /**< SAI3 Receive */
#define DMA_REQUEST_MUXGPIO4_0 (62 | EDMA4_MUX_ID) /**< GPIO4 channel 0 */
#define DMA_REQUEST_MUXGPIO4_1 (63 | EDMA4_MUX_ID) /**< GPIO4 channel 1 */
#define DMA_REQUEST_MUXSPDIF (65 | EDMA4_MUX_ID) /**< SPDIF */
#define DMA_REQUEST_MUXSPDIF_1 (66 | EDMA4_MUX_ID) /**< SPDIF */
#define DMA_REQUEST_MUXENET (67 | EDMA4_MUX_ID) /**< ENET */
#define DMA_REQUEST_MUXENET_1 (68 | EDMA4_MUX_ID) /**< ENET */
#define DMA_REQUEST_MUXENET_2 (69 | EDMA4_MUX_ID) /**< ENET */
#define DMA_REQUEST_MUXENET_3 (70 | EDMA4_MUX_ID) /**< ENET */
#define DMA_REQUEST_MUXLPI2C5TX (71 | EDMA4_MUX_ID) /**< LPI2C5 */
#define DMA_REQUEST_MUXLPI2C5RX (72 | EDMA4_MUX_ID) /**< LPI2C5 */
#define DMA_REQUEST_MUXLPI2C6TX (73 | EDMA4_MUX_ID) /**< LPI2C6 */
#define DMA_REQUEST_MUXLPI2C6RX (74 | EDMA4_MUX_ID) /**< LPI2C6 */
#define DMA_REQUEST_MUXLPI2C7TX (75 | EDMA4_MUX_ID) /**< LPI2C7 */
#define DMA_REQUEST_MUXLPI2C7RX (76 | EDMA4_MUX_ID) /**< LPI2C7 */
#define DMA_REQUEST_MUXLPI2C8TX (77 | EDMA4_MUX_ID) /**< LPI2C8 */
#define DMA_REQUEST_MUXLPI2C8RX (78 | EDMA4_MUX_ID) /**< LPI2C8 */
#define DMA_REQUEST_MUXLPSPI5TX (79 | EDMA4_MUX_ID) /**< LPSPI5 Transmit */
#define DMA_REQUEST_MUXLPSPI5RX (80 | EDMA4_MUX_ID) /**< LPSPI5 Receive */
#define DMA_REQUEST_MUXLPSPI6TX (81 | EDMA4_MUX_ID) /**< LPSPI6 Transmit */
#define DMA_REQUEST_MUXLPSPI6RX (82 | EDMA4_MUX_ID) /**< LPSPI6 Receive */
#define DMA_REQUEST_MUXLPSPI7TX (83 | EDMA4_MUX_ID) /**< LPSPI7 Transmit */
#define DMA_REQUEST_MUXLPSPI7RX (84 | EDMA4_MUX_ID) /**< LPSPI7 Receive */
#define DMA_REQUEST_MUXLPSPI8TX (85 | EDMA4_MUX_ID) /**< LPSPI8 Transmit */
#define DMA_REQUEST_MUXLPSPI8RX (86 | EDMA4_MUX_ID) /**< LPSPI8 Receive */
#define DMA_REQUEST_MUXLPUART7TX (87 | EDMA4_MUX_ID) /**< LPUART7 Transmit */
#define DMA_REQUEST_MUXLPUART7RX (88 | EDMA4_MUX_ID) /**< LPUART7 Receive */
#define DMA_REQUEST_MUXLPUART8TX (89 | EDMA4_MUX_ID) /**< LPUART8 Transmit */
#define DMA_REQUEST_MUXLPUART8RX (90 | EDMA4_MUX_ID) /**< LPUART8 Receive */
#define DMA_REQUEST_MUXENET_QOS (91 | EDMA4_MUX_ID) /**< ENET_QOS */
#define DMA_REQUEST_MUXENET_QOS_1 (92 | EDMA4_MUX_ID) /**< ENET_QOS */
#define DMA_REQUEST_MUXENET_QOS_2 (93 | EDMA4_MUX_ID) /**< ENET_QOS */
#define DMA_REQUEST_MUXENET_QOS_3 (94 | EDMA4_MUX_ID) /**< ENET_QOS */
#define DMA4_REQUEST_MUX_COUNT (95)
/* Combined MUX count (eDMA3 and eDMA4) */
#define DMA_REQUEST_MUX_COUNT (DMA3_REQUEST_MUX_COUNT + DMA4_REQUEST_MUX_COUNT)
/****************************************************************************
* Inline Functions
****************************************************************************/
/****************************************************************************
* Name: imx9_dmamux_get_dmabase
*
* Description:
* Get DMA engine base address from MUX identifier.
*
* Input Parameters:
* dmamux - The DMA MUX identifier.
*
* Returned Value:
* Base address of the associated DMA engine.
*
****************************************************************************/
static inline uintptr_t imx9_dmamux_get_dmabase(uint16_t dmamux)
{
if ((dmamux & EDMA_MUX_ID_MASK) == EDMA3_MUX_ID)
{
return IMX9_DMA3_BASE;
}
else
{
return IMX9_DMA4_BASE;
}
}
#endif /* __ARCH_ARM64_SRC_IMX9_HARDWARE_IMX93_IMX93_DMAMUX_H */

View File

@ -0,0 +1,436 @@
/****************************************************************************
* arch/arm64/src/imx9/hardware/imx93/imx93_edma.h
*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership. The
* ASF licenses this file to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance with the
* License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*
****************************************************************************/
#ifndef __ARCH_ARM64_SRC_IMX9_HARDWARE_IMX93_IMX93_EDMA_H
#define __ARCH_ARM64_SRC_IMX9_HARDWARE_IMX93_IMX93_EDMA_H
/****************************************************************************
* Included Files
****************************************************************************/
#include <nuttx/config.h>
#include <stdbool.h>
#include <stdint.h>
#include "imx93_memorymap.h"
/****************************************************************************
* Pre-processor Definitions
****************************************************************************/
/* eDMA3 / eDMA4 Register Offsets */
#define IMX9_EDMA_CSR_OFFSET (0x000000) /* Management Page Control Register (CSR) */
#define IMX9_EDMA_ES_OFFSET (0x000004) /* Management Page Error Status Register (ES) */
#define IMX9_EDMA_CH_GRPRI_OFFSET(n) (0x000100 + ((n) << 2)) /* Channel n Arbitration Group Register (CHn_GRPRI) */
/* eDMA3 only */
#define IMX9_EDMA_INT_OFFSET (0x000008) /* Management Page Interrupt Request Status Register (INT) */
#define IMX9_EDMA_HRS_OFFSET (0x00000c) /* Management Page Hardware Request Status Register (HRS) */
/* eDMA4 only */
#define IMX9_EDMA_INT_LOW_OFFSET (0x000008) /* Management Page Interrupt Request Status Register (INT_LOW) */
#define IMX9_EDMA_INT_HIGH_OFFSET (0x00000c) /* Management Page Interrupt Request Status Register (INT_HIGH) */
#define IMX9_EDMA_HRS_LOW_OFFSET (0x000010) /* Management Page Hardware Request Status Register (HRS_LOW) */
#define IMX9_EDMA_HRS_HIGH_OFFSET (0x000014) /* Management Page Hardware Request Status Register (HRS_HIGH) */
/* eDMA3 / eDMA4 Register Addresses */
#define IMX9_EDMA_CSR(n) ((n) + IMX9_EDMA_CSR_OFFSET)
#define IMX9_EDMA_ES(n) ((n) + IMX9_EDMA_ES_OFFSET)
#define IMX9_EDMA_CH_GRPRI(n,c) ((n) + IMX9_EDMA_CH_GRPRI_OFFSET(n))
/* eDMA3 only */
#define IMX9_EDMA_INT (IMX9_DMA3_BASE + IMX9_EDMA_INT_OFFSET)
#define IMX9_EDMA_HRS (IMX9_DMA3_BASE + IMX9_EDMA_HRS_OFFSET)
/* eDMA4 only */
#define IMX9_EDMA_INT_LOW (IMX9_DMA4_BASE + IMX9_EDMA_INT_LOW_OFFSET)
#define IMX9_EDMA_INT_HIGH (IMX9_DMA4_BASE + IMX9_EDMA_INT_HIGH_OFFSET)
#define IMX9_EDMA_HRS_LOW (IMX9_DMA4_BASE + IMX9_EDMA_HRS_LOW_OFFSET)
#define IMX9_EDMA_HRS_HIGH (IMX9_DMA4_BASE + IMX9_EDMA_HRS_HIGH_OFFSET)
/* eDMA Transfer Control Descriptor (TCD) Register Offsets */
#define IMX9_EDMA_CH_CSR_OFFSET (0x000000) /* Channel Control and Status Register (CH0_CSR) */
#define IMX9_EDMA_CH_ES_OFFSET (0x000004) /* Channel Error Status Register (CH0_ES) */
#define IMX9_EDMA_CH_INT_OFFSET (0x000008) /* Channel Interrupt Status Register (CH0_INT) */
#define IMX9_EDMA_CH_SBR_OFFSET (0x00000c) /* Channel System Bus Register (CH0_SBR) */
#define IMX9_EDMA_CH_PRI_OFFSET (0x000010) /* Channel Priority Register (CH0_PRI) */
#define IMX9_EDMA_CH_MUX_OFFSET (0x000014) /* Channel Multiplexor Configuration (CH0_MUX) (eDMA4 only) */
#define IMX9_EDMA_CH_MATTR_OFFSET (0x000018) /* Memory Attributes Register (CH0_MATTR) (eDMA4 only) */
#define IMX9_EDMA_TCD_SADDR_OFFSET (0x000020) /* TCD Source Address Register (TCD0_SADDR) */
#define IMX9_EDMA_TCD_SOFF_OFFSET (0x000024) /* TCD Signed Source Address Offset Register (TCD0_SOFF) */
#define IMX9_EDMA_TCD_ATTR_OFFSET (0x000026) /* TCD Transfer Attributes (TCD0_ATTR) */
#define IMX9_EDMA_TCD_NBYTES_OFFSET (0x000028) /* TCD Transfer Size (TCD0_NBYTES) */
#define IMX9_EDMA_TCD_SLAST_SDA_OFFSET (0x00002c) /* TCD Last Source Address Adjustment / Store DADDR Address Register (TCD0_SLAST_SDA) */
#define IMX9_EDMA_TCD_DADDR_OFFSET (0x000030) /* TCD Destination Address Register (TCD0_DADDR) */
#define IMX9_EDMA_TCD_DOFF_OFFSET (0x000034) /* TCD Signed Destination Address Offset Register (TCD0_DOFF) */
#define IMX9_EDMA_TCD_CITER_OFFSET (0x000036) /* TCD Current Major Loop Count Register (TCD0_CITER) */
#define IMX9_EDMA_TCD_DLAST_SGA_OFFSET (0x000038) /* TCD Last Destination Address Adjustment / Scatter Gather Address Register (TCD0_DLAST_SGA)*/
#define IMX9_EDMA_TCD_CSR_OFFSET (0x00003c) /* TCD Control and Status Register (TCD0_CSR) */
#define IMX9_EDMA_TCD_BITER_OFFSET (0x00003e) /* TCD Beginning Major Loop Count Register (TCD0_BITER) */
/* eDMA 3 and eDMA 4 have TCD instance offsets, but same base offset */
#define IMX9_EDMA_TCD_BASE_OFFSET (0x10000) /* Offset to TCD for both eDMA3/4 */
#define IMX9_EDMA3_TCD_INST_OFFSET (0x10000) /* Per instance TCD offset for eDMA3 */
#define IMX9_EDMA4_TCD_INST_OFFSET (0x8000) /* Per instance TCD offset for eDMA4 */
#define IMX9_EDMA_TCD_BASE(n) ((n) + IMX9_EDMA_TCD_BASE_OFFSET)
#define IMX9_EDMA_TCD_INST_OFFSET(n) ((n) == IMX9_DMA3_BASE ? IMX9_EDMA3_TCD_INST_OFFSET : IMX9_EDMA4_TCD_INST_OFFSET)
#define IMX9_EDMA_TCD(n,t) (IMX9_EDMA_TCD_BASE(n) + (t) * IMX9_EDMA_TCD_INST_OFFSET(n))
/* eDMA Transfer Control Descriptor (TCD) Register Addresses ****************/
#define IMX9_EDMA_CH_CSR(n,t) (IMX9_EDMA_TCD(n,t) + IMX9_EDMA_CH_CSR_OFFSET)
#define IMX9_EDMA_CH_ES(n,t) (IMX9_EDMA_TCD(n,t) + IMX9_EDMA_CH_ES_OFFSET)
#define IMX9_EDMA_CH_INT(n,t) (IMX9_EDMA_TCD(n,t) + IMX9_EDMA_CH_INT_OFFSET)
#define IMX9_EDMA_CH_SBR(n,t) (IMX9_EDMA_TCD(n,t) + IMX9_EDMA_CH_SBR_OFFSET)
#define IMX9_EDMA_CH_PRI(n,t) (IMX9_EDMA_TCD(n,t) + IMX9_EDMA_CH_PRI_OFFSET)
#define IMX9_EDMA_CH_MUX(n,t) (IMX9_EDMA_TCD(n,t) + IMX9_EDMA_CH_MUX_OFFSET)
#define IMX9_EDMA_TCD_SADDR(n,t) (IMX9_EDMA_TCD(n,t) + IMX9_EDMA_TCD_SADDR_OFFSET)
#define IMX9_EDMA_TCD_SOFF(n,t) (IMX9_EDMA_TCD(n,t) + IMX9_EDMA_TCD_SOFF_OFFSET)
#define IMX9_EDMA_TCD_ATTR(n,t) (IMX9_EDMA_TCD(n,t) + IMX9_EDMA_TCD_ATTR_OFFSET)
#define IMX9_EDMA_TCD_NBYTES(n,t) (IMX9_EDMA_TCD(n,t) + IMX9_EDMA_TCD_NBYTES_OFFSET)
#define IMX9_EDMA_TCD_SLAST_SDA(n,t) (IMX9_EDMA_TCD(n,t) + IMX9_EDMA_TCD_SLAST_SDA_OFFSET)
#define IMX9_EDMA_TCD_DADDR(n,t) (IMX9_EDMA_TCD(n,t) + IMX9_EDMA_TCD_DADDR_OFFSET)
#define IMX9_EDMA_TCD_DOFF(n,t) (IMX9_EDMA_TCD(n,t) + IMX9_EDMA_TCD_DOFF_OFFSET)
#define IMX9_EDMA_TCD_CITER(n,t) (IMX9_EDMA_TCD(n,t) + IMX9_EDMA_TCD_CITER_OFFSET)
#define IMX9_EDMA_TCD_DLAST_SGA(n,t) (IMX9_EDMA_TCD(n,t) + IMX9_EDMA_TCD_DLAST_SGA_OFFSET)
#define IMX9_EDMA_TCD_CSR(n,t) (IMX9_EDMA_TCD(n,t) + IMX9_EDMA_TCD_CSR_OFFSET)
#define IMX9_EDMA_TCD_BITER(n,t) (IMX9_EDMA_TCD(n,t) + IMX9_EDMA_TCD_BITER_OFFSET)
/* eDMA Register Bitfield Definitions ***************************************/
/* Management Page Control Register (CSR) */
/* Bit 0: Reserved */
#define EDMA_CSR_EDBG (1 << 1) /* Bit 1: Enable Debug (EDBG) */
#define EDMA_CSR_ERCA (1 << 2) /* Bit 2: Enable Round Robin Channel Arbitration (ERCA) */
/* Bit 3: Reserved */
#define EDMA_CSR_HAE (1 << 4) /* Bit 4: Halt After Error (HAE) */
#define EDMA_CSR_HALT (1 << 5) /* Bit 5: Halt DMA Operations (HALT) */
#define EDMA_CSR_GCLC (1 << 6) /* Bit 6: Global Channel Linking Control (GCLC) */
#define EDMA_CSR_GMRC (1 << 7) /* Bit 7: Global Master ID Replication Control (GMRC) */
#define EDMA_CSR_ECX (1 << 8) /* Bit 8: Cancel Transfer With Error (ECX) */
#define EDMA_CSR_CX (1 << 9) /* Bit 9: Cancel Transfer (CX) */
/* Bits 10-23: Reserved */
#define EDMA_CSR_ACTIVE_ID_SHIFT (24) /* Bits 24-28: Active Channel ID (ACTIVE_ID) */
#define EDMA_CSR_ACTIVE_ID_MASK (0x1f << EDMA_CSR_ACTIVE_ID_SHIFT)
/* Bits 29-30: Reserved */
#define EDMA_CSR_ACTIVE (1 << 31) /* Bit 31: DMA Active Status (ACTIVE) */
/* Management Page Error Status Register (ES) */
#define EDMA_ES_DBE (1 << 0) /* Bit 0: Destination Bus Error (DBE) */
#define EDMA_ES_SBE (1 << 1) /* Bit 1: Source Bus Error (SBE) */
#define EDMA_ES_SGE (1 << 2) /* Bit 2: Scatter/Gather Configuration Error (SGE) */
#define EDMA_ES_NCE (1 << 3) /* Bit 3: NBYTES/CITER Configuration Error (NCE) */
#define EDMA_ES_DOE (1 << 4) /* Bit 4: Destination Offset Error (DOE) */
#define EDMA_ES_DAE (1 << 5) /* Bit 5: Destination Address Error (DAE) */
#define EDMA_ES_SOE (1 << 6) /* Bit 6: Source Offset Error (SOE) */
#define EDMA_ES_SAE (1 << 7) /* Bit 7: Source Address Error (SAE) */
#define EDMA_ES_ECX (1 << 8) /* Bit 8: Transfer Canceled (ECX) */
/* Bits 9-23: Reserved */
#define EDMA_ES_ERRCHN_SHIFT (24) /* Bits 24-28: Error Channel Number or Canceled Channel Number (ERRCHN) */
#define EDMA_ES_ERRCHN_MASK (0x1f << EDMA_ES_ERRCHN_SHIFT)
/* Bits 29-30: Reserved */
#define EDMA_ES_VLD (1 << 31) /* Bit 31: Logical OR of all ERR status fields (VALID) */
/* Management Page Interrupt Request Status Register (INT) */
#define EDMA_INT(n) (1 << (n)) /* Bit n: Interrupt Request Status (INT) */
/* Management Page Hardware Request Status Register (HRS) */
#define EDMA_HRS(n) (1 << (n)) /* Bit n: Hardware Request Status (HRS) */
/* Channel n Arbitration Group Register (CHn_GRPRI) */
#define EDMA_CH_GRPRI_SHIFT (0) /* Bits 0-4: Arbitration Group For Channel n (GRPRI) */
#define EDMA_CH_GRPRI_MASK (0x1f << EDMA_CH_GRPRI_SHIFT)
/* Bits 5-31: Reserved */
/* eDMA Transfer Control Descriptor (TCD) Bitfield Definitions **************/
/* Channel n Control and Status Register (CHn_CSR) */
#define EDMA_CH_CSR_ERQ (1 << 0) /* Bit 0: Enable DMA Request (ERQ) */
#define EDMA_CH_CSR_EARQ (1 << 1) /* Bit 1: Enable Asynchronous DMA Request in Stop Mode for Channel (EARQ) */
#define EDMA_CH_CSR_EEI (1 << 2) /* Bit 2: Enable Error Interrupt (EEI) */
#define EDMA_CH_CSR_EBW (1 << 3) /* Bit 3: Enable Buffered Writes (EBW) */
/* Bit 4-29: Reserved */
#define EDMA_CH_CSR_DONE (1 << 30) /* Bit 30: Channel Done (DONE) */
#define EDMA_CH_CSR_ACTIVE (1 << 31) /* Bit 31: CHannel Active (ACTIVE) */
/* Channel n Error Status Register (CHn_ES) */
#define EDMA_CH_ES_DBE (1 << 0) /* Bit 0: Destination Bus Error (DBE) */
#define EDMA_CH_ES_SBE (1 << 1) /* Bit 1: Source Bus Error (SBE) */
#define EDMA_CH_ES_SGE (1 << 2) /* Bit 2: Scatter/Gather Configuration Error (SGE) */
#define EDMA_CH_ES_NCE (1 << 3) /* Bit 3: NBYTES/CITER Configuration Error (NCE) */
#define EDMA_CH_ES_DOE (1 << 4) /* Bit 4: Destination Offset Error (DOE) */
#define EDMA_CH_ES_DAE (1 << 5) /* Bit 5: Destination Address Error (DAE) */
#define EDMA_CH_ES_SOE (1 << 6) /* Bit 6: Source Offset Error (SOE) */
#define EDMA_CH_ES_SAE (1 << 7) /* Bit 7: Source Address Error (SAE) */
/* Bit 8-30: Reserved */
#define EDMA_CH_ES_ERR (1 << 31) /* Bit 31: Error in this channel (ERR) */
/* Channel n Interrupt Status Register (CHn_INT) */
#define EDMA_CH_INT (1 << 0) /* Bit 0: Interrupt Request (INT) */
/* Bits 1-31: Reserved */
/* Channel n System Bus Register (CHn_SBR) */
#define EDMA_CH_SBR_MID_SHIFT (0) /* Bits 0-3: Master ID (MID) */
#define EDMA_CH_SBR_MID_MASK (0x0f << EDMA_CH_SBR_MID_SHIFT)
/* Bits 4-13: Reserved */
#define EDMA_CH_SBR_SEC (1 << 14) /* Bit 14: Security Level (SEC) */
#define EDMA_CH_SBR_PAL (1 << 15) /* Bit 15: Privileged Access Level (PAL) */
#define EDMA_CH_SBR_EMI (1 << 16) /* Bit 16: Enable Master ID Replication (EMI) */
#define EDMA_CH_SBR_ATTR_SHIFT (17) /* Bits 17-19: Attribute Output (ATTR) */
#define EDMA_CH_SBR_ATTR_MASK (0x07 << EDMA_CH_SBR_ATTR_SHIFT)
/* Bits 20-31: Reserved */
/* Channel n Priority Register (CHn_PRI) */
#define EDMA_CH_PRI_APL_SHIFT (0) /* Bits 0-2: Arbitration Priority Level (APL) */
#define EDMA_CH_PRI_APL_MASK (0x07 << EDMA_CH_PRI_APL_SHIFT)
/* Bits 3-29: Reserved */
#define EDMA_CH_PRI_DPA (1 << 30) /* Bit 30: Disable Preempt Ability (DPA) */
#define EDMA_CH_PRI_ECP (1 << 31) /* Bit 31: Enable Channel Preemption (ECP) */
/* Channel Multiplexor Configuration (CHn_MUX) */
#define EDMA_CH_SRC_SHIFT (0) /* Bits 0-6: Service Request Source */
#define EDMA_CH_SRC_MASK (0x7f << EDMA_CH_SRC_SHIFT)
/* TCDn Source Address Register (TCDn_SADDR) */
#define EDMA_TCD_SADDR_SHIFT (0) /* Bits 0-31: Source Address (SADDR) */
#define EDMA_TCD_SADDR_MASK (0xffffffff << EDMA_TCD_SADDR_SHIFT)
/* TCDn Signed Source Address Offset Register (TCDn_SOFF) */
#define EDMA_TCD_SOFF_SHIFT (0) /* Bits 0-31: Source Address Signed Offset (SOFF) */
#define EDMA_TCD_SOFF_MASK (0xffffffff << EDMA_TCD_SOFF_SHIFT)
/* TCDn Transfer Attributes (TCDn_ATTR) */
#define EDMA_TCD_ATTR_DSIZE_SHIFT (0) /* Bits 0-2: Destination Data Transfer Size (DSIZE) */
#define EDMA_TCD_ATTR_DSIZE_MASK (0x07 << EDMA_TCD_ATTR_DSIZE_SHIFT)
#define EDMA_TCD_ATTR_DSIZE(n) (((n) << EDMA_TCD_ATTR_DSIZE_SHIFT) & EDMA_TCD_ATTR_DSIZE_MASK)
#define EDMA_TCD_ATTR_DMOD_SHIFT (3) /* Bits 3-7: Destination Address Modulo (DMOD) */
#define EDMA_TCD_ATTR_DMOD_MASK (0x1f << EDMA_TCD_ATTR_DMOD_SHIFT)
#define EDMA_TCD_ATTR_DMOD(n) (((n) << EDMA_TCD_ATTR_DMOD_SHIFT) & EDMA_TCD_ATTR_DMOD_MASK)
#define EDMA_TCD_ATTR_SSIZE_SHIFT (8) /* Bits 8-10: Source Data Transfer Size (SSIZE) */
#define EDMA_TCD_ATTR_SSIZE_MASK (0x07 << EDMA_TCD_ATTR_SSIZE_SHIFT)
#define EDMA_TCD_ATTR_SSIZE(n) (((n) << EDMA_TCD_ATTR_SSIZE_SHIFT) & EDMA_TCD_ATTR_SSIZE_MASK)
# define EDMA_TCD_ATTR_SSIZE_8BIT (0x00 << EDMA_TCD_ATTR_SSIZE_SHIFT) /* 8-bit */
# define EDMA_TCD_ATTR_SSIZE_16BIT (0x01 << EDMA_TCD_ATTR_SSIZE_SHIFT) /* 16-bit */
# define EDMA_TCD_ATTR_SSIZE_32BIT (0x02 << EDMA_TCD_ATTR_SSIZE_SHIFT) /* 32-bit */
# define EDMA_TCD_ATTR_SSIZE_64BIT (0x03 << EDMA_TCD_ATTR_SSIZE_SHIFT) /* 64-bit */
# define EDMA_TCD_ATTR_SSIZE_16BYTE (0x04 << EDMA_TCD_ATTR_SSIZE_SHIFT) /* 16-byte */
# define EDMA_TCD_ATTR_SSIZE_32BYTE (0x05 << EDMA_TCD_ATTR_SSIZE_SHIFT) /* 32-byte */
# define EDMA_TCD_ATTR_SSIZE_64BYTE (0x06 << EDMA_TCD_ATTR_SSIZE_SHIFT) /* 64-byte */
#define EDMA_TCD_ATTR_SMOD_SHIFT (11) /* Bits 11-15: Source Address Modulo (SMOD) */
#define EDMA_TCD_ATTR_SMOD_MASK (0x1f << EDMA_TCD_ATTR_SMOD_SHIFT)
#define EDMA_TCD_ATTR_SMOD(n) (((n) << EDMA_TCD_ATTR_SMOD_SHIFT) & EDMA_TCD_ATTR_SMOD_MASK)
/* TCDn Transfer Size (TCDn_NBYTES) */
#define EDMA_TCD_NBYTES_SHIFT (0) /* Bits 0-29: Number of Bytes to Transfer per Service Request (NBYTES) */
#define EDMA_TCD_NBYTES_MASK (0x3fffffff << EDMA_TCD_NBYTES_SHIFT)
#define EDMA_TCD_NBYTES_MASK_MLOFF (0x03ff << EDMA_TCD_NBYTES_SHIFT)
#define EDMA_TCD_NBYTES_MLOFF_SHIFT (10) /* Bits 10-29: Minor Loop Offset (MLOFF) */
#define EDMA_TCD_NBYTES_MLOFF_MASK (0x0fffff << EDMA_TCD_NBYTES_MLOFF_SHIFT)
#define EDMA_TCD_NBYTES_DMLOE (1 << 30) /* Bit 30: Destination Minor Loop Offset Enable (DMLOE) */
#define EDMA_TCD_NBYTES_SMLOE (1 << 31) /* Bit 31: Source Minor Loop Offset Enable (SMLOE) */
/* TCDn Last Source Address Adjustment / Store DADDR Address Register
* (TCDn_SLAST_SDA)
*/
#define EDMA_TCD_SLAST_SDA_SHIFT (0) /* Bits 0-31: Last Source Address Adjustment / Store DADDR Address (SLAST_SDA) */
#define EDMA_TCD_SLAST_SDA_MASK (0xffffffff << EDMA_TCD_SLAST_SDA_SHIFT)
/* TCDn Destination Address Register (TCDn_DADDR) */
#define EDMA_TCD_DADDR_SHIFT (0) /* Bits 0-31: Destination Address (DADDR) */
#define EDMA_TCD_DADDR_MASK (0xffffffff << EDMA_TCD_DADDR_SHIFT)
/* TCDn Signed Destination Address Offset Register (TCDn_DOFF) */
#define EDMA_TCD_DOFF_SHIFT (0) /* Bits 0-15: Destination Address Signed Offset (DOFF) */
#define EDMA_TCD_DOFF_MASK (0xffff << EDMA_TCD_DOFF_SHIFT)
/* TCDn Current Major Loop Count Register (TCDn_CITER) */
#define EDMA_TCD_CITER_SHIFT (0) /* Bits 0-14: Current Major Iteration Count (CITER) */
#define EDMA_TCD_CITER_MASK (0x7fff << EDMA_TCD_CITER_SHIFT)
#define EDMA_TCD_CITER_MASK_ELINK (0x01ff << EDMA_TCD_CITER_SHIFT)
#define EDMA_TCD_CITER_LINKCH_SHIFT (9) /* Bits 9-13: Minor Loop Link Channel Number (LINKCH) */
#define EDMA_TCD_CITER_LINKCH_MASK (0x1f << EDMA_TCD_CITER_LINKCH_SHIFT)
#define EDMA_TCD_CITER_LINKCH(n) (((n) << EDMA_TCD_CITER_LINKCH_SHIFT) & EDMA_TCD_CITER_LINKCH_SHIFT)
#define EDMA_TCD_CITER_ELINK (1 << 15) /* Bit 15: Enable Link (ELINK) */
/* TCDn Last Destination Address Adjustment / Scatter Gather Address Register
* (TCDn_DLAST_SGA)
*/
#define EDMA_TCD_DLAST_SGA_SHIFT (0) /* Bits 0-31: Last Destination Address Adjustment / Scatter Gather Address (DLAST_SGA) */
#define EDMA_TCD_DLAST_SGA_MASK (0xffffffff << EDMA_TCD_DLAST_SGA_SHIFT)
/* TCDn Control and Status Register (TCDn_CSR) */
#define EDMA_TCD_CSR_START (1 << 0) /* Bit 0: Channel Start (START) */
#define EDMA_TCD_CSR_INTMAJOR (1 << 1) /* Bit 1: Enable Interrupt if Major count complete (INTMAJOR) */
#define EDMA_TCD_CSR_INTHALF (1 << 2) /* Bit 2: Enable Interrupt if Major Count Half-complete (INTHALF) */
#define EDMA_TCD_CSR_DREQ (1 << 3) /* Bit 3: Disable Request (DREQ) */
#define EDMA_TCD_CSR_ESG (1 << 4) /* Bit 4: Enable Scatter/Gather Processing (ESG) */
#define EDMA_TCD_CSR_MAJORELINK (1 << 5) /* Bit 5: Enable Link When Major Loop Complete (MAJORELINK) */
#define EDMA_TCD_CSR_EEOP (1 << 6) /* Bit 6: Enable End-Of-Packet Processing (EEOP) */
#define EDMA_TCD_CSR_ESDA (1 << 7) /* Bit 7: Enable Store Destination Address (ESDA) */
#define EDMA_TCD_CSR_MAJORLINKCH_SHIFT (8) /* Bits 8-12: Major Loop Link Channel Number (MAJORLINKCH) */
#define EDMA_TCD_CSR_MAJORLINKCH_MASK (0x1f << EDMA_TCD_CSR_MAJORLINKCH_SHIFT)
#define EDMA_TCD_CSR_MAJORLINKCH(n) (((n) << EDMA_TCD_CSR_MAJORLINKCH_SHIFT) & EDMA_TCD_CSR_MAJORLINKCH_MASK)
/* Bit 13: Reserved */
#define EDMA_TCD_CSR_BWC_SHIFT (14) /* Bits 14-15: Bandwidth Control (BWC) */
#define EDMA_TCD_CSR_BWC_MASK (0x03 << EDMA_TCD_CSR_BWC_SHIFT)
# define EDMA_TCD_CSR_BWC_NOSTALL (0x00 << EDMA_TCD_CSR_BWC_SHIFT) /* No eDMA engine stalls */
# define EDMA_TCD_CSR_BWC_HPE (0x01 << EDMA_TCD_CSR_BWC_SHIFT) /* Enable eDMA master high-priority elevation (HPE) mode */
# define EDMA_TCD_CSR_BWC_4CYCLES (0x02 << EDMA_TCD_CSR_BWC_SHIFT) /* eDMA engine stalls for 4 cycles after each R/W */
# define EDMA_TCD_CSR_BWC_8CYCLES (0x03 << EDMA_TCD_CSR_BWC_SHIFT) /* eDMA engine stalls for 8 cycles after each R/W */
/* TCDn Beginning Major Loop Count Register (TCDn_BITER) */
#define EDMA_TCD_BITER_SHIFT (0) /* Bits 0-14: Starting Major Iteration Count (BITER) */
#define EDMA_TCD_BITER_MASK (0x7fff << EDMA_TCD_BITER_SHIFT)
#define EDMA_TCD_BITER_MASK_ELINK (0x01ff << EDMA_TCD_BITER_SHIFT)
#define EDMA_TCD_BITER_LINKCH_SHIFT (9) /* Bits 9-13: Link Channel Number (LINKCH) */
#define EDMA_TCD_BITER_LINKCH_MASK (0x1f << EDMA_TCD_BITER_LINKCH_SHIFT)
#define EDMA_TCD_BITER_LINKCH(n) (((n) << EDMA_TCD_BITER_LINKCH_SHIFT) & EDMA_TCD_BITER_LINKCH_MASK)
#define EDMA_TCD_BITER_ELINK (1 << 15) /* Bit 15: Enable Link (ELINK) */
/* Amount of channels */
#define DMA3_CHANNEL_COUNT (31)
#define DMA4_CHANNEL_COUNT (64)
#define IMX9_EDMA_NCHANNELS (DMA3_CHANNEL_COUNT + DMA4_CHANNEL_COUNT)
/* Amount of interrupt sources */
#define DMA3_IRQ_COUNT (32) /* Error interrupt not counted */
#define DMA4_IRQ_COUNT (32) /* Error interrupt not counted */
/****************************************************************************
* Public Types
****************************************************************************/
/* In-memory representation of the 32-byte Transfer Control Descriptor
* (TCD)
*/
struct imx9_edmatcd_s
{
uint32_t saddr; /* Offset: 0x0000 TCD Source Address */
uint16_t soff; /* Offset: 0x0004 TCD Signed Source Address Offset */
uint16_t attr; /* Offset: 0x0006 TCD Transfer Attributes */
uint32_t nbytes; /* Offset: 0x0008 TCD Signed Minor Loop Offset / Byte Count */
uint32_t slast; /* Offset: 0x000c TCD Last Source Address Adjustment */
uint32_t daddr; /* Offset: 0x0010 TCD Destination Address */
uint16_t doff; /* Offset: 0x0014 TCD Signed Destination Address Offset */
uint16_t citer; /* Offset: 0x0016 TCD Current Minor Loop Link, Major Loop Count */
uint32_t dlastsga; /* Offset: 0x0018 TCD Last Destination Address Adjustment/Scatter Gather Address */
uint16_t csr; /* Offset: 0x001c TCD Control and Status */
uint16_t biter; /* Offset: 0x001e TCD Beginning Minor Loop Link, Major Loop Count */
};
/****************************************************************************
* Inline Functions
****************************************************************************/
/****************************************************************************
* Name: imx9_edma_tcdhasmux
*
* Description:
* Check if DMA TCD has TCD.MUX register.
*
* Input Parameters:
* dmabase - The eDMA base.
*
* Returned Value:
* true if TCD.MUX exists; false if not.
*
****************************************************************************/
static inline bool imx9_edma_tcdhasmux(uintptr_t dmabase)
{
/* Only eDMA4 has TCD.MUX register */
return dmabase == IMX9_DMA4_BASE ? true : false;
}
/****************************************************************************
* Name: imx9_edma_choffset
*
* Description:
* Channel offset in global channel list for dma base.
*
* Input Parameters:
* base - The eDMA base.
*
* Returned Value:
* Channel offset.
*
****************************************************************************/
static inline uint32_t imx9_edma_choffset(uintptr_t base)
{
return base == IMX9_DMA3_BASE ? 0 : DMA3_CHANNEL_COUNT;
}
/****************************************************************************
* Name: imx9_edma_chmax
*
* Description:
* Max channel in global channel list for dma base.
*
* Input Parameters:
* base - The eDMA base.
*
* Returned Value:
* Channel max.
*
****************************************************************************/
static inline uint32_t imx9_edma_chmax(uintptr_t base)
{
return base == IMX9_DMA3_BASE ? DMA3_CHANNEL_COUNT : IMX9_EDMA_NCHANNELS;
}
#endif /* __ARCH_ARM64_SRC_IMX9_HARDWARE_IMX93_IMX93_EDMA_H */

View File

@ -0,0 +1,36 @@
/****************************************************************************
* arch/arm64/src/imx9/hardware/imx9_dmamux.h
*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership. The
* ASF licenses this file to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance with the
* License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*
****************************************************************************/
#ifndef __ARCH_ARM64_SRC_IMX9_HARDWARE_IMX9_DMAMUX_H
#define __ARCH_ARM64_SRC_IMX9_HARDWARE_IMX9_DMAMUX_H
/****************************************************************************
* Included Files
****************************************************************************/
#include <nuttx/config.h>
#if defined(CONFIG_ARCH_CHIP_IMX93)
# include "hardware/imx93/imx93_dmamux.h"
#else
# error Unrecognized i.MX9 architecture
#endif
#endif /* __ARCH_ARM64_SRC_IMX9_HARDWARE_IMX9_DMAMUX_H */

View File

@ -0,0 +1,36 @@
/****************************************************************************
* arch/arm64/src/imx9/hardware/imx9_edma.h
*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership. The
* ASF licenses this file to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance with the
* License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*
****************************************************************************/
#ifndef __ARCH_ARM64_SRC_IMX9_HARDWARE_IMX9_EDMA_H
#define __ARCH_ARM64_SRC_IMX9_HARDWARE_IMX9_EDMA_H
/****************************************************************************
* Included Files
****************************************************************************/
#include <nuttx/config.h>
#if defined(CONFIG_ARCH_CHIP_IMX93)
# include "hardware/imx93/imx93_edma.h"
#else
# error Unrecognized i.MX9 architecture
#endif
#endif /* __ARCH_ARM64_SRC_IMX9_HARDWARE_IMX9_EDMA_H */

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,482 @@
/****************************************************************************
* arch/arm64/src/imx9/imx9_edma.h
*
* Copyright (C) 2019, 2021, 2023 Gregory Nutt. All rights reserved.
* Copyright 2022 NXP
* Authors: Gregory Nutt <gnutt@nuttx.org>
* David Sidrane <david.sidrane@nscdg.com>
* Peter van der Perk <peter.vanderperk@nxp.com>
*
* This file was leveraged from the NuttX S32K1 port. Portions of that eDMA
* logic derived from NXP sample code which has a compatible BSD 3-clause
* license:
*
* Copyright (c) 2015, Freescale Semiconductor, Inc.
* Copyright 2016-2017 NXP
* All rights reserved
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
* 3. Neither the name NuttX nor the names of its contributors may be
* used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
****************************************************************************/
#ifndef __ARCH_ARM64_SRC_IMX9_IMX9_EDMA_H
#define __ARCH_ARM64_SRC_IMX9_IMX9_EDMA_H
/* General Usage:
*
* 1. Allocate a DMA channel
*
* DMACH_HANDLE handle;
* handle = edma_dmach_alloc(dmamux, dchpri);
*
* Where 'dmamux' is the channel DMAMUX configuration register setting and
* 'dchpri' is the channel DCHPRIO priority register setting.
*
* 2. Create the transfer configuration:
*
* struct imx9_edma_xfrconfig_s config;
* config.saddr = ..;
* config.daddr = ..;
* etc.
*
* 3. Setup the transfer in hardware:
*
* int ret;
* ret = imx9_dmach_xfrsetup(handle, &config);
*
* 4. If you are setting up a scatter gather DMA
* (with CONFIG_IMX9_EDMA_NTCD > 0), then repeat steps 2 and 3 for
* each segment of the transfer.
*
* 5. Start the DMA:
*
* ret = imx9_dmach_start(handle, my_callback_func, priv);
*
* Where my_callback_func() is called when the DMA completes or an error
* occurs. 'priv' represents some internal driver state that will be
* provided with the callback.
*
* 6. If you need to stop the DMA and free resources (such as if a timeout
* occurs), then:
*
* i mxrt_dmach_stop(handle);
*
* 7. The callback will be received when the DMA completes (or an error
* occurs). After that, you may free the DMA channel, or re-use it on
* subsequent DMAs.
*
* imx9_dmach_free(handle);
*
* Almost non-invasive debug instrumentation is available. You may call
* imx9_dmasample() to save the current state of the eDMA registers at
* any given point in time. At some later, postmortem analysis, you can
* dump the content of the buffered registers with imx9_dmadump().
* imx9_dmasample() is also available for monitoring DMA progress.
*/
/****************************************************************************
* Included Files
****************************************************************************/
#include <nuttx/config.h>
#include <stdint.h>
/****************************************************************************
* Pre-processor Definitions
****************************************************************************/
/* Configuration flags.
*
* REVISIT: Many missing options that should be represented as flags:
* 1. Bandwidth
* 2. Source/Destination modulo
*/
#define EDMA_CONFIG_LINKTYPE_SHIFT (0) /* Bits 0-1: Link type */
#define EDMA_CONFIG_LINKTYPE_MASK (3 << EDMA_CONFIG_LINKTYPE_SHIFT)
# define EDMA_CONFIG_LINKTYPE_LINKNONE (0 << EDMA_CONFIG_LINKTYPE_SHIFT) /* No channel link */
# define EDMA_CONFIG_LINKTYPE_MINORLINK (1 << EDMA_CONFIG_LINKTYPE_SHIFT) /* Channel link after each minor loop */
# define EDMA_CONFIG_LINKTYPE_MAJORLINK (2 << EDMA_CONFIG_LINKTYPE_SHIFT) /* Channel link when major loop count exhausted */
#define EDMA_CONFIG_LOOP_SHIFT (2) /* Bits 2: Loop type */
#define EDMA_CONFIG_LOOP_MASK (3 << EDMA_CONFIG_LOOP_SHIFT)
# define EDMA_CONFIG_LOOPNONE (0 << EDMA_CONFIG_LOOP_SHIFT) /* No looping */
# define EDMA_CONFIG_LOOPSRC (1 << EDMA_CONFIG_LOOP_SHIFT) /* Source looping */
# define EDMA_CONFIG_LOOPDEST (2 << EDMA_CONFIG_LOOP_SHIFT) /* Dest looping */
#define EDMA_CONFIG_INTHALF (1 << 4) /* Bits 4: Int on HALF */
#define EDMA_CONFIG_INTMAJOR (1 << 5) /* Bits 5: Int on all Major completion
* Default is only on last completion
* if using scatter gather
*/
/****************************************************************************
* Public Types
****************************************************************************/
typedef void *DMACH_HANDLE;
typedef void (*edma_callback_t)(DMACH_HANDLE handle,
void *arg, bool done, int result);
/* eDMA transfer type */
enum imx9_edma_xfrtype_e
{
EDMA_MEM2MEM = 0, /* Transfer from memory to memory */
EDMA_PERIPH2MEM, /* Transfer from peripheral to memory */
EDMA_MEM2PERIPH, /* Transfer from memory to peripheral */
};
/* eDMA transfer sises */
enum imx9_edma_sizes_e
{
EDMA_8BIT = 0, /* Transfer data size 8 */
EDMA_16BIT = 1, /* Transfer data size 16 */
EDMA_32BIT = 2, /* Transfer data size 32 */
EDMA_64BIT = 3, /* Transfer data size 64 */
EDMA_16BYTE = 4, /* Transfer data size 16-byte */
EDMA_32BYTE = 5, /* Transfer data size 32-byte */
EDMA_64BYTE = 6, /* Transfer data size 64-byte */
};
/* This structure holds the source/destination transfer attribute
* configuration.
*/
struct imx9_edma_xfrconfig_s
{
uintptr_t saddr; /* Source data address. */
uintptr_t daddr; /* Destination data address. */
int16_t soff; /* Sign-extended offset for current source address. */
int16_t doff; /* Sign-extended offset for current destination address. */
uint16_t iter; /* Major loop iteration count. */
uint8_t flags; /* See EDMA_CONFIG_* definitions */
uint8_t ssize; /* Source data transfer size (see TCD_ATTR_SIZE_* definitions in rdware/. */
uint8_t dsize; /* Destination data transfer size. */
#ifdef CONFIG_IMX9_EDMA_EMLIM
uint16_t nbytes; /* Bytes to transfer in a minor loop */
#else
uint32_t nbytes; /* Bytes to transfer in a minor loop */
#endif
#ifdef CONFIG_IMX9_EDMA_MOD
uint8_t smod;
uint8_t dmod;
#endif
#ifdef CONFIG_IMX9_EDMA_BWC
uint8_t bwc;
#endif
#ifdef CONFIG_IMX9_EDMA_ELINK
DMACH_HANDLE linkch; /* Link channel (With EDMA_CONFIG_LINKTYPE_* flags) */
#endif
};
/* The following is used for sampling DMA registers when CONFIG DEBUG_DMA
* is selected
*/
#ifdef CONFIG_DEBUG_DMA
struct imx9_dmaregs_s
{
uint8_t chan; /* Sampled channel */
/* eDMA Global Registers */
uint32_t cr; /* Control */
uint32_t es; /* Error Status */
uint32_t req; /* Interrupt Request */
uint32_t hrs; /* Hardware Request Status */
/* eDMA Channel registers */
uint8_t dchpri; /* Channel priority */
/* eDMA TCD */
uint32_t saddr; /* TCD Source Address */
uint16_t soff; /* TCD Signed Source Address Offset */
uint16_t attr; /* TCD Transfer Attributes */
uint32_t nbml; /* TCD Signed Minor Loop Offset / Byte Count */
uint32_t slast; /* TCD Last Source Address Adjustment */
uint32_t daddr; /* TCD Destination Address */
uint16_t doff; /* TCD Signed Destination Address Offset */
uint16_t citer; /* TCD Current Minor Loop Link, Major Loop Count */
uint32_t dlastsga; /* TCD Last Destination Address Adjustment/Scatter Gather Address */
uint16_t csr; /* TCD Control and Status */
uint16_t biter; /* TCD Beginning Minor Loop Link, Major Loop Count */
/* DMAMUX registers */
uint32_t dmamux; /* Channel configuration */
};
#endif /* CONFIG_DEBUG_DMA */
/****************************************************************************
* Inline Functions
****************************************************************************/
#ifndef __ASSEMBLY__
/****************************************************************************
* Public Data
****************************************************************************/
#undef EXTERN
#if defined(__cplusplus)
#define EXTERN extern "C"
extern "C"
{
#else
#define EXTERN extern
#endif
/****************************************************************************
* Public Function Prototypes
****************************************************************************/
/****************************************************************************
* Name: imx9_dmach_alloc
*
* Allocate a DMA channel. This function sets aside a DMA channel,
* initializes the DMAMUX for the channel, then gives the caller exclusive
* access to the DMA channel.
*
* Input Parameters:
* dmamux - DMAMUX configuration see DMAMUX channel configuration register
* bit-field definitions in hardware/imx9_dmamux.h.
* Settings include:
*
* DMAMUX_CHCFG_SOURCE Chip-specific DMA source (required)
* DMAMUX_CHCFG_TRIG DMA Channel Trigger Enable (optional)
* DMAMUX_CHCFG_ENBL DMA Mux Channel Enable (required)
*
* A value of zero will disable the DMAMUX channel.
* dchpri - DCHPRI channel priority configuration. See DCHPRI channel
* configuration register bit-field definitions in
* hardware/imx9_edma.h. Meaningful settings include:
*
* EDMA_DCHPRI_CHPRI Channel Arbitration Priority
* DCHPRI_DPA Disable Preempt Ability
* DCHPRI_ECP Enable Channel Preemption
*
* The power-on default, 0x05, is a reasonable choice.
*
* Returned Value:
* If a DMA channel is available, this function returns a non-NULL, void*
* DMA channel handle. NULL is returned on any failure.
*
****************************************************************************/
DMACH_HANDLE imx9_dmach_alloc(uint16_t dmamux, uint8_t dchpri);
/****************************************************************************
* Name: imx9_dmach_free
*
* Description:
* Release a DMA channel.
* NOTE: The 'handle' used in this argument must NEVER be used again
* until imx9_dmach_alloc() is called again to re-gain a valid handle.
*
* Returned Value:
* None
*
****************************************************************************/
void imx9_dmach_free(DMACH_HANDLE handle);
/****************************************************************************
* Name: imx9_dmach_xfrsetup
*
* Description:
* This function adds the eDMA transfer to the DMA sequence. The request
* is setup according to the content of the transfer configuration
* structure. For "normal" DMA, imx9_dmach_xfrsetup is called only
* once.
* Scatter/gather DMA is accomplished by calling this function repeatedly,
* once for each transfer in the sequence. Scatter/gather DMA processing
* is enabled automatically when the second transfer configuration is
* received.
*
* This function may be called multiple times to handle multiple,
* discontinuous transfers (scatter-gather)
*
* Input Parameters:
* handle - DMA channel handle created by imx9_dmach_alloc()
* config - A DMA transfer configuration instance, populated by the
* The content of 'config' describes the transfer
*
* Returned Value
* Zero (OK) is returned on success; a negated errno value is returned on
* any failure.
*
****************************************************************************/
int imx9_dmach_xfrsetup(DMACH_HANDLE *handle,
const struct imx9_edma_xfrconfig_s *config);
/****************************************************************************
* Name: imx9_dmach_start
*
* Description:
* Start the DMA transfer by enabling the channel DMA request.
* This function should be called after the final call to
* imx9_dmasetup() in order to avoid race conditions.
*
* At the conclusion of each major DMA loop, a callback to the
* user-provided function is made: |For "normal" DMAs, this will
* correspond to the DMA DONE interrupt; for scatter gather DMAs, multiple
* interrupts will be generated with the final being the DONE interrupt.
*
* At the conclusion of the DMA, the DMA channel is reset, all TCDs are
* freed, and the callback function is called with the the success/fail
* result of the DMA.
*
* NOTE:
* On Rx DMAs (peripheral-to-memory or memory-to-memory), it is necessary
* to invalidate the destination memory. That is not done automatically
* by the DMA module. Invalidation of the destination memory regions is
* the responsibility of the caller.
*
* Input Parameters:
* handle - DMA channel handle created by imx9_dmach_alloc()
* callback - The callback to be invoked when the DMA is completes or is
* aborted.
* arg - An argument that accompanies the callback
*
* Returned Value:
* Zero (OK) is returned on success; a negated errno value is returned on
* any failure.
*
****************************************************************************/
int imx9_dmach_start(DMACH_HANDLE handle, edma_callback_t callback,
void *arg);
/****************************************************************************
* Name: imx9_dmach_stop
*
* Description:
* Cancel the DMA. After imx9_dmach_stop() is called, the DMA channel
* is reset, all TCDs are freed, and imx9_dmarx/txsetup() must be called
* before imx9_dmach_start() can be called again
*
* Input Parameters:
* handle - DMA channel handle created by imx9_dmach_alloc()
*
* Returned Value:
* None.
*
****************************************************************************/
void imx9_dmach_stop(DMACH_HANDLE handle);
/****************************************************************************
* Name: imx9_dmach_getcount
*
* Description:
* This function checks the TCD (Task Control Descriptor) status for a
* specified eDMA channel and returns the the number of major loop counts
* that have not finished.
*
* NOTES:
* 1. This function can only be used to get unfinished major loop count of
* transfer without the next TCD, or it might be inaccuracy.
* 2. The unfinished/remaining transfer bytes cannot be obtained directly
* from registers while the channel is running.
*
* Because to calculate the remaining bytes, the initial NBYTES configured
* in DMA_TCDn_NBYTES_MLNO register is needed while the eDMA IP does not
* support getting it while a channel is active. In another words, the
* NBYTES value reading is always the actual (decrementing) NBYTES value
* the dma_engine is working with while a channel is running.
* Consequently, to get the remaining transfer bytes, a software-saved
* initial value of NBYTES (for example copied before enabling the channel)
* is needed. The formula to calculate it is shown below:
*
* RemainingBytes = RemainingMajorLoopCount * NBYTES(initially configured)
*
* Input Parameters:
* handle - DMA channel handle created by imx9_dmach_alloc()
*
* Returned Value:
* Major loop count which has not been transferred yet for the current TCD.
*
****************************************************************************/
unsigned int imx9_dmach_getcount(DMACH_HANDLE *handle);
/****************************************************************************
* Name: imx9_dmach_idle
*
* Description:
* This function checks if the dma is idle
*
* Returned Value:
* 0 - if idle
* !0 - not
*
****************************************************************************/
unsigned int imx9_dmach_idle(DMACH_HANDLE handle);
/****************************************************************************
* Name: imx9_dmasample
*
* Description:
* Sample DMA register contents
*
****************************************************************************/
#ifdef CONFIG_DEBUG_DMA
void imx9_dmasample(DMACH_HANDLE handle, struct imx9_dmaregs_s *regs);
#else
# define imx9_dmasample(handle,regs)
#endif
/****************************************************************************
* Name: imx9_dmadump
*
* Description:
* Dump previously sampled DMA register contents
*
****************************************************************************/
#ifdef CONFIG_DEBUG_DMA
void imx9_dmadump(const struct imx9_dmaregs_s *regs, const char *msg);
#else
# define imx9_dmadump(handle,regs,msg)
#endif
#undef EXTERN
#if defined(__cplusplus)
}
#endif
#endif /* __ASSEMBLY__ */
#endif /* __ARCH_ARM64_SRC_IMX9_IMX9_EDMA_H */