首页 > 系统相关 >linux opp怎么使用

linux opp怎么使用

时间:2023-05-29 20:56:23浏览次数:63  
标签:SoC OPP linux dev 使用 opp freq pm

简介Operating Performance Points (OPP)

SoC是高度集成的,不是SoC中的所有模块需要一直以最高的频率运作。来为了便于实现这一点,SoC中的子模块被分组到不同的域中,允许一些域运行在较低的电压和频率,而其他域运行在更高的电压/频率对。

由频率和电压对组成的离散元组的集合称为工作性能点(opp)。

例如:让我们考虑一个支持以下功能的MPU设备:
{300MHz,最小电压1V},
{800MHz,最小电压1.2V},
{最低电压1.3V时1GHz},

我们可以用{Hz, uV}元组来表示这三个opp:

{300000000, 1000000}
{800000000, 1200000}
{1000000000, 1300000}

OPP API接口

OPP库提供了一组辅助函数来组织和查询OPP信息。库位于drivers/opp/目录中,头文件位于include/linux/pm_opp.h中。可以通过从电源管理菜单CONFIG菜单启用CONFIG_pm_opp来启用opp库。某些SoC,如Texas Instrument的OMAP框架,允许在不需要cpufreq的情况下选择性地在某个OPP启动。

OPP层期望每个域由一个唯一的设备指针来表示。SoC框架在OPP层为每个设备注册一组初始OPP。这个列表的长度一般比较小,通常每个设备大约5个。这个初始列表包含一组 OPP,框架希望系统默认情况下能够安全地启用这些 OPP。

通常使用opp的方式有以下几步:
a. 用户为设备(比如CPU)配置/注册一些默认的opp信息。
b. Soc会根据具体的运行情况,通过opp层去改变/查询设备的opp信息。

(users)  -> registers a set of default OPPs  -> (library)

SoC framework -> modifies on required cases certain OPPs -> OPP layer ->queries to search/retrieve information 

使用OPP的场景

随着系统继续运行,SoC框架可能会根据各种外部因素选择在每个设备上提供某些 OPP 或不提供 OPP。
示例用法:热管理或其他特殊情况,SoC框架可能选择禁用更高频率的OPP以安全地继续操作,直到该OPP可以在可能的情况下重新启用。

警告:如果设备调用了dev_pm_opp_enable/deisable函数,则OPP库的用户应使用get_opp_count刷新其可用性计数,在进行这些操作的情况下,需要注意刷新cpufreq表。

如何使用OPP

OPP列表初始化

迭代调用dev_ pm_opp_ dd 函数为每个设备添加 OPP列表。每个设备的opp个数最好小于5个。

OPP是用频率和电压定义的。一旦完成添加,OPP被认为是可用的,可以用dev_pm_opp_enable/disable函数来控制其可用性。OPP库内部用dev_pm_opp结构体存储并管理这些信息。

注意:不要在中断上下文中使用此函数。

例如,多次调用dev_pm_opp_add为mpu_dev添加多个opp。

soc_pm_init()
{
       /* Do things */
       r = dev_pm_opp_add(mpu_dev, 1000000, 900000);
       if (!r) {
               pr_err("%s: unable to register mpu opp(%d)\n", r);
               goto no_cpufreq;
       }
       /* Do cpufreq things */
no_cpufreq:
       /* Do remaining things */
}

OPP查询获取函数

cpufreq等高层框架对频率进行操作,为了将频率映射到相应的OPP,OPP库提供了便利的函数来搜索OPP库内部管理的OPP链表。这些搜索函数如果找到匹配的OPP,将返回指向该OPP的指针,否则返回错误。这些错误预计由标准的错误检查,如IS_ERR()来处理,并由调用者采取适当的行动。

这些函数的调用者应在使用完OPP后调用dev_pm_opp_put()。否则,OPP的内存将永远不会被释放,并导致内存泄露。

函数 作用
dev_pm_opp_find_freq_ceil, dev_pm_opp_find_freq_floor} 查找某个频率附近的最高频率,或者最低频率
dev_pm_opp_find_freq_exact 此功能对于启用默认情况下不可用的OPP特别有用

cpufreq_driver->target的简化实现:

soc_cpufreq_target(..)
{
       /* Do stuff like policy checks etc. */
       /* Find the best frequency match for the req */
       opp = dev_pm_opp_find_freq_ceil(dev, &freq);
       dev_pm_opp_put(opp);
       if (!IS_ERR(opp))
               soc_switch_to_freq_voltage(freq);
       else
               /* do something when we can't satisfy the req */
       /* do other stuff */
}

OPP可用性控制功能

