static int flexgen_set_rate(struct clk_hw *hw, unsigned long rate, unsigned long parent_rate) { struct flexgen *flexgen = to_flexgen(hw); struct clk_hw *pdiv_hw = &flexgen->pdiv.hw; struct clk_hw *fdiv_hw = &flexgen->fdiv.hw; unsigned long div = 0; int ret = 0; __clk_hw_set_clk(pdiv_hw, hw); __clk_hw_set_clk(fdiv_hw, hw); div = clk_best_div(parent_rate, rate); /* * pdiv is mainly targeted for low freq results, while fdiv * should be used for div <= 64. The other way round can * lead to 'duty cycle' issues. */ if (div <= 64) { clk_divider_ops.set_rate(pdiv_hw, parent_rate, parent_rate); ret = clk_divider_ops.set_rate(fdiv_hw, rate, rate * div); } else { clk_divider_ops.set_rate(fdiv_hw, parent_rate, parent_rate); ret = clk_divider_ops.set_rate(pdiv_hw, rate, rate * div); } return ret; }
static long flexgen_round_rate(struct clk_hw *hw, unsigned long rate, unsigned long *prate) { unsigned long div; /* Round div according to exact prate and wished rate */ div = clk_best_div(*prate, rate); if (__clk_get_flags(hw->clk) & CLK_SET_RATE_PARENT) { *prate = rate * div; return rate; } return *prate / div; }
static int flexgen_set_rate(struct clk_hw *hw, unsigned long rate, unsigned long parent_rate) { struct flexgen *flexgen = to_flexgen(hw); struct clk_hw *pdiv_hw = &flexgen->pdiv.hw; struct clk_hw *fdiv_hw = &flexgen->fdiv.hw; unsigned long primary_div = 0; int ret = 0; pdiv_hw->clk = hw->clk; fdiv_hw->clk = hw->clk; primary_div = clk_best_div(parent_rate, rate); clk_divider_ops.set_rate(fdiv_hw, parent_rate, parent_rate); ret = clk_divider_ops.set_rate(pdiv_hw, rate, rate * primary_div); return ret; }