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:
parent
5c3fc2796b
commit
89752e9993
@ -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)
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
209
arch/arm64/src/imx9/hardware/imx93/imx93_dmamux.h
Normal file
209
arch/arm64/src/imx9/hardware/imx93/imx93_dmamux.h
Normal 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 */
|
436
arch/arm64/src/imx9/hardware/imx93/imx93_edma.h
Normal file
436
arch/arm64/src/imx9/hardware/imx93/imx93_edma.h
Normal 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 */
|
36
arch/arm64/src/imx9/hardware/imx9_dmamux.h
Normal file
36
arch/arm64/src/imx9/hardware/imx9_dmamux.h
Normal 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 */
|
36
arch/arm64/src/imx9/hardware/imx9_edma.h
Normal file
36
arch/arm64/src/imx9/hardware/imx9_edma.h
Normal 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 */
|
1509
arch/arm64/src/imx9/imx9_edma.c
Normal file
1509
arch/arm64/src/imx9/imx9_edma.c
Normal file
File diff suppressed because it is too large
Load Diff
482
arch/arm64/src/imx9/imx9_edma.h
Normal file
482
arch/arm64/src/imx9/imx9_edma.h
Normal 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 */
|
Loading…
Reference in New Issue
Block a user