diff options
author | Mark Kettenis <kettenis@cvs.openbsd.org> | 2019-01-01 12:19:58 +0000 |
---|---|---|
committer | Mark Kettenis <kettenis@cvs.openbsd.org> | 2019-01-01 12:19:58 +0000 |
commit | 23504910208bb30adbe6e1eec5018bf153bc9f13 (patch) | |
tree | 78abb3ffe9c0f17770519f97c04cc037c4f58dad | |
parent | 992756d3e8579d2dd098686e61d1bad1e3310855 (diff) |
Make sure we don't exceed the maximum clock divider.
-rw-r--r-- | sys/dev/fdt/rkclock.c | 16 |
1 files changed, 11 insertions, 5 deletions
diff --git a/sys/dev/fdt/rkclock.c b/sys/dev/fdt/rkclock.c index a510b296129..5ea53a86c27 100644 --- a/sys/dev/fdt/rkclock.c +++ b/sys/dev/fdt/rkclock.c @@ -1,4 +1,4 @@ -/* $OpenBSD: rkclock.c,v 1.36 2019/01/01 11:15:15 kettenis Exp $ */ +/* $OpenBSD: rkclock.c,v 1.37 2019/01/01 12:19:57 kettenis Exp $ */ /* * Copyright (c) 2017, 2018 Mark Kettenis <kettenis@openbsd.org> * @@ -315,13 +315,19 @@ rkclock_lookup(struct rkclock_softc *sc, uint32_t idx) } uint32_t -rkclock_div_con(struct rkclock_softc *sc, int idx, uint32_t freq) +rkclock_div_con(struct rkclock_softc *sc, struct rkclock *clk, + uint32_t mux, uint32_t freq) { - uint32_t parent_freq, div; + uint32_t parent_freq, div, div_con, max_div_con; + uint32_t idx = clk->parents[mux]; + /* Derive maximum value from mask. */ + max_div_con = clk->div_mask >> (ffs(clk->div_mask) - 1); + parent_freq = sc->sc_cd.cd_get_frequency(sc, &idx); div = (parent_freq + freq - 1) / freq; - return (div > 0 ? div - 1 : 0); + div_con = (div > 0 ? div - 1 : 0); + return (div_con < max_div_con) ? div_con : max_div_con; } uint32_t @@ -382,7 +388,7 @@ rkclock_set_frequency(struct rkclock_softc *sc, uint32_t idx, uint32_t freq) return 0; } - div_con = rkclock_div_con(sc, clk->parents[mux], freq); + div_con = rkclock_div_con(sc, clk, mux, freq); shift = ffs(clk->div_mask) - 1; HWRITE4(sc, clk->reg, clk->div_mask << 16 | div_con << shift); return 0; |