1, 介绍
芯片的功耗主要由静态功耗和动态功耗组成。静态功耗:电路稳定后,Vdd到GND之间也有细微的电流产生功耗。动态功耗:一部分,由于MOS管开关切换会对寄生电容充放电,从而产生功耗;另一部分,由于MOS管开关过程中,存在短暂的NMOS与PMOS都导通(Vdd到GND的直连)时刻,此时会产生浪涌电流。一般动态功耗远大于静态功耗,因此减少芯片功耗的关键点就是减少动态功耗。
根据动态功耗的公式(N:晶体管数量,A:反转因子,C:寄生电容,Vdd:电源电压,F:频率):P=N*A*C*Vdd*Vdd*F,动态功耗跟电压的平方成正比,跟频率一次方成正比。另外,对于同一计算量,仅仅调频的能量收益很少,原因就是当频率降低了,计算时间也会相应增加,这样能量消耗其实跟不调频时差别不大。因此,单单做调频,功耗收益不大,做调频调压才会带来比较大的功耗收益。
如今SoC由众多子模块组成,比如CNN、DSP、ISP、CPU等。在不同场景下,并非SoC内部所有模块都要保持最高的性能。因此,SoC设计的时候会划分一些电压域,这些电压域内的模块,可以根据具体的需要调整电压和频率,从而达到既能实现功能,又降低功耗目的。不过频率电压并不是随意搭配的,一般情况下,高频对应着高压,低频对应着低压,这是由于晶体管的电器特性决定的(高频时,为了能快速的反转电路,需要针对寄生电容做快速的充放电,这往往需要更高的电压)。虽然高频对应着高压,但是频率及电压调整并不是独立的调整。为了芯片功能稳定,频率及电压会成对出现,并在芯片产品化前期对这些频率、电压对做长时间、高低温压测,以保证稳定性。 Linux内核用OPP(Operating Performance Point)对这些设备支持的频率、电压对进行描述与管理。之前分享的cpu dvfs就是基于OPP实现的,但是仅仅支持cpu设备的调频、调压。今天这篇文章主要是针对设备的dvfs,它也是基于OPP实现的。Linux内核实现了一个devfreq framework用于实现及管理device的dvfs,支持多设备的调频、调压,并且每个设备都有自己的governor策略。
Devfreq framework规范了设备调频调压的过程,也标准化了用户空间的控制接口。通过设备的需求,利用governor策略控制频率,进而根据opp table选择对应的电压。调频调压的过程中遵循着,降频先降频后降压,升频先升频后升压的原则。
2, 框架
linux device dvfs框架
Devfreq的目的就是为了屏蔽底层硬件差异,提供一些回调函数给设备调频调压驱动,抽象调频调压的公共逻辑组成devfreq core,将不同的调频调压策略封装成一个个的governor,然后为上层提供调频的接口及debug接口。
接下来,我们看一看整个devfreq framework中的各模块组成:
- Devfreq device driver:需要调频调压的设备驱动,需要通过devfreq framework提供的接口进行注册。会通过opp库提供的dts解析函数解析opp频率、电压对。在调频的时候,根据opp库提供频率、电压调整接口借助clk、regulator框架进行调频调压。在查询当前频率时,通过get_cur_freq查询当前的频率。
- Governor:具体的调频策略,需要devfreq framework提供的接口进行注册。内核中已经支持如下策略:
- simple_ondemand:按需调整模式;根据系统负载,动态地调整频率、电压,平衡性能和功耗。
- Performance:性能优先模式,将频率及电压调整到最大。
- Powersave:功耗优先模式,将频率及电压调整到最小。
- Userspace:用户指定模式,用户通过提供的文件节点,根据需要设置的频率及电压。
- Passive:被动模式,使用设备指定方法做频率、电压调整,或跟随父devfreq设备的governor进行调整。
- Devfreq core:devfreq framework的核心,一方面提供需要调频调压设备及governor的注册方法,通过devfreq_list及governor_list分别管理所有的调频调压设备及注册进系统的governor。另一方面,提供具体调频调压的处理逻辑,通过从governor获取目标频率,提供update_devfreq方法供governor调用,从而实现调频调压。
3, 数据结构
linux device dvfs数据结构
4, 流程
Devfreq framework在内核中主要涉及如下流程,初始化、频率调整、devfreq remove。我们从这三个方面介绍devfreq framework的函数调用逻辑。
4.1 初始化流程
devfreq framework初始化流程:
devfreq framework初始化流程
Governor初始化流程:
devfreq governor初始化流程
4.2 调频调压流程
以exynos芯片,simple_ondemend策略为例。
调频调压流程
4.3 remove流程
以tegra20芯片为例。
devfreq remove流程