host->mclk.ufs_sel_min_clki = clki;
                        clk_disable_unprepare(clki->clk);
                        list_del(&clki->list);
+               } else if (!strcmp(clki->name, "ufs_fde")) {
+                       host->mclk.ufs_fde_clki = clki;
+               } else if (!strcmp(clki->name, "ufs_fde_max_src")) {
+                       host->mclk.ufs_fde_max_clki = clki;
+                       clk_disable_unprepare(clki->clk);
+                       list_del(&clki->list);
+               } else if (!strcmp(clki->name, "ufs_fde_min_src")) {
+                       host->mclk.ufs_fde_min_clki = clki;
+                       clk_disable_unprepare(clki->clk);
+                       list_del(&clki->list);
                }
        }
 
+       list_for_each_entry(clki, head, list) {
+               dev_info(hba->dev, "clk \"%s\" present", clki->name);
+       }
+
        if (!ufs_mtk_is_clk_scale_ready(hba)) {
                hba->caps &= ~UFSHCD_CAP_CLK_SCALING;
                dev_info(hba->dev,
        struct ufs_mtk_host *host = ufshcd_get_variant(hba);
        struct ufs_mtk_clk *mclk = &host->mclk;
        struct ufs_clk_info *clki = mclk->ufs_sel_clki;
+       struct ufs_clk_info *fde_clki = mclk->ufs_fde_clki;
        struct regulator *reg;
        int volt, ret = 0;
        bool clk_bind_vcore = false;
+       bool clk_fde_scale = false;
 
        if (!hba->clk_scaling.is_initialized)
                return;
 
-       if (!clki)
+       if (!clki || !fde_clki)
                return;
 
        reg = host->mclk.reg_vcore;
        if (reg && volt != 0)
                clk_bind_vcore = true;
 
+       if (mclk->ufs_fde_max_clki && mclk->ufs_fde_min_clki)
+               clk_fde_scale = true;
+
        ret = clk_prepare_enable(clki->clk);
        if (ret) {
                dev_info(hba->dev,
                return;
        }
 
+       if (clk_fde_scale) {
+               ret = clk_prepare_enable(fde_clki->clk);
+               if (ret) {
+                       dev_info(hba->dev,
+                                "fde clk_prepare_enable() fail, ret: %d\n", ret);
+                       return;
+               }
+       }
+
        if (scale_up) {
                if (clk_bind_vcore) {
                        ret = regulator_set_voltage(reg, volt, INT_MAX);
                        dev_info(hba->dev, "Failed to set clk mux, ret = %d\n",
                                ret);
                }
+
+               if (clk_fde_scale) {
+                       ret = clk_set_parent(fde_clki->clk,
+                               mclk->ufs_fde_max_clki->clk);
+                       if (ret) {
+                               dev_info(hba->dev,
+                                       "Failed to set fde clk mux, ret = %d\n",
+                                       ret);
+                       }
+               }
        } else {
+               if (clk_fde_scale) {
+                       ret = clk_set_parent(fde_clki->clk,
+                               mclk->ufs_fde_min_clki->clk);
+                       if (ret) {
+                               dev_info(hba->dev,
+                                       "Failed to set fde clk mux, ret = %d\n",
+                                       ret);
+                               goto out;
+                       }
+               }
+
                ret = clk_set_parent(clki->clk, mclk->ufs_sel_min_clki->clk);
                if (ret) {
                        dev_info(hba->dev, "Failed to set clk mux, ret = %d\n",
 
 out:
        clk_disable_unprepare(clki->clk);
+
+       if (clk_fde_scale)
+               clk_disable_unprepare(fde_clki->clk);
 }
 
 /**