From owner-svn-src-all@freebsd.org Tue Apr 5 09:20:53 2016 Return-Path: Delivered-To: svn-src-all@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id DB95FB0248B; Tue, 5 Apr 2016 09:20:53 +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 mx1.freebsd.org (Postfix) with ESMTPS id B6AE21AF9; Tue, 5 Apr 2016 09:20:53 +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 u359Kq7A033812; Tue, 5 Apr 2016 09:20:52 GMT (envelope-from mmel@FreeBSD.org) Received: (from mmel@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id u359Kqr6033809; Tue, 5 Apr 2016 09:20:52 GMT (envelope-from mmel@FreeBSD.org) Message-Id: <201604050920.u359Kqr6033809@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: mmel set sender to mmel@FreeBSD.org using -f From: Michal Meloun Date: Tue, 5 Apr 2016 09:20:52 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r297576 - head/sys/arm/nvidia/tegra124 X-SVN-Group: head 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.21 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: Tue, 05 Apr 2016 09:20:54 -0000 Author: mmel Date: Tue Apr 5 09:20:52 2016 New Revision: 297576 URL: https://svnweb.freebsd.org/changeset/base/297576 Log: TEGRA: Fix CPU frequency switching. The PLL_X, base CPU frequency source, doesn't have a bypass switch and thus we must use another frequency source for CPU while changing its frequency. PLL_P is ideal for this, it runs at 480MHz and CPU can be clocked at this frequency at any CPU voltage. Modified: head/sys/arm/nvidia/tegra124/tegra124_clk_pll.c head/sys/arm/nvidia/tegra124/tegra124_clk_super.c head/sys/arm/nvidia/tegra124/tegra124_cpufreq.c Modified: head/sys/arm/nvidia/tegra124/tegra124_clk_pll.c ============================================================================== --- head/sys/arm/nvidia/tegra124/tegra124_clk_pll.c Tue Apr 5 08:37:21 2016 (r297575) +++ head/sys/arm/nvidia/tegra124/tegra124_clk_pll.c Tue Apr 5 09:20:52 2016 (r297576) @@ -823,12 +823,10 @@ pllx_set_freq(struct pll_sc *sc, uint64_ return (0); } - /* Set bypass. */ + /* PLLX doesn't have bypass, disable it first. */ RD4(sc, sc->base_reg, ®); - reg |= PLL_BASE_BYPASS; + reg &= ~PLL_BASE_ENABLE; WR4(sc, sc->base_reg, reg); - RD4(sc, sc->base_reg, ®); - DELAY(100); /* Set PLL. */ RD4(sc, sc->base_reg, ®); @@ -840,16 +838,16 @@ pllx_set_freq(struct pll_sc *sc, uint64_ RD4(sc, sc->base_reg, ®); DELAY(100); + /* Enable lock detection. */ + RD4(sc, sc->misc_reg, ®); + reg |= sc->lock_enable; + WR4(sc, sc->misc_reg, reg); + /* Enable PLL. */ RD4(sc, sc->base_reg, ®); reg |= PLL_BASE_ENABLE; WR4(sc, sc->base_reg, reg); - /* Enable lock detection */ - RD4(sc, sc->misc_reg, ®); - reg |= sc->lock_enable; - WR4(sc, sc->misc_reg, reg); - rv = wait_for_lock(sc); if (rv != 0) { /* Disable PLL */ @@ -860,10 +858,6 @@ pllx_set_freq(struct pll_sc *sc, uint64_ } RD4(sc, sc->misc_reg, ®); - /* Clear bypass. */ - RD4(sc, sc->base_reg, ®); - reg &= ~PLL_BASE_BYPASS; - WR4(sc, sc->base_reg, reg); *fout = ((fin / m) * n) / p; return (0); } Modified: head/sys/arm/nvidia/tegra124/tegra124_clk_super.c ============================================================================== --- head/sys/arm/nvidia/tegra124/tegra124_clk_super.c Tue Apr 5 08:37:21 2016 (r297575) +++ head/sys/arm/nvidia/tegra124/tegra124_clk_super.c Tue Apr 5 09:20:52 2016 (r297576) @@ -205,8 +205,7 @@ super_mux_set_mux(struct clknode *clk, i (state != SUPER_MUX_STATE_IDLE)) { panic("Unexpected super mux state: %u", state); } - - shift = state * SUPER_MUX_MUX_WIDTH; + shift = (state - 1) * SUPER_MUX_MUX_WIDTH; sc->mux = idx; if (sc->flags & SMF_HAVE_DIVIDER_2) { if (idx == sc->src_div2) { @@ -222,6 +221,7 @@ super_mux_set_mux(struct clknode *clk, i } reg &= ~(((1 << SUPER_MUX_MUX_WIDTH) - 1) << shift); reg |= idx << shift; + WR4(sc, sc->base_reg, reg); RD4(sc, sc->base_reg, &dummy); DEVICE_UNLOCK(sc); Modified: head/sys/arm/nvidia/tegra124/tegra124_cpufreq.c ============================================================================== --- head/sys/arm/nvidia/tegra124/tegra124_cpufreq.c Tue Apr 5 08:37:21 2016 (r297575) +++ head/sys/arm/nvidia/tegra124/tegra124_cpufreq.c Tue Apr 5 09:20:52 2016 (r297576) @@ -335,12 +335,27 @@ set_cpu_freq(struct tegra124_cpufreq_sof if (rv != 0) return (rv); } - rv = clk_set_freq(sc->clk_cpu_g, point->freq, CLK_SET_ROUND_DOWN); + + /* Switch supermux to PLLP first */ + rv = clk_set_parent_by_clk(sc->clk_cpu_g, sc->clk_pll_p); + if (rv != 0) { + device_printf(sc->dev, "Can't set parent to PLLP\n"); + return (rv); + } + + /* Set PLLX frequency */ + rv = clk_set_freq(sc->clk_pll_x, point->freq, CLK_SET_ROUND_DOWN); if (rv != 0) { device_printf(sc->dev, "Can't set CPU clock frequency\n"); return (rv); } + rv = clk_set_parent_by_clk(sc->clk_cpu_g, sc->clk_pll_x); + if (rv != 0) { + device_printf(sc->dev, "Can't set parent to PLLX\n"); + return (rv); + } + if (sc->act_speed_point->uvolt > point->uvolt) { /* set cpu voltage */ rv = regulator_set_voltage(sc->supply_vdd_cpu,