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