目录
Linux devfreq 简介
现在的 Soc 由众多的子模块构成,比如CNN,DSP,ISP,CPU等,在不同的场景下,并非所有的模块都要保持最高的性能,因此,SoC 设计的时候会划分一些电压域,这些电压域内的模块,可以根据具体需要调整电压和频率,从而达到既能实现功能,又能降低功耗的目的
不过频率电压并不是随意搭配的,一般情况下,高频对应着高压,低频对应着低压,这是由于晶体管的电器特性决定的
Linux 内核用 OPP(Operation Performance Point) 对这些设备支持的频率和电压进行描述和管理,CPU 的 DVFS 也就是 cpufreq 也是基于 OPP 实现的,但是仅仅支持 CPU 设备的调频和调压,这里主要介绍的是设备的 DVFS,也是基于 OPP 实现的,Linux 内核实现了一个 devfreq framework 用于实现和管理 device 的 dvfs,用于支持非CPU设备的调频,调压,并且设备可以匹配自己的 governor 策略
devFreq framework 规范了设备调频调压的过程,也标准化了用户空间的控制接口,通过设备的需求,利用 governor 策略控制频率,进而根据 opp table 选择对应的电压

核心数据结构
devfreq_dev_profile 结构体
devfreq_dev_profile 结构体, 是OPP device 注册到 devfreq framework 的数据结构,主要包含 OPP 设备的频率信息和相关的回调函数,是 devfreq framework 和 OPP device 的交互接口,将 OPP device driver 对 devfreq 的使用,简化为对 devfreq profile 结构体的填充
// drivers/devfreq/devfreq.c
// include/linux/devfreq.h
struct devfreq_dev_profile {
// devfreq 注册的初始化频率
unsigned long initial_freq;
// governor polling 的时间间隔,单位 ms
unsigned int polling_ms;
// devfreq framework用于设定 OPP device frequency的回调函数
int (*target)(struct device *dev, unsigned long *freq, u32 flags);
// devfreq framework 用于获取 OPP device 负载状态的回调函数
int (*get_dev_status)(struct device *dev, struct devfreq_dev_status *stat);
// devfreq framework 用于获取当前频率的回调函数
int (*get_cur_freq)(struct device *dev, unsigned long *freq);
// 当 devfreq 设备从 devfreq framework 移除的时候调用
// 调用时机是 error 或者 devfreq_remove_device() call
void (*exit)(struct device *dev);
unsigned long *freq_table;
unsigned int max_state;
};
devfreq_governor 结构体
devfreq_governor 是 governor 注册到devfreq framework 的数据结构,主要包含 governor 的相关属性和具体的函数实现,是devfreq framework 和 governor 的交互接口
struct devfreq_governor {
// 将 devfreq_governor 作为链表节点进行管理
struct list_head node;
// governor name
const char name[DEVFREQ_NAME_LEN];
// 是否可以切换为其他 governor 1:不能切换
const unsigned int immutable;
// governor 注册到 devfreq framework 的算法实现函数,返回调整后的频率
int (*get_target_freq)(struct devfreq *this, unsigned

最低0.47元/天 解锁文章
374

被折叠的 条评论
为什么被折叠?



