aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/mmc
diff options
context:
space:
mode:
authorPhilip Rakity <prakity@marvell.com>2012-07-23 18:56:23 -0400
committerChris Ball <cjb@laptop.org>2012-09-04 13:58:13 -0400
commit6231f3de1332b2a8a90e0c598ab6acc8f1eff7c1 (patch)
treebf43eafe176d49684116b5454a81e67b5c12db90 /drivers/mmc
parent137ccd46c5efaed6a8118cce3db2cbb64350113b (diff)
mmc: sdhci: Add regulator support for vccq (voltage regualor)
On some systems the host controller does not support vccq signaling. This is supplied by a dedicated regulator (vqmmc). Add support for this regulator. Signed-off-by: Philip Rakity <prakity@marvell.com> Signed-off-by: Chris Ball <cjb@laptop.org>
Diffstat (limited to 'drivers/mmc')
-rw-r--r--drivers/mmc/host/sdhci.c181
1 files changed, 116 insertions, 65 deletions
diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c
index 9a11dc39921c..828ac6c2990c 100644
--- a/drivers/mmc/host/sdhci.c
+++ b/drivers/mmc/host/sdhci.c
@@ -1597,57 +1597,65 @@ static void sdhci_enable_sdio_irq(struct mmc_host *mmc, int enable)
1597 spin_unlock_irqrestore(&host->lock, flags); 1597 spin_unlock_irqrestore(&host->lock, flags);
1598} 1598}
1599 1599
1600static int sdhci_do_start_signal_voltage_switch(struct sdhci_host *host, 1600static int sdhci_do_3_3v_signal_voltage_switch(struct sdhci_host *host,
1601 struct mmc_ios *ios) 1601 u16 ctrl)
1602{ 1602{
1603 u8 pwr; 1603 int ret;
1604 u16 clk, ctrl;
1605 u32 present_state;
1606 1604
1607 /* 1605 /* Set 1.8V Signal Enable in the Host Control2 register to 0 */
1608 * Signal Voltage Switching is only applicable for Host Controllers 1606 ctrl &= ~SDHCI_CTRL_VDD_180;
1609 * v3.00 and above. 1607 sdhci_writew(host, ctrl, SDHCI_HOST_CONTROL2);
1610 */
1611 if (host->version < SDHCI_SPEC_300)
1612 return 0;
1613 1608
1614 /* 1609 if (host->vqmmc) {
1615 * We first check whether the request is to set signalling voltage 1610 ret = regulator_set_voltage(host->vqmmc, 3300000, 3300000);
1616 * to 3.3V. If so, we change the voltage to 3.3V and return quickly. 1611 if (ret) {
1617 */ 1612 pr_warning("%s: Switching to 3.3V signalling voltage "
1613 " failed\n", mmc_hostname(host->mmc));
1614 return -EIO;
1615 }
1616 }
1617 /* Wait for 5ms */
1618 usleep_range(5000, 5500);
1619
1620 /* 3.3V regulator output should be stable within 5 ms */
1618 ctrl = sdhci_readw(host, SDHCI_HOST_CONTROL2); 1621 ctrl = sdhci_readw(host, SDHCI_HOST_CONTROL2);
1619 if (ios->signal_voltage == MMC_SIGNAL_VOLTAGE_330) { 1622 if (!(ctrl & SDHCI_CTRL_VDD_180))
1620 /* Set 1.8V Signal Enable in the Host Control2 register to 0 */ 1623 return 0;
1621 ctrl &= ~SDHCI_CTRL_VDD_180;
1622 sdhci_writew(host, ctrl, SDHCI_HOST_CONTROL2);
1623 1624
1624 /* Wait for 5ms */ 1625 pr_warning("%s: 3.3V regulator output did not became stable\n",
1625 usleep_range(5000, 5500); 1626 mmc_hostname(host->mmc));
1626 1627
1627 /* 3.3V regulator output should be stable within 5 ms */ 1628 return -EIO;
1628 ctrl = sdhci_readw(host, SDHCI_HOST_CONTROL2); 1629}
1629 if (!(ctrl & SDHCI_CTRL_VDD_180))
1630 return 0;
1631 else {
1632 pr_info(DRIVER_NAME ": Switching to 3.3V "
1633 "signalling voltage failed\n");
1634 return -EIO;
1635 }
1636 } else if (!(ctrl & SDHCI_CTRL_VDD_180) &&
1637 (ios->signal_voltage == MMC_SIGNAL_VOLTAGE_180)) {
1638 /* Stop SDCLK */
1639 clk = sdhci_readw(host, SDHCI_CLOCK_CONTROL);
1640 clk &= ~SDHCI_CLOCK_CARD_EN;
1641 sdhci_writew(host, clk, SDHCI_CLOCK_CONTROL);
1642 1630
1643 /* Check whether DAT[3:0] is 0000 */ 1631static int sdhci_do_1_8v_signal_voltage_switch(struct sdhci_host *host,
1644 present_state = sdhci_readl(host, SDHCI_PRESENT_STATE); 1632 u16 ctrl)
1645 if (!((present_state & SDHCI_DATA_LVL_MASK) >> 1633{
1646 SDHCI_DATA_LVL_SHIFT)) { 1634 u8 pwr;
1647 /* 1635 u16 clk;
1648 * Enable 1.8V Signal Enable in the Host Control2 1636 u32 present_state;
1649 * register 1637 int ret;
1650 */ 1638
1639 /* Stop SDCLK */
1640 clk = sdhci_readw(host, SDHCI_CLOCK_CONTROL);
1641 clk &= ~SDHCI_CLOCK_CARD_EN;
1642 sdhci_writew(host, clk, SDHCI_CLOCK_CONTROL);
1643
1644 /* Check whether DAT[3:0] is 0000 */
1645 present_state = sdhci_readl(host, SDHCI_PRESENT_STATE);
1646 if (!((present_state & SDHCI_DATA_LVL_MASK) >>
1647 SDHCI_DATA_LVL_SHIFT)) {
1648 /*
1649 * Enable 1.8V Signal Enable in the Host Control2
1650 * register
1651 */
1652 if (host->vqmmc)
1653 ret = regulator_set_voltage(host->vqmmc,
1654 1800000, 1800000);
1655 else
1656 ret = 0;
1657
1658 if (!ret) {
1651 ctrl |= SDHCI_CTRL_VDD_180; 1659 ctrl |= SDHCI_CTRL_VDD_180;
1652 sdhci_writew(host, ctrl, SDHCI_HOST_CONTROL2); 1660 sdhci_writew(host, ctrl, SDHCI_HOST_CONTROL2);
1653 1661
@@ -1656,7 +1664,7 @@ static int sdhci_do_start_signal_voltage_switch(struct sdhci_host *host,
1656 1664
1657 ctrl = sdhci_readw(host, SDHCI_HOST_CONTROL2); 1665 ctrl = sdhci_readw(host, SDHCI_HOST_CONTROL2);
1658 if (ctrl & SDHCI_CTRL_VDD_180) { 1666 if (ctrl & SDHCI_CTRL_VDD_180) {
1659 /* Provide SDCLK again and wait for 1ms*/ 1667 /* Provide SDCLK again and wait for 1ms */
1660 clk = sdhci_readw(host, SDHCI_CLOCK_CONTROL); 1668 clk = sdhci_readw(host, SDHCI_CLOCK_CONTROL);
1661 clk |= SDHCI_CLOCK_CARD_EN; 1669 clk |= SDHCI_CLOCK_CARD_EN;
1662 sdhci_writew(host, clk, SDHCI_CLOCK_CONTROL); 1670 sdhci_writew(host, clk, SDHCI_CLOCK_CONTROL);
@@ -1673,29 +1681,55 @@ static int sdhci_do_start_signal_voltage_switch(struct sdhci_host *host,
1673 return 0; 1681 return 0;
1674 } 1682 }
1675 } 1683 }
1684 }
1676 1685
1677 /* 1686 /*
1678 * If we are here, that means the switch to 1.8V signaling 1687 * If we are here, that means the switch to 1.8V signaling
1679 * failed. We power cycle the card, and retry initialization 1688 * failed. We power cycle the card, and retry initialization
1680 * sequence by setting S18R to 0. 1689 * sequence by setting S18R to 0.
1681 */ 1690 */
1682 pwr = sdhci_readb(host, SDHCI_POWER_CONTROL); 1691 pwr = sdhci_readb(host, SDHCI_POWER_CONTROL);
1683 pwr &= ~SDHCI_POWER_ON; 1692 pwr &= ~SDHCI_POWER_ON;
1684 sdhci_writeb(host, pwr, SDHCI_POWER_CONTROL); 1693 sdhci_writeb(host, pwr, SDHCI_POWER_CONTROL);
1685 if (host->vmmc) 1694 if (host->vmmc)
1686 regulator_disable(host->vmmc); 1695 regulator_disable(host->vmmc);
1687 1696
1688 /* Wait for 1ms as per the spec */ 1697 /* Wait for 1ms as per the spec */
1689 usleep_range(1000, 1500); 1698 usleep_range(1000, 1500);
1690 pwr |= SDHCI_POWER_ON; 1699 pwr |= SDHCI_POWER_ON;
1691 sdhci_writeb(host, pwr, SDHCI_POWER_CONTROL); 1700 sdhci_writeb(host, pwr, SDHCI_POWER_CONTROL);
1692 if (host->vmmc) 1701 if (host->vmmc)
1693 regulator_enable(host->vmmc); 1702 regulator_enable(host->vmmc);
1694 1703
1695 pr_info(DRIVER_NAME ": Switching to 1.8V signalling " 1704 pr_warning("%s: Switching to 1.8V signalling voltage failed, "
1696 "voltage failed, retrying with S18R set to 0\n"); 1705 "retrying with S18R set to 0\n", mmc_hostname(host->mmc));
1697 return -EAGAIN; 1706
1698 } else 1707 return -EAGAIN;
1708}
1709
1710static int sdhci_do_start_signal_voltage_switch(struct sdhci_host *host,
1711 struct mmc_ios *ios)
1712{
1713 u16 ctrl;
1714
1715 /*
1716 * Signal Voltage Switching is only applicable for Host Controllers
1717 * v3.00 and above.
1718 */
1719 if (host->version < SDHCI_SPEC_300)
1720 return 0;
1721
1722 /*
1723 * We first check whether the request is to set signalling voltage
1724 * to 3.3V. If so, we change the voltage to 3.3V and return quickly.
1725 */
1726 ctrl = sdhci_readw(host, SDHCI_HOST_CONTROL2);
1727 if (ios->signal_voltage == MMC_SIGNAL_VOLTAGE_330)
1728 return sdhci_do_3_3v_signal_voltage_switch(host, ctrl);
1729 else if (!(ctrl & SDHCI_CTRL_VDD_180) &&
1730 (ios->signal_voltage == MMC_SIGNAL_VOLTAGE_180))
1731 return sdhci_do_1_8v_signal_voltage_switch(host, ctrl);
1732 else
1699 /* No signal voltage switch required */ 1733 /* No signal voltage switch required */
1700 return 0; 1734 return 0;
1701} 1735}
@@ -2802,6 +2836,18 @@ int sdhci_add_host(struct sdhci_host *host)
2802 !(host->mmc->caps & MMC_CAP_NONREMOVABLE)) 2836 !(host->mmc->caps & MMC_CAP_NONREMOVABLE))
2803 mmc->caps |= MMC_CAP_NEEDS_POLL; 2837 mmc->caps |= MMC_CAP_NEEDS_POLL;
2804 2838
2839 /* If vqmmc regulator and no 1.8V signalling, then there's no UHS */
2840 host->vqmmc = regulator_get(mmc_dev(mmc), "vqmmc");
2841 if (IS_ERR(host->vqmmc)) {
2842 pr_info("%s: no vqmmc regulator found\n", mmc_hostname(mmc));
2843 host->vqmmc = NULL;
2844 }
2845 else if (regulator_is_supported_voltage(host->vqmmc, 1800000, 1800000))
2846 regulator_enable(host->vqmmc);
2847 else
2848 caps[1] &= ~(SDHCI_SUPPORT_SDR104 | SDHCI_SUPPORT_SDR50 |
2849 SDHCI_SUPPORT_DDR50);
2850
2805 /* Any UHS-I mode in caps implies SDR12 and SDR25 support. */ 2851 /* Any UHS-I mode in caps implies SDR12 and SDR25 support. */
2806 if (caps[1] & (SDHCI_SUPPORT_SDR104 | SDHCI_SUPPORT_SDR50 | 2852 if (caps[1] & (SDHCI_SUPPORT_SDR104 | SDHCI_SUPPORT_SDR50 |
2807 SDHCI_SUPPORT_DDR50)) 2853 SDHCI_SUPPORT_DDR50))
@@ -3122,6 +3168,11 @@ void sdhci_remove_host(struct sdhci_host *host, int dead)
3122 if (host->vmmc) 3168 if (host->vmmc)
3123 regulator_put(host->vmmc); 3169 regulator_put(host->vmmc);
3124 3170
3171 if (host->vqmmc) {
3172 regulator_disable(host->vqmmc);
3173 regulator_put(host->vqmmc);
3174 }
3175
3125 kfree(host->adma_desc); 3176 kfree(host->adma_desc);
3126 kfree(host->align_buffer); 3177 kfree(host->align_buffer);
3127 3178