diff options
author | Tom Rini <trini@konsulko.com> | 2023-10-17 09:15:56 -0400 |
---|---|---|
committer | Tom Rini <trini@konsulko.com> | 2023-10-17 09:15:56 -0400 |
commit | e65b5d35c9116485366bb08138043d51220551da (patch) | |
tree | a7ff86d5ab6e831cb05c875ab9c1521c5405fe0f /drivers/mmc/renesas-sdhi.c | |
parent | c41df16b27bbe37be861072d876f348748684737 (diff) | |
parent | 4e65545f7a35430710ce95bdddf9d683f7a3f72a (diff) | |
download | u-boot-WIP/17Oct2023.zip u-boot-WIP/17Oct2023.tar.gz u-boot-WIP/17Oct2023.tar.bz2 |
Merge branch 'master' of https://source.denx.de/u-boot/custodians/u-boot-shWIP/17Oct2023
- RZ/G2L part 1, except for two serial port patches which I had to drop
as they broke R2Dplus, they will come later via subsequent PR.
Diffstat (limited to 'drivers/mmc/renesas-sdhi.c')
-rw-r--r-- | drivers/mmc/renesas-sdhi.c | 81 |
1 files changed, 76 insertions, 5 deletions
diff --git a/drivers/mmc/renesas-sdhi.c b/drivers/mmc/renesas-sdhi.c index 8e716f7..1ea6e10 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" @@ -958,17 +959,85 @@ 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); - u32 quirks = dev_get_driver_data(dev); struct fdt_resource reg_res; DECLARE_GLOBAL_DATA_PTR; int ret; priv->clk_get_rate = renesas_sdhi_clk_get_rate; - if (quirks == RENESAS_GEN2_QUIRKS) { + priv->quirks = dev_get_driver_data(dev); + if (priv->quirks == RENESAS_GEN2_QUIRKS) { ret = fdt_get_resource(gd->fdt_blob, dev_of_offset(dev), "reg", 0, ®_res); if (ret < 0) { @@ -978,7 +1047,7 @@ static int renesas_sdhi_probe(struct udevice *dev) } if (fdt_resource_size(®_res) == 0x100) - quirks |= TMIO_SD_CAP_16BIT; + priv->quirks |= TMIO_SD_CAP_16BIT; } ret = clk_get_by_index(dev, 0, &priv->clk); @@ -1012,8 +1081,10 @@ static int renesas_sdhi_probe(struct udevice *dev) goto err_clkh; } - priv->quirks = quirks; - ret = tmio_sd_probe(dev, 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; |