For some applications, we need to reduce the CPU Frequency, but if you are not familiar with our BSP or our devices probably you need some help to do some configurations.
In this post, I will share the configuration to set up lower frequencies (100MHz, 200MHz, 400Mhz, 600MHz, 800MHz, and 1000MHz) on iMX8MP, iMX8MN, and iMX8MM.
Note: Works on Kernel 6.1.xx (not tested on oldest BSP)
1- We have to modify the PLL driver to set the proper parameters to lower frequencies.
The file to modify is "clk-pll14xx.c" adding the following lines:
https://github.com/nxp-imx/linux-imx/blob/770c5fe2c1d1529fae21b7043911cd50c6cf087e/drivers/clk/imx/clk-pll14xx.c#L57
static const struct imx_pll14xx_rate_table imx_pll1416x_tbl[] = {
PLL_1416X_RATE(1800000000U, 225, 3, 0),
PLL_1416X_RATE(1600000000U, 200, 3, 0),
PLL_1416X_RATE(1500000000U, 375, 3, 1),
PLL_1416X_RATE(1400000000U, 350, 3, 1),
PLL_1416X_RATE(1200000000U, 300, 3, 1),
PLL_1416X_RATE(1000000000U, 250, 3, 1),
PLL_1416X_RATE(800000000U, 200, 3, 1),
PLL_1416X_RATE(750000000U, 250, 2, 2),
PLL_1416X_RATE(700000000U, 350, 3, 2),
PLL_1416X_RATE(600000000U, 300, 3, 2),
+ PLL_1416X_RATE(400000000U, 200, 3, 2),
+ PLL_1416X_RATE(200000000U, 200, 3, 3),
+ PLL_1416X_RATE(100000000U, 200, 3, 4),
};
2- Once the pll driver has been modified, only we have to add the values on the opp-table according to the device that you will use.
2.1- For iMX 8MP:
https://github.com/nxp-imx/linux-imx/blob/lf-6.1.y/arch/arm64/boot/dts/freescale/imx8mp.dtsi
a53_opp_table: opp-table {
compatible = "operating-points-v2";
opp-shared;
+ opp-100000000 {
+ opp-hz = /bits/ 64 <100000000>;
+ opp-microvolt = <850000>;
+ opp-supported-hw = <0x8a0>, <0x7>;
+ clock-latency-ns = <150000>;
+ opp-suspend;
+ };
+ opp-200000000 {
+ opp-hz = /bits/ 64 <200000000>;
+ opp-microvolt = <850000>;
+ opp-supported-hw = <0x8a0>, <0x7>;
+ clock-latency-ns = <150000>;
+ opp-suspend;
+ };
+ opp-400000000 {
+ opp-hz = /bits/ 64 <400000000>;
+ opp-microvolt = <850000>;
+ opp-supported-hw = <0x8a0>, <0x7>;
+ clock-latency-ns = <150000>;
+ opp-suspend;
+ };
+ opp-600000000 {
+ opp-hz = /bits/ 64 <600000000>;
+ opp-microvolt = <850000>;
+ opp-supported-hw = <0x8a0>, <0x7>;
+ clock-latency-ns = <150000>;
+ opp-suspend;
+ };
+ opp-800000000 {
+ opp-hz = /bits/ 64 <800000000>;
+ opp-microvolt = <850000>;
+ opp-supported-hw = <0x8a0>, <0x7>;
+ clock-latency-ns = <150000>;
+ opp-suspend;
+ };
+ opp-1000000000 {
+ opp-hz = /bits/ 64 <1000000000>;
+ opp-microvolt = <850000>;
+ opp-supported-hw = <0x8a0>, <0x7>;
+ clock-latency-ns = <150000>;
+ opp-suspend;
+ };
opp-1200000000 {
opp-hz = /bits/ 64 <1200000000>;
2.2 For iMX8MM:
https://github.com/nxp-imx/linux-imx/blob/lf-6.1.y/arch/arm64/boot/dts/freescale/imx8mm.dtsi
a53_opp_table:
opp-table {
compatible = "operating-points-v2";
opp-shared;
+ opp-100000000 {
+ opp-hz = /bits/ 64 <100000000>;
+ opp-microvolt = <850000>;
+ opp-supported-hw = <0xe>, <0x7>;
+ clock-latency-ns = <150000>;
+ opp-suspend;
+ };
+ opp-200000000 {
+ opp-hz = /bits/ 64 <200000000>;
+ opp-microvolt = <850000>;
+ opp-supported-hw = <0xe>, <0x7>;
+ clock-latency-ns = <150000>;
+ opp-suspend;
+ };
+ opp-400000000 {
+ opp-hz = /bits/ 64 <400000000>;
+ opp-microvolt = <850000>;
+ opp-supported-hw = <0xe>, <0x7>;
+ clock-latency-ns = <150000>;
+ opp-suspend;
+ };
+ opp-600000000 {
+ opp-hz = /bits/ 64 <600000000>;
+ opp-microvolt = <850000>;
+ opp-supported-hw = <0xe>, <0x7>;
+ clock-latency-ns = <150000>;
+ opp-suspend;
+ };
+ opp-800000000 {
+ opp-hz = /bits/ 64 <800000000>;
+ opp-microvolt = <850000>;
+ opp-supported-hw = <0xe>, <0x7>;
+ clock-latency-ns = <150000>;
+ opp-suspend;
+ };
+ opp-1000000000 {
+ opp-hz = /bits/ 64 <1000000000>;
+ opp-microvolt = <850000>;
+ opp-supported-hw = <0xe>, <0x7>;
+ clock-latency-ns = <150000>;
+ opp-suspend;
+ };
opp-1200000000 {
opp-hz = /bits/ 64 <1200000000>;
2.3- For iMX8MN:
https://github.com/nxp-imx/linux-imx/blob/lf-6.1.y/arch/arm64/boot/dts/freescale/imx8mn.dtsi
compatible = "operating-points-v2";
opp-shared;
+ opp-100000000 {
+ opp-hz = /bits/ 64 <100000000>;
+ opp-microvolt = <850000>;
+ opp-supported-hw = <0xb00>, <0x7>;
+ clock-latency-ns = <150000>;
+ opp-suspend;
+ };
+
+ opp-200000000 {
+ opp-hz = /bits/ 64 <200000000>;
+ opp-microvolt = <850000>;
+ opp-supported-hw = <0xb00>, <0x7>;
+ clock-latency-ns = <150000>;
+ opp-suspend;
+ };
+
+ opp-400000000 {
+ opp-hz = /bits/ 64 <400000000>;
+ opp-microvolt = <850000>;
+ opp-supported-hw = <0xb00>, <0x7>;
+ clock-latency-ns = <150000>;
+ opp-suspend;
+ };
+
+ opp-600000000 {
+ opp-hz = /bits/ 64 <600000000>;
+ opp-microvolt = <850000>;
+ opp-supported-hw = <0xb00>, <0x7>;
+ clock-latency-ns = <150000>;
+ opp-suspend;
+ };
+
+ opp-800000000 {
+ opp-hz = /bits/ 64 <800000000>;
+ opp-microvolt = <850000>;
+ opp-supported-hw = <0xb00>, <0x7>;
+ clock-latency-ns = <150000>;
+ opp-suspend;
+ };
+
+ opp-1000000000 {
+ opp-hz = /bits/ 64 <1000000000>;
+ opp-microvolt = <850000>;
+ opp-supported-hw = <0xb00>, <0x7>;
+ clock-latency-ns = <150000>;
+ opp-suspend;
+ };
+
opp-1200000000 {
opp-hz = /bits/ 64 <1200000000>;
opp-microvolt = <850000>;
After that, you should note the changes under Linux.
These commands return information about the system and the current settings.
• The kernel is pre-configured to support only certain frequencies. The list of frequencies currently supported
can be obtained from:
cat /sys/devices/system/cpu/cpu0/cpufreq/scaling_available_frequencies
• To get the available scaling governors:
cat /sys/devices/system/cpu/*/cpufreq/scaling_available_governors
• To check the current CPU frequency:
cat /sys/devices/system/cpu/*/cpufreq/cpuinfo_cur_freq
The frequency is displayed depending on the governor set.
• To check the maximum frequency:
cat /sys/devices/system/cpu/*/cpufreq/cpuinfo_max_freq
• To check the minimum frequency:
cat /sys/devices/system/cpu/*/cpufreq/cpuinfo_min_freq
These commands set a constant CPU frequency:
• Use the maximum frequency:
echo performance > /sys/devices/system/cpu/cpu0/cpufreq/scaling_governor
• Use the current frequency to be the constant frequency:
echo userspace > /sys/devices/system/cpu/cpu0/cpufreq/scaling_governor
• The following two commands set the scaling governor to a specified frequency, if that frequency is supported.
If the frequency is not supported, the closest supported frequency is used:
echo userspace > /sys/devices/system/cpu/cpu0/cpufreq/scaling_governor
echo <frequency> > /sys/devices/system/cpu/cpu0/cpufreq/scaling_setspeed
View full article