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...@bp.renesas.com>
Reviewed-by: Biju Das <biju.das...@bp.renesas.com>
Reviewed-by: Lad Prabhakar <prabhakar.mahadev-lad...@bp.renesas.com>
---
 drivers/mmc/renesas-sdhi.c | 61 ++++++++++++++++++++++++++++++++++++++
 1 file changed, 61 insertions(+)

diff --git a/drivers/mmc/renesas-sdhi.c b/drivers/mmc/renesas-sdhi.c
index 8e716f74491f..170c5dcc2ebe 100644
--- a/drivers/mmc/renesas-sdhi.c
+++ b/drivers/mmc/renesas-sdhi.c
@@ -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"
 
@@ -964,6 +965,8 @@ static int renesas_sdhi_probe(struct udevice *dev)
        u32 quirks = dev_get_driver_data(dev);
        struct fdt_resource reg_res;
        DECLARE_GLOBAL_DATA_PTR;
+       struct clk imclk2, aclk;
+       struct reset_ctl rst;
        int ret;
 
        priv->clk_get_rate = renesas_sdhi_clk_get_rate;
@@ -1012,6 +1015,49 @@ static int renesas_sdhi_probe(struct udevice *dev)
                goto err_clkh;
        }
 
+       if (IS_ENABLED(CONFIG_RZG2L)) {
+               /*
+                * 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;
+               }
+       }
+
        priv->quirks = quirks;
        ret = tmio_sd_probe(dev, quirks);
        if (ret)
@@ -1028,6 +1074,21 @@ static int renesas_sdhi_probe(struct udevice *dev)
        return 0;
 
 err_tmio_probe:
+       if (IS_ENABLED(CONFIG_RZG2L))
+               reset_assert(&rst);
+err_reset:
+       if (IS_ENABLED(CONFIG_RZG2L))
+               clk_disable(&aclk);
+err_aclk:
+       if (IS_ENABLED(CONFIG_RZG2L))
+               clk_disable(&imclk2);
+err_imclk2:
+       if (IS_ENABLED(CONFIG_RZG2L))
+               clk_free(&aclk);
+err_get_aclk:
+       if (IS_ENABLED(CONFIG_RZG2L))
+               clk_free(&imclk2);
+err_get_imclk2:
        clk_disable(&priv->clk);
 err_clkh:
        clk_free(&priv->clkh);
-- 
2.34.1

Reply via email to