summaryrefslogtreecommitdiffstats
path: root/drivers/mmc
diff options
context:
space:
mode:
authorUlf Hansson <ulf.hansson@linaro.org>2017-02-08 12:36:20 +0100
committerUlf Hansson <ulf.hansson@linaro.org>2017-02-14 09:10:53 +0100
commita4c38c8dba98643602ae08c0867425b20a3c204b (patch)
tree71e60144cd7cf5404ed14974f5beb5af7c71bfc9 /drivers/mmc
parent37dac0681e2be4f3c32b090a8c0591d4ce57e6f0 (diff)
downloadlinux-stable-a4c38c8dba98643602ae08c0867425b20a3c204b.tar.gz
linux-stable-a4c38c8dba98643602ae08c0867425b20a3c204b.tar.bz2
linux-stable-a4c38c8dba98643602ae08c0867425b20a3c204b.zip
mmc: meson: Assign the minimum clk rate as close to 400KHz as possible
The current code dealing with calculating mmc->f_min is a bit complicated. Additionally, the attempt to set an initial clock rate should explicitly use a rate between 100KHz to 400 KHz, according the (e)MMC/SD specs, which it doesn't. Fix the problem and clean up the code by using clk_round_rate() to pick the nearest minimum rate to 400KHz (rounded down from 400kHz). Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org> [Heiner: Changed from 100KHz to 400KHz to get a proper rounded rate] Signed-off-by: Heiner Kallweit <hkallweit1@gmail.com>
Diffstat (limited to 'drivers/mmc')
-rw-r--r--drivers/mmc/host/meson-gx-mmc.c20
1 files changed, 6 insertions, 14 deletions
diff --git a/drivers/mmc/host/meson-gx-mmc.c b/drivers/mmc/host/meson-gx-mmc.c
index 5eca88bcd562..ef2ce725c31d 100644
--- a/drivers/mmc/host/meson-gx-mmc.c
+++ b/drivers/mmc/host/meson-gx-mmc.c
@@ -132,7 +132,6 @@ struct meson_host {
struct clk_mux mux;
struct clk *mux_clk;
struct clk *mux_parent[MUX_CLK_NUM_PARENTS];
- unsigned long mux_parent_rate[MUX_CLK_NUM_PARENTS];
struct clk_divider cfg_div;
struct clk *cfg_div_clk;
@@ -240,7 +239,6 @@ static int meson_mmc_clk_init(struct meson_host *host)
const char *mux_parent_names[MUX_CLK_NUM_PARENTS];
unsigned int mux_parent_count = 0;
const char *clk_div_parents[1];
- unsigned int f_min = UINT_MAX;
u32 clk_reg, cfg;
/* get the mux parents */
@@ -257,20 +255,10 @@ static int meson_mmc_clk_init(struct meson_host *host)
return ret;
}
- host->mux_parent_rate[i] = clk_get_rate(host->mux_parent[i]);
mux_parent_names[i] = __clk_get_name(host->mux_parent[i]);
mux_parent_count++;
- if (host->mux_parent_rate[i] < f_min)
- f_min = host->mux_parent_rate[i];
}
- /* cacluate f_min based on input clocks, and max divider value */
- if (f_min != UINT_MAX)
- f_min = DIV_ROUND_UP(CLK_SRC_XTAL_RATE, CLK_DIV_MAX);
- else
- f_min = 4000000; /* default min: 400 MHz */
- host->mmc->f_min = f_min;
-
/* create the mux */
snprintf(clk_name, sizeof(clk_name), "%s#mux", dev_name(host->dev));
init.name = clk_name;
@@ -325,9 +313,13 @@ static int meson_mmc_clk_init(struct meson_host *host)
writel(cfg, host->regs + SD_EMMC_CFG);
ret = clk_prepare_enable(host->cfg_div_clk);
- if (!ret)
- ret = meson_mmc_clk_set(host, f_min);
+ if (ret)
+ return ret;
+
+ /* Get the nearest minimum clock to 400KHz */
+ host->mmc->f_min = clk_round_rate(host->cfg_div_clk, 400000);
+ ret = meson_mmc_clk_set(host, host->mmc->f_min);
if (!ret)
clk_disable_unprepare(host->cfg_div_clk);