2013-04-09 18:39:52

by Lee Jones

[permalink] [raw]
Subject: [PATCH 1/8] dmaengine: ste_dma40: Assign memcpy channels in the driver

The channels reserved for memcpy are the same for all currently
supported platforms. With this in mind, we can ease the platform
data passing requirement by moving these assignments out from
platform code and place them directly into the driver.

Cc: Vinod Koul <[email protected]>
Cc: Dan Williams <[email protected]>
Cc: Per Forlin <[email protected]>
Acked-by: Arnd Bergmann <[email protected]>
Signed-off-by: Lee Jones <[email protected]>
---
arch/arm/mach-ux500/devices-db8500.c | 12 ------------
drivers/dma/ste_dma40.c | 12 +++++++-----
include/linux/platform_data/dma-ste-dma40.h | 4 ----
3 files changed, 7 insertions(+), 21 deletions(-)

diff --git a/arch/arm/mach-ux500/devices-db8500.c b/arch/arm/mach-ux500/devices-db8500.c
index afa5b04..9b09683 100644
--- a/arch/arm/mach-ux500/devices-db8500.c
+++ b/arch/arm/mach-ux500/devices-db8500.c
@@ -146,22 +146,10 @@ static const dma_addr_t dma40_rx_map[DB8500_DMA_NR_DEV] = {
[DB8500_DMA_DEV48_CAC1_RX] = U8500_CRYP1_BASE + CRYP1_RX_REG_OFFSET,
};

