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

Commit 85151a6b authored by Lori Hikichi's avatar Lori Hikichi Committed by Stephen Boyd
Browse files

clk: iproc: Fix error in the pll post divider rate calculation



The pll post divider code was using DIV_ROUND_UP when determining the
divider value best suited to produce the target frequency.
Using DIV_ROUND_CLOSEST will give us better divider values when
the division results in a small remainder.
Also, change the post divider clock over to the determine_rate api
instead of round_rate.

Signed-off-by: default avatarSimran Rai <ssimran@broadcom.com>
Signed-off-by: default avatarLori Hikichi <lori.hikichi@broadcom.com>
Signed-off-by: default avatarStephen Boyd <sboyd@codeaurora.org>
parent becf1237
Loading
Loading
Loading
Loading
+17 −16
Original line number Diff line number Diff line
@@ -602,25 +602,26 @@ static unsigned long iproc_clk_recalc_rate(struct clk_hw *hw,
	return clk->rate;
}

static long iproc_clk_round_rate(struct clk_hw *hw, unsigned long rate,
		unsigned long *parent_rate)
static int iproc_clk_determine_rate(struct clk_hw *hw,
		struct clk_rate_request *req)
{
	unsigned int div;
	unsigned int bestdiv;

	if (rate == 0 || *parent_rate == 0)
	if (req->rate == 0)
		return -EINVAL;
	if (req->rate == req->best_parent_rate)
		return 0;

	if (rate == *parent_rate)
		return *parent_rate;
	bestdiv = DIV_ROUND_CLOSEST(req->best_parent_rate, req->rate);
	if (bestdiv < 2)
		req->rate = req->best_parent_rate;

	div = DIV_ROUND_UP(*parent_rate, rate);
	if (div < 2)
		return *parent_rate;
	if (bestdiv > 256)
		bestdiv = 256;

	if (div > 256)
		div = 256;
	req->rate = req->best_parent_rate / bestdiv;

	return *parent_rate / div;
	return 0;
}

static int iproc_clk_set_rate(struct clk_hw *hw, unsigned long rate,
@@ -635,10 +636,10 @@ static int iproc_clk_set_rate(struct clk_hw *hw, unsigned long rate,
	if (rate == 0 || parent_rate == 0)
		return -EINVAL;

	div = DIV_ROUND_CLOSEST(parent_rate, rate);
	if (ctrl->flags & IPROC_CLK_MCLK_DIV_BY_2)
		div = DIV_ROUND_UP(parent_rate, rate * 2);
	else
		div = DIV_ROUND_UP(parent_rate, rate);
		div /=  2;

	if (div > 256)
		return -EINVAL;

@@ -662,7 +663,7 @@ static const struct clk_ops iproc_clk_ops = {
	.enable = iproc_clk_enable,
	.disable = iproc_clk_disable,
	.recalc_rate = iproc_clk_recalc_rate,
	.round_rate = iproc_clk_round_rate,
	.determine_rate = iproc_clk_determine_rate,
	.set_rate = iproc_clk_set_rate,
};