leon, grspw_pkt: allow user controlled DMA intr

The user has already the power to control which DMA buffer
will generate interrupt, but no clean way to enable RX/TX
interrupts on DMA channel. Without this patch the user had
to init DMA config rx/tx_irq_en_cnt to a very large value.
This commit is contained in:
Daniel Hellstrom
2016-03-30 14:29:52 +02:00
parent 1ef9caa26b
commit 77856f67aa
2 changed files with 18 additions and 6 deletions

View File

@@ -261,9 +261,19 @@ struct grspw_core_stats {
#define DMAFLAG_STRIP_PID 0x0008 /* See HW doc DMA-CTRL SP bit */
#define DMAFLAG_RESV2 0x0010 /* HAS NO EFFECT */
#define DMAFLAG_MASK (DMAFLAG_NO_SPILL|DMAFLAG_STRIP_ADR|DMAFLAG_STRIP_PID)
/* grspw_dma_config.flags misc options (not shifted internally) */
#define DMAFLAG2_TXIE 0x00100000 /* See HW doc DMA-CTRL TI bit.
* Used to enable TX DMA interrupt
* when tx_irq_en_cnt=0.
*/
#define DMAFLAG2_RXIE 0x00200000 /* See HW doc DMA-CTRL RI bit.
* Used to enable RX DMA interrupt
* when rx_irq_en_cnt=0.
*/
#define DMAFLAG2_MASK (DMAFLAG2_TXIE | DMAFLAG2_RXIE)
struct grspw_dma_config {
int flags; /* DMA config flags, see DMAFLAG_* options */
int flags; /* DMA config flags, see DMAFLAG1&2_* options */
int rxmaxlen; /* RX Max Packet Length */
int rx_irq_en_cnt; /* Enable RX IRQ every cnt descriptors */
int tx_irq_en_cnt; /* Enable TX IRQ every cnt descriptors */

View File

@@ -2301,7 +2301,7 @@ int grspw_dma_config(void *c, struct grspw_dma_config *cfg)
if (dma->started || !cfg)
return -1;
if (cfg->flags & ~DMAFLAG_MASK)
if (cfg->flags & ~(DMAFLAG_MASK | DMAFLAG2_MASK))
return -1;
/* Update Configuration */
@@ -2398,9 +2398,9 @@ int grspw_dma_start(void *c)
(dma->cfg.flags & DMAFLAG_MASK) << GRSPW_DMACTRL_NS_BIT;
if (dma->core->dis_link_on_err & LINKOPTS_DIS_ONERR)
ctrl |= GRSPW_DMACTRL_LE;
if (dma->cfg.rx_irq_en_cnt != 0)
if (dma->cfg.rx_irq_en_cnt != 0 || dma->cfg.flags & DMAFLAG2_RXIE)
ctrl |= GRSPW_DMACTRL_RI;
if (dma->cfg.tx_irq_en_cnt != 0)
if (dma->cfg.tx_irq_en_cnt != 0 || dma->cfg.flags & DMAFLAG2_TXIE)
ctrl |= GRSPW_DMACTRL_TI;
SPIN_LOCK_IRQ(&dma->core->devlock, irqflags);
ctrl |= REG_READ(&dma->regs->ctrl) & GRSPW_DMACTRL_EN;
@@ -2540,9 +2540,11 @@ static void grspw_work_dma_func(struct grspw_dma_priv *dma)
} else if (ctrl & (GRSPW_DMACTRL_PR | GRSPW_DMACTRL_PS)) {
/* DMA has finished a TX/RX packet */
ctrl &= ~GRSPW_DMACTRL_AT;
if (dma->cfg.rx_irq_en_cnt != 0)
if (dma->cfg.rx_irq_en_cnt != 0 ||
(dma->cfg.flags & DMAFLAG2_RXIE))
ctrl |= GRSPW_DMACTRL_RI;
if (dma->cfg.tx_irq_en_cnt != 0)
if (dma->cfg.tx_irq_en_cnt != 0 ||
(dma->cfg.flags & DMAFLAG2_TXIE))
ctrl |= GRSPW_DMACTRL_TI;
REG_WRITE(&dma->regs->ctrl, ctrl);
SPIN_UNLOCK_IRQ(&priv->devlock, irqflags);