On RK3399, a register bit must be set to enable Enhanced Strobe.
Let the Rockchip SDHCI driver set it when Enhanced Strobe configuration
is requested.

This is mostly ported from Linux' Arasan SDHCI driver which happens
to be the underlying IP. (drivers/mmc/host/sdhci-of-arasan.c in Linux
tree).

Signed-off-by: Alper Nebi Yasak <alpernebiya...@gmail.com>
---

 drivers/mmc/rockchip_sdhci.c | 28 ++++++++++++++++++++++++++++
 1 file changed, 28 insertions(+)

diff --git a/drivers/mmc/rockchip_sdhci.c b/drivers/mmc/rockchip_sdhci.c
index 278473899c7c..7457255fa080 100644
--- a/drivers/mmc/rockchip_sdhci.c
+++ b/drivers/mmc/rockchip_sdhci.c
@@ -42,6 +42,9 @@
        ((((x) >> PHYCTRL_DLLRDY_SHIFT) & PHYCTRL_DLLRDY_MASK) ==\
        PHYCTRL_DLLRDY_DONE)
 
+#define ARASAN_VENDOR_REGISTER         0x78
+#define ARASAN_VENDOR_ENHANCED_STROBE  BIT(0)
+
 /* Rockchip specific Registers */
 #define DWCMSHC_EMMC_DLL_CTRL          0x800
 #define DWCMSHC_EMMC_DLL_CTRL_RESET    BIT(1)
@@ -93,6 +96,7 @@ struct sdhci_data {
        int (*emmc_set_clock)(struct sdhci_host *host, unsigned int clock);
        int (*emmc_phy_init)(struct udevice *dev);
        int (*get_phy)(struct udevice *dev);
+       int (*set_enhanced_strobe)(struct sdhci_host *host);
 };
 
 static int rk3399_emmc_phy_init(struct udevice *dev)
@@ -198,6 +202,17 @@ static int rk3399_sdhci_emmc_set_clock(struct sdhci_host 
*host, unsigned int clo
        return 0;
 }
 
+static int rk3399_set_enhanced_strobe(struct sdhci_host *host)
+{
+       u32 vendor;
+
+       vendor = sdhci_readl(host, ARASAN_VENDOR_REGISTER);
+       vendor |= ARASAN_VENDOR_ENHANCED_STROBE;
+       sdhci_writel(host, vendor, ARASAN_VENDOR_REGISTER);
+
+       return 0;
+}
+
 static int rk3568_emmc_phy_init(struct udevice *dev)
 {
        struct rockchip_sdhc *prv = dev_get_priv(dev);
@@ -355,9 +370,21 @@ static int rockchip_sdhci_execute_tuning(struct mmc *mmc, 
u8 opcode)
        return ret;
 }
 
+static int rockchip_sdhci_set_enhanced_strobe(struct sdhci_host *host)
+{
+       struct rockchip_sdhc *priv = container_of(host, struct rockchip_sdhc, 
host);
+       struct sdhci_data *data = (struct sdhci_data 
*)dev_get_driver_data(priv->dev);
+
+       if (data->set_enhanced_strobe)
+               return data->set_enhanced_strobe(host);
+
+       return -ENOTSUPP;
+}
+
 static struct sdhci_ops rockchip_sdhci_ops = {
        .set_ios_post   = rockchip_sdhci_set_ios_post,
        .platform_execute_tuning = &rockchip_sdhci_execute_tuning,
+       .set_enhanced_strobe = &rockchip_sdhci_set_enhanced_strobe,
 };
 
 static int rockchip_sdhci_probe(struct udevice *dev)
@@ -439,6 +466,7 @@ static const struct sdhci_data rk3399_data = {
        .emmc_set_clock = rk3399_sdhci_emmc_set_clock,
        .get_phy = rk3399_emmc_get_phy,
        .emmc_phy_init = rk3399_emmc_phy_init,
+       .set_enhanced_strobe = rk3399_set_enhanced_strobe,
 };
 
 static const struct sdhci_data rk3568_data = {
-- 
2.33.1

Reply via email to