-/* Reserved event lines for memcpy only */
-static int dma40_memcpy_event[] = {
- DB8500_DMA_MEMCPY_TX_0,
- DB8500_DMA_MEMCPY_TX_1,
- DB8500_DMA_MEMCPY_TX_2,
- DB8500_DMA_MEMCPY_TX_3,
- DB8500_DMA_MEMCPY_TX_4,
- DB8500_DMA_MEMCPY_TX_5,
-};
-
static struct stedma40_platform_data dma40_plat_data = {
.dev_len = DB8500_DMA_NR_DEV,
.dev_rx = dma40_rx_map,
.dev_tx = dma40_tx_map,
- .memcpy = dma40_memcpy_event,
- .memcpy_len = ARRAY_SIZE(dma40_memcpy_event),
.memcpy_conf_phy = &dma40_memcpy_conf_phy,
.memcpy_conf_log = &dma40_memcpy_conf_log,
.disabled_channels = {-1},
diff --git a/drivers/dma/ste_dma40.c b/drivers/dma/ste_dma40.c
index 1734fee..12de79e 100644
--- a/drivers/dma/ste_dma40.c
+++ b/drivers/dma/ste_dma40.c
@@ -55,6 +55,9 @@

#define MAX(a, b) (((a) < (b)) ? (b) : (a))

+/* Reserved event lines for memcpy only. */
+static int dma40_memcpy_channels[] = { 56, 57, 58, 59, 60 };
+
/**
* enum 40_command - The different commands and/or statuses.
*
@@ -2014,8 +2017,7 @@ static int d40_config_memcpy(struct d40_chan *d40c)
if (dma_has_cap(DMA_MEMCPY, cap) && !dma_has_cap(DMA_SLAVE, cap)) {
d40c->dma_cfg = *d40c->base->plat_data->memcpy_conf_log;
d40c->dma_cfg.src_dev_type = STEDMA40_DEV_SRC_MEMORY;
- d40c->dma_cfg.dst_dev_type = d40c->base->plat_data->
- memcpy[d40c->chan.chan_id];
+ d40c->dma_cfg.dst_dev_type = dma40_memcpy_channels[d40c->chan.chan_id];

} else if (dma_has_cap(DMA_MEMCPY, cap) &&
dma_has_cap(DMA_SLAVE, cap)) {
@@ -2927,7 +2929,7 @@ static int __init d40_dmaengine_init(struct d40_base *base,
}

d40_chan_init(base, &base->dma_memcpy, base->log_chans,
- base->num_log_chans, base->plat_data->memcpy_len);
+ base->num_log_chans, ARRAY_SIZE(dma40_memcpy_channels));

dma_cap_zero(base->dma_memcpy.cap_mask);
dma_cap_set(DMA_MEMCPY, base->dma_memcpy.cap_mask);
@@ -3215,7 +3217,7 @@ static struct d40_base * __init d40_hw_detect_init(struct platform_device *pdev)
num_log_chans++;

base = kzalloc(ALIGN(sizeof(struct d40_base), 4) +
- (num_phy_chans + num_log_chans + plat_data->memcpy_len) *
+ (num_phy_chans + num_log_chans + ARRAY_SIZE(dma40_memcpy_channels)) *
sizeof(struct d40_chan), GFP_KERNEL);

if (base == NULL) {
@@ -3276,7 +3278,7 @@ static struct d40_base * __init d40_hw_detect_init(struct platform_device *pdev)
if (!base->lookup_phy_chans)
goto failure;

- if (num_log_chans + plat_data->memcpy_len) {
+ if (num_log_chans + ARRAY_SIZE(dma40_memcpy_channels)) {
/*
* The max number of logical channels are event lines for all
* src devices and dst devices
diff --git a/include/linux/platform_data/dma-ste-dma40.h b/include/linux/platform_data/dma-ste-dma40.h
index 4b78101..a808784 100644
--- a/include/linux/platform_data/dma-ste-dma40.h
+++ b/include/linux/platform_data/dma-ste-dma40.h
@@ -141,8 +141,6 @@ struct stedma40_chan_cfg {
* @dev_len: length of dev_tx and dev_rx
* @dev_tx: mapping between destination event line and io address
* @dev_rx: mapping between source event line and io address
- * @memcpy: list of memcpy event lines
- * @memcpy_len: length of memcpy
* @memcpy_conf_phy: default configuration of physical channel memcpy
* @memcpy_conf_log: default configuration of logical channel memcpy
* @disabled_channels: A vector, ending with -1, that marks physical channels
@@ -162,8 +160,6 @@ struct stedma40_platform_data {
u32 dev_len;
const dma_addr_t *dev_tx;
const dma_addr_t *dev_rx;
- int *memcpy;
- u32 memcpy_len;
struct stedma40_chan_cfg *memcpy_conf_phy;
struct stedma40_chan_cfg *memcpy_conf_log;
int disabled_channels[STEDMA40_MAX_PHYS];
--
1.7.10.4


2013-04-09 18:39:55

by Lee Jones

[permalink] [raw]
Subject: [PATCH 2/8] dmaengine: ste_dma40: Move default memcpy configs into the driver

There are only two default memcpy configurations used for the DMA40
driver; one for physical memcpy and one for logical memcpy. Instead
of invariably passing the same configurations though platform data,
we're moving them into the driver instead.

Cc: Vinod Koul <[email protected]>
Cc: Dan Williams <[email protected]>
Cc: Per Forlin <[email protected]>
Acked-by: Arnd Bergmann <[email protected]>
Signed-off-by: Lee Jones <[email protected]>
---
arch/arm/mach-ux500/devices-db8500.c | 28 -----------------------
drivers/dma/ste_dma40.c | 32 +++++++++++++++++++++++++--
include/linux/platform_data/dma-ste-dma40.h | 4 ----
3 files changed, 30 insertions(+), 34 deletions(-)

diff --git a/arch/arm/mach-ux500/devices-db8500.c b/arch/arm/mach-ux500/devices-db8500.c
index 9b09683..5b1f1f7 100644
--- a/arch/arm/mach-ux500/devices-db8500.c
+++ b/arch/arm/mach-ux500/devices-db8500.c
@@ -42,32 +42,6 @@ static struct resource dma40_resources[] = {
}
};

-/* Default configuration for physcial memcpy */
-struct stedma40_chan_cfg dma40_memcpy_conf_phy = {
- .mode = STEDMA40_MODE_PHYSICAL,
- .dir = STEDMA40_MEM_TO_MEM,
-
- .src_info.data_width = STEDMA40_BYTE_WIDTH,
- .src_info.psize = STEDMA40_PSIZE_PHY_1,
- .src_info.flow_ctrl = STEDMA40_NO_FLOW_CTRL,
-
- .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 = {
- .dir = STEDMA40_MEM_TO_MEM,
-
- .src_info.data_width = STEDMA40_BYTE_WIDTH,
- .src_info.psize = STEDMA40_PSIZE_LOG_1,
- .src_info.flow_ctrl = STEDMA40_NO_FLOW_CTRL,
-
- .dst_info.data_width = STEDMA40_BYTE_WIDTH,
- .dst_info.psize = STEDMA40_PSIZE_LOG_1,
- .dst_info.flow_ctrl = STEDMA40_NO_FLOW_CTRL,
-};
-
/*
* Mapping between destination event lines and physical device address.
* The event line is tied to a device and therefore the address is constant.
@@ -150,8 +124,6 @@ static struct stedma40_platform_data dma40_plat_data = {
.dev_len = DB8500_DMA_NR_DEV,
.dev_rx = dma40_rx_map,
.dev_tx = dma40_tx_map,
- .memcpy_conf_phy = &dma40_memcpy_conf_phy,
- .memcpy_conf_log = &dma40_memcpy_conf_log,
.disabled_channels = {-1},
};

diff --git a/drivers/dma/ste_dma40.c b/drivers/dma/ste_dma40.c
index 12de79e..3b83dee 100644
--- a/drivers/dma/ste_dma40.c
+++ b/drivers/dma/ste_dma40.c
@@ -58,6 +58,34 @@
/* Reserved event lines for memcpy only. */
static int dma40_memcpy_channels[] = { 56, 57, 58, 59, 60 };

+/* Default configuration for physcial memcpy */
+struct stedma40_chan_cfg dma40_memcpy_conf_phy = {
+ .mode = STEDMA40_MODE_PHYSICAL,
+ .dir = STEDMA40_MEM_TO_MEM,
+
+ .src_info.data_width = STEDMA40_BYTE_WIDTH,
+ .src_info.psize = STEDMA40_PSIZE_PHY_1,
+ .src_info.flow_ctrl = STEDMA40_NO_FLOW_CTRL,
+
+ .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 = {
+ .mode = STEDMA40_MODE_LOGICAL,
+ .dir = STEDMA40_MEM_TO_MEM,
+
+ .src_info.data_width = STEDMA40_BYTE_WIDTH,
+ .src_info.psize = STEDMA40_PSIZE_LOG_1,
+ .src_info.flow_ctrl = STEDMA40_NO_FLOW_CTRL,
+
+ .dst_info.data_width = STEDMA40_BYTE_WIDTH,
+ .dst_info.psize = STEDMA40_PSIZE_LOG_1,
+ .dst_info.flow_ctrl = STEDMA40_NO_FLOW_CTRL,
+};
+
/**
* enum 40_command - The different commands and/or statuses.
*
@@ -2015,13 +2043,13 @@ static int d40_config_memcpy(struct d40_chan *d40c)
dma_cap_mask_t cap = d40c->chan.device->cap_mask;

if (dma_has_cap(DMA_MEMCPY, cap) && !dma_has_cap(DMA_SLAVE, cap)) {
- d40c->dma_cfg = *d40c->base->plat_data->memcpy_conf_log;
+ d40c->dma_cfg = dma40_memcpy_conf_log;
d40c->dma_cfg.src_dev_type = STEDMA40_DEV_SRC_MEMORY;
d40c->dma_cfg.dst_dev_type = dma40_memcpy_channels[d40c->chan.chan_id];

} else if (dma_has_cap(DMA_MEMCPY, cap) &&
dma_has_cap(DMA_SLAVE, cap)) {
- d40c->dma_cfg = *d40c->base->plat_data->memcpy_conf_phy;
+ d40c->dma_cfg = dma40_memcpy_conf_phy;
} else {
chan_err(d40c, "No memcpy\n");
return -EINVAL;
diff --git a/include/linux/platform_data/dma-ste-dma40.h b/include/linux/platform_data/dma-ste-dma40.h
index a808784..869c571 100644
--- a/include/linux/platform_data/dma-ste-dma40.h
+++ b/include/linux/platform_data/dma-ste-dma40.h
@@ -141,8 +141,6 @@ struct stedma40_chan_cfg {
* @dev_len: length of dev_tx and dev_rx
* @dev_tx: mapping between destination event line and io address
* @dev_rx: mapping between source event line and io address
- * @memcpy_conf_phy: default configuration of physical channel memcpy
- * @memcpy_conf_log: default configuration of logical channel memcpy
* @disabled_channels: A vector, ending with -1, that marks physical channels
* that are for different reasons not available for the driver.
* @soft_lli_chans: A vector, that marks physical channels will use LLI by SW
@@ -160,8 +158,6 @@ struct stedma40_platform_data {
u32 dev_len;
const dma_addr_t *dev_tx;
const dma_addr_t *dev_rx;
- struct stedma40_chan_cfg *memcpy_conf_phy;
- struct stedma40_chan_cfg *memcpy_conf_log;
int disabled_channels[STEDMA40_MAX_PHYS];
int *soft_lli_chans;
int num_of_soft_lli_chans;
--
1.7.10.4

2013-04-09 18:40:07

by Lee Jones

[permalink] [raw]
Subject: [PATCH 6/8] dmaengine: ste_dma40: Move LCPA allocation and real-time config

There are various pieces of configuration which do not need to happen
until after a channel is allocated. Here we move some of these so they're
dealt with when it's time to configure the channel, rather than allocate
it.

Cc: Vinod Koul <[email protected]>
Cc: Dan Williams <[email protected]>
Cc: Per Forlin <[email protected]>
Signed-off-by: Lee Jones <[email protected]>
---
drivers/dma/ste_dma40.c | 24 ++++++++++++------------
1 file changed, 12 insertions(+), 12 deletions(-)

diff --git a/drivers/dma/ste_dma40.c b/drivers/dma/ste_dma40.c
index 49d8c9d..c14db3e 100644
--- a/drivers/dma/ste_dma40.c
+++ b/drivers/dma/ste_dma40.c
@@ -2464,18 +2464,6 @@ static int d40_alloc_chan_resources(struct dma_chan *chan)

pm_runtime_get_sync(d40c->base->dev);

- d40_set_prio_realtime(d40c);
-
- if (chan_is_logical(d40c)) {
- if (d40c->dma_cfg.dir == STEDMA40_PERIPH_TO_MEM)
- d40c->lcpa = d40c->base->lcpa_base +
- d40c->dma_cfg.src_dev_type * D40_LCPA_CHAN_SIZE;
- else
- d40c->lcpa = d40c->base->lcpa_base +
- d40c->dma_cfg.dst_dev_type *
- D40_LCPA_CHAN_SIZE + D40_LCPA_CHAN_DST_DELTA;
- }
-
dev_dbg(chan2dev(d40c), "allocated %s channel (phy %d%s)\n",
chan_is_logical(d40c) ? "logical" : "physical",
d40c->phy_chan->num,
@@ -2814,6 +2802,18 @@ static int d40_set_runtime_config(struct dma_chan *chan,
d40_phy_cfg(cfg, &d40c->src_def_cfg, &d40c->dst_def_cfg,
chan_is_logical(d40c));

+ d40_set_prio_realtime(d40c);
+
+ if (chan_is_logical(d40c)) {
+ if (cfg->dir == STEDMA40_PERIPH_TO_MEM)
+ d40c->lcpa = d40c->base->lcpa_base +
+ cfg->src_dev_type * D40_LCPA_CHAN_SIZE;
+ else
+ d40c->lcpa = d40c->base->lcpa_base +
+ cfg->dst_dev_type *
+ D40_LCPA_CHAN_SIZE + D40_LCPA_CHAN_DST_DELTA;
+ }
+
/* These settings will take precedence later */
d40c->runtime_addr = config_addr;
d40c->runtime_direction = config->direction;
--
1.7.10.4

2013-04-09 18:40:11

by Lee Jones

[permalink] [raw]
Subject: [PATCH 8/8] ARM: ux500: Amalgamate DMA source and destination channel numbers

Devices which utilise DMA tend to use the same channel numbers for
transmitting and receiving. For this reason and the fact that it'll
decrease the burden of platform data passed to each device, we're
amalgamating source and destination device types.

Signed-off-by: Lee Jones <[email protected]>
---
arch/arm/mach-ux500/board-mop500-audio.c | 18 +--
arch/arm/mach-ux500/board-mop500-sdi.c | 24 ++--
arch/arm/mach-ux500/board-mop500.c | 33 ++---
arch/arm/mach-ux500/cpu-db8500.c | 32 ++---
arch/arm/mach-ux500/devices-db8500.c | 120 ++++++++---------
arch/arm/mach-ux500/ste-dma40-db8500.h | 193 ++++++++++-----------------
arch/arm/mach-ux500/usb.c | 10 +-
drivers/dma/ste_dma40.c | 99 +++++---------
drivers/dma/ste_dma40_ll.c | 4 +-
include/linux/platform_data/dma-ste-dma40.h | 6 +-
10 files changed, 209 insertions(+), 330 deletions(-)

diff --git a/arch/arm/mach-ux500/board-mop500-audio.c b/arch/arm/mach-ux500/board-mop500-audio.c
index 7209db7..f012cfa 100644
--- a/arch/arm/mach-ux500/board-mop500-audio.c
+++ b/arch/arm/mach-ux500/board-mop500-audio.c
@@ -24,8 +24,7 @@ static struct stedma40_chan_cfg msp0_dma_rx = {
.high_priority = true,
.dir = STEDMA40_PERIPH_TO_MEM,

- .src_dev_type = DB8500_DMA_DEV31_MSP0_RX_SLIM0_CH0_RX,
- .dst_dev_type = STEDMA40_DEV_DST_MEMORY,
+ .dev_type = DB8500_DMA_DEV31_MSP0_SLIM0_CH0,

.src_info.psize = STEDMA40_PSIZE_LOG_4,
.dst_info.psize = STEDMA40_PSIZE_LOG_4,
@@ -37,8 +36,7 @@ static struct stedma40_chan_cfg msp0_dma_tx = {
.high_priority = true,
.dir = STEDMA40_MEM_TO_PERIPH,

- .src_dev_type = STEDMA40_DEV_DST_MEMORY,
- .dst_dev_type = DB8500_DMA_DEV31_MSP0_TX_SLIM0_CH0_TX,
+ .dev_type = DB8500_DMA_DEV31_MSP0_SLIM0_CH0,

.src_info.psize = STEDMA40_PSIZE_LOG_4,
.dst_info.psize = STEDMA40_PSIZE_LOG_4,
@@ -56,8 +54,7 @@ static struct stedma40_chan_cfg msp1_dma_rx = {
.high_priority = true,
.dir = STEDMA40_PERIPH_TO_MEM,

- .src_dev_type = DB8500_DMA_DEV30_MSP3_RX,
- .dst_dev_type = STEDMA40_DEV_DST_MEMORY,
+ .dev_type = DB8500_DMA_DEV30_MSP3,

.src_info.psize = STEDMA40_PSIZE_LOG_4,
.dst_info.psize = STEDMA40_PSIZE_LOG_4,
@@ -69,8 +66,7 @@ static struct stedma40_chan_cfg msp1_dma_tx = {
.high_priority = true,
.dir = STEDMA40_MEM_TO_PERIPH,

- .src_dev_type = STEDMA40_DEV_DST_MEMORY,
- .dst_dev_type = DB8500_DMA_DEV30_MSP1_TX,
+ .dev_type = DB8500_DMA_DEV30_MSP1,

.src_info.psize = STEDMA40_PSIZE_LOG_4,
.dst_info.psize = STEDMA40_PSIZE_LOG_4,
@@ -88,8 +84,7 @@ static struct stedma40_chan_cfg msp2_dma_rx = {
.high_priority = true,
.dir = STEDMA40_PERIPH_TO_MEM,

- .src_dev_type = DB8500_DMA_DEV14_MSP2_RX,
- .dst_dev_type = STEDMA40_DEV_DST_MEMORY,
+ .dev_type = DB8500_DMA_DEV14_MSP2,

/* MSP2 DMA doesn't work with PSIZE == 4 on DB8500v2 */
.src_info.psize = STEDMA40_PSIZE_LOG_1,
@@ -102,8 +97,7 @@ static struct stedma40_chan_cfg msp2_dma_tx = {
.high_priority = true,
.dir = STEDMA40_MEM_TO_PERIPH,

- .src_dev_type = STEDMA40_DEV_DST_MEMORY,
- .dst_dev_type = DB8500_DMA_DEV14_MSP2_TX,
+ .dev_type = DB8500_DMA_DEV14_MSP2,

.src_info.psize = STEDMA40_PSIZE_LOG_4,
.dst_info.psize = STEDMA40_PSIZE_LOG_4,
diff --git a/arch/arm/mach-ux500/board-mop500-sdi.c b/arch/arm/mach-ux500/board-mop500-sdi.c
index 7f2cb6c..5c28216 100644
--- a/arch/arm/mach-ux500/board-mop500-sdi.c
+++ b/arch/arm/mach-ux500/board-mop500-sdi.c
@@ -64,8 +64,7 @@ static int mop500_sdi0_ios_handler(struct device *dev, struct mmc_ios *ios)
struct stedma40_chan_cfg mop500_sdi0_dma_cfg_rx = {
.mode = STEDMA40_MODE_LOGICAL,
.dir = STEDMA40_PERIPH_TO_MEM,
- .src_dev_type = DB8500_DMA_DEV29_SD_MM0_RX,
- .dst_dev_type = STEDMA40_DEV_DST_MEMORY,
+ .dev_type = DB8500_DMA_DEV29_SD_MM0,
.src_info.data_width = STEDMA40_WORD_WIDTH,
.dst_info.data_width = STEDMA40_WORD_WIDTH,
};
@@ -73,8 +72,7 @@ struct stedma40_chan_cfg mop500_sdi0_dma_cfg_rx = {
static struct stedma40_chan_cfg mop500_sdi0_dma_cfg_tx = {
.mode = STEDMA40_MODE_LOGICAL,
.dir = STEDMA40_MEM_TO_PERIPH,
- .src_dev_type = STEDMA40_DEV_SRC_MEMORY,
- .dst_dev_type = DB8500_DMA_DEV29_SD_MM0_TX,
+ .dev_type = DB8500_DMA_DEV29_SD_MM0,
.src_info.data_width = STEDMA40_WORD_WIDTH,
.dst_info.data_width = STEDMA40_WORD_WIDTH,
};
@@ -135,8 +133,7 @@ void mop500_sdi_tc35892_init(struct device *parent)
static struct stedma40_chan_cfg sdi1_dma_cfg_rx = {
.mode = STEDMA40_MODE_LOGICAL,
.dir = STEDMA40_PERIPH_TO_MEM,
- .src_dev_type = DB8500_DMA_DEV32_SD_MM1_RX,
- .dst_dev_type = STEDMA40_DEV_DST_MEMORY,
+ .dev_type = DB8500_DMA_DEV32_SD_MM1,
.src_info.data_width = STEDMA40_WORD_WIDTH,
.dst_info.data_width = STEDMA40_WORD_WIDTH,
};
@@ -144,8 +141,7 @@ static struct stedma40_chan_cfg sdi1_dma_cfg_rx = {
static struct stedma40_chan_cfg sdi1_dma_cfg_tx = {
.mode = STEDMA40_MODE_LOGICAL,
.dir = STEDMA40_MEM_TO_PERIPH,
- .src_dev_type = STEDMA40_DEV_SRC_MEMORY,
- .dst_dev_type = DB8500_DMA_DEV32_SD_MM1_TX,
+ .dev_type = DB8500_DMA_DEV32_SD_MM1,
.src_info.data_width = STEDMA40_WORD_WIDTH,
.dst_info.data_width = STEDMA40_WORD_WIDTH,
};
@@ -172,8 +168,7 @@ struct mmci_platform_data mop500_sdi1_data = {
struct stedma40_chan_cfg mop500_sdi2_dma_cfg_rx = {
.mode = STEDMA40_MODE_LOGICAL,
.dir = STEDMA40_PERIPH_TO_MEM,
- .src_dev_type = DB8500_DMA_DEV28_SD_MM2_RX,
- .dst_dev_type = STEDMA40_DEV_DST_MEMORY,
+ .dev_type = DB8500_DMA_DEV28_SD_MM2,
.src_info.data_width = STEDMA40_WORD_WIDTH,
.dst_info.data_width = STEDMA40_WORD_WIDTH,
};
@@ -181,8 +176,7 @@ struct stedma40_chan_cfg mop500_sdi2_dma_cfg_rx = {
static struct stedma40_chan_cfg mop500_sdi2_dma_cfg_tx = {
.mode = STEDMA40_MODE_LOGICAL,
.dir = STEDMA40_MEM_TO_PERIPH,
- .src_dev_type = STEDMA40_DEV_SRC_MEMORY,
- .dst_dev_type = DB8500_DMA_DEV28_SD_MM2_TX,
+ .dev_type = DB8500_DMA_DEV28_SD_MM2,
.src_info.data_width = STEDMA40_WORD_WIDTH,
.dst_info.data_width = STEDMA40_WORD_WIDTH,
};
@@ -210,8 +204,7 @@ struct mmci_platform_data mop500_sdi2_data = {
struct stedma40_chan_cfg mop500_sdi4_dma_cfg_rx = {
.mode = STEDMA40_MODE_LOGICAL,
.dir = STEDMA40_PERIPH_TO_MEM,
- .src_dev_type = DB8500_DMA_DEV42_SD_MM4_RX,
- .dst_dev_type = STEDMA40_DEV_DST_MEMORY,
+ .dev_type = DB8500_DMA_DEV42_SD_MM4,
.src_info.data_width = STEDMA40_WORD_WIDTH,
.dst_info.data_width = STEDMA40_WORD_WIDTH,
};
@@ -219,8 +212,7 @@ struct stedma40_chan_cfg mop500_sdi4_dma_cfg_rx = {
static struct stedma40_chan_cfg mop500_sdi4_dma_cfg_tx = {
.mode = STEDMA40_MODE_LOGICAL,
.dir = STEDMA40_MEM_TO_PERIPH,
- .src_dev_type = STEDMA40_DEV_SRC_MEMORY,
- .dst_dev_type = DB8500_DMA_DEV42_SD_MM4_TX,
+ .dev_type = DB8500_DMA_DEV42_SD_MM4,
.src_info.data_width = STEDMA40_WORD_WIDTH,
.dst_info.data_width = STEDMA40_WORD_WIDTH,
};
diff --git a/arch/arm/mach-ux500/board-mop500.c b/arch/arm/mach-ux500/board-mop500.c
index 87d2d7b..a8b3ad9 100644
--- a/arch/arm/mach-ux500/board-mop500.c
+++ b/arch/arm/mach-ux500/board-mop500.c
@@ -452,8 +452,7 @@ void mop500_snowball_ethernet_clock_enable(void)
static struct cryp_platform_data u8500_cryp1_platform_data = {
.mem_to_engine = {
.dir = STEDMA40_MEM_TO_PERIPH,
- .src_dev_type = STEDMA40_DEV_SRC_MEMORY,
- .dst_dev_type = DB8500_DMA_DEV48_CAC1_TX,
+ .dev_type = DB8500_DMA_DEV48_CAC1,
.src_info.data_width = STEDMA40_WORD_WIDTH,
.dst_info.data_width = STEDMA40_WORD_WIDTH,
.mode = STEDMA40_MODE_LOGICAL,
@@ -462,8 +461,7 @@ static struct cryp_platform_data u8500_cryp1_platform_data = {
},
.engine_to_mem = {
.dir = STEDMA40_PERIPH_TO_MEM,
- .src_dev_type = DB8500_DMA_DEV48_CAC1_RX,
- .dst_dev_type = STEDMA40_DEV_DST_MEMORY,
+ .dev_type = DB8500_DMA_DEV48_CAC1,
.src_info.data_width = STEDMA40_WORD_WIDTH,
.dst_info.data_width = STEDMA40_WORD_WIDTH,
.mode = STEDMA40_MODE_LOGICAL,
@@ -474,8 +472,7 @@ static struct cryp_platform_data u8500_cryp1_platform_data = {

static struct stedma40_chan_cfg u8500_hash_dma_cfg_tx = {
.dir = STEDMA40_MEM_TO_PERIPH,
- .src_dev_type = STEDMA40_DEV_SRC_MEMORY,
- .dst_dev_type = DB8500_DMA_DEV50_HAC1_TX,
+ .dev_type = DB8500_DMA_DEV50_HAC1_TX,
.src_info.data_width = STEDMA40_WORD_WIDTH,
.dst_info.data_width = STEDMA40_WORD_WIDTH,
.mode = STEDMA40_MODE_LOGICAL,
@@ -497,8 +494,7 @@ static struct platform_device *mop500_platform_devs[] __initdata = {
static struct stedma40_chan_cfg ssp0_dma_cfg_rx = {
.mode = STEDMA40_MODE_LOGICAL,
.dir = STEDMA40_PERIPH_TO_MEM,
- .src_dev_type = DB8500_DMA_DEV8_SSP0_RX,
- .dst_dev_type = STEDMA40_DEV_DST_MEMORY,
+ .dev_type = DB8500_DMA_DEV8_SSP0,
.src_info.data_width = STEDMA40_BYTE_WIDTH,
.dst_info.data_width = STEDMA40_BYTE_WIDTH,
};
@@ -506,8 +502,7 @@ static struct stedma40_chan_cfg ssp0_dma_cfg_rx = {
static struct stedma40_chan_cfg ssp0_dma_cfg_tx = {
.mode = STEDMA40_MODE_LOGICAL,
.dir = STEDMA40_MEM_TO_PERIPH,
- .src_dev_type = STEDMA40_DEV_SRC_MEMORY,
- .dst_dev_type = DB8500_DMA_DEV8_SSP0_TX,
+ .dev_type = DB8500_DMA_DEV8_SSP0,
.src_info.data_width = STEDMA40_BYTE_WIDTH,
.dst_info.data_width = STEDMA40_BYTE_WIDTH,
};
@@ -538,8 +533,7 @@ static void __init mop500_spi_init(struct device *parent)
static struct stedma40_chan_cfg uart0_dma_cfg_rx = {
.mode = STEDMA40_MODE_LOGICAL,
.dir = STEDMA40_PERIPH_TO_MEM,
- .src_dev_type = DB8500_DMA_DEV13_UART0_RX,
- .dst_dev_type = STEDMA40_DEV_DST_MEMORY,
+ .dev_type = DB8500_DMA_DEV13_UART0,
.src_info.data_width = STEDMA40_BYTE_WIDTH,
.dst_info.data_width = STEDMA40_BYTE_WIDTH,
};
@@ -547,8 +541,7 @@ static struct stedma40_chan_cfg uart0_dma_cfg_rx = {
static struct stedma40_chan_cfg uart0_dma_cfg_tx = {
.mode = STEDMA40_MODE_LOGICAL,
.dir = STEDMA40_MEM_TO_PERIPH,
- .src_dev_type = STEDMA40_DEV_SRC_MEMORY,
- .dst_dev_type = DB8500_DMA_DEV13_UART0_TX,
+ .dev_type = DB8500_DMA_DEV13_UART0,
.src_info.data_width = STEDMA40_BYTE_WIDTH,
.dst_info.data_width = STEDMA40_BYTE_WIDTH,
};
@@ -556,8 +549,7 @@ static struct stedma40_chan_cfg uart0_dma_cfg_tx = {
static struct stedma40_chan_cfg uart1_dma_cfg_rx = {
.mode = STEDMA40_MODE_LOGICAL,
.dir = STEDMA40_PERIPH_TO_MEM,
- .src_dev_type = DB8500_DMA_DEV12_UART1_RX,
- .dst_dev_type = STEDMA40_DEV_DST_MEMORY,
+ .dev_type = DB8500_DMA_DEV12_UART1,
.src_info.data_width = STEDMA40_BYTE_WIDTH,
.dst_info.data_width = STEDMA40_BYTE_WIDTH,
};
@@ -565,8 +557,7 @@ static struct stedma40_chan_cfg uart1_dma_cfg_rx = {
static struct stedma40_chan_cfg uart1_dma_cfg_tx = {
.mode = STEDMA40_MODE_LOGICAL,
.dir = STEDMA40_MEM_TO_PERIPH,
- .src_dev_type = STEDMA40_DEV_SRC_MEMORY,
- .dst_dev_type = DB8500_DMA_DEV12_UART1_TX,
+ .dev_type = DB8500_DMA_DEV12_UART1,
.src_info.data_width = STEDMA40_BYTE_WIDTH,
.dst_info.data_width = STEDMA40_BYTE_WIDTH,
};
@@ -574,8 +565,7 @@ static struct stedma40_chan_cfg uart1_dma_cfg_tx = {
static struct stedma40_chan_cfg uart2_dma_cfg_rx = {
.mode = STEDMA40_MODE_LOGICAL,
.dir = STEDMA40_PERIPH_TO_MEM,
- .src_dev_type = DB8500_DMA_DEV11_UART2_RX,
- .dst_dev_type = STEDMA40_DEV_DST_MEMORY,
+ .dev_type = DB8500_DMA_DEV11_UART2,
.src_info.data_width = STEDMA40_BYTE_WIDTH,
.dst_info.data_width = STEDMA40_BYTE_WIDTH,
};
@@ -583,8 +573,7 @@ static struct stedma40_chan_cfg uart2_dma_cfg_rx = {
static struct stedma40_chan_cfg uart2_dma_cfg_tx = {
.mode = STEDMA40_MODE_LOGICAL,
.dir = STEDMA40_MEM_TO_PERIPH,
- .src_dev_type = STEDMA40_DEV_SRC_MEMORY,
- .dst_dev_type = DB8500_DMA_DEV11_UART2_TX,
+ .dev_type = DB8500_DMA_DEV11_UART2,
.src_info.data_width = STEDMA40_BYTE_WIDTH,
.dst_info.data_width = STEDMA40_BYTE_WIDTH,
};
diff --git a/arch/arm/mach-ux500/cpu-db8500.c b/arch/arm/mach-ux500/cpu-db8500.c
index e027865..f72cc9b 100644
--- a/arch/arm/mach-ux500/cpu-db8500.c
+++ b/arch/arm/mach-ux500/cpu-db8500.c
@@ -167,25 +167,25 @@ static void __init db8500_add_gpios(struct device *parent)
}

static int usb_db8500_rx_dma_cfg[] = {
- DB8500_DMA_DEV38_USB_OTG_IEP_1_9,
- DB8500_DMA_DEV37_USB_OTG_IEP_2_10,
- DB8500_DMA_DEV36_USB_OTG_IEP_3_11,
- DB8500_DMA_DEV19_USB_OTG_IEP_4_12,
- DB8500_DMA_DEV18_USB_OTG_IEP_5_13,
- DB8500_DMA_DEV17_USB_OTG_IEP_6_14,
- DB8500_DMA_DEV16_USB_OTG_IEP_7_15,
- DB8500_DMA_DEV39_USB_OTG_IEP_8
+ DB8500_DMA_DEV38_USB_OTG_IEP_AND_OEP_1_9,
+ DB8500_DMA_DEV37_USB_OTG_IEP_AND_OEP_2_10,
+ DB8500_DMA_DEV36_USB_OTG_IEP_AND_OEP_3_11,
+ DB8500_DMA_DEV19_USB_OTG_IEP_AND_OEP_4_12,
+ DB8500_DMA_DEV18_USB_OTG_IEP_AND_OEP_5_13,
+ DB8500_DMA_DEV17_USB_OTG_IEP_AND_OEP_6_14,
+ DB8500_DMA_DEV16_USB_OTG_IEP_AND_OEP_7_15,
+ DB8500_DMA_DEV39_USB_OTG_IEP_AND_OEP_8
};

static int usb_db8500_tx_dma_cfg[] = {
- DB8500_DMA_DEV38_USB_OTG_OEP_1_9,
- DB8500_DMA_DEV37_USB_OTG_OEP_2_10,
- DB8500_DMA_DEV36_USB_OTG_OEP_3_11,
- DB8500_DMA_DEV19_USB_OTG_OEP_4_12,
- DB8500_DMA_DEV18_USB_OTG_OEP_5_13,
- DB8500_DMA_DEV17_USB_OTG_OEP_6_14,
- DB8500_DMA_DEV16_USB_OTG_OEP_7_15,
- DB8500_DMA_DEV39_USB_OTG_OEP_8
+ DB8500_DMA_DEV38_USB_OTG_IEP_AND_OEP_1_9,
+ DB8500_DMA_DEV37_USB_OTG_IEP_AND_OEP_2_10,
+ DB8500_DMA_DEV36_USB_OTG_IEP_AND_OEP_3_11,
+ DB8500_DMA_DEV19_USB_OTG_IEP_AND_OEP_4_12,
+ DB8500_DMA_DEV18_USB_OTG_IEP_AND_OEP_5_13,
+ DB8500_DMA_DEV17_USB_OTG_IEP_AND_OEP_6_14,
+ DB8500_DMA_DEV16_USB_OTG_IEP_AND_OEP_7_15,
+ DB8500_DMA_DEV39_USB_OTG_IEP_AND_OEP_8
};

static const char *db8500_read_soc_id(void)
diff --git a/arch/arm/mach-ux500/devices-db8500.c b/arch/arm/mach-ux500/devices-db8500.c
index 5b1f1f7..03efd4c1 100644
--- a/arch/arm/mach-ux500/devices-db8500.c
+++ b/arch/arm/mach-ux500/devices-db8500.c
@@ -50,74 +50,74 @@ static struct resource dma40_resources[] = {
*/
static const dma_addr_t dma40_tx_map[DB8500_DMA_NR_DEV] = {
/* MUSB - these will be runtime-reconfigured */
- [DB8500_DMA_DEV39_USB_OTG_OEP_8] = -1,
- [DB8500_DMA_DEV16_USB_OTG_OEP_7_15] = -1,
- [DB8500_DMA_DEV17_USB_OTG_OEP_6_14] = -1,
- [DB8500_DMA_DEV18_USB_OTG_OEP_5_13] = -1,
- [DB8500_DMA_DEV19_USB_OTG_OEP_4_12] = -1,
- [DB8500_DMA_DEV36_USB_OTG_OEP_3_11] = -1,
- [DB8500_DMA_DEV37_USB_OTG_OEP_2_10] = -1,
- [DB8500_DMA_DEV38_USB_OTG_OEP_1_9] = -1,
+ [DB8500_DMA_DEV39_USB_OTG_IEP_AND_OEP_8] = -1,
+ [DB8500_DMA_DEV16_USB_OTG_IEP_AND_OEP_7_15] = -1,
+ [DB8500_DMA_DEV17_USB_OTG_IEP_AND_OEP_6_14] = -1,
+ [DB8500_DMA_DEV18_USB_OTG_IEP_AND_OEP_5_13] = -1,
+ [DB8500_DMA_DEV19_USB_OTG_IEP_AND_OEP_4_12] = -1,
+ [DB8500_DMA_DEV36_USB_OTG_IEP_AND_OEP_3_11] = -1,
+ [DB8500_DMA_DEV37_USB_OTG_IEP_AND_OEP_2_10] = -1,
+ [DB8500_DMA_DEV38_USB_OTG_IEP_AND_OEP_1_9] = -1,
/* PrimeCells - run-time configured */
- [DB8500_DMA_DEV0_SPI0_TX] = -1,
- [DB8500_DMA_DEV1_SD_MMC0_TX] = -1,
- [DB8500_DMA_DEV2_SD_MMC1_TX] = -1,
- [DB8500_DMA_DEV3_SD_MMC2_TX] = -1,
- [DB8500_DMA_DEV8_SSP0_TX] = -1,
- [DB8500_DMA_DEV9_SSP1_TX] = -1,
- [DB8500_DMA_DEV11_UART2_TX] = -1,
- [DB8500_DMA_DEV12_UART1_TX] = -1,
- [DB8500_DMA_DEV13_UART0_TX] = -1,
- [DB8500_DMA_DEV28_SD_MM2_TX] = -1,
- [DB8500_DMA_DEV29_SD_MM0_TX] = -1,
- [DB8500_DMA_DEV32_SD_MM1_TX] = -1,
- [DB8500_DMA_DEV33_SPI2_TX] = -1,
- [DB8500_DMA_DEV35_SPI1_TX] = -1,
- [DB8500_DMA_DEV40_SPI3_TX] = -1,
- [DB8500_DMA_DEV41_SD_MM3_TX] = -1,
- [DB8500_DMA_DEV42_SD_MM4_TX] = -1,
- [DB8500_DMA_DEV43_SD_MM5_TX] = -1,
- [DB8500_DMA_DEV14_MSP2_TX] = U8500_MSP2_BASE + MSP_TX_RX_REG_OFFSET,
- [DB8500_DMA_DEV30_MSP1_TX] = U8500_MSP1_BASE + MSP_TX_RX_REG_OFFSET,
- [DB8500_DMA_DEV31_MSP0_TX_SLIM0_CH0_TX] = U8500_MSP0_BASE + MSP_TX_RX_REG_OFFSET,
- [DB8500_DMA_DEV48_CAC1_TX] = U8500_CRYP1_BASE + CRYP1_TX_REG_OFFSET,
+ [DB8500_DMA_DEV0_SPI0] = -1,
+ [DB8500_DMA_DEV1_SD_MMC0] = -1,
+ [DB8500_DMA_DEV2_SD_MMC1] = -1,
+ [DB8500_DMA_DEV3_SD_MMC2] = -1,
+ [DB8500_DMA_DEV8_SSP0] = -1,
+ [DB8500_DMA_DEV9_SSP1] = -1,
+ [DB8500_DMA_DEV11_UART2] = -1,
+ [DB8500_DMA_DEV12_UART1] = -1,
+ [DB8500_DMA_DEV13_UART0] = -1,
+ [DB8500_DMA_DEV28_SD_MM2] = -1,
+ [DB8500_DMA_DEV29_SD_MM0] = -1,
+ [DB8500_DMA_DEV32_SD_MM1] = -1,
+ [DB8500_DMA_DEV33_SPI2] = -1,
+ [DB8500_DMA_DEV35_SPI1] = -1,
+ [DB8500_DMA_DEV40_SPI3] = -1,
+ [DB8500_DMA_DEV41_SD_MM3] = -1,
+ [DB8500_DMA_DEV42_SD_MM4] = -1,
+ [DB8500_DMA_DEV43_SD_MM5] = -1,
+ [DB8500_DMA_DEV14_MSP2] = U8500_MSP2_BASE + MSP_TX_RX_REG_OFFSET,
+ [DB8500_DMA_DEV30_MSP1] = U8500_MSP1_BASE + MSP_TX_RX_REG_OFFSET,
+ [DB8500_DMA_DEV31_MSP0_SLIM0_CH0] = U8500_MSP0_BASE + MSP_TX_RX_REG_OFFSET,
+ [DB8500_DMA_DEV48_CAC1] = U8500_CRYP1_BASE + CRYP1_TX_REG_OFFSET,
[DB8500_DMA_DEV50_HAC1_TX] = U8500_HASH1_BASE + HASH1_TX_REG_OFFSET,
};

/* Mapping between source event lines and physical device address */
static const dma_addr_t dma40_rx_map[DB8500_DMA_NR_DEV] = {
/* MUSB - these will be runtime-reconfigured */
- [DB8500_DMA_DEV39_USB_OTG_IEP_8] = -1,
- [DB8500_DMA_DEV16_USB_OTG_IEP_7_15] = -1,
- [DB8500_DMA_DEV17_USB_OTG_IEP_6_14] = -1,
- [DB8500_DMA_DEV18_USB_OTG_IEP_5_13] = -1,
- [DB8500_DMA_DEV19_USB_OTG_IEP_4_12] = -1,
- [DB8500_DMA_DEV36_USB_OTG_IEP_3_11] = -1,
- [DB8500_DMA_DEV37_USB_OTG_IEP_2_10] = -1,
- [DB8500_DMA_DEV38_USB_OTG_IEP_1_9] = -1,
+ [DB8500_DMA_DEV39_USB_OTG_IEP_AND_OEP_8] = -1,
+ [DB8500_DMA_DEV16_USB_OTG_IEP_AND_OEP_7_15] = -1,
+ [DB8500_DMA_DEV17_USB_OTG_IEP_AND_OEP_6_14] = -1,
+ [DB8500_DMA_DEV18_USB_OTG_IEP_AND_OEP_5_13] = -1,
+ [DB8500_DMA_DEV19_USB_OTG_IEP_AND_OEP_4_12] = -1,
+ [DB8500_DMA_DEV36_USB_OTG_IEP_AND_OEP_3_11] = -1,
+ [DB8500_DMA_DEV37_USB_OTG_IEP_AND_OEP_2_10] = -1,
+ [DB8500_DMA_DEV38_USB_OTG_IEP_AND_OEP_1_9] = -1,
/* PrimeCells */
- [DB8500_DMA_DEV0_SPI0_RX] = -1,
- [DB8500_DMA_DEV1_SD_MMC0_RX] = -1,
- [DB8500_DMA_DEV2_SD_MMC1_RX] = -1,
- [DB8500_DMA_DEV3_SD_MMC2_RX] = -1,
- [DB8500_DMA_DEV8_SSP0_RX] = -1,
- [DB8500_DMA_DEV9_SSP1_RX] = -1,
- [DB8500_DMA_DEV11_UART2_RX] = -1,
- [DB8500_DMA_DEV12_UART1_RX] = -1,
- [DB8500_DMA_DEV13_UART0_RX] = -1,
- [DB8500_DMA_DEV28_SD_MM2_RX] = -1,
- [DB8500_DMA_DEV29_SD_MM0_RX] = -1,
- [DB8500_DMA_DEV32_SD_MM1_RX] = -1,
- [DB8500_DMA_DEV33_SPI2_RX] = -1,
- [DB8500_DMA_DEV35_SPI1_RX] = -1,
- [DB8500_DMA_DEV40_SPI3_RX] = -1,
- [DB8500_DMA_DEV41_SD_MM3_RX] = -1,
- [DB8500_DMA_DEV42_SD_MM4_RX] = -1,
- [DB8500_DMA_DEV43_SD_MM5_RX] = -1,
- [DB8500_DMA_DEV14_MSP2_RX] = U8500_MSP2_BASE + MSP_TX_RX_REG_OFFSET,
- [DB8500_DMA_DEV30_MSP3_RX] = U8500_MSP3_BASE + MSP_TX_RX_REG_OFFSET,
- [DB8500_DMA_DEV31_MSP0_RX_SLIM0_CH0_RX] = U8500_MSP0_BASE + MSP_TX_RX_REG_OFFSET,
- [DB8500_DMA_DEV48_CAC1_RX] = U8500_CRYP1_BASE + CRYP1_RX_REG_OFFSET,
+ [DB8500_DMA_DEV0_SPI0] = -1,
+ [DB8500_DMA_DEV1_SD_MMC0] = -1,
+ [DB8500_DMA_DEV2_SD_MMC1] = -1,
+ [DB8500_DMA_DEV3_SD_MMC2] = -1,
+ [DB8500_DMA_DEV8_SSP0] = -1,
+ [DB8500_DMA_DEV9_SSP1] = -1,
+ [DB8500_DMA_DEV11_UART2] = -1,
+ [DB8500_DMA_DEV12_UART1] = -1,
+ [DB8500_DMA_DEV13_UART0] = -1,
+ [DB8500_DMA_DEV28_SD_MM2] = -1,
+ [DB8500_DMA_DEV29_SD_MM0] = -1,
+ [DB8500_DMA_DEV32_SD_MM1] = -1,
+ [DB8500_DMA_DEV33_SPI2] = -1,
+ [DB8500_DMA_DEV35_SPI1] = -1,
+ [DB8500_DMA_DEV40_SPI3] = -1,
+ [DB8500_DMA_DEV41_SD_MM3] = -1,
+ [DB8500_DMA_DEV42_SD_MM4] = -1,
+ [DB8500_DMA_DEV43_SD_MM5] = -1,
+ [DB8500_DMA_DEV14_MSP2] = U8500_MSP2_BASE + MSP_TX_RX_REG_OFFSET,
+ [DB8500_DMA_DEV30_MSP3] = U8500_MSP3_BASE + MSP_TX_RX_REG_OFFSET,
+ [DB8500_DMA_DEV31_MSP0_SLIM0_CH0] = U8500_MSP0_BASE + MSP_TX_RX_REG_OFFSET,
+ [DB8500_DMA_DEV48_CAC1] = U8500_CRYP1_BASE + CRYP1_RX_REG_OFFSET,
};

static struct stedma40_platform_data dma40_plat_data = {
diff --git a/arch/arm/mach-ux500/ste-dma40-db8500.h b/arch/arm/mach-ux500/ste-dma40-db8500.h
index a616419..0296ae5 100644
--- a/arch/arm/mach-ux500/ste-dma40-db8500.h
+++ b/arch/arm/mach-ux500/ste-dma40-db8500.h
@@ -12,133 +12,74 @@

#define DB8500_DMA_NR_DEV 64

-enum dma_src_dev_type {
- DB8500_DMA_DEV0_SPI0_RX = 0,
- DB8500_DMA_DEV1_SD_MMC0_RX = 1,
- DB8500_DMA_DEV2_SD_MMC1_RX = 2,
- DB8500_DMA_DEV3_SD_MMC2_RX = 3,
- DB8500_DMA_DEV4_I2C1_RX = 4,
- DB8500_DMA_DEV5_I2C3_RX = 5,
- DB8500_DMA_DEV6_I2C2_RX = 6,
- DB8500_DMA_DEV7_I2C4_RX = 7, /* Only on V1 and later */
- DB8500_DMA_DEV8_SSP0_RX = 8,
- DB8500_DMA_DEV9_SSP1_RX = 9,
- DB8500_DMA_DEV10_MCDE_RX = 10,
- DB8500_DMA_DEV11_UART2_RX = 11,
- DB8500_DMA_DEV12_UART1_RX = 12,
- DB8500_DMA_DEV13_UART0_RX = 13,
- DB8500_DMA_DEV14_MSP2_RX = 14,
- DB8500_DMA_DEV15_I2C0_RX = 15,
- DB8500_DMA_DEV16_USB_OTG_IEP_7_15 = 16,
- DB8500_DMA_DEV17_USB_OTG_IEP_6_14 = 17,
- DB8500_DMA_DEV18_USB_OTG_IEP_5_13 = 18,
- DB8500_DMA_DEV19_USB_OTG_IEP_4_12 = 19,
- DB8500_DMA_DEV20_SLIM0_CH0_RX_HSI_RX_CH0 = 20,
- DB8500_DMA_DEV21_SLIM0_CH1_RX_HSI_RX_CH1 = 21,
- DB8500_DMA_DEV22_SLIM0_CH2_RX_HSI_RX_CH2 = 22,
- DB8500_DMA_DEV23_SLIM0_CH3_RX_HSI_RX_CH3 = 23,
- DB8500_DMA_DEV24_SRC_SXA0_RX_TX = 24,
- DB8500_DMA_DEV25_SRC_SXA1_RX_TX = 25,
- DB8500_DMA_DEV26_SRC_SXA2_RX_TX = 26,
- DB8500_DMA_DEV27_SRC_SXA3_RX_TX = 27,
- DB8500_DMA_DEV28_SD_MM2_RX = 28,
- DB8500_DMA_DEV29_SD_MM0_RX = 29,
- DB8500_DMA_DEV30_MSP1_RX = 30,
+/*
+ * Unless otherwise specified, all channels numbers are used for
+ * TX & RX, and can be used for either source or destination
+ * channels.
+ */
+enum dma_dev_type {
+ DB8500_DMA_DEV0_SPI0 = 0,
+ DB8500_DMA_DEV1_SD_MMC0 = 1,
+ DB8500_DMA_DEV2_SD_MMC1 = 2,
+ DB8500_DMA_DEV3_SD_MMC2 = 3,
+ DB8500_DMA_DEV4_I2C1 = 4,
+ DB8500_DMA_DEV5_I2C3 = 5,
+ DB8500_DMA_DEV6_I2C2 = 6,
+ DB8500_DMA_DEV7_I2C4 = 7, /* Only on V1 and later */
+ DB8500_DMA_DEV8_SSP0 = 8,
+ DB8500_DMA_DEV9_SSP1 = 9,
+ DB8500_DMA_DEV10_MCDE_RX = 10, /* RX only */
+ DB8500_DMA_DEV11_UART2 = 11,
+ DB8500_DMA_DEV12_UART1 = 12,
+ DB8500_DMA_DEV13_UART0 = 13,
+ DB8500_DMA_DEV14_MSP2 = 14,
+ DB8500_DMA_DEV15_I2C0 = 15,
+ DB8500_DMA_DEV16_USB_OTG_IEP_AND_OEP_7_15 = 16,
+ DB8500_DMA_DEV17_USB_OTG_IEP_AND_OEP_6_14 = 17,
+ DB8500_DMA_DEV18_USB_OTG_IEP_AND_OEP_5_13 = 18,
+ DB8500_DMA_DEV19_USB_OTG_IEP_AND_OEP_4_12 = 19,
+ DB8500_DMA_DEV20_SLIM0_CH0_HSI_CH0 = 20,
+ DB8500_DMA_DEV21_SLIM0_CH1_HSI_CH1 = 21,
+ DB8500_DMA_DEV22_SLIM0_CH2_HSI_CH2 = 22,
+ DB8500_DMA_DEV23_SLIM0_CH3_HSI_CH3 = 23,
+ DB8500_DMA_DEV24_SXA0 = 24,
+ DB8500_DMA_DEV25_SXA1 = 25,
+ DB8500_DMA_DEV26_SXA2 = 26,
+ DB8500_DMA_DEV27_SXA3 = 27,
+ DB8500_DMA_DEV28_SD_MM2 = 28,
+ DB8500_DMA_DEV29_SD_MM0 = 29,
+ DB8500_DMA_DEV30_MSP1 = 30,
/* On DB8500v2, MSP3 RX replaces MSP1 RX */
- DB8500_DMA_DEV30_MSP3_RX = 30,
- DB8500_DMA_DEV31_MSP0_RX_SLIM0_CH0_RX = 31,
- DB8500_DMA_DEV32_SD_MM1_RX = 32,
- DB8500_DMA_DEV33_SPI2_RX = 33,
- DB8500_DMA_DEV34_I2C3_RX2 = 34,
- DB8500_DMA_DEV35_SPI1_RX = 35,
- DB8500_DMA_DEV36_USB_OTG_IEP_3_11 = 36,
- DB8500_DMA_DEV37_USB_OTG_IEP_2_10 = 37,
- DB8500_DMA_DEV38_USB_OTG_IEP_1_9 = 38,
- DB8500_DMA_DEV39_USB_OTG_IEP_8 = 39,
- DB8500_DMA_DEV40_SPI3_RX = 40,
- DB8500_DMA_DEV41_SD_MM3_RX = 41,
- DB8500_DMA_DEV42_SD_MM4_RX = 42,
- DB8500_DMA_DEV43_SD_MM5_RX = 43,
- DB8500_DMA_DEV44_SRC_SXA4_RX_TX = 44,
- DB8500_DMA_DEV45_SRC_SXA5_RX_TX = 45,
- DB8500_DMA_DEV46_SLIM0_CH8_RX_SRC_SXA6_RX_TX = 46,
- DB8500_DMA_DEV47_SLIM0_CH9_RX_SRC_SXA7_RX_TX = 47,
- DB8500_DMA_DEV48_CAC1_RX = 48,
- /* 49, 50 and 51 are not used */
- DB8500_DMA_DEV52_SLIM0_CH4_RX_HSI_RX_CH4 = 52,
- DB8500_DMA_DEV53_SLIM0_CH5_RX_HSI_RX_CH5 = 53,
- DB8500_DMA_DEV54_SLIM0_CH6_RX_HSI_RX_CH6 = 54,
- DB8500_DMA_DEV55_SLIM0_CH7_RX_HSI_RX_CH7 = 55,
- /* 56, 57, 58, 59 and 60 are not used */
- DB8500_DMA_DEV61_CAC0_RX = 61,
- /* 62 and 63 are not used */
-};
-
-enum dma_dest_dev_type {
- DB8500_DMA_DEV0_SPI0_TX = 0,
- DB8500_DMA_DEV1_SD_MMC0_TX = 1,
- DB8500_DMA_DEV2_SD_MMC1_TX = 2,
- DB8500_DMA_DEV3_SD_MMC2_TX = 3,
- DB8500_DMA_DEV4_I2C1_TX = 4,
- DB8500_DMA_DEV5_I2C3_TX = 5,
- DB8500_DMA_DEV6_I2C2_TX = 6,
- DB8500_DMA_DEV7_I2C4_TX = 7, /* Only on V1 and later */
- DB8500_DMA_DEV8_SSP0_TX = 8,
- DB8500_DMA_DEV9_SSP1_TX = 9,
- /* 10 is not used*/
- DB8500_DMA_DEV11_UART2_TX = 11,
- DB8500_DMA_DEV12_UART1_TX = 12,
- DB8500_DMA_DEV13_UART0_TX = 13,
- DB8500_DMA_DEV14_MSP2_TX = 14,
- DB8500_DMA_DEV15_I2C0_TX = 15,
- DB8500_DMA_DEV16_USB_OTG_OEP_7_15 = 16,
- DB8500_DMA_DEV17_USB_OTG_OEP_6_14 = 17,
- DB8500_DMA_DEV18_USB_OTG_OEP_5_13 = 18,
- DB8500_DMA_DEV19_USB_OTG_OEP_4_12 = 19,
- DB8500_DMA_DEV20_SLIM0_CH0_TX_HSI_TX_CH0 = 20,
- DB8500_DMA_DEV21_SLIM0_CH1_TX_HSI_TX_CH1 = 21,
- DB8500_DMA_DEV22_SLIM0_CH2_TX_HSI_TX_CH2 = 22,
- DB8500_DMA_DEV23_SLIM0_CH3_TX_HSI_TX_CH3 = 23,
- DB8500_DMA_DEV24_DST_SXA0_RX_TX = 24,
- DB8500_DMA_DEV25_DST_SXA1_RX_TX = 25,
- DB8500_DMA_DEV26_DST_SXA2_RX_TX = 26,
- DB8500_DMA_DEV27_DST_SXA3_RX_TX = 27,
- DB8500_DMA_DEV28_SD_MM2_TX = 28,
- DB8500_DMA_DEV29_SD_MM0_TX = 29,
- DB8500_DMA_DEV30_MSP1_TX = 30,
- DB8500_DMA_DEV31_MSP0_TX_SLIM0_CH0_TX = 31,
- DB8500_DMA_DEV32_SD_MM1_TX = 32,
- DB8500_DMA_DEV33_SPI2_TX = 33,
- DB8500_DMA_DEV34_I2C3_TX2 = 34,
- DB8500_DMA_DEV35_SPI1_TX = 35,
- DB8500_DMA_DEV36_USB_OTG_OEP_3_11 = 36,
- DB8500_DMA_DEV37_USB_OTG_OEP_2_10 = 37,
- DB8500_DMA_DEV38_USB_OTG_OEP_1_9 = 38,
- DB8500_DMA_DEV39_USB_OTG_OEP_8 = 39,
- DB8500_DMA_DEV40_SPI3_TX = 40,
- DB8500_DMA_DEV41_SD_MM3_TX = 41,
- DB8500_DMA_DEV42_SD_MM4_TX = 42,
- DB8500_DMA_DEV43_SD_MM5_TX = 43,
- DB8500_DMA_DEV44_DST_SXA4_RX_TX = 44,
- DB8500_DMA_DEV45_DST_SXA5_RX_TX = 45,
- DB8500_DMA_DEV46_SLIM0_CH8_TX_DST_SXA6_RX_TX = 46,
- DB8500_DMA_DEV47_SLIM0_CH9_TX_DST_SXA7_RX_TX = 47,
- DB8500_DMA_DEV48_CAC1_TX = 48,
- DB8500_DMA_DEV49_CAC1_TX_HAC1_TX = 49,
- DB8500_DMA_DEV50_HAC1_TX = 50,
- DB8500_DMA_MEMCPY_TX_0 = 51,
- DB8500_DMA_DEV52_SLIM1_CH4_TX_HSI_TX_CH4 = 52,
- DB8500_DMA_DEV53_SLIM1_CH5_TX_HSI_TX_CH5 = 53,
- DB8500_DMA_DEV54_SLIM1_CH6_TX_HSI_TX_CH6 = 54,
- DB8500_DMA_DEV55_SLIM1_CH7_TX_HSI_TX_CH7 = 55,
- DB8500_DMA_MEMCPY_TX_1 = 56,
- DB8500_DMA_MEMCPY_TX_2 = 57,
- DB8500_DMA_MEMCPY_TX_3 = 58,
- DB8500_DMA_MEMCPY_TX_4 = 59,
- DB8500_DMA_MEMCPY_TX_5 = 60,
- DB8500_DMA_DEV61_CAC0_TX = 61,
- DB8500_DMA_DEV62_CAC0_TX_HAC0_TX = 62,
- DB8500_DMA_DEV63_HAC0_TX = 63,
+ DB8500_DMA_DEV30_MSP3 = 30,
+ DB8500_DMA_DEV31_MSP0_SLIM0_CH0 = 31,
+ DB8500_DMA_DEV32_SD_MM1 = 32,
+ DB8500_DMA_DEV33_SPI2 = 33,
+ DB8500_DMA_DEV34_I2C3_RX2_TX2 = 34,
+ DB8500_DMA_DEV35_SPI1 = 35,
+ DB8500_DMA_DEV36_USB_OTG_IEP_AND_OEP_3_11 = 36,
+ DB8500_DMA_DEV37_USB_OTG_IEP_AND_OEP_2_10 = 37,
+ DB8500_DMA_DEV38_USB_OTG_IEP_AND_OEP_1_9 = 38,
+ DB8500_DMA_DEV39_USB_OTG_IEP_AND_OEP_8 = 39,
+ DB8500_DMA_DEV40_SPI3 = 40,
+ DB8500_DMA_DEV41_SD_MM3 = 41,
+ DB8500_DMA_DEV42_SD_MM4 = 42,
+ DB8500_DMA_DEV43_SD_MM5 = 43,
+ DB8500_DMA_DEV44_SXA4 = 44,
+ DB8500_DMA_DEV45_SXA5 = 45,
+ DB8500_DMA_DEV46_SLIM0_CH8_SRC_SXA6 = 46,
+ DB8500_DMA_DEV47_SLIM0_CH9_SRC_SXA7 = 47,
+ DB8500_DMA_DEV48_CAC1 = 48,
+ DB8500_DMA_DEV49_CAC1_TX_HAC1_TX = 49, /* TX only */
+ DB8500_DMA_DEV50_HAC1_TX = 50, /* TX only */
+ DB8500_DMA_MEMCPY_TX_0 = 51, /* TX only */
+ DB8500_DMA_DEV52_SLIM0_CH4_HSI_CH4 = 52,
+ DB8500_DMA_DEV53_SLIM0_CH5_HSI_CH5 = 53,
+ DB8500_DMA_DEV54_SLIM0_CH6_HSI_CH6 = 54,
+ DB8500_DMA_DEV55_SLIM0_CH7_HSI_CH7 = 55,
+ /* 56 -> 60 are channels reserved for memcpy only */
+ DB8500_DMA_DEV61_CAC0 = 61,
+ DB8500_DMA_DEV62_CAC0_TX_HAC0_TX = 62, /* TX only */
+ DB8500_DMA_DEV63_HAC0_TX = 63, /* TX only */
};

#endif
diff --git a/arch/arm/mach-ux500/usb.c b/arch/arm/mach-ux500/usb.c
index 78ac65f..e0ea490 100644
--- a/arch/arm/mach-ux500/usb.c
+++ b/arch/arm/mach-ux500/usb.c
@@ -15,7 +15,6 @@
#define MUSB_DMA40_RX_CH { \
.mode = STEDMA40_MODE_LOGICAL, \
.dir = STEDMA40_PERIPH_TO_MEM, \
- .dst_dev_type = STEDMA40_DEV_DST_MEMORY, \
.src_info.data_width = STEDMA40_WORD_WIDTH, \
.dst_info.data_width = STEDMA40_WORD_WIDTH, \
.src_info.psize = STEDMA40_PSIZE_LOG_16, \
@@ -25,7 +24,6 @@
#define MUSB_DMA40_TX_CH { \
.mode = STEDMA40_MODE_LOGICAL, \
.dir = STEDMA40_MEM_TO_PERIPH, \
- .src_dev_type = STEDMA40_DEV_SRC_MEMORY, \
.src_info.data_width = STEDMA40_WORD_WIDTH, \
.dst_info.data_width = STEDMA40_WORD_WIDTH, \
.src_info.psize = STEDMA40_PSIZE_LOG_16, \
@@ -125,20 +123,20 @@ struct platform_device ux500_musb_device = {
.resource = usb_resources,
};

-static inline void ux500_usb_dma_update_rx_ch_config(int *src_dev_type)
+static inline void ux500_usb_dma_update_rx_ch_config(int *dev_type)
{
u32 idx;

for (idx = 0; idx < UX500_MUSB_DMA_NUM_RX_CHANNELS; idx++)
- musb_dma_rx_ch[idx].src_dev_type = src_dev_type[idx];
+ musb_dma_rx_ch[idx].dev_type = dev_type[idx];
}

-static inline void ux500_usb_dma_update_tx_ch_config(int *dst_dev_type)
+static inline void ux500_usb_dma_update_tx_ch_config(int *dev_type)
{
u32 idx;

for (idx = 0; idx < UX500_MUSB_DMA_NUM_TX_CHANNELS; idx++)
- musb_dma_tx_ch[idx].dst_dev_type = dst_dev_type[idx];
+ musb_dma_tx_ch[idx].dev_type = dev_type[idx];
}

void ux500_add_usb(struct device *parent, resource_size_t base, int irq,
diff --git a/drivers/dma/ste_dma40.c b/drivers/dma/ste_dma40.c
index 7b96e75..67b9d57 100644
--- a/drivers/dma/ste_dma40.c
+++ b/drivers/dma/ste_dma40.c
@@ -28,10 +28,6 @@

#define D40_PHY_CHAN -1

-/* For masking out/in 2 bit channel positions */
-#define D40_CHAN_POS(chan) (2 * (chan / 2))
-#define D40_CHAN_POS_MASK(chan) (0x3 << D40_CHAN_POS(chan))
-
/* Maximum iterations taken before giving up suspending a channel */
#define D40_SUSPEND_MAX_IT 500

@@ -55,6 +51,10 @@

#define MAX(a, b) (((a) < (b)) ? (b) : (a))

+#define D40_IS_SRC(dir) (dir == STEDMA40_PERIPH_TO_MEM) : true : false;
+#define D40_IS_DST(dir) ((dir == STEDMA40_MEM_TO_PERIPH) || \
+ (dir == STEDMA40_MEM_TO_MEM)) : true : false;
+
/* Reserved event lines for memcpy only. */
static int dma40_memcpy_channels[] = { 56, 57, 58, 59, 60 };

@@ -1288,21 +1288,17 @@ static void __d40_config_set_event(struct d40_chan *d40c,
static void d40_config_set_event(struct d40_chan *d40c,
enum d40_events event_type)
{
+ u32 event = D40_TYPE_TO_EVENT(d40c->dma_cfg.dev_type);
+
/* Enable event line connected to device (or memcpy) */
if ((d40c->dma_cfg.dir == STEDMA40_PERIPH_TO_MEM) ||
- (d40c->dma_cfg.dir == STEDMA40_PERIPH_TO_PERIPH)) {
- u32 event = D40_TYPE_TO_EVENT(d40c->dma_cfg.src_dev_type);
-
+ (d40c->dma_cfg.dir == STEDMA40_PERIPH_TO_PERIPH))
__d40_config_set_event(d40c, event_type, event,
D40_CHAN_REG_SSLNK);
- }
-
- if (d40c->dma_cfg.dir != STEDMA40_PERIPH_TO_MEM) {
- u32 event = D40_TYPE_TO_EVENT(d40c->dma_cfg.dst_dev_type);

+ if (d40c->dma_cfg.dir != STEDMA40_PERIPH_TO_MEM)
__d40_config_set_event(d40c, event_type, event,
D40_CHAN_REG_SDLNK);
- }
}

static u32 d40_chan_has_events(struct d40_chan *d40c)
@@ -1744,8 +1740,6 @@ static int d40_validate_conf(struct d40_chan *d40c,
struct stedma40_chan_cfg *conf)
{
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->mode == STEDMA40_MODE_LOGICAL;

if (!conf->dir) {
@@ -1753,44 +1747,24 @@ static int d40_validate_conf(struct d40_chan *d40c,
res = -EINVAL;
}

- if (conf->dst_dev_type != STEDMA40_DEV_DST_MEMORY &&
- d40c->base->plat_data->dev_tx[conf->dst_dev_type] == 0 &&
- d40c->runtime_addr == 0) {
-
- chan_err(d40c, "Invalid TX channel address (%d)\n",
- conf->dst_dev_type);
- res = -EINVAL;
- }
-
- if (conf->src_dev_type != STEDMA40_DEV_SRC_MEMORY &&
- d40c->base->plat_data->dev_rx[conf->src_dev_type] == 0 &&
- d40c->runtime_addr == 0) {
- chan_err(d40c, "Invalid RX channel address (%d)\n",
- conf->src_dev_type);
+ if ((conf->dev_type < 0) && is_log) {
+ chan_err(d40c, "Invalid device type\n");
res = -EINVAL;
}

if (conf->dir == STEDMA40_MEM_TO_PERIPH &&
- dst_event_group == STEDMA40_DEV_DST_MEMORY) {
- chan_err(d40c, "Invalid dst\n");
+ d40c->base->plat_data->dev_tx[conf->dev_type] == 0 &&
+ d40c->runtime_addr == 0) {
+ chan_err(d40c, "Invalid TX channel address (%d)\n",
+ conf->dev_type);
res = -EINVAL;
}

if (conf->dir == STEDMA40_PERIPH_TO_MEM &&
- src_event_group == STEDMA40_DEV_SRC_MEMORY) {
- chan_err(d40c, "Invalid src\n");
- res = -EINVAL;
- }
-
- if (src_event_group == STEDMA40_DEV_SRC_MEMORY &&
- dst_event_group == STEDMA40_DEV_DST_MEMORY && is_log) {
- chan_err(d40c, "No event line\n");
- res = -EINVAL;
- }
-
- if (conf->dir == STEDMA40_PERIPH_TO_PERIPH &&
- (src_event_group != dst_event_group)) {
- chan_err(d40c, "Invalid event group\n");
+ d40c->base->plat_data->dev_rx[conf->dev_type] == 0 &&
+ d40c->runtime_addr == 0) {
+ chan_err(d40c, "Invalid RX channel address (%d)\n",
+ conf->dev_type);
res = -EINVAL;
}

@@ -1911,7 +1885,7 @@ out:

static int d40_allocate_channel(struct d40_chan *d40c, bool *first_phy_user)
{
- int dev_type;
+ int dev_type = d40c->dma_cfg.dev_type;
int event_group;
int event_line;
struct d40_phy_res *phys;
@@ -1926,13 +1900,11 @@ static int d40_allocate_channel(struct d40_chan *d40c, bool *first_phy_user)
num_phy_chans = d40c->base->num_phy_chans;

if (d40c->dma_cfg.dir == STEDMA40_PERIPH_TO_MEM) {
- dev_type = d40c->dma_cfg.src_dev_type;
log_num = 2 * dev_type;
is_src = true;
} else if (d40c->dma_cfg.dir == STEDMA40_MEM_TO_PERIPH ||
d40c->dma_cfg.dir == STEDMA40_MEM_TO_MEM) {
/* dst event lines are used for logical memcpy */
- dev_type = d40c->dma_cfg.dst_dev_type;
log_num = 2 * dev_type + 1;
is_src = false;
} else
@@ -2044,8 +2016,7 @@ static int d40_config_memcpy(struct d40_chan *d40c)

if (dma_has_cap(DMA_MEMCPY, cap) && !dma_has_cap(DMA_SLAVE, cap)) {
d40c->dma_cfg = dma40_memcpy_conf_log;
- d40c->dma_cfg.src_dev_type = STEDMA40_DEV_SRC_MEMORY;
- d40c->dma_cfg.dst_dev_type = dma40_memcpy_channels[d40c->chan.chan_id];
+ d40c->dma_cfg.dev_type = dma40_memcpy_channels[d40c->chan.chan_id];

} else if (dma_has_cap(DMA_MEMCPY, cap) &&
dma_has_cap(DMA_SLAVE, cap)) {
@@ -2062,7 +2033,7 @@ static int d40_free_dma(struct d40_chan *d40c)
{

int res = 0;
- u32 event;
+ u32 event = D40_TYPE_TO_EVENT(d40c->dma_cfg.dev_type);
struct d40_phy_res *phy = d40c->phy_chan;
bool is_src;

@@ -2081,13 +2052,11 @@ static int d40_free_dma(struct d40_chan *d40c)
}

if (d40c->dma_cfg.dir == STEDMA40_MEM_TO_PERIPH ||
- d40c->dma_cfg.dir == STEDMA40_MEM_TO_MEM) {
- event = D40_TYPE_TO_EVENT(d40c->dma_cfg.dst_dev_type);
+ d40c->dma_cfg.dir == STEDMA40_MEM_TO_MEM)
is_src = false;
- } else if (d40c->dma_cfg.dir == STEDMA40_PERIPH_TO_MEM) {
- event = D40_TYPE_TO_EVENT(d40c->dma_cfg.src_dev_type);
+ else if (d40c->dma_cfg.dir == STEDMA40_PERIPH_TO_MEM)
is_src = true;
- } else {
+ else {
chan_err(d40c, "Unknown direction\n");
return -EINVAL;
}
@@ -2128,7 +2097,7 @@ static bool d40_is_paused(struct d40_chan *d40c)
unsigned long flags;
void __iomem *active_reg;
u32 status;
- u32 event;
+ u32 event = D40_TYPE_TO_EVENT(d40c->dma_cfg.dev_type);

spin_lock_irqsave(&d40c->lock, flags);

@@ -2149,10 +2118,8 @@ static bool d40_is_paused(struct d40_chan *d40c)

if (d40c->dma_cfg.dir == STEDMA40_MEM_TO_PERIPH ||
d40c->dma_cfg.dir == STEDMA40_MEM_TO_MEM) {
- event = D40_TYPE_TO_EVENT(d40c->dma_cfg.dst_dev_type);
status = readl(chanbase + D40_CHAN_REG_SDLNK);
} else if (d40c->dma_cfg.dir == STEDMA40_PERIPH_TO_MEM) {
- event = D40_TYPE_TO_EVENT(d40c->dma_cfg.src_dev_type);
status = readl(chanbase + D40_CHAN_REG_SSLNK);
} else {
chan_err(d40c, "Unknown direction\n");
@@ -2294,9 +2261,9 @@ d40_get_dev_addr(struct d40_chan *chan, enum dma_transfer_direction direction)
return chan->runtime_addr;

if (direction == DMA_DEV_TO_MEM)
- addr = plat->dev_rx[cfg->src_dev_type];
+ addr = plat->dev_rx[cfg->dev_type];
else if (direction == DMA_MEM_TO_DEV)
- addr = plat->dev_tx[cfg->dst_dev_type];
+ addr = plat->dev_tx[cfg->dev_type];

return addr;
}
@@ -2427,11 +2394,11 @@ static void d40_set_prio_realtime(struct d40_chan *d40c)

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);
+ __d40_set_prio_rt(d40c, d40c->dma_cfg.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);
+ __d40_set_prio_rt(d40c, d40c->dma_cfg.dev_type, false);
}

/* DMA ENGINE functions */
@@ -2715,7 +2682,7 @@ static int d40_set_runtime_config(struct dma_chan *chan,

if (config->direction == DMA_DEV_TO_MEM) {
dma_addr_t dev_addr_rx =
- d40c->base->plat_data->dev_rx[cfg->src_dev_type];
+ d40c->base->plat_data->dev_rx[cfg->dev_type];

config_addr = config->src_addr;
if (dev_addr_rx)
@@ -2738,7 +2705,7 @@ static int d40_set_runtime_config(struct dma_chan *chan,

} else if (config->direction == DMA_MEM_TO_DEV) {
dma_addr_t dev_addr_tx =
- d40c->base->plat_data->dev_tx[cfg->dst_dev_type];
+ d40c->base->plat_data->dev_tx[cfg->dev_type];

config_addr = config->dst_addr;
if (dev_addr_tx)
@@ -2807,10 +2774,10 @@ static int d40_set_runtime_config(struct dma_chan *chan,
if (chan_is_logical(d40c)) {
if (cfg->dir == STEDMA40_PERIPH_TO_MEM)
d40c->lcpa = d40c->base->lcpa_base +
- cfg->src_dev_type * D40_LCPA_CHAN_SIZE;
+ cfg->dev_type * D40_LCPA_CHAN_SIZE;
else
d40c->lcpa = d40c->base->lcpa_base +
- cfg->dst_dev_type *
+ cfg->dev_type *
D40_LCPA_CHAN_SIZE + D40_LCPA_CHAN_DST_DELTA;
}

diff --git a/drivers/dma/ste_dma40_ll.c b/drivers/dma/ste_dma40_ll.c
index 7180e0d..5eb6c10 100644
--- a/drivers/dma/ste_dma40_ll.c
+++ b/drivers/dma/ste_dma40_ll.c
@@ -63,7 +63,7 @@ void d40_phy_cfg(struct stedma40_chan_cfg *cfg,
(cfg->dir == STEDMA40_PERIPH_TO_PERIPH)) {
/* Set master port to 1 */
src |= 1 << D40_SREG_CFG_MST_POS;
- src |= D40_TYPE_TO_EVENT(cfg->src_dev_type);
+ src |= D40_TYPE_TO_EVENT(cfg->dev_type);

if (cfg->src_info.flow_ctrl == STEDMA40_NO_FLOW_CTRL)
src |= 1 << D40_SREG_CFG_PHY_TM_POS;
@@ -74,7 +74,7 @@ void d40_phy_cfg(struct stedma40_chan_cfg *cfg,
(cfg->dir == STEDMA40_PERIPH_TO_PERIPH)) {
/* Set master port to 1 */
dst |= 1 << D40_SREG_CFG_MST_POS;
- dst |= D40_TYPE_TO_EVENT(cfg->dst_dev_type);
+ dst |= D40_TYPE_TO_EVENT(cfg->dev_type);

if (cfg->dst_info.flow_ctrl == STEDMA40_NO_FLOW_CTRL)
dst |= 1 << D40_SREG_CFG_PHY_TM_POS;
diff --git a/include/linux/platform_data/dma-ste-dma40.h b/include/linux/platform_data/dma-ste-dma40.h
index 869c571..9e42a67 100644
--- a/include/linux/platform_data/dma-ste-dma40.h
+++ b/include/linux/platform_data/dma-ste-dma40.h
@@ -109,8 +109,7 @@ struct stedma40_half_channel_info {
* 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
- * @dst_dev_type: Dst device type
+ * @dev_type: src/dst device type (driver uses dir to figure out which)
* @src_info: Parameters for dst half channel
* @dst_info: Parameters for dst half channel
* @use_fixed_channel: if true, use physical channel specified by phy_channel
@@ -126,8 +125,7 @@ struct stedma40_chan_cfg {
bool realtime;
enum stedma40_mode mode;
enum stedma40_mode_opt mode_opt;
- int src_dev_type;
- int dst_dev_type;
+ int dev_type;
struct stedma40_half_channel_info src_info;
struct stedma40_half_channel_info dst_info;

--
1.7.10.4

2013-04-09 18:40:05

by Lee Jones

[permalink] [raw]
Subject: [PATCH 5/8] dmaengine: ste_dma40: Ensure src and dst registers are configured correctly

Confusingly d40_log_cfg() is used to set up the logical channel
configuration registers, but d40_phy_cfg() is used to configure
physical _and_ logical registers, so it should be called in both
cases. It is the function call's final attribute which determines
whether it's a physical or logical channel, not whether the
function is called or not.

Signed-off-by: Lee Jones <[email protected]>
---
drivers/dma/ste_dma40.c | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/drivers/dma/ste_dma40.c b/drivers/dma/ste_dma40.c
index 9e423ad..49d8c9d 100644
--- a/drivers/dma/ste_dma40.c
+++ b/drivers/dma/ste_dma40.c
@@ -2810,9 +2810,9 @@ static int d40_set_runtime_config(struct dma_chan *chan,
/* Fill in register values */
if (chan_is_logical(d40c))
d40_log_cfg(cfg, &d40c->log_def.lcsp1, &d40c->log_def.lcsp3);
- else
- d40_phy_cfg(cfg, &d40c->src_def_cfg,
- &d40c->dst_def_cfg, false);
+
+ d40_phy_cfg(cfg, &d40c->src_def_cfg, &d40c->dst_def_cfg,
+ chan_is_logical(d40c));

/* These settings will take precedence later */
d40c->runtime_addr = config_addr;
--
1.7.10.4

2013-04-09 18:40:50

by Lee Jones

[permalink] [raw]
Subject: [PATCH 7/8] dmaengine: ste_dma40: Use the BIT macro to replace ugly '(1 << x)'s

The aim is to make the code that little more readable.

Signed-off-by: Lee Jones <[email protected]>
---
drivers/dma/ste_dma40.c | 34 +++++++++++++++++-----------------
1 file changed, 17 insertions(+), 17 deletions(-)

diff --git a/drivers/dma/ste_dma40.c b/drivers/dma/ste_dma40.c
index c14db3e..7b96e75 100644
--- a/drivers/dma/ste_dma40.c
+++ b/drivers/dma/ste_dma40.c
@@ -49,9 +49,9 @@
#define MAX_LCLA_ALLOC_ATTEMPTS 256

/* Bit markings for allocation map */
-#define D40_ALLOC_FREE (1 << 31)
-#define D40_ALLOC_PHY (1 << 30)
-#define D40_ALLOC_LOG_FREE 0
+#define D40_ALLOC_FREE BIT(31)
+#define D40_ALLOC_PHY BIT(30)
+#define D40_ALLOC_LOG_FREE BIT(0)

#define MAX(a, b) (((a) < (b)) ? (b) : (a))

@@ -993,12 +993,12 @@ static int d40_size_2_dmalen(int size, u32 data_width1, u32 data_width2)
int dmalen;
u32 max_w = max(data_width1, data_width2);
u32 min_w = min(data_width1, data_width2);
- u32 seg_max = ALIGN(STEDMA40_MAX_SEG_SIZE << min_w, 1 << max_w);
+ u32 seg_max = ALIGN(STEDMA40_MAX_SEG_SIZE << min_w, BIT(max_w));

if (seg_max > STEDMA40_MAX_SEG_SIZE)
- seg_max -= (1 << max_w);
+ seg_max -= BIT(max_w);

- if (!IS_ALIGNED(size, 1 << max_w))
+ if (!IS_ALIGNED(size, BIT(max_w)))
return -EINVAL;

if (size <= seg_max)
@@ -1448,7 +1448,7 @@ static u32 d40_residue(struct d40_chan *d40c)
>> D40_SREG_ELEM_PHY_ECNT_POS;
}

- return num_elt * (1 << d40c->dma_cfg.dst_info.data_width);
+ return num_elt * BIT(d40c->dma_cfg.dst_info.data_width);
}

static bool d40_tx_is_linked(struct d40_chan *d40c)
@@ -1722,7 +1722,7 @@ static irqreturn_t d40_handle_interrupt(int irq, void *data)
}

/* ACK interrupt */
- writel(1 << idx, base->virtbase + il[row].clr);
+ writel(BIT(idx), base->virtbase + il[row].clr);

spin_lock(&d40c->lock);

@@ -1804,9 +1804,9 @@ static int d40_validate_conf(struct d40_chan *d40c,
}

if (d40_psize_2_burst_size(is_log, conf->src_info.psize) *
- (1 << conf->src_info.data_width) !=
+ BIT(conf->src_info.data_width) !=
d40_psize_2_burst_size(is_log, conf->dst_info.psize) *
- (1 << conf->dst_info.data_width)) {
+ BIT(conf->dst_info.data_width)) {
/*
* The DMAC hardware only supports
* src (burst x width) == dst (burst x width)
@@ -1848,8 +1848,8 @@ static bool d40_alloc_mask_set(struct d40_phy_res *phy,
if (phy->allocated_src == D40_ALLOC_FREE)
phy->allocated_src = D40_ALLOC_LOG_FREE;

- if (!(phy->allocated_src & (1 << log_event_line))) {
- phy->allocated_src |= 1 << log_event_line;
+ if (!(phy->allocated_src & BIT(log_event_line))) {
+ phy->allocated_src |= BIT(log_event_line);
goto found;
} else
goto not_found;
@@ -1860,8 +1860,8 @@ static bool d40_alloc_mask_set(struct d40_phy_res *phy,
if (phy->allocated_dst == D40_ALLOC_FREE)
phy->allocated_dst = D40_ALLOC_LOG_FREE;

- if (!(phy->allocated_dst & (1 << log_event_line))) {
- phy->allocated_dst |= 1 << log_event_line;
+ if (!(phy->allocated_dst & BIT(log_event_line))) {
+ phy->allocated_dst |= BIT(log_event_line);
goto found;
} else
goto not_found;
@@ -1891,11 +1891,11 @@ static bool d40_alloc_mask_free(struct d40_phy_res *phy, bool is_src,

/* Logical channel */
if (is_src) {
- phy->allocated_src &= ~(1 << log_event_line);
+ phy->allocated_src &= ~BIT(log_event_line);
if (phy->allocated_src == D40_ALLOC_LOG_FREE)
phy->allocated_src = D40_ALLOC_FREE;
} else {
- phy->allocated_dst &= ~(1 << log_event_line);
+ phy->allocated_dst &= ~BIT(log_event_line);
if (phy->allocated_dst == D40_ALLOC_LOG_FREE)
phy->allocated_dst = D40_ALLOC_FREE;
}
@@ -2394,7 +2394,7 @@ static void __d40_set_prio_rt(struct d40_chan *d40c, int dev_type, bool src)
u32 rtreg;
u32 event = D40_TYPE_TO_EVENT(dev_type);
u32 group = D40_TYPE_TO_GROUP(dev_type);
- u32 bit = 1 << event;
+ u32 bit = BIT(event);
u32 prioreg;
struct d40_gen_dmac *dmac = &d40c->base->gen_dmac;

--
1.7.10.4

2013-04-09 18:40:00

by Lee Jones

[permalink] [raw]
Subject: [PATCH 4/8] dmaengine: ste_dma40: Do not configure channels during an channel allocation

According to the DMA documentation allocating a channel and configuring
it are two separate actions. By removing the configuration code from the
channel allocation path we lighten the burden on the information required to
successfully allocate a channel.

Cc: Vinod Koul <[email protected]>
Cc: Dan Williams <[email protected]>
Cc: Per Forlin <[email protected]>
Acked-by: Arnd Bergmann <[email protected]>
Signed-off-by: Lee Jones <[email protected]>
---
drivers/dma/ste_dma40.c | 14 --------------
1 file changed, 14 deletions(-)

diff --git a/drivers/dma/ste_dma40.c b/drivers/dma/ste_dma40.c
index 2a0a9d4..9e423ad 100644
--- a/drivers/dma/ste_dma40.c
+++ b/drivers/dma/ste_dma40.c
@@ -2463,16 +2463,10 @@ static int d40_alloc_chan_resources(struct dma_chan *chan)
}

pm_runtime_get_sync(d40c->base->dev);
- /* Fill in basic CFG register values */
- 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);
-
if (d40c->dma_cfg.dir == STEDMA40_PERIPH_TO_MEM)
d40c->lcpa = d40c->base->lcpa_base +
d40c->dma_cfg.src_dev_type * D40_LCPA_CHAN_SIZE;
@@ -2487,14 +2481,6 @@ static int d40_alloc_chan_resources(struct dma_chan *chan)
d40c->phy_chan->num,
d40c->dma_cfg.use_fixed_channel ? ", fixed" : "");

-
- /*
- * Only write channel configuration to the DMA if the physical
- * resource is free. In case of multiple logical channels
- * on the same physical resource, only the first write is necessary.
- */
- if (is_free_phy)
- d40_config_write(d40c);
fail:
pm_runtime_mark_last_busy(d40c->base->dev);
pm_runtime_put_autosuspend(d40c->base->dev);
--
1.7.10.4

2013-04-09 18:39:58

by Lee Jones

[permalink] [raw]
Subject: [PATCH 3/8] dmaengine: ste_dma40: Actually write the runtime configuration to registers

Someone has spent a fair amount of effort writing a runtime configuration
changing algorithm for DMA clients. However, the config appears to never
actually make it to hardware. In order for the configuration to take hold
we need to issue a d40_config_write(), as this is the routine which writes
it into the hardware's registers.

Signed-off-by: Lee Jones <[email protected]>
---
drivers/dma/ste_dma40.c | 3 +++
1 file changed, 3 insertions(+)

diff --git a/drivers/dma/ste_dma40.c b/drivers/dma/ste_dma40.c
index 3b83dee..2a0a9d4 100644
--- a/drivers/dma/ste_dma40.c
+++ b/drivers/dma/ste_dma40.c
@@ -2831,6 +2831,9 @@ static int d40_set_runtime_config(struct dma_chan *chan,
/* These settings will take precedence later */
d40c->runtime_addr = config_addr;
d40c->runtime_direction = config->direction;
+
+ d40_config_write(d40c);
+
dev_dbg(d40c->base->dev,
"configured channel %s for %s, data width %d/%d, "
"maxburst %d/%d elements, LE, no flow control\n",
--
1.7.10.4

2013-04-09 18:51:18

by Arnd Bergmann

[permalink] [raw]
Subject: Re: [PATCH 8/8] ARM: ux500: Amalgamate DMA source and destination channel numbers

On Tuesday 09 April 2013, Lee Jones wrote:
> Devices which utilise DMA tend to use the same channel numbers for
> transmitting and receiving. For this reason and the fact that it'll
> decrease the burden of platform data passed to each device, we're
> amalgamating source and destination device types.
>
> Signed-off-by: Lee Jones <[email protected]>

Very nice cleanup!

Acked-by: Arnd Bergmann <[email protected]>

2013-04-09 18:56:02

by Arnd Bergmann

[permalink] [raw]
Subject: Re: [PATCH 7/8] dmaengine: ste_dma40: Use the BIT macro to replace ugly '(1 << x)'s

On Tuesday 09 April 2013, Lee Jones wrote:
> The aim is to make the code that little more readable.
>
> Signed-off-by: Lee Jones <[email protected]>

I don't find the new version any more or less readable than the old one,
but I have no objections if other people think it's a good idea.

Acked-by: Arnd Bergmann <[email protected]>

2013-04-09 18:56:38

by Arnd Bergmann

[permalink] [raw]
Subject: Re: [PATCH 6/8] dmaengine: ste_dma40: Move LCPA allocation and real-time config

On Tuesday 09 April 2013, Lee Jones wrote:
> There are various pieces of configuration which do not need to happen
> until after a channel is allocated. Here we move some of these so they're
> dealt with when it's time to configure the channel, rather than allocate
> it.
>
> Cc: Vinod Koul <[email protected]>
> Cc: Dan Williams <[email protected]>
> Cc: Per Forlin <[email protected]>
> Signed-off-by: Lee Jones <[email protected]>

Acked-by: Arnd Bergmann <[email protected]>

2013-04-09 18:57:40

by Arnd Bergmann

[permalink] [raw]
Subject: Re: [PATCH 5/8] dmaengine: ste_dma40: Ensure src and dst registers are configured correctly

On Tuesday 09 April 2013, Lee Jones wrote:
> Confusingly d40_log_cfg() is used to set up the logical channel
> configuration registers, but d40_phy_cfg() is used to configure
> physical and logical registers, so it should be called in both
> cases. It is the function call's final attribute which determines
> whether it's a physical or logical channel, not whether the
> function is called or not.

So how did it ever work? Your description sounds like it was
broken all along, but I would assume that someone tested the code.

Arnd

2013-04-09 18:59:45

by Arnd Bergmann

[permalink] [raw]
Subject: Re: [PATCH 3/8] dmaengine: ste_dma40: Actually write the runtime configuration to registers

On Tuesday 09 April 2013, Lee Jones wrote:
> Someone has spent a fair amount of effort writing a runtime configuration
> changing algorithm for DMA clients. However, the config appears to never
> actually make it to hardware. In order for the configuration to take hold
> we need to issue a d40_config_write(), as this is the routine which writes
> it into the hardware's registers.
>
> Signed-off-by: Lee Jones <[email protected]>

So this makes the runtime_addr selection work I suppose, but the
runtime_direction still isn't used anywhere, correct?

Arnd

2013-04-09 19:04:47

by Harvey Harrison

[permalink] [raw]
Subject: Re: [PATCH 7/8] dmaengine: ste_dma40: Use the BIT macro to replace ugly '(1 << x)'s

On Tue, Apr 9, 2013 at 11:39 AM, Lee Jones <[email protected]> wrote:
>
> The aim is to make the code that little more readable.
>
> Signed-off-by: Lee Jones <[email protected]>
> ---

>
> #define MAX(a, b) (((a) < (b)) ? (b) : (a))

Not part of your patch, but probably a good idea to switch to the
generic MAX macro, this
one is evaluating its args twice.

Cheers,

Harvey

2013-04-09 19:07:25

by Lee Jones

[permalink] [raw]
Subject: Re: [PATCH 3/8] dmaengine: ste_dma40: Actually write the runtime configuration to registers

On Tue, 09 Apr 2013, Arnd Bergmann wrote:

> On Tuesday 09 April 2013, Lee Jones wrote:
> > Someone has spent a fair amount of effort writing a runtime configuration
> > changing algorithm for DMA clients. However, the config appears to never
> > actually make it to hardware. In order for the configuration to take hold
> > we need to issue a d40_config_write(), as this is the routine which writes
> > it into the hardware's registers.
> >
> > Signed-off-by: Lee Jones <[email protected]>
>
> So this makes the runtime_addr selection work I suppose, but the
> runtime_direction still isn't used anywhere, correct?

Yes, I have this on my TODO to speak with Linus, as he was the one who
mainlined it.

--
Lee Jones
Linaro ST-Ericsson Landing Team Lead
Linaro.org │ Open source software for ARM SoCs
Follow Linaro: Facebook | Twitter | Blog

2013-04-09 19:09:22

by Lee Jones

[permalink] [raw]
Subject: Re: [PATCH 5/8] dmaengine: ste_dma40: Ensure src and dst registers are configured correctly

On Tue, 09 Apr 2013, Arnd Bergmann wrote:

> On Tuesday 09 April 2013, Lee Jones wrote:
> > Confusingly d40_log_cfg() is used to set up the logical channel
> > configuration registers, but d40_phy_cfg() is used to configure
> > physical and logical registers, so it should be called in both
> > cases. It is the function call's final attribute which determines
> > whether it's a physical or logical channel, not whether the
> > function is called or not.
>
> So how did it ever work? Your description sounds like it was
> broken all along, but I would assume that someone tested the code.

>From what I can see, not.

My best guess is that the 'test' was to see if the configuration
changed using the debug print at the end of the function. I don't see
how else the configuration can be written to hardware.

--
Lee Jones
Linaro ST-Ericsson Landing Team Lead
Linaro.org │ Open source software for ARM SoCs
Follow Linaro: Facebook | Twitter | Blog

2013-04-09 19:13:04

by Lee Jones

[permalink] [raw]
Subject: Re: [PATCH 7/8] dmaengine: ste_dma40: Use the BIT macro to replace ugly '(1 << x)'s

On Tue, 09 Apr 2013, Harvey Harrison wrote:

> On Tue, Apr 9, 2013 at 11:39 AM, Lee Jones <[email protected]> wrote:
> >
> > The aim is to make the code that little more readable.
> >
> > Signed-off-by: Lee Jones <[email protected]>
> > ---
>
> >
> > #define MAX(a, b) (((a) < (b)) ? (b) : (a))
>
> Not part of your patch, but probably a good idea to switch to the
> generic MAX macro, this
> one is evaluating its args twice.

Sure, thanks for the heads-up.

--
Lee Jones
Linaro ST-Ericsson Landing Team Lead
Linaro.org │ Open source software for ARM SoCs
Follow Linaro: Facebook | Twitter | Blog

2013-04-09 19:13:09

by Arnd Bergmann

[permalink] [raw]
Subject: Re: [PATCH 7/8] dmaengine: ste_dma40: Use the BIT macro to replace ugly '(1 << x)'s

On Tuesday 09 April 2013, Harvey Harrison wrote:
>
> On Tue, Apr 9, 2013 at 11:39 AM, Lee Jones <[email protected]> wrote:
> >
> > The aim is to make the code that little more readable.
> >
> > Signed-off-by: Lee Jones <[email protected]>
> > ---
>
> >
> > #define MAX(a, b) (((a) < (b)) ? (b) : (a))
>
> Not part of your patch, but probably a good idea to switch to the
> generic MAX macro, this
> one is evaluating its args twice.

Yes, good point. The macro is only used in one place, to compare
two compile-time constant values, but we should define macros in
drivers that are already provided by the kernel.

Arnd

2013-04-09 20:38:01

by Arnd Bergmann

[permalink] [raw]
Subject: Re: [PATCH 3/8] dmaengine: ste_dma40: Actually write the runtime configuration to registers

On Tuesday 09 April 2013, Lee Jones wrote:
> Someone has spent a fair amount of effort writing a runtime configuration
> changing algorithm for DMA clients. However, the config appears to never
> actually make it to hardware. In order for the configuration to take hold
> we need to issue a d40_config_write(), as this is the routine which writes
> it into the hardware's registers.
>
> Signed-off-by: Lee Jones <[email protected]>

Acked-by: Arnd Bergmann <[email protected]>

2013-04-09 20:38:34

by Arnd Bergmann

[permalink] [raw]
Subject: Re: [PATCH 5/8] dmaengine: ste_dma40: Ensure src and dst registers are configured correctly

On Tuesday 09 April 2013, Lee Jones wrote:
> On Tue, 09 Apr 2013, Arnd Bergmann wrote:
>
> > On Tuesday 09 April 2013, Lee Jones wrote:
> > > Confusingly d40_log_cfg() is used to set up the logical channel
> > > configuration registers, but d40_phy_cfg() is used to configure
> > > physical and logical registers, so it should be called in both
> > > cases. It is the function call's final attribute which determines
> > > whether it's a physical or logical channel, not whether the
> > > function is called or not.
> >
> > So how did it ever work? Your description sounds like it was
> > broken all along, but I would assume that someone tested the code.
>
> From what I can see, not.
>
> My best guess is that the 'test' was to see if the configuration
> changed using the debug print at the end of the function. I don't see
> how else the configuration can be written to hardware.

Acked-by: Arnd Bergmann <[email protected]>

2013-04-10 09:34:20

by Lee Jones

[permalink] [raw]
Subject: Re: [PATCH 7/8] dmaengine: ste_dma40: Use the BIT macro to replace ugly '(1 << x)'s

On Tue, 09 Apr 2013, Arnd Bergmann wrote:

> On Tuesday 09 April 2013, Harvey Harrison wrote:
> >
> > On Tue, Apr 9, 2013 at 11:39 AM, Lee Jones <[email protected]> wrote:
> > >
> > > The aim is to make the code that little more readable.
> > >
> > > Signed-off-by: Lee Jones <[email protected]>
> > > ---
> >
> > >
> > > #define MAX(a, b) (((a) < (b)) ? (b) : (a))
> >
> > Not part of your patch, but probably a good idea to switch to the
> > generic MAX macro, this
> > one is evaluating its args twice.
>
> Yes, good point. The macro is only used in one place, to compare
> two compile-time constant values, but we should define macros in
> drivers that are already provided by the kernel.

Okay, it looks like the generic implementation has brackets in it,
which isn't allowed for this particular usecase. I'll fix this one
instead.

--
Lee Jones
Linaro ST-Ericsson Landing Team Lead
Linaro.org │ Open source software for ARM SoCs
Follow Linaro: Facebook | Twitter | Blog

2013-04-10 12:22:38

by Arnd Bergmann

[permalink] [raw]
Subject: Re: [PATCH 7/8] dmaengine: ste_dma40: Use the BIT macro to replace ugly '(1 << x)'s

On Wednesday 10 April 2013, Lee Jones wrote:
> On Tue, 09 Apr 2013, Arnd Bergmann wrote:

> > Yes, good point. The macro is only used in one place, to compare
> > two compile-time constant values, but we should define macros in
> > drivers that are already provided by the kernel.
>
> Okay, it looks like the generic implementation has brackets in it,
> which isn't allowed for this particular usecase.

Ah, right.

> I'll fix this one instead.

Probably not worth then. You could open-code the comparison where
it is used and remove the macro if you want, but I probably
would not bother.

Arnd

2013-04-12 13:50:13

by Rabin Vincent

[permalink] [raw]
Subject: Re: [PATCH 3/8] dmaengine: ste_dma40: Actually write the runtime configuration to registers

2013/4/9 Lee Jones <[email protected]>:
> Someone has spent a fair amount of effort writing a runtime configuration
> changing algorithm for DMA clients. However, the config appears to never
> actually make it to hardware. In order for the configuration to take hold
> we need to issue a d40_config_write(), as this is the routine which writes
> it into the hardware's registers.

No, it's not. This function is only for initial configuration which
should only be written when the channel is allocated. In fact, by
calling it here in runtime_config, you are introducing a serious bug:
other logical channels on the same physical channel will stop because of
the SSLNK/SDLNK of the physical channel being zeroed.

The runtime config already makes it the hardware in the existing code,
via d40_*_cfg().

2013-04-12 13:55:12

by Rabin Vincent

[permalink] [raw]
Subject: Re: [PATCH 4/8] dmaengine: ste_dma40: Do not configure channels during an channel allocation

2013/4/9 Lee Jones <[email protected]>:
> diff --git a/drivers/dma/ste_dma40.c b/drivers/dma/ste_dma40.c
> index 2a0a9d4..9e423ad 100644
> --- a/drivers/dma/ste_dma40.c
> +++ b/drivers/dma/ste_dma40.c
> @@ -2463,16 +2463,10 @@ static int d40_alloc_chan_resources(struct dma_chan *chan)
> }
>
> pm_runtime_get_sync(d40c->base->dev);
> - /* Fill in basic CFG register values */
> - 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);
> -
> if (d40c->dma_cfg.dir == STEDMA40_PERIPH_TO_MEM)
> d40c->lcpa = d40c->base->lcpa_base +
> d40c->dma_cfg.src_dev_type * D40_LCPA_CHAN_SIZE;
> @@ -2487,14 +2481,6 @@ static int d40_alloc_chan_resources(struct dma_chan *chan)
> d40c->phy_chan->num,
> d40c->dma_cfg.use_fixed_channel ? ", fixed" : "");
>
> -
> - /*
> - * Only write channel configuration to the DMA if the physical
> - * resource is free. In case of multiple logical channels
> - * on the same physical resource, only the first write is necessary.
> - */
> - if (is_free_phy)
> - d40_config_write(d40c);

This function does basic initial configuration which is linked to
whether the channel is pysical or logical -- something that is not being
allowed to be runtime configured, so the place to call this function is
here. Furthermore, it clears the SSLNK/SDLNK which has to be done here,
when the phy channel is first allocated.

2013-04-12 14:03:04

by Rabin Vincent

[permalink] [raw]
Subject: Re: [PATCH 5/8] dmaengine: ste_dma40: Ensure src and dst registers are configured correctly

2013/4/9 Lee Jones <[email protected]>:
> diff --git a/drivers/dma/ste_dma40.c b/drivers/dma/ste_dma40.c
> index 9e423ad..49d8c9d 100644
> --- a/drivers/dma/ste_dma40.c
> +++ b/drivers/dma/ste_dma40.c
> @@ -2810,9 +2810,9 @@ static int d40_set_runtime_config(struct dma_chan *chan,
> /* Fill in register values */
> if (chan_is_logical(d40c))
> d40_log_cfg(cfg, &d40c->log_def.lcsp1, &d40c->log_def.lcsp3);
> - else
> - d40_phy_cfg(cfg, &d40c->src_def_cfg,
> - &d40c->dst_def_cfg, false);
> +
> + d40_phy_cfg(cfg, &d40c->src_def_cfg, &d40c->dst_def_cfg,
> + chan_is_logical(d40c));
>
> /* These settings will take precedence later */
> d40c->runtime_addr = config_addr;

There is no need to call this function there. For a logical channel,
the underlying physical channel's SSCFG/SDCFG should only be written
once in the beginning (via d40_config_write()) so there is no need to
change this src_def_cfg and dst_def_cfg again without using them. For a
logical channel, d40_phy_cfg() does nothing else which is
runtime_config()able.

2013-04-12 16:13:32

by Lee Jones

[permalink] [raw]
Subject: Re: [PATCH 3/8] dmaengine: ste_dma40: Actually write the runtime configuration to registers

On Fri, 12 Apr 2013, Rabin Vincent wrote:

> 2013/4/9 Lee Jones <[email protected]>:
> > Someone has spent a fair amount of effort writing a runtime configuration
> > changing algorithm for DMA clients. However, the config appears to never
> > actually make it to hardware. In order for the configuration to take hold
> > we need to issue a d40_config_write(), as this is the routine which writes
> > it into the hardware's registers.
>
> No, it's not. This function is only for initial configuration which
> should only be written when the channel is allocated. In fact, by
> calling it here in runtime_config, you are introducing a serious bug:
> other logical channels on the same physical channel will stop because of
> the SSLNK/SDLNK of the physical channel being zeroed.
>
> The runtime config already makes it the hardware in the existing code,
> via d40_*_cfg().

Ah, I see. I'll move it all back and investigate my bug further then.

Thanks for taking the time to write such a well written review.

--
Lee Jones
Linaro ST-Ericsson Landing Team Lead
Linaro.org │ Open source software for ARM SoCs
Follow Linaro: Facebook | Twitter | Blog

2013-04-12 16:38:17

by Lee Jones

[permalink] [raw]
Subject: Re: [PATCH 4/8] dmaengine: ste_dma40: Do not configure channels during an channel allocation

On Fri, 12 Apr 2013, Rabin Vincent wrote:

> 2013/4/9 Lee Jones <[email protected]>:
> > diff --git a/drivers/dma/ste_dma40.c b/drivers/dma/ste_dma40.c
> > index 2a0a9d4..9e423ad 100644
> > --- a/drivers/dma/ste_dma40.c
> > +++ b/drivers/dma/ste_dma40.c
> > @@ -2463,16 +2463,10 @@ static int d40_alloc_chan_resources(struct dma_chan *chan)
> > }
> >
> > pm_runtime_get_sync(d40c->base->dev);
> > - /* Fill in basic CFG register values */
> > - 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);
> > -
> > if (d40c->dma_cfg.dir == STEDMA40_PERIPH_TO_MEM)
> > d40c->lcpa = d40c->base->lcpa_base +
> > d40c->dma_cfg.src_dev_type * D40_LCPA_CHAN_SIZE;
> > @@ -2487,14 +2481,6 @@ static int d40_alloc_chan_resources(struct dma_chan *chan)
> > d40c->phy_chan->num,
> > d40c->dma_cfg.use_fixed_channel ? ", fixed" : "");
> >
> > -
> > - /*
> > - * Only write channel configuration to the DMA if the physical
> > - * resource is free. In case of multiple logical channels
> > - * on the same physical resource, only the first write is necessary.
> > - */
> > - if (is_free_phy)
> > - d40_config_write(d40c);
>
> This function does basic initial configuration which is linked to
> whether the channel is pysical or logical -- something that is not being
> allowed to be runtime configured, so the place to call this function is
> here. Furthermore, it clears the SSLNK/SDLNK which has to be done here,
> when the phy channel is first allocated.

Okay, I see what you're saying.

So I need to devise another way, as this function cannot be called
here either. Using the dmaengine API, allocating a channel and
configuring it are to be completed using different calls. Using the
API correctly, there is no way the driver can setup the channel
with all of the relevant information during allocation time.

The steps are as follows:

dma_request_channel() - here we only allot a channel number and
allocate the appropriate resources for the
channel.

dma_slave_config() - this is where we're meant to configure the
channel, so d40_config_write() needs to be
called here, as only dma_slave_config() will
carry the information required so as
d40_*_cfg() can make the correct decisions.

At the moment calling dma_slave_config() ends up calling
d40_set_runtime_config(), which, taking into consideration what you've
been saying about possibly cutting off other logical channels, is
probably not what we want. I'll take a look at the dmaengine API and
see if there's a more appropriate way to do that.

Thanks again for your input Rabin, it's invaluable.

Kind regards,
Lee

--
Lee Jones
Linaro ST-Ericsson Landing Team Lead
Linaro.org │ Open source software for ARM SoCs
Follow Linaro: Facebook | Twitter | Blog

2013-04-14 16:35:35

by Rabin Vincent

[permalink] [raw]
Subject: Re: [PATCH 4/8] dmaengine: ste_dma40: Do not configure channels during an channel allocation

2013/4/12 Lee Jones <[email protected]>:
> So I need to devise another way, as this function cannot be called
> here either. Using the dmaengine API, allocating a channel and
> configuring it are to be completed using different calls. Using the
> API correctly, there is no way the driver can setup the channel
> with all of the relevant information during allocation time.
>
> The steps are as follows:
>
> dma_request_channel() - here we only allot a channel number and
> allocate the appropriate resources for the
> channel.
>
> dma_slave_config() - this is where we're meant to configure the
> channel, so d40_config_write() needs to be
> called here, as only dma_slave_config() will
> carry the information required so as
> d40_*_cfg() can make the correct decisions.

The choice between whether a physical or a logical channel is used is
not something that is configurable via dma_slave_config(). And
d40_config_write() only needs that information, and that information is
available in dma_request_channel(). Therefore no more information
relevant to d40_config_write() will be obtained in dma_slave_config().
Hence d40_config_write() can be called in dma_request_channel().

2013-04-15 11:06:09

by Lee Jones

[permalink] [raw]
Subject: Re: [PATCH 3/8] dmaengine: ste_dma40: Actually write the runtime configuration to registers

On Fri, 12 Apr 2013, Rabin Vincent wrote:

> 2013/4/9 Lee Jones <[email protected]>:
> > Someone has spent a fair amount of effort writing a runtime configuration
> > changing algorithm for DMA clients. However, the config appears to never
> > actually make it to hardware. In order for the configuration to take hold
> > we need to issue a d40_config_write(), as this is the routine which writes
> > it into the hardware's registers.
>
> No, it's not. This function is only for initial configuration which
> should only be written when the channel is allocated. In fact, by
> calling it here in runtime_config, you are introducing a serious bug:
> other logical channels on the same physical channel will stop because of
> the SSLNK/SDLNK of the physical channel being zeroed.
>
> The runtime config already makes it the hardware in the existing code,
> via d40_*_cfg().

Sorry Rabin, but the only place I can see the config being written is
in d40_config_write().

Can you paste the line of code in d40_*_cfg() which actually writes
the config to hardware please? I don't see it.

--
Lee Jones
Linaro ST-Ericsson Landing Team Lead
Linaro.org │ Open source software for ARM SoCs
Follow Linaro: Facebook | Twitter | Blog

2013-04-15 11:36:43

by Rabin Vincent

[permalink] [raw]
Subject: Re: [PATCH 3/8] dmaengine: ste_dma40: Actually write the runtime configuration to registers

2013/4/15 Lee Jones <[email protected]>:
> On Fri, 12 Apr 2013, Rabin Vincent wrote:
>> 2013/4/9 Lee Jones <[email protected]>:
>> > Someone has spent a fair amount of effort writing a runtime configuration
>> > changing algorithm for DMA clients. However, the config appears to never
>> > actually make it to hardware. In order for the configuration to take hold
>> > we need to issue a d40_config_write(), as this is the routine which writes
>> > it into the hardware's registers.
>>
>> No, it's not. This function is only for initial configuration which
>> should only be written when the channel is allocated. In fact, by
>> calling it here in runtime_config, you are introducing a serious bug:
>> other logical channels on the same physical channel will stop because of
>> the SSLNK/SDLNK of the physical channel being zeroed.
>>
>> The runtime config already makes it the hardware in the existing code,
>> via d40_*_cfg().
>
> Sorry Rabin, but the only place I can see the config being written is
> in d40_config_write().
>
> Can you paste the line of code in d40_*_cfg() which actually writes
> the config to hardware please? I don't see it.

It's not that simple. There are some pointers passed to d40_*_cfg() and
that function writes the configuration to the variables those pointers
point to (d40c->log_def.lcsp1, d40c->src_def_cfg, etc.). Please read
the code to see how those variables end up being used later when the
LLIs are prepared for the HW.

2013-04-15 11:59:13

by Lee Jones

[permalink] [raw]
Subject: Re: [PATCH 3/8] dmaengine: ste_dma40: Actually write the runtime configuration to registers

On Mon, 15 Apr 2013, Rabin Vincent wrote:

> 2013/4/15 Lee Jones <[email protected]>:
> > On Fri, 12 Apr 2013, Rabin Vincent wrote:
> >> 2013/4/9 Lee Jones <[email protected]>:
> >> > Someone has spent a fair amount of effort writing a runtime configuration
> >> > changing algorithm for DMA clients. However, the config appears to never
> >> > actually make it to hardware. In order for the configuration to take hold
> >> > we need to issue a d40_config_write(), as this is the routine which writes
> >> > it into the hardware's registers.
> >>
> >> No, it's not. This function is only for initial configuration which
> >> should only be written when the channel is allocated. In fact, by
> >> calling it here in runtime_config, you are introducing a serious bug:
> >> other logical channels on the same physical channel will stop because of
> >> the SSLNK/SDLNK of the physical channel being zeroed.
> >>
> >> The runtime config already makes it the hardware in the existing code,
> >> via d40_*_cfg().
> >
> > Sorry Rabin, but the only place I can see the config being written is
> > in d40_config_write().
> >
> > Can you paste the line of code in d40_*_cfg() which actually writes
> > the config to hardware please? I don't see it.
>
> It's not that simple. There are some pointers passed to d40_*_cfg() and
> that function writes the configuration to the variables those pointers
> point to (d40c->log_def.lcsp1, d40c->src_def_cfg, etc.). Please read
> the code to see how those variables end up being used later when the
> LLIs are prepared for the HW.

I have read the code, which is why I know that the config only gets
written in d40_config_write(). :)

So the configuration which gets set in the runtime_config routine
doesn't ever make it to hardware - hence this patch.

Unless I'm missing something?

--
Lee Jones
Linaro ST-Ericsson Landing Team Lead
Linaro.org │ Open source software for ARM SoCs
Follow Linaro: Facebook | Twitter | Blog

2013-04-15 13:47:33

by Linus Walleij

[permalink] [raw]
Subject: Re: [PATCH 3/8] dmaengine: ste_dma40: Actually write the runtime configuration to registers

On Mon, Apr 15, 2013 at 1:59 PM, Lee Jones <[email protected]> wrote:
> On Mon, 15 Apr 2013, Rabin Vincent wrote:
>> 2013/4/15 Lee Jones <[email protected]>:
>> > On Fri, 12 Apr 2013, Rabin Vincent wrote:
>> >> 2013/4/9 Lee Jones <[email protected]>:
>> >> > Someone has spent a fair amount of effort writing a runtime configuration
>> >> > changing algorithm for DMA clients. However, the config appears to never
>> >> > actually make it to hardware. In order for the configuration to take hold
>> >> > we need to issue a d40_config_write(), as this is the routine which writes
>> >> > it into the hardware's registers.
>> >>
>> >> No, it's not. This function is only for initial configuration which
>> >> should only be written when the channel is allocated. In fact, by
>> >> calling it here in runtime_config, you are introducing a serious bug:
>> >> other logical channels on the same physical channel will stop because of
>> >> the SSLNK/SDLNK of the physical channel being zeroed.
>> >>
>> >> The runtime config already makes it the hardware in the existing code,
>> >> via d40_*_cfg().
>> >
>> > Sorry Rabin, but the only place I can see the config being written is
>> > in d40_config_write().
>> >
>> > Can you paste the line of code in d40_*_cfg() which actually writes
>> > the config to hardware please? I don't see it.
>>
>> It's not that simple. There are some pointers passed to d40_*_cfg() and
>> that function writes the configuration to the variables those pointers
>> point to (d40c->log_def.lcsp1, d40c->src_def_cfg, etc.). Please read
>> the code to see how those variables end up being used later when the
>> LLIs are prepared for the HW.
>
> I have read the code, which is why I know that the config only gets
> written in d40_config_write(). :)
>
> So the configuration which gets set in the runtime_config routine
> doesn't ever make it to hardware - hence this patch.
>
> Unless I'm missing something?

The runtime config sets up the config for all *subsequent* jobs.
struct d40_chan contains e.g. runtime_addr, runtime_direction
etc to store up the stuff being configured. This is done for
all the other config as well using d40_log_cfg() or
d40_phy_cfg(), and the result is cached in the channel
struct, here called d40c.

Next, when preparing jobs, the DMA40 LLI engine will fill in
job descriptors using e.g. d40_get_dev_addr()
and pick settings from this cached runtime config.

When the subsequent jobs trigger, it allocates channel resources
by calling d40_alloc_chan_resources(). The config is written to the
hardware by calling d40_config_write().

So the basic misunderstanding here is that you think
the config shall take effect immediately, that is not the
idea. The configuration will be cached in the channel
struct, then it will take effect when the next job that is
queued up allocates its resources to commence.

Maybe you haven't grasped the asynchronous nature
of the DMAengine? It's a bit like multithreading. You
queue up things, then they commence at a later time.
Not immediately.

Example: the SPI driver for PL022 may talk to a
8, 16 or 32bit capable device. Depending on which device
it wants to queue a job for, it need to be configured differently,
like for another width.

At the time you are queueing a new job, another job may
already be in flight. If you issue d40_config_write() at this
point, you will cause undesired effects to the job that may
already be running. Such as reconfiguring the width
of the channel.

You may not observe that bug because there is no
job in flight, or because the actual configuration is identical
for two consecutive jobs, but if you're really stressing something,
queuing jobs while others are already in flight, you will
see it immediately.

Therefore, this patch should be dropped.

Yours,
Linus Walleij

2013-04-15 14:28:32

by Lee Jones

[permalink] [raw]
Subject: Re: [PATCH 3/8] dmaengine: ste_dma40: Actually write the runtime configuration to registers

On Mon, 15 Apr 2013, Linus Walleij wrote:

> On Mon, Apr 15, 2013 at 1:59 PM, Lee Jones <[email protected]> wrote:
> > On Mon, 15 Apr 2013, Rabin Vincent wrote:
> >> 2013/4/15 Lee Jones <[email protected]>:
> >> > On Fri, 12 Apr 2013, Rabin Vincent wrote:
> >> >> 2013/4/9 Lee Jones <[email protected]>:
> >> >> > Someone has spent a fair amount of effort writing a runtime configuration
> >> >> > changing algorithm for DMA clients. However, the config appears to never
> >> >> > actually make it to hardware. In order for the configuration to take hold
> >> >> > we need to issue a d40_config_write(), as this is the routine which writes
> >> >> > it into the hardware's registers.
> >> >>
> >> >> No, it's not. This function is only for initial configuration which
> >> >> should only be written when the channel is allocated. In fact, by
> >> >> calling it here in runtime_config, you are introducing a serious bug:
> >> >> other logical channels on the same physical channel will stop because of
> >> >> the SSLNK/SDLNK of the physical channel being zeroed.
> >> >>
> >> >> The runtime config already makes it the hardware in the existing code,
> >> >> via d40_*_cfg().
> >> >
> >> > Sorry Rabin, but the only place I can see the config being written is
> >> > in d40_config_write().
> >> >
> >> > Can you paste the line of code in d40_*_cfg() which actually writes
> >> > the config to hardware please? I don't see it.
> >>
> >> It's not that simple. There are some pointers passed to d40_*_cfg() and
> >> that function writes the configuration to the variables those pointers
> >> point to (d40c->log_def.lcsp1, d40c->src_def_cfg, etc.). Please read
> >> the code to see how those variables end up being used later when the
> >> LLIs are prepared for the HW.
> >
> > I have read the code, which is why I know that the config only gets
> > written in d40_config_write(). :)
> >
> > So the configuration which gets set in the runtime_config routine
> > doesn't ever make it to hardware - hence this patch.
> >
> > Unless I'm missing something?
>
> The runtime config sets up the config for all *subsequent* jobs.
> struct d40_chan contains e.g. runtime_addr, runtime_direction
> etc to store up the stuff being configured. This is done for
> all the other config as well using d40_log_cfg() or
> d40_phy_cfg(), and the result is cached in the channel
> struct, here called d40c.
>
> Next, when preparing jobs, the DMA40 LLI engine will fill in
> job descriptors using e.g. d40_get_dev_addr()
> and pick settings from this cached runtime config.
>
> When the subsequent jobs trigger, it allocates channel resources
> by calling d40_alloc_chan_resources(). The config is written to the
> hardware by calling d40_config_write().
>
> So the basic misunderstanding here is that you think
> the config shall take effect immediately, that is not the
> idea. The configuration will be cached in the channel
> struct, then it will take effect when the next job that is
> queued up allocates its resources to commence.
>
> Maybe you haven't grasped the asynchronous nature
> of the DMAengine? It's a bit like multithreading. You
> queue up things, then they commence at a later time.
> Not immediately.
>
> Example: the SPI driver for PL022 may talk to a
> 8, 16 or 32bit capable device. Depending on which device
> it wants to queue a job for, it need to be configured differently,
> like for another width.
>
> At the time you are queueing a new job, another job may
> already be in flight. If you issue d40_config_write() at this
> point, you will cause undesired effects to the job that may
> already be running. Such as reconfiguring the width
> of the channel.
>
> You may not observe that bug because there is no
> job in flight, or because the actual configuration is identical
> for two consecutive jobs, but if you're really stressing something,
> queuing jobs while others are already in flight, you will
> see it immediately.
>
> Therefore, this patch should be dropped.

Ah right, thanks for your explanation.

I have also just finished speaking to Rabin privately, who painted a
good picture of how the configuration side of this driver should
work.

I have dropped this patch and will shortly be replacing it with
something else.

Thanks again to both of you.

--
Lee Jones
Linaro ST-Ericsson Landing Team Lead
Linaro.org │ Open source software for ARM SoCs
Follow Linaro: Facebook | Twitter | Blog

2013-04-24 13:45:39

by Linus Walleij

[permalink] [raw]
Subject: Re: [PATCH 1/8] dmaengine: ste_dma40: Assign memcpy channels in the driver

On Tue, Apr 9, 2013 at 8:39 PM, Lee Jones <[email protected]> wrote:

> The channels reserved for memcpy are the same for all currently
> supported platforms. With this in mind, we can ease the platform
> data passing requirement by moving these assignments out from
> platform code and place them directly into the driver.
>
> Cc: Vinod Koul <[email protected]>
> Cc: Dan Williams <[email protected]>
> Cc: Per Forlin <[email protected]>
> Acked-by: Arnd Bergmann <[email protected]>
> Signed-off-by: Lee Jones <[email protected]>

(...)

> -/* Reserved event lines for memcpy only */
> -static int dma40_memcpy_event[] = {
> - DB8500_DMA_MEMCPY_TX_0,
> - DB8500_DMA_MEMCPY_TX_1,
> - DB8500_DMA_MEMCPY_TX_2,
> - DB8500_DMA_MEMCPY_TX_3,
> - DB8500_DMA_MEMCPY_TX_4,
> - DB8500_DMA_MEMCPY_TX_5,
> -};

(...)

> +/* Reserved event lines for memcpy only. */
> +static int dma40_memcpy_channels[] = { 56, 57, 58, 59, 60 };

So what's so bad with using the #defines?

I would prefer if you took the entire content of
arch/arm/mach-ux500/ste-dma40-db8500.h
and copied into the DMA driver, so you atleast
have a chance of understanding what these numbers
are about.

Yours,
Linus Walleij

2013-04-24 15:05:32

by Linus Walleij

[permalink] [raw]
Subject: Re: [PATCH 1/8] dmaengine: ste_dma40: Assign memcpy channels in the driver

On Wed, Apr 24, 2013 at 4:54 PM, Lee Jones <[email protected]> wrote:
> On 24 April 2013 14:45, Linus Walleij <[email protected]> wrote:
>> On Tue, Apr 9, 2013 at 8:39 PM, Lee Jones <[email protected]> wrote:
>>
>> > The channels reserved for memcpy are the same for all currently
>> > supported platforms. With this in mind, we can ease the platform
>> > data passing requirement by moving these assignments out from
>> > platform code and place them directly into the driver.
>> >
>> > Cc: Vinod Koul <[email protected]>
>> > Cc: Dan Williams <[email protected]>
>> > Cc: Per Forlin <[email protected]>
>> > Acked-by: Arnd Bergmann <[email protected]>
>> > Signed-off-by: Lee Jones <[email protected]>
>>
>> (...)
>>
>> > -/* Reserved event lines for memcpy only */
>> > -static int dma40_memcpy_event[] = {
>> > - DB8500_DMA_MEMCPY_TX_0,
>> > - DB8500_DMA_MEMCPY_TX_1,
>> > - DB8500_DMA_MEMCPY_TX_2,
>> > - DB8500_DMA_MEMCPY_TX_3,
>> > - DB8500_DMA_MEMCPY_TX_4,
>> > - DB8500_DMA_MEMCPY_TX_5,
>> > -};
>>
>> (...)
>>
>> > +/* Reserved event lines for memcpy only. */
>> > +static int dma40_memcpy_channels[] = { 56, 57, 58, 59, 60 };
>>
>> So what's so bad with using the #defines?
>>
>> I would prefer if you took the entire content of
>> arch/arm/mach-ux500/ste-dma40-db8500.h
>> and copied into the DMA driver, so you atleast
>> have a chance of understanding what these numbers
>> are about.
>
>
> I did attempt to do that, but Arnd NAK:ed it:
>
> "Hmm, not sure about this one. The slave numbers are not really
> platform_data and I think they should not be exposed to drivers. It
> makes sense to keep the numbers for the memcpy channels in the driver
> itself as they are hardwired in the driver, but the slave channels
> should stay in the platform I think."
>
> ... and I didn't want to duplicate the defines, but I'll so whatever
> you choose.

I don't think I agree.

OK atleast define the numbers with something like
#define DB8500_DMA_MEMCPY_TX_0 56
etc, just hard-coding the numbers is pretty unhelpful, OK?

Ultimately these 5 numbers should (optionally) come in from
the device tree node for the DMA40 itself, maybe a later patch
adds that...?

Yours,
Linus Walleij