1
0
mirror of https://git.FreeBSD.org/src.git synced 2024-12-03 09:00:21 +00:00

arm64: rockchip: clk: Add support to reparent to clk_composite

All clk_composite type have the possibility to reparent (choosing another
parent to find a better frequency), add the support for that.
This commit is contained in:
Emmanuel Vadot 2018-05-07 07:29:48 +00:00
parent 66a4c42756
commit dff9720331
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=333317

View File

@ -155,22 +155,50 @@ rk_clk_composite_recalc(struct clknode *clk, uint64_t *freq)
return (0);
}
static uint32_t
rk_clk_composite_find_best(struct rk_clk_composite_sc *sc, uint64_t fparent,
uint64_t freq)
{
uint64_t best, cur;
uint32_t best_div, div;
for (best = 0, best_div = 0, div = 0;
div <= ((sc->div_mask >> sc->div_shift) + 1); div++) {
cur = fparent / div;
if ((freq - cur) < (freq - best)) {
best = cur;
best_div = div;
break;
}
}
return (best_div);
}
static int
rk_clk_composite_set_freq(struct clknode *clk, uint64_t fparent, uint64_t *fout,
int flags, int *stop)
{
struct rk_clk_composite_sc *sc;
struct clknode *p_clk;
const char **p_names;
uint64_t best, cur;
uint32_t div, best_div, val;
int p_idx, best_parent;
sc = clknode_get_softc(clk);
for (best = 0, best_div = 0, div = 0; div <= sc->div_mask; div++) {
p_names = clknode_get_parent_names(clk);
for (best_div = 0, best = 0, p_idx = 0;
p_idx != clknode_get_parents_num(clk); p_idx++) {
p_clk = clknode_find_by_name(p_names[p_idx]);
clknode_get_freq(p_clk, &fparent);
div = rk_clk_composite_find_best(sc, fparent, *fout);
cur = fparent / div;
if ((*fout - cur) < (*fout - best)) {
best = cur;
best_div = div;
break;
best_parent = p_idx;
}
}
@ -194,6 +222,9 @@ rk_clk_composite_set_freq(struct clknode *clk, uint64_t fparent, uint64_t *fout,
return (0);
}
if (p_idx != best_parent)
clknode_set_parent_by_idx(clk, best_parent);
DEVICE_LOCK(clk);
READ4(clk, sc->muxdiv_offset, &val);
val &= ~sc->div_mask;