From: Avon Robertson Subject: Re: scmi: hook up to cpu_* to get apm working To: tech@openbsd.org Date: Fri, 23 May 2025 20:40:32 +1200 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