Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 20 Dec 2016 01:37:00 +0000 (UTC)
From:      Jared McNeill <jmcneill@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r310307 - head/sys/mips/ingenic
Message-ID:  <201612200137.uBK1b0BX090096@repo.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: jmcneill
Date: Tue Dec 20 01:37:00 2016
New Revision: 310307
URL: https://svnweb.freebsd.org/changeset/base/310307

Log:
  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

Modified:
  head/sys/mips/ingenic/jz4780_clk_gen.c

Modified: head/sys/mips/ingenic/jz4780_clk_gen.c
==============================================================================
--- head/sys/mips/ingenic/jz4780_clk_gen.c	Tue Dec 20 01:34:29 2016	(r310306)
+++ head/sys/mips/ingenic/jz4780_clk_gen.c	Tue Dec 20 01:37:00 2016	(r310307)
@@ -153,23 +153,29 @@ jz4780_clk_gen_set_freq(struct clknode *
 {
 	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;



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201612200137.uBK1b0BX090096>