dmaengine: sirf: enable the driver support new SiRFmarco SoC
authorBarry Song <Baohua.Song@csr.com>
Thu, 1 Nov 2012 14:54:43 +0000 (22:54 +0800)
committerVinod Koul <vinod.koul@intel.com>
Tue, 8 Jan 2013 06:05:03 +0000 (22:05 -0800)
The driver supports old up SiRFprimaII SoCs, this patch makes it support
the new SiRFmarco as well.
SiRFmarco, as a SMP SoC, adds new DMA_INT_EN_CLR and DMA_CH_LOOP_CTRL_CLR
registers, to disable IRQ/Channel, we should write 1 to the corresponding
bit in the two CLEAR register.

Tested on SiRFmarco using SPI driver:
    $ /mnt/spidev-sirftest -D /dev/spidev32766.0
    spi mode: 0
    bits per word: 8
    max speed: 500000 Hz (500 KHz)

    00 00 00 00 00 00
    00 00 00 00 00 00
    00 00 00 00 00 00
    00 00 00 00 00 00
    00 00 00 00 00 00
    00 00 00 00 00 00
    00 00 00 00

    $ cat /proc/interrupts
               CPU0       CPU1
     32:       1593          0       GIC  sirfsoc_timer0
     33:          0       3533       GIC  sirfsoc_timer1
     44:          0          0       GIC  sirfsoc_dma
     45:         16          0       GIC  sirfsoc_dma
     47:          6          0       GIC  sirfsoc_spi
     50:       5654          0       GIC  sirfsoc-uart
     ...

Signed-off-by: Barry Song <Baohua.Song@csr.com>
Signed-off-by: Vinod Koul <vinod.koul@linux.intel.com>
drivers/dma/Kconfig
drivers/dma/sirf-dma.c

index 6761cc8a59d5e68e18b6f4e4a5a0727c601a7d25..0b408bbb6a17c1df9b504a6f282b4aafcec82e29 100644 (file)
@@ -212,8 +212,8 @@ config TIMB_DMA
          Enable support for the Timberdale FPGA DMA engine.
 
 config SIRF_DMA
-       tristate "CSR SiRFprimaII DMA support"
-       depends on ARCH_PRIMA2
+       tristate "CSR SiRFprimaII/SiRFmarco DMA support"
+       depends on ARCH_SIRF
        select DMA_ENGINE
        help
          Enable support for the CSR SiRFprimaII DMA engine.
index c3de6edb96511bdf1e1e1201563f5d6c550fbcb1..3c210ba9f93853b269a9f9fdaac097341d1ed9e8 100644 (file)
@@ -32,7 +32,9 @@
 #define SIRFSOC_DMA_CH_VALID                    0x140
 #define SIRFSOC_DMA_CH_INT                      0x144
 #define SIRFSOC_DMA_INT_EN                      0x148
+#define SIRFSOC_DMA_INT_EN_CLR                 0x14C
 #define SIRFSOC_DMA_CH_LOOP_CTRL                0x150
+#define SIRFSOC_DMA_CH_LOOP_CTRL_CLR            0x15C
 
 #define SIRFSOC_DMA_MODE_CTRL_BIT               4
 #define SIRFSOC_DMA_DIR_CTRL_BIT                5
@@ -76,6 +78,7 @@ struct sirfsoc_dma {
        struct sirfsoc_dma_chan         channels[SIRFSOC_DMA_CHANNELS];
        void __iomem                    *base;
        int                             irq;
+       bool                            is_marco;
 };
 
 #define DRV_NAME       "sirfsoc_dma"
@@ -288,13 +291,19 @@ static int sirfsoc_dma_terminate_all(struct sirfsoc_dma_chan *schan)
        int cid = schan->chan.chan_id;
        unsigned long flags;
 
-       writel_relaxed(readl_relaxed(sdma->base + SIRFSOC_DMA_INT_EN) &
-               ~(1 << cid), sdma->base + SIRFSOC_DMA_INT_EN);
-       writel_relaxed(1 << cid, sdma->base + SIRFSOC_DMA_CH_VALID);
-
-       writel_relaxed(readl_relaxed(sdma->base + SIRFSOC_DMA_CH_LOOP_CTRL)
-               & ~((1 << cid) | 1 << (cid + 16)),
+       if (!sdma->is_marco) {
+               writel_relaxed(readl_relaxed(sdma->base + SIRFSOC_DMA_INT_EN) &
+                       ~(1 << cid), sdma->base + SIRFSOC_DMA_INT_EN);
+               writel_relaxed(readl_relaxed(sdma->base + SIRFSOC_DMA_CH_LOOP_CTRL)
+                       & ~((1 << cid) | 1 << (cid + 16)),
                        sdma->base + SIRFSOC_DMA_CH_LOOP_CTRL);
+       } else {
+               writel_relaxed(1 << cid, sdma->base + SIRFSOC_DMA_INT_EN_CLR);
+               writel_relaxed((1 << cid) | 1 << (cid + 16),
+                       sdma->base + SIRFSOC_DMA_CH_LOOP_CTRL_CLR);
+       }
+
+       writel_relaxed(1 << cid, sdma->base + SIRFSOC_DMA_CH_VALID);
 
        spin_lock_irqsave(&schan->lock, flags);
        list_splice_tail_init(&schan->active, &schan->free);
@@ -568,6 +577,9 @@ static int sirfsoc_dma_probe(struct platform_device *op)
                return -ENOMEM;
        }
 
+       if (of_device_is_compatible(dn, "sirf,marco-dmac"))
+               sdma->is_marco = true;
+
        if (of_property_read_u32(dn, "cell-index", &id)) {
                dev_err(dev, "Fail to get DMAC index\n");
                return -ENODEV;
@@ -668,6 +680,7 @@ static int __devexit sirfsoc_dma_remove(struct platform_device *op)
 
 static struct of_device_id sirfsoc_dma_match[] = {
        { .compatible = "sirf,prima2-dmac", },
+       { .compatible = "sirf,marco-dmac", },
        {},
 };