return divider_u16 - 1;
}
+static long fixed_src_bus_round_updown(struct clk *c, struct clk *src,
+ u32 flags, unsigned long rate, bool up)
+{
+ int divider;
+ unsigned long source_rate, round_rate;
+
+ source_rate = clk_get_rate(src);
+
+ divider = clk_div71_get_divider(source_rate, rate + (up ? -1 : 1),
+ flags, up ? ROUND_DIVIDER_DOWN : ROUND_DIVIDER_UP);
+ if (divider < 0)
+ return c->min_rate;
+
+ round_rate = source_rate * 2 / (divider + 2);
+
+ if (round_rate > c->max_rate) {
+ divider += flags & DIV_U71_INT ? 2 : 1;
+#if !DIVIDER_1_5_ALLOWED
+ divider = max(2, divider);
+#endif
+ round_rate = source_rate * 2 / (divider + 2);
+ }
+ return round_rate;
+}
+
static inline bool bus_user_is_slower(struct clk *a, struct clk *b)
{
return a->u.shared_bus_user.client->max_rate * a->div <
static long tegra12_sbus_cmplx_round_updown(struct clk *c, unsigned long rate,
bool up)
{
- int divider;
- unsigned long source_rate, round_rate;
+ unsigned long round_rate;
struct clk *new_parent;
rate = max(rate, c->min_rate);
new_parent = (rate <= c->u.system.threshold) ?
c->u.system.sclk_low : c->u.system.sclk_high;
- source_rate = clk_get_rate(new_parent->parent);
-
- divider = clk_div71_get_divider(source_rate, rate,
- new_parent->flags, up ? ROUND_DIVIDER_DOWN : ROUND_DIVIDER_UP);
- if (divider < 0)
- return c->min_rate;
- if (divider == 1)
- divider = 0;
-
- round_rate = source_rate * 2 / (divider + 2);
- if (round_rate > c->max_rate) {
- divider += new_parent->flags & DIV_U71_INT ? 2 : 1;
-#if !DIVIDER_1_5_ALLOWED
- divider = max(2, divider);
-#endif
- round_rate = source_rate * 2 / (divider + 2);
- }
+ round_rate = fixed_src_bus_round_updown(
+ c, new_parent->parent, new_parent->flags, rate, up);
if (new_parent == c->u.system.sclk_high) {
/* Prevent oscillation across threshold */
static long _1x_round_updown(struct clk *c, struct clk *src,
unsigned long rate, bool up)
{
- int divider;
- unsigned long source_rate, round_rate;
-
- source_rate = clk_get_rate(src);
-
- divider = clk_div71_get_divider(source_rate, rate + (up ? -1 : 1),
- c->flags, up ? ROUND_DIVIDER_DOWN : ROUND_DIVIDER_UP);
-
- if (divider < 0)
- return c->min_rate;
-
- round_rate = source_rate * 2 / (divider + 2);
-
- if (round_rate > c->max_rate) {
- divider += c->flags & DIV_U71_INT ? 2 : 1;
-#if !DIVIDER_1_5_ALLOWED
- divider = max(2, divider);
-#endif
- round_rate = source_rate * 2 / (divider + 2);
- }
- return round_rate;
+ return fixed_src_bus_round_updown(c, src, c->flags, rate, up);
}
static long tegra12_1xbus_round_updown(struct clk *c, unsigned long rate,