ARM: tegra: clock: Round frequency up in clock dividers

When picking clock divider values, the clock framework picks
the closest frequency that is lower than the requested
frequency.  If the value from a clock divider rounds down,
and then the new rounded down frequency is requested, it
will get rounded down again, resulting in a frequency two
steps lower than the original requested frequency.

Fix the problem by rounding up when calculating the frequency
coming out of a clock divider, so if that frequency is
requested again, the same divider value will be picked.

Change-Id: Ieaf74448f67d91aeb7ba08226e48c092d8afaa2b
Signed-off-by: Colin Cross <ccross@android.com>
This commit is contained in:
Colin Cross
2011-01-11 16:59:55 -08:00
parent 4ce07d6140
commit 55bfef75ea
2 changed files with 5 additions and 4 deletions

View File

@@ -143,6 +143,7 @@ static unsigned long clk_predict_rate_from_parent(struct clk *c, struct clk *p)
if (c->mul != 0 && c->div != 0) {
rate *= c->mul;
rate += c->div / 2; /* round up */
do_div(rate, c->div);
}

View File

@@ -827,9 +827,9 @@ static long tegra2_pll_div_clk_round_rate(struct clk *c, unsigned long rate)
divider = clk_div71_get_divider(parent_rate, rate);
if (divider < 0)
return divider;
return parent_rate * 2 / (divider + 2);
return DIV_ROUND_UP(parent_rate * 2, divider + 2);
} else if (c->flags & DIV_2) {
return parent_rate / 2;
return DIV_ROUND_UP(parent_rate, 2);
}
return -EINVAL;
}
@@ -1006,12 +1006,12 @@ static long tegra2_periph_clk_round_rate(struct clk *c,
if (divider < 0)
return divider;
return parent_rate * 2 / (divider + 2);
return DIV_ROUND_UP(parent_rate * 2, divider + 2);
} else if (c->flags & DIV_U16) {
divider = clk_div16_get_divider(parent_rate, rate);
if (divider < 0)
return divider;
return parent_rate / (divider + 1);
return DIV_ROUND_UP(parent_rate, divider + 1);
}
return -EINVAL;
}