aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/mmc/host/sdhci.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/mmc/host/sdhci.c')
-rw-r--r--drivers/mmc/host/sdhci.c168
1 files changed, 167 insertions, 1 deletions
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)