How to cut voltage and clocks from USB and GPU/VPU

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

How to cut voltage and clocks from USB and GPU/VPU

Jump to solution
7,862 Views
sergueiivantsov
Contributor II

I'm going to estimate an i.MX6Q in a tiny blade-server environment and use SabreLite as a sample.

I build a custom monolithic Linux kernel without USB, Video, encoders, sound, etc. - just CPUFreq, Thermal, SATA and Network.

Is it possible (via software) to cut voltage and clocks from those "unnecessary" features of the SoC to save power and drop heat dissipation?

Labels (2)
1 Solution
3,869 Views
AnsonHuang
NXP Employee
NXP Employee

Hi, Serguei

     The PU power is powered up by default when SOC boot up, but we turn it off in our uboot, and only turn it on in kernel when their is VPU or GPU driver needed. So, if you build out VPU&GPU module as well as using our uboot, then this PU power is off. You can also dump register value of 0x20c8140 for me, if bit8~15 are all 0, then it is off.

     BTW, please  close this question if you think it is answered, thanks in advanced!

View solution in original post

0 Kudos
18 Replies
3,869 Views
AnsonHuang
NXP Employee
NXP Employee

Hi,

     See below:

     1. Disable PU power domain and PCIe power:

1079         /* Need to power down xPU in GPC before turn off PU LDO */

1080         val = readl(GPC_BASE_ADDR + GPC_PGC_GPU_PGCR_OFFSET);

1081         writel(val | 0x1, GPC_BASE_ADDR + GPC_PGC_GPU_PGCR_OFFSET);

1082  

1083         val = readl(GPC_BASE_ADDR + GPC_CNTR_OFFSET);

1084         writel(val | 0x1, GPC_BASE_ADDR + GPC_CNTR_OFFSET);

1085         while (readl(GPC_BASE_ADDR + GPC_CNTR_OFFSET) & 0x1)

1086                 ;       

1087  

1088         /* Increase the VDDSOC to 1.2V and disable VDDPU */

1089         val = REG_RD(ANATOP_BASE_ADDR, HW_ANADIG_REG_CORE);

1090         val &= ~BM_ANADIG_REG_CORE_REG2_TRG;

1091         val &= ~BM_ANADIG_REG_CORE_REG1_TRG;

1092         val |= BF_ANADIG_REG_CORE_REG2_TRG(0x14);

1093         REG_WR(ANATOP_BASE_ADDR, HW_ANADIG_REG_CORE, val);

1094  

1095         /* Need to power down PCIe */ 

1096         val = REG_RD(IOMUXC_BASE_ADDR, IOMUXC_GPR1_OFFSET);

1097         val |= (0x1 << 18);

1098         REG_WR(IOMUXC_BASE_ADDR, IOMUXC_GPR1_OFFSET, val);

     2. Disable module clock:

     CCM_CCGR0~CCGR6, set those modules clock to 0.

3,869 Views
sergueiivantsov
Contributor II

Thanks, I find those code in arch_cpu_init().

Does it means, that PU is unpowered by default, so I do not need turn it off manually?

0 Kudos
3,870 Views
AnsonHuang
NXP Employee
NXP Employee

Hi, Serguei

     The PU power is powered up by default when SOC boot up, but we turn it off in our uboot, and only turn it on in kernel when their is VPU or GPU driver needed. So, if you build out VPU&GPU module as well as using our uboot, then this PU power is off. You can also dump register value of 0x20c8140 for me, if bit8~15 are all 0, then it is off.

     BTW, please  close this question if you think it is answered, thanks in advanced!

0 Kudos
3,869 Views
sergueiivantsov
Contributor II

how can I read those register?

doing something like int reg=__raw_readl(0x20c8140); from kernel module just makes panic.

0 Kudos
3,869 Views
varsmolta
Contributor V

You cannot read physical registers from the kernel that way.

There is a devregs program from here that you can use to probe the imx6 registers from user space (its for imx5 but applies to imx6 as well): http://boundarydevices.com/i-mx5x-device-register-access/

You may have to add the register definitions to the devregs_imx6x.dat file for the registers you want to access

3,869 Views
sergueiivantsov
Contributor II

devregs is not working as is, I get "Error reading CPU type". This is because it searches for "Revision" string in "/proc/cpuinfo".

Mine looks like the following:

processor    : 0

model name    : ARMv7 Processor rev 10 (v7l)

BogoMIPS    : 790.52

Features    : swp half thumb fastmult vfp edsp thumbee neon vfpv3 tls lpae

CPU implementer    : 0x41

CPU architecture: 7

CPU variant    : 0x2

CPU part    : 0xc09

CPU revision    : 10

processor    : 1

model name    : ARMv7 Processor rev 10 (v7l)

BogoMIPS    : 790.52

Features    : swp half thumb fastmult vfp edsp thumbee neon vfpv3 tls lpae

CPU implementer    : 0x41

CPU architecture: 7

CPU variant    : 0x2

CPU part    : 0xc09

CPU revision    : 10

processor    : 2

model name    : ARMv7 Processor rev 10 (v7l)

BogoMIPS    : 790.52

Features    : swp half thumb fastmult vfp edsp thumbee neon vfpv3 tls lpae

CPU implementer    : 0x41

CPU architecture: 7

CPU variant    : 0x2

CPU part    : 0xc09

CPU revision    : 10

processor    : 3

model name    : ARMv7 Processor rev 10 (v7l)

BogoMIPS    : 790.52

Features    : swp half thumb fastmult vfp edsp thumbee neon vfpv3 tls lpae

CPU implementer    : 0x41

CPU architecture: 7

CPU variant    : 0x2

CPU part    : 0xc09

CPU revision    : 10

