dvfs一共有3处
cpu,gpu,ddr
cpu和gpu都是默认开启的
ddr dvfs代码还没有进行合并,现在是一直工作在533mhz


CPU

cpu,gpu的频点在rk3288.dtsi修改,电压在vdd_cpu上,
如果测试有相应问题,可以先尝试修改这些频点

cpu0: cpu@500 {
            device_type = "cpu";
            compatible = "arm,cortex-a12";
            reg = <0x500>;
            resets = <&cru SRST_CORE0>;
            operating-points = <
                /* KHz    uV */
                1608000 1350000
                1512000 1300000
                1416000 1200000
                1200000 1100000
                1008000 1050000
                 816000 1000000
                 696000  950000
                 600000  900000
                 408000  900000
                 312000  900000
                 216000  900000
                 126000  900000
            >;
            #cooling-cells = <2>; /* min followed by max */
            clock-latency = <40000>;
            clocks = <&cru ARMCLK>;
        };

&cpu0 {
    cpu0-supply = <&vdd_cpu>;
};

GPU

电压在vdd_gpu

    gpu: gpu@ffa30000 {
        compatible = "arm,malit764",
                 "arm,malit76x",
                 "arm,malit7xx",
                 "arm,mali-midgard";
        reg = <0xffa30000 0x10000>;
        interrupts = <GIC_SPI 6 IRQ_TYPE_LEVEL_HIGH>,
                 <GIC_SPI 7 IRQ_TYPE_LEVEL_HIGH>,
                 <GIC_SPI 8 IRQ_TYPE_LEVEL_HIGH>;
        interrupt-names = "JOB", "MMU", "GPU";
        clocks = <&cru ACLK_GPU>;
        clock-names = "clk_mali";
        operating-points = <
            /* KHz uV */
            600000 1250000
            /* 500000 1200000 - See crosbug.com/p/33857 */
            400000 1100000
            300000 1000000
            200000 950000
            100000 950000
        >;
        #cooling-cells = <2>; /* min followed by max */
        power-domains = <&power RK3288_PD_GPU>;
        status = "disabled";
    };

&gpu {
    mali-supply = <&vdd_gpu>;
    status = "okay";
};

DDR

ddr上的变频因为没有硬件支持,实现比较trick,变频代码存在sram中
需要注意的是变频的操作是在vblank的时候进行的,如果vblank不满足要求,不会开启变频
下面的patch里已经打开了debug log,所以可以通过看dmc的log看看是不是没满足要求

drivers/gpu/drm/rockchip/rockchip_drm_vop.c

#ifdef CONFIG_ARM_RK3288_DMC_DEVFREQ
    u64 vblank_time;
    /*
     * Make sure we disable _before_ changing the mode / disabling the
     * clock since we need the mode to be right during the disable.
     */
    vblank_time = adjusted_mode->vtotal - adjusted_mode->vdisplay;
    vblank_time *= (u64)NSEC_PER_SEC * adjusted_mode->htotal;

    do_div(vblank_time,
           clk_round_rate(vop->dclk, adjusted_mode->clock * 1000));

    if (vblank_time <= DMC_SET_RATE_TIME_NS + DMC_PAUSE_CPU_TIME_NS) {
        /*
         * Set a large timeout so we can change the clk rate to max when
         * dmc freq is disabled.
         */
        rockchip_dmc_lock();
        vop->vblank_time = DMC_DEFAULT_TIMEOUT_NS;
        rockchip_dmc_unlock();
        if (!vop->dmc_disabled_rk3288)
            rockchip_dmc_disable();

        vop->dmc_disabled_rk3288 = true;
    }
#endif

patches: (可以checkout这个branch,然后cherry-pick对应的commit)
https://github.com/rockchip-linux/kernel/commits/release-20160920-miniarm-dev
从rockchip: dmc: copy dmc driver from 3.14到MINIARM: dmc work


一些操作

查看cpu可用频点
cat /sys/devices/system/cpu/cpu0/cpufreq/scaling_available_frequencies
设置cpu最高频率
echo 216000 > /sys/devices/system/cpu/cpu0/cpufreq/scaling_max_freq
设置cpu最低频率
echo 216000 > /sys/devices/system/cpu/cpu0/cpufreq/scaling_min_freq
更多详细信息(cpu变频策略,使用率):
cpufreq-info
设置策略
cpufreq-set

gpu 当前频率
cat /sys/devices/platform/ffa30000.gpu/devfreq/ffa30000.gpu/cur_freq
gpu 可以用的变频策略
cat /sys/devices/platform/ffa30000.gpu/devfreq/ffa30000.gpu/available_governors
设置变频策略
/sys/devices/platform/ffa30000.gpu/devfreq/ffa30000.gpu/governors

查看ddr频率
cat /sys/kernel/debug/clk/clk_summary | grep dpll_ddr
查看ddr log
log已经打开,每次变频都会有输出

--测试
所有dvfs全打开的情况下
cpu:
来回stresstest

ddr:
while true
do
killall memtester
memtester 1G 1
sleep $RANDOM%300
done

一般cpu上的异常或者频率电压不匹配会造成随机的kernel panic,
ddr上的异常会死机,另外频率和电压不匹配会有随机的内部clk异常

su linaro -c "DISPLAY=:0.0 glmark2-es2 —benchmark refract —run-forever —off-screen"

while true; do cat /sys/class/thermal/thermal_zone1/temp; sleep 1; done &
while true; do cat /sys/class/thermal/thermal_zone2/temp; sleep 1; done &
while true; do cat /sys/devices/platform/ffa30000.gpu/devfreq/ffa30000.gpu/cur_freq; sleep 1; done &

cpu频率
md5sum /dev/zero
stress —cpu 6 —io 4 —vm 2 —vm-bytes 128M —timeout 1000

升gpu频率
su linaro -c "DISPLAY=:0.0 glmark2-es2 —benchmark refract —run-forever —off-screen"

cpu gpu温度
while true; do cat /sys/class/thermal/thermal_zone1/temp; sleep 1; done &
while true; do cat /sys/class/thermal/thermal_zone2/temp; sleep 1; done &

gpu频率
while true; do cat /sys/devices/platform/ffa30000.gpu/devfreq/ffa30000.gpu/cur_freq; sleep 1; done &
cpu频率
/sys/devices/system/cpu/cpu0/cpufreq/xxx

vlc 测试视频

su lianro -c "DISPLAY=:0.0 vlc 视频“