diff --git a/arch/risc-v/src/mpfs/Kconfig b/arch/risc-v/src/mpfs/Kconfig index 44bb9f38826..dc8ced74850 100755 --- a/arch/risc-v/src/mpfs/Kconfig +++ b/arch/risc-v/src/mpfs/Kconfig @@ -105,7 +105,15 @@ config MPFS_I2C1 endmenu +config MPFS_DMA + bool "MPFS DMA (PDMA)" + default n + select ARCH_DMA + ---help--- + Enable DMA Support. MPFS DMA is Memory-to-Memory only. + menu "MPFS Others" - endmenu + + diff --git a/arch/risc-v/src/mpfs/Make.defs b/arch/risc-v/src/mpfs/Make.defs index 5582815d53b..35bbc0019c7 100755 --- a/arch/risc-v/src/mpfs/Make.defs +++ b/arch/risc-v/src/mpfs/Make.defs @@ -54,6 +54,10 @@ CHIP_CSRCS += mpfs_lowputc.c mpfs_serial.c CHIP_CSRCS += mpfs_start.c mpfs_timerisr.c CHIP_CSRCS += mpfs_gpio.c mpfs_systemreset.c +ifeq ($(CONFIG_MPFS_DMA),y) +CHIP_CSRCS += mpfs_dma.c +endif + ifeq ($(CONFIG_BUILD_PROTECTED),y) CMN_CSRCS += riscv_task_start.c riscv_pthread_start.c CMN_CSRCS += riscv_signal_dispatch.c riscv_pmp.c diff --git a/arch/risc-v/src/mpfs/hardware/mpfs_dma.h b/arch/risc-v/src/mpfs/hardware/mpfs_dma.h new file mode 100755 index 00000000000..422652966fc --- /dev/null +++ b/arch/risc-v/src/mpfs/hardware/mpfs_dma.h @@ -0,0 +1,136 @@ +/**************************************************************************** + * arch/risc-v/src/mpfs/hardware/mpfs_dma.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_RISCV_SRC_MPFS_HARDWARE_MPFS_DMA_H +#define __ARCH_RISCV_SRC_MPFS_HARDWARE_MPFS_DMA_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include "hardware/mpfs_memorymap.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* Register offsets *********************************************************/ + +#define MPFS_DMA_CONTROL_OFFSET 0x0000 /* Channel control register */ +#define MPFS_DMA_NEXT_CONFIG_OFFSET 0x0004 /* Next transfer type */ +#define MPFS_DMA_NEXT_BYTES_OFFSET 0x0008 /* Number of bytes to move */ +#define MPFS_DMA_NEXT_DESTINATION_OFFSET 0x0010 /* Destination start address */ +#define MPFS_DMA_NEXT_SOURCE_OFFSET 0x0018 /* Source start address */ +#define MPFS_DMA_EXEC_CONFIG_OFFSET 0x0104 /* Active transfer type */ +#define MPFS_DMA_EXEC_BYTES_OFFSET 0x0108 /* Number of bytes remaining */ +#define MPFS_DMA_EXEC_DESTINATION_OFFSET 0x0110 /* Destination current address */ +#define MPFS_DMA_EXEC_SOURCE_OFFSET 0x0118 /* Source current address */ + +#define MPFS_DMA_CHANNEL_OFFSET 0x1000 /* Offset to channels */ + +#define MPFS_DMA_REG_OFFSET(x) \ + (uint64_t)(MPFS_PDMA_BASE + (MPFS_DMA_CHANNEL_OFFSET * (x))) + +/* Register bit field definitions *******************************************/ + +/* Control register */ + +/* Indicates that the channel is in use. Setting this bit clears all of the + * channel’s Next registers (NextConfig, NextBytes, NextDestination, and + * NextSource). This bit can only be cleared when run (CR bit 0) is low. + */ + +#define DMA_CONTROL_CLAIM_SHIFT (0) /* Bit: 0: claim */ +#define DMA_CONTROL_CLAIM_MASK (1 << DMA_CONTROL_CLAIM_SHIFT) +# define DMA_CONTROL_CLAIM (0 << DMA_CONTROL_CLAIM_SHIFT) + +/* Setting this bit starts a DMA transfer by copying the Next registers + * into their Exec counterparts. + */ + +#define DMA_CONTROL_RUN_SHIFT (1) /* Bit: 1: run */ +#define DMA_CONTROL_RUN_MASK (1 << DMA_CONTROL_RUN_SHIFT) +# define DMA_CONTROL_RUN (1 << DMA_CONTROL_RUN_SHIFT) + +/* Setting this bit will trigger the channel’s Done interrupt once + * a transfer is complete. + */ + +#define DMA_CONTROL_DONEIE_SHIFT (14) /* Bit: 14: Done Irq enable */ +#define DMA_CONTROL_DONEIE_MASK (1 << DMA_CONTROL_DONEIE_SHIFT) +# define DMA_CONTROL_DONEIE (1 << DMA_CONTROL_DONEIE_SHIFT) + +/* Setting this bit will trigger the channel’s Done interrupt once + * a transfer is complete. + */ + +#define DMA_CONTROL_ERRORIE_SHIFT (15) /* Bit: 15: Error Irq enable */ +#define DMA_CONTROL_ERRORIE_MASK (1 << DMA_CONTROL_ERRORIE_SHIFT) +# define DMA_CONTROL_ERRORIE (1 << DMA_CONTROL_ERRORIE_SHIFT) + +/* Indicates that a transfer has completed since the channel was claimed */ + +#define DMA_CONTROL_DONE_SHIFT (30) /* Bit: 30: Done */ +#define DMA_CONTROL_DONE_MASK (1 << DMA_CONTROL_DONE_SHIFT) +# define DMA_CONTROL_DONE (1 << DMA_CONTROL_DONE_SHIFT) + +/* Indicates that a transfer error has occurred since the channel + * was claimed + */ + +#define DMA_CONTROL_ERROR_SHIFT (31) /* Bit: 31: Error */ +#define DMA_CONTROL_ERROR_MASK (1 << DMA_CONTROL_ERROR_SHIFT) +# define DMA_CONTROL_ERROR (1 << DMA_CONTROL_ERROR_SHIFT) + +/* Channel Next Configuration Register */ + +/* If set, the Exec registers are reloaded from the Next registers once a + * transfer is complete. The repeat bit must be cleared by software + * for the sequence to stop + */ + +#define DMA_NEXT_CONFIG_REPEAT_SHIFT (2) /* Bit: 2: repeat */ +#define DMA_NEXT_CONFIG_REPEAT_MASK (1 << DMA_NEXT_CONFIG_REPEAT_SHIFT) +# define DMA_NEXT_CONFIG_REPEAT (1 << DMA_NEXT_CONFIG_REPEAT_SHIFT) + +/* Enforces strict ordering by only allowing one of each transfer type + * in-flight at a time + */ + +#define DMA_NEXT_CONFIG_ORDER_SHIFT (3) /* Bit: 3: order */ +#define DMA_NEXT_CONFIG_ORDER_MASK (1 << DMA_NEXT_CONFIG_ORDER_SHIFT) +# define DMA_NEXT_CONFIG_ORDER (1 << DMA_NEXT_CONFIG_ORDER_SHIFT) + +/* WSIZE and RSIZE. Base 2 Logarithm of DMA transaction sizes. + * Example: 0 is 1 byte, 3 is 8 bytes, 5 is 32 bytes + * These fields are WARL (Write-Any Read-Legal), so the actual size used + * can be determined by reading the field after writing the requested size. + * */ + +#define DMA_NEXT_CONFIG_WSIZE_SHIFT (24) /* Bits: 24-27: write size */ +#define DMA_NEXT_CONFIG_WSIZE_MASK (15 << DMA_NEXT_CONFIG_WSIZE_SHIFT) +# define DMA_NEXT_CONFIG_WSIZE(x) (x << DMA_NEXT_CONFIG_WSIZE_SHIFT) + +#define DMA_NEXT_CONFIG_RSIZE_SHIFT (28) /* Bits: 28-31: read size */ +#define DMA_NEXT_CONFIG_RSIZE_MASK (15 << DMA_NEXT_CONFIG_RSIZE_SHIFT) +# define DMA_NEXT_CONFIG_RSIZE(x) (x << DMA_NEXT_CONFIG_RSIZE_SHIFT) + +#endif /* __ARCH_RISCV_SRC_MPFS_HARDWARE_MPFS_DMA_H */ diff --git a/arch/risc-v/src/mpfs/hardware/mpfs_memorymap.h b/arch/risc-v/src/mpfs/hardware/mpfs_memorymap.h index 4d07554114f..ff7c0e6f873 100755 --- a/arch/risc-v/src/mpfs/hardware/mpfs_memorymap.h +++ b/arch/risc-v/src/mpfs/hardware/mpfs_memorymap.h @@ -27,8 +27,9 @@ /* Register Base Address ****************************************************/ -#define MPFS_PLIC_BASE (0x0C000000UL) #define MPFS_CLINT_BASE (0x02000000UL) +#define MPFS_PDMA_BASE (0x03000000UL) +#define MPFS_PLIC_BASE (0x0C000000UL) #define MPFS_UART0_LO_BASE (0x20000000UL) #define MPFS_WDOG0_LO_BASE (0x20001000UL) diff --git a/arch/risc-v/src/mpfs/mpfs_dma.c b/arch/risc-v/src/mpfs/mpfs_dma.c new file mode 100755 index 00000000000..d2454c5ce47 --- /dev/null +++ b/arch/risc-v/src/mpfs/mpfs_dma.c @@ -0,0 +1,516 @@ +/**************************************************************************** + * arch/risc-v/src/mpfs/mpfs_dma.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 + +#include "riscv_arch.h" +#include "hardware/mpfs_dma.h" +#include "mpfs_dma.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#define DMA_MAX_TRANSACTION_SIZE (0x0f) + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +static uint8_t g_channel_nextcfg_wsize[MPFS_DMA_NUM_CHANNELS] = +{ + DMA_MAX_TRANSACTION_SIZE, DMA_MAX_TRANSACTION_SIZE, + DMA_MAX_TRANSACTION_SIZE, DMA_MAX_TRANSACTION_SIZE +}; + +static uint8_t g_channel_nextcfg_rsize[MPFS_DMA_NUM_CHANNELS] = +{ + DMA_MAX_TRANSACTION_SIZE, DMA_MAX_TRANSACTION_SIZE, + DMA_MAX_TRANSACTION_SIZE, DMA_MAX_TRANSACTION_SIZE +}; + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: mpfs_dma_setup_transfer + * + * Description: + * Set DMA transfer config for channel. + * + * Parameters: + * channel - Channel number 0-3 + * config - Pointer to the config structure. + * + * Returned Value: + * Zero (OK) is returned on success. A negated errno value is returned on + * failure. + * + ****************************************************************************/ + +int mpfs_dma_setup_transfer(unsigned int channel, + struct mpfs_dma_channel_config *config) +{ + if (channel >= MPFS_DMA_NUM_CHANNELS) + { + dmawarn("Illegal channel"); + return -EINVAL; + } + + if (config->src_addr == 0) + { + dmawarn("Illegal source address\n"); + return -EINVAL; + } + + if (config->dest_addr == 0) + { + dmawarn("Illegal destination address\n"); + return -EINVAL; + } + + /* If transaction is in progress, return error. */ + + if (getreg32(MPFS_DMA_REG_OFFSET(channel)) & DMA_CONTROL_RUN_MASK) + { + dmawarn("channel busy\n"); + return -EBUSY; + } + + /* Set or clear the interrupts for the transfer. */ + + if (config->enable_done_int) + { + dmainfo("enable done irq\n"); + modifyreg32(MPFS_DMA_REG_OFFSET(channel) + MPFS_DMA_CONTROL_OFFSET, + 0, DMA_CONTROL_DONEIE); + } + else + { + dmainfo("disable done irq\n"); + modifyreg32(MPFS_DMA_REG_OFFSET(channel) + MPFS_DMA_CONTROL_OFFSET, + DMA_CONTROL_DONEIE_MASK, 0); + } + + if (config->enable_err_int) + { + dmainfo("enable err irq\n"); + modifyreg32(MPFS_DMA_REG_OFFSET(channel) + MPFS_DMA_CONTROL_OFFSET, + 0, DMA_CONTROL_ERRORIE); + } + else + { + dmainfo("disable err irq\n"); + modifyreg32(MPFS_DMA_REG_OFFSET(channel) + MPFS_DMA_CONTROL_OFFSET, + DMA_CONTROL_ERRORIE_MASK, 0); + } + + /* clear Next registers. */ + + modifyreg32(MPFS_DMA_REG_OFFSET(channel) + MPFS_DMA_CONTROL_OFFSET, + 0, DMA_CONTROL_CLAIM); + + /* clear Done and Error */ + + modifyreg32(MPFS_DMA_REG_OFFSET(channel) + MPFS_DMA_CONTROL_OFFSET, + DMA_CONTROL_DONE_MASK | DMA_CONTROL_ERROR_MASK, 0); + + /* Setup the source and destination addresses. */ + + putreg64(config->dest_addr, + MPFS_DMA_REG_OFFSET(channel) + MPFS_DMA_NEXT_DESTINATION_OFFSET); + putreg64(config->src_addr, + MPFS_DMA_REG_OFFSET(channel) + MPFS_DMA_NEXT_SOURCE_OFFSET); + + /* Set the transfer size. */ + + putreg64(config->num_bytes, + MPFS_DMA_REG_OFFSET(channel) + MPFS_DMA_NEXT_BYTES_OFFSET); + + /* Setup repeat and force order requirements. */ + + if (config->repeat) + { + modifyreg32(MPFS_DMA_REG_OFFSET(channel) + MPFS_DMA_NEXT_CONFIG_OFFSET, + 0, DMA_NEXT_CONFIG_REPEAT); + } + else + { + modifyreg32(MPFS_DMA_REG_OFFSET(channel) + MPFS_DMA_NEXT_CONFIG_OFFSET, + DMA_NEXT_CONFIG_REPEAT_MASK, 0); + } + + if (config->force_order) + { + modifyreg32(MPFS_DMA_REG_OFFSET(channel) + MPFS_DMA_NEXT_CONFIG_OFFSET, + 0, DMA_NEXT_CONFIG_ORDER); + } + else + { + modifyreg32(MPFS_DMA_REG_OFFSET(channel) + MPFS_DMA_NEXT_CONFIG_OFFSET, + DMA_NEXT_CONFIG_ORDER_MASK, 0); + } + + /* Set PDMA transaction size to maximum. */ + + modifyreg32(MPFS_DMA_REG_OFFSET(channel) + MPFS_DMA_NEXT_CONFIG_OFFSET, + DMA_NEXT_CONFIG_WSIZE_MASK, + DMA_NEXT_CONFIG_WSIZE(g_channel_nextcfg_wsize[channel])); + + modifyreg32(MPFS_DMA_REG_OFFSET(channel) + MPFS_DMA_NEXT_CONFIG_OFFSET, + DMA_NEXT_CONFIG_RSIZE_MASK, + DMA_NEXT_CONFIG_RSIZE(g_channel_nextcfg_wsize[channel])); + + dmainfodumpbuffer("dma regs", (uint8_t *)MPFS_DMA_REG_OFFSET(channel), + MPFS_DMA_NEXT_SOURCE_OFFSET + 8); + + return OK; +} + +/**************************************************************************** + * Name: mpfs_dma_set_transaction_size + * + * Description: + * Set read and write transaction size for mpfs_dma_setup_transfer() + * + * Parameters: + * channel - Channel number 0-3 + * write_size - Write transaction size + * read_size - Read transaction size + * + * Returned Value: + * Zero (OK) is returned on success. A negated errno value is returned on + * failure. + * + ****************************************************************************/ + +int mpfs_dma_set_transaction_size(unsigned int channel, + uint8_t write_size, uint8_t read_size) +{ + if (channel >= MPFS_DMA_NUM_CHANNELS) + { + dmawarn("Illegal channel\n"); + return -EINVAL; + } + + if (write_size > DMA_MAX_TRANSACTION_SIZE) + { + dmawarn("Illegal write size\n"); + return -EINVAL; + } + + if (read_size > DMA_MAX_TRANSACTION_SIZE) + { + dmawarn("Illegal write size\n"); + return -EINVAL; + } + + dmainfo("new default dma transaction size. channel:%d write:%d, read:%d\n", + channel, write_size, read_size); + g_channel_nextcfg_wsize[channel] = write_size; + g_channel_nextcfg_rsize[channel] = read_size; + + return OK; +} + +/**************************************************************************** + * Name: mpfs_dma_start + * + * Description: + * Start DMA transfer. + * + * Parameters: + * channel - Channel number 0-3 + * + * Returned Value: + * Zero (OK) is returned on success. A negated errno value is returned on + * failure. + * + ****************************************************************************/ + +int mpfs_dma_start(unsigned int channel) +{ + if (channel >= MPFS_DMA_NUM_CHANNELS) + { + dmawarn("Illegal channel\n"); + return -EINVAL; + } + + dmainfo("start dma channel:%d\n", channel); + modifyreg32(MPFS_DMA_REG_OFFSET(channel) + MPFS_DMA_CONTROL_OFFSET, + 0, DMA_CONTROL_RUN); + + return OK; +} + +/**************************************************************************** + * Name: mpfs_dma_get_transfer_type + * + * Description: + * Return channels active config. + * + * Parameters: + * channel - Channel number 0-3 + * + * Returned Value: + * 0 - Illegal channel + * bit 2 - Repeat + * bit 3 - Strict ordering + * + ****************************************************************************/ + +uint32_t mpfs_dma_get_transfer_type(unsigned int channel) +{ + if (channel >= MPFS_DMA_NUM_CHANNELS) + { + dmawarn("Illegal channel\n"); + return 0; + } + + return getreg32(MPFS_DMA_REG_OFFSET(channel) + + MPFS_DMA_EXEC_CONFIG_OFFSET); +} + +/**************************************************************************** + * Name: mpfs_dma_get_bytes_remaining + * + * Description: + * Return number of bytes remaining on transfer. + * + * Parameters: + * channel - Channel number 0-3 + * + * Returned Value: + * Number of bytes remaining + * + ****************************************************************************/ + +uint64_t mpfs_dma_get_bytes_remaining(unsigned int channel) +{ + if (channel >= MPFS_DMA_NUM_CHANNELS) + { + dmawarn("Illegal channel\n"); + return 0; + } + + return getreg64(MPFS_DMA_REG_OFFSET(channel) + MPFS_DMA_EXEC_BYTES_OFFSET); +} + +/**************************************************************************** + * Name: mpfs_dma_get_current_dest + * + * Description: + * Return current destination address of transfer + * + * Parameters: + * channel - Channel number 0-3 + * + * Returned Value: + * Current destination address + * + ****************************************************************************/ + +uint64_t mpfs_dma_get_current_destination(unsigned int channel) +{ + if (channel >= MPFS_DMA_NUM_CHANNELS) + { + dmawarn("Illegal channel\n"); + return 0; + } + + return getreg64(MPFS_DMA_REG_OFFSET(channel) + + MPFS_DMA_EXEC_DESTINATION_OFFSET); +} + +/**************************************************************************** + * Name: mpfs_dma_get_current_source + * + * Description: + * Return current sourceaddress of transfer + * + * Parameters: + * channel - Channel number 0-3 + * + * Returned Value: + * Current source address + * + ****************************************************************************/ + +uint64_t mpfs_dma_get_current_source(unsigned int channel) +{ + if (channel >= MPFS_DMA_NUM_CHANNELS) + { + dmawarn("Illegal channel\n"); + return 0; + } + + return getreg64(MPFS_DMA_REG_OFFSET(channel) + + MPFS_DMA_EXEC_SOURCE_OFFSET); +} + +/**************************************************************************** + * Name: mpfs_dma_get_complete_status + * + * Description: + * Return complete status for DMA channel + * + * Parameters: + * channel - Channel number 0-3 + * + * Returned Value: + * 0 - Not completed + * 1 - Transfer completed + * + ****************************************************************************/ + +int mpfs_dma_get_complete_status(unsigned int channel) +{ + uint32_t control; + + if (channel >= MPFS_DMA_NUM_CHANNELS) + { + dmawarn("Illegal channel\n"); + return 0; + } + + control = getreg32(MPFS_DMA_REG_OFFSET(channel) + + MPFS_DMA_CONTROL_OFFSET); + + return ((control & DMA_CONTROL_DONE_MASK) >> DMA_CONTROL_DONE_SHIFT); +} + +/**************************************************************************** + * Name: mpfs_dma_get_error_status + * + * Description: + * Return error status for DMA channel + * + * Parameters: + * channel - Channel number 0-3 + * + * Returned Value: + * 0 - No Error + * 1 - Transfer Errror + * + ****************************************************************************/ + +int mpfs_dma_get_error_status(unsigned int channel) +{ + uint32_t control; + + if (channel >= MPFS_DMA_NUM_CHANNELS) + { + dmawarn("Illegal channel\n"); + return 0; + } + + control = getreg32(MPFS_DMA_REG_OFFSET(channel) + + MPFS_DMA_CONTROL_OFFSET); + + return ((control & DMA_CONTROL_ERROR_MASK) >> DMA_CONTROL_ERROR_SHIFT); +} + +/**************************************************************************** + * Name: mpfs_dma_clear_complete_status + * + * Description: + * Clear and return complete status for DMA channel + * + * Parameters: + * channel - Channel number 0-3 + * + * Returned Value: + * 0 - Not completed + * 1 - Transfer completed + * + ****************************************************************************/ + +int mpfs_dma_clear_complete_status(unsigned int channel) +{ + int status = 0; + uint32_t control; + + if (channel >= MPFS_DMA_NUM_CHANNELS) + { + dmawarn("Illegal channel\n"); + return 0; + } + + control = getreg32(MPFS_DMA_REG_OFFSET(channel) + MPFS_DMA_CONTROL_OFFSET); + if (control & DMA_CONTROL_DONE) + { + status = 1; + } + + modifyreg32(MPFS_DMA_REG_OFFSET(channel) + MPFS_DMA_CONTROL_OFFSET, + DMA_CONTROL_DONE_MASK, 0); + + return status; +} + +/**************************************************************************** + * Name: mpfs_dma_clear_error_status + * + * Description: + * Clear and return error status for DMA channel + * + * Parameters: + * channel - Channel number 0-3 + * + * Returned Value: + * 0 - No Error + * 1 - Transfer Errror + * + ****************************************************************************/ + +int mpfs_dma_clear_error_status(unsigned int channel) +{ + int status = 0; + uint32_t control; + + if (channel >= MPFS_DMA_NUM_CHANNELS) + { + dmawarn("Illegal channel\n"); + return 0; + } + + control = getreg32(MPFS_DMA_REG_OFFSET(channel) + MPFS_DMA_CONTROL_OFFSET); + if (control & DMA_CONTROL_ERROR) + { + status = 1; + } + + modifyreg32(MPFS_DMA_REG_OFFSET(channel) + MPFS_DMA_CONTROL_OFFSET, + DMA_CONTROL_ERROR, 0); + + return status; +} diff --git a/arch/risc-v/src/mpfs/mpfs_dma.h b/arch/risc-v/src/mpfs/mpfs_dma.h new file mode 100755 index 00000000000..7f401a79383 --- /dev/null +++ b/arch/risc-v/src/mpfs/mpfs_dma.h @@ -0,0 +1,93 @@ +/**************************************************************************** + * arch/risc-v/src/mpfs/mpfs_dma.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_RISCV_SRC_MPFS_MPFS_DMA_H +#define __ARCH_RISCV_SRC_MPFS_MPFS_DMA_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include "mpfs_memorymap.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#define MPFS_DMA_NUM_CHANNELS (4) + +/**************************************************************************** + * Public Types + ****************************************************************************/ + +#ifndef __ASSEMBLY__ + +struct mpfs_dma_channel_config +{ + uint64_t src_addr; /* source address */ + uint64_t dest_addr; /* destination address */ + uint64_t num_bytes; /* Number of bytes to be transfered. (Base-2) */ + uint8_t enable_done_int; /* enable transfer complete interrupt */ + uint8_t enable_err_int; /* enable transfer error interrupt */ + uint8_t repeat; /* repeat the transaction */ + uint8_t force_order; /* Enforces strict ordering by only + * allowing one of each transfer type + * in-flight at a time */ +}; + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +#ifdef __cplusplus +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +EXTERN int mpfs_dma_setup_transfer(unsigned int channel, + struct mpfs_dma_channel_config *config); +EXTERN int mpfs_dma_set_transaction_size(unsigned int channel, + uint8_t write_size, + uint8_t read_size); +EXTERN int mpfs_dma_start(unsigned int channel); +EXTERN uint32_t mpfs_dma_get_transfer_type(unsigned int channel); +EXTERN uint64_t mpfs_dma_get_bytes_remaining(unsigned int channel); +EXTERN uint64_t mpfs_dma_get_current_destination(unsigned int channel); +EXTERN uint64_t mpfs_dma_get_current_source(unsigned int channel); +EXTERN int mpfs_dma_get_complete_status(unsigned int channel); +EXTERN int mpfs_dma_get_error_status(unsigned int channel); +EXTERN int mpfs_dma_clear_complete_status(unsigned int channel); +EXTERN int mpfs_dma_clear_error_status(unsigned int channel); + +#if defined(__cplusplus) +} +#endif +#undef EXTERN + +#endif /* __ASSEMBLY__ */ +#endif /* __ARCH_RISCV_SRC_MPFS_MPFS_DMA_H */