dev_pm_opp_enable:使OPP可用。示例:假设只有当SoC温度低于某个阈值时,1GHz OPP才可用

if (cur_temp < temp_low_thresh) {
       /* Enable 1GHz if it was disabled */
       opp = dev_pm_opp_find_freq_exact(dev, 1000000000, false);
       dev_pm_opp_put(opp);
       /* just error check */
       if (!IS_ERR(opp))
               ret = dev_pm_opp_enable(dev, 1000000000);
       else
               goto try_something_else;
}

dev_pm_opp_disable: OPP不可用于。示例: 如果温度超过阈值,则禁用1GHz OPP。

if (cur_temp > temp_high_thresh) {
       /* Disable 1GHz if it was enabled */
       opp = dev_pm_opp_find_freq_exact(dev, 1000000000, true);
       dev_pm_opp_put(opp);
       /* just error check */
       if (!IS_ERR(opp))
               ret = dev_pm_opp_disable(dev, 1000000000);
       else
               goto try_something_else;
}

OPP数据检索功能

dev_pm_opp_get_voltage:检索opp指针表示的电压。示例:在cpufreq转换到不同频率时,需要使用regulator框架将由OPP表示的电压来配置到pmic:

soc_switch_to_freq_voltage(freq)
{
       /* do things */
       opp = dev_pm_opp_find_freq_ceil(dev, &freq);
       v = dev_pm_opp_get_voltage(opp);
       dev_pm_opp_put(opp);
       if (v)
               regulator_set_voltage(.., v);
       /* do other things */
}

dev_pm_opp_get_freq:检索opp指针表示的频率。例如:假设SoC框架使用了几个辅助函数,我们可以传递opp指针,而不是做额外的参数来处理一些安静的数据参数:

soc_cpufreq_target(..)
{
       /* do things.. */
        max_freq = ULONG_MAX;
        max_opp = dev_pm_opp_find_freq_floor(dev,&max_freq);
        requested_opp = dev_pm_opp_find_freq_ceil(dev,&freq);
        if (!IS_ERR(max_opp) && !IS_ERR(requested_opp))
               r = soc_test_validity(max_opp, requested_opp);
        dev_pm_opp_put(max_opp);
        dev_pm_opp_put(requested_opp);
       /* do other things */
}
soc_test_validity(..)
{
        if(dev_pm_opp_get_voltage(max_opp) < dev_pm_opp_get_voltage(requested_opp))
                return -EINVAL;
        if(dev_pm_opp_get_freq(max_opp) < dev_pm_opp_get_freq(requested_opp))
                return -EINVAL;
       /* do things.. */
}

dev_pm_opp_get_opp_count:检索设备的可用opp数量示例:假设SoC中的协同处理器需要知道表中的可用频率,主处理器可以通知如下:

soc_notify_coproc_available_frequencies()
{
       /* Do things */
       num_available = dev_pm_opp_get_opp_count(dev);
       speeds = kzalloc(sizeof(u32) * num_available, GFP_KERNEL);
       /* populate the table in increasing order */
       freq = 0;
       while (!IS_ERR(opp = dev_pm_opp_find_freq_ceil(dev, &freq))) {
               speeds[i] = freq;
               freq++;
               i++;
               dev_pm_opp_put(opp);
       }

       soc_notify_coproc(AVAILABLE_FREQs, speeds, num_available);
       /* Do other things */
}

OPP数据结构

通常,一个SoC包含多个可变电压域。每个域由一个设备指针描述。和OPP之间的关系可以按以下方式描述::

SoC
 |- device 1
 |    |- opp 1 (availability, freq, voltage)
 |    |- opp 2 ..
 ...  ...
 |    `- opp n ..
 |- device 2
 ...
 `- device m

OPP库维护着一个内部链表,SoC框架使用上文描述的各个函数来填充和访问。然而,描述真实OPP和域的结构体是OPP库自身的内部组成,以允许合适的抽象在不同系统中得到复用。

struct dev_pm_opp
OPP库的内部数据结构,用于表示一个OPP。除了频率、电压、可用性信息外,它还包含OPP库运行所需的内部统计信息。指向这个结构体的指针被提供给用户(比如SoC框架)使用,在与OPP层的交互中作为OPP的标识符。

警告:结构体dev_pm_opp的指针不应该由用户解析或修改。一个实例的默认值由dev_pm_opp_add填充,但OPP的可用性由dev_pm_opp_enable/disable函数修改。

struct device
这用于向OPP层标识一个域。设备的性质和它的实现是由OPP库的用户决定的,如SoC框架。
总体来说,以一个简化的视角看,对数据结构的操作可以描述为下面各图::

初始化和修改相关:
            +-----+        /- dev_pm_opp_enable
