On Thu, May 5, 2011 at 2:49 AM, Arindam Nath <arindam.nath@xxxxxxx> wrote: > According to the Host Controller spec v3.00, setting Preset Value Enable > in the Host Control2 register lets SDCLK Frequency Select, Clock Generator > Select and Driver Strength Select to be set automatically by the Host > Controller based on the UHS-I mode set. This patch enables this feature. > Since Preset Value Enable makes sense only for UHS-I cards, we enable this > feature after successfull UHS-I initialization. We also reset Preset Value > Enable next time before initialization. > > Signed-off-by: Arindam Nath <arindam.nath@xxxxxxx> > Reviewed-by: Philip Rakity <prakity@xxxxxxxxxxx> > Tested-by: Philip Rakity <prakity@xxxxxxxxxxx> Acked-by: Zhangfei Gao<zhangfei.gao@xxxxxxxxxxx> Verified with Toshiba uhs card and general hs card, on mmp2 in SDMA mode. > --- > drivers/mmc/core/sd.c | 11 +++++++++++ > drivers/mmc/host/sdhci.c | 32 ++++++++++++++++++++++++++++++++ > include/linux/mmc/host.h | 1 + > 3 files changed, 44 insertions(+), 0 deletions(-) > > diff --git a/drivers/mmc/core/sd.c b/drivers/mmc/core/sd.c > index 84cb8c3..851c8fc 100644 > --- a/drivers/mmc/core/sd.c > +++ b/drivers/mmc/core/sd.c > @@ -931,6 +931,13 @@ static int mmc_sd_init_card(struct mmc_host *host, u32 ocr, > > /* Card is an ultra-high-speed card */ > mmc_sd_card_set_uhs(card); > + > + /* > + * Since initialization is now complete, enable preset > + * value registers for UHS-I cards. > + */ > + if (host->ops->enable_preset_value) > + host->ops->enable_preset_value(host, 1); > } else { > /* > * Attempt to change to high-speed (if supported) > @@ -1101,6 +1108,10 @@ int mmc_attach_sd(struct mmc_host *host) > if (err) > return err; > > + /* Disable preset value enable if already set since last time */ > + if (host->ops->enable_preset_value) > + host->ops->enable_preset_value(host, 0); > + > err = mmc_send_app_op_cond(host, 0, &ocr); > if (err) > return err; > diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c > index 85775cf..cb767a0 100644 > --- a/drivers/mmc/host/sdhci.c > +++ b/drivers/mmc/host/sdhci.c > @@ -1655,6 +1655,37 @@ out: > return err; > } > > +static void sdhci_enable_preset_value(struct mmc_host *mmc, int enable) > +{ > + struct sdhci_host *host; > + u16 ctrl; > + unsigned long flags; > + > + host = mmc_priv(mmc); > + > + /* Host Controller v3.00 defines preset value registers */ > + if (host->version < SDHCI_SPEC_300) > + return; > + > + spin_lock_irqsave(&host->lock, flags); > + > + ctrl = sdhci_readw(host, SDHCI_HOST_CONTROL2); > + > + /* > + * We only enable or disable Preset Value if they are not already > + * enabled or disabled respectively. Otherwise, we bail out. > + */ > + if (enable && !(ctrl & SDHCI_CTRL_PRESET_VAL_ENABLE)) { > + ctrl |= SDHCI_CTRL_PRESET_VAL_ENABLE; > + sdhci_writew(host, ctrl, SDHCI_HOST_CONTROL2); > + } else if (!enable && (ctrl & SDHCI_CTRL_PRESET_VAL_ENABLE)) { > + ctrl &= ~SDHCI_CTRL_PRESET_VAL_ENABLE; > + sdhci_writew(host, ctrl, SDHCI_HOST_CONTROL2); > + } > + > + spin_unlock_irqrestore(&host->lock, flags); > +} > + > static const struct mmc_host_ops sdhci_ops = { > .request = sdhci_request, > .set_ios = sdhci_set_ios, > @@ -1662,6 +1693,7 @@ static const struct mmc_host_ops sdhci_ops = { > .enable_sdio_irq = sdhci_enable_sdio_irq, > .start_signal_voltage_switch = sdhci_start_signal_voltage_switch, > .execute_tuning = sdhci_execute_tuning, > + .enable_preset_value = sdhci_enable_preset_value, > }; > > /*****************************************************************************\ > diff --git a/include/linux/mmc/host.h b/include/linux/mmc/host.h > index ca7007f..2209e01 100644 > --- a/include/linux/mmc/host.h > +++ b/include/linux/mmc/host.h > @@ -137,6 +137,7 @@ struct mmc_host_ops { > > int (*start_signal_voltage_switch)(struct mmc_host *host, struct mmc_ios *ios); > int (*execute_tuning)(struct mmc_host *host); > + void (*enable_preset_value)(struct mmc_host *host, int enable); > }; > > struct mmc_card; > -- > 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