当前位置:网站首页>UFS Power Management 介绍
UFS Power Management 介绍
2022-07-08 00:56:00 【果汁底线】
一 . UFS Power Management Overview
1. UFS Power Management 管理UFS Power相关资源,
在收到访问请求的时候唤醒UFS工作,切换为工作模式,在完成请求后让UFS进行睡眠,切换为睡眠模式,能够节省功耗,提高续航。
主要是分为UFS Runtime Power Management和UFS System Power Management。
2. UFS Runtime Power Management:
UFS模块运行时睡眠唤醒机制,只需要UFS模块空闲,即可进入睡眠状态,不受其他模块的睡眠唤醒状态影响,通俗点讲就是个人自扫门前雪。
3. UFS System Power Management:
UFS系统睡眠唤醒机制,和系统的睡眠唤醒状态有关,需要系统所有的模块都睡眠下去,UFS 模块才会睡眠下去,当只有存在系统一个模块是唤醒状态/或者系统存在唤醒源导致睡眠部下去,UFS模块也是不能成功睡眠下去,通俗点讲就是有福同享,有难同当,不放弃任何一个民众。
二 . UFS Power Management Detail
1. UFS Runtime Power Management :
(1) UFS Runtime Power Management是在Linux Kernel RPM Framework下进行管理的,在没有访问请求/UFS空闲的时候,将UFS置为睡眠状态,当UFS有访问请求/不是空闲状态时,将UFS置为唤醒状态。
(2) UFS Driver RPM Power Management 主要是管理UFS Device Power Mode State和MPHY Link State。
UFS PM Level State划分为六个等级,默认rpm_lvl 是3,也就是UFS_SLEEP_PWR_MODE, UIC_LINK_ACTIVE_STATE。
UFS_SLEEP_PWR_MODE:指的是UFS Device PowerMode为Sleep Mode, 需要发送SSU命令切换UFS Power Mode。
UIC_LINK_ACTIVE_STATE:指的是将UFS MPHY Link设置为Hibernate状态,需要发送DME_HIBERNATE_ENTER命令切换Link Status.
struct ufs_pm_lvl_states ufs_pm_lvl_states[] = {
{UFS_ACTIVE_PWR_MODE, UIC_LINK_ACTIVE_STATE},
{UFS_ACTIVE_PWR_MODE, UIC_LINK_HIBERN8_STATE},
{UFS_SLEEP_PWR_MODE, UIC_LINK_ACTIVE_STATE},
{UFS_SLEEP_PWR_MODE, UIC_LINK_HIBERN8_STATE},
{UFS_POWERDOWN_PWR_MODE, UIC_LINK_HIBERN8_STATE},
{UFS_POWERDOWN_PWR_MODE, UIC_LINK_OFF_STATE},
};
(3) UFS RPM 相关Sysfs节点:
UFS RPM Sysfs节点目录: /sys/device/platform/soc/1d84.ufshci/power
UFS RPM 相关节点:
1. control: Report/change current runtime PM setting of the device
*
* Runtime power management of a device can be blocked with the help of
* this attribute. All devices have one of the following two values for
* the power/control file:
* + "auto\n" to allow the device to be power managed at run time;
* + "on\n" to prevent the device from being power managed at run time;
2. autosuspend_delay_ms - Report/change a device's autosuspend_delay value
*
* Some drivers don't want to carry out a runtime suspend as soon as a
* device becomes idle; they want it always to remain idle for some period
* of time before suspending it. This period is the autosuspend_delay
* value (expressed in milliseconds) and it can be controlled by the user.
* If the value is negative then the device will never be runtime
* suspended.
3. runtime_active_time: report runtime active status totol time.
4. runtime_suspended_time: report runtime suspended status totol time.
5. runtime_status: report runtime status.
(4) UFS 设备Runtime Power Management状态:
/*
* Device run-time power management status.
*
* These status labels are used internally by the PM core to indicate the
* current status of a device with respect to the PM core operations. They do
* not reflect the actual power state of the device or its status as seen by the
* driver.
*
* RPM_ACTIVE Device is fully operational. Indicates that the device
* bus type's ->runtime_resume() callback has completed
* successfully.
*
* RPM_SUSPENDED Device bus type's ->runtime_suspend() callback has
* completed successfully. The device is regarded as
* suspended.
*
* RPM_RESUMING Device bus type's ->runtime_resume() callback is being
* executed.
*
* RPM_SUSPENDING Device bus type's ->runtime_suspend() callback is being
* executed.
*/
enum rpm_status {
RPM_ACTIVE = 0,
RPM_RESUMING,
RPM_SUSPENDED,
RPM_SUSPENDING,
};
(5) UFS 驱动常用Runtime PM使用接口和使用场景
在访问UFS 设备之前,为了防止UFS 进入Suspend , 我们需要调用以下两个接口增加设备使用计数,然后唤醒UFS 设备(Resume)为Active状态,这里UFS设备指的是UFS Host Controller,
Note:不管是UFS驱动还是USB驱动还是其他驱动,在访问设备之前都应该遵循以上流程,唤醒设备为Active状态,保证设备正常工作,否则如果设备进入了Suspend状态去访问会出现未知的错误。
pm_runtime_get_sync
pm_runtime_get
访问UFS设备之后,就可以让UFS 设备进入Suspend, 我们需要调用以下两个接口减少设备使用技术,然后使得UFS设备进入睡眠状态(Suspended), 这里UFS设备指的是UFS Host Controller.
pm_runtime_put
pm_runtime_put_sync
下面是一个具体的使用场景:
在对UFS Host Controller做访问之前,调用pm,_runtime_get_sync增加设备引用计数,唤醒设备,然后对设备进行访问操作,访问完成后调用pm_runtimr_put_sync减少设备引用计数,让设备睡眠。
int ufshcd_clk_scaling_enable(struct ufs_hba *hba, int value)
{
int err;
value = !!value;
mutex_lock(&ufshcd_clkscale_lock);
if (value == hba->clk_scaling.is_allowed)
goto out;
// 获取UFS PM Runtime 资源,增加PM Usage Count, 让UFS Host处于Active Status
pm_runtime_get_sync(hba->dev);
ufshcd_hold(hba, false);
cancel_work_sync(&hba->clk_scaling.suspend_work);
cancel_work_sync(&hba->clk_scaling.resume_work);
hba->clk_scaling.is_allowed = value;
if (value) {
ufshcd_resume_clkscaling(hba);
} else {
ufshcd_suspend_clkscaling(hba);
err = ufshcd_devfreq_scale(hba, true);
if (err)
dev_err(hba->dev, "%s: failed to scale clocks up %d\n",
__func__, err);
}
ufshcd_release(hba, false);
// 释放UFS PM Runtime资源,减少PM Usage Count, 让UFS Host处于Suspend Status
pm_runtime_put_sync(hba->dev);
out:
mutex_unlock(&ufshcd_clkscale_lock);
return 0;
}
阻塞UFS设备在Linux RPM Power Management 管理运行时进入Suspend.
增加设备引用计数和清除设备power.runtime_auto标志
除非调用pm_runtime_allow,否则UFS设备不会在运行的时候进入Suspend状态
pm_runtime_forbid
UFS设备在Linux RPM Power Management 管理运行时允许挂起(进入Suspended)
减少设备引用计数和设置设备power.runtime_auto标志
pm_runtime_allow
下面是一个具体的使用场景:
static const char ctrl_auto[] = "auto";
static const char ctrl_on[] = "on";static ssize_t control_show(struct device *dev, struct device_attribute *attr,
char *buf)
{
return sprintf(buf, "%s\n",
dev->power.runtime_auto ? ctrl_auto : ctrl_on);
}static ssize_t control_store(struct device * dev, struct device_attribute *attr,
const char * buf, size_t n)
{
device_lock(dev);
if (sysfs_streq(buf, ctrl_auto))
pm_runtime_allow(dev);
else if (sysfs_streq(buf, ctrl_on))
pm_runtime_forbid(dev);
else
n = -EINVAL;
device_unlock(dev);
return n;
}
2. UFS System Power Management:
(1)UFS System Power Management是受整个内核系统影响的,需要内核系统所有模块都睡眠 了或者内核系统没有唤醒事件,UFS设备才会进入UFS System Suspend。
UFS手机功耗续航测试就是在整个系统进入System Suspend(包括UFS System Suspend)后进行 测试的,相关开发同事需要对整个系统的System Suspend/Resume 机制非常了解,才能清晰的 定位到某个模块影响了系统进入System Suspend,导致功耗问题。
(2) UFS Driver RPM Power Management 主要是管理UFS Device Power Mode State和 MPHY Link State 还有UFS Device的供电VCC。
UFS PM Level State划分为六个等级,默认spm_lvl 是3,也就是UFS_SLEEP_PWR_MODE, UIC_LINK_ACTIVE_STATE。
UFS_SLEEP_PWR_MODE:指的是UFS Device PowerMode为Sleep Mode, 需要发送SSU命 令切换UFS Power Mode。
UIC_LINK_ACTIVE_STATE:指的是将UFS MPHY Link设置为Hibernate状态,需要发送 DME_HIBERNATE_ENTER命令切换Link Status.
VCC: UFS Device进入System Suspend的时候,会将VCC电压关闭节省耗电,减少功耗。
(3) UFS System Suspend相关Sysfs节点:
系统PM节点目录: /sys/power/*
wake_lock: 系统唤醒锁,如果有进程持有wake_lock, 整个系统就不会进入System Suspend, 当然UFS 设备也不能进入system suspend.
wake_unlock: 释放系统唤醒锁,让整个系统可以进入System Suspend, 当然UFS 设备也 能进入system suspend.
(4) UFS 设备相关System PM状态:
系统System PM 相关状态:
#define PM_SUSPEND_ON ((__force suspend_state_t) 0)
#define PM_SUSPEND_TO_IDLE ((__force suspend_state_t) 1)
#define PM_SUSPEND_STANDBY ((__force suspend_state_t) 2)
#define PM_SUSPEND_MEM ((__force suspend_state_t) 3)
#define PM_SUSPEND_MIN PM_SUSPEND_TO_IDLE
#define PM_SUSPEND_MAX ((__force suspend_state_t) 4)
kernel/power/main.c
static ssize_t state_store(struct kobject *kobj, struct kobj_attribute *attr,
const char *buf, size_t n)
{
suspend_state_t state;
int error;error = pm_autosleep_lock();
if (error)
return error;if (pm_autosleep_state() > PM_SUSPEND_ON) {
error = -EBUSY;
goto out;
}state = decode_state(buf, n);
if (state < PM_SUSPEND_MAX) {
if (state == PM_SUSPEND_MEM)
state = mem_sleep_current;error = pm_suspend(state);
} else if (state == PM_SUSPEND_MAX) {
error = hibernate();
} else {
error = -EINVAL;
}out:
pm_autosleep_unlock();
return error ? error : n;
}
UFS System PM相关状态:
/* Used to differentiate the power management options */
enum ufs_pm_op {
UFS_RUNTIME_PM,
UFS_SYSTEM_PM,
UFS_SHUTDOWN_PM,
};
/**
* ufshcd_system_suspend - system suspend routine
* @hba: per adapter instance
*
* Check the description of ufshcd_suspend() function for more details.
*
* Returns 0 for success and non-zero for failure
*/
int ufshcd_system_suspend(struct ufs_hba *hba)
{
int ret = 0;
ktime_t start = ktime_get();if (!hba || !hba->is_powered)
return 0;if ((ufs_get_pm_lvl_to_dev_pwr_mode(hba->spm_lvl) ==
hba->curr_dev_pwr_mode) &&
(ufs_get_pm_lvl_to_link_pwr_state(hba->spm_lvl) ==
hba->uic_link_state))
goto out;if (pm_runtime_suspended(hba->dev)) {
/*
* UFS device and/or UFS link low power states during runtime
* suspend seems to be different than what is expected during
* system suspend. Hence runtime resume the devic & link and
* let the system suspend low power states to take effect.
* TODO: If resume takes longer time, we might have optimize
* it in future by not resuming everything if possible.
*/
ret = ufshcd_runtime_resume(hba);
if (ret)
goto out;
}ret = ufshcd_suspend(hba, UFS_SYSTEM_PM);
out:
trace_ufshcd_system_suspend(dev_name(hba->dev), ret,
ktime_to_us(ktime_sub(ktime_get(), start)),
hba->curr_dev_pwr_mode, hba->uic_link_state);
if (!ret)
hba->is_sys_suspended = true;
return ret;
}
EXPORT_SYMBOL(ufshcd_system_suspend);
(6)UFS 驱动常用System PM使用接口和使用场景:
系统开始进入System Suspend的时候,会循环遍历每个设备都进入System Suspend状态,包 括UFS设备,UFS驱动没有显性调用System PM的接口,主要是受系统Suspend机制管理,当系 统开始进入Suspend流程的时候,UFS设备也是空闲的状态的时候,此时UFS设备就会进入System Suspend的状态,UFS驱动发送SSU命令让UFS Device进入SLEEP Mode, 发送DME_HIBER_ENTER让MPHY Link 进入Hibernate状态,并且UFS Device的VCC供电也会关闭,节省功耗。
三. 参考资料
1. Kernel System Power Management Source Code
2 . Kernel Runtime Power Management Source Code
3. Kernel UFS Power Management Source Code
边栏推荐
- [reinforcement learning medical] deep reinforcement learning for clinical decision support: a brief overview
- 牛熊周期与加密的未来如何演变?看看红杉资本怎么说
- LeetCode精选200道--数组篇
- The bank needs to build the middle office capability of the intelligent customer service module to drive the upgrade of the whole scene intelligent customer service
- 很多小夥伴不太了解ORM框架的底層原理,這不,冰河帶你10分鐘手擼一個極簡版ORM框架(趕快收藏吧)
- burpsuite
- Nacos microservice gateway component +swagger2 interface generation
- Version 2.0 of tapdata, the open source live data platform, has been released
- metasploit
- 《ClickHouse原理解析与应用实践》读书笔记(7)
猜你喜欢
关于TXE和TC标志位的小知识
Nanny level tutorial: Azkaban executes jar package (with test samples and results)
Nacos microservice gateway component +swagger2 interface generation
Keras深度学习实战——基于Inception v3实现性别分类
Clickhouse principle analysis and application practice "reading notes (8)
List of top ten domestic industrial 3D visual guidance enterprises in 2022
Nmap tool introduction and common commands
咋吃都不胖的朋友,Nature告诉你原因:是基因突变了
力争做到国内赛事应办尽办,国家体育总局明确安全有序恢复线下体育赛事
牛熊周期与加密的未来如何演变?看看红杉资本怎么说
随机推荐
#797div3 A---C
A comprehensive and detailed explanation of static routing configuration, a quick start guide to static routing
微信小程序uniapp页面无法跳转:“navigateTo:fail can not navigateTo a tabbar page“
Strive to ensure that domestic events should be held as much as possible, and the State General Administration of sports has made it clear that offline sports events should be resumed safely and order
电路如图,R1=2kΩ,R2=2kΩ,R3=4kΩ,Rf=4kΩ。求输出与输入关系表达式。
Can you write the software test questions?
JVM memory and garbage collection-3-runtime data area / method area
Reading notes of Clickhouse principle analysis and Application Practice (7)
Leetcode featured 200 channels -- array article
分布式定时任务之XXL-JOB
leetcode 865. Smallest Subtree with all the Deepest Nodes | 865.具有所有最深节点的最小子树(树的BFS,parent反向索引map)
阿锅鱼的大度
很多小夥伴不太了解ORM框架的底層原理,這不,冰河帶你10分鐘手擼一個極簡版ORM框架(趕快收藏吧)
"Hands on learning in depth" Chapter 2 - preparatory knowledge_ 2.2 data preprocessing_ Learning thinking and exercise answers
In depth analysis of ArrayList source code, from the most basic capacity expansion principle, to the magic iterator and fast fail mechanism, you have everything you want!!!
线程死锁——死锁产生的条件
Emqx 5.0 release: open source Internet of things message server with single cluster supporting 100million mqtt connections
Alo who likes TestMan
Direct addition is more appropriate
鱼和虾走的路