mmc: add packed command feature of eMMC4.5
Seungwon Jeon [Wed, 6 Feb 2013 08:01:43 +0000 (17:01 +0900)]
This patch adds packed command feature of eMMC4.5.  The maximum number
for packing read (or write) is offered and exception event relevant to
packed command which is used for error handling is enabled. If host
wants to use this feature, MMC_CAP2_PACKED_CMD should be set.

Signed-off-by: Seungwon Jeon <tgih.jun@samsung.com>
Signed-off-by: Chris Ball <cjb@laptop.org>
(cherry picked from commit abd9ac144947d9a604beb763339e2f77ce8bec79)

Bug 1242730

Change-Id: I739489b759f1b3d58e544307c2bed8572c091323
Signed-off-by: Naveen Kumar Arepalli <naveenk@nvidia.com>
Reviewed-on: http://git-master/r/206218
Reviewed-by: Riham Haidar <rhaidar@nvidia.com>
Tested-by: Riham Haidar <rhaidar@nvidia.com>

drivers/mmc/core/mmc.c
include/linux/mmc/card.h
include/linux/mmc/host.h
include/linux/mmc/mmc.h

index 0a0748c..a064479 100644 (file)
@@ -541,6 +541,11 @@ static int mmc_read_ext_csd(struct mmc_card *card, u8 *ext_csd)
                } else {
                        card->ext_csd.data_tag_unit_size = 0;
                }
+
+               card->ext_csd.max_packed_writes =
+                       ext_csd[EXT_CSD_MAX_PACKED_WRITES];
+               card->ext_csd.max_packed_reads =
+                       ext_csd[EXT_CSD_MAX_PACKED_READS];
        } else {
                card->ext_csd.data_sector_size = 512;
        }
@@ -1325,6 +1330,29 @@ static int mmc_init_card(struct mmc_host *host, u32 ocr,
                }
        }
 
+       /*
+        * The mandatory minimum values are defined for packed command.
+        * read: 5, write: 3
+        */
+       if (card->ext_csd.max_packed_writes >= 3 &&
+           card->ext_csd.max_packed_reads >= 5 &&
+           host->caps2 & MMC_CAP2_PACKED_CMD) {
+               err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL,
+                               EXT_CSD_EXP_EVENTS_CTRL,
+                               EXT_CSD_PACKED_EVENT_EN,
+                               card->ext_csd.generic_cmd6_time);
+               if (err && err != -EBADMSG)
+                       goto free_card;
+               if (err) {
+                       pr_warn("%s: Enabling packed event failed\n",
+                               mmc_hostname(card->host));
+                       card->ext_csd.packed_event_en = 0;
+                       err = 0;
+               } else {
+                       card->ext_csd.packed_event_en = 1;
+               }
+       }
+
        if (!oldcard)
                host->card = card;
 
