aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/mmc
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/mmc')
-rw-r--r--drivers/mmc/host/omap_hsmmc.c85
1 files changed, 41 insertions, 44 deletions
diff --git a/drivers/mmc/host/omap_hsmmc.c b/drivers/mmc/host/omap_hsmmc.c
index bda284ba1303..f82a0535afd1 100644
--- a/drivers/mmc/host/omap_hsmmc.c
+++ b/drivers/mmc/host/omap_hsmmc.c
@@ -638,6 +638,41 @@ static void omap_hsmmc_set_clock(struct omap_hsmmc_host *host)
638 omap_hsmmc_start_clock(host); 638 omap_hsmmc_start_clock(host);
639} 639}
640 640
641static void omap_hsmmc_set_bus_width(struct omap_hsmmc_host *host)
642{
643 struct mmc_ios *ios = &host->mmc->ios;
644 u32 con;
645
646 con = OMAP_HSMMC_READ(host->base, CON);
647 switch (ios->bus_width) {
648 case MMC_BUS_WIDTH_8:
649 OMAP_HSMMC_WRITE(host->base, CON, con | DW8);
650 break;
651 case MMC_BUS_WIDTH_4:
652 OMAP_HSMMC_WRITE(host->base, CON, con & ~DW8);
653 OMAP_HSMMC_WRITE(host->base, HCTL,
654 OMAP_HSMMC_READ(host->base, HCTL) | FOUR_BIT);
655 break;
656 case MMC_BUS_WIDTH_1:
657 OMAP_HSMMC_WRITE(host->base, CON, con & ~DW8);
658 OMAP_HSMMC_WRITE(host->base, HCTL,
659 OMAP_HSMMC_READ(host->base, HCTL) & ~FOUR_BIT);
660 break;
661 }
662}
663
664static void omap_hsmmc_set_bus_mode(struct omap_hsmmc_host *host)
665{
666 struct mmc_ios *ios = &host->mmc->ios;
667 u32 con;
668
669 con = OMAP_HSMMC_READ(host->base, CON);
670 if (ios->bus_mode == MMC_BUSMODE_OPENDRAIN)
671 OMAP_HSMMC_WRITE(host->base, CON, con | OD);
672 else
673 OMAP_HSMMC_WRITE(host->base, CON, con & ~OD);
674}
675
641#ifdef CONFIG_PM 676#ifdef CONFIG_PM
642 677
643/* 678/*
@@ -649,7 +684,7 @@ static int omap_hsmmc_context_restore(struct omap_hsmmc_host *host)
649 struct mmc_ios *ios = &host->mmc->ios; 684 struct mmc_ios *ios = &host->mmc->ios;
650 struct omap_mmc_platform_data *pdata = host->pdata; 685 struct omap_mmc_platform_data *pdata = host->pdata;
651 int context_loss = 0; 686 int context_loss = 0;
652 u32 hctl, capa, con; 687 u32 hctl, capa;
653 unsigned long timeout; 688 unsigned long timeout;
654 689
655 if (pdata->get_context_loss_count) { 690 if (pdata->get_context_loss_count) {
@@ -711,30 +746,12 @@ static int omap_hsmmc_context_restore(struct omap_hsmmc_host *host)
711 if (host->power_mode == MMC_POWER_OFF) 746 if (host->power_mode == MMC_POWER_OFF)
712 goto out; 747 goto out;
713 748
714 con = OMAP_HSMMC_READ(host->base, CON); 749 omap_hsmmc_set_bus_width(host);
715 switch (ios->bus_width) {
716 case MMC_BUS_WIDTH_8:
717 OMAP_HSMMC_WRITE(host->base, CON, con | DW8);
718 break;
719 case MMC_BUS_WIDTH_4:
720 OMAP_HSMMC_WRITE(host->base, CON, con & ~DW8);
721 OMAP_HSMMC_WRITE(host->base, HCTL,
722 OMAP_HSMMC_READ(host->base, HCTL) | FOUR_BIT);
723 break;
724 case MMC_BUS_WIDTH_1:
725 OMAP_HSMMC_WRITE(host->base, CON, con & ~DW8);
726 OMAP_HSMMC_WRITE(host->base, HCTL,
727 OMAP_HSMMC_READ(host->base, HCTL) & ~FOUR_BIT);
728 break;
729 }
730 750
731 omap_hsmmc_set_clock(host); 751 omap_hsmmc_set_clock(host);
732 752
733 con = OMAP_HSMMC_READ(host->base, CON); 753 omap_hsmmc_set_bus_mode(host);
734 if (ios->bus_mode == MMC_BUSMODE_OPENDRAIN) 754
735 OMAP_HSMMC_WRITE(host->base, CON, con | OD);
736 else
737 OMAP_HSMMC_WRITE(host->base, CON, con & ~OD);
738out: 755out:
739 host->context_loss = context_loss; 756 host->context_loss = context_loss;
740 757
@@ -1628,7 +1645,6 @@ static void omap_hsmmc_request(struct mmc_host *mmc, struct mmc_request *req)
1628static void omap_hsmmc_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) 1645static void omap_hsmmc_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
1629{ 1646{
1630 struct omap_hsmmc_host *host = mmc_priv(mmc); 1647 struct omap_hsmmc_host *host = mmc_priv(mmc);
1631 u32 con;
1632 int do_send_init_stream = 0; 1648 int do_send_init_stream = 0;
1633 1649
1634 pm_runtime_get_sync(host->dev); 1650 pm_runtime_get_sync(host->dev);
@@ -1654,22 +1670,7 @@ static void omap_hsmmc_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
1654 1670
1655 /* FIXME: set registers based only on changes to ios */ 1671 /* FIXME: set registers based only on changes to ios */
1656 1672
1657 con = OMAP_HSMMC_READ(host->base, CON); 1673 omap_hsmmc_set_bus_width(host);
1658 switch (mmc->ios.bus_width) {
1659 case MMC_BUS_WIDTH_8:
1660 OMAP_HSMMC_WRITE(host->base, CON, con | DW8);
1661 break;
1662 case MMC_BUS_WIDTH_4:
1663 OMAP_HSMMC_WRITE(host->base, CON, con & ~DW8);
1664 OMAP_HSMMC_WRITE(host->base, HCTL,
1665 OMAP_HSMMC_READ(host->base, HCTL) | FOUR_BIT);
1666 break;
1667 case MMC_BUS_WIDTH_1:
1668 OMAP_HSMMC_WRITE(host->base, CON, con & ~DW8);
1669 OMAP_HSMMC_WRITE(host->base, HCTL,
1670 OMAP_HSMMC_READ(host->base, HCTL) & ~FOUR_BIT);
1671 break;
1672 }
1673 1674
1674 if (host->pdata->controller_flags & OMAP_HSMMC_SUPPORTS_DUAL_VOLT) { 1675 if (host->pdata->controller_flags & OMAP_HSMMC_SUPPORTS_DUAL_VOLT) {
1675 /* Only MMC1 can interface at 3V without some flavor 1676 /* Only MMC1 can interface at 3V without some flavor
@@ -1694,11 +1695,7 @@ static void omap_hsmmc_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
1694 if (do_send_init_stream) 1695 if (do_send_init_stream)
1695 send_init_stream(host); 1696 send_init_stream(host);
1696 1697
1697 con = OMAP_HSMMC_READ(host->base, CON); 1698 omap_hsmmc_set_bus_mode(host);
1698 if (ios->bus_mode == MMC_BUSMODE_OPENDRAIN)
1699 OMAP_HSMMC_WRITE(host->base, CON, con | OD);
1700 else
1701 OMAP_HSMMC_WRITE(host->base, CON, con & ~OD);
1702 1699
1703 pm_runtime_put_autosuspend(host->dev); 1700 pm_runtime_put_autosuspend(host->dev);
1704} 1701}