aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBrian Swetland <swetland@google.com>2011-01-31 00:26:49 -0800
committerVikram Pandita <vikram.pandita@ti.com>2011-01-31 09:57:05 -0800
commit41685f651455d24ea02e851a3b57e21e8296a41c (patch)
treee5753e69fb58f97742a27dc14da827a6541ea944
parentfdc2691844c622519b083cb55a45fb53609d744f (diff)
downloadu-boot-pandroid-41685f651455d24ea02e851a3b57e21e8296a41c.tar.gz
omap4: mmc: deal with card-terminated multi-block writes
In some cases when doing multi-sector writes, mmc_write_data() will terminate with a transaction complete before we've written all the data blocks we expected to. Return the number of blocks written so that omap_mmc_write_sect() can advance by that count instead of the count it asked to write. I assume the reason we were seeing this in sparse image writes is due to the random access patterns defeating the card's buffering. Signed-off-by: Brian Swetland <swetland@google.com>
-rw-r--r--cpu/omap4/mmc.c20
1 files changed, 13 insertions, 7 deletions
diff --git a/cpu/omap4/mmc.c b/cpu/omap4/mmc.c
index ee1025a0..1ae68b98 100644
--- a/cpu/omap4/mmc.c
+++ b/cpu/omap4/mmc.c
@@ -265,9 +265,10 @@ unsigned char mmc_read_data(unsigned int base, unsigned int *output_buf)
return 1;
}
-unsigned char mmc_write_data(unsigned int base, unsigned int *input_buf)
+int mmc_write_data(unsigned int base, unsigned int *input_buf)
{
unsigned int mmc_stat;
+ int count = 0;
/*
* Start Polled Write
@@ -277,8 +278,10 @@ unsigned char mmc_write_data(unsigned int base, unsigned int *input_buf)
mmc_stat = OMAP_HSMMC_STAT(base);
} while (mmc_stat == 0);
- if ((mmc_stat & ERRI_MASK) != 0)
- return (unsigned char)mmc_stat;
+ if ((mmc_stat & ERRI_MASK) != 0) {
+ printf("mmc write error %08x\n", mmc_stat);
+ return -1;
+ }
if (mmc_stat & BWR_MASK) {
unsigned int k;
@@ -288,6 +291,7 @@ unsigned char mmc_write_data(unsigned int base, unsigned int *input_buf)
OMAP_HSMMC_DATA(base) = *input_buf;
input_buf++;
}
+ count++;
}
if (mmc_stat & BRR_MASK)
@@ -298,7 +302,7 @@ unsigned char mmc_write_data(unsigned int base, unsigned int *input_buf)
break;
}
}
- return 1;
+ return count;
}
unsigned char mmc_detect_card(mmc_card_data *mmc_card_cur,
@@ -535,6 +539,7 @@ unsigned char omap_mmc_write_sect(unsigned int *input_buf,
(num_bytes + (MMCSD_SECTOR_SIZE - 1)) / MMCSD_SECTOR_SIZE;
unsigned int sec_inc_val;
unsigned int blk_cnt_current_tns;
+ int r;
if (num_sec_val == 0) {
printf("mmc write: Invalid size\n");
@@ -577,9 +582,10 @@ unsigned char omap_mmc_write_sect(unsigned int *input_buf,
if (err != 1)
return err;
}
- err = mmc_write_data(mmc_cont_cur->base, input_buf);
- if (err != 1)
- return err;
+ r = mmc_write_data(mmc_cont_cur->base, input_buf);
+ if (r < 0)
+ return 1;
+ blk_cnt_current_tns = r;
#if defined(CONFIG_4430PANDA)
if (blk_cnt_current_tns > 1) {