static void clk_change_rate(struct clk *clk)
{
struct clk *child;
- unsigned long old_rate;
+ unsigned long old_rate, tmp_rate;
unsigned long best_parent_rate = 0;
old_rate = clk->rate;
/* set parent */
- if (clk->new_parent && clk->new_parent != clk->parent)
+ if (clk->new_parent && clk->new_parent != clk->parent) {
+ if (clk->flags & CLK_SET_RATE_PARENT_IN_ORDER) {
+ tmp_rate = clk->ops->recalc_rate(clk->hw, clk->new_parent->rate);
+ if ((tmp_rate > clk->rate) && (tmp_rate > clk->new_rate)) {
+ if (clk->ops->set_rate)
+ clk->ops->set_rate(clk->hw, clk->new_rate, clk->new_parent->rate);
+ }
+ }
+
__clk_set_parent(clk, clk->new_parent, clk->new_parent_index);
+ }
if (clk->parent)
best_parent_rate = clk->parent->rate;
#define CLK_IS_BASIC BIT(5) /* Basic clk, can't do a to_clk_foo() */
#define CLK_GET_RATE_NOCACHE BIT(6) /* do not use the cached clk rate */
#define CLK_SET_RATE_NO_REPARENT BIT(7) /* don't re-parent on rate change */
+#define CLK_SET_RATE_PARENT_IN_ORDER BIT(8) /* consider the order of re-parent
+ and set_div on rate change */
+
+
/* Rockchip pll flags */
#define CLK_PLL_3188 BIT(0)
#define CLK_IS_BASIC BIT(5) /* Basic clk, can't do a to_clk_foo() */
#define CLK_GET_RATE_NOCACHE BIT(6) /* do not use the cached clk rate */
#define CLK_SET_RATE_NO_REPARENT BIT(7) /* don't re-parent on rate change */
+#define CLK_SET_RATE_PARENT_IN_ORDER BIT(8) /* consider the order of re-parent
+ and set_div on rate change */
+
struct clk_hw;