mmc: meson: Assign the minimum clk rate as close to 400KHz as possible
authorUlf Hansson <ulf.hansson@linaro.org>
Wed, 8 Feb 2017 11:36:20 +0000 (12:36 +0100)
committerUlf Hansson <ulf.hansson@linaro.org>
Tue, 14 Feb 2017 08:10:53 +0000 (09:10 +0100)
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>
drivers/mmc/host/meson-gx-mmc.c

index 5eca88bcd5629d3f3b2c1f28d802acdd39eac86d..ef2ce725c31d0c9914a219aa9e2f0cc396cd65b2 100644 (file)
@@ -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);