aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/mmc/host/sdhci.c
diff options
context:
space:
mode:
authorArindam Nath <arindam.nath@amd.com>2011-05-05 02:49:05 -0400
committerChris Ball <cjb@laptop.org>2011-05-24 23:53:47 -0400
commit4d55c5a13a189a80d40383f02c8026f9a87d7c87 (patch)
tree6151dd86bac16adf96e7aefb6bc0ca6604a0ebc8 /drivers/mmc/host/sdhci.c
parentb513ea250eb7c36a8afb3df938d632ca6b4df7cd (diff)
mmc: sdhci: enable preset value after uhs initialization
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. Tested by Zhangfei Gao with a Toshiba uhs card and general hs card, on mmp2 in SDMA mode. Signed-off-by: Arindam Nath <arindam.nath@amd.com> Reviewed-by: Philip Rakity <prakity@marvell.com> Tested-by: Philip Rakity <prakity@marvell.com> Acked-by: Zhangfei Gao <zhangfei.gao@marvell.com> Signed-off-by: Chris Ball <cjb@laptop.org>
Diffstat (limited to 'drivers/mmc/host/sdhci.c')
-rw-r--r--drivers/mmc/host/sdhci.c32
1 files changed, 32 insertions, 0 deletions
diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c
index 8a56eacea34d..a1ab22415883 100644
--- a/drivers/mmc/host/sdhci.c
+++ b/drivers/mmc/host/sdhci.c
@@ -1649,6 +1649,37 @@ out:
1649 return err; 1649 return err;
1650} 1650}
1651 1651
1652static void sdhci_enable_preset_value(struct mmc_host *mmc, bool enable)
1653{
1654 struct sdhci_host *host;
1655 u16 ctrl;
1656 unsigned long flags;
1657
1658 host = mmc_priv(mmc);
1659
1660 /* Host Controller v3.00 defines preset value registers */
1661 if (host->version < SDHCI_SPEC_300)
1662 return;
1663
1664 spin_lock_irqsave(&host->lock, flags);
1665
1666 ctrl = sdhci_readw(host, SDHCI_HOST_CONTROL2);
1667
1668 /*
1669 * We only enable or disable Preset Value if they are not already
1670 * enabled or disabled respectively. Otherwise, we bail out.
1671 */
1672 if (enable && !(ctrl & SDHCI_CTRL_PRESET_VAL_ENABLE)) {
1673 ctrl |= SDHCI_CTRL_PRESET_VAL_ENABLE;
1674 sdhci_writew(host, ctrl, SDHCI_HOST_CONTROL2);
1675 } else if (!enable && (ctrl & SDHCI_CTRL_PRESET_VAL_ENABLE)) {
1676 ctrl &= ~SDHCI_CTRL_PRESET_VAL_ENABLE;
1677 sdhci_writew(host, ctrl, SDHCI_HOST_CONTROL2);
1678 }
1679
1680 spin_unlock_irqrestore(&host->lock, flags);
1681}
1682
1652static const struct mmc_host_ops sdhci_ops = { 1683static const struct mmc_host_ops sdhci_ops = {
1653 .request = sdhci_request, 1684 .request = sdhci_request,
1654 .set_ios = sdhci_set_ios, 1685 .set_ios = sdhci_set_ios,
@@ -1656,6 +1687,7 @@ static const struct mmc_host_ops sdhci_ops = {
1656 .enable_sdio_irq = sdhci_enable_sdio_irq, 1687 .enable_sdio_irq = sdhci_enable_sdio_irq,
1657 .start_signal_voltage_switch = sdhci_start_signal_voltage_switch, 1688 .start_signal_voltage_switch = sdhci_start_signal_voltage_switch,
1658 .execute_tuning = sdhci_execute_tuning, 1689 .execute_tuning = sdhci_execute_tuning,
1690 .enable_preset_value = sdhci_enable_preset_value,
1659}; 1691};
1660 1692
1661/*****************************************************************************\ 1693/*****************************************************************************\