msm_shared: sdhci: Clear transfer complete for busy commands
Commands with busy response set the transfer complete bit after
their execution is complete. Clear the transfer complete bit for
these commands. Also add support for reading data which is less
than max supported block length from the capabilities register.
CRs-Fixed: 492353
Change-Id: I05514a6098538287157f2f34b7c2d218a44949a0
diff --git a/platform/msm_shared/include/sdhci.h b/platform/msm_shared/include/sdhci.h
index ff61868..0c15c06 100644
--- a/platform/msm_shared/include/sdhci.h
+++ b/platform/msm_shared/include/sdhci.h
@@ -63,6 +63,7 @@
*/
struct mmc_data {
void *data_ptr; /* Points to stream of data */
+ uint32_t blk_sz; /* Block size for the data */
uint32_t num_blocks; /* num of blocks, each always of size SDHCI_MMC_BLK_SZ */
};
diff --git a/platform/msm_shared/sdhci.c b/platform/msm_shared/sdhci.c
index dac6fdc..221d2dd 100644
--- a/platform/msm_shared/sdhci.c
+++ b/platform/msm_shared/sdhci.c
@@ -432,7 +432,7 @@
/*
* Clear the transfer complete interrupt
*/
- if (cmd->data_present || cmd->cmd_index == SDHCI_SWITCH_CMD) {
+ if (cmd->data_present || cmd->resp_type == SDHCI_CMD_RESP_R1B) {
do {
int_status = REG_READ16(host, SDHCI_NRML_INT_STS_REG);
int_status &= SDHCI_INT_STS_TRANS_COMPLETE;
@@ -567,13 +567,27 @@
num_blks = cmd->data.num_blocks;
data = cmd->data.data_ptr;
- sz = num_blks * SDHCI_MMC_BLK_SZ;
+ /*
+ * Some commands send data on DAT lines which is less
+ * than SDHCI_MMC_BLK_SZ, in that case trying to read
+ * more than the data sent by the card results in data
+ * CRC errors. To avoid such errors allow data to pass
+ * the required block size, if the block size is not
+ * passed use the default value
+ */
+ if (cmd->data.blk_sz)
+ sz = num_blks * cmd->data.blk_sz;
+ else
+ sz = num_blks * SDHCI_MMC_BLK_SZ;
/* Prepare adma descriptor table */
adma_addr = sdhci_prep_desc_table(data, sz);
/* Write the block size */
- REG_WRITE16(host, SDHCI_MMC_BLK_SZ, SDHCI_BLKSZ_REG);
+ if (cmd->data.blk_sz)
+ REG_WRITE16(host, cmd->data.blk_sz, SDHCI_BLKSZ_REG);
+ else
+ REG_WRITE16(host, SDHCI_MMC_BLK_SZ, SDHCI_BLKSZ_REG);
/* Enalbe auto cmd 23 for multi block transfer */
if (num_blks > 1) {