static void mmc_select_card_type(struct mmc_card *card)
 {
        struct mmc_host *host = card->host;
-       u8 card_type = card->ext_csd.raw_card_type & EXT_CSD_CARD_TYPE_MASK;
+       u8 card_type = card->ext_csd.raw_card_type;
        u32 caps = host->caps, caps2 = host->caps2;
        unsigned int hs_max_dtr = 0, hs200_max_dtr = 0;
        unsigned int avail_type = 0;
                avail_type |= EXT_CSD_CARD_TYPE_HS200_1_2V;
        }
 
+       if (caps2 & MMC_CAP2_HS400_1_8V &&
+           card_type & EXT_CSD_CARD_TYPE_HS400_1_8V) {
+               hs200_max_dtr = MMC_HS200_MAX_DTR;
+               avail_type |= EXT_CSD_CARD_TYPE_HS400_1_8V;
+       }
+
+       if (caps2 & MMC_CAP2_HS400_1_2V &&
+           card_type & EXT_CSD_CARD_TYPE_HS400_1_2V) {
+               hs200_max_dtr = MMC_HS200_MAX_DTR;
+               avail_type |= EXT_CSD_CARD_TYPE_HS400_1_2V;
+       }
+
        card->ext_csd.hs_max_dtr = hs_max_dtr;
        card->ext_csd.hs200_max_dtr = hs200_max_dtr;
        card->mmc_avail_type = avail_type;
                        ext_csd[EXT_CSD_PWR_CL_DDR_52_195];
                card->ext_csd.raw_pwr_cl_ddr_52_360 =
                        ext_csd[EXT_CSD_PWR_CL_DDR_52_360];
+               card->ext_csd.raw_pwr_cl_ddr_200_360 =
+                       ext_csd[EXT_CSD_PWR_CL_DDR_200_360];
        }
 
        if (card->ext_csd.rev >= 5) {
                (card->ext_csd.raw_pwr_cl_ddr_52_195 ==
                        bw_ext_csd[EXT_CSD_PWR_CL_DDR_52_195]) &&
                (card->ext_csd.raw_pwr_cl_ddr_52_360 ==
-                       bw_ext_csd[EXT_CSD_PWR_CL_DDR_52_360]));
+                       bw_ext_csd[EXT_CSD_PWR_CL_DDR_52_360]) &&
+               (card->ext_csd.raw_pwr_cl_ddr_200_360 ==
+                       bw_ext_csd[EXT_CSD_PWR_CL_DDR_200_360]));
+
        if (err)
                err = -EINVAL;
 
                                ext_csd->raw_pwr_cl_52_360 :
                                ext_csd->raw_pwr_cl_ddr_52_360;
                else if (host->ios.clock <= MMC_HS200_MAX_DTR)
