diff --git a/arch/arm64/src/imx9/Kconfig b/arch/arm64/src/imx9/Kconfig index 4ad6caf585dcc..82387fb438c5e 100644 --- a/arch/arm64/src/imx9/Kconfig +++ b/arch/arm64/src/imx9/Kconfig @@ -24,6 +24,24 @@ endchoice # i.MX9 Chip Selection endmenu # "i.MX9 Chip Selection" +config IMX9_DMA_ALLOC + bool "Enable DMA capable memory allocator" + depends on GRAN + default y if CONFIG_FAT_DMAMEMORY + +menu "DMA Allocator Configuration" + depends on IMX9_DMA_ALLOC + +config IMX9_DMA_ALLOC_POOL_SIZE + int "DMA allocator memory pool size in bytes" + default 4096 + +config IMX9_DMA_ALLOC_SECT + string "Section for DMA allocator memory pool, default is .bss" + default ".bss" + +endmenu # DMA Allocator Configuration + config IMX9_FLEXIO_PWM bool select PWM_MULTICHAN diff --git a/arch/arm64/src/imx9/Make.defs b/arch/arm64/src/imx9/Make.defs index dcca949e0f42e..9bce853d4626a 100644 --- a/arch/arm64/src/imx9/Make.defs +++ b/arch/arm64/src/imx9/Make.defs @@ -55,3 +55,7 @@ endif ifeq ($(CONFIG_IMX9_EDMA), y) CHIP_CSRCS += imx9_edma.c endif + +ifeq ($(CONFIG_IMX9_DMA_ALLOC),y) + CHIP_CSRCS += imx9_dma_alloc.c +endif diff --git a/arch/arm64/src/imx9/imx9_dma_alloc.c b/arch/arm64/src/imx9/imx9_dma_alloc.c new file mode 100644 index 0000000000000..b397f9112745d --- /dev/null +++ b/arch/arm64/src/imx9/imx9_dma_alloc.c @@ -0,0 +1,145 @@ +/**************************************************************************** + * arch/arm64/src/imx9/imx9_dma_alloc.c + * + * 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. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include + +#include + +#include + +#if defined(CONFIG_IMX9_DMA_ALLOC) + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* DMA buffers must be aligned with the D-Cache line boundaries to facilitate + * cache operations on the DMA buffers when the D-Cache is enabled. + */ + +#define DMA_ALIGN ARMV8A_DCACHE_LINESIZE +#define DMA_ALIGN_MASK (DMA_ALIGN - 1) +#define DMA_ALIGN_UP(n) (((n) + DMA_ALIGN_MASK) & ~DMA_ALIGN_MASK) + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +static GRAN_HANDLE dma_allocator; + +/* The DMA heap size constrains the total number of things that can be + * ready to do DMA at a time. + * + * For example, FAT DMA depends on one sector-sized buffer per filesystem + * plus one sector-sized buffer per file. + * + * We use a fundamental alignment / granule size of 64B; it fulfills the + * requirement for any DMA engine. + */ + +static uint8_t g_dma_heap[CONFIG_IMX9_DMA_ALLOC_POOL_SIZE] +aligned_data(DMA_ALIGN) locate_data(CONFIG_IMX9_DMA_ALLOC_SECT); + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: imx9_dma_alloc_init + * + * Description: + * Initialize the DMA memory allocator. + * + * Returned Value: + * Zero (OK) is returned on success; a negated errno value is returned + * on failure. + * + ****************************************************************************/ + +int imx9_dma_alloc_init(void) +{ + /* Allocate 64B granules with 64B alignment */ + + /* REVISIT: Use 256B granule size to get 8K maximum allocation. This is a + * limitation in the granule allocator itself. + */ + + dma_allocator = gran_initialize(g_dma_heap, sizeof(g_dma_heap), 8, 6); + + if (dma_allocator == NULL) + { + return -ENOMEM; + } + + return OK; +} + +/**************************************************************************** + * Name: imx9_dma_alloc + * + * Description: + * Allocate a contiguous block of physical memory for DMA. + * + * Input Parameters: + * size - Size of the requested block in bytes. + * + * Returned Value: + * Physical address of the first page on success; NULL on failure. + * + ****************************************************************************/ + +void *imx9_dma_alloc(size_t size) +{ + return gran_alloc(dma_allocator, size); +} + +/**************************************************************************** + * Name: imx9_dma_free + * + * Description: + * Free a previously allocated DMA memory block. + * + * Input Parameters: + * memory - Physical address of the first page of DMA memory. + * size - Size of the allocated block in bytes. + * + * Returned Value: + * None. + * + ****************************************************************************/ + +void imx9_dma_free(void *memory, size_t size) +{ + gran_free(dma_allocator, memory, size); +} + +#endif /* CONFIG_IMX9_DMA_ALLOC */ diff --git a/arch/arm64/src/imx9/imx9_dma_alloc.h b/arch/arm64/src/imx9/imx9_dma_alloc.h new file mode 100644 index 0000000000000..dd98bdf3695b9 --- /dev/null +++ b/arch/arm64/src/imx9/imx9_dma_alloc.h @@ -0,0 +1,88 @@ +/**************************************************************************** + * arch/arm64/src/imx9/imx9_dma_alloc.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_IMX9_DMA_ALLOC_H +#define __ARCH_ARM64_SRC_IMX9_IMX9_DMA_ALLOC_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +/**************************************************************************** + * Name: imx9_dma_alloc_init + * + * Description: + * Initialize the DMA memory allocator. + * + * Returned Value: + * Zero (OK) is returned on success; a negated errno value is returned + * on failure. + * + ****************************************************************************/ + +int imx9_dma_alloc_init(void); + +/**************************************************************************** + * Name: imx9_dma_alloc + * + * Description: + * Allocate a contiguous block of physical memory for DMA. + * + * Input Parameters: + * size - Size of the requested block in bytes. + * + * Returned Value: + * Physical address of the first page on success; NULL on failure. + * + ****************************************************************************/ + +void *imx9_dma_alloc(size_t size); + +/**************************************************************************** + * Name: imx9_dma_free + * + * Description: + * Free a previously allocated DMA memory block. + * + * Input Parameters: + * memory - Physical address of the first page of DMA memory. + * size - Size of the allocated block in bytes. + * + * Returned Value: + * None. + * + ****************************************************************************/ + +void imx9_dma_free(void *memory, size_t size); + +#ifdef CONFIG_FAT_DMAMEMORY +# define fat_dma_alloc(s) imx9_dma_alloc(s) +# define fat_dma_free(m,s) imx9_dma_free(m,s) +#endif + +#endif /* __ARCH_ARM64_SRC_IMX9_IMX9_DMA_ALLOC_H */ diff --git a/boards/arm64/imx9/imx93-evk/configs/nsh/defconfig b/boards/arm64/imx9/imx93-evk/configs/nsh/defconfig index 8c685db7a90db..791d4dad57ad0 100644 --- a/boards/arm64/imx9/imx93-evk/configs/nsh/defconfig +++ b/boards/arm64/imx9/imx93-evk/configs/nsh/defconfig @@ -26,11 +26,15 @@ CONFIG_EXAMPLES_HELLO=y CONFIG_EXPERIMENTAL=y CONFIG_FS_PROCFS=y CONFIG_FS_ROMFS=y +CONFIG_GRAN=y CONFIG_HAVE_CXX=y CONFIG_HAVE_CXXINITIALIZE=y CONFIG_I2C=y CONFIG_I2C_RESET=y CONFIG_IDLETHREAD_STACKSIZE=8192 +CONFIG_IMX9_DMA_ALLOC=y +CONFIG_IMX9_DMA_ALLOC_POOL_SIZE=81920 +CONFIG_IMX9_DMA_ALLOC_SECT=".bss" CONFIG_IMX9_EDMA=y CONFIG_IMX9_FLEXIO1_PWM=y CONFIG_IMX9_GPIO_IRQ=y diff --git a/boards/arm64/imx9/imx93-evk/src/imx9_bringup.c b/boards/arm64/imx9/imx93-evk/src/imx9_bringup.c index acd7b309a0afe..fc27bc3c9567b 100644 --- a/boards/arm64/imx9/imx93-evk/src/imx9_bringup.c +++ b/boards/arm64/imx9/imx93-evk/src/imx9_bringup.c @@ -29,6 +29,8 @@ #include +#include "imx9_dma_alloc.h" + #include "imx93-evk.h" /**************************************************************************** @@ -57,6 +59,16 @@ int imx9_bringup(void) } #endif +#ifdef CONFIG_IMX9_DMA_ALLOC + /* Initialize the DMA memory allocator */ + + ret = imx9_dma_alloc_init(); + if (ret < 0) + { + syslog(LOG_ERR, "ERROR: Failed initialize DMA allocator: %d\n", ret); + } +#endif + #ifdef CONFIG_PWM /* Configure PWM outputs */