summaryrefslogtreecommitdiff
path: root/drivers
diff options
context:
space:
mode:
authorSaugata Das <saugata.das@linaro.org>2011-12-21 11:39:17 +0400
committerChris Ball <cjb@laptop.org>2012-03-26 03:33:44 +0400
commit4265900e0be653f5b78baf2816857ef57cf1332f (patch)
tree156dc60c8f5b24aa0c8be7d18759faae6ecff5f7 /drivers
parente2a0883e4071237d09b604a342c28b96b44a04b3 (diff)
downloadlinux-4265900e0be653f5b78baf2816857ef57cf1332f.tar.xz
mmc: MMC-4.5 Data Tag Support
MMC-4.5 data tag feature will be used to store the file system meta-data in the tagged region of eMMC. This will improve the write and subsequent read transfer time for the meta data. Signed-off-by: Saugata Das <saugata.das@linaro.org> Tested-by: Venkatraman S <svenkatr@ti.com> Signed-off-by: Chris Ball <cjb@laptop.org>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/mmc/card/block.c21
-rw-r--r--drivers/mmc/core/mmc.c14
2 files changed, 30 insertions, 5 deletions
diff --git a/drivers/mmc/card/block.c b/drivers/mmc/card/block.c
index e5a3c7b6dedb..f2020d37c658 100644
--- a/drivers/mmc/card/block.c
+++ b/drivers/mmc/card/block.c
@@ -1080,6 +1080,7 @@ static void mmc_blk_rw_rq_prep(struct mmc_queue_req *mqrq,
struct mmc_blk_request *brq = &mqrq->brq;
struct request *req = mqrq->req;
struct mmc_blk_data *md = mq->data;
+ bool do_data_tag;
/*
* Reliable writes are used to implement Forced Unit Access and
@@ -1156,6 +1157,16 @@ static void mmc_blk_rw_rq_prep(struct mmc_queue_req *mqrq,
mmc_apply_rel_rw(brq, card, req);
/*
+ * Data tag is used only during writing meta data to speed
+ * up write and any subsequent read of this meta data
+ */
+ do_data_tag = (card->ext_csd.data_tag_unit_size) &&
+ (req->cmd_flags & REQ_META) &&
+ (rq_data_dir(req) == WRITE) &&
+ ((brq->data.blocks * brq->data.blksz) >=
+ card->ext_csd.data_tag_unit_size);
+
+ /*
* Pre-defined multi-block transfers are preferable to
* open ended-ones (and necessary for reliable writes).
* However, it is not sufficient to just send CMD23,
@@ -1173,13 +1184,13 @@ static void mmc_blk_rw_rq_prep(struct mmc_queue_req *mqrq,
* We'll avoid using CMD23-bounded multiblock writes for
* these, while retaining features like reliable writes.
*/
-
- if ((md->flags & MMC_BLK_CMD23) &&
- mmc_op_multi(brq->cmd.opcode) &&
- (do_rel_wr || !(card->quirks & MMC_QUIRK_BLK_NO_CMD23))) {
+ if ((md->flags & MMC_BLK_CMD23) && mmc_op_multi(brq->cmd.opcode) &&
+ (do_rel_wr || !(card->quirks & MMC_QUIRK_BLK_NO_CMD23) ||
+ do_data_tag)) {
brq->sbc.opcode = MMC_SET_BLOCK_COUNT;
brq->sbc.arg = brq->data.blocks |
- (do_rel_wr ? (1 << 31) : 0);
+ (do_rel_wr ? (1 << 31) : 0) |
+ (do_data_tag ? (1 << 29) : 0);
brq->sbc.flags = MMC_RSP_R1 | MMC_CMD_AC;
brq->mrq.sbc = &brq->sbc;
}
diff --git a/drivers/mmc/core/mmc.c b/drivers/mmc/core/mmc.c
index 2b9ed1401dc4..6defddd795f6 100644
--- a/drivers/mmc/core/mmc.c
+++ b/drivers/mmc/core/mmc.c
@@ -519,6 +519,20 @@ static int mmc_read_ext_csd(struct mmc_card *card, u8 *ext_csd)
ext_csd[EXT_CSD_CACHE_SIZE + 1] << 8 |
ext_csd[EXT_CSD_CACHE_SIZE + 2] << 16 |
ext_csd[EXT_CSD_CACHE_SIZE + 3] << 24;
+
+ if (ext_csd[EXT_CSD_DATA_SECTOR_SIZE] == 1)
+ card->ext_csd.data_sector_size = 4096;
+ else
+ card->ext_csd.data_sector_size = 512;
+
+ if ((ext_csd[EXT_CSD_DATA_TAG_SUPPORT] & 1) &&
+ (ext_csd[EXT_CSD_TAG_UNIT_SIZE] <= 8)) {
+ card->ext_csd.data_tag_unit_size =
+ ((unsigned int) 1 << ext_csd[EXT_CSD_TAG_UNIT_SIZE]) *
+ (card->ext_csd.data_sector_size);
+ } else {
+ card->ext_csd.data_tag_unit_size = 0;
+ }
}
out: