Fixes the PIO mode for MMC/SD on TI's DA830/OMAP-L137 architecture.

On TI's DA830/OMAP-L137, the DMATRIG bit should be set for PIO
transfers.  If MMC is being used for both PIO 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 PIO to EDMA, clear any extra or
unexpected event latched in the Event register, by doing a write
to the corresponding bits in the ECR register.

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           |   15 +++++++++++++++
 4 files changed, 26 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..5a85e24 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 = 0, /* 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..3d9bfb3 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,8 @@ 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;
 
+       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