index 1fb7876..1289e9f 100644 (file)
@@ -54,6 +54,9 @@ struct mmc_ext_csd {
        u8                      part_config;
        u8                      cache_ctrl;
        u8                      rst_n_function;
+       u8                      max_packed_writes;
+       u8                      max_packed_reads;
+       u8                      packed_event_en;
        unsigned int            part_time;              /* Units: ms */
        unsigned int            sa_timeout;             /* Units: 100ns */
        unsigned int            generic_cmd6_time;      /* Units: 10ms */
index 45dddd0..61f1a87 100644 (file)
@@ -248,6 +248,12 @@ struct mmc_host {
 #define MMC_CAP2_DETECT_ON_ERR (1 << 8)        /* On I/O err check card removal */
 #define MMC_CAP2_HC_ERASE_SZ   (1 << 9)        /* High-capacity erase size */
 #define MMC_CAP2_BKOPS         (1 << 10)       /* Host supports BKOPS */
+#define MMC_CAP2_CD_ACTIVE_HIGH        (1 << 10)       /* Card-detect signal active high */
+#define MMC_CAP2_RO_ACTIVE_HIGH        (1 << 11)       /* Write-protect signal active high */
+#define MMC_CAP2_PACKED_RD     (1 << 12)       /* Allow packed read */
+#define MMC_CAP2_PACKED_WR     (1 << 13)       /* Allow packed write */
+#define MMC_CAP2_PACKED_CMD    (MMC_CAP2_PACKED_RD | \
+                                MMC_CAP2_PACKED_WR)
 
        mmc_pm_flag_t           pm_caps;        /* supported pm features */
        unsigned int        power_notify_type;
index f07c9d9..1b67385 100644 (file)
@@ -140,6 +140,7 @@ static inline bool mmc_op_multi(u32 opcode)
 #define R1_READY_FOR_DATA      (1 << 8)        /* sx, a */
 #define R1_SWITCH_ERROR                (1 << 7)        /* sx, c */
 #define R1_URGENT_BKOPS        (1 << 6)        /* sr, a */
+#define R1_EXCEPTION_EVENT     (1 << 6)        /* sr, a */
 #define R1_APP_CMD             (1 << 5)        /* sr, c */
 
 #define R1_STATE_IDLE  0
@@ -275,6 +276,10 @@ struct _mmc_csd {
 #define EXT_CSD_FLUSH_CACHE            32      /* W */
 #define EXT_CSD_CACHE_CTRL             33      /* R/W */
 #define EXT_CSD_POWER_OFF_NOTIFICATION 34      /* R/W */
+#define EXT_CSD_PACKED_FAILURE_INDEX   35      /* RO */
+#define EXT_CSD_PACKED_CMD_STATUS      36      /* RO */
+#define EXT_CSD_EXP_EVENTS_STATUS      54      /* RO, 2 bytes */
+#define EXT_CSD_EXP_EVENTS_CTRL                56      /* R/W, 2 bytes */
 #define EXT_CSD_DATA_SECTOR_SIZE       61      /* R */
 #define EXT_CSD_GP_SIZE_MULT           143     /* R/W */
 #define EXT_CSD_PARTITION_ATTRIBUTE    156     /* R/W */
@@ -322,6 +327,8 @@ struct _mmc_csd {
 #define EXT_CSD_CACHE_SIZE             249     /* RO, 4 bytes */
 #define EXT_CSD_TAG_UNIT_SIZE          498     /* RO */
 #define EXT_CSD_DATA_TAG_SUPPORT       499     /* RO */
+#define EXT_CSD_MAX_PACKED_WRITES      500     /* RO */
+#define EXT_CSD_MAX_PACKED_READS       501     /* RO */
 #define EXT_CSD_BKOPS_SUPPORT          502     /* RO */
 #define EXT_CSD_HPI_FEATURES           503     /* RO */
 #define EXT_CSD_PWR_CL_200_195         236     /* RO */
@@ -387,6 +394,25 @@ struct _mmc_csd {
 #define EXT_CSD_PWR_CL_4BIT_MASK       0x0F    /* 8 bit PWR CLS */
 #define EXT_CSD_PWR_CL_8BIT_SHIFT      4
 #define EXT_CSD_PWR_CL_4BIT_SHIFT      0
+
+#define EXT_CSD_PACKED_EVENT_EN        BIT(3)
+
+/*
+ * EXCEPTION_EVENT_STATUS field
+ */
+#define EXT_CSD_URGENT_BKOPS           BIT(0)
+#define EXT_CSD_DYNCAP_NEEDED          BIT(1)
+#define EXT_CSD_SYSPOOL_EXHAUSTED      BIT(2)
+#define EXT_CSD_PACKED_FAILURE         BIT(3)
+
+#define EXT_CSD_PACKED_GENERIC_ERROR   BIT(0)
+#define EXT_CSD_PACKED_INDEXED_ERROR   BIT(1)
+
+/*
+ * BKOPS status level
+ */
+#define EXT_CSD_BKOPS_LEVEL_2          0x2
+
 /*
  * MMC_SWITCH access modes
  */