Hi Girish, > -----Original Message----- > From: linux-mmc-owner@xxxxxxxxxxxxxxx [mailto:linux-mmc- > owner@xxxxxxxxxxxxxxx] On Behalf Of Girish K S > Sent: Wednesday, November 30, 2011 2:24 PM > To: linux-mmc@xxxxxxxxxxxxxxx > Cc: patches@xxxxxxxxxx; linux-samsung-soc@xxxxxxxxxxxxxxx; > subhashj@xxxxxxxxxxxxxx; Girish K S; Chris Ball > Subject: [PATCH V5] mmc: core: HS200 mode support for eMMC 4.5 > > This patch adds the support of the HS200 bus speed for eMMC 4.5 > devices. > The eMMC 4.5 devices have support for 200MHz bus speed.The mmc core and > host modules have been touched to add support for this module. > > It is necessary to know the card type in the sdhci.c file to add > support > for eMMC tuning function. So card.h file is included to import the card > data structure. > > cc: Chris Ball <cjb@xxxxxxxxxx> > Signed-off-by: Girish K S <girish.shivananjappa@xxxxxxxxxx> > --- > Changes in v5: > Reduced the case statements for better code readability. Removed > unused macro definitions. Modified the tuning function prototype > and definition to support tuning for both SD and eMMC cards. > Changes in v4: > Rebased onto chris-mmc/mmc-next branch. This patch is > successfully > applied on commit with id > de022ed3fdc14808299b2fa66dbb1ed5ab921912. > Changes in v3: > In the previous commits of chris-mmc/mmc-next branch, the patch > with > commit id (c0f22a2c92e357e7cb3988b0b13034d70b7461f9) defines > caps2 for > more capabilities. This patch version deletes the member > ext_caps(created > in my earlier patch) from struct mmc_host and reuses already > accepted > caps2 member. > Changes in v2: > Rebased to latest chris-mmc/mmc-next branch. Resolved indentation > problems identified in review. This patch has to be applied > before > the patch released for modifying the printk messages. > Changes in v1: > Case statements in switch that produce same result have > been combined to reduce repeated assignments. > patch recreated after rebase to chris balls mmc-next branch. > > drivers/mmc/core/bus.c | 3 +- > drivers/mmc/core/mmc.c | 77 > ++++++++++++++++++++++++++++++++++++++++---- > drivers/mmc/core/sd.c | 3 +- > drivers/mmc/core/sdio.c | 4 ++- > drivers/mmc/host/sdhci.c | 38 +++++++++++++++++----- > include/linux/mmc/card.h | 3 ++ > include/linux/mmc/host.h | 11 ++++++- > include/linux/mmc/mmc.h | 66 > ++++++++++++++++++++++++++++++++++++++- > include/linux/mmc/sdhci.h | 1 + > 9 files changed, 185 insertions(+), 21 deletions(-) > > diff --git a/drivers/mmc/core/bus.c b/drivers/mmc/core/bus.c > index 5639fdf..83c9f8d 100644 > --- a/drivers/mmc/core/bus.c > +++ b/drivers/mmc/core/bus.c > @@ -301,10 +301,11 @@ int mmc_add_card(struct mmc_card *card) > mmc_card_ddr_mode(card) ? "DDR " : "", > type); > } else { > - printk(KERN_INFO "%s: new %s%s%s card at address %04x\n", > + pr_info("%s: new %s%s%s%s card at address %04x\n", > mmc_hostname(card->host), > mmc_card_uhs(card) ? "ultra high speed " : > (mmc_card_highspeed(card) ? "high speed " : ""), > + (mmc_card_hs200(card) ? "HS200 " : ""), > mmc_card_ddr_mode(card) ? "DDR " : "", > type, card->rca); > } > diff --git a/drivers/mmc/core/mmc.c b/drivers/mmc/core/mmc.c > index a1223bd..f4124d6 100644 > --- a/drivers/mmc/core/mmc.c > +++ b/drivers/mmc/core/mmc.c > @@ -285,6 +285,27 @@ static int mmc_read_ext_csd(struct mmc_card *card, > u8 *ext_csd) > } > card->ext_csd.raw_card_type = ext_csd[EXT_CSD_CARD_TYPE]; > switch (ext_csd[EXT_CSD_CARD_TYPE] & EXT_CSD_CARD_TYPE_MASK) { > + case EXT_CSD_CARD_TYPE_SDR_ALL: > + case EXT_CSD_CARD_TYPE_SDR_ALL_DDR_1_8V: > + case EXT_CSD_CARD_TYPE_SDR_ALL_DDR_1_2V: > + case EXT_CSD_CARD_TYPE_SDR_ALL_DDR_52: > + card->ext_csd.hs_max_dtr = 200000000; > + card->ext_csd.card_type = EXT_CSD_CARD_TYPE_SDR_200; > + break; > + case EXT_CSD_CARD_TYPE_SDR_1_2V_ALL: > + case EXT_CSD_CARD_TYPE_SDR_1_2V_DDR_1_8V: > + case EXT_CSD_CARD_TYPE_SDR_1_2V_DDR_1_2V: > + case EXT_CSD_CARD_TYPE_SDR_1_2V_DDR_52: > + card->ext_csd.hs_max_dtr = 200000000; > + card->ext_csd.card_type = EXT_CSD_CARD_TYPE_SDR_1_2V; > + break; > + case EXT_CSD_CARD_TYPE_SDR_1_8V_ALL: > + case EXT_CSD_CARD_TYPE_SDR_1_8V_DDR_1_8V: > + case EXT_CSD_CARD_TYPE_SDR_1_8V_DDR_1_2V: > + case EXT_CSD_CARD_TYPE_SDR_1_8V_DDR_52: > + card->ext_csd.hs_max_dtr = 200000000; > + card->ext_csd.card_type = EXT_CSD_CARD_TYPE_SDR_1_8V; > + break; > case EXT_CSD_CARD_TYPE_DDR_52 | EXT_CSD_CARD_TYPE_52 | > EXT_CSD_CARD_TYPE_26: > card->ext_csd.hs_max_dtr = 52000000; > @@ -699,6 +720,7 @@ static int mmc_init_card(struct mmc_host *host, u32 > ocr, > { > struct mmc_card *card; > int err, ddr = 0; > + int hs_sdr = 0; > u32 cid[4]; > unsigned int max_dtr; > u32 rocr; > @@ -894,11 +916,16 @@ static int mmc_init_card(struct mmc_host *host, > u32 ocr, > /* > * Activate high speed (if supported) > */ > - if ((card->ext_csd.hs_max_dtr != 0) && > - (host->caps & MMC_CAP_MMC_HIGHSPEED)) { > - err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL, > - EXT_CSD_HS_TIMING, 1, > - card->ext_csd.generic_cmd6_time); > + if (card->ext_csd.hs_max_dtr != 0) { > + err = 0; > + if ((card->ext_csd.hs_max_dtr > 52000000) && > + (host->caps2 & MMC_CAP2_HS200)) > + err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL, > + EXT_CSD_HS_TIMING, 2, 0); > + else if (host->caps & MMC_CAP_MMC_HIGHSPEED) > + err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL, > + EXT_CSD_HS_TIMING, 1, 0); > + > if (err && err != -EBADMSG) > goto free_card; > > @@ -907,7 +934,11 @@ static int mmc_init_card(struct mmc_host *host, > u32 ocr, > mmc_hostname(card->host)); > err = 0; > } else { > - mmc_card_set_highspeed(card); > + if ((card->ext_csd.hs_max_dtr > 52000000) && > + (host->caps2 & MMC_CAP2_HS200)) > + mmc_card_set_hs200(card); > + else > + mmc_card_set_highspeed(card); > mmc_set_timing(card->host, MMC_TIMING_MMC_HS); MMC_TIMING_MMC_HS200 is defined but still not used. So I guess it should be like this :: + if ((card->ext_csd.hs_max_dtr > 52000000) && + (host->caps2 & MMC_CAP2_HS200)) { + mmc_card_set_hs200(card); + mmc_set_timing(card->host, MMC_TIMING_MMC_HS200) + } else { + mmc_card_set_highspeed(card); + mmc_set_timing(card->host, MMC_TIMING_MMC_HS) + } > } > } > @@ -933,7 +964,7 @@ static int mmc_init_card(struct mmc_host *host, u32 > ocr, > */ > max_dtr = (unsigned int)-1; > > - if (mmc_card_highspeed(card)) { > + if (mmc_card_highspeed(card) || mmc_card_hs200(card)) { > if (max_dtr > card->ext_csd.hs_max_dtr) > max_dtr = card->ext_csd.hs_max_dtr; > } else if (max_dtr > card->csd.max_dtr) { > @@ -959,6 +990,18 @@ static int mmc_init_card(struct mmc_host *host, > u32 ocr, > } > > /* > + * Indicate HS200 SDR mode (if supported). > + */ > + if (mmc_card_hs200(card)) { > + if ((card->ext_csd.card_type & EXT_CSD_CARD_TYPE_SDR_1_8V) > + && (host->caps2 & MMC_CAP2_HS200_1_8V_SDR)) > + hs_sdr = MMC_1_8V_SDR_MODE; > + else if ((card->ext_csd.card_type & > EXT_CSD_CARD_TYPE_SDR_1_2V) > + && (host->caps2 & MMC_CAP2_HS200_1_2V_SDR)) > + hs_sdr = MMC_1_2V_SDR_MODE; > + } > + > + /* > * Activate wide bus and DDR (if supported). > */ > if ((card->csd.mmca_vsn >= CSD_SPEC_VER_4) && > @@ -998,6 +1041,17 @@ static int mmc_init_card(struct mmc_host *host, > u32 ocr, > if (!err) { > mmc_set_bus_width(card->host, bus_width); > > + if ((host->caps2 & MMC_CAP2_HS200) && > + card->host->ops->execute_tuning) > + err = card->host->ops-> \ > + execute_tuning(card->host, > + MMC_SEND_TUNING_BLOCK_HS200); execute_tuning should be done right after the timing is changed to HS200 and clock rate is changed to 200Mhz. This is not the correct sequence to call the execute_tuning(). > + > + if (err) { > + pr_warning("tuning execution failed\n"); > + continue; > + } > + > /* > * If controller can't handle bus width test, > * compare ext_csd previously read in 1 bit > mode > @@ -1056,6 +1110,15 @@ static int mmc_init_card(struct mmc_host *host, > u32 ocr, > mmc_card_set_ddr_mode(card); > mmc_set_timing(card->host, MMC_TIMING_UHS_DDR50); > mmc_set_bus_width(card->host, bus_width); > + } else if (hs_sdr) { > + if (hs_sdr == EXT_CSD_CARD_TYPE_SDR_1_2V) { > + err = mmc_set_signal_voltage(host, > + MMC_SIGNAL_VOLTAGE_120, 0); > + if (err) > + goto err; > + } > + mmc_set_timing(card->host, MMC_TIMING_MMC_HS); > + mmc_set_bus_width(card->host, bus_width); > } > } > > diff --git a/drivers/mmc/core/sd.c b/drivers/mmc/core/sd.c > index 1d5a3bd..c1d3ee3 100644 > --- a/drivers/mmc/core/sd.c > +++ b/drivers/mmc/core/sd.c > @@ -660,7 +660,8 @@ static int mmc_sd_init_uhs_card(struct mmc_card > *card) > > /* SPI mode doesn't define CMD19 */ > if (!mmc_host_is_spi(card->host) && card->host->ops- > >execute_tuning) > - err = card->host->ops->execute_tuning(card->host); > + err = card->host->ops->execute_tuning(card->host, \ > + MMC_SEND_TUNING_BLOCK); > > out: > kfree(status); > diff --git a/drivers/mmc/core/sdio.c b/drivers/mmc/core/sdio.c > index 8c04f7f..8ef8817 100644 > --- a/drivers/mmc/core/sdio.c > +++ b/drivers/mmc/core/sdio.c > @@ -14,6 +14,7 @@ > > #include <linux/mmc/host.h> > #include <linux/mmc/card.h> > +#include <linux/mmc/mmc.h> > #include <linux/mmc/sdio.h> > #include <linux/mmc/sdio_func.h> > #include <linux/mmc/sdio_ids.h> > @@ -556,7 +557,8 @@ static int mmc_sdio_init_uhs_card(struct mmc_card > *card) > > /* Initialize and start re-tuning timer */ > if (!mmc_host_is_spi(card->host) && card->host->ops- > >execute_tuning) > - err = card->host->ops->execute_tuning(card->host); > + err = card->host->ops->execute_tuning(card->host, > + MMC_SEND_TUNING_BLOCK); > > out: > > diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c > index a7c2311..13d74bb 100644 > --- a/drivers/mmc/host/sdhci.c > +++ b/drivers/mmc/host/sdhci.c > @@ -49,7 +49,7 @@ static void sdhci_finish_data(struct sdhci_host *); > > static void sdhci_send_command(struct sdhci_host *, struct mmc_command > *); > static void sdhci_finish_command(struct sdhci_host *); > -static int sdhci_execute_tuning(struct mmc_host *mmc); > +static int sdhci_execute_tuning(struct mmc_host *mmc, u32 opcode); > static void sdhci_tuning_timer(unsigned long data); > > #ifdef CONFIG_PM_RUNTIME > @@ -1016,7 +1016,8 @@ static void sdhci_send_command(struct sdhci_host > *host, struct mmc_command *cmd) > flags |= SDHCI_CMD_INDEX; > > /* CMD19 is special in that the Data Present Select should be set > */ > - if (cmd->data || (cmd->opcode == MMC_SEND_TUNING_BLOCK)) > + if (cmd->data || (cmd->opcode == MMC_SEND_TUNING_BLOCK) || > + (cmd->opcode == MMC_SEND_TUNING_BLOCK_HS200)) > flags |= SDHCI_CMD_DATA; > > sdhci_writew(host, SDHCI_MAKE_CMD(cmd->opcode, flags), > SDHCI_COMMAND); > @@ -1287,7 +1288,7 @@ static void sdhci_request(struct mmc_host *mmc, > struct mmc_request *mrq) > if ((host->flags & SDHCI_NEEDS_RETUNING) && > !(present_state & (SDHCI_DOING_WRITE | > SDHCI_DOING_READ))) { > spin_unlock_irqrestore(&host->lock, flags); > - sdhci_execute_tuning(mmc); > + sdhci_execute_tuning(mmc, mrq->cmd->opcode); > spin_lock_irqsave(&host->lock, flags); > > /* Restore original mmc_request structure */ > @@ -1673,7 +1674,7 @@ static int > sdhci_start_signal_voltage_switch(struct mmc_host *mmc, > return err; > } > > -static int sdhci_execute_tuning(struct mmc_host *mmc) > +static int sdhci_execute_tuning(struct mmc_host *mmc, u32 opcode) > { > struct sdhci_host *host; > u16 ctrl; > @@ -1694,10 +1695,13 @@ static int sdhci_execute_tuning(struct mmc_host > *mmc) > * Host Controller needs tuning only in case of SDR104 mode > * and for SDR50 mode when Use Tuning for SDR50 is set in > * Capabilities register. > + * If the Host Controller supports the HS200 mode then tuning > + * function has to be executed. > */ > if (((ctrl & SDHCI_CTRL_UHS_MASK) == SDHCI_CTRL_UHS_SDR104) || > (((ctrl & SDHCI_CTRL_UHS_MASK) == SDHCI_CTRL_UHS_SDR50) && > - (host->flags & SDHCI_SDR50_NEEDS_TUNING))) > + (host->flags & SDHCI_SDR50_NEEDS_TUNING)) || > + (host->flags & SDHCI_HS200_NEEDS_TUNING)) > ctrl |= SDHCI_CTRL_EXEC_TUNING; > else { > spin_unlock(&host->lock); > @@ -1733,7 +1737,7 @@ static int sdhci_execute_tuning(struct mmc_host > *mmc) > if (!tuning_loop_counter && !timeout) > break; > > - cmd.opcode = MMC_SEND_TUNING_BLOCK; > + cmd.opcode = opcode; > cmd.arg = 0; > cmd.flags = MMC_RSP_R1 | MMC_CMD_ADTC; > cmd.retries = 0; > @@ -1748,7 +1752,17 @@ static int sdhci_execute_tuning(struct mmc_host > *mmc) > * block to the Host Controller. So we set the block size > * to 64 here. > */ > - sdhci_writew(host, SDHCI_MAKE_BLKSZ(7, 64), > SDHCI_BLOCK_SIZE); > + if (cmd.opcode == MMC_SEND_TUNING_BLOCK_HS200) { > + if (mmc->ios.bus_width == MMC_BUS_WIDTH_8) > + sdhci_writew(host, SDHCI_MAKE_BLKSZ(7, 128), > + SDHCI_BLOCK_SIZE); > + else if (mmc->ios.bus_width == MMC_BUS_WIDTH_4) > + sdhci_writew(host, SDHCI_MAKE_BLKSZ(7, 64), > + SDHCI_BLOCK_SIZE); > + } else { > + sdhci_writew(host, SDHCI_MAKE_BLKSZ(7, 64), > + SDHCI_BLOCK_SIZE); > + } > > /* > * The tuning block is sent by the card to the host > controller. > @@ -2131,12 +2145,14 @@ static void sdhci_show_adma_error(struct > sdhci_host *host) { } > > static void sdhci_data_irq(struct sdhci_host *host, u32 intmask) > { > + u32 command; > BUG_ON(intmask == 0); > > /* CMD19 generates _only_ Buffer Read Ready interrupt */ > if (intmask & SDHCI_INT_DATA_AVAIL) { > - if (SDHCI_GET_CMD(sdhci_readw(host, SDHCI_COMMAND)) == > - MMC_SEND_TUNING_BLOCK) { > + command = SDHCI_GET_CMD(sdhci_readw(host, SDHCI_COMMAND)); > + if ((command == MMC_SEND_TUNING_BLOCK) || > + (command == MMC_SEND_TUNING_BLOCK_HS200)) { > host->tuning_done = 1; > wake_up(&host->buf_ready_int); > return; > @@ -2741,6 +2757,10 @@ int sdhci_add_host(struct sdhci_host *host) > if (caps[1] & SDHCI_USE_SDR50_TUNING) > host->flags |= SDHCI_SDR50_NEEDS_TUNING; > > + /* Does the host needs tuning for HS200? */ > + if (mmc->caps2 & MMC_CAP2_HS200) > + host->flags |= SDHCI_HS200_NEEDS_TUNING; > + > /* Driver Type(s) (A, C, D) supported by the host */ > if (caps[1] & SDHCI_DRIVER_TYPE_A) > mmc->caps |= MMC_CAP_DRIVER_TYPE_A; > diff --git a/include/linux/mmc/card.h b/include/linux/mmc/card.h > index 534974c..e76f649 100644 > --- a/include/linux/mmc/card.h > +++ b/include/linux/mmc/card.h > @@ -209,6 +209,7 @@ struct mmc_card { > #define MMC_STATE_HIGHSPEED_DDR (1<<4) /* card is in high > speed mode */ > #define MMC_STATE_ULTRAHIGHSPEED (1<<5) /* card is in ultra > high speed mode */ > #define MMC_CARD_SDXC (1<<6) /* card is SDXC */ > +#define MMC_STATE_HIGHSPEED_200 (1<<7) /* card is in HS200 > mode */ > unsigned int quirks; /* card quirks */ > #define MMC_QUIRK_LENIENT_FN0 (1<<0) /* allow SDIO FN0 > writes outside of the VS CCCR range */ > #define MMC_QUIRK_BLKSZ_FOR_BYTE_MODE (1<<1) /* use func- > >cur_blksize */ > @@ -365,6 +366,7 @@ static inline void __maybe_unused > remove_quirk(struct mmc_card *card, int data) > #define mmc_card_present(c) ((c)->state & MMC_STATE_PRESENT) > #define mmc_card_readonly(c) ((c)->state & MMC_STATE_READONLY) > #define mmc_card_highspeed(c) ((c)->state & MMC_STATE_HIGHSPEED) > +#define mmc_card_hs200(c) ((c)->state & MMC_STATE_HIGHSPEED_200) > #define mmc_card_blockaddr(c) ((c)->state & MMC_STATE_BLOCKADDR) > #define mmc_card_ddr_mode(c) ((c)->state & MMC_STATE_HIGHSPEED_DDR) > #define mmc_card_uhs(c) ((c)->state & > MMC_STATE_ULTRAHIGHSPEED) > @@ -374,6 +376,7 @@ static inline void __maybe_unused > remove_quirk(struct mmc_card *card, int data) > #define mmc_card_set_present(c) ((c)->state |= MMC_STATE_PRESENT) > #define mmc_card_set_readonly(c) ((c)->state |= MMC_STATE_READONLY) > #define mmc_card_set_highspeed(c) ((c)->state |= MMC_STATE_HIGHSPEED) > +#define mmc_card_set_hs200(c) ((c)->state |= > MMC_STATE_HIGHSPEED_200) > #define mmc_card_set_blockaddr(c) ((c)->state |= MMC_STATE_BLOCKADDR) > #define mmc_card_set_ddr_mode(c) ((c)->state |= > MMC_STATE_HIGHSPEED_DDR) > #define mmc_card_set_uhs(c) ((c)->state |= MMC_STATE_ULTRAHIGHSPEED) > diff --git a/include/linux/mmc/host.h b/include/linux/mmc/host.h > index 706f722..5eac57a 100644 > --- a/include/linux/mmc/host.h > +++ b/include/linux/mmc/host.h > @@ -50,6 +50,7 @@ struct mmc_ios { > > #define MMC_TIMING_LEGACY 0 > #define MMC_TIMING_MMC_HS 1 > +#define MMC_TIMING_MMC_HS200 2 > #define MMC_TIMING_SD_HS 2 > #define MMC_TIMING_UHS_SDR12 MMC_TIMING_LEGACY > #define MMC_TIMING_UHS_SDR25 MMC_TIMING_SD_HS > @@ -60,6 +61,8 @@ struct mmc_ios { > #define MMC_SDR_MODE 0 > #define MMC_1_2V_DDR_MODE 1 > #define MMC_1_8V_DDR_MODE 2 > +#define MMC_1_2V_SDR_MODE 3 > +#define MMC_1_8V_SDR_MODE 4 > > unsigned char signal_voltage; /* signalling voltage > (1.8V or 3.3V) */ > > @@ -148,7 +151,9 @@ struct mmc_host_ops { > void (*init_card)(struct mmc_host *host, struct mmc_card *card); > > int (*start_signal_voltage_switch)(struct mmc_host *host, > struct mmc_ios *ios); > - int (*execute_tuning)(struct mmc_host *host); > + > + /* The tuning command opcode value is different for SD and eMMC > cards */ > + int (*execute_tuning)(struct mmc_host *host, u32 opcode); > void (*enable_preset_value)(struct mmc_host *host, bool enable); > int (*select_drive_strength)(unsigned int max_dtr, int > host_drv, int card_drv); > void (*hw_reset)(struct mmc_host *host); > @@ -242,6 +247,10 @@ struct mmc_host { > #define MMC_CAP2_CACHE_CTRL (1 << 1) /* Allow cache control */ > #define MMC_CAP2_POWEROFF_NOTIFY (1 << 2) /* Notify poweroff > supported */ > #define MMC_CAP2_NO_MULTI_READ (1 << 3) /* Multiblock reads > don't work */ > +#define MMC_CAP2_HS200_1_8V_SDR (1 << 4) /* can support */ > +#define MMC_CAP2_HS200_1_2V_SDR (1 << 5) /* can support */ > +#define MMC_CAP2_HS200 (MMC_CAP2_HS200_1_8V_SDR | \ > + MMC_CAP2_HS200_1_2V_SDR) > > mmc_pm_flag_t pm_caps; /* supported pm features */ > unsigned int power_notify_type; > diff --git a/include/linux/mmc/mmc.h b/include/linux/mmc/mmc.h > index 0e71356..7996272 100644 > --- a/include/linux/mmc/mmc.h > +++ b/include/linux/mmc/mmc.h > @@ -51,6 +51,7 @@ > #define MMC_READ_SINGLE_BLOCK 17 /* adtc [31:0] data addr R1 > */ > #define MMC_READ_MULTIPLE_BLOCK 18 /* adtc [31:0] data addr R1 > */ > #define MMC_SEND_TUNING_BLOCK 19 /* adtc R1 > */ > +#define MMC_SEND_TUNING_BLOCK_HS200 21 /* adtc R1 */ > > /* class 3 */ > #define MMC_WRITE_DAT_UNTIL_STOP 20 /* adtc [31:0] data addr R1 > */ > @@ -333,13 +334,76 @@ struct _mmc_csd { > > #define EXT_CSD_CARD_TYPE_26 (1<<0) /* Card can run at 26MHz */ > #define EXT_CSD_CARD_TYPE_52 (1<<1) /* Card can run at 52MHz */ > -#define EXT_CSD_CARD_TYPE_MASK 0xF /* Mask out reserved bits */ > +#define EXT_CSD_CARD_TYPE_MASK 0x3F /* Mask out reserved bits */ > #define EXT_CSD_CARD_TYPE_DDR_1_8V (1<<2) /* Card can run at 52MHz > */ > /* DDR mode @1.8V or 3V I/O */ > #define EXT_CSD_CARD_TYPE_DDR_1_2V (1<<3) /* Card can run at 52MHz > */ > /* DDR mode @1.2V I/O */ > #define EXT_CSD_CARD_TYPE_DDR_52 (EXT_CSD_CARD_TYPE_DDR_1_8V \ > | EXT_CSD_CARD_TYPE_DDR_1_2V) > +#define EXT_CSD_CARD_TYPE_SDR_1_8V (1<<4) /* Card can run at > 200MHz */ > +#define EXT_CSD_CARD_TYPE_SDR_1_2V (1<<5) /* Card can run at > 200MHz */ > + /* SDR mode @1.2V I/O */ > + > +#define EXT_CSD_CARD_TYPE_SDR_200 (EXT_CSD_CARD_TYPE_SDR_1_8V \ > + | EXT_CSD_CARD_TYPE_SDR_1_2V) > + > +#define EXT_CSD_CARD_TYPE_SDR_ALL (EXT_CSD_CARD_TYPE_SDR_200 \ > + | EXT_CSD_CARD_TYPE_52 \ > + | EXT_CSD_CARD_TYPE_26) > + > +#define EXT_CSD_CARD_TYPE_SDR_1_2V_ALL > (EXT_CSD_CARD_TYPE_SDR_1_2V \ > + | EXT_CSD_CARD_TYPE_52 \ > + | EXT_CSD_CARD_TYPE_26) > + > +#define EXT_CSD_CARD_TYPE_SDR_1_8V_ALL > (EXT_CSD_CARD_TYPE_SDR_1_8V \ > + | EXT_CSD_CARD_TYPE_52 \ > + | EXT_CSD_CARD_TYPE_26) > + > +#define EXT_CSD_CARD_TYPE_SDR_1_2V_DDR_1_8V > (EXT_CSD_CARD_TYPE_SDR_1_2V \ > + | EXT_CSD_CARD_TYPE_DDR_1_8V \ > + | EXT_CSD_CARD_TYPE_52 \ > + | EXT_CSD_CARD_TYPE_26) > + > +#define EXT_CSD_CARD_TYPE_SDR_1_8V_DDR_1_8V > (EXT_CSD_CARD_TYPE_SDR_1_8V \ > + | EXT_CSD_CARD_TYPE_DDR_1_8V \ > + | EXT_CSD_CARD_TYPE_52 \ > + | EXT_CSD_CARD_TYPE_26) > + > +#define EXT_CSD_CARD_TYPE_SDR_1_2V_DDR_1_2V > (EXT_CSD_CARD_TYPE_SDR_1_2V \ > + | EXT_CSD_CARD_TYPE_DDR_1_2V \ > + | EXT_CSD_CARD_TYPE_52 \ > + | EXT_CSD_CARD_TYPE_26) > + > +#define EXT_CSD_CARD_TYPE_SDR_1_8V_DDR_1_2V > (EXT_CSD_CARD_TYPE_SDR_1_8V \ > + | EXT_CSD_CARD_TYPE_DDR_1_2V \ > + | EXT_CSD_CARD_TYPE_52 \ > + | EXT_CSD_CARD_TYPE_26) > + > +#define EXT_CSD_CARD_TYPE_SDR_1_2V_DDR_52 > (EXT_CSD_CARD_TYPE_SDR_1_2V \ > + | EXT_CSD_CARD_TYPE_DDR_52 \ > + | EXT_CSD_CARD_TYPE_52 \ > + | EXT_CSD_CARD_TYPE_26) > + > +#define EXT_CSD_CARD_TYPE_SDR_1_8V_DDR_52 > (EXT_CSD_CARD_TYPE_SDR_1_8V \ > + | EXT_CSD_CARD_TYPE_DDR_52 \ > + | EXT_CSD_CARD_TYPE_52 \ > + | EXT_CSD_CARD_TYPE_26) > + > +#define EXT_CSD_CARD_TYPE_SDR_ALL_DDR_1_8V > (EXT_CSD_CARD_TYPE_SDR_200 \ > + | EXT_CSD_CARD_TYPE_DDR_1_8V \ > + | EXT_CSD_CARD_TYPE_52 \ > + | EXT_CSD_CARD_TYPE_26) > + > +#define EXT_CSD_CARD_TYPE_SDR_ALL_DDR_1_2V > (EXT_CSD_CARD_TYPE_SDR_200 \ > + | EXT_CSD_CARD_TYPE_DDR_1_2V \ > + | EXT_CSD_CARD_TYPE_52 \ > + | EXT_CSD_CARD_TYPE_26) > + > +#define EXT_CSD_CARD_TYPE_SDR_ALL_DDR_52 (EXT_CSD_CARD_TYPE_SDR_200 > \ > + | EXT_CSD_CARD_TYPE_DDR_52 \ > + | EXT_CSD_CARD_TYPE_52 \ > + | EXT_CSD_CARD_TYPE_26) > > #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 */ > diff --git a/include/linux/mmc/sdhci.h b/include/linux/mmc/sdhci.h > index e4b6935..d9a2222 100644 > --- a/include/linux/mmc/sdhci.h > +++ b/include/linux/mmc/sdhci.h > @@ -121,6 +121,7 @@ struct sdhci_host { > #define SDHCI_AUTO_CMD23 (1<<7) /* Auto CMD23 support */ > #define SDHCI_PV_ENABLED (1<<8) /* Preset value enabled */ > #define SDHCI_SDIO_IRQ_ENABLED (1<<9) /* SDIO irq enabled */ > +#define SDHCI_HS200_NEEDS_TUNING (1<<10) /* HS200 needs tuning */ > > unsigned int version; /* SDHCI spec. version */ > > -- > 1.7.1 > > -- > To unsubscribe from this list: send the line "unsubscribe linux-mmc" in > the body of a message to majordomo@xxxxxxxxxxxxxxx > More majordomo info at http://vger.kernel.org/majordomo-info.html -- To unsubscribe from this list: send the line "unsubscribe linux-mmc" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html