CLKSEL register offset may vary between different Exynos chips, e.g. on
ARM64 vs ARM32 chips. Provide a way to specify its offset value for each
compatible instead of hard-coding its value in read/write calls.

No functional change.

Signed-off-by: Sam Protsenko <semen.protse...@linaro.org>
---
Changes in v5:
  - (none)

Changes in v4:
  - (none)

Changes in v3:
  - (none)

Changes in v2:
  - (none)

 drivers/mmc/exynos_dw_mmc.c | 30 ++++++++++++++++++++++++++----
 1 file changed, 26 insertions(+), 4 deletions(-)

diff --git a/drivers/mmc/exynos_dw_mmc.c b/drivers/mmc/exynos_dw_mmc.c
index 4108af47e518..fd2ced3d711d 100644
--- a/drivers/mmc/exynos_dw_mmc.c
+++ b/drivers/mmc/exynos_dw_mmc.c
@@ -33,6 +33,11 @@ struct exynos_mmc_plat {
 };
 #endif
 
+/* Chip specific data */
+struct exynos_dwmmc_variant {
+       u32 clksel;             /* CLKSEL register offset */
+};
+
 /* Exynos implmentation specific drver private data */
 struct dwmci_exynos_priv_data {
 #ifdef CONFIG_DM_MMC
@@ -40,6 +45,7 @@ struct dwmci_exynos_priv_data {
 #endif
        struct clk clk;
        u32 sdr_timing;
+       const struct exynos_dwmmc_variant *chip;
 };
 
 static struct dwmci_exynos_priv_data *exynos_dwmmc_get_priv(
@@ -115,13 +121,14 @@ static int exynos_dwmci_clksel(struct dwmci_host *host)
 {
        struct dwmci_exynos_priv_data *priv = exynos_dwmmc_get_priv(host);
 
-       dwmci_writel(host, DWMCI_CLKSEL, priv->sdr_timing);
+       dwmci_writel(host, priv->chip->clksel, priv->sdr_timing);
 
        return 0;
 }
 
 unsigned int exynos_dwmci_get_clk(struct dwmci_host *host, uint freq)
 {
+       struct dwmci_exynos_priv_data *priv = exynos_dwmmc_get_priv(host);
        unsigned long sclk;
        int8_t clk_div;
        int err;
@@ -132,7 +139,7 @@ unsigned int exynos_dwmci_get_clk(struct dwmci_host *host, 
uint freq)
         * 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)
+       clk_div = ((dwmci_readl(host, priv->chip->clksel) >> DWMCI_DIVRATIO_BIT)
                        & DWMCI_DIVRATIO_MASK) + 1;
 
        err = exynos_dwmmc_get_sclk(host, &sclk);
@@ -229,6 +236,8 @@ static int exynos_dwmmc_of_to_plat(struct udevice *dev)
        int err = 0;
        u32 div, timing[2];
 
+       priv->chip = (struct exynos_dwmmc_variant *)dev_get_driver_data(dev);
+
 #ifdef CONFIG_CPU_V7A
        const void *blob = gd->fdt_blob;
        int node = dev_of_offset(dev);
@@ -322,9 +331,22 @@ static int exynos_dwmmc_bind(struct udevice *dev)
        return dwmci_bind(dev, &plat->mmc, &plat->cfg);
 }
 
+static const struct exynos_dwmmc_variant exynos4_drv_data = {
+       .clksel = DWMCI_CLKSEL,
+};
+
+static const struct exynos_dwmmc_variant exynos5_drv_data = {
+       .clksel = DWMCI_CLKSEL,
+};
+
 static const struct udevice_id exynos_dwmmc_ids[] = {
-       { .compatible = "samsung,exynos4412-dw-mshc" },
-       { .compatible = "samsung,exynos-dwmmc" },
+       {
+               .compatible     = "samsung,exynos4412-dw-mshc",
+               .data           = (ulong)&exynos4_drv_data,
+       }, {
+               .compatible     = "samsung,exynos-dwmmc",
+               .data           = (ulong)&exynos5_drv_data,
+       },
        { }
 };
 
-- 
2.39.2

Reply via email to