]> git.dujemihanovic.xyz Git - u-boot.git/commitdiff
mmc: renesas-sdhi: Initialize module on RZ/G2L
authorPaul Barker <paul.barker.ct@bp.renesas.com>
Mon, 16 Oct 2023 09:25:38 +0000 (10:25 +0100)
committerMarek Vasut <marek.vasut+renesas@mailbox.org>
Tue, 17 Oct 2023 01:27:42 +0000 (03:27 +0200)
On the Renesas RZ/G2L SoC family, we must ensure that the required clock
signals are enabled and the reset signal is de-asserted before we try to
communicate with the SDHI module.

Signed-off-by: Paul Barker <paul.barker.ct@bp.renesas.com>
Reviewed-by: Biju Das <biju.das.jz@bp.renesas.com>
Reviewed-by: Lad Prabhakar <prabhakar.mahadev-lad.rj@bp.renesas.com>
Reviewed-by: Marek Vasut <marek.vasut+renesas@mailbox.org>
drivers/mmc/renesas-sdhi.c

index 1536c9782041affa58f16fa16423480dc3db5a2e..1ea6e1066f2b881c3189b5a1f5df29918ae50a90 100644 (file)
@@ -20,6 +20,7 @@
 #include <linux/io.h>
 #include <linux/sizes.h>
 #include <power/regulator.h>
+#include <reset.h>
 #include <asm/unaligned.h>
 #include "tmio-common.h"
 
@@ -958,6 +959,74 @@ static void renesas_sdhi_filter_caps(struct udevice *dev)
                priv->needs_clkh_fallback = false;
 }
 
+static int rzg2l_sdhi_setup(struct udevice *dev)
+{
+       struct tmio_sd_priv *priv = dev_get_priv(dev);
+       struct clk imclk2, aclk;
+       struct reset_ctl rst;
+       int ret;
+
+       /*
+        * On members of the RZ/G2L SoC family, we need to enable
+        * additional chip detect and bus clocks, then release the SDHI
+        * module from reset.
+        */
+       ret = clk_get_by_name(dev, "cd", &imclk2);
+       if (ret < 0) {
+               dev_err(dev, "failed to get imclk2 (chip detect clk)\n");
+               goto err_get_imclk2;
+       }
+
+       ret = clk_get_by_name(dev, "aclk", &aclk);
+       if (ret < 0) {
+               dev_err(dev, "failed to get aclk\n");
+               goto err_get_aclk;
+       }
+
+       ret = clk_enable(&imclk2);
+       if (ret < 0) {
+               dev_err(dev, "failed to enable imclk2 (chip detect clk)\n");
+               goto err_imclk2;
+       }
+
+       ret = clk_enable(&aclk);
+       if (ret < 0) {
+               dev_err(dev, "failed to enable aclk\n");
+               goto err_aclk;
+       }
+
+       ret = reset_get_by_index(dev, 0, &rst);
+       if (ret < 0) {
+               dev_err(dev, "failed to get reset line\n");
+               goto err_reset;
+       }
+
+       ret = reset_deassert(&rst);
+       if (ret < 0) {
+               dev_err(dev, "failed to de-assert reset line\n");
+               goto err_reset;
+       }
+
+       ret = tmio_sd_probe(dev, priv->quirks);
+       if (ret)
+               goto err_tmio_probe;
+
+       return 0;
+
+err_tmio_probe:
+       reset_assert(&rst);
+err_reset:
+       clk_disable(&aclk);
+err_aclk:
+       clk_disable(&imclk2);
+err_imclk2:
+       clk_free(&aclk);
+err_get_aclk:
+       clk_free(&imclk2);
+err_get_imclk2:
+       return ret;
+}
+
 static int renesas_sdhi_probe(struct udevice *dev)
 {
        struct tmio_sd_priv *priv = dev_get_priv(dev);
@@ -1012,7 +1081,10 @@ static int renesas_sdhi_probe(struct udevice *dev)
                goto err_clkh;
        }
 
-       ret = tmio_sd_probe(dev, priv->quirks);
+       if (device_is_compatible(dev, "renesas,sdhi-r9a07g044"))
+               ret = rzg2l_sdhi_setup(dev);
+       else
+               ret = tmio_sd_probe(dev, priv->quirks);
        if (ret)
                goto err_tmio_probe;