Commit 92afa75d authored by Sudhakar Rajashekhara's avatar Sudhakar Rajashekhara Committed by Kevin Hilman

ARM: DaVinci: Fix for MMC/SD PIO mode on DA830/OMAP-L137

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: default avatarSudhakar Rajashekhara <sudhakar.raj@ti.com>
parent e26199ae
...@@ -215,6 +215,7 @@ static struct davinci_mmc_config dm355evm_mmc_config = { ...@@ -215,6 +215,7 @@ static struct davinci_mmc_config dm355evm_mmc_config = {
.wires = 4, .wires = 4,
.max_freq = 50000000, .max_freq = 50000000,
.caps = MMC_CAP_MMC_HIGHSPEED | MMC_CAP_SD_HIGHSPEED, .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 /* Don't connect anything to J10 unless you're only using USB host
......
...@@ -542,7 +542,8 @@ static int dm6444evm_mmc_get_ro(int module) ...@@ -542,7 +542,8 @@ static int dm6444evm_mmc_get_ro(int module)
static struct davinci_mmc_config dm6446evm_mmc_config = { static struct davinci_mmc_config dm6446evm_mmc_config = {
.get_cd = dm6444evm_mmc_get_cd, .get_cd = dm6444evm_mmc_get_cd,
.get_ro = dm6444evm_mmc_get_ro, .get_ro = dm6444evm_mmc_get_ro,
.wires = 4 .wires = 4,
.version = MMC_CTLR_VERSION_1
}; };
static struct i2c_board_info __initdata i2c_info[] = { static struct i2c_board_info __initdata i2c_info[] = {
......
...@@ -19,7 +19,15 @@ struct davinci_mmc_config { ...@@ -19,7 +19,15 @@ struct davinci_mmc_config {
/* any additional host capabilities: OR'd in to mmc->f_caps */ /* any additional host capabilities: OR'd in to mmc->f_caps */
u32 caps; u32 caps;
/* Version of the MMC/SD controller */
u8 version;
}; };
void davinci_setup_mmc(int module, struct davinci_mmc_config *config); 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 #endif
...@@ -148,7 +148,7 @@ ...@@ -148,7 +148,7 @@
static unsigned rw_threshold = 32; static unsigned rw_threshold = 32;
module_param(rw_threshold, uint, S_IRUGO); module_param(rw_threshold, uint, S_IRUGO);
MODULE_PARM_DESC(rw_threshold, MODULE_PARM_DESC(rw_threshold,
"Read/Write threshold, can be 16/32. Default = 32"); "Read/Write threshold. Default = 32");
static unsigned __initdata use_dma = 1; static unsigned __initdata use_dma = 1;
module_param(use_dma, uint, 0); module_param(use_dma, uint, 0);
...@@ -195,6 +195,9 @@ struct mmc_davinci_host { ...@@ -195,6 +195,9 @@ struct mmc_davinci_host {
/* For PIO we walk scatterlists one segment at a time. */ /* For PIO we walk scatterlists one segment at a time. */
unsigned int sg_len; unsigned int sg_len;
int sg_idx; 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, ...@@ -317,6 +320,10 @@ static void mmc_davinci_start_command(struct mmc_davinci_host *host,
if (host->do_dma) if (host->do_dma)
cmd_reg |= MMCCMD_DMATRIG; 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 */ /* Setting whether command involves data transfer or not */
if (cmd->data) if (cmd->data)
cmd_reg |= MMCCMD_WDATX; cmd_reg |= MMCCMD_WDATX;
...@@ -471,7 +478,7 @@ static void mmc_davinci_send_dma_request(struct mmc_davinci_host *host, ...@@ -471,7 +478,7 @@ static void mmc_davinci_send_dma_request(struct mmc_davinci_host *host,
struct scatterlist *sg; struct scatterlist *sg;
unsigned sg_len; unsigned sg_len;
unsigned bytes_left = host->bytes_left; unsigned bytes_left = host->bytes_left;
const unsigned shift = (rw_threshold == 32) ? 5 : 4; const unsigned shift = ffs(rw_threshold) - 1;
if (host->data_dir == DAVINCI_MMC_DATADIR_WRITE) { if (host->data_dir == DAVINCI_MMC_DATADIR_WRITE) {
template = &host->tx_template; template = &host->tx_template;
...@@ -509,6 +516,9 @@ static void mmc_davinci_send_dma_request(struct mmc_davinci_host *host, ...@@ -509,6 +516,9 @@ static void mmc_davinci_send_dma_request(struct mmc_davinci_host *host,
edma_write_slot(slot, template); edma_write_slot(slot, template);
} }
if (host->version == MMC_CTLR_VERSION_2)
edma_clear_event(channel);
edma_start(channel); edma_start(channel);
} }
...@@ -611,6 +621,9 @@ mmc_davinci_prepare_data(struct mmc_davinci_host *host, struct mmc_request *req) ...@@ -611,6 +621,9 @@ mmc_davinci_prepare_data(struct mmc_davinci_host *host, struct mmc_request *req)
int timeout; int timeout;
struct mmc_data *data = req->data; struct mmc_data *data = req->data;
if (host->version == MMC_CTLR_VERSION_2)
fifo_lev = (rw_threshold == 64) ? MMCFIFOCTL_FIFOLEV : 0;
host->data = data; host->data = data;
if (data == NULL) { if (data == NULL) {
host->data_dir = DAVINCI_MMC_DATADIR_NONE; host->data_dir = DAVINCI_MMC_DATADIR_NONE;
...@@ -1114,6 +1127,8 @@ static int __init davinci_mmcsd_probe(struct platform_device *pdev) ...@@ -1114,6 +1127,8 @@ static int __init davinci_mmcsd_probe(struct platform_device *pdev)
if (!pdata || pdata->wires == 4 || pdata->wires == 0) if (!pdata || pdata->wires == 4 || pdata->wires == 0)
mmc->caps |= MMC_CAP_4_BIT_DATA; mmc->caps |= MMC_CAP_4_BIT_DATA;
host->version = pdata->version;
mmc->ops = &mmc_davinci_ops; mmc->ops = &mmc_davinci_ops;
mmc->f_min = 312500; mmc->f_min = 312500;
mmc->f_max = 25000000; mmc->f_max = 25000000;
......
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