mmc: add hs400 enhanced strobe support for mmc subsystem
[firefly-linux-kernel-4.4.55.git] / include / linux / mmc / host.h
index 83b81fd865f3bba12e7bc7d4c0ac8091ca067c09..ec55e25115d191afe5d89ea6cac5b4002e28a197 100644 (file)
@@ -19,6 +19,7 @@
 
 #include <linux/mmc/core.h>
 #include <linux/mmc/card.h>
+#include <linux/mmc/mmc.h>
 #include <linux/mmc/pm.h>
 
 struct mmc_ios {
@@ -126,12 +127,15 @@ struct mmc_host_ops {
 
        /* Check if the card is pulling dat[0:3] low */
        int     (*card_busy)(struct mmc_host *host);
+       int     (*set_sdio_status)(struct mmc_host *host, int val);
 
        /* 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);
+       /* Prepare enhanced strobe depending host driver */
+       int     (*prepare_enhanced_strobe)(struct mmc_host *host, bool enable);
        int     (*select_drive_strength)(struct mmc_card *card,
                                         unsigned int max_dtr, int host_drv,
                                         int card_drv, int *drv_type);
@@ -289,20 +293,14 @@ struct mmc_host {
 #define MMC_CAP2_HSX00_1_2V    (MMC_CAP2_HS200_1_2V_SDR | MMC_CAP2_HS400_1_2V)
 #define MMC_CAP2_SDIO_IRQ_NOTHREAD (1 << 17)
 #define MMC_CAP2_NO_WRITE_PROTECT (1 << 18)    /* No physical write protect pin, assume that card is always read-write */
+#define MMC_CAP2_HS400_ENHANCED_STROBE (1 << 20) /* Host supports enhanced strobe */
 
        mmc_pm_flag_t           pm_caps;        /* supported pm features */
 
-#ifdef CONFIG_MMC_CLKGATE
-       int                     clk_requests;   /* internal reference counter */
-       unsigned int            clk_delay;      /* number of MCI clk hold cycles */
-       bool                    clk_gated;      /* clock gated */
-       struct delayed_work     clk_gate_work; /* delayed clock gate */
-       unsigned int            clk_old;        /* old clock value cache */
-       spinlock_t              clk_lock;       /* lock for clk fields */
-       struct mutex            clk_gate_mutex; /* mutex for clock gating */
-       struct device_attribute clkgate_delay_attr;
-       unsigned long           clkgate_delay;
-#endif
+       u32                     restrict_caps;  /* Indicate slot specific card type */
+#define RESTRICT_CARD_TYPE_SD   (1 << 0)        /* Can support Secure-Digital Card */
+#define RESTRICT_CARD_TYPE_SDIO (1 << 1)        /* Can support Secure-Digital I/O Card or Combo-Mem */
+#define RESTRICT_CARD_TYPE_EMMC (1 << 2)        /* Can support embedded Multi-Media Card */
 
        /* host specific block data */
        unsigned int            max_seg_size;   /* see blk_queue_max_segment_size */
@@ -382,6 +380,15 @@ struct mmc_host {
        int                     dsr_req;        /* DSR value is valid */
        u32                     dsr;    /* optional driver stage (DSR) value */
 
+#ifdef CONFIG_MMC_EMBEDDED_SDIO
+       struct {
+               struct sdio_cis                 *cis;
+               struct sdio_cccr                *cccr;
+               struct sdio_embedded_func       *funcs;
+               int                             num_funcs;
+       } embedded_sdio_data;
+#endif
+
        unsigned long           private[0] ____cacheline_aligned;
 };
 
@@ -391,6 +398,14 @@ void mmc_remove_host(struct mmc_host *);
 void mmc_free_host(struct mmc_host *);
 int mmc_of_parse(struct mmc_host *host);
 
+#ifdef CONFIG_MMC_EMBEDDED_SDIO
+extern void mmc_set_embedded_sdio_data(struct mmc_host *host,
+                                      struct sdio_cis *cis,
+                                      struct sdio_cccr *cccr,
+                                      struct sdio_embedded_func *funcs,
+                                      int num_funcs);
+#endif
+
 static inline void *mmc_priv(struct mmc_host *host)
 {
        return (void *)host->private;
@@ -423,6 +438,7 @@ int mmc_regulator_get_ocrmask(struct regulator *supply);
 int mmc_regulator_set_ocr(struct mmc_host *mmc,
                        struct regulator *supply,
                        unsigned short vdd_bit);
+int mmc_regulator_set_vqmmc(struct mmc_host *mmc, struct mmc_ios *ios);
 #else
 static inline int mmc_regulator_get_ocrmask(struct regulator *supply)
 {
@@ -435,6 +451,12 @@ static inline int mmc_regulator_set_ocr(struct mmc_host *mmc,
 {
        return 0;
 }
+
+static inline int mmc_regulator_set_vqmmc(struct mmc_host *mmc,
+                                         struct mmc_ios *ios)
+{
+       return -EINVAL;
+}
 #endif
 
 int mmc_regulator_get_supply(struct mmc_host *mmc);
@@ -474,31 +496,16 @@ static inline int mmc_host_uhs(struct mmc_host *host)
                 MMC_CAP_UHS_DDR50);
 }
 
-static inline int mmc_host_packed_wr(struct mmc_host *host)
-{
-       return host->caps2 & MMC_CAP2_PACKED_WR;
-}
-
-#ifdef CONFIG_MMC_CLKGATE
-void mmc_host_clk_hold(struct mmc_host *host);
-void mmc_host_clk_release(struct mmc_host *host);
-unsigned int mmc_host_clk_rate(struct mmc_host *host);
-
-#else
-static inline void mmc_host_clk_hold(struct mmc_host *host)
+static inline int mmc_host_hs400_enhanced_strobe(struct mmc_host *host)
 {
+       return host->caps2 & MMC_CAP2_HS400_ENHANCED_STROBE;
 }
 
-static inline void mmc_host_clk_release(struct mmc_host *host)
+static inline int mmc_host_packed_wr(struct mmc_host *host)
 {
+       return host->caps2 & MMC_CAP2_PACKED_WR;
 }
 
-static inline unsigned int mmc_host_clk_rate(struct mmc_host *host)
-{
-       return host->ios.clock;
-}
-#endif
-
 static inline int mmc_card_hs(struct mmc_card *card)
 {
        return card->host->ios.timing == MMC_TIMING_SD_HS ||
@@ -526,6 +533,15 @@ static inline bool mmc_card_hs400(struct mmc_card *card)
        return card->host->ios.timing == MMC_TIMING_MMC_HS400;
 }
 
+static inline bool mmc_card_hs400es(struct mmc_card *card)
+{
+       if (mmc_card_hs400(card) &&
+           (card->mmc_avail_type & EXT_CSD_CARD_TYPE_HS400ES))
+               return 1;
+
+       return 0;
+}
+
 void mmc_retune_timer_stop(struct mmc_host *host);
 
 static inline void mmc_retune_needed(struct mmc_host *host)