svn commit: r350823 - stable/12/sys/dev/cpufreq
Michal Meloun
mmel at FreeBSD.org
Fri Aug 9 11:21:43 UTC 2019
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 at 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) {
More information about the svn-src-stable-12
mailing list