const struct clk_ops *mux_ops = composite->mux_ops;
        struct clk_hw *rate_hw = composite->rate_hw;
        struct clk_hw *mux_hw = composite->mux_hw;
+       struct clk *parent;
+       unsigned long parent_rate;
+       long tmp_rate, best_rate = 0;
+       unsigned long rate_diff;
+       unsigned long best_rate_diff = ULONG_MAX;
+       int i;
 
        if (rate_hw && rate_ops && rate_ops->determine_rate) {
                rate_hw->clk = hw->clk;
                return rate_ops->determine_rate(rate_hw, rate, best_parent_rate,
                                                best_parent_p);
+       } else if (rate_hw && rate_ops && rate_ops->round_rate &&
+                  mux_hw && mux_ops && mux_ops->set_parent) {
+               *best_parent_p = NULL;
+
+               if (__clk_get_flags(hw->clk) & CLK_SET_RATE_NO_REPARENT) {
+                       *best_parent_p = clk_get_parent(mux_hw->clk);
+                       *best_parent_rate = __clk_get_rate(*best_parent_p);
+
+                       return rate_ops->round_rate(rate_hw, rate,
+                                                   best_parent_rate);
+               }
+
+               for (i = 0; i < __clk_get_num_parents(mux_hw->clk); i++) {
+                       parent = clk_get_parent_by_index(mux_hw->clk, i);
+                       if (!parent)
+                               continue;
+
+                       parent_rate = __clk_get_rate(parent);
+
+                       tmp_rate = rate_ops->round_rate(rate_hw, rate,
+                                                       &parent_rate);
+                       if (tmp_rate < 0)
+                               continue;
+
+                       rate_diff = abs(rate - tmp_rate);
+
+                       if (!rate_diff || !*best_parent_p
+                                      || best_rate_diff > rate_diff) {
+                               *best_parent_p = parent;
+                               *best_parent_rate = parent_rate;
+                               best_rate_diff = rate_diff;
+                               best_rate = tmp_rate;
+                       }
+
+                       if (!rate_diff)
+                               return rate;
+               }
+
+               return best_rate;
        } else if (mux_hw && mux_ops && mux_ops->determine_rate) {
                mux_hw->clk = hw->clk;
                return mux_ops->determine_rate(mux_hw, rate, best_parent_rate,
                composite->rate_hw = rate_hw;
                composite->rate_ops = rate_ops;
                clk_composite_ops->recalc_rate = clk_composite_recalc_rate;
-               if (rate_ops->determine_rate)
+               if (rate_ops->determine_rate ||
+                   (rate_ops->round_rate && clk_composite_ops->set_parent))
                        clk_composite_ops->determine_rate = clk_composite_determine_rate;
        }