From 31ba1f218afab0329469fd471d047b244640a755 Mon Sep 17 00:00:00 2001 From: Javier Jalle Date: Wed, 15 Feb 2017 11:14:13 +0100 Subject: leon, grpci2: prepare for GRPCI2DMA driver --- c/src/lib/libbsp/sparc/shared/pci/grpci2.c | 110 +++++++++++++++++++---------- 1 file changed, 72 insertions(+), 38 deletions(-) diff --git a/c/src/lib/libbsp/sparc/shared/pci/grpci2.c b/c/src/lib/libbsp/sparc/shared/pci/grpci2.c index a537c67400..2d8e1521f7 100644 --- a/c/src/lib/libbsp/sparc/shared/pci/grpci2.c +++ b/c/src/lib/libbsp/sparc/shared/pci/grpci2.c @@ -169,44 +169,6 @@ struct grpci2_regs { #define STS_ITGTABRT (1<<13) #define STS_IPARERR (1<<12) -struct grpci2_bd_chan { - volatile unsigned int ctrl; /* 0x00 DMA Control */ - volatile unsigned int nchan; /* 0x04 Next DMA Channel Address */ - volatile unsigned int nbd; /* 0x08 Next Data Descriptor in channel */ - volatile unsigned int res; /* 0x0C Reserved */ -}; - -#define BD_CHAN_EN (1<regs->sts_cap & (STS_IDMAERR | STS_IDMA)); + + /* Clear Interrupt if taken*/ + if (sts != 0){ + /* Clear IDMAERR and IDMA bits */ + priv->regs->sts_cap = (STS_IDMAERR | STS_IDMA); + /* Clear DRVMGR interrupt */ + drvmgr_interrupt_clear(priv->dev, priv->irq_dma); + /* Call DMA driver ISR */ + (priv->dma_isr)(priv->dma_isr_arg); + } +} + static int grpci2_hw_init(struct grpci2_priv *priv) { struct grpci2_regs *regs = priv->regs; @@ -956,6 +955,11 @@ int grpci2_init3(struct drvmgr_dev *dev) /* Install and Enable PCI Error interrupt handler */ drvmgr_interrupt_register(dev, 0, "grpci2", grpci2_err_isr, priv); + /* Initialize DMA driver (if supported) */ + if (priv->regs->sts_cap & STS_DMA){ + grpci2dma_init((void *) &(priv->regs->dma_ctrl), grpci2_dma_isr_register); + } + /* Unmask Error IRQ and all PCI interrupts at PCI Core. For this to be * safe every PCI board have to be resetted (no IRQ generation) before * Global IRQs are enabled (Init is reached or similar) @@ -964,3 +968,33 @@ int grpci2_init3(struct drvmgr_dev *dev) return DRVMGR_OK; } + +static void grpci2_dma_isr_register( void (*isr)(void *), void * arg) +{ + struct grpci2_priv *priv = grpci2priv; + + /* Handle unregistration */ + if (priv->dma_isr != NULL) { + drvmgr_interrupt_unregister(priv->dev, priv->irq_dma, grpci2_dma_isr, priv); + /* Uninstall user ISR */ + priv->dma_isr = NULL; + priv->dma_isr_arg = NULL; + } + + if (isr == NULL) + return; + + /* Install user ISR */ + priv->dma_isr_arg = arg; + priv->dma_isr = isr; + + /* Install and Enable PCI DMA interrupt handler */ + if (priv->irq_mode == 1) { + priv->irq_dma = 1; + } else if (priv->irq_mode == 3) { + priv->irq_dma = 4; + } else { + priv->irq_dma = 0; + } + drvmgr_interrupt_register(priv->dev, priv->irq_dma, "grpci2dma", grpci2_dma_isr, priv); +} -- cgit v1.2.3