dev_pm_opp_add --> | opp | <-------
  |         +-----+        \- dev_pm_opp_disable
  \-------> domain_info(device)

查找函数:
             /-- dev_pm_opp_find_freq_ceil  ---\   +-----+
domain_info<---- dev_pm_opp_find_freq_exact -----> | opp |
             \-- dev_pm_opp_find_freq_floor ---/   +-----+

检索函数:
+-----+     /- dev_pm_opp_get_voltage
| opp | <---
+-----+     \- dev_pm_opp_get_freq

domain_info <- dev_pm_opp_get_opp_count

OPP的DTS配置

Ref

https://docs.kernel.org/power/opp.html

标签:SoC,OPP,linux,dev,使用,opp,freq,pm
From: https://www.cnblogs.com/lvzh/p/17441280.html

相关文章

  • tailwindcss在使用cdn引入静态html的时候,使用vscode代码提示
    原文:Hey!TheIntellisenseextensiondoesneedaconfigfiletoworktoday.Iwouldsuggestcreatingoneinyourprojectroottoenabletheextension.Anemptyfilewillworkjustfineforthiscaseifthedefaultssuityourneeds.Ifyouwanttocustomiz......
  • git使用
    1.下载git2.生成ssh密钥,执行ssh-keygen-trsa-C"公司内部邮箱地址"3.切换到~/.ssh目录,ls打开当前文件,复制其中id_rsa.pub的内容4.在仓库中添加sshkey,比如code中,点击页面右上方的SSHKey,把id_rsa.pub的内容粘过来5.全局配置git的用户名和邮箱gitconfig--......
  • Javaweb中在SQL语句中使用未知数进行多表查询
    这个问题主要是匹配好引号和单引号即可。如果是varchar型,那么变量要带单引号('),如果是int型就不用带。同时要注意用+号进行String的拼接。示例:publicList<Student>huizong_bujige(Stringkemu1){List<Student>list=newArrayList<>();Connectionconn......
  • flask得使用
    简单的flask使用fromflaskimportFlask,requestapp=Flask(__name__)#在当前文件下创建应用@app.route("/",methods=['POST'])#装饰器,url,路由defindex():#视图函数data=request.get_json(force=True)print(data)[email protected]......
  • 统计应用的使用时间长短
    以下是一个简单的Java代码,用于统计应用的使用时间长短:importjava.time.Duration;importjava.time.LocalDateTime;importjava.util.Scanner;publicclassAppUsageTracker{publicstaticvoidmain(String[]args){Scannerscanner=newScanner(System.in)......
  • 在linux上搭建web服务(静态网站)
    目录在linux上搭建web服务(静态网站)一、简介1.1.什么是web服务器1.2.web服务器的工作原理1.3.web服务软件有哪些1.4.http/https协议1.5.URL/URI1.6.apache1.7.nginx二、搭建apache服务,部署静态网站1.1.安装apache服务程序1.2.配置服务器文件参数1.2.1.配置文件/etc/httpd/conf/ht......
  • jwt原理开发,drf-jwt快速使用和自定义使用,jwt签发认证源码分析
    一眼弄懂cookieSeesiontoken区别彻底弄懂cookie,session和token区别1jwt原理1.1使用jwt认证和使用session认证的区别1.2三段式eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiYWRtaW4iOnRydWV9.TJVA95OrM7E2cBab30RMHrHDcEf......
  • linux运维之bash脚本编程
    算法+数据结构=程序编程语言分类:低级语言:机器语言:二进制码,0、1汇编语言:用一些容易理解和记忆的缩写单词来代替一些特定的指令高级语言:解释型语言:源代码-->编译-->得到二进制可执行文件-->执行eg:PHP、Python、Shell编译型语言:源代码-->执行eg:Java、C、C++、Golang动态编译语言不......
  • 【一步步开发AI运动小程序】九、姿态辅助调试桌面工具折使用
    随着人工智能技术的不断发展,阿里体育等IT大厂,推出的“乐动力”、“天天跳绳”AI运动APP,让云上运动会、线上运动会、健身打卡、AI体育指导等概念空前火热。那么,能否将这些在APP成功应用的场景搬上小程序,分享这些概念的红利呢?本系列文章就带您一步一步从零开始开发一个AI运动小程序......
  • SourceTree使用教程
    SourceTree使用教程1.克隆、提交、推送​ 在使用SourceTree之前必须要先安装Git和sourceTree,具体安装过程不再赘述(1)以加入我的管理团队为例,进入5-27-dq这个仓库,点击管理,然后进入仓库成员管理,发现现在我的仓库成员有4个了,gitee免费版最多可5个成员。​ 若要加入我的代码仓,请......