aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/mmc/core/sd.c6
-rw-r--r--drivers/mmc/host/sdhci.c168
-rw-r--r--drivers/mmc/host/sdhci.h3
-rw-r--r--include/linux/mmc/host.h1
-rw-r--r--include/linux/mmc/mmc.h1
-rw-r--r--include/linux/mmc/sdhci.h4
6 files changed, 182 insertions, 1 deletions
diff --git a/drivers/mmc/core/sd.c b/drivers/mmc/core/sd.c
index 732c3171ceca..fc65475a26ee 100644
--- a/drivers/mmc/core/sd.c
+++ b/drivers/mmc/core/sd.c
@@ -618,6 +618,12 @@ static int mmc_sd_init_uhs_card(struct mmc_card *card)
618 618
619 /* Set current limit for the card */ 619 /* Set current limit for the card */
620 err = sd_set_current_limit(card, status); 620 err = sd_set_current_limit(card, status);
621 if (err)
622 goto out;
623
624 /* SPI mode doesn't define CMD19 */
625 if (!mmc_host_is_spi(card->host) && card->host->ops->execute_tuning)
626 err = card->host->ops->execute_tuning(card->host);
621 627
622out: 628out:
623 kfree(status); 629 kfree(status);
diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c
index 2a15aad2eba5..8a56eacea34d 100644
--- a/drivers/mmc/host/sdhci.c
+++ b/drivers/mmc/host/sdhci.c
@@ -38,6 +38,8 @@
38#define SDHCI_USE_LEDS_CLASS 38#define SDHCI_USE_LEDS_CLASS
39#endif 39#endif
40 40
41#define MAX_TUNING_LOOP 40
42
41static unsigned int debug_quirks = 0; 43static unsigned int debug_quirks = 0;
42 44
43static void sdhci_finish_data(struct sdhci_host *); 45static void sdhci_finish_data(struct sdhci_host *);
@@ -968,7 +970,9 @@ static void sdhci_send_command(struct sdhci_host *host, struct mmc_command *cmd)
968 flags |= SDHCI_CMD_CRC; 970 flags |= SDHCI_CMD_CRC;
969 if (cmd->flags & MMC_RSP_OPCODE) 971 if (cmd->flags & MMC_RSP_OPCODE)
970 flags |= SDHCI_CMD_INDEX; 972 flags |= SDHCI_CMD_INDEX;
971 if (cmd->data) 973
974 /* CMD19 is special in that the Data Present Select should be set */
975 if (cmd->data || (cmd->opcode == MMC_SEND_TUNING_BLOCK))
972 flags |= SDHCI_CMD_DATA; 976 flags |= SDHCI_CMD_DATA;
973 977
974 sdhci_writew(host, SDHCI_MAKE_CMD(cmd->opcode, flags), SDHCI_COMMAND); 978 sdhci_writew(host, SDHCI_MAKE_CMD(cmd->opcode, flags), SDHCI_COMMAND);
@@ -1501,12 +1505,157 @@ static int sdhci_start_signal_voltage_switch(struct mmc_host *mmc,
1501 return 0; 1505 return 0;
1502} 1506}
1503 1507
1508static int sdhci_execute_tuning(struct mmc_host *mmc)
1509{
1510 struct sdhci_host *host;
1511 u16 ctrl;
1512 u32 ier;
1513 int tuning_loop_counter = MAX_TUNING_LOOP;
1514 unsigned long timeout;
1515 int err = 0;
1516
1517 host = mmc_priv(mmc);
1518
1519 disable_irq(host->irq);
1520 spin_lock(&host->lock);
1521
1522 ctrl = sdhci_readw(host, SDHCI_HOST_CONTROL2);
1523
1524 /*
1525 * Host Controller needs tuning only in case of SDR104 mode
1526 * and for SDR50 mode when Use Tuning for SDR50 is set in
1527 * Capabilities register.
1528 */
1529 if (((ctrl & SDHCI_CTRL_UHS_MASK) == SDHCI_CTRL_UHS_SDR104) ||
1530 (((ctrl & SDHCI_CTRL_UHS_MASK) == SDHCI_CTRL_UHS_SDR50) &&
1531 (host->flags & SDHCI_SDR50_NEEDS_TUNING)))
1532 ctrl |= SDHCI_CTRL_EXEC_TUNING;
1533 else {
1534 spin_unlock(&host->lock);
1535 enable_irq(host->irq);
1536 return 0;
1537 }
1538
1539 sdhci_writew(host, ctrl, SDHCI_HOST_CONTROL2);
1540
1541 /*
1542 * As per the Host Controller spec v3.00, tuning command
1543 * generates Buffer Read Ready interrupt, so enable that.
1544 *
1545 * Note: The spec clearly says that when tuning sequence
1546 * is being performed, the controller does not generate
1547 * interrupts other than Buffer Read Ready interrupt. But
1548 * to make sure we don't hit a controller bug, we _only_
1549 * enable Buffer Read Ready interrupt here.
1550 */
1551 ier = sdhci_readl(host, SDHCI_INT_ENABLE);
1552 sdhci_clear_set_irqs(host, ier, SDHCI_INT_DATA_AVAIL);
1553
1554 /*
1555 * Issue CMD19 repeatedly till Execute Tuning is set to 0 or the number
1556 * of loops reaches 40 times or a timeout of 150ms occurs.
1557 */
1558 timeout = 150;
1559 do {
1560 struct mmc_command cmd = {0};
1561 struct mmc_request mrq = {0};
1562
1563 if (!tuning_loop_counter && !timeout)
1564 break;
1565
1566 cmd.opcode = MMC_SEND_TUNING_BLOCK;
1567 cmd.arg = 0;
1568 cmd.flags = MMC_RSP_R1 | MMC_CMD_ADTC;
1569 cmd.retries = 0;
1570 cmd.data = NULL;
1571 cmd.error = 0;
1572
1573 mrq.cmd = &cmd;
1574 host->mrq = &mrq;
1575
1576 /*
1577 * In response to CMD19, the card sends 64 bytes of tuning
1578 * block to the Host Controller. So we set the block size
1579 * to 64 here.
1580 */
1581 sdhci_writew(host, SDHCI_MAKE_BLKSZ(7, 64), SDHCI_BLOCK_SIZE);
1582
1583 /*
1584 * The tuning block is sent by the card to the host controller.
1585 * So we set the TRNS_READ bit in the Transfer Mode register.
1586 * This also takes care of setting DMA Enable and Multi Block
1587 * Select in the same register to 0.
1588 */
1589 sdhci_writew(host, SDHCI_TRNS_READ, SDHCI_TRANSFER_MODE);
1590
1591 sdhci_send_command(host, &cmd);
1592
1593 host->cmd = NULL;
1594 host->mrq = NULL;
1595
1596 spin_unlock(&host->lock);
1597 enable_irq(host->irq);
1598
1599 /* Wait for Buffer Read Ready interrupt */
1600 wait_event_interruptible_timeout(host->buf_ready_int,
1601 (host->tuning_done == 1),
1602 msecs_to_jiffies(50));
1603 disable_irq(host->irq);
1604 spin_lock(&host->lock);
1605
1606 if (!host->tuning_done) {
1607 printk(KERN_INFO DRIVER_NAME ": Timeout waiting for "
1608 "Buffer Read Ready interrupt during tuning "
1609 "procedure, falling back to fixed sampling "
1610 "clock\n");
1611 ctrl = sdhci_readw(host, SDHCI_HOST_CONTROL2);
1612 ctrl &= ~SDHCI_CTRL_TUNED_CLK;
1613 ctrl &= ~SDHCI_CTRL_EXEC_TUNING;
1614 sdhci_writew(host, ctrl, SDHCI_HOST_CONTROL2);
1615
1616 err = -EIO;
1617 goto out;
1618 }
1619
1620 host->tuning_done = 0;
1621
1622 ctrl = sdhci_readw(host, SDHCI_HOST_CONTROL2);
1623 tuning_loop_counter--;
1624 timeout--;
1625 mdelay(1);
1626 } while (ctrl & SDHCI_CTRL_EXEC_TUNING);
1627
1628 /*
1629 * The Host Driver has exhausted the maximum number of loops allowed,
1630 * so use fixed sampling frequency.
1631 */
1632 if (!tuning_loop_counter || !timeout) {
1633 ctrl &= ~SDHCI_CTRL_TUNED_CLK;
1634 sdhci_writew(host, ctrl, SDHCI_HOST_CONTROL2);
1635 } else {
1636 if (!(ctrl & SDHCI_CTRL_TUNED_CLK)) {
1637 printk(KERN_INFO DRIVER_NAME ": Tuning procedure"
1638 " failed, falling back to fixed sampling"
1639 " clock\n");
1640 err = -EIO;
1641 }
1642 }
1643
1644out:
1645 sdhci_clear_set_irqs(host, SDHCI_INT_DATA_AVAIL, ier);
1646 spin_unlock(&host->lock);
1647 enable_irq(host->irq);
1648
1649 return err;
1650}
1651
1504static const struct mmc_host_ops sdhci_ops = { 1652static const struct mmc_host_ops sdhci_ops = {
1505 .request = sdhci_request, 1653 .request = sdhci_request,
1506 .set_ios = sdhci_set_ios, 1654 .set_ios = sdhci_set_ios,
1507 .get_ro = sdhci_get_ro, 1655 .get_ro = sdhci_get_ro,
1508 .enable_sdio_irq = sdhci_enable_sdio_irq, 1656 .enable_sdio_irq = sdhci_enable_sdio_irq,
1509 .start_signal_voltage_switch = sdhci_start_signal_voltage_switch, 1657 .start_signal_voltage_switch = sdhci_start_signal_voltage_switch,
1658 .execute_tuning = sdhci_execute_tuning,
1510}; 1659};
1511 1660
1512/*****************************************************************************\ 1661/*****************************************************************************\
@@ -1724,6 +1873,16 @@ static void sdhci_data_irq(struct sdhci_host *host, u32 intmask)
1724{ 1873{
1725 BUG_ON(intmask == 0); 1874 BUG_ON(intmask == 0);
1726 1875
1876 /* CMD19 generates _only_ Buffer Read Ready interrupt */
1877 if (intmask & SDHCI_INT_DATA_AVAIL) {
1878 if (SDHCI_GET_CMD(sdhci_readw(host, SDHCI_COMMAND)) ==
1879 MMC_SEND_TUNING_BLOCK) {
1880 host->tuning_done = 1;
1881 wake_up(&host->buf_ready_int);
1882 return;
1883 }
1884 }
1885
1727 if (!host->data) { 1886 if (!host->data) {
1728 /* 1887 /*
1729 * The "data complete" interrupt is also used to 1888 * The "data complete" interrupt is also used to
@@ -2160,6 +2319,10 @@ int sdhci_add_host(struct sdhci_host *host)
2160 if (caps[1] & SDHCI_SUPPORT_DDR50) 2319 if (caps[1] & SDHCI_SUPPORT_DDR50)
2161 mmc->caps |= MMC_CAP_UHS_DDR50; 2320 mmc->caps |= MMC_CAP_UHS_DDR50;
2162 2321
2322 /* Does the host needs tuning for SDR50? */
2323 if (caps[1] & SDHCI_USE_SDR50_TUNING)
2324 host->flags |= SDHCI_SDR50_NEEDS_TUNING;
2325
2163 /* Driver Type(s) (A, C, D) supported by the host */ 2326 /* Driver Type(s) (A, C, D) supported by the host */
2164 if (caps[1] & SDHCI_DRIVER_TYPE_A) 2327 if (caps[1] & SDHCI_DRIVER_TYPE_A)
2165 mmc->caps |= MMC_CAP_DRIVER_TYPE_A; 2328 mmc->caps |= MMC_CAP_DRIVER_TYPE_A;
@@ -2313,6 +2476,9 @@ int sdhci_add_host(struct sdhci_host *host)
2313 2476
2314 setup_timer(&host->timer, sdhci_timeout_timer, (unsigned long)host); 2477 setup_timer(&host->timer, sdhci_timeout_timer, (unsigned long)host);
2315 2478
2479 if (host->version >= SDHCI_SPEC_300)
2480 init_waitqueue_head(&host->buf_ready_int);
2481
2316 ret = request_irq(host->irq, sdhci_irq, IRQF_SHARED, 2482 ret = request_irq(host->irq, sdhci_irq, IRQF_SHARED,
2317 mmc_hostname(mmc), host); 2483 mmc_hostname(mmc), host);
2318 if (ret) 2484 if (ret)
diff --git a/drivers/mmc/host/sdhci.h b/drivers/mmc/host/sdhci.h
index d96f6afcca1f..e62367491eee 100644
--- a/drivers/mmc/host/sdhci.h
+++ b/drivers/mmc/host/sdhci.h
@@ -161,6 +161,8 @@
161#define SDHCI_CTRL_DRV_TYPE_A 0x0010 161#define SDHCI_CTRL_DRV_TYPE_A 0x0010
162#define SDHCI_CTRL_DRV_TYPE_C 0x0020 162#define SDHCI_CTRL_DRV_TYPE_C 0x0020
163#define SDHCI_CTRL_DRV_TYPE_D 0x0030 163#define SDHCI_CTRL_DRV_TYPE_D 0x0030
164#define SDHCI_CTRL_EXEC_TUNING 0x0040
165#define SDHCI_CTRL_TUNED_CLK 0x0080
164#define SDHCI_CTRL_PRESET_VAL_ENABLE 0x8000 166#define SDHCI_CTRL_PRESET_VAL_ENABLE 0x8000
165 167
166#define SDHCI_CAPABILITIES 0x40 168#define SDHCI_CAPABILITIES 0x40
@@ -188,6 +190,7 @@
188#define SDHCI_DRIVER_TYPE_A 0x00000010 190#define SDHCI_DRIVER_TYPE_A 0x00000010
189#define SDHCI_DRIVER_TYPE_C 0x00000020 191#define SDHCI_DRIVER_TYPE_C 0x00000020
190#define SDHCI_DRIVER_TYPE_D 0x00000040 192#define SDHCI_DRIVER_TYPE_D 0x00000040
193#define SDHCI_USE_SDR50_TUNING 0x00002000
191 194
192#define SDHCI_CAPABILITIES_1 0x44 195#define SDHCI_CAPABILITIES_1 0x44
193 196
diff --git a/include/linux/mmc/host.h b/include/linux/mmc/host.h
index 52b5dc914a8c..ca7007fdb399 100644
--- a/include/linux/mmc/host.h
+++ b/include/linux/mmc/host.h
@@ -136,6 +136,7 @@ struct mmc_host_ops {
136 void (*init_card)(struct mmc_host *host, struct mmc_card *card); 136 void (*init_card)(struct mmc_host *host, struct mmc_card *card);
137 137
138 int (*start_signal_voltage_switch)(struct mmc_host *host, struct mmc_ios *ios); 138 int (*start_signal_voltage_switch)(struct mmc_host *host, struct mmc_ios *ios);
139 int (*execute_tuning)(struct mmc_host *host);
139}; 140};
140 141
141struct mmc_card; 142struct mmc_card;
diff --git a/include/linux/mmc/mmc.h b/include/linux/mmc/mmc.h
index 373b2bf5e5b5..9fa5a73f393d 100644
--- a/include/linux/mmc/mmc.h
+++ b/include/linux/mmc/mmc.h
@@ -50,6 +50,7 @@
50#define MMC_SET_BLOCKLEN 16 /* ac [31:0] block len R1 */ 50#define MMC_SET_BLOCKLEN 16 /* ac [31:0] block len R1 */
51#define MMC_READ_SINGLE_BLOCK 17 /* adtc [31:0] data addr R1 */ 51#define MMC_READ_SINGLE_BLOCK 17 /* adtc [31:0] data addr R1 */
52#define MMC_READ_MULTIPLE_BLOCK 18 /* adtc [31:0] data addr R1 */ 52#define MMC_READ_MULTIPLE_BLOCK 18 /* adtc [31:0] data addr R1 */
53#define MMC_SEND_TUNING_BLOCK 19 /* adtc R1 */
53 54
54 /* class 3 */ 55 /* class 3 */
55#define MMC_WRITE_DAT_UNTIL_STOP 20 /* adtc [31:0] data addr R1 */ 56#define MMC_WRITE_DAT_UNTIL_STOP 20 /* adtc [31:0] data addr R1 */
diff --git a/include/linux/mmc/sdhci.h b/include/linux/mmc/sdhci.h
index 92e1c9ad126c..b74c8530e959 100644
--- a/include/linux/mmc/sdhci.h
+++ b/include/linux/mmc/sdhci.h
@@ -111,6 +111,7 @@ struct sdhci_host {
111#define SDHCI_USE_ADMA (1<<1) /* Host is ADMA capable */ 111#define SDHCI_USE_ADMA (1<<1) /* Host is ADMA capable */
112#define SDHCI_REQ_USE_DMA (1<<2) /* Use DMA for this req. */ 112#define SDHCI_REQ_USE_DMA (1<<2) /* Use DMA for this req. */
113#define SDHCI_DEVICE_DEAD (1<<3) /* Device unresponsive */ 113#define SDHCI_DEVICE_DEAD (1<<3) /* Device unresponsive */
114#define SDHCI_SDR50_NEEDS_TUNING (1<<4) /* SDR50 needs tuning */
114 115
115 unsigned int version; /* SDHCI spec. version */ 116 unsigned int version; /* SDHCI spec. version */
116 117
@@ -147,6 +148,9 @@ struct sdhci_host {
147 unsigned int ocr_avail_sd; 148 unsigned int ocr_avail_sd;
148 unsigned int ocr_avail_mmc; 149 unsigned int ocr_avail_mmc;
149 150
151 wait_queue_head_t buf_ready_int; /* Waitqueue for Buffer Read Ready interrupt */
152 unsigned int tuning_done; /* Condition flag set when CMD19 succeeds */
153
150 unsigned long private[0] ____cacheline_aligned; 154 unsigned long private[0] ____cacheline_aligned;
151}; 155};
152#endif /* __SDHCI_H */ 156#endif /* __SDHCI_H */