Commit 3fc7eaef authored by Shawn Lin's avatar Shawn Lin Committed by Ulf Hansson

mmc: dw_mmc: Add external dma interface support

DesignWare MMC Controller can supports two types of DMA
mode: external dma and internal dma. We get a RK312x platform
integrated dw_mmc and ARM pl330 dma controller. This patch add
edmac ops to support these platforms. I've tested it on RK31xx
platform with edmac mode and RK3288 platform with idmac mode.
Signed-off-by: default avatarShawn Lin <shawn.lin@rock-chips.com>
Signed-off-by: default avatarJaehoon Chung <jh80.chung@samsung.com>
Signed-off-by: default avatarUlf Hansson <ulf.hansson@linaro.org>
parent 9e4703df
......@@ -615,15 +615,7 @@ config MMC_DW
help
This selects support for the Synopsys DesignWare Mobile Storage IP
block, this provides host support for SD and MMC interfaces, in both
PIO and external DMA modes.
config MMC_DW_IDMAC
bool "Internal DMAC interface"
depends on MMC_DW
help
This selects support for the internal DMAC block within the Synopsys
Designware Mobile Storage IP block. This disables the external DMA
interface.
PIO, internal DMA mode and external DMA mode.
config MMC_DW_PLTFM
tristate "Synopsys Designware MCI Support as platform device"
......@@ -652,7 +644,6 @@ config MMC_DW_K3
tristate "K3 specific extensions for Synopsys DW Memory Card Interface"
depends on MMC_DW
select MMC_DW_PLTFM
select MMC_DW_IDMAC
help
This selects support for Hisilicon K3 SoC specific extensions to the
Synopsys DesignWare Memory Card Interface driver. Select this option
......
......@@ -59,6 +59,8 @@ int dw_mci_pltfm_register(struct platform_device *pdev,
host->pdata = pdev->dev.platform_data;
regs = platform_get_resource(pdev, IORESOURCE_MEM, 0);
/* Get registers' physical base address */
host->phy_regs = (void *)(regs->start);
host->regs = devm_ioremap_resource(&pdev->dev, regs);
if (IS_ERR(host->regs))
return PTR_ERR(host->regs);
......
This diff is collapsed.
......@@ -148,6 +148,12 @@
#define SDMMC_SET_FIFOTH(m, r, t) (((m) & 0x7) << 28 | \
((r) & 0xFFF) << 16 | \
((t) & 0xFFF))
/* HCON register defines */
#define DMA_INTERFACE_IDMA (0x0)
#define DMA_INTERFACE_DWDMA (0x1)
#define DMA_INTERFACE_GDMA (0x2)
#define DMA_INTERFACE_NODMA (0x3)
#define SDMMC_GET_TRANS_MODE(x) (((x)>>16) & 0x3)
/* Internal DMAC interrupt defines */
#define SDMMC_IDMAC_INT_AI BIT(9)
#define SDMMC_IDMAC_INT_NI BIT(8)
......
......@@ -16,6 +16,7 @@
#include <linux/scatterlist.h>
#include <linux/mmc/core.h>
#include <linux/dmaengine.h>
#define MAX_MCI_SLOTS 2
......@@ -40,6 +41,17 @@ enum {
struct mmc_data;
enum {
TRANS_MODE_PIO = 0,
TRANS_MODE_IDMAC,
TRANS_MODE_EDMAC
};
struct dw_mci_dma_slave {
struct dma_chan *ch;
enum dma_transfer_direction direction;
};
/**
* struct dw_mci - MMC controller state shared between all slots
* @lock: Spinlock protecting the queue and associated data.
......@@ -154,7 +166,14 @@ struct dw_mci {
dma_addr_t sg_dma;
void *sg_cpu;
const struct dw_mci_dma_ops *dma_ops;
/* For idmac */
unsigned int ring_size;
/* For edmac */
struct dw_mci_dma_slave *dms;
/* Registers's physical base address */
void *phy_regs;
u32 cmd_status;
u32 data_status;
u32 stop_cmdr;
......@@ -208,8 +227,8 @@ struct dw_mci {
struct dw_mci_dma_ops {
/* DMA Ops */
int (*init)(struct dw_mci *host);
void (*start)(struct dw_mci *host, unsigned int sg_len);
void (*complete)(struct dw_mci *host);
int (*start)(struct dw_mci *host, unsigned int sg_len);
void (*complete)(void *host);
void (*stop)(struct dw_mci *host);
void (*cleanup)(struct dw_mci *host);
void (*exit)(struct dw_mci *host);
......
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