From a41e5cd1dfdf95286e2cebf022ec1d300cb8ed9e Mon Sep 17 00:00:00 2001 From: junaidaslamRS Date: Wed, 3 Jul 2024 19:11:45 +0500 Subject: [PATCH 01/10] Supporting ATCDMAC100 Driver by modifying existing ATCDMAC300 driver --- drivers/dma/CMakeLists.txt | 1 + drivers/dma/Kconfig | 2 + drivers/dma/Kconfig.andes_atcdmac100 | 12 + drivers/dma/dma_andes_atcdmac100.c | 548 +++++++++++++++++++++ dts/bindings/dma/andestech,atcdmac100.yaml | 84 ++++ dts/riscv/rapidsilicon/rapidsi_virgo.dtsi | 2 +- 6 files changed, 648 insertions(+), 1 deletion(-) create mode 100644 drivers/dma/Kconfig.andes_atcdmac100 create mode 100644 drivers/dma/dma_andes_atcdmac100.c create mode 100644 dts/bindings/dma/andestech,atcdmac100.yaml diff --git a/drivers/dma/CMakeLists.txt b/drivers/dma/CMakeLists.txt index 5b2a2ea3353c7..d9af43768851e 100644 --- a/drivers/dma/CMakeLists.txt +++ b/drivers/dma/CMakeLists.txt @@ -36,6 +36,7 @@ zephyr_library_sources_ifdef(CONFIG_DMA_RPI_PICO dma_rpi_pico.c) zephyr_library_sources_ifdef(CONFIG_MCUX_PXP dma_mcux_pxp.c) zephyr_library_sources_ifdef(CONFIG_DMA_MCUX_SMARTDMA dma_mcux_smartdma.c) zephyr_library_sources_ifdef(CONFIG_DMA_ANDES_ATCDMAC300 dma_andes_atcdmac300.c) +zephyr_library_sources_ifdef(CONFIG_DMA_ANDES_ATCDMAC100 dma_andes_atcdmac100.c) zephyr_library_sources_ifdef(CONFIG_DMA_SEDI dma_sedi.c) zephyr_library_sources_ifdef(CONFIG_DMA_SMARTBOND dma_smartbond.c) zephyr_library_sources_ifdef(CONFIG_DMA_NXP_SOF_HOST_DMA dma_nxp_sof_host_dma.c) diff --git a/drivers/dma/Kconfig b/drivers/dma/Kconfig index 7f584dae57bcd..8d39d5d474f94 100644 --- a/drivers/dma/Kconfig +++ b/drivers/dma/Kconfig @@ -64,6 +64,8 @@ source "drivers/dma/Kconfig.mcux_pxp" source "drivers/dma/Kconfig.mcux_smartdma" +source "drivers/dma/Kconfig.andes_atcdmac100" + source "drivers/dma/Kconfig.andes_atcdmac300" source "drivers/dma/Kconfig.sedi" diff --git a/drivers/dma/Kconfig.andes_atcdmac100 b/drivers/dma/Kconfig.andes_atcdmac100 new file mode 100644 index 0000000000000..1c00a3fc926dc --- /dev/null +++ b/drivers/dma/Kconfig.andes_atcdmac100 @@ -0,0 +1,12 @@ +# Andestech ATCDMAC100 configuration options +# Copyright (c) 2024 Rapid Silicon + +# SPDX-License-Identifier: Apache-2.0 + + +config DMA_ANDES_ATCDMAC100 + bool "Using Andes ATCDMAC100 DMA driver" + default y + depends on DT_HAS_ANDESTECH_ATCDMAC100_ENABLED + help + Andes ATCDMAC100 DMA driver. diff --git a/drivers/dma/dma_andes_atcdmac100.c b/drivers/dma/dma_andes_atcdmac100.c new file mode 100644 index 0000000000000..fe6241524f187 --- /dev/null +++ b/drivers/dma/dma_andes_atcdmac100.c @@ -0,0 +1,548 @@ +/* + * Copyright (c) 2023 Andes Technology Corporation. + * + * SPDX-License-Identifier: Apache-2.0 + */ +#include + +#include +#include +#include +#include +#include +#include + +#define DT_DRV_COMPAT andestech_atcdmac100 + +#define LOG_LEVEL CONFIG_DMA_LOG_LEVEL +#include +LOG_MODULE_REGISTER(dma_andes_atcdmac100); + +#define ATCDMAC100_MAX_CHAN 8 + +#define DMA_ID_REV_REG(dev) \ + (((struct dma_atcdmac100_cfg *)dev->config)->base + 0x00) + +#define DMA_CFG_REG(dev) \ + (((struct dma_atcdmac100_cfg *)dev->config)->base + 0x10) + +#define DMA_CTRL_REG(dev) \ + (((struct dma_atcdmac100_cfg *)dev->config)->base + 0x20) + +#define DMA_INT_STATUS(dev) \ + (((struct dma_atcdmac100_cfg *)dev->config)->base + 0x30) + +#define DMA_CH_ENABLE(dev) \ + (((struct dma_atcdmac100_cfg *)dev->config)->base + 0x34) + +#define DMA_CH_OFFSET(ch) (ch * 0x14) +#define DMA_ABORT(dev) \ + (((struct dma_atcdmac100_cfg *)dev->config)->base + 0x40) +#define DMA_CH_CTRL(dev, ch) \ + (((struct dma_atcdmac100_cfg *)dev->config)->base + 0x44 + DMA_CH_OFFSET(ch)) +#define DMA_CH_SRC_ADDR_L(dev, ch) \ + (((struct dma_atcdmac100_cfg *)dev->config)->base + 0x48 + DMA_CH_OFFSET(ch)) +#define DMA_CH_DST_ADDR_L(dev, ch) \ + (((struct dma_atcdmac100_cfg *)dev->config)->base + 0x4C + DMA_CH_OFFSET(ch)) +#define DMA_CH_TRANSIZE(dev, ch) \ + (((struct dma_atcdmac100_cfg *)dev->config)->base + 0x50 + DMA_CH_OFFSET(ch)) +#define DMA_CH_LL_PTR_L(dev, ch) \ + (((struct dma_atcdmac100_cfg *)dev->config)->base + 0x54 + DMA_CH_OFFSET(ch)) + +/* ID and Revision Register Bits */ +#define DMA_REV_MINOR_OFFSET 0 +#define DMA_REV_MINOR_MASK GENMASK(3, 0) +#define DMA_REV_MAJOR_OFFSET 4 +#define DMA_REV_MAJOR_MASK GENMASK(11, 4) +#define DMA_ID_OFFSET 12 +#define DMA_ID_MASK GENMASK(31, 12) + +/* Configuration Register Bits */ +#define DMA_RO_CFG_CH_NUM_OFFSET 0 +#define DMA_RO_CFG_CH_NUM_MASK GENMASK(3, 0) +#define DMA_RO_FIFO_DEPTH_OFFSET 4 +#define DMA_RO_FIFO_DEPTH_MASK GENMASK(9, 4) +#define DMA_RO_REQ_ACK_NUM_OFFSET 10 +#define DMA_RO_REQ_ACK_NUM_MASK GENMASK(15, 10) +#define DMA_RO_REQ_SYNC_OFFSET 30 +#define DMA_RO_REQ_SYNC_MASK GENMASK(30, 30) +#define DMA_RO_CHAIN_XFR_OFFSET 31 +#define DMA_RO_CHAIN_XFR_MASK GENMASK(31, 31) + +/* DMA Control Register Bits */ +#define DMA_CTRL_RESET_OFFSET 0 +#define DMA_CTRL_RESET_MASK GENMASK(0, 0) + +/* Source burst size options */ +#define DMA_BSIZE_1 (0) +#define DMA_BSIZE_2 (1) +#define DMA_BSIZE_4 (2) +#define DMA_BSIZE_8 (3) +#define DMA_BSIZE_16 (4) +#define DMA_BSIZE_32 (5) +#define DMA_BSIZE_64 (6) +#define DMA_BSIZE_128 (7) + +/* Source/Destination transfer width options */ +#define DMA_WIDTH_BYTE (0) +#define DMA_WIDTH_HALFWORD (1) +#define DMA_WIDTH_WORD (2) +#define DMA_WIDTH_RESERVED (3) + +/* DMA Channel Control Register Definition */ +#define DMA_CH_CTRL_SRCREQB5_MASK BIT(31) +#define DMA_CH_CTRL_DSTREQB5_MASK BIT(30) +#define DMA_CH_CTRL_PRIORITY_HIGH BIT(29) +#define DMA_CH_CTRL_SBSIZE_MASK GENMASK(24, 22) +#define DMA_CH_CTRL_SBSIZE(n) FIELD_PREP(DMA_CH_CTRL_SBSIZE_MASK, (n)) +#define DMA_CH_CTRL_SWIDTH_MASK GENMASK(21, 20) +#define DMA_CH_CTRL_SWIDTH(n) FIELD_PREP(DMA_CH_CTRL_SWIDTH_MASK, (n)) +#define DMA_CH_CTRL_DWIDTH_MASK GENMASK(19, 18) +#define DMA_CH_CTRL_DWIDTH(n) FIELD_PREP(DMA_CH_CTRL_DWIDTH_MASK, (n)) +#define DMA_CH_CTRL_SMODE_HANDSHAKE BIT(17) +#define DMA_CH_CTRL_DMODE_HANDSHAKE BIT(16) +#define DMA_CH_CTRL_SRCADDRCTRL_MASK GENMASK(15, 14) +#define DMA_CH_CTRL_SRCADDR_INC FIELD_PREP(DMA_CH_CTRL_SRCADDRCTRL_MASK, (0)) +#define DMA_CH_CTRL_SRCADDR_DEC FIELD_PREP(DMA_CH_CTRL_SRCADDRCTRL_MASK, (1)) +#define DMA_CH_CTRL_SRCADDR_FIX FIELD_PREP(DMA_CH_CTRL_SRCADDRCTRL_MASK, (2)) +#define DMA_CH_CTRL_DSTADDRCTRL_MASK GENMASK(13, 12) +#define DMA_CH_CTRL_DSTADDR_INC FIELD_PREP(DMA_CH_CTRL_DSTADDRCTRL_MASK, (0)) +#define DMA_CH_CTRL_DSTADDR_DEC FIELD_PREP(DMA_CH_CTRL_DSTADDRCTRL_MASK, (1)) +#define DMA_CH_CTRL_DSTADDR_FIX FIELD_PREP(DMA_CH_CTRL_DSTADDRCTRL_MASK, (2)) +#define DMA_CH_CTRL_SRCREQ_MASK GENMASK(11, 8) +#define DMA_CH_CTRL_SRCREQ(n) FIELD_PREP(DMA_CH_CTRL_SRCREQ_MASK, (n)) +#define DMA_CH_CTRL_DSTREQ_MASK GENMASK(7, 4) +#define DMA_CH_CTRL_DSTREQ(n) FIELD_PREP(DMA_CH_CTRL_DSTREQ_MASK, (n)) +#define DMA_CH_CTRL_INTABT BIT(3) +#define DMA_CH_CTRL_INTERR BIT(2) +#define DMA_CH_CTRL_INTTC BIT(1) +#define DMA_CH_CTRL_ENABLE BIT(0) + +/* DMA Interrupt Status Register Definition */ +#define DMA_INT_STATUS_TC_MASK GENMASK(23, 16) +#define DMA_INT_STATUS_ABORT_MASK GENMASK(15, 8) +#define DMA_INT_STATUS_ERROR_MASK GENMASK(7, 0) +#define DMA_INT_STATUS_TC_VAL(x) FIELD_GET(DMA_INT_STATUS_TC_MASK, (x)) +#define DMA_INT_STATUS_ABORT_VAL(x) FIELD_GET(DMA_INT_STATUS_ABORT_MASK, (x)) +#define DMA_INT_STATUS_ERROR_VAL(x) FIELD_GET(DMA_INT_STATUS_ERROR_MASK, (x)) +#define DMA_INT_STATUS_CH_MSK(ch) (0x111 << ch) + +typedef void (*atcdmac100_cfg_func_t)(void); + +struct chain_block { + uint32_t ctrl; + uint32_t srcaddrl; + uint32_t dstaddrl; + uint32_t transize; + uint32_t llpointerl; + struct chain_block *next_block; +}; + +/* data for each DMA channel */ +struct dma_chan_data { + void *blkuser_data; + dma_callback_t blkcallback; + struct chain_block *head_block; + struct dma_status status; +}; + +/* Device run time data */ +struct dma_atcdmac100_data { + struct dma_chan_data chan[ATCDMAC100_MAX_CHAN]; + struct k_spinlock lock; +}; + +/* Device constant configuration parameters */ +struct dma_atcdmac100_cfg { + atcdmac100_cfg_func_t irq_config; + uint32_t base; + uint32_t irq_num; +}; + +static struct __aligned(64) + chain_block dma_chain[ATCDMAC100_MAX_CHAN][8]; + +static void dma_atcdmac100_isr(const struct device *dev) +{ + uint32_t int_status, int_ch_status, channel; + struct dma_atcdmac100_data *const data = dev->data; + struct dma_chan_data *ch_data; + k_spinlock_key_t key; + + key = k_spin_lock(&data->lock); + int_status = sys_read32(DMA_INT_STATUS(dev)); + /* Clear interrupt*/ + sys_write32(int_status, DMA_INT_STATUS(dev)); + + k_spin_unlock(&data->lock, key); + + /* Handle terminal count status */ + int_ch_status = DMA_INT_STATUS_TC_VAL(int_status); + while (int_ch_status) { + channel = find_msb_set(int_ch_status) - 1; + int_ch_status &= ~(BIT(channel)); + + ch_data = &data->chan[channel]; + if (ch_data->blkcallback) { + ch_data->blkcallback(dev, ch_data->blkuser_data, channel, 0); + } + data->chan[channel].status.busy = false; + } + + /* Handle error status */ + int_ch_status = DMA_INT_STATUS_ERROR_VAL(int_status); + while (int_ch_status) { + channel = find_msb_set(int_ch_status) - 1; + int_ch_status &= ~(BIT(channel)); + + ch_data = &data->chan[channel]; + if (ch_data->blkcallback) { + ch_data->blkcallback(dev, ch_data->blkuser_data, channel, -EIO); + } + } +} + +static int dma_atcdmac100_config(const struct device *dev, uint32_t channel, + struct dma_config *cfg) +{ + struct dma_atcdmac100_data *const data = dev->data; + uint32_t src_width, dst_width, src_burst_size, ch_ctrl, tfr_size; + int32_t ret = 0; + struct dma_block_config *cfg_blocks; + k_spinlock_key_t key; + + if (channel >= ATCDMAC100_MAX_CHAN) { + return -EINVAL; + } + + __ASSERT_NO_MSG(cfg->source_data_size == cfg->dest_data_size); + __ASSERT_NO_MSG(cfg->source_burst_length == cfg->dest_burst_length); + + if (cfg->source_data_size != 1 && cfg->source_data_size != 2 && + cfg->source_data_size != 4) { + LOG_ERR("Invalid 'source_data_size' value"); + ret = -EINVAL; + goto end; + } + + cfg_blocks = cfg->head_block; + if (cfg_blocks == NULL) { + ret = -EINVAL; + goto end; + } + + tfr_size = cfg_blocks->block_size/cfg->source_data_size; + if (tfr_size == 0) { + ret = -EINVAL; + goto end; + } + + ch_ctrl = 0; + + /* dma_slot is effective the req/sel pair number for a particular IP (e.g. SPI, UART, I2C) */ + switch (cfg->channel_direction) { + case MEMORY_TO_MEMORY: + break; + case MEMORY_TO_PERIPHERAL: { + if(cfg->dest_handshake) { + ch_ctrl |= DMA_CH_CTRL_DSTREQ(cfg->dma_slot); + ch_ctrl |= DMA_CH_CTRL_DMODE_HANDSHAKE; + } + } + break; + case PERIPHERAL_TO_MEMORY: { + if(cfg->source_handshake) { + ch_ctrl |= DMA_CH_CTRL_SRCREQ(cfg->dma_slot); + ch_ctrl |= DMA_CH_CTRL_SMODE_HANDSHAKE; + } + } + break; + default: + ret = -EINVAL; + goto end; + } + + + switch (cfg_blocks->source_addr_adj) { + case DMA_ADDR_ADJ_INCREMENT: + ch_ctrl |= DMA_CH_CTRL_SRCADDR_INC; + break; + case DMA_ADDR_ADJ_DECREMENT: + ch_ctrl |= DMA_CH_CTRL_SRCADDR_DEC; + break; + case DMA_ADDR_ADJ_NO_CHANGE: + ch_ctrl |= DMA_CH_CTRL_SRCADDR_FIX; + break; + default: + ret = -EINVAL; + goto end; + } + + switch (cfg_blocks->dest_addr_adj) { + case DMA_ADDR_ADJ_INCREMENT: + ch_ctrl |= DMA_CH_CTRL_DSTADDR_INC; + break; + case DMA_ADDR_ADJ_DECREMENT: + ch_ctrl |= DMA_CH_CTRL_DSTADDR_DEC; + break; + case DMA_ADDR_ADJ_NO_CHANGE: + ch_ctrl |= DMA_CH_CTRL_DSTADDR_FIX; + break; + default: + ret = -EINVAL; + goto end; + } + + ch_ctrl |= DMA_CH_CTRL_INTABT; + + /* Disable the error callback */ + if (!cfg->error_callback_dis) { + ch_ctrl |= DMA_CH_CTRL_INTERR; + } + + src_width = find_msb_set(cfg->source_data_size) - 1; + dst_width = find_msb_set(cfg->dest_data_size) - 1; + src_burst_size = find_msb_set(cfg->source_burst_length) - 1; + + ch_ctrl |= DMA_CH_CTRL_SWIDTH(src_width) | + DMA_CH_CTRL_DWIDTH(dst_width) | + DMA_CH_CTRL_SBSIZE(src_burst_size); + + + /* Reset DMA channel configuration */ + sys_write32(0, DMA_CH_CTRL(dev, channel)); + + key = k_spin_lock(&data->lock); + /* Clear DMA interrupts status */ + sys_write32(DMA_INT_STATUS_CH_MSK(channel), DMA_INT_STATUS(dev)); + k_spin_unlock(&data->lock, key); + + /* Set transfer size */ + sys_write32(tfr_size, DMA_CH_TRANSIZE(dev, channel)); + + /* Update the status of channel */ + data->chan[channel].status.dir = cfg->channel_direction; + data->chan[channel].status.pending_length = cfg->source_data_size; + + /* Configure a callback appropriately depending on whether the + * interrupt is requested at the end of transaction completion or + * at the end of each block. + */ + data->chan[channel].blkcallback = cfg->dma_callback; + data->chan[channel].blkuser_data = cfg->user_data; + + sys_write32(ch_ctrl, DMA_CH_CTRL(dev, channel)); + + /* Set source and destination address */ + sys_write32(cfg_blocks->source_address, + DMA_CH_SRC_ADDR_L(dev, channel)); + sys_write32(cfg_blocks->dest_address, + DMA_CH_DST_ADDR_L(dev, channel)); + + if (cfg->dest_chaining_en == 1 && cfg_blocks->next_block) { + uint32_t current_block_idx = 0; + + sys_write32((uint32_t)((long)&dma_chain[channel][current_block_idx]), + DMA_CH_LL_PTR_L(dev, channel)); + + for (cfg_blocks = cfg_blocks->next_block; cfg_blocks != NULL; + cfg_blocks = cfg_blocks->next_block) { + + ch_ctrl &= ~(DMA_CH_CTRL_SRCADDRCTRL_MASK | + DMA_CH_CTRL_DSTADDRCTRL_MASK); + + switch (cfg_blocks->source_addr_adj) { + case DMA_ADDR_ADJ_INCREMENT: + ch_ctrl |= DMA_CH_CTRL_SRCADDR_INC; + break; + case DMA_ADDR_ADJ_DECREMENT: + ch_ctrl |= DMA_CH_CTRL_SRCADDR_DEC; + break; + case DMA_ADDR_ADJ_NO_CHANGE: + ch_ctrl |= DMA_CH_CTRL_SRCADDR_FIX; + break; + default: + ret = -EINVAL; + goto end; + } + + switch (cfg_blocks->dest_addr_adj) { + case DMA_ADDR_ADJ_INCREMENT: + ch_ctrl |= DMA_CH_CTRL_DSTADDR_INC; + break; + case DMA_ADDR_ADJ_DECREMENT: + ch_ctrl |= DMA_CH_CTRL_DSTADDR_DEC; + break; + case DMA_ADDR_ADJ_NO_CHANGE: + ch_ctrl |= DMA_CH_CTRL_DSTADDR_FIX; + break; + default: + ret = -EINVAL; + goto end; + } + dma_chain[channel][current_block_idx].ctrl = ch_ctrl; + dma_chain[channel][current_block_idx].transize = + cfg_blocks->block_size/cfg->source_data_size; + + dma_chain[channel][current_block_idx].srcaddrl = + (uint32_t)cfg_blocks->source_address; + + dma_chain[channel][current_block_idx].dstaddrl = + (uint32_t)((long)cfg_blocks->dest_address); + + if (cfg_blocks->next_block) { + dma_chain[channel][current_block_idx].llpointerl = + (uint32_t)&dma_chain[channel][current_block_idx + 1]; + + current_block_idx = current_block_idx + 1; + + } else { + dma_chain[channel][current_block_idx].llpointerl = 0x0; + dma_chain[channel][current_block_idx].next_block = NULL; + } + } + } else { + /* Single transfer is supported, but Chain transfer is still + * not supported. Therefore, set LLPointer to zero + */ + sys_write32(0, DMA_CH_LL_PTR_L(dev, channel)); + } + +end: + return ret; +} + +static int dma_atcdmac100_reload(const struct device *dev, uint32_t channel, + uint32_t src, uint32_t dst, size_t size) +{ + uint32_t src_width; + + if (channel >= ATCDMAC100_MAX_CHAN) { + return -EINVAL; + } + + /* Set source and destination address */ + sys_write32(src, DMA_CH_SRC_ADDR_L(dev, channel)); + sys_write32(dst, DMA_CH_DST_ADDR_L(dev, channel)); + + src_width = FIELD_GET(DMA_CH_CTRL_SWIDTH_MASK, sys_read32(DMA_CH_CTRL(dev, channel))); + src_width = BIT(src_width); + + /* Set transfer size */ + sys_write32(size/src_width, DMA_CH_TRANSIZE(dev, channel)); + + return 0; +} + +static int dma_atcdmac100_transfer_start(const struct device *dev, + uint32_t channel) +{ + struct dma_atcdmac100_data *const data = dev->data; + + if (channel >= ATCDMAC100_MAX_CHAN) { + return -EINVAL; + } + + sys_write32(sys_read32(DMA_CH_CTRL(dev, channel)) | DMA_CH_CTRL_ENABLE, + DMA_CH_CTRL(dev, channel)); + + data->chan[channel].status.busy = true; + + return 0; +} + +static int dma_atcdmac100_transfer_stop(const struct device *dev, + uint32_t channel) +{ + struct dma_atcdmac100_data *const data = dev->data; + k_spinlock_key_t key; + + if (channel >= ATCDMAC100_MAX_CHAN) { + return -EINVAL; + } + + key = k_spin_lock(&data->lock); + + sys_write32(BIT(channel), DMA_ABORT(dev)); + sys_write32(0, DMA_CH_CTRL(dev, channel)); + sys_write32(FIELD_GET(DMA_INT_STATUS_ABORT_MASK, (channel)), DMA_INT_STATUS(dev)); + data->chan[channel].status.busy = false; + + k_spin_unlock(&data->lock, key); + + return 0; +} + +static int dma_atcdmac100_init(const struct device *dev) +{ + const struct dma_atcdmac100_cfg *const config = (struct dma_atcdmac100_cfg *)dev->config; + uint32_t ch_num; + + /* Disable all channels and Channel interrupts */ + for (ch_num = 0; ch_num < ATCDMAC100_MAX_CHAN; ch_num++) { + sys_write32(0, DMA_CH_CTRL(dev, ch_num)); + } + + sys_write32(0xFFFFFF, DMA_INT_STATUS(dev)); + + /* Configure interrupts */ + config->irq_config(); + + irq_enable(config->irq_num); + + return 0; +} + +static int dma_atcdmac100_get_status(const struct device *dev, + uint32_t channel, + struct dma_status *stat) +{ + struct dma_atcdmac100_data *const data = dev->data; + + stat->busy = data->chan[channel].status.busy; + stat->dir = data->chan[channel].status.dir; + stat->pending_length = data->chan[channel].status.pending_length; + + return 0; +} + +static const struct dma_driver_api dma_atcdmac100_api = { + .config = dma_atcdmac100_config, + .reload = dma_atcdmac100_reload, + .start = dma_atcdmac100_transfer_start, + .stop = dma_atcdmac100_transfer_stop, + .get_status = dma_atcdmac100_get_status +}; + +#define ATCDMAC100_INIT(n) \ + \ + static void dma_atcdmac100_irq_config_##n(void); \ + \ + static const struct dma_atcdmac100_cfg dma_config_##n = { \ + .irq_config = dma_atcdmac100_irq_config_##n, \ + .base = DT_INST_REG_ADDR(n), \ + .irq_num = DT_INST_IRQN(n), \ + }; \ + \ + static struct dma_atcdmac100_data dma_data_##n; \ + \ + DEVICE_DT_INST_DEFINE(0, \ + dma_atcdmac100_init, \ + NULL, \ + &dma_data_##n, \ + &dma_config_##n, \ + POST_KERNEL, \ + CONFIG_KERNEL_INIT_PRIORITY_DEVICE, \ + &dma_atcdmac100_api); \ + \ + static void dma_atcdmac100_irq_config_##n(void) \ + { \ + IRQ_CONNECT(DT_INST_IRQN(n), \ + 1, \ + dma_atcdmac100_isr, \ + DEVICE_DT_INST_GET(n), \ + 0); \ + } + + +DT_INST_FOREACH_STATUS_OKAY(ATCDMAC100_INIT) diff --git a/dts/bindings/dma/andestech,atcdmac100.yaml b/dts/bindings/dma/andestech,atcdmac100.yaml new file mode 100644 index 0000000000000..6665794f45fc9 --- /dev/null +++ b/dts/bindings/dma/andestech,atcdmac100.yaml @@ -0,0 +1,84 @@ +# +# Copyright (c) 2024 Rapid Silicon +# +# SPDX-License-Identifier: Apache-2.0 + +compatible: "andestech,atcdmac100" + +include: dma-controller.yaml + +properties: + reg: + required: true + + interrupts: + required: true + + chain-transfer: + type: int + + "#dma-cells": + const: 3 + +dma-cells: + - channel + - slot + - channel-config + +description: | + Andes DMA controller + channel: a phandle to the DMA controller plus the following four integer cells: + 1. channel: the dma channel + 2. slot: DMA peripheral request ID + 3. channel-config: A 32bit mask specifying the DMA channel configuration + which is device dependent: + -bit 0-1 : Direction (see dma.h) + 0x0: MEM to MEM + 0x1: MEM to PERIPH + 0x2: PERIPH to MEM + 0x3: reserved for PERIPH to PERIPH + -bit 2 : Peripheral Increment Address + 0x0: no address increment between transfers + 0x1: increment address between transfers + -bit 3 : Memory Increment Address + 0x0: no address increment between transfers + 0x1: increment address between transfers + -bit 4-6 : Peripheral data size + 0x0: Byte (8 bits) + 0x1: Half-word (16 bits) + 0x2: Word (32 bits) + 0x3: Double word (64 bits) + 0x4: Quad word (128 bits) + 0x5: Eight word (256 bits) + 0x6-0x7: reserved + -bit 7-9 : Memory data size + 0x0: Byte (8 bits) + 0x1: Half-word (16 bits) + 0x2: Word (32 bits) + 0x3: Double word (64 bits) + 0x4: Quad word (128 bits) + 0x5: Eight word (256 bits) + 0x6-0x7: reserved + -bit 10 : Priority level + 0x0: lower priority + 0x1: higher priority + + examples for andes_v5_ae350 DMA instance + dma0: dma0@f0c00000 { + compatible = "andestech,atcdmac300"; + ... + dma-channels = <8>; + dma-requests = <16>; + status = "disabled"; + label = "DMA_0"; + }; + + For the client part, example for andes_ae350 DMA instance + Tx using channel 2, slot 0 + Rx using channel 3, slot 1 + spi1: spi@f0f00000 { + compatible = "andestech,atcspi200" + dmas = <&dma0 2 0 0x0129>, + <&dma0 3 1 0x012A>; + dma-names = "tx", "rx"; + }; diff --git a/dts/riscv/rapidsilicon/rapidsi_virgo.dtsi b/dts/riscv/rapidsilicon/rapidsi_virgo.dtsi index 0c320ddfabf1b..475d83eeb922c 100644 --- a/dts/riscv/rapidsilicon/rapidsi_virgo.dtsi +++ b/dts/riscv/rapidsilicon/rapidsi_virgo.dtsi @@ -161,7 +161,7 @@ }; dma0: dma@A0600000 { - compatible = "andestech,atcdmac300"; + compatible = "andestech,atcdmac100"; reg = <0xA0600000 0xFFFF>; interrupts = <27 9>; interrupt-parent = <&eclic>; From 4bb0c0137e9a44d7b918d8877386c6a88df27d82 Mon Sep 17 00:00:00 2001 From: junaidaslamRS Date: Wed, 10 Jul 2024 14:37:18 +0500 Subject: [PATCH 02/10] Supporting ATCDMAC100 Driver in progress --- boards/rapidsilicon/virgo_proto/virgo_proto.dts | 4 ++++ drivers/dma/dma_andes_atcdmac100.c | 2 ++ samples/hello_world/src/main.c | 9 ++++++++- 3 files changed, 14 insertions(+), 1 deletion(-) diff --git a/boards/rapidsilicon/virgo_proto/virgo_proto.dts b/boards/rapidsilicon/virgo_proto/virgo_proto.dts index e5288479dc023..c77f94f9ed5a3 100644 --- a/boards/rapidsilicon/virgo_proto/virgo_proto.dts +++ b/boards/rapidsilicon/virgo_proto/virgo_proto.dts @@ -40,6 +40,10 @@ clock-frequency = <26666667>; }; + &dma0 { + status = "disabled"; + }; + &spi0 { status = "okay"; clock-frequency = <26666667>; diff --git a/drivers/dma/dma_andes_atcdmac100.c b/drivers/dma/dma_andes_atcdmac100.c index fe6241524f187..b7e5ca20600cf 100644 --- a/drivers/dma/dma_andes_atcdmac100.c +++ b/drivers/dma/dma_andes_atcdmac100.c @@ -211,6 +211,8 @@ static int dma_atcdmac100_config(const struct device *dev, uint32_t channel, struct dma_block_config *cfg_blocks; k_spinlock_key_t key; + LOG_DBG("JATW %s(%d) channel:%d\n", __func__, __LINE__, channel); + if (channel >= ATCDMAC100_MAX_CHAN) { return -EINVAL; } diff --git a/samples/hello_world/src/main.c b/samples/hello_world/src/main.c index a7886a4ad1d41..2e9bfa3d73235 100644 --- a/samples/hello_world/src/main.c +++ b/samples/hello_world/src/main.c @@ -14,6 +14,7 @@ #define ATTR_RST "\x1b[37;1m" // ANSI_COLOR_RESET #define FLASH_RW_SIZE 255 +#define FLASH_BASE_ADDR (uint32_t*)0xB0000000 void Flash_Test(const struct device *flash, uint32_t FLASH_ADDR, uint8_t EVEN_ODD_MUL, uint8_t FORMATTER) { int errorcode = 0; @@ -89,6 +90,12 @@ void Flash_Test(const struct device *flash, uint32_t FLASH_ADDR, uint8_t EVEN_OD } } } + + uint8_t *MemMapReadAddr = (uint8_t*)(FLASH_BASE_ADDR+FLASH_ADDR); + printf("Memory Mapped Reading Test\n"); + for(uint8_t i = 0; i < FLASH_RW_SIZE; i++) { + printf("%s %d%s", ATTR_INF, MemMapReadAddr[i],i%FORMATTER==0?"\n":""); + } printf("\n"); } int main(void) @@ -124,7 +131,7 @@ int main(void) if((flash == NULL) || (!device_is_ready(flash))) { printf("%s flash has status disabled or driver is not initialized...%s\n", ATTR_ERR,ATTR_RST); } else { - printf("%s flash Object is Created\n", ATTR_INF); + printf("%s flash Object is Created. Test Via DMA\n", ATTR_INF); Flash_Test(flash, 0x1000, 0, 20); } From d628224e05b17c0a41a2d1f430ed37b54b0816d4 Mon Sep 17 00:00:00 2001 From: junaidaslamRS Date: Wed, 10 Jul 2024 16:30:18 +0500 Subject: [PATCH 03/10] Supporting ATCDMAC100 Driver in progress --- .../rapidsilicon/virgo_proto/virgo_proto.dts | 2 +- samples/hello_world/src/main.c | 29 +++++++++++++++---- soc/rapidsilicon/virgo/scu.c | 5 ++++ soc/rapidsilicon/virgo/scu.h | 1 + 4 files changed, 30 insertions(+), 7 deletions(-) diff --git a/boards/rapidsilicon/virgo_proto/virgo_proto.dts b/boards/rapidsilicon/virgo_proto/virgo_proto.dts index c77f94f9ed5a3..83ad02a3f186d 100644 --- a/boards/rapidsilicon/virgo_proto/virgo_proto.dts +++ b/boards/rapidsilicon/virgo_proto/virgo_proto.dts @@ -55,7 +55,7 @@ status = "okay"; reg = <0>; sfdp-bfp = [ - e5 D8 f1 ff ff ff ff 00 44 eb 08 6b 08 3b 04 bb + e5 20 f1 ff ff ff ff 00 44 eb 08 6b 08 3b 04 bb fe ff ff ff ff ff 00 ff ff ff 44 eb 0c D8 0f 52 10 d8 00 ff ]; diff --git a/samples/hello_world/src/main.c b/samples/hello_world/src/main.c index 2e9bfa3d73235..ddccfef098516 100644 --- a/samples/hello_world/src/main.c +++ b/samples/hello_world/src/main.c @@ -14,7 +14,7 @@ #define ATTR_RST "\x1b[37;1m" // ANSI_COLOR_RESET #define FLASH_RW_SIZE 255 -#define FLASH_BASE_ADDR (uint32_t*)0xB0000000 +#define FLASH_BASE_ADDR 0xB0000000 void Flash_Test(const struct device *flash, uint32_t FLASH_ADDR, uint8_t EVEN_ODD_MUL, uint8_t FORMATTER) { int errorcode = 0; @@ -60,7 +60,7 @@ void Flash_Test(const struct device *flash, uint32_t FLASH_ADDR, uint8_t EVEN_OD if(errorcode == 0) { printf("%s Writing the following data After Erasing Flash%s\n", ATTR_INF,ATTR_RST); for(uint8_t i = 0; i < FLASH_RW_SIZE; i++) { - flash_data_write[i] = (rand() % (FLASH_RW_SIZE - 1 + 1)) + 1; + flash_data_write[i] = ((rand() % (FLASH_RW_SIZE - 1 + 1)) + 1)*2; printf("%s %d%s", ATTR_INF, flash_data_write[i],i%FORMATTER==0?"\n":""); } printf("\n"); errorcode = flash_write(flash, FLASH_ADDR, flash_data_write, FLASH_RW_SIZE); @@ -91,11 +91,20 @@ void Flash_Test(const struct device *flash, uint32_t FLASH_ADDR, uint8_t EVEN_OD } } - uint8_t *MemMapReadAddr = (uint8_t*)(FLASH_BASE_ADDR+FLASH_ADDR); - printf("Memory Mapped Reading Test\n"); + uint8_t *MemMapReadAddr = (uint8_t*)(FLASH_BASE_ADDR + FLASH_ADDR); + printf("Memory Mapped Reading Test from address:%p\n", MemMapReadAddr); + bool memmaptestfail = false; for(uint8_t i = 0; i < FLASH_RW_SIZE; i++) { - printf("%s %d%s", ATTR_INF, MemMapReadAddr[i],i%FORMATTER==0?"\n":""); + if(MemMapReadAddr[i] != flash_data_write[i]) { + printf("%s %d%s Mismatch in memory mapped read", ATTR_ERR, MemMapReadAddr[i],i%FORMATTER==0?"\n":""); + memmaptestfail = true; break; + } } printf("\n"); + if(memmaptestfail) { + printf("%s Memory mapped read failed\n", ATTR_ERR); + } else { + printf("%s Memory mapped read passed\n", ATTR_INF); + } } int main(void) @@ -105,7 +114,6 @@ int main(void) uint8_t chip_id = 0, vendor_id = 0; int errorcode = 0; - soc_get_id(&chip_id, &vendor_id); const struct device *pvt = DEVICE_DT_GET(DT_NODELABEL(pvt0)); @@ -132,6 +140,15 @@ int main(void) printf("%s flash has status disabled or driver is not initialized...%s\n", ATTR_ERR,ATTR_RST); } else { printf("%s flash Object is Created. Test Via DMA\n", ATTR_INF); + scu_irq_map(IRQ_ID_SPI, SCU_IRQ_MAP_TO_BCPU); + scu_irq_map(IRQ_ID_SYSTEM_DMA, SCU_IRQ_MAP_TO_BCPU); + scu_irq_enable(IRQ_ID_SPI); + scu_irq_enable(IRQ_ID_SYSTEM_DMA); + printf( + "%s SPI_(%d)_IRQ_Reg_Val:[0x%08x]; DMA_(%d)_IRQ_Reg_Val:[0x%08x]\n", ATTR_RST, \ + IRQ_ID_SPI, scu_get_irq_reg_val(IRQ_ID_SPI), \ + IRQ_ID_SYSTEM_DMA, scu_get_irq_reg_val(IRQ_ID_SYSTEM_DMA) + ); Flash_Test(flash, 0x1000, 0, 20); } diff --git a/soc/rapidsilicon/virgo/scu.c b/soc/rapidsilicon/virgo/scu.c index 7e03fdb9c73ed..871a3525aff1c 100644 --- a/soc/rapidsilicon/virgo/scu.c +++ b/soc/rapidsilicon/virgo/scu.c @@ -47,3 +47,8 @@ void scu_irq_disable(enum map_mask_control_irq_id IRQn) { s_scu_regs->irq_map_mask[IRQn] &= ~(SCU_MASK_IRQ_ENABLE << SCU_IRQ_MASK_OFFSET); } + +uint32_t scu_get_irq_reg_val(enum map_mask_control_irq_id IRQn) +{ + return s_scu_regs->irq_map_mask[IRQn]; +} \ No newline at end of file diff --git a/soc/rapidsilicon/virgo/scu.h b/soc/rapidsilicon/virgo/scu.h index ea4b12f0eaa9f..13b538b6dd3c2 100644 --- a/soc/rapidsilicon/virgo/scu.h +++ b/soc/rapidsilicon/virgo/scu.h @@ -71,6 +71,7 @@ void scu_irq_map(enum map_mask_control_irq_id IRQn, uint8_t SubSystem); void scu_irq_unmap(enum map_mask_control_irq_id IRQn); void scu_irq_enable(enum map_mask_control_irq_id IRQn); void scu_irq_disable(enum map_mask_control_irq_id IRQn); +uint32_t scu_get_irq_reg_val(enum map_mask_control_irq_id IRQn); #define SCU_CHIP_ID_OFFSET 16 #define SCU_CHIP_ID_MASK 0x00FF0000 From f938eb7d1a0c17161a89c7b5fc589d16da2edc36 Mon Sep 17 00:00:00 2001 From: junaidaslamRS Date: Wed, 10 Jul 2024 17:09:13 +0500 Subject: [PATCH 04/10] Supporting ATCDMAC100 Driver in progress --- boards/rapidsilicon/virgo_proto/virgo_proto.dts | 2 +- drivers/dma/dma_andes_atcdmac100.c | 12 ++++++++++-- dts/riscv/rapidsilicon/rapidsi_virgo.dtsi | 2 +- 3 files changed, 12 insertions(+), 4 deletions(-) diff --git a/boards/rapidsilicon/virgo_proto/virgo_proto.dts b/boards/rapidsilicon/virgo_proto/virgo_proto.dts index 83ad02a3f186d..3ab8bd40383f7 100644 --- a/boards/rapidsilicon/virgo_proto/virgo_proto.dts +++ b/boards/rapidsilicon/virgo_proto/virgo_proto.dts @@ -41,7 +41,7 @@ }; &dma0 { - status = "disabled"; + status = "okay"; }; &spi0 { diff --git a/drivers/dma/dma_andes_atcdmac100.c b/drivers/dma/dma_andes_atcdmac100.c index b7e5ca20600cf..ffc5f29d824fd 100644 --- a/drivers/dma/dma_andes_atcdmac100.c +++ b/drivers/dma/dma_andes_atcdmac100.c @@ -211,8 +211,6 @@ static int dma_atcdmac100_config(const struct device *dev, uint32_t channel, struct dma_block_config *cfg_blocks; k_spinlock_key_t key; - LOG_DBG("JATW %s(%d) channel:%d\n", __func__, __LINE__, channel); - if (channel >= ATCDMAC100_MAX_CHAN) { return -EINVAL; } @@ -246,6 +244,7 @@ static int dma_atcdmac100_config(const struct device *dev, uint32_t channel, case MEMORY_TO_MEMORY: break; case MEMORY_TO_PERIPHERAL: { + LOG_DBG("JATW %s(%d) MEMORY_TO_PERIPHERAL\n", __func__, __LINE__); if(cfg->dest_handshake) { ch_ctrl |= DMA_CH_CTRL_DSTREQ(cfg->dma_slot); ch_ctrl |= DMA_CH_CTRL_DMODE_HANDSHAKE; @@ -253,6 +252,7 @@ static int dma_atcdmac100_config(const struct device *dev, uint32_t channel, } break; case PERIPHERAL_TO_MEMORY: { + LOG_DBG("JATW %s(%d) PERIPHERAL_TO_MEMORY\n", __func__, __LINE__); if(cfg->source_handshake) { ch_ctrl |= DMA_CH_CTRL_SRCREQ(cfg->dma_slot); ch_ctrl |= DMA_CH_CTRL_SMODE_HANDSHAKE; @@ -280,6 +280,8 @@ static int dma_atcdmac100_config(const struct device *dev, uint32_t channel, goto end; } + LOG_DBG("JATW %s(%d) cfg_blocks->source_addr_adj:%d\n", __func__, __LINE__, cfg_blocks->source_addr_adj); + switch (cfg_blocks->dest_addr_adj) { case DMA_ADDR_ADJ_INCREMENT: ch_ctrl |= DMA_CH_CTRL_DSTADDR_INC; @@ -295,6 +297,8 @@ static int dma_atcdmac100_config(const struct device *dev, uint32_t channel, goto end; } + LOG_DBG("JATW %s(%d) cfg_blocks->dest_addr_adj:%d\n", __func__, __LINE__, cfg_blocks->dest_addr_adj); + ch_ctrl |= DMA_CH_CTRL_INTABT; /* Disable the error callback */ @@ -341,6 +345,9 @@ static int dma_atcdmac100_config(const struct device *dev, uint32_t channel, sys_write32(cfg_blocks->dest_address, DMA_CH_DST_ADDR_L(dev, channel)); + LOG_DBG("JATW %s(%d) cfg_blocks->source_address:0x%08x\n", __func__, __LINE__, cfg_blocks->source_address); + LOG_DBG("JATW %s(%d) cfg_blocks->dest_address:0x%08x\n", __func__, __LINE__, cfg_blocks->dest_address); + if (cfg->dest_chaining_en == 1 && cfg_blocks->next_block) { uint32_t current_block_idx = 0; @@ -411,6 +418,7 @@ static int dma_atcdmac100_config(const struct device *dev, uint32_t channel, } end: + LOG_DBG("JATW %s(%d) channel:%d ret:%d\n", __func__, __LINE__, channel, ret); return ret; } diff --git a/dts/riscv/rapidsilicon/rapidsi_virgo.dtsi b/dts/riscv/rapidsilicon/rapidsi_virgo.dtsi index f985d4ede61f9..bc0fb28712cd4 100644 --- a/dts/riscv/rapidsilicon/rapidsi_virgo.dtsi +++ b/dts/riscv/rapidsilicon/rapidsi_virgo.dtsi @@ -167,7 +167,7 @@ interrupts = <27 9>; interrupt-parent = <&eclic>; dma-channels = <8>; - dma-requests = <16>; + dma-requests = <32>; chain-transfer = <1>; #dma-cells = <3>; status = "disabled"; From 722119a5467ada41cc9b0ca7c7b1f149d83278f5 Mon Sep 17 00:00:00 2001 From: junaidaslamRS Date: Wed, 24 Jul 2024 16:43:35 +0500 Subject: [PATCH 05/10] Supported ATCDMAC100 Driver --- drivers/dma/dma_andes_atcdmac100.c | 51 ++---- dts/riscv/rapidsilicon/rapidsi_virgo.dtsi | 4 +- samples/hello_world/src/main.c | 189 +++++++++++++++++----- 3 files changed, 161 insertions(+), 83 deletions(-) diff --git a/drivers/dma/dma_andes_atcdmac100.c b/drivers/dma/dma_andes_atcdmac100.c index ffc5f29d824fd..b407f5f08815d 100644 --- a/drivers/dma/dma_andes_atcdmac100.c +++ b/drivers/dma/dma_andes_atcdmac100.c @@ -49,26 +49,6 @@ LOG_MODULE_REGISTER(dma_andes_atcdmac100); #define DMA_CH_LL_PTR_L(dev, ch) \ (((struct dma_atcdmac100_cfg *)dev->config)->base + 0x54 + DMA_CH_OFFSET(ch)) -/* ID and Revision Register Bits */ -#define DMA_REV_MINOR_OFFSET 0 -#define DMA_REV_MINOR_MASK GENMASK(3, 0) -#define DMA_REV_MAJOR_OFFSET 4 -#define DMA_REV_MAJOR_MASK GENMASK(11, 4) -#define DMA_ID_OFFSET 12 -#define DMA_ID_MASK GENMASK(31, 12) - -/* Configuration Register Bits */ -#define DMA_RO_CFG_CH_NUM_OFFSET 0 -#define DMA_RO_CFG_CH_NUM_MASK GENMASK(3, 0) -#define DMA_RO_FIFO_DEPTH_OFFSET 4 -#define DMA_RO_FIFO_DEPTH_MASK GENMASK(9, 4) -#define DMA_RO_REQ_ACK_NUM_OFFSET 10 -#define DMA_RO_REQ_ACK_NUM_MASK GENMASK(15, 10) -#define DMA_RO_REQ_SYNC_OFFSET 30 -#define DMA_RO_REQ_SYNC_MASK GENMASK(30, 30) -#define DMA_RO_CHAIN_XFR_OFFSET 31 -#define DMA_RO_CHAIN_XFR_MASK GENMASK(31, 31) - /* DMA Control Register Bits */ #define DMA_CTRL_RESET_OFFSET 0 #define DMA_CTRL_RESET_MASK GENMASK(0, 0) @@ -129,7 +109,7 @@ LOG_MODULE_REGISTER(dma_andes_atcdmac100); typedef void (*atcdmac100_cfg_func_t)(void); -struct chain_block { +struct __attribute__((packed, aligned(4))) chain_block { uint32_t ctrl; uint32_t srcaddrl; uint32_t dstaddrl; @@ -180,12 +160,14 @@ static void dma_atcdmac100_isr(const struct device *dev) int_ch_status = DMA_INT_STATUS_TC_VAL(int_status); while (int_ch_status) { channel = find_msb_set(int_ch_status) - 1; + int_ch_status &= ~(BIT(channel)); ch_data = &data->chan[channel]; if (ch_data->blkcallback) { ch_data->blkcallback(dev, ch_data->blkuser_data, channel, 0); - } + } + data->chan[channel].status.busy = false; } @@ -199,7 +181,7 @@ static void dma_atcdmac100_isr(const struct device *dev) if (ch_data->blkcallback) { ch_data->blkcallback(dev, ch_data->blkuser_data, channel, -EIO); } - } + } } static int dma_atcdmac100_config(const struct device *dev, uint32_t channel, @@ -243,17 +225,15 @@ static int dma_atcdmac100_config(const struct device *dev, uint32_t channel, switch (cfg->channel_direction) { case MEMORY_TO_MEMORY: break; - case MEMORY_TO_PERIPHERAL: { - LOG_DBG("JATW %s(%d) MEMORY_TO_PERIPHERAL\n", __func__, __LINE__); + case MEMORY_TO_PERIPHERAL: { if(cfg->dest_handshake) { ch_ctrl |= DMA_CH_CTRL_DSTREQ(cfg->dma_slot); ch_ctrl |= DMA_CH_CTRL_DMODE_HANDSHAKE; } } break; - case PERIPHERAL_TO_MEMORY: { - LOG_DBG("JATW %s(%d) PERIPHERAL_TO_MEMORY\n", __func__, __LINE__); - if(cfg->source_handshake) { + case PERIPHERAL_TO_MEMORY: { + if(cfg->source_handshake) { ch_ctrl |= DMA_CH_CTRL_SRCREQ(cfg->dma_slot); ch_ctrl |= DMA_CH_CTRL_SMODE_HANDSHAKE; } @@ -280,8 +260,6 @@ static int dma_atcdmac100_config(const struct device *dev, uint32_t channel, goto end; } - LOG_DBG("JATW %s(%d) cfg_blocks->source_addr_adj:%d\n", __func__, __LINE__, cfg_blocks->source_addr_adj); - switch (cfg_blocks->dest_addr_adj) { case DMA_ADDR_ADJ_INCREMENT: ch_ctrl |= DMA_CH_CTRL_DSTADDR_INC; @@ -297,8 +275,6 @@ static int dma_atcdmac100_config(const struct device *dev, uint32_t channel, goto end; } - LOG_DBG("JATW %s(%d) cfg_blocks->dest_addr_adj:%d\n", __func__, __LINE__, cfg_blocks->dest_addr_adj); - ch_ctrl |= DMA_CH_CTRL_INTABT; /* Disable the error callback */ @@ -342,17 +318,15 @@ static int dma_atcdmac100_config(const struct device *dev, uint32_t channel, /* Set source and destination address */ sys_write32(cfg_blocks->source_address, DMA_CH_SRC_ADDR_L(dev, channel)); + sys_write32(cfg_blocks->dest_address, DMA_CH_DST_ADDR_L(dev, channel)); - LOG_DBG("JATW %s(%d) cfg_blocks->source_address:0x%08x\n", __func__, __LINE__, cfg_blocks->source_address); - LOG_DBG("JATW %s(%d) cfg_blocks->dest_address:0x%08x\n", __func__, __LINE__, cfg_blocks->dest_address); - if (cfg->dest_chaining_en == 1 && cfg_blocks->next_block) { uint32_t current_block_idx = 0; sys_write32((uint32_t)((long)&dma_chain[channel][current_block_idx]), - DMA_CH_LL_PTR_L(dev, channel)); + DMA_CH_LL_PTR_L(dev, channel)); for (cfg_blocks = cfg_blocks->next_block; cfg_blocks != NULL; cfg_blocks = cfg_blocks->next_block) { @@ -418,7 +392,7 @@ static int dma_atcdmac100_config(const struct device *dev, uint32_t channel, } end: - LOG_DBG("JATW %s(%d) channel:%d ret:%d\n", __func__, __LINE__, channel, ret); + return ret; } @@ -433,6 +407,7 @@ static int dma_atcdmac100_reload(const struct device *dev, uint32_t channel, /* Set source and destination address */ sys_write32(src, DMA_CH_SRC_ADDR_L(dev, channel)); + sys_write32(dst, DMA_CH_DST_ADDR_L(dev, channel)); src_width = FIELD_GET(DMA_CH_CTRL_SWIDTH_MASK, sys_read32(DMA_CH_CTRL(dev, channel))); @@ -548,7 +523,7 @@ static const struct dma_driver_api dma_atcdmac100_api = { static void dma_atcdmac100_irq_config_##n(void) \ { \ IRQ_CONNECT(DT_INST_IRQN(n), \ - 1, \ + DT_INST_IRQ(n, priority), \ dma_atcdmac100_isr, \ DEVICE_DT_INST_GET(n), \ 0); \ diff --git a/dts/riscv/rapidsilicon/rapidsi_virgo.dtsi b/dts/riscv/rapidsilicon/rapidsi_virgo.dtsi index bc0fb28712cd4..83a5add91295e 100644 --- a/dts/riscv/rapidsilicon/rapidsi_virgo.dtsi +++ b/dts/riscv/rapidsilicon/rapidsi_virgo.dtsi @@ -150,7 +150,7 @@ spi0: spi@A0800000 { compatible = "andestech,atcspi200"; reg = <0xA0800000 0xFFFF>; - interrupts = <24 5>; + interrupts = <24 10>; interrupt-parent = <&eclic>; dmas = <&dma0 0 0 0x009>, <&dma0 1 1 0x00A>; @@ -168,7 +168,7 @@ interrupt-parent = <&eclic>; dma-channels = <8>; dma-requests = <32>; - chain-transfer = <1>; + chain-transfer = <0>; #dma-cells = <3>; status = "disabled"; }; diff --git a/samples/hello_world/src/main.c b/samples/hello_world/src/main.c index ddccfef098516..5f885f5fcbfcc 100644 --- a/samples/hello_world/src/main.c +++ b/samples/hello_world/src/main.c @@ -7,6 +7,7 @@ #include #include #include +#include #include #define ATTR_INF "\x1b[32;1m" // ANSI_COLOR_GREEN @@ -16,7 +17,7 @@ #define FLASH_RW_SIZE 255 #define FLASH_BASE_ADDR 0xB0000000 -void Flash_Test(const struct device *flash, uint32_t FLASH_ADDR, uint8_t EVEN_ODD_MUL, uint8_t FORMATTER) { +void Flash_Test(const struct device *flash, const struct device *dma, uint32_t FLASH_ADDR, uint8_t EVEN_ODD_MUL, uint8_t FORMATTER) { int errorcode = 0; uint8_t flash_data_write[FLASH_RW_SIZE] = {0}; uint8_t flash_data_read[FLASH_RW_SIZE] = {0}; @@ -26,13 +27,13 @@ void Flash_Test(const struct device *flash, uint32_t FLASH_ADDR, uint8_t EVEN_OD } else { printf("%s Reading Back Before Erasing Flash%s\n", ATTR_INF,ATTR_RST); - for(uint8_t i = 0; i < FLASH_RW_SIZE; i++) { - printf("%s %d%s", ATTR_INF, flash_data_read[i],i%FORMATTER==0?"\n":""); - } printf("\n"); + // for(uint8_t i = 0; i < FLASH_RW_SIZE; i++) { + // printf("%s %d%s", ATTR_INF, flash_data_read[i],i%FORMATTER==0?"\n":""); + // } printf("\n"); } errorcode = flash_erase(flash, FLASH_ADDR, 0x1000); if(errorcode < 0) { - printf("%s\nError Erasing the flash at 0x%08x offset errorcode:%d%s\n", ATTR_ERR, FLASH_ADDR, errorcode,ATTR_RST); + printf("%s\nError Erasing the flash at 0x%08x offset errorcode:%d%s\n", ATTR_ERR, FLASH_ADDR, errorcode, ATTR_RST); } else { printf("%s\nSuccessfully Erased Flash\n", ATTR_RST); errorcode = flash_read(flash, FLASH_ADDR, flash_data_read, FLASH_RW_SIZE); @@ -48,9 +49,9 @@ void Flash_Test(const struct device *flash, uint32_t FLASH_ADDR, uint8_t EVEN_OD } if(errorcode == -1) { printf("%s\nFlash erase at 0x%08x did not produce correct results%s\n", ATTR_ERR, FLASH_ADDR,ATTR_RST); - for(uint8_t i = 0; i < FLASH_RW_SIZE; i++) { - printf("%s 0x%02x%s", ATTR_INF, flash_data_read[i],i%FORMATTER==0?"\n":""); - } printf("\n"); + // for(uint8_t i = 0; i < FLASH_RW_SIZE; i++) { + // printf("%s 0x%02x%s", ATTR_INF, flash_data_read[i],i%FORMATTER==0?"\n":""); + // } printf("\n"); } else { printf("%s\nSuccessfully performed erase to flash with code:%d%s\n", ATTR_INF, errorcode,ATTR_RST); } @@ -60,9 +61,10 @@ void Flash_Test(const struct device *flash, uint32_t FLASH_ADDR, uint8_t EVEN_OD if(errorcode == 0) { printf("%s Writing the following data After Erasing Flash%s\n", ATTR_INF,ATTR_RST); for(uint8_t i = 0; i < FLASH_RW_SIZE; i++) { - flash_data_write[i] = ((rand() % (FLASH_RW_SIZE - 1 + 1)) + 1)*2; + flash_data_write[i] = ((rand() % (FLASH_RW_SIZE - 1 + 1)) + 1)+((rand() % (FLASH_RW_SIZE - 1 + 1)) + 1); printf("%s %d%s", ATTR_INF, flash_data_write[i],i%FORMATTER==0?"\n":""); - } printf("\n"); + } + printf("\n"); errorcode = flash_write(flash, FLASH_ADDR, flash_data_write, FLASH_RW_SIZE); } @@ -92,32 +94,134 @@ void Flash_Test(const struct device *flash, uint32_t FLASH_ADDR, uint8_t EVEN_OD } uint8_t *MemMapReadAddr = (uint8_t*)(FLASH_BASE_ADDR + FLASH_ADDR); - printf("Memory Mapped Reading Test from address:%p\n", MemMapReadAddr); - bool memmaptestfail = false; - for(uint8_t i = 0; i < FLASH_RW_SIZE; i++) { - if(MemMapReadAddr[i] != flash_data_write[i]) { - printf("%s %d%s Mismatch in memory mapped read", ATTR_ERR, MemMapReadAddr[i],i%FORMATTER==0?"\n":""); - memmaptestfail = true; break; - } - } printf("\n"); - if(memmaptestfail) { - printf("%s Memory mapped read failed\n", ATTR_ERR); - } else { - printf("%s Memory mapped read passed\n", ATTR_INF); + uint8_t MemMapReadDestAddr[FLASH_RW_SIZE]; + { + printf("CPU Memory Mapped Reading Test from address:%p\n", MemMapReadAddr); + bool memmaptestfail = false; + for(uint8_t i = 0; i < FLASH_RW_SIZE; i++) { + if(MemMapReadAddr[i] != flash_data_write[i]) { + printf("%s %d%s", ATTR_ERR, MemMapReadAddr[i],i%FORMATTER==0?"\n":""); + memmaptestfail = true; + } + else { + printf("%s %d%s", ATTR_INF, MemMapReadAddr[i],i%FORMATTER==0?"\n":""); + } + } printf("\n"); + if(memmaptestfail) { + printf("%s CPU Memory mapped read failed\n", ATTR_ERR); + } else { + printf("%s CPU Memory mapped read passed\n", ATTR_INF); + } + } + + if(dma != NULL) { + printf("%s DMA Memory Mapped Reading Test from address:%p\n", ATTR_RST, MemMapReadAddr); + // Configure DMA Block + struct dma_block_config lv_dma_block_config = { + .block_size = FLASH_RW_SIZE, + .dest_addr_adj = DMA_ADDR_ADJ_INCREMENT, + .dest_address = (uint32_t)&MemMapReadDestAddr[0], + .dest_reload_en = 0, + .dest_scatter_count = 0, + .dest_scatter_en = 0, + .dest_scatter_interval = 0, + .fifo_mode_control = 0, + .flow_control_mode = 0, + .next_block = NULL, + .source_addr_adj = DMA_ADDR_ADJ_INCREMENT, + .source_address = (uint32_t)&MemMapReadAddr[0], + .source_gather_count = 0, + .source_gather_en = 0, + .source_gather_interval = 0, + .source_reload_en = 0, + ._reserved = 0 + }; + // Configure DMA + struct dma_config lv_Dma_Config = { + .block_count = 1, + .channel_direction = MEMORY_TO_MEMORY, + .channel_priority = 1, + .complete_callback_en = 0, + .cyclic = 0, + .dest_burst_length = 1, + .dest_chaining_en = 0, + .dest_data_size = 1, + .dest_handshake = 1, + .dma_callback = NULL, + .dma_slot = 0, + .error_callback_dis = 1, + .head_block = &lv_dma_block_config, + .linked_channel = 0, + .source_burst_length = 1, + .source_chaining_en = 0, + .source_data_size = 1, + .user_data = NULL + }; + struct dma_status stat = {0}; + printf("%s DMA Configuration...\n", ATTR_RST); + int dma_error = dma_config(dma, 1, &lv_Dma_Config); + k_msleep(10); + if(dma_error) { + printf("%s Error %d Configuration...\n", ATTR_RST, dma_error); + } else { + // Call DMA Read + printf("%s DMA Starting...\n", ATTR_INF); + dma_error = dma_start(dma, 1); + k_msleep(10); + } + (void)dma_get_status(dma, 1, &stat); + while(stat.pending_length > 1) { + dma_error = dma_get_status(dma, 1, &stat); + if(dma_error) { + printf("Error %d dma_status...\n", dma_error); + break; + } else { + printf("dma_pending_length:%d \n", stat.pending_length); + } + } + + if(!dma_error) { + bool memmaptestfail = false; + for(uint8_t i = 0; i < FLASH_RW_SIZE; i++) { + if(MemMapReadDestAddr[i] != flash_data_write[i]) { + printf("%s %d%s", ATTR_ERR, MemMapReadDestAddr[i],i%FORMATTER==0?"\n":""); + memmaptestfail = true; + } + else { + printf("%s %d%s", ATTR_INF, MemMapReadDestAddr[i],i%FORMATTER==0?"\n":""); + } + } + printf("\n"); + if(memmaptestfail) { + printf("%s DMA Memory mapped read failed\n", ATTR_ERR); + } else { + printf("%s DMA Memory mapped read passed\n", ATTR_INF); + } + } else { + printf("Error %d DMA Start...\n", dma_error); + } } } int main(void) { int Cnt = 0; - struct sensor_value lvTemp = {0}, lvVolt = {0}; uint8_t chip_id = 0, vendor_id = 0; - int errorcode = 0; + + printf( + "%s SPI_(%d)_IRQ_Reg_Val:[0x%08x]; DMA_(%d)_IRQ_Reg_Val:[0x%08x]\n", ATTR_RST, \ + IRQ_ID_SPI, scu_get_irq_reg_val(IRQ_ID_SPI), \ + IRQ_ID_SYSTEM_DMA, scu_get_irq_reg_val(IRQ_ID_SYSTEM_DMA) + ); soc_get_id(&chip_id, &vendor_id); + int errorcode = 0; + struct sensor_value lvTemp = {0}, lvVolt = {0}; const struct device *pvt = DEVICE_DT_GET(DT_NODELABEL(pvt0)); + const struct device *spi = DEVICE_DT_GET(DT_NODELABEL(spi0)); const struct device *flash = DEVICE_DT_GET(DT_NODELABEL(m25p32)); + const struct device *dma = DEVICE_DT_GET(DT_NODELABEL(dma0)); if((pvt == NULL) || (!device_is_ready(pvt))) { printf("%s pvt has status disabled or driver is not initialized...%s\n", ATTR_ERR, ATTR_RST); @@ -127,38 +231,37 @@ int main(void) if(errorcode == 0) { printf("%s Error fetching temperature value. Error code:%u%s\n", ATTR_ERR, errorcode,ATTR_RST); } - errorcode = sensor_channel_get(pvt, SENSOR_CHAN_VOLTAGE, &lvVolt); if(errorcode == 0) { printf("%s Error fetching Voltage value. Error code:%u%s\n", ATTR_ERR, errorcode,ATTR_RST); } - printf("%s Die Temperature:%d Voltage:%d%s\n", ATTR_INF, lvTemp.val1, lvVolt.val1,ATTR_RST); } - if((flash == NULL) || (!device_is_ready(flash))) { - printf("%s flash has status disabled or driver is not initialized...%s\n", ATTR_ERR,ATTR_RST); - } else { - printf("%s flash Object is Created. Test Via DMA\n", ATTR_INF); - scu_irq_map(IRQ_ID_SPI, SCU_IRQ_MAP_TO_BCPU); - scu_irq_map(IRQ_ID_SYSTEM_DMA, SCU_IRQ_MAP_TO_BCPU); - scu_irq_enable(IRQ_ID_SPI); - scu_irq_enable(IRQ_ID_SYSTEM_DMA); - printf( - "%s SPI_(%d)_IRQ_Reg_Val:[0x%08x]; DMA_(%d)_IRQ_Reg_Val:[0x%08x]\n", ATTR_RST, \ - IRQ_ID_SPI, scu_get_irq_reg_val(IRQ_ID_SPI), \ - IRQ_ID_SYSTEM_DMA, scu_get_irq_reg_val(IRQ_ID_SYSTEM_DMA) - ); - Flash_Test(flash, 0x1000, 0, 20); + if(spi == NULL) { + printf("%s spi has status disabled...%s\n", ATTR_ERR,ATTR_RST); + } else { + printf("%s spi Object is Created. Test Via DMA\n", ATTR_INF); + if(flash == NULL) { + printf("%s flash has status disabled...%s\n", ATTR_ERR,ATTR_RST); + } else { + printf("%s flash Object is Created. Initialize to Test Via DMA%s\n", ATTR_INF,ATTR_RST); + if(flash != NULL) { + Flash_Test(flash, dma, 0x1000, 0, 20); + } else { + printf("%s Error Initializing DMA Device%s\n", ATTR_ERR,ATTR_RST); + Flash_Test(flash, NULL, 0x1000, 0, 20); + } + } } while(true) { printf( - "%s%d - %s [CHIP_ID:0x%02x VENDOR_ID:0x%02x] Die[Temp:%d Volt:%d] mTimerClock = %d Hz\r", + "%s%d - %s [CHIP_ID:0x%02x VENDOR_ID:0x%02x] Build[Date:%s Time:%s]\r", ATTR_RST, Cnt++, CONFIG_BOARD_TARGET, - chip_id, vendor_id, lvTemp.val1, lvVolt.val1, - CONFIG_SYS_CLOCK_HW_CYCLES_PER_SEC + chip_id, vendor_id, + __DATE__, __TIME__ ); k_msleep(1000); } From 5a045e9c0ae16f132496da0c29e7c6e64a2a656f Mon Sep 17 00:00:00 2001 From: junaidaslamRS Date: Tue, 6 Aug 2024 14:50:33 +0500 Subject: [PATCH 06/10] Supported ATCDMAC100 Driver --- drivers/dma/dma_andes_atcdmac100.c | 2 +- dts/riscv/rapidsilicon/rapidsi_virgo.dtsi | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/dma/dma_andes_atcdmac100.c b/drivers/dma/dma_andes_atcdmac100.c index b407f5f08815d..06cd03ccb2da9 100644 --- a/drivers/dma/dma_andes_atcdmac100.c +++ b/drivers/dma/dma_andes_atcdmac100.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023 Andes Technology Corporation. + * Copyright (c) 2024 Rapid Silicon * * SPDX-License-Identifier: Apache-2.0 */ diff --git a/dts/riscv/rapidsilicon/rapidsi_virgo.dtsi b/dts/riscv/rapidsilicon/rapidsi_virgo.dtsi index 83a5add91295e..b1f5bb37b9ebb 100644 --- a/dts/riscv/rapidsilicon/rapidsi_virgo.dtsi +++ b/dts/riscv/rapidsilicon/rapidsi_virgo.dtsi @@ -168,7 +168,7 @@ interrupt-parent = <&eclic>; dma-channels = <8>; dma-requests = <32>; - chain-transfer = <0>; + chain-transfer = <1>; #dma-cells = <3>; status = "disabled"; }; From 3fca7daddc336b56f649eab9c1af263df93892fa Mon Sep 17 00:00:00 2001 From: junaidaslamRS Date: Wed, 7 Aug 2024 19:35:03 +0500 Subject: [PATCH 07/10] Supported ATCDMAC100 Driver + GPT (PIT) Counter Verification Done --- .../rapidsilicon/virgo_proto/virgo_proto.dts | 6 + samples/hello_world/src/main.c | 258 +++++++++++------- 2 files changed, 167 insertions(+), 97 deletions(-) diff --git a/boards/rapidsilicon/virgo_proto/virgo_proto.dts b/boards/rapidsilicon/virgo_proto/virgo_proto.dts index 3ab8bd40383f7..a116964a01762 100644 --- a/boards/rapidsilicon/virgo_proto/virgo_proto.dts +++ b/boards/rapidsilicon/virgo_proto/virgo_proto.dts @@ -40,6 +40,12 @@ clock-frequency = <26666667>; }; + &pit0 { + clock-frequency = <26666667>; + prescaler = <600>; + status = "okay"; + }; + &dma0 { status = "okay"; }; diff --git a/samples/hello_world/src/main.c b/samples/hello_world/src/main.c index 5f885f5fcbfcc..1b183addd7d7b 100644 --- a/samples/hello_world/src/main.c +++ b/samples/hello_world/src/main.c @@ -5,6 +5,7 @@ */ #include +#include #include #include #include @@ -93,112 +94,168 @@ void Flash_Test(const struct device *flash, const struct device *dma, uint32_t F } } - uint8_t *MemMapReadAddr = (uint8_t*)(FLASH_BASE_ADDR + FLASH_ADDR); - uint8_t MemMapReadDestAddr[FLASH_RW_SIZE]; - { - printf("CPU Memory Mapped Reading Test from address:%p\n", MemMapReadAddr); - bool memmaptestfail = false; - for(uint8_t i = 0; i < FLASH_RW_SIZE; i++) { - if(MemMapReadAddr[i] != flash_data_write[i]) { - printf("%s %d%s", ATTR_ERR, MemMapReadAddr[i],i%FORMATTER==0?"\n":""); - memmaptestfail = true; - } - else { - printf("%s %d%s", ATTR_INF, MemMapReadAddr[i],i%FORMATTER==0?"\n":""); + if(errorcode == 0) + { + uint8_t *MemMapReadAddr = (uint8_t*)(FLASH_BASE_ADDR + FLASH_ADDR); + uint8_t MemMapReadDestAddr[FLASH_RW_SIZE]; + { + printf("CPU Memory Mapped Reading Test from address:%p\n", MemMapReadAddr); + bool memmaptestfail = false; + for(uint8_t i = 0; i < FLASH_RW_SIZE; i++) { + if(MemMapReadAddr[i] != flash_data_write[i]) { + printf("%s %d%s", ATTR_ERR, MemMapReadAddr[i],i%FORMATTER==0?"\n":""); + memmaptestfail = true; + } + else { + printf("%s %d%s", ATTR_INF, MemMapReadAddr[i],i%FORMATTER==0?"\n":""); + } + } printf("\n"); + if(memmaptestfail) { + printf("%s CPU Memory mapped read failed\n", ATTR_ERR); + } else { + printf("%s CPU Memory mapped read passed\n", ATTR_INF); } - } printf("\n"); - if(memmaptestfail) { - printf("%s CPU Memory mapped read failed\n", ATTR_ERR); - } else { - printf("%s CPU Memory mapped read passed\n", ATTR_INF); - } - } + } - if(dma != NULL) { - printf("%s DMA Memory Mapped Reading Test from address:%p\n", ATTR_RST, MemMapReadAddr); - // Configure DMA Block - struct dma_block_config lv_dma_block_config = { - .block_size = FLASH_RW_SIZE, - .dest_addr_adj = DMA_ADDR_ADJ_INCREMENT, - .dest_address = (uint32_t)&MemMapReadDestAddr[0], - .dest_reload_en = 0, - .dest_scatter_count = 0, - .dest_scatter_en = 0, - .dest_scatter_interval = 0, - .fifo_mode_control = 0, - .flow_control_mode = 0, - .next_block = NULL, - .source_addr_adj = DMA_ADDR_ADJ_INCREMENT, - .source_address = (uint32_t)&MemMapReadAddr[0], - .source_gather_count = 0, - .source_gather_en = 0, - .source_gather_interval = 0, - .source_reload_en = 0, - ._reserved = 0 - }; - // Configure DMA - struct dma_config lv_Dma_Config = { - .block_count = 1, - .channel_direction = MEMORY_TO_MEMORY, - .channel_priority = 1, - .complete_callback_en = 0, - .cyclic = 0, - .dest_burst_length = 1, - .dest_chaining_en = 0, - .dest_data_size = 1, - .dest_handshake = 1, - .dma_callback = NULL, - .dma_slot = 0, - .error_callback_dis = 1, - .head_block = &lv_dma_block_config, - .linked_channel = 0, - .source_burst_length = 1, - .source_chaining_en = 0, - .source_data_size = 1, - .user_data = NULL - }; - struct dma_status stat = {0}; - printf("%s DMA Configuration...\n", ATTR_RST); - int dma_error = dma_config(dma, 1, &lv_Dma_Config); - k_msleep(10); - if(dma_error) { - printf("%s Error %d Configuration...\n", ATTR_RST, dma_error); - } else { - // Call DMA Read - printf("%s DMA Starting...\n", ATTR_INF); - dma_error = dma_start(dma, 1); + if(dma != NULL) { + printf("%s DMA Memory Mapped Reading Test from address:%p\n", ATTR_RST, MemMapReadAddr); + // Configure DMA Block + struct dma_block_config lv_dma_block_config = { + .block_size = FLASH_RW_SIZE, + .dest_addr_adj = DMA_ADDR_ADJ_INCREMENT, + .dest_address = (uint32_t)&MemMapReadDestAddr[0], + .dest_reload_en = 0, + .dest_scatter_count = 0, + .dest_scatter_en = 0, + .dest_scatter_interval = 0, + .fifo_mode_control = 0, + .flow_control_mode = 0, + .next_block = NULL, + .source_addr_adj = DMA_ADDR_ADJ_INCREMENT, + .source_address = (uint32_t)&MemMapReadAddr[0], + .source_gather_count = 0, + .source_gather_en = 0, + .source_gather_interval = 0, + .source_reload_en = 0, + ._reserved = 0 + }; + // Configure DMA + struct dma_config lv_Dma_Config = { + .block_count = 1, + .channel_direction = MEMORY_TO_MEMORY, + .channel_priority = 1, + .complete_callback_en = 0, + .cyclic = 0, + .dest_burst_length = 1, + .dest_chaining_en = 0, + .dest_data_size = 1, + .dest_handshake = 1, + .dma_callback = NULL, + .dma_slot = 0, + .error_callback_dis = 1, + .head_block = &lv_dma_block_config, + .linked_channel = 0, + .source_burst_length = 1, + .source_chaining_en = 0, + .source_data_size = 1, + .user_data = NULL + }; + struct dma_status stat = {0}; + printf("%s DMA Configuration...\n", ATTR_RST); + int dma_error = dma_config(dma, 1, &lv_Dma_Config); k_msleep(10); - } - (void)dma_get_status(dma, 1, &stat); - while(stat.pending_length > 1) { - dma_error = dma_get_status(dma, 1, &stat); if(dma_error) { - printf("Error %d dma_status...\n", dma_error); - break; - } else { - printf("dma_pending_length:%d \n", stat.pending_length); + printf("%s Error %d Configuration...\n", ATTR_RST, dma_error); + } else { + // Call DMA Read + printf("%s DMA Starting...\n", ATTR_INF); + dma_error = dma_start(dma, 1); + k_msleep(10); + } + (void)dma_get_status(dma, 1, &stat); + while(stat.pending_length > 1) { + dma_error = dma_get_status(dma, 1, &stat); + if(dma_error) { + printf("Error %d dma_status...\n", dma_error); + break; + } else { + printf("dma_pending_length:%d \n", stat.pending_length); + } } - } - if(!dma_error) { - bool memmaptestfail = false; - for(uint8_t i = 0; i < FLASH_RW_SIZE; i++) { - if(MemMapReadDestAddr[i] != flash_data_write[i]) { - printf("%s %d%s", ATTR_ERR, MemMapReadDestAddr[i],i%FORMATTER==0?"\n":""); - memmaptestfail = true; + if(!dma_error) { + bool memmaptestfail = false; + for(uint8_t i = 0; i < FLASH_RW_SIZE; i++) { + if(MemMapReadDestAddr[i] != flash_data_write[i]) { + printf("%s %d%s", ATTR_ERR, MemMapReadDestAddr[i],i%FORMATTER==0?"\n":""); + memmaptestfail = true; + } + else { + printf("%s %d%s", ATTR_INF, MemMapReadDestAddr[i],i%FORMATTER==0?"\n":""); + } } - else { - printf("%s %d%s", ATTR_INF, MemMapReadDestAddr[i],i%FORMATTER==0?"\n":""); + printf("\n"); + if(memmaptestfail) { + printf("%s DMA Memory mapped read failed\n", ATTR_ERR); + } else { + printf("%s DMA Memory mapped read passed\n", ATTR_INF); } - } - printf("\n"); - if(memmaptestfail) { - printf("%s DMA Memory mapped read failed\n", ATTR_ERR); } else { - printf("%s DMA Memory mapped read passed\n", ATTR_INF); + printf("Error %d DMA Start...\n", dma_error); } - } else { - printf("Error %d DMA Start...\n", dma_error); + } + } +} + +void CounterCallBack(const struct device *dev, void *UserData) +{ + uint32_t *lvData = ((uint32_t*)UserData); + printf("andestech_atcpit100 %s # %d\n", __func__, *lvData); + *lvData += 1; +} + +void CounterAlarmCallBack(const struct device *dev, + uint8_t chan_id, uint32_t ticks, + void *UserData) +{ + uint32_t *lvData = ((uint32_t*)UserData); + printf("andestech_atcpit100 %s # %d\n", __func__, *lvData); +} + +static uint32_t s_CallBackData = 0; + +void CounterTest(const struct device *pit) +{ + struct counter_alarm_cfg lvCntAlarmCfg = {0}; + lvCntAlarmCfg.callback = CounterAlarmCallBack; + lvCntAlarmCfg.flags = COUNTER_ALARM_CFG_EXPIRE_WHEN_LATE; + lvCntAlarmCfg.ticks = 24000; + lvCntAlarmCfg.user_data = (void*)&s_CallBackData; + + struct counter_top_cfg lvCntTopCfg = {0}; + + lvCntTopCfg.callback = CounterCallBack; + lvCntTopCfg.user_data = (void*)&s_CallBackData; + lvCntTopCfg.flags = COUNTER_TOP_CFG_DONT_RESET; + lvCntTopCfg.ticks = 6000; + + int lvErrorCode = 0; + /* + lvErrorCode = counter_set_channel_alarm(pit, 0, &lvCntAlarmCfg); + if(lvErrorCode < 0) { + printf("%s%s(%d) counter Alarm set error code:%d %s\n", \ + ATTR_ERR,__func__,__LINE__,lvErrorCode,ATTR_RST); + } + */ + lvErrorCode = counter_set_top_value(pit, &lvCntTopCfg); + if(lvErrorCode < 0) { + printf("%s%s(%d) counter setting top error code:%d %s\n", \ + ATTR_ERR,__func__,__LINE__,lvErrorCode,ATTR_RST); + } else { + int lvErrorCode = counter_start(pit); + if(lvErrorCode < 0) { + printf("%s%s(%d) counter start error code:%d %s\n", \ + ATTR_ERR,__func__,__LINE__,lvErrorCode,ATTR_RST); } } } @@ -222,6 +279,7 @@ int main(void) const struct device *spi = DEVICE_DT_GET(DT_NODELABEL(spi0)); const struct device *flash = DEVICE_DT_GET(DT_NODELABEL(m25p32)); const struct device *dma = DEVICE_DT_GET(DT_NODELABEL(dma0)); + const struct device *pit = DEVICE_DT_GET(DT_NODELABEL(pit0)); if((pvt == NULL) || (!device_is_ready(pvt))) { printf("%s pvt has status disabled or driver is not initialized...%s\n", ATTR_ERR, ATTR_RST); @@ -255,9 +313,15 @@ int main(void) } } + if((pit == NULL) || !device_is_ready(pit)) { + printf("%s flash has status disabled or driver is not initialized...%s\n", ATTR_ERR,ATTR_RST); + } else { + CounterTest(pit); + } + while(true) { printf( - "%s%d - %s [CHIP_ID:0x%02x VENDOR_ID:0x%02x] Build[Date:%s Time:%s]\r", + "%s%d - %s [CHIP_ID:0x%02x VENDOR_ID:0x%02x] Build[Date:%s Time:%s]\n", ATTR_RST, Cnt++, CONFIG_BOARD_TARGET, chip_id, vendor_id, From 3a6bc072f959389d82480040851e7ca6d12a2ef7 Mon Sep 17 00:00:00 2001 From: junaidaslamRS Date: Fri, 9 Aug 2024 15:11:14 +0500 Subject: [PATCH 08/10] Supported ATCDMAC100 Driver ReWork --- dts/bindings/dma/andestech,atcdmac100.yaml | 4 ++-- .../{andestech.atcspi200.yaml => andestech,atcspi200.yaml} | 0 2 files changed, 2 insertions(+), 2 deletions(-) rename dts/bindings/spi/{andestech.atcspi200.yaml => andestech,atcspi200.yaml} (100%) diff --git a/dts/bindings/dma/andestech,atcdmac100.yaml b/dts/bindings/dma/andestech,atcdmac100.yaml index 6665794f45fc9..1023731f65d8a 100644 --- a/dts/bindings/dma/andestech,atcdmac100.yaml +++ b/dts/bindings/dma/andestech,atcdmac100.yaml @@ -65,10 +65,10 @@ description: | examples for andes_v5_ae350 DMA instance dma0: dma0@f0c00000 { - compatible = "andestech,atcdmac300"; + compatible = "andestech,atcdmac100"; ... dma-channels = <8>; - dma-requests = <16>; + dma-requests = <32>; status = "disabled"; label = "DMA_0"; }; diff --git a/dts/bindings/spi/andestech.atcspi200.yaml b/dts/bindings/spi/andestech,atcspi200.yaml similarity index 100% rename from dts/bindings/spi/andestech.atcspi200.yaml rename to dts/bindings/spi/andestech,atcspi200.yaml From dfed2b62cefa30e9a9fc5d2020a6c914cefe35e1 Mon Sep 17 00:00:00 2001 From: junaidaslamRS Date: Tue, 13 Aug 2024 13:33:00 +0500 Subject: [PATCH 09/10] Corrected WDT Related Data in DTS --- dts/riscv/rapidsilicon/rapidsi_virgo.dtsi | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/dts/riscv/rapidsilicon/rapidsi_virgo.dtsi b/dts/riscv/rapidsilicon/rapidsi_virgo.dtsi index b1f5bb37b9ebb..1dd6b4ea998b9 100644 --- a/dts/riscv/rapidsilicon/rapidsi_virgo.dtsi +++ b/dts/riscv/rapidsilicon/rapidsi_virgo.dtsi @@ -174,11 +174,8 @@ }; bcpu_wdt: wdt@A0120000 { - compatible = "andestech,atcwdt100"; + compatible = "andestech,atcwdt200"; reg = <0xA0120000 DT_SIZE_K(16)>; - clock-frequency = <266666667>; - intr-time-scale = <7>; - rst-time-scale = <7>; interrupts = <0xffffffff 1>; interrupt-parent = <&eclic>; status = "disabled"; From 86d1bea02b2b137686e02f05dbc5ef748c7c0b96 Mon Sep 17 00:00:00 2001 From: junaidaslamRS Date: Thu, 15 Aug 2024 13:08:49 +0500 Subject: [PATCH 10/10] Supported ATCDMAC100 Driver ReWork --- drivers/dma/dma_andes_atcdmac100.c | 14 +++++++------- samples/hello_world/src/main.c | 9 ++------- 2 files changed, 9 insertions(+), 14 deletions(-) diff --git a/drivers/dma/dma_andes_atcdmac100.c b/drivers/dma/dma_andes_atcdmac100.c index 06cd03ccb2da9..9e26c6cd71635 100644 --- a/drivers/dma/dma_andes_atcdmac100.c +++ b/drivers/dma/dma_andes_atcdmac100.c @@ -111,10 +111,10 @@ typedef void (*atcdmac100_cfg_func_t)(void); struct __attribute__((packed, aligned(4))) chain_block { uint32_t ctrl; - uint32_t srcaddrl; - uint32_t dstaddrl; + uint32_t srcaddr; + uint32_t dstaddr; uint32_t transize; - uint32_t llpointerl; + uint32_t llpointer; struct chain_block *next_block; }; @@ -367,20 +367,20 @@ static int dma_atcdmac100_config(const struct device *dev, uint32_t channel, dma_chain[channel][current_block_idx].transize = cfg_blocks->block_size/cfg->source_data_size; - dma_chain[channel][current_block_idx].srcaddrl = + dma_chain[channel][current_block_idx].srcaddr = (uint32_t)cfg_blocks->source_address; - dma_chain[channel][current_block_idx].dstaddrl = + dma_chain[channel][current_block_idx].dstaddr = (uint32_t)((long)cfg_blocks->dest_address); if (cfg_blocks->next_block) { - dma_chain[channel][current_block_idx].llpointerl = + dma_chain[channel][current_block_idx].llpointer = (uint32_t)&dma_chain[channel][current_block_idx + 1]; current_block_idx = current_block_idx + 1; } else { - dma_chain[channel][current_block_idx].llpointerl = 0x0; + dma_chain[channel][current_block_idx].llpointer = 0x0; dma_chain[channel][current_block_idx].next_block = NULL; } } diff --git a/samples/hello_world/src/main.c b/samples/hello_world/src/main.c index 1b183addd7d7b..071e84822a5c2 100644 --- a/samples/hello_world/src/main.c +++ b/samples/hello_world/src/main.c @@ -301,15 +301,10 @@ int main(void) } else { printf("%s spi Object is Created. Test Via DMA\n", ATTR_INF); if(flash == NULL) { - printf("%s flash has status disabled...%s\n", ATTR_ERR,ATTR_RST); + printf("%s flash has status disabled or not initialized properly...%s\n", ATTR_ERR,ATTR_RST); } else { printf("%s flash Object is Created. Initialize to Test Via DMA%s\n", ATTR_INF,ATTR_RST); - if(flash != NULL) { - Flash_Test(flash, dma, 0x1000, 0, 20); - } else { - printf("%s Error Initializing DMA Device%s\n", ATTR_ERR,ATTR_RST); - Flash_Test(flash, NULL, 0x1000, 0, 20); - } + Flash_Test(flash, dma, 0x1000, 0, 20); } }