From owner-svn-src-all@freebsd.org Sat Dec 1 20:27:01 2018 Return-Path: Delivered-To: svn-src-all@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id 3C571132688E; Sat, 1 Dec 2018 20:27:01 +0000 (UTC) (envelope-from manu@FreeBSD.org) Received: from mxrelay.nyi.freebsd.org (mxrelay.nyi.freebsd.org [IPv6:2610:1c1:1:606c::19:3]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client CN "mxrelay.nyi.freebsd.org", Issuer "Let's Encrypt Authority X3" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id E3E76727C2; Sat, 1 Dec 2018 20:27:00 +0000 (UTC) (envelope-from manu@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 C4C961CADD; Sat, 1 Dec 2018 20:27:00 +0000 (UTC) (envelope-from manu@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id wB1KR0KD059880; Sat, 1 Dec 2018 20:27:00 GMT (envelope-from manu@FreeBSD.org) Received: (from manu@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id wB1KQxsF059870; Sat, 1 Dec 2018 20:26:59 GMT (envelope-from manu@FreeBSD.org) Message-Id: <201812012026.wB1KQxsF059870@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: manu set sender to manu@FreeBSD.org using -f From: Emmanuel Vadot Date: Sat, 1 Dec 2018 20:26:59 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r341381 - head/sys/arm64/rockchip/clk X-SVN-Group: head X-SVN-Commit-Author: manu X-SVN-Commit-Paths: head/sys/arm64/rockchip/clk X-SVN-Commit-Revision: 341381 X-SVN-Commit-Repository: base MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-Rspamd-Queue-Id: E3E76727C2 X-Spamd-Result: default: False [0.80 / 15.00]; local_wl_from(0.00)[FreeBSD.org]; NEURAL_SPAM_LONG(0.36)[0.363,0]; NEURAL_SPAM_MEDIUM(0.21)[0.206,0]; ASN(0.00)[asn:11403, ipnet:2610:1c1:1::/48, country:US]; NEURAL_SPAM_SHORT(0.23)[0.226,0] X-Rspamd-Server: mx1.freebsd.org 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: Sat, 01 Dec 2018 20:27:01 -0000 Author: manu Date: Sat Dec 1 20:26:59 2018 New Revision: 341381 URL: https://svnweb.freebsd.org/changeset/base/341381 Log: arm64: rockchip: Add RK3399_CLK_PLL PLLs on the RK3399 are different than the ones on the RK3328. Add a new type and some dedicated recalc and set_freq functions. Rename the RK3328 dedicated rk_clk_pll function with rk3328_ prefix. MFC after: 1 month Modified: head/sys/arm64/rockchip/clk/rk3328_cru.c head/sys/arm64/rockchip/clk/rk_clk_pll.c head/sys/arm64/rockchip/clk/rk_clk_pll.h head/sys/arm64/rockchip/clk/rk_cru.c head/sys/arm64/rockchip/clk/rk_cru.h Modified: head/sys/arm64/rockchip/clk/rk3328_cru.c ============================================================================== --- head/sys/arm64/rockchip/clk/rk3328_cru.c Sat Dec 1 18:23:41 2018 (r341380) +++ head/sys/arm64/rockchip/clk/rk3328_cru.c Sat Dec 1 20:26:59 2018 (r341381) @@ -973,23 +973,23 @@ static struct rk_clk_composite_def i2c3 = { static struct rk_clk rk3328_clks[] = { { - .type = RK_CLK_PLL, + .type = RK3328_CLK_PLL, .clk.pll = &apll }, { - .type = RK_CLK_PLL, + .type = RK3328_CLK_PLL, .clk.pll = &dpll }, { - .type = RK_CLK_PLL, + .type = RK3328_CLK_PLL, .clk.pll = &cpll }, { - .type = RK_CLK_PLL, + .type = RK3328_CLK_PLL, .clk.pll = &gpll }, { - .type = RK_CLK_PLL, + .type = RK3328_CLK_PLL, .clk.pll = &npll }, Modified: head/sys/arm64/rockchip/clk/rk_clk_pll.c ============================================================================== --- head/sys/arm64/rockchip/clk/rk_clk_pll.c Sat Dec 1 18:23:41 2018 (r341380) +++ head/sys/arm64/rockchip/clk/rk_clk_pll.c Sat Dec 1 20:26:59 2018 (r341381) @@ -65,47 +65,7 @@ struct rk_clk_pll_sc { #define DEVICE_UNLOCK(_clk) \ CLKDEV_DEVICE_UNLOCK(clknode_get_device(_clk)) -#define RK_CLK_PLL_FBDIV_OFFSET 0 -#define RK_CLK_PLL_FBDIV_SHIFT 0 -#define RK_CLK_PLL_FBDIV_MASK 0xFFF - -#define RK_CLK_PLL_POSTDIV1_OFFSET 0 -#define RK_CLK_PLL_POSTDIV1_SHIFT 12 -#define RK_CLK_PLL_POSTDIV1_MASK 0x7000 - -#define RK_CLK_PLL_DSMPD_OFFSET 4 -#define RK_CLK_PLL_DSMPD_SHIFT 12 -#define RK_CLK_PLL_DSMPD_MASK 0x1000 - -#define RK_CLK_PLL_REFDIV_OFFSET 4 -#define RK_CLK_PLL_REFDIV_SHIFT 0 -#define RK_CLK_PLL_REFDIV_MASK 0x3F - -#define RK_CLK_PLL_POSTDIV2_OFFSET 4 -#define RK_CLK_PLL_POSTDIV2_SHIFT 6 -#define RK_CLK_PLL_POSTDIV2_MASK 0x1C0 - -#define RK_CLK_PLL_FRAC_OFFSET 8 -#define RK_CLK_PLL_FRAC_SHIFT 0 -#define RK_CLK_PLL_FRAC_MASK 0xFFFFFF - -#define RK_CLK_PLL_LOCK_MASK 0x400 - -#define RK_CLK_PLL_WRITE_MASK 0xFFFF0000 - static int -rk_clk_pll_init(struct clknode *clk, device_t dev) -{ - struct rk_clk_pll_sc *sc; - - sc = clknode_get_softc(clk); - - clknode_init_parent_idx(clk, 0); - - return (0); -} - -static int rk_clk_pll_set_gate(struct clknode *clk, bool enable) { struct rk_clk_pll_sc *sc; @@ -128,10 +88,50 @@ rk_clk_pll_set_gate(struct clknode *clk, bool enable) return (0); } +#define RK3328_CLK_PLL_FBDIV_OFFSET 0 +#define RK3328_CLK_PLL_FBDIV_SHIFT 0 +#define RK3328_CLK_PLL_FBDIV_MASK 0xFFF + +#define RK3328_CLK_PLL_POSTDIV1_OFFSET 0 +#define RK3328_CLK_PLL_POSTDIV1_SHIFT 12 +#define RK3328_CLK_PLL_POSTDIV1_MASK 0x7000 + +#define RK3328_CLK_PLL_DSMPD_OFFSET 4 +#define RK3328_CLK_PLL_DSMPD_SHIFT 12 +#define RK3328_CLK_PLL_DSMPD_MASK 0x1000 + +#define RK3328_CLK_PLL_REFDIV_OFFSET 4 +#define RK3328_CLK_PLL_REFDIV_SHIFT 0 +#define RK3328_CLK_PLL_REFDIV_MASK 0x3F + +#define RK3328_CLK_PLL_POSTDIV2_OFFSET 4 +#define RK3328_CLK_PLL_POSTDIV2_SHIFT 6 +#define RK3328_CLK_PLL_POSTDIV2_MASK 0x1C0 + +#define RK3328_CLK_PLL_FRAC_OFFSET 8 +#define RK3328_CLK_PLL_FRAC_SHIFT 0 +#define RK3328_CLK_PLL_FRAC_MASK 0xFFFFFF + +#define RK3328_CLK_PLL_LOCK_MASK 0x400 + +#define RK3328_CLK_PLL_WRITE_MASK 0xFFFF0000 + static int -rk_clk_pll_recalc(struct clknode *clk, uint64_t *freq) +rk3328_clk_pll_init(struct clknode *clk, device_t dev) { struct rk_clk_pll_sc *sc; + + sc = clknode_get_softc(clk); + + clknode_init_parent_idx(clk, 0); + + return (0); +} + +static int +rk3328_clk_pll_recalc(struct clknode *clk, uint64_t *freq) +{ + struct rk_clk_pll_sc *sc; uint64_t rate; uint32_t dsmpd, refdiv, fbdiv; uint32_t postdiv1, postdiv2, frac; @@ -145,14 +145,14 @@ rk_clk_pll_recalc(struct clknode *clk, uint64_t *freq) READ4(clk, sc->base_offset + 4, &raw2); READ4(clk, sc->base_offset + 8, &raw3); - fbdiv = (raw1 & RK_CLK_PLL_FBDIV_MASK) >> RK_CLK_PLL_FBDIV_SHIFT; - postdiv1 = (raw1 & RK_CLK_PLL_POSTDIV1_MASK) >> RK_CLK_PLL_POSTDIV1_SHIFT; + fbdiv = (raw1 & RK3328_CLK_PLL_FBDIV_MASK) >> RK3328_CLK_PLL_FBDIV_SHIFT; + postdiv1 = (raw1 & RK3328_CLK_PLL_POSTDIV1_MASK) >> RK3328_CLK_PLL_POSTDIV1_SHIFT; - dsmpd = (raw2 & RK_CLK_PLL_DSMPD_MASK) >> RK_CLK_PLL_DSMPD_SHIFT; - refdiv = (raw2 & RK_CLK_PLL_REFDIV_MASK) >> RK_CLK_PLL_REFDIV_SHIFT; - postdiv2 = (raw2 & RK_CLK_PLL_POSTDIV2_MASK) >> RK_CLK_PLL_POSTDIV2_SHIFT; + dsmpd = (raw2 & RK3328_CLK_PLL_DSMPD_MASK) >> RK3328_CLK_PLL_DSMPD_SHIFT; + refdiv = (raw2 & RK3328_CLK_PLL_REFDIV_MASK) >> RK3328_CLK_PLL_REFDIV_SHIFT; + postdiv2 = (raw2 & RK3328_CLK_PLL_POSTDIV2_MASK) >> RK3328_CLK_PLL_POSTDIV2_SHIFT; - frac = (raw3 & RK_CLK_PLL_FRAC_MASK) >> RK_CLK_PLL_FRAC_SHIFT; + frac = (raw3 & RK3328_CLK_PLL_FRAC_MASK) >> RK3328_CLK_PLL_FRAC_SHIFT; DEVICE_UNLOCK(clk); @@ -174,7 +174,7 @@ rk_clk_pll_recalc(struct clknode *clk, uint64_t *freq) } static int -rk_clk_pll_set_freq(struct clknode *clk, uint64_t fparent, uint64_t *fout, +rk3328_clk_pll_set_freq(struct clknode *clk, uint64_t fparent, uint64_t *fout, int flags, int *stop) { struct rk_clk_pll_rate *rates; @@ -204,24 +204,24 @@ rk_clk_pll_set_freq(struct clknode *clk, uint64_t fpar /* Setting postdiv1 and fbdiv */ READ4(clk, sc->base_offset, ®); - reg &= ~(RK_CLK_PLL_POSTDIV1_MASK | RK_CLK_PLL_FBDIV_MASK); - reg |= rates->postdiv1 << RK_CLK_PLL_POSTDIV1_SHIFT; - reg |= rates->fbdiv << RK_CLK_PLL_FBDIV_SHIFT; - WRITE4(clk, sc->base_offset, reg | RK_CLK_PLL_WRITE_MASK); + reg &= ~(RK3328_CLK_PLL_POSTDIV1_MASK | RK3328_CLK_PLL_FBDIV_MASK); + reg |= rates->postdiv1 << RK3328_CLK_PLL_POSTDIV1_SHIFT; + reg |= rates->fbdiv << RK3328_CLK_PLL_FBDIV_SHIFT; + WRITE4(clk, sc->base_offset, reg | RK3328_CLK_PLL_WRITE_MASK); /* Setting dsmpd, postdiv2 and refdiv */ READ4(clk, sc->base_offset + 0x4, ®); - reg &= ~(RK_CLK_PLL_DSMPD_MASK | RK_CLK_PLL_POSTDIV2_MASK | - RK_CLK_PLL_REFDIV_MASK); - reg |= rates->dsmpd << RK_CLK_PLL_DSMPD_SHIFT; - reg |= rates->postdiv2 << RK_CLK_PLL_POSTDIV2_SHIFT; - reg |= rates->refdiv << RK_CLK_PLL_REFDIV_SHIFT; - WRITE4(clk, sc->base_offset + 0x4, reg | RK_CLK_PLL_WRITE_MASK); + reg &= ~(RK3328_CLK_PLL_DSMPD_MASK | RK3328_CLK_PLL_POSTDIV2_MASK | + RK3328_CLK_PLL_REFDIV_MASK); + reg |= rates->dsmpd << RK3328_CLK_PLL_DSMPD_SHIFT; + reg |= rates->postdiv2 << RK3328_CLK_PLL_POSTDIV2_SHIFT; + reg |= rates->refdiv << RK3328_CLK_PLL_REFDIV_SHIFT; + WRITE4(clk, sc->base_offset + 0x4, reg | RK3328_CLK_PLL_WRITE_MASK); /* Setting frac */ READ4(clk, sc->base_offset + 0x8, ®); - reg &= ~RK_CLK_PLL_FRAC_MASK; - reg |= rates->frac << RK_CLK_PLL_FRAC_SHIFT; + reg &= ~RK3328_CLK_PLL_FRAC_MASK; + reg |= rates->frac << RK3328_CLK_PLL_FRAC_SHIFT; WRITE4(clk, sc->base_offset + 0x8, reg); /* Setting to normal mode */ @@ -232,7 +232,7 @@ rk_clk_pll_set_freq(struct clknode *clk, uint64_t fpar /* Reading lock */ for (timeout = 1000; timeout; timeout--) { READ4(clk, sc->base_offset + 0x4, ®); - if ((reg & RK_CLK_PLL_LOCK_MASK) == 0) + if ((reg & RK3328_CLK_PLL_LOCK_MASK) == 0) break; DELAY(1); } @@ -243,25 +243,236 @@ rk_clk_pll_set_freq(struct clknode *clk, uint64_t fpar return (0); } -static clknode_method_t rk_clk_pll_clknode_methods[] = { +static clknode_method_t rk3328_clk_pll_clknode_methods[] = { /* Device interface */ - CLKNODEMETHOD(clknode_init, rk_clk_pll_init), + CLKNODEMETHOD(clknode_init, rk3328_clk_pll_init), CLKNODEMETHOD(clknode_set_gate, rk_clk_pll_set_gate), - CLKNODEMETHOD(clknode_recalc_freq, rk_clk_pll_recalc), - CLKNODEMETHOD(clknode_set_freq, rk_clk_pll_set_freq), + CLKNODEMETHOD(clknode_recalc_freq, rk3328_clk_pll_recalc), + CLKNODEMETHOD(clknode_set_freq, rk3328_clk_pll_set_freq), CLKNODEMETHOD_END }; -DEFINE_CLASS_1(rk_clk_pll_clknode, rk_clk_pll_clknode_class, - rk_clk_pll_clknode_methods, sizeof(struct rk_clk_pll_sc), clknode_class); +DEFINE_CLASS_1(rk3328_clk_pll_clknode, rk3328_clk_pll_clknode_class, + rk3328_clk_pll_clknode_methods, sizeof(struct rk_clk_pll_sc), clknode_class); int -rk_clk_pll_register(struct clkdom *clkdom, struct rk_clk_pll_def *clkdef) +rk3328_clk_pll_register(struct clkdom *clkdom, struct rk_clk_pll_def *clkdef) { struct clknode *clk; struct rk_clk_pll_sc *sc; - clk = clknode_create(clkdom, &rk_clk_pll_clknode_class, + clk = clknode_create(clkdom, &rk3328_clk_pll_clknode_class, + &clkdef->clkdef); + if (clk == NULL) + return (1); + + sc = clknode_get_softc(clk); + + sc->base_offset = clkdef->base_offset; + sc->gate_offset = clkdef->gate_offset; + sc->gate_shift = clkdef->gate_shift; + sc->mode_reg = clkdef->mode_reg; + sc->mode_val = clkdef->mode_val; + sc->flags = clkdef->flags; + sc->rates = clkdef->rates; + sc->frac_rates = clkdef->frac_rates; + + clknode_register(clkdom, clk); + + return (0); +} + +#define RK3399_CLK_PLL_FBDIV_OFFSET 0 +#define RK3399_CLK_PLL_FBDIV_SHIFT 0 +#define RK3399_CLK_PLL_FBDIV_MASK 0xFFF + +#define RK3399_CLK_PLL_POSTDIV2_OFFSET 4 +#define RK3399_CLK_PLL_POSTDIV2_SHIFT 12 +#define RK3399_CLK_PLL_POSTDIV2_MASK 0x7000 + +#define RK3399_CLK_PLL_POSTDIV1_OFFSET 4 +#define RK3399_CLK_PLL_POSTDIV1_SHIFT 8 +#define RK3399_CLK_PLL_POSTDIV1_MASK 0x700 + +#define RK3399_CLK_PLL_REFDIV_OFFSET 4 +#define RK3399_CLK_PLL_REFDIV_SHIFT 0 +#define RK3399_CLK_PLL_REFDIV_MASK 0x3F + +#define RK3399_CLK_PLL_FRAC_OFFSET 8 +#define RK3399_CLK_PLL_FRAC_SHIFT 0 +#define RK3399_CLK_PLL_FRAC_MASK 0xFFFFFF + +#define RK3399_CLK_PLL_DSMPD_OFFSET 0xC +#define RK3399_CLK_PLL_DSMPD_SHIFT 3 +#define RK3399_CLK_PLL_DSMPD_MASK 0x8 + +#define RK3399_CLK_PLL_LOCK_OFFSET 8 +#define RK3399_CLK_PLL_LOCK_MASK 0x400 + +#define RK3399_CLK_PLL_MODE_OFFSET 0xC +#define RK3399_CLK_PLL_MODE_MASK 0x300 +#define RK3399_CLK_PLL_MODE_SLOW 0 +#define RK3399_CLK_PLL_MODE_NORMAL 1 +#define RK3399_CLK_PLL_MODE_DEEPSLOW 2 +#define RK3399_CLK_PLL_MODE_SHIFT 8 + +#define RK3399_CLK_PLL_WRITE_MASK 0xFFFF0000 + +static int +rk3399_clk_pll_init(struct clknode *clk, device_t dev) +{ + struct rk_clk_pll_sc *sc; + uint32_t reg; + + sc = clknode_get_softc(clk); + + /* Setting to normal mode */ + READ4(clk, sc->base_offset + RK3399_CLK_PLL_MODE_OFFSET, ®); + reg &= ~RK3399_CLK_PLL_MODE_MASK; + reg |= RK3399_CLK_PLL_MODE_NORMAL << RK3399_CLK_PLL_MODE_SHIFT; + WRITE4(clk, sc->base_offset + RK3399_CLK_PLL_MODE_OFFSET, + reg | RK3399_CLK_PLL_WRITE_MASK); + + clknode_init_parent_idx(clk, 0); + + return (0); +} + +static int +rk3399_clk_pll_recalc(struct clknode *clk, uint64_t *freq) +{ + struct rk_clk_pll_sc *sc; + uint64_t rate; + uint32_t dsmpd, refdiv, fbdiv; + uint32_t postdiv1, postdiv2, frac; + uint32_t raw1, raw2, raw3, raw4; + + sc = clknode_get_softc(clk); + + DEVICE_LOCK(clk); + READ4(clk, sc->base_offset, &raw1); + READ4(clk, sc->base_offset + 4, &raw2); + READ4(clk, sc->base_offset + 8, &raw3); + READ4(clk, sc->base_offset + 0xC, &raw4); + DEVICE_UNLOCK(clk); + + fbdiv = (raw1 & RK3399_CLK_PLL_FBDIV_MASK) >> RK3399_CLK_PLL_FBDIV_SHIFT; + + postdiv1 = (raw2 & RK3399_CLK_PLL_POSTDIV1_MASK) >> RK3399_CLK_PLL_POSTDIV1_SHIFT; + postdiv2 = (raw2 & RK3399_CLK_PLL_POSTDIV2_MASK) >> RK3399_CLK_PLL_POSTDIV2_SHIFT; + refdiv = (raw2 & RK3399_CLK_PLL_REFDIV_MASK) >> RK3399_CLK_PLL_REFDIV_SHIFT; + + frac = (raw3 & RK3399_CLK_PLL_FRAC_MASK) >> RK3399_CLK_PLL_FRAC_SHIFT; + + dsmpd = (raw4 & RK3399_CLK_PLL_DSMPD_MASK) >> RK3399_CLK_PLL_DSMPD_SHIFT; + + rate = *freq * fbdiv / refdiv; + if (dsmpd == 0) { + /* Fractional mode */ + uint64_t frac_rate; + + frac_rate = *freq * frac / refdiv; + rate += frac_rate >> 24; + } + + *freq = rate / postdiv1 / postdiv2; + + if (*freq % 2) + *freq = *freq + 1; + + return (0); +} + +static int +rk3399_clk_pll_set_freq(struct clknode *clk, uint64_t fparent, uint64_t *fout, + int flags, int *stop) +{ + struct rk_clk_pll_rate *rates; + struct rk_clk_pll_sc *sc; + uint32_t reg; + int timeout; + + sc = clknode_get_softc(clk); + + if (sc->rates) + rates = sc->rates; + else if (sc->frac_rates) + rates = sc->frac_rates; + else + return (EINVAL); + + for (; rates->freq; rates++) { + if (rates->freq == *fout) + break; + } + if (rates->freq == 0) { + *stop = 1; + return (EINVAL); + } + + DEVICE_LOCK(clk); + + /* Setting fbdiv */ + READ4(clk, sc->base_offset, ®); + reg &= ~RK3399_CLK_PLL_FBDIV_MASK; + reg |= rates->fbdiv << RK3399_CLK_PLL_FBDIV_SHIFT; + WRITE4(clk, sc->base_offset, reg | RK3399_CLK_PLL_WRITE_MASK); + + /* Setting postdiv1, postdiv2 and refdiv */ + READ4(clk, sc->base_offset + 0x4, ®); + reg &= ~(RK3399_CLK_PLL_POSTDIV1_MASK | RK3399_CLK_PLL_POSTDIV2_MASK | + RK3399_CLK_PLL_REFDIV_MASK); + reg |= rates->postdiv1 << RK3399_CLK_PLL_POSTDIV1_SHIFT; + reg |= rates->postdiv2 << RK3399_CLK_PLL_POSTDIV2_SHIFT; + reg |= rates->refdiv << RK3399_CLK_PLL_REFDIV_SHIFT; + WRITE4(clk, sc->base_offset + 0x4, reg | RK3399_CLK_PLL_WRITE_MASK); + + /* Setting frac */ + READ4(clk, sc->base_offset + 0x8, ®); + reg &= ~RK3399_CLK_PLL_FRAC_MASK; + reg |= rates->frac << RK3399_CLK_PLL_FRAC_SHIFT; + WRITE4(clk, sc->base_offset + 0x8, reg | RK3399_CLK_PLL_WRITE_MASK); + + /* Setting to normal mode and dsmpd */ + READ4(clk, sc->base_offset + 0xC, ®); + reg &= ~RK3399_CLK_PLL_MODE_MASK; + reg |= RK3399_CLK_PLL_MODE_NORMAL << RK3399_CLK_PLL_MODE_SHIFT; + reg |= rates->dsmpd << RK3399_CLK_PLL_DSMPD_SHIFT; + WRITE4(clk, sc->base_offset + 0xC, reg | RK3399_CLK_PLL_WRITE_MASK); + + /* Reading lock */ + for (timeout = 1000; timeout; timeout--) { + READ4(clk, sc->base_offset + RK3399_CLK_PLL_LOCK_OFFSET, ®); + if ((reg & RK3399_CLK_PLL_LOCK_MASK) == 0) + break; + DELAY(1); + } + + DEVICE_UNLOCK(clk); + + *stop = 1; + return (0); +} + +static clknode_method_t rk3399_clk_pll_clknode_methods[] = { + /* Device interface */ + CLKNODEMETHOD(clknode_init, rk3399_clk_pll_init), + CLKNODEMETHOD(clknode_set_gate, rk_clk_pll_set_gate), + CLKNODEMETHOD(clknode_recalc_freq, rk3399_clk_pll_recalc), + CLKNODEMETHOD(clknode_set_freq, rk3399_clk_pll_set_freq), + CLKNODEMETHOD_END +}; + +DEFINE_CLASS_1(rk3399_clk_pll_clknode, rk3399_clk_pll_clknode_class, + rk3399_clk_pll_clknode_methods, sizeof(struct rk_clk_pll_sc), clknode_class); + +int +rk3399_clk_pll_register(struct clkdom *clkdom, struct rk_clk_pll_def *clkdef) +{ + struct clknode *clk; + struct rk_clk_pll_sc *sc; + + clk = clknode_create(clkdom, &rk3399_clk_pll_clknode_class, &clkdef->clkdef); if (clk == NULL) return (1); Modified: head/sys/arm64/rockchip/clk/rk_clk_pll.h ============================================================================== --- head/sys/arm64/rockchip/clk/rk_clk_pll.h Sat Dec 1 18:23:41 2018 (r341380) +++ head/sys/arm64/rockchip/clk/rk_clk_pll.h Sat Dec 1 20:26:59 2018 (r341381) @@ -63,6 +63,7 @@ struct rk_clk_pll_def { #define RK_CLK_PLL_MASK 0xFFFF0000 -int rk_clk_pll_register(struct clkdom *clkdom, struct rk_clk_pll_def *clkdef); +int rk3328_clk_pll_register(struct clkdom *clkdom, struct rk_clk_pll_def *clkdef); +int rk3399_clk_pll_register(struct clkdom *clkdom, struct rk_clk_pll_def *clkdef); #endif /* _RK_CLK_PLL_H_ */ Modified: head/sys/arm64/rockchip/clk/rk_cru.c ============================================================================== --- head/sys/arm64/rockchip/clk/rk_cru.c Sat Dec 1 18:23:41 2018 (r341380) +++ head/sys/arm64/rockchip/clk/rk_cru.c Sat Dec 1 20:26:59 2018 (r341381) @@ -220,8 +220,11 @@ rk_cru_attach(device_t dev) switch (sc->clks[i].type) { case RK_CLK_UNDEFINED: break; - case RK_CLK_PLL: - rk_clk_pll_register(sc->clkdom, sc->clks[i].clk.pll); + case RK3328_CLK_PLL: + rk3328_clk_pll_register(sc->clkdom, sc->clks[i].clk.pll); + break; + case RK3399_CLK_PLL: + rk3399_clk_pll_register(sc->clkdom, sc->clks[i].clk.pll); break; case RK_CLK_COMPOSITE: rk_clk_composite_register(sc->clkdom, Modified: head/sys/arm64/rockchip/clk/rk_cru.h ============================================================================== --- head/sys/arm64/rockchip/clk/rk_cru.h Sat Dec 1 18:23:41 2018 (r341380) +++ head/sys/arm64/rockchip/clk/rk_cru.h Sat Dec 1 20:26:59 2018 (r341381) @@ -61,7 +61,8 @@ struct rk_cru_gate { enum rk_clk_type { RK_CLK_UNDEFINED = 0, - RK_CLK_PLL, + RK3328_CLK_PLL, + RK3399_CLK_PLL, RK_CLK_COMPOSITE, RK_CLK_MUX, RK_CLK_ARMCLK,