Hardware    : Freescale i.MX6 Quad/DualLite (Device Tree)

Revision    : 0000

Serial        : 0000000000000000

So I fix to search for "CPU revision". Though I get "unsupported CPU type: 10" it reads the register of interest!

The value is : 0x0050240a

Thus, bit8~15 are not zero...

0 Kudos
3,869 Views
varsmolta
Contributor V

If you moved over devregs_imx6x.dat from the git repo to /etc/devregs.dat on your sabrelite and added the necessary register address to this file, then the value that you are reading is correct. (getDataPath() function in devregs.cpp is returning /etc/devregs.dat filename for an unsupported cpu type)

Otherwise, the value that you are reading may not be correct. What OS are you running on the sabrelite? Most likely your proc/cpuinfo is not set up as expected (for the devregs program to read the cpu revision correctly). In any case, I think you have your answer as long as the steps above have been taken.

0 Kudos
3,869 Views
sergueiivantsov
Contributor II

Linux 3.11.0-rc1

Yep, I move dat file to the proper location and add an entry for register 0x20c8140.

I try to write back a value 0x50000A (with cleared bits) to that register and see what is happen - nothing

The temperature stays at 50℃ in idle. What is pretty high, I think so.

0 Kudos
3,869 Views
varsmolta
Contributor V

According to the datasheet section 10.4.1.4.3.2, you also need to configure the PGC_GPU_CTRL (PGC Control Register - register 0x20DC260) to allow power down of the GPU/VPU platform. Bit 0 (Power Control) of this register must be set to '1' before you write to the  0x20c8140 register.

0 Kudos
3,869 Views
sergueiivantsov
Contributor II

I get "Bus error" when reading 0x20DC260

0 Kudos
3,869 Views
varsmolta
Contributor V

According to section 27.8:PGC Memory Map/Register Definition of the datasheet, "Attempts to access registers when not in supervisor mode or attempts to access an unimplemented address location might trigger a bus transfer error". So this is what you may be seeing. So you will have to figure how to circumvent this. There is info in the datasheet on how to do this. As an alternate solution, I would recommend to not build GPU and VPU drivers in the kernel, just like

0 Kudos
3,869 Views
sergueiivantsov
Contributor II

As I mentioned above - I already build a monolithic kernel without GPU/VPU/CAAM (and others unnecessary) modules.

0 Kudos
3,869 Views
varsmolta
Contributor V

There is a series of power measurement scripts here:https://community.freescale.com/docs/DOC-93884

An alternate solution is to power off the VPU/GPU using Yongcai's code above at the end of the kernel boot sequence (presumably you will be in supervisory mode since you are still executing the kernel)

0 Kudos
3,869 Views
sergueiivantsov
Contributor II

I can't read it from the kernel, and you say it is impossible.

Let's assume I'm turning off power, when clearing bits in 0x20c8140.

Should the temperature drop down?

Is it ok for this SoC to be 50℃ hot while idle (with 25℃ ambient)?

Probably AnsonHuang can help?

0 Kudos
3,869 Views
AnsonHuang
NXP Employee
NXP Employee

Yes, it is about ~40C on my board when idle. If you still get 50C, maybe you can check the all the CCM_CCGRx register, and turn off all unnecessary clocks, this could save many power and reduce the temperature. It would be great that if you can measure enable power rail, VDDARM_IN, VDDSOC_IN and VDDHIGH_IN, then compare it to our power application notes to see which rail is abnormal. Then maybe we can find some clues to lower the power consumption. Also, you can try different ODT setting of DDR3, it can save many power. The offset 0x818 of MMDC controller.

    We can use weak ODT setting, it will save about 50% DDR

    power in runtime. Now we use 0x00007

   

    MMDC0_MPODTCTRL MMDC1_MPODTCTRL, (Ohm)

   

    Setting             DDR_ODT         imx_ODT         Max_overclocking

   

    0x22227             120             060             615MHz

    0x11117             120             120             604MHz

    0x00007             120             000             576MHz

    0x00000             000             000             556MHz

0 Kudos
3,869 Views
sergueiivantsov
Contributor II

I found that I use u-boot from BoundaryDevices, which does not shutdown PU.

The latest u-boot from Freescale is not working for me - it can't initialize SATA. So I just add

    imx_set_pcie_phy_power_down();
    imx_set_vddpu_power_down();

calls to arch_cpu_init(void).

Now the bits you mentioned are clear, but the temperature the same.

Maybe this is due to (high) voltage on CPU?

set_vddsoc(1200);  

/* Set VDDSOC to 1.2V */

Is it safe to lower voltage here? Processor works max at 996Mhz.

Is it possible to look for current voltage, or measure. Should the voltage drop down, when CPUfreq lowering clock?

0 Kudos
3,869 Views
AnsonHuang
NXP Employee
NXP Employee

It should be not caused by the voltage, as in uboot the loading is very light. I think you should check the CCM_CCGRx, maybe there are too many clocks enabled. You should disable those modules' clock which are not necessary.

Do NOT lower the voltage, and yes, you can measure the voltage from the VDDARM_CAP/VDDSOC_CAP/VDDPU_CAP to get the output of LDO.

Yes, if CPUFreq is low, the voltage can be down. But in uboot, we run CPU at fixed clock of 792M. In kernel, the cpufreq driver will scale the freq/voltage accordingly. So there is no need to do any change to these voltage/freq.

My suggestion is to check the CCM_CCGRx's setting.

0 Kudos
3,869 Views
AnsonHuang
NXP Employee
NXP Employee

Yes, you can disable PU power which is supplying VPU and GPU. Please refer to Uboot, we have done that. For clock, you can gate those unnecessary clock in CCM ccgr register.

0 Kudos