diff options
author | Pavan Kunapuli <pkunapuli@nvidia.com> | 2012-07-16 14:57:35 +0530 |
---|---|---|
committer | Simone Willett <swillett@nvidia.com> | 2012-07-25 18:22:06 -0700 |
commit | 503103dabe8b55358379d4cd3ecd5acac45ebd3d (patch) | |
tree | 8201c267db8c00381bf1804d9bd1c5d2c086d808 /drivers/mmc | |
parent | 484a143002681370f7ff6c8c9c07a22cdca9360a (diff) |
mmc: core: SDXC speed class support
Unlike SDSC and SDHC, for SDXC cards CMD20 needs to be
issued to meet the class performance for speed class
recording. Adding mmc_speed_class_control() which should
be used by an AV recording app/utility before starting
recording on an SDXC card.
Bug 969360
Reviewed-on: http://git-master/r/39394
Signed-off-by: Pavan Kunapuli <pkunapuli@nvidia.com>
Reviewed-on: http://git-master/r/115685
(cherry picked from commit 04b8d1287a95e1882d956cdf7997015350408a3c)
Change-Id: Id567effb476ee580de3d49b70201ebae5a13360a
Reviewed-on: http://git-master/r/118038
Reviewed-by: Automatic_Commit_Validation_User
Reviewed-by: Naveen Kumar Arepalli <naveenk@nvidia.com>
Reviewed-by: Bitan Biswas <bbiswas@nvidia.com>
Diffstat (limited to 'drivers/mmc')
-rw-r--r-- | drivers/mmc/core/core.c | 20 | ||||
-rw-r--r-- | drivers/mmc/core/sd_ops.c | 26 | ||||
-rw-r--r-- | drivers/mmc/core/sd_ops.h | 3 |
3 files changed, 48 insertions, 1 deletions
diff --git a/drivers/mmc/core/core.c b/drivers/mmc/core/core.c index 35f3df8810e0..3fe73a7c1e99 100644 --- a/drivers/mmc/core/core.c +++ b/drivers/mmc/core/core.c @@ -2109,6 +2109,26 @@ void mmc_stop_host(struct mmc_host *host) mmc_power_off(host); } +int mmc_speed_class_control(struct mmc_host *host, + unsigned int speed_class_ctrl_arg) +{ + int err = -ENOSYS; + u32 status; + + err = mmc_send_speed_class_ctrl(host, speed_class_ctrl_arg); + if (err) + return err; + + /* Issue CMD13 to check for any errors during the busy period of CMD20 */ + err = mmc_send_status(host->card, &status); + if (!err) { + if (status & R1_ERROR) + err = -EINVAL; + } + return err; +} +EXPORT_SYMBOL(mmc_speed_class_control); + int mmc_power_save_host(struct mmc_host *host) { int ret = 0; diff --git a/drivers/mmc/core/sd_ops.c b/drivers/mmc/core/sd_ops.c index 021fed153804..b06781e69ce3 100644 --- a/drivers/mmc/core/sd_ops.c +++ b/drivers/mmc/core/sd_ops.c @@ -389,3 +389,29 @@ int mmc_app_sd_status(struct mmc_card *card, void *ssr) return 0; } + +int mmc_send_speed_class_ctrl(struct mmc_host *host, + unsigned int speed_class_ctrl_arg) +{ + int err = 0; + struct mmc_command cmd = { + .opcode = SD_SPEED_CLASS_CONTROL, + .arg = (speed_class_ctrl_arg << 28), + .flags = MMC_RSP_R1B | MMC_CMD_AC | MMC_RSP_BUSY, + }; + + BUG_ON(!host); + BUG_ON(speed_class_ctrl_arg > 3); + err = mmc_wait_for_cmd(host, &cmd, MMC_CMD_RETRIES); + if (err) + return err; + + /* + * If the host does not wait while the card signals busy, then we will + * will have to wait the max busy indication timeout. + */ + if (!(host->caps & MMC_CAP_WAIT_WHILE_BUSY)) + mmc_delay(1000); + return err; +} + diff --git a/drivers/mmc/core/sd_ops.h b/drivers/mmc/core/sd_ops.h index ffc2305d905f..a77b8facceb4 100644 --- a/drivers/mmc/core/sd_ops.h +++ b/drivers/mmc/core/sd_ops.h @@ -20,6 +20,7 @@ int mmc_app_send_scr(struct mmc_card *card, u32 *scr); int mmc_sd_switch(struct mmc_card *card, int mode, int group, u8 value, u8 *resp); int mmc_app_sd_status(struct mmc_card *card, void *ssr); - +int mmc_send_speed_class_ctrl(struct mmc_host *host, + unsigned int speed_class_ctrl_arg); #endif |