How can i change the core frequency on iMX7S module?


I would like to experiment with lowering the current consumption by reducing core frequency lower than the default 800Mhz. What would be the correct way for doing this?


You can do it through sys fs. Please see details here -


This is what i get:

cpufrequtils 008: cpufreq-info (C) Dominik Brodowski 2004-2009
Report errors and bugs to, please.
analyzing CPU 0:
  driver: imx7d-cpufreq
  CPUs which run at the same hardware frequency: 0
  CPUs which need to have their frequency coordinated by software: 0
  maximum transition latency: 61.0 us.
  hardware limits: 792 MHz - 996 MHz
  available frequency steps: 792 MHz, 996 MHz
  available cpufreq governors: conservative, ondemand, userspace, powersave, interactive, performance
  current policy: frequency should be within 792 MHz and 996 MHz.
                  The governor "interactive" may decide which speed to use
                  within this range.
  current CPU frequency is 792 MHz (asserted by call to hardware).
  cpufreq stats: 792 MHz:99.99%, 996 MHz:0.01%  (32)

I am using iMX7S so the highst for it, according to the spec is 800MHz and not 1GHz as shown.
The thing is that with the current build configuration there is no way of runing the core with lower than 800MHz as there are only two OPPs defined…
My question is which additional OPPs i can add , safely , during kernel build to be able to change the frequency later, using sys fs as suggested.

The frequency operating points are specified in the device tree. Currently we only switch between 800MHz and 1GHz on Colibri iMX7D and stay at fixed 800 MHz for Colibri iMX7S (since the chip is only validated up to 800MHz). However, looking at the current device tree it actually turns out that we specify the operating points in the i.MX 7Solo SoC device tree at arch/arm/boot/dts/imx7s.dtsi. So the current BSP clocks the CPU outside of the official clock range. I will create a ticket and fix that in the next release.

Note also that the Colibri iMX7S is not capable to change voltage on the VDD_ARM rail separately. But the i.MX 7Solo data sheet anyway only specifies one voltage at 800MHz or below, so when running within specs you can’t lower the voltage anyway. However. Lowering the CPU clock should be fine. A quick test with 400MHz seems to work:

		operating-points = <
			/* KHz	uV */
			792000	975000
			396000	975000

(due to PLL limitations the clock tree seems to choose 324MHz)

However, the usefulness of such an operation point is somewhat limited: Under load my measurements showed a difference of only 64mW (612-676mW). And in idle it did not make any difference. The reason for that is the i.MX 7 actually has a mode which automatically power gates most of the CPU (referred as System IDLE in the data sheet).

Furthermore there is bus frequency scaling which only triggers if all drivers which require higher bus speeds are idle. You have to disable display (set dcu to disabled) and shut down ethernet (e.g. systemctl stop connman) so that the driver can scale the bus frequency. With that I measure idle power consumption of 142mW!

Hi Stephan,

Thank you for the detailed response!
I just want to make sure i got this right. If i add another OPP (400MHz for example) and disable ethernet, then the bus scaler should choose the lower frequency? I am using the console image, do i still nee to disable the display?


The bus frequency scaling is outside of CPU frequency scaling, so you don’t have to add additional operating points… In fact, due to the power gating of the core in idle state, additional operating points only make sense if you try to lower power consumption under load.

Yes, even in the console image the framebuffer/display is active. You have to disable the display in the device tree. Also make sure you disconnect Ethernet. If you measure power, you should see a massive drop in power usage once the system is idle.