How to reduce the i.MX8M Mini VPU frequency

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

How to reduce the i.MX8M Mini VPU frequency

1,388 Views
marioschuknecht
Contributor III

Hello,

To reduce power consumption, on a customer board based on i.MX8M Mini EVK board, the VPU frequency is to be reduced.

The data sheet https://www.nxp.com/docs/en/data-sheet/IMX8MMIEC.pdf table 9 lists 3 operating ranges for VDD_VPU with different voltage ranges and possible frequencies.

How can the i.MX8M Mini VPU frequency be reduced to 450MHz to enable the operating range 0.805 to 0.9V?

The NXP kernel 4.14.98 is used.

Can the VPU frequency be set at runtime, via device tree or in a kernel module?

Thanks in advance.

Mario

Labels (1)
0 Kudos
4 Replies

1,166 Views
weidong_sun
NXP TechSupport
NXP TechSupport

Hi Mario,

find fsl-imx8mm.dtsi file, and open it, you will find VPU node :

    vpu_h1: vpu_h1@38320000 {
        compatible = "nxp,imx8mm-hantro-h1";
        reg = <0x0 0x38320000 0x0 0x10000>;
        reg-names = "regs_hantro_h1";
        interrupts = <GIC_SPI 30 IRQ_TYPE_LEVEL_HIGH>;
        interrupt-names = "irq_hantro_h1";
        clocks = <&clk IMX8MM_CLK_VPU_H1_ROOT>, <&clk IMX8MM_CLK_VPU_DEC_ROOT>;
        clock-names = "clk_hantro_h1", "clk_hantro_h1_bus";
        assigned-clocks = <&clk IMX8MM_CLK_VPU_H1>,<&clk IMX8MM_CLK_VPU_BUS>;
        assigned-clock-parents = <&clk IMX8MM_VPU_PLL_OUT>, <&clk IMX8MM_SYS_PLL1_800M>;
        assigned-clock-rates = <600000000>, <800000000>;
        power-domains = <&vpu_h1_pd>;
        status = "disabled";
    };

    vpu_g1: vpu_g1@38300000 {
        compatible = "nxp,imx8mm-hantro";
        reg = <0x0 0x38300000 0x0 0x100000>;
        reg-names = "regs_hantro";
        interrupts = <GIC_SPI 7 IRQ_TYPE_LEVEL_HIGH>;
        interrupt-names = "irq_hantro";
        clocks = <&clk IMX8MM_CLK_VPU_G1_ROOT>, <&clk IMX8MM_CLK_VPU_DEC_ROOT>;
        clock-names = "clk_hantro", "clk_hantro_bus";
        assigned-clocks = <&clk IMX8MM_CLK_VPU_G1>, <&clk IMX8MM_CLK_VPU_BUS>;
        assigned-clock-parents = <&clk IMX8MM_VPU_PLL_OUT>, <&clk IMX8MM_SYS_PLL1_800M>;
        assigned-clock-rates = <600000000>, <800000000>;
        power-domains = <&vpu_g1_pd>;
        status = "disabled";
    };

    vpu_g2: vpu_g2@38310000 {
        compatible = "nxp,imx8mm-hantro";
        reg = <0x0 0x38310000 0x0 0x100000>;
        reg-names = "regs_hantro";
        interrupts = <GIC_SPI 8 IRQ_TYPE_LEVEL_HIGH>;
        interrupt-names = "irq_hantro";
        clocks = <&clk IMX8MM_CLK_VPU_G2_ROOT>, <&clk IMX8MM_CLK_VPU_DEC_ROOT>;
        clock-names = "clk_hantro", "clk_hantro_bus";
        assigned-clocks = <&clk IMX8MM_CLK_VPU_G2>, <&clk IMX8MM_CLK_VPU_BUS>;
        assigned-clock-parents = <&clk IMX8MM_VPU_PLL_OUT>, <&clk IMX8MM_SYS_PLL1_800M>;
        assigned-clock-rates = <600000000>, <800000000>;
        power-domains = <&vpu_g2_pd>;
        status = "disabled";
    };

600000000Hz is VPU frequency.

Have a nice day!

BR,

weidong

0 Kudos

1,166 Views
marioschuknecht
Contributor III

Hi Wigros,

thank you for the quick response.

