Commit a6a6464a authored by Linus Walleij's avatar Linus Walleij Committed by Russell King

ARM: 5697/1: MMCI Break out clock divider setup

This breaks out the clock divider set-up code from the
mmci_set_ios() code and surrounds the two register
writes with a host lock so we don't get collisions if
(in future code) two code paths want to change the
clock divider at the same time as can be the case if
we get something like pre/post- clock frequency change
notifications soonish.
Signed-off-by: default avatarLinus Walleij <linus.walleij@stericsson.com>
Signed-off-by: default avatarRussell King <rmk+kernel@arm.linux.org.uk>
parent bc581770
...@@ -38,6 +38,33 @@ ...@@ -38,6 +38,33 @@
static unsigned int fmax = 515633; static unsigned int fmax = 515633;
/*
* This must be called with host->lock held
*/
static void mmci_set_clkreg(struct mmci_host *host, unsigned int desired)
{
u32 clk = 0;
if (desired) {
if (desired >= host->mclk) {
clk = MCI_CLK_BYPASS;
host->cclk = host->mclk;
} else {
clk = host->mclk / (2 * desired) - 1;
if (clk >= 256)
clk = 255;
host->cclk = host->mclk / (2 * (clk + 1));
}
if (host->hw_designer == 0x80)
clk |= MCI_FCEN; /* Bug fix in ST IP block */
clk |= MCI_CLK_ENABLE;
/* This hasn't proven to be worthwhile */
/* clk |= MCI_CLK_PWRSAVE; */
}
writel(clk, host->base + MMCICLOCK);
}
static void static void
mmci_request_end(struct mmci_host *host, struct mmc_request *mrq) mmci_request_end(struct mmci_host *host, struct mmc_request *mrq)
{ {
...@@ -419,22 +446,8 @@ static void mmci_request(struct mmc_host *mmc, struct mmc_request *mrq) ...@@ -419,22 +446,8 @@ static void mmci_request(struct mmc_host *mmc, struct mmc_request *mrq)
static void mmci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) static void mmci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
{ {
struct mmci_host *host = mmc_priv(mmc); struct mmci_host *host = mmc_priv(mmc);
u32 clk = 0, pwr = 0; u32 pwr = 0;
unsigned long flags;
if (ios->clock) {
if (ios->clock >= host->mclk) {
clk = MCI_CLK_BYPASS;
host->cclk = host->mclk;
} else {
clk = host->mclk / (2 * ios->clock) - 1;
if (clk >= 256)
clk = 255;
host->cclk = host->mclk / (2 * (clk + 1));
}
if (host->hw_designer == AMBA_VENDOR_ST)
clk |= MCI_FCEN; /* Bug fix in ST IP block */
clk |= MCI_CLK_ENABLE;
}
if (host->plat->translate_vdd) if (host->plat->translate_vdd)
pwr |= host->plat->translate_vdd(mmc_dev(mmc), ios->vdd); pwr |= host->plat->translate_vdd(mmc_dev(mmc), ios->vdd);
...@@ -465,12 +478,16 @@ static void mmci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) ...@@ -465,12 +478,16 @@ static void mmci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
} }
} }
writel(clk, host->base + MMCICLOCK); spin_lock_irqsave(&host->lock, flags);
mmci_set_clkreg(host, ios->clock);
if (host->pwr != pwr) { if (host->pwr != pwr) {
host->pwr = pwr; host->pwr = pwr;
writel(pwr, host->base + MMCIPOWER); writel(pwr, host->base + MMCIPOWER);
} }
spin_unlock_irqrestore(&host->lock, flags);
} }
static int mmci_get_ro(struct mmc_host *mmc) static int mmci_get_ro(struct mmc_host *mmc)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment