Commit c8ebae37 authored by Russell King's avatar Russell King

ARM: mmci: add dmaengine-based DMA support

Based on a patch from Linus Walleij.

Add dmaengine based support for DMA to the MMCI driver, using the
Primecell DMA engine interface.  The changes over Linus' driver are:

- rename txsize_threshold to dmasize_threshold, as this reflects the
  purpose more.
- use 'mmci_dma_' as the function prefix rather than 'dma_mmci_'.
- clean up requesting of dma channels.
- don't release a single channel twice when it's shared between tx and rx.
- get rid of 'dma_enable' bool - instead check whether the channel is NULL.
- detect incomplete DMA at the end of a transfer.  Some DMA controllers
  (eg, PL08x) are unable to be configured for scatter DMA and also listen
  to all four DMA request signals [BREQ,SREQ,LBREQ,LSREQ] from the MMCI.
  They can do one or other but not both.  As MMCI uses LBREQ/LSREQ for the
  final burst/words, PL08x does not transfer the last few words.
- map and unmap DMA buffers using the DMA engine struct device, not the
  MMCI struct device - the DMA engine is doing the DMA transfer, not us.
- avoid double-unmapping of the DMA buffers on MMCI data errors.
- don't check for negative values from the dmaengine tx submission
  function - Dan says this must never fail.
- use new dmaengine helper functions rather than using the ugly function
  pointers directly.
- allow DMA code to be fully optimized away using dma_inprogress() which
  is defined to constant 0 if DMA engine support is disabled.
- request maximum segment size from the DMA engine struct device and
  set this appropriately.
- removed checking of buffer alignment - the DMA engine should deal with
  its own restrictions on buffer alignment, not the individual DMA engine
  users.
- removed setting DMAREQCTL - this confuses some DMA controllers as it
  causes LBREQ to be asserted for the last seven transfers, rather than
  six SREQ and one LSREQ.
- removed burst setting - the DMA controller should not burst past the
  transfer size required to complete the DMA operation.
Tested-by: default avatarLinus Walleij <linus.walleij@linaro.org>
Signed-off-by: default avatarRussell King <rmk+kernel@arm.linux.org.uk>
parent 51d4375d
This diff is collapsed.
......@@ -148,8 +148,10 @@
struct clk;
struct variant_data;
struct dma_chan;
struct mmci_host {
phys_addr_t phybase;
void __iomem *base;
struct mmc_request *mrq;
struct mmc_command *cmd;
......@@ -179,5 +181,16 @@ struct mmci_host {
struct sg_mapping_iter sg_miter;
unsigned int size;
struct regulator *vcc;
#ifdef CONFIG_DMA_ENGINE
/* DMA stuff */
struct dma_chan *dma_current;
struct dma_chan *dma_rx_channel;
struct dma_chan *dma_tx_channel;
#define dma_inprogress(host) ((host)->dma_current)
#else
#define dma_inprogress(host) (0)
#endif
};
......@@ -6,6 +6,9 @@
#include <linux/mmc/host.h>
/* Just some dummy forwarding */
struct dma_chan;
/**
* struct mmci_platform_data - platform configuration for the MMCI
* (also known as PL180) block.
......@@ -27,6 +30,17 @@
* @cd_invert: true if the gpio_cd pin value is active low
* @capabilities: the capabilities of the block as implemented in
* this platform, signify anything MMC_CAP_* from mmc/host.h
* @dma_filter: function used to select an apropriate RX and TX
* DMA channel to be used for DMA, if and only if you're deploying the
* generic DMA engine
* @dma_rx_param: parameter passed to the DMA allocation
* filter in order to select an apropriate RX channel. If
* there is a bidirectional RX+TX channel, then just specify
* this and leave dma_tx_param set to NULL
* @dma_tx_param: parameter passed to the DMA allocation
* filter in order to select an apropriate TX channel. If this
* is NULL the driver will attempt to use the RX channel as a
* bidirectional channel
*/
struct mmci_platform_data {
unsigned int f_max;
......@@ -38,6 +52,9 @@ struct mmci_platform_data {
int gpio_cd;
bool cd_invert;
unsigned long capabilities;
bool (*dma_filter)(struct dma_chan *chan, void *filter_param);
void *dma_rx_param;
void *dma_tx_param;
};
#endif
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment