dw_dmac: Pass Channel Priority from platform_data
authorViresh Kumar <viresh.kumar@st.com>
Thu, 3 Mar 2011 10:17:22 +0000 (15:47 +0530)
committerVinod Koul <vinod.koul@intel.com>
Sun, 6 Mar 2011 19:42:28 +0000 (01:12 +0530)
In Synopsys designware, channel priority is programmable. This patch adds
support for passing channel priority through platform data. By default Ascending
channel priority will be followed, i.e. channel 0 will get highest priority and
channel 7 will get lowest.

Signed-off-by: Viresh Kumar <viresh.kumar@st.com>
Signed-off-by: Vinod Koul <vinod.koul@intel.com>
drivers/dma/dw_dmac.c
drivers/dma/dw_dmac_regs.h
include/linux/dw_dmac.h

index f413e12..318a342 100644 (file)
@@ -901,8 +901,11 @@ static int dwc_alloc_chan_resources(struct dma_chan *chan)
                BUG_ON(!dws->dma_dev || dws->dma_dev != dw->dma.dev);
 
                cfghi = dws->cfg_hi;
-               cfglo = dws->cfg_lo;
+               cfglo = dws->cfg_lo & ~DWC_CFGL_CH_PRIOR_MASK;
        }
+
+       cfglo |= DWC_CFGL_CH_PRIOR(dwc->priority);
+
        channel_writel(dwc, CFG_LO, cfglo);
        channel_writel(dwc, CFG_HI, cfghi);
 
@@ -1325,6 +1328,12 @@ static int __init dw_probe(struct platform_device *pdev)
                else
                        list_add(&dwc->chan.device_node, &dw->dma.channels);
 
+               /* 7 is highest priority & 0 is lowest. */
+               if (pdata->chan_priority == CHAN_PRIORITY_ASCENDING)
+                       dwc->priority = 7 - i;
+               else
+                       dwc->priority = i;
+
                dwc->ch_regs = &__dw_regs(dw)->CHAN[i];
                spin_lock_init(&dwc->lock);
                dwc->mask = 1 << i;
index d9a939f..6a8e6d3 100644 (file)
@@ -101,6 +101,8 @@ struct dw_dma_regs {
 #define DWC_CTLH_BLOCK_TS_MASK 0x00000fff
 
 /* Bitfields in CFG_LO. Platform-configurable bits are in <linux/dw_dmac.h> */
+#define DWC_CFGL_CH_PRIOR_MASK (0x7 << 5)      /* priority mask */
+#define DWC_CFGL_CH_PRIOR(x)   ((x) << 5)      /* priority */
 #define DWC_CFGL_CH_SUSP       (1 << 8)        /* pause xfer */
 #define DWC_CFGL_FIFO_EMPTY    (1 << 9)        /* pause xfer */
 #define DWC_CFGL_HS_DST                (1 << 10)       /* handshake w/dst */
@@ -134,6 +136,7 @@ struct dw_dma_chan {
        struct dma_chan         chan;
        void __iomem            *ch_regs;
        u8                      mask;
+       u8                      priority;
 
        spinlock_t              lock;
 
index a18c498..64c76da 100644 (file)
@@ -25,6 +25,9 @@ struct dw_dma_platform_data {
 #define CHAN_ALLOCATION_ASCENDING      0       /* zero to seven */
 #define CHAN_ALLOCATION_DESCENDING     1       /* seven to zero */
        unsigned char   chan_allocation_order;
+#define CHAN_PRIORITY_ASCENDING                0       /* chan0 highest */
+#define CHAN_PRIORITY_DESCENDING       1       /* chan7 highest */
+       unsigned char   chan_priority;
 };
 
 /**
@@ -70,7 +73,6 @@ struct dw_dma_slave {
 #define DWC_CFGH_DST_PER(x)    ((x) << 11)
 
 /* Platform-configurable bits in CFG_LO */
-#define DWC_CFGL_PRIO(x)       ((x) << 5)      /* priority */
 #define DWC_CFGL_LOCK_CH_XFER  (0 << 12)       /* scope of LOCK_CH */
 #define DWC_CFGL_LOCK_CH_BLOCK (1 << 12)
 #define DWC_CFGL_LOCK_CH_XACT  (2 << 12)