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: Simran Rai <ssimran@broadcom.com> Signed-off-by: Lori Hikichi <lori.hikichi@broadcom.com> Signed-off-by: Stephen Boyd <sboyd@codeaurora.org>
This commit is contained in:
Родитель
becf123772
Коммит
85151a6b0b
|
@ -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,
|
||||
};
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче