]> git.karo-electronics.de Git - mv-sheeva.git/commitdiff
Merge branch 'dma40' into dmaengine
authorDan Williams <dan.j.williams@intel.com>
Tue, 19 Oct 2010 22:34:26 +0000 (15:34 -0700)
committerDan Williams <dan.j.williams@intel.com>
Tue, 19 Oct 2010 22:34:26 +0000 (15:34 -0700)
arch/arm/mach-ux500/devices-db8500.c
arch/arm/plat-nomadik/include/plat/ste_dma40.h
drivers/dma/ste_dma40.c
drivers/dma/ste_dma40_ll.c
drivers/dma/ste_dma40_ll.h

index 58b3e723b1831a89b7baca629c00c080a95c390d..c04bf2b61dcd43a9201790e8d1b4acb4c1df0b38 100644 (file)
@@ -132,35 +132,25 @@ static struct resource dma40_resources[] = {
 
 /* Default configuration for physcial memcpy */
 struct stedma40_chan_cfg dma40_memcpy_conf_phy = {
-       .channel_type = (STEDMA40_CHANNEL_IN_PHY_MODE |
-                        STEDMA40_LOW_PRIORITY_CHANNEL |
-                        STEDMA40_PCHAN_BASIC_MODE),
+       .mode = STEDMA40_MODE_PHYSICAL,
        .dir = STEDMA40_MEM_TO_MEM,
 
-       .src_info.endianess = STEDMA40_LITTLE_ENDIAN,
        .src_info.data_width = STEDMA40_BYTE_WIDTH,
        .src_info.psize = STEDMA40_PSIZE_PHY_1,
        .src_info.flow_ctrl = STEDMA40_NO_FLOW_CTRL,
 
-       .dst_info.endianess = STEDMA40_LITTLE_ENDIAN,
        .dst_info.data_width = STEDMA40_BYTE_WIDTH,
        .dst_info.psize = STEDMA40_PSIZE_PHY_1,
        .dst_info.flow_ctrl = STEDMA40_NO_FLOW_CTRL,
 };
 /* Default configuration for logical memcpy */
 struct stedma40_chan_cfg dma40_memcpy_conf_log = {
-       .channel_type = (STEDMA40_CHANNEL_IN_LOG_MODE |
-                        STEDMA40_LOW_PRIORITY_CHANNEL |
-                        STEDMA40_LCHAN_SRC_LOG_DST_LOG |
-                        STEDMA40_NO_TIM_FOR_LINK),
        .dir = STEDMA40_MEM_TO_MEM,
 
-       .src_info.endianess = STEDMA40_LITTLE_ENDIAN,
        .src_info.data_width = STEDMA40_BYTE_WIDTH,
        .src_info.psize = STEDMA40_PSIZE_LOG_1,
        .src_info.flow_ctrl = STEDMA40_NO_FLOW_CTRL,
 
-       .dst_info.endianess = STEDMA40_LITTLE_ENDIAN,
        .dst_info.data_width = STEDMA40_BYTE_WIDTH,
        .dst_info.psize = STEDMA40_PSIZE_LOG_1,
        .dst_info.flow_ctrl = STEDMA40_NO_FLOW_CTRL,
index 3dd42551de0419bdac34a195ed95ffc17465ac65..da1f08ff9ee2710c1b04cc616d110297ea2c8ec1 100644 (file)
 #define STEDMA40_DEV_DST_MEMORY (-1)
 #define        STEDMA40_DEV_SRC_MEMORY (-1)
 
-/*
- * Description of bitfields of channel_type variable is available in
- * the info structure.
- */
+enum stedma40_mode {
+       STEDMA40_MODE_LOGICAL = 0,
+       STEDMA40_MODE_PHYSICAL,
+       STEDMA40_MODE_OPERATION,
+};
 
-/* Priority */
-#define STEDMA40_INFO_PRIO_TYPE_POS 2
-#define STEDMA40_HIGH_PRIORITY_CHANNEL (0x1 << STEDMA40_INFO_PRIO_TYPE_POS)
-#define STEDMA40_LOW_PRIORITY_CHANNEL (0x2 << STEDMA40_INFO_PRIO_TYPE_POS)
-
-/* Mode  */
-#define STEDMA40_INFO_CH_MODE_TYPE_POS 6
-#define STEDMA40_CHANNEL_IN_PHY_MODE (0x1 << STEDMA40_INFO_CH_MODE_TYPE_POS)
-#define STEDMA40_CHANNEL_IN_LOG_MODE (0x2 << STEDMA40_INFO_CH_MODE_TYPE_POS)
-#define STEDMA40_CHANNEL_IN_OPER_MODE (0x3 << STEDMA40_INFO_CH_MODE_TYPE_POS)
-
-/* Mode options */
-#define STEDMA40_INFO_CH_MODE_OPT_POS 8
-#define STEDMA40_PCHAN_BASIC_MODE (0x1 << STEDMA40_INFO_CH_MODE_OPT_POS)
-#define STEDMA40_PCHAN_MODULO_MODE (0x2 << STEDMA40_INFO_CH_MODE_OPT_POS)
-#define STEDMA40_PCHAN_DOUBLE_DST_MODE (0x3 << STEDMA40_INFO_CH_MODE_OPT_POS)
-#define STEDMA40_LCHAN_SRC_PHY_DST_LOG (0x1 << STEDMA40_INFO_CH_MODE_OPT_POS)
-#define STEDMA40_LCHAN_SRC_LOG_DST_PHS (0x2 << STEDMA40_INFO_CH_MODE_OPT_POS)
-#define STEDMA40_LCHAN_SRC_LOG_DST_LOG (0x3 << STEDMA40_INFO_CH_MODE_OPT_POS)
-
-/* Interrupt */
-#define STEDMA40_INFO_TIM_POS 10
-#define STEDMA40_NO_TIM_FOR_LINK (0x0 << STEDMA40_INFO_TIM_POS)
-#define STEDMA40_TIM_FOR_LINK (0x1 << STEDMA40_INFO_TIM_POS)
-
-/* End of channel_type configuration */
+enum stedma40_mode_opt {
+       STEDMA40_PCHAN_BASIC_MODE = 0,
+       STEDMA40_LCHAN_SRC_LOG_DST_LOG = 0,
+       STEDMA40_PCHAN_MODULO_MODE,
+       STEDMA40_PCHAN_DOUBLE_DST_MODE,
+       STEDMA40_LCHAN_SRC_PHY_DST_LOG,
+       STEDMA40_LCHAN_SRC_LOG_DST_PHY,
+};
 
 #define STEDMA40_ESIZE_8_BIT  0x0
 #define STEDMA40_ESIZE_16_BIT 0x1
@@ -79,11 +62,6 @@ enum stedma40_flow_ctrl {
        STEDMA40_FLOW_CTRL,
 };
 
-enum stedma40_endianess {
-       STEDMA40_LITTLE_ENDIAN,
-       STEDMA40_BIG_ENDIAN
-};
-
 enum stedma40_periph_data_width {
        STEDMA40_BYTE_WIDTH = STEDMA40_ESIZE_8_BIT,
        STEDMA40_HALFWORD_WIDTH = STEDMA40_ESIZE_16_BIT,
@@ -102,13 +80,13 @@ enum stedma40_xfer_dir {
 /**
  * struct stedma40_chan_cfg - dst/src channel configuration
  *
- * @endianess: Endianess of the src/dst hardware
+ * @big_endian: true if the src/dst should be read as big endian
  * @data_width: Data width of the src/dst hardware
  * @p_size: Burst size
  * @flow_ctrl: Flow control on/off.
  */
 struct stedma40_half_channel_info {
-       enum stedma40_endianess endianess;
+       bool big_endian;
        enum stedma40_periph_data_width data_width;
        int psize;
        enum stedma40_flow_ctrl flow_ctrl;
@@ -118,7 +96,9 @@ struct stedma40_half_channel_info {
  * struct stedma40_chan_cfg - Structure to be filled by client drivers.
  *
  * @dir: MEM 2 MEM, PERIPH 2 MEM , MEM 2 PERIPH, PERIPH 2 PERIPH
- * @channel_type: priority, mode, mode options and interrupt configuration.
+ * @high_priority: true if high-priority
+ * @mode: channel mode: physical, logical, or operation
+ * @mode_opt: options for the chosen channel mode
  * @src_dev_type: Src device type
  * @dst_dev_type: Dst device type
  * @src_info: Parameters for dst half channel
@@ -131,7 +111,9 @@ struct stedma40_half_channel_info {
  */
 struct stedma40_chan_cfg {
        enum stedma40_xfer_dir                   dir;
-       unsigned int                             channel_type;
+       bool                                     high_priority;
+       enum stedma40_mode                       mode;
+       enum stedma40_mode_opt                   mode_opt;
        int                                      src_dev_type;
        int                                      dst_dev_type;
        struct stedma40_half_channel_info        src_info;
index 3f76cd9af7c317ded4c2a290e4ab957098e38f76..fab68a5532054650f979143d2508827a458da9e9 100644 (file)
@@ -175,6 +175,7 @@ struct d40_base;
  * @active: Active descriptor.
  * @queue: Queued jobs.
  * @dma_cfg: The client configuration of this dma channel.
+ * @configured: whether the dma_cfg configuration is valid
  * @base: Pointer to the device instance struct.
  * @src_def_cfg: Default cfg register setting for src.
  * @dst_def_cfg: Default cfg register setting for dst.
@@ -198,6 +199,7 @@ struct d40_chan {
        struct list_head                 active;
        struct list_head                 queue;
        struct stedma40_chan_cfg         dma_cfg;
+       bool                             configured;
        struct d40_base                 *base;
        /* Default register configurations */
        u32                              src_def_cfg;
@@ -691,6 +693,31 @@ static u32 d40_chan_has_events(struct d40_chan *d40c)
        return val;
 }
 
+static u32 d40_get_prmo(struct d40_chan *d40c)
+{
+       static const unsigned int phy_map[] = {
+               [STEDMA40_PCHAN_BASIC_MODE]
+                       = D40_DREG_PRMO_PCHAN_BASIC,
+               [STEDMA40_PCHAN_MODULO_MODE]
+                       = D40_DREG_PRMO_PCHAN_MODULO,
+               [STEDMA40_PCHAN_DOUBLE_DST_MODE]
+                       = D40_DREG_PRMO_PCHAN_DOUBLE_DST,
+       };
+       static const unsigned int log_map[] = {
+               [STEDMA40_LCHAN_SRC_PHY_DST_LOG]
+                       = D40_DREG_PRMO_LCHAN_SRC_PHY_DST_LOG,
+               [STEDMA40_LCHAN_SRC_LOG_DST_PHY]
+                       = D40_DREG_PRMO_LCHAN_SRC_LOG_DST_PHY,
+               [STEDMA40_LCHAN_SRC_LOG_DST_LOG]
+                       = D40_DREG_PRMO_LCHAN_SRC_LOG_DST_LOG,
+       };
+
+       if (d40c->log_num == D40_PHY_CHAN)
+               return phy_map[d40c->dma_cfg.mode_opt];
+       else
+               return log_map[d40c->dma_cfg.mode_opt];
+}
+
 static void d40_config_write(struct d40_chan *d40c)
 {
        u32 addr_base;
@@ -704,8 +731,7 @@ static void d40_config_write(struct d40_chan *d40c)
        writel(var, d40c->base->virtbase + D40_DREG_PRMSE + addr_base);
 
        /* Setup operational mode option register */
-       var = ((d40c->dma_cfg.channel_type >> STEDMA40_INFO_CH_MODE_OPT_POS) &
-              0x3) << D40_CHAN_POS(d40c->phy_chan->num);
+       var = d40_get_prmo(d40c) << D40_CHAN_POS(d40c->phy_chan->num);
 
        writel(var, d40c->base->virtbase + D40_DREG_PRMOE + addr_base);
 
@@ -1149,8 +1175,7 @@ static int d40_validate_conf(struct d40_chan *d40c,
        int res = 0;
        u32 dst_event_group = D40_TYPE_TO_GROUP(conf->dst_dev_type);
        u32 src_event_group = D40_TYPE_TO_GROUP(conf->src_dev_type);
-       bool is_log = (conf->channel_type & STEDMA40_CHANNEL_IN_OPER_MODE)
-               == STEDMA40_CHANNEL_IN_LOG_MODE;
+       bool is_log = conf->mode == STEDMA40_MODE_LOGICAL;
 
        if (!conf->dir) {
                dev_err(&d40c->chan.dev->device, "[%s] Invalid direction.\n",
@@ -1314,10 +1339,7 @@ static int d40_allocate_channel(struct d40_chan *d40c)
        int j;
        int log_num;
        bool is_src;
-       bool is_log = (d40c->dma_cfg.channel_type &
-                      STEDMA40_CHANNEL_IN_OPER_MODE)
-               == STEDMA40_CHANNEL_IN_LOG_MODE;
-
+       bool is_log = d40c->dma_cfg.mode == STEDMA40_MODE_LOGICAL;
 
        phys = d40c->base->phy_res;
 
@@ -1518,8 +1540,7 @@ static int d40_free_dma(struct d40_chan *d40c)
                return res;
        }
        d40c->phy_chan = NULL;
-       /* Invalidate channel type */
-       d40c->dma_cfg.channel_type = 0;
+       d40c->configured = false;
        d40c->base->lookup_phy_chans[phy->num] = NULL;
 
        return 0;
@@ -1704,6 +1725,9 @@ bool stedma40_filter(struct dma_chan *chan, void *data)
        } else
                err = d40_config_memcpy(d40c);
 
+       if (!err)
+               d40c->configured = true;
+
        return err == 0;
 }
 EXPORT_SYMBOL(stedma40_filter);
@@ -1720,12 +1744,8 @@ static int d40_alloc_chan_resources(struct dma_chan *chan)
 
        d40c->completed = chan->cookie = 1;
 
-       /*
-        * If no dma configuration is set (channel_type == 0)
-        * use default configuration (memcpy)
-        */
-       if (d40c->dma_cfg.channel_type == 0) {
-
+       /* If no dma configuration is set use default configuration (memcpy) */
+       if (!d40c->configured) {
                err = d40_config_memcpy(d40c);
                if (err) {
                        dev_err(&d40c->chan.dev->device,
@@ -2231,11 +2251,11 @@ static void d40_set_runtime_config(struct dma_chan *chan,
        /* Set up all the endpoint configs */
        cfg->src_info.data_width = addr_width;
        cfg->src_info.psize = psize;
-       cfg->src_info.endianess = STEDMA40_LITTLE_ENDIAN;
+       cfg->src_info.big_endian = false;
        cfg->src_info.flow_ctrl = STEDMA40_NO_FLOW_CTRL;
        cfg->dst_info.data_width = addr_width;
        cfg->dst_info.psize = psize;
-       cfg->dst_info.endianess = STEDMA40_LITTLE_ENDIAN;
+       cfg->dst_info.big_endian = false;
        cfg->dst_info.flow_ctrl = STEDMA40_NO_FLOW_CTRL;
 
        /* Fill in register values */
index 86a306dbe1b4eeb92e4ded94ed15b96c669f6c14..8557cb88b255858efe98dbe0811c05ac4bf1c4a8 100644 (file)
@@ -108,13 +108,15 @@ void d40_phy_cfg(struct stedma40_chan_cfg *cfg,
                src |= 1 << D40_SREG_CFG_LOG_GIM_POS;
        }
 
-       if (cfg->channel_type & STEDMA40_HIGH_PRIORITY_CHANNEL) {
+       if (cfg->high_priority) {
                src |= 1 << D40_SREG_CFG_PRI_POS;
                dst |= 1 << D40_SREG_CFG_PRI_POS;
        }
 
-       src |= cfg->src_info.endianess << D40_SREG_CFG_LBE_POS;
-       dst |= cfg->dst_info.endianess << D40_SREG_CFG_LBE_POS;
+       if (cfg->src_info.big_endian)
+               src |= 1 << D40_SREG_CFG_LBE_POS;
+       if (cfg->dst_info.big_endian)
+               dst |= 1 << D40_SREG_CFG_LBE_POS;
 
        *src_cfg = src;
        *dst_cfg = dst;
index 37f81e84cd135fc889756e9b5763c3e470ee8e6e..9e419b907544bc3b6e1ba7bcfb7ffccbf22600cb 100644 (file)
 #define D40_DREG_PRMSO         0x014
 #define D40_DREG_PRMOE         0x018
 #define D40_DREG_PRMOO         0x01C
+#define D40_DREG_PRMO_PCHAN_BASIC              0x1
+#define D40_DREG_PRMO_PCHAN_MODULO             0x2
+#define D40_DREG_PRMO_PCHAN_DOUBLE_DST         0x3
+#define D40_DREG_PRMO_LCHAN_SRC_PHY_DST_LOG    0x1
+#define D40_DREG_PRMO_LCHAN_SRC_LOG_DST_PHY    0x2
+#define D40_DREG_PRMO_LCHAN_SRC_LOG_DST_LOG    0x3
+
 #define D40_DREG_LCPA          0x020
 #define D40_DREG_LCLA          0x024
 #define D40_DREG_ACTIVE                0x050