SAML21: Completes first rought cut of DMAC driver

This commit is contained in:
Gregory Nutt
2015-06-14 13:29:59 -06:00
parent e6df02fc17
commit d9e90fc1ac
3 changed files with 239 additions and 93 deletions
+6 -6
View File
@@ -158,19 +158,19 @@
#define DMAC_QOSCTRL_WRBQOS_SHIFT (0) /* Bits 0-1: Write back quality of service */
#define DMAC_QOSCTRL_WRBQOS_MASK (3 << DMAC_QOSCTRL_WRBQOS_SHIFT)
# define DMAC_QOSCTRL_WRBQOS_DISABLE (0 << DMAC_QOSCTRL_WRBQOS_SHIFT) /* Background */
# define DMAC_QOSCTRL_WRBQOS_LOW (1 << DMAC_QOSCTRL_WRBQOS_SHIFT) /* Sensitve bandwidth */
# define DMAC_QOSCTRL_WRBQOS_LOW (1 << DMAC_QOSCTRL_WRBQOS_SHIFT) /* Sensitive bandwidth */
# define DMAC_QOSCTRL_WRBQOS_MEDIUM (2 << DMAC_QOSCTRL_WRBQOS_SHIFT) /* Sensitive latency */
# define DMAC_QOSCTRL_WRBQOS_HIGH (3 << DMAC_QOSCTRL_WRBQOS_SHIFT) /* Critical latency */
#define DMAC_QOSCTRL_FQOS_SHIFT (2) /* Bits 2-3: Fetch quality of service */
#define DMAC_QOSCTRL_FQOS_MASK (3 << DMAC_QOSCTRL_FQOS_SHIFT)
# define DMAC_QOSCTRL_FQOS_DISABLE (0 << DMAC_QOSCTRL_FQOS_SHIFT) /* Background */
# define DMAC_QOSCTRL_FQOS_LOW (1 << DMAC_QOSCTRL_FQOS_SHIFT) /* Sensitve bandwidth */
# define DMAC_QOSCTRL_FQOS_LOW (1 << DMAC_QOSCTRL_FQOS_SHIFT) /* Sensitive bandwidth */
# define DMAC_QOSCTRL_FQOS_MEDIUM (2 << DMAC_QOSCTRL_FQOS_SHIFT) /* Sensitive latency */
# define DMAC_QOSCTRL_FQOS_HIGH (3 << DMAC_QOSCTRL_FQOS_SHIFT) /* Critical latency */
#define DMAC_QOSCTRL_DQOS_SHIFT (4) /* Bits 4-5: Data transfer quality of service */
#define DMAC_QOSCTRL_DQOS_MASK (3 << DMAC_QOSCTRL_DQOS_SHIFT)
# define DMAC_QOSCTRL_DQOS_DISABLE (0 << DMAC_QOSCTRL_DQOS_SHIFT) /* Background */
# define DMAC_QOSCTRL_DQOS_LOW (1 << DMAC_QOSCTRL_DQOS_SHIFT) /* Sensitve bandwidth */
# define DMAC_QOSCTRL_DQOS_LOW (1 << DMAC_QOSCTRL_DQOS_SHIFT) /* Sensitive bandwidth */
# define DMAC_QOSCTRL_DQOS_MEDIUM (2 << DMAC_QOSCTRL_DQOS_SHIFT) /* Sensitive latency */
# define DMAC_QOSCTRL_DQOS_HIGH (3 << DMAC_QOSCTRL_DQOS_SHIFT) /* Critical latency */
@@ -208,9 +208,9 @@
/* Active Channels and Levels Register */
#define DMAC_ACTIVE_LVLEX0 (1 << 0) /* Bit 0: Level 0 channel trigger requrest executing */
#define DMAC_ACTIVE_LVLEX1 (1 << 1) /* Bit 1: Level 1 channel trigger requrest executing */
#define DMAC_ACTIVE_LVLEX2 (1 << 2) /* Bit 2: Level 2 channel trigger requrest executing */
#define DMAC_ACTIVE_LVLEX0 (1 << 0) /* Bit 0: Level 0 channel trigger request executing */
#define DMAC_ACTIVE_LVLEX1 (1 << 1) /* Bit 1: Level 1 channel trigger request executing */
#define DMAC_ACTIVE_LVLEX2 (1 << 2) /* Bit 2: Level 2 channel trigger request executing */
#define DMAC_ACTIVE_ID_SHIFT (8) /* Bits 8-11: Active channel ID */
#define DMAC_ACTIVE_ID_MASK (15 << DMAC_ACTIVE_ID_SHIFT)
#define DMAC_ACTIVE_ABUSY (1 << 15) /* Bit 15: Active channel busy */
+219 -79
View File
@@ -83,13 +83,23 @@
/****************************************************************************
* Private Types
****************************************************************************/
/* The direction of the transfer */
enum sam_dmadir_e
{
DMADIR_UNKOWN = 0, /* We don't know the direction of the
* transfer yet */
DMADIR_TX, /* Transmit: Memory to peripheral */
DMADIR_RX /* Receive: Peripheral to memory */
};
/* This structure describes one DMA channel */
struct sam_dmach_s
{
uint8_t dc_chan; /* DMA channel number (0-6) */
bool dc_inuse; /* TRUE: The DMA channel is in use */
uint8_t dc_chan; /* DMA channel number (0-15) */
uint8_t dc_dir; /* See enum sam_dmadir_e */
uint32_t dc_flags; /* DMA channel flags */
dma_callback_t dc_callback; /* Callback invoked when the DMA completes */
void *dc_arg; /* Argument passed to callback function */
@@ -116,12 +126,11 @@ static struct dma_desc_s *sam_append_desc(struct sam_dmach_s *dmach,
uint32_t srcaddr,uint32_t dstaddr);
static void sam_freelinklist(struct sam_dmach_s *dmach);
static size_t sam_maxtransfer(struct sam_dmach_s *dmach);
static uint16_t sam_bytes2beats(struct sam_dmach_s *dmach, size_t nbytes);
static int sam_txbuffer(struct sam_dmach_s *dmach, uint32_t paddr,
uint32_t maddr, size_t nbytes);
static int sam_rxbuffer(struct sam_dmach_s *dmach, uint32_t paddr,
uint32_t maddr, size_t nbytes);
static int sam_single(struct sam_dmach_s *dmach);
static int sam_multiple(struct sam_dmach_s *dmach);
/****************************************************************************
* Private Data
@@ -259,6 +268,7 @@ static void sam_dmaterminate(struct sam_dmach_s *dmach, int result)
dmach->dc_callback = NULL;
dmach->dc_arg = NULL;
dmach->dc_dir = DMADIR_UNKOWN;
}
/****************************************************************************
@@ -310,7 +320,7 @@ static int sam_dmainterrupt(int irq, void *context)
else if ((intpend & DMAC_INTPEND_SUSP) != 0)
{
#warning Missing logic
/* REVISIT: Do we want to do anything here? */
}
}
@@ -538,8 +548,43 @@ static void sam_freelinklist(struct sam_dmach_s *dmach)
static size_t sam_maxtransfer(struct sam_dmach_s *dmach)
{
#warning Missing logic
return 0;
int beatsize;
/* The number of bytes per beat is 2**BEATSIZE */
beatsize = (dmach->dc_flags & DMACH_FLAG_BEATSIZE_MASK) >>
LPSRAM_BTCTRL_STEPSIZE_SHIFT;
/* Maximum beats is UINT16_MAX */
return (size_t)UINT16_MAX << beatsize;
}
/****************************************************************************
* Name: sam_bytes2beats
*
* Description:
* Convert a count of bytes into a count of beats
*
****************************************************************************/
static uint16_t sam_bytes2beats(struct sam_dmach_s *dmach, size_t nbytes)
{
size_t mask;
int beatsize;
size_t nbeats;
/* The number of bytes per beat is 2**BEATSIZE */
beatsize = (dmach->dc_flags & DMACH_FLAG_BEATSIZE_MASK) >>
LPSRAM_BTCTRL_STEPSIZE_SHIFT;
/* The number of beats is then the ceiling of the division */
mask = (1 < beatsize) - 1;
nbeats = (nbytes + mask) >> beatsize;
DEBUGASSERT(nbeats <= UINT16_MAX);
return (uint16_t)nbeats;
}
/****************************************************************************
@@ -557,12 +602,55 @@ static int sam_txbuffer(struct sam_dmach_s *dmach, uint32_t paddr,
{
uint16_t btctrl;
uint16_t btcnt;
uint16_t tmp;
/* Set up the Block Transfer Control Register configuration */
#warning Missing logic
DEBUGASSERT(dmac->dc_dir == DMADIR_UNKOWN || dmac->dc_dir == DMADIR_TX);
/* Set up the Block Transfer Control Register configuration:
*
* This are fixed register selections:
*
* LPSRAM_BTCTRL_VALID - Descriptor is valid
* LPSRAM_BTCTRL_EVOSEL_DISABLE - No event output
* LPSRAM_BTCTRL_BLOCKACT_INT - Disable channel and generate interrupt
* when the last block transfer completes.
*
* Other settings come from the channel configuration:
*
* LPSRAM_BTCTRL_BEATSIZE - Determined by DMACH_FLAG_BEATSIZE
* LPSRAM_BTCTRL_SRCINC - Determined by DMACH_FLAG_MEMINCREMENT
* LPSRAM_BTCTRL_DSTINC - Determined by DMACH_FLAG_PERIPHINCREMENT
* LPSRAM_BTCTRL_STEPSEL - Determined by DMACH_FLAG_STEPSEL
* LPSRAM_BTCTRL_STEPSIZE - Determined by DMACH_FLAG_STEPSIZE
*/
btctrl = LPSRAM_BTCTRL_VALID | LPSRAM_BTCTRL_EVOSEL_DISABLE |
LPSRAM_BTCTRL_BLOCKACT_INT;
tmp = (dmach->dc_flags & DMACH_FLAG_BEATSIZE_MASK) >> DMACH_FLAG_BEATSIZE_SHIFT;
btctrl |= tmp << LPSRAM_BTCTRL_BEATSIZE_SHIFT;
if ((dmach->dc_flags & DMACH_FLAG_MEMINCREMENT) != 0)
{
btctrl |= LPSRAM_BTCTRL_SRCINC;
}
if ((dmach->dc_flags & DMACH_FLAG_PERIPHINCREMENT) != 0)
{
btctrl |= LPSRAM_BTCTRL_DSTINC;
}
if ((dmach->dc_flags & DMACH_FLAG_STEPSEL) == DMACH_FLAG_STEPSEL_PERIPH)
{
btctrl |= LPSRAM_BTCTRL_STEPSEL;
}
tmp = (dmach->dc_flags & DMACH_FLAG_STEPSIZE_MASK) >> LPSRAM_BTCTRL_STEPSIZE_SHIFT;
btctrl |= tmp << LPSRAM_BTCTRL_STEPSIZE_SHIFT;
/* Set up the Block Transfer Count Register configuration */
#warning Missing logic
btcnt = sam_bytes2beats(dmach, nbytes);
/* Add the new link list entry */
@@ -571,6 +659,7 @@ static int sam_txbuffer(struct sam_dmach_s *dmach, uint32_t paddr,
return -ENOMEM;
}
dmach->dc_dir = DMADIR_TX;
return OK;
}
@@ -589,12 +678,55 @@ static int sam_rxbuffer(struct sam_dmach_s *dmach, uint32_t paddr,
{
uint16_t btctrl;
uint16_t btcnt;
uint16_t tmp;
/* Set up the Block Transfer Control Register configuration */
#warning Missing logic
DEBUGASSERT(dmac->dc_dir == DMADIR_UNKOWN || dmac->dc_dir == DMADIR_RX);
/* Set up the Block Transfer Control Register configuration:
*
* This are fixed register selections:
*
* LPSRAM_BTCTRL_VALID - Descriptor is valid
* LPSRAM_BTCTRL_EVOSEL_DISABLE - No event output
* LPSRAM_BTCTRL_BLOCKACT_INT - Disable channel and generate interrupt
* when the last block transfer completes.
*
* Other settings come from the channel configuration:
*
* LPSRAM_BTCTRL_BEATSIZE - Determined by DMACH_FLAG_BEATSIZE
* LPSRAM_BTCTRL_SRCINC - Determined by DMACH_FLAG_PERIPHINCREMENT
* LPSRAM_BTCTRL_DSTINC - Determined by DMACH_FLAG_MEMINCREMENT
* LPSRAM_BTCTRL_STEPSEL - Determined by DMACH_FLAG_STEPSEL
* LPSRAM_BTCTRL_STEPSIZE - Determined by DMACH_FLAG_STEPSIZE
*/
btctrl = LPSRAM_BTCTRL_VALID | LPSRAM_BTCTRL_EVOSEL_DISABLE |
LPSRAM_BTCTRL_BLOCKACT_INT;
tmp = (dmach->dc_flags & DMACH_FLAG_BEATSIZE_MASK) >> DMACH_FLAG_BEATSIZE_SHIFT;
btctrl |= tmp << LPSRAM_BTCTRL_BEATSIZE_SHIFT;
if ((dmach->dc_flags & DMACH_FLAG_PERIPHINCREMENT) != 0)
{
btctrl |= LPSRAM_BTCTRL_SRCINC;
}
if ((dmach->dc_flags & DMACH_FLAG_MEMINCREMENT) != 0)
{
btctrl |= LPSRAM_BTCTRL_DSTINC;
}
if ((dmach->dc_flags & DMACH_FLAG_STEPSEL) == DMACH_FLAG_STEPSEL_MEM)
{
btctrl |= LPSRAM_BTCTRL_STEPSEL;
}
tmp = (dmach->dc_flags & DMACH_FLAG_STEPSIZE_MASK) >> LPSRAM_BTCTRL_STEPSIZE_SHIFT;
btctrl |= tmp << LPSRAM_BTCTRL_STEPSIZE_SHIFT;
/* Set up the Block Transfer Count Register configuration */
#warning Missing logic
btcnt = sam_bytes2beats(dmach, nbytes);
/* Add the new link list entry */
@@ -603,67 +735,10 @@ static int sam_rxbuffer(struct sam_dmach_s *dmach, uint32_t paddr,
return -ENOMEM;
}
dmach->dc_dir = DMADIR_RX;
return OK;
}
/****************************************************************************
* Name: sam_single
*
* Description:
* Start a single buffer DMA.
*
****************************************************************************/
static int sam_single(struct sam_dmach_s *dmach)
{
struct dma_desc_s *head = &g_base_desc[dmach->dc_chan];
/* Clear any pending interrupts from any previous DMAC transfer. */
#warning Missing logic
/* Set up the DMA */
#warning Missing logic
DEBUGASSERT(head->srcaddr != 0);
/* Enable the channel */
#warning Missing logic
/* Enable DMA interrupts */
#warning Missing logic
return OK;
}
/****************************************************************************
* Name: sam_multiple
*
* Description:
* Start a multiple buffer DMA.
*
****************************************************************************/
#if CONFIG_SAMDL_DMAC_NDESC > 0
static int sam_multiple(struct sam_dmach_s *dmach)
{
struct dma_desc_s *head = &g_base_desc[dmach->dc_chan];
/* Clear any pending interrupts from any previous DMAC transfer. */
#warning Missing logic
/* Set up the initial DMA */
#warning Missing logic
DEBUGASSERT(head->srcaddr != 0);
/* Enable the channel */
#warning Missing logic
/* Enable DMA interrupts */
#warning Missing logic
return OK;
}
#endif
/****************************************************************************
* Public Functions
****************************************************************************/
@@ -1014,6 +1089,13 @@ int sam_dmastart(DMA_HANDLE handle, dma_callback_t callback, void *arg)
{
struct sam_dmach_s *dmach = (struct sam_dmach_s *)handle;
struct dma_desc_s *head;
irqstate_t flags;
uint8_t ctrla;
uint32_t chctrlb;
uint32_t tmp;
uint8_t qosctrl;
uint8_t periphqos;
uint8_t memqos;
int ret = -EINVAL;
dmavdbg("dmach: %p callback: %p arg: %p\n", dmach, callback, arg);
@@ -1031,20 +1113,78 @@ int sam_dmastart(DMA_HANDLE handle, dma_callback_t callback, void *arg)
dmach->dc_callback = callback;
dmach->dc_arg = arg;
#if CONFIG_SAMDL_DMAC_NDESC > 0
/* Is this a single block transfer? Or a multiple block transfer? */
/* Clear any pending interrupts from any previous DMAC transfer. */
if (head == dmach->dc_tail)
flags = irqsave();
putreg8(dmach->dc_chan, SAM_DMAC_CHID);
putreg8(0, SAM_DMAC_CHCTRLA);
/* Setup the Channel Control B Register
*
* DMAC_CHCTRLB_EVACT_TRIG - Normal transfer and trigger
* DMAC_CHCTRLB_EVIE=0 - No channel input actions
* DMAC_CHCTRLB_EVOE=0 - Channel event output disabled
* DMAC_CHCTRLB_LVL - Determined by DMACH_FLAG_PRIORITY
* DMAC_CHCTRLB_TRIGSRC - Determined by DMACH_FLAG_PERIPHTRIG
* DMAC_CHCTRLB_TRIGACT_BEAT - One trigger required for beat transfer
* DMAC_CHCTRLB_CMD_NOACTION - No action
*/
chctrlb = DMAC_CHCTRLB_EVACT_TRIG | DMAC_CHCTRLB_TRIGACT_BEAT |
DMAC_CHCTRLB_CMD_NOACTION;
tmp = (dmach->dc_flags & DMACH_FLAG_PRIORITY_MASK) >>
DMACH_FLAG_PRIORITY_SHIFT;
chctrlb |= tmp << DMAC_CHCTRLB_LVL_SHIFT;
tmp = (dmach->dc_flags & DMACH_FLAG_PERIPHTRIG_MASK) >>
DMACH_FLAG_PERIPHTRIG_SHIFT;
chctrlb |= tmp << DMAC_CHCTRLB_TRIGSRC_SHIFT;
putreg8(chctrlb, SAM_DMAC_CHCTRLB);
/* Setup the Quality of Service Control Register
*
* DMAC_QOSCTRL_WRBQOS_DISABLE - Background
* DMAC_QOSCTRL_FQOS, DMAC_QOSCTRL_DQOS - Depend on DMACH_FLAG_PERIPHQOS
* and DMACH_FLAG_MEMQOS
*/
periphqos = (dmach->dc_flags & DMACH_FLAG_PERIPHQOS_MASK) >>
DMACH_FLAG_PERIPHQOS_SHIFT;
memqos = (dmach->dc_flags & DMACH_FLAG_MEMQOS_MASK) >>
DMACH_FLAG_MEMQOS_SHIFT;
if (dmach->dc_dir == DMADIR_TX)
{
ret = sam_single(dmach);
/* Memory to periphery */
qosctrl = (memqos << DMAC_QOSCTRL_FQOS_SHIFT) |
(periphqos << DMAC_QOSCTRL_DQOS_SHIFT);
}
else
{
ret = sam_multiple(dmach);
qosctrl = (periphqos << DMAC_QOSCTRL_FQOS_SHIFT) |
(memqos << DMAC_QOSCTRL_DQOS_SHIFT);
}
#else
ret = sam_single(dmach);
#endif
putreg8(qosctrl | DMAC_QOSCTRL_WRBQOS_DISABLE, SAM_DMAC_QOSCTRL);
/* Enable the channel */
ctrla = DMAC_CHCTRLA_ENABLE;
if (dmach->dc_flags & DMACH_FLAG_RUNINSTDBY)
{
ctrla |= DMAC_CHCTRLA_RUNSTDBY;
}
putreg8(ctrla, SAM_DMAC_CHCTRLA);
/* Enable DMA channel interrupts */
putreg8(DMAC_INT_TERR | DMAC_INT_TCMPL, SAM_DMAC_CHINTENSET);
irqrestore(flags);
ret = OK;
}
return ret;
@@ -1146,7 +1286,7 @@ void sam_dmadump(DMA_HANDLE handle, const struct sam_dmaregs_s *regs,
dmadbg(" PENDCH: %08x ACTIVE: %08x BASEADDR: %08x WRBADDR: %08x\n",
regs->pendch, regs->active, regs->baseaddr, regs->wrbaddr);
dmadbg(" CHID: %02x CHCRTRLA: %02x CHCRTRLB: %08x CHINFLAG: %02x\n",
regs->chid, regs->chctrla, regs->chctrlb, regs->chintflag,
regs->chid, regs->chctrla, regs->chctrlb, regs->chintflag,
dmadbg(" CHSTATUS: %02x\n",
regs->chstatus);
}
+14 -8
View File
@@ -82,7 +82,10 @@
# define DMACH_FLAG_BEATSIZE_BYTE (0 << DMACH_FLAG_BEATSIZE_SHIFT) /* 8-bit bus transfer */
# define DMACH_FLAG_BEATSIZE_HWORD (1 << DMACH_FLAG_BEATSIZE_SHIFT) /* 16-bit bus transfer */
# define DMACH_FLAG_BEATSIZE_WORD (2 << DMACH_FLAG_BEATSIZE_SHIFT) /* 32-bit bus transfer */
#define DMACH_FLAG_STEPSIZE_SHIFT (2) /* Bits 2-4: Address increment step */
#define DMACH_FLAG_STEPSEL (1 << 2) /* Bit 2: Step selection */
# define DMACH_FLAG_STEPSEL_MEM (0) /* 0=Step size applies to memory */
# define DMACH_FLAG_STEPSEL_PERIPH (1 << 2) /* 1=Step size applies to peripheral */
#define DMACH_FLAG_STEPSIZE_SHIFT (3) /* Bits 3-5: Address increment step */
#define DMACH_FLAG_STEPSIZE_MASK (7 << DMACH_FLAG_STEPSIZE_SHIFT)
# define DMACH_FLAG_STEPSIZE_X1 (0 << DMACH_FLAG_STEPSIZE_SHIFT) /* Next ADDR = ADDR + (BEATSIZE+1) * 1 */
# define DMACH_FLAG_STEPSIZE_X2 (1 << DMACH_FLAG_STEPSIZE_SHIFT) /* Next ADDR = ADDR + (BEATSIZE+1) * 2 */
@@ -92,15 +95,18 @@
# define DMACH_FLAG_STEPSIZE_X32 (5 << DMACH_FLAG_STEPSIZE_SHIFT) /* Next ADDR = ADDR + (BEATSIZE+1) * 32 */
# define DMACH_FLAG_STEPSIZE_X64 (6 << DMACH_FLAG_STEPSIZE_SHIFT) /* Next ADDR = ADDR + (BEATSIZE+1) * 64 */
# define DMACH_FLAG_STEPSIZE_X128 (7 << DMACH_FLAG_STEPSIZE_SHIFT) /* Next ADDR = ADDR + (BEATSIZE+1) * 128 */
#define DMACH_FLAG_RUNINSTDBY (1 << 5) /* Bit 5: Run in standby */
#define DMACH_FLAG_PRIORITY_SHIFT (6) /* Bit 6-7: Arbitration priority */
#define DMACH_FLAG_PRIORITY_MASK (3 << DMACH_FLAG_PRIORITY_SHIFT)
# define DMACH_FLAG_PRIORITY(n) ((uint32_t)(n) << DMACH_FLAG_PRIORITY_SHIFT)
#define DMACH_FLAG_RUNINSTDBY (1 << 8) /* Bit 8: Run in standby */
/* Peripheral endpoint characteristics */
#define DMACH_FLAG_PERIPHTRIG_SHIFT (6) /* Bits 6-11: See DMAC_TRIGSRC_* */
#define DMACH_FLAG_PERIPHTRIG_SHIFT (9) /* Bits 9-13: See DMAC_TRIGSRC_* */
#define DMACH_FLAG_PERIPHTRIG_MASK (0x3f << DMACH_FLAG_PERIPHTRIG_SHIFT)
# define DMACH_FLAG_PERIPHTRIG(n) ((uint32_t)(n) << DMACH_FLAG_PERIPHTRIG_SHIFT)
#define DMACH_FLAG_PERIPHINCREMENT (1 << 12) /* Bit 12: Autoincrement peripheral address */
#define DMACH_FLAG_PERIPHQOS_SHIFT (14) /* Bits 14-15: Peripheral quality of service */
#define DMACH_FLAG_PERIPHINCREMENT (1 << 14) /* Bit 14: Autoincrement peripheral address */
#define DMACH_FLAG_PERIPHQOS_SHIFT (15) /* Bits 15-16: Peripheral quality of service */
#define DMACH_FLAG_PERIPHQOS_MASK (3 << DMACH_FLAG_PERIPHQOS_SHIFT)
# define DMACH_FLAG_PERIPHQOS_DISABLE (0 << DMACH_FLAG_PERIPHQOS_SHIFT) /* Background */
# define DMACH_FLAG_PERIPHQOS_LOW (1 << DMACH_FLAG_PERIPHQOS_SHIFT) /* Sensitve bandwidth */
@@ -109,14 +115,14 @@
/* Memory endpoint characteristics */
#define DMACH_FLAG_MEMINCREMENT (1 << 16) /* Bit 16: Autoincrement memory address */
#define DMACH_FLAG_MEMQOS_SHIFT (17) /* Bits 17-18: Memory quality of service */
#define DMACH_FLAG_MEMINCREMENT (1 << 17) /* Bit 17: Autoincrement memory address */
#define DMACH_FLAG_MEMQOS_SHIFT (18) /* Bits 18-19: Memory quality of service */
#define DMACH_FLAG_MEMQOS_MASK (3 << DMACH_FLAG_MEMQOS_SHIFT)
# define DMACH_FLAG_MEMQOS_DISABLE (0 << DMACH_FLAG_MEMQOS_SHIFT) /* Background */
# define DMACH_FLAG_MEMQOS_LOW (1 << DMACH_FLAG_MEMQOS_SHIFT) /* Sensitve bandwidth */
# define DMACH_FLAG_MEMQOS_MEDIUM (2 << DMACH_FLAG_MEMQOS_SHIFT) /* Sensitive latency */
# define DMACH_FLAG_MEMQOS_HIGH (3 << DMACH_FLAG_MEMQOS_SHIFT) /* Critical latency */
/* Bits 19-31: Not used */
/* Bits 20-31: Not used */
/************************************************************************************
* Public Types