+#if defined(CONFIG_ARCH_VERSAL_NET)
+/**
+ * arasan_phy_set_delaychain - Set eMMC delay chain based Input/Output clock
+ *
+ * @host: Pointer to the sdhci_host structure
+ * @enable: Enable or disable Delay chain based Tx and Rx clock
+ * Return: None
+ *
+ * Enable or disable eMMC delay chain based Input and Output clock in
+ * PHY_CTRL_REG2
+ */
+static void arasan_phy_set_delaychain(struct sdhci_host *host, bool enable)
+{
+ u32 reg;
+
+ reg = sdhci_readw(host, PHY_CTRL_REG2);
+ if (enable)
+ reg |= PHY_CTRL_SEL_DLY_TX_MASK | PHY_CTRL_SEL_DLY_RX_MASK;
+ else
+ reg &= ~(PHY_CTRL_SEL_DLY_TX_MASK | PHY_CTRL_SEL_DLY_RX_MASK);
+
+ sdhci_writew(host, reg, PHY_CTRL_REG2);
+}
+
+/**
+ * arasan_phy_set_dll - Set eMMC DLL clock
+ *
+ * @host: Pointer to the sdhci_host structure
+ * @enable: Enable or disable DLL clock
+ * Return: 0 if success or timeout error
+ *
+ * Enable or disable eMMC DLL clock in PHY_CTRL_REG2. When DLL enable is
+ * set, wait till DLL is locked
+ */
+static int arasan_phy_set_dll(struct sdhci_host *host, bool enable)
+{
+ u32 reg;
+
+ reg = sdhci_readw(host, PHY_CTRL_REG2);
+ if (enable)
+ reg |= PHY_CTRL_EN_DLL_MASK;
+ else
+ reg &= ~PHY_CTRL_EN_DLL_MASK;
+
+ sdhci_writew(host, reg, PHY_CTRL_REG2);
+
+ /* If DLL is disabled return success */
+ if (!enable)
+ return 0;
+
+ /* If DLL is enabled wait till DLL loop is locked, which is
+ * indicated by dll_rdy bit(bit1) in PHY_CTRL_REG2
+ */
+ return readl_relaxed_poll_timeout(host->ioaddr + PHY_CTRL_REG2, reg,
+ (reg & PHY_CTRL_DLL_RDY_MASK),
+ 1000 * PHY_DLL_TIMEOUT_MS);
+}
+
+/**
+ * arasan_phy_dll_set_freq - Select frequency range of DLL for eMMC
+ *
+ * @host: Pointer to the sdhci_host structure
+ * @clock: clock value
+ * Return: None
+ *
+ * Set frequency range bits based on the selected clock for eMMC
+ */
+static void arasan_phy_dll_set_freq(struct sdhci_host *host, int clock)
+{
+ u32 reg, freq_sel, freq;
+
+ freq = DIV_ROUND_CLOSEST(clock, 1000000);
+ if (freq <= 200 && freq > 170)
+ freq_sel = FREQSEL_200M_170M;
+ else if (freq <= 170 && freq > 140)
+ freq_sel = FREQSEL_170M_140M;
+ else if (freq <= 140 && freq > 110)
+ freq_sel = FREQSEL_140M_110M;
+ else if (freq <= 110 && freq > 80)
+ freq_sel = FREQSEL_110M_80M;
+ else
+ freq_sel = FREQSEL_80M_50M;
+
+ reg = sdhci_readw(host, PHY_CTRL_REG2);
+ reg &= ~PHY_CTRL_FREQ_SEL_MASK;
+ reg |= (freq_sel << PHY_CTRL_FREQ_SEL_SHIFT);
+ sdhci_writew(host, reg, PHY_CTRL_REG2);
+}
+
+static int arasan_sdhci_config_dll(struct sdhci_host *host, unsigned int clock, bool enable)
+{
+ struct mmc *mmc = (struct mmc *)host->mmc;
+ struct arasan_sdhci_priv *priv = dev_get_priv(mmc->dev);
+
+ if (enable) {
+ if (priv->internal_phy_reg && clock >= MIN_PHY_CLK_HZ && enable)
+ arasan_phy_set_dll(host, 1);
+ return 0;
+ }
+
+ if (priv->internal_phy_reg && clock >= MIN_PHY_CLK_HZ) {
+ sdhci_writew(host, 0, SDHCI_CLOCK_CONTROL);
+ arasan_phy_set_dll(host, 0);
+ arasan_phy_set_delaychain(host, 0);
+ arasan_phy_dll_set_freq(host, clock);
+ return 0;
+ }
+
+ sdhci_writew(host, 0, SDHCI_CLOCK_CONTROL);
+ arasan_phy_set_delaychain(host, 1);
+
+ return 0;
+}
+#endif
+