mmc: core: SDXC speed class support
Pavan Kunapuli [Mon, 16 Jul 2012 09:27:35 +0000 (14:27 +0530)]
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>

drivers/mmc/core/core.c
drivers/mmc/core/sd_ops.c
drivers/mmc/core/sd_ops.h
include/linux/mmc/host.h
include/linux/mmc/sd.h

index 2b374bb..24ee1b5 100644 (file)
@@ -2305,6 +2305,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;
index 274ef00..5065047 100644 (file)
@@ -390,3 +390,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;
+}
+
index ffc2305..a77b8fa 100644 (file)
@@ -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
 
index 05354a9..dd458b3 100644 (file)
@@ -419,6 +419,9 @@ int mmc_card_sleep(struct mmc_host *host);
 int mmc_card_can_sleep(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);
+
 
 /* Module parameter */
 extern bool mmc_assume_removable;
index 1ebcf9b..e65bf7c 100644 (file)
 #define SD_SEND_IF_COND           8   /* bcr  [11:0] See below   R7  */
 #define SD_SWITCH_VOLTAGE         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  */
 
 #define SD_SWITCH_ACCESS_DEF   0
 #define SD_SWITCH_ACCESS_HS    1
 
+/*
+ * SD_SPEED_CLASS_CONTROL definitions
+ */
+#define SD_SPEED_CLASS_CONTROL_START_REC               0x0
+#define SD_SPEED_CLASS_CONTROL_CREATE_DIR              0x1
+#define SD_SPEED_CLASS_CONTROL_UPDATE_CI               0x4
+
+
 #endif /* LINUX_MMC_SD_H */
+