aboutsummaryrefslogtreecommitdiff
path: root/drivers/mmc/host/mmci.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/mmc/host/mmci.c')
-rw-r--r--drivers/mmc/host/mmci.c27
1 files changed, 27 insertions, 0 deletions
diff --git a/drivers/mmc/host/mmci.c b/drivers/mmc/host/mmci.c
index a5849bc3a80..4f37c5d57df 100644
--- a/drivers/mmc/host/mmci.c
+++ b/drivers/mmc/host/mmci.c
@@ -178,8 +178,22 @@ static void mmci_set_mask1(struct mmci_host *host, unsigned int mask)
static void mmci_stop_data(struct mmci_host *host)
{
+ u32 clk;
+
writel(0, host->base + MMCIDATACTRL);
mmci_set_mask1(host, 0);
+
+ /* Needed for DDR */
+ if (host->mmc->card && mmc_card_ddr_mode(host->mmc->card)) {
+ clk = readl(host->base + MMCICLOCK);
+ if (clk & MCI_ST_UX500_NEG_EDGE)
+ clk &= ~(MCI_ST_UX500_NEG_EDGE);
+ if (clk & MCI_ST_UX500_CLK_INV)
+ clk &= ~(MCI_ST_UX500_CLK_INV);
+
+ writel(clk, (host->base + MMCICLOCK));
+ }
+
host->data = NULL;
}
@@ -444,6 +458,7 @@ static void mmci_start_data(struct mmci_host *host, struct mmc_data *data)
unsigned long long clks;
void __iomem *base;
int blksz_bits;
+ u32 clk;
dev_dbg(mmc_dev(host->mmc), "blksz %04x blks %04x flags %08x\n",
data->blksz, data->blocks, data->flags);
@@ -469,6 +484,18 @@ static void mmci_start_data(struct mmci_host *host, struct mmc_data *data)
if (data->flags & MMC_DATA_READ)
datactrl |= MCI_DPSM_DIRECTION;
+ if (host->mmc->card && mmc_card_ddr_mode(host->mmc->card)) {
+ datactrl |= MCI_ST_DPSM_DDRMODE;
+
+ /* Needed for DDR */
+ clk = readl(base + MMCICLOCK);
+ clk |= MCI_ST_UX500_CLK_INV;
+ if ((data->flags & MMC_DATA_READ))
+ clk |= MCI_ST_UX500_NEG_EDGE;
+
+ writel(clk, (base + MMCICLOCK));
+ }
+
/*
* Attempt to use DMA operation mode, if this
* should fail, fall back to PIO mode