From 664a57ecb026dc47f9d8b002e6dcb557e877e4d1 Mon Sep 17 00:00:00 2001 From: Lee Jones <lee.jones@linaro.org> Date: Fri, 3 May 2013 15:31:53 +0100 Subject: 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. Acked-by: Vinod Koul <vnod.koul@intel.com> Acked-by: Arnd Bergmann <arnd@arndb.de> Signed-off-by: Lee Jones <lee.jones@linaro.org> Signed-off-by: Linus Walleij <linus.walleij@linaro.org> --- drivers/dma/ste_dma40.c | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) (limited to 'drivers/dma') diff --git a/drivers/dma/ste_dma40.c b/drivers/dma/ste_dma40.c index 1734feec47b1..12de79e84b15 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 -- cgit v1.2.3 From a2acaa2163566ad2e04b10fdf81de650e9b9261b Mon Sep 17 00:00:00 2001 From: Linus Walleij <linus.walleij@linaro.org> Date: Fri, 3 May 2013 21:46:09 +0200 Subject: dmaengine: ste_dma40: Fix up static memcpy event lines The commit "dmaengine: ste_dma40: Assign memcpy channels in the driver" had two problems: - It assigned magic numbers to the memcpy event lines instead of giving them symbolic names. - It seems to have missed one of the memcpy event lines, number 51. This patch fixes it up. Acked-by: Lee Jones <lee.jones@linaro.org> Acked-by: Vinod Koul <vinod.koul@intel.com> Signed-off-by: Linus Walleij <linus.walleij@linaro.org> --- drivers/dma/ste_dma40.c | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) (limited to 'drivers/dma') diff --git a/drivers/dma/ste_dma40.c b/drivers/dma/ste_dma40.c index 12de79e84b15..cd7b4808d08c 100644 --- a/drivers/dma/ste_dma40.c +++ b/drivers/dma/ste_dma40.c @@ -56,7 +56,21 @@ #define MAX(a, b) (((a) < (b)) ? (b) : (a)) /* Reserved event lines for memcpy only. */ -static int dma40_memcpy_channels[] = { 56, 57, 58, 59, 60 }; +#define DB8500_DMA_MEMCPY_EV_0 51 +#define DB8500_DMA_MEMCPY_EV_1 56 +#define DB8500_DMA_MEMCPY_EV_2 57 +#define DB8500_DMA_MEMCPY_EV_3 58 +#define DB8500_DMA_MEMCPY_EV_4 59 +#define DB8500_DMA_MEMCPY_EV_5 60 + +static int dma40_memcpy_channels[] = { + DB8500_DMA_MEMCPY_EV_0, + DB8500_DMA_MEMCPY_EV_1, + DB8500_DMA_MEMCPY_EV_2, + DB8500_DMA_MEMCPY_EV_3, + DB8500_DMA_MEMCPY_EV_4, + DB8500_DMA_MEMCPY_EV_5, +}; /** * enum 40_command - The different commands and/or statuses. -- cgit v1.2.3 From 29027a1e1121a1c9c5e726cf09dc2e9789a282f3 Mon Sep 17 00:00:00 2001 From: Lee Jones <lee.jones@linaro.org> Date: Fri, 3 May 2013 15:31:54 +0100 Subject: 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. Acked-by: Vinod Koul <vnod.koul@intel.com> Acked-by: Arnd Bergmann <arnd@arndb.de> Acked-by: Linus Walleij <linus.walleij@linaro.org> Signed-off-by: Lee Jones <lee.jones@linaro.org> Signed-off-by: Linus Walleij <linus.walleij@linaro.org> --- 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(-) (limited to 'drivers/dma') diff --git a/arch/arm/mach-ux500/devices-db8500.c b/arch/arm/mach-ux500/devices-db8500.c index 159855fae55b..a30977b374ba 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 cd7b4808d08c..c47139ae8fa8 100644 --- a/drivers/dma/ste_dma40.c +++ b/drivers/dma/ste_dma40.c @@ -72,6 +72,34 @@ static int dma40_memcpy_channels[] = { DB8500_DMA_MEMCPY_EV_5, }; +/* 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. * @@ -2029,13 +2057,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 a8087843a99b..869c571c8c08 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; -- cgit v1.2.3 From 4f8fc46c797015dddc1d4c76e1b485b57373683b Mon Sep 17 00:00:00 2001 From: Lee Jones <lee.jones@linaro.org> Date: Fri, 3 May 2013 15:31:55 +0100 Subject: dmaengine: ste_dma40: Rectify incorrect configuration validation checking If we compare an event's group (dev_type / 16) with STEDMA40_DEV_DST_MEMORY (-1), the only way we'd obtain a positive result is if we passed -16 as a device type, which is unfeasible. Instead, it would be much more sane to compare STEDMA40_DEV_DST_MEMORY against the raw dev_type in order to expect the expected result. Acked-by: Vinod Koul <vinod.koul@intel.com> Signed-off-by: Lee Jones <lee.jones@linaro.org> Signed-off-by: Linus Walleij <linus.walleij@linaro.org> --- drivers/dma/ste_dma40.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'drivers/dma') diff --git a/drivers/dma/ste_dma40.c b/drivers/dma/ste_dma40.c index c47139ae8fa8..d481cb8521d9 100644 --- a/drivers/dma/ste_dma40.c +++ b/drivers/dma/ste_dma40.c @@ -1785,19 +1785,19 @@ static int d40_validate_conf(struct d40_chan *d40c, } if (conf->dir == STEDMA40_MEM_TO_PERIPH && - dst_event_group == STEDMA40_DEV_DST_MEMORY) { + conf->dst_dev_type == STEDMA40_DEV_DST_MEMORY) { chan_err(d40c, "Invalid dst\n"); res = -EINVAL; } if (conf->dir == STEDMA40_PERIPH_TO_MEM && - src_event_group == STEDMA40_DEV_SRC_MEMORY) { + conf->src_dev_type == 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) { + if (conf->src_dev_type == STEDMA40_DEV_SRC_MEMORY && + conf->dst_dev_type == STEDMA40_DEV_DST_MEMORY && is_log) { chan_err(d40c, "No event line\n"); res = -EINVAL; } -- cgit v1.2.3 From 26955c07dcf3c36b6427e52fec0f725300ca079e Mon Sep 17 00:00:00 2001 From: Lee Jones <lee.jones@linaro.org> Date: Fri, 3 May 2013 15:31:56 +0100 Subject: dmaengine: ste_dma40: Amalgamate DMA source and destination channel numbers Devices which utilise DMA use the same device numbers for transmitting and receiving. In this patch we encode the source and destination information into one single attribute. We can subsequently exploit the direction attribute to see which of the transfer directions are being described. This also lessens the burden on platform data. Cc: Dan Williams <djbw@fb.com> Cc: Per Forlin <per.forlin@stericsson.com> Cc: Rabin Vincent <rabin@rab.in> Acked-by: Vinod Koul <vinod.koul@intel.com> Acked-by: Arnd Bergmann <arnd@arndb.de> Signed-off-by: Lee Jones <lee.jones@linaro.org> Signed-off-by: Linus Walleij <linus.walleij@linaro.org> --- 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 | 93 +++++--------- drivers/dma/ste_dma40_ll.c | 4 +- include/linux/platform_data/dma-ste-dma40.h | 6 +- 10 files changed, 207 insertions(+), 326 deletions(-) (limited to 'drivers/dma') diff --git a/arch/arm/mach-ux500/board-mop500-audio.c b/arch/arm/mach-ux500/board-mop500-audio.c index aba9e5692958..5a968fa8b90c 100644 --- a/arch/arm/mach-ux500/board-mop500-audio.c +++ b/arch/arm/mach-ux500/board-mop500-audio.c @@ -23,8 +23,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, @@ -36,8 +35,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, @@ -55,8 +53,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, @@ -68,8 +65,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, @@ -87,8 +83,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, @@ -101,8 +96,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 0ef38775a0c1..4e30b6dc9ac5 100644 --- a/arch/arm/mach-ux500/board-mop500-sdi.c +++ b/arch/arm/mach-ux500/board-mop500-sdi.c @@ -35,8 +35,7 @@ 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, }; @@ -44,8 +43,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, }; @@ -88,8 +86,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, }; @@ -97,8 +94,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, }; @@ -125,8 +121,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, }; @@ -134,8 +129,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, }; @@ -163,8 +157,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, }; @@ -172,8 +165,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 3cd555ac6d0a..871e61517fb2 100644 --- a/arch/arm/mach-ux500/board-mop500.c +++ b/arch/arm/mach-ux500/board-mop500.c @@ -425,8 +425,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, @@ -435,8 +434,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, @@ -447,8 +445,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, @@ -471,8 +468,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, }; @@ -480,8 +476,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, }; @@ -512,8 +507,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, }; @@ -521,8 +515,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, }; @@ -530,8 +523,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, }; @@ -539,8 +531,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, }; @@ -548,8 +539,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, }; @@ -557,8 +547,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 e90b5ab23b6d..67d68e05f3a7 100644 --- a/arch/arm/mach-ux500/cpu-db8500.c +++ b/arch/arm/mach-ux500/cpu-db8500.c @@ -163,25 +163,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 a30977b374ba..7989c564e47a 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 a616419bea76..0296ae5b0fd9 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 2dfc72f7cd8a..45af3031dfef 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 d481cb8521d9..63495f6a36f9 100644 --- a/drivers/dma/ste_dma40.c +++ b/drivers/dma/ste_dma40.c @@ -1302,21 +1302,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) @@ -1758,8 +1754,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) { @@ -1767,44 +1761,26 @@ 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 ((is_log && conf->dev_type > d40c->base->num_log_chans) || + (!is_log && conf->dev_type > d40c->base->num_phy_chans) || + (conf->dev_type < 0)) { + chan_err(d40c, "Invalid device type (%d)\n", conf->dev_type); res = -EINVAL; } if (conf->dir == STEDMA40_MEM_TO_PERIPH && - conf->dst_dev_type == 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 && - conf->src_dev_type == STEDMA40_DEV_SRC_MEMORY) { - chan_err(d40c, "Invalid src\n"); - res = -EINVAL; - } - - if (conf->src_dev_type == STEDMA40_DEV_SRC_MEMORY && - conf->dst_dev_type == 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; } @@ -1925,7 +1901,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; @@ -1940,13 +1916,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 @@ -2058,8 +2032,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)) { @@ -2076,7 +2049,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; @@ -2095,13 +2068,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; } @@ -2142,7 +2113,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); @@ -2163,10 +2134,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"); @@ -2308,9 +2277,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; } @@ -2441,11 +2410,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 */ @@ -2489,10 +2458,10 @@ static int d40_alloc_chan_resources(struct dma_chan *chan) 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; + d40c->dma_cfg.dev_type * D40_LCPA_CHAN_SIZE; else d40c->lcpa = d40c->base->lcpa_base + - d40c->dma_cfg.dst_dev_type * + d40c->dma_cfg.dev_type * D40_LCPA_CHAN_SIZE + D40_LCPA_CHAN_DST_DELTA; } @@ -2755,7 +2724,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) @@ -2778,7 +2747,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) diff --git a/drivers/dma/ste_dma40_ll.c b/drivers/dma/ste_dma40_ll.c index 7180e0d41722..5eb6c10beae1 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 869c571c8c08..9e42a67d0cd5 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; -- cgit v1.2.3 From 84b3da1498943840005d7d5652caf4fe6fd333e6 Mon Sep 17 00:00:00 2001 From: Lee Jones <lee.jones@linaro.org> Date: Fri, 3 May 2013 15:31:58 +0100 Subject: dmaengine: ste_dma40: Remove home-brew MAX() macro The current implementation of the DMA40's local MAX() macro evaluates its arguments more times than is necessary and it not type checked. This patch strips replaces it with a new, more efficient constant. Cc: Dan Williams <djbw@fb.com> Cc: Per Forlin <per.forlin@stericsson.com> Cc: Rabin Vincent <rabin@rab.in> Acked-by: Vinod Koul <vinod.koul@intel.com> Reported-by: Harvey Harrison <harvey.harrison@gmail.com> Signed-off-by: Lee Jones <lee.jones@linaro.org> Signed-off-by: Linus Walleij <linus.walleij@linaro.org> --- drivers/dma/ste_dma40.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'drivers/dma') diff --git a/drivers/dma/ste_dma40.c b/drivers/dma/ste_dma40.c index 63495f6a36f9..367ef15a3cd8 100644 --- a/drivers/dma/ste_dma40.c +++ b/drivers/dma/ste_dma40.c @@ -53,8 +53,6 @@ #define D40_ALLOC_PHY (1 << 30) #define D40_ALLOC_LOG_FREE 0 -#define MAX(a, b) (((a) < (b)) ? (b) : (a)) - /* Reserved event lines for memcpy only. */ #define DB8500_DMA_MEMCPY_EV_0 51 #define DB8500_DMA_MEMCPY_EV_1 56 @@ -216,6 +214,9 @@ static u32 d40_backup_regs_chan[] = { D40_CHAN_REG_SDLNK, }; +#define BACKUP_REGS_SZ_MAX ((BACKUP_REGS_SZ_V4A > BACKUP_REGS_SZ_V4B) ? \ + BACKUP_REGS_SZ_V4A : BACKUP_REGS_SZ_V4B) + /** * struct d40_interrupt_lookup - lookup table for interrupt handler * @@ -579,7 +580,7 @@ struct d40_base { resource_size_t lcpa_size; struct kmem_cache *desc_slab; u32 reg_val_backup[BACKUP_REGS_SZ]; - u32 reg_val_backup_v4[MAX(BACKUP_REGS_SZ_V4A, BACKUP_REGS_SZ_V4B)]; + u32 reg_val_backup_v4[BACKUP_REGS_SZ_MAX]; u32 *reg_val_backup_chan; u16 gcc_pwr_off_mask; bool initialized; -- cgit v1.2.3 From db72da92103e3023e6a4fdfe65183b21bfe5d883 Mon Sep 17 00:00:00 2001 From: Lee Jones <lee.jones@linaro.org> Date: Fri, 3 May 2013 15:32:03 +0100 Subject: dmaengine: ste_dma40: Calculate number of logical channels from physical ones This change will cost ~25KB of memory, but it's worth the trade-off, as it removes a great deal of overhead. It means that instead of only allocating memory for the logical channels in use, it does so for all available ones, which is 32 per physical channel. However, this now means we can remove some platform data and we don't have to worry about adding vendor specific variables to Device Tree. Acked-by: Vinod Koul <vnod.koul@intel.com> Signed-off-by: Lee Jones <lee.jones@linaro.org> Signed-off-by: Linus Walleij <linus.walleij@linaro.org> --- arch/arm/mach-ux500/devices-db8500.c | 1 - drivers/dma/ste_dma40.c | 16 ++++++---------- include/linux/platform_data/dma-ste-dma40.h | 2 -- 3 files changed, 6 insertions(+), 13 deletions(-) (limited to 'drivers/dma') diff --git a/arch/arm/mach-ux500/devices-db8500.c b/arch/arm/mach-ux500/devices-db8500.c index 7989c564e47a..130f3d9917e7 100644 --- a/arch/arm/mach-ux500/devices-db8500.c +++ b/arch/arm/mach-ux500/devices-db8500.c @@ -121,7 +121,6 @@ static const dma_addr_t dma40_rx_map[DB8500_DMA_NR_DEV] = { }; static struct stedma40_platform_data dma40_plat_data = { - .dev_len = DB8500_DMA_NR_DEV, .dev_rx = dma40_rx_map, .dev_tx = dma40_tx_map, .disabled_channels = {-1}, diff --git a/drivers/dma/ste_dma40.c b/drivers/dma/ste_dma40.c index 367ef15a3cd8..f25c9ccf28e8 100644 --- a/drivers/dma/ste_dma40.c +++ b/drivers/dma/ste_dma40.c @@ -45,6 +45,9 @@ #define D40_LCLA_LINK_PER_EVENT_GRP 128 #define D40_LCLA_END D40_LCLA_LINK_PER_EVENT_GRP +/* Max number of logical channels per physical channel */ +#define D40_MAX_LOG_CHAN_PER_PHY 32 + /* Attempts before giving up to trying to get pages that are aligned */ #define MAX_LCLA_ALLOC_ATTEMPTS 256 @@ -3210,6 +3213,8 @@ static struct d40_base * __init d40_hw_detect_init(struct platform_device *pdev) else num_phy_chans = 4 * (readl(virtbase + D40_DREG_ICFG) & 0x7) + 4; + num_log_chans = num_phy_chans * D40_MAX_LOG_CHAN_PER_PHY; + dev_info(&pdev->dev, "hardware revision: %d @ 0x%x with %d physical channels\n", rev, res->start, num_phy_chans); @@ -3219,15 +3224,6 @@ static struct d40_base * __init d40_hw_detect_init(struct platform_device *pdev) goto failure; } - /* Count the number of logical channels in use */ - for (i = 0; i < plat_data->dev_len; i++) - if (plat_data->dev_rx[i] != 0) - num_log_chans++; - - for (i = 0; i < plat_data->dev_len; i++) - if (plat_data->dev_tx[i] != 0) - num_log_chans++; - base = kzalloc(ALIGN(sizeof(struct d40_base), 4) + (num_phy_chans + num_log_chans + ARRAY_SIZE(dma40_memcpy_channels)) * sizeof(struct d40_chan), GFP_KERNEL); @@ -3295,7 +3291,7 @@ static struct d40_base * __init d40_hw_detect_init(struct platform_device *pdev) * The max number of logical channels are event lines for all * src devices and dst devices */ - base->lookup_log_chans = kzalloc(plat_data->dev_len * 2 * + base->lookup_log_chans = kzalloc(num_log_chans * sizeof(struct d40_chan *), GFP_KERNEL); if (!base->lookup_log_chans) diff --git a/include/linux/platform_data/dma-ste-dma40.h b/include/linux/platform_data/dma-ste-dma40.h index 9e42a67d0cd5..c54af61c9e48 100644 --- a/include/linux/platform_data/dma-ste-dma40.h +++ b/include/linux/platform_data/dma-ste-dma40.h @@ -136,7 +136,6 @@ struct stedma40_chan_cfg { /** * struct stedma40_platform_data - Configuration struct for the dma device. * - * @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 * @disabled_channels: A vector, ending with -1, that marks physical channels @@ -153,7 +152,6 @@ struct stedma40_chan_cfg { * for 'multiple of 4' channels, like 8. */ struct stedma40_platform_data { - u32 dev_len; const dma_addr_t *dev_tx; const dma_addr_t *dev_rx; int disabled_channels[STEDMA40_MAX_PHYS]; -- cgit v1.2.3 From 8a59fed39577d7313921a59dba8cc1711ae90da5 Mon Sep 17 00:00:00 2001 From: Lee Jones <lee.jones@linaro.org> Date: Fri, 3 May 2013 15:32:04 +0100 Subject: dmaengine: ste_dma40: Remove 'always true' checking Before allocating memory for logical channels, the current driver checks to see if there are any. Well as the dma40_memcpy_channels[] array is always populated, the check is always true. Best to remove the check. Cc: Dan Williams <djbw@fb.com> Cc: Per Forlin <per.forlin@stericsson.com> Cc: Rabin Vincent <rabin@rab.in> Acked-by: Vinod Koul <vinod.koul@intel.com> Acked-by: Arnd Bergmann <arnd@arndb.de> Signed-off-by: Lee Jones <lee.jones@linaro.org> Signed-off-by: Linus Walleij <linus.walleij@linaro.org> --- drivers/dma/ste_dma40.c | 16 +++++----------- 1 file changed, 5 insertions(+), 11 deletions(-) (limited to 'drivers/dma') diff --git a/drivers/dma/ste_dma40.c b/drivers/dma/ste_dma40.c index f25c9ccf28e8..7ccb8e2d59be 100644 --- a/drivers/dma/ste_dma40.c +++ b/drivers/dma/ste_dma40.c @@ -3286,17 +3286,11 @@ static struct d40_base * __init d40_hw_detect_init(struct platform_device *pdev) if (!base->lookup_phy_chans) goto failure; - 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 - */ - base->lookup_log_chans = kzalloc(num_log_chans * - sizeof(struct d40_chan *), - GFP_KERNEL); - if (!base->lookup_log_chans) - goto failure; - } + base->lookup_log_chans = kzalloc(num_log_chans * + sizeof(struct d40_chan *), + GFP_KERNEL); + if (!base->lookup_log_chans) + goto failure; base->reg_val_backup_chan = kmalloc(base->num_phy_chans * sizeof(d40_backup_regs_chan), -- cgit v1.2.3 From 8b2fe9b6b310a6e5d68de648d6f0697227581d66 Mon Sep 17 00:00:00 2001 From: Lee Jones <lee.jones@linaro.org> Date: Fri, 3 May 2013 15:32:08 +0100 Subject: dmaengine: ste_dma40: Move rev error-check up to revision acquisition At the moment we fetch the hardware revision, then do some stuff, then check whether the revision is correct and return in error if it's not. Well we may as well check it as soon as we know what it is, so let's move the check right up underneath where we acquire the version. Acked-by: Vinod Koul <vnod.koul@intel.com> Signed-off-by: Lee Jones <lee.jones@linaro.org> Signed-off-by: Linus Walleij <linus.walleij@linaro.org> --- drivers/dma/ste_dma40.c | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) (limited to 'drivers/dma') diff --git a/drivers/dma/ste_dma40.c b/drivers/dma/ste_dma40.c index 7ccb8e2d59be..fb79db3313d3 100644 --- a/drivers/dma/ste_dma40.c +++ b/drivers/dma/ste_dma40.c @@ -3204,6 +3204,10 @@ static struct d40_base * __init d40_hw_detect_init(struct platform_device *pdev) * DB8540v1 has revision 4 */ rev = AMBA_REV_BITS(pid); + if (rev < 2) { + d40_err(&pdev->dev, "hardware revision: %d is not supported", rev); + goto failure; + } plat_data = pdev->dev.platform_data; @@ -3218,12 +3222,6 @@ static struct d40_base * __init d40_hw_detect_init(struct platform_device *pdev) dev_info(&pdev->dev, "hardware revision: %d @ 0x%x with %d physical channels\n", rev, res->start, num_phy_chans); - if (rev < 2) { - d40_err(&pdev->dev, "hardware revision: %d is not supported", - rev); - goto failure; - } - base = kzalloc(ALIGN(sizeof(struct d40_base), 4) + (num_phy_chans + num_log_chans + ARRAY_SIZE(dma40_memcpy_channels)) * sizeof(struct d40_chan), GFP_KERNEL); -- cgit v1.2.3 From b2abb249de5ffca71ade8b79c9969e046fc03722 Mon Sep 17 00:00:00 2001 From: Lee Jones <lee.jones@linaro.org> Date: Fri, 3 May 2013 15:32:09 +0100 Subject: dmaengine: ste_dma40: Also report the number of logical channels Now we know the total of physical and logical channels, we may as well report them within the information log. Before: dma40 dma40.0: hardware revision: 3 @ 0x801c0000 with 8 physical channels After: <as above ...> and 256 logical channels Cc: Dan Williams <djbw@fb.com> Cc: Per Forlin <per.forlin@stericsson.com> Cc: Rabin Vincent <rabin@rab.in> Acked-by: Vinod Koul <vinod.koul@intel.com> Signed-off-by: Lee Jones <lee.jones@linaro.org> Signed-off-by: Linus Walleij <linus.walleij@linaro.org> --- drivers/dma/ste_dma40.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'drivers/dma') diff --git a/drivers/dma/ste_dma40.c b/drivers/dma/ste_dma40.c index fb79db3313d3..665541df5798 100644 --- a/drivers/dma/ste_dma40.c +++ b/drivers/dma/ste_dma40.c @@ -3219,8 +3219,9 @@ static struct d40_base * __init d40_hw_detect_init(struct platform_device *pdev) num_log_chans = num_phy_chans * D40_MAX_LOG_CHAN_PER_PHY; - dev_info(&pdev->dev, "hardware revision: %d @ 0x%x with %d physical channels\n", - rev, res->start, num_phy_chans); + dev_info(&pdev->dev, + "hardware rev: %d @ 0x%x with %d physical and %d logical channels\n", + rev, res->start, num_phy_chans, num_log_chans); base = kzalloc(ALIGN(sizeof(struct d40_base), 4) + (num_phy_chans + num_log_chans + ARRAY_SIZE(dma40_memcpy_channels)) * -- cgit v1.2.3 From bb75d93b903afcd0904c83850835857fd9f8ef2d Mon Sep 17 00:00:00 2001 From: Lee Jones <lee.jones@linaro.org> Date: Fri, 3 May 2013 15:32:10 +0100 Subject: dmaengine: ste_dma40: Allocate plat_data on declaration It's the way that most other drivers do it. Very trivial clean-up which reduces line count and simplifies code. Acked-by: Vinod Koul <vnod.koul@intel.com> Signed-off-by: Lee Jones <lee.jones@linaro.org> Signed-off-by: Linus Walleij <linus.walleij@linaro.org> --- drivers/dma/ste_dma40.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) (limited to 'drivers/dma') diff --git a/drivers/dma/ste_dma40.c b/drivers/dma/ste_dma40.c index 665541df5798..925cdbe08c2e 100644 --- a/drivers/dma/ste_dma40.c +++ b/drivers/dma/ste_dma40.c @@ -3138,7 +3138,7 @@ static int __init d40_phy_res_init(struct d40_base *base) static struct d40_base * __init d40_hw_detect_init(struct platform_device *pdev) { - struct stedma40_platform_data *plat_data; + struct stedma40_platform_data *plat_data = pdev->dev.platform_data; struct clk *clk = NULL; void __iomem *virtbase = NULL; struct resource *res = NULL; @@ -3209,8 +3209,6 @@ static struct d40_base * __init d40_hw_detect_init(struct platform_device *pdev) goto failure; } - plat_data = pdev->dev.platform_data; - /* The number of physical channels on this HW */ if (plat_data->num_of_phy_chans) num_phy_chans = plat_data->num_of_phy_chans; -- cgit v1.2.3 From 1814a1703ce2d6d4b88b5f62a52b137afebad990 Mon Sep 17 00:00:00 2001 From: Lee Jones <lee.jones@linaro.org> Date: Fri, 3 May 2013 15:32:11 +0100 Subject: dmaengine: ste_dma40: Allow driver to be probe()able when DT is enabled When booting using Device Tree, devices aren't registered in the normal way. Instead, they need to be provided with a compatible string which is held in an OF Match Table for comparison during start-up. Here we provide the compatible string and prepare the driver to not receive a platform data pointer. Acked-by: Vinod Koul <vnod.koul@intel.com> Acked-by: Arnd Bergmann <arnd@arndb.de> Signed-off-by: Lee Jones <lee.jones@linaro.org> [Fixed up whitespace error] Signed-off-by: Linus Walleij <linus.walleij@linaro.org> --- drivers/dma/ste_dma40.c | 46 ++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 44 insertions(+), 2 deletions(-) (limited to 'drivers/dma') diff --git a/drivers/dma/ste_dma40.c b/drivers/dma/ste_dma40.c index 925cdbe08c2e..495e8869b9b0 100644 --- a/drivers/dma/ste_dma40.c +++ b/drivers/dma/ste_dma40.c @@ -17,6 +17,7 @@ #include <linux/pm.h> #include <linux/pm_runtime.h> #include <linux/err.h> +#include <linux/of.h> #include <linux/amba/bus.h> #include <linux/regulator/consumer.h> #include <linux/platform_data/dma-ste-dma40.h> @@ -3471,17 +3472,52 @@ failure: return ret; } +static int __init d40_of_probe(struct platform_device *pdev, + struct device_node *np) +{ + struct stedma40_platform_data *pdata; + + /* + * FIXME: Fill in this routine as more support is added. + * First platform enabled (u8500) doens't need any extra + * properties to run, so this is fairly sparce currently. + */ + + pdata = devm_kzalloc(&pdev->dev, + sizeof(struct stedma40_platform_data), + GFP_KERNEL); + if (!pdata) + return -ENOMEM; + + pdev->dev.platform_data = pdata; + + return 0; +} + static int __init d40_probe(struct platform_device *pdev) { + struct stedma40_platform_data *plat_data = pdev->dev.platform_data; + struct device_node *np = pdev->dev.of_node; int err; int ret = -ENOENT; - struct d40_base *base; + struct d40_base *base = NULL; struct resource *res = NULL; int num_reserved_chans; u32 val; - base = d40_hw_detect_init(pdev); + if (!plat_data) { + if (np) { + if(d40_of_probe(pdev, np)) { + ret = -ENOMEM; + goto failure; + } + } else { + d40_err(&pdev->dev, "No pdata or Device Tree provided\n"); + goto failure; + } + } + base = d40_hw_detect_init(pdev); if (!base) goto failure; @@ -3655,11 +3691,17 @@ failure: return ret; } +static const struct of_device_id d40_match[] = { + { .compatible = "stericsson,dma40", }, + {} +}; + static struct platform_driver d40_driver = { .driver = { .owner = THIS_MODULE, .name = D40_NAME, .pm = DMA40_PM_OPS, + .of_match_table = d40_match, }, }; -- cgit v1.2.3 From fa332de5c6b3891485798adfe3252125457e5377 Mon Sep 17 00:00:00 2001 From: Lee Jones <lee.jones@linaro.org> Date: Fri, 3 May 2013 15:32:12 +0100 Subject: dmaengine: ste_dma40: Supply full Device Tree parsing support Using the new DMA DT bindings and API, we can register the DMA40 driver as Device Tree capable. Now, when a client attempts to allocate a channel using the DMA DT bindings via its own node, we are able to parse the request and allocate a channel in the correct manner. Cc: Dan Williams <djbw@fb.com> Cc: Per Forlin <per.forlin@stericsson.com> Cc: Rabin Vincent <rabin@rab.in> Cc: Rob Herring <rob.herring@calxeda.com> Cc: devicetree-discuss@lists.ozlabs.org Acked-by: Vinod Koul <vinod.koul@intel.com> Reviewed-by: Arnd Bergmann <arnd@arndb.de> Signed-off-by: Lee Jones <lee.jones@linaro.org> Signed-off-by: Linus Walleij <linus.walleij@linaro.org> --- .../devicetree/bindings/dma/ste-dma40.txt | 62 ++++++++++++++++++++++ drivers/dma/ste_dma40.c | 52 ++++++++++++++++++ 2 files changed, 114 insertions(+) create mode 100644 Documentation/devicetree/bindings/dma/ste-dma40.txt (limited to 'drivers/dma') diff --git a/Documentation/devicetree/bindings/dma/ste-dma40.txt b/Documentation/devicetree/bindings/dma/ste-dma40.txt new file mode 100644 index 000000000000..2679a873522d --- /dev/null +++ b/Documentation/devicetree/bindings/dma/ste-dma40.txt @@ -0,0 +1,62 @@ +* DMA40 DMA Controller + +Required properties: +- compatible: "stericsson,dma40" +- reg: Address range of the DMAC registers +- reg-names: Names of the above areas to use during resource look-up +- interrupt: Should contain the DMAC interrupt number +- #dma-cells: must be <3> + +Optional properties: +- dma-channels: Number of channels supported by hardware - if not present + the driver will attempt to obtain the information from H/W + +Example: + + dma: dma-controller@801C0000 { + compatible = "stericsson,db8500-dma40", "stericsson,dma40"; + reg = <0x801C0000 0x1000 0x40010000 0x800>; + reg-names = "base", "lcpa"; + interrupt-parent = <&intc>; + interrupts = <0 25 0x4>; + + #dma-cells = <2>; + dma-channels = <8>; + }; + +Clients +Required properties: +- dmas: Comma separated list of dma channel requests +- dma-names: Names of the aforementioned requested channels + +Each dmas request consists of 4 cells: + 1. A phandle pointing to the DMA controller + 2. Device Type + 3. The DMA request line number (only when 'use fixed channel' is set) + 4. A 32bit mask specifying; mode, direction and endianess [NB: This list will grow] + 0x00000001: Mode: + Logical channel when unset + Physical channel when set + 0x00000002: Direction: + Memory to Device when unset + Device to Memory when set + 0x00000004: Endianess: + Little endian when unset + Big endian when set + 0x00000008: Use fixed channel: + Use automatic channel selection when unset + Use DMA request line number when set + +Example: + + uart@80120000 { + compatible = "arm,pl011", "arm,primecell"; + reg = <0x80120000 0x1000>; + interrupts = <0 11 0x4>; + + dmas = <&dma 13 0 0x2>, /* Logical - DevToMem */ + <&dma 13 0 0x0>; /* Logical - MemToDev */ + dma-names = "rx", "rx"; + + status = "disabled"; + }; diff --git a/drivers/dma/ste_dma40.c b/drivers/dma/ste_dma40.c index 495e8869b9b0..5e9f6d670891 100644 --- a/drivers/dma/ste_dma40.c +++ b/drivers/dma/ste_dma40.c @@ -18,6 +18,7 @@ #include <linux/pm_runtime.h> #include <linux/err.h> #include <linux/of.h> +#include <linux/of_dma.h> #include <linux/amba/bus.h> #include <linux/regulator/consumer.h> #include <linux/platform_data/dma-ste-dma40.h> @@ -2422,6 +2423,50 @@ static void d40_set_prio_realtime(struct d40_chan *d40c) __d40_set_prio_rt(d40c, d40c->dma_cfg.dev_type, false); } +#define D40_DT_FLAGS_MODE(flags) ((flags >> 0) & 0x1) +#define D40_DT_FLAGS_DIR(flags) ((flags >> 1) & 0x1) +#define D40_DT_FLAGS_BIG_ENDIAN(flags) ((flags >> 2) & 0x1) +#define D40_DT_FLAGS_FIXED_CHAN(flags) ((flags >> 3) & 0x1) + +static struct dma_chan *d40_xlate(struct of_phandle_args *dma_spec, + struct of_dma *ofdma) +{ + struct stedma40_chan_cfg cfg; + dma_cap_mask_t cap; + u32 flags; + + memset(&cfg, 0, sizeof(struct stedma40_chan_cfg)); + + dma_cap_zero(cap); + dma_cap_set(DMA_SLAVE, cap); + + cfg.dev_type = dma_spec->args[0]; + flags = dma_spec->args[2]; + + switch (D40_DT_FLAGS_MODE(flags)) { + case 0: cfg.mode = STEDMA40_MODE_LOGICAL; break; + case 1: cfg.mode = STEDMA40_MODE_PHYSICAL; break; + } + + switch (D40_DT_FLAGS_DIR(flags)) { + case 0: + cfg.dir = STEDMA40_MEM_TO_PERIPH; + cfg.dst_info.big_endian = D40_DT_FLAGS_BIG_ENDIAN(flags); + break; + case 1: + cfg.dir = STEDMA40_PERIPH_TO_MEM; + cfg.src_info.big_endian = D40_DT_FLAGS_BIG_ENDIAN(flags); + break; + } + + if (D40_DT_FLAGS_FIXED_CHAN(flags)) { + cfg.phy_channel = dma_spec->args[1]; + cfg.use_fixed_channel = true; + } + + return dma_request_channel(cap, stedma40_filter, &cfg); +} + /* DMA ENGINE functions */ static int d40_alloc_chan_resources(struct dma_chan *chan) { @@ -3638,6 +3683,13 @@ static int __init d40_probe(struct platform_device *pdev) d40_hw_init(base); + if (np) { + err = of_dma_controller_register(np, d40_xlate, NULL); + if (err && err != -ENODEV) + dev_err(&pdev->dev, + "could not register of_dma_controller\n"); + } + dev_info(base->dev, "initialized\n"); return 0; -- cgit v1.2.3 From 9778256b9810d2c758a7537a43825b7d81b5765f Mon Sep 17 00:00:00 2001 From: Lee Jones <lee.jones@linaro.org> Date: Wed, 15 May 2013 10:51:24 +0100 Subject: dmaengine: ste_dma40: Separate Logical Global Interrupt Mask (GIM) unmasking During the initial setup of a logical channel, it is necessary to unmask the GIM in order to receive generated terminal count and error interrupts. We're separating out this required code so it will be possible to move the remaining code in d40_phy_cfg(), which is mostly runtime configuration into the runtime_config() routine. Cc: Dan Williams <djbw@fb.com> Cc: Per Forlin <per.forlin@stericsson.com> Cc: Rabin Vincent <rabin@rab.in> Acked-by: Vinod Koul <vinod.koul@intel.com> Acked-by: Arnd Bergmann <arnd@arndb.de> Signed-off-by: Lee Jones <lee.jones@linaro.org> Signed-off-by: Linus Walleij <linus.walleij@linaro.org> --- drivers/dma/ste_dma40.c | 4 ++++ drivers/dma/ste_dma40_ll.c | 5 ----- 2 files changed, 4 insertions(+), 5 deletions(-) (limited to 'drivers/dma') diff --git a/drivers/dma/ste_dma40.c b/drivers/dma/ste_dma40.c index 5e9f6d670891..759293e4a1cc 100644 --- a/drivers/dma/ste_dma40.c +++ b/drivers/dma/ste_dma40.c @@ -2513,6 +2513,10 @@ static int d40_alloc_chan_resources(struct dma_chan *chan) d40c->lcpa = d40c->base->lcpa_base + d40c->dma_cfg.dev_type * D40_LCPA_CHAN_SIZE + D40_LCPA_CHAN_DST_DELTA; + + /* Unmask the Global Interrupt Mask. */ + d40c->src_def_cfg |= BIT(D40_SREG_CFG_LOG_GIM_POS); + d40c->dst_def_cfg |= BIT(D40_SREG_CFG_LOG_GIM_POS); } dev_dbg(chan2dev(d40c), "allocated %s channel (phy %d%s)\n", diff --git a/drivers/dma/ste_dma40_ll.c b/drivers/dma/ste_dma40_ll.c index 5eb6c10beae1..435a223c891f 100644 --- a/drivers/dma/ste_dma40_ll.c +++ b/drivers/dma/ste_dma40_ll.c @@ -107,11 +107,6 @@ void d40_phy_cfg(struct stedma40_chan_cfg *cfg, src |= 1 << D40_SREG_CFG_PRI_POS; dst |= 1 << D40_SREG_CFG_PRI_POS; } - - } else { - /* Logical channel */ - dst |= 1 << D40_SREG_CFG_LOG_GIM_POS; - src |= 1 << D40_SREG_CFG_LOG_GIM_POS; } if (cfg->src_info.big_endian) -- cgit v1.2.3 From 57e65ad77fef1b026f5bdf1cd417bb6346b24fdf Mon Sep 17 00:00:00 2001 From: Lee Jones <lee.jones@linaro.org> Date: Wed, 15 May 2013 10:51:25 +0100 Subject: dmaengine: ste_dma40: Remove unnecessary call to d40_phy_cfg() The majority of configuration done in d40_phy_config() pertains to physical channels. Move the call over to runtime config which has different code paths for physical and logical channels already, and make it an exclusive physical channel config function as the name implies, and drop the is_log argument. Since we moved the call to runtime_config() it only gets called for device transfers, so encode the small snippet of configuration pertaining to memcpy channels into the d40_config_memcpy() function. Acked-by: Vinod Koul <vinod.koul@intel.com> Acked-by: Arnd Bergmann <arnd@arndb.de> Signed-off-by: Lee Jones <lee.jones@linaro.org> [rewrote the commit message] Signed-off-by: Linus Walleij <linus.walleij@linaro.org> --- drivers/dma/ste_dma40.c | 14 ++++--- drivers/dma/ste_dma40_ll.c | 101 +++++++++++++++++++++------------------------ drivers/dma/ste_dma40_ll.h | 3 +- 3 files changed, 58 insertions(+), 60 deletions(-) (limited to 'drivers/dma') diff --git a/drivers/dma/ste_dma40.c b/drivers/dma/ste_dma40.c index 759293e4a1cc..b7fe46bd6a8e 100644 --- a/drivers/dma/ste_dma40.c +++ b/drivers/dma/ste_dma40.c @@ -2043,6 +2043,14 @@ static int d40_config_memcpy(struct d40_chan *d40c) } else if (dma_has_cap(DMA_MEMCPY, cap) && dma_has_cap(DMA_SLAVE, cap)) { d40c->dma_cfg = dma40_memcpy_conf_phy; + + /* Generate interrrupt at end of transfer or relink. */ + d40c->dst_def_cfg |= BIT(D40_SREG_CFG_TIM_POS); + + /* Generate interrupt on error. */ + d40c->src_def_cfg |= BIT(D40_SREG_CFG_EIM_POS); + d40c->dst_def_cfg |= BIT(D40_SREG_CFG_EIM_POS); + } else { chan_err(d40c, "No memcpy\n"); return -EINVAL; @@ -2496,9 +2504,6 @@ 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); @@ -2862,8 +2867,7 @@ static int d40_set_runtime_config(struct dma_chan *chan, 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); /* These settings will take precedence later */ d40c->runtime_addr = config_addr; diff --git a/drivers/dma/ste_dma40_ll.c b/drivers/dma/ste_dma40_ll.c index 435a223c891f..ab5a2a706f7a 100644 --- a/drivers/dma/ste_dma40_ll.c +++ b/drivers/dma/ste_dma40_ll.c @@ -50,63 +50,58 @@ void d40_log_cfg(struct stedma40_chan_cfg *cfg, } -/* Sets up SRC and DST CFG register for both logical and physical channels */ -void d40_phy_cfg(struct stedma40_chan_cfg *cfg, - u32 *src_cfg, u32 *dst_cfg, bool is_log) +void d40_phy_cfg(struct stedma40_chan_cfg *cfg, u32 *src_cfg, u32 *dst_cfg) { u32 src = 0; u32 dst = 0; - if (!is_log) { - /* Physical channel */ - if ((cfg->dir == STEDMA40_PERIPH_TO_MEM) || - (cfg->dir == STEDMA40_PERIPH_TO_PERIPH)) { - /* Set master port to 1 */ - src |= 1 << D40_SREG_CFG_MST_POS; - 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; - else - src |= 3 << D40_SREG_CFG_PHY_TM_POS; - } - if ((cfg->dir == STEDMA40_MEM_TO_PERIPH) || - (cfg->dir == STEDMA40_PERIPH_TO_PERIPH)) { - /* Set master port to 1 */ - dst |= 1 << D40_SREG_CFG_MST_POS; - 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; - else - dst |= 3 << D40_SREG_CFG_PHY_TM_POS; - } - /* Interrupt on end of transfer for destination */ - dst |= 1 << D40_SREG_CFG_TIM_POS; - - /* Generate interrupt on error */ - src |= 1 << D40_SREG_CFG_EIM_POS; - dst |= 1 << D40_SREG_CFG_EIM_POS; - - /* PSIZE */ - if (cfg->src_info.psize != STEDMA40_PSIZE_PHY_1) { - src |= 1 << D40_SREG_CFG_PHY_PEN_POS; - src |= cfg->src_info.psize << D40_SREG_CFG_PSIZE_POS; - } - if (cfg->dst_info.psize != STEDMA40_PSIZE_PHY_1) { - dst |= 1 << D40_SREG_CFG_PHY_PEN_POS; - dst |= cfg->dst_info.psize << D40_SREG_CFG_PSIZE_POS; - } - - /* Element size */ - src |= cfg->src_info.data_width << D40_SREG_CFG_ESIZE_POS; - dst |= cfg->dst_info.data_width << D40_SREG_CFG_ESIZE_POS; - - /* Set the priority bit to high for the physical channel */ - if (cfg->high_priority) { - src |= 1 << D40_SREG_CFG_PRI_POS; - dst |= 1 << D40_SREG_CFG_PRI_POS; - } + if ((cfg->dir == STEDMA40_PERIPH_TO_MEM) || + (cfg->dir == STEDMA40_PERIPH_TO_PERIPH)) { + /* Set master port to 1 */ + src |= 1 << D40_SREG_CFG_MST_POS; + 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; + else + src |= 3 << D40_SREG_CFG_PHY_TM_POS; + } + if ((cfg->dir == STEDMA40_MEM_TO_PERIPH) || + (cfg->dir == STEDMA40_PERIPH_TO_PERIPH)) { + /* Set master port to 1 */ + dst |= 1 << D40_SREG_CFG_MST_POS; + 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; + else + dst |= 3 << D40_SREG_CFG_PHY_TM_POS; + } + /* Interrupt on end of transfer for destination */ + dst |= 1 << D40_SREG_CFG_TIM_POS; + + /* Generate interrupt on error */ + src |= 1 << D40_SREG_CFG_EIM_POS; + dst |= 1 << D40_SREG_CFG_EIM_POS; + + /* PSIZE */ + if (cfg->src_info.psize != STEDMA40_PSIZE_PHY_1) { + src |= 1 << D40_SREG_CFG_PHY_PEN_POS; + src |= cfg->src_info.psize << D40_SREG_CFG_PSIZE_POS; + } + if (cfg->dst_info.psize != STEDMA40_PSIZE_PHY_1) { + dst |= 1 << D40_SREG_CFG_PHY_PEN_POS; + dst |= cfg->dst_info.psize << D40_SREG_CFG_PSIZE_POS; + } + + /* Element size */ + src |= cfg->src_info.data_width << D40_SREG_CFG_ESIZE_POS; + dst |= cfg->dst_info.data_width << D40_SREG_CFG_ESIZE_POS; + + /* Set the priority bit to high for the physical channel */ + if (cfg->high_priority) { + src |= 1 << D40_SREG_CFG_PRI_POS; + dst |= 1 << D40_SREG_CFG_PRI_POS; } if (cfg->src_info.big_endian) diff --git a/drivers/dma/ste_dma40_ll.h b/drivers/dma/ste_dma40_ll.h index fdde8ef77542..1b47312bc574 100644 --- a/drivers/dma/ste_dma40_ll.h +++ b/drivers/dma/ste_dma40_ll.h @@ -432,8 +432,7 @@ enum d40_lli_flags { void d40_phy_cfg(struct stedma40_chan_cfg *cfg, u32 *src_cfg, - u32 *dst_cfg, - bool is_log); + u32 *dst_cfg); void d40_log_cfg(struct stedma40_chan_cfg *cfg, u32 *lcsp1, -- cgit v1.2.3 From 9b233f9b2e927a93b3dc8b8e9c1d59f79be13dcc Mon Sep 17 00:00:00 2001 From: Lee Jones <lee.jones@linaro.org> Date: Wed, 15 May 2013 10:51:26 +0100 Subject: dmaengine: ste_dma40: Don't configure runtime configurable setup during allocate Using the dmaengine API for slave transfers, allocating and configuring a channel are two separate actions. Here we're removing logical channel configuration from the channel allocation routine for slave transfers, as the same config is already done in the runtime config function, and put the corresponding call into d40_config_memcpy() for the memcpy code path. Cc: Dan Williams <djbw@fb.com> Cc: Per Forlin <per.forlin@stericsson.com> Cc: Rabin Vincent <rabin@rab.in> Acked-by: Vinod Koul <vinod.koul@intel.com> Signed-off-by: Lee Jones <lee.jones@linaro.org> [Edited the commit message] Signed-off-by: Linus Walleij <linus.walleij@linaro.org> --- drivers/dma/ste_dma40.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers/dma') diff --git a/drivers/dma/ste_dma40.c b/drivers/dma/ste_dma40.c index b7fe46bd6a8e..ba84df8fc9d8 100644 --- a/drivers/dma/ste_dma40.c +++ b/drivers/dma/ste_dma40.c @@ -2040,6 +2040,9 @@ static int d40_config_memcpy(struct d40_chan *d40c) d40c->dma_cfg = dma40_memcpy_conf_log; d40c->dma_cfg.dev_type = dma40_memcpy_channels[d40c->chan.chan_id]; + d40_log_cfg(&d40c->dma_cfg, + &d40c->log_def.lcsp1, &d40c->log_def.lcsp3); + } else if (dma_has_cap(DMA_MEMCPY, cap) && dma_has_cap(DMA_SLAVE, cap)) { d40c->dma_cfg = dma40_memcpy_conf_phy; @@ -2508,9 +2511,6 @@ static int d40_alloc_chan_resources(struct dma_chan *chan) 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.dev_type * D40_LCPA_CHAN_SIZE; -- cgit v1.2.3 From ef9c89b3ec6916dd0b7db1563d51d85af3e7f031 Mon Sep 17 00:00:00 2001 From: Lee Jones <lee.jones@linaro.org> Date: Wed, 15 May 2013 10:51:30 +0100 Subject: dmaengine: ste_dma40: Only use addresses passed as configuration information Addresses are passed in from the client's driver via the invocation of dmaengine_slave_config(), so there's no need to fetch them from platform data too, hardwired or otherwise. This is a great step forward, as it elevates a large burden from platform data in the way of a look-up table. Signed-off-by: Lee Jones <lee.jones@linaro.org> Acked-by: Vinod Koul <vinod.koul@intel.com> Signed-off-by: Linus Walleij <linus.walleij@linaro.org> --- drivers/dma/ste_dma40.c | 51 +++++++++++-------------------------------------- 1 file changed, 11 insertions(+), 40 deletions(-) (limited to 'drivers/dma') diff --git a/drivers/dma/ste_dma40.c b/drivers/dma/ste_dma40.c index ba84df8fc9d8..57a127e5c896 100644 --- a/drivers/dma/ste_dma40.c +++ b/drivers/dma/ste_dma40.c @@ -1774,22 +1774,6 @@ static int d40_validate_conf(struct d40_chan *d40c, res = -EINVAL; } - if (conf->dir == STEDMA40_MEM_TO_PERIPH && - 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 && - 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; - } - if (conf->dir == STEDMA40_PERIPH_TO_PERIPH) { /* * DMAC HW supports it. Will be added to this driver, @@ -2327,14 +2311,10 @@ d40_prep_sg(struct dma_chan *dchan, struct scatterlist *sg_src, if (sg_next(&sg_src[sg_len - 1]) == sg_src) desc->cyclic = true; - if (direction != DMA_TRANS_NONE) { - dma_addr_t dev_addr = d40_get_dev_addr(chan, direction); - - if (direction == DMA_DEV_TO_MEM) - src_dev_addr = dev_addr; - else if (direction == DMA_MEM_TO_DEV) - dst_dev_addr = dev_addr; - } + if (direction == DMA_DEV_TO_MEM) + src_dev_addr = chan->runtime_addr; + else if (direction == DMA_MEM_TO_DEV) + dst_dev_addr = chan->runtime_addr; if (chan_is_logical(chan)) ret = d40_prep_sg_log(chan, desc, sg_src, sg_dst, @@ -2782,15 +2762,8 @@ static int d40_set_runtime_config(struct dma_chan *chan, dst_maxburst = config->dst_maxburst; if (config->direction == DMA_DEV_TO_MEM) { - dma_addr_t dev_addr_rx = - d40c->base->plat_data->dev_rx[cfg->dev_type]; - config_addr = config->src_addr; - if (dev_addr_rx) - dev_dbg(d40c->base->dev, - "channel has a pre-wired RX address %08x " - "overriding with %08x\n", - dev_addr_rx, config_addr); + if (cfg->dir != STEDMA40_PERIPH_TO_MEM) dev_dbg(d40c->base->dev, "channel was not configured for peripheral " @@ -2805,15 +2778,8 @@ static int d40_set_runtime_config(struct dma_chan *chan, dst_maxburst = src_maxburst; } else if (config->direction == DMA_MEM_TO_DEV) { - dma_addr_t dev_addr_tx = - d40c->base->plat_data->dev_tx[cfg->dev_type]; - config_addr = config->dst_addr; - if (dev_addr_tx) - dev_dbg(d40c->base->dev, - "channel has a pre-wired TX address %08x " - "overriding with %08x\n", - dev_addr_tx, config_addr); + if (cfg->dir != STEDMA40_MEM_TO_PERIPH) dev_dbg(d40c->base->dev, "channel was not configured for memory " @@ -2833,6 +2799,11 @@ static int d40_set_runtime_config(struct dma_chan *chan, return -EINVAL; } + if (config_addr <= 0) { + dev_err(d40c->base->dev, "no address supplied\n"); + return -EINVAL; + } + if (src_maxburst * src_addr_width != dst_maxburst * dst_addr_width) { dev_err(d40c->base->dev, "src/dst width/maxburst mismatch: %d*%d != %d*%d\n", -- cgit v1.2.3 From 01c935c4ecbf6e67d8b7b8258c5eb3be84c248aa Mon Sep 17 00:00:00 2001 From: Lee Jones <lee.jones@linaro.org> Date: Wed, 15 May 2013 10:51:31 +0100 Subject: dmaengine: ste_dma40: Remove redundant address fetching function Addresses are now stored in local data structures and are easy to obtain, thus a specialist function used to fetch them is now surplus to requirement. Signed-off-by: Lee Jones <lee.jones@linaro.org> Acked-by: Vinod Koul <vinod.koul@intel.com> Signed-off-by: Linus Walleij <linus.walleij@linaro.org> --- drivers/dma/ste_dma40.c | 18 ------------------ 1 file changed, 18 deletions(-) (limited to 'drivers/dma') diff --git a/drivers/dma/ste_dma40.c b/drivers/dma/ste_dma40.c index 57a127e5c896..6ed775736853 100644 --- a/drivers/dma/ste_dma40.c +++ b/drivers/dma/ste_dma40.c @@ -2267,24 +2267,6 @@ err: return NULL; } -static dma_addr_t -d40_get_dev_addr(struct d40_chan *chan, enum dma_transfer_direction direction) -{ - struct stedma40_platform_data *plat = chan->base->plat_data; - struct stedma40_chan_cfg *cfg = &chan->dma_cfg; - dma_addr_t addr = 0; - - if (chan->runtime_addr) - return chan->runtime_addr; - - if (direction == DMA_DEV_TO_MEM) - addr = plat->dev_rx[cfg->dev_type]; - else if (direction == DMA_MEM_TO_DEV) - addr = plat->dev_tx[cfg->dev_type]; - - return addr; -} - static struct dma_async_tx_descriptor * d40_prep_sg(struct dma_chan *dchan, struct scatterlist *sg_src, struct scatterlist *sg_dst, unsigned int sg_len, -- cgit v1.2.3