@@ -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,
+ },
{ }
};
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.protsenko@linaro.org> --- Changes in v3: - (none) Changes in v2: - (none) drivers/mmc/exynos_dw_mmc.c | 30 ++++++++++++++++++++++++++---- 1 file changed, 26 insertions(+), 4 deletions(-)