Adds support for MMC/SD on TI's DA830 architecture.

On TI's DA830, the DMATRIG bit should be set for CPU transfers.
If MMC is being used for both CPU and EDMA based transfers, then
it is likely that, an extra MMC EVENT is latched in the EDMA Event
register even when just the CPU and MMC are in play. To properly
switch from CPU to EDMA, clear any extra/unexpected event latched
in the Event register, by doing a write to the corresponding bits
in the ECR register.

Tested on DM644x EVM.

Signed-off-by: Sudhakar Rajashekhara <[email protected]>
---
 arch/arm/mach-davinci/board-dm355-evm.c  |    1 +
 arch/arm/mach-davinci/board-dm644x-evm.c |    3 ++-
 arch/arm/mach-davinci/include/mach/mmc.h |    8 ++++++++
 drivers/mmc/host/davinci_mmc.c           |   16 ++++++++++++++++
 4 files changed, 27 insertions(+), 1 deletions(-)

diff --git a/arch/arm/mach-davinci/board-dm355-evm.c 
b/arch/arm/mach-davinci/board-dm355-evm.c
index e104650..c2cf531 100644
--- a/arch/arm/mach-davinci/board-dm355-evm.c
+++ b/arch/arm/mach-davinci/board-dm355-evm.c
@@ -215,6 +215,7 @@ static struct davinci_mmc_config dm355evm_mmc_config = {
        .wires          = 4,
        .max_freq       = 50000000,
        .caps           = MMC_CAP_MMC_HIGHSPEED | MMC_CAP_SD_HIGHSPEED,
+       .version        = MMC_CTLR_VERSION_1,
 };
 
 /* Don't connect anything to J10 unless you're only using USB host
diff --git a/arch/arm/mach-davinci/board-dm644x-evm.c 
b/arch/arm/mach-davinci/board-dm644x-evm.c
index ad5b7bf..49e253f 100644
--- a/arch/arm/mach-davinci/board-dm644x-evm.c
+++ b/arch/arm/mach-davinci/board-dm644x-evm.c
@@ -542,7 +542,8 @@ static int dm6444evm_mmc_get_ro(int module)
 static struct davinci_mmc_config dm6446evm_mmc_config = {
        .get_cd         = dm6444evm_mmc_get_cd,
        .get_ro         = dm6444evm_mmc_get_ro,
-       .wires          = 4
+       .wires          = 4,
+       .version        = MMC_CTLR_VERSION_1
 };
 
 static struct i2c_board_info __initdata i2c_info[] =  {
diff --git a/arch/arm/mach-davinci/include/mach/mmc.h 
b/arch/arm/mach-davinci/include/mach/mmc.h
index aad20a5..5426fac 100644
--- a/arch/arm/mach-davinci/include/mach/mmc.h
+++ b/arch/arm/mach-davinci/include/mach/mmc.h
@@ -19,7 +19,15 @@ struct davinci_mmc_config {
 
        /* any additional host capabilities: OR'd in to mmc->f_caps */
        u32     caps;
+
+       /* Version of the MMC/SD controller */
+       u8      version;
 };
 void davinci_setup_mmc(int module, struct davinci_mmc_config *config);
 
+enum {
+       MMC_CTLR_VERSION_1,     /* DM644x and DM355 */
+       MMC_CTLR_VERSION_2,     /* DA830 */
+};
+
 #endif
diff --git a/drivers/mmc/host/davinci_mmc.c b/drivers/mmc/host/davinci_mmc.c
index 49c1004..f943be2 100644
--- a/drivers/mmc/host/davinci_mmc.c
+++ b/drivers/mmc/host/davinci_mmc.c
@@ -195,6 +195,9 @@ struct mmc_davinci_host {
        /* For PIO we walk scatterlists one segment at a time. */
        unsigned int            sg_len;
        int                     sg_idx;
+
+       /* Version of the MMC/SD controller */
+       u8 version;
 };
 
 
@@ -317,6 +320,10 @@ static void mmc_davinci_start_command(struct 
mmc_davinci_host *host,
        if (host->do_dma)
                cmd_reg |= MMCCMD_DMATRIG;
 
+       if ((host->version == MMC_CTLR_VERSION_2) && (host->data != NULL) &&
+                       (host->data_dir == DAVINCI_MMC_DATADIR_READ))
+               cmd_reg |= MMCCMD_DMATRIG;
+
        /* Setting whether command involves data transfer or not */
        if (cmd->data)
                cmd_reg |= MMCCMD_WDATX;
@@ -509,6 +516,9 @@ static void mmc_davinci_send_dma_request(struct 
mmc_davinci_host *host,
                edma_write_slot(slot, template);
        }
 
+       if (host->version == MMC_CTLR_VERSION_2)
+               edma_clear_event(channel);
+
        edma_start(channel);
 }
 
@@ -611,6 +621,9 @@ mmc_davinci_prepare_data(struct mmc_davinci_host *host, 
struct mmc_request *req)
        int timeout;
        struct mmc_data *data = req->data;
 
+       if (host->version == MMC_CTLR_VERSION_2)
+               fifo_lev = (rw_threshold == 64) ? MMCFIFOCTL_FIFOLEV : 0;
+
        host->data = data;
        if (data == NULL) {
                host->data_dir = DAVINCI_MMC_DATADIR_NONE;
@@ -1114,6 +1127,9 @@ static int __init davinci_mmcsd_probe(struct 
platform_device *pdev)
        if (!pdata || pdata->wires == 4 || pdata->wires == 0)
                mmc->caps |= MMC_CAP_4_BIT_DATA;
 
+       if (pdata->version)
+               host->version = pdata->version;
+
        mmc->ops = &mmc_davinci_ops;
        mmc->f_min = 312500;
        mmc->f_max = 25000000;
-- 
1.5.6

_______________________________________________
Davinci-linux-open-source mailing list
[email protected]
http://linux.davincidsp.com/mailman/listinfo/davinci-linux-open-source

Reply via email to