From f63422d5f053acdd47a40691ec8e0c12f8ee3f28 Mon Sep 17 00:00:00 2001 From: Ivan Date: Tue, 30 May 2017 17:30:53 +0900 Subject: [PATCH] s5j/dma: Add dma driver for i2s This DMA code initally is intended to be used with I2S driver. Can be also used with common memory transfers, and other IPs. Change-Id: If2a30e00a1f2ec7f5d410d11a8b4a3a59814ecf3 Signed-off-by: Ivan Signed-off-by: Bongryul Lee Signed-off-by: Junhwan Park --- os/arch/arm/include/s5j/dma.h | 103 ++++++ os/arch/arm/src/s5j/Kconfig | 10 + os/arch/arm/src/s5j/Make.defs | 7 + os/arch/arm/src/s5j/s5j_dma.c | 467 +++++++++++++++++++++++++++ os/arch/arm/src/s5j/s5j_dma.h | 332 +++++++++++++++++++ os/arch/arm/src/s5j/s5j_dma_m2m_sb_4B_x256.c | 177 ++++++++++ os/arch/arm/src/s5j/s5j_dma_m2p_sb_4B_x256.c | 194 +++++++++++ os/arch/arm/src/s5j/s5j_dma_p2m_sb_4B_x256.c | 193 +++++++++++ os/include/debug.h | 1 - 9 files changed, 1483 insertions(+), 1 deletion(-) create mode 100644 os/arch/arm/include/s5j/dma.h create mode 100644 os/arch/arm/src/s5j/s5j_dma.c create mode 100644 os/arch/arm/src/s5j/s5j_dma.h create mode 100644 os/arch/arm/src/s5j/s5j_dma_m2m_sb_4B_x256.c create mode 100644 os/arch/arm/src/s5j/s5j_dma_m2p_sb_4B_x256.c create mode 100644 os/arch/arm/src/s5j/s5j_dma_p2m_sb_4B_x256.c diff --git a/os/arch/arm/include/s5j/dma.h b/os/arch/arm/include/s5j/dma.h new file mode 100644 index 0000000..481d610 --- /dev/null +++ b/os/arch/arm/include/s5j/dma.h @@ -0,0 +1,103 @@ +/**************************************************************************** + * + * Copyright 2017 Samsung Electronics All Rights Reserved. + * + * Licensed 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_ARM_INCLUDE_S5J_DMA_H +#define __ARCH_ARM_INCLUDE_S5J_DMA_H + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ +#define s5j_dmasetup(a, b) if((b)->setup) (b)->setup(a, b); + +/************************************************************************************ + * Public Types + ************************************************************************************/ + +typedef enum { + DMA_UART0_RX = (0), + DMA_UART0_TX = (1), + DMA_UART1_RX = (2), + DMA_UART1_TX = (3), + DMA_UART2_RX = (4), + DMA_UART2_TX = (5), + DMA_UART3_RX = (6), + DMA_UART3_TX = (7), + DMA_HSI2C0_RX = (8), + DMA_HSI2C0_TX = (9), + DMA_HSI2C1_RX = (10), + DMA_HSI2C1_TX = (11), + DMA_HSI2C2_RX = (12), + DMA_HSI2C2_TX = (13), + DMA_HSI2C3_RX = (14), + DMA_HSI2C3_TX = (15), + DMA_SPI0_RX = (16), + DMA_SPI0_TX = (17), + DMA_SPI1_RX = (18), + DMA_SPI1_TX = (19), + DMA_SPI2_RX = (20), + DMA_SPI2_TX = (21), + DMA_SPI3_RX = (22), + DMA_SPI3_TX = (23), + DMA_I2S_RX = (24), + DMA_I2S_TX = (25), + DMA_I2S_TX_S = (26), + DMA_UART_Debug_RX = (28), + DMA_UART_Debug_TX = (29), + DMA_PWM0 = (30), + DMA_PWM1 = (31), +} DMA_REQ_MAP; + +typedef FAR void *DMA_HANDLE; +typedef struct dma_task dma_task; + +typedef void (*dma_callback_t)(DMA_HANDLE handle, void *arg, int result); +typedef int (*dma_setup_t)(DMA_HANDLE handle, dma_task *task); + +struct dma_task { + void *src; + void *dst; + u32 size; + void *microcode; + + dma_setup_t setup; + + dma_callback_t callback; + void *arg; +}; + +/************************************************************************************ + * Public Functions + ************************************************************************************/ +DMA_HANDLE s5j_dma_alloc(char *name); +DMA_HANDLE s5j_dmachannel(uint8_t dmacno, char *name); +void s5j_dmafree(DMA_HANDLE handle); + +dma_task *dma_task_m2m_sb_4B_x256_alloc(void); +dma_task *dma_task_m2p_sb_4B_x256_alloc(DMA_REQ_MAP d_ph_ch); +dma_task *dma_task_p2m_sb_4B_x256_alloc(DMA_REQ_MAP d_ph_ch); +dma_task *dma_task_m2mp_sb_4B_x256_alloc(void); +dma_task *dma_task_mp2m_sb_4B_x256_alloc(void); + +int s5j_dmatask_free(dma_task *task); + +int s5j_dmastart(DMA_HANDLE handle, dma_task *task); +dma_task *s5j_dmastop(DMA_HANDLE handle); + +void dma_clean_dcache(void *start, void *end); +void dma_invalidate_dcache(void *start, void *end); + +#endif diff --git a/os/arch/arm/src/s5j/Kconfig b/os/arch/arm/src/s5j/Kconfig index 374d667..6dafa17 100644 --- a/os/arch/arm/src/s5j/Kconfig +++ b/os/arch/arm/src/s5j/Kconfig @@ -25,6 +25,7 @@ config S5J_S5JT200 bool default n select S5J_HAVE_ADC + select S5J_HAVE_DMA select S5J_HAVE_I2C select S5J_HAVE_I2S select S5J_HAVE_MCT @@ -55,6 +56,10 @@ config S5J_HAVE_ADC bool default n +config S5J_HAVE_DMA + bool + default n + config S5J_HAVE_I2C bool default n @@ -147,6 +152,11 @@ config S5J_ADC S5J has 12-bits ADC with 4 channels. Say Y here, if you want to use it. +config S5J_DMA + bool "DMA" + default n + depends on S5J_HAVE_DMA + config S5J_I2C bool "I2C" default n diff --git a/os/arch/arm/src/s5j/Make.defs b/os/arch/arm/src/s5j/Make.defs index c023f53..89299a4 100644 --- a/os/arch/arm/src/s5j/Make.defs +++ b/os/arch/arm/src/s5j/Make.defs @@ -133,6 +133,13 @@ ifeq ($(CONFIG_S5J_ADC),y) CHIP_CSRCS += s5j_adc.c endif +ifeq ($(CONFIG_S5J_DMA),y) +CHIP_CSRCS += s5j_dma.c +CHIP_CSRCS += s5j_dma_m2m_sb_4B_x256.c +CHIP_CSRCS += s5j_dma_m2p_sb_4B_x256.c +CHIP_CSRCS += s5j_dma_p2m_sb_4B_x256.c +endif + ifeq ($(CONFIG_S5J_I2C),y) CHIP_CSRCS += s5j_i2c.c endif diff --git a/os/arch/arm/src/s5j/s5j_dma.c b/os/arch/arm/src/s5j/s5j_dma.c new file mode 100644 index 0000000..8a03d0a --- /dev/null +++ b/os/arch/arm/src/s5j/s5j_dma.c @@ -0,0 +1,467 @@ +/**************************************************************************** + * + * Copyright 2017 Samsung Electronics All Rights Reserved. + * + * Licensed 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. + * + ****************************************************************************/ + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include +#include +#include +#include +#include + +#include "up_internal.h" +#include "up_arch.h" +#include "cache.h" + +#include "chip.h" +#include "s5j_dma.h" + +/**************************************************************************** + * Private Types + ****************************************************************************/ +int pdma_irq_handler(int irq, FAR void *context, FAR void *arg); + +static struct dma_drvdata dma_dev[] = { + [0] = { + .name = "pdma", + .isr_num = IRQ_PDMA_U1, /* IRQ_PDMA, */ + .isr_handler = pdma_irq_handler, + .base = (void *)S5J_PDMA_BASE, + }, +}; + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +static u32 dma_get_intstatus(struct dma_drvdata *dma) +{ + return getreg32(dma->base + (u32)(DMAC_INTMIS)); +} + +static void dma_enable_ch_interrupt(struct dma_drvdata *dma, + DMA_CHANNEL_NUM ch_num) +{ + volatile u32 inten_reg; + inten_reg = getreg32(dma->base + (u32)(DMAC_INTEN)); + putreg32((inten_reg | (1 << ch_num)), (dma->base + (u32) DMAC_INTEN)); +} + +static void dma_disable_ch_interrupt(struct dma_drvdata *dma, + DMA_CHANNEL_NUM ch_num) +{ + volatile u32 inten_reg; + inten_reg = getreg32(dma->base + (u32)(DMAC_INTEN)); + putreg32((inten_reg & ~(1 << ch_num)), (dma->base + (u32) DMAC_INTEN)); +} + +static u32 dma_clear_ch_interrupt(struct dma_drvdata *dma, + DMA_CHANNEL_NUM ch_num) +{ + + volatile u32 reg = getreg32(dma->base + (u32)(DMAC_INTCLR)); + putreg32((reg | (1 << ch_num)), (dma->base + (u32) DMAC_INTCLR)); + return getreg32(dma->base + (u32)(DMAC_INTCLR)); +} + +static void dma_ch_kill(DMA_CH_CONTEXT *dma_ch) +{ + struct dma_drvdata *dma = dma_ch->dma; + int debug_inst0; + + /* Debug status busy? */ + while ((getreg32(dma->base + DMAC_DBG_STATUS) & 0x1)); + + debug_inst0 = (0 << 24) | ((0x01) << 16) | + (dma_ch->dma_chan_num << 8) | (1 << 0); + + putreg32(debug_inst0, dma->base + (u32) DMAC_DBG_INTST0); + putreg32(0, dma->base + DMAC_DBG_CMD); +} + +int pdma_irq_handler(int irq, FAR void *context, FAR void *arg) +{ + + struct dma_drvdata *dma = (struct dma_drvdata *)arg; + u32 intstatus; + int i; + volatile u32 reg; + + intstatus = dma_get_intstatus(dma); + + for (i = 0; i < dma->max_ch_num; i++) { + if ((intstatus & (1 << i)) && (dma->dma_ch[i].task->callback)) { + dma->dma_ch[i].task->callback(&dma->dma_ch[i], + dma->dma_ch[i].task->arg, 0); + dma_clear_ch_interrupt(dma, i); + dma_disable_ch_interrupt(dma, i); + } + } + + /* Check faults here */ + reg = getreg32(dma->base + (u32)(DMAC_FSRC)); + if (reg) { + for (i = 0; i < dma->max_ch_num; i++) { + if (reg & (1 << i)) { + dmalldbg("\nChannel %d failt FTRD = 0x%x CH_FTR = 0x%x \n", + i, getreg32(dma->base + (u32)(DMAC_FTRD)), + getreg32(dma->base + (u32)(DMAC_CH_FTR(i)))); + + dmalldbg("- CSR 0x%x, CPC 0x%x, SAR 0x%x, DAR 0x%x,\ + CCR 0x%x, LC0 0x%x, LC1 0x%x\n", + getreg32(dma->base + (u32)(DMAC_CH_CSR(i))), + getreg32(dma->base + (u32)(DMAC_CH_CPC(i))), + getreg32(dma->base + (u32)(DMAC_CH_SAR(i))), + getreg32(dma->base + (u32)(DMAC_CH_DAR(i))), + getreg32(dma->base + (u32)(DMAC_CH_CCR(i))), + getreg32(dma->base + (u32)(DMAC_CH_LC0(i))), + getreg32(dma->base + (u32)(DMAC_CH_LC1(i)))); + + dmalldbg("- INTEN 0x%x, RIS 0x%x, INTMIS 0x%x,\ + FSRD 0x%x, FSRC 0x%x, FTRD 0x%x \n", + getreg32(dma->base + (u32)(DMAC_INTEN)), + getreg32(dma->base + (u32)(DMAC_INT_EVENT_RIS)), + getreg32(dma->base + (u32)(DMAC_INTMIS)), + getreg32(dma->base + (u32)(DMAC_FSRD)), + getreg32(dma->base + (u32)(DMAC_FSRC)), + getreg32(dma->base + (u32)(DMAC_FTRD))); + + dma_ch_kill(&dma->dma_ch[i]); + dma_disable_ch_interrupt(dma, i); + if (dma->dma_ch[i].task->callback) { + dma->dma_ch[i].task->callback(&dma->dma_ch[i], + dma->dma_ch[i].task->arg, -1); + } + + } + } + } + return 0; +} + +static struct dma_drvdata *get_dma_drvdata(char *name) +{ + int i; + + i = sizeof(dma_dev) / sizeof(struct dma_drvdata); + + while (i--) + if (strcmp(name, dma_dev[i].name) == 0) { + return &dma_dev[i]; + } + return NULL; +} + +static void dma_set_max_params(struct dma_drvdata *dma) +{ + volatile u32 reg_val; + + reg_val = getreg32(dma->base + (u32)(DMAC_CR0)); + dma->max_ch_num = ((reg_val >> 4) & 0x7) + 1; + + reg_val = getreg32(dma->base + (u32)(DMAC_CRD)); + dma->max_burst_size = ((reg_val) & 0x7) + 1; + + reg_val = getreg32(dma->base + (u32)(DMAC_CRD)); + dma->max_burst_len = ((reg_val >> 20) & 0x1FF) + 1; +} + +static void dma_init(struct dma_drvdata *dma) +{ + int i; + /* INIT SOMETHING HERE before everything starts */ + dma_set_max_params(dma); + irq_attach(dma->isr_num, dma->isr_handler, dma); + up_enable_irq(dma->isr_num); + + for (i = 0; i < 8; i++) { + dma->dma_ch[i].dma = dma; + dma->dma_ch[i].dma_chan_num = i; + dma->dma_ch[i].channel_assigned = 0; + } + + dmavdbg("DMA %s is configured\n", dma->name); +} + +static void dma_ch_exec(DMA_CH_CONTEXT *dma_ch) +{ + struct dma_drvdata *dma = dma_ch->dma; + int secure_status; + int debug_inst0; + + while ((getreg32(dma->base + DMAC_DBG_STATUS) & 0x1)) ; /* Debug status busy? */ + + secure_status = ((getreg32(dma->base + DMAC_CR0) >> 2) & 0x1); + debug_inst0 = (dma_ch->dma_chan_num << 24) | + ((0xA0 | secure_status << 1) << 16) | + (dma_ch->dma_chan_num << 8) | + (0 << 0); + + putreg32(debug_inst0, dma->base + (u32) DMAC_DBG_INTST0); + putreg32((int)(dma_ch->task->microcode), dma->base + DMAC_DBG_INTST1); + putreg32(0, dma->base + DMAC_DBG_CMD); +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ +/**************************************************************************** + * Name: s5j_dma_alloc + * + * Description: + * Allocate first avaliable DMA channel in DMA controller + * + * Input Parameters: + * name - Name of DMA controller + * + * Returned Value: + * allocted DMA channel handler, or NULL; + * + ****************************************************************************/ +DMA_HANDLE s5j_dma_alloc(char *name) +{ + int i; + struct dma_drvdata *dma; + + dma = get_dma_drvdata(name); + + if (dma == NULL) { + return NULL; + } + + for (i = 0; i < dma->max_ch_num; i++) { + if (dma->dma_ch[i].channel_assigned == 0) { + dma->dma_ch[i].channel_assigned = 1; + return (DMA_HANDLE) & dma->dma_ch[i]; + } + } + return NULL; +} + +/**************************************************************************** + * Name: s5j_dmachannel + * + * Description: + * Allocate specified DMA channel in DMA controller + * + * Input Parameters: + * dmacno - DMA channel number + * name - Name of DMA controller + * + * Returned Value: + * allocted DMA channel handler, or NULL; + * + ****************************************************************************/ +DMA_HANDLE s5j_dmachannel(uint8_t dmacno, char *name) +{ + struct dma_drvdata *dma; + + dma = get_dma_drvdata(name); + + if (dma == NULL) { + return NULL; + } + + if (dmacno >= dma->max_ch_num) { + return NULL; + } + + if (dma->dma_ch[dmacno].channel_assigned != 0) { + return NULL; + } + + dma->dma_ch[dmacno].channel_assigned = 1; + return (DMA_HANDLE) & dma->dma_ch[dmacno]; +} + +/**************************************************************************** + * Name: s5j_dmafree + * + * Description: + * Release Allocated DMA channel + * + * Input Parameters: + * handle - DMA handler + * + * Returned Value: + * none + * + ****************************************************************************/ +void s5j_dmafree(DMA_HANDLE handle) +{ + DMA_CH_CONTEXT *ch; + ch = (DMA_CH_CONTEXT *) handle; + ch->channel_assigned = 0; + ch->task = NULL; + return; +} + +/**************************************************************************** + * Name: s5j_dmastart + * + * Description: + * Start DMA operation + * + * Input Parameters: + * handle - DMA handler + * task - DMA task structure with microcode + * + * Returned Value: + * OK + * + ****************************************************************************/ +int s5j_dmastart(DMA_HANDLE handle, dma_task *task) +{ + DMA_CH_CONTEXT *ch; + ch = handle; + + /* Somwhere here run DMA */ + ch->task = task; + + /* FIXME Here I should put task in DMA queue and start DMA */ + if (ch->task->callback) { + dma_enable_ch_interrupt(ch->dma, ch->dma_chan_num); + } + dma_ch_exec(ch); + + return OK; +} + +/**************************************************************************** + * Name: s5j_dmastop + * + * Description: + * Stop DMA operation + * + * Input Parameters: + * handle - DMA handler + * + * Returned Value: + * task structure, which was in prosess. + * + ****************************************************************************/ +dma_task *s5j_dmastop(DMA_HANDLE handle) +{ + DMA_CH_CONTEXT *ch; + dma_task *task; + + ch = handle; + + dma_ch_kill(ch); + dma_disable_ch_interrupt(ch->dma, ch->dma_chan_num); + + task = ch->task; + ch->task = NULL; + + return task; +} + +/**************************************************************************** + * Name: s5j_dmatask_free + * + * Description: + * Free DMA task structure and microcode. + * + * Input Parameters: + * task srtucture to free + * + * Returned Value: + * OK + * + ****************************************************************************/ +int s5j_dmatask_free(dma_task *task) +{ + free(task->microcode); + free(task); + return OK; +} + +/**************************************************************************** + * Name: up_dmainitialize + * + * Description: + * Initialize the DMA subsystem + * + * Returned Value: + * None + * + ****************************************************************************/ + +void weak_function up_dmainitialize(void) +{ + struct dma_drvdata *dma; + dmavdbg("Initialize PDMA 0\n"); + dma = get_dma_drvdata("pdma"); + + if (dma != NULL) { + dma_init(dma); + } else { + dmavdbg("There is NO PDMA 0\n"); + } +} + +/**************************************************************************** + * Name: dma_clean_dcache + * + * Description: + * User application clean cache, used with data before transfer; + * + * Input Parameters: + * start - pointer on first byte to clean + * end - pointer on last byte to clean + * + * Returned Value: + * none + * + ****************************************************************************/ +void dma_clean_dcache(void *start, void *end) +{ + arch_clean_dcache((uintptr_t) start, (uintptr_t) end); +} + +/**************************************************************************** + * Name: dma_invalidate_dcache + * + * Description: + * User application invalidate cache, used with data before transfer; + * + * Input Parameters: + * start - pointer on first byte to clean + * end - pointer on last byte to clean + * + * Returned Value: + * none + * + ****************************************************************************/ +void dma_invalidate_dcache(void *start, void *end) +{ + arch_invalidate_dcache((uintptr_t) start, (uintptr_t) end); +} diff --git a/os/arch/arm/src/s5j/s5j_dma.h b/os/arch/arm/src/s5j/s5j_dma.h new file mode 100644 index 0000000..7cc3e29 --- /dev/null +++ b/os/arch/arm/src/s5j/s5j_dma.h @@ -0,0 +1,332 @@ +/**************************************************************************** + * + * Copyright 2017 Samsung Electronics All Rights Reserved. + * + * Licensed 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_ARM_SRC_S5J_PDMA_H +#define __ARCH_ARM_SRC_S5J_PDMA_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include + +#include +#include +#include + +#include + +#include + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#define DMAC_MAX_CH 8 + +#define DMAC_DSR (0x000) +#define DMAC_DPC (0x004) + +#define DMAC_INTEN (0x020) +#define DMAC_INT_EVENT_RIS (0x024) +#define DMAC_INTMIS (0x028) +#define DMAC_INTCLR (0x02C) +#define DMAC_FSRD (0x030) +#define DMAC_FSRC (0x034) +#define DMAC_FTRD (0x038) + +#define DMAC_CH_FTR(n) 0x040 + 0x04*(n) +#define DMAC_CH_CSR(n) (u32)(0x100 + 0x08*(n)) +#define DMAC_CH_CPC(n) 0x104 + 0x08*(n) +#define DMAC_CH_SAR(n) 0x400 + 0x20*(n) +#define DMAC_CH_DAR(n) 0x404 + 0x20*(n) +#define DMAC_CH_CCR(n) 0x408 + 0x20*(n) +#define DMAC_CH_LC0(n) 0x40C + 0x20*(n) +#define DMAC_CH_LC1(n) 0x410 + 0x20*(n) + +#define DMAC_DBG_STATUS 0xD00 +#define DMAC_DBG_CMD 0xD04 +#define DMAC_DBG_INTST0 0xD08 +#define DMAC_DBG_INTST1 0xD0C + +#define DMAC_CR0 0xE00 +#define DMAC_CR1 0xE04 +#define DMAC_CR2 0xE08 +#define DMAC_CR3 0xE0C +#define DMAC_CR4 0xE10 +#define DMAC_CRD 0xE14 +#define DMAC_WD 0xE80 + +#define DMA_BYTE(inst) (u8)((inst) & 0xFF) +#define DMA_LOOP_MAX 256 + +/* CCR BITFIELDS */ + +#define NOSWAP (0) +#define ENDIAN_SWAP_SIZE_MASK (7 << 28) +#define ENDIAN_SWAP_SIZE(x) ((x & 7) << 28) + +#define AWCACHE0 (1) +#define AWCACHE1 (2) +#define AWCACHE2 (4) +#define DST_CACHE_CTRL_MASK (7 << 25) +#define DST_CACHE_CTRL(x) ((x & 7) << 25) + +#define AWPROT0 (1) +#define AWPROT1 (2) +#define AWPROT2 (4) +#define DST_PROT_CTRL_MASK (7 << 22) +#define DST_PROT_CTRL(x) ((x & 7) << 22) + +/* Burst Len absolute value */ +#define DST_BURST_LEN_MASK (0xf << 18) +#define DST_BURST_LEN(x) (((x - 1) & 0xf) << 18) + +#define BS_1 0 +#define BS_2 1 +#define BS_4 2 +#define BS_8 3 +#define DST_BURST_SIZE_MASK (7 << 15) +#define DST_BURST_SIZE(x) ((x & 7) << 15) + +#define DST_INC (1 << 14) + +#define ARCACHE0 (1) +#define ARCACHE1 (2) +#define ARCACHE2 (4) +#define SRC_CACHE_CTRL_MASK (7 << 11) +#define SRC_CACHE_CTRL(x) ((x & 7) << 11) + +#define ARPROT0 (1) +#define ARPROT1 (2) +#define ARPROT2 (4) +#define SRC_PROT_CTRL_MASK (7 << 8) +#define SRC_PROT_CTRL(x) ((x & 7) << 8) + +/* Burst Len absolute value */ +#define SRC_BURST_LENGTH_MASK (0xf << 4) +#define SRC_BURST_LENGTH(x) (((x - 1) & 0xf) << 4) + +/* Burst Size absolute value */ +#define SRC_BURST_SIZE_MASK (7 << 1) +#define SRC_BURST_SIZE(x) ((x & 7) << 1) + +#define SRC_INC (1 << 0) + +#define LC0 0x0 +#define LC0_END 0x10 +#define LC1 0x2 +#define LC1_END 0x14 + +#define CCR_M2M_DFLT (ENDIAN_SWAP_SIZE(NOSWAP) | \ + DST_CACHE_CTRL(AWCACHE1) | \ + DST_INC | \ + SRC_CACHE_CTRL(ARCACHE1) | \ + SRC_INC | \ + SRC_PROT_CTRL(2) | \ + DST_PROT_CTRL(2)) + +#define CCR_P2P_DFLT (ENDIAN_SWAP_SIZE(NOSWAP) | \ + DST_CACHE_CTRL(AWCACHE1) | \ + SRC_CACHE_CTRL(ARCACHE1)) + +#define CCR_P2M_DFLT (ENDIAN_SWAP_SIZE(NOSWAP) | \ + DST_CACHE_CTRL(AWCACHE1) | \ + DST_INC | \ + SRC_CACHE_CTRL(ARCACHE1) | \ + SRC_PROT_CTRL(2) | \ + DST_PROT_CTRL(2)) + +#define CCR_M2P_DFLT (ENDIAN_SWAP_SIZE(NOSWAP) | \ + DST_CACHE_CTRL(AWCACHE1) | \ + SRC_CACHE_CTRL(ARCACHE1) | \ + SRC_INC | \ + SRC_PROT_CTRL(2) | \ + DST_PROT_CTRL(2)) + +#define CCR_M2MP_DFLT (ENDIAN_SWAP_SIZE(NOSWAP) | \ + DST_CACHE_CTRL(AWCACHE1) | \ + SRC_CACHE_CTRL(ARCACHE1) | \ + SRC_PROT_CTRL(2) | \ + DST_PROT_CTRL(2)) + +#define DMA_MC_4B_SET(a, b) (*(unsigned int *)(a) = (unsigned int)(b)) +#define DMA_MC_1B_SET(a, b) (*(char *)(a) = (char)(b)) +#define DMA_MC_EV_SET(a, b) (*(char *)(a) = (char)(b << 3)) + + +/************************************************************************************ + * Public Types + ************************************************************************************/ + +typedef enum { + DMA_SAR = 0, + DMA_CCR, + DMA_DAR, +} DMA_INST_REG; + +typedef enum { + DMA_LC0 = 0, + DMA_LC1, +} DMA_LC; + +typedef enum { + DMA_CH0 = 0x0, + DMA_CH1, + DMA_CH2, + DMA_CH3, + DMA_CH4, + DMA_CH5, + DMA_CH6, + DMA_CH7 +} DMA_CHANNEL_NUM; + + +typedef struct dma_drvdata dma_drvdata; + +typedef struct { + dma_drvdata *dma; + DMA_CHANNEL_NUM dma_chan_num; + u8 channel_assigned; + + dma_task *task; + +} DMA_CH_CONTEXT; + +struct dma_drvdata { + char *name; + void *base; + int isr_num; + xcpt_t isr_handler; + + /* struct dma_device *dev; */ + + /* Add private data structures if it is needed */ + u32 max_ch_num; + u32 max_burst_len; + u32 max_burst_size; /* data_size */ + /* bool dma_initialized; */ + DMA_CH_CONTEXT dma_ch[DMAC_MAX_CH]; +}; + +typedef enum { + m2m, + m2p, + p2m, + p2p, +} mc_tmplt; + +/************************************************************************************ + * Inline Functions + ************************************************************************************/ + +/* Microcode functions */ +inline static int DMA_Encode_DMAMOV(char *base, void **reg_addr, DMA_INST_REG rd) +{ + rd &= 0x07; + + base[0] = 0xBC; + base[1] = rd; + base[2] = 0xd; + base[3] = 0xe; + base[4] = 0xa; + base[5] = 0xd; + + *reg_addr = base + 2; + return 6; +} + +inline static int DMA_Encode_DMALP(char *base, DMA_LC lc, void **iter) +{ + + base[0] = 0x20 | lc; + base[1] = 0xe; + + *iter = base + 1; + return 2; +} + +inline static int DMA_Encode_DMALPEND(char *base, u8 CTRL, char backwards_jump) +{ + base[0] = 0x28 | CTRL; + base[1] = backwards_jump; + return 2; +} + +inline static int DMA_Encode_DMALD(char *base, u8 CTRL) +{ + base[0] = 0x04 | CTRL; + return 1; +} + +inline static int DMA_Encode_DMALDP(char *base, u8 CTRL, DMA_REQ_MAP periph) +{ + base[0] = 0x25 | CTRL; + base[1] = periph << 3; + return 2; +} + +inline static int DMA_Encode_DMAST(char *base, u8 CTRL) +{ + base[0] = 0x08 | CTRL; + return 1; +} + +inline static int DMA_Encode_DMASTP(char *base, u8 CTRL, DMA_REQ_MAP periph) +{ + base[0] = 0x29 | CTRL; + base[1] = periph << 3; + return 2; +} + +inline static int DMA_Encode_DMAWFP(char *base, u8 CTRL, DMA_REQ_MAP periph) +{ + base[0] = 0x30 | CTRL; + base[1] = periph << 3; + return 2; +} + +inline static int DMA_Encode_DMASEV(char *base, void **event_num) +{ + base[0] = 0x34; + base[1] = 0xe; + *event_num = base + 1; + return 2; +} + +inline static int DMA_Encode_DMAEND(char *base) +{ + base[0] = 0x00; + return 1; +} + +inline static int DMA_Encode_DMAFLUSHP(char *base, u8 periph) +{ + base[0] = 0x35; + base[1] = periph << 3; + return 2; +} + +inline static int DMA_Encode_DMAWMB(char *base) +{ + base[0] = 0x13; + return 1; +} + +#endif diff --git a/os/arch/arm/src/s5j/s5j_dma_m2m_sb_4B_x256.c b/os/arch/arm/src/s5j/s5j_dma_m2m_sb_4B_x256.c new file mode 100644 index 0000000..45388e7 --- /dev/null +++ b/os/arch/arm/src/s5j/s5j_dma_m2m_sb_4B_x256.c @@ -0,0 +1,177 @@ +/**************************************************************************** + * + * Copyright 2017 Samsung Electronics All Rights Reserved. + * + * Licensed 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 +#include +#include +#include +#include + +#include + +#include +#include +#include +#include +#include + +#include "up_internal.h" +#include "up_arch.h" +#include "cache.h" + +#include "chip.h" +#include "s5j_dma.h" + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +typedef struct d_dma_task_priv { + struct dma_task task; + int mc_array_size; + int mc_size; + int chflags; + void *SAR; + void *DAR; + void *CCR; + void *LOOP1; + void *LOOP0; + void *EVENT_CH; +} t_dma_task_priv; + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: s5j_dma_priv_setup + * + * Description: + * Private method to prepare mocrocode for DMA M2M operation. + * + * Input Parameters + * handle - DMA channel handle structure; + * task - DMA task structure with microcode to execute + * + * Returned Value: + * OK; + * + ****************************************************************************/ +static int s5j_dma_priv_setup(DMA_HANDLE handle, dma_task *task) +{ + t_dma_task_priv *priv_task = (t_dma_task_priv *) task; + DMA_CH_CONTEXT *ch; + ch = handle; + + priv_task->chflags = CCR_M2M_DFLT | + SRC_BURST_SIZE(BS_4) | + DST_BURST_SIZE(BS_4); + + DMA_MC_4B_SET(priv_task->SAR, task->src); + DMA_MC_4B_SET(priv_task->DAR, task->dst); + DMA_MC_4B_SET(priv_task->CCR, priv_task->chflags); + + DMA_MC_1B_SET(priv_task->LOOP1, (((task->size / 4 - 1) >> 8) & 0xFF)); + DMA_MC_1B_SET(priv_task->LOOP0, (task->size / 4 - 1) & 0xFF); + + DMA_MC_EV_SET(priv_task->EVENT_CH, ch->dma_chan_num); + + arch_clean_dcache((uintptr_t)task->microcode, + (uintptr_t)(task->microcode + priv_task->mc_size)); + + return OK; +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ +/**************************************************************************** + * Name: dma_task_m2m_sb_4B_x256_alloc + * + * Description: + * This function allocated task structure for M2M DMA transfers microcode. + * It prepares microcode and place holders for loop counters and addresses. + * + * Input Parameters + * None + * + * Returned Value: + * Pointer on dma_task structure + * + ****************************************************************************/ +dma_task *dma_task_m2m_sb_4B_x256_alloc(void) +{ + dma_task *task; + t_dma_task_priv *priv_task; + void *mc_base; + void *loop_offs0; + void *loop_offs1; + + task = zalloc(sizeof(t_dma_task_priv)); + if (task == NULL) { + dmadbg("ERROR: Failed to allocate microcode memory\n"); + return NULL; + } + + task->microcode = zalloc(32); + if (task->microcode == NULL) { + dmadbg("ERROR: Failed to allocate microcode memory\n"); + free(task); + return NULL; + } + + priv_task = (t_dma_task_priv *) task; + priv_task->mc_array_size = 32; + + mc_base = task->microcode; + + mc_base += DMA_Encode_DMAMOV(mc_base, &(priv_task->SAR), DMA_SAR); + mc_base += DMA_Encode_DMAMOV(mc_base, &(priv_task->DAR), DMA_DAR); + mc_base += DMA_Encode_DMAMOV(mc_base, &(priv_task->CCR), DMA_CCR); + + mc_base += DMA_Encode_DMALP(mc_base, LC1, &(priv_task->LOOP1)); + loop_offs1 = mc_base; + mc_base += DMA_Encode_DMALP(mc_base, LC0, &(priv_task->LOOP0)); + loop_offs0 = mc_base; + + /* 0 - LD & ST does not depend on burst L/S settings */ + mc_base += DMA_Encode_DMALD(mc_base, 0); + mc_base += DMA_Encode_DMAST(mc_base, 0); + + mc_base += DMA_Encode_DMALPEND(mc_base, LC0_END, mc_base - loop_offs0); + mc_base += DMA_Encode_DMALPEND(mc_base, LC1_END, mc_base - loop_offs1); + mc_base += DMA_Encode_DMAWMB(mc_base); + mc_base += DMA_Encode_DMASEV(mc_base, &(priv_task->EVENT_CH)); + mc_base += DMA_Encode_DMAEND(mc_base); + + priv_task->mc_size = mc_base - task->microcode; + + task->setup = s5j_dma_priv_setup; + return task; +} diff --git a/os/arch/arm/src/s5j/s5j_dma_m2p_sb_4B_x256.c b/os/arch/arm/src/s5j/s5j_dma_m2p_sb_4B_x256.c new file mode 100644 index 0000000..9574230 --- /dev/null +++ b/os/arch/arm/src/s5j/s5j_dma_m2p_sb_4B_x256.c @@ -0,0 +1,194 @@ +/**************************************************************************** + * + * Copyright 2017 Samsung Electronics All Rights Reserved. + * + * Licensed 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 +#include +#include +#include +#include + +#include + +#include +#include +#include +#include +#include + +#include "up_internal.h" +#include "up_arch.h" +#include "cache.h" + +#include "chip.h" +#include "s5j_dma.h" + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +typedef struct d_dma_task_priv { + struct dma_task task; + int mc_array_size; + int mc_size; + int chflags; + void *SAR; + void *DAR; + void *CCR; + void *LOOP1; + void *LOOP0; + void *EVENT_CH; +} t_dma_task_priv; + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: s5j_dma_priv_setup + * + * Description: + * Private method to prepare mocrocode for DMA M2P operation. + * + * Input Parameters + * handle - DMA channel handle structure; + * task - DMA task structure with microcode to execute + * + * Returned Value: + * OK; + * + ****************************************************************************/ +static int s5j_dma_priv_setup(DMA_HANDLE handle, dma_task *task) +{ + t_dma_task_priv *priv_task = (t_dma_task_priv *) task; + DMA_CH_CONTEXT *ch; + ch = handle; + + priv_task->chflags = CCR_M2P_DFLT | + SRC_BURST_SIZE(BS_1) | + DST_BURST_SIZE(BS_4); + + DMA_MC_4B_SET(priv_task->SAR, task->src); + DMA_MC_4B_SET(priv_task->DAR, task->dst); + DMA_MC_4B_SET(priv_task->CCR, priv_task->chflags); + DMA_MC_1B_SET(priv_task->LOOP1, (((task->size / 4 - 1) >> 8) & 0xFF)); + DMA_MC_1B_SET(priv_task->LOOP0, (task->size / 4 - 1) & 0xFF); + + DMA_MC_EV_SET(priv_task->EVENT_CH, ch->dma_chan_num); + + arch_clean_dcache((uintptr_t)task->microcode, + (uintptr_t)(task->microcode + priv_task->mc_size)); + + return OK; +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ +/**************************************************************************** + * Name: dma_task_m2p_sb_4B_x256_alloc + * + * Description: + * This function allocated task structure for M2P DMA transfers microcode. + * It prepares microcode and place holders for loop counters and addresses. + * + * Input Parameters + * d_ph_ch - destination peripheral DMA shannel number + * + * Returned Value: + * Pointer on dma_task structure + * + ****************************************************************************/ +dma_task *dma_task_m2p_sb_4B_x256_alloc(DMA_REQ_MAP d_ph_ch) +{ + dma_task *task; + t_dma_task_priv *priv_task; + void *mc_base; + void *loop_offs0; + void *loop_offs1; + + task = zalloc(sizeof(t_dma_task_priv)); + if (task == NULL) { + dmadbg("ERROR: Failed to allocate microcode memory\n"); + return NULL; + } + + task->microcode = zalloc(64); + if (task->microcode == NULL) { + dmadbg("ERROR: Failed to allocate microcode memory\n"); + free(task); + return NULL; + } + + priv_task = (t_dma_task_priv *) task; + priv_task->mc_array_size = 64; + + mc_base = task->microcode; + + mc_base += DMA_Encode_DMAMOV(mc_base, &(priv_task->SAR), DMA_SAR); + mc_base += DMA_Encode_DMAMOV(mc_base, &(priv_task->DAR), DMA_DAR); + mc_base += DMA_Encode_DMAMOV(mc_base, &(priv_task->CCR), DMA_CCR); + + mc_base += DMA_Encode_DMAFLUSHP(mc_base, d_ph_ch); + + /*loop start */ + mc_base += DMA_Encode_DMALP(mc_base, LC1, &(priv_task->LOOP1)); + loop_offs1 = mc_base; + mc_base += DMA_Encode_DMALP(mc_base, LC0, &(priv_task->LOOP0)); + loop_offs0 = mc_base; + + /* 0 - wait for either Sinnle/Busrs requests */ + mc_base += DMA_Encode_DMAWFP(mc_base, 1, d_ph_ch); + + /* 0 - LD does not depend on burst L/S settings */ + mc_base += DMA_Encode_DMALD(mc_base, 0); + mc_base += DMA_Encode_DMALD(mc_base, 0); + mc_base += DMA_Encode_DMALD(mc_base, 0); + mc_base += DMA_Encode_DMALD(mc_base, 0); + + /* 0 - STP singles / NOP burst */ + mc_base += DMA_Encode_DMASTP(mc_base, 0, d_ph_ch); + + /* 2 - NOP singles / STP burst */ + mc_base += DMA_Encode_DMASTP(mc_base, 2, d_ph_ch); + + mc_base += DMA_Encode_DMAFLUSHP(mc_base, d_ph_ch); + + /*loop end */ + mc_base += DMA_Encode_DMALPEND(mc_base, LC0_END, mc_base - loop_offs0); + mc_base += DMA_Encode_DMALPEND(mc_base, LC1_END, mc_base - loop_offs1); + + mc_base += DMA_Encode_DMAWMB(mc_base); + mc_base += DMA_Encode_DMASEV(mc_base, &(priv_task->EVENT_CH)); + mc_base += DMA_Encode_DMAEND(mc_base); + + priv_task->mc_size = mc_base - task->microcode; + + task->setup = s5j_dma_priv_setup; + return task; +} diff --git a/os/arch/arm/src/s5j/s5j_dma_p2m_sb_4B_x256.c b/os/arch/arm/src/s5j/s5j_dma_p2m_sb_4B_x256.c new file mode 100644 index 0000000..b4dede4 --- /dev/null +++ b/os/arch/arm/src/s5j/s5j_dma_p2m_sb_4B_x256.c @@ -0,0 +1,193 @@ +/**************************************************************************** + * + * Copyright 2017 Samsung Electronics All Rights Reserved. + * + * Licensed 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 +#include +#include +#include +#include + +#include + +#include +#include +#include +#include +#include + +#include "up_internal.h" +#include "up_arch.h" +#include "cache.h" + +#include "chip.h" +#include "s5j_dma.h" + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +typedef struct d_dma_task_priv { + struct dma_task task; + int mc_array_size; + int mc_size; + int chflags; + void *SAR; + void *DAR; + void *CCR; + void *LOOP1; + void *LOOP0; + void *EVENT_CH; +} t_dma_task_priv; + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: s5j_dma_priv_setup + * + * Description: + * Private method to prepare mocrocode for DMA P2M operation. + * + * Input Parameters + * handle - DMA channel handle structure; + * task - DMA task structure with microcode to execute + * + * Returned Value: + * OK; + * + ****************************************************************************/ +static int s5j_dma_priv_setup(DMA_HANDLE handle, dma_task *task) +{ + t_dma_task_priv *priv_task = (t_dma_task_priv *) task; + DMA_CH_CONTEXT *ch; + ch = handle; + + priv_task->chflags = CCR_P2M_DFLT | + SRC_BURST_SIZE(BS_4) | + DST_BURST_SIZE(BS_1); + + DMA_MC_4B_SET(priv_task->SAR, task->src); + DMA_MC_4B_SET(priv_task->DAR, task->dst); + DMA_MC_4B_SET(priv_task->CCR, priv_task->chflags); + DMA_MC_1B_SET(priv_task->LOOP1, (((task->size / 4 - 1) >> 8) & 0xFF)); + DMA_MC_1B_SET(priv_task->LOOP0, (task->size / 4 - 1) & 0xFF); + + DMA_MC_EV_SET(priv_task->EVENT_CH, ch->dma_chan_num); + + arch_clean_dcache((uintptr_t)task->microcode, + (uintptr_t)(task->microcode + priv_task->mc_size)); + + return OK; +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ +/**************************************************************************** + * Name: dma_task_p2m_sb_4B_x256_alloc + * + * Description: + * This function allocated task structure for M2P DMA transfers microcode. + * It prepares microcode and place holders for loop counters and addresses. + * + * Input Parameters + * s_ph_ch - source peripheral DMA shannel number + * + * Returned Value: + * Pointer on dma_task structure + * + ****************************************************************************/ +dma_task *dma_task_p2m_sb_4B_x256_alloc(DMA_REQ_MAP s_ph_ch) +{ + dma_task *task; + t_dma_task_priv *priv_task; + void *mc_base; + void *loop_offs0; + void *loop_offs1; + + task = zalloc(sizeof(t_dma_task_priv)); + if (task == NULL) { + dmadbg("ERROR: Failed to allocate microcode memory\n"); + return NULL; + } + + task->microcode = zalloc(64); + if (task->microcode == NULL) { + dmadbg("ERROR: Failed to allocate microcode memory\n"); + free(task); + return NULL; + } + + priv_task = (t_dma_task_priv *) task; + priv_task->mc_array_size = 64; + + mc_base = task->microcode; + + mc_base += DMA_Encode_DMAMOV(mc_base, &(priv_task->SAR), DMA_SAR); + mc_base += DMA_Encode_DMAMOV(mc_base, &(priv_task->DAR), DMA_DAR); + mc_base += DMA_Encode_DMAMOV(mc_base, &(priv_task->CCR), DMA_CCR); + + mc_base += DMA_Encode_DMAFLUSHP(mc_base, s_ph_ch); + + /*loop start */ + mc_base += DMA_Encode_DMALP(mc_base, LC1, &(priv_task->LOOP1)); + loop_offs1 = mc_base; + mc_base += DMA_Encode_DMALP(mc_base, LC0, &(priv_task->LOOP0)); + loop_offs0 = mc_base; + + /* 0 - wait for either Single/Busrst requests */ + mc_base += DMA_Encode_DMAWFP(mc_base, 1, s_ph_ch); + + /* 0 - LDP singles / NOP burst */ + mc_base += DMA_Encode_DMALDP(mc_base, 0, s_ph_ch); + + /* 2 - NOP singles / STP burst */ + mc_base += DMA_Encode_DMALDP(mc_base, 2, s_ph_ch); + + /* 0 - ST does not depend on burst L/S settings */ + mc_base += DMA_Encode_DMAST(mc_base, 0); + mc_base += DMA_Encode_DMAST(mc_base, 0); + mc_base += DMA_Encode_DMAST(mc_base, 0); + mc_base += DMA_Encode_DMAST(mc_base, 0); + + mc_base += DMA_Encode_DMAFLUSHP(mc_base, s_ph_ch); + + /*loop end */ + mc_base += DMA_Encode_DMALPEND(mc_base, LC0_END, mc_base - loop_offs0); + mc_base += DMA_Encode_DMALPEND(mc_base, LC1_END, mc_base - loop_offs1); + + mc_base += DMA_Encode_DMASEV(mc_base, &(priv_task->EVENT_CH)); + mc_base += DMA_Encode_DMAEND(mc_base); + + priv_task->mc_size = mc_base - task->microcode; + + task->setup = s5j_dma_priv_setup; + return task; +} diff --git a/os/include/debug.h b/os/include/debug.h index a374bb0..5121468 100644 --- a/os/include/debug.h +++ b/os/include/debug.h @@ -630,7 +630,6 @@ Once LOGM is approved, each module should have its own index #define ttdbg(format, ...) #endif - #else /* CONFIG_CPP_HAVE_VARARGS */ /* Variadic macros NOT supported */ -- 2.7.4