Add support for emmc hardware reset for the emmc card, trigger this
hardware reset at the end of arasan_sdhci_probe() function.

Signed-off-by: Venkatesh Yadav Abbarapu <venkatesh.abbar...@amd.com>
---
 drivers/mmc/zynq_sdhci.c | 25 ++++++++++++++++++++++++-
 1 file changed, 24 insertions(+), 1 deletion(-)

diff --git a/drivers/mmc/zynq_sdhci.c b/drivers/mmc/zynq_sdhci.c
index 4d1f92931a3..f99d464a467 100644
--- a/drivers/mmc/zynq_sdhci.c
+++ b/drivers/mmc/zynq_sdhci.c
@@ -85,6 +85,8 @@
 #define VERSAL_NET_EMMC_ICLK_PHASE_DDR52_DLL           146
 #define VERSAL_NET_PHY_CTRL_STRB90_STRB180_VAL         0X77
 
+#define SDHCI_HW_RST_EN                        BIT(4)
+
 struct arasan_sdhci_clk_data {
        int clk_phase_in[MMC_TIMING_MMC_HS400 + 1];
        int clk_phase_out[MMC_TIMING_MMC_HS400 + 1];
@@ -1101,6 +1103,21 @@ static int sdhci_zynqmp_set_dynamic_config(struct 
arasan_sdhci_priv *priv,
 }
 #endif
 
+static void sdhci_arasan_hw_reset(struct sdhci_host *host)
+{
+       u8 reg;
+
+       reg = sdhci_readb(host, SDHCI_POWER_CONTROL);
+       reg |= SDHCI_HW_RST_EN;
+       sdhci_writeb(host, reg, SDHCI_POWER_CONTROL);
+       /* As per eMMC spec, minimum 1us is required but give it 2us for good 
measure */
+       udelay(2);
+       reg &= ~SDHCI_HW_RST_EN;
+       sdhci_writeb(host, reg, SDHCI_POWER_CONTROL);
+       /* As per eMMC spec, minimum 200us is required but give it 300us for 
good measure */
+       udelay(300);
+}
+
 static int arasan_sdhci_probe(struct udevice *dev)
 {
        struct arasan_sdhci_plat *plat = dev_get_plat(dev);
@@ -1221,7 +1238,13 @@ static int arasan_sdhci_probe(struct udevice *dev)
                }
        }
 
-       return sdhci_probe(dev);
+       ret = sdhci_probe(dev);
+       if (ret)
+               return ret;
+
+       sdhci_arasan_hw_reset(host);
+
+       return 0;
 }
 
 static int arasan_sdhci_of_to_plat(struct udevice *dev)
-- 
2.34.1

Reply via email to