summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--drivers/mmc/renesas-sdhi.c21
-rw-r--r--drivers/mmc/tmio-common.c17
-rw-r--r--drivers/mmc/tmio-common.h5
-rw-r--r--drivers/mmc/uniphier-sd.c30
4 files changed, 51 insertions, 22 deletions
diff --git a/drivers/mmc/renesas-sdhi.c b/drivers/mmc/renesas-sdhi.c
index e7f96f8bf2..f4283d055f 100644
--- a/drivers/mmc/renesas-sdhi.c
+++ b/drivers/mmc/renesas-sdhi.c
@@ -358,15 +358,21 @@ static const struct udevice_id renesas_sdhi_match[] = {
{ /* sentinel */ }
};
+static ulong renesas_sdhi_clk_get_rate(struct tmio_sd_priv *priv)
+{
+ return clk_get_rate(&priv->clk);
+}
+
static int renesas_sdhi_probe(struct udevice *dev)
{
struct tmio_sd_priv *priv = dev_get_priv(dev);
u32 quirks = dev_get_driver_data(dev);
struct fdt_resource reg_res;
- struct clk clk;
DECLARE_GLOBAL_DATA_PTR;
int ret;
+ priv->clk_get_rate = renesas_sdhi_clk_get_rate;
+
if (quirks == RENESAS_GEN2_QUIRKS) {
ret = fdt_get_resource(gd->fdt_blob, dev_of_offset(dev),
"reg", 0, &reg_res);
@@ -380,22 +386,21 @@ static int renesas_sdhi_probe(struct udevice *dev)
quirks |= TMIO_SD_CAP_16BIT;
}
- ret = clk_get_by_index(dev, 0, &clk);
+ ret = clk_get_by_index(dev, 0, &priv->clk);
if (ret < 0) {
dev_err(dev, "failed to get host clock\n");
return ret;
}
/* set to max rate */
- priv->mclk = clk_set_rate(&clk, ULONG_MAX);
- if (IS_ERR_VALUE(priv->mclk)) {
+ ret = clk_set_rate(&priv->clk, 200000000);
+ if (ret < 0) {
dev_err(dev, "failed to set rate for host clock\n");
- clk_free(&clk);
- return priv->mclk;
+ clk_free(&priv->clk);
+ return ret;
}
- ret = clk_enable(&clk);
- clk_free(&clk);
+ ret = clk_enable(&priv->clk);
if (ret) {
dev_err(dev, "failed to enable host clock\n");
return ret;
diff --git a/drivers/mmc/tmio-common.c b/drivers/mmc/tmio-common.c
index 0eca83a0f4..3ba2f07460 100644
--- a/drivers/mmc/tmio-common.c
+++ b/drivers/mmc/tmio-common.c
@@ -555,16 +555,24 @@ static void tmio_sd_set_ddr_mode(struct tmio_sd_priv *priv,
tmio_sd_writel(priv, tmp, TMIO_SD_IF_MODE);
}
+static ulong tmio_sd_clk_get_rate(struct tmio_sd_priv *priv)
+{
+ return priv->clk_get_rate(priv);
+}
+
static void tmio_sd_set_clk_rate(struct tmio_sd_priv *priv,
struct mmc *mmc)
{
unsigned int divisor;
u32 val, tmp;
+ ulong mclk;
if (!mmc->clock)
return;
- divisor = DIV_ROUND_UP(priv->mclk, mmc->clock);
+ mclk = tmio_sd_clk_get_rate(priv);
+
+ divisor = DIV_ROUND_UP(mclk, mmc->clock);
if (divisor <= 1)
val = (priv->caps & TMIO_SD_CAP_RCAR) ?
@@ -708,6 +716,7 @@ int tmio_sd_probe(struct udevice *dev, u32 quirks)
struct tmio_sd_priv *priv = dev_get_priv(dev);
struct mmc_uclass_priv *upriv = dev_get_uclass_priv(dev);
fdt_addr_t base;
+ ulong mclk;
int ret;
base = devfdt_get_addr(dev);
@@ -750,10 +759,12 @@ int tmio_sd_probe(struct udevice *dev, u32 quirks)
tmio_sd_host_init(priv);
+ mclk = tmio_sd_clk_get_rate(priv);
+
plat->cfg.voltages = MMC_VDD_165_195 | MMC_VDD_32_33 | MMC_VDD_33_34;
- plat->cfg.f_min = priv->mclk /
+ plat->cfg.f_min = mclk /
(priv->caps & TMIO_SD_CAP_DIV1024 ? 1024 : 512);
- plat->cfg.f_max = priv->mclk;
+ plat->cfg.f_max = mclk;
plat->cfg.b_max = U32_MAX; /* max value of TMIO_SD_SECCNT */
upriv->mmc = &plat->mmc;
diff --git a/drivers/mmc/tmio-common.h b/drivers/mmc/tmio-common.h
index 792b1ba5ae..6591c61c3c 100644
--- a/drivers/mmc/tmio-common.h
+++ b/drivers/mmc/tmio-common.h
@@ -117,7 +117,6 @@ struct tmio_sd_plat {
struct tmio_sd_priv {
void __iomem *regbase;
- unsigned long mclk;
unsigned int version;
u32 caps;
#define TMIO_SD_CAP_NONREMOVABLE BIT(0) /* Nonremovable e.g. eMMC */
@@ -133,6 +132,10 @@ struct tmio_sd_priv {
#ifdef CONFIG_DM_REGULATOR
struct udevice *vqmmc_dev;
#endif
+#if CONFIG_IS_ENABLED(CLK)
+ struct clk clk;
+#endif
+ ulong (*clk_get_rate)(struct tmio_sd_priv *);
};
int tmio_sd_send_cmd(struct udevice *dev, struct mmc_cmd *cmd,
diff --git a/drivers/mmc/uniphier-sd.c b/drivers/mmc/uniphier-sd.c
index 813c28494c..6539880ab5 100644
--- a/drivers/mmc/uniphier-sd.c
+++ b/drivers/mmc/uniphier-sd.c
@@ -31,35 +31,45 @@ static const struct udevice_id uniphier_sd_match[] = {
{ /* sentinel */ }
};
+static ulong uniphier_sd_clk_get_rate(struct tmio_sd_priv *priv)
+{
+#if CONFIG_IS_ENABLED(CLK)
+ return clk_get_rate(&priv->clk);
+#elif CONFIG_SPL_BUILD
+ return 100000000;
+#else
+ return 0;
+#endif
+}
+
static int uniphier_sd_probe(struct udevice *dev)
{
struct tmio_sd_priv *priv = dev_get_priv(dev);
+
+ priv->clk_get_rate = uniphier_sd_clk_get_rate;
+
#ifndef CONFIG_SPL_BUILD
- struct clk clk;
int ret;
- ret = clk_get_by_index(dev, 0, &clk);
+ ret = clk_get_by_index(dev, 0, &priv->clk);
if (ret < 0) {
dev_err(dev, "failed to get host clock\n");
return ret;
}
/* set to max rate */
- priv->mclk = clk_set_rate(&clk, ULONG_MAX);
- if (IS_ERR_VALUE(priv->mclk)) {
+ ret = clk_set_rate(&priv->clk, ULONG_MAX);
+ if (ret < 0) {
dev_err(dev, "failed to set rate for host clock\n");
- clk_free(&clk);
- return priv->mclk;
+ clk_free(&priv->clk);
+ return ret;
}
- ret = clk_enable(&clk);
- clk_free(&clk);
+ ret = clk_enable(&priv->clk);
if (ret) {
dev_err(dev, "failed to enable host clock\n");
return ret;
}
-#else
- priv->mclk = 100000000;
#endif
return tmio_sd_probe(dev, 0);