From owner-svn-src-all@freebsd.org Fri Nov 8 19:15:51 2019 Return-Path: Delivered-To: svn-src-all@mailman.nyi.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mailman.nyi.freebsd.org (Postfix) with ESMTP id 67C7F15C33C; Fri, 8 Nov 2019 19:15:51 +0000 (UTC) (envelope-from mmel@FreeBSD.org) Received: from mxrelay.nyi.freebsd.org (mxrelay.nyi.freebsd.org [IPv6:2610:1c1:1:606c::19:3]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) server-signature RSA-PSS (4096 bits) client-signature RSA-PSS (4096 bits) client-digest SHA256) (Client CN "mxrelay.nyi.freebsd.org", Issuer "Let's Encrypt Authority X3" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id 478qjz2373z3JmB; Fri, 8 Nov 2019 19:15:51 +0000 (UTC) (envelope-from mmel@FreeBSD.org) Received: from repo.freebsd.org (repo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mxrelay.nyi.freebsd.org (Postfix) with ESMTPS id 2A82F2BB7; Fri, 8 Nov 2019 19:15:51 +0000 (UTC) (envelope-from mmel@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id xA8JFpT6004175; Fri, 8 Nov 2019 19:15:51 GMT (envelope-from mmel@FreeBSD.org) Received: (from mmel@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id xA8JFokc004173; Fri, 8 Nov 2019 19:15:50 GMT (envelope-from mmel@FreeBSD.org) Message-Id: <201911081915.xA8JFokc004173@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: mmel set sender to mmel@FreeBSD.org using -f From: Michal Meloun Date: Fri, 8 Nov 2019 19:15:50 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r354557 - head/sys/arm64/rockchip/clk X-SVN-Group: head X-SVN-Commit-Author: mmel X-SVN-Commit-Paths: head/sys/arm64/rockchip/clk X-SVN-Commit-Revision: 354557 X-SVN-Commit-Repository: base MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-all@freebsd.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: "SVN commit messages for the entire src tree \(except for " user" and " projects" \)" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 08 Nov 2019 19:15:51 -0000 Author: mmel Date: Fri Nov 8 19:15:50 2019 New Revision: 354557 URL: https://svnweb.freebsd.org/changeset/base/354557 Log: Tidy up Rockchip composite clock. - add support for log2 based dividers - use proper write mask when writing to divider register MFC after: 3 weeks Reviewed by: manu Differential Revision: https://reviews.freebsd.org/D22283 Modified: head/sys/arm64/rockchip/clk/rk_clk_composite.c head/sys/arm64/rockchip/clk/rk_clk_composite.h Modified: head/sys/arm64/rockchip/clk/rk_clk_composite.c ============================================================================== --- head/sys/arm64/rockchip/clk/rk_clk_composite.c Fri Nov 8 19:13:11 2019 (r354556) +++ head/sys/arm64/rockchip/clk/rk_clk_composite.c Fri Nov 8 19:15:50 2019 (r354557) @@ -158,31 +158,44 @@ rk_clk_composite_recalc(struct clknode *clk, uint64_t DEVICE_UNLOCK(clk); - div = ((reg & sc->div_mask) >> sc->div_shift) + 1; - dprintf("parent_freq=%lu, div=%u\n", *freq, div); + div = ((reg & sc->div_mask) >> sc->div_shift); + if (sc->flags & RK_CLK_COMPOSITE_DIV_EXP) + div = 1 << div; + else + div += 1; + dprintf("parent_freq=%ju, div=%u\n", *freq, div); *freq = *freq / div; - dprintf("Final freq=%ju\n", *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 freq, uint32_t *reg) { uint64_t best, cur; - uint32_t best_div, div; + uint32_t best_div, best_div_reg; + uint32_t div, div_reg; - for (best = 0, best_div = 0, div = 0; - div <= ((sc->div_mask >> sc->div_shift) + 1); div++) { + best = 0; + best_div = 0; + best_div_reg = 0; + + for (div_reg = 0; div_reg <= ((sc->div_mask >> sc->div_shift) + 1); + div_reg++) { + if (sc->flags == RK_CLK_COMPOSITE_DIV_EXP) + div = 1 << div_reg; + else + div = div_reg + 1; cur = fparent / div; if ((freq - cur) < (freq - best)) { best = cur; best_div = div; + best_div_reg = div_reg; break; } } - + *reg = div_reg; return (best_div); } @@ -194,11 +207,10 @@ rk_clk_composite_set_freq(struct clknode *clk, uint64_ struct clknode *p_clk; const char **p_names; uint64_t best, cur; - uint32_t div, best_div, val = 0; + uint32_t div, div_reg, best_div, best_div_reg, val; int p_idx, best_parent; sc = clknode_get_softc(clk); - dprintf("Finding best parent/div for target freq of %ju\n", *fout); p_names = clknode_get_parent_names(clk); for (best_div = 0, best = 0, p_idx = 0; @@ -207,34 +219,31 @@ rk_clk_composite_set_freq(struct clknode *clk, uint64_ clknode_get_freq(p_clk, &fparent); dprintf("Testing with parent %s (%d) at freq %ju\n", clknode_get_name(p_clk), p_idx, fparent); - div = rk_clk_composite_find_best(sc, fparent, *fout); + div = rk_clk_composite_find_best(sc, fparent, *fout, &div_reg); cur = fparent / div; if ((*fout - cur) < (*fout - best)) { best = cur; best_div = div; + best_div_reg = div_reg; best_parent = p_idx; dprintf("Best parent so far %s (%d) with best freq at " "%ju\n", clknode_get_name(p_clk), p_idx, best); } } + *stop = 1; if (best_div == 0) - return (0); + return (ERANGE); - if ((best < *fout) && - ((flags & CLK_SET_ROUND_DOWN) == 0)) { - *stop = 1; + if ((best < *fout) && ((flags & CLK_SET_ROUND_DOWN) == 0)) return (ERANGE); - } - if ((best > *fout) && - ((flags & CLK_SET_ROUND_UP) == 0)) { - *stop = 1; + + if ((best > *fout) && ((flags & CLK_SET_ROUND_UP) == 0)) { return (ERANGE); } if ((flags & CLK_SET_DRYRUN) != 0) { *fout = best; - *stop = 1; return (0); } @@ -245,17 +254,18 @@ rk_clk_composite_set_freq(struct clknode *clk, uint64_ clknode_set_parent_by_idx(clk, best_parent); } - dprintf("Setting divider to %d\n", best_div); + dprintf("Setting divider to %d (reg: %d)\n", best_div, best_div_reg); + dprintf(" div_mask: 0x%X, div_shift: %d\n", sc->div_mask, + sc->div_shift); + DEVICE_LOCK(clk); - val |= (best_div - 1) << sc->div_shift; - val |= (sc->div_mask << sc->div_shift) << RK_CLK_COMPOSITE_MASK_SHIFT; + val = best_div_reg << sc->div_shift; + val |= sc->div_mask << RK_CLK_COMPOSITE_MASK_SHIFT; dprintf("Write: muxdiv_offset=%x, val=%x\n", sc->muxdiv_offset, val); WRITE4(clk, sc->muxdiv_offset, val); DEVICE_UNLOCK(clk); *fout = best; - *stop = 1; - return (0); } Modified: head/sys/arm64/rockchip/clk/rk_clk_composite.h ============================================================================== --- head/sys/arm64/rockchip/clk/rk_clk_composite.h Fri Nov 8 19:13:11 2019 (r354556) +++ head/sys/arm64/rockchip/clk/rk_clk_composite.h Fri Nov 8 19:15:50 2019 (r354557) @@ -52,7 +52,8 @@ struct rk_clk_composite_def { #define RK_CLK_COMPOSITE_HAVE_MUX 0x0001 #define RK_CLK_COMPOSITE_HAVE_GATE 0x0002 - +#define RK_CLK_COMPOSITE_DIV_EXP 0x0004 /* Register 0, 1, 2, 2, ... */ + /* Divider 1, 2, 4, 8, ... */ int rk_clk_composite_register(struct clkdom *clkdom, struct rk_clk_composite_def *clkdef);