aboutsummaryrefslogtreecommitdiff
path: root/sys/mips/ingenic
diff options
context:
space:
mode:
authorJared McNeill <jmcneill@FreeBSD.org>2016-12-20 01:37:00 +0000
committerJared McNeill <jmcneill@FreeBSD.org>2016-12-20 01:37:00 +0000
commit8ee54cadae9a6b8f026d9b110f66573bb6460928 (patch)
tree426f3e9e212e89fa33f431d5cdc7d8ef3ea55d41 /sys/mips/ingenic
parent06785ff66a43ab781458116d6ef419b6af47223e (diff)
downloadsrc-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.c14
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;