aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/mmc
diff options
context:
space:
mode:
authorKevin Liu <kliu5@marvell.com>2012-12-17 06:29:26 -0500
committerChris Ball <cjb@laptop.org>2013-02-24 14:37:09 -0500
commit20b92a30b5610a5222060417961bc4ccb42ea5a5 (patch)
tree53672837a479970a0db28626907aaa0ff7250522 /drivers/mmc
parent0797e5f1453b2bedc08bbcbea0ea4fbe20350823 (diff)
mmc: sdhci: update signal voltage switch code
The protocol related code is moved to core stack. So update the host driver accordingly. Signed-off-by: Kevin Liu <kliu5@marvell.com> Tested-by: Tim Wang <wangtt@marvell.com> Signed-off-by: Chris Ball <cjb@laptop.org>
Diffstat (limited to 'drivers/mmc')
-rw-r--r--drivers/mmc/host/sdhci.c192
1 files changed, 78 insertions, 114 deletions
diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c
index 3bb9b88772cf..efb112684787 100644
--- a/drivers/mmc/host/sdhci.c
+++ b/drivers/mmc/host/sdhci.c
@@ -1615,145 +1615,95 @@ static void sdhci_enable_sdio_irq(struct mmc_host *mmc, int enable)
1615 spin_unlock_irqrestore(&host->lock, flags); 1615 spin_unlock_irqrestore(&host->lock, flags);
1616} 1616}
1617 1617
1618static int sdhci_do_3_3v_signal_voltage_switch(struct sdhci_host *host, 1618static int sdhci_do_start_signal_voltage_switch(struct sdhci_host *host,
1619 u16 ctrl) 1619 int signal_voltage)
1620{ 1620{
1621 u16 ctrl;
1621 int ret; 1622 int ret;
1622 1623
1623 /* Set 1.8V Signal Enable in the Host Control2 register to 0 */ 1624 /*
1624 ctrl &= ~SDHCI_CTRL_VDD_180; 1625 * Signal Voltage Switching is only applicable for Host Controllers
1625 sdhci_writew(host, ctrl, SDHCI_HOST_CONTROL2); 1626 * v3.00 and above.
1626 1627 */
1627 if (host->vqmmc) { 1628 if (host->version < SDHCI_SPEC_300)
1628 ret = regulator_set_voltage(host->vqmmc, 2700000, 3600000); 1629 return 0;
1629 if (ret) {
1630 pr_warning("%s: Switching to 3.3V signalling voltage "
1631 " failed\n", mmc_hostname(host->mmc));
1632 return -EIO;
1633 }
1634 }
1635 /* Wait for 5ms */
1636 usleep_range(5000, 5500);
1637 1630
1638 /* 3.3V regulator output should be stable within 5 ms */
1639 ctrl = sdhci_readw(host, SDHCI_HOST_CONTROL2); 1631 ctrl = sdhci_readw(host, SDHCI_HOST_CONTROL2);
1640 if (!(ctrl & SDHCI_CTRL_VDD_180))
1641 return 0;
1642 1632
1643 pr_warning("%s: 3.3V regulator output did not became stable\n", 1633 switch (signal_voltage) {
1644 mmc_hostname(host->mmc)); 1634 case MMC_SIGNAL_VOLTAGE_330:
1635 /* Set 1.8V Signal Enable in the Host Control2 register to 0 */
1636 ctrl &= ~SDHCI_CTRL_VDD_180;
1637 sdhci_writew(host, ctrl, SDHCI_HOST_CONTROL2);
1645 1638
1646 return -EIO; 1639 if (host->vqmmc) {
1647} 1640 ret = regulator_set_voltage(host->vqmmc, 2700000, 3600000);
1641 if (ret) {
1642 pr_warning("%s: Switching to 3.3V signalling voltage "
1643 " failed\n", mmc_hostname(host->mmc));
1644 return -EIO;
1645 }
1646 }
1647 /* Wait for 5ms */
1648 usleep_range(5000, 5500);
1648 1649
1649static int sdhci_do_1_8v_signal_voltage_switch(struct sdhci_host *host, 1650 /* 3.3V regulator output should be stable within 5 ms */
1650 u16 ctrl) 1651 ctrl = sdhci_readw(host, SDHCI_HOST_CONTROL2);
1651{ 1652 if (!(ctrl & SDHCI_CTRL_VDD_180))
1652 u8 pwr; 1653 return 0;
1653 u16 clk;
1654 u32 present_state;
1655 int ret;
1656 1654
1657 /* Stop SDCLK */ 1655 pr_warning("%s: 3.3V regulator output did not became stable\n",
1658 clk = sdhci_readw(host, SDHCI_CLOCK_CONTROL); 1656 mmc_hostname(host->mmc));
1659 clk &= ~SDHCI_CLOCK_CARD_EN; 1657
1660 sdhci_writew(host, clk, SDHCI_CLOCK_CONTROL); 1658 return -EAGAIN;
1659 case MMC_SIGNAL_VOLTAGE_180:
1660 if (host->vqmmc) {
1661 ret = regulator_set_voltage(host->vqmmc,
1662 1700000, 1950000);
1663 if (ret) {
1664 pr_warning("%s: Switching to 1.8V signalling voltage "
1665 " failed\n", mmc_hostname(host->mmc));
1666 return -EIO;
1667 }
1668 }
1661 1669
1662 /* Check whether DAT[3:0] is 0000 */
1663 present_state = sdhci_readl(host, SDHCI_PRESENT_STATE);
1664 if (!((present_state & SDHCI_DATA_LVL_MASK) >>
1665 SDHCI_DATA_LVL_SHIFT)) {
1666 /* 1670 /*
1667 * Enable 1.8V Signal Enable in the Host Control2 1671 * Enable 1.8V Signal Enable in the Host Control2
1668 * register 1672 * register
1669 */ 1673 */
1670 if (host->vqmmc) 1674 ctrl |= SDHCI_CTRL_VDD_180;
1671 ret = regulator_set_voltage(host->vqmmc, 1675 sdhci_writew(host, ctrl, SDHCI_HOST_CONTROL2);
1672 1700000, 1950000);
1673 else
1674 ret = 0;
1675 1676
1676 if (!ret) { 1677 /* Wait for 5ms */
1677 ctrl |= SDHCI_CTRL_VDD_180; 1678 usleep_range(5000, 5500);
1678 sdhci_writew(host, ctrl, SDHCI_HOST_CONTROL2);
1679 1679
1680 /* Wait for 5ms */ 1680 /* 1.8V regulator output should be stable within 5 ms */
1681 usleep_range(5000, 5500); 1681 ctrl = sdhci_readw(host, SDHCI_HOST_CONTROL2);
1682 if (ctrl & SDHCI_CTRL_VDD_180)
1683 return 0;
1682 1684
1683 ctrl = sdhci_readw(host, SDHCI_HOST_CONTROL2); 1685 pr_warning("%s: 1.8V regulator output did not became stable\n",
1684 if (ctrl & SDHCI_CTRL_VDD_180) { 1686 mmc_hostname(host->mmc));
1685 /* Provide SDCLK again and wait for 1ms */
1686 clk = sdhci_readw(host, SDHCI_CLOCK_CONTROL);
1687 clk |= SDHCI_CLOCK_CARD_EN;
1688 sdhci_writew(host, clk, SDHCI_CLOCK_CONTROL);
1689 usleep_range(1000, 1500);
1690 1687
1691 /* 1688 return -EAGAIN;
1692 * If DAT[3:0] level is 1111b, then the card 1689 case MMC_SIGNAL_VOLTAGE_120:
1693 * was successfully switched to 1.8V signaling. 1690 if (host->vqmmc) {
1694 */ 1691 ret = regulator_set_voltage(host->vqmmc, 1100000, 1300000);
1695 present_state = sdhci_readl(host, 1692 if (ret) {
1696 SDHCI_PRESENT_STATE); 1693 pr_warning("%s: Switching to 1.2V signalling voltage "
1697 if ((present_state & SDHCI_DATA_LVL_MASK) == 1694 " failed\n", mmc_hostname(host->mmc));
1698 SDHCI_DATA_LVL_MASK) 1695 return -EIO;
1699 return 0;
1700 } 1696 }
1701 } 1697 }
1702 }
1703
1704 /*
1705 * If we are here, that means the switch to 1.8V signaling
1706 * failed. We power cycle the card, and retry initialization
1707 * sequence by setting S18R to 0.
1708 */
1709 pwr = sdhci_readb(host, SDHCI_POWER_CONTROL);
1710 pwr &= ~SDHCI_POWER_ON;
1711 sdhci_writeb(host, pwr, SDHCI_POWER_CONTROL);
1712 if (host->vmmc)
1713 regulator_disable(host->vmmc);
1714
1715 /* Wait for 1ms as per the spec */
1716 usleep_range(1000, 1500);
1717 pwr |= SDHCI_POWER_ON;
1718 sdhci_writeb(host, pwr, SDHCI_POWER_CONTROL);
1719 if (host->vmmc)
1720 regulator_enable(host->vmmc);
1721
1722 pr_warning("%s: Switching to 1.8V signalling voltage failed, "
1723 "retrying with S18R set to 0\n", mmc_hostname(host->mmc));
1724
1725 return -EAGAIN;
1726}
1727
1728static int sdhci_do_start_signal_voltage_switch(struct sdhci_host *host,
1729 struct mmc_ios *ios)
1730{
1731 u16 ctrl;
1732
1733 /*
1734 * Signal Voltage Switching is only applicable for Host Controllers
1735 * v3.00 and above.
1736 */
1737 if (host->version < SDHCI_SPEC_300)
1738 return 0; 1698 return 0;
1739 1699 default:
1740 /*
1741 * We first check whether the request is to set signalling voltage
1742 * to 3.3V. If so, we change the voltage to 3.3V and return quickly.
1743 */
1744 ctrl = sdhci_readw(host, SDHCI_HOST_CONTROL2);
1745 if (ios->signal_voltage == MMC_SIGNAL_VOLTAGE_330)
1746 return sdhci_do_3_3v_signal_voltage_switch(host, ctrl);
1747 else if (!(ctrl & SDHCI_CTRL_VDD_180) &&
1748 (ios->signal_voltage == MMC_SIGNAL_VOLTAGE_180))
1749 return sdhci_do_1_8v_signal_voltage_switch(host, ctrl);
1750 else
1751 /* No signal voltage switch required */ 1700 /* No signal voltage switch required */
1752 return 0; 1701 return 0;
1702 }
1753} 1703}
1754 1704
1755static int sdhci_start_signal_voltage_switch(struct mmc_host *mmc, 1705static int sdhci_start_signal_voltage_switch(struct mmc_host *mmc,
1756 struct mmc_ios *ios) 1706 int signal_voltage)
1757{ 1707{
1758 struct sdhci_host *host = mmc_priv(mmc); 1708 struct sdhci_host *host = mmc_priv(mmc);
1759 int err; 1709 int err;
@@ -1761,11 +1711,24 @@ static int sdhci_start_signal_voltage_switch(struct mmc_host *mmc,
1761 if (host->version < SDHCI_SPEC_300) 1711 if (host->version < SDHCI_SPEC_300)
1762 return 0; 1712 return 0;
1763 sdhci_runtime_pm_get(host); 1713 sdhci_runtime_pm_get(host);
1764 err = sdhci_do_start_signal_voltage_switch(host, ios); 1714 err = sdhci_do_start_signal_voltage_switch(host, signal_voltage);
1765 sdhci_runtime_pm_put(host); 1715 sdhci_runtime_pm_put(host);
1766 return err; 1716 return err;
1767} 1717}
1768 1718
1719static int sdhci_card_busy(struct mmc_host *mmc)
1720{
1721 struct sdhci_host *host = mmc_priv(mmc);
1722 u32 present_state;
1723
1724 sdhci_runtime_pm_get(host);
1725 /* Check whether DAT[3:0] is 0000 */
1726 present_state = sdhci_readl(host, SDHCI_PRESENT_STATE);
1727 sdhci_runtime_pm_put(host);
1728
1729 return !(present_state & SDHCI_DATA_LVL_MASK);
1730}
1731
1769static int sdhci_execute_tuning(struct mmc_host *mmc, u32 opcode) 1732static int sdhci_execute_tuning(struct mmc_host *mmc, u32 opcode)
1770{ 1733{
1771 struct sdhci_host *host; 1734 struct sdhci_host *host;
@@ -2036,6 +1999,7 @@ static const struct mmc_host_ops sdhci_ops = {
2036 .execute_tuning = sdhci_execute_tuning, 1999 .execute_tuning = sdhci_execute_tuning,
2037 .enable_preset_value = sdhci_enable_preset_value, 2000 .enable_preset_value = sdhci_enable_preset_value,
2038 .card_event = sdhci_card_event, 2001 .card_event = sdhci_card_event,
2002 .card_busy = sdhci_card_busy,
2039}; 2003};
2040 2004
2041/*****************************************************************************\ 2005/*****************************************************************************\