From: Javier Jalle <javier.ja...@gaisler.com>

---
 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 7556f68..eb62226 100644
--- a/c/src/lib/libbsp/sparc/shared/pci/grpci2.c
+++ b/c/src/lib/libbsp/sparc/shared/pci/grpci2.c
@@ -170,44 +170,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<<BD_CHAN_EN_BIT)
-#define BD_CHAN_ID             (0x3<<BD_CHAN_ID_BIT)
-#define BD_CHAN_TYPE           (0x3<<BD_CHAN_TYPE_BIT)
-#define BD_CHAN_BDCNT          (0xffff<<BD_CHAN_BDCNT_BIT)
-#define BD_CHAN_EN_BIT         31
-#define BD_CHAN_ID_BIT         22
-#define BD_CHAN_TYPE_BIT       20
-#define BD_CHAN_BDCNT_BIT      0
-
-struct grpci2_bd_data {
-       volatile unsigned int ctrl;     /* 0x00 DMA Data Control */
-       volatile unsigned int pci_adr;  /* 0x04 PCI Start Address */
-       volatile unsigned int ahb_adr;  /* 0x08 AHB Start address */
-       volatile unsigned int next;     /* 0x0C Next Data Descriptor in channel 
*/
-};
-
-#define BD_DATA_EN             (0x1<<BD_DATA_EN_BIT)
-#define BD_DATA_IE             (0x1<<BD_DATA_IE_BIT)
-#define BD_DATA_DR             (0x1<<BD_DATA_DR_BIT)
-#define BD_DATA_BE             (0x1<<BD_DATA_BE_BIT)
-#define BD_DATA_TYPE           (0x3<<BD_DATA_TYPE_BIT)
-#define BD_DATA_ER             (0x1<<BD_DATA_ER_BIT)
-#define BD_DATA_LEN            (0xffff<<BD_DATA_LEN_BIT)
-#define BD_DATA_EN_BIT         31
-#define BD_DATA_IE_BIT         30
-#define BD_DATA_DR_BIT         29
-#define BD_DATA_BE_BIT         28
-#define BD_DATA_TYPE_BIT       20
-#define BD_DATA_ER_BIT         19
-#define BD_DATA_LEN_BIT                0
-
 /* GRPCI2 Capability */
 struct grpci2_cap_first {
        unsigned int ctrl;
@@ -260,6 +222,7 @@ struct grpci2_priv {
        unsigned char                   ver;
        char                            irq;
        char                            irq_mode; /* IRQ Mode from CAPSTS REG */
+       char                            irq_dma; /* IRQ Index for DMA */
        char                            bt_enabled;
        unsigned int                    irq_mask;
        unsigned int                    latency_timer;
@@ -278,12 +241,17 @@ struct grpci2_priv {
        struct drvmgr_map_entry         maps_down[2];
        struct pcibus_config            config;
 
+       /* DMA interrupts */
+       void (*dma_isr)(void *data);
+       void *dma_isr_arg;
+
        SPIN_DECLARE(devlock)
 };
 
 int grpci2_init1(struct drvmgr_dev *dev);
 int grpci2_init3(struct drvmgr_dev *dev);
 void grpci2_err_isr(void *arg);
+void grpci2_dma_isr(void *arg);
 
 /* GRPCI2 DRIVER */
 
@@ -317,6 +285,19 @@ struct amba_drv_info grpci2_info =
        &grpci2_ids[0]
 };
 
+/* Defaults to do nothing - user can override this function
+ * by including the DMA DRIVER.
+ */
+int __attribute__((weak)) grpci2dma_init(void * regs, void isr_register( void 
(*isr)(void *), void * arg));
+
+int grpci2dma_init(void * regs, void isr_register( void (*isr)(void *), void * 
arg))
+{
+       return 0;
+}
+
+/* Prototype of grpci2_dma_isr_register function */
+static void grpci2_dma_isr_register( void (*isr)(void *), void * arg);
+
 void grpci2_register_drv(void)
 {
        DBG("Registering GRPCI2 driver\n");
@@ -662,6 +643,24 @@ void grpci2_err_isr(void *arg)
        }
 }
 
+/* PCI DMA Interrupt handler, called when there may be a PCI DMA interrupt.
+ */
+void grpci2_dma_isr(void *arg)
+{
+       struct grpci2_priv *priv = arg;
+       unsigned int sts = (priv->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;
@@ -957,6 +956,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)
@@ -965,3 +969,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);
+}
-- 
2.7.4

_______________________________________________
devel mailing list
devel@rtems.org
http://lists.rtems.org/mailman/listinfo/devel

Reply via email to