Date: Fri, 9 Aug 2019 11:21:42 +0000 (UTC) From: Michal Meloun <mmel@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: r350823 - stable/12/sys/dev/cpufreq Message-ID: <201908091121.x79BLgVq013320@repo.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: mmel Date: Fri Aug 9 11:21:42 2019 New Revision: 350823 URL: https://svnweb.freebsd.org/changeset/base/350823 Log: MFC r345297: 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. Modified: stable/12/sys/dev/cpufreq/cpufreq_dt.c Directory Properties: stable/12/ (props changed) Modified: stable/12/sys/dev/cpufreq/cpufreq_dt.c ============================================================================== --- stable/12/sys/dev/cpufreq/cpufreq_dt.c Fri Aug 9 11:20:05 2019 (r350822) +++ stable/12/sys/dev/cpufreq/cpufreq_dt.c Fri Aug 9 11:21:42 2019 (r350823) @@ -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) {
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201908091121.x79BLgVq013320>