mmc: msm_sdcc: use DATA_PEND bit for write opration
DATA_PEND bit is designed to be used with CMD24 and CMD25
(WRITE_SINGLE_BLOCK and WRITE_MULTIPLE_BLOCK) to automatically
start the DPSM after a normal (non-error) response is received.
MCI_DATA_CTL should be written with the enable bit and the pending
bit asserted before MCI_CMD is enabled.
As of now driver is not using the DATA_PEND bit register for write
operation. For write operation, driver first sends the write command
to card and then waits for the CMD_RESPOND_END and once interrupt is
received, driver configures ADM/BAM and DATA_CTL register
(with ENABLE bit set) in interrupt context.
Driver can use DATA_PEND bit for SD card write operation. So basically
this would be the sequence of configuration:
1. Configure ADM/BAM
2. Configure DATA_CTL with DATA_PEND and ENABLE bit set
3. Configure CMD register for sending the write command.
All of the above configuration will now happen in thread context.
CRs-fixed: 311787
Change-Id: I5caa7e61413e53f58e067888f9cf1cfffae3dbd6
Signed-off-by: Subhash Jadavani <subhashj@codeaurora.org>
diff --git a/drivers/mmc/host/msm_sdcc.c b/drivers/mmc/host/msm_sdcc.c
index c1df55e..102b27d 100644
--- a/drivers/mmc/host/msm_sdcc.c
+++ b/drivers/mmc/host/msm_sdcc.c
@@ -1013,6 +1013,8 @@
if (data->flags & MMC_DATA_READ)
datactrl |= (MCI_DPSM_DIRECTION | MCI_RX_DATA_PEND);
+ else if (data->flags & MMC_DATA_WRITE)
+ datactrl |= MCI_DATA_PEND;
clks = (unsigned long long)data->timeout_ns * host->clk_rate;
do_div(clks, 1000000000UL);
@@ -1351,9 +1353,6 @@
msmsdcc_start_command(host, host->curr.mrq->cmd, 0);
else
msmsdcc_request_start(host, host->curr.mrq);
- } else if (cmd->data) {
- if (!(cmd->data->flags & MMC_DATA_READ))
- msmsdcc_start_data(host, cmd->data, NULL, 0);
}
}
@@ -1560,9 +1559,9 @@
static void
msmsdcc_request_start(struct msmsdcc_host *host, struct mmc_request *mrq)
{
- if (mrq->data && mrq->data->flags & MMC_DATA_READ) {
+ if (mrq->data) {
/* Queue/read data, daisy-chain command when data starts */
- if (mrq->sbc)
+ if (mrq->sbc && (mrq->data->flags & MMC_DATA_READ))
msmsdcc_start_data(host, mrq->data, mrq->sbc, 0);
else
msmsdcc_start_data(host, mrq->data, mrq->cmd, 0);