[U-Boot] [PATCH] MMC: DWMMC: Correct the CLKDIV register value

Rajeshwari Birje rajeshwari.birje at gmail.com
Thu Aug 29 13:04:19 CEST 2013


CCing the MMC Maintainer.

On Thu, Aug 29, 2013 at 4:22 PM, Rajeshwari S Shinde
<rajeshwari.s at samsung.com> wrote:
> This patch corrects the divider value written to CLKDIV register.
> Since SDCLKIN is divided inside controller by the DIVRATIO value set
> in the CLKSEL register, we need to use the same output clock value to
> calculate the CLKDIV value.
> as per user manual: cclk_in = SDCLKIN / (DIVRATIO + 1)
>
> Input parameter to mmc_clk is changed to dwmci_host, since
> we need the same to read DWMCI_CLKSEL register.
>
> This improves the read timing values for channel 0 on SMDK5250
> from 0.288sec to 0.144sec
>
> Signed-off-by: Rajeshwari S Shinde <rajeshwari.s at samsung.com>
> ---
>  arch/arm/include/asm/arch-exynos/dwmmc.h |  4 ++++
>  drivers/mmc/dw_mmc.c                     |  2 +-
>  drivers/mmc/exynos_dw_mmc.c              | 17 +++++++++++++++--
>  include/dwmmc.h                          |  2 +-
>  4 files changed, 21 insertions(+), 4 deletions(-)
>
> diff --git a/arch/arm/include/asm/arch-exynos/dwmmc.h b/arch/arm/include/asm/arch-exynos/dwmmc.h
> index b9eca76..f1c8d8a 100644
> --- a/arch/arm/include/asm/arch-exynos/dwmmc.h
> +++ b/arch/arm/include/asm/arch-exynos/dwmmc.h
> @@ -14,6 +14,10 @@
>  #define DWMCI_SET_DRV_CLK(x)   ((x) << 16)
>  #define DWMCI_SET_DIV_RATIO(x) ((x) << 24)
>
> +/* CLKSEL Register */
> +#define DWMCI_DIVRATIO_BIT             24
> +#define DWMCI_DIVRATIO_MASK            0x7
> +
>  #ifdef CONFIG_OF_CONTROL
>  int exynos_dwmmc_init(const void *blob);
>  #endif
> diff --git a/drivers/mmc/dw_mmc.c b/drivers/mmc/dw_mmc.c
> index a82ee17..3406bdd 100644
> --- a/drivers/mmc/dw_mmc.c
> +++ b/drivers/mmc/dw_mmc.c
> @@ -224,7 +224,7 @@ static int dwmci_setup_bus(struct dwmci_host *host, u32 freq)
>          * host->bus_hz should be set from user.
>          */
>         if (host->mmc_clk)
> -               sclk = host->mmc_clk(host->dev_index);
> +               sclk = host->mmc_clk(host);
>         else if (host->bus_hz)
>                 sclk = host->bus_hz;
>         else {
> diff --git a/drivers/mmc/exynos_dw_mmc.c b/drivers/mmc/exynos_dw_mmc.c
> index 4ef9fec..1ed4afe 100644
> --- a/drivers/mmc/exynos_dw_mmc.c
> +++ b/drivers/mmc/exynos_dw_mmc.c
> @@ -29,9 +29,22 @@ static void exynos_dwmci_clksel(struct dwmci_host *host)
>         dwmci_writel(host, DWMCI_CLKSEL, host->clksel_val);
>  }
>
> -unsigned int exynos_dwmci_get_clk(int dev_index)
> +unsigned int exynos_dwmci_get_clk(struct dwmci_host *host)
>  {
> -       return get_mmc_clk(dev_index);
> +       unsigned long sclk;
> +       int8_t clk_div;
> +
> +       /*
> +        * Since SDCLKIN is divided inside controller by the DIVRATIO
> +        * value set in the CLKSEL register, we need to use the same output
> +        * clock value to calculate the CLKDIV value.
> +        * as per user manual:cclk_in = SDCLKIN / (DIVRATIO + 1)
> +        */
> +       clk_div = ((dwmci_readl(host, DWMCI_CLKSEL) >> DWMCI_DIVRATIO_BIT)
> +                       & DWMCI_DIVRATIO_MASK) + 1;
> +       sclk = get_mmc_clk(host->dev_index);
> +
> +       return sclk / clk_div;
>  }
>
>  /*
> diff --git a/include/dwmmc.h b/include/dwmmc.h
> index 08ced0b..26b53af 100644
> --- a/include/dwmmc.h
> +++ b/include/dwmmc.h
> @@ -138,7 +138,7 @@ struct dwmci_host {
>         struct mmc *mmc;
>
>         void (*clksel)(struct dwmci_host *host);
> -       unsigned int (*mmc_clk)(int dev_index);
> +       unsigned int (*mmc_clk)(struct dwmci_host *host);
>  };
>
>  struct dwmci_idmac {
> --
> 1.7.12.4
>
> _______________________________________________
> U-Boot mailing list
> U-Boot at lists.denx.de
> http://lists.denx.de/mailman/listinfo/u-boot



-- 
Regards,
Rajeshwari Shinde


More information about the U-Boot mailing list