From owner-svn-src-head@freebsd.org Tue Mar 19 14:34:54 2019 Return-Path: Delivered-To: svn-src-head@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 BBA2B155277D; Tue, 19 Mar 2019 14:34:54 +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 58755878BD; Tue, 19 Mar 2019 14:34:54 +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 45729A912; Tue, 19 Mar 2019 14:34:54 +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 x2JEYsTS061195; Tue, 19 Mar 2019 14:34:54 GMT (envelope-from mmel@FreeBSD.org) Received: (from mmel@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id x2JEYsRQ061194; Tue, 19 Mar 2019 14:34:54 GMT (envelope-from mmel@FreeBSD.org) Message-Id: <201903191434.x2JEYsRQ061194@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: mmel set sender to mmel@FreeBSD.org using -f From: Michal Meloun Date: Tue, 19 Mar 2019 14:34:54 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r345297 - head/sys/dev/cpufreq X-SVN-Group: head X-SVN-Commit-Author: mmel X-SVN-Commit-Paths: head/sys/dev/cpufreq X-SVN-Commit-Revision: 345297 X-SVN-Commit-Repository: base MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-Rspamd-Queue-Id: 58755878BD X-Spamd-Bar: -- Authentication-Results: mx1.freebsd.org X-Spamd-Result: default: False [-2.94 / 15.00]; local_wl_from(0.00)[FreeBSD.org]; NEURAL_HAM_SHORT(-0.94)[-0.943,0]; ASN(0.00)[asn:11403, ipnet:2610:1c1:1::/48, country:US]; NEURAL_HAM_MEDIUM(-1.00)[-0.998,0]; NEURAL_HAM_LONG(-1.00)[-1.000,0] X-BeenThere: svn-src-head@freebsd.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: SVN commit messages for the src tree for head/-current List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 19 Mar 2019 14:34:55 -0000 Author: mmel Date: Tue Mar 19 14:34:53 2019 New Revision: 345297 URL: https://svnweb.freebsd.org/changeset/base/345297 Log: Improve cpufreq_dt. - older DT can use 'cpu0-supply' property for power supply binding. - don't expect that actual CPU frequency is contained in CPU operational point table, but read current CPU voltage directly from reguator. Typically, u-boot can set starting CPU frequency to any value. MFC after: 2 weeks Modified: head/sys/dev/cpufreq/cpufreq_dt.c Modified: head/sys/dev/cpufreq/cpufreq_dt.c ============================================================================== --- head/sys/dev/cpufreq/cpufreq_dt.c Tue Mar 19 14:32:54 2019 (r345296) +++ head/sys/dev/cpufreq/cpufreq_dt.c Tue Mar 19 14:34:53 2019 (r345297) @@ -166,7 +166,7 @@ cpufreq_dt_set(device_t dev, const struct cf_setting * struct cpufreq_dt_softc *sc; const struct cpufreq_dt_opp *opp, *copp; uint64_t freq; - int error = 0; + int uvolt, error; sc = device_get_softc(dev); @@ -174,23 +174,38 @@ cpufreq_dt_set(device_t dev, const struct cf_setting * device_printf(dev, "Can't get current clk freq\n"); return (ENXIO); } + /* Try to get current valtage by using regulator first. */ + error = regulator_get_voltage(sc->reg, &uvolt); + if (error != 0) { + /* + * Try oppoints table as backup way. However, + * this is insufficient because the actual processor + * frequency may not be in the table. PLL frequency + * granularity can be different that granularity of + * oppoint table. + */ + copp = cpufreq_dt_find_opp(sc->dev, freq); + if (copp == NULL) { + device_printf(dev, + "Can't find the current freq in opp\n"); + return (ENOENT); + } + uvolt = copp->uvolt_target; - DEBUG(sc->dev, "Current freq %ju\n", freq); - DEBUG(sc->dev, "Target freq %ju\n", (uint64_t)set->freq * 1000000); - copp = cpufreq_dt_find_opp(sc->dev, freq); - if (copp == NULL) { - device_printf(dev, "Can't find the current freq in opp\n"); - return (ENOENT); } + opp = cpufreq_dt_find_opp(sc->dev, set->freq * 1000000); if (opp == NULL) { device_printf(dev, "Couldn't find an opp for this freq\n"); return (EINVAL); } + DEBUG(sc->dev, "Current freq %ju, uvolt: %d\n", freq, uvolt); + DEBUG(sc->dev, "Target freq %ju, , uvolt: %d\n", + opp->freq, opp->uvolt_target); - if (copp->uvolt_target < opp->uvolt_target) { + if (uvolt < opp->uvolt_target) { DEBUG(dev, "Changing regulator from %u to %u\n", - copp->uvolt_target, opp->uvolt_target); + uvolt, opp->uvolt_target); error = regulator_set_voltage(sc->reg, opp->uvolt_min, opp->uvolt_max); @@ -201,7 +216,7 @@ cpufreq_dt_set(device_t dev, const struct cf_setting * } DEBUG(dev, "Setting clk to %ju\n", opp->freq); - error = clk_set_freq(sc->clk, opp->freq, 0); + error = clk_set_freq(sc->clk, opp->freq, CLK_SET_ROUND_DOWN); if (error != 0) { DEBUG(dev, "Failed, backout\n"); /* Restore previous voltage (best effort) */ @@ -211,7 +226,9 @@ cpufreq_dt_set(device_t dev, const struct cf_setting * return (ENXIO); } - if (copp->uvolt_target > opp->uvolt_target) { + if (uvolt > opp->uvolt_target) { + DEBUG(dev, "Changing regulator from %u to %u\n", + uvolt, opp->uvolt_target); error = regulator_set_voltage(sc->reg, opp->uvolt_min, opp->uvolt_max); @@ -219,8 +236,7 @@ cpufreq_dt_set(device_t dev, const struct cf_setting * DEBUG(dev, "Failed to switch regulator to %d\n", opp->uvolt_target); /* Restore previous CPU frequency (best effort) */ - (void)clk_set_freq(sc->clk, - copp->freq, 0); + (void)clk_set_freq(sc->clk, copp->freq, 0); return (ENXIO); } } @@ -277,7 +293,8 @@ cpufreq_dt_identify(driver_t *driver, device_t parent) /* The cpu@0 node must have the following properties */ if (!OF_hasprop(node, "clocks") || - !OF_hasprop(node, "cpu-supply")) + (!OF_hasprop(node, "cpu-supply") && + !OF_hasprop(node, "cpu0-supply"))) return; if (!OF_hasprop(node, "operating-points") && @@ -299,7 +316,9 @@ cpufreq_dt_probe(device_t dev) node = ofw_bus_get_node(device_get_parent(dev)); if (!OF_hasprop(node, "clocks") || - !OF_hasprop(node, "cpu-supply")) + (!OF_hasprop(node, "cpu-supply") && + !OF_hasprop(node, "cpu0-supply"))) + return (ENXIO); if (!OF_hasprop(node, "operating-points") && @@ -439,9 +458,12 @@ cpufreq_dt_attach(device_t dev) if (regulator_get_by_ofw_property(dev, node, "cpu-supply", &sc->reg) != 0) { - device_printf(dev, "no regulator for %s\n", - ofw_bus_get_name(device_get_parent(dev))); - return (ENXIO); + if (regulator_get_by_ofw_property(dev, node, + "cpu0-supply", &sc->reg) != 0) { + device_printf(dev, "no regulator for %s\n", + ofw_bus_get_name(device_get_parent(dev))); + return (ENXIO); + } } if (clk_get_by_ofw_index(dev, node, 0, &sc->clk) != 0) {