diff options
author | Pavan Kunapuli <pkunapuli@nvidia.com> | 2011-07-01 19:50:59 +0530 |
---|---|---|
committer | Varun Colbert <vcolbert@nvidia.com> | 2011-07-25 18:43:48 -0700 |
commit | d580981423e8c40218badcc1ba9a11c32ad96dec (patch) | |
tree | b74712e56ab418684638c400a99ecdf00ad9df89 | |
parent | 486ad27011945b5f7b1d622780eeea7a49e0872d (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 820469
Bug 769962
Change-Id: Ic89fd6e475e6bf7ea610e43c78a752dcb444d477
Reviewed-on: http://git-master/r/39394
Reviewed-by: Pavan Kunapuli <pkunapuli@nvidia.com>
Tested-by: Pavan Kunapuli <pkunapuli@nvidia.com>
Reviewed-by: Sachin Nikam <snikam@nvidia.com>
Reviewed-by: Hanumanth Venkateswa Moganty <vmoganty@nvidia.com>
-rw-r--r-- | drivers/mmc/core/core.c | 20 | ||||
-rw-r--r-- | drivers/mmc/core/sd_ops.c | 25 | ||||
-rw-r--r-- | drivers/mmc/core/sd_ops.h | 2 | ||||
-rw-r--r-- | include/linux/mmc/host.h | 3 | ||||
-rw-r--r-- | include/linux/mmc/sd.h | 11 |
5 files changed, 61 insertions, 0 deletions
diff --git a/drivers/mmc/core/core.c b/drivers/mmc/core/core.c index c3225d68d9a5..39bd8a1e0f24 100644 --- a/drivers/mmc/core/core.c +++ b/drivers/mmc/core/core.c @@ -1646,6 +1646,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); + void mmc_power_save_host(struct mmc_host *host) { mmc_bus_get(host); diff --git a/drivers/mmc/core/sd_ops.c b/drivers/mmc/core/sd_ops.c index c450af8276d8..a2576adc5353 100644 --- a/drivers/mmc/core/sd_ops.c +++ b/drivers/mmc/core/sd_ops.c @@ -453,3 +453,28 @@ int mmc_send_tuning_pattern(struct mmc_card *card, u8 *resp) 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 17daf7842485..2db99e920a79 100644 --- a/drivers/mmc/core/sd_ops.h +++ b/drivers/mmc/core/sd_ops.h @@ -22,6 +22,8 @@ int mmc_sd_switch(struct mmc_card *card, int mode, int group, int mmc_app_sd_status(struct mmc_card *card, void *ssr); int mmc_send_voltage_switch(struct mmc_host *host); int mmc_send_tuning_pattern(struct mmc_card *card, u8 *resp); +int mmc_send_speed_class_ctrl(struct mmc_host *host, + unsigned int speed_class_ctrl_arg); #endif diff --git a/include/linux/mmc/host.h b/include/linux/mmc/host.h index 62ffcb05fb78..8c0c7a2728b0 100644 --- a/include/linux/mmc/host.h +++ b/include/linux/mmc/host.h @@ -328,6 +328,9 @@ int mmc_host_enable(struct mmc_host *host); int mmc_host_disable(struct mmc_host *host); int mmc_host_lazy_disable(struct mmc_host *host); int mmc_pm_notify(struct notifier_block *notify_block, unsigned long, void *); +int mmc_speed_class_control(struct mmc_host *host, + unsigned int speed_class_ctrl_arg); + static inline void mmc_set_disable_delay(struct mmc_host *host, unsigned int disable_delay) diff --git a/include/linux/mmc/sd.h b/include/linux/mmc/sd.h index 0f70416b0a49..b4dbcd39379a 100644 --- a/include/linux/mmc/sd.h +++ b/include/linux/mmc/sd.h @@ -18,7 +18,10 @@ #define SD_SEND_RELATIVE_ADDR 3 /* bcr R6 */ #define SD_SEND_IF_COND 8 /* bcr [11:0] See below R7 */ #define SD_VOLTAGE_SWITCH 11 /* ac R1 */ + + /* class 2 */ #define SD_SEND_TUNING_PATTERN 19 /* adtc R1 */ +#define SD_SPEED_CLASS_CONTROL 20 /* ac R1b */ /* class 10 */ #define SD_SWITCH 6 /* adtc [31:0] See below R1 */ @@ -86,5 +89,13 @@ #define SD_SWITCH_ACCESS_DEF 0 #define SD_SWITCH_ACCESS_HS 1 +/* + * SD_SPEED_CLASS_CONTROL definitions + */ +#define SD_SPEED_CLASS_CONTROL_START_REC 0 +#define SD_SPEED_CLASS_CONTROL_CREATE_DIR 1 +#define SD_SPEED_CLASS_CONTROL_END_REC_WITHOUT_MOVE 2 +#define SD_SPEED_CLASS_CONTROL_END_REC_WITH_MOVE 3 + #endif |