dma40: allow realtime and priority for event lines
authorRabin Vincent <rabin.vincent@stericsson.com>
Tue, 25 Jan 2011 10:18:11 +0000 (11:18 +0100)
committerDan Williams <dan.j.williams@intel.com>
Mon, 31 Jan 2011 06:27:16 +0000 (22:27 -0800)
DB8500v2's DMA40 (revision 3) allows setting event lines as high priority and
real time.

Acked-by: Per Forlin <per.forlin@stericsson.com>
Acked-by: Jonas Aaberg <jonas.aberg@stericsson.com>
Signed-off-by: Rabin Vincent <rabin.vincent@stericsson.com>
Signed-off-by: Linus Walleij <linus.walleij@stericsson.com>
Signed-off-by: Dan Williams <dan.j.williams@intel.com>
arch/arm/plat-nomadik/include/plat/ste_dma40.h
drivers/dma/ste_dma40.c
drivers/dma/ste_dma40_ll.h

index 4d6dd4c39b750e76cdf199f6ee00713d3e3731cb..8358f857a29ed8af5dce82321f66b876921697f9 100644 (file)
@@ -104,6 +104,8 @@ struct stedma40_half_channel_info {
  *
  * @dir: MEM 2 MEM, PERIPH 2 MEM , MEM 2 PERIPH, PERIPH 2 PERIPH
  * @high_priority: true if high-priority
+ * @realtime: true if realtime mode is to be enabled.  Only available on DMA40
+ * version 3+, i.e DB8500v2+
  * @mode: channel mode: physical, logical, or operation
  * @mode_opt: options for the chosen channel mode
  * @src_dev_type: Src device type
@@ -119,6 +121,7 @@ struct stedma40_half_channel_info {
 struct stedma40_chan_cfg {
        enum stedma40_xfer_dir                   dir;
        bool                                     high_priority;
+       bool                                     realtime;
        enum stedma40_mode                       mode;
        enum stedma40_mode_opt                   mode_opt;
        int                                      src_dev_type;
index 0faae662ad15a96cb1e5a3c510a6581dfd230269..ce551622158127262c0c9a8b134a22a7166bd187 100644 (file)
@@ -1724,6 +1724,38 @@ bool stedma40_filter(struct dma_chan *chan, void *data)
 }
 EXPORT_SYMBOL(stedma40_filter);
 
+static void __d40_set_prio_rt(struct d40_chan *d40c, int dev_type, bool src)
+{
+       bool realtime = d40c->dma_cfg.realtime;
+       bool highprio = d40c->dma_cfg.high_priority;
+       u32 prioreg = highprio ? D40_DREG_PSEG1 : D40_DREG_PCEG1;
+       u32 rtreg = realtime ? D40_DREG_RSEG1 : D40_DREG_RCEG1;
+       u32 event = D40_TYPE_TO_EVENT(dev_type);
+       u32 group = D40_TYPE_TO_GROUP(dev_type);
+       u32 bit = 1 << event;
+
+       /* Destination event lines are stored in the upper halfword */
+       if (!src)
+               bit <<= 16;
+
+       writel(bit, d40c->base->virtbase + prioreg + group * 4);
+       writel(bit, d40c->base->virtbase + rtreg + group * 4);
+}
+
+static void d40_set_prio_realtime(struct d40_chan *d40c)
+{
+       if (d40c->base->rev < 3)
+               return;
+
+       if ((d40c->dma_cfg.dir ==  STEDMA40_PERIPH_TO_MEM) ||
+           (d40c->dma_cfg.dir == STEDMA40_PERIPH_TO_PERIPH))
+               __d40_set_prio_rt(d40c, d40c->dma_cfg.src_dev_type, true);
+
+       if ((d40c->dma_cfg.dir ==  STEDMA40_MEM_TO_PERIPH) ||
+           (d40c->dma_cfg.dir == STEDMA40_PERIPH_TO_PERIPH))
+               __d40_set_prio_rt(d40c, d40c->dma_cfg.dst_dev_type, false);
+}
+
 /* DMA ENGINE functions */
 static int d40_alloc_chan_resources(struct dma_chan *chan)
 {
@@ -1756,6 +1788,8 @@ static int d40_alloc_chan_resources(struct dma_chan *chan)
        d40_phy_cfg(&d40c->dma_cfg, &d40c->src_def_cfg,
                    &d40c->dst_def_cfg, chan_is_logical(d40c));
 
+       d40_set_prio_realtime(d40c);
+
        if (chan_is_logical(d40c)) {
                d40_log_cfg(&d40c->dma_cfg,
                            &d40c->log_def.lcsp1, &d40c->log_def.lcsp3);
index 9cc43495bea2051292f1952b7cc0d683cbf7c915..e93f394187a37c2ca18aa98c48d129c6ba08c111 100644 (file)
 #define D40_DREG_LCEIS1                0x0B4
 #define D40_DREG_LCEIS2                0x0B8
 #define D40_DREG_LCEIS3                0x0BC
+#define D40_DREG_PSEG1         0x110
+#define D40_DREG_PSEG2         0x114
+#define D40_DREG_PSEG3         0x118
+#define D40_DREG_PSEG4         0x11C
+#define D40_DREG_PCEG1         0x120
+#define D40_DREG_PCEG2         0x124
+#define D40_DREG_PCEG3         0x128
+#define D40_DREG_PCEG4         0x12C
+#define D40_DREG_RSEG1         0x130
+#define D40_DREG_RSEG2         0x134
+#define D40_DREG_RSEG3         0x138
+#define D40_DREG_RSEG4         0x13C
+#define D40_DREG_RCEG1         0x140
+#define D40_DREG_RCEG2         0x144
+#define D40_DREG_RCEG3         0x148
+#define D40_DREG_RCEG4         0x14C
 #define D40_DREG_STFU          0xFC8
 #define D40_DREG_ICFG          0xFCC
 #define D40_DREG_PERIPHID0     0xFE0