Changeset View
Changeset View
Standalone View
Standalone View
head/sys/mips/ingenic/jz4780_clk_gen.c
Show First 20 Lines • Show All 147 Lines • ▼ Show 20 Lines | |||||
#define DIV_TIMEOUT 100 | #define DIV_TIMEOUT 100 | ||||
static int | static int | ||||
jz4780_clk_gen_set_freq(struct clknode *clk, uint64_t fin, | jz4780_clk_gen_set_freq(struct clknode *clk, uint64_t fin, | ||||
uint64_t *fout, int flags, int *stop) | uint64_t *fout, int flags, int *stop) | ||||
{ | { | ||||
struct jz4780_clk_gen_sc *sc; | struct jz4780_clk_gen_sc *sc; | ||||
uint64_t _fout; | 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; | int rv; | ||||
sc = clknode_get_softc(clk); | 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 */ | /* Adjust for divider multiplier */ | ||||
div_reg = divider >> sc->clk_descr->clk_div.div_lg; | div_reg = divider >> sc->clk_descr->clk_div.div_lg; | ||||
divider = div_reg << 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; | _fout = fin / divider; | ||||
/* Rounding */ | /* Rounding */ | ||||
if ((flags & CLK_SET_ROUND_UP) && (*fout < _fout)) | if ((flags & CLK_SET_ROUND_UP) && (*fout > _fout)) | ||||
div_reg--; | div_reg--; | ||||
else if ((flags & CLK_SET_ROUND_DOWN) && (*fout > _fout)) | else if ((flags & CLK_SET_ROUND_DOWN) && (*fout < _fout)) | ||||
div_reg++; | div_reg++; | ||||
if (div_reg == 0) | if (div_reg == 0) | ||||
div_reg = 1; | div_reg = 1; | ||||
div_msk = (1u << sc->clk_descr->clk_div.div_bits) - 1; | div_msk = (1u << sc->clk_descr->clk_div.div_bits) - 1; | ||||
*stop = 1; | *stop = 1; | ||||
if (div_reg > div_msk + 1) { | if (div_reg > div_msk + 1) { | ||||
▲ Show 20 Lines • Show All 137 Lines • Show Last 20 Lines |