aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/dma/ste_dma40.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/dma/ste_dma40.c')
-rw-r--r--drivers/dma/ste_dma40.c56
1 files changed, 38 insertions, 18 deletions
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 */