I have changed the values as follows:

        vpu_h1: vpu_h1@38320000 {
                compatible = "nxp,imx8mm-hantro-h1";
                reg = <0x0 0x38320000 0x0 0x10000>;
                reg-names = "regs_hantro_h1";
                interrupts = <GIC_SPI 30 IRQ_TYPE_LEVEL_HIGH>;
                interrupt-names = "irq_hantro_h1";
                clocks = <&clk IMX8MM_CLK_VPU_H1_ROOT>, <&clk IMX8MM_CLK_VPU_DEC_ROOT>;
                clock-names = "clk_hantro_h1", "clk_hantro_h1_bus";
                assigned-clocks = <&clk IMX8MM_CLK_VPU_H1_SRC>,<&clk IMX8MM_CLK_VPU_BUS_SRC>;
                assigned-clock-parents = <&clk IMX8MM_VPU_PLL_OUT>, <&clk IMX8MM_SYS_PLL1_800M>;
                assigned-clock-rates = <450000000>, <800000000>;
                power-domains = <&vpu_h1_pd>;
                status = "disabled";
        };

        vpu_g1: vpu_g1@38300000 {
                compatible = "nxp,imx8mm-hantro";
                reg = <0x0 0x38300000 0x0 0x100000>;
                reg-names = "regs_hantro";
                interrupts = <GIC_SPI 7 IRQ_TYPE_LEVEL_HIGH>;
                interrupt-names = "irq_hantro";
                clocks = <&clk IMX8MM_CLK_VPU_G1_ROOT>, <&clk IMX8MM_CLK_VPU_DEC_ROOT>;
                clock-names = "clk_hantro", "clk_hantro_bus";
                assigned-clocks = <&clk IMX8MM_CLK_VPU_G1_SRC>, <&clk IMX8MM_CLK_VPU_BUS_SRC>;
                assigned-clock-parents = <&clk IMX8MM_VPU_PLL_OUT>, <&clk IMX8MM_SYS_PLL1_800M>;
                assigned-clock-rates = <450000000>, <800000000>;
                power-domains = <&vpu_g1_pd>;
                status = "disabled";
        };

        vpu_g2: vpu_g2@38310000 {
                compatible = "nxp,imx8mm-hantro";
                reg = <0x0 0x38310000 0x0 0x100000>;
                reg-names = "regs_hantro";
                interrupts = <GIC_SPI 8 IRQ_TYPE_LEVEL_HIGH>;
                interrupt-names = "irq_hantro";
                clocks = <&clk IMX8MM_CLK_VPU_G2_ROOT>, <&clk IMX8MM_CLK_VPU_DEC_ROOT>;
                clock-names = "clk_hantro", "clk_hantro_bus";
                assigned-clocks = <&clk IMX8MM_CLK_VPU_G2_SRC>, <&clk IMX8MM_CLK_VPU_BUS_SRC>;
                assigned-clock-parents = <&clk IMX8MM_VPU_PLL_OUT>, <&clk IMX8MM_SYS_PLL1_800M>;
                assigned-clock-rates = <450000000>, <800000000>;
                power-domains = <&vpu_g2_pd>;
                status = "disabled";
        };

And they are correctly present in the device tree:

# hexdump -C /proc/device-tree/vpu_h1\@38320000/assigned-clock-rates
00000000  1a d2 74 80 2f af 08 00                           |..t./...|
00000008
# hexdump -C /proc/device-tree/vpu_g1\@38300000/assigned-clock-rates
00000000  1a d2 74 80 2f af 08 00                           |..t./...|
00000008
# hexdump -C /proc/device-tree/vpu_g2\@38310000/assigned-clock-rates
00000000  1a d2 74 80 2f af 08 00                           |..t./...|
00000008

1a d2 74 80 --> 450 000 000

But the VPU frequency has not changed. It's still 600MHz.

# cat /sys/kernel/debug/clk/clk_summary | grep vpu
                   vpu_bus_src            0            0   800000000          0 0
                      vpu_bus_cg           0            0   800000000          0 0
                         vpu_bus_pre_div           0            0   800000000          0 0
                            vpu_bus_div           0            0   800000000          0 0
                               vpu_dec_root_clk           0            0   800000000          0 0
                vpu_src                   0            0  1200000000          0 0
                   vpu_cg                 0            0  1200000000          0 0
                      vpu_div             0            0  1200000000          0 0
    vpu_pll_ref_sel                       0            0    24000000          0 0
       vpu_pll                            0            0   600000000          0 0
          vpu_pll_bypass                  0            0   600000000          0 0
             vpu_pll_out                  0            0   600000000          0 0
                vpu_h1_src                0            0   600000000          0 0
                   vpu_h1_cg              0            0   600000000          0 0
                      vpu_h1_pre_div           0            0   600000000          0 0
                         vpu_h1_div           0            0   600000000          0 0
                            vpu_h1_root_clk           0            0   600000000          0 0
                vpu_g2_src                0            0   600000000          0 0
                   vpu_g2_cg              0            0   600000000          0 0
                      vpu_g2_pre_div           0            0   600000000          0 0
                         vpu_g2_div           0            0   600000000          0 0
                            vpu_g2_root_clk           0            0   600000000          0 0
                vpu_g1_src                0            0   600000000          0 0
                   vpu_g1_cg              0            0   600000000          0 0
                      vpu_g1_pre_div           0            0   600000000          0 0
                         vpu_g1_div           0            0   600000000          0 0
                            vpu_g1_root_clk           0            0   600000000          0 0

