aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/mmc/host/sdhci.c57
-rw-r--r--drivers/mmc/host/sdhci.h1
-rw-r--r--include/linux/mmc/sdhci.h1
3 files changed, 44 insertions, 15 deletions
diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c
index 0636e9a587b1..96f4e548ba22 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 *);
49 49
50static void sdhci_send_command(struct sdhci_host *, struct mmc_command *); 50static void sdhci_send_command(struct sdhci_host *, struct mmc_command *);
51static void sdhci_finish_command(struct sdhci_host *); 51static void sdhci_finish_command(struct sdhci_host *);
52static int sdhci_execute_tuning(struct mmc_host *mmc); 52static int sdhci_execute_tuning(struct mmc_host *mmc, u32 opcode);
53static void sdhci_tuning_timer(unsigned long data); 53static void sdhci_tuning_timer(unsigned long data);
54 54
55#ifdef CONFIG_PM_RUNTIME 55#ifdef CONFIG_PM_RUNTIME
@@ -1014,7 +1014,8 @@ static void sdhci_send_command(struct sdhci_host *host, struct mmc_command *cmd)
1014 flags |= SDHCI_CMD_INDEX; 1014 flags |= SDHCI_CMD_INDEX;
1015 1015
1016 /* CMD19 is special in that the Data Present Select should be set */ 1016 /* CMD19 is special in that the Data Present Select should be set */
1017 if (cmd->data || (cmd->opcode == MMC_SEND_TUNING_BLOCK)) 1017 if (cmd->data || cmd->opcode == MMC_SEND_TUNING_BLOCK ||
1018 cmd->opcode == MMC_SEND_TUNING_BLOCK_HS200)
1018 flags |= SDHCI_CMD_DATA; 1019 flags |= SDHCI_CMD_DATA;
1019 1020
1020 sdhci_writew(host, SDHCI_MAKE_CMD(cmd->opcode, flags), SDHCI_COMMAND); 1021 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)
1287 if ((host->flags & SDHCI_NEEDS_RETUNING) && 1288 if ((host->flags & SDHCI_NEEDS_RETUNING) &&
1288 !(present_state & (SDHCI_DOING_WRITE | SDHCI_DOING_READ))) { 1289 !(present_state & (SDHCI_DOING_WRITE | SDHCI_DOING_READ))) {
1289 spin_unlock_irqrestore(&host->lock, flags); 1290 spin_unlock_irqrestore(&host->lock, flags);
1290 sdhci_execute_tuning(mmc); 1291 sdhci_execute_tuning(mmc, mrq->cmd->opcode);
1291 spin_lock_irqsave(&host->lock, flags); 1292 spin_lock_irqsave(&host->lock, flags);
1292 1293
1293 /* Restore original mmc_request structure */ 1294 /* Restore original mmc_request structure */
@@ -1382,7 +1383,8 @@ static void sdhci_do_set_ios(struct sdhci_host *host, struct mmc_ios *ios)
1382 unsigned int clock; 1383 unsigned int clock;
1383 1384
1384 /* In case of UHS-I modes, set High Speed Enable */ 1385 /* In case of UHS-I modes, set High Speed Enable */
1385 if ((ios->timing == MMC_TIMING_UHS_SDR50) || 1386 if ((ios->timing == MMC_TIMING_MMC_HS200) ||
1387 (ios->timing == MMC_TIMING_UHS_SDR50) ||
1386 (ios->timing == MMC_TIMING_UHS_SDR104) || 1388 (ios->timing == MMC_TIMING_UHS_SDR104) ||
1387 (ios->timing == MMC_TIMING_UHS_DDR50) || 1389 (ios->timing == MMC_TIMING_UHS_DDR50) ||
1388 (ios->timing == MMC_TIMING_UHS_SDR25)) 1390 (ios->timing == MMC_TIMING_UHS_SDR25))
@@ -1435,7 +1437,9 @@ static void sdhci_do_set_ios(struct sdhci_host *host, struct mmc_ios *ios)
1435 ctrl_2 = sdhci_readw(host, SDHCI_HOST_CONTROL2); 1437 ctrl_2 = sdhci_readw(host, SDHCI_HOST_CONTROL2);
1436 /* Select Bus Speed Mode for host */ 1438 /* Select Bus Speed Mode for host */
1437 ctrl_2 &= ~SDHCI_CTRL_UHS_MASK; 1439 ctrl_2 &= ~SDHCI_CTRL_UHS_MASK;
1438 if (ios->timing == MMC_TIMING_UHS_SDR12) 1440 if (ios->timing == MMC_TIMING_MMC_HS200)
1441 ctrl_2 |= SDHCI_CTRL_HS_SDR200;
1442 else if (ios->timing == MMC_TIMING_UHS_SDR12)
1439 ctrl_2 |= SDHCI_CTRL_UHS_SDR12; 1443 ctrl_2 |= SDHCI_CTRL_UHS_SDR12;
1440 else if (ios->timing == MMC_TIMING_UHS_SDR25) 1444 else if (ios->timing == MMC_TIMING_UHS_SDR25)
1441 ctrl_2 |= SDHCI_CTRL_UHS_SDR25; 1445 ctrl_2 |= SDHCI_CTRL_UHS_SDR25;
@@ -1682,7 +1686,7 @@ static int sdhci_start_signal_voltage_switch(struct mmc_host *mmc,
1682 return err; 1686 return err;
1683} 1687}
1684 1688
1685static int sdhci_execute_tuning(struct mmc_host *mmc) 1689static int sdhci_execute_tuning(struct mmc_host *mmc, u32 opcode)
1686{ 1690{
1687 struct sdhci_host *host; 1691 struct sdhci_host *host;
1688 u16 ctrl; 1692 u16 ctrl;
@@ -1690,6 +1694,7 @@ static int sdhci_execute_tuning(struct mmc_host *mmc)
1690 int tuning_loop_counter = MAX_TUNING_LOOP; 1694 int tuning_loop_counter = MAX_TUNING_LOOP;
1691 unsigned long timeout; 1695 unsigned long timeout;
1692 int err = 0; 1696 int err = 0;
1697 bool requires_tuning_nonuhs = false;
1693 1698
1694 host = mmc_priv(mmc); 1699 host = mmc_priv(mmc);
1695 1700
@@ -1700,13 +1705,19 @@ static int sdhci_execute_tuning(struct mmc_host *mmc)
1700 ctrl = sdhci_readw(host, SDHCI_HOST_CONTROL2); 1705 ctrl = sdhci_readw(host, SDHCI_HOST_CONTROL2);
1701 1706
1702 /* 1707 /*
1703 * Host Controller needs tuning only in case of SDR104 mode 1708 * The Host Controller needs tuning only in case of SDR104 mode
1704 * and for SDR50 mode when Use Tuning for SDR50 is set in 1709 * and for SDR50 mode when Use Tuning for SDR50 is set in the
1705 * Capabilities register. 1710 * Capabilities register.
1711 * If the Host Controller supports the HS200 mode then the
1712 * tuning function has to be executed.
1706 */ 1713 */
1714 if (((ctrl & SDHCI_CTRL_UHS_MASK) == SDHCI_CTRL_UHS_SDR50) &&
1715 (host->flags & SDHCI_SDR50_NEEDS_TUNING ||
1716 host->flags & SDHCI_HS200_NEEDS_TUNING))
1717 requires_tuning_nonuhs = true;
1718
1707 if (((ctrl & SDHCI_CTRL_UHS_MASK) == SDHCI_CTRL_UHS_SDR104) || 1719 if (((ctrl & SDHCI_CTRL_UHS_MASK) == SDHCI_CTRL_UHS_SDR104) ||
1708 (((ctrl & SDHCI_CTRL_UHS_MASK) == SDHCI_CTRL_UHS_SDR50) && 1720 requires_tuning_nonuhs)
1709 (host->flags & SDHCI_SDR50_NEEDS_TUNING)))
1710 ctrl |= SDHCI_CTRL_EXEC_TUNING; 1721 ctrl |= SDHCI_CTRL_EXEC_TUNING;
1711 else { 1722 else {
1712 spin_unlock(&host->lock); 1723 spin_unlock(&host->lock);
@@ -1742,7 +1753,7 @@ static int sdhci_execute_tuning(struct mmc_host *mmc)
1742 if (!tuning_loop_counter && !timeout) 1753 if (!tuning_loop_counter && !timeout)
1743 break; 1754 break;
1744 1755
1745 cmd.opcode = MMC_SEND_TUNING_BLOCK; 1756 cmd.opcode = opcode;
1746 cmd.arg = 0; 1757 cmd.arg = 0;
1747 cmd.flags = MMC_RSP_R1 | MMC_CMD_ADTC; 1758 cmd.flags = MMC_RSP_R1 | MMC_CMD_ADTC;
1748 cmd.retries = 0; 1759 cmd.retries = 0;
@@ -1757,7 +1768,17 @@ static int sdhci_execute_tuning(struct mmc_host *mmc)
1757 * block to the Host Controller. So we set the block size 1768 * block to the Host Controller. So we set the block size
1758 * to 64 here. 1769 * to 64 here.
1759 */ 1770 */
1760 sdhci_writew(host, SDHCI_MAKE_BLKSZ(7, 64), SDHCI_BLOCK_SIZE); 1771 if (cmd.opcode == MMC_SEND_TUNING_BLOCK_HS200) {
1772 if (mmc->ios.bus_width == MMC_BUS_WIDTH_8)
1773 sdhci_writew(host, SDHCI_MAKE_BLKSZ(7, 128),
1774 SDHCI_BLOCK_SIZE);
1775 else if (mmc->ios.bus_width == MMC_BUS_WIDTH_4)
1776 sdhci_writew(host, SDHCI_MAKE_BLKSZ(7, 64),
1777 SDHCI_BLOCK_SIZE);
1778 } else {
1779 sdhci_writew(host, SDHCI_MAKE_BLKSZ(7, 64),
1780 SDHCI_BLOCK_SIZE);
1781 }
1761 1782
1762 /* 1783 /*
1763 * The tuning block is sent by the card to the host controller. 1784 * The tuning block is sent by the card to the host controller.
@@ -2140,12 +2161,14 @@ static void sdhci_show_adma_error(struct sdhci_host *host) { }
2140 2161
2141static void sdhci_data_irq(struct sdhci_host *host, u32 intmask) 2162static void sdhci_data_irq(struct sdhci_host *host, u32 intmask)
2142{ 2163{
2164 u32 command;
2143 BUG_ON(intmask == 0); 2165 BUG_ON(intmask == 0);
2144 2166
2145 /* CMD19 generates _only_ Buffer Read Ready interrupt */ 2167 /* CMD19 generates _only_ Buffer Read Ready interrupt */
2146 if (intmask & SDHCI_INT_DATA_AVAIL) { 2168 if (intmask & SDHCI_INT_DATA_AVAIL) {
2147 if (SDHCI_GET_CMD(sdhci_readw(host, SDHCI_COMMAND)) == 2169 command = SDHCI_GET_CMD(sdhci_readw(host, SDHCI_COMMAND));
2148 MMC_SEND_TUNING_BLOCK) { 2170 if (command == MMC_SEND_TUNING_BLOCK ||
2171 command == MMC_SEND_TUNING_BLOCK_HS200) {
2149 host->tuning_done = 1; 2172 host->tuning_done = 1;
2150 wake_up(&host->buf_ready_int); 2173 wake_up(&host->buf_ready_int);
2151 return; 2174 return;
@@ -2747,10 +2770,14 @@ int sdhci_add_host(struct sdhci_host *host)
2747 if (caps[1] & SDHCI_SUPPORT_DDR50) 2770 if (caps[1] & SDHCI_SUPPORT_DDR50)
2748 mmc->caps |= MMC_CAP_UHS_DDR50; 2771 mmc->caps |= MMC_CAP_UHS_DDR50;
2749 2772
2750 /* Does the host needs tuning for SDR50? */ 2773 /* Does the host need tuning for SDR50? */
2751 if (caps[1] & SDHCI_USE_SDR50_TUNING) 2774 if (caps[1] & SDHCI_USE_SDR50_TUNING)
2752 host->flags |= SDHCI_SDR50_NEEDS_TUNING; 2775 host->flags |= SDHCI_SDR50_NEEDS_TUNING;
2753 2776
2777 /* Does the host need tuning for HS200? */
2778 if (mmc->caps2 & MMC_CAP2_HS200)
2779 host->flags |= SDHCI_HS200_NEEDS_TUNING;
2780
2754 /* Driver Type(s) (A, C, D) supported by the host */ 2781 /* Driver Type(s) (A, C, D) supported by the host */
2755 if (caps[1] & SDHCI_DRIVER_TYPE_A) 2782 if (caps[1] & SDHCI_DRIVER_TYPE_A)
2756 mmc->caps |= MMC_CAP_DRIVER_TYPE_A; 2783 mmc->caps |= MMC_CAP_DRIVER_TYPE_A;
diff --git a/drivers/mmc/host/sdhci.h b/drivers/mmc/host/sdhci.h
index a04d4d0c6fd2..ad265b96b75b 100644
--- a/drivers/mmc/host/sdhci.h
+++ b/drivers/mmc/host/sdhci.h
@@ -158,6 +158,7 @@
158#define SDHCI_CTRL_UHS_SDR50 0x0002 158#define SDHCI_CTRL_UHS_SDR50 0x0002
159#define SDHCI_CTRL_UHS_SDR104 0x0003 159#define SDHCI_CTRL_UHS_SDR104 0x0003
160#define SDHCI_CTRL_UHS_DDR50 0x0004 160#define SDHCI_CTRL_UHS_DDR50 0x0004
161#define SDHCI_CTRL_HS_SDR200 0x0005 /* reserved value in SDIO spec */
161#define SDHCI_CTRL_VDD_180 0x0008 162#define SDHCI_CTRL_VDD_180 0x0008
162#define SDHCI_CTRL_DRV_TYPE_MASK 0x0030 163#define SDHCI_CTRL_DRV_TYPE_MASK 0x0030
163#define SDHCI_CTRL_DRV_TYPE_B 0x0000 164#define SDHCI_CTRL_DRV_TYPE_B 0x0000
diff --git a/include/linux/mmc/sdhci.h b/include/linux/mmc/sdhci.h
index dad7a469f09c..c750f85177d9 100644
--- a/include/linux/mmc/sdhci.h
+++ b/include/linux/mmc/sdhci.h
@@ -119,6 +119,7 @@ struct sdhci_host {
119#define SDHCI_AUTO_CMD23 (1<<7) /* Auto CMD23 support */ 119#define SDHCI_AUTO_CMD23 (1<<7) /* Auto CMD23 support */
120#define SDHCI_PV_ENABLED (1<<8) /* Preset value enabled */ 120#define SDHCI_PV_ENABLED (1<<8) /* Preset value enabled */
121#define SDHCI_SDIO_IRQ_ENABLED (1<<9) /* SDIO irq enabled */ 121#define SDHCI_SDIO_IRQ_ENABLED (1<<9) /* SDIO irq enabled */
122#define SDHCI_HS200_NEEDS_TUNING (1<<10) /* HS200 needs tuning */
122 123
123 unsigned int version; /* SDHCI spec. version */ 124 unsigned int version; /* SDHCI spec. version */
124 125