Date: Tue, 6 Aug 2019 12:19:09 +0000 (UTC) From: Emmanuel Vadot <manu@FreeBSD.org> To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-12@freebsd.org Subject: svn commit: r350629 - in stable/12/sys: arm/allwinner arm/allwinner/clkng conf Message-ID: <201908061219.x76CJ9Mu062460@repo.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: manu Date: Tue Aug 6 12:19:09 2019 New Revision: 350629 URL: https://svnweb.freebsd.org/changeset/base/350629 Log: MFC r348179-r348182 r348179: allwinner: aw_ccu: Add some debug printfs (disabled by default) Also print information about setting frequency at boot under bootverbose r348180: arm: allwinner: clk: Add new clock aw_clk_frac Add a clock driver for clock that can either be used in integer mode with one N factor and one M divider or in fractional mode where the output frequency is chosen between two predifined output. r348181: arm: allwinner: clk: Use the new frac clock Some clocks used the NM type but this clock is for the ones with the formula "clk = clkin / n / m" and not "clk = clkin * n / m" Use the new frac clock for them. r348182: arm: allwinner: Remove frac mode from NM clk We have a correct clock type aw_clk_frac now for this. Added: stable/12/sys/arm/allwinner/clkng/aw_clk_frac.c - copied unchanged from r348182, head/sys/arm/allwinner/clkng/aw_clk_frac.c stable/12/sys/arm/allwinner/clkng/aw_clk_frac.h - copied unchanged from r348182, head/sys/arm/allwinner/clkng/aw_clk_frac.h Modified: stable/12/sys/arm/allwinner/clkng/aw_ccung.c stable/12/sys/arm/allwinner/clkng/aw_ccung.h stable/12/sys/arm/allwinner/clkng/aw_clk.h stable/12/sys/arm/allwinner/clkng/aw_clk_nm.c stable/12/sys/arm/allwinner/clkng/aw_clk_nm.h stable/12/sys/arm/allwinner/clkng/ccu_a10.c stable/12/sys/arm/allwinner/clkng/ccu_a31.c stable/12/sys/arm/allwinner/clkng/ccu_a64.c stable/12/sys/arm/allwinner/clkng/ccu_h3.c stable/12/sys/arm/allwinner/files.allwinner stable/12/sys/conf/files.arm64 Directory Properties: stable/12/ (props changed) Modified: stable/12/sys/arm/allwinner/clkng/aw_ccung.c ============================================================================== --- stable/12/sys/arm/allwinner/clkng/aw_ccung.c Tue Aug 6 12:12:29 2019 (r350628) +++ stable/12/sys/arm/allwinner/clkng/aw_ccung.c Tue Aug 6 12:19:09 2019 (r350629) @@ -62,6 +62,12 @@ __FBSDID("$FreeBSD$"); #include "clkdev_if.h" #include "hwreset_if.h" +#if 0 +#define dprintf(format, arg...) device_printf(dev, "%s: " format, __func__, arg) +#else +#define dprintf(format, arg...) +#endif + static struct resource_spec aw_ccung_spec[] = { { SYS_RES_MEMORY, 0, RF_ACTIVE }, { -1, 0 } @@ -76,6 +82,7 @@ aw_ccung_write_4(device_t dev, bus_addr_t addr, uint32 struct aw_ccung_softc *sc; sc = device_get_softc(dev); + dprintf("offset=%lx write %x\n", addr, val); CCU_WRITE4(sc, addr, val); return (0); } @@ -88,6 +95,7 @@ aw_ccung_read_4(device_t dev, bus_addr_t addr, uint32_ sc = device_get_softc(dev); *val = CCU_READ4(sc, addr); + dprintf("offset=%lx Read %x\n", addr, *val); return (0); } @@ -99,6 +107,7 @@ aw_ccung_modify_4(device_t dev, bus_addr_t addr, uint3 sc = device_get_softc(dev); + dprintf("offset=%lx clr: %x set: %x\n", addr, clr, set); reg = CCU_READ4(sc, addr); reg &= ~clr; reg |= set; @@ -115,6 +124,7 @@ aw_ccung_reset_assert(device_t dev, intptr_t id, bool sc = device_get_softc(dev); + dprintf("%sassert reset id %ld\n", reset ? "" : "De", id); if (id >= sc->nresets || sc->resets[id].offset == 0) return (0); @@ -222,6 +232,11 @@ aw_ccung_init_clocks(struct aw_ccung_softc *sc) } } if (sc->clk_init[i].default_freq != 0) { + if (bootverbose) + device_printf(sc->dev, + "Setting freq %ju for %s\n", + sc->clk_init[i].default_freq, + sc->clk_init[i].name); error = clknode_set_freq(clknode, sc->clk_init[i].default_freq, 0 , 0); if (error != 0) { @@ -287,6 +302,9 @@ aw_ccung_attach(device_t dev) case AW_CLK_PREDIV_MUX: aw_clk_prediv_mux_register(sc->clkdom, sc->clks[i].clk.prediv_mux); + break; + case AW_CLK_FRAC: + aw_clk_frac_register(sc->clkdom, sc->clks[i].clk.frac); break; } } Modified: stable/12/sys/arm/allwinner/clkng/aw_ccung.h ============================================================================== --- stable/12/sys/arm/allwinner/clkng/aw_ccung.h Tue Aug 6 12:12:29 2019 (r350628) +++ stable/12/sys/arm/allwinner/clkng/aw_ccung.h Tue Aug 6 12:19:09 2019 (r350629) @@ -34,6 +34,7 @@ #include <arm/allwinner/clkng/aw_clk_nkmp.h> #include <arm/allwinner/clkng/aw_clk_nm.h> #include <arm/allwinner/clkng/aw_clk_prediv_mux.h> +#include <arm/allwinner/clkng/aw_clk_frac.h> #include <dev/extres/clk/clk_mux.h> #include <dev/extres/clk/clk_div.h> #include <dev/extres/clk/clk_fixed.h> @@ -46,6 +47,7 @@ enum aw_ccung_clk_type { AW_CLK_NKMP, AW_CLK_NM, AW_CLK_PREDIV_MUX, + AW_CLK_FRAC, }; struct aw_ccung_clk { @@ -57,6 +59,7 @@ struct aw_ccung_clk { struct aw_clk_nkmp_def *nkmp; struct aw_clk_nm_def *nm; struct aw_clk_prediv_mux_def *prediv_mux; + struct aw_clk_frac_def *frac; } clk; }; Modified: stable/12/sys/arm/allwinner/clkng/aw_clk.h ============================================================================== --- stable/12/sys/arm/allwinner/clkng/aw_clk.h Tue Aug 6 12:12:29 2019 (r350628) +++ stable/12/sys/arm/allwinner/clkng/aw_clk.h Tue Aug 6 12:19:09 2019 (r350629) @@ -64,7 +64,6 @@ struct aw_clk_init { #define AW_CLK_HAS_MUX 0x0004 #define AW_CLK_REPARENT 0x0008 #define AW_CLK_SCALE_CHANGE 0x0010 -#define AW_CLK_HAS_FRAC 0x0020 #define AW_CLK_HAS_UPDATE 0x0040 #define AW_CLK_HAS_PREDIV 0x0080 @@ -309,14 +308,13 @@ aw_clk_factor_get_value(struct aw_clk_factor *factor, .flags = _flags | AW_CLK_HAS_UPDATE, \ } -#define NM_CLK(_clkname, _id, _name, _pnames, \ +#define FRAC_CLK(_clkname, _id, _name, _pnames, \ _offset, \ _nshift, _nwidth, _nvalue, _nflags, \ _mshift, _mwidth, _mvalue, _mflags, \ - _mux_shift, _mux_width, \ - _gate_shift, \ - _flags) \ - static struct aw_clk_nm_def _clkname = { \ + _gate_shift, _lock_shift,_lock_retries, \ + _flags, _freq0, _freq1, _mode_sel, _freq_sel) \ + static struct aw_clk_frac_def _clkname = { \ .clkdef = { \ .id = _id, \ .name = _name, \ @@ -328,23 +326,28 @@ aw_clk_factor_get_value(struct aw_clk_factor *factor, .n.width = _nwidth, \ .n.value = _nvalue, \ .n.flags = _nflags, \ - .mux_shift = _mux_shift, \ .m.shift = _mshift, \ .m.width = _mwidth, \ .m.value = _mvalue, \ .m.flags = _mflags, \ - .mux_width = _mux_width, \ .gate_shift = _gate_shift, \ + .lock_shift = _lock_shift, \ + .lock_retries = _lock_retries, \ .flags = _flags, \ + .frac.freq0 = _freq0, \ + .frac.freq1 = _freq1, \ + .frac.mode_sel = _mode_sel, \ + .frac.freq_sel = _freq_sel, \ } -#define NM_CLK_WITH_FRAC(_clkname, _id, _name, _pnames, \ +#define NM_CLK(_clkname, _id, _name, _pnames, \ _offset, \ _nshift, _nwidth, _nvalue, _nflags, \ _mshift, _mwidth, _mvalue, _mflags, \ - _gate_shift, _lock_shift,_lock_retries, \ - _flags, _freq0, _freq1, _mode_sel, _freq_sel) \ - static struct aw_clk_nm_def _clkname = { \ + _mux_shift, _mux_width, \ + _gate_shift, \ + _flags) \ + static struct aw_clk_nm_def _clkname = { \ .clkdef = { \ .id = _id, \ .name = _name, \ @@ -356,18 +359,14 @@ aw_clk_factor_get_value(struct aw_clk_factor *factor, .n.width = _nwidth, \ .n.value = _nvalue, \ .n.flags = _nflags, \ + .mux_shift = _mux_shift, \ .m.shift = _mshift, \ .m.width = _mwidth, \ .m.value = _mvalue, \ .m.flags = _mflags, \ + .mux_width = _mux_width, \ .gate_shift = _gate_shift, \ - .lock_shift = _lock_shift, \ - .lock_retries = _lock_retries, \ - .flags = _flags | AW_CLK_HAS_FRAC, \ - .frac.freq0 = _freq0, \ - .frac.freq1 = _freq1, \ - .frac.mode_sel = _mode_sel, \ - .frac.freq_sel = _freq_sel, \ + .flags = _flags, \ } #define PREDIV_CLK(_clkname, _id, _name, _pnames, \ Copied: stable/12/sys/arm/allwinner/clkng/aw_clk_frac.c (from r348182, head/sys/arm/allwinner/clkng/aw_clk_frac.c) ============================================================================== --- /dev/null 00:00:00 1970 (empty, because file is newly added) +++ stable/12/sys/arm/allwinner/clkng/aw_clk_frac.c Tue Aug 6 12:19:09 2019 (r350629, copy of r348182, head/sys/arm/allwinner/clkng/aw_clk_frac.c) @@ -0,0 +1,338 @@ +/*- + * Copyright (c) 2019 Emmanuel Vadot <manu@freebsd.org> + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $FreeBSD$ + */ + +#include <sys/cdefs.h> +__FBSDID("$FreeBSD$"); + +#include <sys/param.h> +#include <sys/systm.h> +#include <sys/bus.h> + +#include <dev/extres/clk/clk.h> + +#include <arm/allwinner/clkng/aw_clk.h> +#include <arm/allwinner/clkng/aw_clk_frac.h> + +#include "clkdev_if.h" + +/* + * clknode for clocks matching the formula : + * + * clk = (24Mhz * n) / m in integer mode + * clk = frac_out1 or frac_out2 in fractional mode + * + */ + +struct aw_clk_frac_sc { + uint32_t offset; + + struct aw_clk_factor m; + struct aw_clk_factor n; + struct aw_clk_frac frac; + + uint32_t mux_shift; + uint32_t mux_mask; + uint32_t gate_shift; + uint32_t lock_shift; + uint32_t lock_retries; + + uint32_t flags; +}; + +#define WRITE4(_clk, off, val) \ + CLKDEV_WRITE_4(clknode_get_device(_clk), off, val) +#define READ4(_clk, off, val) \ + CLKDEV_READ_4(clknode_get_device(_clk), off, val) +#define DEVICE_LOCK(_clk) \ + CLKDEV_DEVICE_LOCK(clknode_get_device(_clk)) +#define DEVICE_UNLOCK(_clk) \ + CLKDEV_DEVICE_UNLOCK(clknode_get_device(_clk)) + +static int +aw_clk_frac_init(struct clknode *clk, device_t dev) +{ + struct aw_clk_frac_sc *sc; + uint32_t val, idx; + + sc = clknode_get_softc(clk); + + idx = 0; + if ((sc->flags & AW_CLK_HAS_MUX) != 0) { + DEVICE_LOCK(clk); + READ4(clk, sc->offset, &val); + DEVICE_UNLOCK(clk); + + idx = (val & sc->mux_mask) >> sc->mux_shift; + } + + clknode_init_parent_idx(clk, idx); + return (0); +} + +static int +aw_clk_frac_set_gate(struct clknode *clk, bool enable) +{ + struct aw_clk_frac_sc *sc; + uint32_t val; + + sc = clknode_get_softc(clk); + + if ((sc->flags & AW_CLK_HAS_GATE) == 0) + return (0); + + DEVICE_LOCK(clk); + READ4(clk, sc->offset, &val); + if (enable) + val |= (1 << sc->gate_shift); + else + val &= ~(1 << sc->gate_shift); + WRITE4(clk, sc->offset, val); + DEVICE_UNLOCK(clk); + + return (0); +} + +static int +aw_clk_frac_set_mux(struct clknode *clk, int index) +{ + struct aw_clk_frac_sc *sc; + uint32_t val; + + sc = clknode_get_softc(clk); + + if ((sc->flags & AW_CLK_HAS_MUX) == 0) + return (0); + + DEVICE_LOCK(clk); + READ4(clk, sc->offset, &val); + val &= ~sc->mux_mask; + val |= index << sc->mux_shift; + WRITE4(clk, sc->offset, val); + DEVICE_UNLOCK(clk); + + return (0); +} + +static uint64_t +aw_clk_frac_find_best(struct aw_clk_frac_sc *sc, uint64_t fparent, uint64_t *fout, + uint32_t *factor_n, uint32_t *factor_m) +{ + uint64_t cur, best; + uint32_t m, n, max_m, max_n, min_m, min_n; + + *factor_n = *factor_m = 0; + best = cur = 0; + + max_m = aw_clk_factor_get_max(&sc->m); + max_n = aw_clk_factor_get_max(&sc->n); + min_m = aw_clk_factor_get_min(&sc->m); + min_n = aw_clk_factor_get_min(&sc->n); + + for (n = min_n; n <= max_n; n++) { + for (m = min_m; m <= max_m; m++) { + cur = fparent * n / m; + if ((*fout - cur) < (*fout - best)) { + best = cur; + *factor_n = n; + *factor_m = m; + } + if (best == *fout) + return (best); + } + } + + return (best); +} + +static int +aw_clk_frac_set_freq(struct clknode *clk, uint64_t fparent, uint64_t *fout, + int flags, int *stop) +{ + struct aw_clk_frac_sc *sc; + uint64_t cur, best, best_frac; + uint32_t val, m, n, best_m, best_n; + int retry; + + sc = clknode_get_softc(clk); + + best = best_frac = cur = 0; + + if (*fout == sc->frac.freq0) + best = best_frac = sc->frac.freq0; + else if (*fout == sc->frac.freq1) + best = best_frac = sc->frac.freq1; + else + best = aw_clk_frac_find_best(sc, fparent, fout, + &best_n, &best_m); + + if ((flags & CLK_SET_DRYRUN) != 0) { + *fout = best; + *stop = 1; + return (0); + } + + if ((best < *fout) && + ((flags & CLK_SET_ROUND_DOWN) == 0)) { + *stop = 1; + return (ERANGE); + } + if ((best > *fout) && + ((flags & CLK_SET_ROUND_UP) == 0)) { + *stop = 1; + return (ERANGE); + } + + DEVICE_LOCK(clk); + READ4(clk, sc->offset, &val); + /* Disable clock during freq changes */ + val &= ~(1 << sc->gate_shift); + WRITE4(clk, sc->offset, val); + + if (best_frac != 0) { + val &= ~sc->frac.mode_sel; + /* M should be 0 per the manual */ + val &= ~sc->m.mask; + if (best_frac == sc->frac.freq0) + val &= ~sc->frac.freq_sel; + else + val |= sc->frac.freq_sel; + } else { + val |= sc->frac.mode_sel; /* Select integer mode */ + n = aw_clk_factor_get_value(&sc->n, best_n); + m = aw_clk_factor_get_value(&sc->m, best_m); + val &= ~sc->n.mask; + val &= ~sc->m.mask; + val |= n << sc->n.shift; + val |= m << sc->m.shift; + } + + /* Write the clock changes */ + WRITE4(clk, sc->offset, val); + + /* Enable clock now that we've change it */ + val |= 1 << sc->gate_shift; + WRITE4(clk, sc->offset, val); + DEVICE_UNLOCK(clk); + + for (retry = 0; retry < sc->lock_retries; retry++) { + READ4(clk, sc->offset, &val); + if ((val & (1 << sc->lock_shift)) != 0) + break; + DELAY(1000); + } + + *fout = best; + *stop = 1; + + return (0); +} + +static int +aw_clk_frac_recalc(struct clknode *clk, uint64_t *freq) +{ + struct aw_clk_frac_sc *sc; + uint32_t val, m, n; + + sc = clknode_get_softc(clk); + + DEVICE_LOCK(clk); + READ4(clk, sc->offset, &val); + DEVICE_UNLOCK(clk); + + if ((val & sc->frac.mode_sel) == 0) { + if (val & sc->frac.freq_sel) + *freq = sc->frac.freq1; + else + *freq = sc->frac.freq0; + } else { + m = aw_clk_get_factor(val, &sc->m); + n = aw_clk_get_factor(val, &sc->n); + + *freq = *freq * n / m; + } + + return (0); +} + +static clknode_method_t aw_frac_clknode_methods[] = { + /* Device interface */ + CLKNODEMETHOD(clknode_init, aw_clk_frac_init), + CLKNODEMETHOD(clknode_set_gate, aw_clk_frac_set_gate), + CLKNODEMETHOD(clknode_set_mux, aw_clk_frac_set_mux), + CLKNODEMETHOD(clknode_recalc_freq, aw_clk_frac_recalc), + CLKNODEMETHOD(clknode_set_freq, aw_clk_frac_set_freq), + CLKNODEMETHOD_END +}; + +DEFINE_CLASS_1(aw_frac_clknode, aw_frac_clknode_class, aw_frac_clknode_methods, + sizeof(struct aw_clk_frac_sc), clknode_class); + +int +aw_clk_frac_register(struct clkdom *clkdom, struct aw_clk_frac_def *clkdef) +{ + struct clknode *clk; + struct aw_clk_frac_sc *sc; + + clk = clknode_create(clkdom, &aw_frac_clknode_class, &clkdef->clkdef); + if (clk == NULL) + return (1); + + sc = clknode_get_softc(clk); + + sc->offset = clkdef->offset; + + sc->m.shift = clkdef->m.shift; + sc->m.width = clkdef->m.width; + sc->m.mask = ((1 << sc->m.width) - 1) << sc->m.shift; + sc->m.value = clkdef->m.value; + sc->m.flags = clkdef->m.flags; + + sc->n.shift = clkdef->n.shift; + sc->n.width = clkdef->n.width; + sc->n.mask = ((1 << sc->n.width) - 1) << sc->n.shift; + sc->n.value = clkdef->n.value; + sc->n.flags = clkdef->n.flags; + + sc->frac.freq0 = clkdef->frac.freq0; + sc->frac.freq1 = clkdef->frac.freq1; + sc->frac.mode_sel = 1 << clkdef->frac.mode_sel; + sc->frac.freq_sel = 1 << clkdef->frac.freq_sel; + + sc->mux_shift = clkdef->mux_shift; + sc->mux_mask = ((1 << clkdef->mux_width) - 1) << sc->mux_shift; + + sc->gate_shift = clkdef->gate_shift; + + sc->lock_shift = clkdef->lock_shift; + sc->lock_retries = clkdef->lock_retries; + + sc->flags = clkdef->flags; + + clknode_register(clkdom, clk); + + return (0); +} Copied: stable/12/sys/arm/allwinner/clkng/aw_clk_frac.h (from r348182, head/sys/arm/allwinner/clkng/aw_clk_frac.h) ============================================================================== --- /dev/null 00:00:00 1970 (empty, because file is newly added) +++ stable/12/sys/arm/allwinner/clkng/aw_clk_frac.h Tue Aug 6 12:19:09 2019 (r350629, copy of r348182, head/sys/arm/allwinner/clkng/aw_clk_frac.h) @@ -0,0 +1,52 @@ +/*- + * Copyright (c) 2019 Emmanuel Vadot <manu@freebsd.org> + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $FreeBSD$ + */ + +#ifndef __AW_CLK_FRAC_H__ +#define __AW_CLK_FRAC_H__ + +#include <dev/extres/clk/clk.h> + +struct aw_clk_frac_def { + struct clknode_init_def clkdef; + uint32_t offset; + + struct aw_clk_factor m; + struct aw_clk_factor n; + struct aw_clk_frac frac; + + uint32_t mux_shift; + uint32_t mux_width; + uint32_t gate_shift; + uint32_t lock_shift; + uint32_t lock_retries; + + uint32_t flags; +}; + +int aw_clk_frac_register(struct clkdom *clkdom, struct aw_clk_frac_def *clkdef); + +#endif /* __AW_CLK_FRAC_H__ */ Modified: stable/12/sys/arm/allwinner/clkng/aw_clk_nm.c ============================================================================== --- stable/12/sys/arm/allwinner/clkng/aw_clk_nm.c Tue Aug 6 12:12:29 2019 (r350628) +++ stable/12/sys/arm/allwinner/clkng/aw_clk_nm.c Tue Aug 6 12:19:09 2019 (r350629) @@ -53,7 +53,6 @@ struct aw_clk_nm_sc { struct aw_clk_factor m; struct aw_clk_factor n; struct aw_clk_factor prediv; - struct aw_clk_frac frac; uint32_t mux_shift; uint32_t mux_mask; @@ -182,13 +181,13 @@ aw_clk_nm_set_freq(struct clknode *clk, uint64_t fpare struct aw_clk_nm_sc *sc; struct clknode *p_clk; const char **p_names; - uint64_t cur, best, best_frac; + uint64_t cur, best; uint32_t val, m, n, best_m, best_n; int p_idx, best_parent, retry; sc = clknode_get_softc(clk); - best = best_frac = cur = 0; + best = cur = 0; best_parent = 0; if ((sc->flags & AW_CLK_REPARENT) != 0) { @@ -210,13 +209,8 @@ aw_clk_nm_set_freq(struct clknode *clk, uint64_t fpare p_clk = clknode_get_parent(clk); clknode_get_freq(p_clk, &fparent); } else { - if (sc->flags & AW_CLK_HAS_FRAC && - (*fout == sc->frac.freq0 || *fout == sc->frac.freq1)) - best = best_frac = *fout; - - if (best == 0) - best = aw_clk_nm_find_best(sc, fparent, fout, - &best_n, &best_m); + best = aw_clk_nm_find_best(sc, fparent, fout, + &best_n, &best_m); } if ((flags & CLK_SET_DRYRUN) != 0) { @@ -242,20 +236,12 @@ aw_clk_nm_set_freq(struct clknode *clk, uint64_t fpare DEVICE_LOCK(clk); READ4(clk, sc->offset, &val); - if (best_frac != 0) { - val &= ~sc->frac.mode_sel; - if (best_frac == sc->frac.freq0) - val &= ~sc->frac.freq_sel; - else - val |= sc->frac.freq_sel; - } else { - n = aw_clk_factor_get_value(&sc->n, best_n); - m = aw_clk_factor_get_value(&sc->m, best_m); - val &= ~sc->n.mask; - val &= ~sc->m.mask; - val |= n << sc->n.shift; - val |= m << sc->m.shift; - } + n = aw_clk_factor_get_value(&sc->n, best_n); + m = aw_clk_factor_get_value(&sc->m, best_m); + val &= ~sc->n.mask; + val &= ~sc->m.mask; + val |= n << sc->n.shift; + val |= m << sc->m.shift; WRITE4(clk, sc->offset, val); DEVICE_UNLOCK(clk); @@ -287,25 +273,14 @@ aw_clk_nm_recalc(struct clknode *clk, uint64_t *freq) READ4(clk, sc->offset, &val); DEVICE_UNLOCK(clk); - if (sc->flags & AW_CLK_HAS_FRAC && ((val & sc->frac.mode_sel) == 0)) { - if (val & sc->frac.freq_sel) - *freq = sc->frac.freq1; - else - *freq = sc->frac.freq0; - } else { - m = aw_clk_get_factor(val, &sc->m); - n = aw_clk_get_factor(val, &sc->n); - if (sc->flags & AW_CLK_HAS_PREDIV) - prediv = aw_clk_get_factor(val, &sc->prediv); - else - prediv = 1; + m = aw_clk_get_factor(val, &sc->m); + n = aw_clk_get_factor(val, &sc->n); + if (sc->flags & AW_CLK_HAS_PREDIV) + prediv = aw_clk_get_factor(val, &sc->prediv); + else + prediv = 1; - /* For FRAC NM the formula is freq_parent * n / m */ - if (sc->flags & AW_CLK_HAS_FRAC) - *freq = *freq * n / m; - else - *freq = *freq / prediv / n / m; - } + *freq = *freq / prediv / n / m; return (0); } @@ -360,11 +335,6 @@ aw_clk_nm_register(struct clkdom *clkdom, struct aw_cl else sc->prediv.cond_mask = clkdef->prediv.cond_mask; sc->prediv.cond_value = clkdef->prediv.cond_value; - - sc->frac.freq0 = clkdef->frac.freq0; - sc->frac.freq1 = clkdef->frac.freq1; - sc->frac.mode_sel = 1 << clkdef->frac.mode_sel; - sc->frac.freq_sel = 1 << clkdef->frac.freq_sel; sc->mux_shift = clkdef->mux_shift; sc->mux_mask = ((1 << clkdef->mux_width) - 1) << sc->mux_shift; Modified: stable/12/sys/arm/allwinner/clkng/aw_clk_nm.h ============================================================================== --- stable/12/sys/arm/allwinner/clkng/aw_clk_nm.h Tue Aug 6 12:12:29 2019 (r350628) +++ stable/12/sys/arm/allwinner/clkng/aw_clk_nm.h Tue Aug 6 12:19:09 2019 (r350629) @@ -38,7 +38,6 @@ struct aw_clk_nm_def { struct aw_clk_factor m; struct aw_clk_factor n; struct aw_clk_factor prediv; - struct aw_clk_frac frac; uint32_t mux_shift; uint32_t mux_width; Modified: stable/12/sys/arm/allwinner/clkng/ccu_a10.c ============================================================================== --- stable/12/sys/arm/allwinner/clkng/ccu_a10.c Tue Aug 6 12:12:29 2019 (r350628) +++ stable/12/sys/arm/allwinner/clkng/ccu_a10.c Tue Aug 6 12:19:09 2019 (r350629) @@ -212,7 +212,7 @@ NKMP_CLK(pll_core_clk, 0, 0, /* lock */ AW_CLK_HAS_GATE); /* flags */ -NM_CLK_WITH_FRAC(pll_video0_clk, +FRAC_CLK(pll_video0_clk, CLK_PLL_VIDEO0, /* id */ "pll_video0", pll_parents, /* name, parents */ 0x10, /* offset */ @@ -231,7 +231,7 @@ FIXED_CLK(pll_video0_2x_clk, 1, /* div */ 0); /* flags */ -NM_CLK_WITH_FRAC(pll_video1_clk, +FRAC_CLK(pll_video1_clk, CLK_PLL_VIDEO1, /* id */ "pll_video1", pll_parents, /* name, parents */ 0x30, /* offset */ @@ -537,8 +537,8 @@ static struct aw_ccung_clk a10_ccu_clks[] = { { .type = AW_CLK_NM, .clk.nm = &ahb_clk}, { .type = AW_CLK_NM, .clk.nm = &apb0_clk}, { .type = AW_CLK_NM, .clk.nm = &apb1_clk}, - { .type = AW_CLK_NM, .clk.nm = &pll_video0_clk}, - { .type = AW_CLK_NM, .clk.nm = &pll_video1_clk}, + { .type = AW_CLK_FRAC, .clk.frac = &pll_video0_clk}, + { .type = AW_CLK_FRAC, .clk.frac = &pll_video1_clk}, { .type = AW_CLK_NM, .clk.nm = &nand_clk}, { .type = AW_CLK_NM, .clk.nm = &ms_clk}, { .type = AW_CLK_NM, .clk.nm = &mmc0_clk}, Modified: stable/12/sys/arm/allwinner/clkng/ccu_a31.c ============================================================================== --- stable/12/sys/arm/allwinner/clkng/ccu_a31.c Tue Aug 6 12:12:29 2019 (r350628) +++ stable/12/sys/arm/allwinner/clkng/ccu_a31.c Tue Aug 6 12:19:09 2019 (r350629) @@ -293,7 +293,7 @@ FIXED_CLK(pll_audio_8x_clk, 1, /* div */ 0); /* flags */ -NM_CLK_WITH_FRAC(pll_video0_clk, +FRAC_CLK(pll_video0_clk, CLK_PLL_VIDEO0, /* id */ "pll_video0", pll_parents, /* name, parents */ 0x10, /* offset */ @@ -314,7 +314,7 @@ FIXED_CLK(pll_video0_2x_clk, 1, /* div */ 0); /* flags */ -NM_CLK_WITH_FRAC(pll_ve_clk, +FRAC_CLK(pll_ve_clk, CLK_PLL_VE, /* id */ "pll_ve", pll_parents, /* name, parents */ 0x18, /* offset */ @@ -360,7 +360,7 @@ FIXED_CLK(pll_periph_2x_clk, 1, /* div */ 0); /* flags */ -NM_CLK_WITH_FRAC(pll_video1_clk, +FRAC_CLK(pll_video1_clk, CLK_PLL_VIDEO1, /* id */ "pll_video1", pll_parents, /* name, parents */ 0x30, /* offset */ @@ -381,7 +381,7 @@ FIXED_CLK(pll_video1_2x_clk, 1, /* div */ 0); /* flags */ -NM_CLK_WITH_FRAC(pll_gpu_clk, +FRAC_CLK(pll_gpu_clk, CLK_PLL_GPU, /* id */ "pll_gpu", pll_parents, /* name, parents */ 0x38, /* offset */ @@ -405,7 +405,7 @@ NKMP_CLK(pll_mipi_clk, 28, 1000, /* lock */ AW_CLK_HAS_GATE | AW_CLK_HAS_LOCK); /* flags */ -NM_CLK_WITH_FRAC(pll9_clk, +FRAC_CLK(pll9_clk, CLK_PLL9, /* id */ "pll9", pll_parents, /* name, parents */ 0x44, /* offset */ @@ -416,7 +416,7 @@ NM_CLK_WITH_FRAC(pll9_clk, 270000000, 297000000, /* freq0, freq1 */ 24, 25); /* mode sel, freq sel */ -NM_CLK_WITH_FRAC(pll10_clk, +FRAC_CLK(pll10_clk, CLK_PLL10, /* id */ "pll10", pll_parents, /* name, parents */ 0x48, /* offset */ @@ -869,12 +869,12 @@ static struct aw_ccung_clk a31_ccu_clks[] = { { .type = AW_CLK_NKMP, .clk.nkmp = &pll_periph_clk}, { .type = AW_CLK_NKMP, .clk.nkmp = &pll_ddr_clk}, { .type = AW_CLK_NKMP, .clk.nkmp = &pll_mipi_clk}, - { .type = AW_CLK_NM, .clk.nm = &pll_video0_clk}, - { .type = AW_CLK_NM, .clk.nm = &pll_ve_clk}, - { .type = AW_CLK_NM, .clk.nm = &pll_video1_clk}, - { .type = AW_CLK_NM, .clk.nm = &pll_gpu_clk}, - { .type = AW_CLK_NM, .clk.nm = &pll9_clk}, - { .type = AW_CLK_NM, .clk.nm = &pll10_clk}, + { .type = AW_CLK_FRAC, .clk.frac = &pll_video0_clk}, + { .type = AW_CLK_FRAC, .clk.frac = &pll_ve_clk}, + { .type = AW_CLK_FRAC, .clk.frac = &pll_video1_clk}, + { .type = AW_CLK_FRAC, .clk.frac = &pll_gpu_clk}, + { .type = AW_CLK_FRAC, .clk.frac = &pll9_clk}, + { .type = AW_CLK_FRAC, .clk.frac = &pll10_clk}, { .type = AW_CLK_NM, .clk.nm = &apb2_clk}, { .type = AW_CLK_NM, .clk.nm = &nand0_clk}, { .type = AW_CLK_NM, .clk.nm = &nand1_clk}, Modified: stable/12/sys/arm/allwinner/clkng/ccu_a64.c ============================================================================== --- stable/12/sys/arm/allwinner/clkng/ccu_a64.c Tue Aug 6 12:12:29 2019 (r350628) +++ stable/12/sys/arm/allwinner/clkng/ccu_a64.c Tue Aug 6 12:19:09 2019 (r350629) @@ -279,7 +279,7 @@ FIXED_CLK(pll_audio_8x_clk, 0); /* flags */ static const char *pll_video0_parents[] = {"osc24M"}; -NM_CLK_WITH_FRAC(pll_video0_clk, +FRAC_CLK(pll_video0_clk, CLK_PLL_VIDEO0, /* id */ "pll_video0", pll_video0_parents, /* name, parents */ 0x10, /* offset */ @@ -300,7 +300,7 @@ FIXED_CLK(pll_video0_2x_clk, 0); /* flags */ static const char *pll_ve_parents[] = {"osc24M"}; -NM_CLK_WITH_FRAC(pll_ve_clk, +FRAC_CLK(pll_ve_clk, CLK_PLL_VE, /* id */ "pll_ve", pll_ve_parents, /* name, parents */ 0x18, /* offset */ @@ -370,7 +370,7 @@ FIXED_CLK(pll_periph1_clk, 0); /* flags */ static const char *pll_video1_parents[] = {"osc24M"}; -NM_CLK_WITH_FRAC(pll_video1_clk, +FRAC_CLK(pll_video1_clk, CLK_PLL_VIDEO1, /* id */ "pll_video1", pll_video1_parents, /* name, parents */ 0x30, /* offset */ @@ -382,7 +382,7 @@ NM_CLK_WITH_FRAC(pll_video1_clk, 24, 25); /* mode sel, freq sel */ static const char *pll_gpu_parents[] = {"osc24M"}; -NM_CLK_WITH_FRAC(pll_gpu_clk, +FRAC_CLK(pll_gpu_clk, CLK_PLL_GPU, /* id */ "pll_gpu", pll_gpu_parents, /* name, parents */ 0x38, /* offset */ @@ -396,7 +396,7 @@ NM_CLK_WITH_FRAC(pll_gpu_clk, /* PLL MIPI is missing */ static const char *pll_hsic_parents[] = {"osc24M"}; -NM_CLK_WITH_FRAC(pll_hsic_clk, +FRAC_CLK(pll_hsic_clk, CLK_PLL_HSIC, /* id */ "pll_hsic", pll_hsic_parents, /* name, parents */ 0x44, /* offset */ @@ -408,7 +408,7 @@ NM_CLK_WITH_FRAC(pll_hsic_clk, 24, 25); /* mode sel, freq sel */ static const char *pll_de_parents[] = {"osc24M"}; -NM_CLK_WITH_FRAC(pll_de_clk, +FRAC_CLK(pll_de_clk, CLK_PLL_DE, /* id */ "pll_de", pll_de_parents, /* name, parents */ 0x48, /* offset */ @@ -723,16 +723,18 @@ NM_CLK(gpu_clk, static struct aw_ccung_clk a64_ccu_clks[] = { { .type = AW_CLK_NKMP, .clk.nkmp = &pll_cpux_clk}, { .type = AW_CLK_NKMP, .clk.nkmp = &pll_audio_clk}, + { .type = AW_CLK_FRAC, .clk.frac = &pll_video0_clk}, + { .type = AW_CLK_FRAC, .clk.frac = &pll_ve_clk}, + { .type = AW_CLK_NKMP, .clk.nkmp = &pll_ddr0_clk}, { .type = AW_CLK_NKMP, .clk.nkmp = &pll_periph0_2x_clk}, { .type = AW_CLK_NKMP, .clk.nkmp = &pll_periph1_2x_clk}, - { .type = AW_CLK_NKMP, .clk.nkmp = &pll_ddr0_clk}, + { .type = AW_CLK_FRAC, .clk.frac = &pll_video1_clk}, + { .type = AW_CLK_FRAC, .clk.frac = &pll_gpu_clk}, + /* PLL_MIPI */ + { .type = AW_CLK_FRAC, .clk.frac = &pll_hsic_clk}, + { .type = AW_CLK_FRAC, .clk.frac = &pll_de_clk}, { .type = AW_CLK_NKMP, .clk.nkmp = &pll_ddr1_clk}, - { .type = AW_CLK_NM, .clk.nm = &pll_video0_clk}, - { .type = AW_CLK_NM, .clk.nm = &pll_video1_clk}, - { .type = AW_CLK_NM, .clk.nm = &pll_ve_clk}, - { .type = AW_CLK_NM, .clk.nm = &pll_gpu_clk}, - { .type = AW_CLK_NM, .clk.nm = &pll_de_clk}, - { .type = AW_CLK_NM, .clk.nm = &pll_hsic_clk}, + { .type = AW_CLK_NM, .clk.nm = &apb2_clk}, { .type = AW_CLK_NM, .clk.nm = &nand_clk}, { .type = AW_CLK_NM, .clk.nm = &mmc0_clk}, Modified: stable/12/sys/arm/allwinner/clkng/ccu_h3.c ============================================================================== --- stable/12/sys/arm/allwinner/clkng/ccu_h3.c Tue Aug 6 12:12:29 2019 (r350628) +++ stable/12/sys/arm/allwinner/clkng/ccu_h3.c Tue Aug 6 12:19:09 2019 (r350629) @@ -297,7 +297,7 @@ FIXED_CLK(pll_audio_8x_clk, 0); /* flags */ static const char *pll_video_parents[] = {"osc24M"}; -NM_CLK_WITH_FRAC(pll_video_clk, +FRAC_CLK(pll_video_clk, CLK_PLL_VIDEO, /* id */ "pll_video", pll_video_parents, /* name, parents */ 0x10, /* offset */ @@ -309,7 +309,7 @@ NM_CLK_WITH_FRAC(pll_video_clk, 24, 25); /* mode sel, freq sel */ static const char *pll_ve_parents[] = {"osc24M"}; -NM_CLK_WITH_FRAC(pll_ve_clk, +FRAC_CLK(pll_ve_clk, CLK_PLL_VE, /* id */ "pll_ve", pll_ve_parents, /* name, parents */ 0x18, /* offset */ @@ -357,7 +357,7 @@ FIXED_CLK(pll_periph0_2x_clk, 0); /* flags */ static const char *pll_gpu_parents[] = {"osc24M"}; -NM_CLK_WITH_FRAC(pll_gpu_clk, +FRAC_CLK(pll_gpu_clk, CLK_PLL_GPU, /* id */ "pll_gpu", pll_gpu_parents, /* name, parents */ 0x38, /* offset */ @@ -382,7 +382,7 @@ NKMP_CLK(pll_periph1_clk, AW_CLK_HAS_GATE | AW_CLK_HAS_LOCK); /* flags */ static const char *pll_de_parents[] = {"osc24M"}; -NM_CLK_WITH_FRAC(pll_de_clk, +FRAC_CLK(pll_de_clk, CLK_PLL_DE, /* id */ "pll_de", pll_de_parents, /* name, parents */ 0x48, /* offset */ @@ -684,10 +684,10 @@ static struct aw_ccung_clk h3_ccu_clks[] = { { .type = AW_CLK_NKMP, .clk.nkmp = &pll_periph0_clk}, { .type = AW_CLK_NKMP, .clk.nkmp = &pll_periph1_clk}, { .type = AW_CLK_NKMP, .clk.nkmp = &pll_ddr_clk}, - { .type = AW_CLK_NM, .clk.nm = &pll_video_clk}, - { .type = AW_CLK_NM, .clk.nm = &pll_ve_clk}, - { .type = AW_CLK_NM, .clk.nm = &pll_gpu_clk}, - { .type = AW_CLK_NM, .clk.nm = &pll_de_clk}, + { .type = AW_CLK_FRAC, .clk.frac = &pll_video_clk}, + { .type = AW_CLK_FRAC, .clk.frac = &pll_ve_clk}, + { .type = AW_CLK_FRAC, .clk.frac = &pll_gpu_clk}, + { .type = AW_CLK_FRAC, .clk.frac = &pll_de_clk}, { .type = AW_CLK_NM, .clk.nm = &apb2_clk}, { .type = AW_CLK_NM, .clk.nm = &nand_clk}, { .type = AW_CLK_NM, .clk.nm = &mmc0_clk}, Modified: stable/12/sys/arm/allwinner/files.allwinner ============================================================================== --- stable/12/sys/arm/allwinner/files.allwinner Tue Aug 6 12:12:29 2019 (r350628) +++ stable/12/sys/arm/allwinner/files.allwinner Tue Aug 6 12:19:09 2019 (r350629) @@ -36,6 +36,7 @@ arm/allwinner/aw_ccu.c standard arm/allwinner/aw_gmacclk.c standard arm/allwinner/clkng/aw_ccung.c standard +arm/allwinner/clkng/aw_clk_frac.c standard arm/allwinner/clkng/aw_clk_nkmp.c standard arm/allwinner/clkng/aw_clk_nm.c standard arm/allwinner/clkng/aw_clk_prediv_mux.c standard Modified: stable/12/sys/conf/files.arm64 ============================================================================== --- stable/12/sys/conf/files.arm64 Tue Aug 6 12:12:29 2019 (r350628) +++ stable/12/sys/conf/files.arm64 Tue Aug 6 12:19:09 2019 (r350629) @@ -49,6 +49,7 @@ arm/allwinner/if_awg.c optional awg ext_resources sys # Allwinner clock driver arm/allwinner/clkng/aw_ccung.c optional aw_ccu fdt +arm/allwinner/clkng/aw_clk_frac.c optional aw_ccu fdt arm/allwinner/clkng/aw_clk_nkmp.c optional aw_ccu fdt arm/allwinner/clkng/aw_clk_nm.c optional aw_ccu fdt arm/allwinner/clkng/aw_clk_prediv_mux.c optional aw_ccu fdt
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201908061219.x76CJ9Mu062460>