Any ideas?

0 Kudos

1,166 Views
weidong_sun
NXP TechSupport
NXP TechSupport

try this seting, please!

....

assigned-clocks = <&clk IMX8MM_VPU_PLL_OUT>,<&clk IMX8MM_CLK_VPU_H1>,<&clk IMX8MM_CLK_VPU_BUS>;
        assigned-clock-parents = <0>, <&clk IMX8MM_VPU_PLL_OUT>, <&clk IMX8MM_SYS_PLL1_800M>;
    assigned-clocks = <&clk IMX8MM_VPU_PLL_OUT>,<&clk IMX8MM_CLK_VPU_H1>,<&clk IMX8MM_CLK_VPU_BUS>;
        assigned-clock-parents = <0>, <&clk IMX8MM_VPU_PLL_OUT>, <&clk IMX8MM_SYS_PLL1_800M>;
assigned-clock-rates = <800000000>, <400000000>, <800000000>;

...

Have a ncie day!

BR,

weidong

0 Kudos

1,166 Views
marioschuknecht
Contributor III

Following change in device tree. Can you check it?

        vpu_h1: vpu_h1@38320000 {
                compatible = "nxp,imx8mm-hantro-h1";
                reg = <0x0 0x38320000 0x0 0x10000>;
                reg-names = "regs_hantro_h1";
                interrupts = <GIC_SPI 30 IRQ_TYPE_LEVEL_HIGH>;
                interrupt-names = "irq_hantro_h1";
                clocks = <&clk IMX8MM_CLK_VPU_H1_ROOT>, <&clk IMX8MM_CLK_VPU_DEC_ROOT>;
                clock-names = "clk_hantro_h1", "clk_hantro_h1_bus";
                assigned-clocks = <&clk IMX8MM_VPU_PLL_OUT>,<&clk IMX8MM_CLK_VPU_H1_SRC>,<&clk IMX8MM_CLK_VPU_BUS_SRC>;
                assigned-clock-parents = <0>, <&clk IMX8MM_VPU_PLL_OUT>, <&clk IMX8MM_SYS_PLL1_800M>;
                assigned-clock-rates = <800000000>, <400000000>, <800000000>;
                power-domains = <&vpu_h1_pd>;
                status = "disabled";
        };

        vpu_g1: vpu_g1@38300000 {
                compatible = "nxp,imx8mm-hantro";
                reg = <0x0 0x38300000 0x0 0x100000>;
                reg-names = "regs_hantro";
                interrupts = <GIC_SPI 7 IRQ_TYPE_LEVEL_HIGH>;
                interrupt-names = "irq_hantro";
                clocks = <&clk IMX8MM_CLK_VPU_G1_ROOT>, <&clk IMX8MM_CLK_VPU_DEC_ROOT>;
                clock-names = "clk_hantro", "clk_hantro_bus";
                assigned-clocks = <&clk IMX8MM_VPU_PLL_OUT>,<&clk IMX8MM_CLK_VPU_G1_SRC>,<&clk IMX8MM_CLK_VPU_BUS_SRC>;
                assigned-clock-parents = <0>, <&clk IMX8MM_VPU_PLL_OUT>, <&clk IMX8MM_SYS_PLL1_800M>;
                assigned-clock-rates = <800000000>, <400000000>, <800000000>;
                power-domains = <&vpu_g1_pd>;
                status = "disabled";
        };

        vpu_g2: vpu_g2@38310000 {
                compatible = "nxp,imx8mm-hantro";
                reg = <0x0 0x38310000 0x0 0x100000>;
                reg-names = "regs_hantro";
                interrupts = <GIC_SPI 8 IRQ_TYPE_LEVEL_HIGH>;
                interrupt-names = "irq_hantro";
                clocks = <&clk IMX8MM_CLK_VPU_G2_ROOT>, <&clk IMX8MM_CLK_VPU_DEC_ROOT>;
                clock-names = "clk_hantro", "clk_hantro_bus";
                assigned-clocks = <&clk IMX8MM_VPU_PLL_OUT>,<&clk IMX8MM_CLK_VPU_G2_SRC>,<&clk IMX8MM_CLK_VPU_BUS_SRC>;
                assigned-clock-parents = <0>, <&clk IMX8MM_VPU_PLL_OUT>, <&clk IMX8MM_SYS_PLL1_800M>;
                assigned-clock-rates = <800000000>, <400000000>, <800000000>;
                power-domains = <&vpu_g2_pd>;
                status = "disabled";
        };

