diff options
author | Jared McNeill <jmcneill@FreeBSD.org> | 2016-12-20 01:37:00 +0000 |
---|---|---|
committer | Jared McNeill <jmcneill@FreeBSD.org> | 2016-12-20 01:37:00 +0000 |
commit | 8ee54cadae9a6b8f026d9b110f66573bb6460928 (patch) | |
tree | 426f3e9e212e89fa33f431d5cdc7d8ef3ea55d41 /sys/mips/ingenic | |
parent | 06785ff66a43ab781458116d6ef419b6af47223e (diff) | |
download | src-8ee54cadae9a6b8f026d9b110f66573bb6460928.tar.gz src-8ee54cadae9a6b8f026d9b110f66573bb6460928.zip |
Choose the closes matching divider instead of one that results in a
frequency >= target. Fix inverted rounding logic for CLK_SET_ROUND_UP/DOWN.
Reviewed by: kan
Differential Revision: https://reviews.freebsd.org/D8784
Notes
Notes:
svn path=/head/; revision=310307
Diffstat (limited to 'sys/mips/ingenic')
-rw-r--r-- | sys/mips/ingenic/jz4780_clk_gen.c | 14 |
1 files changed, 10 insertions, 4 deletions
diff --git a/sys/mips/ingenic/jz4780_clk_gen.c b/sys/mips/ingenic/jz4780_clk_gen.c index 7c65fb824d93..94ecd61b993a 100644 --- a/sys/mips/ingenic/jz4780_clk_gen.c +++ b/sys/mips/ingenic/jz4780_clk_gen.c @@ -153,23 +153,29 @@ jz4780_clk_gen_set_freq(struct clknode *clk, uint64_t fin, { struct jz4780_clk_gen_sc *sc; uint64_t _fout; - uint32_t divider, div_reg, div_msk, reg; + uint32_t divider, div_reg, div_msk, reg, div_l, div_h; int rv; sc = clknode_get_softc(clk); - divider = fin / *fout; + /* Find closest divider */ + div_l = howmany(fin, *fout); + div_h = fin / *fout; + divider = abs((int64_t)*fout - (fin / div_l)) < + abs((int64_t)*fout - (fin / div_h)) ? div_l : div_h; /* Adjust for divider multiplier */ div_reg = divider >> sc->clk_descr->clk_div.div_lg; divider = div_reg << sc->clk_descr->clk_div.div_lg; + if (divider == 0) + divider = 1; _fout = fin / divider; /* Rounding */ - if ((flags & CLK_SET_ROUND_UP) && (*fout < _fout)) + if ((flags & CLK_SET_ROUND_UP) && (*fout > _fout)) div_reg--; - else if ((flags & CLK_SET_ROUND_DOWN) && (*fout > _fout)) + else if ((flags & CLK_SET_ROUND_DOWN) && (*fout < _fout)) div_reg++; if (div_reg == 0) div_reg = 1; |