aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDan Williams <dan.j.williams@intel.com>2010-10-19 18:34:26 -0400
committerDan Williams <dan.j.williams@intel.com>2010-10-19 18:34:26 -0400
commit42e55736f7efd7658f8826a5f441c3ccb962db74 (patch)
tree150a54e47af512c72a1ec105d31fcdfa9957a673
parent9cb047d4d19fc15791a64d900d483405eae6200d (diff)
parent5c3720935813c45c2893fdb53eb6f73f1aee93c7 (diff)
Merge branch 'dma40' into dmaengine
-rw-r--r--arch/arm/mach-ux500/devices-db8500.c12
-rw-r--r--arch/arm/plat-nomadik/include/plat/ste_dma40.h60
-rw-r--r--drivers/dma/ste_dma40.c56
-rw-r--r--drivers/dma/ste_dma40_ll.c8
-rw-r--r--drivers/dma/ste_dma40_ll.h7
5 files changed, 72 insertions, 71 deletions
diff --git a/arch/arm/mach-ux500/devices-db8500.c b/arch/arm/mach-ux500/devices-db8500.c
index 58b3e723b183..c04bf2b61dcd 100644
--- a/arch/arm/mach-ux500/devices-db8500.c
+++ b/arch/arm/mach-ux500/devices-db8500.c
@@ -132,35 +132,25 @@ static struct resource dma40_resources[] = {
132 132
133/* Default configuration for physcial memcpy */ 133/* Default configuration for physcial memcpy */
134struct stedma40_chan_cfg dma40_memcpy_conf_phy = { 134struct stedma40_chan_cfg dma40_memcpy_conf_phy = {
135 .channel_type = (STEDMA40_CHANNEL_IN_PHY_MODE | 135 .mode = STEDMA40_MODE_PHYSICAL,
136 STEDMA40_LOW_PRIORITY_CHANNEL |
137 STEDMA40_PCHAN_BASIC_MODE),
138 .dir = STEDMA40_MEM_TO_MEM, 136 .dir = STEDMA40_MEM_TO_MEM,
139 137
140 .src_info.endianess = STEDMA40_LITTLE_ENDIAN,
141 .src_info.data_width = STEDMA40_BYTE_WIDTH, 138 .src_info.data_width = STEDMA40_BYTE_WIDTH,
142 .src_info.psize = STEDMA40_PSIZE_PHY_1, 139 .src_info.psize = STEDMA40_PSIZE_PHY_1,
143 .src_info.flow_ctrl = STEDMA40_NO_FLOW_CTRL, 140 .src_info.flow_ctrl = STEDMA40_NO_FLOW_CTRL,
144 141
145 .dst_info.endianess = STEDMA40_LITTLE_ENDIAN,
146 .dst_info.data_width = STEDMA40_BYTE_WIDTH, 142 .dst_info.data_width = STEDMA40_BYTE_WIDTH,
147 .dst_info.psize = STEDMA40_PSIZE_PHY_1, 143 .dst_info.psize = STEDMA40_PSIZE_PHY_1,
148 .dst_info.flow_ctrl = STEDMA40_NO_FLOW_CTRL, 144 .dst_info.flow_ctrl = STEDMA40_NO_FLOW_CTRL,
149}; 145};
150/* Default configuration for logical memcpy */ 146/* Default configuration for logical memcpy */
151struct stedma40_chan_cfg dma40_memcpy_conf_log = { 147struct stedma40_chan_cfg dma40_memcpy_conf_log = {
152 .channel_type = (STEDMA40_CHANNEL_IN_LOG_MODE |
153 STEDMA40_LOW_PRIORITY_CHANNEL |
154 STEDMA40_LCHAN_SRC_LOG_DST_LOG |
155 STEDMA40_NO_TIM_FOR_LINK),
156 .dir = STEDMA40_MEM_TO_MEM, 148 .dir = STEDMA40_MEM_TO_MEM,
157 149
158 .src_info.endianess = STEDMA40_LITTLE_ENDIAN,
159 .src_info.data_width = STEDMA40_BYTE_WIDTH, 150 .src_info.data_width = STEDMA40_BYTE_WIDTH,
160 .src_info.psize = STEDMA40_PSIZE_LOG_1, 151 .src_info.psize = STEDMA40_PSIZE_LOG_1,
161 .src_info.flow_ctrl = STEDMA40_NO_FLOW_CTRL, 152 .src_info.flow_ctrl = STEDMA40_NO_FLOW_CTRL,
162 153
163 .dst_info.endianess = STEDMA40_LITTLE_ENDIAN,
164 .dst_info.data_width = STEDMA40_BYTE_WIDTH, 154 .dst_info.data_width = STEDMA40_BYTE_WIDTH,
165 .dst_info.psize = STEDMA40_PSIZE_LOG_1, 155 .dst_info.psize = STEDMA40_PSIZE_LOG_1,
166 .dst_info.flow_ctrl = STEDMA40_NO_FLOW_CTRL, 156 .dst_info.flow_ctrl = STEDMA40_NO_FLOW_CTRL,
diff --git a/arch/arm/plat-nomadik/include/plat/ste_dma40.h b/arch/arm/plat-nomadik/include/plat/ste_dma40.h
index 3dd42551de04..da1f08ff9ee2 100644
--- a/arch/arm/plat-nomadik/include/plat/ste_dma40.h
+++ b/arch/arm/plat-nomadik/include/plat/ste_dma40.h
@@ -18,37 +18,20 @@
18#define STEDMA40_DEV_DST_MEMORY (-1) 18#define STEDMA40_DEV_DST_MEMORY (-1)
19#define STEDMA40_DEV_SRC_MEMORY (-1) 19#define STEDMA40_DEV_SRC_MEMORY (-1)
20 20
21/* 21enum stedma40_mode {
22 * Description of bitfields of channel_type variable is available in 22 STEDMA40_MODE_LOGICAL = 0,
23 * the info structure. 23 STEDMA40_MODE_PHYSICAL,
24 */ 24 STEDMA40_MODE_OPERATION,
25};
25 26
26/* Priority */ 27enum stedma40_mode_opt {
27#define STEDMA40_INFO_PRIO_TYPE_POS 2 28 STEDMA40_PCHAN_BASIC_MODE = 0,
28#define STEDMA40_HIGH_PRIORITY_CHANNEL (0x1 << STEDMA40_INFO_PRIO_TYPE_POS) 29 STEDMA40_LCHAN_SRC_LOG_DST_LOG = 0,
29#define STEDMA40_LOW_PRIORITY_CHANNEL (0x2 << STEDMA40_INFO_PRIO_TYPE_POS) 30 STEDMA40_PCHAN_MODULO_MODE,
30 31 STEDMA40_PCHAN_DOUBLE_DST_MODE,
31/* Mode */ 32 STEDMA40_LCHAN_SRC_PHY_DST_LOG,
32#define STEDMA40_INFO_CH_MODE_TYPE_POS 6 33 STEDMA40_LCHAN_SRC_LOG_DST_PHY,
33#define STEDMA40_CHANNEL_IN_PHY_MODE (0x1 << STEDMA40_INFO_CH_MODE_TYPE_POS) 34};
34#define STEDMA40_CHANNEL_IN_LOG_MODE (0x2 << STEDMA40_INFO_CH_MODE_TYPE_POS)
35#define STEDMA40_CHANNEL_IN_OPER_MODE (0x3 << STEDMA40_INFO_CH_MODE_TYPE_POS)
36
37/* Mode options */
38#define STEDMA40_INFO_CH_MODE_OPT_POS 8
39#define STEDMA40_PCHAN_BASIC_MODE (0x1 << STEDMA40_INFO_CH_MODE_OPT_POS)
40#define STEDMA40_PCHAN_MODULO_MODE (0x2 << STEDMA40_INFO_CH_MODE_OPT_POS)
41#define STEDMA40_PCHAN_DOUBLE_DST_MODE (0x3 << STEDMA40_INFO_CH_MODE_OPT_POS)
42#define STEDMA40_LCHAN_SRC_PHY_DST_LOG (0x1 << STEDMA40_INFO_CH_MODE_OPT_POS)
43#define STEDMA40_LCHAN_SRC_LOG_DST_PHS (0x2 << STEDMA40_INFO_CH_MODE_OPT_POS)
44#define STEDMA40_LCHAN_SRC_LOG_DST_LOG (0x3 << STEDMA40_INFO_CH_MODE_OPT_POS)
45
46/* Interrupt */
47#define STEDMA40_INFO_TIM_POS 10
48#define STEDMA40_NO_TIM_FOR_LINK (0x0 << STEDMA40_INFO_TIM_POS)
49#define STEDMA40_TIM_FOR_LINK (0x1 << STEDMA40_INFO_TIM_POS)
50
51/* End of channel_type configuration */
52 35
53#define STEDMA40_ESIZE_8_BIT 0x0 36#define STEDMA40_ESIZE_8_BIT 0x0
54#define STEDMA40_ESIZE_16_BIT 0x1 37#define STEDMA40_ESIZE_16_BIT 0x1
@@ -79,11 +62,6 @@ enum stedma40_flow_ctrl {
79 STEDMA40_FLOW_CTRL, 62 STEDMA40_FLOW_CTRL,
80}; 63};
81 64
82enum stedma40_endianess {
83 STEDMA40_LITTLE_ENDIAN,
84 STEDMA40_BIG_ENDIAN
85};
86
87enum stedma40_periph_data_width { 65enum stedma40_periph_data_width {
88 STEDMA40_BYTE_WIDTH = STEDMA40_ESIZE_8_BIT, 66 STEDMA40_BYTE_WIDTH = STEDMA40_ESIZE_8_BIT,
89 STEDMA40_HALFWORD_WIDTH = STEDMA40_ESIZE_16_BIT, 67 STEDMA40_HALFWORD_WIDTH = STEDMA40_ESIZE_16_BIT,
@@ -102,13 +80,13 @@ enum stedma40_xfer_dir {
102/** 80/**
103 * struct stedma40_chan_cfg - dst/src channel configuration 81 * struct stedma40_chan_cfg - dst/src channel configuration
104 * 82 *
105 * @endianess: Endianess of the src/dst hardware 83 * @big_endian: true if the src/dst should be read as big endian
106 * @data_width: Data width of the src/dst hardware 84 * @data_width: Data width of the src/dst hardware
107 * @p_size: Burst size 85 * @p_size: Burst size
108 * @flow_ctrl: Flow control on/off. 86 * @flow_ctrl: Flow control on/off.
109 */ 87 */
110struct stedma40_half_channel_info { 88struct stedma40_half_channel_info {
111 enum stedma40_endianess endianess; 89 bool big_endian;
112 enum stedma40_periph_data_width data_width; 90 enum stedma40_periph_data_width data_width;
113 int psize; 91 int psize;
114 enum stedma40_flow_ctrl flow_ctrl; 92 enum stedma40_flow_ctrl flow_ctrl;
@@ -118,7 +96,9 @@ struct stedma40_half_channel_info {
118 * struct stedma40_chan_cfg - Structure to be filled by client drivers. 96 * struct stedma40_chan_cfg - Structure to be filled by client drivers.
119 * 97 *
120 * @dir: MEM 2 MEM, PERIPH 2 MEM , MEM 2 PERIPH, PERIPH 2 PERIPH 98 * @dir: MEM 2 MEM, PERIPH 2 MEM , MEM 2 PERIPH, PERIPH 2 PERIPH
121 * @channel_type: priority, mode, mode options and interrupt configuration. 99 * @high_priority: true if high-priority
100 * @mode: channel mode: physical, logical, or operation
101 * @mode_opt: options for the chosen channel mode
122 * @src_dev_type: Src device type 102 * @src_dev_type: Src device type
123 * @dst_dev_type: Dst device type 103 * @dst_dev_type: Dst device type
124 * @src_info: Parameters for dst half channel 104 * @src_info: Parameters for dst half channel
@@ -131,7 +111,9 @@ struct stedma40_half_channel_info {
131 */ 111 */
132struct stedma40_chan_cfg { 112struct stedma40_chan_cfg {
133 enum stedma40_xfer_dir dir; 113 enum stedma40_xfer_dir dir;
134 unsigned int channel_type; 114 bool high_priority;
115 enum stedma40_mode mode;
116 enum stedma40_mode_opt mode_opt;
135 int src_dev_type; 117 int src_dev_type;
136 int dst_dev_type; 118 int dst_dev_type;
137 struct stedma40_half_channel_info src_info; 119 struct stedma40_half_channel_info src_info;
diff --git a/drivers/dma/ste_dma40.c b/drivers/dma/ste_dma40.c
index 3f76cd9af7c3..fab68a553205 100644
--- a/drivers/dma/ste_dma40.c
+++ b/drivers/dma/ste_dma40.c
@@ -175,6 +175,7 @@ struct d40_base;
175 * @active: Active descriptor. 175 * @active: Active descriptor.
176 * @queue: Queued jobs. 176 * @queue: Queued jobs.
177 * @dma_cfg: The client configuration of this dma channel. 177 * @dma_cfg: The client configuration of this dma channel.
178 * @configured: whether the dma_cfg configuration is valid
178 * @base: Pointer to the device instance struct. 179 * @base: Pointer to the device instance struct.
179 * @src_def_cfg: Default cfg register setting for src. 180 * @src_def_cfg: Default cfg register setting for src.
180 * @dst_def_cfg: Default cfg register setting for dst. 181 * @dst_def_cfg: Default cfg register setting for dst.
@@ -198,6 +199,7 @@ struct d40_chan {
198 struct list_head active; 199 struct list_head active;
199 struct list_head queue; 200 struct list_head queue;
200 struct stedma40_chan_cfg dma_cfg; 201 struct stedma40_chan_cfg dma_cfg;
202 bool configured;
201 struct d40_base *base; 203 struct d40_base *base;
202 /* Default register configurations */ 204 /* Default register configurations */
203 u32 src_def_cfg; 205 u32 src_def_cfg;
@@ -691,6 +693,31 @@ static u32 d40_chan_has_events(struct d40_chan *d40c)
691 return val; 693 return val;
692} 694}
693 695
696static u32 d40_get_prmo(struct d40_chan *d40c)
697{
698 static const unsigned int phy_map[] = {
699 [STEDMA40_PCHAN_BASIC_MODE]
700 = D40_DREG_PRMO_PCHAN_BASIC,
701 [STEDMA40_PCHAN_MODULO_MODE]
702 = D40_DREG_PRMO_PCHAN_MODULO,
703 [STEDMA40_PCHAN_DOUBLE_DST_MODE]
704 = D40_DREG_PRMO_PCHAN_DOUBLE_DST,
705 };
706 static const unsigned int log_map[] = {
707 [STEDMA40_LCHAN_SRC_PHY_DST_LOG]
708 = D40_DREG_PRMO_LCHAN_SRC_PHY_DST_LOG,
709 [STEDMA40_LCHAN_SRC_LOG_DST_PHY]
710 = D40_DREG_PRMO_LCHAN_SRC_LOG_DST_PHY,
711 [STEDMA40_LCHAN_SRC_LOG_DST_LOG]
712 = D40_DREG_PRMO_LCHAN_SRC_LOG_DST_LOG,
713 };
714
715 if (d40c->log_num == D40_PHY_CHAN)
716 return phy_map[d40c->dma_cfg.mode_opt];
717 else
718 return log_map[d40c->dma_cfg.mode_opt];
719}
720
694static void d40_config_write(struct d40_chan *d40c) 721static void d40_config_write(struct d40_chan *d40c)
695{ 722{
696 u32 addr_base; 723 u32 addr_base;
@@ -704,8 +731,7 @@ static void d40_config_write(struct d40_chan *d40c)
704 writel(var, d40c->base->virtbase + D40_DREG_PRMSE + addr_base); 731 writel(var, d40c->base->virtbase + D40_DREG_PRMSE + addr_base);
705 732
706 /* Setup operational mode option register */ 733 /* Setup operational mode option register */
707 var = ((d40c->dma_cfg.channel_type >> STEDMA40_INFO_CH_MODE_OPT_POS) & 734 var = d40_get_prmo(d40c) << D40_CHAN_POS(d40c->phy_chan->num);
708 0x3) << D40_CHAN_POS(d40c->phy_chan->num);
709 735
710 writel(var, d40c->base->virtbase + D40_DREG_PRMOE + addr_base); 736 writel(var, d40c->base->virtbase + D40_DREG_PRMOE + addr_base);
711 737
@@ -1149,8 +1175,7 @@ static int d40_validate_conf(struct d40_chan *d40c,
1149 int res = 0; 1175 int res = 0;
1150 u32 dst_event_group = D40_TYPE_TO_GROUP(conf->dst_dev_type); 1176 u32 dst_event_group = D40_TYPE_TO_GROUP(conf->dst_dev_type);
1151 u32 src_event_group = D40_TYPE_TO_GROUP(conf->src_dev_type); 1177 u32 src_event_group = D40_TYPE_TO_GROUP(conf->src_dev_type);
1152 bool is_log = (conf->channel_type & STEDMA40_CHANNEL_IN_OPER_MODE) 1178 bool is_log = conf->mode == STEDMA40_MODE_LOGICAL;
1153 == STEDMA40_CHANNEL_IN_LOG_MODE;
1154 1179
1155 if (!conf->dir) { 1180 if (!conf->dir) {
1156 dev_err(&d40c->chan.dev->device, "[%s] Invalid direction.\n", 1181 dev_err(&d40c->chan.dev->device, "[%s] Invalid direction.\n",
@@ -1314,10 +1339,7 @@ static int d40_allocate_channel(struct d40_chan *d40c)
1314 int j; 1339 int j;
1315 int log_num; 1340 int log_num;
1316 bool is_src; 1341 bool is_src;
1317 bool is_log = (d40c->dma_cfg.channel_type & 1342 bool is_log = d40c->dma_cfg.mode == STEDMA40_MODE_LOGICAL;
1318 STEDMA40_CHANNEL_IN_OPER_MODE)
1319 == STEDMA40_CHANNEL_IN_LOG_MODE;
1320
1321 1343
1322 phys = d40c->base->phy_res; 1344 phys = d40c->base->phy_res;
1323 1345
@@ -1518,8 +1540,7 @@ static int d40_free_dma(struct d40_chan *d40c)
1518 return res; 1540 return res;
1519 } 1541 }
1520 d40c->phy_chan = NULL; 1542 d40c->phy_chan = NULL;
1521 /* Invalidate channel type */ 1543 d40c->configured = false;
1522 d40c->dma_cfg.channel_type = 0;
1523 d40c->base->lookup_phy_chans[phy->num] = NULL; 1544 d40c->base->lookup_phy_chans[phy->num] = NULL;
1524 1545
1525 return 0; 1546 return 0;
@@ -1704,6 +1725,9 @@ bool stedma40_filter(struct dma_chan *chan, void *data)
1704 } else 1725 } else
1705 err = d40_config_memcpy(d40c); 1726 err = d40_config_memcpy(d40c);
1706 1727
1728 if (!err)
1729 d40c->configured = true;
1730
1707 return err == 0; 1731 return err == 0;
1708} 1732}
1709EXPORT_SYMBOL(stedma40_filter); 1733EXPORT_SYMBOL(stedma40_filter);
@@ -1720,12 +1744,8 @@ static int d40_alloc_chan_resources(struct dma_chan *chan)
1720 1744
1721 d40c->completed = chan->cookie = 1; 1745 d40c->completed = chan->cookie = 1;
1722 1746
1723 /* 1747 /* If no dma configuration is set use default configuration (memcpy) */
1724 * If no dma configuration is set (channel_type == 0) 1748 if (!d40c->configured) {
1725 * use default configuration (memcpy)
1726 */
1727 if (d40c->dma_cfg.channel_type == 0) {
1728
1729 err = d40_config_memcpy(d40c); 1749 err = d40_config_memcpy(d40c);
1730 if (err) { 1750 if (err) {
1731 dev_err(&d40c->chan.dev->device, 1751 dev_err(&d40c->chan.dev->device,
@@ -2231,11 +2251,11 @@ static void d40_set_runtime_config(struct dma_chan *chan,
2231 /* Set up all the endpoint configs */ 2251 /* Set up all the endpoint configs */
2232 cfg->src_info.data_width = addr_width; 2252 cfg->src_info.data_width = addr_width;
2233 cfg->src_info.psize = psize; 2253 cfg->src_info.psize = psize;
2234 cfg->src_info.endianess = STEDMA40_LITTLE_ENDIAN; 2254 cfg->src_info.big_endian = false;
2235 cfg->src_info.flow_ctrl = STEDMA40_NO_FLOW_CTRL; 2255 cfg->src_info.flow_ctrl = STEDMA40_NO_FLOW_CTRL;
2236 cfg->dst_info.data_width = addr_width; 2256 cfg->dst_info.data_width = addr_width;
2237 cfg->dst_info.psize = psize; 2257 cfg->dst_info.psize = psize;
2238 cfg->dst_info.endianess = STEDMA40_LITTLE_ENDIAN; 2258 cfg->dst_info.big_endian = false;
2239 cfg->dst_info.flow_ctrl = STEDMA40_NO_FLOW_CTRL; 2259 cfg->dst_info.flow_ctrl = STEDMA40_NO_FLOW_CTRL;
2240 2260
2241 /* Fill in register values */ 2261 /* Fill in register values */
diff --git a/drivers/dma/ste_dma40_ll.c b/drivers/dma/ste_dma40_ll.c
index 86a306dbe1b4..8557cb88b255 100644
--- a/drivers/dma/ste_dma40_ll.c
+++ b/drivers/dma/ste_dma40_ll.c
@@ -108,13 +108,15 @@ void d40_phy_cfg(struct stedma40_chan_cfg *cfg,
108 src |= 1 << D40_SREG_CFG_LOG_GIM_POS; 108 src |= 1 << D40_SREG_CFG_LOG_GIM_POS;
109 } 109 }
110 110
111 if (cfg->channel_type & STEDMA40_HIGH_PRIORITY_CHANNEL) { 111 if (cfg->high_priority) {
112 src |= 1 << D40_SREG_CFG_PRI_POS; 112 src |= 1 << D40_SREG_CFG_PRI_POS;
113 dst |= 1 << D40_SREG_CFG_PRI_POS; 113 dst |= 1 << D40_SREG_CFG_PRI_POS;
114 } 114 }
115 115
116 src |= cfg->src_info.endianess << D40_SREG_CFG_LBE_POS; 116 if (cfg->src_info.big_endian)
117 dst |= cfg->dst_info.endianess << D40_SREG_CFG_LBE_POS; 117 src |= 1 << D40_SREG_CFG_LBE_POS;
118 if (cfg->dst_info.big_endian)
119 dst |= 1 << D40_SREG_CFG_LBE_POS;
118 120
119 *src_cfg = src; 121 *src_cfg = src;
120 *dst_cfg = dst; 122 *dst_cfg = dst;
diff --git a/drivers/dma/ste_dma40_ll.h b/drivers/dma/ste_dma40_ll.h
index 37f81e84cd13..9e419b907544 100644
--- a/drivers/dma/ste_dma40_ll.h
+++ b/drivers/dma/ste_dma40_ll.h
@@ -130,6 +130,13 @@
130#define D40_DREG_PRMSO 0x014 130#define D40_DREG_PRMSO 0x014
131#define D40_DREG_PRMOE 0x018 131#define D40_DREG_PRMOE 0x018
132#define D40_DREG_PRMOO 0x01C 132#define D40_DREG_PRMOO 0x01C
133#define D40_DREG_PRMO_PCHAN_BASIC 0x1
134#define D40_DREG_PRMO_PCHAN_MODULO 0x2
135#define D40_DREG_PRMO_PCHAN_DOUBLE_DST 0x3
136#define D40_DREG_PRMO_LCHAN_SRC_PHY_DST_LOG 0x1
137#define D40_DREG_PRMO_LCHAN_SRC_LOG_DST_PHY 0x2
138#define D40_DREG_PRMO_LCHAN_SRC_LOG_DST_LOG 0x3
139
133#define D40_DREG_LCPA 0x020 140#define D40_DREG_LCPA 0x020
134#define D40_DREG_LCLA 0x024 141#define D40_DREG_LCLA 0x024
135#define D40_DREG_ACTIVE 0x050 142#define D40_DREG_ACTIVE 0x050