-                       pwrclass_val = ext_csd->raw_pwr_cl_200_360;
+                       pwrclass_val = (bus_width == EXT_CSD_DDR_BUS_WIDTH_8) ?
+                               ext_csd->raw_pwr_cl_ddr_200_360 :
+                               ext_csd->raw_pwr_cl_200_360;
                break;
        default:
                pr_warning("%s: Voltage range not supported "
 {
        unsigned int max_dtr = (unsigned int)-1;
 
-       if (mmc_card_hs200(card) && max_dtr > card->ext_csd.hs200_max_dtr)
+       if ((mmc_card_hs200(card) || mmc_card_hs400(card)) &&
+            max_dtr > card->ext_csd.hs200_max_dtr)
                max_dtr = card->ext_csd.hs200_max_dtr;
        else if (mmc_card_hs(card) && max_dtr > card->ext_csd.hs_max_dtr)
                max_dtr = card->ext_csd.hs_max_dtr;
        return err;
 }
 
+static int mmc_select_hs400(struct mmc_card *card)
+{
+       struct mmc_host *host = card->host;
+       int err = 0;
+
+       /*
+        * HS400 mode requires 8-bit bus width
+        */
+       if (!(card->mmc_avail_type & EXT_CSD_CARD_TYPE_HS400 &&
+             host->ios.bus_width == MMC_BUS_WIDTH_8))
+               return 0;
+
+       /*
+        * Before switching to dual data rate operation for HS400,
+        * it is required to convert from HS200 mode to HS mode.
+        */
+       mmc_set_timing(card->host, MMC_TIMING_MMC_HS);
+       mmc_set_bus_speed(card);
+
+       err = __mmc_switch(card, EXT_CSD_CMD_SET_NORMAL,
+                          EXT_CSD_HS_TIMING, EXT_CSD_TIMING_HS,
+                          card->ext_csd.generic_cmd6_time,
+                          true, true, true);
+       if (err) {
+               pr_warn("%s: switch to high-speed from hs200 failed, err:%d\n",
+                       mmc_hostname(host), err);
+               return err;
+       }
+
+       err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL,
+                        EXT_CSD_BUS_WIDTH,
+                        EXT_CSD_DDR_BUS_WIDTH_8,
+                        card->ext_csd.generic_cmd6_time);
+       if (err) {
+               pr_warn("%s: switch to bus width for hs400 failed, err:%d\n",
+                       mmc_hostname(host), err);
+               return err;
+       }
+
+       err = __mmc_switch(card, EXT_CSD_CMD_SET_NORMAL,
+                          EXT_CSD_HS_TIMING, EXT_CSD_TIMING_HS400,
+                          card->ext_csd.generic_cmd6_time,
+                          true, true, true);
+       if (err) {
+               pr_warn("%s: switch to hs400 failed, err:%d\n",
+                        mmc_hostname(host), err);
+               return err;
+       }
+
+       mmc_set_timing(host, MMC_TIMING_MMC_HS400);
+       mmc_set_bus_speed(card);
+
+       return 0;
+}
+
 /*
  * For device supporting HS200 mode, the following sequence
  * should be done before executing the tuning process.
 
 /*
  * Execute tuning sequence to seek the proper bus operating
- * conditions for HS200, which sends CMD21 to the device.
+ * conditions for HS200 and HS400, which sends CMD21 to the device.
  */
 static int mmc_hs200_tuning(struct mmc_card *card)
 {
        struct mmc_host *host = card->host;
        int err = 0;
 
+       /*
+        * Timing should be adjusted to the HS400 target
+        * operation frequency for tuning process
+        */
+       if (card->mmc_avail_type & EXT_CSD_CARD_TYPE_HS400 &&
+           host->ios.bus_width == MMC_BUS_WIDTH_8)
+               if (host->ops->prepare_hs400_tuning)
+                       host->ops->prepare_hs400_tuning(host, &host->ios);
+
        if (host->ops->execute_tuning) {
                mmc_host_clk_hold(host);
                err = host->ops->execute_tuning(host,
                err = mmc_hs200_tuning(card);
                if (err)
                        goto err;
+
+               err = mmc_select_hs400(card);
+               if (err)
+                       goto err;
        } else if (mmc_card_hs(card)) {
                /* Select the desired bus width optionally */
                err = mmc_select_bus_width(card);
 
 #define MMC_TIMING_UHS_DDR50   7
 #define MMC_TIMING_MMC_DDR52   8
 #define MMC_TIMING_MMC_HS200   9
+#define MMC_TIMING_MMC_HS400   10
 
        unsigned char   signal_voltage;         /* signalling voltage (1.8V or 3.3V) */
 
 
        /* The tuning command opcode value is different for SD and eMMC cards */
        int     (*execute_tuning)(struct mmc_host *host, u32 opcode);
+
+       /* Prepare HS400 target operating frequency depending host driver */
+       int     (*prepare_hs400_tuning)(struct mmc_host *host, struct mmc_ios *ios);
        int     (*select_drive_strength)(unsigned int max_dtr, int host_drv, int card_drv);
        void    (*hw_reset)(struct mmc_host *host);
        void    (*card_event)(struct mmc_host *host);
 #define MMC_CAP2_PACKED_CMD    (MMC_CAP2_PACKED_RD | \
                                 MMC_CAP2_PACKED_WR)
 #define MMC_CAP2_NO_PRESCAN_POWERUP (1 << 14)  /* Don't power up before scan */
+#define MMC_CAP2_HS400_1_8V    (1 << 15)       /* Can support HS400 1.8V */
+#define MMC_CAP2_HS400_1_2V    (1 << 16)       /* Can support HS400 1.2V */
+#define MMC_CAP2_HS400         (MMC_CAP2_HS400_1_8V | \
+                                MMC_CAP2_HS400_1_2V)
 
        mmc_pm_flag_t           pm_caps;        /* supported pm features */
 
 {
        return card->host->ios.timing == MMC_TIMING_MMC_DDR52;
 }
+
+static inline bool mmc_card_hs400(struct mmc_card *card)
+{
+       return card->host->ios.timing == MMC_TIMING_MMC_HS400;
+}
+
 #endif /* LINUX_MMC_HOST_H */
 
 #define EXT_CSD_POWER_OFF_LONG_TIME    247     /* RO */
 #define EXT_CSD_GENERIC_CMD6_TIME      248     /* RO */
 #define EXT_CSD_CACHE_SIZE             249     /* RO, 4 bytes */
+#define EXT_CSD_PWR_CL_DDR_200_360     253     /* RO */
 #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_CMD_SET_SECURE         (1<<1)
 #define EXT_CSD_CMD_SET_CPSECURE       (1<<2)
 
-#define EXT_CSD_CARD_TYPE_MASK 0x3F    /* Mask out reserved bits */
 #define EXT_CSD_CARD_TYPE_HS_26        (1<<0)  /* Card can run at 26MHz */
 #define EXT_CSD_CARD_TYPE_HS_52        (1<<1)  /* Card can run at 52MHz */
 #define EXT_CSD_CARD_TYPE_HS   (EXT_CSD_CARD_TYPE_HS_26 | \
                                                /* SDR mode @1.2V I/O */
 #define EXT_CSD_CARD_TYPE_HS200                (EXT_CSD_CARD_TYPE_HS200_1_8V | \
                                         EXT_CSD_CARD_TYPE_HS200_1_2V)
+#define EXT_CSD_CARD_TYPE_HS400_1_8V   (1<<6)  /* Card can run at 200MHz DDR, 1.8V */
+#define EXT_CSD_CARD_TYPE_HS400_1_2V   (1<<7)  /* Card can run at 200MHz DDR, 1.2V */
+#define EXT_CSD_CARD_TYPE_HS400                (EXT_CSD_CARD_TYPE_HS400_1_8V | \
+                                        EXT_CSD_CARD_TYPE_HS400_1_2V)
 
 #define EXT_CSD_BUS_WIDTH_1    0       /* Card is in 1 bit mode */
 #define EXT_CSD_BUS_WIDTH_4    1       /* Card is in 4 bit mode */
 #define EXT_CSD_TIMING_BC      0       /* Backwards compatility */
 #define EXT_CSD_TIMING_HS      1       /* High speed */
 #define EXT_CSD_TIMING_HS200   2       /* HS200 */
+#define EXT_CSD_TIMING_HS400   3       /* HS400 */
 
 #define EXT_CSD_SEC_ER_EN      BIT(0)
 #define EXT_CSD_SEC_BD_BLK_EN  BIT(2)