summaryrefslogtreecommitdiff
path: root/drivers/mmc/core/mmc.c
diff options
context:
space:
mode:
authorShridhar Rasal <srasal@nvidia.com>2012-01-25 17:54:30 +0530
committerSimone Willett <swillett@nvidia.com>2012-02-10 13:12:17 -0800
commit506e63fcfb563581c4a0417d424e36a75cf51acf (patch)
treee9bf67c45323f25b73c60418c8a2b68b7355182d /drivers/mmc/core/mmc.c
parent9c5ce68dd28bb7d750c47181ebcca6ac6c071eab (diff)
mmc: core: Add support for BKOPS and HPI interrupt
Added support for starting BKOPS and issuing HPI commands which are supported by eMMC v4.41 and eMMC v4.5 cards. Enable BKOPS and HPI interrupt if the host and card support it. Originally reviewed on: http://git-master/r/69778 Bug 919232 Change-Id: I09b33ddc18013e2eeb505fdb28dd8357fa75b569 Signed-off-by: Pavan Kunapuli <pkunapuli@nvidia.com> Signed-off-by: Shridhar Rasal <srasal@nvidia.com> Reviewed-on: http://git-master/r/77319 Reviewed-by: Automatic_Commit_Validation_User Reviewed-by: Sachin Nikam <snikam@nvidia.com> Reviewed-by: Varun Wadekar <vwadekar@nvidia.com>
Diffstat (limited to 'drivers/mmc/core/mmc.c')
-rw-r--r--drivers/mmc/core/mmc.c58
1 files changed, 56 insertions, 2 deletions
diff --git a/drivers/mmc/core/mmc.c b/drivers/mmc/core/mmc.c
index 6952f778c294..69fb2275845c 100644
--- a/drivers/mmc/core/mmc.c
+++ b/drivers/mmc/core/mmc.c
@@ -4,6 +4,7 @@
* Copyright (C) 2003-2004 Russell King, All Rights Reserved.
* Copyright (C) 2005-2007 Pierre Ossman, All Rights Reserved.
* MMCv4 support Copyright (C) 2006 Philip Langdale, All Rights Reserved.
+ * Copyright (c) 2012 NVIDIA Corporation, All Rights Reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
@@ -403,10 +404,29 @@ static int mmc_read_ext_csd(struct mmc_card *card, u8 *ext_csd)
ext_csd[EXT_CSD_TRIM_MULT];
}
- if (card->ext_csd.rev >= 5)
+ card->ext_csd.raw_erased_mem_count = ext_csd[EXT_CSD_ERASED_MEM_CONT];
+ if (card->ext_csd.rev >= 5) {
card->ext_csd.rel_param = ext_csd[EXT_CSD_WR_REL_PARAM];
+ /* check whether the eMMC card supports HPI */
+ if (ext_csd[EXT_CSD_HPI_FEATURES] & 0x1) {
+ card->ext_csd.hpi = 1;
+ if (ext_csd[EXT_CSD_HPI_FEATURES] & 0x2)
+ card->ext_csd.hpi_cmd = MMC_STOP_TRANSMISSION;
+ else
+ card->ext_csd.hpi_cmd = MMC_SEND_STATUS;
+ /*
+ * Indicate the maximum timeout to close
+ * a command interrupted by HPI
+ */
+ card->ext_csd.out_of_int_time =
+ ext_csd[EXT_CSD_OUT_OF_INTERRUPT_TIME] * 10;
+ }
+
+ /* Check whether the eMMC card supports background ops */
+ if (ext_csd[EXT_CSD_BKOPS_SUPPORT] & 0x1)
+ card->ext_csd.bk_ops = 1;
+ }
- card->ext_csd.raw_erased_mem_count = ext_csd[EXT_CSD_ERASED_MEM_CONT];
if (ext_csd[EXT_CSD_ERASED_MEM_CONT])
card->erased_byte = 0xFF;
else
@@ -728,6 +748,40 @@ static int mmc_init_card(struct mmc_host *host, u32 ocr,
}
/*
+ * Enable HPI feature (if supported)
+ */
+ if (card->ext_csd.hpi && (card->host->caps & MMC_CAP_BKOPS)) {
+ err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL,
+ EXT_CSD_HPI_MGMT, 1, 0);
+ if (err && err != -EBADMSG)
+ goto free_card;
+ if (err) {
+ pr_warning("%s: Enabling HPI failed\n",
+ mmc_hostname(card->host));
+ err = 0;
+ } else {
+ card->ext_csd.hpi_en = 1;
+ }
+ }
+
+ /*
+ * Enable Background ops feature (if supported)
+ */
+ if (card->ext_csd.bk_ops && (card->host->caps & MMC_CAP_BKOPS)) {
+ err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL,
+ EXT_CSD_BKOPS_EN, 1, 0);
+ if (err && err != -EBADMSG)
+ goto free_card;
+ if (err) {
+ pr_warning("%s: Enabling BK ops failed\n",
+ mmc_hostname(card->host));
+ err = 0;
+ } else {
+ card->ext_csd.bk_ops_en = 1;
+ }
+ }
+
+ /*
* Compute bus speed.
*/
max_dtr = (unsigned int)-1;