The frequencies look different now. But they've been increased instead of decreased.

# cat /sys/kernel/debug/clk/clk_summary | grep vpu
                   vpu_bus_src            0            0   800000000          0 0
                      vpu_bus_cg           0            0   800000000          0 0
                         vpu_bus_pre_div           0            0   800000000          0 0
                            vpu_bus_div           0            0   800000000          0 0
                               vpu_dec_root_clk           0            0   800000000          0 0
                vpu_src                   0            0  1200000000          0 0
                   vpu_cg                 0            0  1200000000          0 0
                      vpu_div             0            0  1200000000          0 0
    vpu_pll_ref_sel                       0            0    24000000          0 0
       vpu_pll                            0            0   800000000          0 0
          vpu_pll_bypass                  0            0   800000000          0 0
             vpu_pll_out                  0            0   800000000          0 0
                vpu_h1_src                0            0   800000000          0 0
                   vpu_h1_cg              0            0   800000000          0 0
                      vpu_h1_pre_div           0            0   800000000          0 0
                         vpu_h1_div           0            0   800000000          0 0
                            vpu_h1_root_clk           0            0   800000000          0 0
                vpu_g2_src                0            0   800000000          0 0
                   vpu_g2_cg              0            0   800000000          0 0
                      vpu_g2_pre_div           0            0   800000000          0 0
                         vpu_g2_div           0            0   800000000          0 0
                            vpu_g2_root_clk           0            0   800000000          0 0
                vpu_g1_src                0            0   800000000          0 0
                   vpu_g1_cg              0            0   800000000          0 0
                      vpu_g1_pre_div           0            0   800000000          0 0
                         vpu_g1_div           0            0   800000000          0 0
                            vpu_g1_root_clk           0            0   800000000          0 0

Set frequency in device tree at 3 places from 800MHz to 400MHz.

assigned-clock-rates = <400000000>, <400000000>, <800000000>;

There is no difference in the output of /sys/kernel/debug/clk/clk_summary.

Now in file drivers/clk/imx/clk-imx8mm.c 400MHz added:

static const struct imx_int_pll_rate_table imx8mm_intpll_tbl[] = {
        PLL_1416X_RATE(1800000000U, 225, 3, 0),
        PLL_1416X_RATE(1600000000U, 200, 3, 0),
        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),
};

Now there is a difference in /sys/kernel/debug/clk/clk_summary, there will be 400MHz output:

# cat /sys/kernel/debug/clk/clk_summary | grep vpu
                   vpu_bus_src            0            0   800000000          0 0
                      vpu_bus_cg           0            0   800000000          0 0
                         vpu_bus_pre_div           0            0   800000000          0 0
                            vpu_bus_div           0            0   800000000          0 0
                               vpu_dec_root_clk           0            0   800000000          0 0
                vpu_src                   0            0  1200000000          0 0
                   vpu_cg                 0            0  1200000000          0 0
                      vpu_div             0            0  1200000000          0 0
    vpu_pll_ref_sel                       0            0    24000000          0 0
       vpu_pll                            0            0   400000000          0 0
          vpu_pll_bypass                  0            0   400000000          0 0
             vpu_pll_out                  0            0   400000000          0 0
                vpu_h1_src                0            0   400000000          0 0
                   vpu_h1_cg              0            0   400000000          0 0
                      vpu_h1_pre_div           0            0   400000000          0 0
                         vpu_h1_div           0            0   400000000          0 0
                            vpu_h1_root_clk           0            0   400000000          0 0
                vpu_g2_src                0            0   400000000          0 0
                   vpu_g2_cg              0            0   400000000          0 0
                      vpu_g2_pre_div           0            0   400000000          0 0
                         vpu_g2_div           0            0   400000000          0 0
                            vpu_g2_root_clk           0            0   400000000          0 0
                vpu_g1_src                0            0   400000000          0 0
                   vpu_g1_cg              0            0   400000000          0 0
                      vpu_g1_pre_div           0            0   400000000          0 0
                         vpu_g1_div           0            0   400000000          0 0
                            vpu_g1_root_clk           0            0   400000000          0 0

I'm not an expert and don't know if the change in drivers/clk/imx/clk-imx8mm.c is correct. And why 400Mhz and not 450MHz?

0 Kudos