Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 448c3c05 authored by Lars-Peter Clausen's avatar Lars-Peter Clausen Committed by Stephen Boyd
Browse files

clk: axi-clkgen: Round closest in round_rate() and recalc_rate()



To minimize the rounding error round to the closest integer when
calculating the result in the recalc_rate() and set_rate() callbacks.

Also in order to improve precision multiply first and then divide.

Signed-off-by: default avatarLars-Peter Clausen <lars@metafoo.de>
Signed-off-by: default avatarStephen Boyd <sboyd@codeaurora.org>
parent 063578dc
Loading
Loading
Loading
Loading
+7 −3
Original line number Diff line number Diff line
@@ -302,13 +302,17 @@ static long axi_clkgen_round_rate(struct clk_hw *hw, unsigned long rate,
	unsigned long *parent_rate)
{
	unsigned int d, m, dout;
	unsigned long long tmp;

	axi_clkgen_calc_params(*parent_rate, rate, &d, &m, &dout);

	if (d == 0 || dout == 0 || m == 0)
		return -EINVAL;

	return *parent_rate / d * m / dout;
	tmp = (unsigned long long)*parent_rate * m;
	tmp = DIV_ROUND_CLOSEST_ULL(tmp, dout * d);

	return min_t(unsigned long long, tmp, LONG_MAX);
}

static unsigned long axi_clkgen_recalc_rate(struct clk_hw *clk_hw,
@@ -344,8 +348,8 @@ static unsigned long axi_clkgen_recalc_rate(struct clk_hw *clk_hw,
	if (d == 0 || dout == 0)
		return 0;

	tmp = (unsigned long long)(parent_rate / d) * m;
	do_div(tmp, dout);
	tmp = (unsigned long long)parent_rate * m;
	tmp = DIV_ROUND_CLOSEST_ULL(tmp, dout * d);

	return min_t(unsigned long long, tmp, ULONG_MAX);
}