From 5137c4ea06a48c3a9e47c8fbbb81701db9e816f9 Mon Sep 17 00:00:00 2001 From: Ulf Hansson Date: Tue, 1 Nov 2011 12:03:59 +0100 Subject: mmc: mmci: Limit command frequency when using a levelshifter Due to timing issues for command direction signaling when using a levelshifter, we limit the frequency to 25 MHz while sending commands. The frequency is just limited during the command send/response, then it is restored to it's original value. ST-Ericsson ID: 355531 ST-Ericsson Linux next: - ST-Ericsson FOSS-OUT ID: Trivial Change-Id: I15d06e3c331a4db717a904937ce6ce60972d185e Signed-off-by: Ulf Hansson Reviewed-on: http://gerrit.lud.stericsson.com/gerrit/51785 --- drivers/mmc/host/mmci.c | 15 +++++++++++++++ drivers/mmc/host/mmci.h | 1 + 2 files changed, 16 insertions(+) diff --git a/drivers/mmc/host/mmci.c b/drivers/mmc/host/mmci.c index e3d67089265..368f855ceac 100644 --- a/drivers/mmc/host/mmci.c +++ b/drivers/mmc/host/mmci.c @@ -789,6 +789,14 @@ mmci_start_command(struct mmci_host *host, struct mmc_command *cmd, u32 c) if (/*interrupt*/0) c |= MCI_CPSM_INTERRUPT; + /* + * For levelshifters we must not use more than 25MHz when + * sending commands. + */ + host->cclk_desired = host->cclk; + if (host->plat->ios_handler && (host->cclk_desired > 25000000)) + mmci_set_clkreg(host, 25000000); + host->cmd = cmd; writel(cmd->arg, base + MMCIARGUMENT); @@ -881,6 +889,13 @@ mmci_cmd_irq(struct mmci_host *host, struct mmc_command *cmd, cmd->resp[3] = readl(base + MMCIRESPONSE3); } + /* + * For levelshifters we might have decreased cclk to 25MHz when + * sending commands, then we restore the frequency here. + */ + if (host->plat->ios_handler && (host->cclk_desired > host->cclk)) + mmci_set_clkreg(host, host->cclk_desired); + if (!cmd->data || cmd->error) { /* Terminate the DMA transfer */ if (dma_inprogress(host)) { diff --git a/drivers/mmc/host/mmci.h b/drivers/mmc/host/mmci.h index ba09a603787..5a17beafd05 100644 --- a/drivers/mmc/host/mmci.h +++ b/drivers/mmc/host/mmci.h @@ -186,6 +186,7 @@ struct mmci_host { unsigned int mclk; unsigned int cclk; + unsigned int cclk_desired; u32 pwr_reg; u32 clk_reg; u32 datactrl_reg; -- cgit v1.2.3