From be2dbb09a014cba5691c8483ad2d0747d3eeb514 Mon Sep 17 00:00:00 2001 From: Lee Jones Date: Wed, 15 May 2013 10:51:43 +0100 Subject: usb: musb: ux500: move channel number knowledge into the driver For all ux500 based platforms the maximum number of end-points are used. Move this knowledge into the driver so we can relinquish the burden from platform data. This also removes quite a bit of complexity from the driver and will aid us when we come to enable the driver for Device Tree. Cc: linux-usb@vger.kernel.org Acked-by: Felipe Balbi Acked-by: Fabio Baltieri Signed-off-by: Lee Jones Signed-off-by: Linus Walleij diff --git a/arch/arm/mach-ux500/usb.c b/arch/arm/mach-ux500/usb.c index 72754e3..a21c2e1 100644 --- a/arch/arm/mach-ux500/usb.c +++ b/arch/arm/mach-ux500/usb.c @@ -22,7 +22,7 @@ .dir = STEDMA40_MEM_TO_PERIPH, \ } -static struct stedma40_chan_cfg musb_dma_rx_ch[UX500_MUSB_DMA_NUM_RX_CHANNELS] +static struct stedma40_chan_cfg musb_dma_rx_ch[UX500_MUSB_DMA_NUM_RX_TX_CHANNELS] = { MUSB_DMA40_RX_CH, MUSB_DMA40_RX_CH, @@ -34,7 +34,7 @@ static struct stedma40_chan_cfg musb_dma_rx_ch[UX500_MUSB_DMA_NUM_RX_CHANNELS] MUSB_DMA40_RX_CH }; -static struct stedma40_chan_cfg musb_dma_tx_ch[UX500_MUSB_DMA_NUM_TX_CHANNELS] +static struct stedma40_chan_cfg musb_dma_tx_ch[UX500_MUSB_DMA_NUM_RX_TX_CHANNELS] = { MUSB_DMA40_TX_CH, MUSB_DMA40_TX_CH, @@ -46,7 +46,7 @@ static struct stedma40_chan_cfg musb_dma_tx_ch[UX500_MUSB_DMA_NUM_TX_CHANNELS] MUSB_DMA40_TX_CH, }; -static void *ux500_dma_rx_param_array[UX500_MUSB_DMA_NUM_RX_CHANNELS] = { +static void *ux500_dma_rx_param_array[UX500_MUSB_DMA_NUM_RX_TX_CHANNELS] = { &musb_dma_rx_ch[0], &musb_dma_rx_ch[1], &musb_dma_rx_ch[2], @@ -57,7 +57,7 @@ static void *ux500_dma_rx_param_array[UX500_MUSB_DMA_NUM_RX_CHANNELS] = { &musb_dma_rx_ch[7] }; -static void *ux500_dma_tx_param_array[UX500_MUSB_DMA_NUM_TX_CHANNELS] = { +static void *ux500_dma_tx_param_array[UX500_MUSB_DMA_NUM_RX_TX_CHANNELS] = { &musb_dma_tx_ch[0], &musb_dma_tx_ch[1], &musb_dma_tx_ch[2], @@ -71,8 +71,6 @@ static void *ux500_dma_tx_param_array[UX500_MUSB_DMA_NUM_TX_CHANNELS] = { static struct ux500_musb_board_data musb_board_data = { .dma_rx_param_array = ux500_dma_rx_param_array, .dma_tx_param_array = ux500_dma_tx_param_array, - .num_rx_channels = UX500_MUSB_DMA_NUM_RX_CHANNELS, - .num_tx_channels = UX500_MUSB_DMA_NUM_TX_CHANNELS, .dma_filter = stedma40_filter, }; @@ -119,7 +117,7 @@ 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++) + for (idx = 0; idx < UX500_MUSB_DMA_NUM_RX_TX_CHANNELS; idx++) musb_dma_rx_ch[idx].dev_type = dev_type[idx]; } @@ -127,7 +125,7 @@ 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++) + for (idx = 0; idx < UX500_MUSB_DMA_NUM_RX_TX_CHANNELS; idx++) musb_dma_tx_ch[idx].dev_type = dev_type[idx]; } diff --git a/drivers/usb/musb/ux500_dma.c b/drivers/usb/musb/ux500_dma.c index 3381206..382291b 100644 --- a/drivers/usb/musb/ux500_dma.c +++ b/drivers/usb/musb/ux500_dma.c @@ -48,10 +48,8 @@ struct ux500_dma_channel { struct ux500_dma_controller { struct dma_controller controller; - struct ux500_dma_channel rx_channel[UX500_MUSB_DMA_NUM_RX_CHANNELS]; - struct ux500_dma_channel tx_channel[UX500_MUSB_DMA_NUM_TX_CHANNELS]; - u32 num_rx_channels; - u32 num_tx_channels; + struct ux500_dma_channel rx_channel[UX500_MUSB_DMA_NUM_RX_TX_CHANNELS]; + struct ux500_dma_channel tx_channel[UX500_MUSB_DMA_NUM_RX_TX_CHANNELS]; void *private_data; dma_addr_t phy_base; }; @@ -144,19 +142,15 @@ static struct dma_channel *ux500_dma_channel_allocate(struct dma_controller *c, struct ux500_dma_channel *ux500_channel = NULL; struct musb *musb = controller->private_data; u8 ch_num = hw_ep->epnum - 1; - u32 max_ch; - /* Max 8 DMA channels (0 - 7). Each DMA channel can only be allocated + /* 8 DMA channels (0 - 7). Each DMA channel can only be allocated * to specified hw_ep. For example DMA channel 0 can only be allocated * to hw_ep 1 and 9. */ if (ch_num > 7) ch_num -= 8; - max_ch = is_tx ? controller->num_tx_channels : - controller->num_rx_channels; - - if (ch_num >= max_ch) + if (ch_num >= UX500_MUSB_DMA_NUM_RX_TX_CHANNELS) return NULL; ux500_channel = is_tx ? &(controller->tx_channel[ch_num]) : @@ -264,7 +258,7 @@ static int ux500_dma_controller_stop(struct dma_controller *c) struct dma_channel *channel; u8 ch_num; - for (ch_num = 0; ch_num < controller->num_rx_channels; ch_num++) { + for (ch_num = 0; ch_num < UX500_MUSB_DMA_NUM_RX_TX_CHANNELS; ch_num++) { channel = &controller->rx_channel[ch_num].channel; ux500_channel = channel->private_data; @@ -274,7 +268,7 @@ static int ux500_dma_controller_stop(struct dma_controller *c) dma_release_channel(ux500_channel->dma_chan); } - for (ch_num = 0; ch_num < controller->num_tx_channels; ch_num++) { + for (ch_num = 0; ch_num < UX500_MUSB_DMA_NUM_RX_TX_CHANNELS; ch_num++) { channel = &controller->tx_channel[ch_num].channel; ux500_channel = channel->private_data; @@ -303,26 +297,21 @@ static int ux500_dma_controller_start(struct dma_controller *c) void **param_array; struct ux500_dma_channel *channel_array; - u32 ch_count; dma_cap_mask_t mask; - if ((data->num_rx_channels > UX500_MUSB_DMA_NUM_RX_CHANNELS) || - (data->num_tx_channels > UX500_MUSB_DMA_NUM_TX_CHANNELS)) - return -EINVAL; - controller->num_rx_channels = data->num_rx_channels; - controller->num_tx_channels = data->num_tx_channels; dma_cap_zero(mask); dma_cap_set(DMA_SLAVE, mask); /* Prepare the loop for RX channels */ channel_array = controller->rx_channel; - ch_count = data->num_rx_channels; param_array = data->dma_rx_param_array; for (dir = 0; dir < 2; dir++) { - for (ch_num = 0; ch_num < ch_count; ch_num++) { + for (ch_num = 0; + ch_num < UX500_MUSB_DMA_NUM_RX_TX_CHANNELS; + ch_num++) { ux500_channel = &channel_array[ch_num]; ux500_channel->controller = controller; ux500_channel->ch_num = ch_num; @@ -350,7 +339,6 @@ static int ux500_dma_controller_start(struct dma_controller *c) /* Prepare the loop for TX channels */ channel_array = controller->tx_channel; - ch_count = data->num_tx_channels; param_array = data->dma_tx_param_array; is_tx = 1; } diff --git a/include/linux/platform_data/usb-musb-ux500.h b/include/linux/platform_data/usb-musb-ux500.h index 4c1cc50..dd9c83a 100644 --- a/include/linux/platform_data/usb-musb-ux500.h +++ b/include/linux/platform_data/usb-musb-ux500.h @@ -9,14 +9,11 @@ #include -#define UX500_MUSB_DMA_NUM_RX_CHANNELS 8 -#define UX500_MUSB_DMA_NUM_TX_CHANNELS 8 +#define UX500_MUSB_DMA_NUM_RX_TX_CHANNELS 8 struct ux500_musb_board_data { void **dma_rx_param_array; void **dma_tx_param_array; - u32 num_rx_channels; - u32 num_tx_channels; bool (*dma_filter)(struct dma_chan *chan, void *filter_param); }; -- cgit v0.10.2 From a20b1b791e42d84dedd5854b60abb841ec1a7585 Mon Sep 17 00:00:00 2001 From: Lee Jones Date: Wed, 15 May 2013 10:51:44 +0100 Subject: usb: musb: ux500: move the MUSB HDRC configuration into the driver The MUSB HDRC configuration never changes between each of the ux500 supported platforms, so there's little point passing it though platform data. If we set it in the driver instead, we can make good use of it when booting with either ATAGs or Device Tree. Cc: linux-usb@vger.kernel.org Acked-by: Felipe Balbi Acked-by: Fabio Baltieri Signed-off-by: Lee Jones Signed-off-by: Linus Walleij diff --git a/arch/arm/mach-ux500/usb.c b/arch/arm/mach-ux500/usb.c index a21c2e1..49d6e57 100644 --- a/arch/arm/mach-ux500/usb.c +++ b/arch/arm/mach-ux500/usb.c @@ -76,16 +76,8 @@ static struct ux500_musb_board_data musb_board_data = { static u64 ux500_musb_dmamask = DMA_BIT_MASK(32); -static struct musb_hdrc_config musb_hdrc_config = { - .multipoint = true, - .dyn_fifo = true, - .num_eps = 16, - .ram_bits = 16, -}; - static struct musb_hdrc_platform_data musb_platform_data = { .mode = MUSB_OTG, - .config = &musb_hdrc_config, .board_data = &musb_board_data, }; diff --git a/drivers/usb/musb/ux500.c b/drivers/usb/musb/ux500.c index 2c80004..371776f 100644 --- a/drivers/usb/musb/ux500.c +++ b/drivers/usb/musb/ux500.c @@ -30,6 +30,13 @@ #include "musb_core.h" +static struct musb_hdrc_config ux500_musb_hdrc_config = { + .multipoint = true, + .dyn_fifo = true, + .num_eps = 16, + .ram_bits = 16, +}; + struct ux500_glue { struct device *dev; struct platform_device *musb; @@ -229,6 +236,7 @@ static int ux500_probe(struct platform_device *pdev) glue->clk = clk; pdata->platform_ops = &ux500_ops; + pdata->config = &ux500_musb_hdrc_config; platform_set_drvdata(pdev, glue); -- cgit v0.10.2 From 1e6eebb4e907548d53347a6e90769feb3d73e9da Mon Sep 17 00:00:00 2001 From: Lee Jones Date: Wed, 15 May 2013 10:51:45 +0100 Subject: usb: musb: ux500: take the dma_mask from coherent_dma_mask The dma_mask will always be the same as the coherent_dma_mask, so let's cut down on the platform_data burden and set it as such in the driver. This also saves us from supporting it separately when we come to enable this driver for Device Tree. Cc: linux-usb@vger.kernel.org Acked-by: Felipe Balbi Acked-by: Fabio Baltieri Signed-off-by: Lee Jones Signed-off-by: Linus Walleij diff --git a/arch/arm/mach-ux500/usb.c b/arch/arm/mach-ux500/usb.c index 49d6e57..2f9abe9 100644 --- a/arch/arm/mach-ux500/usb.c +++ b/arch/arm/mach-ux500/usb.c @@ -74,8 +74,6 @@ static struct ux500_musb_board_data musb_board_data = { .dma_filter = stedma40_filter, }; -static u64 ux500_musb_dmamask = DMA_BIT_MASK(32); - static struct musb_hdrc_platform_data musb_platform_data = { .mode = MUSB_OTG, .board_data = &musb_board_data, @@ -98,7 +96,6 @@ struct platform_device ux500_musb_device = { .id = 0, .dev = { .platform_data = &musb_platform_data, - .dma_mask = &ux500_musb_dmamask, .coherent_dma_mask = DMA_BIT_MASK(32), }, .num_resources = ARRAY_SIZE(usb_resources), diff --git a/drivers/usb/musb/ux500.c b/drivers/usb/musb/ux500.c index 371776f..3cf10bc 100644 --- a/drivers/usb/musb/ux500.c +++ b/drivers/usb/musb/ux500.c @@ -228,7 +228,7 @@ static int ux500_probe(struct platform_device *pdev) } musb->dev.parent = &pdev->dev; - musb->dev.dma_mask = pdev->dev.dma_mask; + musb->dev.dma_mask = &pdev->dev.coherent_dma_mask; musb->dev.coherent_dma_mask = pdev->dev.coherent_dma_mask; glue->dev = &pdev->dev; -- cgit v0.10.2 From 5f6091a023ca435c49467348e388fa89e635436a Mon Sep 17 00:00:00 2001 From: Lee Jones Date: Wed, 15 May 2013 10:51:46 +0100 Subject: usb: musb: ux500: harden checks for platform data In its current state, the ux500-musb driver uses platform data pointers blindly with no prior checking. If no platform data pointer is passed this will Oops the kernel. In this patch we ensure platform data and board data are present prior to using them. Cc: linux-usb@vger.kernel.org Acked-by: Felipe Balbi Acked-by: Fabio Baltieri Signed-off-by: Lee Jones Signed-off-by: Linus Walleij diff --git a/drivers/usb/musb/ux500_dma.c b/drivers/usb/musb/ux500_dma.c index 382291b..4bd5400 100644 --- a/drivers/usb/musb/ux500_dma.c +++ b/drivers/usb/musb/ux500_dma.c @@ -289,7 +289,7 @@ static int ux500_dma_controller_start(struct dma_controller *c) struct musb *musb = controller->private_data; struct device *dev = musb->controller; struct musb_hdrc_platform_data *plat = dev->platform_data; - struct ux500_musb_board_data *data = plat->board_data; + struct ux500_musb_board_data *data; struct dma_channel *dma_channel = NULL; u32 ch_num; u8 dir; @@ -299,14 +299,19 @@ static int ux500_dma_controller_start(struct dma_controller *c) struct ux500_dma_channel *channel_array; dma_cap_mask_t mask; + if (!plat) { + dev_err(musb->controller, "No platform data\n"); + return -EINVAL; + } + data = plat->board_data; dma_cap_zero(mask); dma_cap_set(DMA_SLAVE, mask); /* Prepare the loop for RX channels */ channel_array = controller->rx_channel; - param_array = data->dma_rx_param_array; + param_array = data ? data->dma_rx_param_array : NULL; for (dir = 0; dir < 2; dir++) { for (ch_num = 0; @@ -339,7 +344,7 @@ static int ux500_dma_controller_start(struct dma_controller *c) /* Prepare the loop for TX channels */ channel_array = controller->tx_channel; - param_array = data->dma_tx_param_array; + param_array = data ? data->dma_tx_param_array : NULL; is_tx = 1; } -- cgit v0.10.2 From 2968da0b2c7297a29d49c7084d6865c2cf627093 Mon Sep 17 00:00:00 2001 From: Lee Jones Date: Wed, 15 May 2013 10:51:47 +0100 Subject: usb: musb: ux500: attempt to find channels by name before using pdata If we can ever get to a state where we can solely search for DMA channels by name, this will almost completely alleviate the requirement to pass copious amounts of information though platform data. Here we take the first step towards this. The next step will be to enable Device Tree complete with name<->event_line mapping. Cc: linux-usb@vger.kernel.org Acked-by: Felipe Balbi Acked-by: Fabio Baltieri Signed-off-by: Lee Jones Signed-off-by: Linus Walleij diff --git a/drivers/usb/musb/ux500_dma.c b/drivers/usb/musb/ux500_dma.c index 4bd5400..7d80699 100644 --- a/drivers/usb/musb/ux500_dma.c +++ b/drivers/usb/musb/ux500_dma.c @@ -34,6 +34,11 @@ #include #include "musb_core.h" +static const char *iep_chan_names[] = { "iep_1_9", "iep_2_10", "iep_3_11", "iep_4_12", + "iep_5_13", "iep_6_14", "iep_7_15", "iep_8" }; +static const char *oep_chan_names[] = { "oep_1_9", "oep_2_10", "oep_3_11", "oep_4_12", + "oep_5_13", "oep_6_14", "oep_7_15", "oep_8" }; + struct ux500_dma_channel { struct dma_channel channel; struct ux500_dma_controller *controller; @@ -291,6 +296,7 @@ static int ux500_dma_controller_start(struct dma_controller *c) struct musb_hdrc_platform_data *plat = dev->platform_data; struct ux500_musb_board_data *data; struct dma_channel *dma_channel = NULL; + char **chan_names; u32 ch_num; u8 dir; u8 is_tx = 0; @@ -312,6 +318,7 @@ static int ux500_dma_controller_start(struct dma_controller *c) /* Prepare the loop for RX channels */ channel_array = controller->rx_channel; param_array = data ? data->dma_rx_param_array : NULL; + chan_names = (char **)iep_chan_names; for (dir = 0; dir < 2; dir++) { for (ch_num = 0; @@ -327,9 +334,15 @@ static int ux500_dma_controller_start(struct dma_controller *c) dma_channel->status = MUSB_DMA_STATUS_FREE; dma_channel->max_len = SZ_16M; - ux500_channel->dma_chan = dma_request_channel(mask, - data->dma_filter, - param_array[ch_num]); + ux500_channel->dma_chan = + dma_request_slave_channel(dev, chan_names[ch_num]); + + if (!ux500_channel->dma_chan) + ux500_channel->dma_chan = + dma_request_channel(mask, + data->dma_filter, + param_array[ch_num]); + if (!ux500_channel->dma_chan) { ERR("Dma pipe allocation error dir=%d ch=%d\n", dir, ch_num); @@ -345,6 +358,7 @@ static int ux500_dma_controller_start(struct dma_controller *c) /* Prepare the loop for TX channels */ channel_array = controller->tx_channel; param_array = data ? data->dma_tx_param_array : NULL; + chan_names = (char **)oep_chan_names; is_tx = 1; } -- cgit v0.10.2 From 313bdb11e52a301aa7f6f8729a87ff0908785163 Mon Sep 17 00:00:00 2001 From: Lee Jones Date: Wed, 15 May 2013 10:51:48 +0100 Subject: usb: musb: ux500: add device tree probing support This patch will allow ux500-musb to be probed and configured solely from configuration found in Device Tree. Cc: Rob Herring Cc: linux-usb@vger.kernel.org Cc: devicetree-discuss@lists.ozlabs.org Acked-by: Felipe Balbi Acked-by: Fabio Baltieri Signed-off-by: Lee Jones Signed-off-by: Linus Walleij diff --git a/Documentation/devicetree/bindings/usb/ux500-usb.txt b/Documentation/devicetree/bindings/usb/ux500-usb.txt new file mode 100644 index 0000000..330d6ec --- /dev/null +++ b/Documentation/devicetree/bindings/usb/ux500-usb.txt @@ -0,0 +1,50 @@ +Ux500 MUSB + +Required properties: + - compatible : Should be "stericsson,db8500-musb" + - reg : Offset and length of registers + - interrupts : Interrupt; mode, number and trigger + - dr_mode : Dual-role; either host mode "host", peripheral mode "peripheral" + or both "otg" + +Optional properties: + - dmas : A list of dma channels; + dma-controller, event-line, fixed-channel, flags + - dma-names : An ordered list of channel names affiliated to the above + +Example: + +usb_per5@a03e0000 { + compatible = "stericsson,db8500-musb", "mentor,musb"; + reg = <0xa03e0000 0x10000>; + interrupts = <0 23 0x4>; + interrupt-names = "mc"; + + dr_mode = "otg"; + + dmas = <&dma 38 0 0x2>, /* Logical - DevToMem */ + <&dma 38 0 0x0>, /* Logical - MemToDev */ + <&dma 37 0 0x2>, /* Logical - DevToMem */ + <&dma 37 0 0x0>, /* Logical - MemToDev */ + <&dma 36 0 0x2>, /* Logical - DevToMem */ + <&dma 36 0 0x0>, /* Logical - MemToDev */ + <&dma 19 0 0x2>, /* Logical - DevToMem */ + <&dma 19 0 0x0>, /* Logical - MemToDev */ + <&dma 18 0 0x2>, /* Logical - DevToMem */ + <&dma 18 0 0x0>, /* Logical - MemToDev */ + <&dma 17 0 0x2>, /* Logical - DevToMem */ + <&dma 17 0 0x0>, /* Logical - MemToDev */ + <&dma 16 0 0x2>, /* Logical - DevToMem */ + <&dma 16 0 0x0>, /* Logical - MemToDev */ + <&dma 39 0 0x2>, /* Logical - DevToMem */ + <&dma 39 0 0x0>; /* Logical - MemToDev */ + + dma-names = "iep_1_9", "oep_1_9", + "iep_2_10", "oep_2_10", + "iep_3_11", "oep_3_11", + "iep_4_12", "oep_4_12", + "iep_5_13", "oep_5_13", + "iep_6_14", "oep_6_14", + "iep_7_15", "oep_7_15", + "iep_8", "oep_8"; +}; diff --git a/drivers/usb/musb/ux500.c b/drivers/usb/musb/ux500.c index 3cf10bc..f0beee7 100644 --- a/drivers/usb/musb/ux500.c +++ b/drivers/usb/musb/ux500.c @@ -25,6 +25,7 @@ #include #include #include +#include #include #include @@ -194,14 +195,57 @@ static const struct musb_platform_ops ux500_ops = { .set_vbus = ux500_musb_set_vbus, }; +static struct musb_hdrc_platform_data * +ux500_of_probe(struct platform_device *pdev, struct device_node *np) +{ + struct musb_hdrc_platform_data *pdata; + const char *mode; + int strlen; + + pdata = devm_kzalloc(&pdev->dev, sizeof(*pdata), GFP_KERNEL); + if (!pdata) + return NULL; + + mode = of_get_property(np, "dr_mode", &strlen); + if (!mode) { + dev_err(&pdev->dev, "No 'dr_mode' property found\n"); + return NULL; + } + + if (strlen > 0) { + if (!strcmp(mode, "host")) + pdata->mode = MUSB_HOST; + if (!strcmp(mode, "otg")) + pdata->mode = MUSB_OTG; + if (!strcmp(mode, "peripheral")) + pdata->mode = MUSB_PERIPHERAL; + } + + return pdata; +} + static int ux500_probe(struct platform_device *pdev) { struct musb_hdrc_platform_data *pdata = pdev->dev.platform_data; + struct device_node *np = pdev->dev.of_node; struct platform_device *musb; struct ux500_glue *glue; struct clk *clk; int ret = -ENOMEM; + if (!pdata) { + if (np) { + pdata = ux500_of_probe(pdev, np); + if (!pdata) + goto err0; + + pdev->dev.platform_data = pdata; + } else { + dev_err(&pdev->dev, "no pdata or device tree found\n"); + goto err0; + } + } + glue = kzalloc(sizeof(*glue), GFP_KERNEL); if (!glue) { dev_err(&pdev->dev, "failed to allocate glue context\n"); @@ -230,6 +274,7 @@ static int ux500_probe(struct platform_device *pdev) musb->dev.parent = &pdev->dev; musb->dev.dma_mask = &pdev->dev.coherent_dma_mask; musb->dev.coherent_dma_mask = pdev->dev.coherent_dma_mask; + musb->dev.of_node = pdev->dev.of_node; glue->dev = &pdev->dev; glue->musb = musb; @@ -328,12 +373,18 @@ static const struct dev_pm_ops ux500_pm_ops = { #define DEV_PM_OPS NULL #endif +static const struct of_device_id ux500_match[] = { + { .compatible = "stericsson,db8500-musb", }, + {} +}; + static struct platform_driver ux500_driver = { .probe = ux500_probe, .remove = ux500_remove, .driver = { .name = "musb-ux500", .pm = DEV_PM_OPS, + .of_match_table = ux500_match, }, }; -- cgit v0.10.2 From d4999b19d96decc48eb456b0a33be0e6dc5d793b Mon Sep 17 00:00:00 2001 From: Lee Jones Date: Wed, 15 May 2013 10:51:50 +0100 Subject: ARM: ux500: Remove ux500-musb platform registation when booting with DT Now the ux500-musb driver has been enabled for Device Tree, there is no requirement to register it from platform code. Acked-by: Fabio Baltieri Signed-off-by: Lee Jones Signed-off-by: Linus Walleij diff --git a/arch/arm/mach-ux500/cpu-db8500.c b/arch/arm/mach-ux500/cpu-db8500.c index 959a105..fbe1fb8 100644 --- a/arch/arm/mach-ux500/cpu-db8500.c +++ b/arch/arm/mach-ux500/cpu-db8500.c @@ -223,8 +223,6 @@ static struct device * __init u8500_of_init_devices(void) { struct device *parent = db8500_soc_device_init(); - db8500_add_usb(parent, usb_db8500_dma_cfg, usb_db8500_dma_cfg); - return parent; } -- cgit v0.10.2 From 1e74043a29cdec67279d6e4f494dd1674a1b2365 Mon Sep 17 00:00:00 2001 From: Lee Jones Date: Wed, 15 May 2013 10:51:51 +0100 Subject: ARM: ux500: Remove empty function u8500_of_init_devices() As promised, now all devices which resided in u8500_of_init_devices() have been enabled for Device Tree, we can completely remove it. Acked-by: Fabio Baltieri Signed-off-by: Lee Jones Signed-off-by: Linus Walleij diff --git a/arch/arm/mach-ux500/cpu-db8500.c b/arch/arm/mach-ux500/cpu-db8500.c index fbe1fb8..6e49e4f 100644 --- a/arch/arm/mach-ux500/cpu-db8500.c +++ b/arch/arm/mach-ux500/cpu-db8500.c @@ -217,15 +217,6 @@ struct device * __init u8500_init_devices(struct ab8500_platform_data *ab8500) } #ifdef CONFIG_MACH_UX500_DT - -/* TODO: Once all pieces are DT:ed, remove completely. */ -static struct device * __init u8500_of_init_devices(void) -{ - struct device *parent = db8500_soc_device_init(); - - return parent; -} - static struct of_dev_auxdata u8500_auxdata_lookup[] __initdata = { /* Requires call-back bindings. */ OF_DEV_AUXDATA("arm,cortex-a9-pmu", 0, "arm-pmu", &db8500_pmu_platdata), @@ -284,7 +275,7 @@ static const struct of_device_id u8500_local_bus_nodes[] = { static void __init u8500_init_machine(void) { - struct device *parent = NULL; + struct device *parent = db8500_soc_device_init(); /* Pinmaps must be in place before devices register */ if (of_machine_is_compatible("st-ericsson,mop500")) @@ -297,9 +288,6 @@ static void __init u8500_init_machine(void) else if (of_machine_is_compatible("st-ericsson,ccu9540")) {} /* TODO: Add pinmaps for ccu9540 board. */ - /* TODO: Export SoC, USB, cpu-freq and DMA40 */ - parent = u8500_of_init_devices(); - /* automatically probe child nodes of db8500 device */ of_platform_populate(NULL, u8500_local_bus_nodes, u8500_auxdata_lookup, parent); } -- cgit v0.10.2 From 8a3b6e143c3aa31fab4a820105e91e1cdb17ad42 Mon Sep 17 00:00:00 2001 From: Lee Jones Date: Wed, 15 May 2013 10:51:52 +0100 Subject: dmaengine: ste_dma40: Use the BIT macro to replace ugly '(1 << x)'s The aim is to make the code that little more readable. Acked-by: Vinod Koul Acked-by: Arnd Bergmann Signed-off-by: Lee Jones Signed-off-by: Linus Walleij diff --git a/drivers/dma/ste_dma40.c b/drivers/dma/ste_dma40.c index 6ed7757..08bc58a 100644 --- a/drivers/dma/ste_dma40.c +++ b/drivers/dma/ste_dma40.c @@ -54,8 +54,8 @@ #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_FREE BIT(31) +#define D40_ALLOC_PHY BIT(30) #define D40_ALLOC_LOG_FREE 0 /* Reserved event lines for memcpy only. */ @@ -1738,7 +1738,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); @@ -1828,8 +1828,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; @@ -1840,8 +1840,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; @@ -1871,11 +1871,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; } @@ -2356,7 +2356,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; -- cgit v0.10.2 From 98b68ab5ce2a8d1b98a375f9bed66724222ef9b4 Mon Sep 17 00:00:00 2001 From: Lee Jones Date: Wed, 15 May 2013 10:51:53 +0100 Subject: ARM: ux500: Replace ST-E's home-brew DMA direction definition with the generic one STEDMA40_*_TO_* direction definitions are identical in all but name to the pre-defined generic DMA_*_TO_* ones. Let's make things easy by not duplicating such things. Signed-off-by: Lee Jones Signed-off-by: Linus Walleij diff --git a/arch/arm/mach-ux500/board-mop500-audio.c b/arch/arm/mach-ux500/board-mop500-audio.c index ec87262..bfe443d 100644 --- a/arch/arm/mach-ux500/board-mop500-audio.c +++ b/arch/arm/mach-ux500/board-mop500-audio.c @@ -21,13 +21,13 @@ static struct stedma40_chan_cfg msp0_dma_rx = { .high_priority = true, - .dir = STEDMA40_PERIPH_TO_MEM, + .dir = DMA_DEV_TO_MEM, .dev_type = DB8500_DMA_DEV31_MSP0_SLIM0_CH0, }; static struct stedma40_chan_cfg msp0_dma_tx = { .high_priority = true, - .dir = STEDMA40_MEM_TO_PERIPH, + .dir = DMA_MEM_TO_DEV, .dev_type = DB8500_DMA_DEV31_MSP0_SLIM0_CH0, }; @@ -39,13 +39,13 @@ struct msp_i2s_platform_data msp0_platform_data = { static struct stedma40_chan_cfg msp1_dma_rx = { .high_priority = true, - .dir = STEDMA40_PERIPH_TO_MEM, + .dir = DMA_DEV_TO_MEM, .dev_type = DB8500_DMA_DEV30_MSP3, }; static struct stedma40_chan_cfg msp1_dma_tx = { .high_priority = true, - .dir = STEDMA40_MEM_TO_PERIPH, + .dir = DMA_MEM_TO_DEV, .dev_type = DB8500_DMA_DEV30_MSP1, }; @@ -57,13 +57,13 @@ struct msp_i2s_platform_data msp1_platform_data = { static struct stedma40_chan_cfg msp2_dma_rx = { .high_priority = true, - .dir = STEDMA40_PERIPH_TO_MEM, + .dir = DMA_DEV_TO_MEM, .dev_type = DB8500_DMA_DEV14_MSP2, }; static struct stedma40_chan_cfg msp2_dma_tx = { .high_priority = true, - .dir = STEDMA40_MEM_TO_PERIPH, + .dir = DMA_MEM_TO_DEV, .dev_type = DB8500_DMA_DEV14_MSP2, .use_fixed_channel = true, .phy_channel = 1, diff --git a/arch/arm/mach-ux500/board-mop500-sdi.c b/arch/arm/mach-ux500/board-mop500-sdi.c index 29be714..e6891d1 100644 --- a/arch/arm/mach-ux500/board-mop500-sdi.c +++ b/arch/arm/mach-ux500/board-mop500-sdi.c @@ -34,13 +34,13 @@ #ifdef CONFIG_STE_DMA40 struct stedma40_chan_cfg mop500_sdi0_dma_cfg_rx = { .mode = STEDMA40_MODE_LOGICAL, - .dir = STEDMA40_PERIPH_TO_MEM, + .dir = DMA_DEV_TO_MEM, .dev_type = DB8500_DMA_DEV29_SD_MM0, }; static struct stedma40_chan_cfg mop500_sdi0_dma_cfg_tx = { .mode = STEDMA40_MODE_LOGICAL, - .dir = STEDMA40_MEM_TO_PERIPH, + .dir = DMA_MEM_TO_DEV, .dev_type = DB8500_DMA_DEV29_SD_MM0, }; #endif @@ -81,13 +81,13 @@ void mop500_sdi_tc35892_init(struct device *parent) #ifdef CONFIG_STE_DMA40 static struct stedma40_chan_cfg sdi1_dma_cfg_rx = { .mode = STEDMA40_MODE_LOGICAL, - .dir = STEDMA40_PERIPH_TO_MEM, + .dir = DMA_DEV_TO_MEM, .dev_type = DB8500_DMA_DEV32_SD_MM1, }; static struct stedma40_chan_cfg sdi1_dma_cfg_tx = { .mode = STEDMA40_MODE_LOGICAL, - .dir = STEDMA40_MEM_TO_PERIPH, + .dir = DMA_MEM_TO_DEV, .dev_type = DB8500_DMA_DEV32_SD_MM1, }; #endif @@ -112,13 +112,13 @@ struct mmci_platform_data mop500_sdi1_data = { #ifdef CONFIG_STE_DMA40 struct stedma40_chan_cfg mop500_sdi2_dma_cfg_rx = { .mode = STEDMA40_MODE_LOGICAL, - .dir = STEDMA40_PERIPH_TO_MEM, + .dir = DMA_DEV_TO_MEM, .dev_type = DB8500_DMA_DEV28_SD_MM2, }; static struct stedma40_chan_cfg mop500_sdi2_dma_cfg_tx = { .mode = STEDMA40_MODE_LOGICAL, - .dir = STEDMA40_MEM_TO_PERIPH, + .dir = DMA_MEM_TO_DEV, .dev_type = DB8500_DMA_DEV28_SD_MM2, }; #endif @@ -144,13 +144,13 @@ struct mmci_platform_data mop500_sdi2_data = { #ifdef CONFIG_STE_DMA40 struct stedma40_chan_cfg mop500_sdi4_dma_cfg_rx = { .mode = STEDMA40_MODE_LOGICAL, - .dir = STEDMA40_PERIPH_TO_MEM, + .dir = DMA_DEV_TO_MEM, .dev_type = DB8500_DMA_DEV42_SD_MM4, }; static struct stedma40_chan_cfg mop500_sdi4_dma_cfg_tx = { .mode = STEDMA40_MODE_LOGICAL, - .dir = STEDMA40_MEM_TO_PERIPH, + .dir = DMA_MEM_TO_DEV, .dev_type = DB8500_DMA_DEV42_SD_MM4, }; #endif diff --git a/arch/arm/mach-ux500/board-mop500.c b/arch/arm/mach-ux500/board-mop500.c index 3507399..fcf06ac 100644 --- a/arch/arm/mach-ux500/board-mop500.c +++ b/arch/arm/mach-ux500/board-mop500.c @@ -424,19 +424,19 @@ void mop500_snowball_ethernet_clock_enable(void) static struct cryp_platform_data u8500_cryp1_platform_data = { .mem_to_engine = { - .dir = STEDMA40_MEM_TO_PERIPH, + .dir = DMA_MEM_TO_DEV, .dev_type = DB8500_DMA_DEV48_CAC1, .mode = STEDMA40_MODE_LOGICAL, }, .engine_to_mem = { - .dir = STEDMA40_PERIPH_TO_MEM, + .dir = DMA_DEV_TO_MEM, .dev_type = DB8500_DMA_DEV48_CAC1, .mode = STEDMA40_MODE_LOGICAL, } }; static struct stedma40_chan_cfg u8500_hash_dma_cfg_tx = { - .dir = STEDMA40_MEM_TO_PERIPH, + .dir = DMA_MEM_TO_DEV, .dev_type = DB8500_DMA_DEV50_HAC1_TX, .mode = STEDMA40_MODE_LOGICAL, }; @@ -455,13 +455,13 @@ static struct platform_device *mop500_platform_devs[] __initdata = { #ifdef CONFIG_STE_DMA40 static struct stedma40_chan_cfg ssp0_dma_cfg_rx = { .mode = STEDMA40_MODE_LOGICAL, - .dir = STEDMA40_PERIPH_TO_MEM, + .dir = DMA_DEV_TO_MEM, .dev_type = DB8500_DMA_DEV8_SSP0, }; static struct stedma40_chan_cfg ssp0_dma_cfg_tx = { .mode = STEDMA40_MODE_LOGICAL, - .dir = STEDMA40_MEM_TO_PERIPH, + .dir = DMA_MEM_TO_DEV, .dev_type = DB8500_DMA_DEV8_SSP0, }; #endif @@ -490,37 +490,37 @@ static void __init mop500_spi_init(struct device *parent) #ifdef CONFIG_STE_DMA40 static struct stedma40_chan_cfg uart0_dma_cfg_rx = { .mode = STEDMA40_MODE_LOGICAL, - .dir = STEDMA40_PERIPH_TO_MEM, + .dir = DMA_DEV_TO_MEM, .dev_type = DB8500_DMA_DEV13_UART0, }; static struct stedma40_chan_cfg uart0_dma_cfg_tx = { .mode = STEDMA40_MODE_LOGICAL, - .dir = STEDMA40_MEM_TO_PERIPH, + .dir = DMA_MEM_TO_DEV, .dev_type = DB8500_DMA_DEV13_UART0, }; static struct stedma40_chan_cfg uart1_dma_cfg_rx = { .mode = STEDMA40_MODE_LOGICAL, - .dir = STEDMA40_PERIPH_TO_MEM, + .dir = DMA_DEV_TO_MEM, .dev_type = DB8500_DMA_DEV12_UART1, }; static struct stedma40_chan_cfg uart1_dma_cfg_tx = { .mode = STEDMA40_MODE_LOGICAL, - .dir = STEDMA40_MEM_TO_PERIPH, + .dir = DMA_MEM_TO_DEV, .dev_type = DB8500_DMA_DEV12_UART1, }; static struct stedma40_chan_cfg uart2_dma_cfg_rx = { .mode = STEDMA40_MODE_LOGICAL, - .dir = STEDMA40_PERIPH_TO_MEM, + .dir = DMA_DEV_TO_MEM, .dev_type = DB8500_DMA_DEV11_UART2, }; static struct stedma40_chan_cfg uart2_dma_cfg_tx = { .mode = STEDMA40_MODE_LOGICAL, - .dir = STEDMA40_MEM_TO_PERIPH, + .dir = DMA_MEM_TO_DEV, .dev_type = DB8500_DMA_DEV11_UART2, }; #endif diff --git a/arch/arm/mach-ux500/usb.c b/arch/arm/mach-ux500/usb.c index 2f9abe9..b7bd8d3 100644 --- a/arch/arm/mach-ux500/usb.c +++ b/arch/arm/mach-ux500/usb.c @@ -14,12 +14,12 @@ #define MUSB_DMA40_RX_CH { \ .mode = STEDMA40_MODE_LOGICAL, \ - .dir = STEDMA40_PERIPH_TO_MEM, \ + .dir = DMA_DEV_TO_MEM, \ } #define MUSB_DMA40_TX_CH { \ .mode = STEDMA40_MODE_LOGICAL, \ - .dir = STEDMA40_MEM_TO_PERIPH, \ + .dir = DMA_MEM_TO_DEV, \ } static struct stedma40_chan_cfg musb_dma_rx_ch[UX500_MUSB_DMA_NUM_RX_TX_CHANNELS] -- cgit v0.10.2 From 2c2b62d5d911da10c0fc37c31458baf4047d531c Mon Sep 17 00:00:00 2001 From: Lee Jones Date: Wed, 15 May 2013 10:51:54 +0100 Subject: dmaengine: ste_dma40: Replace ST-E's home-brew DMA direction defs with generic ones STEDMA40_*_TO_* direction definitions are identical in all but name to the pre-defined generic DMA_*_TO_* ones. Let's make things easy by not duplicating such things. Cc: Dan Williams Cc: Per Forlin Cc: Rabin Vincent Acked-by: Vinod Koul Signed-off-by: Lee Jones Signed-off-by: Linus Walleij diff --git a/drivers/dma/ste_dma40.c b/drivers/dma/ste_dma40.c index 08bc58a..483da16 100644 --- a/drivers/dma/ste_dma40.c +++ b/drivers/dma/ste_dma40.c @@ -78,7 +78,7 @@ static int dma40_memcpy_channels[] = { /* Default configuration for physcial memcpy */ struct stedma40_chan_cfg dma40_memcpy_conf_phy = { .mode = STEDMA40_MODE_PHYSICAL, - .dir = STEDMA40_MEM_TO_MEM, + .dir = DMA_MEM_TO_MEM, .src_info.data_width = STEDMA40_BYTE_WIDTH, .src_info.psize = STEDMA40_PSIZE_PHY_1, @@ -92,7 +92,7 @@ struct stedma40_chan_cfg dma40_memcpy_conf_phy = { /* Default configuration for logical memcpy */ struct stedma40_chan_cfg dma40_memcpy_conf_log = { .mode = STEDMA40_MODE_LOGICAL, - .dir = STEDMA40_MEM_TO_MEM, + .dir = DMA_MEM_TO_MEM, .src_info.data_width = STEDMA40_BYTE_WIDTH, .src_info.psize = STEDMA40_PSIZE_LOG_1, @@ -843,7 +843,7 @@ static void d40_log_lli_to_lcxa(struct d40_chan *chan, struct d40_desc *desc) * that uses linked lists. */ if (!(chan->phy_chan->use_soft_lli && - chan->dma_cfg.dir == STEDMA40_PERIPH_TO_MEM)) + chan->dma_cfg.dir == DMA_DEV_TO_MEM)) curr_lcla = d40_lcla_alloc_one(chan, desc); first_lcla = curr_lcla; @@ -1311,12 +1311,12 @@ static void d40_config_set_event(struct d40_chan *d40c, 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)) + if ((d40c->dma_cfg.dir == DMA_DEV_TO_MEM) || + (d40c->dma_cfg.dir == DMA_DEV_TO_DEV)) __d40_config_set_event(d40c, event_type, event, D40_CHAN_REG_SSLNK); - if (d40c->dma_cfg.dir != STEDMA40_PERIPH_TO_MEM) + if (d40c->dma_cfg.dir != DMA_DEV_TO_MEM) __d40_config_set_event(d40c, event_type, event, D40_CHAN_REG_SDLNK); } @@ -1774,7 +1774,7 @@ static int d40_validate_conf(struct d40_chan *d40c, res = -EINVAL; } - if (conf->dir == STEDMA40_PERIPH_TO_PERIPH) { + if (conf->dir == DMA_DEV_TO_DEV) { /* * DMAC HW supports it. Will be added to this driver, * in case any dma client requires it. @@ -1905,11 +1905,11 @@ static int d40_allocate_channel(struct d40_chan *d40c, bool *first_phy_user) phys = d40c->base->phy_res; num_phy_chans = d40c->base->num_phy_chans; - if (d40c->dma_cfg.dir == STEDMA40_PERIPH_TO_MEM) { + if (d40c->dma_cfg.dir == DMA_DEV_TO_MEM) { 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) { + } else if (d40c->dma_cfg.dir == DMA_MEM_TO_DEV || + d40c->dma_cfg.dir == DMA_MEM_TO_MEM) { /* dst event lines are used for logical memcpy */ log_num = 2 * dev_type + 1; is_src = false; @@ -1920,7 +1920,7 @@ static int d40_allocate_channel(struct d40_chan *d40c, bool *first_phy_user) event_line = D40_TYPE_TO_EVENT(dev_type); if (!is_log) { - if (d40c->dma_cfg.dir == STEDMA40_MEM_TO_MEM) { + if (d40c->dma_cfg.dir == DMA_MEM_TO_MEM) { /* Find physical half channel */ if (d40c->dma_cfg.use_fixed_channel) { i = d40c->dma_cfg.phy_channel; @@ -2068,10 +2068,10 @@ static int d40_free_dma(struct d40_chan *d40c) return -EINVAL; } - if (d40c->dma_cfg.dir == STEDMA40_MEM_TO_PERIPH || - d40c->dma_cfg.dir == STEDMA40_MEM_TO_MEM) + if (d40c->dma_cfg.dir == DMA_MEM_TO_DEV || + d40c->dma_cfg.dir == DMA_MEM_TO_MEM) is_src = false; - else if (d40c->dma_cfg.dir == STEDMA40_PERIPH_TO_MEM) + else if (d40c->dma_cfg.dir == DMA_DEV_TO_MEM) is_src = true; else { chan_err(d40c, "Unknown direction\n"); @@ -2133,10 +2133,10 @@ static bool d40_is_paused(struct d40_chan *d40c) goto _exit; } - if (d40c->dma_cfg.dir == STEDMA40_MEM_TO_PERIPH || - d40c->dma_cfg.dir == STEDMA40_MEM_TO_MEM) { + if (d40c->dma_cfg.dir == DMA_MEM_TO_DEV || + d40c->dma_cfg.dir == DMA_MEM_TO_MEM) { status = readl(chanbase + D40_CHAN_REG_SDLNK); - } else if (d40c->dma_cfg.dir == STEDMA40_PERIPH_TO_MEM) { + } else if (d40c->dma_cfg.dir == DMA_DEV_TO_MEM) { status = readl(chanbase + D40_CHAN_REG_SSLNK); } else { chan_err(d40c, "Unknown direction\n"); @@ -2387,12 +2387,12 @@ static void d40_set_prio_realtime(struct d40_chan *d40c) if (d40c->base->rev < 3) return; - if ((d40c->dma_cfg.dir == STEDMA40_PERIPH_TO_MEM) || - (d40c->dma_cfg.dir == STEDMA40_PERIPH_TO_PERIPH)) + if ((d40c->dma_cfg.dir == DMA_DEV_TO_MEM) || + (d40c->dma_cfg.dir == DMA_DEV_TO_DEV)) __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)) + if ((d40c->dma_cfg.dir == DMA_MEM_TO_DEV) || + (d40c->dma_cfg.dir == DMA_DEV_TO_DEV)) __d40_set_prio_rt(d40c, d40c->dma_cfg.dev_type, false); } @@ -2423,11 +2423,11 @@ static struct dma_chan *d40_xlate(struct of_phandle_args *dma_spec, switch (D40_DT_FLAGS_DIR(flags)) { case 0: - cfg.dir = STEDMA40_MEM_TO_PERIPH; + cfg.dir = DMA_MEM_TO_DEV; cfg.dst_info.big_endian = D40_DT_FLAGS_BIG_ENDIAN(flags); break; case 1: - cfg.dir = STEDMA40_PERIPH_TO_MEM; + cfg.dir = DMA_DEV_TO_MEM; cfg.src_info.big_endian = D40_DT_FLAGS_BIG_ENDIAN(flags); break; } @@ -2473,7 +2473,7 @@ static int d40_alloc_chan_resources(struct dma_chan *chan) d40_set_prio_realtime(d40c); if (chan_is_logical(d40c)) { - if (d40c->dma_cfg.dir == STEDMA40_PERIPH_TO_MEM) + if (d40c->dma_cfg.dir == DMA_DEV_TO_MEM) d40c->lcpa = d40c->base->lcpa_base + d40c->dma_cfg.dev_type * D40_LCPA_CHAN_SIZE; else @@ -2746,12 +2746,12 @@ static int d40_set_runtime_config(struct dma_chan *chan, if (config->direction == DMA_DEV_TO_MEM) { config_addr = config->src_addr; - if (cfg->dir != STEDMA40_PERIPH_TO_MEM) + if (cfg->dir != DMA_DEV_TO_MEM) dev_dbg(d40c->base->dev, "channel was not configured for peripheral " "to memory transfer (%d) overriding\n", cfg->dir); - cfg->dir = STEDMA40_PERIPH_TO_MEM; + cfg->dir = DMA_DEV_TO_MEM; /* Configure the memory side */ if (dst_addr_width == DMA_SLAVE_BUSWIDTH_UNDEFINED) @@ -2762,12 +2762,12 @@ static int d40_set_runtime_config(struct dma_chan *chan, } else if (config->direction == DMA_MEM_TO_DEV) { config_addr = config->dst_addr; - if (cfg->dir != STEDMA40_MEM_TO_PERIPH) + if (cfg->dir != DMA_MEM_TO_DEV) dev_dbg(d40c->base->dev, "channel was not configured for memory " "to peripheral transfer (%d) overriding\n", cfg->dir); - cfg->dir = STEDMA40_MEM_TO_PERIPH; + cfg->dir = DMA_MEM_TO_DEV; /* Configure the memory side */ if (src_addr_width == DMA_SLAVE_BUSWIDTH_UNDEFINED) diff --git a/drivers/dma/ste_dma40_ll.c b/drivers/dma/ste_dma40_ll.c index ab5a2a7..121c0ce 100644 --- a/drivers/dma/ste_dma40_ll.c +++ b/drivers/dma/ste_dma40_ll.c @@ -18,23 +18,23 @@ void d40_log_cfg(struct stedma40_chan_cfg *cfg, u32 l1 = 0; /* src */ /* src is mem? -> increase address pos */ - if (cfg->dir == STEDMA40_MEM_TO_PERIPH || - cfg->dir == STEDMA40_MEM_TO_MEM) + if (cfg->dir == DMA_MEM_TO_DEV || + cfg->dir == DMA_MEM_TO_MEM) l1 |= 1 << D40_MEM_LCSP1_SCFG_INCR_POS; /* dst is mem? -> increase address pos */ - if (cfg->dir == STEDMA40_PERIPH_TO_MEM || - cfg->dir == STEDMA40_MEM_TO_MEM) + if (cfg->dir == DMA_DEV_TO_MEM || + cfg->dir == DMA_MEM_TO_MEM) l3 |= 1 << D40_MEM_LCSP3_DCFG_INCR_POS; /* src is hw? -> master port 1 */ - if (cfg->dir == STEDMA40_PERIPH_TO_MEM || - cfg->dir == STEDMA40_PERIPH_TO_PERIPH) + if (cfg->dir == DMA_DEV_TO_MEM || + cfg->dir == DMA_DEV_TO_DEV) l1 |= 1 << D40_MEM_LCSP1_SCFG_MST_POS; /* dst is hw? -> master port 1 */ - if (cfg->dir == STEDMA40_MEM_TO_PERIPH || - cfg->dir == STEDMA40_PERIPH_TO_PERIPH) + if (cfg->dir == DMA_MEM_TO_DEV || + cfg->dir == DMA_DEV_TO_DEV) l3 |= 1 << D40_MEM_LCSP3_DCFG_MST_POS; l3 |= 1 << D40_MEM_LCSP3_DCFG_EIM_POS; @@ -55,8 +55,8 @@ void d40_phy_cfg(struct stedma40_chan_cfg *cfg, u32 *src_cfg, u32 *dst_cfg) u32 src = 0; u32 dst = 0; - if ((cfg->dir == STEDMA40_PERIPH_TO_MEM) || - (cfg->dir == STEDMA40_PERIPH_TO_PERIPH)) { + if ((cfg->dir == DMA_DEV_TO_MEM) || + (cfg->dir == DMA_DEV_TO_DEV)) { /* Set master port to 1 */ src |= 1 << D40_SREG_CFG_MST_POS; src |= D40_TYPE_TO_EVENT(cfg->dev_type); @@ -66,8 +66,8 @@ void d40_phy_cfg(struct stedma40_chan_cfg *cfg, u32 *src_cfg, u32 *dst_cfg) else src |= 3 << D40_SREG_CFG_PHY_TM_POS; } - if ((cfg->dir == STEDMA40_MEM_TO_PERIPH) || - (cfg->dir == STEDMA40_PERIPH_TO_PERIPH)) { + if ((cfg->dir == DMA_MEM_TO_DEV) || + (cfg->dir == DMA_DEV_TO_DEV)) { /* Set master port to 1 */ dst |= 1 << D40_SREG_CFG_MST_POS; dst |= D40_TYPE_TO_EVENT(cfg->dev_type); -- cgit v0.10.2 From e7bab58b73a653d4c226b11ead07fd30ffaea914 Mon Sep 17 00:00:00 2001 From: Lee Jones Date: Wed, 15 May 2013 10:51:55 +0100 Subject: ARM: ux500: Remove recently unused stedma40_xfer_dir enums We're now using the transfer direction definitions provided by the DMA sub-system, so the home-brew ones have become obsolete. Signed-off-by: Lee Jones Signed-off-by: Linus Walleij diff --git a/include/linux/platform_data/dma-ste-dma40.h b/include/linux/platform_data/dma-ste-dma40.h index 288dc24..54ddca6 100644 --- a/include/linux/platform_data/dma-ste-dma40.h +++ b/include/linux/platform_data/dma-ste-dma40.h @@ -77,14 +77,6 @@ enum stedma40_periph_data_width { STEDMA40_DOUBLEWORD_WIDTH = STEDMA40_ESIZE_64_BIT }; -enum stedma40_xfer_dir { - STEDMA40_MEM_TO_MEM = 1, - STEDMA40_MEM_TO_PERIPH, - STEDMA40_PERIPH_TO_MEM, - STEDMA40_PERIPH_TO_PERIPH -}; - - /** * struct stedma40_half_channel_info - dst/src channel configuration * @@ -120,7 +112,7 @@ struct stedma40_half_channel_info { * */ struct stedma40_chan_cfg { - enum stedma40_xfer_dir dir; + enum dma_transfer_direction dir; bool high_priority; bool realtime; enum stedma40_mode mode; -- cgit v0.10.2 From 16db3411ebd4777b0b1b7207b10730b726fb751c Mon Sep 17 00:00:00 2001 From: Lee Jones Date: Wed, 15 May 2013 10:51:56 +0100 Subject: dmaengine: ste_dma40_ll: Use the BIT macro to replace ugly '(1 << x)'s The aim is to make the code that little more readable. Cc: Dan Williams Cc: Per Forlin Cc: Rabin Vincent Acked-by: Vinod Koul Signed-off-by: Lee Jones Signed-off-by: Linus Walleij diff --git a/drivers/dma/ste_dma40_ll.c b/drivers/dma/ste_dma40_ll.c index 121c0ce..5ddd724 100644 --- a/drivers/dma/ste_dma40_ll.c +++ b/drivers/dma/ste_dma40_ll.c @@ -20,28 +20,28 @@ void d40_log_cfg(struct stedma40_chan_cfg *cfg, /* src is mem? -> increase address pos */ if (cfg->dir == DMA_MEM_TO_DEV || cfg->dir == DMA_MEM_TO_MEM) - l1 |= 1 << D40_MEM_LCSP1_SCFG_INCR_POS; + l1 |= BIT(D40_MEM_LCSP1_SCFG_INCR_POS); /* dst is mem? -> increase address pos */ if (cfg->dir == DMA_DEV_TO_MEM || cfg->dir == DMA_MEM_TO_MEM) - l3 |= 1 << D40_MEM_LCSP3_DCFG_INCR_POS; + l3 |= BIT(D40_MEM_LCSP3_DCFG_INCR_POS); /* src is hw? -> master port 1 */ if (cfg->dir == DMA_DEV_TO_MEM || cfg->dir == DMA_DEV_TO_DEV) - l1 |= 1 << D40_MEM_LCSP1_SCFG_MST_POS; + l1 |= BIT(D40_MEM_LCSP1_SCFG_MST_POS); /* dst is hw? -> master port 1 */ if (cfg->dir == DMA_MEM_TO_DEV || cfg->dir == DMA_DEV_TO_DEV) - l3 |= 1 << D40_MEM_LCSP3_DCFG_MST_POS; + l3 |= BIT(D40_MEM_LCSP3_DCFG_MST_POS); - l3 |= 1 << D40_MEM_LCSP3_DCFG_EIM_POS; + l3 |= BIT(D40_MEM_LCSP3_DCFG_EIM_POS); l3 |= cfg->dst_info.psize << D40_MEM_LCSP3_DCFG_PSIZE_POS; l3 |= cfg->dst_info.data_width << D40_MEM_LCSP3_DCFG_ESIZE_POS; - l1 |= 1 << D40_MEM_LCSP1_SCFG_EIM_POS; + l1 |= BIT(D40_MEM_LCSP1_SCFG_EIM_POS); l1 |= cfg->src_info.psize << D40_MEM_LCSP1_SCFG_PSIZE_POS; l1 |= cfg->src_info.data_width << D40_MEM_LCSP1_SCFG_ESIZE_POS; @@ -58,39 +58,39 @@ void d40_phy_cfg(struct stedma40_chan_cfg *cfg, u32 *src_cfg, u32 *dst_cfg) if ((cfg->dir == DMA_DEV_TO_MEM) || (cfg->dir == DMA_DEV_TO_DEV)) { /* Set master port to 1 */ - src |= 1 << D40_SREG_CFG_MST_POS; + src |= BIT(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; + src |= BIT(D40_SREG_CFG_PHY_TM_POS); else src |= 3 << D40_SREG_CFG_PHY_TM_POS; } if ((cfg->dir == DMA_MEM_TO_DEV) || (cfg->dir == DMA_DEV_TO_DEV)) { /* Set master port to 1 */ - dst |= 1 << D40_SREG_CFG_MST_POS; + dst |= BIT(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; + dst |= BIT(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; + dst |= BIT(D40_SREG_CFG_TIM_POS); /* Generate interrupt on error */ - src |= 1 << D40_SREG_CFG_EIM_POS; - dst |= 1 << D40_SREG_CFG_EIM_POS; + src |= BIT(D40_SREG_CFG_EIM_POS); + dst |= BIT(D40_SREG_CFG_EIM_POS); /* PSIZE */ if (cfg->src_info.psize != STEDMA40_PSIZE_PHY_1) { - src |= 1 << D40_SREG_CFG_PHY_PEN_POS; + src |= BIT(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 |= BIT(D40_SREG_CFG_PHY_PEN_POS); dst |= cfg->dst_info.psize << D40_SREG_CFG_PSIZE_POS; } @@ -100,14 +100,14 @@ void d40_phy_cfg(struct stedma40_chan_cfg *cfg, u32 *src_cfg, u32 *dst_cfg) /* 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; + src |= BIT(D40_SREG_CFG_PRI_POS); + dst |= BIT(D40_SREG_CFG_PRI_POS); } if (cfg->src_info.big_endian) - src |= 1 << D40_SREG_CFG_LBE_POS; + src |= BIT(D40_SREG_CFG_LBE_POS); if (cfg->dst_info.big_endian) - dst |= 1 << D40_SREG_CFG_LBE_POS; + dst |= BIT(D40_SREG_CFG_LBE_POS); *src_cfg = src; *dst_cfg = dst; @@ -157,15 +157,15 @@ static int d40_phy_fill_lli(struct d40_phy_lli *lli, /* If this scatter list entry is the last one, no next link */ if (next_lli == 0) - lli->reg_lnk = 0x1 << D40_SREG_LNK_PHY_TCP_POS; + lli->reg_lnk = BIT(D40_SREG_LNK_PHY_TCP_POS); else lli->reg_lnk = next_lli; /* Set/clear interrupt generation on this link item.*/ if (term_int) - lli->reg_cfg |= 0x1 << D40_SREG_CFG_TIM_POS; + lli->reg_cfg |= BIT(D40_SREG_CFG_TIM_POS); else - lli->reg_cfg &= ~(0x1 << D40_SREG_CFG_TIM_POS); + lli->reg_cfg &= ~BIT(D40_SREG_CFG_TIM_POS); /* Post link */ lli->reg_lnk |= 0 << D40_SREG_LNK_PHY_PRE_POS; -- cgit v0.10.2 From 43f2e1a3be5d83004f09bcb53c46f273e7473a00 Mon Sep 17 00:00:00 2001 From: Lee Jones Date: Wed, 15 May 2013 11:51:57 +0200 Subject: dmaengine: ste_dma40: Convert data_width from register bit format to value When a DMA client requests and configures a DMA channel, it requests data_width in Bytes. The DMA40 driver then swiftly converts it over to the necessary register bit value. Unfortunately, for any subsequent calculations we have to shift '1' by the bit pattern (1 << data_width) times to make any sense of it. This patch flips the semantics on its head and only converts the value to its respective register bit pattern when writing to registers. This way we can use the true data_width (in Bytes) value. Cc: Dan Williams Cc: Per Forlin Cc: Rabin Vincent Acked-by: Vinod Koul Signed-off-by: Lee Jones Signed-off-by: Linus Walleij diff --git a/drivers/dma/ste_dma40.c b/drivers/dma/ste_dma40.c index 483da16..76c255f 100644 --- a/drivers/dma/ste_dma40.c +++ b/drivers/dma/ste_dma40.c @@ -80,11 +80,11 @@ struct stedma40_chan_cfg dma40_memcpy_conf_phy = { .mode = STEDMA40_MODE_PHYSICAL, .dir = DMA_MEM_TO_MEM, - .src_info.data_width = STEDMA40_BYTE_WIDTH, + .src_info.data_width = DMA_SLAVE_BUSWIDTH_1_BYTE, .src_info.psize = STEDMA40_PSIZE_PHY_1, .src_info.flow_ctrl = STEDMA40_NO_FLOW_CTRL, - .dst_info.data_width = STEDMA40_BYTE_WIDTH, + .dst_info.data_width = DMA_SLAVE_BUSWIDTH_1_BYTE, .dst_info.psize = STEDMA40_PSIZE_PHY_1, .dst_info.flow_ctrl = STEDMA40_NO_FLOW_CTRL, }; @@ -94,11 +94,11 @@ struct stedma40_chan_cfg dma40_memcpy_conf_log = { .mode = STEDMA40_MODE_LOGICAL, .dir = DMA_MEM_TO_MEM, - .src_info.data_width = STEDMA40_BYTE_WIDTH, + .src_info.data_width = DMA_SLAVE_BUSWIDTH_1_BYTE, .src_info.psize = STEDMA40_PSIZE_LOG_1, .src_info.flow_ctrl = STEDMA40_NO_FLOW_CTRL, - .dst_info.data_width = STEDMA40_BYTE_WIDTH, + .dst_info.data_width = DMA_SLAVE_BUSWIDTH_1_BYTE, .dst_info.psize = STEDMA40_PSIZE_LOG_1, .dst_info.flow_ctrl = STEDMA40_NO_FLOW_CTRL, }; @@ -1005,20 +1005,21 @@ static int d40_psize_2_burst_size(bool is_log, int psize) /* * The dma only supports transmitting packages up to - * STEDMA40_MAX_SEG_SIZE << data_width. Calculate the total number of - * dma elements required to send the entire sg list + * STEDMA40_MAX_SEG_SIZE * data_width, where data_width is stored in Bytes. + * + * Calculate the total number of dma elements required to send the entire sg list. */ 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, max_w); if (seg_max > STEDMA40_MAX_SEG_SIZE) - seg_max -= (1 << max_w); + seg_max -= max_w; - if (!IS_ALIGNED(size, 1 << max_w)) + if (!IS_ALIGNED(size, max_w)) return -EINVAL; if (size <= seg_max) @@ -1464,7 +1465,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 * d40c->dma_cfg.dst_info.data_width; } static bool d40_tx_is_linked(struct d40_chan *d40c) @@ -1784,9 +1785,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) != + conf->src_info.data_width != d40_psize_2_burst_size(is_log, conf->dst_info.psize) * - (1 << conf->dst_info.data_width)) { + conf->dst_info.data_width) { /* * The DMAC hardware only supports * src (burst x width) == dst (burst x width) @@ -2673,33 +2674,10 @@ static void d40_terminate_all(struct dma_chan *chan) static int dma40_config_to_halfchannel(struct d40_chan *d40c, struct stedma40_half_channel_info *info, - enum dma_slave_buswidth width, u32 maxburst) { - enum stedma40_periph_data_width addr_width; int psize; - switch (width) { - case DMA_SLAVE_BUSWIDTH_1_BYTE: - addr_width = STEDMA40_BYTE_WIDTH; - break; - case DMA_SLAVE_BUSWIDTH_2_BYTES: - addr_width = STEDMA40_HALFWORD_WIDTH; - break; - case DMA_SLAVE_BUSWIDTH_4_BYTES: - addr_width = STEDMA40_WORD_WIDTH; - break; - case DMA_SLAVE_BUSWIDTH_8_BYTES: - addr_width = STEDMA40_DOUBLEWORD_WIDTH; - break; - default: - dev_err(d40c->base->dev, - "illegal peripheral address width " - "requested (%d)\n", - width); - return -EINVAL; - } - if (chan_is_logical(d40c)) { if (maxburst >= 16) psize = STEDMA40_PSIZE_LOG_16; @@ -2720,7 +2698,6 @@ dma40_config_to_halfchannel(struct d40_chan *d40c, psize = STEDMA40_PSIZE_PHY_1; } - info->data_width = addr_width; info->psize = psize; info->flow_ctrl = STEDMA40_NO_FLOW_CTRL; @@ -2804,14 +2781,24 @@ static int d40_set_runtime_config(struct dma_chan *chan, src_maxburst = dst_maxburst * dst_addr_width / src_addr_width; } + /* Only valid widths are; 1, 2, 4 and 8. */ + if (src_addr_width <= DMA_SLAVE_BUSWIDTH_UNDEFINED || + src_addr_width > DMA_SLAVE_BUSWIDTH_8_BYTES || + dst_addr_width <= DMA_SLAVE_BUSWIDTH_UNDEFINED || + dst_addr_width > DMA_SLAVE_BUSWIDTH_8_BYTES || + ((src_addr_width > 1) && (src_addr_width & 1)) || + ((dst_addr_width > 1) && (dst_addr_width & 1))) + return -EINVAL; + + cfg->src_info.data_width = src_addr_width; + cfg->dst_info.data_width = dst_addr_width; + ret = dma40_config_to_halfchannel(d40c, &cfg->src_info, - src_addr_width, src_maxburst); if (ret) return ret; ret = dma40_config_to_halfchannel(d40c, &cfg->dst_info, - dst_addr_width, dst_maxburst); if (ret) return ret; diff --git a/drivers/dma/ste_dma40_ll.c b/drivers/dma/ste_dma40_ll.c index 5ddd724..a035dfe 100644 --- a/drivers/dma/ste_dma40_ll.c +++ b/drivers/dma/ste_dma40_ll.c @@ -10,6 +10,18 @@ #include "ste_dma40_ll.h" +u8 d40_width_to_bits(enum dma_slave_buswidth width) +{ + if (width == DMA_SLAVE_BUSWIDTH_1_BYTE) + return STEDMA40_ESIZE_8_BIT; + else if (width == DMA_SLAVE_BUSWIDTH_2_BYTES) + return STEDMA40_ESIZE_16_BIT; + else if (width == DMA_SLAVE_BUSWIDTH_8_BYTES) + return STEDMA40_ESIZE_64_BIT; + else + return STEDMA40_ESIZE_32_BIT; +} + /* Sets up proper LCSP1 and LCSP3 register for a logical channel */ void d40_log_cfg(struct stedma40_chan_cfg *cfg, u32 *lcsp1, u32 *lcsp3) @@ -39,11 +51,13 @@ void d40_log_cfg(struct stedma40_chan_cfg *cfg, l3 |= BIT(D40_MEM_LCSP3_DCFG_EIM_POS); l3 |= cfg->dst_info.psize << D40_MEM_LCSP3_DCFG_PSIZE_POS; - l3 |= cfg->dst_info.data_width << D40_MEM_LCSP3_DCFG_ESIZE_POS; + l3 |= d40_width_to_bits(cfg->dst_info.data_width) + << D40_MEM_LCSP3_DCFG_ESIZE_POS; l1 |= BIT(D40_MEM_LCSP1_SCFG_EIM_POS); l1 |= cfg->src_info.psize << D40_MEM_LCSP1_SCFG_PSIZE_POS; - l1 |= cfg->src_info.data_width << D40_MEM_LCSP1_SCFG_ESIZE_POS; + l1 |= d40_width_to_bits(cfg->src_info.data_width) + << D40_MEM_LCSP1_SCFG_ESIZE_POS; *lcsp1 = l1; *lcsp3 = l3; @@ -95,8 +109,10 @@ void d40_phy_cfg(struct stedma40_chan_cfg *cfg, u32 *src_cfg, u32 *dst_cfg) } /* Element size */ - src |= cfg->src_info.data_width << D40_SREG_CFG_ESIZE_POS; - dst |= cfg->dst_info.data_width << D40_SREG_CFG_ESIZE_POS; + src |= d40_width_to_bits(cfg->src_info.data_width) + << D40_SREG_CFG_ESIZE_POS; + dst |= d40_width_to_bits(cfg->dst_info.data_width) + << D40_SREG_CFG_ESIZE_POS; /* Set the priority bit to high for the physical channel */ if (cfg->high_priority) { @@ -133,23 +149,22 @@ static int d40_phy_fill_lli(struct d40_phy_lli *lli, num_elems = 2 << psize; /* Must be aligned */ - if (!IS_ALIGNED(data, 0x1 << data_width)) + if (!IS_ALIGNED(data, data_width)) return -EINVAL; /* Transfer size can't be smaller than (num_elms * elem_size) */ - if (data_size < num_elems * (0x1 << data_width)) + if (data_size < num_elems * data_width) return -EINVAL; /* The number of elements. IE now many chunks */ - lli->reg_elt = (data_size >> data_width) << D40_SREG_ELEM_PHY_ECNT_POS; + lli->reg_elt = (data_size / data_width) << D40_SREG_ELEM_PHY_ECNT_POS; /* * Distance to next element sized entry. * Usually the size of the element unless you want gaps. */ if (addr_inc) - lli->reg_elt |= (0x1 << data_width) << - D40_SREG_ELEM_PHY_EIDX_POS; + lli->reg_elt |= data_width << D40_SREG_ELEM_PHY_EIDX_POS; /* Where the data is */ lli->reg_ptr = data; @@ -177,16 +192,16 @@ static int d40_seg_size(int size, int data_width1, int data_width2) { 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, max_w); if (seg_max > STEDMA40_MAX_SEG_SIZE) - seg_max -= (1 << max_w); + seg_max -= max_w; if (size <= seg_max) return size; if (size <= 2 * seg_max) - return ALIGN(size / 2, 1 << max_w); + return ALIGN(size / 2, max_w); return seg_max; } @@ -352,10 +367,10 @@ static void d40_log_fill_lli(struct d40_log_lli *lli, lli->lcsp13 = reg_cfg; /* The number of elements to transfer */ - lli->lcsp02 = ((data_size >> data_width) << + lli->lcsp02 = ((data_size / data_width) << D40_MEM_LCSP0_ECNT_POS) & D40_MEM_LCSP0_ECNT_MASK; - BUG_ON((data_size >> data_width) > STEDMA40_MAX_SEG_SIZE); + BUG_ON((data_size / data_width) > STEDMA40_MAX_SEG_SIZE); /* 16 LSBs address of the current element */ lli->lcsp02 |= data & D40_MEM_LCSP0_SPTR_MASK; diff --git a/include/linux/platform_data/dma-ste-dma40.h b/include/linux/platform_data/dma-ste-dma40.h index 54ddca6..ceba6dc 100644 --- a/include/linux/platform_data/dma-ste-dma40.h +++ b/include/linux/platform_data/dma-ste-dma40.h @@ -70,13 +70,6 @@ enum stedma40_flow_ctrl { STEDMA40_FLOW_CTRL, }; -enum stedma40_periph_data_width { - STEDMA40_BYTE_WIDTH = STEDMA40_ESIZE_8_BIT, - STEDMA40_HALFWORD_WIDTH = STEDMA40_ESIZE_16_BIT, - STEDMA40_WORD_WIDTH = STEDMA40_ESIZE_32_BIT, - STEDMA40_DOUBLEWORD_WIDTH = STEDMA40_ESIZE_64_BIT -}; - /** * struct stedma40_half_channel_info - dst/src channel configuration * @@ -87,7 +80,7 @@ enum stedma40_periph_data_width { */ struct stedma40_half_channel_info { bool big_endian; - enum stedma40_periph_data_width data_width; + enum dma_slave_buswidth data_width; int psize; enum stedma40_flow_ctrl flow_ctrl; }; diff --git a/sound/soc/ux500/ux500_pcm.c b/sound/soc/ux500/ux500_pcm.c index b6e5ae2..31f9bbc 100644 --- a/sound/soc/ux500/ux500_pcm.c +++ b/sound/soc/ux500/ux500_pcm.c @@ -76,20 +76,20 @@ static struct dma_chan *ux500_pcm_request_chan(struct snd_soc_pcm_runtime *rtd, dma_params = snd_soc_dai_get_dma_data(dai, substream); dma_cfg = dma_params->dma_cfg; - mem_data_width = STEDMA40_HALFWORD_WIDTH; + mem_data_width = DMA_SLAVE_BUSWIDTH_2_BYTES; switch (dma_params->data_size) { case 32: - per_data_width = STEDMA40_WORD_WIDTH; + per_data_width = DMA_SLAVE_BUSWIDTH_4_BYTES; break; case 16: - per_data_width = STEDMA40_HALFWORD_WIDTH; + per_data_width = DMA_SLAVE_BUSWIDTH_2_BYTES; break; case 8: - per_data_width = STEDMA40_BYTE_WIDTH; + per_data_width = DMA_SLAVE_BUSWIDTH_1_BYTE; break; default: - per_data_width = STEDMA40_WORD_WIDTH; + per_data_width = DMA_SLAVE_BUSWIDTH_4_BYTES; } if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { -- cgit v0.10.2 From 8cc5af1255966ed82117249a64fe8b13edabc8c5 Mon Sep 17 00:00:00 2001 From: Lee Jones Date: Wed, 15 May 2013 10:51:58 +0100 Subject: dmaengine: ste_dma40_ll: Replace meaningless register set with comment Unsure of the author's intentions, rather than just removing the nop, we're replacing it with a comment containing the possible intention of the statement OR:ing with 0. Cc: Dan Williams Cc: Per Forlin Cc: Rabin Vincent Acked-by: Vinod Koul Signed-off-by: Lee Jones Signed-off-by: Linus Walleij diff --git a/drivers/dma/ste_dma40_ll.c b/drivers/dma/ste_dma40_ll.c index a035dfe..27b818d 100644 --- a/drivers/dma/ste_dma40_ll.c +++ b/drivers/dma/ste_dma40_ll.c @@ -182,8 +182,10 @@ static int d40_phy_fill_lli(struct d40_phy_lli *lli, else lli->reg_cfg &= ~BIT(D40_SREG_CFG_TIM_POS); - /* Post link */ - lli->reg_lnk |= 0 << D40_SREG_LNK_PHY_PRE_POS; + /* + * Post link - D40_SREG_LNK_PHY_PRE_POS = 0 + * Relink happens after transfer completion. + */ return 0; } -- cgit v0.10.2 From a7dacb68b35a193d9bdaabde1e4e98140d81a991 Mon Sep 17 00:00:00 2001 From: Lee Jones Date: Wed, 15 May 2013 10:51:59 +0100 Subject: dmaengine: ste_dma40: Allow memcpy channels to be configured from DT At this moment in time the memcpy channels which can be used by the D40 are fixed, as each supported platform in Mainline uses the same ones. However, platforms do exist which don't follow this convention, so these will need to be tailored. Fortunately, these platforms will be DT only, so this change has very little impact on platform data. Cc: Dan Williams Cc: Per Forlin Cc: Rabin Vincent Acked-by: Vinod Koul Acked-by: Arnd Bergmann Signed-off-by: Lee Jones Signed-off-by: Linus Walleij diff --git a/Documentation/devicetree/bindings/dma/ste-dma40.txt b/Documentation/devicetree/bindings/dma/ste-dma40.txt index 2679a87..aa272d8 100644 --- a/Documentation/devicetree/bindings/dma/ste-dma40.txt +++ b/Documentation/devicetree/bindings/dma/ste-dma40.txt @@ -6,6 +6,7 @@ Required properties: - 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> +- memcpy-channels: Channels to be used for memcpy Optional properties: - dma-channels: Number of channels supported by hardware - if not present @@ -21,6 +22,7 @@ Example: interrupts = <0 25 0x4>; #dma-cells = <2>; + memcpy-channels = <56 57 58 59 60>; dma-channels = <8>; }; diff --git a/drivers/dma/ste_dma40.c b/drivers/dma/ste_dma40.c index 76c255f..ae462d3 100644 --- a/drivers/dma/ste_dma40.c +++ b/drivers/dma/ste_dma40.c @@ -58,6 +58,8 @@ #define D40_ALLOC_PHY BIT(30) #define D40_ALLOC_LOG_FREE 0 +#define D40_MEMCPY_MAX_CHANS 8 + /* Reserved event lines for memcpy only. */ #define DB8500_DMA_MEMCPY_EV_0 51 #define DB8500_DMA_MEMCPY_EV_1 56 @@ -522,6 +524,8 @@ struct d40_gen_dmac { * @phy_start: Physical memory start of the DMA registers. * @phy_size: Size of the DMA register map. * @irq: The IRQ number. + * @num_memcpy_chans: The number of channels used for memcpy (mem-to-mem + * transfers). * @num_phy_chans: The number of physical channels. Read from HW. This * is the number of available channels for this driver, not counting "Secure * mode" allocated physical channels. @@ -565,6 +569,7 @@ struct d40_base { phys_addr_t phy_start; resource_size_t phy_size; int irq; + int num_memcpy_chans; int num_phy_chans; int num_log_chans; struct device_dma_parameters dma_parms; @@ -2938,7 +2943,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, ARRAY_SIZE(dma40_memcpy_channels)); + base->num_log_chans, base->num_memcpy_chans); dma_cap_zero(base->dma_memcpy.cap_mask); dma_cap_set(DMA_MEMCPY, base->dma_memcpy.cap_mask); @@ -3139,6 +3144,7 @@ static struct d40_base * __init d40_hw_detect_init(struct platform_device *pdev) struct d40_base *base = NULL; int num_log_chans = 0; int num_phy_chans; + int num_memcpy_chans; int clk_ret = -EINVAL; int i; u32 pid; @@ -3209,6 +3215,12 @@ 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; + /* The number of channels used for memcpy */ + if (plat_data->num_of_memcpy_chans) + num_memcpy_chans = plat_data->num_of_memcpy_chans; + else + num_memcpy_chans = ARRAY_SIZE(dma40_memcpy_channels); + num_log_chans = num_phy_chans * D40_MAX_LOG_CHAN_PER_PHY; dev_info(&pdev->dev, @@ -3216,7 +3228,7 @@ static struct d40_base * __init d40_hw_detect_init(struct platform_device *pdev) 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)) * + (num_phy_chans + num_log_chans + num_memcpy_chans) * sizeof(struct d40_chan), GFP_KERNEL); if (base == NULL) { @@ -3226,6 +3238,7 @@ static struct d40_base * __init d40_hw_detect_init(struct platform_device *pdev) base->rev = rev; base->clk = clk; + base->num_memcpy_chans = num_memcpy_chans; base->num_phy_chans = num_phy_chans; base->num_log_chans = num_log_chans; base->phy_start = res->start; @@ -3469,12 +3482,8 @@ 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. - */ + int num_memcpy = 0; + const const __be32 *list; pdata = devm_kzalloc(&pdev->dev, sizeof(struct stedma40_platform_data), @@ -3482,6 +3491,21 @@ static int __init d40_of_probe(struct platform_device *pdev, if (!pdata) return -ENOMEM; + list = of_get_property(np, "memcpy-channels", &num_memcpy); + num_memcpy /= sizeof(*list); + + if (num_memcpy > D40_MEMCPY_MAX_CHANS || num_memcpy <= 0) { + d40_err(&pdev->dev, + "Invalid number of memcpy channels specified (%d)\n", + num_memcpy); + return -EINVAL; + } + pdata->num_of_memcpy_chans = num_memcpy; + + of_property_read_u32_array(np, "memcpy-channels", + dma40_memcpy_channels, + num_memcpy); + pdev->dev.platform_data = pdata; return 0; diff --git a/include/linux/platform_data/dma-ste-dma40.h b/include/linux/platform_data/dma-ste-dma40.h index ceba6dc..1bb9b18 100644 --- a/include/linux/platform_data/dma-ste-dma40.h +++ b/include/linux/platform_data/dma-ste-dma40.h @@ -132,6 +132,7 @@ struct stedma40_chan_cfg { * @num_of_soft_lli_chans: The number of channels that needs to be configured * to use SoftLLI. * @use_esram_lcla: flag for mapping the lcla into esram region + * @num_of_memcpy_chans: The number of channels reserved for memcpy. * @num_of_phy_chans: The number of physical channels implemented in HW. * 0 means reading the number of channels from DMA HW but this is only valid * for 'multiple of 4' channels, like 8. @@ -141,6 +142,7 @@ struct stedma40_platform_data { int *soft_lli_chans; int num_of_soft_lli_chans; bool use_esram_lcla; + int num_of_memcpy_chans; int num_of_phy_chans; }; -- cgit v0.10.2 From 0117f7c7a3e8cdf72bea7d463b142db35e9c9cdc Mon Sep 17 00:00:00 2001 From: Lee Jones Date: Wed, 15 May 2013 10:52:00 +0100 Subject: ARM: ux500: Stop passing DMA platform data though AUXDATA The DMA platform data is now empty due to some recent refactoring, so there is no longer a requirement to pass it though. Acked-by: Arnd Bergmann Signed-off-by: Lee Jones Signed-off-by: Linus Walleij diff --git a/arch/arm/mach-ux500/cpu-db8500.c b/arch/arm/mach-ux500/cpu-db8500.c index 6e49e4f..a40afd9 100644 --- a/arch/arm/mach-ux500/cpu-db8500.c +++ b/arch/arm/mach-ux500/cpu-db8500.c @@ -260,8 +260,7 @@ static struct of_dev_auxdata u8500_auxdata_lookup[] __initdata = { OF_DEV_AUXDATA("stericsson,ux500-msp-i2s", 0x80125000, "ux500-msp-i2s.3", &msp3_platform_data), /* Requires clock name bindings and channel address lookup table. */ - OF_DEV_AUXDATA("stericsson,db8500-dma40", 0x801C0000, - "dma40.0", &dma40_plat_data), + OF_DEV_AUXDATA("stericsson,db8500-dma40", 0x801C0000, "dma40.0", NULL), {}, }; -- cgit v0.10.2 From fd59f9e6abf2ebf0098c616e1742168db4360d13 Mon Sep 17 00:00:00 2001 From: Lee Jones Date: Wed, 15 May 2013 10:52:01 +0100 Subject: dmaengine: ste_dma40: Fetch the number of physical channels from DT Some platforms insist on obscure physical channel availability. This information is currently passed though platform data in internal BSP kernels. Once those platforms land, they'll need to configure them appropriately, so we may as well add the infrastructure. Cc: Dan Williams Cc: Per Forlin Cc: Rabin Vincent Acked-by: Vinod Koul Signed-off-by: Lee Jones Signed-off-by: Linus Walleij diff --git a/drivers/dma/ste_dma40.c b/drivers/dma/ste_dma40.c index ae462d3..4e528dd 100644 --- a/drivers/dma/ste_dma40.c +++ b/drivers/dma/ste_dma40.c @@ -3482,7 +3482,7 @@ static int __init d40_of_probe(struct platform_device *pdev, struct device_node *np) { struct stedma40_platform_data *pdata; - int num_memcpy = 0; + int num_phy = 0, num_memcpy = 0; const const __be32 *list; pdata = devm_kzalloc(&pdev->dev, @@ -3491,6 +3491,11 @@ static int __init d40_of_probe(struct platform_device *pdev, if (!pdata) return -ENOMEM; + /* If absent this value will be obtained from h/w. */ + of_property_read_u32(np, "dma-channels", &num_phy); + if (num_phy > 0) + pdata->num_of_phy_chans = num_phy; + list = of_get_property(np, "memcpy-channels", &num_memcpy); num_memcpy /= sizeof(*list); -- cgit v0.10.2 From 499c2bc3cc89dcbbf08aa526cd4a984b92a4d2a8 Mon Sep 17 00:00:00 2001 From: Lee Jones Date: Wed, 15 May 2013 10:52:02 +0100 Subject: dmaengine: ste_dma40: Fetch disabled channels from DT Some platforms have channels which are not available for normal use. This information is currently passed though platform data in internal BSP kernels. Once those platforms land, they'll need to configure them appropriately, so we may as well add the infrastructure. Cc: Dan Williams Cc: Per Forlin Cc: Rabin Vincent Acked-by: Vinod Koul Acked-by: Arnd Bergmann Signed-off-by: Lee Jones Signed-off-by: Linus Walleij diff --git a/Documentation/devicetree/bindings/dma/ste-dma40.txt b/Documentation/devicetree/bindings/dma/ste-dma40.txt index aa272d8..bea5b73 100644 --- a/Documentation/devicetree/bindings/dma/ste-dma40.txt +++ b/Documentation/devicetree/bindings/dma/ste-dma40.txt @@ -11,6 +11,7 @@ Required properties: Optional properties: - dma-channels: Number of channels supported by hardware - if not present the driver will attempt to obtain the information from H/W +- disabled-channels: Channels which can not be used Example: @@ -23,6 +24,7 @@ Example: #dma-cells = <2>; memcpy-channels = <56 57 58 59 60>; + disabled-channels = <12>; dma-channels = <8>; }; diff --git a/drivers/dma/ste_dma40.c b/drivers/dma/ste_dma40.c index 4e528dd..ffac822 100644 --- a/drivers/dma/ste_dma40.c +++ b/drivers/dma/ste_dma40.c @@ -3482,7 +3482,7 @@ static int __init d40_of_probe(struct platform_device *pdev, struct device_node *np) { struct stedma40_platform_data *pdata; - int num_phy = 0, num_memcpy = 0; + int num_phy = 0, num_memcpy = 0, num_disabled = 0; const const __be32 *list; pdata = devm_kzalloc(&pdev->dev, @@ -3511,6 +3511,21 @@ static int __init d40_of_probe(struct platform_device *pdev, dma40_memcpy_channels, num_memcpy); + list = of_get_property(np, "disabled-channels", &num_disabled); + num_disabled /= sizeof(*list); + + if (num_disabled > STEDMA40_MAX_PHYS || num_disabled < 0) { + d40_err(&pdev->dev, + "Invalid number of disabled channels specified (%d)\n", + num_disabled); + return -EINVAL; + } + + of_property_read_u32_array(np, "disabled-channels", + pdata->disabled_channels, + num_disabled); + pdata->disabled_channels[num_disabled] = -1; + pdev->dev.platform_data = pdata; return 0; -- cgit v0.10.2