Download raw body.
scmi: hook up to cpu_* to get apm working
Hello Tobias, please see below.
On Thu, May 22, 2025 at 07:16:17AM +0200, Tobias Heider wrote:
> On Snapdragon X Elite chips we have to use ARM SCMI to control cpu performance.
> Our driver now supports reading the current performance level, translating
> it to HZ and exporting it as a sensor as well as setting initial levels.
>
> I think it is time to hook everything up to cpu_setperf and cpu_clockspeed to
> make those controls available to apm and hw.setperf.
> Loosely inspired by aplcpu which deals with a similar problem on Apple machines.
>
> ok? test feedback?
>
> Index: scmi.c
> ===================================================================
> RCS file: /cvs/src/sys/dev/fdt/scmi.c,v
> diff -u -p -r1.3 scmi.c
> --- scmi.c 22 May 2025 03:04:01 -0000 1.3
> +++ scmi.c 22 May 2025 03:37:38 -0000
> @@ -484,6 +484,9 @@ int scmi_perf_level_get(struct scmi_soft
> int scmi_perf_level_set(struct scmi_softc *, int, int);
> void scmi_perf_refresh_sensor(void *);
>
> +int scmi_perf_cpuspeed(int *);
> +void scmi_perf_cpusetperf(int);
> +
> void
> scmi_attach_perf(struct scmi_softc *sc, int node)
> {
> @@ -558,6 +561,10 @@ scmi_attach_perf(struct scmi_softc *sc,
> }
> sensordev_install(&sc->sc_perf_sensordev);
> sensor_task_register(sc, scmi_perf_refresh_sensor, 1);
> +
> + cpu_setperf = scmi_perf_cpusetperf;
> + cpu_cpuspeed = scmi_perf_cpuspeed;
A
> +
> return;
> err:
> free(sc->sc_perf_fsensors, M_DEVBUF,
> @@ -647,6 +654,63 @@ scmi_perf_level_set(struct scmi_softc *s
> return -1;
> }
> return 0;
> +}
> +
> +int
> +scmi_perf_cpuspeed(int *freq)
> +{
> + struct scmi_softc *sc;
> + int i, level = -1;
> + uint64_t opp_hz = 0;
> +
> + for (i = 0; i < scmi_cd.cd_ndevs; i++) {
> + sc = scmi_cd.cd_devs[i];
> + if (sc == NULL)
> + continue;
> +
> + if (sc->sc_perf_domains == NULL)
> + continue;
> +
> + for (i = 0; i < sc->sc_perf_ndomains; i++) {
> + if (sc->sc_perf_domains[i].pd_levels == NULL)
> + return EINVAL;
> +
> + level = scmi_perf_level_get(sc, i);
> + opp_hz = MAX(opp_hz, (uint64_t)sc->sc_perf_domains[i].
> + pd_levels[level].pl_ifreq * 1000);
> + }
> + }
> +
> + if (opp_hz == 0)
> + return EINVAL;
> +
> + *freq = opp_hz / 1000000;
> + return 0;
> +}
> +
> +void
> +scmi_perf_cpusetperf(int level)
> +{
> + struct scmi_softc *sc;
> + size_t nlevels;
> + int i;
> +
> + for (i = 0; i < scmi_cd.cd_ndevs; i++) {
> + sc = scmi_cd.cd_devs[i];
> + if (sc == NULL)
> + return;
> + if (sc->sc_perf_domains == NULL)
> + continue;
> +
> + /* Find number of levels per domain */
> + for (i = 0; i < sc->sc_perf_ndomains; i++) {
> + nlevels = sc->sc_perf_domains[i].pd_nlevels;
> + if (nlevels == 0)
> + continue;
> + scmi_perf_level_set(sc, i,
> + (level * (nlevels - 1) / 100));
> + }
> + }
> }
>
> void
>
The below information was captured from an ASUS Vivobook S 15
S5507QA_S5507QAD.
Before patch applied.
$ sysctl kern.version
kern.version=OpenBSD 7.7-current (GENERIC.MP) #382: Wed May 21 02:40:23 MDT 2025
deraadt@arm64.openbsd.org:/usr/src/sys/arch/arm64/compile/GENERIC.MP
$ sysctl hw.sensors | tail -n 6
hw.sensors.scmi0.power0=0.23 W
hw.sensors.scmi0.power1=0.33 W
hw.sensors.scmi0.power2=0.36 W
hw.sensors.scmi0.frequency0=2976000000.00 Hz
hw.sensors.scmi0.frequency1=3417600000.00 Hz
hw.sensors.scmi0.frequency2=3417600000.00 Hz
$ sysctl hw.cpuspeed
sysctl: hw.cpuspeed: value is not available
$ sysctl hw.setperf
sysctl: hw.setperf: value is not available
$ sysctl hw.perfpolicy
sysctl: hw.perfpolicy: value is not available
After patch applied
$ sysctl kern.version
kern.version=OpenBSD 7.7-current (GENERIC.MP) #0: Fri May 23 12:32:09 NZST 2025
aer@lts15.xan.priv:/sys/arch/arm64/compile/GENERIC.MP
$ sysctl hw.sensors | tail -n 6
hw.sensors.scmi0.power0=0.34 W
hw.sensors.scmi0.power1=0.33 W
hw.sensors.scmi0.power2=0.36 W
hw.sensors.scmi0.frequency0=3417600000.00 Hz
hw.sensors.scmi0.frequency1=3417600000.00 Hz
hw.sensors.scmi0.frequency2=3417600000.00 Hz
$ sysctl hw.cpuspeed
hw.cpuspeed=3417
$ sysctl hw.setperf
hw.setperf=100
$ sysctl hw.perfpolicy
hw.perfpolicy=high
This may be helpful to you too.
Guided by release(8) I also tried to build base without rebooting, and
after a 'halt -p / and a cold restart'. Both ended as shown at the
end of the following text that was captured from/in the tmux pane the
build was attempted.
The base build attempt was also perfomed as root.
rm -f a.out [Ee]rrs mklog *.core y.tab.h *.o *.out
===> regress/misc/exceptions
===> regress/misc/exceptions/simple
rm -f a.out [Ee]rrs mklog *.core y.tab.h exceptions exceptions.o exceptions.d
rm -f /usr/src/regress/misc/exceptions/simple/tags
===> regress/misc/exceptions/simple2
rm -f a.out [Ee]rrs mklog *.core y.tab.h simple2 simple2.o simple2.d
rm -f /usr/src/regress/misc/exceptions/simple2/tags
===> regress/misc/exceptions/libbar
rm -f a.out [Ee]rrs mklog *.core y.tab.h bar.d
rm -f libbar.a bar.o
rm -f libbar_g.a
rm -f libbar_p.a bar.po
rm -f libbar.so.*.* bar.so .ldadd
rm -f libbar_d.a bar.do
rm -f /usr/src/regress/misc/exceptions/libbar/tags
===> regress/misc/exceptions/foo
rm -f a.out [Ee]rrs mklog *.core y.tab.h foo foo.o foo.d
rm -f /usr/src/regress/misc/exceptions/foo/tags
===> regress/misc/exceptions/threads
rm -f a.out [Ee]rrs mklog *.core y.tab.h exceptions exceptions.o exceptions.d
rm -f /usr/src/regress/misc/exceptions/threads/tags
===> regress/misc/os-test
rm -f uname.out os-test.html
rm -rf io io.expect udp udp.expect
===> regress/misc/posixtestsuite
rm -f logfile *.log uname.out posixtestsuite.html
rm -rf conformance functional
===> regress/misc/sse2
===> regress/gnu
===> regress/gnu/egcs
===> regress/gnu/egcs/gcc-bounds
rm -f a.out [Ee]rrs mklog *.core y.tab.h
===> regress/gnu/egcs/gcc-builtins
rm -f a.out [Ee]rrs mklog *.core y.tab.h
===> regress/gnu/lib
===> regress/gnu/lib/libexecinfo
rm -f a.out [Ee]rrs mklog *.core y.tab.h t_backtrace t_backtrace.o atf-c.o t_backtrace.d atf-c.d
rm -f /usr/src/regress/gnu/lib/libexecinfo/tags
exec make includes
cd /usr/src/include && su build -c 'exec make prereq' && exec make includes
make: getcwd: Permission denied <<<<<<
*** Error 2 in . (Makefile:55 'includes')
*** Error 2 in . (Makefile:87 'do-build')
*** Error 2 in /usr/src (Makefile:74 'build')
lts15:/usr/src
# gtmuxpane /root/base_build.err
Note: there is no getcwd binary on this system.
--
aer
scmi: hook up to cpu_* to get apm working