diff mbox series

[U-Boot,V3,1/6] mmc: tmio: Switch to clock framework

Message ID 20181113234050.7653-1-marek.vasut+renesas@gmail.com
State Deferred
Delegated to: Peng Fan
Headers show
Series [U-Boot,V3,1/6] mmc: tmio: Switch to clock framework | expand

Commit Message

Marek Vasut Nov. 13, 2018, 11:40 p.m. UTC
Switch the driver to using clk_get_rate()/clk_set_rate() instead of
caching the mclk frequency in it's private data. This is required on
the SDHI variant of the controller, where the upstream mclk need to
be adjusted when using UHS modes.

Platforms which do not support clock framework or do not support it
in eg. SPL default to 100 MHz clock.

Signed-off-by: Marek Vasut <marek.vasut+renesas@gmail.com>
Cc: Masahiro Yamada <yamada.masahiro@socionext.com>
---
V2: - Fix build on certain platforms using SPL without clock framework
V3: - Turn clk_get_rate into a callback and fill it as needed on both
      renesas and socionext platforms
---
 drivers/mmc/renesas-sdhi.c | 21 +++++++++++++--------
 drivers/mmc/tmio-common.c  | 17 ++++++++++++++---
 drivers/mmc/tmio-common.h  |  5 ++++-
 drivers/mmc/uniphier-sd.c  | 30 ++++++++++++++++++++----------
 4 files changed, 51 insertions(+), 22 deletions(-)

Comments

Marek Vasut Nov. 26, 2018, 9:35 p.m. UTC | #1
On 11/14/2018 12:40 AM, Marek Vasut wrote:
> Switch the driver to using clk_get_rate()/clk_set_rate() instead of
> caching the mclk frequency in it's private data. This is required on
> the SDHI variant of the controller, where the upstream mclk need to
> be adjusted when using UHS modes.
> 
> Platforms which do not support clock framework or do not support it
> in eg. SPL default to 100 MHz clock.
> 
> Signed-off-by: Marek Vasut <marek.vasut+renesas@gmail.com>
> Cc: Masahiro Yamada <yamada.masahiro@socionext.com>

Yamada-san, can you please check 1/6..3/6 ?

Thanks !
Masahiro Yamada Nov. 27, 2018, 3:45 a.m. UTC | #2
On Tue, Nov 27, 2018 at 6:35 AM Marek Vasut <marek.vasut@gmail.com> wrote:
>
> On 11/14/2018 12:40 AM, Marek Vasut wrote:
> > Switch the driver to using clk_get_rate()/clk_set_rate() instead of
> > caching the mclk frequency in it's private data. This is required on
> > the SDHI variant of the controller, where the upstream mclk need to
> > be adjusted when using UHS modes.
> >
> > Platforms which do not support clock framework or do not support it
> > in eg. SPL default to 100 MHz clock.
> >
> > Signed-off-by: Marek Vasut <marek.vasut+renesas@gmail.com>
> > Cc: Masahiro Yamada <yamada.masahiro@socionext.com>
>
> Yamada-san, can you please check 1/6..3/6 ?


Not tested, but 1/6, 2/6 look good.
I left comments in 3/6.




--
Best Regards
Masahiro Yamada
Marek Vasut Nov. 27, 2018, 12:24 p.m. UTC | #3
On 11/27/2018 04:45 AM, Masahiro Yamada wrote:
> On Tue, Nov 27, 2018 at 6:35 AM Marek Vasut <marek.vasut@gmail.com> wrote:
>>
>> On 11/14/2018 12:40 AM, Marek Vasut wrote:
>>> Switch the driver to using clk_get_rate()/clk_set_rate() instead of
>>> caching the mclk frequency in it's private data. This is required on
>>> the SDHI variant of the controller, where the upstream mclk need to
>>> be adjusted when using UHS modes.
>>>
>>> Platforms which do not support clock framework or do not support it
>>> in eg. SPL default to 100 MHz clock.
>>>
>>> Signed-off-by: Marek Vasut <marek.vasut+renesas@gmail.com>
>>> Cc: Masahiro Yamada <yamada.masahiro@socionext.com>
>>
>> Yamada-san, can you please check 1/6..3/6 ?
> 
> 
> Not tested, but 1/6, 2/6 look good.
> I left comments in 3/6.

You can grab the whole bulk at [1] and test it if you want. There are
some extra renesas-specific bits, but those shouldn't affect you.

btw is there any chance to buy a uniphier board with TMIO SD controller?

[1] https://github.com/marex/u-boot-sh/commits/mmc-next-v4
diff mbox series

Patch

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);